From 89d2bdce5b930fb20ec5c2ad764962a0dd16fa3a Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 19 Aug 2022 16:47:28 +0200 Subject: [PATCH 001/291] Initial commit for real hidpi support Note: This commit has only been tested on MacOS Changes: - Icons now use the native hidpi support from Gtk (through Icon Theme) - Icons are now directly generated from scalable file (i.e. SVG file) - Widget sizes are scaled based on DPI and scale factor - Font size is scaled based on DPI and scale factor --- CMakeLists.txt | 14 +- rtdata/CMakeLists.txt | 25 +- rtdata/images/{svg => }/splash.svg | 0 rtdata/images/{svg => }/splash_template.svg | 0 rtdata/images/svg/index.theme | 55 +++ rtgui/adjuster.cc | 9 +- rtgui/batchqueue.cc | 6 +- rtgui/batchqueuebuttonset.cc | 12 +- rtgui/batchqueuebuttonset.h | 6 +- rtgui/batchqueueentry.cc | 12 +- rtgui/batchqueueentry.h | 3 +- rtgui/batchqueuepanel.cc | 18 +- rtgui/blackwhite.cc | 22 +- rtgui/cacorrection.cc | 8 +- rtgui/chmixer.cc | 20 +- rtgui/coarsepanel.cc | 8 +- rtgui/colorappearance.cc | 66 +-- rtgui/colortoning.cc | 58 +-- rtgui/controllines.cc | 20 +- rtgui/controllines.h | 4 +- rtgui/controlspotpanel.cc | 20 +- rtgui/crop.cc | 8 +- rtgui/cropwindow.cc | 58 ++- rtgui/cursormanager.cc | 99 ++--- rtgui/cursormanager.h | 1 - rtgui/curveeditor.cc | 14 +- rtgui/curveeditorgroup.cc | 13 +- rtgui/darkframe.cc | 2 +- rtgui/diagonalcurveeditorsubgroup.cc | 40 +- rtgui/dirbrowser.cc | 40 +- rtgui/dirbrowser.h | 16 +- rtgui/distortion.cc | 8 +- rtgui/editorpanel.cc | 52 +-- rtgui/editwidgets.cc | 34 +- rtgui/editwidgets.h | 36 +- rtgui/editwindow.cc | 59 +-- rtgui/editwindow.h | 3 - rtgui/exifpanel.cc | 25 +- rtgui/exifpanel.h | 9 +- rtgui/exportpanel.cc | 4 +- rtgui/fattaltonemap.cc | 6 +- rtgui/favoritbrowser.cc | 7 +- rtgui/filebrowser.cc | 6 +- rtgui/filebrowserentry.cc | 36 +- rtgui/filebrowserentry.h | 11 +- rtgui/filecatalog.cc | 82 ++-- rtgui/filethumbnailbuttonset.cc | 40 +- rtgui/filethumbnailbuttonset.h | 14 +- rtgui/filmnegative.cc | 16 +- rtgui/filterpanel.cc | 2 +- rtgui/flatcurveeditorsubgroup.cc | 14 +- rtgui/flatfield.cc | 2 +- rtgui/gradient.cc | 6 +- rtgui/guiutils.cc | 133 +++--- rtgui/guiutils.h | 18 +- rtgui/histogrampanel.cc | 84 ++-- rtgui/history.cc | 4 +- rtgui/iccprofilecreator.cc | 19 +- rtgui/icmpanel.cc | 34 +- rtgui/imagearea.cc | 8 +- rtgui/indclippedpanel.cc | 39 +- rtgui/indclippedpanel.h | 8 +- rtgui/inspector.cc | 10 +- rtgui/iptcpanel.cc | 16 +- rtgui/labgrid.cc | 60 +-- rtgui/lensgeom.cc | 2 +- rtgui/lensprofile.cc | 32 +- rtgui/locallabtools.cc | 128 +++--- rtgui/locallabtools2.cc | 290 +++++++------- rtgui/lwbutton.cc | 10 +- rtgui/lwbutton.h | 8 +- rtgui/main.cc | 13 +- rtgui/mycurve.cc | 14 +- rtgui/mydiagonalcurve.cc | 10 +- rtgui/myflatcurve.cc | 8 +- rtgui/perspective.cc | 40 +- rtgui/placesbrowser.cc | 6 +- rtgui/popupcommon.cc | 15 +- rtgui/preferences.cc | 30 +- rtgui/previewmodepanel.cc | 91 ++--- rtgui/previewmodepanel.h | 25 +- rtgui/previewwindow.cc | 10 +- rtgui/profilepanel.cc | 24 +- rtgui/profilepanel.h | 4 +- rtgui/rawcacorrection.cc | 8 +- rtgui/retinex.cc | 8 +- rtgui/rotate.cc | 6 +- rtgui/rtimage.cc | 201 +--------- rtgui/rtimage.h | 38 +- rtgui/rtscalable.cc | 423 ++++++++++---------- rtgui/rtscalable.h | 62 +-- rtgui/rtsurface.cc | 274 +++++++++---- rtgui/rtsurface.h | 82 ++-- rtgui/rtwindow.cc | 167 ++++---- rtgui/shcselector.cc | 20 +- rtgui/splash.cc | 79 ++-- rtgui/splash.h | 3 +- rtgui/spot.cc | 16 +- rtgui/thresholdadjuster.cc | 2 +- rtgui/thresholdselector.cc | 10 +- rtgui/thumbbrowserbase.cc | 10 +- rtgui/toolbar.cc | 16 +- rtgui/toolpanel.cc | 2 +- rtgui/toolpanelcoord.cc | 26 +- rtgui/wavelet.cc | 70 ++-- rtgui/whitebalance.cc | 98 ++--- rtgui/whitebalance.h | 6 +- rtgui/zoompanel.cc | 12 +- 108 files changed, 1949 insertions(+), 2032 deletions(-) rename rtdata/images/{svg => }/splash.svg (100%) rename rtdata/images/{svg => }/splash_template.svg (100%) create mode 100644 rtdata/images/svg/index.theme diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a55ca6d5..53480968c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ endif() # Warning for GCC vectorization issues, which causes problems #5749 and #6384: if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "10.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.2") OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0"))) - message(STATUS "WARNING: gcc ${CMAKE_CXX_COMPILER_VERSION} is known to miscompile RawTherapee when using -ftree-loop-vectorize, forcing the option to be off") + message(STATUS "WARNING: gcc ${CMAKE_CXX_COMPILER_VERSION} is known to miscompile RawTherapee when using -ftree-loop-vectorize, forcing the option to be off") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-loop-vectorize") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-loop-vectorize") endif() @@ -438,13 +438,9 @@ endif() # Check for libraries: find_package(PkgConfig) -if(WIN32) - pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.22.24) - pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.22) -else() - pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.16) - pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.16) -endif() +# Gtk version shall be greater than 3.24.3 for fixed Hi-DPI support +pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.24.3) +pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.24) if(GTK_VERSION VERSION_GREATER "3.24.1" AND GTK_VERSION VERSION_LESS "3.24.7") if(GTK_VERSION VERSION_EQUAL "3.24.5") @@ -471,7 +467,7 @@ pkg_check_modules(GTHREAD REQUIRED gthread-2.0>=2.48) pkg_check_modules(GOBJECT REQUIRED gobject-2.0>=2.48) pkg_check_modules(SIGC REQUIRED sigc++-2.0>=2.3.1) pkg_check_modules(LENSFUN REQUIRED lensfun>=0.2) -pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.40) +pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.46) if(WIN32) add_definitions(-DWIN32) diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index eb4b5e934..5597f51b7 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -8,8 +8,7 @@ file(GLOB FONTS "fonts/*") set(PROFILESDIR "profiles") set(THEMEDIR "themes") -file(GLOB IMG_SVG LIST_DIRECTORIES false "images/svg/*") -file(GLOB IMG_PNG LIST_DIRECTORIES false "images/png/*") +file(GLOB IMG_SVG LIST_DIRECTORIES false "images/svg/*.svg") file(GLOB IMG_ICO LIST_DIRECTORIES false "images/*") if(WIN32) @@ -27,16 +26,17 @@ endif() if(UNIX) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/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}/images/png/rawtherapee-logo-16.png" DESTINATION "${ICONSDIR}/hicolor/16x16/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-24.png" DESTINATION "${ICONSDIR}/hicolor/24x24/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-32.png" DESTINATION "${ICONSDIR}/hicolor/32x32/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-48.png" DESTINATION "${ICONSDIR}/hicolor/48x48/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-64.png" DESTINATION "${ICONSDIR}/hicolor/64x64/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-128.png" DESTINATION "${ICONSDIR}/hicolor/128x128/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-256.png" DESTINATION "${ICONSDIR}/hicolor/256x256/apps" RENAME rawtherapee.png) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/rt-logo.svg" DESTINATION "${ICONSDIR}/hicolor/scalable/apps" RENAME rawtherapee.svg) endif() +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-16.png" DESTINATION "${ICONSDIR}/rawtherapee/16x16/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-24.png" DESTINATION "${ICONSDIR}/rawtherapee/24x24/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-32.png" DESTINATION "${ICONSDIR}/rawtherapee/32x32/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-48.png" DESTINATION "${ICONSDIR}/rawtherapee/48x48/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-64.png" DESTINATION "${ICONSDIR}/rawtherapee/64x64/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-128.png" DESTINATION "${ICONSDIR}/rawtherapee/128x128/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-256.png" DESTINATION "${ICONSDIR}/rawtherapee/256x256/app_icons" RENAME rawtherapee.png) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/rt-logo.svg" DESTINATION "${ICONSDIR}/rawtherapee/scalable/app_icons" RENAME rawtherapee.svg) + install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") install(FILES ${SOUNDFILES} DESTINATION "${DATADIR}/sounds") install(FILES ${INPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/input") @@ -50,8 +50,9 @@ endif() install(DIRECTORY "${PROFILESDIR}" DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") -install(FILES ${IMG_SVG} DESTINATION "${DATADIR}/images") -install(FILES ${IMG_PNG} DESTINATION "${DATADIR}/images") +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/empty.png" DESTINATION "${ICONSDIR}/rawtherapee/24x24/apps") +install(FILES ${IMG_SVG} DESTINATION "${ICONSDIR}/rawtherapee/scalable/apps") +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/svg/Index.theme" DESTINATION "${ICONSDIR}/rawtherapee") install(FILES ${IMG_ICO} DESTINATION "${DATADIR}/images") if(APPLE) diff --git a/rtdata/images/svg/splash.svg b/rtdata/images/splash.svg similarity index 100% rename from rtdata/images/svg/splash.svg rename to rtdata/images/splash.svg diff --git a/rtdata/images/svg/splash_template.svg b/rtdata/images/splash_template.svg similarity index 100% rename from rtdata/images/svg/splash_template.svg rename to rtdata/images/splash_template.svg diff --git a/rtdata/images/svg/index.theme b/rtdata/images/svg/index.theme new file mode 100644 index 000000000..c862ff01f --- /dev/null +++ b/rtdata/images/svg/index.theme @@ -0,0 +1,55 @@ +[Icon Theme] +Name=RawTherapee +Comment=RawTherapee icon theme +Inherits=Adwaita +Directories=16x16/app_icons,24x24/app_icons,32x32/app_icons,48x48/app_icons,64x64/app_icons,128x128/app_icons,256x256/app_icons,scalable/app_icons,scalable/apps + + +[16x16/app_icons] +Size=16 +Context=ApplicationIcons +Type=Threshold + +[24x24/app_icons] +Size=24 +Context=ApplicationIcons +Type=Threshold + +[32x32/app_icons] +Size=32 +Context=ApplicationIcons +Type=Threshold + +[48x48/app_icons] +Size=48 +Context=ApplicationIcons +Type=Threshold + +[64x64/app_icons] +Size=64 +Context=ApplicationIcons +Type=Threshold + +[128x128/app_icons] +Size=128 +Context=ApplicationIcons +Type=Threshold + +[256x256/app_icons] +Size=256 +Context=ApplicationIcons +Type=Threshold + +[scalable/app_icons] +MinSize=16 +Size=128 +MaxSize=256 +Context=ApplicationIcons +Type=Scalable + +[scalable/apps] +MinSize=16 +Size=128 +MaxSize=256 +Context=Applications +Type=Scalable diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index a2f96cac3..c7077ddcf 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -24,6 +24,7 @@ #include "multilangmgr.h" #include "options.h" #include "rtimage.h" +#include "rtscalable.h" #include "../rtengine/rt_math.h" namespace { @@ -92,7 +93,7 @@ Adjuster::Adjuster( reset = Gtk::manage(new Gtk::Button()); - reset->add(*Gtk::manage(new RTImage("undo-small.png", "redo-small.png"))); + reset->add(*Gtk::manage(new RTImage("undo-small", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(reset, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); reset->set_relief(Gtk::RELIEF_NONE); reset->set_tooltip_markup(M("ADJUSTER_RESET_TO_DEFAULT")); @@ -104,7 +105,7 @@ Adjuster::Adjuster( setExpandAlignProperties(spin, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); spin->set_input_purpose(Gtk::INPUT_PURPOSE_DIGITS); - reset->set_size_request(-1, spin->get_height() > MIN_RESET_BUTTON_HEIGHT ? spin->get_height() : MIN_RESET_BUTTON_HEIGHT); + reset->set_size_request(-1, RTScalable::scalePixelSize(spin->get_height() > MIN_RESET_BUTTON_HEIGHT ? spin->get_height() : MIN_RESET_BUTTON_HEIGHT)); slider = Gtk::manage(new MyHScale()); setExpandAlignProperties(slider, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); slider->set_draw_value(false); @@ -192,7 +193,7 @@ void Adjuster::addAutoButton (const Glib::ustring &tooltip) { if (!automatic) { automatic = Gtk::manage(new Gtk::CheckButton()); - //automatic->add (*Gtk::manage (new RTImage ("gears.png"))); + //automatic->add (*Gtk::manage (new RTImage ("gears"))); automatic->set_tooltip_markup(tooltip.length() ? Glib::ustring::compose("%1\n\n%2", M("GENERAL_AUTO"), tooltip) : M("GENERAL_AUTO")); setExpandAlignProperties(automatic, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); autoChange = automatic->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::autoToggled) ); @@ -615,7 +616,7 @@ void Adjuster::setLogScale(double base, double pivot, bool anchorMiddle) logPivot = pivot; logAnchorMiddle = anchorMiddle; setSliderValue(cur); - + sliderChange.block(false); spinChange.block(false); } diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 19da96fb5..463ac7cde 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -57,16 +57,16 @@ BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCa pmenu.attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p + 1); p++; - pmenu.attach (*Gtk::manage(head = new MyImageMenuItem (M("FILEBROWSER_POPUPMOVEHEAD"), "goto-start-small.png")), 0, 1, p, p + 1); + pmenu.attach (*Gtk::manage(head = new MyImageMenuItem (M("FILEBROWSER_POPUPMOVEHEAD"), "goto-start-small")), 0, 1, p, p + 1); p++; - pmenu.attach (*Gtk::manage(tail = new MyImageMenuItem (M("FILEBROWSER_POPUPMOVEEND"), "goto-end-small.png")), 0, 1, p, p + 1); + pmenu.attach (*Gtk::manage(tail = new MyImageMenuItem (M("FILEBROWSER_POPUPMOVEEND"), "goto-end-small")), 0, 1, p, p + 1); p++; pmenu.attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p + 1); p++; - pmenu.attach (*Gtk::manage(cancel = new MyImageMenuItem (M("FILEBROWSER_POPUPCANCELJOB"), "cancel-small.png")), 0, 1, p, p + 1); + pmenu.attach (*Gtk::manage(cancel = new MyImageMenuItem (M("FILEBROWSER_POPUPCANCELJOB"), "cancel-small")), 0, 1, p, p + 1); pmenu.show_all (); diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc index 969a55079..f68a7b4e7 100644 --- a/rtgui/batchqueuebuttonset.cc +++ b/rtgui/batchqueuebuttonset.cc @@ -25,9 +25,9 @@ bool BatchQueueButtonSet::iconsLoaded = false; -Cairo::RefPtr BatchQueueButtonSet::cancelIcon; -Cairo::RefPtr BatchQueueButtonSet::headIcon; -Cairo::RefPtr BatchQueueButtonSet::tailIcon; +std::shared_ptr BatchQueueButtonSet::cancelIcon = std::shared_ptr(nullptr); +std::shared_ptr BatchQueueButtonSet::headIcon = std::shared_ptr(nullptr); +std::shared_ptr BatchQueueButtonSet::tailIcon = std::shared_ptr(nullptr); Glib::ustring BatchQueueButtonSet::moveHeadToolTip; Glib::ustring BatchQueueButtonSet::moveEndToolTip; @@ -37,9 +37,9 @@ BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) { if (!iconsLoaded) { - cancelIcon = Cairo::RefPtr(new RTSurface("cancel-small.png")); - headIcon = Cairo::RefPtr(new RTSurface("goto-start-small.png")); - tailIcon = Cairo::RefPtr(new RTSurface("goto-end-small.png")); + cancelIcon = std::shared_ptr(new RTSurface("cancel-small", Gtk::ICON_SIZE_BUTTON)); + headIcon = std::shared_ptr(new RTSurface("goto-start-small", Gtk::ICON_SIZE_BUTTON)); + tailIcon = std::shared_ptr(new RTSurface("goto-end-small", Gtk::ICON_SIZE_BUTTON)); moveHeadToolTip = M("FILEBROWSER_POPUPMOVEHEAD"); moveEndToolTip = M("FILEBROWSER_POPUPMOVEEND"); cancelJobToolTip = M("FILEBROWSER_POPUPCANCELJOB"); diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h index fb45df518..2ff96c914 100644 --- a/rtgui/batchqueuebuttonset.h +++ b/rtgui/batchqueuebuttonset.h @@ -31,9 +31,9 @@ class BatchQueueButtonSet : public LWButtonSet static bool iconsLoaded; public: - static Cairo::RefPtr cancelIcon; - static Cairo::RefPtr headIcon; - static Cairo::RefPtr tailIcon; + static std::shared_ptr cancelIcon; + static std::shared_ptr headIcon; + static std::shared_ptr tailIcon; static Glib::ustring moveHeadToolTip; static Glib::ustring moveEndToolTip; diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 31a6f40c7..6ab6ccf83 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -22,7 +22,7 @@ #include "guiutils.h" #include "threadutils.h" -#include "rtimage.h" +#include "rtsurface.h" #include "multilangmgr.h" #include "thumbbrowserbase.h" #include "thumbnail.h" @@ -31,7 +31,7 @@ #include "../rtengine/rtengine.h" bool BatchQueueEntry::iconsLoaded(false); -Glib::RefPtr BatchQueueEntry::savedAsIcon; +std::shared_ptr BatchQueueEntry::savedAsIcon; BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm, bool overwrite) : ThumbBrowserEntryBase(fname), @@ -59,7 +59,7 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine: #endif if (!iconsLoaded) { - savedAsIcon = RTImage::createPixbufFromFile ("save-small.png"); + savedAsIcon = std::shared_ptr(new RTPixbuf("save-small", Gtk::ICON_SIZE_BUTTON)); iconsLoaded = true; } @@ -159,7 +159,7 @@ std::vector> BatchQueueEntry::getIconsOnImageArea () std::vector > ret; if (!outFileName.empty()) { - ret.push_back (savedAsIcon); + ret.push_back (savedAsIcon->get()); } return ret; @@ -168,8 +168,8 @@ std::vector> BatchQueueEntry::getIconsOnImageArea () void BatchQueueEntry::getIconSize (int& w, int& h) const { - w = savedAsIcon->get_width (); - h = savedAsIcon->get_height (); + w = savedAsIcon->get()->get_width (); + h = savedAsIcon->get()->get_height (); } diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index f06b65046..6b57614e8 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -29,6 +29,7 @@ #include "../rtengine/noncopyable.h" class Thumbnail; +class RTPixbuf; namespace rtengine { @@ -61,7 +62,7 @@ class BatchQueueEntry final : public ThumbBrowserEntryBase, public BQEntryUpdate public: - static Glib::RefPtr savedAsIcon; + static std::shared_ptr savedAsIcon; rtengine::ProcessingJob* job; const std::unique_ptr params; diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 8a6dd25b4..f44c54cd0 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -89,7 +89,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) hb3->pack_start (*outdirFolderButton); outdirFolderButton->signal_pressed().connect( sigc::mem_fun(*this, &BatchQueuePanel::pathFolderButtonPressed) ); outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder)); - Gtk::Image* folderImg = Gtk::manage (new RTImage ("folder-closed.png")); + Gtk::Image* folderImg = Gtk::manage (new RTImage ("folder-closed", Gtk::ICON_SIZE_LARGE_TOOLBAR)); folderImg->show (); outdirFolderButton->set_image (*folderImg); outdirFolder = nullptr; @@ -152,13 +152,13 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) 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 ("magnifier-plus.png"))); + zoomInButton->set_image (*Gtk::manage (new RTImage ("magnifier-plus", Gtk::ICON_SIZE_LARGE_TOOLBAR))); 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 ("magnifier-minus.png"))); + zoomOutButton->set_image (*Gtk::manage (new RTImage ("magnifier-minus", Gtk::ICON_SIZE_LARGE_TOOLBAR))); zoomOutButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomOut)); zoomOutButton->set_relief (Gtk::RELIEF_NONE); zoomOutButton->set_tooltip_markup (M("FILEBROWSER_ZOOMOUTHINT")); @@ -208,13 +208,13 @@ void BatchQueuePanel::updateTab (int qsize, int forceOrientation) Gtk::Label* l; if(!qsize ) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears.png")), Gtk::POS_TOP, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_TOP, 1, 1); l = Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_QUEUE")) ); } else if (qStartStop->get_active()) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play.png")), Gtk::POS_TOP, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_TOP, 1, 1); l = Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]")); } else { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause.png")), Gtk::POS_TOP, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_TOP, 1, 1); l = Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]" )); } @@ -228,13 +228,13 @@ void BatchQueuePanel::updateTab (int qsize, int forceOrientation) } } else { if (!qsize ) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears.png")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears")), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") )), Gtk::POS_RIGHT, 1, 1); } else if (qStartStop->get_active()) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play.png")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play")), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]" )), Gtk::POS_RIGHT, 1, 1); } else { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause.png")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause")), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]" )), Gtk::POS_RIGHT, 1, 1); } diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc index 7b54f09d2..215f28503 100644 --- a/rtgui/blackwhite.cc +++ b/rtgui/blackwhite.cc @@ -187,18 +187,18 @@ BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LAB //----------- RGB / ROYGCBPM Mixer ------------------------------ - imgIcon[0] = Gtk::manage (new RTImage ("circle-red-small.png")); - imgIcon[1] = Gtk::manage (new RTImage ("circle-orange-small.png")); - imgIcon[2] = Gtk::manage (new RTImage ("circle-yellow-small.png")); - imgIcon[3] = Gtk::manage (new RTImage ("circle-green-small.png")); - imgIcon[4] = Gtk::manage (new RTImage ("circle-cyan-small.png")); - imgIcon[5] = Gtk::manage (new RTImage ("circle-blue-small.png")); - imgIcon[6] = Gtk::manage (new RTImage ("circle-purple-small.png")); - imgIcon[7] = Gtk::manage (new RTImage ("circle-magenta-small.png")); + imgIcon[0] = Gtk::manage (new RTImage ("circle-red-small")); + imgIcon[1] = Gtk::manage (new RTImage ("circle-orange-small")); + imgIcon[2] = Gtk::manage (new RTImage ("circle-yellow-small")); + imgIcon[3] = Gtk::manage (new RTImage ("circle-green-small")); + imgIcon[4] = Gtk::manage (new RTImage ("circle-cyan-small")); + imgIcon[5] = Gtk::manage (new RTImage ("circle-blue-small")); + imgIcon[6] = Gtk::manage (new RTImage ("circle-purple-small")); + imgIcon[7] = Gtk::manage (new RTImage ("circle-magenta-small")); - imgIcon[8] = Gtk::manage (new RTImage ("circle-empty-red-small.png")); - imgIcon[9] = Gtk::manage (new RTImage ("circle-empty-green-small.png")); - imgIcon[10] = Gtk::manage (new RTImage ("circle-empty-blue-small.png")); + imgIcon[8] = Gtk::manage (new RTImage ("circle-empty-red-small")); + imgIcon[9] = Gtk::manage (new RTImage ("circle-empty-green-small")); + imgIcon[10] = Gtk::manage (new RTImage ("circle-empty-blue-small")); mixerVBox->pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL))); diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc index 971c0a284..79df63963 100644 --- a/rtgui/cacorrection.cc +++ b/rtgui/cacorrection.cc @@ -30,10 +30,10 @@ using namespace rtengine::procparams; CACorrection::CACorrection () : FoldableToolPanel(this, "cacorrection", M("TP_CACORRECTION_LABEL")) { - Gtk::Image* icaredL = Gtk::manage (new RTImage ("circle-red-cyan-small.png")); - Gtk::Image* icaredR = Gtk::manage (new RTImage ("circle-cyan-red-small.png")); - Gtk::Image* icablueL = Gtk::manage (new RTImage ("circle-blue-yellow-small.png")); - Gtk::Image* icablueR = Gtk::manage (new RTImage ("circle-yellow-blue-small.png")); + Gtk::Image* icaredL = Gtk::manage (new RTImage ("circle-red-cyan-small")); + Gtk::Image* icaredR = Gtk::manage (new RTImage ("circle-cyan-red-small")); + Gtk::Image* icablueL = Gtk::manage (new RTImage ("circle-blue-yellow-small")); + Gtk::Image* icablueR = Gtk::manage (new RTImage ("circle-yellow-blue-small")); red = Gtk::manage (new Adjuster (M("TP_CACORRECTION_RED"), -0.005, 0.005, 0.0001, 0, icaredL, icaredR)); red->setAdjusterListener (this); diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc index 619d7be3e..c64b7f252 100644 --- a/rtgui/chmixer.cc +++ b/rtgui/chmixer.cc @@ -28,15 +28,15 @@ using namespace rtengine::procparams; ChMixer::ChMixer (): FoldableToolPanel(this, "chmixer", M("TP_CHMIXER_LABEL"), false, true) { - imgIcon[0] = Gtk::manage (new RTImage ("circle-red-small.png")); - imgIcon[1] = Gtk::manage (new RTImage ("circle-green-red-small.png")); - imgIcon[2] = Gtk::manage (new RTImage ("circle-blue-red-small.png")); - imgIcon[3] = Gtk::manage (new RTImage ("circle-red-green-small.png")); - imgIcon[4] = Gtk::manage (new RTImage ("circle-green-small.png")); - imgIcon[5] = Gtk::manage (new RTImage ("circle-blue-green-small.png")); - imgIcon[6] = Gtk::manage (new RTImage ("circle-red-blue-small.png")); - imgIcon[7] = Gtk::manage (new RTImage ("circle-green-blue-small.png")); - imgIcon[8] = Gtk::manage (new RTImage ("circle-blue-small.png")); + imgIcon[0] = Gtk::manage (new RTImage ("circle-red-small")); + imgIcon[1] = Gtk::manage (new RTImage ("circle-green-red-small")); + imgIcon[2] = Gtk::manage (new RTImage ("circle-blue-red-small")); + imgIcon[3] = Gtk::manage (new RTImage ("circle-red-green-small")); + imgIcon[4] = Gtk::manage (new RTImage ("circle-green-small")); + imgIcon[5] = Gtk::manage (new RTImage ("circle-blue-green-small")); + imgIcon[6] = Gtk::manage (new RTImage ("circle-red-blue-small")); + imgIcon[7] = Gtk::manage (new RTImage ("circle-green-blue-small")); + imgIcon[8] = Gtk::manage (new RTImage ("circle-blue-small")); Gtk::Label* rlabel = Gtk::manage (new Gtk::Label ()); rlabel->set_markup (Glib::ustring("\t") + M("TP_CHMIXER_RED") + Glib::ustring(":")); @@ -108,7 +108,7 @@ void ChMixer::read (const ProcParams* pp, const ParamsEdited* pedited) disableListener (); setEnabled(pp->chmixer.enabled); - + if (pedited) { for (int i = 0; i < 3; i++) { red[i]->setEditedState (pedited->chmixer.red[i] ? Edited : UnEdited); diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc index c64d53017..48f8041df 100644 --- a/rtgui/coarsepanel.cc +++ b/rtgui/coarsepanel.cc @@ -31,25 +31,25 @@ CoarsePanel::CoarsePanel () : ToolPanel (), oldhflip(false), oldvflip(false) degree = 0; degreechanged = true; - Gtk::Image* rotateli = Gtk::manage (new RTImage ("rotate-left-90.png")); + Gtk::Image* rotateli = Gtk::manage (new RTImage ("rotate-left-90", Gtk::ICON_SIZE_LARGE_TOOLBAR)); 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 ("rotate-right-90.png")); + Gtk::Image* rotateri = Gtk::manage (new RTImage ("rotate-right-90", Gtk::ICON_SIZE_LARGE_TOOLBAR)); 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 ("flip-horizontal.png")); + Gtk::Image* fliphi = Gtk::manage (new RTImage ("flip-horizontal", Gtk::ICON_SIZE_LARGE_TOOLBAR)); 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 ("flip-vertical.png")); + Gtk::Image* flipvi = Gtk::manage (new RTImage ("flip-vertical", Gtk::ICON_SIZE_LARGE_TOOLBAR)); vflip = Gtk::manage (new Gtk::ToggleButton ()); vflip->add (*flipvi); vflip->set_relief(Gtk::RELIEF_NONE); diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index f579da6e6..8c2a79d63 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -234,7 +234,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" genFrame->set_tooltip_markup (M ("TP_COLORAPP_GEN_TOOLTIP")); genVBox = Gtk::manage ( new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); genVBox->set_spacing (2); - + complexmethod = Gtk::manage (new MyComboBoxText ()); complexmethod->append(M("TP_WAVELET_COMPNORMAL")); complexmethod->append(M("TP_WAVELET_COMPEXPERT")); @@ -245,7 +245,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" complexHBox->pack_start(*complexLabel, Gtk::PACK_SHRINK, 4); complexHBox->pack_start(*complexmethod); genVBox->pack_start (*complexHBox, Gtk::PACK_SHRINK); - + modelmethod = Gtk::manage (new MyComboBoxText ()); modelmethod->append(M("TP_COLORAPP_MOD02")); modelmethod->append(M("TP_COLORAPP_MOD16")); @@ -268,7 +268,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" catHBox->pack_start(*catLabel, Gtk::PACK_SHRINK, 4); catHBox->pack_start(*catmethod); genVBox->pack_start (*catHBox, Gtk::PACK_SHRINK); - + presetcat02 = Gtk::manage (new Gtk::CheckButton (M ("TP_COLORAPP_PRESETCAT02"))); presetcat02->set_tooltip_markup (M("TP_COLORAPP_PRESETCAT02_TIP")); presetcat02conn = presetcat02->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::presetcat02pressed)); @@ -324,7 +324,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" wbmHBox = Gtk::manage (new Gtk::Box ()); - + wbmHBox->set_spacing (2); wbmHBox->set_tooltip_markup (M ("TP_COLORAPP_MODEL_TOOLTIP")); Gtk::Label* wbmLab = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_MODEL") + ":")); @@ -358,10 +358,10 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" illumHBox->pack_start (*illum); p1VBox->pack_start (*illumHBox); - Gtk::Image* itempL = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* itempR = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* igreenL = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* itempL = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* itempR = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* igreenL = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small")); tempsc = Gtk::manage (new Adjuster (M ("TP_WBALANCE_TEMPERATURE"), MINTEMP0, MAXTEMP0, 5, CENTERTEMP0, itempL, itempR, &wbSlider2Temp, &wbTemp2Slider)); @@ -649,10 +649,10 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" p3VBox = Gtk::manage ( new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); p3VBox->set_spacing (2); - Gtk::Image* itempL1 = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* itempR1 = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* igreenL1 = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenR1 = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* itempL1 = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* itempR1 = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* igreenL1 = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenR1 = Gtk::manage (new RTImage ("circle-green-small")); adaplum = Gtk::manage (new Adjuster (M ("TP_COLORAPP_ABSOLUTELUMINANCE"), MINLA0, MAXLA0, 0.01, 16.));//, NULL, NULL, &wbSlider2la, &wbla2Slider)); adaplum->setLogScale(500, 0); @@ -662,8 +662,8 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" adaplum->set_tooltip_markup (M ("TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP")); p3VBox->pack_start (*adaplum); -// Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small.png")); -// Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small.png")); +// Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small")); +// Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small")); degreeout = Gtk::manage (new Adjuster (M ("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 90.)); @@ -675,10 +675,10 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" degreeout->addAutoButton (M ("TP_COLORAPP_CAT02ADAPTATION_TOOLTIP")); p3VBox->pack_start (*degreeout); /* - Gtk::Image* itempL1 = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* itempR1 = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* igreenL1 = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenR1 = Gtk::manage (new RTImage ("circle-green-small.png")); + Gtk::Image* itempL1 = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* itempR1 = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* igreenL1 = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenR1 = Gtk::manage (new RTImage ("circle-green-small")); */ tempout = Gtk::manage (new Adjuster (M ("TP_WBALANCE_TEMPERATURE"), MINTEMP0, MAXTEMP0, 5, CENTERTEMP0, itempR1, itempL1, &wbSlider2Temp, &wbTemp2Slider)); greenout = Gtk::manage (new Adjuster (M ("TP_WBALANCE_GREEN"), MINGREEN0, MAXGREEN0, 0.001, 1.0, igreenR1, igreenL1)); @@ -742,7 +742,7 @@ ColorAppearance::ColorAppearance () : FoldableToolPanel (this, "colorappearance" //reset button neutral = Gtk::manage (new Gtk::Button (M ("TP_COLORAPP_NEUTRAL"))); setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); + RTImage* const resetImg = Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON)); setExpandAlignProperties (resetImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); neutral->set_image (*resetImg); neutral->set_tooltip_text (M ("TP_COLORAPP_NEUTRAL_TIP")); @@ -887,7 +887,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) nexttemp = pp->wb.temperature; nextgreen = 1.; //pp->wb.green; - + if (pedited) { degree->setEditedState (pedited->colorappearance.degree ? Edited : UnEdited); degreeout->setEditedState (pedited->colorappearance.degreeout ? Edited : UnEdited); @@ -959,7 +959,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) } else if (pp->colorappearance.complexmethod == "expert") { complexmethod->set_active(1); } - + modelmethod->set_active(0); if (pp->colorappearance.modelmethod == "02") { @@ -1374,7 +1374,7 @@ void ColorAppearance::updateGUIToMode(int mode) badpixsl->hide(); datacie->hide(); } else { - alHBox->show(); + alHBox->show(); wbmHBox->show(); curveEditorG->show(); curveEditorG2->show(); @@ -1416,7 +1416,7 @@ void ColorAppearance::convertParamToNormal() } void ColorAppearance::complexmethodChanged() -{ +{ if (complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); convertParamToNormal(); @@ -1431,7 +1431,7 @@ void ColorAppearance::complexmethodChanged() } void ColorAppearance::modelmethodChanged() -{ +{ if (listener && (multiImage || getEnabled())) { listener->panelChanged(EvCATmodel, modelmethod->get_active_text()); @@ -1439,7 +1439,7 @@ void ColorAppearance::modelmethodChanged() } void ColorAppearance::catmethodChanged() -{ +{ if (catmethod->get_active_row_number() == 1) { disableListener(); @@ -1488,7 +1488,7 @@ void ColorAppearance::catmethodChanged() degreeout->setValue(90); ybout->setValue(18); tempout->setValue (nexttemp); - + /* if(tempout->getAutoValue()) { tempout->resetValue (false); } else { @@ -1498,7 +1498,7 @@ void ColorAppearance::catmethodChanged() */ greenout->setValue (nextgreen); enableListener(); - + } else if (catmethod->get_active_row_number() == 0) { disableListener(); degree->setAutoValue (true); @@ -1756,7 +1756,7 @@ void ColorAppearance::presetcat02pressed () //keep in case of... degreeout->setValue(90); ybout->setValue(18); tempout->setValue (nexttemp); - + /* if(tempout->getAutoValue()) { tempout->resetValue (false); } else { @@ -1816,7 +1816,7 @@ void ColorAppearance::presetcat02pressed () //keep in case of... tempout->resetValue (false); greenout->resetValue (false); enableListener(); - + } if (batchMode) { if (presetcat02->get_inconsistent()) { @@ -2005,7 +2005,7 @@ void ColorAppearance::adapCamChanged (double cadap) if(presetcat02->get_active()){ return; } - + idle_register.add( [this, cadap]() -> bool { @@ -2020,7 +2020,7 @@ void ColorAppearance::adapCamChanged (double cadap) void ColorAppearance::wbCamChanged (double temp, double tin) { - + idle_register.add( [this, temp, tin]() -> bool { @@ -2132,7 +2132,7 @@ void ColorAppearance::adjusterAutoToggled(Adjuster* a) tempout->setAutoValue (true); } } -*/ +*/ if (multiImage) { if (degree->getAutoInconsistent()) { degree->setAutoInconsistent (false); @@ -2276,7 +2276,7 @@ void ColorAppearance::wbmodelChanged () tempsc->hide(); greensc->hide(); tempsc->setValue (5003); - greensc->setValue (1); + greensc->setValue (1); } if (wbmodel->get_active_row_number() == 2) { diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 0140c5b62..43332a500 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -127,8 +127,8 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR pack_start( *opacityCurveEditorG, Gtk::PACK_SHRINK, 2); //---------Chroma curve 1 -------------------- - iby = Gtk::manage (new RTImage ("circle-yellow-blue-small.png")); - irg = Gtk::manage (new RTImage ("circle-green-red-small.png")); + iby = Gtk::manage (new RTImage ("circle-yellow-blue-small")); + irg = Gtk::manage (new RTImage ("circle-green-red-small")); clCurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_CHROMAC")); clCurveEditorG->setCurveListener (this); @@ -169,7 +169,7 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR //--------------------- Reset curves ----------------------------- /* Each curve can reset to a different curve, so this button only save one click now... so we remove it. neutralCurves = Gtk::manage (new Gtk::Button (M("TP_COLORTONING_NEUTRALCUR"))); - RTImage *resetImgc = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); + RTImage *resetImgc = Gtk::manage (new RTImage ("undo-small")); neutralCurves->set_image(*resetImgc); neutralCurves->set_tooltip_text (M("TP_COLORTONING_NEUTRALCUR_TIP")); neutralcurvesconn = neutralCurves->signal_pressed().connect( sigc::mem_fun(*this, &ColorToning::neutralCurves_pressed) ); @@ -249,26 +249,26 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR Gtk::Box* chanMixerMidBox = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); Gtk::Box* chanMixerShadowsBox = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); - Gtk::Image* iblueR = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iyelL = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* imagL = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small.png")); - Gtk::Image* icyanL = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iredR = Gtk::manage (new RTImage ("circle-red-small.png")); + Gtk::Image* iblueR = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iyelL = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* imagL = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small")); + Gtk::Image* icyanL = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iredR = Gtk::manage (new RTImage ("circle-red-small")); - Gtk::Image* iblueRm = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iyelLm = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* imagLm = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenRm = Gtk::manage (new RTImage ("circle-green-small.png")); - Gtk::Image* icyanLm = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iredRm = Gtk::manage (new RTImage ("circle-red-small.png")); + Gtk::Image* iblueRm = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iyelLm = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* imagLm = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenRm = Gtk::manage (new RTImage ("circle-green-small")); + Gtk::Image* icyanLm = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iredRm = Gtk::manage (new RTImage ("circle-red-small")); - Gtk::Image* iblueRh = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iyelLh = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* imagLh = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenRh = Gtk::manage (new RTImage ("circle-green-small.png")); - Gtk::Image* icyanLh = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iredRh = Gtk::manage (new RTImage ("circle-red-small.png")); + Gtk::Image* iblueRh = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iyelLh = Gtk::manage (new RTImage ("circle-yellow-small")); + Gtk::Image* imagLh = Gtk::manage (new RTImage ("circle-magenta-small")); + Gtk::Image* igreenRh = Gtk::manage (new RTImage ("circle-green-small")); + Gtk::Image* icyanLh = Gtk::manage (new RTImage ("circle-blue-small")); + Gtk::Image* iredRh = Gtk::manage (new RTImage ("circle-red-small")); redhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., icyanLh, iredRh )); greenhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., imagLh , igreenRh)); @@ -299,7 +299,7 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR chanMixerHLFrame->set_label_align (0.025, 0.5); chanMixerMidFrame->set_label_align (0.025, 0.5); chanMixerShadowsFrame->set_label_align (0.025, 0.5); - + chanMixerHLFrame->add(*chanMixerHLBox); chanMixerMidFrame->add(*chanMixerMidBox); chanMixerShadowsFrame->add(*chanMixerShadowsBox); @@ -393,23 +393,23 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR hb->pack_start(*labRegionList, Gtk::PACK_EXPAND_WIDGET); Gtk::Box* vb = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); labRegionAdd = Gtk::manage(new Gtk::Button()); - labRegionAdd->add(*Gtk::manage(new RTImage("add-small.png"))); + labRegionAdd->add(*Gtk::manage(new RTImage("add-small", Gtk::ICON_SIZE_BUTTON))); labRegionAdd->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionAddPressed)); add_button(labRegionAdd, vb); labRegionRemove = Gtk::manage(new Gtk::Button()); - labRegionRemove->add(*Gtk::manage(new RTImage("remove-small.png"))); + labRegionRemove->add(*Gtk::manage(new RTImage("remove-small", Gtk::ICON_SIZE_BUTTON))); labRegionRemove->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionRemovePressed)); add_button(labRegionRemove, vb); labRegionUp = Gtk::manage(new Gtk::Button()); - labRegionUp->add(*Gtk::manage(new RTImage("arrow-up-small.png"))); + labRegionUp->add(*Gtk::manage(new RTImage("arrow-up-small", Gtk::ICON_SIZE_BUTTON))); labRegionUp->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionUpPressed)); add_button(labRegionUp, vb); labRegionDown = Gtk::manage(new Gtk::Button()); - labRegionDown->add(*Gtk::manage(new RTImage("arrow-down-small.png"))); + labRegionDown->add(*Gtk::manage(new RTImage("arrow-down-small", Gtk::ICON_SIZE_BUTTON))); labRegionDown->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionDownPressed)); add_button(labRegionDown, vb); labRegionCopy = Gtk::manage(new Gtk::Button()); - labRegionCopy->add(*Gtk::manage(new RTImage("arrow-right-small.png"))); + labRegionCopy->add(*Gtk::manage(new RTImage("arrow-right-small", Gtk::ICON_SIZE_BUTTON))); labRegionCopy->signal_clicked().connect(sigc::mem_fun(*this, &ColorToning::labRegionCopyPressed)); add_button(labRegionCopy, vb); hb->pack_start(*vb, Gtk::PACK_SHRINK); @@ -717,7 +717,7 @@ void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) pp->colorToning.strength = strength->getIntValue(); double zerox = 0.; double zeroy = 0.; - + labgrid->getParams(pp->colorToning.labgridALow, pp->colorToning.labgridBLow, pp->colorToning.labgridAHigh, pp->colorToning.labgridBHigh, zerox, zeroy, zerox, zeroy); pp->colorToning.labgridALow *= ColorToningParams::LABGRID_CORR_MAX; pp->colorToning.labgridAHigh *= ColorToningParams::LABGRID_CORR_MAX; @@ -1570,7 +1570,7 @@ void ColorToning::labRegionShow(int idx, bool list_only) disableListener(); } rtengine::procparams::ColorToningParams::LabCorrectionRegion dflt; - auto &r = labRegionData[idx]; + auto &r = labRegionData[idx]; if (!list_only) { labRegionAB->setParams(0, 0, r.a, r.b,0, 0, 0, 0, false); labRegionSaturation->setValue(r.saturation); diff --git a/rtgui/controllines.cc b/rtgui/controllines.cc index d28ef12ca..3ef144295 100644 --- a/rtgui/controllines.cc +++ b/rtgui/controllines.cc @@ -92,14 +92,14 @@ ControlLineManager::ControlLineManager(): canvas_area->topLeft = Coord(0, 0); mouseOverGeometry.push_back(canvas_area.get()); - line_icon_h = Cairo::RefPtr(new RTSurface( - "bidirectional-arrow-horizontal-hicontrast.png")); - line_icon_v = Cairo::RefPtr(new RTSurface( - "bidirectional-arrow-vertical-hicontrast.png")); - line_icon_h_prelight = Cairo::RefPtr(new RTSurface( - "bidirectional-arrow-horizontal-prelight.png")); - line_icon_v_prelight = Cairo::RefPtr(new RTSurface( - "bidirectional-arrow-vertical-prelight.png")); + line_icon_h = std::shared_ptr(new RTSurface( + "bidirectional-arrow-horizontal-hicontrast", Gtk::ICON_SIZE_BUTTON)); + line_icon_v = std::shared_ptr(new RTSurface( + "bidirectional-arrow-vertical-hicontrast", Gtk::ICON_SIZE_BUTTON)); + line_icon_h_prelight = std::shared_ptr(new RTSurface( + "bidirectional-arrow-horizontal-prelight", Gtk::ICON_SIZE_BUTTON)); + line_icon_v_prelight = std::shared_ptr(new RTSurface( + "bidirectional-arrow-vertical-prelight", Gtk::ICON_SIZE_BUTTON)); } ControlLineManager::~ControlLineManager() = default; @@ -438,8 +438,8 @@ void ControlLineManager::addLine(Coord begin, Coord end, line->begin = begin; line->end = end; - const Cairo::RefPtr null_surface = - Cairo::RefPtr(nullptr); + const std::shared_ptr null_surface = + std::shared_ptr(nullptr); icon_h = std::make_shared(line_icon_h, null_surface, line_icon_h_prelight, diff --git a/rtgui/controllines.h b/rtgui/controllines.h index 9e850da1c..e440f838f 100644 --- a/rtgui/controllines.h +++ b/rtgui/controllines.h @@ -60,8 +60,8 @@ protected: bool drawing_line; bool edited; std::size_t horizontalCount, verticalCount; - Cairo::RefPtr line_icon_h, line_icon_v; - Cairo::RefPtr line_icon_h_prelight, line_icon_v_prelight; + std::shared_ptr line_icon_h, line_icon_v; + std::shared_ptr line_icon_h_prelight, line_icon_v_prelight; int prev_obj; int selected_object; diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 400309512..1e986eed7 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -72,14 +72,14 @@ ControlSpotPanel::ControlSpotPanel(): struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))), thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 10.0, 0.1, 2.0))), iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0.2, 10.0, 0.1, 2.0))), - balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), - balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16.png")), Gtk::manage(new RTImage("circle-red-green-small.png"))))), - colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small.png")), Gtk::manage(new RTImage("circle-gray-green-small.png"))))), + balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee")), Gtk::manage(new RTImage("circle-white-small"))))), + balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee")), Gtk::manage(new RTImage("circle-red-green-small"))))), + colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-gray-green-small"))))), colorscope_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORSCOPE"), 0., 100.0, 1., 30.))), avoidrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_AVOIDRAD"), 0., 30.0, 0.1, 0.7))), scopemask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SCOPEMASK"), 0, 100, 1, 60))), denoichmask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DENOIMASK"), 0., 100., 0.5, 0))), - lumask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LUMASK"), -50, 30, 1, 10, Gtk::manage(new RTImage("circle-yellow-small.png")), Gtk::manage(new RTImage("circle-gray-small.png")) ))), + lumask_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LUMASK"), -50, 30, 1, 10, Gtk::manage(new RTImage("circle-yellow-small")), Gtk::manage(new RTImage("circle-gray-small")) ))), hishow_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_PREVSHOW")))), activ_(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIVSPOT")))), @@ -121,7 +121,7 @@ ControlSpotPanel::ControlSpotPanel(): prevMethodconn_ = prevMethod_->signal_changed().connect( sigc::mem_fun( *this, &ControlSpotPanel::prevMethodChanged)); - + // ctboxprevmethod->pack_start(*prevMethod_); pack_start(*ctboxprevmethod); @@ -253,7 +253,7 @@ ControlSpotPanel::ControlSpotPanel(): sensiexclu_->setAdjusterListener(this); structexclu_->setAdjusterListener(this); structexclu_->setLogScale(10, 0); - + excluBox->pack_start(*sensiexclu_); excluBox->pack_start(*structexclu_); excluFrame->add(*excluBox); @@ -385,7 +385,7 @@ ControlSpotPanel::ControlSpotPanel(): expShapeDetect_->add(*artifBox, false); pack_start(*expShapeDetect_, false, false); ToolParamBlock* const artifBox2 = Gtk::manage(new ToolParamBlock()); - + artifBox2->pack_start(*preview_); artifBox2->pack_start(*colorscope_); pack_start(*artifBox2); @@ -401,7 +401,7 @@ ControlSpotPanel::ControlSpotPanel(): sigc::mem_fun(*this, &ControlSpotPanel::avoidChanged)); avoidmunConn_ = avoidmun_->signal_toggled().connect( sigc::mem_fun(*this, &ControlSpotPanel::avoidmunChanged)); - + Gtk::Frame* const avFrame = Gtk::manage(new Gtk::Frame()); ToolParamBlock* const avbox = Gtk::manage(new ToolParamBlock()); avFrame->set_label_align(0.025, 0.5); @@ -455,7 +455,7 @@ ControlSpotPanel::ControlSpotPanel(): ctboxwavmethod->pack_start(*wavMethod_); specCaseBox->pack_start(*ctboxwavmethod); - + expSpecCases_->add(*specCaseBox, false); pack_start(*expSpecCases_, false, false); @@ -1297,7 +1297,7 @@ void ControlSpotPanel::updateParamVisibility() ctboxshape->show(); } - + } void ControlSpotPanel::adjusterChanged(Adjuster* a, double newval) diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 853cec255..bf26dcc63 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -174,12 +174,12 @@ Crop::Crop(): selectCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_SELECTCROP"))); setExpandAlignProperties(selectCrop, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); selectCrop->get_style_context()->add_class("independent"); - selectCrop->set_image (*Gtk::manage (new RTImage ("crop-small.png"))); + selectCrop->set_image (*Gtk::manage (new RTImage ("crop-small", Gtk::ICON_SIZE_BUTTON))); resetCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_RESETCROP"))); setExpandAlignProperties(resetCrop, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); resetCrop->get_style_context()->add_class("independent"); - resetCrop->set_image (*Gtk::manage (new RTImage ("undo-small.png"))); + resetCrop->set_image (*Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON))); methodgrid->attach (*xlab, 0, 0, 1, 1); methodgrid->attach (*x, 1, 0, 1, 1); @@ -592,11 +592,11 @@ void Crop::doresetCrop () yDirty = true; wDirty = true; hDirty = true; - + // Reset ratio, ratio lock and orientation as well ratio->set_active(0); orientation->set_active(2); - fixr->set_active(true); + fixr->set_active(true); int X = 0; int Y = 0; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index c7d7348b3..a5f332f9f 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -64,7 +64,21 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet 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); + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px" + const int fontSize = 8; + const int absoluteFontSize = fontSize * Pango::SCALE; + // Guessing that absolute pixel size is given for a 96 DPI reference: +#ifndef __APPLE__ + const double fontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); context->set_font_description (fontd); Glib::RefPtr cllayout = parent->create_pango_layout("1000%"); @@ -80,11 +94,11 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet closett = "Close"; initialized = true; } - bZoomOut = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-minus-small.png")), 0, nullptr, LWButton::Left, LWButton::Center, &zoomOuttt); - bZoomIn = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-plus-small.png")), 1, nullptr, LWButton::Left, LWButton::Center, &zoomIntt); - bZoom100 = new LWButton(Cairo::RefPtr(new RTSurface("magnifier-1to1-small.png")), 2, nullptr, LWButton::Left, LWButton::Center, &zoom100tt); - //bZoomFit = new LWButton (Cairo::RefPtr(new RTSurface("magnifier-fit.png")), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); - bClose = new LWButton(Cairo::RefPtr(new RTSurface("cancel-small.png")), 4, nullptr, LWButton::Right, LWButton::Center, &closett); + bZoomOut = new LWButton(std::shared_ptr(new RTSurface("magnifier-minus-small", Gtk::ICON_SIZE_BUTTON)), 0, nullptr, LWButton::Left, LWButton::Center, &zoomOuttt); + bZoomIn = new LWButton(std::shared_ptr(new RTSurface("magnifier-plus-small", Gtk::ICON_SIZE_BUTTON)), 1, nullptr, LWButton::Left, LWButton::Center, &zoomIntt); + bZoom100 = new LWButton(std::shared_ptr(new RTSurface("magnifier-1to1-small", Gtk::ICON_SIZE_BUTTON)), 2, nullptr, LWButton::Left, LWButton::Center, &zoom100tt); + //bZoomFit = new LWButton (std::shared_ptr(new RTSurface("magnifier-fit", Gtk::ICON_SIZE_BUTTON)), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); + bClose = new LWButton(std::shared_ptr(new RTSurface("cancel-small", Gtk::ICON_SIZE_BUTTON)), 4, nullptr, LWButton::Right, LWButton::Center, &closett); buttonSet.add (bZoomOut); buttonSet.add (bZoomIn); @@ -2451,7 +2465,21 @@ void CropWindow::drawDecoration (Cairo::RefPtr cr) 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); + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px" + const int fontSize = 8; + const int absoluteFontSize = fontSize * Pango::SCALE; + // Guessing that absolute pixel size is given for a 96 DPI reference: +#ifndef __APPLE__ + const double fontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); context->set_font_description (fontd); Glib::RefPtr cllayout = iarea->create_pango_layout(cropLabel); int iw, ih; @@ -2515,7 +2543,21 @@ void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) 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); + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px" + const int fontSize = 8; + const int absoluteFontSize = fontSize * Pango::SCALE; + // Guessing that absolute pixel size is given for a 96 DPI reference: +#ifndef __APPLE__ + const double fontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); 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))); diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index e915150aa..f683e9964 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -17,8 +17,7 @@ * along with RawTherapee. If not, see . */ #include "cursormanager.h" - -#include "rtimage.h" +#include "rtsurface.h" CursorManager mainWindowCursorManager; CursorManager editWindowCursorManager; @@ -35,74 +34,46 @@ void CursorManager::init (Glib::RefPtr mainWindow) #endif - Glib::RefPtr add = RTImage::createPixbufFromFile("crosshair-small.png"); - Glib::RefPtr colPick = RTImage::createPixbufFromFile("color-picker-hicontrast.png"); - Glib::RefPtr colPickAdd = RTImage::createPixbufFromFile("color-picker-add-hicontrast.png"); - Glib::RefPtr cropDraw = RTImage::createPixbufFromFile("crop-point-hicontrast.png"); - Glib::RefPtr crosshair = RTImage::createPixbufFromFile("crosshair-hicontrast.png"); - Glib::RefPtr empty = RTImage::createPixbufFromFile("empty.png"); - Glib::RefPtr handClosed = RTImage::createPixbufFromFile("hand-closed-hicontrast.png"); - Glib::RefPtr handOpen = RTImage::createPixbufFromFile("hand-open-hicontrast.png"); - Glib::RefPtr moveBL = RTImage::createPixbufFromFile("node-move-sw-ne-hicontrast.png"); - Glib::RefPtr moveBR = RTImage::createPixbufFromFile("node-move-nw-se-hicontrast.png"); - Glib::RefPtr moveL = RTImage::createPixbufFromFile("node-move-x-hicontrast.png"); - Glib::RefPtr moveR = RTImage::createPixbufFromFile("node-move-x-hicontrast.png"); - Glib::RefPtr moveTL = RTImage::createPixbufFromFile("node-move-nw-se-hicontrast.png"); - Glib::RefPtr moveTR = RTImage::createPixbufFromFile("node-move-sw-ne-hicontrast.png"); - Glib::RefPtr moveX = RTImage::createPixbufFromFile("node-move-x-hicontrast.png"); - Glib::RefPtr moveXY = RTImage::createPixbufFromFile("node-move-xy-hicontrast.png"); - Glib::RefPtr moveY = RTImage::createPixbufFromFile("node-move-y-hicontrast.png"); - Glib::RefPtr rotate = RTImage::createPixbufFromFile("rotate-aroundnode-hicontrast.png"); - Glib::RefPtr wait = RTImage::createPixbufFromFile("gears.png"); // Currently unused, create *-hicontrast once used. + auto createCursor = [this] (const Glib::ustring &name, const Gdk::CursorType &fb_cursor) -> Glib::RefPtr + { + // Gdk Cursor Theme is not supported on some OS (ex : MacOS) + // Cursor is retrieved from theme thanks to an RTSurface + auto cursor_surf = RTSurface(name, Gtk::ICON_SIZE_MENU); + auto cursor = Gdk::Cursor::create(this->display, + cursor_surf.get(), + cursor_surf.getWidth() / 2, + cursor_surf.getHeight() / 2); - double s = RTScalable::getTweakedDPI() / RTScalable::baseDPI; // RTScalable::getDPI() might be preferable, however it imply a lot of work to support this option + if (!cursor) { + cursor = Gdk::Cursor::create(this->display, fb_cursor); + } - cAdd = add ? Gdk::Cursor::create(display, add, (int)(8.*s), (int)(8.*s)) : Gdk::Cursor::create(display, Gdk::PLUS); - cAddPicker = colPickAdd ? Gdk::Cursor::create(display, colPickAdd, (int)(4.*s), (int)(21.*s)) : Gdk::Cursor::create(display, Gdk::PLUS); - cCropDraw = cropDraw ? Gdk::Cursor::create(display, cropDraw, (int)(3.*s), (int)(3.*s)) : Gdk::Cursor::create(display, Gdk::DIAMOND_CROSS); - cCrosshair = crosshair ? Gdk::Cursor::create(display, crosshair, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::CROSSHAIR); - cEmpty = empty ? Gdk::Cursor::create(display, empty, 12, 12) /* PNG: do not scale */ : Gdk::Cursor::create(display, Gdk::BLANK_CURSOR); - cHandClosed = handClosed ? Gdk::Cursor::create(display, handClosed, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND1); - cHandOpen = handOpen ? Gdk::Cursor::create(display, handOpen, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::HAND2); - cMoveBL = moveBL ? Gdk::Cursor::create(display, moveBL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BOTTOM_LEFT_CORNER); - cMoveBR = moveBR ? Gdk::Cursor::create(display, moveBR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::BOTTOM_RIGHT_CORNER); - cMoveL = moveL ? Gdk::Cursor::create(display, moveL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_LEFT_ARROW); - cMoveR = moveR ? Gdk::Cursor::create(display, moveR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_RIGHT_ARROW); - cMoveTL = moveTL ? Gdk::Cursor::create(display, moveTL, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::TOP_LEFT_CORNER); - cMoveTR = moveTR ? Gdk::Cursor::create(display, moveTR, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::TOP_RIGHT_CORNER); - cMoveX = moveX ? Gdk::Cursor::create(display, moveX, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_H_DOUBLE_ARROW); - cMoveXY = moveXY ? Gdk::Cursor::create(display, moveXY, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::FLEUR); - cMoveY = moveY ? Gdk::Cursor::create(display, moveY, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::SB_V_DOUBLE_ARROW); - cRotate = rotate ? Gdk::Cursor::create(display, rotate, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::EXCHANGE); - cWB = colPick ? Gdk::Cursor::create(display, colPick, (int)(4.*s), (int)(21.*s)) : Gdk::Cursor::create(display, Gdk::TARGET); - cWait = wait ? Gdk::Cursor::create(display, wait, (int)(12.*s), (int)(12.*s)) : Gdk::Cursor::create(display, Gdk::CLOCK); + return cursor; + }; + + cAdd = createCursor("crosshair-small", Gdk::PLUS); + cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS); + cCropDraw = createCursor("crop-point-hicontrast", Gdk::DIAMOND_CROSS); + cCrosshair = createCursor("crosshair-hicontrast", Gdk::CROSSHAIR); + cEmpty = createCursor("empty", Gdk::BLANK_CURSOR); + cHandClosed = createCursor("hand-closed-hicontrast", Gdk::HAND1); + cHandOpen = createCursor("hand-open-hicontrast", Gdk::HAND2); + cMoveBL = createCursor("node-move-sw-ne-hicontrast", Gdk::BOTTOM_LEFT_CORNER); + cMoveBR = createCursor("node-move-nw-se-hicontrast", Gdk::BOTTOM_RIGHT_CORNER); + cMoveL = createCursor("node-move-x-hicontrast", Gdk::SB_LEFT_ARROW); + cMoveR = createCursor("node-move-x-hicontrast", Gdk::SB_RIGHT_ARROW); + cMoveTL = createCursor("node-move-nw-se-hicontrast", Gdk::TOP_LEFT_CORNER); + cMoveTR = createCursor("node-move-sw-ne-hicontrast", Gdk::TOP_RIGHT_CORNER); + cMoveX = createCursor("node-move-x-hicontrast", Gdk::SB_H_DOUBLE_ARROW); + cMoveXY = createCursor("node-move-xy-hicontrast", Gdk::FLEUR); + cMoveY = createCursor("node-move-y-hicontrast", Gdk::SB_V_DOUBLE_ARROW); + cRotate = createCursor("rotate-aroundnode-hicontrast", Gdk::EXCHANGE); + cWB = createCursor("color-picker-hicontrast", Gdk::TARGET); + cWait = createCursor("gears", Gdk::CLOCK); window = mainWindow; } -void CursorManager::cleanup() -{ - cAdd.reset(); - cAddPicker.reset(); - cCropDraw.reset(); - cCrosshair.reset(); - cHandClosed.reset(); - cHandOpen.reset(); - cEmpty.reset(); - cMoveBL.reset(); - cMoveBR.reset(); - cMoveL.reset(); - cMoveR.reset(); - cMoveTL.reset(); - cMoveTR.reset(); - cMoveX.reset(); - cMoveY.reset(); - cMoveXY.reset(); - cRotate.reset(); - cWB.reset(); - cWait.reset(); -} - /* Set the cursor of the given window */ void CursorManager::setCursor (Glib::RefPtr window, CursorShape shape) { diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h index 38f198e32..8b506bb1d 100644 --- a/rtgui/cursormanager.h +++ b/rtgui/cursormanager.h @@ -81,7 +81,6 @@ private: public: void init (Glib::RefPtr mainWindow); - void cleanup (); static void setWidgetCursor (Glib::RefPtr window, CursorShape shape); static void setCursorOfMainWindow (Glib::RefPtr window, CursorShape shape); }; diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index 67cea5174..efe2ef200 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -75,11 +75,11 @@ bool CurveEditor::reset() DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup) : CurveEditor::CurveEditor(text, static_cast(ceGroup), ceSubGroup) { - curveType->addEntry("curve-linear-small.png", M("CURVEEDITOR_LINEAR")); // 0 Linear - curveType->addEntry("curve-spline-small.png", M("CURVEEDITOR_CUSTOM")); // 1 Spline - curveType->addEntry("curve-catmullrom-small.png", M("CURVEEDITOR_CATMULLROM")); // 4 CatmullRom - curveType->addEntry("curve-parametric-small.png", M("CURVEEDITOR_PARAMETRIC")); // 2 Parametric - curveType->addEntry("curve-nurbs-small.png", M("CURVEEDITOR_NURBS")); // 3 NURBS + curveType->addEntry("curve-linear-small", M("CURVEEDITOR_LINEAR")); // 0 Linear + curveType->addEntry("curve-spline-small", M("CURVEEDITOR_CUSTOM")); // 1 Spline + curveType->addEntry("curve-catmullrom-small", M("CURVEEDITOR_CATMULLROM")); // 4 CatmullRom + curveType->addEntry("curve-parametric-small", M("CURVEEDITOR_PARAMETRIC")); // 2 Parametric + curveType->addEntry("curve-nurbs-small", M("CURVEEDITOR_NURBS")); // 3 NURBS static_cast(curveType)->setPosIndexMap({ 0, 1, 4, 2, 3 }); curveType->setSelected(DCT_Linear); @@ -199,8 +199,8 @@ FlatCurveEditor::FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, identityValue = 0.5; // Order set in the same order than "enum FlatCurveType". Shouldn't change, for compatibility reason - curveType->addEntry("curve-flat-small.png", M("CURVEEDITOR_LINEAR")); // 0 Linear - curveType->addEntry("curve-controlpoints-small.png", M("CURVEEDITOR_MINMAXCPOINTS")); // 1 Min/Max ControlPoints + curveType->addEntry("curve-flat-small", M("CURVEEDITOR_LINEAR")); // 0 Linear + curveType->addEntry("curve-controlpoints-small", M("CURVEEDITOR_MINMAXCPOINTS")); // 1 Min/Max ControlPoints curveType->setSelected(FCT_Linear); curveType->show(); } diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index d099e1a99..f348ac33b 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -28,6 +28,7 @@ #include "rtimage.h" #include "options.h" #include "pathutils.h" +#include "rtscalable.h" CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel, int blank) : curveDir(curveDir), line(0), curve_reset(nullptr), displayedCurve(nullptr), flatSubGroup(nullptr), diagonalSubGroup(nullptr), cl(nullptr), numberOfPackedCurve(0) @@ -39,9 +40,9 @@ CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring group } else if(blank == 1){ curveGroupLabel = Gtk::manage (new Gtk::Label (groupLabel, Gtk::ALIGN_START)); } - + setExpandAlignProperties(curveGroupLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - set_row_spacing(RTScalable::getScale()); + set_row_spacing(RTScalable::scalePixelSize(1)); } CurveEditorGroup::~CurveEditorGroup() @@ -129,7 +130,7 @@ void CurveEditorGroup::newLine() if (curveEditors.size() > numberOfPackedCurve) { Gtk::Grid* currLine = Gtk::manage (new Gtk::Grid ()); setExpandAlignProperties(currLine, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - currLine->set_column_spacing(RTScalable::getScale()); + currLine->set_column_spacing(RTScalable::scalePixelSize(1)); bool isHeader = false; int x = 0; @@ -162,7 +163,7 @@ void CurveEditorGroup::newLine() if (isHeader) { curve_reset = Gtk::manage (new Gtk::Button ()); setExpandAlignProperties(curve_reset, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - curve_reset->add (*Gtk::manage (new RTImage ("undo-small.png", "redo-small.png"))); + curve_reset->add (*Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON))); curve_reset->set_relief (Gtk::RELIEF_NONE); curve_reset->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLINEAR")); curve_reset->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditorGroup::curveResetPressed) ); @@ -381,7 +382,7 @@ void CurveEditorGroup::setTooltip( Glib::ustring ttip) void CurveEditorGroup::setBatchMode (bool batchMode) { for (std::vector::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) { - (*i)->curveType->addEntry("template-24.png", M("GENERAL_UNCHANGED")); + (*i)->curveType->addEntry("template-24", M("GENERAL_UNCHANGED")); (*i)->curveType->show(); } } @@ -441,7 +442,7 @@ void CurveEditorSubGroup::initButton (Gtk::Button &button, const Glib::ustring & vAlign = options.curvebboxpos == 0 || options.curvebboxpos == 2 ? Gtk::ALIGN_FILL : Gtk::ALIGN_END; } - button.add (*Gtk::manage (new RTImage (iconName))); + button.add (*Gtk::manage (new RTImage(iconName, Gtk::ICON_SIZE_BUTTON))); button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT); if (!tooltip.empty()) { button.set_tooltip_text(M(tooltip)); diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index b6b1201a7..1d478b2a3 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -38,7 +38,7 @@ DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_L bindCurrentFolder (*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 ("cancel-small.png"))); + btnReset->set_image (*Gtk::manage(new RTImage ("cancel-small", Gtk::ICON_SIZE_BUTTON))); hbdf->pack_start(*dfLabel, Gtk::PACK_SHRINK, 0); hbdf->pack_start(*darkFrameFile); hbdf->pack_start(*btnReset, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index f4fc8449e..55d6d457f 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -33,6 +33,7 @@ #include "rtimage.h" #include "options.h" #include "popuptogglebutton.h" +#include "rtscalable.h" #include "../rtengine/curves.h" @@ -85,18 +86,18 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointCustom = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCustom, Glib::ustring("edit-point.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); + initButton(*editPointCustom, Glib::ustring("edit-point"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editCustom = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCustom, Glib::ustring("crosshair-node-curve.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); + initButton(*editCustom, Glib::ustring("crosshair-node-curve"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editCustom->hide(); copyCustom = Gtk::manage (new Gtk::Button ()); - initButton(*copyCustom, Glib::ustring("copy.png"), Gtk::ALIGN_END, true); + initButton(*copyCustom, Glib::ustring("copy"), Gtk::ALIGN_END, true); pasteCustom = Gtk::manage (new Gtk::Button ()); - initButton(*pasteCustom, Glib::ustring("paste.png"), Gtk::ALIGN_END, false); + initButton(*pasteCustom, Glib::ustring("paste"), Gtk::ALIGN_END, false); loadCustom = Gtk::manage (new Gtk::Button ()); - initButton(*loadCustom, Glib::ustring("folder-open.png"), Gtk::ALIGN_END, false); + initButton(*loadCustom, Glib::ustring("folder-open"), Gtk::ALIGN_END, false); saveCustom = Gtk::manage (new Gtk::Button ()); - initButton(*saveCustom, Glib::ustring("save.png"), Gtk::ALIGN_END, false); + initButton(*saveCustom, Glib::ustring("save"), Gtk::ALIGN_END, false); custombbox->attach_next_to(*editPointCustom, sideStart, 1, 1); custombbox->attach_next_to(*editCustom, sideStart, 1, 1); @@ -177,18 +178,18 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } editPointNURBS = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointNURBS, Glib::ustring("edit-point.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); + initButton(*editPointNURBS, Glib::ustring("edit-point"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); editNURBS = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editNURBS, Glib::ustring("crosshair-node-curve.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); + initButton(*editNURBS, Glib::ustring("crosshair-node-curve"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editNURBS->hide(); copyNURBS = Gtk::manage (new Gtk::Button ()); - initButton(*copyNURBS, Glib::ustring("copy.png"), Gtk::ALIGN_END, true); + initButton(*copyNURBS, Glib::ustring("copy"), Gtk::ALIGN_END, true); pasteNURBS = Gtk::manage (new Gtk::Button ()); - initButton(*pasteNURBS, Glib::ustring("paste.png"), Gtk::ALIGN_END, false); + initButton(*pasteNURBS, Glib::ustring("paste"), Gtk::ALIGN_END, false); loadNURBS = Gtk::manage (new Gtk::Button ()); - initButton(*loadNURBS, Glib::ustring("folder-open.png"), Gtk::ALIGN_END, false); + initButton(*loadNURBS, Glib::ustring("folder-open"), Gtk::ALIGN_END, false); saveNURBS = Gtk::manage (new Gtk::Button ()); - initButton(*saveNURBS, Glib::ustring("save.png"), Gtk::ALIGN_END, false); + initButton(*saveNURBS, Glib::ustring("save"), Gtk::ALIGN_END, false); NURBSbbox->attach_next_to(*editPointNURBS, sideStart, 1, 1); NURBSbbox->attach_next_to(*editNURBS, sideStart, 1, 1); @@ -273,16 +274,16 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, paramCurveBox->attach_next_to(*shcSelector, *paramCurve, Gtk::POS_BOTTOM, 1, 1); editParam = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editParam, Glib::ustring("crosshair-node-curve.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); + initButton(*editParam, Glib::ustring("crosshair-node-curve"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editParam->hide(); copyParam = Gtk::manage (new Gtk::Button ()); - initButton(*copyParam, Glib::ustring("copy.png"), Gtk::ALIGN_END, true); + initButton(*copyParam, Glib::ustring("copy"), Gtk::ALIGN_END, true); pasteParam = Gtk::manage (new Gtk::Button ()); - initButton(*pasteParam, Glib::ustring("paste.png"), Gtk::ALIGN_END, false); + initButton(*pasteParam, Glib::ustring("paste"), Gtk::ALIGN_END, false); loadParam = Gtk::manage (new Gtk::Button ()); - initButton(*loadParam, Glib::ustring("folder-open.png"), Gtk::ALIGN_END, false); + initButton(*loadParam, Glib::ustring("folder-open"), Gtk::ALIGN_END, false); saveParam = Gtk::manage (new Gtk::Button ()); - initButton(*saveParam, Glib::ustring("save.png"), Gtk::ALIGN_END, false); + initButton(*saveParam, Glib::ustring("save"), Gtk::ALIGN_END, false); parambbox->attach_next_to(*editParam, sideStart, 1, 1); parambbox->attach_next_to(*copyParam, sideEnd, 1, 1); @@ -753,7 +754,6 @@ void DiagonalCurveEditorSubGroup::switchGUI() dCurve->paramCurveEd.at(3) ); - double s = (double)RTScalable::getScale(); highlights->setValue (dCurve->paramCurveEd.at(4)); highlights->setLabel(label[3]); lights->setValue (dCurve->paramCurveEd.at(5)); @@ -765,8 +765,8 @@ void DiagonalCurveEditorSubGroup::switchGUI() shcSelector->coloredBar.setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); shcSelector->coloredBar.setBgGradient(bgGradient); shcSelector->setMargins( - (int)( ((leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5) * s ), - (int)((RADIUS - 1.5) * s) + (int)( RTScalable::scalePixelSize((leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5) ), + (int)( RTScalable::scalePixelSize(RADIUS - 1.5) ) ); paramCurve->setColoredBar(leftBar, nullptr); paramCurve->queue_resize_no_redraw(); diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 2be1e3f3a..369b69233 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -28,7 +28,7 @@ #endif #include "guiutils.h" -#include "rtimage.h" +#include "rtsurface.h" #include "multilangmgr.h" #include "options.h" @@ -121,13 +121,13 @@ DirBrowser::~DirBrowser() void DirBrowser::fillDirTree () { - openfolder = RTImage::createPixbufFromFile ("folder-open-small.png"); - closedfolder = RTImage::createPixbufFromFile ("folder-closed-small.png"); - icdrom = RTImage::createPixbufFromFile ("device-optical.png"); - ifloppy = RTImage::createPixbufFromFile ("device-floppy.png"); - ihdd = RTImage::createPixbufFromFile ("device-hdd.png"); - iremovable = RTImage::createPixbufFromFile ("device-usb.png"); - inetwork = RTImage::createPixbufFromFile ("device-network.png"); + openfolder = std::shared_ptr(new RTPixbuf("folder-open-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + closedfolder = std::shared_ptr(new RTPixbuf("folder-closed-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + icdrom = std::shared_ptr(new RTPixbuf("device-optical", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + ifloppy = std::shared_ptr(new RTPixbuf("device-floppy", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + ihdd = std::shared_ptr(new RTPixbuf("device-hdd", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + iremovable = std::shared_ptr(new RTPixbuf("device-usb", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + inetwork = std::shared_ptr(new RTPixbuf("device-network", Gtk::ICON_SIZE_SMALL_TOOLBAR)); //Create the Tree model: dirTreeModel = Gtk::TreeStore::create(dtColumns); @@ -175,22 +175,22 @@ void DirBrowser::addRoot (char letter) int type = GetDriveType (volume); if (type == DRIVE_CDROM) { - root->set_value (0, icdrom); - root->set_value (1, icdrom); + root->set_value (0, icdrom->get()); + root->set_value (1, icdrom->get()); } else if (type == DRIVE_REMOVABLE) { if (letter - 'A' < 2) { - root->set_value (0, ifloppy); - root->set_value (1, ifloppy); + root->set_value (0, ifloppy->get()); + root->set_value (1, ifloppy->get()); } else { - root->set_value (0, iremovable); - root->set_value (1, iremovable); + root->set_value (0, iremovable->get()); + root->set_value (1, iremovable->get()); } } else if (type == DRIVE_REMOTE) { - root->set_value (0, inetwork); - root->set_value (1, inetwork); + root->set_value (0, inetwork->get()); + root->set_value (1, inetwork->get()); } else if (type == DRIVE_FIXED) { - root->set_value (0, ihdd); - root->set_value (1, ihdd); + root->set_value (0, ihdd->get()); + root->set_value (1, ihdd->get()); } Gtk::TreeModel::iterator child = dirTreeModel->append (root->children()); @@ -366,8 +366,8 @@ void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustri Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children()); child->set_value (dtColumns.filename, dirname); - child->set_value (dtColumns.icon1, openfolder); - child->set_value (dtColumns.icon2, closedfolder); + child->set_value (dtColumns.icon1, openfolder->get()); + child->set_value (dtColumns.icon2, closedfolder->get()); 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()); diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h index 0254d6eb5..599f9fa16 100644 --- a/rtgui/dirbrowser.h +++ b/rtgui/dirbrowser.h @@ -23,6 +23,8 @@ #include "guiutils.h" +class RTPixbuf; + class DirBrowser : public Gtk::Box { public: @@ -62,13 +64,13 @@ private: void fillRoot (); - Glib::RefPtr openfolder; - Glib::RefPtr closedfolder; - Glib::RefPtr icdrom; - Glib::RefPtr ifloppy; - Glib::RefPtr ihdd; - Glib::RefPtr inetwork; - Glib::RefPtr iremovable; + std::shared_ptr openfolder; + std::shared_ptr closedfolder; + std::shared_ptr icdrom; + std::shared_ptr ifloppy; + std::shared_ptr ihdd; + std::shared_ptr inetwork; + std::shared_ptr iremovable; bool expandSuccess; diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc index 165ccee06..5089a2dfe 100644 --- a/rtgui/distortion.cc +++ b/rtgui/distortion.cc @@ -32,7 +32,7 @@ Distortion::Distortion (): FoldableToolPanel(this, "distortion", M("TP_DISTORTIO rlistener = nullptr; autoDistor = Gtk::manage (new Gtk::Button (M("GENERAL_AUTO"))); - autoDistor->set_image (*Gtk::manage (new RTImage ("distortion-auto-small.png"))); + autoDistor->set_image (*Gtk::manage (new RTImage ("distortion-auto-small", Gtk::ICON_SIZE_BUTTON))); autoDistor->get_style_context()->add_class("independent"); autoDistor->set_alignment(0.5f, 0.5f); autoDistor->set_tooltip_text (M("TP_DISTORTION_AUTO_TIP")); @@ -40,14 +40,14 @@ Distortion::Distortion (): FoldableToolPanel(this, "distortion", M("TP_DISTORTIO autoDistor->show(); pack_start (*autoDistor); - Gtk::Image* idistL = Gtk::manage (new RTImage ("distortion-pincushion-small.png")); - Gtk::Image* idistR = Gtk::manage (new RTImage ("distortion-barrel-small.png")); + Gtk::Image* idistL = Gtk::manage (new RTImage ("distortion-pincushion-small")); + Gtk::Image* idistR = Gtk::manage (new RTImage ("distortion-barrel-small")); distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0, idistL, idistR)); distor->setAdjusterListener (this); distor->setLogScale(2, 0); - + distor->show(); pack_start (*distor); } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 78a07ddd6..d21ef3917 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -186,9 +186,9 @@ private: void prepareIntentBox () { // same order as the enum - intentBox.addEntry ("intent-perceptual.png", M ("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox.addEntry ("intent-relative.png", M ("PREFERENCES_INTENT_RELATIVE")); - intentBox.addEntry ("intent-absolute.png", M ("PREFERENCES_INTENT_ABSOLUTE")); + intentBox.addEntry ("intent-perceptual", M ("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.addEntry ("intent-relative", M ("PREFERENCES_INTENT_RELATIVE")); + intentBox.addEntry ("intent-absolute", M ("PREFERENCES_INTENT_ABSOLUTE")); setExpandAlignProperties (intentBox.buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); intentBox.setSelected (1); @@ -197,7 +197,7 @@ private: void prepareSoftProofingBox () { - Gtk::Image *softProofImage = Gtk::manage (new RTImage ("gamut-softproof.png")); + Gtk::Image *softProofImage = Gtk::manage (new RTImage ("gamut-softproof", Gtk::ICON_SIZE_LARGE_TOOLBAR)); softProofImage->set_padding (0, 0); softProof.add (*softProofImage); softProof.set_relief (Gtk::RELIEF_NONE); @@ -206,7 +206,7 @@ private: softProof.set_active (false); softProof.show (); - Gtk::Image *spGamutCheckImage = Gtk::manage (new RTImage ("gamut-warning.png")); + Gtk::Image *spGamutCheckImage = Gtk::manage (new RTImage ("gamut-warning", Gtk::ICON_SIZE_LARGE_TOOLBAR)); spGamutCheckImage->set_padding (0, 0); spGamutCheck.add (*spGamutCheckImage); spGamutCheck.set_relief (Gtk::RELIEF_NONE); @@ -509,7 +509,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) //leftsubpaned->pack_start (*ppframe, Gtk::PACK_SHRINK, 4); navigator = Gtk::manage(new Navigator()); - navigator->previewWindow->set_size_request(-1, 150 * RTScalable::getScale()); + navigator->previewWindow->set_size_request(-1, RTScalable::scalePixelSize(150)); leftsubpaned->pack1(*navigator, false, false); history = Gtk::manage(new History()); @@ -525,19 +525,19 @@ EditorPanel::EditorPanel (FilePanel* filePanel) Gtk::Box* editbox = Gtk::manage (new Gtk::Box (Gtk::ORIENTATION_VERTICAL)); info = Gtk::manage (new Gtk::ToggleButton ()); - Gtk::Image* infoimg = Gtk::manage (new RTImage ("info.png")); + Gtk::Image* infoimg = Gtk::manage (new RTImage ("info", Gtk::ICON_SIZE_LARGE_TOOLBAR)); 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")); + Gtk::Image* beforeAfterIcon = Gtk::manage (new RTImage ("beforeafter", Gtk::ICON_SIZE_LARGE_TOOLBAR)); beforeAfter->add (*beforeAfterIcon); beforeAfter->set_relief (Gtk::RELIEF_NONE); beforeAfter->set_tooltip_markup (M ("MAIN_TOOLTIP_TOGGLE")); - iBeforeLockON = new RTImage ("padlock-locked-small.png"); - iBeforeLockOFF = new RTImage ("padlock-unlocked-small.png"); + iBeforeLockON = new RTImage ("padlock-locked-small", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iBeforeLockOFF = new RTImage ("padlock-unlocked-small", Gtk::ICON_SIZE_LARGE_TOOLBAR); Gtk::Separator* vsept = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)); Gtk::Separator* vsepz = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)); @@ -546,8 +546,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) hidehp = Gtk::manage (new Gtk::ToggleButton ()); - iHistoryShow = new RTImage ("panel-to-right.png"); - iHistoryHide = new RTImage ("panel-to-left.png"); + iHistoryShow = new RTImage ("panel-to-right", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iHistoryHide = new RTImage ("panel-to-left", Gtk::ICON_SIZE_LARGE_TOOLBAR); hidehp->set_relief (Gtk::RELIEF_NONE); hidehp->set_active (options.showHistory); @@ -563,8 +563,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) 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"); + iTopPanel_1_Show = new RTImage ("panel-to-bottom", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iTopPanel_1_Hide = new RTImage ("panel-to-top", Gtk::ICON_SIZE_LARGE_TOOLBAR); tbTopPanel_1->set_relief (Gtk::RELIEF_NONE); tbTopPanel_1->set_active (true); tbTopPanel_1->set_tooltip_markup (M ("MAIN_TOOLTIP_SHOWHIDETP1")); @@ -581,7 +581,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Histogram profile toggle controls toggleHistogramProfile = Gtk::manage (new Gtk::ToggleButton ()); - Gtk::Image* histProfImg = Gtk::manage (new RTImage ("gamut-hist.png")); + Gtk::Image* histProfImg = Gtk::manage (new RTImage ("gamut-hist", Gtk::ICON_SIZE_LARGE_TOOLBAR)); toggleHistogramProfile->add (*histProfImg); toggleHistogramProfile->set_relief (Gtk::RELIEF_NONE); toggleHistogramProfile->set_active (options.rtSettings.HistogramWorking); @@ -654,21 +654,21 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->set_row_spacing (2); iops->set_column_spacing (2); - Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("save.png")); + Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("save", Gtk::ICON_SIZE_LARGE_TOOLBAR)); saveimgas = Gtk::manage (new Gtk::Button ()); saveimgas->set_relief(Gtk::RELIEF_NONE); saveimgas->add (*saveButtonImage); saveimgas->set_tooltip_markup (M ("MAIN_BUTTON_SAVE_TOOLTIP")); setExpandAlignProperties (saveimgas, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image *queueButtonImage = Gtk::manage (new RTImage ("gears.png")); + Gtk::Image *queueButtonImage = Gtk::manage (new RTImage ("gears", Gtk::ICON_SIZE_LARGE_TOOLBAR)); queueimg = Gtk::manage (new Gtk::Button ()); queueimg->set_relief(Gtk::RELIEF_NONE); queueimg->add (*queueButtonImage); queueimg->set_tooltip_markup (M ("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP")); setExpandAlignProperties (queueimg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image *sendToEditorButtonImage = Gtk::manage (new RTImage ("palette-brush.png")); + Gtk::Image *sendToEditorButtonImage = Gtk::manage (new RTImage ("palette-brush", Gtk::ICON_SIZE_LARGE_TOOLBAR)); sendtogimp = Gtk::manage (new Gtk::Button ()); sendtogimp->set_relief(Gtk::RELIEF_NONE); sendtogimp->add (*sendToEditorButtonImage); @@ -683,8 +683,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // tbRightPanel_1 tbRightPanel_1 = Gtk::manage(new Gtk::ToggleButton()); - iRightPanel_1_Show = new RTImage ("panel-to-left.png"); - iRightPanel_1_Hide = new RTImage ("panel-to-right.png"); + iRightPanel_1_Show = new RTImage ("panel-to-left", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iRightPanel_1_Hide = new RTImage ("panel-to-right", Gtk::ICON_SIZE_LARGE_TOOLBAR); tbRightPanel_1->set_relief (Gtk::RELIEF_NONE); tbRightPanel_1->set_active (true); tbRightPanel_1->set_tooltip_markup (M ("MAIN_TOOLTIP_SHOWHIDERP1")); @@ -693,8 +693,8 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // ShowHideSidePanels tbShowHideSidePanels = Gtk::manage(new Gtk::ToggleButton()); - iShowHideSidePanels = new RTImage ("crossed-arrows-out.png"); - iShowHideSidePanels_exit = new RTImage ("crossed-arrows-in.png"); + iShowHideSidePanels = new RTImage ("crossed-arrows-out", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iShowHideSidePanels_exit = new RTImage ("crossed-arrows-in", Gtk::ICON_SIZE_LARGE_TOOLBAR); tbShowHideSidePanels->set_relief (Gtk::RELIEF_NONE); tbShowHideSidePanels->set_active (false); tbShowHideSidePanels->set_tooltip_markup (M ("MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP")); @@ -705,7 +705,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) if (!simpleEditor && !options.tabbedUI) { // Navigation buttons - Gtk::Image *navPrevImage = Gtk::manage (new RTImage ("arrow2-left.png")); + Gtk::Image *navPrevImage = Gtk::manage (new RTImage ("arrow2-left", Gtk::ICON_SIZE_LARGE_TOOLBAR)); navPrevImage->set_padding (0, 0); navPrev = Gtk::manage (new Gtk::Button ()); navPrev->add (*navPrevImage); @@ -713,7 +713,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navPrev->set_tooltip_markup (M ("MAIN_BUTTON_NAVPREV_TOOLTIP")); setExpandAlignProperties (navPrev, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image *navNextImage = Gtk::manage (new RTImage ("arrow2-right.png")); + Gtk::Image *navNextImage = Gtk::manage (new RTImage ("arrow2-right", Gtk::ICON_SIZE_LARGE_TOOLBAR)); navNextImage->set_padding (0, 0); navNext = Gtk::manage (new Gtk::Button ()); navNext->add (*navNextImage); @@ -721,7 +721,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navNext->set_tooltip_markup (M ("MAIN_BUTTON_NAVNEXT_TOOLTIP")); setExpandAlignProperties (navNext, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image *navSyncImage = Gtk::manage (new RTImage ("arrow-updown.png")); + Gtk::Image *navSyncImage = Gtk::manage (new RTImage ("arrow-updown", Gtk::ICON_SIZE_LARGE_TOOLBAR)); navSyncImage->set_padding (0, 0); navSync = Gtk::manage (new Gtk::Button ()); navSync->add (*navSyncImage); @@ -2072,7 +2072,7 @@ bool EditorPanel::idle_sendToGimp ( ProgressConnector *p sf.tiffBits = 16; sf.tiffFloat = false; } - + sf.tiffUncompressed = true; sf.saveParams = true; diff --git a/rtgui/editwidgets.cc b/rtgui/editwidgets.cc index f9c9b3781..ff662f1fa 100644 --- a/rtgui/editwidgets.cc +++ b/rtgui/editwidgets.cc @@ -989,11 +989,11 @@ void OPIcon::drivenPointToRectangle(const rtengine::Coord &pos, bottomRight.y = topLeft.y + H - 1; } -OPIcon::OPIcon(const Cairo::RefPtr &normal, - const Cairo::RefPtr &active, - const Cairo::RefPtr &prelight, - const Cairo::RefPtr &dragged, - const Cairo::RefPtr &insensitive, +OPIcon::OPIcon(const std::shared_ptr &normal, + const std::shared_ptr &active, + const std::shared_ptr &prelight, + const std::shared_ptr &dragged, + const std::shared_ptr&insensitive, DrivenPoint drivenPoint) : drivenPoint(drivenPoint) { @@ -1022,48 +1022,48 @@ OPIcon::OPIcon(Glib::ustring normalImage, Glib::ustring activeImage, Glib::ustri Glib::ustring draggedImage, Glib::ustring insensitiveImage, DrivenPoint drivenPoint) : drivenPoint(drivenPoint) { if (!normalImage.empty()) { - normalImg = Cairo::RefPtr(new RTSurface(normalImage)); + normalImg = std::shared_ptr(new RTSurface(normalImage, Gtk::ICON_SIZE_MENU)); } if (!prelightImage.empty()) { - prelightImg = Cairo::RefPtr(new RTSurface(prelightImage)); + prelightImg = std::shared_ptr(new RTSurface(prelightImage, Gtk::ICON_SIZE_MENU)); } if (!activeImage.empty()) { - activeImg = Cairo::RefPtr(new RTSurface(activeImage)); + activeImg = std::shared_ptr(new RTSurface(activeImage, Gtk::ICON_SIZE_MENU)); } if (!draggedImage.empty()) { - draggedImg = Cairo::RefPtr(new RTSurface(draggedImage)); + draggedImg = std::shared_ptr(new RTSurface(draggedImage, Gtk::ICON_SIZE_MENU)); } if (!insensitiveImage.empty()) { - insensitiveImg = Cairo::RefPtr(new RTSurface(insensitiveImage)); + insensitiveImg = std::shared_ptr(new RTSurface(insensitiveImage, Gtk::ICON_SIZE_MENU)); } } -const Cairo::RefPtr OPIcon::getNormalImg() +const std::shared_ptr OPIcon::getNormalImg() { return normalImg; } -const Cairo::RefPtr OPIcon::getPrelightImg() +const std::shared_ptr OPIcon::getPrelightImg() { return prelightImg; } -const Cairo::RefPtr OPIcon::getActiveImg() +const std::shared_ptr OPIcon::getActiveImg() { return activeImg; } -const Cairo::RefPtr OPIcon::getDraggedImg() +const std::shared_ptr OPIcon::getDraggedImg() { return draggedImg; } -const Cairo::RefPtr OPIcon::getInsensitiveImg() +const std::shared_ptr OPIcon::getInsensitiveImg() { return insensitiveImg; } -void OPIcon::drawImage(Cairo::RefPtr &img, +void OPIcon::drawImage(std::shared_ptr &img, Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { @@ -1089,7 +1089,7 @@ void OPIcon::drawImage(Cairo::RefPtr &img, cr->fill(); } -void OPIcon::drawMOImage(Cairo::RefPtr &img, Cairo::RefPtr &cr, +void OPIcon::drawMOImage(std::shared_ptr &img, Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) { // test of F_HOVERABLE has already been done diff --git a/rtgui/editwidgets.h b/rtgui/editwidgets.h index fd539c355..968796ceb 100644 --- a/rtgui/editwidgets.h +++ b/rtgui/editwidgets.h @@ -354,34 +354,32 @@ class OPIcon : public Geometry // OP stands for "On Preview" { private: - Cairo::RefPtr normalImg; - Cairo::RefPtr prelightImg; - Cairo::RefPtr activeImg; - Cairo::RefPtr draggedImg; - Cairo::RefPtr insensitiveImg; + std::shared_ptr normalImg; + std::shared_ptr prelightImg; + std::shared_ptr activeImg; + std::shared_ptr draggedImg; + std::shared_ptr insensitiveImg; - static void updateImages(); - void changeImage(Glib::ustring &newImage); - void drawImage (Cairo::RefPtr &img, Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem); - void drawMOImage (Cairo::RefPtr &img, Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem); + void drawImage (std::shared_ptr &img, Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem); + void drawMOImage (std::shared_ptr &img, Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem); void drivenPointToRectangle(const rtengine::Coord &pos, rtengine::Coord &topLeft, rtengine::Coord &bottomRight, int W, int H); public: DrivenPoint drivenPoint; rtengine::Coord position; - OPIcon (const Cairo::RefPtr &normal, - const Cairo::RefPtr &active, - const Cairo::RefPtr &prelight = {}, - const Cairo::RefPtr &dragged = {}, - const Cairo::RefPtr &insensitive = {}, + OPIcon (const std::shared_ptr &normal, + const std::shared_ptr &active, + const std::shared_ptr &prelight = nullptr, + const std::shared_ptr &dragged = nullptr, + const std::shared_ptr &insensitive = nullptr, DrivenPoint drivenPoint = DP_CENTERCENTER); OPIcon (Glib::ustring normalImage, Glib::ustring activeImage, Glib::ustring prelightImage = "", Glib::ustring draggedImage = "", Glib::ustring insensitiveImage = "", DrivenPoint drivenPoint = DP_CENTERCENTER); - const Cairo::RefPtr getNormalImg(); - const Cairo::RefPtr getPrelightImg(); - const Cairo::RefPtr getActiveImg(); - const Cairo::RefPtr getDraggedImg(); - const Cairo::RefPtr getInsensitiveImg(); + const std::shared_ptr getNormalImg(); + const std::shared_ptr getPrelightImg(); + const std::shared_ptr getActiveImg(); + const std::shared_ptr getDraggedImg(); + const std::shared_ptr getInsensitiveImg(); void drawOuterGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) override; void drawInnerGeometry (Cairo::RefPtr &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) override; void drawToMOChannel (Cairo::RefPtr &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem) override; diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index d0e53d730..5b57e35c7 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -57,15 +57,14 @@ EditWindow* EditWindow::getInstance(RTWindow* p) } EditWindow::EditWindow (RTWindow* p) - : resolution(RTScalable::baseDPI) - , parent(p) + : parent(p) , isFullscreen(false) , isClosed(true) , isMinimized(false) { + // Set window icon + set_default_icon_name("rawtherapee"); - updateResolution(); - setAppIcon(); set_title_decorated(""); set_modal(false); set_resizable(true); @@ -165,56 +164,8 @@ void EditWindow::on_realize () editWindowCursorManager.init (get_window()); } -bool EditWindow::updateResolution() -{ - int scale = get_scale_factor(); - double res = get_screen()->get_resolution(); - if (scale == 2) { - // from Windows' behavior : if scale==2, resolution = 192. (Gtk shows 96 dpi !?), there's no higher value - res = RTScalable::baseHiDPI; - } - bool retVal = res != resolution; - resolution = res; - return retVal; -} - -void EditWindow::setAppIcon() -{ - Glib::ustring fName; - bool downsize = false; - // findIconAbsolutePath won't be able to select the image based on resolution with the - // storage of the images, we're doing the selection here - if (resolution == RTScalable::baseDPI) { - fName = "rawtherapee-logo-24.png"; - } else { - fName = "rawtherapee-logo-48.png"; - if (resolution < RTScalable::baseHiDPI) { - downsize = true; - } - } - Glib::ustring icon_path = Glib::build_filename (argv0, "images", fName); - const Glib::RefPtr pixbuf = Gdk::Pixbuf::create_from_file(icon_path); - if (!pixbuf) { - return; - } - if (downsize) { - int size = int((48. * resolution) / RTScalable::baseHiDPI); - pixbuf->scale_simple(size, size, Gdk::InterpType::INTERP_BILINEAR); - } - - try { - set_default_icon(pixbuf); - } catch(Glib::Exception& ex) { - printf ("%s\n", ex.what().c_str()); - } -} - bool EditWindow::on_configure_event(GdkEventConfigure* event) { - if (updateResolution()) { - setAppIcon(); - } - if (!options.meowMaximized && !isFullscreen && !isMinimized) { get_position(options.meowX, options.meowY); get_size(options.meowWidth, options.meowHeight); @@ -253,11 +204,11 @@ void EditWindow::addEditorPanel (EditorPanel* ep, const std::string &name) // construct closeable tab for the image Gtk::Box* hb = Gtk::manage (new Gtk::Box ()); - hb->pack_start (*Gtk::manage (new RTImage ("aperture.png"))); + hb->pack_start (*Gtk::manage (new RTImage ("aperture"))); hb->pack_start (*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name)))); hb->set_tooltip_markup (name); Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); - closeb->set_image (*Gtk::manage(new RTImage ("cancel-small.png"))); + closeb->set_image (*Gtk::manage(new RTImage ("cancel-small", Gtk::ICON_SIZE_BUTTON))); closeb->set_relief (Gtk::RELIEF_NONE); closeb->set_focus_on_click (false); diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index b8eeaee82..bbe9a14c2 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -31,7 +31,6 @@ class EditWindow : { private: - double resolution; RTWindow* parent; RTImage appIcon; @@ -44,8 +43,6 @@ private: bool isMinimized; sigc::connection onConfEventConn; void toggleFullscreen (); - bool updateResolution(); - void setAppIcon(); IdleRegister idle_register; diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index eeff0c8c7..246a75388 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -31,7 +31,11 @@ using namespace rtexif; ExifPanel::ExifPanel() : idata(nullptr), changeList(new rtengine::procparams::ExifPairs), - defChangeList(new rtengine::procparams::ExifPairs) + defChangeList(new rtengine::procparams::ExifPairs), + + delicon("cancel-small"), + keepicon("tick-small"), + editicon("add-small") { set_orientation(Gtk::ORIENTATION_VERTICAL); recursiveOp = true; @@ -54,17 +58,14 @@ ExifPanel::ExifPanel() : exifTree->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_NONE); exifTree->set_row_separator_func (sigc::mem_fun(*this, &ExifPanel::rowSeperatorFunc)); - delicon = RTImage::createPixbufFromFile ("cancel-small.png"); - keepicon = RTImage::createPixbufFromFile ("tick-small.png"); - editicon = RTImage::createPixbufFromFile ("add-small.png"); - Gtk::TreeView::Column *viewcol = Gtk::manage (new Gtk::TreeView::Column ("Field Name")); - Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf ()); + Gtk::CellRendererPixbuf* render_pb = Gtk::manage (new Gtk::CellRendererPixbuf()); + render_pb->property_stock_size() = Gtk::ICON_SIZE_SMALL_TOOLBAR; Gtk::CellRendererText *render_txt = Gtk::manage (new Gtk::CellRendererText()); render_txt->property_ellipsize() = Pango::ELLIPSIZE_END; viewcol->pack_start (*render_pb, false); viewcol->pack_start (*render_txt, true); - viewcol->add_attribute (*render_pb, "pixbuf", exifColumns.icon); + viewcol->add_attribute (*render_pb, "icon-name", exifColumns.icon); viewcol->add_attribute (*render_txt, "markup", exifColumns.field); viewcol->set_expand (true); viewcol->set_resizable (true); @@ -106,21 +107,21 @@ ExifPanel::ExifPanel() : setExpandAlignProperties (buttons2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); remove = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_REMOVE") - remove->set_image (*Gtk::manage (new RTImage(delicon))); + remove->set_image (*Gtk::manage (new RTImage(delicon, Gtk::ICON_SIZE_BUTTON))); remove->set_tooltip_text (M ("EXIFPANEL_REMOVEHINT")); remove->get_style_context()->add_class ("Left"); setExpandAlignProperties (remove, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); buttons1->attach_next_to (*remove, Gtk::POS_LEFT, 1, 1); keep = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_KEEP") - keep->set_image (*Gtk::manage (new RTImage(keepicon))); + keep->set_image (*Gtk::manage (new RTImage(keepicon, Gtk::ICON_SIZE_BUTTON))); keep->set_tooltip_text (M ("EXIFPANEL_KEEPHINT")); keep->get_style_context()->add_class ("MiddleH"); setExpandAlignProperties (keep, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); buttons1->attach_next_to (*keep, Gtk::POS_RIGHT, 1, 1); add = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_ADDEDIT") - add->set_image (*Gtk::manage (new RTImage(editicon))); + add->set_image (*Gtk::manage (new RTImage(editicon, Gtk::ICON_SIZE_BUTTON))); add->set_tooltip_text (M ("EXIFPANEL_ADDEDITHINT")); add->get_style_context()->add_class ("Right"); setExpandAlignProperties (add, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); @@ -134,14 +135,14 @@ ExifPanel::ExifPanel() : buttons2->attach_next_to (*showAll, Gtk::POS_LEFT, 1, 1); reset = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESET") - reset->set_image (*Gtk::manage (new RTImage("undo.png", "redo.png"))); + reset->set_image (*Gtk::manage (new RTImage ("undo", Gtk::ICON_SIZE_BUTTON))); reset->set_tooltip_text (M ("EXIFPANEL_RESETHINT")); reset->get_style_context()->add_class ("MiddleH"); setExpandAlignProperties (reset, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); buttons2->attach_next_to (*reset, Gtk::POS_RIGHT, 1, 1); resetAll = Gtk::manage (new Gtk::Button ()); // M("EXIFPANEL_RESETALL") - resetAll->set_image (*Gtk::manage (new RTImage ("undo-all.png", "redo-all.png"))); + resetAll->set_image (*Gtk::manage (new RTImage ("undo-all", Gtk::ICON_SIZE_BUTTON))); resetAll->set_tooltip_text (M ("EXIFPANEL_RESETALLHINT")); resetAll->get_style_context()->add_class ("Right"); setExpandAlignProperties (resetAll, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h index 4c28af289..7723e56c3 100644 --- a/rtgui/exifpanel.h +++ b/rtgui/exifpanel.h @@ -39,7 +39,7 @@ private: class ExifColumns : public Gtk::TreeModelColumnRecord { public: - Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn icon; Gtk::TreeModelColumn field; Gtk::TreeModelColumn field_nopango; Gtk::TreeModelColumn value; @@ -64,9 +64,10 @@ private: add (isSeparator); } }; - Glib::RefPtr delicon; - Glib::RefPtr keepicon; - Glib::RefPtr editicon; + + Glib::ustring delicon; + Glib::ustring keepicon; + Glib::ustring editicon; ExifColumns exifColumns; Gtk::TreeView* exifTree; diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index a4ce63c1d..3c299e714 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -185,14 +185,14 @@ ExportPanel::ExportPanel () : listener (nullptr) // Buttons btnFastExport = Gtk::manage ( new Gtk::Button () ); btnFastExport->set_tooltip_text (M ("EXPORT_PUTTOQUEUEFAST")); - btnFastExport->set_image (*Gtk::manage (new RTImage ("gears.png"))); + btnFastExport->set_image (*Gtk::manage (new RTImage ("gears"))); pack_start (*btnFastExport, Gtk::PACK_SHRINK, 4); // add panel ending Gtk::Box* vboxpe = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); Gtk::Separator* hseptpe = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - Gtk::Image* peImg = Gtk::manage (new RTImage ("ornament1.png")); + Gtk::Image* peImg = Gtk::manage (new RTImage ("ornament1")); vboxpe->pack_start (*hseptpe, Gtk::PACK_SHRINK, 4); vboxpe->pack_start (*peImg); pack_start (*vboxpe, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/fattaltonemap.cc b/rtgui/fattaltonemap.cc index 89a1e9e30..1e3c7171a 100644 --- a/rtgui/fattaltonemap.cc +++ b/rtgui/fattaltonemap.cc @@ -1,5 +1,5 @@ /** -*- C++ -*- - * + * * This file is part of RawTherapee. * * Copyright (c) 2017 Alberto Griggio @@ -39,8 +39,8 @@ FattalToneMapping::FattalToneMapping(): FoldableToolPanel(this, "fattal", M("TP_ amount = Gtk::manage(new Adjuster (M("TP_TM_FATTAL_AMOUNT"), 1., 100., 1., 30.)); threshold = Gtk::manage(new Adjuster (M("TP_TM_FATTAL_THRESHOLD"), -100., 300., 1., 0.0)); threshold->setLogScale(10, 0); - Gtk::Image *al = Gtk::manage(new RTImage("circle-black-small.png")); - Gtk::Image *ar = Gtk::manage(new RTImage("circle-white-small.png")); + Gtk::Image *al = Gtk::manage(new RTImage("circle-black-small")); + Gtk::Image *ar = Gtk::manage(new RTImage("circle-white-small")); anchor = Gtk::manage(new Adjuster(M("TP_TM_FATTAL_ANCHOR"), 1, 100, 1, 50, al, ar)); amount->setAdjusterListener(this); diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 0481847cb..2b16aadcc 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -16,7 +16,8 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include +#include "favoritbrowser.h" + #include "multilangmgr.h" #include "rtimage.h" @@ -57,7 +58,7 @@ FavoritBrowser::FavoritBrowser () : listener (NULL) add->set_vexpand(false); add->set_halign(Gtk::ALIGN_FILL); add->set_valign(Gtk::ALIGN_START); - add->set_image (*Gtk::manage (new RTImage ("add-small.png"))); + add->set_image (*Gtk::manage (new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON))); add->get_style_context()->add_class("Left"); del = Gtk::manage (new Gtk::Button ()); del->set_tooltip_text(M("MAIN_FRAME_PLACES_DEL")); @@ -65,7 +66,7 @@ FavoritBrowser::FavoritBrowser () : listener (NULL) del->set_vexpand(false); del->set_halign(Gtk::ALIGN_FILL); del->set_valign(Gtk::ALIGN_START); - del->set_image (*Gtk::manage (new RTImage ("remove-small.png"))); + del->set_image (*Gtk::manage (new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON))); del->get_style_context()->add_class("Right"); Gtk::Box* buttonBox = Gtk::manage (new Gtk::Box ()); buttonBox->pack_start (*add); diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 97e724174..91eb8dc72 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -157,7 +157,7 @@ FileBrowser::FileBrowser () : pmenu->attach (*Gtk::manage(inspect = new Gtk::MenuItem (M("FILEBROWSER_POPUPINSPECT"))), 0, 1, p, p + 1); p++; } - pmenu->attach (*Gtk::manage(develop = new MyImageMenuItem (M("FILEBROWSER_POPUPPROCESS"), "gears.png")), 0, 1, p, p + 1); + pmenu->attach (*Gtk::manage(develop = new MyImageMenuItem (M("FILEBROWSER_POPUPPROCESS"), "gears")), 0, 1, p, p + 1); p++; pmenu->attach (*Gtk::manage(developfast = new Gtk::MenuItem (M("FILEBROWSER_POPUPPROCESSFAST"))), 0, 1, p, p + 1); p++; @@ -209,8 +209,8 @@ FileBrowser::FileBrowser () : // Thumbnail context menu // Similar image arrays in filecatalog.cc - std::array clabelActiveIcons = {"circle-empty-gray-small.png", "circle-red-small.png", "circle-yellow-small.png", "circle-green-small.png", "circle-blue-small.png", "circle-purple-small.png"}; - std::array clabelInactiveIcons = {"circle-empty-darkgray-small.png", "circle-empty-red-small.png", "circle-empty-yellow-small.png", "circle-empty-green-small.png", "circle-empty-blue-small.png", "circle-empty-purple-small.png"}; + std::array clabelActiveIcons = {"circle-empty-gray-small", "circle-red-small", "circle-yellow-small", "circle-green-small", "circle-blue-small", "circle-purple-small"}; + std::array clabelInactiveIcons = {"circle-empty-darkgray-small", "circle-empty-red-small", "circle-empty-yellow-small", "circle-empty-green-small", "circle-empty-blue-small", "circle-empty-purple-small"}; if (options.menuGroupLabel) { pmenu->attach (*Gtk::manage(menuLabel = new Gtk::MenuItem (M("FILEBROWSER_POPUPCOLORLABEL"))), 0, 1, p, p + 1); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index bf3f11a79..9f9be2eff 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -25,7 +25,7 @@ #include "cursormanager.h" #include "guiutils.h" #include "inspector.h" -#include "rtimage.h" +#include "rtsurface.h" #include "threadutils.h" #include "thumbbrowserbase.h" #include "thumbnail.h" @@ -38,11 +38,11 @@ //extern Glib::Threads::Thread* mainThread; bool FileBrowserEntry::iconsLoaded(false); -Glib::RefPtr FileBrowserEntry::editedIcon; -Glib::RefPtr FileBrowserEntry::recentlySavedIcon; -Glib::RefPtr FileBrowserEntry::enqueuedIcon; -Glib::RefPtr FileBrowserEntry::hdr; -Glib::RefPtr FileBrowserEntry::ps; +std::shared_ptr FileBrowserEntry::editedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::recentlySavedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::enqueuedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::hdr(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::ps(std::shared_ptr(nullptr)); FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), press_x(0), press_y(0), action_x(0), action_y(0), rot_deg(0.0), landscape(true), cropParams(new rtengine::procparams::CropParams), cropgl(nullptr), state(SNormal), crop_custom_ratio(0.f) @@ -61,11 +61,11 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) scale = 1; if (!iconsLoaded) { - editedIcon = RTImage::createPixbufFromFile ("tick-small.png"); - recentlySavedIcon = RTImage::createPixbufFromFile ("save-small.png"); - enqueuedIcon = RTImage::createPixbufFromFile ("gears-small.png"); - hdr = RTImage::createPixbufFromFile ("filetype-hdr.png"); - ps = RTImage::createPixbufFromFile ("filetype-ps.png"); + editedIcon = std::shared_ptr(new RTPixbuf("tick-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + recentlySavedIcon = std::shared_ptr(new RTPixbuf("save-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + enqueuedIcon = std::shared_ptr(new RTPixbuf("gears-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + hdr = std::shared_ptr(new RTPixbuf("filetype-hdr", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + ps = std::shared_ptr(new RTPixbuf("filetype-ps", Gtk::ICON_SIZE_SMALL_TOOLBAR)); iconsLoaded = true; } @@ -134,15 +134,15 @@ std::vector> FileBrowserEntry::getIconsOnImageArea () std::vector> ret; if (thumbnail->hasProcParams() && editedIcon) { - ret.push_back(editedIcon); + ret.push_back(editedIcon->get()); } if (thumbnail->isRecentlySaved() && recentlySavedIcon) { - ret.push_back(recentlySavedIcon); + ret.push_back(recentlySavedIcon->get()); } if (thumbnail->isEnqueued () && enqueuedIcon) { - ret.push_back(enqueuedIcon); + ret.push_back(enqueuedIcon->get()); } return ret; @@ -157,11 +157,11 @@ std::vector> FileBrowserEntry::getSpecificityIconsOnIm std::vector> ret; if (thumbnail->isHDR() && hdr) { - ret.push_back (hdr); + ret.push_back (hdr->get()); } if (thumbnail->isPixelShift() && ps) { - ret.push_back (ps); + ret.push_back (ps->get()); } return ret; @@ -195,8 +195,8 @@ void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) void FileBrowserEntry::getIconSize (int& w, int& h) const { - w = editedIcon->get_width (); - h = editedIcon->get_height (); + w = editedIcon->get()->get_width (); + h = editedIcon->get()->get_height (); } FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet () diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 67b953514..fcf916f00 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -35,6 +35,7 @@ class FileBrowserEntry; class Thumbnail; +class RTPixbuf; struct FileBrowserEntryIdleHelper { FileBrowserEntry* fbentry; @@ -72,11 +73,11 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase, public: - static Glib::RefPtr editedIcon; - static Glib::RefPtr recentlySavedIcon; - static Glib::RefPtr enqueuedIcon; - static Glib::RefPtr hdr; - static Glib::RefPtr ps; + static std::shared_ptr editedIcon; + static std::shared_ptr recentlySavedIcon; + static std::shared_ptr enqueuedIcon; + static std::shared_ptr hdr; + static std::shared_ptr ps; FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); ~FileBrowserEntry () override; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d6c440570..b01d83223 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -83,7 +83,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : trashButtonBox = Gtk::manage( new Gtk::Box(Gtk::ORIENTATION_VERTICAL) ); Gtk::Button* emptyT = Gtk::manage( new Gtk::Button ()); emptyT->set_tooltip_markup (M("FILEBROWSER_EMPTYTRASHHINT")); - emptyT->set_image (*Gtk::manage(new RTImage ("trash-delete.png"))); + emptyT->set_image (*Gtk::manage(new RTImage ("trash-delete", Gtk::ICON_SIZE_LARGE_TOOLBAR))); emptyT->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::emptyTrash)); trashButtonBox->pack_start (*emptyT, Gtk::PACK_SHRINK, 4); emptyT->show (); @@ -93,8 +93,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : hbToolBar1 = Gtk::manage(new Gtk::Box ()); //setup BrowsePath - iRefreshWhite = new RTImage("refresh-small.png"); - iRefreshRed = new RTImage("refresh-red-small.png"); + iRefreshWhite = new RTImage("refresh-small", Gtk::ICON_SIZE_BUTTON); + iRefreshRed = new RTImage("refresh-red-small", Gtk::ICON_SIZE_BUTTON); BrowsePath = Gtk::manage(new Gtk::Entry ()); BrowsePath->set_width_chars (50); @@ -113,7 +113,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : BrowsePath->signal_key_press_event().connect(sigc::mem_fun(*this, &FileCatalog::BrowsePath_key_pressed)); //setup Query - iQueryClear = new RTImage("cancel-small.png"); + iQueryClear = new RTImage("cancel-small", Gtk::ICON_SIZE_BUTTON); 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(""); @@ -151,8 +151,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : pack_start (*stb, 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"); + iLeftPanel_1_Show = new RTImage("panel-to-right", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iLeftPanel_1_Hide = new RTImage("panel-to-left", Gtk::ICON_SIZE_LARGE_TOOLBAR); tbLeftPanel_1->set_relief(Gtk::RELIEF_NONE); tbLeftPanel_1->set_active (true); @@ -164,11 +164,11 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : vSepiLeftPanel = new Gtk::Separator(Gtk::ORIENTATION_VERTICAL); buttonBar->pack_start (*vSepiLeftPanel, Gtk::PACK_SHRINK); - iFilterClear = new RTImage ("filter-clear.png"); - igFilterClear = new RTImage ("filter.png"); + iFilterClear = new RTImage ("filter-clear", Gtk::ICON_SIZE_LARGE_TOOLBAR); + igFilterClear = new RTImage ("filter", Gtk::ICON_SIZE_LARGE_TOOLBAR); bFilterClear = Gtk::manage(new Gtk::ToggleButton ()); bFilterClear->set_active (true); - bFilterClear->set_image(*iFilterClear);// (*Gtk::manage(new RTImage ("filter-clear.png"))); + bFilterClear->set_image(*iFilterClear); 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); @@ -182,8 +182,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : fltrLabelbox = Gtk::manage (new Gtk::Box()); fltrLabelbox->get_style_context()->add_class("smallbuttonbox"); - iUnRanked = new RTImage ("star-gold-hollow-small.png"); - igUnRanked = new RTImage ("star-hollow-small.png"); + iUnRanked = new RTImage ("star-gold-hollow-small", Gtk::ICON_SIZE_BUTTON); + igUnRanked = new RTImage ("star-hollow-small", Gtk::ICON_SIZE_BUTTON); bUnRanked = Gtk::manage( new Gtk::ToggleButton () ); bUnRanked->get_style_context()->add_class("smallbutton"); bUnRanked->set_active (false); @@ -195,8 +195,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : 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 ("star-gold-small.png"); - igranked[i] = new RTImage ("star-small.png"); + iranked[i] = new RTImage ("star-gold-small", Gtk::ICON_SIZE_BUTTON); + igranked[i] = new RTImage ("star-small", Gtk::ICON_SIZE_BUTTON); iranked[i]->show (); igranked[i]->show (); bRank[i] = Gtk::manage( new Gtk::ToggleButton () ); @@ -210,11 +210,11 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : // Toolbar // Similar image arrays in filebrowser.cc - std::array clabelActiveIcons = {"circle-gray-small.png", "circle-red-small.png", "circle-yellow-small.png", "circle-green-small.png", "circle-blue-small.png", "circle-purple-small.png"}; - std::array clabelInactiveIcons = {"circle-empty-gray-small.png", "circle-empty-red-small.png", "circle-empty-yellow-small.png", "circle-empty-green-small.png", "circle-empty-blue-small.png", "circle-empty-purple-small.png"}; + std::array clabelActiveIcons = {"circle-gray-small", "circle-red-small", "circle-yellow-small", "circle-green-small", "circle-blue-small", "circle-purple-small"}; + std::array clabelInactiveIcons = {"circle-empty-gray-small", "circle-empty-red-small", "circle-empty-yellow-small", "circle-empty-green-small", "circle-empty-blue-small", "circle-empty-purple-small"}; - iUnCLabeled = new RTImage(clabelActiveIcons[0]); - igUnCLabeled = new RTImage(clabelInactiveIcons[0]); + iUnCLabeled = new RTImage(clabelActiveIcons[0], Gtk::ICON_SIZE_BUTTON); + igUnCLabeled = new RTImage(clabelInactiveIcons[0], Gtk::ICON_SIZE_BUTTON); bUnCLabeled = Gtk::manage(new Gtk::ToggleButton()); bUnCLabeled->get_style_context()->add_class("smallbutton"); bUnCLabeled->set_active(false); @@ -226,8 +226,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : 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(clabelActiveIcons[i+1]); - igCLabeled[i] = new RTImage(clabelInactiveIcons[i+1]); + iCLabeled[i] = new RTImage(clabelActiveIcons[i+1], Gtk::ICON_SIZE_BUTTON); + igCLabeled[i] = new RTImage(clabelInactiveIcons[i+1], Gtk::ICON_SIZE_BUTTON); iCLabeled[i]->show(); igCLabeled[i]->show(); bCLabel[i] = Gtk::manage(new Gtk::ToggleButton()); @@ -267,10 +267,10 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : // TODO The "g" variant was the more transparent variant of the icon, used // when the button was not toggled. Simplify this, change to ordinary // togglebutton, use CSS for opacity change. - iEdited[0] = new RTImage ("tick-hollow-small.png"); - igEdited[0] = new RTImage ("tick-hollow-small.png"); - iEdited[1] = new RTImage ("tick-small.png"); - igEdited[1] = new RTImage ("tick-small.png"); + iEdited[0] = new RTImage ("tick-hollow-small", Gtk::ICON_SIZE_BUTTON); + igEdited[0] = new RTImage ("tick-hollow-small", Gtk::ICON_SIZE_BUTTON); + iEdited[1] = new RTImage ("tick-small", Gtk::ICON_SIZE_BUTTON); + igEdited[1] = new RTImage ("tick-small", Gtk::ICON_SIZE_BUTTON); for (int i = 0; i < 2; i++) { iEdited[i]->show (); @@ -292,10 +292,10 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : // TODO The "g" variant was the more transparent variant of the icon, used // when the button was not toggled. Simplify this, change to ordinary // togglebutton, use CSS for opacity change. - iRecentlySaved[0] = new RTImage ("saved-no-small.png"); - igRecentlySaved[0] = new RTImage ("saved-no-small.png"); - iRecentlySaved[1] = new RTImage ("saved-yes-small.png"); - igRecentlySaved[1] = new RTImage ("saved-yes-small.png"); + iRecentlySaved[0] = new RTImage ("saved-no-small", Gtk::ICON_SIZE_BUTTON); + igRecentlySaved[0] = new RTImage ("saved-no-small", Gtk::ICON_SIZE_BUTTON); + iRecentlySaved[1] = new RTImage ("saved-yes-small", Gtk::ICON_SIZE_BUTTON); + igRecentlySaved[1] = new RTImage ("saved-yes-small", Gtk::ICON_SIZE_BUTTON); for (int i = 0; i < 2; i++) { iRecentlySaved[i]->show (); @@ -320,8 +320,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : buttonBar->pack_start (*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_SHRINK); // Trash - iTrashShowEmpty = new RTImage("trash-empty-show.png") ; - iTrashShowFull = new RTImage("trash-full-show.png") ; + iTrashShowEmpty = new RTImage("trash-empty-show", Gtk::ICON_SIZE_LARGE_TOOLBAR) ; + iTrashShowFull = new RTImage("trash-full-show", Gtk::ICON_SIZE_LARGE_TOOLBAR) ; bTrash = Gtk::manage( new Gtk::ToggleButton () ); bTrash->set_image (*iTrashShowEmpty); @@ -330,8 +330,8 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bCateg[17] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash, true)); bTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); - iNotTrash = new RTImage("trash-hide-deleted.png") ; - iOriginal = new RTImage("filter-original.png"); + iNotTrash = new RTImage("trash-hide-deleted", Gtk::ICON_SIZE_LARGE_TOOLBAR) ; + iOriginal = new RTImage("filter-original", Gtk::ICON_SIZE_LARGE_TOOLBAR); bNotTrash = Gtk::manage( new Gtk::ToggleButton () ); bNotTrash->set_image (*iNotTrash); @@ -400,7 +400,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : categoryButtons[19] = bOriginal; exifInfo = Gtk::manage(new Gtk::ToggleButton ()); - exifInfo->set_image (*Gtk::manage(new RTImage ("info.png"))); + exifInfo->set_image (*Gtk::manage(new RTImage ("info", Gtk::ICON_SIZE_LARGE_TOOLBAR))); exifInfo->set_relief (Gtk::RELIEF_NONE); exifInfo->set_tooltip_markup (M("FILEBROWSER_SHOWEXIFINFO")); exifInfo->set_active( options.showFileNames ); @@ -410,13 +410,13 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : // thumbnail zoom Gtk::Box* zoomBox = Gtk::manage( new Gtk::Box () ); zoomInButton = Gtk::manage( new Gtk::Button () ); - zoomInButton->set_image (*Gtk::manage(new RTImage ("magnifier-plus.png"))); + zoomInButton->set_image (*Gtk::manage(new RTImage ("magnifier-plus", Gtk::ICON_SIZE_LARGE_TOOLBAR))); 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 ("magnifier-minus.png"))); + zoomOutButton->set_image (*Gtk::manage(new RTImage ("magnifier-minus", Gtk::ICON_SIZE_LARGE_TOOLBAR))); zoomOutButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomOut)); zoomOutButton->set_relief (Gtk::RELIEF_NONE); zoomOutButton->set_tooltip_markup (M("FILEBROWSER_ZOOMOUTHINT")); @@ -425,17 +425,14 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : buttonBar->pack_start (*zoomBox, Gtk::PACK_SHRINK); buttonBar->pack_start (*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), 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"); + iRightPanel_1_Show = new RTImage("panel-to-left", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iRightPanel_1_Hide = new RTImage("panel-to-right", Gtk::ICON_SIZE_LARGE_TOOLBAR); tbRightPanel_1->set_relief(Gtk::RELIEF_NONE); tbRightPanel_1->set_active (true); @@ -713,7 +710,8 @@ void FileCatalog::_refreshProgressBar () // create tab label once Gtk::Notebook *nb = (Gtk::Notebook *)(filepanel->get_parent()); Gtk::Grid* grid = Gtk::manage(new Gtk::Grid()); - progressImage = Gtk::manage(new RTImage("folder-closed.png")); + setExpandAlignProperties (grid, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + progressImage = Gtk::manage(new RTImage("folder-closed", Gtk::ICON_SIZE_LARGE_TOOLBAR)); progressLabel = Gtk::manage(new Gtk::Label(M("MAIN_FRAME_FILEBROWSER"))); grid->attach_next_to(*progressImage, options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*progressLabel, options.mainNBVertical ? Gtk::POS_TOP : Gtk::POS_RIGHT, 1, 1); @@ -727,14 +725,14 @@ void FileCatalog::_refreshProgressBar () } } if (!previewsToLoad) { - progressImage->changeImage("folder-closed.png"); + progressImage->set_from_icon_name("folder-closed", Gtk::ICON_SIZE_LARGE_TOOLBAR); int filteredCount = min(fileBrowser->getNumFiltered(), previewsLoaded); progressLabel->set_text(M("MAIN_FRAME_FILEBROWSER") + (filteredCount != previewsLoaded ? " [" + Glib::ustring::format(filteredCount) + "/" : " (") + Glib::ustring::format(previewsLoaded) + (filteredCount != previewsLoaded ? "]" : ")")); } else { - progressImage->changeImage("magnifier.png"); + progressImage->set_from_icon_name("magnifier", Gtk::ICON_SIZE_LARGE_TOOLBAR); progressLabel->set_text(M("MAIN_FRAME_FILEBROWSER") + " [" + Glib::ustring::format(previewsLoaded) + "/" + Glib::ustring::format(previewsToLoad) + "]" ); diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc index bb64675a1..cb288b0c0 100644 --- a/rtgui/filethumbnailbuttonset.cc +++ b/rtgui/filethumbnailbuttonset.cc @@ -18,20 +18,20 @@ */ #include "filethumbnailbuttonset.h" -#include "rtimage.h" +#include "rtsurface.h" #include "multilangmgr.h" #include "lwbutton.h" #include "rtsurface.h" 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; -std::array, 6> FileThumbnailButtonSet::colorLabelIcon; +std::shared_ptr FileThumbnailButtonSet::rankIcon = std::shared_ptr(nullptr); +std::shared_ptr FileThumbnailButtonSet::gRankIcon = std::shared_ptr(nullptr); +std::shared_ptr FileThumbnailButtonSet::unRankIcon = std::shared_ptr(nullptr); +std::shared_ptr FileThumbnailButtonSet::trashIcon = std::shared_ptr(nullptr); +std::shared_ptr FileThumbnailButtonSet::unTrashIcon = std::shared_ptr(nullptr); +std::shared_ptr FileThumbnailButtonSet::processIcon = std::shared_ptr(nullptr); +std::array, 6> FileThumbnailButtonSet::colorLabelIcon; Glib::ustring FileThumbnailButtonSet::processToolTip; Glib::ustring FileThumbnailButtonSet::unrankToolTip; @@ -44,18 +44,18 @@ FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { if (!iconsLoaded) { - unRankIcon = Cairo::RefPtr(new RTSurface("star-hollow-narrow.png")); - rankIcon = Cairo::RefPtr(new RTSurface("star-gold-narrow.png")); - gRankIcon = Cairo::RefPtr(new RTSurface("star-narrow.png")); - trashIcon = Cairo::RefPtr(new RTSurface("trash-small.png")); - unTrashIcon = Cairo::RefPtr(new RTSurface("trash-remove-small.png")); - processIcon = Cairo::RefPtr(new RTSurface("gears-small.png")); - colorLabelIcon[0] = Cairo::RefPtr(new RTSurface("circle-empty-gray-small.png")); - colorLabelIcon[1] = Cairo::RefPtr(new RTSurface("circle-red-small.png")); - colorLabelIcon[2] = Cairo::RefPtr(new RTSurface("circle-yellow-small.png")); - colorLabelIcon[3] = Cairo::RefPtr(new RTSurface("circle-green-small.png")); - colorLabelIcon[4] = Cairo::RefPtr(new RTSurface("circle-blue-small.png")); - colorLabelIcon[5] = Cairo::RefPtr(new RTSurface("circle-purple-small.png")); + unRankIcon = std::shared_ptr(new RTSurface("star-hollow-narrow", Gtk::ICON_SIZE_BUTTON)); + rankIcon = std::shared_ptr(new RTSurface("star-gold-narrow", Gtk::ICON_SIZE_BUTTON)); + gRankIcon = std::shared_ptr(new RTSurface("star-narrow", Gtk::ICON_SIZE_BUTTON)); + trashIcon = std::shared_ptr(new RTSurface("trash-small", Gtk::ICON_SIZE_BUTTON)); + unTrashIcon = std::shared_ptr(new RTSurface("trash-remove-small", Gtk::ICON_SIZE_BUTTON)); + processIcon = std::shared_ptr(new RTSurface("gears-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[0] = std::shared_ptr(new RTSurface("circle-empty-gray-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[1] = std::shared_ptr(new RTSurface("circle-red-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[2] = std::shared_ptr(new RTSurface("circle-yellow-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[3] = std::shared_ptr(new RTSurface("circle-green-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[4] = std::shared_ptr(new RTSurface("circle-blue-small", Gtk::ICON_SIZE_BUTTON)); + colorLabelIcon[5] = std::shared_ptr(new RTSurface("circle-purple-small", Gtk::ICON_SIZE_BUTTON)); processToolTip = M("FILEBROWSER_POPUPPROCESS"); unrankToolTip = M("FILEBROWSER_UNRANK_TOOLTIP"); diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h index 868d3b58a..af6d1321d 100644 --- a/rtgui/filethumbnailbuttonset.h +++ b/rtgui/filethumbnailbuttonset.h @@ -34,14 +34,14 @@ class FileThumbnailButtonSet : 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 std::shared_ptr rankIcon; + static std::shared_ptr gRankIcon; + static std::shared_ptr unRankIcon; + static std::shared_ptr trashIcon; + static std::shared_ptr unTrashIcon; + static std::shared_ptr processIcon; - static std::array, 6> colorLabelIcon; + static std::array, 6> colorLabelIcon; static Glib::ustring processToolTip; static Glib::ustring unrankToolTip; diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index 068575a96..ad998a364 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -204,13 +204,13 @@ FilmNegative::FilmNegative() : refInputLabel(Gtk::manage(new Gtk::Label(Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), "- - -")))), refSpotButton(Gtk::manage(new Gtk::ToggleButton(M("TP_FILMNEGATIVE_REF_PICK")))), outputLevel(createLevelAdjuster(this, M("TP_FILMNEGATIVE_OUT_LEVEL"))), // ref level - greenBalance(createBalanceAdjuster(this, M("TP_FILMNEGATIVE_GREENBALANCE"), -3.0, 3.0, 0.0, "circle-magenta-small.png", "circle-green-small.png")), // green balance - blueBalance(createBalanceAdjuster(this, M("TP_FILMNEGATIVE_BLUEBALANCE"), -3.0, 3.0, 0.0, "circle-blue-small.png", "circle-yellow-small.png")) // blue balance + greenBalance(createBalanceAdjuster(this, M("TP_FILMNEGATIVE_GREENBALANCE"), -3.0, 3.0, 0.0, "circle-magenta-small", "circle-green-small")), // green balance + blueBalance(createBalanceAdjuster(this, M("TP_FILMNEGATIVE_BLUEBALANCE"), -3.0, 3.0, 0.0, "circle-blue-small", "circle-yellow-small")) // blue balance { setExpandAlignProperties(spotButton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotButton->get_style_context()->add_class("independent"); spotButton->set_tooltip_text(M("TP_FILMNEGATIVE_GUESS_TOOLTIP")); - spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small.png"))); + spotButton->set_image(*Gtk::manage(new RTImage("color-picker-small", Gtk::ICON_SIZE_BUTTON))); refSpotButton->set_tooltip_text(M("TP_FILMNEGATIVE_REF_TOOLTIP")); @@ -518,18 +518,18 @@ void FilmNegative::filmRefValuesChanged(const RGB &refInput, const RGB &refOutpu [this, refInput, refOutput]() -> bool { refInputValues = refInput; paramsUpgraded = true; - + disableListener(); - + refInputLabel->set_markup( Glib::ustring::compose(M("TP_FILMNEGATIVE_REF_LABEL"), fmt(refInputValues))); - + writeOutputSliders(refOutput); - + outputLevel->show(); blueBalance->show(); greenBalance->show(); - + enableListener(); return false; } diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index c407b88d7..1ea843e28 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -138,7 +138,7 @@ FilterPanel::FilterPanel () : listener (nullptr) // add panel ending Gtk::Box* vboxpe = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); Gtk::Separator* hseptpe = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - Gtk::Image* peImg = Gtk::manage (new RTImage("ornament1.png")); + Gtk::Image* peImg = Gtk::manage (new RTImage("ornament1")); vboxpe->pack_start(*hseptpe, Gtk::PACK_SHRINK, 4); vboxpe->pack_start(*peImg); pack_start(*vboxpe, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 1cc3f5c14..0cabd2f80 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -54,7 +54,7 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u CPointsCurve = Gtk::manage (new MyFlatCurve ()); CPointsCurve->setType (FCT_MinMaxCPoints); - + Gtk::Grid* CPointsCurveBox = Gtk::manage (new Gtk::Grid ()); CPointsCurveBox->get_style_context()->add_class("curve-curvebox"); CPointsCurveBox->add(*CPointsCurve); @@ -81,17 +81,17 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u } editCPoints = Gtk::manage (new Gtk::ToggleButton()); - initButton(*editCPoints, Glib::ustring("crosshair-node-curve.png"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); + initButton(*editCPoints, Glib::ustring("crosshair-node-curve"), Gtk::ALIGN_START, false, "EDIT_PIPETTE_TOOLTIP"); editPointCPoints = Gtk::manage (new Gtk::ToggleButton ()); - initButton(*editPointCPoints, Glib::ustring("edit-point.png"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); + initButton(*editPointCPoints, Glib::ustring("edit-point"), Gtk::ALIGN_START, false, "CURVEEDITOR_EDITPOINT_HINT"); copyCPoints = Gtk::manage (new Gtk::Button ()); - initButton(*copyCPoints, Glib::ustring("copy.png"), Gtk::ALIGN_END, true); + initButton(*copyCPoints, Glib::ustring("copy"), Gtk::ALIGN_END, true); pasteCPoints = Gtk::manage (new Gtk::Button ()); - initButton(*pasteCPoints, Glib::ustring("paste.png"), Gtk::ALIGN_END, false); + initButton(*pasteCPoints, Glib::ustring("paste"), Gtk::ALIGN_END, false); loadCPoints = Gtk::manage (new Gtk::Button ()); - initButton(*loadCPoints, Glib::ustring("folder-open.png"), Gtk::ALIGN_END, false); + initButton(*loadCPoints, Glib::ustring("folder-open"), Gtk::ALIGN_END, false); saveCPoints = Gtk::manage (new Gtk::Button ()); - initButton(*saveCPoints, Glib::ustring("save.png"), Gtk::ALIGN_END, false); + initButton(*saveCPoints, Glib::ustring("save"), Gtk::ALIGN_END, false); CPointsbbox->attach_next_to(*editPointCPoints, sideStart, 1, 1); CPointsbbox->attach_next_to(*editCPoints, sideStart, 1, 1); diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 71fa0aab6..b217bb7c5 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -37,7 +37,7 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L bindCurrentFolder (*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 ("cancel-small.png"))); + flatFieldFileReset->set_image (*Gtk::manage(new RTImage ("cancel-small", Gtk::ICON_SIZE_BUTTON))); hbff->pack_start(*ffLabel, Gtk::PACK_SHRINK); hbff->pack_start(*flatFieldFile); hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK); diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index 1274da9ab..79f8d085f 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -31,7 +31,7 @@ Gradient::Gradient () : FoldableToolPanel(this, "gradient", M("TP_GRADIENT_LABEL editHBox = Gtk::manage (new Gtk::Box()); edit = Gtk::manage (new Gtk::ToggleButton()); edit->get_style_context()->add_class("independent"); - edit->add (*Gtk::manage (new RTImage ("crosshair-adjust.png"))); + edit->add (*Gtk::manage (new RTImage ("crosshair-adjust", Gtk::ICON_SIZE_BUTTON))); edit->set_tooltip_text(M("EDIT_OBJECT_TOOLTIP")); editConn = edit->signal_toggled().connect( sigc::mem_fun(*this, &Gradient::editToggled) ); editHBox->pack_start(*edit, Gtk::PACK_SHRINK, 0); @@ -164,8 +164,8 @@ void Gradient::updateGeometry(const int centerX, const int centerY, const double int imW=0; int imH=0; - - + + if (fullWidth != -1 && fullHeight != -1) { imW = fullWidth; imH = fullHeight; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 61cbde140..c6399bed6 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -23,6 +23,7 @@ #include "../rtengine/utils.h" #include "../rtengine/procparams.h" #include "rtimage.h" +#include "rtscalable.h" #include "multilangmgr.h" #include @@ -31,12 +32,6 @@ using namespace std; -Glib::RefPtr MyExpander::inconsistentImage; -Glib::RefPtr MyExpander::enabledImage; -Glib::RefPtr MyExpander::disabledImage; -Glib::RefPtr MyExpander::openedImage; -Glib::RefPtr MyExpander::closedImage; - IdleRegister::~IdleRegister() { destroy(); @@ -184,13 +179,14 @@ Gtk::Border getPadding(const Glib::RefPtr style) return padding; } - int s = (double)RTScalable::getScale(); padding = style->get_padding(); - if (s > 1) { - padding.set_left(padding.get_left() * s); - padding.set_right(padding.get_right() * s); - padding.set_top(padding.get_top() * s); - padding.set_bottom(padding.get_bottom() * s); + + if (RTScalable::getGlobalScale() > 1.0) { + // Scale pixel border size based on DPI and Scale + padding.set_left(RTScalable::scalePixelSize(padding.get_left())); + padding.set_right(RTScalable::scalePixelSize(padding.get_right())); + padding.set_top(RTScalable::scalePixelSize(padding.get_top())); + padding.set_bottom(RTScalable::scalePixelSize(padding.get_bottom())); } return padding; @@ -589,27 +585,12 @@ void ExpanderBox::hideBox() Gtk::EventBox::hide(); } -void MyExpander::init() -{ - if (!inconsistentImage) { // if one is null, all are null - inconsistentImage = Glib::RefPtr(new RTImage("power-inconsistent-small.png")); - enabledImage = Glib::RefPtr(new RTImage("power-on-small.png")); - disabledImage = Glib::RefPtr(new RTImage("power-off-small.png")); - openedImage = Glib::RefPtr(new RTImage("expander-open-small.png")); - closedImage = Glib::RefPtr(new RTImage("expander-closed-small.png")); - } -} - -void MyExpander::cleanup() -{ - inconsistentImage.reset(); - enabledImage.reset(); - disabledImage.reset(); - openedImage.reset(); - closedImage.reset(); -} - MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) : + inconsistentImage("power-inconsistent-small"), + enabledImage("power-on-small"), + disabledImage("power-off-small"), + openedImage("expander-open-small"), + closedImage("expander-closed-small"), enabled(false), inconsistent(false), flushEvent(false), expBox(nullptr), child(nullptr), headerWidget(nullptr), statusImage(nullptr), label(nullptr), useEnabled(useEnabled) @@ -666,6 +647,11 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) : } MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : + inconsistentImage("power-inconsistent-small"), + enabledImage("power-on-small"), + disabledImage("power-off-small"), + openedImage("expander-open-small"), + closedImage("expander-closed-small"), enabled(false), inconsistent(false), flushEvent(false), expBox(nullptr), child(nullptr), headerWidget(nullptr), label(nullptr), useEnabled(useEnabled) @@ -807,13 +793,13 @@ void MyExpander::set_inconsistent(bool isInconsistent) if (useEnabled) { if (isInconsistent) { - statusImage->set(inconsistentImage->get_surface()); + statusImage->set_from_icon_name(inconsistentImage); } else { if (enabled) { - statusImage->set(enabledImage->get_surface()); + statusImage->set_from_icon_name(enabledImage); get_style_context()->add_class("enabledTool"); } else { - statusImage->set(disabledImage->get_surface()); + statusImage->set_from_icon_name(disabledImage); get_style_context()->remove_class("enabledTool"); } } @@ -840,7 +826,7 @@ void MyExpander::setEnabled(bool isEnabled) enabled = false; if (!inconsistent) { - statusImage->set(disabledImage->get_surface()); + statusImage->set_from_icon_name(disabledImage); get_style_context()->remove_class("enabledTool"); message.emit(); } @@ -848,7 +834,7 @@ void MyExpander::setEnabled(bool isEnabled) enabled = true; if (!inconsistent) { - statusImage->set(enabledImage->get_surface()); + statusImage->set_from_icon_name(enabledImage); get_style_context()->add_class("enabledTool"); message.emit(); } @@ -879,9 +865,9 @@ void MyExpander::set_expanded( bool expanded ) if (!useEnabled) { if (expanded ) { - statusImage->set(openedImage->get_surface()); + statusImage->set_from_icon_name(openedImage); } else { - statusImage->set(closedImage->get_surface()); + statusImage->set_from_icon_name(closedImage); } } @@ -924,9 +910,9 @@ bool MyExpander::on_toggle(GdkEventButton* event) if (!useEnabled) { if (isVisible) { - statusImage->set(closedImage->get_surface()); + statusImage->set_from_icon_name(closedImage); } else { - statusImage->set(openedImage->get_surface()); + statusImage->set_from_icon_name(openedImage); } } @@ -951,11 +937,11 @@ bool MyExpander::on_enabled_change(GdkEventButton* event) if (event->button == 1) { if (enabled) { enabled = false; - statusImage->set(disabledImage->get_surface()); + statusImage->set_from_icon_name(disabledImage); get_style_context()->remove_class("enabledTool"); } else { enabled = true; - statusImage->set(enabledImage->get_surface()); + statusImage->set_from_icon_name(enabledImage); get_style_context()->add_class("enabledTool"); } @@ -1019,17 +1005,17 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) void MyScrolledWindow::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - natural_width = minimum_width = 100 * RTScalable::getScale(); + natural_width = minimum_width = RTScalable::scalePixelSize(100); } void MyScrolledWindow::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - natural_height = minimum_height = 50 * RTScalable::getScale(); + natural_height = minimum_height = RTScalable::scalePixelSize(50); } void MyScrolledWindow::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - natural_height = minimum_height = 50 * RTScalable::getScale(); + natural_height = minimum_height = RTScalable::scalePixelSize(50); } /* @@ -1108,7 +1094,7 @@ void MyScrolledToolbar::get_preferred_height_vfunc (int &minimumHeight, int &nat MyComboBoxText::MyComboBoxText (bool has_entry) : Gtk::ComboBoxText(has_entry) { - minimumWidth = naturalWidth = 70; + minimumWidth = naturalWidth = RTScalable::scalePixelSize(70); Gtk::CellRendererText* cellRenderer = dynamic_cast(get_first_cell()); cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; add_events(Gdk::SCROLL_MASK|Gdk::SMOOTH_SCROLL_MASK); @@ -1132,12 +1118,12 @@ bool MyComboBoxText::on_scroll_event (GdkEventScroll* event) void MyComboBoxText::setPreferredWidth (int minimum_width, int natural_width) { if (natural_width == -1 && minimum_width == -1) { - naturalWidth = minimumWidth = 70 * RTScalable::getScale(); + naturalWidth = minimumWidth = RTScalable::scalePixelSize(70); } else if (natural_width == -1) { naturalWidth = minimumWidth = minimum_width; } else if (minimum_width == -1) { naturalWidth = natural_width; - minimumWidth = rtengine::max(naturalWidth / 2, 20); + minimumWidth = rtengine::max(naturalWidth / 2, RTScalable::scalePixelSize(20)); minimumWidth = rtengine::min(naturalWidth, minimumWidth); } else { naturalWidth = natural_width; @@ -1147,19 +1133,20 @@ void MyComboBoxText::setPreferredWidth (int minimum_width, int natural_width) void MyComboBoxText::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - natural_width = rtengine::max(naturalWidth, 10 * RTScalable::getScale()); - minimum_width = rtengine::max(minimumWidth, 10 * RTScalable::getScale()); + natural_width = rtengine::max(naturalWidth, RTScalable::scalePixelSize(10)); + minimum_width = rtengine::max(minimumWidth, RTScalable::scalePixelSize(10)); } + void MyComboBoxText::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const { - natural_width = rtengine::max(naturalWidth, 10 * RTScalable::getScale()); - minimum_width = rtengine::max(minimumWidth, 10 * RTScalable::getScale()); + natural_width = rtengine::max(naturalWidth, RTScalable::scalePixelSize(10)); + minimum_width = rtengine::max(minimumWidth, RTScalable::scalePixelSize(10)); } MyComboBox::MyComboBox () { - minimumWidth = naturalWidth = 70 * RTScalable::getScale(); + minimumWidth = naturalWidth = RTScalable::scalePixelSize(70); } bool MyComboBox::on_scroll_event (GdkEventScroll* event) @@ -1178,12 +1165,12 @@ bool MyComboBox::on_scroll_event (GdkEventScroll* event) void MyComboBox::setPreferredWidth (int minimum_width, int natural_width) { if (natural_width == -1 && minimum_width == -1) { - naturalWidth = minimumWidth = 70 * RTScalable::getScale(); + naturalWidth = minimumWidth = RTScalable::scalePixelSize(70); } else if (natural_width == -1) { naturalWidth = minimumWidth = minimum_width; } else if (minimum_width == -1) { naturalWidth = natural_width; - minimumWidth = rtengine::max(naturalWidth / 2, 20); + minimumWidth = rtengine::max(naturalWidth / 2, RTScalable::scalePixelSize(20)); minimumWidth = rtengine::min(naturalWidth, minimumWidth); } else { naturalWidth = natural_width; @@ -1193,13 +1180,14 @@ void MyComboBox::setPreferredWidth (int minimum_width, int natural_width) void MyComboBox::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - natural_width = rtengine::max(naturalWidth, 10 * RTScalable::getScale()); - minimum_width = rtengine::max(minimumWidth, 10 * RTScalable::getScale()); + natural_width = rtengine::max(naturalWidth, RTScalable::scalePixelSize(10)); + minimum_width = rtengine::max(minimumWidth, RTScalable::scalePixelSize(10)); } + void MyComboBox::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const { - natural_width = rtengine::max(naturalWidth, 10 * RTScalable::getScale()); - minimum_width = rtengine::max(minimumWidth, 10 * RTScalable::getScale()); + natural_width = rtengine::max(naturalWidth, RTScalable::scalePixelSize(10)); + minimum_width = rtengine::max(minimumWidth, RTScalable::scalePixelSize(10)); } MySpinButton::MySpinButton () @@ -1485,19 +1473,20 @@ bool MyFileChooserButton::on_scroll_event (GdkEventScroll* event) void MyFileChooserButton::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = natural_width = 35 * RTScalable::getScale(); + minimum_width = natural_width = RTScalable::scalePixelSize(35); } + void MyFileChooserButton::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const { - minimum_width = natural_width = 35 * RTScalable::getScale(); + minimum_width = natural_width = RTScalable::scalePixelSize(35); } -TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx) +TextOrIcon::TextOrIcon (const Glib::ustring &icon_name, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx) { - RTImage *img = Gtk::manage(new RTImage(fname)); + RTImage *img = Gtk::manage(new RTImage(icon_name, Gtk::ICON_SIZE_LARGE_TOOLBAR)); pack_start(*img, Gtk::PACK_SHRINK, 0); set_tooltip_markup("" + labelTx + "\n" + tooltipTx); @@ -1506,14 +1495,14 @@ TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx } -MyImageMenuItem::MyImageMenuItem(Glib::ustring label, Glib::ustring imageFileName) +MyImageMenuItem::MyImageMenuItem(Glib::ustring label, Glib::ustring iconName) { box = Gtk::manage (new Gtk::Grid()); this->label = Gtk::manage( new Gtk::Label(label)); box->set_orientation(Gtk::ORIENTATION_HORIZONTAL); - if (!imageFileName.empty()) { - image = Gtk::manage( new RTImage(imageFileName) ); + if (!iconName.empty()) { + image = Gtk::manage( new RTImage(iconName, Gtk::ICON_SIZE_MENU) ); box->attach_next_to(*image, Gtk::POS_LEFT, 1, 1); } else { image = nullptr; @@ -1535,18 +1524,18 @@ const Gtk::Label* MyImageMenuItem::getLabel () const return label; } -MyProgressBar::MyProgressBar(int width) : w(rtengine::max(width, 10 * RTScalable::getScale())) {} -MyProgressBar::MyProgressBar() : w(200 * RTScalable::getScale()) {} +MyProgressBar::MyProgressBar(int width) : w(rtengine::max(width, RTScalable::scalePixelSize(10))) {} +MyProgressBar::MyProgressBar() : w(RTScalable::scalePixelSize(200)) {} void MyProgressBar::setPreferredWidth(int width) { - w = rtengine::max(width, 10 * RTScalable::getScale()); + w = rtengine::max(width, RTScalable::scalePixelSize(10)); } void MyProgressBar::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = rtengine::max(w / 2, 50 * RTScalable::getScale()); - natural_width = rtengine::max(w, 50 * RTScalable::getScale()); + minimum_width = rtengine::max(w / 2, RTScalable::scalePixelSize(50)); + natural_width = rtengine::max(w, RTScalable::scalePixelSize(50)); } void MyProgressBar::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 126cf672b..3b8e80ebb 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -191,11 +191,11 @@ public: typedef sigc::signal type_signal_enabled_toggled; private: type_signal_enabled_toggled message; - static Glib::RefPtr inconsistentImage; /// "inconsistent" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed - static Glib::RefPtr enabledImage; /// "enabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed - static Glib::RefPtr disabledImage; /// "disabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed - static Glib::RefPtr openedImage; /// "opened" image, displayed when useEnabled is false - static Glib::RefPtr closedImage; /// "closed" image, displayed when useEnabled is false + const Glib::ustring inconsistentImage; /// "inconsistent" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + const Glib::ustring enabledImage; /// "enabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + const Glib::ustring disabledImage; /// "disabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + const Glib::ustring openedImage; /// "opened" image, displayed when useEnabled is false + const Glib::ustring closedImage; /// "closed" image, displayed when useEnabled is false bool enabled; /// Enabled feature (default to true) bool inconsistent; /// True if the enabled button is inconsistent Gtk::EventBox *titleEvBox; /// EventBox of the title, to get a connector from it @@ -238,10 +238,6 @@ public: */ MyExpander(bool useEnabled, Gtk::Widget* titleWidget); - /// Initialize the class by loading the images - static void init(); - static void cleanup(); - Glib::SignalProxy1< bool, GdkEventButton* > signal_button_release_event() { return titleEvBox->signal_button_release_event(); @@ -479,7 +475,7 @@ class TextOrIcon final : public Gtk::Box { public: - TextOrIcon (const Glib::ustring &filename, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx); + TextOrIcon (const Glib::ustring &icon_name, const Glib::ustring &labelTx, const Glib::ustring &tooltipTx); }; class MyImageMenuItem final : public Gtk::MenuItem @@ -490,7 +486,7 @@ private: Gtk::Label *label; public: - MyImageMenuItem (Glib::ustring label, Glib::ustring imageFileName); + MyImageMenuItem (Glib::ustring label, Glib::ustring iconName); const RTImage *getImage () const; const Gtk::Label* getLabel () const; }; diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 6bda0812e..a7e652460 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -25,6 +25,7 @@ #include "../rtengine/array2D.h" #include "../rtengine/LUT.h" #include "rtimage.h" +#include "rtscalable.h" #include "../rtengine/color.h" using namespace rtengine; @@ -114,30 +115,30 @@ HistogramPanel::HistogramPanel () : histogramRGBAreaHori->set_no_show_all(); histogramRGBAreaVert->set_no_show_all(); - redImage = new RTImage ("histogram-red-on-small.png"); - greenImage = new RTImage ("histogram-green-on-small.png"); - blueImage = new RTImage ("histogram-blue-on-small.png"); - valueImage = new RTImage ("histogram-silver-on-small.png"); - chroImage = new RTImage ("histogram-gold-on-small.png"); - barImage = new RTImage ("histogram-bar-on-small.png"); + redImage = new RTImage ("histogram-red-on-small", Gtk::ICON_SIZE_BUTTON); + greenImage = new RTImage ("histogram-green-on-small", Gtk::ICON_SIZE_BUTTON); + blueImage = new RTImage ("histogram-blue-on-small", Gtk::ICON_SIZE_BUTTON); + valueImage = new RTImage ("histogram-silver-on-small", Gtk::ICON_SIZE_BUTTON); + chroImage = new RTImage ("histogram-gold-on-small", Gtk::ICON_SIZE_BUTTON); + barImage = new RTImage ("histogram-bar-on-small", Gtk::ICON_SIZE_BUTTON); - redImage_g = new RTImage ("histogram-red-off-small.png"); - greenImage_g = new RTImage ("histogram-green-off-small.png"); - blueImage_g = new RTImage ("histogram-blue-off-small.png"); - valueImage_g = new RTImage ("histogram-silver-off-small.png"); - chroImage_g = new RTImage ("histogram-gold-off-small.png"); - barImage_g = new RTImage ("histogram-bar-off-small.png"); + redImage_g = new RTImage ("histogram-red-off-small", Gtk::ICON_SIZE_BUTTON); + greenImage_g = new RTImage ("histogram-green-off-small", Gtk::ICON_SIZE_BUTTON); + blueImage_g = new RTImage ("histogram-blue-off-small", Gtk::ICON_SIZE_BUTTON); + valueImage_g = new RTImage ("histogram-silver-off-small", Gtk::ICON_SIZE_BUTTON); + chroImage_g = new RTImage ("histogram-gold-off-small", Gtk::ICON_SIZE_BUTTON); + barImage_g = new RTImage ("histogram-bar-off-small", Gtk::ICON_SIZE_BUTTON); - mode0Image = new RTImage ("histogram-mode-linear-small.png"); - mode1Image = new RTImage ("histogram-mode-logx-small.png"); - mode2Image = new RTImage ("histogram-mode-logxy-small.png"); + mode0Image = new RTImage ("histogram-mode-linear-small", Gtk::ICON_SIZE_BUTTON); + mode1Image = new RTImage ("histogram-mode-logx-small", Gtk::ICON_SIZE_BUTTON); + mode2Image = new RTImage ("histogram-mode-logxy-small", Gtk::ICON_SIZE_BUTTON); - Gtk::Image* histImage = Gtk::manage(new RTImage("histogram-type-histogram-small.png")); - Gtk::Image* histRawImage = Gtk::manage(new RTImage("histogram-type-histogram-raw-small.png")); - Gtk::Image* paradeImage = Gtk::manage(new RTImage("histogram-type-parade-small.png")); - Gtk::Image* waveImage = Gtk::manage(new RTImage("histogram-type-waveform-small.png")); - Gtk::Image* vectHcImage = Gtk::manage(new RTImage("histogram-type-vectorscope-hc-small.png")); - Gtk::Image* vectHsImage = Gtk::manage(new RTImage("histogram-type-vectorscope-hs-small.png")); + Gtk::Image* histImage = Gtk::manage(new RTImage("histogram-type-histogram-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* histRawImage = Gtk::manage(new RTImage("histogram-type-histogram-raw-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* paradeImage = Gtk::manage(new RTImage("histogram-type-parade-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* waveImage = Gtk::manage(new RTImage("histogram-type-waveform-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* vectHcImage = Gtk::manage(new RTImage("histogram-type-vectorscope-hc-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* vectHsImage = Gtk::manage(new RTImage("histogram-type-vectorscope-hs-small", Gtk::ICON_SIZE_BUTTON)); showRed = Gtk::manage (new Gtk::ToggleButton ()); showGreen = Gtk::manage (new Gtk::ToggleButton ()); @@ -275,7 +276,7 @@ HistogramPanel::HistogramPanel () : case ScopeType::NONE: break; } - scopeOptions->set_image(*Gtk::manage(new RTImage("histogram-ellipsis-small.png"))); + scopeOptions->set_image(*Gtk::manage(new RTImage("histogram-ellipsis-small"))); showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g); setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); @@ -760,21 +761,18 @@ void HistogramRGBArea::getPreferredThickness(int& min_thickness, int& natural_th void HistogramRGBArea::getPreferredLength(int& min_length, int& natural_length) const { - int s = RTScalable::getScale(); - min_length = 60 * s; - natural_length = 200 * s; + min_length = RTScalable::scalePixelSize(60); + natural_length = RTScalable::scalePixelSize(200); } void HistogramRGBArea::getPreferredThicknessForLength(int length, int& min_thickness, int& natural_thickness) const { int bThickness = length / 30; - int s = RTScalable::getScale(); - - if (bThickness > (10 * s)) { - bThickness = 10 * s; - } else if (bThickness < (5 * s)) { - bThickness = 5 * s; + if (bThickness > RTScalable::scalePixelSize(10)) { + bThickness = RTScalable::scalePixelSize(10); + } else if (bThickness < RTScalable::scalePixelSize(5)) { + bThickness = RTScalable::scalePixelSize(5); } min_thickness = bThickness; @@ -814,7 +812,7 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin int winx, winy, winw, winh; window->get_geometry(winx, winy, winw, winh); - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); // This will create or update the size of the BackBuffer::surface setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, winw, winh, true); @@ -1032,7 +1030,7 @@ void HistogramRGBAreaVert::get_preferred_height_vfunc (int &minimum_height, int void HistogramRGBAreaVert::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 10 * RTScalable::getScale(); + minimum_width = RTScalable::scalePixelSize(10); natural_width = minimum_width; } @@ -1103,22 +1101,18 @@ Gtk::SizeRequestMode HistogramArea::get_request_mode_vfunc () const void HistogramArea::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - int s = RTScalable::getScale(); - minimum_height = 100 * s; - natural_height = 200 * s; + minimum_height = RTScalable::scalePixelSize(100); + natural_height = RTScalable::scalePixelSize(200); } void HistogramArea::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - - int s = RTScalable::getScale(); - minimum_width = 200 * s; - natural_width = 400 * s; + minimum_width = RTScalable::scalePixelSize(200); + natural_width = RTScalable::scalePixelSize(400); } void HistogramArea::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - minimum_height = 0; natural_height = 0; } @@ -1252,7 +1246,7 @@ void HistogramArea::updateBackBuffer () Cairo::RefPtr cr = Cairo::Context::create(surface); const Glib::RefPtr style = get_style_context(); - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); // Setup drawing cr->set_source_rgba (0., 0., 0., 0.); @@ -1471,7 +1465,7 @@ void HistogramArea::on_realize () void HistogramArea::drawCurve(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int vsize) { - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); cr->set_line_width(s); cr->move_to (padding, vsize - 1); @@ -1501,7 +1495,7 @@ void HistogramArea::drawCurve(Cairo::RefPtr &cr, void HistogramArea::drawMarks(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi) { - int s = 8 * RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); if(data[0] > scale) { cr->rectangle(padding, (ui++)*s, s, s); @@ -1674,7 +1668,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in scope_scale * std::max(vect_width, vect_height) : std::min(w, h) - 2 * padding; const float o_x = (w - scope_scale * vect_width) / 2; const float o_y = (h - scope_scale * vect_height) / 2; - const double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); auto orig_matrix = cr->get_matrix(); const double line_length = scope_size / 2.0; std::valarray ch_ds(1); diff --git a/rtgui/history.cc b/rtgui/history.cc index 4d6940e9b..9cd9173a8 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -98,7 +98,7 @@ History::History (bool bookmarkSupport) : historyVPaned (nullptr), blistener (nu //addBookmark->get_style_context()->set_junction_sides(Gtk::JUNCTION_RIGHT); addBookmark->get_style_context()->add_class ("Left"); addBookmark->set_tooltip_markup (M ("HISTORY_NEWSNAPSHOT_TOOLTIP")); - Gtk::Image* addimg = Gtk::manage (new RTImage ("add-small.png")); + Gtk::Image* addimg = Gtk::manage (new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON)); addBookmark->set_image (*addimg); ahbox->pack_start (*addBookmark); @@ -106,7 +106,7 @@ History::History (bool bookmarkSupport) : historyVPaned (nullptr), blistener (nu setExpandAlignProperties (delBookmark, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); //delBookmark->get_style_context()->set_junction_sides(Gtk::JUNCTION_LEFT); delBookmark->get_style_context()->add_class ("Right"); - Gtk::Image* delimg = Gtk::manage (new RTImage ("remove-small.png")); + Gtk::Image* delimg = Gtk::manage (new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON)); delBookmark->set_image (*delimg); ahbox->pack_start (*delBookmark); diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 446dda3fb..542234db2 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -87,21 +87,6 @@ ICCProfileCreator::ICCProfileCreator(RTWindow *rtwindow) setExpandAlignProperties(primariesGrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); primariesGrid->set_column_spacing(5); - /* - Gtk::Image* gamuts0 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl0 = Gtk::manage(new RTImage("rt-logo-small.png")); - Gtk::Image* gamuts1 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl1 = Gtk::manage(new RTImage("rt-logo-small.png")); - Gtk::Image* gamuts2 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl2 = Gtk::manage(new RTImage("rt-logo-small.png")); - Gtk::Image* gamuts3 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl3 = Gtk::manage(new RTImage("rt-logo-small.png")); - Gtk::Image* gamuts4 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl4 = Gtk::manage(new RTImage("rt-logo-small.png")); - Gtk::Image* gamuts5 = Gtk::manage(new RTImage("rt-logo-tiny.png")); - Gtk::Image* gamutl5 = Gtk::manage(new RTImage("rt-logo-small.png")); - */ - aPrimariesRedX = Gtk::manage(new Adjuster(M("ICCPROFCREATOR_PRIM_REDX"), 0.4100, 0.9000, 0.0001, 0.6400/*, gamuts0, gamutl0*/)); setExpandAlignProperties(aPrimariesRedX, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); aPrimariesRedY = Gtk::manage(new Adjuster(M("ICCPROFCREATOR_PRIM_REDY"), 0.1000, 0.6000, 0.0001, 0.3300/*, gamutl1, gamuts1*/)); @@ -219,7 +204,7 @@ ICCProfileCreator::ICCProfileCreator(RTWindow *rtwindow) setExpandAlignProperties(eCopyright, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); copygrid->attach(*eCopyright, 0, 0, 1, 1); resetCopyright = Gtk::manage(new Gtk::Button()); - resetCopyright->add(*Gtk::manage(new RTImage("undo-small.png", "redo-small.png"))); + resetCopyright->add(*Gtk::manage(new RTImage("undo-small", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(resetCopyright, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); resetCopyright->set_relief(Gtk::RELIEF_NONE); resetCopyright->set_tooltip_markup(M("ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP")); @@ -850,7 +835,7 @@ void ICCProfileCreator::savePressed() //g5=0.517448 presetGamma = 2.22; presetSlope = 4.5; - + } else if (gammaPreset == "linear_g1.0") { sGammaPreset = "Linear_g=1.0"; ga[0] = 1.0; //gamma=1 linear : for high dynamic images (cf D.Coffin...) diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 90528e831..d57e9e7a8 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -170,7 +170,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha iVBox->pack_start(*dcpFrame); saveRef = Gtk::manage(new Gtk::Button(M("TP_ICM_SAVEREFERENCE"))); - saveRef->set_image(*Gtk::manage(new RTImage("save-small.png"))); + saveRef->set_image(*Gtk::manage(new RTImage("save-small", Gtk::ICON_SIZE_BUTTON))); saveRef->set_alignment(0.5f, 0.5f); saveRef->set_tooltip_markup(M("TP_ICM_SAVEREFERENCE_TOOLTIP")); iVBox->pack_start(*saveRef, Gtk::PACK_SHRINK); @@ -268,7 +268,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha neutral = Gtk::manage (new Gtk::Button (M ("TP_ICM_NEUTRAL"))); setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); + RTImage *resetImg = Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON)); setExpandAlignProperties (resetImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); neutral->set_image (*resetImg); neutralconn = neutral->signal_pressed().connect ( sigc::mem_fun (*this, &ICMPanel::neutral_pressed) ); @@ -340,7 +340,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha redVBox->pack_start(*bluBox, Gtk::PACK_EXPAND_WIDGET); preser = Gtk::manage(new Adjuster(M("TP_ICM_WORKING_PRESER"), 0., 100., 0.5, 0.)); preser->setAdjusterListener(this); - + preBox = Gtk::manage(new Gtk::Box()); preBox->pack_start(*preser, Gtk::PACK_SHRINK); redVBox->pack_start(*separator1, Gtk::PACK_SHRINK); @@ -352,7 +352,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha redVBox->pack_start(*cielab, Gtk::PACK_SHRINK); redVBox->pack_start(*labgridcie, Gtk::PACK_EXPAND_WIDGET, 4); - + redFrame->add(*redVBox); wGamma->setAdjusterListener(this); @@ -374,10 +374,10 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha Gtk::Label* abIntentLbl = Gtk::manage(new Gtk::Label(M("TP_ICM_PROFILEINTENT"))); riaHBox->pack_start(*abIntentLbl, Gtk::PACK_SHRINK); aRendIntent.reset(new PopUpButton()); - aRendIntent->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - aRendIntent->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - aRendIntent->addEntry("intent-saturation.png", M("PREFERENCES_INTENT_SATURATION")); - aRendIntent->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + aRendIntent->addEntry("intent-perceptual", M("PREFERENCES_INTENT_PERCEPTUAL")); + aRendIntent->addEntry("intent-relative", M("PREFERENCES_INTENT_RELATIVE")); + aRendIntent->addEntry("intent-saturation", M("PREFERENCES_INTENT_SATURATION")); + aRendIntent->addEntry("intent-absolute", M("PREFERENCES_INTENT_ABSOLUTE")); aRendIntent->setSelected(1); aRendIntent->show(); riaHBox->pack_start(*aRendIntent->buttonGroup, Gtk::PACK_EXPAND_PADDING); @@ -417,10 +417,10 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha Gtk::Label* outputIntentLbl = Gtk::manage(new Gtk::Label(M("TP_ICM_PROFILEINTENT"))); riHBox->pack_start(*outputIntentLbl, Gtk::PACK_SHRINK); oRendIntent.reset(new PopUpButton()); - oRendIntent->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - oRendIntent->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - oRendIntent->addEntry("intent-saturation.png", M("PREFERENCES_INTENT_SATURATION")); - oRendIntent->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + oRendIntent->addEntry("intent-perceptual", M("PREFERENCES_INTENT_PERCEPTUAL")); + oRendIntent->addEntry("intent-relative", M("PREFERENCES_INTENT_RELATIVE")); + oRendIntent->addEntry("intent-saturation", M("PREFERENCES_INTENT_SATURATION")); + oRendIntent->addEntry("intent-absolute", M("PREFERENCES_INTENT_ABSOLUTE")); oRendIntent->setSelected(1); oRendIntent->show(); riHBox->pack_start(*oRendIntent->buttonGroup, Gtk::PACK_EXPAND_PADDING); @@ -1671,8 +1671,8 @@ void ICMPanel::wprimChanged() break; } } - - + + if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { if (wProfNames->get_active_text() == "Rec2020") { redx->setValue(0.708); @@ -1776,7 +1776,7 @@ void ICMPanel::wprimChanged() labgridcie->set_sensitive(false); will->set_sensitive(true); } - + } willChanged (); @@ -2156,9 +2156,9 @@ void ICMPanel::setBatchMode(bool batchMode) iVBox->reorder_child(*iunchanged, 5); removeIfThere(this, saveRef); oProfNames->append(M("GENERAL_UNCHANGED")); - oRendIntent->addEntry("template-24.png", M("GENERAL_UNCHANGED")); + oRendIntent->addEntry("template-24", M("GENERAL_UNCHANGED")); oRendIntent->show(); - aRendIntent->addEntry("template-24.png", M("GENERAL_UNCHANGED")); + aRendIntent->addEntry("template-24", M("GENERAL_UNCHANGED")); aRendIntent->show(); wProfNames->append(M("GENERAL_UNCHANGED")); wTRC->append(M("GENERAL_UNCHANGED")); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 22e140e7d..df9756e88 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -788,14 +788,14 @@ Gtk::SizeRequestMode ImageArea::get_request_mode_vfunc () const void ImageArea::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height= 50 * RTScalable::getScale(); - natural_height = 300 * RTScalable::getScale(); + minimum_height = RTScalable::scalePixelSize(50); + natural_height = RTScalable::scalePixelSize(300); } void ImageArea::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 100 * RTScalable::getScale(); - natural_width = 400 * RTScalable::getScale(); + minimum_width = RTScalable::scalePixelSize(100); + natural_width = RTScalable::scalePixelSize(400); } void ImageArea::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc index df9f632ab..72f68887f 100644 --- a/rtgui/indclippedpanel.cc +++ b/rtgui/indclippedpanel.cc @@ -21,31 +21,30 @@ #include "imagearea.h" #include "rtimage.h" -IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) +IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : + Fon("focusscreen-on"), + Foff("focusscreen-off"), + Son("contrastmask-on"), + Soff("contrastmask-off"), + iF(Gtk::manage(new RTImage(Foff, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iS(Gtk::manage(new RTImage(Soff, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + imageArea(ia) { - - iFon = new RTImage ("focusscreen-on.png"); - iFoff = new RTImage ("focusscreen-off.png"); - - // for previewSharpMask, needs to be replaced with different icons - iSon = new RTImage ("contrastmask-on.png"); - iSoff = new RTImage ("contrastmask-off.png"); - previewFocusMask = Gtk::manage (new Gtk::ToggleButton ()); previewFocusMask->set_relief(Gtk::RELIEF_NONE); previewFocusMask->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWFOCUSMASK")); - previewFocusMask->set_image(*iFoff); + previewFocusMask->set_image(*iF); previewSharpMask = Gtk::manage (new Gtk::ToggleButton ()); previewSharpMask->set_relief(Gtk::RELIEF_NONE); previewSharpMask->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWSHARPMASK")); - previewSharpMask->set_image(*iSoff); + previewSharpMask->set_image(*iS); Glib::ustring tt; indClippedH = Gtk::manage (new Gtk::ToggleButton ()); indClippedH->set_relief(Gtk::RELIEF_NONE); - indClippedH->add (*Gtk::manage (new RTImage ("warning-highlights.png"))); + indClippedH->add (*Gtk::manage (new RTImage ("warning-highlights", Gtk::ICON_SIZE_LARGE_TOOLBAR))); 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) { @@ -56,7 +55,7 @@ IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) indClippedS = Gtk::manage (new Gtk::ToggleButton ()); indClippedS->set_relief(Gtk::RELIEF_NONE); - indClippedS->add (*Gtk::manage (new RTImage ("warning-shadows.png"))); + indClippedS->add (*Gtk::manage (new RTImage ("warning-shadows", Gtk::ICON_SIZE_LARGE_TOOLBAR))); 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) { @@ -102,7 +101,7 @@ void IndicateClippedPanel::silentlyDisableSharpMask () { ConnectionBlocker conBlocker(connSharpMask); previewSharpMask->set_active(false); - previewSharpMask->set_image(*iSoff); + iS->set_from_icon_name(Soff); } @@ -141,8 +140,8 @@ void IndicateClippedPanel::buttonToggled (Gtk::ToggleButton* tb) } imageArea->sharpMaskSelected(previewSharpMask->get_active()); - previewFocusMask->set_image(previewFocusMask->get_active() ? *iFon : *iFoff); - previewSharpMask->set_image(previewSharpMask->get_active() ? *iSon : *iSoff); + iF->set_from_icon_name(previewFocusMask->get_active() ? Fon : Foff); + iS->set_from_icon_name(previewSharpMask->get_active() ? Son : Soff); connFocusMask.block(false); connSharpMask.block(false); @@ -158,10 +157,4 @@ void IndicateClippedPanel::buttonToggled (Gtk::ToggleButton* tb) } } -IndicateClippedPanel::~IndicateClippedPanel () -{ - delete iFon; - delete iFoff; - delete iSon; - delete iSoff; -} +IndicateClippedPanel::~IndicateClippedPanel () {} diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h index 6be0a6c40..aeeb14315 100644 --- a/rtgui/indclippedpanel.h +++ b/rtgui/indclippedpanel.h @@ -22,13 +22,19 @@ #include class ImageArea; +class RTImage; class IndicateClippedPanel : public Gtk::Box { protected: - Gtk::Image* iFon, *iFoff, *iSon, *iSoff; + const Glib::ustring Fon; + const Glib::ustring Foff; + const Glib::ustring Son; + const Glib::ustring Soff; + RTImage* const iF; + RTImage* const iS; Gtk::ToggleButton* previewSharpMask; Gtk::ToggleButton* previewFocusMask; Gtk::ToggleButton* indClippedH; diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 675da51c6..e2f9df35b 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -590,7 +590,7 @@ void Inspector::switchImage (const Glib::ustring &fullPath) bool Inspector::doSwitchImage() { Glib::ustring fullPath = next_image_path; - + // we first check the size of the list, it may have been changed in Preference if (images.size() > size_t(options.maxInspectorBuffers)) { // deleting the last entries @@ -688,14 +688,14 @@ Gtk::SizeRequestMode Inspector::get_request_mode_vfunc () const void Inspector::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height= 50 * RTScalable::getScale(); - natural_height = 300 * RTScalable::getScale(); + minimum_height = RTScalable::scalePixelSize(50); + natural_height = RTScalable::scalePixelSize(300); } void Inspector::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 50 * RTScalable::getScale(); - natural_width = 200 * RTScalable::getScale(); + minimum_width = RTScalable::scalePixelSize(50); + natural_width = RTScalable::scalePixelSize(200); } void Inspector::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc index 1134b36da..ac4d976b4 100644 --- a/rtgui/iptcpanel.cc +++ b/rtgui/iptcpanel.cc @@ -118,9 +118,9 @@ IPTCPanel::IPTCPanel () : setExpandAlignProperties(addKW, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); delKW = Gtk::manage( new Gtk::Button () ); setExpandAlignProperties(delKW, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image* addKWImg = Gtk::manage( new RTImage ("add-small.png") ); + Gtk::Image* const addKWImg = Gtk::manage( new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON) ); setExpandAlignProperties(addKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Image* delKWImg = Gtk::manage( new RTImage ("remove-small.png") ); + Gtk::Image* const delKWImg = Gtk::manage( new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON) ); setExpandAlignProperties(delKWImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); addKW->add (*addKWImg); delKW->add (*delKWImg); @@ -168,9 +168,9 @@ IPTCPanel::IPTCPanel () : setExpandAlignProperties(addSC, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); delSC = Gtk::manage( new Gtk::Button () ); setExpandAlignProperties(delSC, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); - Gtk::Image* addSCImg = Gtk::manage( new RTImage ("add-small.png") ); + Gtk::Image* const addSCImg = Gtk::manage( new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON) ); setExpandAlignProperties(addSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - Gtk::Image* delSCImg = Gtk::manage( new RTImage ("remove-small.png") ); + Gtk::Image* const delSCImg = Gtk::manage( new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON) ); setExpandAlignProperties(delSCImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); addSC->add (*addSCImg); delSC->add (*delSCImg); @@ -334,25 +334,25 @@ IPTCPanel::IPTCPanel () : reset = Gtk::manage( new Gtk::Button () ); // M("IPTCPANEL_RESET") reset->get_style_context()->add_class("Left"); - reset->set_image (*Gtk::manage(new RTImage ("undo.png", "redo.png"))); + reset->set_image (*Gtk::manage(new RTImage ("undo", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(reset, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); bbox->attach_next_to (*reset, Gtk::POS_LEFT, 1, 1); file = Gtk::manage( new Gtk::Button () ); // M("IPTCPANEL_EMBEDDED") file->get_style_context()->add_class("MiddleH"); - file->set_image (*Gtk::manage(new RTImage ("folder-open.png"))); + file->set_image (*Gtk::manage(new RTImage ("folder-open", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(file, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); bbox->attach_next_to (*file, Gtk::POS_RIGHT, 1, 1); copy = Gtk::manage( new Gtk::Button () ); copy->get_style_context()->add_class("MiddleH"); - copy->set_image (*Gtk::manage(new RTImage ("copy.png"))); + copy->set_image (*Gtk::manage(new RTImage ("copy", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(copy, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); bbox->attach_next_to (*copy, Gtk::POS_RIGHT, 1, 1); paste = Gtk::manage( new Gtk::Button () ); paste->get_style_context()->add_class("Right"); - paste->set_image (*Gtk::manage(new RTImage ("paste.png"))); + paste->set_image (*Gtk::manage(new RTImage ("paste", Gtk::ICON_SIZE_BUTTON))); setExpandAlignProperties(paste, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); bbox->attach_next_to (*paste, Gtk::POS_RIGHT, 1, 1); diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index bc3b806de..fc34fb53a 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -1,5 +1,5 @@ /** -*- C++ -*- - * + * * This file is part of RawTherapee. * * Copyright (c) 2017 Alberto Griggio @@ -43,6 +43,7 @@ #include "../rtengine/color.h" #include "options.h" #include "rtimage.h" +#include "rtscalable.h" using rtengine::Color; @@ -86,7 +87,7 @@ LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool isDragged(false), low_enabled(enable_low), ciexy_enabled(ciexy) - + { set_can_focus(false); // prevent moving the grid while you're moving a point add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK); @@ -120,7 +121,7 @@ void LabGridArea::setParams(double la, double lb, double ha, double hb, double g gre_y = rtengine::LIM(gy, lo, hi); whi_x = rtengine::LIM(wx, lo, hi); whi_y = rtengine::LIM(wy, lo, hi); - + queue_draw(); if (notify) { notifyListener(); @@ -200,7 +201,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) int width = allocation.get_width(); int height = allocation.get_height(); - int s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); cr->set_line_cap(Cairo::LINE_CAP_SQUARE); @@ -210,23 +211,24 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) cr->paint (); cr->set_operator (Cairo::OPERATOR_OVER); style->render_background(cr, - inset * s + padding.get_left() - s, - inset * s + padding.get_top() - s, - width - 2 * inset * s - padding.get_right() - padding.get_left() + 2 * s, - height - 2 * inset * s - padding.get_top() - padding.get_bottom() + 2 * s + (int)(inset * s + padding.get_left() - s + 0.5), + (int)(inset * s + padding.get_top() - s + 0.5), + (int)(width - 2 * inset * s - padding.get_right() - padding.get_left() + 2 * s + 0.5), + (int)(height - 2 * inset * s - padding.get_top() - padding.get_bottom() + 2 * s + 0.5) ); // drawing the cells - cr->translate(inset * s + padding.get_left(), inset * s + padding.get_top()); + cr->translate((int)(inset * s + padding.get_left() + 0.5), + (int)(inset * s + padding.get_top() + 0.5)); cr->set_antialias(Cairo::ANTIALIAS_NONE); - width -= 2 * inset * s + padding.get_right() + padding.get_left(); - height -= 2 * inset * s + padding.get_top() + padding.get_bottom(); + width -= (int)(2 * inset * s + 0.5) + padding.get_right() + padding.get_left(); + height -= (int)(2 * inset * s + 0.5) + padding.get_top() + padding.get_bottom(); // flip y: cr->translate(0, height); cr->scale(1., -1.); - if (! ciexy_enabled) {//draw cells for Labgrid + if (! ciexy_enabled) {//draw cells for Labgrid int cells = 8; float step = 12000.f / float(cells/2); double cellW = double(width) / double(cells); @@ -270,7 +272,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) // this graph is not accurate...I replace curve by polygon or parabolic float xa = 0.2653f / (0.7347f - 0.17f); float xb = -0.17f * xa; - //linear values + //linear values // float ax = (0.1f - 0.6f) / 0.08f; // float bx = 0.6f; // float ax0 = -0.1f / (0.17f - 0.08f); @@ -306,16 +308,16 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) // float y3 = axss * x + bxss; // float y4 = axsss * x + bxsss; // float y5 = bx4s; - float y6 = 22.52f * x * x - 7.652f * x + 0.65f;//parabolic passing in x=0.17 y=0 - x=0.1 y =0.11 - x=0 y= 0.65 + float y6 = 22.52f * x * x - 7.652f * x + 0.65f;//parabolic passing in x=0.17 y=0 - x=0.1 y =0.11 - x=0 y= 0.65 float y3 = -1.266666f * x * x -0.170002f * x + 0.859686f;//other parabolic for green passing in x=0.35 y=0.65 - x=0.20 y=0.775 - x=0.1 y=0.83 float y4 = -60.71428f * x * x + 6.821428f * x + 0.65f;//other parabolic x=0 y=0.65 - x=0.03 y=0.8 - x=0.07 y=0.83 //small difference in the connection of the 2 last parabolic - + Color::xyz2srgb(XX, YY, ZZ, R, G, B); //replace color by gray if(y < yr && x > 0.17f) { R = 0.7f; G = 0.7f; B = 0.7f; - } + } /* if(y < y0 && x <= 0.17f && x >= 0.08f) { R = 0.7f; G = 0.7f; B = 0.7f; @@ -327,7 +329,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) if(y < y6 && y < 0.65f && x < 0.17f) { R = 0.7f; G = 0.7f; B = 0.7f; } - + if(y > y2 && x > 0.35f) {//0.35 R = 0.7f; G = 0.7f; B = 0.7f; } @@ -396,7 +398,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) cr->line_to(width, 0.04545 * i * height); } - cr->stroke(); + cr->stroke(); //draw abciss and ordonate cr->set_line_width(1.f * double(s)); cr->set_source_rgb(0.4, 0., 0.); @@ -404,7 +406,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) cr->line_to(0.04545 * 2 * width, height); cr->move_to(0., 0.04545 * 2 * height ); cr->line_to(width, 0.04545 * 2 * height); - cr->stroke(); + cr->stroke(); //draw 0 and 1 with circle and lines cr->set_line_width(1.2f * double(s)); @@ -420,7 +422,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) cr->line_to(0.07 * width, 0.965 * height); cr->stroke(); - + } @@ -468,7 +470,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) bool LabGridArea::on_button_press_event(GdkEventButton *event) { if (event->button == 1) { - if (!ciexy_enabled) { + if (!ciexy_enabled) { if (event->type == GDK_2BUTTON_PRESS) { switch (litPoint) { case NONE: @@ -527,9 +529,9 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) State oldLitPoint = litPoint; - int s = RTScalable::getScale(); - int width = get_allocated_width() - 2 * inset * s - padding.get_right() - padding.get_left(); - int height = get_allocated_height() - 2 * inset * s - padding.get_top() - padding.get_bottom(); + const double s = RTScalable::scalePixelSize(1.); + int width = (int)(get_allocated_width() - 2 * inset * s - padding.get_right() - padding.get_left() + 0.5); + int height = (int)(get_allocated_height() - 2 * inset * s - padding.get_top() - padding.get_bottom() + 0.5); const float mouse_x = std::min(double(std::max(event->x - inset * s - padding.get_right(), 0.)), double(width)); const float mouse_y = std::min(double(std::max(get_allocated_height() - 1 - event->y - inset * s - padding.get_bottom(), 0.)), double(height)); const float ma = (2.f * mouse_x - width) / width; @@ -590,11 +592,11 @@ void LabGridArea::get_preferred_width_vfunc(int &minimum_width, int &natural_wid { Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled - int s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); int p = padding.get_left() + padding.get_right(); - minimum_width = 50 * s + p; - natural_width = 150 * s + p; // same as GRAPH_SIZE from mycurve.h + minimum_width = (int)(50 * s + p + 0.5); + natural_width = (int)(150 * s + p + 0.5); // same as GRAPH_SIZE from mycurve.h } @@ -643,7 +645,7 @@ LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_ Gtk::Button *reset = Gtk::manage(new Gtk::Button()); reset->set_tooltip_markup(M("ADJUSTER_RESET_TO_DEFAULT")); if(!ciexy) {//disabled for Cie xy - reset->add(*Gtk::manage(new RTImage("undo-small.png", "redo-small.png"))); + reset->add(*Gtk::manage(new RTImage("undo-small", Gtk::ICON_SIZE_BUTTON))); } reset->signal_button_release_event().connect(sigc::mem_fun(*this, &LabGrid::resetPressed)); @@ -662,5 +664,5 @@ LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_ bool LabGrid::resetPressed(GdkEventButton *event) { grid.reset(event->state & GDK_CONTROL_MASK); - return false; + return false; } diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 8bdbf6dd4..621f9c278 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -46,7 +46,7 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGE pack_start (*fill); autoCrop = Gtk::manage (new Gtk::Button (M("TP_LENSGEOM_AUTOCROP"))); - autoCrop->set_image (*Gtk::manage (new RTImage ("crop-auto-small.png"))); + autoCrop->set_image (*Gtk::manage (new RTImage ("crop-auto-small", Gtk::ICON_SIZE_BUTTON))); autoCrop->get_style_context()->add_class("independent"); pack_start (*autoCrop, Gtk::PACK_SHRINK, 2); diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 73fb0399b..e33fd314c 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -62,7 +62,7 @@ LensProfilePanel::LensProfilePanel() : lensfunCameras(Gtk::manage((new MyComboBox()))), lensfunLensesLbl(Gtk::manage((new Gtk::Label(M("EXIFFILTER_LENS"))))), lensfunLenses(Gtk::manage((new MyComboBox()))), - warning(Gtk::manage(new RTImage("warning.png"))), + warning(Gtk::manage(new RTImage("warning"))), ckbUseDist(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_GEOMETRIC"))))), ckbUseVign(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_VIGNETTING"))))), ckbUseCA(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_CA"))))) @@ -163,7 +163,7 @@ LensProfilePanel::LensProfilePanel() : // Attach grids: nodesFrame->add(*modesGrid); distFrame->add(*distGrid); - + pack_start(*nodesFrame, Gtk::PACK_EXPAND_WIDGET); pack_start(*distFrame, Gtk::PACK_EXPAND_WIDGET); @@ -257,7 +257,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa } - /* + /* if (!batchMode && !checkLensfunCanCorrect(true)) { if (corrLensfunAutoRB->get_active()) { corrOffRB->set_active(true); @@ -268,26 +268,26 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa if (!batchMode && corrLensfunManualRB->get_active() && !checkLensfunCanCorrect(false)) { corrOffRB->set_active(true); - } + } */ - + ckbUseDist->set_active(pp->lensProf.useDist); ckbUseVign->set_active(pp->lensProf.useVign); ckbUseCA->set_active(pp->lensProf.useCA); - + if (pedited) { corrUnchangedRB->set_active(!pedited->lensProf.lcMode); ckbUseDist->set_inconsistent(!pedited->lensProf.useDist); ckbUseVign->set_inconsistent(!pedited->lensProf.useVign); ckbUseCA->set_inconsistent(!pedited->lensProf.useCA); - + if (!pedited->lensProf.lfCameraMake || !pedited->lensProf.lfCameraModel) { setLensfunCamera("", ""); } if (!pedited->lensProf.lfLens) { setLensfunLens(""); } - + ckbUseDist->set_sensitive(true); ckbUseVign->set_sensitive(true); ckbUseCA->set_sensitive(true); @@ -295,7 +295,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa lcModeChanged = lcpFileChanged = useDistChanged = useVignChanged = useCAChanged = false; useLensfunChanged = lensfunAutoChanged = lensfunCameraChanged = lensfunLensChanged = false; - + updateLensfunWarning(); enableListener(); conUseDist.block(false); @@ -434,7 +434,7 @@ void LensProfilePanel::onUseCAChanged() void LensProfilePanel::setBatchMode(bool yes) { FoldableToolPanel::setBatchMode(yes); - + corrUnchangedRB->set_group(corrGroup); modesGrid->attach_next_to(*corrUnchangedRB, Gtk::POS_TOP, 3, 1); corrUnchangedRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrUnchangedRB)); @@ -498,7 +498,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) ckbUseCA->set_sensitive(false); mode = M("GENERAL_NONE"); - + } else if (rbChanged == corrLensfunAutoRB) { lcModeChanged = true; useLensfunChanged = true; @@ -511,7 +511,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) ckbUseVign->set_sensitive(true); ckbUseCA->set_sensitive(true); - + const bool disabled = disableListener(); if (batchMode) { setLensfunCamera("", ""); @@ -526,9 +526,9 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) if (disabled) { enableListener(); } - + mode = M("TP_LENSPROFILE_CORRECTION_AUTOMATCH"); - + } else if (rbChanged == corrLensfunManualRB) { lcModeChanged = true; useLensfunChanged = true; @@ -542,7 +542,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) ckbUseCA->set_sensitive(false); mode = M("TP_LENSPROFILE_CORRECTION_MANUAL"); - + } else if (rbChanged == corrLcpFileRB) { lcModeChanged = true; useLensfunChanged = true; @@ -552,7 +552,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) updateDisabled(true); mode = M("TP_LENSPROFILE_CORRECTION_LCPFILE"); - + } else if (rbChanged == corrUnchangedRB) { lcModeChanged = false; useLensfunChanged = false; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index bc72a8f35..ad035b81f 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -141,12 +141,12 @@ LocallabTool::LocallabTool(Gtk::Box* content, Glib::ustring toolName, Glib::ustr titleLabel->set_markup(Glib::ustring("") + escapeHtmlChars(UILabel) + Glib::ustring("")); titleLabel->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); titleBox->pack_start(*titleLabel, Gtk::PACK_EXPAND_WIDGET, 0); - + Gtk::EventBox* const removeEvBox = Gtk::manage(new Gtk::EventBox()); // Glue to manage mouse clicking event on remove image removeEvBox->set_can_focus(false); removeEvBox->set_above_child(false); // To have priority over expander title bar when mouse clicking on remove image removeEvBox->signal_button_release_event().connect(sigc::mem_fun(this, &LocallabTool::on_remove_change)); - RTImage* const removeImage = Gtk::manage(new RTImage("cancel-small.png")); + RTImage* const removeImage = Gtk::manage(new RTImage("cancel-small", Gtk::ICON_SIZE_BUTTON)); removeEvBox->add(*removeImage); titleBox->pack_end(*removeEvBox, Gtk::PACK_SHRINK, 1); if (needMode) { @@ -161,7 +161,7 @@ LocallabTool::LocallabTool(Gtk::Box* content, Glib::ustring toolName, Glib::ustr titleBox->pack_end(*separator, Gtk::PACK_SHRINK, 0); if (need100Percent) { - RTImage* const titleImage = Gtk::manage(new RTImage("one-to-one-small.png")); + RTImage* const titleImage = Gtk::manage(new RTImage("one-to-one-small", Gtk::ICON_SIZE_BUTTON)); titleImage->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); titleBox->pack_end(*titleImage, Gtk::PACK_SHRINK, 0); } @@ -490,7 +490,7 @@ LocallabColor::LocallabColor(): conthrcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTTHR"), 0.0, 100.0, 0.5, 0.))), gridmerFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LABGRIDMERG")))), labgridmerg(Gtk::manage(new LabGrid(EvLocallabLabGridmergValue, M("TP_LOCALLAB_LABGRID_VALUES"), false))), - merlucol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MERLUCOL"), 0.0, 100.0, 0.5, 32., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + merlucol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MERLUCOL"), 0.0, 100.0, 0.5, 32., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), expmaskcol(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWC")))), mergecolFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_MERGECOLFRA")))), showmaskcolMethod(Gtk::manage(new MyComboBoxText())), @@ -526,9 +526,9 @@ LocallabColor::LocallabColor(): LLmaskcolshapewav(static_cast(mask2CurveEditorGwav->addCurve(CT_Flat, "L(L)", nullptr, false, false))), csThresholdcol(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) { - + set_orientation(Gtk::ORIENTATION_VERTICAL); - + float R, G, B; std::vector six_shape; @@ -848,8 +848,8 @@ LocallabColor::LocallabColor(): // colBox3->pack_start(*invmaskc); exprecov->add(*colBox3, false); pack_start(*exprecov, false, false); - - + + ToolParamBlock* const gradcolBox = Gtk::manage(new ToolParamBlock()); gradcolBox->pack_start(*strcol); gradcolBox->pack_start(*strcolab); @@ -1541,7 +1541,7 @@ void LocallabColor::setDefaults(const rtengine::procparams::ProcParams* defParam lowthresc->setDefault((double)defSpot.lowthresc); higthresc->setDefault((double)defSpot.higthresc); decayc->setDefault((double)defSpot.decayc); - + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -1621,7 +1621,7 @@ void LocallabColor::adjusterChanged(Adjuster* a, double newval) } if (a == recothresc) { - + if (listener) { listener->panelChanged(Evlocallabrecothresc, recothresc->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -2117,7 +2117,7 @@ void LocallabColor::updateGUIToMode(const modeType new_type) if (enaColorMask->get_active()) { maskusablec->show(); maskunusablec->hide(); - + } else { maskusablec->hide(); maskunusablec->show(); @@ -2154,7 +2154,7 @@ void LocallabColor::updateGUIToMode(const modeType new_type) if (enaColorMask->get_active()) { maskusablec->show(); maskunusablec->hide(); - + } else { maskusablec->hide(); maskunusablec->show(); @@ -2371,7 +2371,7 @@ void LocallabColor::enaColorMaskChanged() maskusablec->hide(); maskunusablec->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enaColorMask->get_active()) { @@ -2570,7 +2570,7 @@ LocallabExposure::LocallabExposure(): fatdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATDETAIL"), -100., 300., 1., 0.))), norm(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EQUIL")))), fatlevel(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATLEVEL"), 0.5, 2.0, 0.01, 1.))), - fatanchor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 0.1, 100.0, 0.01, 50., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + fatanchor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 0.1, 100.0, 0.01, 50., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), gamex(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMC"), 0.5, 3.0, 0.05, 1.))), sensiex(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), structexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), @@ -2620,7 +2620,7 @@ LocallabExposure::LocallabExposure(): Lmaskexpshape(static_cast(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Exposure specific widgets @@ -3625,7 +3625,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) if (enaExpMask->get_active()) { maskusablee->show(); maskunusablee->hide(); - + } else { maskusablee->hide(); maskunusablee->show(); @@ -3637,7 +3637,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) // Specific Simple mode widgets are shown in Normal mode softradiusexp->hide(); blurexpde->hide(); - + if (!inversex->get_active()) { // Keep widget hidden when invers is toggled expgradexp->show(); softradiusexp->show(); @@ -3676,7 +3676,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) if (enaExpMask->get_active()) { maskusablee->show(); maskunusablee->hide(); - + } else { maskusablee->hide(); maskunusablee->show(); @@ -3822,7 +3822,7 @@ void LocallabExposure::enaExpMaskChanged() maskusablee->hide(); maskunusablee->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enaExpMask->get_active()) { @@ -3938,7 +3938,7 @@ void LocallabExposure::updateExposureGUI3() gamex->show(); } - + reparexp->show(); showmaskexpMethodinv->hide(); @@ -3982,7 +3982,7 @@ LocallabShadow::LocallabShadow(): shadows(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0))), s_tonalwidth(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 30))), sh_radius(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_RADIUS"), 0, 100, 1, 40))), - sensihs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt + sensihs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt blurSHde(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURDE"), 2, 100, 1, 5))), exprecovs(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusables(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), @@ -4017,10 +4017,10 @@ LocallabShadow::LocallabShadow(): LmaskSHshape(static_cast(mask2SHCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), fatSHFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_FATSHFRA")))), fatamountSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATAMOUNT"), 1., 100., 1., 1.))), - fatanchorSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 1., 100., 1., 50., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))) + fatanchorSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 1., 100., 1., 50., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Shadow highlight specific widgets @@ -4149,7 +4149,7 @@ LocallabShadow::LocallabShadow(): pack_start(*shadows); pack_start(*s_tonalwidth); pack_start(*sh_radius); - // pack_start(*sensihs);//unused here, but used for normalize_mean_dt + // pack_start(*sensihs);//unused here, but used for normalize_mean_dt pack_start(*blurSHde); ToolParamBlock* const shBox3 = Gtk::manage(new ToolParamBlock()); shBox3->pack_start(*maskusables, Gtk::PACK_SHRINK, 0); @@ -4266,7 +4266,7 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) decays->set_tooltip_text(M("TP_LOCALLAB_MASKDECAY_TOOLTIP")); lowthress->set_tooltip_text(M("TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP")); higthress->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP")); - + } else { exp->set_tooltip_text(""); @@ -4301,7 +4301,7 @@ void LocallabShadow::updateAdviceTooltips(const bool showTooltips) decays->set_tooltip_text(""); lowthress->set_tooltip_text(""); higthress->set_tooltip_text(""); - + } } @@ -4571,7 +4571,7 @@ void LocallabShadow::adjusterChanged(Adjuster* a, double newval) } if (a == recothress) { - + if (listener) { listener->panelChanged(Evlocallabrecothress, recothress->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -4791,7 +4791,7 @@ void LocallabShadow::convertParamToSimple() // radmaskSH->setValue(defSpot.radmaskSH); // chromaskSH->setValue(defSpot.chromaskSH); // LmaskSHshape->setCurve(defSpot.LmaskSHcurve); - + recothress->setValue(defSpot.recothress); lowthress->setValue(defSpot.lowthress); higthress->setValue(defSpot.higthresc); @@ -4834,7 +4834,7 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) if (enaSHMask->get_active()) { maskusables->show(); maskunusables->hide(); - + } else { maskusables->hide(); maskunusables->show(); @@ -4865,7 +4865,7 @@ void LocallabShadow::updateGUIToMode(const modeType new_type) if (enaSHMask->get_active()) { maskusables->show(); maskunusables->hide(); - + } else { maskusables->hide(); maskunusables->show(); @@ -4987,7 +4987,7 @@ void LocallabShadow::enaSHMaskChanged() maskusables->hide(); maskunusables->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enaSHMask->get_active()) { @@ -5075,12 +5075,12 @@ LocallabVibrance::LocallabVibrance(): saturated(Gtk::manage(new Adjuster(M("TP_VIBRANCE_SATURATED"), -100., 100., 1., 0.))), pastels(Gtk::manage(new Adjuster(M("TP_VIBRANCE_PASTELS"), -100., 100., 1., 0.))), vibgam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMC"), 0.5, 3., 0.05, 1.))), - warm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WARM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), + warm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WARM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small")), Gtk::manage(new RTImage("circle-orange-small"))))), 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))), protectSkins(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PROTECTSKINS")))), avoidColorShift(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_AVOIDCOLORSHIFT")))), pastSatTog(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PASTSATTOG")))), - sensiv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt + sensiv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt curveEditorGG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL"))), skinTonesCurve(static_cast(curveEditorGG->addCurve(CT_Diagonal, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES")))), exprecovv(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), @@ -5113,7 +5113,7 @@ LocallabVibrance::LocallabVibrance(): Lmaskvibshape(static_cast(mask2vibCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + float R, G, B; const LocallabParams::LocallabSpot defSpot; @@ -5237,7 +5237,7 @@ LocallabVibrance::LocallabVibrance(): pack_start(*protectSkins, Gtk::PACK_SHRINK, 0); pack_start(*avoidColorShift, Gtk::PACK_SHRINK, 0); pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0); - // pack_start(*sensiv, Gtk::PACK_SHRINK, 0);//unused here, but used for normalize_mean_dt + // pack_start(*sensiv, Gtk::PACK_SHRINK, 0);//unused here, but used for normalize_mean_dt pack_start(*curveEditorGG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor ToolParamBlock* const vibBox3 = Gtk::manage(new ToolParamBlock()); vibBox3->pack_start(*maskusablev, Gtk::PACK_SHRINK, 0); @@ -5583,7 +5583,7 @@ void LocallabVibrance::adjusterChanged(Adjuster* a, double newval) } if (a == recothresv) { - + if (listener) { listener->panelChanged(Evlocallabrecothresv, recothresv->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -5806,7 +5806,7 @@ void LocallabVibrance::convertParamToNormal() // Set hidden GUI widgets in Normal mode to default spot values saturated->setValue((double)defSpot.saturated); vibgam->setValue(defSpot.vibgam); - + psThreshold->setValue(defSpot.psthreshold); protectSkins->set_active(defSpot.protectskins); avoidColorShift->set_active(defSpot.avoidcolorshift); @@ -5900,7 +5900,7 @@ void LocallabVibrance::updateGUIToMode(const modeType new_type) if (enavibMask->get_active()) { maskusablev->show(); maskunusablev->hide(); - + } else { maskusablev->hide(); maskunusablev->show(); @@ -5930,7 +5930,7 @@ void LocallabVibrance::updateGUIToMode(const modeType new_type) if (enavibMask->get_active()) { maskusablev->show(); maskunusablev->hide(); - + } else { maskusablev->hide(); maskunusablev->show(); @@ -6027,7 +6027,7 @@ void LocallabVibrance::enavibMaskChanged() maskusablev->hide(); maskunusablev->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enavibMask->get_active()) { @@ -6069,7 +6069,7 @@ LocallabSoft::LocallabSoft(): sensisf(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 1, 100, 1, 30))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + // Parameter Soft light specific widgets softMethod->append(M("TP_LOCALLAB_SOFTM")); softMethod->append(M("TP_LOCALLAB_RETIM")); @@ -6493,9 +6493,9 @@ LocallabBlur::LocallabBlur(): noiselumf0(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINEZERO"), MINCHRO, MAXCHRO, 0.01, 0.))), noiselumf(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINE"), MINCHRO, MAXCHRO, 0.01, 0.))), noiselumf2(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINETWO"), MINCHRO, MAXCHRO, 0.01, 0.))), - noiselumc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), MINCHRO, MAXCHROCC, 0.01, 0.))),//unused here, but used for normalize_mean_dt + noiselumc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), MINCHRO, MAXCHROCC, 0.01, 0.))),//unused here, but used for normalize_mean_dt noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0., 100., 0.01, 50.))), - noiselequal(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELEQUAL"), -2, 10, 1, 7, Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))), + noiselequal(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELEQUAL"), -2, 10, 1, 7, Gtk::manage(new RTImage("circle-white-small")), Gtk::manage(new RTImage("circle-black-small"))))), noisegam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISEGAM"), 1.0, 5., 0.1, 1.))), LocalcurveEditorwavhue(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_WAVELET_DENOISEHUE"))), wavhue(static_cast(LocalcurveEditorwavhue->addCurve(CT_Flat, "", nullptr, false, true))), @@ -6504,7 +6504,7 @@ LocallabBlur::LocallabBlur(): noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0., 100., 0.01, 50.))), detailFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_DETAILFRA")))), detailthr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAILTHR"), 0, 100, 1, 50))), - adjblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJ"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-yellow-small.png")), Gtk::manage(new RTImage("circle-red-green-small.png"))))), + adjblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJ"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-red-green-small"))))), expdenoise3(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), recothresd(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKRECOTHRES"), 1., 2., 0.01, 1.))), lowthresd(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKLCTHRLOW2"), 1., 80., 0.5, 12.))), @@ -6553,7 +6553,7 @@ LocallabBlur::LocallabBlur(): csThresholdblur(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Blur, Noise & Denoise specific widgets @@ -6714,7 +6714,7 @@ LocallabBlur::LocallabBlur(): setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); + RTImage *resetImg = Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON)); setExpandAlignProperties (resetImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); neutral->set_image (*resetImg); neutral->set_tooltip_text (M ("TP_RETINEX_NEUTRAL_TIP")); @@ -6842,7 +6842,7 @@ LocallabBlur::LocallabBlur(): // wavBox->pack_start(*noiselumf0); // wavBox->pack_start(*noiselumf); // wavBox->pack_start(*noiselumf2); - // wavBox->pack_start(*noiselumc);//unused here, but used for normalize_mean_dt + // wavBox->pack_start(*noiselumc);//unused here, but used for normalize_mean_dt wavBox->pack_start(*noiselumdetail); wavBox->pack_start(*noiselequal); wavBox->pack_start(*noisegam); @@ -6862,7 +6862,7 @@ LocallabBlur::LocallabBlur(): wavBox->pack_start(*detailFrame); denoisebox->pack_start(*sensiden); denoisebox->pack_start(*reparden); - + ToolParamBlock* const nlbox = Gtk::manage(new ToolParamBlock()); nlbox->pack_start(*nlstr); nlbox->pack_start(*nldet); @@ -6871,7 +6871,7 @@ LocallabBlur::LocallabBlur(): nlbox->pack_start(*nlrad); nlFrame->add(*nlbox); wavBox->pack_start(*nlFrame); - + wavBox->pack_start(*noisechrof); wavBox->pack_start(*noisechroc); wavBox->pack_start(*noisechrodetail); @@ -7026,7 +7026,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) higthres->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRES_TOOLTIP")); decayd->set_tooltip_text(M("TP_LOCALLAB_MASKDECAY_TOOLTIP")); } else { - + expblnoise->set_tooltip_markup(""); radius->set_tooltip_text(""); strength->set_tooltip_text(""); @@ -7099,7 +7099,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) } void LocallabBlur::neutral_pressed () -{ +{ const LocallabParams::LocallabSpot defSpot; lnoiselow->setValue(defSpot.lnoiselow); levelthr->setValue(defSpot.levelthr); @@ -7135,7 +7135,7 @@ void LocallabBlur::neutral_pressed () recothres->setValue(defSpot.recothres); lowthres->setValue(defSpot.lowthres); higthres->setValue(defSpot.higthres); - + } @@ -7303,7 +7303,7 @@ void LocallabBlur::read(const rtengine::procparams::ProcParams* pp, const Params nlrad->setValue((double)spot.nlrad); nlgam->setValue((double)spot.nlgam); sensiden->setValue((double)spot.sensiden); - + if (spot.showmaskblMethodtyp == "blur") { showmaskblMethodtyp ->set_active(0); } else if (spot.showmaskblMethodtyp == "nois") { @@ -7477,7 +7477,7 @@ void LocallabBlur::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped spot.Lmaskblcurve = Lmaskblshape->getCurve(); spot.LLmaskblcurvewav = LLmaskblshapewav->getCurve(); spot.csthresholdblur = csThresholdblur->getValue(); - + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -7621,7 +7621,7 @@ void LocallabBlur::adjusterChanged(Adjuster* a, double newval) showmaskblMethodtyp->set_active(2); } } - + if (listener) { listener->panelChanged(Evlocallabrecothres, recothres->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -7648,7 +7648,7 @@ void LocallabBlur::adjusterChanged(Adjuster* a, double newval) showmaskblMethodtyp->set_active(2); } } - + if (listener) { listener->panelChanged(Evlocallabrecothresd, recothresd->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -8038,7 +8038,7 @@ void LocallabBlur::convertParamToNormal() lnoiselow->setValue(defSpot.lnoiselow); nlrad->setValue(defSpot.nlrad); noisegam->setValue(defSpot.noisegam); - + // Enable all listeners enableListener(); } @@ -8094,7 +8094,7 @@ void LocallabBlur::convertParamToSimple() nlrad->setValue(defSpot.nlrad); nlgam->setValue(defSpot.nlgam); noisegam->setValue(defSpot.noisegam); - + // Enable all listeners enableListener(); } @@ -8175,7 +8175,7 @@ void LocallabBlur::updateGUIToMode(const modeType new_type) showmaskblMethodtyp->set_active(2); } } - + if (enablMask->get_active()) { maskusable->show(); maskunusable->hide(); @@ -8183,7 +8183,7 @@ void LocallabBlur::updateGUIToMode(const modeType new_type) maskunusable2->hide(); maskusable3->show(); maskunusable3->hide(); - + } else { maskusable->hide(); maskunusable->show(); @@ -8248,7 +8248,7 @@ void LocallabBlur::updateGUIToMode(const modeType new_type) showmaskblMethodtyp->set_active(2); } } - + if (enablMask->get_active()) { maskusable->show(); maskunusable->hide(); @@ -8264,7 +8264,7 @@ void LocallabBlur::updateGUIToMode(const modeType new_type) maskusable3->show(); maskunusable3->hide(); } - + } } @@ -8388,7 +8388,7 @@ void LocallabBlur::invblChanged() } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (invbl->get_active()) { @@ -8560,7 +8560,7 @@ void LocallabBlur::updateBlurGUI() guidbl->setValue(defSpot.guidbl); } - + const int mode = complexity->get_active_row_number(); if (blMethod->get_active_row_number() == 0) { diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 3358a61ef..95e84d847 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -128,7 +128,7 @@ LocallabTone::LocallabTone(): estop(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ESTOP"), 0.1, 4., 0.01, 1.4))), scaltm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SCALTM"), 0.1, 10.0, 0.01, 1.0))), rewei(Gtk::manage(new Adjuster(M("TP_LOCALLAB_REWEI"), 0, 3, 1, 0))), - softradiustm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.1, 0.))),//unused here, but used for normalize_mean_dt + softradiustm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.1, 0.))),//unused here, but used for normalize_mean_dt sensitm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), exprecovt(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusablet(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), @@ -156,7 +156,7 @@ LocallabTone::LocallabTone(): Lmasktmshape(static_cast(mask2tmCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Tone Mapping specific widgets @@ -253,7 +253,7 @@ LocallabTone::LocallabTone(): pack_start(*estop); pack_start(*scaltm); pack_start(*rewei); - // pack_start(*softradiustm); //unused here, but used for normalize_mean_dt + // pack_start(*softradiustm); //unused here, but used for normalize_mean_dt // pack_start(*sensitm); ToolParamBlock* const tmBox3 = Gtk::manage(new ToolParamBlock()); tmBox3->pack_start(*maskusablet, Gtk::PACK_SHRINK, 0); @@ -265,7 +265,7 @@ LocallabTone::LocallabTone(): // colBox3->pack_start(*invmaskc); exprecovt->add(*tmBox3, false); pack_start(*exprecovt, false, false); - + ToolParamBlock* const masktmBox = Gtk::manage(new ToolParamBlock()); masktmBox->pack_start(*showmasktmMethod, Gtk::PACK_SHRINK, 4); masktmBox->pack_start(*enatmMask, Gtk::PACK_SHRINK, 0); @@ -673,7 +673,7 @@ void LocallabTone::updateGUIToMode(const modeType new_type) if (enatmMask->get_active()) { maskusablet->show(); maskunusablet->hide(); - + } else { maskusablet->hide(); maskunusablet->show(); @@ -695,7 +695,7 @@ void LocallabTone::updateGUIToMode(const modeType new_type) if (enatmMask->get_active()) { maskusablet->show(); maskunusablet->hide(); - + } else { maskusablet->hide(); maskunusablet->show(); @@ -758,7 +758,7 @@ void LocallabTone::enatmMaskChanged() maskusablet->hide(); maskunusablet->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enatmMask->get_active()) { @@ -849,7 +849,7 @@ LocallabRetinex::LocallabRetinex(): inversret(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Retinex specific widgets @@ -1530,7 +1530,7 @@ void LocallabRetinex::adjusterChanged(Adjuster* a, double newval) } if (a == recothresr) { - + if (listener) { listener->panelChanged(Evlocallabrecothresr, recothresr->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -1740,7 +1740,7 @@ void LocallabRetinex::convertParamToSimple() higthresr->setValue(defSpot.higthresr); decayr->setValue(defSpot.decayr); enableListener(); - + } void LocallabRetinex::updateGUIToMode(const modeType new_type) @@ -1778,7 +1778,7 @@ void LocallabRetinex::updateGUIToMode(const modeType new_type) if (enaretiMask->get_active()) { maskusabler->show(); maskunusabler->hide(); - + } else { maskusabler->hide(); maskunusabler->show(); @@ -1882,7 +1882,7 @@ void LocallabRetinex::enaretiMaskChanged() maskusabler->hide(); maskunusabler->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enaretiMask->get_active()) { @@ -1994,7 +1994,7 @@ LocallabSharp::LocallabSharp(): showmasksharMethod(Gtk::manage(new MyComboBoxText())) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + // Parameter Sharpening specific widgets sharcontrast->setAdjusterListener(this); @@ -2412,7 +2412,7 @@ LocallabContrast::LocallabContrast(): expcontrastpyr2(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), wavcont(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_CONTFRA")))), sigma(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMAWAV"), 0.2, 2.5, 0.01, 1.))), - offset(Gtk::manage(new Adjuster(M("TP_LOCALLAB_OFFSETWAV"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + offset(Gtk::manage(new Adjuster(M("TP_LOCALLAB_OFFSETWAV"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), chromalev(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMALEV"), 0.1, 5., 0.1, 1.))), LocalcurveEditorwavcon(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVCON"))), wavshapecon(static_cast(LocalcurveEditorwavcon->addCurve(CT_Flat, "", nullptr, false, false))), @@ -2424,7 +2424,7 @@ LocallabContrast::LocallabContrast(): residcomp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_RESIDCOMP"), -1., 1., 0.01, 0.))), wavcomp(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_COMPFRA")))), sigmadc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMAWAV"), 0.2, 3., 0.01, 1.))), - deltad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DELTAD"), -3., 3., 0.1, 0.))),//, Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + deltad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DELTAD"), -3., 3., 0.1, 0.))),//, Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), LocalcurveEditorwavcomp(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVCOMP"))), wavshapecomp(static_cast(LocalcurveEditorwavcomp->addCurve(CT_Flat, "", nullptr, false, false))), fatres(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATRES"), 0., 100., 1., 0.))), @@ -2452,7 +2452,7 @@ LocallabContrast::LocallabContrast(): Lmasklcshape(static_cast(mask2lcCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Local contrast specific widgets @@ -2636,7 +2636,7 @@ LocallabContrast::LocallabContrast(): TittleVBox2->pack_start(*LCTitleHBox2, Gtk::PACK_SHRINK); TittleVBox2->pack_start(*LCTitleHBox22, Gtk::PACK_SHRINK); expcontrastpyr2->setLabel(TittleVBox2); - + setExpandAlignProperties(expcontrastpyr2, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); wavcontConn = wavcont->signal_toggled().connect(sigc::mem_fun(*this, &LocallabContrast::wavcontChanged)); @@ -2841,7 +2841,7 @@ LocallabContrast::LocallabContrast(): blurlevelFrame->add(*blurlevcontBox); blurcontBox->pack_start(*blurlevelFrame); expcontrastpyr->add(*blurcontBox, false); - pack_start(*gamlc); + pack_start(*gamlc); pack_start(*expcontrastpyr); ToolParamBlock* const blurcontBox2 = Gtk::manage(new ToolParamBlock()); Gtk::Frame* const contFrame2 = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_CONTFRA"))); @@ -2981,7 +2981,7 @@ void LocallabContrast::updateAdviceTooltips(const bool showTooltips) threswav->set_tooltip_text(M("TP_LOCALLAB_WAT_BALTHRES_TOOLTIP")); residcomp->set_tooltip_text(M("TP_LOCALLAB_WAT_RESIDCOMP_TOOLTIP")); - + expresidpyr->set_tooltip_text(M("TP_LOCALLAB_WAT_EXPRESID_TOOLTIP")); expcontrastpyr->set_tooltip_text(M("TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP")); wavgradl->set_tooltip_text(M("TP_LOCALLAB_WAVGRAD_TOOLTIP")); @@ -3767,7 +3767,7 @@ void LocallabContrast::adjusterChanged(Adjuster* a, double newval) } if (a == recothresw) { - + if (listener) { listener->panelChanged(Evlocallabrecothresw, recothresw->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -4025,7 +4025,7 @@ void LocallabContrast::convertParamToSimple() lowthresw->setValue(defSpot.lowthresw); higthresw->setValue(defSpot.higthresw); decayw->setValue(defSpot.decayw); - + enableListener(); // Update GUI based on converted widget parameters: @@ -4066,7 +4066,7 @@ void LocallabContrast::updateGUIToMode(const modeType new_type) if (enalcMask->get_active()) { maskusablew->show(); maskunusablew->hide(); - + } else { maskusablew->hide(); maskunusablew->show(); @@ -4096,12 +4096,12 @@ void LocallabContrast::updateGUIToMode(const modeType new_type) if (enalcMask->get_active()) { maskusablew->show(); maskunusablew->hide(); - + } else { maskusablew->hide(); maskunusablew->show(); } - + } } @@ -4335,7 +4335,7 @@ void LocallabContrast::enalcMaskChanged() maskusablew->hide(); maskunusablew->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enalcMask->get_active()) { @@ -4474,7 +4474,7 @@ LocallabCBDL::LocallabCBDL(): lumacontrastPlusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS")))) { set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter CBDL specific widgets @@ -4911,7 +4911,7 @@ void LocallabCBDL::adjusterChanged(Adjuster* a, double newval) } if (a == recothrescb) { - + if (listener) { listener->panelChanged(Evlocallabrecothrescb, recothrescb->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -5100,7 +5100,7 @@ void LocallabCBDL::updateGUIToMode(const modeType new_type) if (enacbMask->get_active()) { maskusablecb->show(); maskunusablecb->hide(); - + } else { maskusablecb->hide(); maskunusablecb->show(); @@ -5118,7 +5118,7 @@ void LocallabCBDL::updateGUIToMode(const modeType new_type) if (enacbMask->get_active()) { maskusablecb->show(); maskunusablecb->hide(); - + } else { maskusablecb->hide(); maskunusablecb->show(); @@ -5166,7 +5166,7 @@ void LocallabCBDL::enacbMaskChanged() maskusablecb->hide(); maskunusablecb->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enacbMask->get_active()) { @@ -5234,7 +5234,7 @@ LocallabLog::LocallabLog(): log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 4.0, 80.0, 0.1, 18.0))), detail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 1., 0.01, 0.6))), - catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), + catad(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small")), Gtk::manage(new RTImage("circle-orange-small"))))), lightl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTL"), -100., 100., 0.5, 0.))), lightq(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTQ"), -100., 100., 0.5, 0.))), contl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTL"), -100., 100., 0.5, 0.))), @@ -5249,7 +5249,7 @@ LocallabLog::LocallabLog(): targabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), surround(Gtk::manage (new MyComboBoxText ())), surrHBox(Gtk::manage(new Gtk::Box())), - baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 3., 0.05, 2.))),//, Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 3., 0.05, 2.))),//, Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), exprecovl(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusablel(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), maskunusablel(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), @@ -5275,11 +5275,11 @@ LocallabLog::LocallabLog(): chromaskL(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMASKCOL"), -100.0, 100.0, 0.1, 0.))), mask2CurveEditorL(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), LmaskshapeL(static_cast(mask2CurveEditorL->addCurve(CT_Diagonal, "L(L)"))) - - + + { set_orientation(Gtk::ORIENTATION_VERTICAL); - + // Parameter Log encoding specific widgets autoconn = autocompute->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::autocomputeToggled)); const LocallabParams::LocallabSpot defSpot; @@ -5350,7 +5350,7 @@ LocallabLog::LocallabLog(): strlog->setAdjusterListener(this); anglog->setAdjusterListener(this); - + surHBox->set_spacing (2); surHBox->set_tooltip_markup (M ("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); Gtk::Label* surLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); @@ -5457,11 +5457,11 @@ LocallabLog::LocallabLog(): logP11Box->pack_start(*colorfl); expL->add(*logP11Box, false); logP1Box->pack_start(*expL, false, false); - + // logP1Box->pack_start(*CurveEditorL, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor log1Frame->add(*logP1Box); pack_start(*log1Frame); - log2Frame->set_label_align(0.025, 0.5); + log2Frame->set_label_align(0.025, 0.5); ToolParamBlock* const logP2Box = Gtk::manage(new ToolParamBlock()); logP2Box->pack_start(*targetGray); logP2Box->pack_start(*targabs); @@ -5476,7 +5476,7 @@ LocallabLog::LocallabLog(): logBox3->pack_start(*decayl); // colBox3->pack_start(*invmaskc); exprecovl->add(*logBox3, false); - + ToolParamBlock* const logP3Box = Gtk::manage(new ToolParamBlock()); logP3Box->pack_start(*showmaskLMethod, Gtk::PACK_SHRINK, 4); logP3Box->pack_start(*enaLMask, Gtk::PACK_SHRINK, 0); @@ -5491,11 +5491,11 @@ LocallabLog::LocallabLog(): log2Frame->add(*logP2Box); pack_start(*log2Frame); pack_start(*exprecovl, false, false); - + // pack_start(*baselog); // pack_start(*sensilog); pack_start(*expmaskL, false, false); - + // Gtk::Frame* const gradlogFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA"))); gradlogFrame->set_label_align(0.025, 0.5); ToolParamBlock* const gradlogBox = Gtk::manage(new ToolParamBlock()); @@ -5510,7 +5510,7 @@ LocallabLog::~LocallabLog() delete maskCurveEditorL; delete mask2CurveEditorL; delete CurveEditorL; - + } void LocallabLog::setDefaultExpanderVisibility() @@ -5549,8 +5549,8 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) contq->set_tooltip_text(M("TP_LOCALLAB_LOGCONTQ_TOOLTIP")); contthres->set_tooltip_text(M("TP_LOCALLAB_LOGCONTTHRES_TOOLTIP")); colorfl->set_tooltip_text(M("TP_LOCALLAB_LOGCOLORF_TOOLTIP")); - lightl->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTL_TOOLTIP")); - lightq->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTQ_TOOLTIP")); + lightl->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTL_TOOLTIP")); + lightq->set_tooltip_text(M("TP_LOCALLAB_LOGLIGHTQ_TOOLTIP")); saturl->set_tooltip_text(M("TP_LOCALLAB_LOGSATURL_TOOLTIP")); chroml->set_tooltip_text(M("TP_COLORAPP_CHROMA_TOOLTIP")); detail->set_tooltip_text(M("TP_LOCALLAB_LOGDETAIL_TOOLTIP")); @@ -5747,7 +5747,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE chromaskL->setValue(spot.chromaskL); LmaskshapeL->setCurve(spot.LmaskcurveL); - + } // Enable all listeners @@ -5831,7 +5831,7 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi } else if (surround->get_active_row_number() == 3) { spot.surround = "ExtremelyDark"; } - + } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -5847,7 +5847,7 @@ void LocallabLog::enaLMaskChanged() maskusablel->hide(); maskunusablel->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enaLMask->get_active()) { @@ -5917,12 +5917,12 @@ void LocallabLog::updateGUIToMode(const modeType new_type) if (enaLMask->get_active()) { maskusablel->show(); maskunusablel->hide(); - + } else { maskusablel->hide(); maskunusablel->show(); } - + exprecovl->show(); decayl->hide(); @@ -5951,7 +5951,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) if (enaLMask->get_active()) { maskusablel->show(); maskunusablel->hide(); - + } else { maskusablel->hide(); maskunusablel->show(); @@ -6242,7 +6242,7 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } if (a == recothresl) { - + if (listener) { listener->panelChanged(Evlocallabrecothresl, recothresl->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -6291,7 +6291,7 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) anglog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); } } - + if (a == blendmaskL) { if (listener) { listener->panelChanged(EvLocallabblendmaskL, @@ -6313,7 +6313,7 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } - + } } @@ -6403,7 +6403,7 @@ void LocallabLog::ciecamChanged() targabs->set_sensitive(true); catad->set_sensitive(true); surrHBox->set_sensitive(true); - + sourceabs->show(); targabs->show(); catad->show(); @@ -6515,7 +6515,7 @@ void LocallabLog::updateLogGUI2() void LocallabLog::updateLogGUI() { const int mode = complexity->get_active_row_number(); - + if (autocompute->get_active()) { blackEv->set_sensitive(false); whiteEv->set_sensitive(false); @@ -6538,7 +6538,7 @@ void LocallabLog::updateLogGUI() if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode exprecovl->show(); } - + } @@ -6583,9 +6583,9 @@ LocallabMask::LocallabMask(): str_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2., 2., 0.05, 0.))), ang_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180., 180., 0.1, 0.))) { - + set_orientation(Gtk::ORIENTATION_VERTICAL); - + const LocallabParams::LocallabSpot defSpot; // Parameter Mask common specific widgets @@ -7281,7 +7281,7 @@ void LocallabMask::updateGUIToMode(const modeType new_type) csThresholdmask->show(); gradFramemask->show(); } - + } void LocallabMask::updateMaskBackground(const double normChromar, const double normLumar, const double normHuer, const double normHuerjz) @@ -7446,14 +7446,14 @@ Locallabcie::Locallabcie(): sigmoidFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGFRA")))), sigq(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGFRA")))), sigmoidldacie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDLAMBDA"), 0.0, 1., 0.01, 0.5))), - sigmoidthcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + sigmoidthcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), sigmoidblcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDBL"), 0.5, 1.5, 0.01, 1.))), sigmoidqjcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGMOIDQJ")))), logcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LOGCIE")))), sigmoidjzFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGJZFRA")))), sigjz(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGJZFRA")))), sigmoidldajzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDLAMBDA"), 0., 1.0, 0.01, 0.5))), - sigmoidthjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + sigmoidthjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), sigmoidbljzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDBL"), 0.5, 1.5, 0.01, 1.))), colorflcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCOLORFL"), -100., 100., 0.5, 0.))), saturlcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), @@ -7486,7 +7486,7 @@ Locallabcie::Locallabcie(): thrhjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZTHRHCIE"), 40., 150., 0.5, 60.))), chjzcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JZCH")))), strsoftjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZSTRSOFTCIE"), 0, 100., 0.5, 100.))), - + /* ciezFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_ZCAMFRA")))), @@ -7498,13 +7498,13 @@ Locallabcie::Locallabcie(): colorflzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCOLORFL"), -100., 100., 0.5, 0.))), saturzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), chromzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROML"), -100., 100., 0.5, 0.))), -*/ +*/ expLcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_CIETOOLEXP")))), cie2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGraycie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), targabscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), detailcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 100., 0.1, 0.))), - catadcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-orange-small.png"))))), + catadcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small")), Gtk::manage(new RTImage("circle-orange-small"))))), surroundcie(Gtk::manage (new MyComboBoxText ())), surrHBoxcie(Gtk::manage(new Gtk::Box())), exprecovcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), @@ -7530,11 +7530,11 @@ Locallabcie::Locallabcie(): slomaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOMASKCOL"), 0.0, 15.0, 0.1, 0.))), mask2cieCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), Lmaskcieshape(static_cast(mask2cieCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) - - + + { set_orientation(Gtk::ORIENTATION_VERTICAL); - + // Parameter Ciecam specific widgets const LocallabParams::LocallabSpot defSpot; reparcie->setAdjusterListener(this); @@ -7617,12 +7617,12 @@ Locallabcie::Locallabcie(): sigmoidFrame->set_label_widget(*sigq); ToolParamBlock* const sigBox = Gtk::manage(new ToolParamBlock()); Gtk::Separator* const separatorsig = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - + sigBox->pack_start(*sigmoidldacie); sigBox->pack_start(*sigmoidthcie); sigBox->pack_start(*sigmoidblcie); sigBox->pack_start(*sigmoidqjcie); - sigBox->pack_start(*separatorsig); + sigBox->pack_start(*separatorsig); sigBox->pack_start(*logcie); sigmoidFrame->add(*sigBox); cieFBox->pack_start(*sigmoidFrame); @@ -7636,10 +7636,10 @@ Locallabcie::Locallabcie(): sigjzBox->pack_start(*sigmoidbljzcie); sigjzBox->pack_start(*forcebw); sigmoidjzFrame->add(*sigjzBox); - + // jzBox->pack_start(*sigmoidjzFrame); cieFBox->pack_start(*sigmoidjzFrame); - + cieFBox->pack_start (*surHBoxcie); cieFrame->add(*cieFBox); pack_start(*cieFrame); @@ -7734,7 +7734,7 @@ Locallabcie::Locallabcie(): jz3CurveEditorG->curveListComplete(); - + jzFrame->set_label_align(0.025, 0.5); ToolParamBlock* const jzBox = Gtk::manage(new ToolParamBlock()); jzBox->pack_start(*qtoj); @@ -7752,7 +7752,7 @@ Locallabcie::Locallabcie(): ciePzcolorBox->pack_start(*huejzcie); czcolorFrame->add(*ciePzcolorBox); jzBox->pack_start(*czcolorFrame); - + jzBox->pack_start(*jz1CurveEditorG, Gtk::PACK_SHRINK, 4); HFramejz->set_label_align(0.025, 0.5); ToolParamBlock* const jzHHBox = Gtk::manage(new ToolParamBlock()); @@ -7763,7 +7763,7 @@ Locallabcie::Locallabcie(): jzHBox->pack_start(*thrhjzcie); JzHFramejz->add(*jzHBox); jzHHBox->pack_start(*JzHFramejz); - + jzHHBox->pack_start(*jz3CurveEditorG, Gtk::PACK_SHRINK, 4); // jzBox->pack_start(*adapjzcie); jzHHBox->pack_start(*softjzcie); HFramejz->add(*jzHHBox); @@ -7776,9 +7776,9 @@ Locallabcie::Locallabcie(): sigjzBox->pack_start(*sigmoidbljzcie); sigjzBox->pack_start(*jabcie); sigmoidjzFrame->add(*sigjzBox); - + // jzBox->pack_start(*sigmoidjzFrame); - */ + */ jzshFrame->set_label_align(0.025, 0.5); ToolParamBlock* const jzshBox = Gtk::manage(new ToolParamBlock()); jzshBox->pack_start(*hljzcie); @@ -7812,7 +7812,7 @@ Locallabcie::Locallabcie(): clarilresjz->setAdjusterListener(this); claricresjz->setAdjusterListener(this); clarisoftjz->setAdjusterListener(this); - + clariFramejz->set_label_align(0.025, 0.5); ToolParamBlock* const coBox3jz = Gtk::manage(new ToolParamBlock()); coBox3jz->pack_start(*clarilresjz); @@ -7821,13 +7821,13 @@ Locallabcie::Locallabcie(): clariFramejz->add(*coBox3jz); coBox2jz->pack_start(*clariFramejz); expwavjz->add(*coBox2jz, false); - + jzBox->pack_start(*expwavjz, false, false); jzallBox->add(*jzBox); expjz->add(*jzallBox, false); - + jabcieConn = jabcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::jabcieChanged)); AutograycieConn = Autograycie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::AutograycieChanged)); sigmoidqjcieconn = sigmoidqjcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigmoidqjcieChanged)); @@ -7876,7 +7876,7 @@ Locallabcie::Locallabcie(): shapecie2->setBottomBarColorProvider (this, 1); shapecie2->setLeftBarColorProvider (this, 1); shapecie2->setRangeDefaultMilestones (0.05, 0.2, 0.58); - + std::vector shape2Milestones; // float R, G, B; @@ -7890,7 +7890,7 @@ Locallabcie::Locallabcie(): shapecie2->setLeftBarBgGradient (shape2Milestones); shapecie2->setRangeDefaultMilestones (0.05, 0.2, 0.58); - + cieCurveEditorG2->curveListComplete(); @@ -8006,7 +8006,7 @@ Locallabcie::Locallabcie(): /* sigmoidFrame->set_label_align(0.025, 0.5); ToolParamBlock* const sigBox = Gtk::manage(new ToolParamBlock()); - + sigBox->pack_start(*sigmoidldacie); sigBox->pack_start(*sigmoidthcie); sigBox->pack_start(*sigmoidblcie); @@ -8022,9 +8022,9 @@ Locallabcie::Locallabcie(): // cie1Frame->add(*cieP1Box); // expcam16->pack_start(*cie1Frame); expcam16->add(*cieP1Box, false); - + pack_start(*expcam16, false, false); - + pack_start(*expjz, false, false); /* ciezFrame->set_label_align(0.025, 0.5); @@ -8040,8 +8040,8 @@ Locallabcie::Locallabcie(): ciezFrame->add(*ciePzBox); pack_start(*ciezFrame); */ - - cie2Frame->set_label_align(0.025, 0.5); + + cie2Frame->set_label_align(0.025, 0.5); ToolParamBlock* const cieP2Box = Gtk::manage(new ToolParamBlock()); cieP2Box->pack_start(*targetGraycie); cieP2Box->pack_start(*targabscie); @@ -8049,7 +8049,7 @@ Locallabcie::Locallabcie(): cieP2Box->pack_start(*surrHBoxcie); // cieP2Box->pack_start(*detailcie); // cieP2Box->pack_start(*jabcie); - + cie2Frame->add(*cieP2Box); pack_start(*cie2Frame); @@ -8070,7 +8070,7 @@ Locallabcie::Locallabcie(): showmaskcieMethod->set_active(0); showmaskcieMethod->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKCOL_TOOLTIP")); showmaskcieMethodConn = showmaskcieMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::showmaskcieMethodChanged)); - + enacieMaskConn = enacieMask->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::enacieMaskChanged)); maskcieCurveEditorG->setCurveListener(this); @@ -8127,8 +8127,8 @@ Locallabcie::Locallabcie(): maskcieBox->pack_start(*mask2cieCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor expmaskcie->add(*maskcieBox, false); pack_start(*expmaskcie, false, false); - - + + } Locallabcie::~Locallabcie() @@ -8180,7 +8180,7 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) cieFrame->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); PQFrame->set_tooltip_text(M("TP_LOCALLAB_JZPQFRA_TOOLTIP")); qtoj->set_tooltip_text(M("TP_LOCALLAB_JZQTOJ_TOOLTIP")); - logcie->set_tooltip_text(M("TP_LOCALLAB_LOGCIE_TOOLTIP")); + logcie->set_tooltip_text(M("TP_LOCALLAB_LOGCIE_TOOLTIP")); modecam->set_tooltip_text(M("TP_LOCALLAB_JZMODECAM_TOOLTIP")); adapjzcie->set_tooltip_text(M("TP_LOCALLAB_JABADAP_TOOLTIP")); jz100->set_tooltip_text(M("TP_LOCALLAB_JZ100_TOOLTIP")); @@ -8364,7 +8364,7 @@ void Locallabcie::enacieMaskChanged() maskusablecie->hide(); maskunusablecie->show(); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (enacieMask->get_active()) { @@ -8430,7 +8430,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE } else if (spot.toneMethodcie2 == "thrc") { toneMethodcie2->set_active(2); } - + Autograycie->set_active(spot.Autograycie); forcejz->set_active(spot.forcejz); forcebw->set_active(spot.forcebw); @@ -8447,7 +8447,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE jabcie->set_active(spot.jabcie); jabcieChanged(); modecamChanged(); - + if(logcie->get_active()) { sigmoidldacie->set_sensitive(false); sigmoidthcie->set_sensitive(false); @@ -8459,7 +8459,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE sigmoidblcie->set_sensitive(true); sigmoidqjcie->set_sensitive(true); } - + if (spot.sursourcie == "Average") { sursourcie->set_active (0); } else if (spot.sursourcie == "Dim") { @@ -8559,7 +8559,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE higthrescie->setValue((double)spot.higthrescie); decaycie->setValue((double)spot.decaycie); - + } enableListener(); // Update GUI according to complexity mode @@ -8707,7 +8707,7 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.lightlzcam = lightlzcam->getValue(); spot.lightqzcam = lightqzcam->getValue(); spot.contlzcam = contlzcam->getValue(); - spot.contqzcam = contqzcam->getValue(); + spot.contqzcam = contqzcam->getValue(); spot.contthreszcam = contthreszcam->getValue(); spot.colorflzcam = colorflzcam->getValue(); spot.saturzcam = saturzcam->getValue(); @@ -8780,7 +8780,7 @@ void Locallabcie::updateMaskBackground(const double normChromar, const double no void Locallabcie::updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const float jz1) -{ +{ if (Autograycie->get_active()) { idle_register.add( @@ -8889,7 +8889,7 @@ void Locallabcie::qtojChanged() } void Locallabcie::jabcieChanged() -{ +{ if (isLocActivated && exp->getEnabled()) { if (listener) { if (jabcie->get_active()) { @@ -8920,7 +8920,7 @@ void Locallabcie::sigmoidqjcieChanged() void Locallabcie::logcieChanged() { - + if(logcie->get_active()) { sigmoidldacie->set_sensitive(false); sigmoidthcie->set_sensitive(false); @@ -8932,7 +8932,7 @@ void Locallabcie::logcieChanged() sigmoidblcie->set_sensitive(true); sigmoidqjcie->set_sensitive(true); } - + if (isLocActivated && exp->getEnabled()) { if (listener) { if (logcie->get_active()) { @@ -9014,7 +9014,7 @@ void Locallabcie::chjzcieChanged() void Locallabcie::modecamChanged() { const int mode = complexity->get_active_row_number(); - + if (modecam->get_active_row_number() == 1 || modecam->get_active_row_number() == 2) { expjz->show(); jzFrame->show(); @@ -9028,7 +9028,7 @@ void Locallabcie::modecamChanged() sigmoidjzFrame->show(); sigmoidFrame->hide(); forcejz->hide(); - + } else { expjz->hide(); jzFrame->hide(); @@ -9039,7 +9039,7 @@ void Locallabcie::modecamChanged() jabcie->hide(); PQFrame->hide(); logjzFrame->hide(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } @@ -9071,7 +9071,7 @@ void Locallabcie::modecamChanged() exprecovcie->show(); expmaskcie->show(); } - + } if (modecam->get_active_row_number() == 3) { if(mode == Expert) { @@ -9101,7 +9101,7 @@ void Locallabcie::modecamChanged() cie2Frame->hide(); } - } + } if(mode != Expert) { expjz->hide(); @@ -9115,7 +9115,7 @@ void Locallabcie::modecamChanged() sigmoidjzFrame->hide(); sigmoidFrame->hide(); bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } @@ -9137,10 +9137,10 @@ void Locallabcie::modecamChanged() } else { cieFrame->show(); cie2Frame->show(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidjzFrame->hide(); - + } if (modecam->get_active_row_number() == 1) { targetGraycie->hide(); @@ -9160,8 +9160,8 @@ void Locallabcie::modecamChanged() } else { thrhjzcie->set_sensitive(false); } - - + + } if (modecam->get_active_row_number() == 3) { cieFrame->show(); @@ -9179,7 +9179,7 @@ void Locallabcie::modecamChanged() catadcie->hide(); cie2Frame->hide(); } - + } if (modecam->get_active_row_number() == 0 || modecam->get_active_row_number() == 2) { targetGraycie->show(); @@ -9188,7 +9188,7 @@ void Locallabcie::modecamChanged() cie2Frame->show(); pqremapcam16->show(); } - + if (isLocActivated && exp->getEnabled()) { @@ -9204,17 +9204,17 @@ void Locallabcie::modecamChanged() void Locallabcie::modecieChanged() { if (isLocActivated && exp->getEnabled()) { - + const int mode = complexity->get_active_row_number(); exprecovcie->show(); expmaskcie->show(); - + if (modecie->get_active_row_number() > 0) { sensicie->hide(); reparcie->hide(); exprecovcie->hide(); expmaskcie->hide(); - + } else { sensicie->show(); reparcie->show(); @@ -9224,11 +9224,11 @@ void Locallabcie::modecieChanged() } } if (mode == Simple || mode == Normal) { // Keep widget hidden in Normal and Simple mode - + modecie->set_active (0); sensicie->show(); reparcie->show(); - + } if (listener) { @@ -9286,7 +9286,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sensicie->show(); reparcie->show(); sigmoidblcie->hide(); - + expjz->hide(); jzFrame->hide(); adapjzcie->hide(); @@ -9314,7 +9314,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) bevwevFrame->hide(); sigmoidFrame->hide(); } - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } @@ -9347,7 +9347,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) logjzFrame->hide(); catadcie->hide(); } - + break; case Normal: // Expert mode widgets are hidden in Normal mode @@ -9397,12 +9397,12 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if (enacieMask->get_active()) { maskusablecie->show(); maskunusablecie->hide(); - + } else { maskusablecie->hide(); maskunusablecie->show(); } - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } @@ -9431,7 +9431,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) expmaskcie->hide(); maskusablecie->hide(); maskunusablecie->hide(); - + } if (modecam->get_active_row_number() == 3) { cieFrame->hide(); @@ -9489,12 +9489,12 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if (enacieMask->get_active()) { maskusablecie->show(); maskunusablecie->hide(); - + } else { maskusablecie->hide(); maskunusablecie->show(); } - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); } @@ -9511,7 +9511,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sigmoidjzFrame->show(); sigmoidFrame->hide(); forcejz->hide(); - + } cieFrame->show(); cie2Frame->show(); @@ -9525,11 +9525,11 @@ void Locallabcie::updateGUIToMode(const modeType new_type) logjzFrame->hide(); sigmoidjzFrame->hide(); bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } - + } if (modecam->get_active_row_number() == 2) { PQFrame->show(); @@ -9560,9 +9560,9 @@ void Locallabcie::updateGUIToMode(const modeType new_type) } else { thrhjzcie->set_sensitive(false); } - + } - + if (modecam->get_active_row_number() == 3) { cieFrame->show(); cie1Frame->hide(); @@ -9583,7 +9583,7 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); expmaskcie->hide(); - } + } } } @@ -9608,10 +9608,10 @@ void Locallabcie::updatecieGUI() cie1Frame->show(); cie2Frame->show(); expcam16->show(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); } - + if (modecam->get_active_row_number() == 2 && mode == Expert) { PQFrame->show(); logjzFrame->show(); @@ -9624,7 +9624,7 @@ void Locallabcie::updatecieGUI() if (enacieMask->get_active() && mode != Simple) { maskusablecie->show(); maskunusablecie->hide(); - + } else { maskusablecie->hide(); maskunusablecie->show(); @@ -9655,7 +9655,7 @@ void Locallabcie::updatecieGUI() sigmoidjzFrame->hide(); sigmoidFrame->hide(); bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0){ bevwevFrame->show(); sigmoidFrame->show(); } @@ -9718,7 +9718,7 @@ void Locallabcie::updatecieGUI() exprecovcie->hide(); expmaskcie->hide(); } - + } @@ -9778,10 +9778,10 @@ void Locallabcie::convertParamToNormal() lapmaskcie->setValue(defSpot.lapmaskcie); gammaskcie->setValue(defSpot.gammaskcie); slomaskcie->setValue(defSpot.slomaskcie); - + // Enable all listeners enableListener(); - + } void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) @@ -9875,13 +9875,13 @@ void Locallabcie::curveChanged(CurveEditor* ce) listener->panelChanged(Evlocallabshapeczjz, spName); } } - + if (ce == HHshapejz) { if (listener) { listener->panelChanged(EvlocallabHHshapejz, spName); } } - + if (ce == CHshapejz) { if (listener) { listener->panelChanged(EvlocallabCHshapejz, spName); @@ -9905,7 +9905,7 @@ void Locallabcie::curveChanged(CurveEditor* ce) listener->panelChanged(Evlocallabshapecie2, spName); } } - + if (ce == CCmaskcieshape) { if (listener) { listener->panelChanged(EvlocallabCCmaskcieshape, @@ -9989,7 +9989,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) float pal = std::max(10. * (double) sqrt(sour), 1.5); adapjzcie->setValue(pal);//max to 10 if La > 10000 and mini to 1.5 jz100->setValue(defSpot.jz100); - + if (listener) { listener->panelChanged(Evlocallabsourceabscie, sourceabscie->getTextValue() + spName ); @@ -10361,7 +10361,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) detailcie->getTextValue() + spName); } } - + if (a == blendmaskcie) { if (listener) { listener->panelChanged(Evlocallabblendmaskcie, @@ -10405,7 +10405,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } if (a == recothrescie) { - + if (listener) { listener->panelChanged(Evlocallabrecothrescie, recothrescie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index 26d36f9e0..9f65218cf 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -20,7 +20,7 @@ #include "guiutils.h" #include "rtsurface.h" -LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring* tooltip) +LWButton::LWButton (std::shared_ptr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring* tooltip) : xpos(0), ypos(0), halign(ha), valign(va), icon(i), bgr(0.0), bgg(0.0), bgb(0.0), fgr(0.0), fgg(0.0), fgb(0.0), state(Normal), listener(nullptr), actionCode(aCode), actionData(aData), toolTip(tooltip) { @@ -32,7 +32,7 @@ LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignmen } } -void LWButton::getSize (int& minw, int& minh) const +void LWButton::getSize (int& minw, int& minh) const { minw = w; @@ -59,7 +59,7 @@ void LWButton::getPosition (int& x, int& y) const y = ypos; } -void LWButton::setIcon (Cairo::RefPtr i) +void LWButton::setIcon (std::shared_ptr i) { icon = i; @@ -72,7 +72,7 @@ void LWButton::setIcon (Cairo::RefPtr i) } } -Cairo::RefPtr LWButton::getIcon () const +std::shared_ptr LWButton::getIcon () const { return icon; @@ -211,7 +211,7 @@ void LWButton::redraw (Cairo::RefPtr context) dilat++; } - if (icon) { + if (icon && icon->hasSurface()) { context->set_source (icon->get(), xpos + dilat, ypos + dilat); context->paint (); } diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h index a98f1fe46..43c3ffe06 100644 --- a/rtgui/lwbutton.h +++ b/rtgui/lwbutton.h @@ -40,7 +40,7 @@ public: private: int xpos, ypos, w, h; Alignment halign, valign; - Cairo::RefPtr icon; + std::shared_ptr icon; double bgr, bgg, bgb; double fgr, fgg, fgb; State state; @@ -50,7 +50,7 @@ private: Glib::ustring* toolTip; public: - LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha = Left, Alignment va = Center, Glib::ustring* tooltip = nullptr); + LWButton (std::shared_ptr i, int aCode, void* aData, Alignment ha = Left, Alignment va = Center, Glib::ustring* tooltip = nullptr); void getSize (int& minw, int& minh) const; void getAlignment (Alignment& ha, Alignment& va) const; @@ -58,8 +58,8 @@ public: void addPosition (int x, int y); void getPosition (int& x, int& y) const; bool inside (int x, int y) const; - void setIcon (Cairo::RefPtr i); - Cairo::RefPtr getIcon () const; + void setIcon (std::shared_ptr i); + std::shared_ptr getIcon () const; void setColors (const Gdk::RGBA& bg, const Gdk::RGBA& fg); void setToolTip (Glib::ustring* tooltip); diff --git a/rtgui/main.cc b/rtgui/main.cc index 9f623a6df..2ca0d9c91 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -68,7 +68,6 @@ Glib::ustring argv2; bool simpleEditor = false; bool gimpPlugin = false; bool remote = false; -unsigned char initialGdkScale = 1; //Glib::Threads::Thread* mainThread; namespace @@ -250,7 +249,7 @@ void cleanup_rt() RTWindow *create_rt_window() { - Glib::ustring icon_path = Glib::build_filename (argv0, "images"); + Glib::ustring icon_path = Glib::build_filename (argv0, "icons"); Glib::RefPtr defaultIconTheme = Gtk::IconTheme::get_default(); defaultIconTheme->append_search_path (icon_path); @@ -533,16 +532,6 @@ int main (int argc, char **argv) int ret = 0; - if (options.pseudoHiDPISupport) { - // Reading/updating GDK_SCALE early if it exists - const gchar *gscale = g_getenv("GDK_SCALE"); - if (gscale && gscale[0] == '2') { - initialGdkScale = 2; - } - // HOMBRE: On Windows, if resolution is set to 200%, Gtk internal variables are SCALE=2 and DPI=96 - g_setenv("GDK_SCALE", "1", true); - } - gdk_threads_set_lock_functions (G_CALLBACK (myGdkLockEnter), (G_CALLBACK (myGdkLockLeave))); gdk_threads_init(); gtk_init (&argc, &argv); // use the "--g-fatal-warnings" command line flag to make warnings fatal diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index d460713fb..851db0ec6 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -41,9 +41,7 @@ MyCurve::MyCurve () : snapToValX(0.0), snapToValY(0.0) { - - int s = RTScalable::getScale(); - int pointDiameter = (int)(RADIUS * 2.) * s; + int pointDiameter = RTScalable::scalePixelSize((int)(RADIUS * 2.)); graphW = get_allocation().get_width() - pointDiameter; graphH = get_allocation().get_height() - pointDiameter; prevGraphW = graphW; @@ -78,7 +76,7 @@ MyCurve::~MyCurve () void MyCurve::calcDimensions () { double newRequestedW, newRequestedH; - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); newRequestedW = newRequestedH = get_allocation().get_width(); @@ -103,21 +101,19 @@ void MyCurve::get_preferred_height_vfunc (int &minimum_height, int &natural_heig void MyCurve::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - int s = RTScalable::getScale(); - natural_width = minimum_width = (GRAPH_SIZE + (int)(RADIUS * 2.) + (leftBar ? (CBAR_WIDTH + 2 + CBAR_MARGIN) : 0)) * s; + natural_width = minimum_width = (GRAPH_SIZE + (int)(RADIUS * 2.) + RTScalable::scalePixelSize(leftBar ? (CBAR_WIDTH + 2 + CBAR_MARGIN) : 0)); } void MyCurve::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { minimum_height = width; - int s = RTScalable::getScale(); if (leftBar && !bottomBar) { - minimum_height -= (CBAR_WIDTH + 2 + CBAR_MARGIN) * s; + minimum_height -= RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN); } if (!leftBar && bottomBar) { - minimum_height += (CBAR_WIDTH + 2 + CBAR_MARGIN) * s; + minimum_height += RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN); } natural_height = minimum_height; diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index 4f9422c69..a2ffbc905 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -260,7 +260,7 @@ void MyDiagonalCurve::draw (int handle) return; } - const double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); // re-calculate curve if dimensions changed int currLUTSize = point.getUpperBound(); @@ -594,7 +594,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) return false; } - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double minDistanceX = double(MIN_DISTANCE) / graphW * s; double minDistanceY = double(MIN_DISTANCE) / graphH * s; @@ -1069,7 +1069,7 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi return; } - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double minDistanceX = MIN_DISTANCE / graphW * s; if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS || curve.type == DCT_CatumullRom) { @@ -1124,7 +1124,7 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi return false; } - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double minDistanceX = double(MIN_DISTANCE) * s / graphW; snapToElmt = -100; @@ -1201,7 +1201,7 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider) return; } - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double minDistanceX = double(MIN_DISTANCE) * s / graphW; snapToElmt = -100; diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 11d89ebd8..e95faf3d4 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -140,7 +140,7 @@ void MyFlatCurve::draw () return; } - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); // re-calculate curve if dimensions changed int currLUTSize = point.getUpperBound(); @@ -535,7 +535,7 @@ bool MyFlatCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) allocation.set_x(0); allocation.set_y(0); - int s = RTScalable::getScale(); + const int s = RTScalable::scalePixelSize(1); // setDrawRectangle will allocate the backbuffer Surface if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) { @@ -619,7 +619,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) return false; } - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); minDistanceX = double(MIN_DISTANCE) / graphW * s; minDistanceY = double(MIN_DISTANCE) / graphH * s; @@ -1321,7 +1321,7 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier // hide the tangent handles tanHandlesDisplayed = false; - int s = RTScalable::getScale(); + const int s = RTScalable::scalePixelSize(1); // Action on BUTTON_PRESS and no edited point switch (area) { diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index 317732bd2..34feed221 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -111,29 +111,29 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" panel_listener = nullptr; metadata = nullptr; - Gtk::Image* ipers_draw(new RTImage ("draw.png")); - Gtk::Image* ipers_trash = Gtk::manage (new RTImage ("trash-empty.png")); - Gtk::Image* ipers_apply = Gtk::manage (new RTImage ("tick.png")); + RTImage* const ipers_draw = Gtk::manage (new RTImage ("draw", Gtk::ICON_SIZE_BUTTON)); + RTImage* const ipers_trash = Gtk::manage (new RTImage ("trash-empty", Gtk::ICON_SIZE_BUTTON)); + RTImage* const ipers_apply = Gtk::manage (new RTImage ("tick", Gtk::ICON_SIZE_BUTTON)); - Gtk::Image* ipersHL = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); - Gtk::Image* ipersHR = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); - Gtk::Image* ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); - Gtk::Image* ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small.png")); + RTImage* const ipersHL = Gtk::manage (new RTImage ("perspective-horizontal-left-small")); + RTImage* const ipersHR = Gtk::manage (new RTImage ("perspective-horizontal-right-small")); + RTImage* const ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small")); + RTImage* const ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small")); - Gtk::Image* ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-bottom.png")); - Gtk::Image* ipers_auto_yaw = Gtk::manage (new RTImage ("perspective-horizontal-left.png")); - Gtk::Image* ipers_auto_pitch_yaw = Gtk::manage (new RTImage ("perspective-horizontal-vertical.png")); + RTImage* const ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-botton", Gtk::ICON_SIZE_BUTTON)); + RTImage* const ipers_auto_yaw = Gtk::manage (new RTImage ("perspective-horizontal-left", Gtk::ICON_SIZE_BUTTON)); + RTImage* const ipers_auto_pitch_yaw = Gtk::manage (new RTImage ("perspective-horizontal-vertical", Gtk::ICON_SIZE_BUTTON)); - Gtk::Image* ipers_cam_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); - Gtk::Image* ipers_cam_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); - Gtk::Image* ipers_cam_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); - Gtk::Image* ipers_cam_pitch_right = Gtk::manage (new RTImage ("perspective-vertical-top-small.png")); - Gtk::Image* ipers_proj_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small.png")); - Gtk::Image* ipers_proj_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small.png")); - Gtk::Image* ipers_proj_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small.png")); - Gtk::Image* ipers_proj_pitch_right = Gtk::manage (new RTImage ("perspective-vertical-top-small.png")); - Gtk::Image* ipers_rotate_left = Gtk::manage(new RTImage("rotate-right-small.png")); - Gtk::Image* ipers_rotate_right = Gtk::manage(new RTImage("rotate-left-small.png")); + RTImage* const ipers_cam_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small")); + RTImage* const ipers_cam_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small")); + RTImage* const ipers_cam_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small")); + RTImage* const ipers_cam_pitch_right = Gtk::manage (new RTImage ("perspective-vertical-top-small")); + RTImage* const ipers_proj_yaw_left = Gtk::manage (new RTImage ("perspective-horizontal-left-small")); + RTImage* const ipers_proj_yaw_right = Gtk::manage (new RTImage ("perspective-horizontal-right-small")); + RTImage* const ipers_proj_pitch_left = Gtk::manage (new RTImage ("perspective-vertical-bottom-small")); + RTImage* const ipers_proj_pitch_right = Gtk::manage (new RTImage ("perspective-vertical-top-small")); + RTImage* const ipers_rotate_left = Gtk::manage(new RTImage("rotate-right-small")); + RTImage* const ipers_rotate_right = Gtk::manage(new RTImage("rotate-left-small")); Gtk::Box* method_hbox = Gtk::manage (new Gtk::Box()); Gtk::Label* method_label = Gtk::manage (new Gtk::Label (M("TP_PERSPECTIVE_METHOD") + ": ")); diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 3440080f8..aec203ee2 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -32,7 +32,7 @@ PlacesBrowser::PlacesBrowser () { set_orientation(Gtk::ORIENTATION_VERTICAL); - + scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); pack_start (*scrollw); @@ -43,13 +43,13 @@ PlacesBrowser::PlacesBrowser () setExpandAlignProperties(add, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); //add->get_style_context()->set_junction_sides(Gtk::JUNCTION_RIGHT); add->get_style_context()->add_class("Left"); - add->set_image (*Gtk::manage (new RTImage ("add-small.png"))); + add->set_image (*Gtk::manage (new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON))); del = Gtk::manage (new Gtk::Button ()); del->set_tooltip_text(M("MAIN_FRAME_PLACES_DEL")); setExpandAlignProperties(del, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); //del->get_style_context()->set_junction_sides(Gtk::JUNCTION_LEFT); del->get_style_context()->add_class("Right"); - del->set_image (*Gtk::manage (new RTImage ("remove-small.png"))); + del->set_image (*Gtk::manage (new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON))); Gtk::Grid* buttonBox = Gtk::manage (new Gtk::Grid ()); buttonBox->set_orientation(Gtk::ORIENTATION_HORIZONTAL); buttonBox->attach_next_to(*add, Gtk::POS_LEFT, 1, 1); diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 8c4c9dda1..69d51f2dd 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -56,21 +56,21 @@ PopUpCommon::~PopUpCommon () delete buttonImage; } -bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) +bool PopUpCommon::addEntry (const Glib::ustring& iconName, const Glib::ustring& label) { if (label.empty ()) return false; // Create the menu item and image - MyImageMenuItem* newItem = Gtk::manage (new MyImageMenuItem (label, fileName)); - imageFilenames.push_back (fileName); + MyImageMenuItem* newItem = Gtk::manage (new MyImageMenuItem (label, iconName)); + imageFilenames.push_back (iconName); images.push_back (newItem->getImage ()); if (selected == -1) { // Create the menu on the first item menu = new Gtk::Menu (); // Create the image for the button - buttonImage = new RTImage(fileName); + buttonImage = new RTImage(iconName, Gtk::ICON_SIZE_BUTTON); setExpandAlignProperties(buttonImage, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); // Use the first image by default imageContainer->attach_next_to(*buttonImage, Gtk::POS_RIGHT, 1, 1); @@ -80,8 +80,7 @@ bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& // When there is at least 1 choice, we add the arrow button if (images.size() == 1) { Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); - Gtk::Image *arrowImage = Gtk::manage(new Gtk::Image()); - arrowImage->set_from_icon_name("pan-down-symbolic", Gtk::ICON_SIZE_BUTTON); + Gtk::Image *arrowImage = Gtk::manage(new RTImage("pan-down-symbolic", Gtk::ICON_SIZE_BUTTON)); setExpandAlignProperties(arrowButton, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); arrowButton->add(*arrowImage); //menuSymbol); buttonGroup->attach_next_to(*arrowButton, *button, Gtk::POS_RIGHT, 1, 1); @@ -125,12 +124,12 @@ void PopUpCommon::setItemSensitivity (int index, bool isSensitive) { bool PopUpCommon::setSelected (int entryNum) { entryNum = indexToPos(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)); + buttonImage->set_from_icon_name(imageFilenames.at(entryNum), Gtk::ICON_SIZE_BUTTON); selected = entryNum; setButtonHint(); return true; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c6c2eb61b..0cf7ebd47 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -527,7 +527,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () iprofiles->set_size_request(50, -1); setExpandAlignProperties(iprofiles, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); ipconn = iprofiles->signal_changed().connect(sigc::mem_fun(*this, &Preferences::forImageComboChanged)); - + Gtk::Grid* defpt = Gtk::manage(new Gtk::Grid()); defpt->set_row_spacing(2); defpt->attach(*drlab, 0, 0, 1, 1); @@ -535,7 +535,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () defpt->attach(*drimg, 0, 1, 1, 1); defpt->attach(*iprofiles, 1, 1, 1, 1); vbpp->pack_start(*defpt, Gtk::PACK_SHRINK, 4); - + useBundledProfiles = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_USEBUNDLEDPROFILES"))); bpconn = useBundledProfiles->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::bundledProfilesChanged)); vbpp->pack_start(*useBundledProfiles, Gtk::PACK_SHRINK, 4); @@ -779,7 +779,7 @@ Gtk::Widget* Preferences::getColorManPanel () vbColorMan->pack_start (*iccdgrid, Gtk::PACK_SHRINK); - + //------------------------- MONITOR ---------------------- Gtk::Frame* fmonitor = Gtk::manage(new Gtk::Frame(M("PREFERENCES_MONITOR"))); @@ -898,7 +898,7 @@ Gtk::Widget* Preferences::getColorManPanel () fprinter->add(*gprinter); vbColorMan->pack_start (*fprinter, Gtk::PACK_SHRINK); - + //-------------CIECAM Gtk::Frame* fcie = Gtk::manage(new Gtk::Frame(M("PREFERENCES_CIE"))); Gtk::Grid* gcie = Gtk::manage(new Gtk::Grid()); @@ -1118,7 +1118,7 @@ Gtk::Widget* Preferences::getGeneralPanel() setExpandAlignProperties(pseudoHiDPI, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); Gtk::Separator *vSep = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)); - + appearanceGrid->attach(*themeLbl, 0, 0, 1, 1); appearanceGrid->attach(*themeCBT, 1, 0, 1, 1); @@ -1281,7 +1281,7 @@ Gtk::Widget* Preferences::getGeneralPanel() hb->pack_start(*editor_dir_custom_path, Gtk::PACK_EXPAND_WIDGET, 2); vb->pack_start(*hb); f->add(*vb); - + hb = Gtk::manage(new Gtk::Box()); hb->pack_start(*externaleditorGrid); hb->pack_start(*f, Gtk::PACK_EXPAND_WIDGET, 4); @@ -1298,8 +1298,8 @@ Gtk::Widget* Preferences::getGeneralPanel() vb->show(); fdg->add(*vb); } - - + + vbGeneral->attach_next_to (*fdg, *fclip, Gtk::POS_BOTTOM, 2, 1); langAutoDetectConn = ckbLangAutoDetect->signal_toggled().connect(sigc::mem_fun(*this, &Preferences::langAutoDetectToggled)); tconn = themeCBT->signal_changed().connect ( sigc::mem_fun (*this, &Preferences::themeChanged) ); @@ -1326,7 +1326,7 @@ Gtk::Widget* Preferences::getFileBrowserPanel() startupdir = Gtk::manage(new Gtk::Entry()); Gtk::Button* sdselect = Gtk::manage(new Gtk::Button()); - sdselect->set_image (*Gtk::manage (new RTImage ("folder-open-small.png"))); + sdselect->set_image (*Gtk::manage (new RTImage ("folder-open-small", Gtk::ICON_SIZE_BUTTON))); Gtk::RadioButton::Group opts = sdcurrent->get_group(); sdlast->set_group(opts); @@ -1437,10 +1437,10 @@ Gtk::Widget* Preferences::getFileBrowserPanel() delExt->set_tooltip_text(M("PREFERENCES_PARSEDEXTDELHINT")); moveExtUp->set_tooltip_text(M("PREFERENCES_PARSEDEXTUPHINT")); moveExtDown->set_tooltip_text(M("PREFERENCES_PARSEDEXTDOWNHINT")); - Gtk::Image* addExtImg = Gtk::manage ( new RTImage ("add-small.png") ); - Gtk::Image* delExtImg = Gtk::manage ( new RTImage ("remove-small.png") ); - Gtk::Image* moveExtUpImg = Gtk::manage(new RTImage("arrow-up-small.png")); - Gtk::Image* moveExtDownImg = Gtk::manage(new RTImage("arrow-down-small.png")); + Gtk::Image* addExtImg = Gtk::manage ( new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON) ); + Gtk::Image* delExtImg = Gtk::manage ( new RTImage ("remove-small", Gtk::ICON_SIZE_BUTTON) ); + Gtk::Image* moveExtUpImg = Gtk::manage(new RTImage("arrow-up-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* moveExtDownImg = Gtk::manage(new RTImage("arrow-down-small", Gtk::ICON_SIZE_BUTTON)); addExt->add(*addExtImg); delExt->add(*delExtImg); moveExtUp->set_image(*moveExtUpImg); @@ -2133,7 +2133,7 @@ void Preferences::fillPreferences() } curveBBoxPosC->set_active(moptions.curvebboxpos); - complexitylocal->set_active(moptions.complexity); + complexitylocal->set_active(moptions.complexity); inspectorWindowCB->set_active(moptions.inspectorWindow); zoomOnScrollCB->set_active(moptions.zoomOnScroll); @@ -2263,7 +2263,6 @@ void Preferences::cancelPressed() { // set the initial theme back if (themeFNames.at (themeCBT->get_active_row_number ()).longFName != options.theme) { - RTImage::updateImages(); switchThemeTo(options.theme); } @@ -2320,7 +2319,6 @@ void Preferences::themeChanged() { moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName; - RTImage::updateImages(); switchThemeTo(moptions.theme); } diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc index 586923173..8bec03ee9 100644 --- a/rtgui/previewmodepanel.cc +++ b/rtgui/previewmodepanel.cc @@ -21,74 +21,72 @@ #include "imagearea.h" #include "rtimage.h" -PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) +PreviewModePanel::PreviewModePanel (ImageArea* ia) : + imageArea(ia), + nR("square-toggle-red-on-narrow"), ngR("square-toggle-red-off-narrow"), + nG("square-toggle-green-on-narrow"), ngG("square-toggle-green-off-narrow"), + nB("square-toggle-blue-on-narrow"), ngB("square-toggle-blue-off-narrow"), + nL("square-toggle-luminosity-on-narrow"), ngL("square-toggle-luminosity-off-narrow"), + nBC0("square-toggle-theme-on-narrow"), ngBC0("square-toggle-theme-off-narrow"), + nBC1("square-toggle-black-on-narrow"), ngBC1("square-toggle-black-off-narrow"), + nBC2("square-toggle-white-on-narrow"), ngBC2("square-toggle-white-off-narrow"), + nBC3("square-toggle-gray-on-narrow"), ngBC3("square-toggle-gray-off-narrow"), + iR(Gtk::manage (new RTImage(ngR, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iG(Gtk::manage (new RTImage(ngG, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iB(Gtk::manage (new RTImage(ngB, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iL(Gtk::manage (new RTImage(ngL, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iBC0(Gtk::manage (new RTImage(options.bgcolor == 0 ? nBC0 : ngBC0, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iBC1(Gtk::manage (new RTImage(options.bgcolor == 1 ? nBC1 : ngBC1, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iBC2(Gtk::manage (new RTImage(options.bgcolor == 2 ? nBC2 : ngBC2, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + iBC3(Gtk::manage (new RTImage(options.bgcolor == 3 ? nBC3 : ngBC3, Gtk::ICON_SIZE_LARGE_TOOLBAR))) { - - iR = new RTImage ("square-toggle-red-on-narrow.png"); - iG = new RTImage ("square-toggle-green-on-narrow.png"); - iB = new RTImage ("square-toggle-blue-on-narrow.png"); - iL = new RTImage ("square-toggle-luminosity-on-narrow.png"); - iBC0 = new RTImage ("square-toggle-theme-on-narrow.png"); - iBC1 = new RTImage ("square-toggle-black-on-narrow.png"); - iBC2 = new RTImage ("square-toggle-white-on-narrow.png"); - iBC3 = new RTImage ("square-toggle-gray-on-narrow.png"); - - igR = new RTImage ("square-toggle-red-off-narrow.png"); - igG = new RTImage ("square-toggle-green-off-narrow.png"); - igB = new RTImage ("square-toggle-blue-off-narrow.png"); - igL = new RTImage ("square-toggle-luminosity-off-narrow.png"); - igBC0 = new RTImage ("square-toggle-theme-off-narrow.png"); - igBC1 = new RTImage ("square-toggle-black-off-narrow.png"); - igBC2 = new RTImage ("square-toggle-white-off-narrow.png"); - igBC3 = new RTImage ("square-toggle-gray-off-narrow.png"); - backColor0 = Gtk::manage (new Gtk::ToggleButton ()); backColor0->get_style_context()->add_class("narrowbutton"); backColor0->set_relief(Gtk::RELIEF_NONE); backColor0->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR0")); - backColor0->set_image(options.bgcolor == 0 ? *iBC0 : *igBC0); + backColor0->set_image(*iBC0); backColor1 = Gtk::manage (new Gtk::ToggleButton ()); backColor1->get_style_context()->add_class("narrowbutton"); backColor1->set_relief(Gtk::RELIEF_NONE); backColor1->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR1")); - backColor1->set_image(options.bgcolor == 1 ? *iBC1 : *igBC1); + backColor1->set_image(*iBC1); backColor3 = Gtk::manage (new Gtk::ToggleButton ()); backColor3->get_style_context()->add_class("narrowbutton"); backColor3->set_relief(Gtk::RELIEF_NONE); backColor3->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR3")); - backColor3->set_image(options.bgcolor == 3 ? *iBC3 : *igBC3); + backColor3->set_image(*iBC3); backColor2 = Gtk::manage (new Gtk::ToggleButton ()); backColor2->get_style_context()->add_class("narrowbutton"); backColor2->set_relief(Gtk::RELIEF_NONE); backColor2->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR2")); - backColor2->set_image(options.bgcolor == 2 ? *iBC2 : *igBC2); + backColor2->set_image(*iBC2); previewR = Gtk::manage (new Gtk::ToggleButton ()); previewR->get_style_context()->add_class("narrowbutton"); previewR->set_relief(Gtk::RELIEF_NONE); previewR->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWR")); - previewR->set_image(*igR); + previewR->set_image(*iR); previewG = Gtk::manage (new Gtk::ToggleButton ()); previewG->get_style_context()->add_class("narrowbutton"); previewG->set_relief(Gtk::RELIEF_NONE); previewG->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWG")); - previewG->set_image(*igG); + previewG->set_image(*iG); previewB = Gtk::manage (new Gtk::ToggleButton ()); previewB->get_style_context()->add_class("narrowbutton"); previewB->set_relief(Gtk::RELIEF_NONE); previewB->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWB")); - previewB->set_image(*igB); + previewB->set_image(*iB); previewL = Gtk::manage (new Gtk::ToggleButton ()); previewL->get_style_context()->add_class("narrowbutton"); previewL->set_relief(Gtk::RELIEF_NONE); previewL->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWL")); - previewL->set_image(*igL); + previewL->set_image(*iL); previewR->set_active (false); previewG->set_active (false); @@ -125,25 +123,8 @@ PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) //show_all (); } -PreviewModePanel::~PreviewModePanel () -{ - delete iR; - delete iG; - delete iB; - delete iL; - delete iBC0; - delete iBC1; - delete iBC2; - delete iBC3; - delete igR; - delete igG; - delete igB; - delete igL; - delete igBC0; - delete igBC1; - delete igBC2; - delete igBC3; -} +PreviewModePanel::~PreviewModePanel () {} + //toggle Functions below are for shortcuts void PreviewModePanel::toggleR () { @@ -206,10 +187,10 @@ void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) } // 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); + iR->set_from_icon_name(previewR->get_active() ? nR : ngR); + iG->set_from_icon_name(previewG->get_active() ? nG : ngG); + iB->set_from_icon_name(previewB->get_active() ? nB : ngB); + iL->set_from_icon_name(previewL->get_active() ? nL : ngL); connR.block(false); connG.block(false); @@ -306,10 +287,10 @@ void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) } // set image based on button's state - backColor0->set_image(backColor0->get_active() ? *iBC0 : *igBC0); - backColor1->set_image(backColor1->get_active() ? *iBC1 : *igBC1); - backColor2->set_image(backColor2->get_active() ? *iBC2 : *igBC2); - backColor3->set_image(backColor3->get_active() ? *iBC3 : *igBC3); + iBC0->set_from_icon_name(backColor0->get_active() ? nBC0 : ngBC0); + iBC1->set_from_icon_name(backColor1->get_active() ? nBC1 : ngBC1); + iBC2->set_from_icon_name(backColor2->get_active() ? nBC2 : ngBC2); + iBC3->set_from_icon_name(backColor3->get_active() ? nBC3 : ngBC3); connbackColor0.block(false); connbackColor1.block(false); diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h index d475fd4a4..b496958ab 100644 --- a/rtgui/previewmodepanel.h +++ b/rtgui/previewmodepanel.h @@ -20,6 +20,7 @@ #include class ImageArea; +class RTImage; class PreviewModePanel : public Gtk::Box @@ -36,14 +37,22 @@ protected: Gtk::ToggleButton* backColor3; ImageArea* imageArea; - Gtk::Image* iR, *igR; - Gtk::Image* iG, *igG; - Gtk::Image* iB, *igB; - Gtk::Image* iL, *igL; - Gtk::Image* iBC0, *igBC0; - Gtk::Image* iBC1, *igBC1; - Gtk::Image* iBC2, *igBC2; - Gtk::Image* iBC3, *igBC3; + const Glib::ustring nR, ngR; + const Glib::ustring nG, ngG; + const Glib::ustring nB, ngB; + const Glib::ustring nL, ngL; + const Glib::ustring nBC0, ngBC0; + const Glib::ustring nBC1, ngBC1; + const Glib::ustring nBC2, ngBC2; + const Glib::ustring nBC3, ngBC3; + RTImage* const iR; + RTImage* const iG; + RTImage* const iB; + RTImage* const iL; + RTImage* const iBC0; + RTImage* const iBC1; + RTImage* const iBC2; + RTImage* const iBC3; public: explicit PreviewModePanel (ImageArea* ia); diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc index 90d0a7b4b..cc239ed26 100644 --- a/rtgui/previewwindow.cc +++ b/rtgui/previewwindow.cc @@ -156,7 +156,7 @@ bool PreviewWindow::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) int x, y, w, h; getObservedFrameArea (x, y, w, h); if (x>imgX || y>imgY || w < imgW || h < imgH) { - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double rectX = x + 0.5; double rectY = y + 0.5; double rectW = std::min(w, (int)(imgW - (x - imgX) - 1)); @@ -307,14 +307,14 @@ Gtk::SizeRequestMode PreviewWindow::get_request_mode_vfunc () const void PreviewWindow::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height= 50 * RTScalable::getScale(); - natural_height = 100 * RTScalable::getScale(); + minimum_height= RTScalable::scalePixelSize(50); + natural_height = RTScalable::scalePixelSize(100); } void PreviewWindow::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 80 * RTScalable::getScale(); - natural_width = 120 * RTScalable::getScale(); + minimum_width = RTScalable::scalePixelSize(80); + natural_width = RTScalable::scalePixelSize(120); } void PreviewWindow::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index e18ec8cff..da18807a6 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -45,16 +45,16 @@ void ProfilePanel::cleanup () delete partialProfileDlg; } -ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastSavedPSE(nullptr), customPSE(nullptr) +ProfilePanel::ProfilePanel () : storedPProfile(nullptr), + modeOn("profile-filled"), modeOff("profile-partial"), + profileFillImage(Gtk::manage(new RTImage(options.filledProfile ? modeOn : modeOff, Gtk::ICON_SIZE_LARGE_TOOLBAR))), + lastSavedPSE(nullptr), customPSE(nullptr) { - tpc = nullptr; - profileFillModeOnImage = new RTImage("profile-filled.png"); - profileFillModeOffImage = new RTImage("profile-partial.png"); fillMode = Gtk::manage (new Gtk::ToggleButton()); fillMode->set_active(options.filledProfile); - fillMode->add( options.filledProfile ? *profileFillModeOnImage : *profileFillModeOffImage ); + fillMode->add(*profileFillImage); fillMode->signal_toggled().connect ( sigc::mem_fun(*this, &ProfilePanel::profileFillModeToggled) ); fillMode->set_tooltip_text(M("PROFILEPANEL_MODE_TIP")); //GTK318 @@ -69,20 +69,20 @@ ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastSavedPSE(nullptr), setExpandAlignProperties(profiles, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); load = Gtk::manage (new Gtk::Button ()); - load->add (*Gtk::manage (new RTImage ("folder-open.png"))); + load->add (*Gtk::manage (new RTImage ("folder-open", Gtk::ICON_SIZE_LARGE_TOOLBAR))); load->get_style_context()->add_class("Left"); load->set_margin_left(2); setExpandAlignProperties(load, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); save = Gtk::manage (new Gtk::Button ()); - save->add (*Gtk::manage (new RTImage ("save.png"))); + save->add (*Gtk::manage (new RTImage ("save", Gtk::ICON_SIZE_LARGE_TOOLBAR))); save->get_style_context()->add_class("MiddleH"); setExpandAlignProperties(save, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); copy = Gtk::manage (new Gtk::Button ()); - copy->add (*Gtk::manage (new RTImage ("copy.png"))); + copy->add (*Gtk::manage (new RTImage ("copy", Gtk::ICON_SIZE_LARGE_TOOLBAR))); copy->get_style_context()->add_class("MiddleH"); setExpandAlignProperties(copy, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); paste = Gtk::manage (new Gtk::Button ()); - paste->add (*Gtk::manage (new RTImage ("paste.png"))); + paste->add (*Gtk::manage (new RTImage ("paste", Gtk::ICON_SIZE_LARGE_TOOLBAR))); paste->get_style_context()->add_class("Right"); setExpandAlignProperties(paste, false, true, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); @@ -132,8 +132,6 @@ ProfilePanel::~ProfilePanel () delete lastsaved; } - delete profileFillModeOnImage; - delete profileFillModeOffImage; delete lastSavedPSE; delete customPSE; } @@ -887,10 +885,10 @@ void ProfilePanel::profileFillModeToggled() { if (fillMode->get_active()) { // The button is pressed, we'll use the profileFillModeOnImage - fillMode->set_image(*profileFillModeOnImage); + profileFillImage->set_from_icon_name(modeOn); } else { // The button is released, we'll use the profileFillModeOffImage - fillMode->set_image(*profileFillModeOffImage); + profileFillImage->set_from_icon_name(modeOff); } } diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index c3a125c49..e1d1f4067 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -62,8 +62,8 @@ private: Glib::ustring storedValue; Glib::ustring lastFilename; Glib::ustring imagePath; - RTImage *profileFillModeOnImage; - RTImage *profileFillModeOffImage; + const Glib::ustring modeOn, modeOff; + RTImage* const profileFillImage; Gtk::ToggleButton* fillMode; Gtk::TreeIter currRow; ProfileStoreEntry *lastSavedPSE; diff --git a/rtgui/rawcacorrection.cc b/rtgui/rawcacorrection.cc index 58c7995f9..207d535ac 100644 --- a/rtgui/rawcacorrection.cc +++ b/rtgui/rawcacorrection.cc @@ -35,10 +35,10 @@ RAWCACorr::RAWCACorr () : FoldableToolPanel(this, "rawcacorrection", M("TP_RAWCA EvPreProcessCAColourshift = m->newEvent(DARKFRAME, "HISTORY_MSG_RAWCACORR_COLORSHIFT"); EvPreProcessCAColourshiftHistory = m->newEvent(M_VOID, "HISTORY_MSG_RAWCACORR_COLORSHIFT"); - Gtk::Image* icaredL = Gtk::manage (new RTImage ("circle-red-cyan-small.png")); - Gtk::Image* icaredR = Gtk::manage (new RTImage ("circle-cyan-red-small.png")); - Gtk::Image* icablueL = Gtk::manage (new RTImage ("circle-blue-yellow-small.png")); - Gtk::Image* icablueR = Gtk::manage (new RTImage ("circle-yellow-blue-small.png")); + Gtk::Image* const icaredL = Gtk::manage (new RTImage ("circle-red-cyan-small")); + Gtk::Image* const icaredR = Gtk::manage (new RTImage ("circle-cyan-red-small")); + Gtk::Image* const icablueL = Gtk::manage (new RTImage ("circle-blue-yellow-small")); + Gtk::Image* const icablueR = Gtk::manage (new RTImage ("circle-yellow-blue-small")); caAutocorrect = Gtk::manage (new CheckBox(M("TP_RAWCACORR_AUTO"), multiImage)); caAutocorrect->setCheckBoxListener (this); diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index a9d7cc376..d77849be2 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -491,7 +491,7 @@ Retinex::Retinex () : FoldableToolPanel (this, "retinex", M ("TP_RETINEX_LABEL") neutral = Gtk::manage (new Gtk::Button (M ("TP_RETINEX_NEUTRAL"))); setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); + RTImage *resetImg = Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON)); setExpandAlignProperties (resetImg, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); neutral->set_image (*resetImg); neutral->set_tooltip_text (M ("TP_RETINEX_NEUTRAL_TIP")); @@ -939,7 +939,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) cdshapeH->setCurve (pp->retinex.cdHcurve); lhshape->setCurve (pp->retinex.lhcurve); mapshape->setCurve (pp->retinex.mapcurve); - + retinexMethodConn.block (false); retinexColorSpaceConn.block (false); gammaretinexConn.block (false); @@ -951,7 +951,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) complexmethodconn.block (false); enableListener (); - + if (complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); // convertParamToNormal(); @@ -959,7 +959,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) } else { updateGUIToMode(1); } - + } diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc index 06c53cd4e..a2456a681 100644 --- a/rtgui/rotate.cc +++ b/rtgui/rotate.cc @@ -35,15 +35,15 @@ Rotate::Rotate () : FoldableToolPanel(this, "rotate", M("TP_ROTATE_LABEL")) rlistener = nullptr; //TODO the action of the rotation slider is counter-intuitive - Gtk::Image* irotateL = Gtk::manage (new RTImage ("rotate-right-small.png")); - Gtk::Image* irotateR = Gtk::manage (new RTImage ("rotate-left-small.png")); + Gtk::Image* irotateL = Gtk::manage (new RTImage ("rotate-right-small")); + Gtk::Image* irotateR = Gtk::manage (new RTImage ("rotate-left-small")); degree = Gtk::manage (new Adjuster (M("TP_ROTATE_DEGREE"), -45, 45, 0.01, 0, irotateL, irotateR)); degree->setAdjusterListener (this); pack_start (*degree); selectStraight = Gtk::manage (new Gtk::Button (M("TP_ROTATE_SELECTLINE"))); - selectStraight->set_image (*Gtk::manage (new RTImage ("rotate-straighten-small.png"))); + selectStraight->set_image (*Gtk::manage (new RTImage ("rotate-straighten-small"))); selectStraight->get_style_context()->add_class("independent"); pack_start (*selectStraight, Gtk::PACK_SHRINK, 2); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 44078ed3b..2040ec21d 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -3,6 +3,7 @@ * * Copyright (c) 2004-2010 Gabor Horvath * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,205 +21,21 @@ #include "rtimage.h" -#include -#include - -#include "../rtengine/settings.h" - -namespace -{ - -std::map > pixbufCache; -std::map > surfaceCache; - -} - -double RTImage::dpiBack = 0.; -int RTImage::scaleBack = 0; - RTImage::RTImage () {} -RTImage::RTImage (RTImage &other) : surface(other.surface), pixbuf(other.pixbuf) +RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) : + Gtk::Image(iconName, iconSize), + size(iconSize) { - if (pixbuf) { - set(pixbuf); - } else if (surface) { - set(surface); - } } -RTImage::RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName) : Gtk::Image() +void RTImage::set_from_icon_name(const Glib::ustring& iconName) { - setImage (fileName, rtlFileName); + Gtk::Image::set_from_icon_name(iconName, this->size); } -RTImage::RTImage (Glib::RefPtr &pbuf) +void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize) { - if (surface) { - surface.clear(); - } - if (pbuf) { - set(pbuf); - this->pixbuf = pbuf; - } -} - -RTImage::RTImage (Cairo::RefPtr &surf) -{ - if (pixbuf) { - pixbuf.clear(); - } - if (surf) { - set(surf); - surface = surf; - } -} - -RTImage::RTImage (Glib::RefPtr &other) -{ - if (other) { - if (other->get_surface()) { - surface = other->get_surface(); - set(surface); - } else { - pixbuf = other->get_pixbuf(); - set(pixbuf); - } - } -} - -void RTImage::setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName) -{ - Glib::ustring imageName; - - if (!rtlFileName.empty() && getDirection() == Gtk::TEXT_DIR_RTL) { - imageName = rtlFileName; - } else { - imageName = fileName; - } - - changeImage (imageName); -} - -/* - * On windows, if scale = 2, the dpi is non significant, i.e. should be considered = 192 - */ -void RTImage::setDPInScale (const double newDPI, const int newScale) -{ - if (scaleBack != newScale || (scaleBack == 1 && dpiBack != newDPI)) { - RTScalable::setDPInScale(newDPI, newScale); - dpiBack = getDPI(); - scaleBack = getScale(); - updateImages(); - } -} - -void RTImage::changeImage (const Glib::ustring& imageName) -{ - clear (); - - if (imageName.empty()) { - return; - } - - if (pixbuf) { - auto iterator = pixbufCache.find (imageName); - assert(iterator != pixbufCache.end ()); - pixbuf = iterator->second; - set(iterator->second); - } else { // if no Pixbuf is set, we update or create a Cairo::ImageSurface - auto iterator = surfaceCache.find (imageName); - if (iterator == surfaceCache.end ()) { - auto surf = createImgSurfFromFile(imageName); - iterator = surfaceCache.emplace (imageName, surf).first; - } - surface = iterator->second; - set(iterator->second); - } -} - -Cairo::RefPtr RTImage::get_surface() -{ - return surface; -} - -int RTImage::get_width() -{ - if (surface) { - return surface->get_width(); - } - if (pixbuf) { - return pixbuf->get_width(); - } - return -1; -} - -int RTImage::get_height() -{ - if (surface) { - return surface->get_height(); - } - if (pixbuf) { - return pixbuf->get_height(); - } - return -1; -} - -void RTImage::init() -{ - dpiBack = RTScalable::getDPI(); - scaleBack = RTScalable::getScale(); -} - -void RTImage::cleanup(bool all) -{ - for (auto& entry : pixbufCache) { - entry.second.reset(); - } - for (auto& entry : surfaceCache) { - entry.second.clear(); - } - RTScalable::cleanup(all); -} - -void RTImage::updateImages() -{ - for (auto& entry : pixbufCache) { - entry.second = createPixbufFromFile(entry.first); - } - for (auto& entry : surfaceCache) { - entry.second = createImgSurfFromFile(entry.first); - } -} - -Glib::RefPtr RTImage::createPixbufFromFile (const Glib::ustring& fileName) -{ - Cairo::RefPtr imgSurf = createImgSurfFromFile(fileName); - return Gdk::Pixbuf::create(imgSurf, 0, 0, imgSurf->get_width(), imgSurf->get_height()); -} - -Cairo::RefPtr RTImage::createImgSurfFromFile (const Glib::ustring& fileName) -{ - Cairo::RefPtr surf; - - try { - surf = loadImage(fileName, getTweakedDPI()); - - // HOMBRE: As of now, GDK_SCALE is forced to 1, so setting the Cairo::ImageSurface scale is not required - /* - double x=0., y=0.; - cairo_surface_get_device_scale(surf->cobj(), &x, &y); - if (getScale() == 2) { - cairo_surface_set_device_scale(surf->cobj(), 0.5, 0.5); - cairo_surface_get_device_scale(surf->cobj(), &x, &y); - surf->flush(); - } - */ - } catch (const Glib::Exception& exception) { - if (rtengine::settings->verbose) { - std::cerr << "Failed to load image \"" << fileName << "\": " << exception.what() << std::endl; - } - } - - return surf; + this->size = iconSize; + Gtk::Image::set_from_icon_name(iconName, this->size); } diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index eb1930d28..895267dbd 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -3,6 +3,7 @@ * * Copyright (c) 2004-2010 Gabor Horvath * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,44 +21,19 @@ #pragma once #include -#include "rtscalable.h" /** * @brief A derived class of Gtk::Image in order to handle theme-related icon sets. */ -class RTImage final : public Gtk::Image, public RTScalable +class RTImage final : public Gtk::Image { - static double dpiBack; // used to keep track of master dpi change - static int scaleBack; // used to keep track of master scale change - //bool on_configure_event(GdkEventConfigure* configure_event); - -protected: - Cairo::RefPtr surface; - Glib::RefPtr pixbuf; +private: + Gtk::IconSize size; public: RTImage (); - RTImage (RTImage &other); - explicit RTImage (Glib::RefPtr &pixbuf); - explicit RTImage (Cairo::RefPtr &surf); - explicit RTImage(Cairo::RefPtr other); - explicit RTImage (Glib::RefPtr &other); - explicit RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); - - void setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); - void changeImage (const Glib::ustring& imageName); - Cairo::RefPtr get_surface(); - int get_width(); - int get_height(); - - - static void init(); - static void cleanup(bool all = false); - static void updateImages (); - static void setDPInScale (const double newDPI, const int newScale); - static void setScale (const int newScale); - - static Glib::RefPtr createPixbufFromFile (const Glib::ustring& fileName); - static Cairo::RefPtr createImgSurfFromFile (const Glib::ustring& fileName); + explicit RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize = Gtk::ICON_SIZE_SMALL_TOOLBAR); + void set_from_icon_name(const Glib::ustring& iconName); + void set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize); }; diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 78202326a..09fb82205 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -2,6 +2,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,47 +19,221 @@ */ #include "rtscalable.h" -#include -#include -#include + #include #include -#include "../rtengine/rt_math.h" -#include "options.h" +#include "../rtengine/settings.h" +#include "config.h" +#include "guiutils.h" -double RTScalable::dpi = 0.; -int RTScalable::scale = 0; +// Default static parameter values +double RTScalable::dpi = 96.; +int RTScalable::scale = 1; -extern Glib::ustring argv0; -extern unsigned char initialGdkScale; -extern float fontScale; -Gtk::TextDirection RTScalable::direction = Gtk::TextDirection::TEXT_DIR_NONE; +void RTScalable::updateDPInScale(const Gtk::Window* window, double &newDPI, int &newScale) +{ + if (window) { + const auto screen = window->get_screen(); + newDPI = screen->get_resolution(); // Get DPI retrieved from the OS + newScale = window->get_scale_factor(); // Get scale factor associated to the window + } +} + +Cairo::RefPtr RTScalable::loadSurfaceFromIcon(const Glib::ustring &iconName, const Gtk::IconSize iconSize) +{ + GThreadLock lock; // All icon theme access or image access on separate thread HAVE to be protected + + Cairo::RefPtr surf; // Create Cairo::RefPtr nullptr + + // Get icon theme + const auto theme = Gtk::IconTheme::get_default(); + + // Get pixel size from Gtk::IconSize + int wSize, hSize; + + if (!Gtk::IconSize::lookup(iconSize, wSize, hSize)) { // Size in invalid + wSize = hSize = 16; // Set to a default size of 16px (i.e. Gtk::ICON_SIZE_SMALL_TOOLBAR one) + } + + // Get scale based on DPI and scale + // Note: hSize not used because icon are considered squared + const int size = wSize; + + // Looking for corresponding icon (if existing) + const auto iconInfo = theme->lookup_icon(iconName, size); + const auto iconPath = iconInfo.get_filename(); + + if ((iconPath.empty() || !iconInfo) && rtengine::settings->verbose) { + std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; + return surf; + } + + // Create surface from corresponding icon + const auto pos = iconPath.find_last_of('.'); + + if (pos >= 0 && pos < iconPath.length()) { + const auto fext = iconPath.substr(pos + 1, iconPath.length()).lowercase(); + + // Case where iconPath is a PNG file + if (fext == "png") { + // Create surface from PNG file + surf = RTScalable::loadSurfaceFromPNG(iconPath, true); + } + + // Case where iconPath is a SVG file + if (fext == "svg") { + // Create surface from SVG file + surf = RTScalable::loadSurfaceFromSVG(iconPath, size, size, true); + } + } + + /* + // Scale current surface size to desired scaled size + if (surface) { + // Note: surface is considered made from squared icon + const double scale_factor = static_cast(size) / static_cast(surface->get_width()); + surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, + static_cast(surface->get_width() * scale_factor + 0.5), + static_cast(surface->get_height() * scale_factor + 0.5)); + const auto cr = Cairo::Context::create(surf); + cr->scale(scale_factor, scale_factor); + cr->set_source(surface, 0, 0); + cr->paint(); + } + */ + + return surf; +} + +Cairo::RefPtr RTScalable::loadSurfaceFromPNG(const Glib::ustring &fname, const bool is_path) +{ + GThreadLock lock; // All icon theme access or image access on separate thread HAVE to be protected + + Cairo::RefPtr surf; // Create Cairo::RefPtr nullptr + + Glib::ustring path; + + if (is_path) { + // Directly use fname as a path + path = fname; + } else { + // Look for PNG file in "images" folder + Glib::ustring imagesFolder = Glib::build_filename(DATA_SEARCH_PATH, "images"); + path = Glib::build_filename(imagesFolder, fname); + } + + // Create surface from PNG file if file exist + if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { + surf = Cairo::ImageSurface::create_from_png(path); + } else { + if (rtengine::settings->verbose) { + std::cerr << "Failed to load PNG file \"" << fname << "\"" << std::endl; + } + } + + return surf; +} + +Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::ustring &fname, const int width, const int height, const bool is_path) +{ + GThreadLock lock; // All icon theme access or image access on separate thread HAVE to be protected + + Cairo::RefPtr surf; // Create Cairo::RefPtr nullptr + + Glib::ustring path; + + if (is_path) { + // Directly use fname as a path + path = fname; + } else { + // Look for PNG file in "images" folder + Glib::ustring imagesFolder = Glib::build_filename(DATA_SEARCH_PATH, "images"); + path = Glib::build_filename(imagesFolder, fname); + } + + // Create surface from SVG file if file exist + if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { + // Read content of SVG file + std::string svgFile; + try { + svgFile = Glib::file_get_contents(path); + } + catch (Glib::FileError &err) { + std::cerr << "Failed to load SVG file \"" << fname << "\": " << err.what() << std::endl; + return surf; + } + + // Create surface with librsvg library + GError* error = nullptr; + RsvgHandle* handle = rsvg_handle_new_from_data((unsigned const char*)svgFile.c_str(), svgFile.length(), &error); + + if (error) { + std::cerr << "Failed to load SVG file \"" << fname << "\": " << std::endl + << Glib::ustring(error->message) << std::endl; + return surf; + } + + if (width == -1 || height == -1) { + // Use SVG image natural width and height + RsvgDimensionData dim; + rsvg_handle_get_dimensions(handle, &dim); // Get SVG image dimensions + surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, dim.width, dim.height); + } else { + // Use given width and height + surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, width, height); + } + + // Render (and erase with) default surface background + Cairo::RefPtr c = Cairo::Context::create(surf); + c->set_source_rgba (0., 0., 0., 0.); + c->set_operator (Cairo::OPERATOR_CLEAR); + c->paint(); + + // Render surface based on SVG image + error = nullptr; + RsvgRectangle rect = { + .x = 0., + .y = 0., + .width = static_cast(width * RTScalable::getScale()), // SVG image is upscaled to avoid blur effect + .height = static_cast(height * RTScalable::getScale()) // SVG image is upscaled to avoid blur effect + }; + c->set_operator (Cairo::OPERATOR_OVER); + c->scale(1. / RTScalable::getScale(), 1. / RTScalable::getScale()); // Cairo surface is scaled to match image dimensions + + const bool success = rsvg_handle_render_document(handle, c->cobj(), &rect, &error); + + if (!success && error) { + std::cerr << "Failed to load SVG file \"" << fname << "\": " << std::endl + << Glib::ustring(error->message) << std::endl; + return surf; + } + + rsvg_handle_free(handle); + } else { + if (rtengine::settings->verbose) { + std::cerr << "Failed to load SVG file \"" << fname << "\"" << std::endl; + } + } + + return surf; +} + +void RTScalable::init(const Gtk::Window* window) +{ + // Retrieve DPI and Scale paremeters from OS + updateDPInScale(window, dpi, scale); +} + +void RTScalable::setDPInScale (const Gtk::Window* window) +{ + updateDPInScale(window, dpi, scale); +} void RTScalable::setDPInScale (const double newDPI, const int newScale) { - if (!options.pseudoHiDPISupport) { - scale = 1; - dpi = baseDPI; - return; - } - - if (scale != newScale || (scale == 1 && dpi != newDPI)) { - // reload all images - scale = newScale; - // HOMBRE: On windows, if scale = 2, the dpi is non significant, i.e. should be considered = 192 ; don't know for linux/macos - dpi = newDPI; - if (scale == 1) { - if (dpi >= baseHiDPI) { - scale = 2; - } - } - else if (scale == 2) { - if (dpi < baseHiDPI) { - dpi *= 2.; - } - } - } + dpi = newDPI; + scale = newScale; } double RTScalable::getDPI () @@ -66,188 +241,26 @@ double RTScalable::getDPI () return dpi; } -double RTScalable::getTweakedDPI () -{ - return dpi * static_cast(fontScale); -} - int RTScalable::getScale () { return scale; } -Gtk::TextDirection RTScalable::getDirection() +double RTScalable::getGlobalScale() { - return direction; + return (static_cast(RTScalable::getDPI()) / + static_cast(RTScalable::baseDPI) * + RTScalable::getScale()); } -void RTScalable::init(Gtk::Window *window) +int RTScalable::scalePixelSize(const int pixel_size) { - dpi = 0.; - scale = 0; - - setDPInScale(window->get_screen()->get_resolution(), rtengine::max((int)initialGdkScale, window->get_scale_factor())); - direction = window->get_direction(); + const double s = getGlobalScale(); + return static_cast(pixel_size * s + 0.5); // Rounded scaled size } -void RTScalable::deleteDir(const Glib::ustring& path) +double RTScalable::scalePixelSize(const double pixel_size) { - int error = 0; - try { - - Glib::Dir dir (path); - - // Removing the directory content - for (auto entry = dir.begin(); entry != dir.end(); ++entry) { - error |= g_remove (Glib::build_filename (path, *entry).c_str()); - } - - if (error != 0 && rtengine::settings->verbose) { - std::cerr << "Failed to delete all entries in '" << path << "': " << g_strerror(errno) << std::endl; - } - - } catch (Glib::Error&) { - error = 1; - } - - // Removing the directory itself - if (!error) { - try { - - error = g_remove (path.c_str()); - - } catch (Glib::Error&) {} - } -} - -void RTScalable::cleanup(bool all) -{ - Glib::ustring imagesCacheFolder = Glib::build_filename (options.cacheBaseDir, "svg2png"); - Glib::ustring sDPI = Glib::ustring::compose("%1", (int)getTweakedDPI()); - - try { - Glib::Dir dir(imagesCacheFolder); - - for (Glib::DirIterator entry = dir.begin(); entry != dir.end(); ++entry) { - const Glib::ustring fileName = *entry; - const Glib::ustring filePath = Glib::build_filename(imagesCacheFolder, fileName); - if (fileName == "." || fileName == ".." || !Glib::file_test(filePath, Glib::FILE_TEST_IS_DIR)) { - continue; - } - - if (all || fileName != sDPI) { - deleteDir(filePath); - } - } - } catch (Glib::Exception&) { - } - -} - -/* - * This function try to find the svg file converted to png in a cache and return - * the Cairo::ImageSurface. If it can't find it, it will generate it. - * - * If the provided filename doesn't end with ".svg" (and then we're assuming it's a png file), - * it will try to load that file directly from the source images folder. Scaling is disabled - * for anything else than svg files. - * - * This function will always return a usable value, but it might be a garbage image - * if something went wrong. - */ -Cairo::RefPtr RTScalable::loadImage(const Glib::ustring &fname, double dpi) -{ - // Magic color : #2a7fff - // Dark theme color : #CCCCCC - // Light theme color : #252525 -- not used - - Glib::ustring imagesFolder = Glib::build_filename (argv0, "images"); - Glib::ustring imagesCacheFolder = Glib::build_filename (options.cacheBaseDir, "svg2png"); - - // -------------------- Looking for the cached PNG file first -------------------- - - Glib::ustring imagesCacheFolderDPI = Glib::build_filename (imagesCacheFolder, Glib::ustring::compose("%1", (int)dpi)); - auto path = Glib::build_filename(imagesCacheFolderDPI, fname); - - if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { - return Cairo::ImageSurface::create_from_png(path); - } else { - - // -------------------- Looking for the PNG file in install directory -------------------- - - path = Glib::build_filename(imagesFolder, fname); - if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { - return Cairo::ImageSurface::create_from_png(path); - } - } - - // Last chance: looking for the svg file and creating the cached image file - - // -------------------- Creating the cache folder for PNGs -------------------- - - if (!Glib::file_test(imagesCacheFolderDPI.c_str(), Glib::FILE_TEST_EXISTS)) { - auto error = g_mkdir_with_parents (imagesCacheFolderDPI.c_str(), 0777); - if (error != 0) { - std::cerr << "ERROR: Can't create \"" << imagesCacheFolderDPI << "\" cache folder: " << g_strerror(error) << std::endl; - Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); - return surf; - } - } - - // -------------------- Loading the SVG file -------------------- - - std::string svgFile; - Glib::ustring iconNameSVG; - if (fname.find(".png") != Glib::ustring::npos) { - iconNameSVG = fname.substr(0, fname.length() - 3) + Glib::ustring("svg"); - } - try { - path = Glib::build_filename (imagesFolder, iconNameSVG); - //printf("Trying to get content of %s\n", path.c_str()); - svgFile = Glib::file_get_contents(Glib::build_filename (imagesFolder, iconNameSVG)); - } - catch (Glib::FileError &err) { - std::cerr << "ERROR: " << err.what() << std::endl; - Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); - return surf; - } - - // -------------------- Updating the the magic color -------------------- - - std::string updatedSVG = std::regex_replace(svgFile, std::regex("#2a7fff"), "#CCCCCC"); - - // -------------------- Creating the rsvg handle -------------------- - - GError **error = nullptr; - RsvgHandle *handle = rsvg_handle_new_from_data((unsigned const char*)updatedSVG.c_str(), updatedSVG.length(), error); - - if (error && !handle) { - std::cerr << "ERROR: Can't use the provided data for \"" << fname << "\" to create a RsvgHandle:" << std::endl - << Glib::ustring((*error)->message) << std::endl; - Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); - return surf; - } - - // -------------------- Drawing the image to a Cairo::ImageSurface -------------------- - - RsvgDimensionData dim; - rsvg_handle_get_dimensions(handle, &dim); - double r = dpi / baseDPI; - Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, (int)(dim.width * r + 0.499), (int)(dim.height * r + 0.499)); - Cairo::RefPtr c = Cairo::Context::create(surf); - c->set_source_rgba (0., 0., 0., 0.); - c->set_operator (Cairo::OPERATOR_CLEAR); - c->paint (); - c->set_operator (Cairo::OPERATOR_OVER); - c->scale(r, r); - rsvg_handle_render_cairo(handle, c->cobj()); - rsvg_handle_free(handle); - - // -------------------- Saving the image in cache -------------------- - - surf->write_to_png(Glib::build_filename(imagesCacheFolderDPI, fname)); - - // -------------------- Finished! Pfeeew ! -------------------- - - return surf; + const double s = getGlobalScale(); + return (pixel_size * s); } diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index 28ebf7be8..f78c3bf3d 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -2,6 +2,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,39 +20,52 @@ #pragma once -#include +#include /** - * @brief A master class for derived class of Gtk::Image in order to handle theme-related icon sets. + * A static class in order to handle Hi-DPI. + * + * About Cairo size convention (for surface): + * Cairo size is expressed in "px" with a 96 DPI (i.e. px per inch) default resolution + * + * About Pango size convention (for font): + * Pango size can be expressed in two different units: + * - Absolute size (i.e. "px"): If size is int type, absolute size is given in "Pango unit" + * shall be divided by Pango::SCALE (i.e. 1024) to get "px". If size is double, absolute + * is already given in "px". + * - Non-absolute size (i.e. "pt"): The default resolution is 72 DPI (i.e. pt per inch). To + * convert the size to "px", use the following formula: + * "size in px" = "size in pt" * ("device resolution" / 72) * "device scale" + * + * Hi-DPI implementation according to the OS (source: GDK code): + * - Windows: A default DPI of 96 is considered. Current DPI parameter is provided by the OS. + * Scale is calculated by (int)("current DPI" / 96). If Scale is greater than 1, DPI is + * forced to 96. + * - MacOS: Scale is calculated from OS parameters (= "Retina screen width" / "Virtual width"). + * DPI is forced to 72. + * - Linux: DPI is calculated from OS parameter (= 96 * "text-scaling-factor"). */ class RTScalable { +private: static double dpi; static int scale; - static Gtk::TextDirection direction; // cached value for text-direction - static void deleteDir(const Glib::ustring& path); + static void updateDPInScale(const Gtk::Window* window, double &newDPI, int &newScale); protected: - static void setDPInScale (const double newDPI, const int newScale); - static Cairo::RefPtr loadImage(const Glib::ustring &fname, double dpi); - static Gtk::TextDirection getDirection(); - + static Cairo::RefPtr loadSurfaceFromIcon(const Glib::ustring &icon_name, const Gtk::IconSize iconSize = Gtk::ICON_SIZE_SMALL_TOOLBAR); + static Cairo::RefPtr loadSurfaceFromPNG(const Glib::ustring &fname, const bool is_path = false); + static Cairo::RefPtr loadSurfaceFromSVG(const Glib::ustring &fname, const int width = -1, const int height = -1, const bool is_path = false); public: - -#ifdef __APPLE__ - static constexpr double baseDPI = 72.; - static constexpr double baseHiDPI = 144.; - static constexpr int baseFontSize = 12; -#else - static constexpr double baseDPI = 96.; - static constexpr double baseHiDPI = 192.; - static constexpr int baseFontSize = 9; -#endif - - static void init(Gtk::Window *window); - static void cleanup(bool all = false); - static double getDPI (); - static double getTweakedDPI (); // The returned value is tweaked DPI to adapt to main the font size. Maybe not an ideal solution. - static int getScale (); + static constexpr double pangoDPI = 72.; // Pango default DPI for "pt" size + static constexpr double baseDPI = 96.; // Cairo default DPI + static void init(const Gtk::Window* window); + static void setDPInScale(const Gtk::Window* window); + static void setDPInScale(const double newDPI, const int newScale); + static double getDPI(); + static int getScale(); + static double getGlobalScale(); + static int scalePixelSize(const int pixel_size); + static double scalePixelSize(const double pixel_size); }; diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index 62dfe36d5..46bddcaa1 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -2,6 +2,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,37 +24,69 @@ #include "options.h" -namespace -{ - -using SurfaceCache = std::map>; - -SurfaceCache surfaceCache; - -} - RTSurface::RTSurface() : surface(new Cairo::ImageSurface(nullptr, false)) { + // Initialize "back" parameters from RTScalable + dpiBack = RTScalable::getDPI(); + scaleBack = RTScalable::getScale(); + + // Initialize other private parameters + type = RTSurface::InvalidType; + name = ""; + icon_size = Gtk::ICON_SIZE_INVALID; } -RTSurface::RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName) : +RTSurface::RTSurface(const Glib::ustring &icon_name, const Gtk::IconSize iconSize) : RTSurface() { - setImage(fileName, rtlFileName); + // Create surface + surface = RTScalable::loadSurfaceFromIcon(icon_name, iconSize); + + if (surface) { + // Save private parameters + type = RTSurface::IconType; + name = icon_name; + icon_size = iconSize; + } } -void RTSurface::setImage(const Glib::ustring& fileName, const Glib::ustring& rtlFileName) +RTSurface::RTSurface(const Glib::ustring &fname) : + RTSurface() { - const Glib::ustring& imageName = - !rtlFileName.empty() && getDirection() == Gtk::TEXT_DIR_RTL - ? rtlFileName - : fileName; + // Create surface based on file extension + const auto pos = fname.find_last_of('.'); - changeImage (imageName); + if (pos >= 0 && pos < fname.length()) { + const auto fext = fname.substr(pos + 1, fname.length()).lowercase(); + + // Case where fname is a PNG file + if (fext == "png") { + // Create surface from PNG file + surface = RTScalable::loadSurfaceFromPNG(fname); + + if (surface) { + // Save private parameter + type = RTSurface::PNGType; + name = fname; + } + } + + // Case where fname is a SVG file + if (fext == "svg") { + // Create surface from SVG file + surface = RTScalable::loadSurfaceFromSVG(fname); + + if (surface) { + // Save private parameter + type = RTSurface::SVGType; + name = fname; + } + } + } } -int RTSurface::getWidth() const +int RTSurface::getWidth() { return surface @@ -61,7 +94,7 @@ int RTSurface::getWidth() const : -1; } -int RTSurface::getHeight() const +int RTSurface::getHeight() { return surface @@ -69,77 +102,156 @@ int RTSurface::getHeight() const : -1; } -bool RTSurface::hasSurface() const +bool RTSurface::hasSurface() { return static_cast(surface); } -Cairo::RefPtr RTSurface::get() const +Cairo::RefPtr RTSurface::get() { - return surface; -} + if (dpiBack != RTScalable::getDPI() || + scaleBack != RTScalable::getScale()) { + switch (type) { + case RTSurface::IconType : + surface = RTScalable::loadSurfaceFromIcon(name, icon_size); + break; + case RTSurface::PNGType : + surface = RTScalable::loadSurfaceFromPNG(name); + break; + case RTSurface::SVGType : + surface = RTScalable::loadSurfaceFromSVG(name); + break; + default : + break; + } -const Cairo::RefPtr& RTSurface::get() -{ - return surface; -} - -void RTSurface::init() -{ - dpiBack = getDPI(); - scaleBack = getScale(); -} - -void RTSurface::updateImages() -{ - const double tweakedDpi = getTweakedDPI(); - - for (auto& entry : surfaceCache) { - entry.second = loadImage(entry.first, tweakedDpi); - } -} - -void RTSurface::setDPInScale(const double newDPI, const int newScale) -{ - if ( - getScale() != newScale - || ( - getScale() == 1 - && getDPI() != newDPI - ) - ) { - setDPInScale(newDPI, newScale); - dpiBack = getDPI(); - scaleBack = getScale(); - - updateImages(); - } -} - -void RTSurface::changeImage(const Glib::ustring& imageName) -{ - const SurfaceCache::const_iterator iterator = surfaceCache.find(imageName); - - if (iterator != surfaceCache.end()) { - surface = iterator->second; - } else { - surface = loadImage(imageName, getTweakedDPI()); - - // HOMBRE: As of now, GDK_SCALE is forced to 1, so setting the Cairo::ImageSurface scale is not required - // Anyway, this might be of use one day - /* - double x=0., y=0.; - cairo_surface_get_device_scale(surface->cobj(), &x, &y); - if (getScale() == 2) { - cairo_surface_set_device_scale(surface->cobj(), 0.5, 0.5); // Not sure if it should be 0.5 or 2.0 here ! - surface->flush(); + // Save new DPI and scale + dpiBack = RTScalable::getDPI(); + scaleBack = RTScalable::getScale(); } - */ - surfaceCache.emplace(imageName, surface); + return surface; +} + +RTPixbuf::RTPixbuf() +{ + // Initialize "back" parameters from RTScalable + dpiBack = RTPixbuf::getDPI(); + scaleBack = RTPixbuf::getScale(); + + // Initialize other private parameters + type = RTPixbuf::InvalidType; + name = ""; + icon_size = Gtk::ICON_SIZE_INVALID; +} + +RTPixbuf::RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize) : + RTPixbuf() +{ + // Create surface + const Cairo::RefPtr surface = RTScalable::loadSurfaceFromIcon(icon_name, iconSize); + + if (surface) { + // Create pixbuf from surface + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + + // Save private parameters + type = RTPixbuf::IconType; + name = icon_name; + icon_size = iconSize; } } -double RTSurface::dpiBack = 0.; +RTPixbuf::RTPixbuf(const Glib::ustring &fname) : + RTPixbuf() +{ + // Create surface based on file extension + const auto pos = fname.find_last_of('.'); -int RTSurface::scaleBack = 0; + if (pos >= 0 && pos < fname.length()) { + const auto fext = fname.substr(pos + 1, fname.length()).lowercase(); + + // Case where fname is a PNG file + if (fext == "png") { + // Create surface from PNG file + const Cairo::RefPtr surface = RTScalable::loadSurfaceFromPNG(fname); + + if (surface) { + // Create pixbuf from surface + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + + // Save private parameter + type = RTPixbuf::PNGType; + name = fname; + } + } + + // Case where fname is a SVG file + if (fext == "svg") { + // Create surface from SVG file + const Cairo::RefPtr surface = RTScalable::loadSurfaceFromSVG(fname); + + if (surface) { + // Create pixbuf from surface + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + + // Save private parameter + type = RTPixbuf::SVGType; + name = fname; + } + } + } +} + +int RTPixbuf::getWidth() +{ + return + pixbuf + ? pixbuf->get_width() + : -1; +} + +int RTPixbuf::getHeight() +{ + return + pixbuf + ? pixbuf->get_height() + : -1; +} + +bool RTPixbuf::hasPixbuf() +{ + return static_cast(pixbuf); +} + +Glib::RefPtr RTPixbuf::get() +{ + if (dpiBack != RTScalable::getDPI() || + scaleBack != RTScalable::getScale()) { + Cairo::RefPtr surface; + + // Surface needs to be regenerated + switch (type) { + case RTPixbuf::IconType : + surface = RTScalable::loadSurfaceFromIcon(name, icon_size); + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + break; + case RTPixbuf::PNGType : + surface = RTScalable::loadSurfaceFromPNG(name); + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + break; + case RTPixbuf::SVGType : + surface = RTScalable::loadSurfaceFromSVG(name); + pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + break; + default : + break; + } + + // Save new DPI and scale + dpiBack = RTScalable::getDPI(); + scaleBack = RTScalable::getScale(); + } + + return pixbuf; +} diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index 1944cc2dc..46a8bcdb5 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -2,6 +2,7 @@ * This file is part of RawTherapee. * * Copyright (c) 2018 Jean-Christophe FRISCH + * Copyright (c) 2022 Pierre CABRERA * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,37 +19,70 @@ */ #pragma once -#include - #include "rtscalable.h" /** - * @brief A derived class of Gtk::Image in order to handle theme-related icon sets. + * @brief A custom class in order to handle Hi-DPI surface. */ -class RTSurface : - public RTScalable +class RTSurface final : public RTScalable { public: - RTSurface(); - explicit RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); - - void setImage(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); - - int getWidth() const; - int getHeight() const; - bool hasSurface() const; - - Cairo::RefPtr get() const; - const Cairo::RefPtr& get(); - - static void init(); - static void updateImages(); - static void setDPInScale(double newDPI, int newScale); + enum RTSurfaceType { + InvalidType = 1, + IconType = 2, + PNGType = 3, + SVGType = 4 + }; private: - void changeImage(const Glib::ustring& imageName); - - static double dpiBack; // used to keep track of master dpi change - static int scaleBack; // used to keep track of master scale change + double dpiBack; // Used to identify dpi change + int scaleBack; // Used to identify scale change + RTSurfaceType type; + Glib::ustring name; + Gtk::IconSize icon_size; Cairo::RefPtr surface; + +public: + RTSurface(); + explicit RTSurface(const Glib::ustring &icon_name, const Gtk::IconSize iconSize); + explicit RTSurface(const Glib::ustring &fname); + + int getWidth(); + int getHeight(); + bool hasSurface(); + + Cairo::RefPtr get(); +}; + +/** + * @brief A custom class in order to handle Hi-DPI pixbuf. + */ +class RTPixbuf final : public RTScalable +{ +public: + enum RTPixbufType { + InvalidType = 1, + IconType = 2, + PNGType = 3, + SVGType = 4 + }; + +private: + double dpiBack; // Used to identify dpi change + int scaleBack; // Used to identify scale change + RTPixbufType type; + Glib::ustring name; + Gtk::IconSize icon_size; + Glib::RefPtr pixbuf; + +public: + RTPixbuf(); + explicit RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize); + explicit RTPixbuf(const Glib::ustring &fname); + + int getWidth(); + int getHeight(); + bool hasPixbuf(); + + Glib::RefPtr get(); }; diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 1b90d631b..9ea9dec5a 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -34,12 +34,9 @@ #include "filepanel.h" #include "filmsimulation.h" -float fontScale = 1.f; Glib::RefPtr cssForced; Glib::RefPtr cssRT; -extern unsigned char initialGdkScale; - #if defined(__APPLE__) static gboolean osx_should_quit_cb (GtkosxApplication *app, gpointer data) @@ -104,10 +101,6 @@ RTWindow::RTWindow () , epanel (nullptr) , fpanel (nullptr) { - - if (options.is_new_version()) { - RTImage::cleanup(true); - } cacheMgr->init (); ProfilePanel::init (this); @@ -116,9 +109,15 @@ RTWindow::RTWindow () Glib::RefPtr screen = Gdk::Screen::get_default(); if (screen) { + // Setting default theme and icon theme (bases for custom themes) Gtk::Settings::get_for_screen (screen)->property_gtk_theme_name() = "Adwaita"; Gtk::Settings::get_for_screen (screen)->property_gtk_application_prefer_dark_theme() = true; + Gtk::Settings::get_for_screen (screen)->property_gtk_icon_theme_name() = "RawTherapee"; + // Initialize RTScalable for Hi-DPI support + RTScalable::init(this); + + // Look for theme and set it Glib::RefPtr regex = Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); Glib::ustring filename; Glib::MatchInfo mInfo; @@ -169,63 +168,84 @@ RTWindow::RTWindow () // Set the font face and size Glib::ustring css; - if (options.fontFamily != "default") { - //GTK318 - #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 - css = Glib::ustring::compose ("* { font-family: %1; font-size: %2px}", options.fontFamily, options.fontSize * (int)initialGdkScale); - #else - css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt}", options.fontFamily, options.fontSize * (int)initialGdkScale); - #endif - //GTK318 - if (options.pseudoHiDPISupport) { - fontScale = options.fontSize / (float)RTScalable::baseFontSize; - } + +#ifndef __APPLE__ + const double fontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + auto style = get_pango_context(); + + if (options.fontFamily != "default") { // Set font and size according to user choice + // Scale font size based on DPI and Scale + const int scaledFontSize = static_cast(options.fontSize * fontScale + 0.5); + + // Set font and size in css + css = Glib::ustring::compose ("* { font-family: %1; font-size: %2px}", options.fontFamily, scaledFontSize); + if (rtengine::settings->verbose) { - printf("\"Non-Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", options.fontSize, (int)initialGdkScale, static_cast(fontScale)); + printf("\"Non-Default\" font size in pt(%d) * scale(%.3f) = font size in px(%d)\n", options.fontSize, fontScale, scaledFontSize); } - } else { + } else { // Set font and size according to default values + // Retrieve default style values Glib::RefPtr style = Gtk::StyleContext::create(); Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); + if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { - int pt; - int fontSize = pfd.get_size(); - bool isPix = pfd.get_size_is_absolute(); - int resolution = (int)style->get_screen()->get_resolution(); - if (isPix) { - // HOMBRE: guessing here... - // if resolution is lower than baseHiDPI, we're supposing that it's already expressed in a scale==1 scenario - if (resolution >= int(RTScalable::baseHiDPI)) { - // converting the resolution to a scale==1 scenario - resolution /= 2; - } - // 1pt = 1/72in @ 96 ppi - // HOMBRE: If the font unit is px, is it already scaled up to match the resolution ? - // px >inch >pt >"scaled pt" - pt = (int)(double(fontSize) / RTScalable::baseDPI * 72. * (96. / (double)resolution) + 0.49); - } else { - pt = fontSize / Pango::SCALE; - } - if (options.pseudoHiDPISupport) { - fontScale = (float)pt / (float)RTScalable::baseFontSize; - } - if ((int)initialGdkScale > 1 || pt != RTScalable::baseFontSize) { - css = Glib::ustring::compose ("* { font-size: %1pt}", pt * (int)initialGdkScale); + const int fontSize = pfd.get_size(); + const bool isAbsoluteFontSize = pfd.get_size_is_absolute(); + int newFontSize; + + if (isAbsoluteFontSize) { + // Absolute size is defined in "Pango units" and shall be divided by + // Pango::SCALE to get "px" + newFontSize = fontSize / Pango::SCALE; + + // Guessing that pixel size is given for a 96 DPI reference: +#ifndef __APPLE__ + const double newFontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double newFontScale = 1.; +#endif + newFontSize = static_cast(newFontSize * newFontScale + 0.5); + if (rtengine::settings->verbose) { - printf("\"Default\" font size(%d) * scale(%d) / fontScale(%.3f)\n", pt, (int)initialGdkScale, static_cast(fontScale)); + printf("\"Default\" absolute font size(%d)\n", newFontSize); + } + } else { + // Non-absolute size is defined in "pt" and shall be converted to "px" + newFontSize = static_cast(fontSize * fontScale + 0.5); + + if (rtengine::settings->verbose) { + printf("\"Default\" non-absolute font size in pt(%d) * scale(%.3f) = font size in px(%d)\n", fontSize, fontScale, newFontSize); } } + + // Set font and size in css + css = Glib::ustring::compose ("* { font-size: %1px}", newFontSize); + printf("newFontSize: %d\n", newFontSize); } } + + // Load custom CSS for font if (!css.empty()) { if (rtengine::settings->verbose) { printf("CSS:\n%s\n\n", css.c_str()); } + try { cssForced = Gtk::CssProvider::create(); cssForced->load_from_data (css); Gtk::StyleContext::add_provider_for_screen (screen, cssForced, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - } catch (Glib::Error &err) { printf ("Error: \"%s\"\n", err.what().c_str()); } catch (...) { @@ -236,22 +256,10 @@ RTWindow::RTWindow () // ------- end loading theme files - RTScalable::init(this); - RTSurface::init(); - RTImage::init(); - WhiteBalance::init(); - MyExpander::init(); - + // For UNIX system, set app icon #ifndef WIN32 - const std::vector> appIcons = { - RTImage::createPixbufFromFile("rawtherapee-logo-16.png"), - RTImage::createPixbufFromFile("rawtherapee-logo-24.png"), - RTImage::createPixbufFromFile("rawtherapee-logo-48.png"), - RTImage::createPixbufFromFile("rawtherapee-logo-128.png"), - RTImage::createPixbufFromFile("rawtherapee-logo-256.png") - }; try { - set_default_icon_list(appIcons); + set_default_icon_name("rawtherapee"); } catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } @@ -324,11 +332,11 @@ RTWindow::RTWindow () if (options.mainNBVertical) { mainNB->set_tab_pos (Gtk::POS_LEFT); fpl->set_angle (90); - RTImage* folderIcon = Gtk::manage (new RTImage ("folder-closed.png")); + RTImage* folderIcon = Gtk::manage (new RTImage ("folder-closed", Gtk::ICON_SIZE_LARGE_TOOLBAR)); fpanelLabelGrid->attach_next_to (*folderIcon, Gtk::POS_TOP, 1, 1); fpanelLabelGrid->attach_next_to (*fpl, Gtk::POS_TOP, 1, 1); } else { - RTImage* folderIcon = Gtk::manage (new RTImage ("folder-closed.png")); + RTImage* folderIcon = Gtk::manage (new RTImage ("folder-closed", Gtk::ICON_SIZE_LARGE_TOOLBAR)); fpanelLabelGrid->attach_next_to (*folderIcon, Gtk::POS_RIGHT, 1, 1); fpanelLabelGrid->attach_next_to (*fpl, Gtk::POS_RIGHT, 1, 1); } @@ -361,27 +369,27 @@ RTWindow::RTWindow () //mainBox->pack_start (*mainNB); // filling bottom box - iFullscreen = new RTImage ("fullscreen-enter.png"); - iFullscreen_exit = new RTImage ("fullscreen-leave.png"); + iFullscreen = new RTImage ("fullscreen-enter", Gtk::ICON_SIZE_LARGE_TOOLBAR); + iFullscreen_exit = new RTImage ("fullscreen-leave", Gtk::ICON_SIZE_LARGE_TOOLBAR); Gtk::Button* iccProfileCreator = Gtk::manage (new Gtk::Button ()); setExpandAlignProperties (iccProfileCreator, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); iccProfileCreator->set_relief(Gtk::RELIEF_NONE); - iccProfileCreator->set_image (*Gtk::manage (new RTImage ("gamut-plus.png"))); + iccProfileCreator->set_image (*Gtk::manage (new RTImage ("gamut-plus", Gtk::ICON_SIZE_LARGE_TOOLBAR))); iccProfileCreator->set_tooltip_markup (M ("MAIN_BUTTON_ICCPROFCREATOR")); iccProfileCreator->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::showICCProfileCreator) ); Gtk::Button* helpBtn = Gtk::manage (new Gtk::Button ()); setExpandAlignProperties (helpBtn, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); helpBtn->set_relief(Gtk::RELIEF_NONE); - helpBtn->set_image (*Gtk::manage (new RTImage ("questionmark.png"))); + helpBtn->set_image (*Gtk::manage (new RTImage("questionmark", Gtk::ICON_SIZE_LARGE_TOOLBAR))); helpBtn->set_tooltip_markup (M ("GENERAL_HELP")); helpBtn->signal_clicked().connect (sigc::mem_fun (*this, &RTWindow::showRawPedia)); Gtk::Button* preferences = Gtk::manage (new Gtk::Button ()); setExpandAlignProperties (preferences, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); preferences->set_relief(Gtk::RELIEF_NONE); - preferences->set_image (*Gtk::manage (new RTImage ("preferences.png"))); + preferences->set_image (*Gtk::manage (new RTImage ("preferences", Gtk::ICON_SIZE_LARGE_TOOLBAR))); preferences->set_tooltip_markup (M ("MAIN_BUTTON_PREFERENCES")); preferences->signal_clicked().connect ( sigc::mem_fun (*this, &RTWindow::showPreferences) ); @@ -454,7 +462,6 @@ RTWindow::~RTWindow() delete fpanel; delete iFullscreen; delete iFullscreen_exit; - RTImage::cleanup(); } void RTWindow::on_realize () @@ -529,8 +536,8 @@ bool RTWindow::on_configure_event (GdkEventConfigure* event) get_position (options.windowX, options.windowY); } - RTImage::setDPInScale(RTScalable::getDPI(), RTScalable::getScale()); // will update the RTImage on scale/resolution change - RTSurface::setDPInScale(RTScalable::getDPI(), RTScalable::getScale()); // will update the RTSurface on scale/resolution change + // With update the RTScalable on scale or resolution change + RTScalable::setDPInScale(this); return Gtk::Widget::on_configure_event (event); } @@ -541,7 +548,7 @@ bool RTWindow::on_window_state_event (GdkEventWindowState* event) options.windowMaximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED; is_minimized = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED; is_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; - + return Gtk::Widget::on_window_state_event (event); } @@ -592,7 +599,7 @@ void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) // construct closeable tab for the image Gtk::Grid* titleGrid = Gtk::manage (new Gtk::Grid ()); titleGrid->set_tooltip_markup (name); - RTImage *closebimg = Gtk::manage (new RTImage ("cancel-small.png")); + RTImage *closebimg = Gtk::manage (new RTImage ("cancel-small", Gtk::ICON_SIZE_LARGE_TOOLBAR)); Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); closeb->set_name ("CloseButton"); closeb->add (*closebimg); @@ -601,7 +608,7 @@ void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) closeb->signal_clicked().connect ( sigc::bind (sigc::mem_fun (*this, &RTWindow::remEditorPanel), ep)); if (!EditWindow::isMultiDisplayEnabled()) { - titleGrid->attach_next_to (*Gtk::manage (new RTImage ("aperture.png")), Gtk::POS_RIGHT, 1, 1); + titleGrid->attach_next_to (*Gtk::manage (new RTImage ("aperture", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_RIGHT, 1, 1); } titleGrid->attach_next_to (*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name))), Gtk::POS_RIGHT, 1, 1); titleGrid->attach_next_to (*closeb, Gtk::POS_RIGHT, 1, 1); @@ -855,12 +862,8 @@ bool RTWindow::on_delete_event (GdkEventAny* event) } cacheMgr->closeCache (); // also makes cleanup if too large - WhiteBalance::cleanup(); ProfilePanel::cleanup(); ClutComboBox::cleanup(); - MyExpander::cleanup(); - mainWindowCursorManager.cleanup(); - editWindowCursorManager.cleanup(); BatchQueueEntry::savedAsIcon.reset(); FileBrowserEntry::editedIcon.reset(); FileBrowserEntry::recentlySavedIcon.reset(); @@ -997,7 +1000,7 @@ void RTWindow::error(const Glib::ustring& descr) void RTWindow::toggle_fullscreen () { onConfEventConn.block(true); // Avoid getting size and position while window is getting fullscreen - + if (is_fullscreen) { unfullscreen(); @@ -1013,7 +1016,7 @@ void RTWindow::toggle_fullscreen () btn_fullscreen->set_image (*iFullscreen_exit); } } - + onConfEventConn.block(false); } @@ -1121,7 +1124,7 @@ bool RTWindow::splashClosed (GdkEventAny* event) void RTWindow::setWindowSize () { onConfEventConn.block(true); // Avoid getting size and position while window is being moved, maximized, ... - + Gdk::Rectangle lMonitorRect; const auto display = get_screen()->get_display(); display->get_monitor (std::min (options.windowMonitor, display->get_n_monitors() - 1))->get_geometry(lMonitorRect); @@ -1160,7 +1163,7 @@ void RTWindow::setWindowSize () unmaximize(); resize (options.windowWidth, options.windowHeight); } - + onConfEventConn.block(false); } @@ -1168,7 +1171,7 @@ void RTWindow::get_position(int& x, int& y) const { // Call native function Gtk::Window::get_position (x, y); - + // Retrieve display (concatenation of all monitors) size int width = 0, height = 0; const auto display = get_screen()->get_display(); @@ -1253,7 +1256,7 @@ void RTWindow::createSetmEditor() el->set_angle (90); } - editorLabelGrid->attach_next_to (*Gtk::manage (new RTImage ("aperture.png")), pos, 1, 1); + editorLabelGrid->attach_next_to (*Gtk::manage (new RTImage ("aperture", Gtk::ICON_SIZE_LARGE_TOOLBAR)), pos, 1, 1); editorLabelGrid->attach_next_to (*el, pos, 1, 1); editorLabelGrid->set_tooltip_markup (M ("MAIN_FRAME_EDITOR_TOOLTIP")); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index ad2c28aaa..ac1149893 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -26,14 +26,11 @@ SHCSelector::SHCSelector() : movingPosition(-1), tmpX(0.0), tmpPos(0.0), wslider(0.0), cl(nullptr), coloredBar(RTO_Left2Right) { - - int s = RTScalable::getScale(); - positions[0] = defaults[0] = 0.25; positions[1] = defaults[1] = 0.5; positions[2] = defaults[2] = 0.75; - leftMargin = (RADIUS - 1.5) * s; - rightMargin = (RADIUS - 1.5) * s; + leftMargin = static_cast(RTScalable::scalePixelSize(RADIUS - 1.5)); + rightMargin = static_cast(RTScalable::scalePixelSize(RADIUS - 1.5)); Glib::RefPtr style = get_style_context(); style->add_class("drawingarea"); @@ -62,14 +59,13 @@ void SHCSelector::get_preferred_height_vfunc (int &minimum_height, int &natural_ void SHCSelector::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - int s = RTScalable::getScale(); - minimum_width = 100 * s; - natural_width = 150 * s; + minimum_width = RTScalable::scalePixelSize(100); + natural_width = RTScalable::scalePixelSize(150); } void SHCSelector::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - natural_height = minimum_height = 14 * RTScalable::getScale(); + natural_height = minimum_height = RTScalable::scalePixelSize(14); } void SHCSelector::get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const @@ -141,7 +137,7 @@ void SHCSelector::updateBackBuffer() int w = get_width () - leftMargin - rightMargin; int h = get_height (); - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); wslider = (double)std::max(h / 5, 10) * s; double hwslider = wslider / 2.; @@ -244,7 +240,7 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event) double w = double(get_width () - leftMargin - rightMargin); movingPosition = -1; - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); for (int i = 0; i < 3; i++) { double currPos = double(leftMargin) + 1. * s + (w - 2. * s) * positions[i]; @@ -290,7 +286,7 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) { if (movingPosition >= 0) { - double s = RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double innerw = double(get_width () - leftMargin - rightMargin) - 2. * s; positions[movingPosition] = tmpPos + (event->x - tmpX) / innerw; diff --git a/rtgui/splash.cc b/rtgui/splash.cc index 7ae5bf4d7..b7d118d58 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -21,48 +21,62 @@ #include #include "multilangmgr.h" -#include "rtimage.h" extern Glib::ustring creditsPath; extern Glib::ustring licensePath; extern Glib::ustring versionString; -SplashImage::SplashImage () : surface(RTImage::createImgSurfFromFile("splash.png")) +SplashImage::SplashImage () : surface(new RTSurface("splash.svg")) { } bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { + if (surface->hasSurface()) { + cr->set_source(surface->get(), 0., 0.); + cr->rectangle(0, 0, surface->get()->get_width(), surface->get()->get_height()); + cr->fill(); - cr->set_source(surface, 0., 0.); - cr->rectangle(0, 0, surface->get_width(), surface->get_height()); - cr->fill(); + 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); + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px" + const int fontSize = 12; + const int absoluteFontSize = fontSize * Pango::SCALE; + // Guessing that absolute pixel size is given for a 96 DPI reference: +#ifndef __APPLE__ + const double fontScale = static_cast(RTScalable::getDPI()) + / static_cast(RTScalable::pangoDPI) + * RTScalable::getScale(); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); + context->set_font_description (fontd); - 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); + int w, h; + Glib::ustring versionStr(versionString); - int w, h; - Glib::ustring versionStr(versionString); - - version = create_pango_layout (versionStr); - version->set_text(versionStr); - version->get_pixel_size (w, h); - cr->set_source_rgb (0., 0., 0.); - cr->set_line_width(3.); - cr->set_line_join(Cairo::LINE_JOIN_ROUND); - cr->move_to (surface->get_width() - w - 32, surface->get_height() - h - 20); - version->add_to_cairo_context (cr); - cr->stroke_preserve(); - cr->set_source_rgb (1., 1., 1.); - cr->set_line_width(0.5); - cr->stroke_preserve(); - cr->fill(); + version = create_pango_layout (versionStr); + version->set_text(versionStr); + version->get_pixel_size (w, h); + cr->set_source_rgb (0., 0., 0.); + cr->set_line_width(3.); + cr->set_line_join(Cairo::LINE_JOIN_ROUND); + cr->move_to (surface->get()->get_width() - w - 32, surface->get()->get_height() - h - 20); + version->add_to_cairo_context (cr); + cr->stroke_preserve(); + cr->set_source_rgb (1., 1., 1.); + cr->set_line_width(0.5); + cr->stroke_preserve(); + cr->fill(); + } return true; } @@ -74,12 +88,12 @@ Gtk::SizeRequestMode SplashImage::get_request_mode_vfunc () const void SplashImage::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height = natural_height = surface ? surface->get_height() : 100 * RTScalable::getScale(); + minimum_height = natural_height = surface ? surface->get()->get_height() : RTScalable::scalePixelSize(100); } void SplashImage::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = natural_width = surface ? surface->get_width() : 100 * RTScalable::getScale(); + minimum_width = natural_width = surface ? surface->get()->get_width() : RTScalable::scalePixelSize(100); } void SplashImage::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const @@ -111,6 +125,8 @@ Splash::Splash (Gtk::Window& parent) : Gtk::Dialog(M("GENERAL_ABOUT"), parent, t // Tab 1: the image splashImage = Gtk::manage(new SplashImage ()); + splashImage->set_halign(Gtk::ALIGN_CENTER); + splashImage->set_valign(Gtk::ALIGN_CENTER); nb->append_page (*splashImage, M("ABOUT_TAB_SPLASH")); splashImage->show (); @@ -242,7 +258,6 @@ Splash::Splash (Gtk::Window& parent) : Gtk::Dialog(M("GENERAL_ABOUT"), parent, t } } - set_position (Gtk::WIN_POS_CENTER); //add_events(Gdk::BUTTON_RELEASE_MASK); set_resizable (true); diff --git a/rtgui/splash.h b/rtgui/splash.h index bc63cef91..6abfe91c7 100644 --- a/rtgui/splash.h +++ b/rtgui/splash.h @@ -19,13 +19,14 @@ #pragma once #include +#include "rtsurface.h" class SplashImage final : public Gtk::DrawingArea { private: - Cairo::RefPtr surface; + std::shared_ptr surface; Glib::RefPtr version; public: diff --git a/rtgui/spot.cc b/rtgui/spot.cc index 2f9910b70..34e2f0c18 100644 --- a/rtgui/spot.cc +++ b/rtgui/spot.cc @@ -58,18 +58,18 @@ Spot::Spot() : draggedSide(DraggedSide::NONE), lastObject(-1), activeSpot(-1), - sourceIcon("spot-normal.png", "spot-active.png", "spot-prelight.png", "", "", Geometry::DP_CENTERCENTER), + sourceIcon("spot-normal", "spot-active", "spot-prelight", "", "", Geometry::DP_CENTERCENTER), editedCheckBox(nullptr) { countLabel = Gtk::manage (new Gtk::Label (Glib::ustring::compose (M ("TP_SPOT_COUNTLABEL"), 0))); edit = Gtk::manage (new Gtk::ToggleButton()); - edit->add (*Gtk::manage (new RTImage ("edit-point.png"))); + edit->add (*Gtk::manage (new RTImage ("edit-point"))); editConn = edit->signal_toggled().connect ( sigc::mem_fun (*this, &Spot::editToggled) ); edit->set_tooltip_text(M("TP_SPOT_HINT")); reset = Gtk::manage (new Gtk::Button ()); - reset->add (*Gtk::manage (new RTImage ("undo-small.png"))); + reset->add (*Gtk::manage (new RTImage ("undo-small"))); reset->set_relief (Gtk::RELIEF_NONE); reset->set_border_width (0); reset->signal_clicked().connect ( sigc::mem_fun (*this, &Spot::resetPressed) ); @@ -83,7 +83,7 @@ Spot::Spot() : labelBox->pack_end (*reset, false, false, 0); labelBox->pack_end (*spotSize, false, false, 0); pack_start (*labelBox); - + sourceIcon.datum = Geometry::IMAGE; sourceIcon.setActive (false); sourceIcon.state = Geometry::ACTIVE; @@ -344,12 +344,12 @@ void Spot::createGeometry () EditSubscriber::mouseOverGeometry.at (i++) = &sourceFeatherCircle; // MO_OBJECT_COUNT + 5 // recreate all spots geometry - Cairo::RefPtr normalImg = sourceIcon.getNormalImg(); - Cairo::RefPtr prelightImg = sourceIcon.getPrelightImg(); - Cairo::RefPtr activeImg = sourceIcon.getActiveImg(); + std::shared_ptr normalImg = sourceIcon.getNormalImg(); + std::shared_ptr prelightImg = sourceIcon.getPrelightImg(); + std::shared_ptr activeImg = sourceIcon.getActiveImg(); for (; j < EditSubscriber::visibleGeometry.size() - VISIBLE_OBJECT_COUNT; ++i, ++j) { - EditSubscriber::mouseOverGeometry.at (i) = EditSubscriber::visibleGeometry.at (j) = new OPIcon (normalImg, activeImg, prelightImg, Cairo::RefPtr (nullptr), Cairo::RefPtr (nullptr), Geometry::DP_CENTERCENTER); + EditSubscriber::mouseOverGeometry.at (i) = EditSubscriber::visibleGeometry.at (j) = new OPIcon (normalImg, activeImg, prelightImg, nullptr, nullptr, Geometry::DP_CENTERCENTER); EditSubscriber::visibleGeometry.at (j)->setActive (true); EditSubscriber::visibleGeometry.at (j)->datum = Geometry::IMAGE; EditSubscriber::visibleGeometry.at (j)->state = Geometry::NORMAL; diff --git a/rtgui/thresholdadjuster.cc b/rtgui/thresholdadjuster.cc index 1f8b1c967..7f8aec508 100644 --- a/rtgui/thresholdadjuster.cc +++ b/rtgui/thresholdadjuster.cc @@ -99,7 +99,7 @@ void ThresholdAdjuster::initObject (Glib::ustring label, bool editedcb) hbox->pack_start (*this->label); reset = Gtk::manage (new Gtk::Button ()); - reset->add (*Gtk::manage (new RTImage ("undo-small.png", "redo-small.png"))); + reset->add (*Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON))); reset->set_relief (Gtk::RELIEF_NONE); reset->set_tooltip_markup (M("ADJUSTER_RESET_TO_DEFAULT")); diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index 61043525c..62694d086 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -167,7 +167,7 @@ void ThresholdSelector::get_preferred_height_vfunc (int &minimum_height, int &na void ThresholdSelector::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - int s = RTScalable::getScale(); + const int s = RTScalable::scalePixelSize(1); Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled int margins = padding.get_left() + padding.get_right(); @@ -177,7 +177,7 @@ void ThresholdSelector::get_preferred_width_vfunc (int &minimum_width, int &natu void ThresholdSelector::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const { - int s = RTScalable::getScale(); + const int s = RTScalable::scalePixelSize(1); Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled int margins = padding.get_left() + padding.get_right(); @@ -275,7 +275,7 @@ void ThresholdSelector::updateBackBuffer() cr->paint (); cr->set_operator (Cairo::OPERATOR_OVER); - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double positions01[4]; int w = get_allocated_width (); @@ -499,7 +499,7 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double wslider = sliderWidth * s; // constant must be an odd value double hwslider = wslider / 2.; @@ -586,7 +586,7 @@ void ThresholdSelector::findLitCursor(int posX, int posY) Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled - double s = (double)RTScalable::getScale(); + const double s = RTScalable::scalePixelSize(1.); double wslider = sliderWidth * s; // constant must be an odd value double hwslider = wslider / 2.; diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 06c662e51..29222992e 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -34,7 +34,7 @@ ThumbBrowserBase::ThumbBrowserBase () { inW = -1; inH = -1; - + hscroll.set_orientation(Gtk::ORIENTATION_HORIZONTAL); vscroll.set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -1026,14 +1026,14 @@ Gtk::SizeRequestMode ThumbBrowserBase::Internal::get_request_mode_vfunc () const void ThumbBrowserBase::Internal::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height = 20 * RTScalable::getScale(); - natural_height = 80 * RTScalable::getScale(); + minimum_height = RTScalable::scalePixelSize(20); + natural_height = RTScalable::scalePixelSize(80); } void ThumbBrowserBase::Internal::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = 200 * RTScalable::getScale(); - natural_width = 1000 * RTScalable::getScale(); + minimum_width = RTScalable::scalePixelSize(200); + natural_width = RTScalable::scalePixelSize(1000); } void ThumbBrowserBase::Internal::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index 5cdfc2787..56237197c 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -28,8 +28,8 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n editingMode = false; - handimg.reset(new RTImage("hand-open.png")); - editinghandimg.reset(new RTImage("crosshair-adjust.png")); + handimg.reset(new RTImage("hand-open", Gtk::ICON_SIZE_LARGE_TOOLBAR)); + editinghandimg.reset(new RTImage("crosshair-adjust", Gtk::ICON_SIZE_LARGE_TOOLBAR)); handTool = Gtk::manage (new Gtk::ToggleButton ()); handTool->add (*handimg); @@ -40,7 +40,7 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n pack_start (*handTool); wbTool = Gtk::manage (new Gtk::ToggleButton ()); - Gtk::Image* wbimg = Gtk::manage (new RTImage ("color-picker.png")); + Gtk::Image* wbimg = Gtk::manage (new RTImage ("color-picker", Gtk::ICON_SIZE_LARGE_TOOLBAR)); wbTool->add (*wbimg); wbimg->show (); wbTool->set_relief(Gtk::RELIEF_NONE); @@ -48,8 +48,8 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n pack_start (*wbTool); - showcolpickersimg.reset(new RTImage("color-picker-bars.png")); - hidecolpickersimg.reset(new RTImage("color-picker-hide.png")); + showcolpickersimg.reset(new RTImage("color-picker-bars", Gtk::ICON_SIZE_LARGE_TOOLBAR)); + hidecolpickersimg.reset(new RTImage("color-picker-hide", Gtk::ICON_SIZE_LARGE_TOOLBAR)); colPickerTool = Gtk::manage (new Gtk::ToggleButton ()); colPickerTool->add (*showcolpickersimg); @@ -60,7 +60,7 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n pack_start (*colPickerTool); cropTool = Gtk::manage (new Gtk::ToggleButton ()); - Gtk::Image* cropimg = Gtk::manage (new RTImage ("crop.png")); + Gtk::Image* cropimg = Gtk::manage (new RTImage ("crop", Gtk::ICON_SIZE_LARGE_TOOLBAR)); cropTool->add (*cropimg); cropimg->show (); cropTool->set_relief(Gtk::RELIEF_NONE); @@ -69,7 +69,7 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n pack_start (*cropTool); straTool = Gtk::manage (new Gtk::ToggleButton ()); - Gtk::Image* straimg = Gtk::manage (new RTImage ("rotate-straighten.png")); + Gtk::Image* straimg = Gtk::manage (new RTImage ("rotate-straighten", Gtk::ICON_SIZE_LARGE_TOOLBAR)); straTool->add (*straimg); straimg->show (); straTool->set_relief(Gtk::RELIEF_NONE); @@ -78,7 +78,7 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n pack_start (*straTool); perspTool = Gtk::manage(new Gtk::ToggleButton()); - Gtk::Image* perspimg = Gtk::manage(new RTImage("perspective-vertical-bottom.png")); + Gtk::Image* perspimg = Gtk::manage(new RTImage("perspective-vertical-bottom", Gtk::ICON_SIZE_LARGE_TOOLBAR)); perspTool->set_image(*perspimg); perspTool->set_relief(Gtk::RELIEF_NONE); pack_start(*perspTool); diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc index cfc53639b..2024e76cc 100644 --- a/rtgui/toolpanel.cc +++ b/rtgui/toolpanel.cc @@ -61,7 +61,7 @@ FoldableToolPanel::FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); titleHBox->pack_start(*label, Gtk::PACK_EXPAND_WIDGET, 0); - RTImage *image = Gtk::manage (new RTImage("one-to-one-small.png")); + RTImage *image = Gtk::manage (new RTImage("one-to-one-small")); image->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); titleHBox->pack_end(*image, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 9099f5620..58e6d538b 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -143,7 +143,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit addfavoritePanel (detailsPanel, dehaze); addfavoritePanel (advancedPanel, wavelet); addfavoritePanel(locallabPanel, locallab); - + addfavoritePanel (transformPanel, crop); addfavoritePanel (transformPanel, resize); addPanel (resize->getPackBox(), prsharpening, 2); @@ -189,12 +189,12 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit transformPanelSW = Gtk::manage (new MyScrolledWindow ()); rawPanelSW = Gtk::manage (new MyScrolledWindow ()); advancedPanelSW = Gtk::manage (new MyScrolledWindow ()); - locallabPanelSW = Gtk::manage(new MyScrolledWindow()); + locallabPanelSW = Gtk::manage(new MyScrolledWindow()); // load panel endings for (int i = 0; i < 8; i++) { vbPanelEnd[i] = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); - imgPanelEnd[i] = Gtk::manage (new RTImage ("ornament1.png")); + imgPanelEnd[i] = Gtk::manage (new RTImage ("ornament1")); imgPanelEnd[i]->show(); vbPanelEnd[i]->pack_start(*imgPanelEnd[i], Gtk::PACK_SHRINK); vbPanelEnd[i]->show_all(); @@ -220,23 +220,23 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit locallabPanelSW->add(*locallabPanel); locallabPanel->pack_start(*vbPanelEnd[7], Gtk::PACK_SHRINK, 4); - + transformPanelSW->add (*transformPanel); transformPanel->pack_start (*vbPanelEnd[4], Gtk::PACK_SHRINK, 4); rawPanelSW->add (*rawPanel); rawPanel->pack_start (*vbPanelEnd[5], Gtk::PACK_SHRINK, 0); - toiF = Gtk::manage (new TextOrIcon ("star.png", M ("MAIN_TAB_FAVORITES"), M ("MAIN_TAB_FAVORITES_TOOLTIP"))); - toiE = Gtk::manage (new TextOrIcon ("exposure.png", M ("MAIN_TAB_EXPOSURE"), M ("MAIN_TAB_EXPOSURE_TOOLTIP"))); - toiD = Gtk::manage (new TextOrIcon ("detail.png", M ("MAIN_TAB_DETAIL"), M ("MAIN_TAB_DETAIL_TOOLTIP"))); - toiC = Gtk::manage (new TextOrIcon ("color-circles.png", M ("MAIN_TAB_COLOR"), M ("MAIN_TAB_COLOR_TOOLTIP"))); - toiW = Gtk::manage (new TextOrIcon ("atom.png", M ("MAIN_TAB_ADVANCED"), M ("MAIN_TAB_ADVANCED_TOOLTIP"))); - toiL = Gtk::manage(new TextOrIcon("hand-open.png", M("MAIN_TAB_LOCALLAB"), M("MAIN_TAB_LOCALLAB_TOOLTIP"))); + toiF = Gtk::manage (new TextOrIcon ("star", M ("MAIN_TAB_FAVORITES"), M ("MAIN_TAB_FAVORITES_TOOLTIP"))); + toiE = Gtk::manage (new TextOrIcon ("exposure", M ("MAIN_TAB_EXPOSURE"), M ("MAIN_TAB_EXPOSURE_TOOLTIP"))); + toiD = Gtk::manage (new TextOrIcon ("detail", M ("MAIN_TAB_DETAIL"), M ("MAIN_TAB_DETAIL_TOOLTIP"))); + toiC = Gtk::manage (new TextOrIcon ("color-circles", M ("MAIN_TAB_COLOR"), M ("MAIN_TAB_COLOR_TOOLTIP"))); + toiW = Gtk::manage (new TextOrIcon ("atom", M ("MAIN_TAB_ADVANCED"), M ("MAIN_TAB_ADVANCED_TOOLTIP"))); + toiL = Gtk::manage(new TextOrIcon("hand-open", M("MAIN_TAB_LOCALLAB"), M("MAIN_TAB_LOCALLAB_TOOLTIP"))); - toiT = Gtk::manage (new TextOrIcon ("transform.png", M ("MAIN_TAB_TRANSFORM"), M ("MAIN_TAB_TRANSFORM_TOOLTIP"))); - toiR = Gtk::manage (new TextOrIcon ("bayer.png", M ("MAIN_TAB_RAW"), M ("MAIN_TAB_RAW_TOOLTIP"))); - toiM = Gtk::manage (new TextOrIcon ("metadata.png", M ("MAIN_TAB_METADATA"), M ("MAIN_TAB_METADATA_TOOLTIP"))); + toiT = Gtk::manage (new TextOrIcon ("transform", M ("MAIN_TAB_TRANSFORM"), M ("MAIN_TAB_TRANSFORM_TOOLTIP"))); + toiR = Gtk::manage (new TextOrIcon ("bayer", M ("MAIN_TAB_RAW"), M ("MAIN_TAB_RAW_TOOLTIP"))); + toiM = Gtk::manage (new TextOrIcon ("metadata", M ("MAIN_TAB_METADATA"), M ("MAIN_TAB_METADATA_TOOLTIP"))); if (favoritePanelSW) { toolPanelNotebook->append_page (*favoritePanelSW, *toiF); } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index f14dd8c8c..7e675a289 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -90,7 +90,7 @@ Wavelet::Wavelet() : oldsh(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_OLDSH")))), neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.05, 2.5, 0.01, 1.))), - offset(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVOFFSET"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), + offset(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVOFFSET"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), lowthr(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVLOWTHR"), 20., 100., 0.5, 40.))), rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), -100, 100, 1, 0))), resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), 0, 100, 1, 0))), @@ -150,8 +150,8 @@ Wavelet::Wavelet() : edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))), edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))), edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))), - ballum(Gtk::manage(new Adjuster(M("TP_WAVELET_BALLUM"), -2., 10., 0.5, 7., Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))), - balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-yellow-small.png")), Gtk::manage(new RTImage("circle-red-green-small.png"))))), + ballum(Gtk::manage(new Adjuster(M("TP_WAVELET_BALLUM"), -2., 10., 0.5, 7., Gtk::manage(new RTImage("circle-white-small")), Gtk::manage(new RTImage("circle-black-small"))))), + balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-red-green-small"))))), chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0.0, 150., 0.01, 0.))), chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100., 0.01, 0.))), mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 20))), @@ -604,7 +604,7 @@ Wavelet::Wavelet() : opaCurveEditorG->curveListComplete(); opaCurveEditorG->show(); tonBox->pack_start(*sigmaton); - + tonFrame->set_label_align(0.025, 0.5); ToolParamBlock* const ton2Box = Gtk::manage(new ToolParamBlock()); ton2Box->pack_start(*labgrid, Gtk::PACK_EXPAND_WIDGET, 2); @@ -714,7 +714,7 @@ Wavelet::Wavelet() : CurveEditorwavnoise->curveListComplete(); CurveEditorwavnoise->show(); const std::vector milestones4 = makeWholeHueRange(); - + wavdenoiseh = static_cast(CurveEditorwavnoiseh->addCurve(CT_Flat, "", nullptr, false, false)); wavdenoiseh->setIdentityValue(0.); wavdenoiseh->setResetCurve(FlatCurveType(default_params.wavdenoiseh.at(0)), default_params.wavdenoiseh); @@ -740,7 +740,7 @@ Wavelet::Wavelet() : wavguidf->setBottomBarBgGradient(milestones4); - + levelsigm->set_tooltip_text(M("TP_WAVELET_DENSIGMA_TOOLTIP")); // levden->set_tooltip_text(M("TP_WAVELET_DENLEV_TOOLTIP")); thrden->set_tooltip_text(M("TP_WAVELET_THRDEN_TOOLTIP")); @@ -764,7 +764,7 @@ Wavelet::Wavelet() : noiseBox->pack_start(*sigm); noiseBox->pack_start(*CurveEditorwavnoise); // noiseBox->pack_start(*CurveEditorwavnoiseh); - + balchrom->setAdjusterListener(this); chromfi->setAdjusterListener(this); @@ -920,7 +920,7 @@ Wavelet::Wavelet() : //Blur Wavelet ToolParamBlock* const blBox = Gtk::manage(new ToolParamBlock()); - + curveEditorbl->setCurveListener(this); blshape = static_cast(curveEditorbl->addCurve(CT_Flat, "", nullptr, false, false)); @@ -935,8 +935,8 @@ Wavelet::Wavelet() : blBox->pack_start(*bluwav); bluwav->setAdjusterListener(this); blBox->pack_start(*curveEditorbl, Gtk::PACK_SHRINK, 4); - - + + chrwav->setAdjusterListener(this); blBox->pack_start(*chrwav); @@ -1118,20 +1118,20 @@ Wavelet::Wavelet() : cbenabConn = cbenab->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::cbenabToggled)); cbenab->set_tooltip_text(M("TP_WAVELET_CB_TOOLTIP")); - Gtk::Image* const iblueR = Gtk::manage(new RTImage("circle-blue-small.png")); - Gtk::Image* const iyelL = Gtk::manage(new RTImage("circle-yellow-small.png")); - Gtk::Image* const imagL = Gtk::manage(new RTImage("circle-magenta-small.png")); - Gtk::Image* const igreenR = Gtk::manage(new RTImage("circle-green-small.png")); + Gtk::Image* const iblueR = Gtk::manage(new RTImage("circle-blue-small")); + Gtk::Image* const iyelL = Gtk::manage(new RTImage("circle-yellow-small")); + Gtk::Image* const imagL = Gtk::manage(new RTImage("circle-magenta-small")); + Gtk::Image* const igreenR = Gtk::manage(new RTImage("circle-green-small")); - Gtk::Image* const iblueRm = Gtk::manage(new RTImage("circle-blue-small.png")); - Gtk::Image* const iyelLm = Gtk::manage(new RTImage("circle-yellow-small.png")); - Gtk::Image* const imagLm = Gtk::manage(new RTImage("circle-magenta-small.png")); - Gtk::Image* const igreenRm = Gtk::manage(new RTImage("circle-green-small.png")); + Gtk::Image* const iblueRm = Gtk::manage(new RTImage("circle-blue-small")); + Gtk::Image* const iyelLm = Gtk::manage(new RTImage("circle-yellow-small")); + Gtk::Image* const imagLm = Gtk::manage(new RTImage("circle-magenta-small")); + Gtk::Image* const igreenRm = Gtk::manage(new RTImage("circle-green-small")); - Gtk::Image* const iblueRh = Gtk::manage(new RTImage("circle-blue-small.png")); - Gtk::Image* const iyelLh = Gtk::manage(new RTImage("circle-yellow-small.png")); - Gtk::Image* const imagLh = Gtk::manage(new RTImage("circle-magenta-small.png")); - Gtk::Image* const igreenRh = Gtk::manage(new RTImage("circle-green-small.png")); + Gtk::Image* const iblueRh = Gtk::manage(new RTImage("circle-blue-small")); + Gtk::Image* const iyelLh = Gtk::manage(new RTImage("circle-yellow-small")); + Gtk::Image* const imagLh = Gtk::manage(new RTImage("circle-magenta-small")); + Gtk::Image* const igreenRh = Gtk::manage(new RTImage("circle-green-small")); greenhigh = Gtk::manage(new Adjuster("", -100., 100., 1., 0., igreenRh, imagLh)); bluehigh = Gtk::manage(new Adjuster("", -100., 100., 1., 0., iblueRh, iyelLh)); @@ -1165,8 +1165,6 @@ Wavelet::Wavelet() : resBox->pack_start(*chanMixerMidFrame, Gtk::PACK_SHRINK); resBox->pack_start(*chanMixerShadowsFrame, Gtk::PACK_SHRINK); - //RTImage *resetImg = Gtk::manage (new RTImage ("undo-small.png", "redo-small.png")); - //neutral->set_image(*resetImg); Gtk::Button* const neutral = Gtk::manage(new Gtk::Button(M("TP_COLORTONING_NEUTRAL"))); neutral->set_tooltip_text(M("TP_COLORTONING_NEUTRAL_TIP")); neutralconn = neutral->signal_pressed().connect(sigc::mem_fun(*this, &Wavelet::neutral_pressed)); @@ -1275,7 +1273,7 @@ Wavelet::Wavelet() : guidBox->pack_start(*CurveEditorwavguid); guidFrame->add(*guidBox); finalBox->pack_start(*guidFrame); - + //----------------------------- @@ -1582,7 +1580,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) } else if (pp->wavelet.slimethod == "cur") { slimethod->set_active(1); } - + if (pp->wavelet.quamethod == "cons") { quamethod->set_active(0); } else if (pp->wavelet.quamethod == "agre") { @@ -2051,7 +2049,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) } else { sup->hide(); } - + if (complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); convertParamToNormal(); @@ -2059,7 +2057,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) } else { updateGUIToMode(1); } - + } /***************************************************************************************************** @@ -3286,7 +3284,7 @@ void Wavelet::convertParamToNormal() cbenab->set_active(false); //final touchup - BAmethod->set_active(0); + BAmethod->set_active(0); sigmafin->setValue(def_params.sigmafin); enableListener(); @@ -3368,7 +3366,7 @@ void Wavelet::updateGUIToMode(int mode) void Wavelet::complexmethodChanged() -{ +{ if (complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); convertParamToNormal(); @@ -3383,7 +3381,7 @@ void Wavelet::complexmethodChanged() } void Wavelet::denmethodChanged() -{ +{ if (listener && (multiImage || getEnabled())) { listener->panelChanged(EvWavdenmethod, denmethod->get_active_text()); @@ -3391,7 +3389,7 @@ void Wavelet::denmethodChanged() } void Wavelet::mixmethodChanged() -{ +{ if (listener && (multiImage || getEnabled())) { listener->panelChanged(EvWavmixmethod, mixmethod->get_active_text()); @@ -3399,8 +3397,8 @@ void Wavelet::mixmethodChanged() } void Wavelet::slimethodChanged() -{ - +{ + if (slimethod->get_active_row_number() == 0 && complexmethod->get_active_row_number() == 0) { updateGUIToMode(0); convertParamToNormal(); @@ -3416,7 +3414,7 @@ void Wavelet::slimethodChanged() CurveEditorwavnoiseh->show(); CurveEditorwavnoise->show(); } - + if (listener && (multiImage || getEnabled())) { listener->panelChanged(EvWavslimethod, slimethod->get_active_text()); @@ -3424,7 +3422,7 @@ void Wavelet::slimethodChanged() } void Wavelet::quamethodChanged() -{ +{ if (listener && (multiImage || getEnabled())) { listener->panelChanged(EvWavquamethod, quamethod->get_active_text()); diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index fbcf40faf..e1e3af22a 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -21,6 +21,7 @@ #include #include "rtimage.h" +#include "rtsurface.h" #include "options.h" #define MINTEMP 1500 //1200 @@ -34,32 +35,6 @@ using namespace rtengine; using namespace rtengine::procparams; -Glib::RefPtr WhiteBalance::wbPixbufs[toUnderlying(WBEntry::Type::CUSTOM) + 1]; - -void WhiteBalance::init () -{ - wbPixbufs[toUnderlying(WBEntry::Type::CAMERA)] = RTImage::createPixbufFromFile ("wb-camera-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::AUTO)] = RTImage::createPixbufFromFile ("wb-auto-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::DAYLIGHT)] = RTImage::createPixbufFromFile ("wb-sun-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::CLOUDY)] = RTImage::createPixbufFromFile ("wb-cloudy-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::SHADE)] = RTImage::createPixbufFromFile ("wb-shade-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::WATER)] = RTImage::createPixbufFromFile ("wb-water-small.png"); - //wbPixbufs[toUnderlying(WBEntry::Type::WATER2)] = RTImage::createPixbufFromFile ("wb-water-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::TUNGSTEN)] = RTImage::createPixbufFromFile ("wb-tungsten-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::FLUORESCENT)] = RTImage::createPixbufFromFile ("wb-fluorescent-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::LAMP)] = RTImage::createPixbufFromFile ("wb-lamp-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::FLASH)] = RTImage::createPixbufFromFile ("wb-flash-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::LED)] = RTImage::createPixbufFromFile ("wb-led-small.png"); - wbPixbufs[toUnderlying(WBEntry::Type::CUSTOM)] = RTImage::createPixbufFromFile ("wb-custom-small.png"); -} - -void WhiteBalance::cleanup () -{ - for (int i = 0; i < toUnderlying(WBEntry::Type::CUSTOM) + 1; i++) { - wbPixbufs[i].reset(); - } -} - static double wbSlider2Temp(double sval) { @@ -144,6 +119,19 @@ static double wbTemp2Slider(double temp) WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WBALANCE_LABEL"), true, true), wbp(nullptr), wblistener(nullptr) { + // Assign icon name to wbIcons + wbIcons[toUnderlying(WBEntry::Type::CAMERA)] = "wb-camera-small"; + wbIcons[toUnderlying(WBEntry::Type::AUTO)] = "wb-auto-small"; + wbIcons[toUnderlying(WBEntry::Type::DAYLIGHT)] = "wb-sun-small"; + wbIcons[toUnderlying(WBEntry::Type::CLOUDY)] = "wb-cloudy-small"; + wbIcons[toUnderlying(WBEntry::Type::SHADE)] = "wb-shade-small"; + wbIcons[toUnderlying(WBEntry::Type::WATER)] = "wb-water-small"; + wbIcons[toUnderlying(WBEntry::Type::TUNGSTEN)] = "wb-tungsten-small"; + wbIcons[toUnderlying(WBEntry::Type::FLUORESCENT)] = "wb-fluorescent-small"; + wbIcons[toUnderlying(WBEntry::Type::LAMP)] = "wb-lamp-small"; + wbIcons[toUnderlying(WBEntry::Type::FLASH)] = "wb-flash-small"; + wbIcons[toUnderlying(WBEntry::Type::LED)] = "wb-led-small"; + wbIcons[toUnderlying(WBEntry::Type::CUSTOM)] = "wb-custom-small"; Gtk::Grid* methodgrid = Gtk::manage(new Gtk::Grid()); methodgrid->get_style_context()->add_class("grid-spacing"); @@ -159,6 +147,15 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB setExpandAlignProperties(method, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); // Assign the model to the Combobox method->set_model(refTreeModel); + method->clear(); // Clear default cell layout to add custom one + Gtk::CellRendererPixbuf* const renderer_icon = Gtk::manage(new Gtk::CellRendererPixbuf()); + renderer_icon->property_stock_size() = Gtk::ICON_SIZE_MENU; + method->pack_start(*renderer_icon, false); + method->add_attribute(*renderer_icon, "icon-name", methodColumns.colIcon); + Gtk::CellRendererText* const renderer_label = Gtk::manage(new Gtk::CellRendererText()); + renderer_label->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; + method->pack_start(*renderer_label, true); + method->add_attribute(*renderer_label, "markup", methodColumns.colLabel); WBEntry::Type oldType = WBParams::getWbEntries()[0].type; WBEntry::Type currType; @@ -170,7 +167,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::FLUORESCENT) { // Creating the Fluorescent subcategory header row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_FLUO_HEADER"); row[methodColumns.colId] = i + 100; } @@ -178,7 +175,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::AUTO) { // Creating the auto category row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_AUTO_HEADER"); row[methodColumns.colId] = i + 100; } @@ -186,7 +183,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::WATER) { // Creating the under water subcategory header row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_WATER_HEADER"); row[methodColumns.colId] = i + 100; } @@ -194,7 +191,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::LAMP) { // Creating the Lamp subcategory header row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_LAMP_HEADER"); row[methodColumns.colId] = i + 100; } @@ -202,7 +199,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::LED) { // Creating the LED subcategory header row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_LED_HEADER"); row[methodColumns.colId] = i + 100; } @@ -210,7 +207,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB if (currType == WBEntry::Type::FLASH) { // Creating the Flash subcategory header row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = M("TP_WBALANCE_FLASH_HEADER"); row[methodColumns.colId] = i + 100; } @@ -224,12 +221,12 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB || currType == WBEntry::Type::AUTO ) { childrow = *(refTreeModel->append(row.children())); - childrow[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + childrow[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; childrow[methodColumns.colLabel] = WBParams::getWbEntries()[i].GUILabel; childrow[methodColumns.colId] = i; } else { row = *(refTreeModel->append()); - row[methodColumns.colIcon] = wbPixbufs[toUnderlying(currType)]; + row[methodColumns.colIcon] = wbIcons[toUnderlying(currType)]; row[methodColumns.colLabel] = WBParams::getWbEntries()[i].GUILabel; row[methodColumns.colId] = i; } @@ -240,20 +237,11 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB custom_equal = 1.0; } - //Add the model columns to the Combo (which is a kind of view), - //rendering them in the default way: - method->pack_start(methodColumns.colIcon, false); - method->pack_start(methodColumns.colLabel, true); - - std::vector cells = method->get_cells(); - Gtk::CellRendererText* cellRenderer = dynamic_cast(cells.at(1)); - cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_MIDDLE; - resetButton = Gtk::manage (new Gtk::Button()); // No label, keep it short setExpandAlignProperties(resetButton, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); resetButton->set_relief(Gtk::RELIEF_NONE); resetButton->get_style_context()->add_class(GTK_STYLE_CLASS_FLAT); - resetButton->set_image (*Gtk::manage (new RTImage ("undo-small.png"))); + resetButton->set_image (*Gtk::manage (new RTImage ("undo-small", Gtk::ICON_SIZE_BUTTON))); method->set_active (0); // Camera methodgrid->attach (*lab, 0, 0, 1, 1); @@ -270,7 +258,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB setExpandAlignProperties(spotbutton, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); spotbutton->get_style_context()->add_class("independent"); spotbutton->set_tooltip_text(M("TP_WBALANCE_SPOTWB")); - spotbutton->set_image (*Gtk::manage (new RTImage ("color-picker-small.png"))); + spotbutton->set_image (*Gtk::manage (new RTImage ("color-picker-small", Gtk::ICON_SIZE_BUTTON))); Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); setExpandAlignProperties(slab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -322,14 +310,14 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WB separator->get_style_context()->add_class("grid-row-separator"); pack_start (*separator, Gtk::PACK_SHRINK, 0); - Gtk::Image* itempL = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* itempR = Gtk::manage (new RTImage ("circle-yellow-small.png")); - Gtk::Image* igreenL = Gtk::manage (new RTImage ("circle-magenta-small.png")); - Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small.png")); - Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small.png")); - Gtk::Image* itempbiasL = Gtk::manage (new RTImage ("circle-blue-small.png")); - Gtk::Image* itempbiasR = Gtk::manage (new RTImage ("circle-yellow-small.png")); + Gtk::Image* itempL = Gtk::manage (new RTImage ("circle-blue-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* itempR = Gtk::manage (new RTImage ("circle-yellow-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* igreenL = Gtk::manage (new RTImage ("circle-magenta-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("circle-green-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* iblueredL = Gtk::manage (new RTImage ("circle-blue-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* iblueredR = Gtk::manage (new RTImage ("circle-red-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* itempbiasL = Gtk::manage (new RTImage ("circle-blue-small", Gtk::ICON_SIZE_BUTTON)); + Gtk::Image* itempbiasR = Gtk::manage (new RTImage ("circle-yellow-small", Gtk::ICON_SIZE_BUTTON)); StudLabel = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); StudLabel->set_tooltip_text(M("TP_WBALANCE_STUDLABEL_TOOLTIP")); @@ -719,7 +707,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) } else { StudLabel->hide(); } - + } setEnabled(pp->wb.enabled); @@ -954,7 +942,7 @@ void WhiteBalance::WBChanged(double temperature, double greenVal, float studgood StudLabel->set_text( Glib::ustring::compose(M("TP_WBALANCE_STUDLABEL"), Glib::ustring::format(std::fixed, std::setprecision(4), studgood)) - ); + ); temp->setDefault(temperature); green->setDefault(greenVal); enableListener(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 1ed99a2aa..a034c1686 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -50,7 +50,7 @@ protected: class MethodColumns : public Gtk::TreeModel::ColumnRecord { public: - Gtk::TreeModelColumn< Glib::RefPtr > colIcon; + Gtk::TreeModelColumn colIcon; Gtk::TreeModelColumn colLabel; Gtk::TreeModelColumn colId; MethodColumns() @@ -61,7 +61,7 @@ protected: } }; - static Glib::RefPtr wbPixbufs[rtengine::toUnderlying(rtengine::procparams::WBEntry::Type::CUSTOM) + 1]; + Glib::ustring wbIcons[rtengine::toUnderlying(rtengine::procparams::WBEntry::Type::CUSTOM) + 1]; Glib::RefPtr refTreeModel; MethodColumns methodColumns; MyComboBox* method; @@ -102,8 +102,6 @@ public: WhiteBalance (); ~WhiteBalance () override; - static void init (); - static void cleanup (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override; void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/zoompanel.cc b/rtgui/zoompanel.cc index c10ec97b9..a683870c9 100644 --- a/rtgui/zoompanel.cc +++ b/rtgui/zoompanel.cc @@ -25,15 +25,15 @@ ZoomPanel::ZoomPanel (ImageArea* iarea) : iarea(iarea) { set_name ("EditorZoomPanel"); - Gtk::Image* imageOut = Gtk::manage (new RTImage ("magnifier-minus.png")); + Gtk::Image* imageOut = Gtk::manage (new RTImage ("magnifier-minus", Gtk::ICON_SIZE_LARGE_TOOLBAR)); imageOut->set_padding(0, 0); - Gtk::Image* imageIn = Gtk::manage (new RTImage ("magnifier-plus.png")); + Gtk::Image* imageIn = Gtk::manage (new RTImage ("magnifier-plus", Gtk::ICON_SIZE_LARGE_TOOLBAR)); imageIn->set_padding(0, 0); - Gtk::Image* image11 = Gtk::manage ( new RTImage ("magnifier-1to1.png")); + Gtk::Image* image11 = Gtk::manage ( new RTImage ("magnifier-1to1", Gtk::ICON_SIZE_LARGE_TOOLBAR)); image11->set_padding(0, 0); - Gtk::Image* imageFit = Gtk::manage (new RTImage ("magnifier-fit.png")); + Gtk::Image* imageFit = Gtk::manage (new RTImage ("magnifier-fit", Gtk::ICON_SIZE_LARGE_TOOLBAR)); imageFit->set_padding(0, 0); - Gtk::Image* imageFitCrop = Gtk::manage (new RTImage ("magnifier-crop.png")); + Gtk::Image* imageFitCrop = Gtk::manage (new RTImage ("magnifier-crop", Gtk::ICON_SIZE_LARGE_TOOLBAR)); imageFit->set_padding(0, 0); zoomOut = Gtk::manage (new Gtk::Button()); @@ -67,7 +67,7 @@ ZoomPanel::ZoomPanel (ImageArea* iarea) : iarea(iarea) setExpandAlignProperties(zoomLabel, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); attach_next_to (*zoomLabel, Gtk::POS_RIGHT, 1, 1); - Gtk::Image* imageCrop = Gtk::manage (new RTImage ("window-add.png")); + Gtk::Image* imageCrop = Gtk::manage (new RTImage ("window-add", Gtk::ICON_SIZE_LARGE_TOOLBAR)); imageCrop->set_padding(0, 0); newCrop = Gtk::manage (new Gtk::Button()); newCrop->add (*imageCrop); From 7ee6fd795bc3f45f1aac69bef15d24fbdbd41b74 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 19 Aug 2022 19:05:06 +0200 Subject: [PATCH 002/291] Add other font size scaling Minor fixes: - Fixes some incorrect cast - fixes some incorrect comments --- rtgui/cropwindow.cc | 51 +++++++++++++++++------------------- rtgui/filebrowserentry.cc | 15 ++++++++++- rtgui/imagearea.cc | 15 ++++++++++- rtgui/lockablecolorpicker.cc | 15 ++++++++++- rtgui/rtscalable.cc | 5 ++-- rtgui/rtwindow.cc | 13 ++++----- rtgui/shcselector.cc | 17 +++++++++++- rtgui/splash.cc | 17 ++++++------ 8 files changed, 97 insertions(+), 51 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index a5f332f9f..110555251 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -64,21 +64,20 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet Glib::RefPtr context = parent->get_pango_context () ; Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_BOLD); - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px" - const int fontSize = 8; - const int absoluteFontSize = fontSize * Pango::SCALE; - // Guessing that absolute pixel size is given for a 96 DPI reference: + const int fontSize = 8; // pt + // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c const double fontScale = 1.; #endif - fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); Glib::RefPtr cllayout = parent->create_pango_layout("1000%"); @@ -2465,21 +2464,20 @@ void CropWindow::drawDecoration (Cairo::RefPtr cr) Glib::RefPtr context = iarea->get_pango_context () ; Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_BOLD); - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px" - const int fontSize = 8; - const int absoluteFontSize = fontSize * Pango::SCALE; - // Guessing that absolute pixel size is given for a 96 DPI reference: + const int fontSize = 8; // pt + // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c const double fontScale = 1.; #endif - fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); Glib::RefPtr cllayout = iarea->create_pango_layout(cropLabel); int iw, ih; @@ -2543,21 +2541,20 @@ void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) Glib::RefPtr context = iarea->get_pango_context () ; Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_BOLD); - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px" - const int fontSize = 8; - const int absoluteFontSize = fontSize * Pango::SCALE; - // Guessing that absolute pixel size is given for a 96 DPI reference: + const int fontSize = 8; // pt + // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c const double fontScale = 1.; #endif - fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(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))); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 9f9be2eff..b3d4e6904 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -789,7 +789,20 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) 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); + const int fontSize = 8; // pt + // Converting font size to "px" based on DPI and scale +#ifndef __APPLE__ + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(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))); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index df9756e88..d60232ff9 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -155,7 +155,20 @@ void ImageArea::setInfoText (Glib::ustring text) // update font fontd.set_weight (Pango::WEIGHT_BOLD); - fontd.set_size (10 * Pango::SCALE); + const int fontSize = 10; // pt + // Converting font size to "px" based on DPI and scale +#ifndef __APPLE__ + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); // create text layout diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 0a08bb945..22760c6a2 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -48,7 +48,20 @@ void LockableColorPicker::updateBackBuffer () Pango::FontDescription fontd = pangoContext->get_font_description(); // set font family and size fontd.set_family(options.CPFontFamily == "default" ? "sans" : options.CPFontFamily); - fontd.set_size((options.CPFontFamily == "default" ? 8 : options.CPFontSize) * Pango::SCALE); + const int fontSize = options.CPFontFamily == "default" ? 8 : options.CPFontSize; // pt + // Converting font size to "px" based on DPI and scale +#ifndef __APPLE__ + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); fontd.set_weight(Pango::WEIGHT_NORMAL); pangoContext->set_font_description (fontd); diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 09fb82205..5606fe677 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -248,9 +248,8 @@ int RTScalable::getScale () double RTScalable::getGlobalScale() { - return (static_cast(RTScalable::getDPI()) / - static_cast(RTScalable::baseDPI) * - RTScalable::getScale()); + return (RTScalable::getDPI() / RTScalable::baseDPI * + static_cast(RTScalable::getScale())); } int RTScalable::scalePixelSize(const int pixel_size) diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 9ea9dec5a..fede08a9a 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -170,9 +170,8 @@ RTWindow::RTWindow () Glib::ustring css; #ifndef __APPLE__ - const double fontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c @@ -205,11 +204,10 @@ RTWindow::RTWindow () // Pango::SCALE to get "px" newFontSize = fontSize / Pango::SCALE; - // Guessing that pixel size is given for a 96 DPI reference: #ifndef __APPLE__ - const double newFontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + // Guessing that pixel size is given for a 96 DPI reference: + const double newFontScale = RTScalable::getDPI() / RTScalable::baseDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c @@ -231,7 +229,6 @@ RTWindow::RTWindow () // Set font and size in css css = Glib::ustring::compose ("* { font-size: %1px}", newFontSize); - printf("newFontSize: %d\n", newFontSize); } } diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index ac1149893..dc7e06936 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -195,7 +195,22 @@ void SHCSelector::updateBackBuffer() // update font fontd.set_weight (Pango::WEIGHT_NORMAL); - fontd.set_absolute_size((double)h * 0.8 * (double)Pango::SCALE); + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px" + const double fontSize = static_cast(h) * 0.8; // pt + // Converting font size to "px" based on DPI and scale +#ifndef __APPLE__ + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h +#else + // On MacOS, font is already scaled by the System library + // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c + const double fontScale = 1.; +#endif + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); diff --git a/rtgui/splash.cc b/rtgui/splash.cc index b7d118d58..d00a074dc 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -43,21 +43,20 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) context->set_cairo_font_options (cfo); Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_LIGHT); - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px" - const int fontSize = 12; - const int absoluteFontSize = fontSize * Pango::SCALE; - // Guessing that absolute pixel size is given for a 96 DPI reference: + const int fontSize = 12; // pt + // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = static_cast(RTScalable::getDPI()) - / static_cast(RTScalable::pangoDPI) - * RTScalable::getScale(); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI + * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c const double fontScale = 1.; #endif - fontd.set_absolute_size (static_cast(absoluteFontSize) * fontScale); + const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + // Absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "px": + fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); int w, h; From 36222d14a2ad126d2aef0a1000b6d65584e6a2bc Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sun, 21 Aug 2022 15:45:07 +0200 Subject: [PATCH 003/291] Fixes blur rendering with RTSurface on hidpi screen Other fixes: - Fixes splash image not rendered - Cleans commented code - Replaces deprecated librsvg functions - Updates Makefile librsvg required minimum version - Correctly uses RTSurface getWidth / getHeight functions - Improves lwbutton aspect Known issues: - Blur rendering with RTPixbuf on hidpi screen --- CMakeLists.txt | 2 +- rtgui/batchqueueentry.cc | 4 +-- rtgui/filebrowserentry.cc | 4 +-- rtgui/lwbutton.cc | 14 +++++----- rtgui/rtscalable.cc | 57 ++++++++++++++++++++++----------------- rtgui/rtsurface.cc | 52 +++++++++++++++++++++++++++++++---- rtgui/splash.cc | 8 +++--- 7 files changed, 95 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53480968c..7806af000 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -467,7 +467,7 @@ pkg_check_modules(GTHREAD REQUIRED gthread-2.0>=2.48) pkg_check_modules(GOBJECT REQUIRED gobject-2.0>=2.48) pkg_check_modules(SIGC REQUIRED sigc++-2.0>=2.3.1) pkg_check_modules(LENSFUN REQUIRED lensfun>=0.2) -pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.46) +pkg_check_modules(RSVG REQUIRED librsvg-2.0>=2.52) if(WIN32) add_definitions(-DWIN32) diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 6ab6ccf83..a04ede5b8 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -168,8 +168,8 @@ std::vector> BatchQueueEntry::getIconsOnImageArea () void BatchQueueEntry::getIconSize (int& w, int& h) const { - w = savedAsIcon->get()->get_width (); - h = savedAsIcon->get()->get_height (); + w = savedAsIcon->getWidth (); + h = savedAsIcon->getHeight (); } diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index b3d4e6904..f922e2084 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -195,8 +195,8 @@ void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) void FileBrowserEntry::getIconSize (int& w, int& h) const { - w = editedIcon->get()->get_width (); - h = editedIcon->get()->get_height (); + w = editedIcon->getWidth (); + h = editedIcon->getHeight (); } FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet () diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc index 9f65218cf..cd6678ed5 100644 --- a/rtgui/lwbutton.cc +++ b/rtgui/lwbutton.cc @@ -25,8 +25,8 @@ LWButton::LWButton (std::shared_ptr i, int aCode, void* aData, Alignm { if (i) { - w = i->getWidth () + 2; - h = i->getHeight () + 2; + w = i->getWidth (); + h = i->getHeight (); } else { w = h = 2; } @@ -65,8 +65,8 @@ void LWButton::setIcon (std::shared_ptr i) icon = i; if (i) { - w = i->getWidth () + 2; - h = i->getHeight () + 2; + w = i->getWidth (); + h = i->getHeight (); } else { w = h = 2; } @@ -186,9 +186,9 @@ void LWButton::redraw (Cairo::RefPtr context) { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - context->set_line_width (1.0); + context->set_line_width (2.0); // Line width shall be even to avoid blur effect when upscaling context->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - context->rectangle (xpos + 0.5, ypos + 0.5, w - 1.0, h - 1.0); + context->rectangle (xpos, ypos, w, h); if (state == Pressed_In) { context->set_source_rgb (fgr, fgg, fgb); @@ -205,7 +205,7 @@ void LWButton::redraw (Cairo::RefPtr context) } context->stroke (); - int dilat = 1; + int dilat = 0; if (state == Pressed_In) { dilat++; diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 5606fe677..b161591cb 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -36,7 +36,13 @@ void RTScalable::updateDPInScale(const Gtk::Window* window, double &newDPI, int if (window) { const auto screen = window->get_screen(); newDPI = screen->get_resolution(); // Get DPI retrieved from the OS - newScale = window->get_scale_factor(); // Get scale factor associated to the window + + if (window->get_scale_factor() > 0) { + // Get scale factor associated to the window + newScale = window->get_scale_factor(); + } else { + newScale = 1; // Default minimum value of 1 as scale is used to scale surface + } } } @@ -88,21 +94,6 @@ Cairo::RefPtr RTScalable::loadSurfaceFromIcon(const Glib::u } } - /* - // Scale current surface size to desired scaled size - if (surface) { - // Note: surface is considered made from squared icon - const double scale_factor = static_cast(size) / static_cast(surface->get_width()); - surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, - static_cast(surface->get_width() * scale_factor + 0.5), - static_cast(surface->get_height() * scale_factor + 0.5)); - const auto cr = Cairo::Context::create(surf); - cr->scale(scale_factor, scale_factor); - cr->set_source(surface, 0, 0); - cr->paint(); - } - */ - return surf; } @@ -174,33 +165,44 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us return surf; } + int w, h; + if (width == -1 || height == -1) { // Use SVG image natural width and height - RsvgDimensionData dim; - rsvg_handle_get_dimensions(handle, &dim); // Get SVG image dimensions - surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, dim.width, dim.height); + double _w, _h; + const bool has_dim = rsvg_handle_get_intrinsic_size_in_pixels(handle, &_w, &_h); // Get SVG image dimensions + if (has_dim) { + w = std::ceil(_w); + h = std::ceil(_h); + } else { + w = h = 16; // Set to a default size of 16px (i.e. Gtk::ICON_SIZE_SMALL_TOOLBAR one) + } } else { // Use given width and height - surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, width, height); + w = width; + h = height; } + // Create an upscaled surface to avoid blur effect + surf = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, + w * RTScalable::getScale(), + h * RTScalable::getScale()); + // Render (and erase with) default surface background Cairo::RefPtr c = Cairo::Context::create(surf); c->set_source_rgba (0., 0., 0., 0.); c->set_operator (Cairo::OPERATOR_CLEAR); c->paint(); - // Render surface based on SVG image + // Render upscaled surface based on SVG image error = nullptr; RsvgRectangle rect = { .x = 0., .y = 0., - .width = static_cast(width * RTScalable::getScale()), // SVG image is upscaled to avoid blur effect - .height = static_cast(height * RTScalable::getScale()) // SVG image is upscaled to avoid blur effect + .width = static_cast(w * RTScalable::getScale()), + .height = static_cast(h * RTScalable::getScale()) }; c->set_operator (Cairo::OPERATOR_OVER); - c->scale(1. / RTScalable::getScale(), 1. / RTScalable::getScale()); // Cairo surface is scaled to match image dimensions - const bool success = rsvg_handle_render_document(handle, c->cobj(), &rect, &error); if (!success && error) { @@ -210,6 +212,11 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us } rsvg_handle_free(handle); + + // Set device scale to avoid blur effect + cairo_surface_set_device_scale(surf->cobj(), + static_cast(RTScalable::getScale()), + static_cast(RTScalable::getScale())); } else { if (rtengine::settings->verbose) { std::cerr << "Failed to load SVG file \"" << fname << "\"" << std::endl; diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index 46bddcaa1..b72a87d0d 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -90,7 +90,7 @@ int RTSurface::getWidth() { return surface - ? surface->get_width() + ? (surface->get_width() / RTScalable::getScale()) : -1; } @@ -98,7 +98,7 @@ int RTSurface::getHeight() { return surface - ? surface->get_height() + ? (surface->get_height() / RTScalable::getScale()) : -1; } @@ -152,8 +152,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize) const Cairo::RefPtr surface = RTScalable::loadSurfaceFromIcon(icon_name, iconSize); if (surface) { + // Downscale surface before creating pixbuf + const Cairo::RefPtr _surface = Cairo::Surface::create(surface, + Cairo::CONTENT_COLOR_ALPHA, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); + const auto c = Cairo::Context::create(_surface); + c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); + c->set_source(surface, 0., 0.); + c->paint(); + // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + pixbuf = Gdk::Pixbuf::create(_surface, + 0, + 0, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); // Save private parameters type = RTPixbuf::IconType; @@ -177,8 +191,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &fname) : const Cairo::RefPtr surface = RTScalable::loadSurfaceFromPNG(fname); if (surface) { + // Downscale surface before creating pixbuf + const Cairo::RefPtr _surface = Cairo::Surface::create(surface, + Cairo::CONTENT_COLOR_ALPHA, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); + const auto c = Cairo::Context::create(_surface); + c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); + c->set_source(surface, 0., 0.); + c->paint(); + // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + pixbuf = Gdk::Pixbuf::create(_surface, + 0, + 0, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); // Save private parameter type = RTPixbuf::PNGType; @@ -192,8 +220,22 @@ RTPixbuf::RTPixbuf(const Glib::ustring &fname) : const Cairo::RefPtr surface = RTScalable::loadSurfaceFromSVG(fname); if (surface) { + // Downscale surface before creating pixbuf + const Cairo::RefPtr _surface = Cairo::Surface::create(surface, + Cairo::CONTENT_COLOR_ALPHA, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); + const auto c = Cairo::Context::create(_surface); + c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); + c->set_source(surface, 0., 0.); + c->paint(); + // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); + pixbuf = Gdk::Pixbuf::create(_surface, + 0, + 0, + surface->get_width() / RTScalable::getScale(), + surface->get_height() / RTScalable::getScale()); // Save private parameter type = RTPixbuf::SVGType; diff --git a/rtgui/splash.cc b/rtgui/splash.cc index d00a074dc..9b2aa67d0 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -34,7 +34,7 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { if (surface->hasSurface()) { cr->set_source(surface->get(), 0., 0.); - cr->rectangle(0, 0, surface->get()->get_width(), surface->get()->get_height()); + cr->rectangle(0, 0, surface->getWidth(), surface->getHeight()); cr->fill(); Cairo::FontOptions cfo; @@ -68,7 +68,7 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) cr->set_source_rgb (0., 0., 0.); cr->set_line_width(3.); cr->set_line_join(Cairo::LINE_JOIN_ROUND); - cr->move_to (surface->get()->get_width() - w - 32, surface->get()->get_height() - h - 20); + cr->move_to (surface->getWidth() - w - 32, surface->getHeight() - h - 20); version->add_to_cairo_context (cr); cr->stroke_preserve(); cr->set_source_rgb (1., 1., 1.); @@ -87,12 +87,12 @@ Gtk::SizeRequestMode SplashImage::get_request_mode_vfunc () const void SplashImage::get_preferred_height_vfunc (int &minimum_height, int &natural_height) const { - minimum_height = natural_height = surface ? surface->get()->get_height() : RTScalable::scalePixelSize(100); + minimum_height = natural_height = surface ? surface->getHeight() : RTScalable::scalePixelSize(100); } void SplashImage::get_preferred_width_vfunc (int &minimum_width, int &natural_width) const { - minimum_width = natural_width = surface ? surface->get()->get_width() : RTScalable::scalePixelSize(100); + minimum_width = natural_width = surface ? surface->getWidth() : RTScalable::scalePixelSize(100); } void SplashImage::get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const From 50e54aa395bfc0b0f972c4952439f624d48bf649 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 27 Aug 2022 11:37:59 +0200 Subject: [PATCH 004/291] Convert remaining RTPixbuf to RTSurface Changes: - Remove RTPixbuf use in directory browser to use native GTK mechanism - Replace RTPixbuf by RTSurface for thumbnail icons - Remove now useless RTPixbuf class Fixes: - Elaborate RTSurface width / height based on the type --- rtgui/batchqueueentry.cc | 11 +- rtgui/batchqueueentry.h | 6 +- rtgui/dirbrowser.cc | 51 ++++---- rtgui/dirbrowser.h | 24 ++-- rtgui/filebrowserentry.cc | 38 +++--- rtgui/filebrowserentry.h | 16 +-- rtgui/rtscalable.cc | 2 +- rtgui/rtsurface.cc | 231 +++++++++------------------------ rtgui/rtsurface.h | 33 ----- rtgui/thumbbrowserentrybase.cc | 27 ++-- rtgui/thumbbrowserentrybase.h | 9 +- 11 files changed, 151 insertions(+), 297 deletions(-) diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index a04ede5b8..334dc529f 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -26,12 +26,13 @@ #include "multilangmgr.h" #include "thumbbrowserbase.h" #include "thumbnail.h" +#include "rtsurface.h" #include "../rtengine/procparams.h" #include "../rtengine/rtengine.h" bool BatchQueueEntry::iconsLoaded(false); -std::shared_ptr BatchQueueEntry::savedAsIcon; +std::shared_ptr BatchQueueEntry::savedAsIcon(std::shared_ptr(nullptr)); BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm, bool overwrite) : ThumbBrowserEntryBase(fname), @@ -59,7 +60,7 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine: #endif if (!iconsLoaded) { - savedAsIcon = std::shared_ptr(new RTPixbuf("save-small", Gtk::ICON_SIZE_BUTTON)); + savedAsIcon = std::shared_ptr(new RTSurface("save-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); iconsLoaded = true; } @@ -153,13 +154,13 @@ void BatchQueueEntry::removeButtonSet () buttonSet = nullptr; } -std::vector> BatchQueueEntry::getIconsOnImageArea () +std::vector> BatchQueueEntry::getIconsOnImageArea () { - std::vector > ret; + std::vector> ret; if (!outFileName.empty()) { - ret.push_back (savedAsIcon->get()); + ret.push_back (savedAsIcon); } return ret; diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 6b57614e8..5d17939fb 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -29,7 +29,7 @@ #include "../rtengine/noncopyable.h" class Thumbnail; -class RTPixbuf; +class RTSurface; namespace rtengine { @@ -62,7 +62,7 @@ class BatchQueueEntry final : public ThumbBrowserEntryBase, public BQEntryUpdate public: - static std::shared_ptr savedAsIcon; + static std::shared_ptr savedAsIcon; rtengine::ProcessingJob* job; const std::unique_ptr params; @@ -85,7 +85,7 @@ public: void removeButtonSet (); - std::vector> getIconsOnImageArea () override; + std::vector> getIconsOnImageArea () override; void getIconSize (int& w, int& h) const override; std::tuple getToolTip (int x, int y) const override; diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 369b69233..6a1168fa4 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -86,6 +86,15 @@ std::vector listSubDirs (const Glib::RefPtr& dir, bool DirBrowser::DirBrowser () : dirTreeModel(), dtColumns(), tvc(M("DIRBROWSER_FOLDERS")), + + openfolder("folder-open-small"), + closedfolder("folder-closed-small"), + icdrom("device-optical"), + ifloppy("device-floppy"), + ihdd("device-hdd"), + inetwork("device-network"), + iremovable("device-usb"), + expandSuccess(false) #ifdef WIN32 , volumes(0) @@ -120,15 +129,6 @@ DirBrowser::~DirBrowser() void DirBrowser::fillDirTree () { - - openfolder = std::shared_ptr(new RTPixbuf("folder-open-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - closedfolder = std::shared_ptr(new RTPixbuf("folder-closed-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - icdrom = std::shared_ptr(new RTPixbuf("device-optical", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - ifloppy = std::shared_ptr(new RTPixbuf("device-floppy", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - ihdd = std::shared_ptr(new RTPixbuf("device-hdd", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - iremovable = std::shared_ptr(new RTPixbuf("device-usb", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - inetwork = std::shared_ptr(new RTPixbuf("device-network", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - //Create the Tree model: dirTreeModel = Gtk::TreeStore::create(dtColumns); dirtree->set_model (dirTreeModel); @@ -136,10 +136,9 @@ void DirBrowser::fillDirTree () fillRoot (); Gtk::CellRendererPixbuf* render_pb = Gtk::manage ( new Gtk::CellRendererPixbuf () ); + render_pb->property_stock_size() = Gtk::ICON_SIZE_SMALL_TOOLBAR; tvc.pack_start (*render_pb, false); - tvc.add_attribute(*render_pb, "pixbuf-expander-closed", dtColumns.icon2); - tvc.add_attribute(*render_pb, "pixbuf", dtColumns.icon2); - tvc.add_attribute(*render_pb, "pixbuf-expander-open", dtColumns.icon1); + tvc.add_attribute(*render_pb, "icon-name", dtColumns.icon_name); tvc.pack_start (crt); tvc.add_attribute(crt, "text", dtColumns.filename); @@ -156,6 +155,7 @@ void DirBrowser::fillDirTree () render_pb->property_ypad() = 0; dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded)); + dirtree->signal_row_collapsed().connect(sigc::mem_fun(*this, &DirBrowser::row_collapsed)); dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated)); dirTreeModel->signal_sort_column_changed().connect(sigc::mem_fun(*this, &DirBrowser::on_sort_column_changed)); } @@ -175,22 +175,17 @@ void DirBrowser::addRoot (char letter) int type = GetDriveType (volume); if (type == DRIVE_CDROM) { - root->set_value (0, icdrom->get()); - root->set_value (1, icdrom->get()); + root->set_value (dtColumns.icon_name, icdrom); } else if (type == DRIVE_REMOVABLE) { if (letter - 'A' < 2) { - root->set_value (0, ifloppy->get()); - root->set_value (1, ifloppy->get()); + root->set_value (dtColumns.icon_name, ifloppy); } else { - root->set_value (0, iremovable->get()); - root->set_value (1, iremovable->get()); + root->set_value (dtColumns.icon_name, iremovable); } } else if (type == DRIVE_REMOTE) { - root->set_value (0, inetwork->get()); - root->set_value (1, inetwork->get()); + root->set_value (dtColumns.icon_name, inetwork); } else if (type == DRIVE_FIXED) { - root->set_value (0, ihdd->get()); - root->set_value (1, ihdd->get()); + root->set_value (dtColumns.icon_name, ihdd); } Gtk::TreeModel::iterator child = dirTreeModel->append (root->children()); @@ -319,11 +314,20 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk:: expandSuccess = true; + // Update row icon + iter->set_value(dtColumns.icon_name, openfolder); + 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())); } +void DirBrowser::row_collapsed (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) +{ + // Update row icon + iter->set_value(dtColumns.icon_name, closedfolder); +} + void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) { @@ -366,8 +370,7 @@ void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustri Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children()); child->set_value (dtColumns.filename, dirname); - child->set_value (dtColumns.icon1, openfolder->get()); - child->set_value (dtColumns.icon2, closedfolder->get()); + child->set_value (dtColumns.icon_name, 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()); diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h index 599f9fa16..706efb8bb 100644 --- a/rtgui/dirbrowser.h +++ b/rtgui/dirbrowser.h @@ -23,8 +23,6 @@ #include "guiutils.h" -class RTPixbuf; - class DirBrowser : public Gtk::Box { public: @@ -37,15 +35,13 @@ private: struct DirTreeColumns : public Gtk::TreeModelColumnRecord { public: Gtk::TreeModelColumn filename; - Gtk::TreeModelColumn > icon1; - Gtk::TreeModelColumn > icon2; + Gtk::TreeModelColumn icon_name; Gtk::TreeModelColumn dirname; Gtk::TreeModelColumn > monitor; DirTreeColumns() { - add(icon1); - add(icon2); + add(icon_name); add(filename); add(dirname); add(monitor); @@ -55,7 +51,6 @@ private: DirTreeColumns dtColumns; Gtk::TreeViewColumn tvc; Gtk::CellRendererText crt; - Gtk::CellRendererPixbuf crb; Gtk::TreeView *dirtree; @@ -64,13 +59,13 @@ private: void fillRoot (); - std::shared_ptr openfolder; - std::shared_ptr closedfolder; - std::shared_ptr icdrom; - std::shared_ptr ifloppy; - std::shared_ptr ihdd; - std::shared_ptr inetwork; - std::shared_ptr iremovable; + Glib::ustring openfolder; + Glib::ustring closedfolder; + Glib::ustring icdrom; + Glib::ustring ifloppy; + Glib::ustring ihdd; + Glib::ustring inetwork; + Glib::ustring iremovable; bool expandSuccess; @@ -96,6 +91,7 @@ public: void fillDirTree (); void on_sort_column_changed() const; void row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path); + void row_collapsed (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" diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index f922e2084..60691d8b6 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -38,11 +38,11 @@ //extern Glib::Threads::Thread* mainThread; bool FileBrowserEntry::iconsLoaded(false); -std::shared_ptr FileBrowserEntry::editedIcon(std::shared_ptr(nullptr)); -std::shared_ptr FileBrowserEntry::recentlySavedIcon(std::shared_ptr(nullptr)); -std::shared_ptr FileBrowserEntry::enqueuedIcon(std::shared_ptr(nullptr)); -std::shared_ptr FileBrowserEntry::hdr(std::shared_ptr(nullptr)); -std::shared_ptr FileBrowserEntry::ps(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::editedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::recentlySavedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::enqueuedIcon(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::hdr(std::shared_ptr(nullptr)); +std::shared_ptr FileBrowserEntry::ps(std::shared_ptr(nullptr)); FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), press_x(0), press_y(0), action_x(0), action_y(0), rot_deg(0.0), landscape(true), cropParams(new rtengine::procparams::CropParams), cropgl(nullptr), state(SNormal), crop_custom_ratio(0.f) @@ -61,11 +61,11 @@ FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) scale = 1; if (!iconsLoaded) { - editedIcon = std::shared_ptr(new RTPixbuf("tick-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - recentlySavedIcon = std::shared_ptr(new RTPixbuf("save-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - enqueuedIcon = std::shared_ptr(new RTPixbuf("gears-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - hdr = std::shared_ptr(new RTPixbuf("filetype-hdr", Gtk::ICON_SIZE_SMALL_TOOLBAR)); - ps = std::shared_ptr(new RTPixbuf("filetype-ps", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + editedIcon = std::shared_ptr(new RTSurface("tick-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + recentlySavedIcon = std::shared_ptr(new RTSurface("save-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + enqueuedIcon = std::shared_ptr(new RTSurface("gears-small", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + hdr = std::shared_ptr(new RTSurface("filetype-hdr", Gtk::ICON_SIZE_SMALL_TOOLBAR)); + ps = std::shared_ptr(new RTSurface("filetype-ps", Gtk::ICON_SIZE_SMALL_TOOLBAR)); iconsLoaded = true; } @@ -125,43 +125,43 @@ void FileBrowserEntry::calcThumbnailSize () } } -std::vector> FileBrowserEntry::getIconsOnImageArea () +std::vector> FileBrowserEntry::getIconsOnImageArea () { if (!thumbnail) { return {}; } - std::vector> ret; + std::vector> ret; if (thumbnail->hasProcParams() && editedIcon) { - ret.push_back(editedIcon->get()); + ret.push_back(editedIcon); } if (thumbnail->isRecentlySaved() && recentlySavedIcon) { - ret.push_back(recentlySavedIcon->get()); + ret.push_back(recentlySavedIcon); } if (thumbnail->isEnqueued () && enqueuedIcon) { - ret.push_back(enqueuedIcon->get()); + ret.push_back(enqueuedIcon); } return ret; } -std::vector> FileBrowserEntry::getSpecificityIconsOnImageArea () +std::vector> FileBrowserEntry::getSpecificityIconsOnImageArea () { if (!thumbnail) { return {}; } - std::vector> ret; + std::vector> ret; if (thumbnail->isHDR() && hdr) { - ret.push_back (hdr->get()); + ret.push_back (hdr); } if (thumbnail->isPixelShift() && ps) { - ret.push_back (ps->get()); + ret.push_back (ps); } return ret; diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index fcf916f00..0b0b07b7c 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -35,7 +35,7 @@ class FileBrowserEntry; class Thumbnail; -class RTPixbuf; +class RTSurface; struct FileBrowserEntryIdleHelper { FileBrowserEntry* fbentry; @@ -73,11 +73,11 @@ class FileBrowserEntry final : public ThumbBrowserEntryBase, public: - static std::shared_ptr editedIcon; - static std::shared_ptr recentlySavedIcon; - static std::shared_ptr enqueuedIcon; - static std::shared_ptr hdr; - static std::shared_ptr ps; + static std::shared_ptr editedIcon; + static std::shared_ptr recentlySavedIcon; + static std::shared_ptr enqueuedIcon; + static std::shared_ptr hdr; + static std::shared_ptr ps; FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); ~FileBrowserEntry () override; @@ -94,8 +94,8 @@ public: void refreshQuickThumbnailImage () override; void calcThumbnailSize () override; - std::vector> getIconsOnImageArea () override; - std::vector> getSpecificityIconsOnImageArea () override; + std::vector> getIconsOnImageArea () override; + std::vector> getSpecificityIconsOnImageArea () override; void getIconSize (int& w, int& h) const override; // thumbnaillistener interface diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index b161591cb..26ea0542e 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -138,7 +138,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us // Directly use fname as a path path = fname; } else { - // Look for PNG file in "images" folder + // Look for SVG file in "images" folder Glib::ustring imagesFolder = Glib::build_filename(DATA_SEARCH_PATH, "images"); path = Glib::build_filename(imagesFolder, fname); } diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index b72a87d0d..dccb3271c 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -88,18 +88,68 @@ RTSurface::RTSurface(const Glib::ustring &fname) : int RTSurface::getWidth() { - return - surface - ? (surface->get_width() / RTScalable::getScale()) - : -1; + int w, h; + + if (hasSurface()) { + switch (type) { + case RTSurface::IconType: + // Get width from Gtk::IconSize + if (!Gtk::IconSize::lookup(icon_size, w, h)) { // Size in invalid + w = h = -1; // Invalid case + } + + return w; + + case RTSurface::PNGType: + // Directly return surface width + return surface->get_width(); + + case RTSurface::SVGType: + // Returned size shall consider the scaling + return (surface->get_width() / RTScalable::getScale()); + + case RTSurface::InvalidType: + default: + // Invalid case + return -1; + } + } else { + // Invalid case + return -1; + } } int RTSurface::getHeight() { - return - surface - ? (surface->get_height() / RTScalable::getScale()) - : -1; + int w, h; + + if (hasSurface()) { + switch (type) { + case RTSurface::IconType: + // Get width from Gtk::IconSize + if (!Gtk::IconSize::lookup(icon_size, w, h)) { // Size in invalid + w = h = -1; // Invalid case + } + + return h; + + case RTSurface::PNGType: + // Directly return surface width + return surface->get_height(); + + case RTSurface::SVGType: + // Returned size shall consider the scaling + return (surface->get_height() / RTScalable::getScale()); + + case RTSurface::InvalidType: + default: + // Invalid case + return -1; + } + } else { + // Invalid case + return -1; + } } bool RTSurface::hasSurface() @@ -132,168 +182,3 @@ Cairo::RefPtr RTSurface::get() return surface; } - -RTPixbuf::RTPixbuf() -{ - // Initialize "back" parameters from RTScalable - dpiBack = RTPixbuf::getDPI(); - scaleBack = RTPixbuf::getScale(); - - // Initialize other private parameters - type = RTPixbuf::InvalidType; - name = ""; - icon_size = Gtk::ICON_SIZE_INVALID; -} - -RTPixbuf::RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize) : - RTPixbuf() -{ - // Create surface - const Cairo::RefPtr surface = RTScalable::loadSurfaceFromIcon(icon_name, iconSize); - - if (surface) { - // Downscale surface before creating pixbuf - const Cairo::RefPtr _surface = Cairo::Surface::create(surface, - Cairo::CONTENT_COLOR_ALPHA, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - const auto c = Cairo::Context::create(_surface); - c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); - c->set_source(surface, 0., 0.); - c->paint(); - - // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(_surface, - 0, - 0, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - - // Save private parameters - type = RTPixbuf::IconType; - name = icon_name; - icon_size = iconSize; - } -} - -RTPixbuf::RTPixbuf(const Glib::ustring &fname) : - RTPixbuf() -{ - // Create surface based on file extension - const auto pos = fname.find_last_of('.'); - - if (pos >= 0 && pos < fname.length()) { - const auto fext = fname.substr(pos + 1, fname.length()).lowercase(); - - // Case where fname is a PNG file - if (fext == "png") { - // Create surface from PNG file - const Cairo::RefPtr surface = RTScalable::loadSurfaceFromPNG(fname); - - if (surface) { - // Downscale surface before creating pixbuf - const Cairo::RefPtr _surface = Cairo::Surface::create(surface, - Cairo::CONTENT_COLOR_ALPHA, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - const auto c = Cairo::Context::create(_surface); - c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); - c->set_source(surface, 0., 0.); - c->paint(); - - // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(_surface, - 0, - 0, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - - // Save private parameter - type = RTPixbuf::PNGType; - name = fname; - } - } - - // Case where fname is a SVG file - if (fext == "svg") { - // Create surface from SVG file - const Cairo::RefPtr surface = RTScalable::loadSurfaceFromSVG(fname); - - if (surface) { - // Downscale surface before creating pixbuf - const Cairo::RefPtr _surface = Cairo::Surface::create(surface, - Cairo::CONTENT_COLOR_ALPHA, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - const auto c = Cairo::Context::create(_surface); - c->scale(1. / static_cast(RTScalable::getScale()), 1. / static_cast(RTScalable::getScale())); - c->set_source(surface, 0., 0.); - c->paint(); - - // Create pixbuf from surface - pixbuf = Gdk::Pixbuf::create(_surface, - 0, - 0, - surface->get_width() / RTScalable::getScale(), - surface->get_height() / RTScalable::getScale()); - - // Save private parameter - type = RTPixbuf::SVGType; - name = fname; - } - } - } -} - -int RTPixbuf::getWidth() -{ - return - pixbuf - ? pixbuf->get_width() - : -1; -} - -int RTPixbuf::getHeight() -{ - return - pixbuf - ? pixbuf->get_height() - : -1; -} - -bool RTPixbuf::hasPixbuf() -{ - return static_cast(pixbuf); -} - -Glib::RefPtr RTPixbuf::get() -{ - if (dpiBack != RTScalable::getDPI() || - scaleBack != RTScalable::getScale()) { - Cairo::RefPtr surface; - - // Surface needs to be regenerated - switch (type) { - case RTPixbuf::IconType : - surface = RTScalable::loadSurfaceFromIcon(name, icon_size); - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); - break; - case RTPixbuf::PNGType : - surface = RTScalable::loadSurfaceFromPNG(name); - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); - break; - case RTPixbuf::SVGType : - surface = RTScalable::loadSurfaceFromSVG(name); - pixbuf = Gdk::Pixbuf::create(surface, 0, 0, surface->get_width(), surface->get_height()); - break; - default : - break; - } - - // Save new DPI and scale - dpiBack = RTScalable::getDPI(); - scaleBack = RTScalable::getScale(); - } - - return pixbuf; -} diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index 46a8bcdb5..e58c1b206 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -53,36 +53,3 @@ public: Cairo::RefPtr get(); }; - -/** - * @brief A custom class in order to handle Hi-DPI pixbuf. - */ -class RTPixbuf final : public RTScalable -{ -public: - enum RTPixbufType { - InvalidType = 1, - IconType = 2, - PNGType = 3, - SVGType = 4 - }; - -private: - double dpiBack; // Used to identify dpi change - int scaleBack; // Used to identify scale change - RTPixbufType type; - Glib::ustring name; - Gtk::IconSize icon_size; - Glib::RefPtr pixbuf; - -public: - RTPixbuf(); - explicit RTPixbuf(const Glib::ustring &icon_name, const Gtk::IconSize iconSize); - explicit RTPixbuf(const Glib::ustring &fname); - - int getWidth(); - int getHeight(); - bool hasPixbuf(); - - Glib::RefPtr get(); -}; diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 306b491be..2b5c102e3 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -21,6 +21,7 @@ #include "options.h" #include "thumbbrowserbase.h" #include "../rtengine/rt_math.h" +#include "rtsurface.h" namespace { @@ -284,10 +285,10 @@ void ThumbBrowserEntryBase::updateBackBuffer () int iheight = 0; for (size_t i = 0; i < bbIcons.size(); i++) { - iwidth += bbIcons[i]->get_width() + (i > 0 ? igap : 0); + iwidth += bbIcons[i]->getWidth() + (i > 0 ? igap : 0); - if (bbIcons[i]->get_height() > iheight) { - iheight = bbIcons[i]->get_height(); + if (bbIcons[i]->getHeight() > iheight) { + iheight = bbIcons[i]->getHeight(); } } @@ -310,10 +311,10 @@ void ThumbBrowserEntryBase::updateBackBuffer () for (size_t i = 0; i < bbIcons.size(); i++) { // Draw the image at 110, 90, except for the outermost 10 pixels. - Gdk::Cairo::set_source_pixbuf(cc, bbIcons[i], istartx, istarty); - cc->rectangle(istartx, istarty, bbIcons[i]->get_width(), bbIcons[i]->get_height()); + cc->set_source(bbIcons[i]->get(), istartx, istarty); + cc->rectangle(istartx, istarty, bbIcons[i]->getWidth(), bbIcons[i]->getHeight()); cc->fill(); - istartx += bbIcons[i]->get_width() + igap; + istartx += bbIcons[i]->getWidth() + igap; } } @@ -323,9 +324,9 @@ void ThumbBrowserEntryBase::updateBackBuffer () int istarty2 = prey + preh - igap - 1; for (size_t i = 0; i < bbSpecificityIcons.size(); ++i) { - istartx2 -= bbSpecificityIcons[i]->get_width() - igap; - Gdk::Cairo::set_source_pixbuf(cc, bbSpecificityIcons[i], istartx2, istarty2 - bbSpecificityIcons[i]->get_height()); - cc->rectangle(istartx2, istarty2 - bbSpecificityIcons[i]->get_height(), bbSpecificityIcons[i]->get_width(), bbSpecificityIcons[i]->get_height()); + istartx2 -= bbSpecificityIcons[i]->getWidth() - igap; + cc->set_source(bbSpecificityIcons[i]->get(), istartx2, istarty2 - bbSpecificityIcons[i]->getHeight()); + cc->rectangle(istartx2, istarty2 - bbSpecificityIcons[i]->getHeight(), bbSpecificityIcons[i]->getWidth(), bbSpecificityIcons[i]->getHeight()); cc->fill(); } } @@ -694,14 +695,14 @@ bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) const return !(ofsX + startx > x + w || ofsX + startx + exp_width < x || ofsY + starty > y + h || ofsY + starty + exp_height < y); } -std::vector> ThumbBrowserEntryBase::getIconsOnImageArea() +std::vector> ThumbBrowserEntryBase::getIconsOnImageArea() { - return std::vector >(); + return std::vector>(); } -std::vector > ThumbBrowserEntryBase::getSpecificityIconsOnImageArea() +std::vector> ThumbBrowserEntryBase::getSpecificityIconsOnImageArea() { - return std::vector >(); + return std::vector>(); } bool ThumbBrowserEntryBase::motionNotify (int x, int y) diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index 764f806fd..fa3e8f0f3 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -31,6 +31,7 @@ class Thumbnail; class ThumbBrowserBase; +class RTSurface; class ThumbBrowserEntryBase { @@ -83,8 +84,8 @@ protected: Glib::RefPtr backBuffer; bool bbSelected, bbFramed; guint8* bbPreview; - std::vector> bbIcons; - std::vector> bbSpecificityIcons; + std::vector> bbIcons; + std::vector> bbSpecificityIcons; CursorShape cursor_type; void drawFrame (Cairo::RefPtr cr, const Gdk::RGBA& bg, const Gdk::RGBA& fg); @@ -185,8 +186,8 @@ public: virtual void drawProgressBar (Glib::RefPtr win, const Gdk::RGBA& foregr, const Gdk::RGBA& backgr, int x, int w, int y, int h) {} - virtual std::vector> getIconsOnImageArea (); - virtual std::vector> getSpecificityIconsOnImageArea (); + virtual std::vector> getIconsOnImageArea (); + virtual std::vector> getSpecificityIconsOnImageArea (); virtual void getIconSize (int& w, int& h) const = 0; virtual bool motionNotify (int x, int y); From 35ce0d12275a1c5c8c34f712751d3b93e2989305 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Mon, 29 Aug 2022 19:26:41 +0200 Subject: [PATCH 005/291] Fixes hi-dpi on Windows - Fixes incorrect install path for icons - Fixes incorrect font size conversion from "Pango units" (updates some comments) - Fixes incorrect volume icon in directory browser --- CMakeLists.txt | 2 ++ rtgui/dirbrowser.cc | 12 ++++++++---- rtgui/rtscalable.h | 4 +--- rtgui/rtwindow.cc | 10 +++++++--- rtgui/shcselector.cc | 3 +-- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0bd6e92b..4910a56d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -368,6 +368,8 @@ if(NOT DEFINED ICONSDIR) else() set(ICONSDIR "${CMAKE_INSTALL_PREFIX}/share/icons") endif() + else() + set(ICONSDIR "${DATADIR}/icons") endif() endif() diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 6a1168fa4..25cfd0ae3 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -314,8 +314,10 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk:: expandSuccess = true; - // Update row icon - iter->set_value(dtColumns.icon_name, openfolder); + // Update row icon (only if row icon is not a volume one or is empty) + if (iter->get_value(dtColumns.icon_name) == closedfolder || iter->get_value(dtColumns.icon_name) == "") { + iter->set_value(dtColumns.icon_name, openfolder); + } Glib::RefPtr monitor = dir->monitor_directory (); iter->set_value (dtColumns.monitor, monitor); @@ -324,8 +326,10 @@ void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk:: void DirBrowser::row_collapsed (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) { - // Update row icon - iter->set_value(dtColumns.icon_name, closedfolder); + // Update row icon (only if row icon is not a volume one) + if (iter->get_value(dtColumns.icon_name) == openfolder) { + iter->set_value(dtColumns.icon_name, closedfolder); + } } void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index f78c3bf3d..e96fdddfc 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -30,9 +30,7 @@ * * About Pango size convention (for font): * Pango size can be expressed in two different units: - * - Absolute size (i.e. "px"): If size is int type, absolute size is given in "Pango unit" - * shall be divided by Pango::SCALE (i.e. 1024) to get "px". If size is double, absolute - * is already given in "px". + * - Absolute size (i.e. "px") * - Non-absolute size (i.e. "pt"): The default resolution is 72 DPI (i.e. pt per inch). To * convert the size to "px", use the following formula: * "size in px" = "size in pt" * ("device resolution" / 72) * "device scale" diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index fede08a9a..11d4087f3 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -195,14 +195,14 @@ RTWindow::RTWindow () Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { - const int fontSize = pfd.get_size(); + int fontSize = pfd.get_size(); const bool isAbsoluteFontSize = pfd.get_size_is_absolute(); int newFontSize; if (isAbsoluteFontSize) { // Absolute size is defined in "Pango units" and shall be divided by // Pango::SCALE to get "px" - newFontSize = fontSize / Pango::SCALE; + fontSize = fontSize / Pango::SCALE; #ifndef __APPLE__ // Guessing that pixel size is given for a 96 DPI reference: @@ -213,12 +213,16 @@ RTWindow::RTWindow () // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c const double newFontScale = 1.; #endif - newFontSize = static_cast(newFontSize * newFontScale + 0.5); + newFontSize = static_cast(fontSize * newFontScale + 0.5); if (rtengine::settings->verbose) { printf("\"Default\" absolute font size(%d)\n", newFontSize); } } else { + // Non-absolute size is defined in "Pango units" and shall be divided by + // Pango::SCALE to get "px" + fontSize = fontSize / Pango::SCALE; + // Non-absolute size is defined in "pt" and shall be converted to "px" newFontSize = static_cast(fontSize * fontScale + 0.5); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index dc7e06936..132a5f1ef 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -195,8 +195,7 @@ void SHCSelector::updateBackBuffer() // update font fontd.set_weight (Pango::WEIGHT_NORMAL); - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px" + const double fontSize = static_cast(h) * 0.8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ From 1c859262001c7865946739baa8414c5369f45031 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 2 Sep 2022 19:15:42 +0200 Subject: [PATCH 006/291] Creates an RTImage cache Fixes: - Fixes GUI issue on Windows (GDI handles limit reached) - Fixes an incorrect icon name in Perspective tool - Adds robustness RTScalable::loadSurfaceFromIcon function --- rtgui/perspective.cc | 2 +- rtgui/rtimage.cc | 82 +++++++++++++++++++++++++++++++++++++++++--- rtgui/rtimage.h | 18 +++++++++- rtgui/rtscalable.cc | 16 +++++++-- rtgui/rtsurface.cc | 32 ++++++++++------- rtgui/rtsurface.h | 1 + 6 files changed, 130 insertions(+), 21 deletions(-) diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index 83b6c660f..af182617e 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -120,7 +120,7 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M(" RTImage* const ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small")); RTImage* const ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small")); - RTImage* const ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-botton", Gtk::ICON_SIZE_BUTTON)); + RTImage* const ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-bottom", Gtk::ICON_SIZE_BUTTON)); RTImage* const ipers_auto_yaw = Gtk::manage (new RTImage ("perspective-horizontal-left", Gtk::ICON_SIZE_BUTTON)); RTImage* const ipers_auto_pitch_yaw = Gtk::manage (new RTImage ("perspective-horizontal-vertical", Gtk::ICON_SIZE_BUTTON)); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 2040ec21d..6096b9251 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -21,21 +21,95 @@ #include "rtimage.h" +#include "rtsurface.h" + +std::map, std::shared_ptr> RTImageCache::cache; + +std::shared_ptr RTImageCache::getCachedSurface(const Glib::ustring &icon_name, const Gtk::IconSize icon_size) +{ + // Look for an existing cached icon + const auto key = std::pair(icon_name, icon_size); + const auto item = cache.find(key); + + if (item != cache.end()) { // A cached icon exists + return item->second; + } else { // Create the icon + auto surface = std::shared_ptr(new RTSurface(icon_name, icon_size)); + + // Add the surface to the cache if the icon exist + if (surface) { + cache.insert({key, surface}); + } + + return surface; + } +} + +void RTImageCache::updateCache() +{ + // Iterate over cache to updated RTSurface + for (auto const& item : cache) { + item.second->updateSurface(); + } +} + RTImage::RTImage () {} RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) : - Gtk::Image(iconName, iconSize), - size(iconSize) + Gtk::Image(), + size(iconSize), + icon_name(iconName) { + // Set surface from icon cache + surface = RTImageCache::getCachedSurface(this->icon_name, this->size); + + // Add it to the RTImage if surface exists + if (surface) { + set(surface->get()); + } } void RTImage::set_from_icon_name(const Glib::ustring& iconName) { - Gtk::Image::set_from_icon_name(iconName, this->size); + this->icon_name = iconName; + + // Set surface from icon cache + surface = RTImageCache::getCachedSurface(this->icon_name, this->size); + + // Add it to the RTImage if surface exists + if (surface) { + set(surface->get()); + } } void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize) { + this->icon_name = iconName; this->size = iconSize; - Gtk::Image::set_from_icon_name(iconName, this->size); + + // Set surface from icon cache + surface = RTImageCache::getCachedSurface(this->icon_name, this->size); + + // Add it to the RTImage if surface exists + if (surface) { + set(surface->get()); + } +} + +int RTImage::get_width() +{ + if (surface) { + return surface->getWidth(); + } + + return -1; +} + +int RTImage::get_height() +{ + if (surface) { + return surface->getHeight(); + } + + return -1; } diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 895267dbd..0908683c8 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -20,7 +20,18 @@ */ #pragma once -#include +#include + +class RTSurface; +class RTImageCache final +{ +private: + static std::map, std::shared_ptr> cache; + +public: + static std::shared_ptr getCachedSurface(const Glib::ustring &icon_name, const Gtk::IconSize icon_size); + static void updateCache(); +}; /** * @brief A derived class of Gtk::Image in order to handle theme-related icon sets. @@ -29,6 +40,8 @@ class RTImage final : public Gtk::Image { private: Gtk::IconSize size; + Glib::ustring icon_name; + std::shared_ptr surface; public: RTImage (); @@ -36,4 +49,7 @@ public: void set_from_icon_name(const Glib::ustring& iconName); void set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize); + + int get_width(); + int get_height(); }; diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 26ea0542e..586d38dfa 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -68,10 +68,22 @@ Cairo::RefPtr RTScalable::loadSurfaceFromIcon(const Glib::u // Looking for corresponding icon (if existing) const auto iconInfo = theme->lookup_icon(iconName, size); + + if (!iconInfo) { + if (rtengine::settings->verbose) { + std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; + } + + return surf; + } + const auto iconPath = iconInfo.get_filename(); - if ((iconPath.empty() || !iconInfo) && rtengine::settings->verbose) { - std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; + if (iconPath.empty()) { + if (rtengine::settings->verbose) { + std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; + } + return surf; } diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index dccb3271c..d26f2cb02 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -161,19 +161,7 @@ Cairo::RefPtr RTSurface::get() { if (dpiBack != RTScalable::getDPI() || scaleBack != RTScalable::getScale()) { - switch (type) { - case RTSurface::IconType : - surface = RTScalable::loadSurfaceFromIcon(name, icon_size); - break; - case RTSurface::PNGType : - surface = RTScalable::loadSurfaceFromPNG(name); - break; - case RTSurface::SVGType : - surface = RTScalable::loadSurfaceFromSVG(name); - break; - default : - break; - } + updateSurface(); // Save new DPI and scale dpiBack = RTScalable::getDPI(); @@ -182,3 +170,21 @@ Cairo::RefPtr RTSurface::get() return surface; } + +void RTSurface::updateSurface() +{ + // Update surface based on the scale + switch (type) { + case RTSurface::IconType : + surface = RTScalable::loadSurfaceFromIcon(name, icon_size); + break; + case RTSurface::PNGType : + surface = RTScalable::loadSurfaceFromPNG(name); + break; + case RTSurface::SVGType : + surface = RTScalable::loadSurfaceFromSVG(name); + break; + default : + break; + } +} diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index e58c1b206..629a07a83 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -52,4 +52,5 @@ public: bool hasSurface(); Cairo::RefPtr get(); + void updateSurface(); }; From 68d1eae1a7c6c9e87d27f5f7e25105298847e210 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Wed, 2 Nov 2022 13:12:24 +0100 Subject: [PATCH 007/291] Hidpi support for histogram panel Other fixes: - Reduce number of queue_draw function calls (and so optimize panel redraw) - Code cleanup --- rtgui/histogrampanel.cc | 844 +++++++++++++++++++--------------------- rtgui/histogrampanel.h | 161 ++++---- 2 files changed, 480 insertions(+), 525 deletions(-) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index a7e652460..98a9a2789 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -42,24 +42,28 @@ HistogramPanel::HistogramPanel () : pointer_moved_delayed_call( [this](bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int r, int g, int b) { - bool update_hist_area; + bool update_hist_area, update_hist_rgb_area; if (!validPos) { // do something to un-show vertical bars if (histogramRGBArea) { - histogramRGBArea->updateBackBuffer(-1, -1, -1); + update_hist_rgb_area = histogramRGBArea->updatePointer(-1, -1, -1); } + update_hist_area = histogramArea->updatePointer(-1, -1, -1); } else { // do something to show vertical bars if (histogramRGBArea) { - histogramRGBArea->updateBackBuffer(r, g, b, profile, profileW); + update_hist_rgb_area = histogramRGBArea->updatePointer(r, g, b, profile, profileW); } + update_hist_area = histogramArea->updatePointer(r, g, b, profile, profileW); } - if (histogramRGBArea) { + + if (histogramRGBArea && update_hist_rgb_area) { histogramRGBArea->queue_draw(); } + if (update_hist_area) { histogramArea->queue_draw(); } @@ -279,14 +283,14 @@ HistogramPanel::HistogramPanel () : scopeOptions->set_image(*Gtk::manage(new RTImage("histogram-ellipsis-small"))); showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g); - setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties(showRed, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - setExpandAlignProperties(showBlue , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties(showBlue, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); setExpandAlignProperties(showValue, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - setExpandAlignProperties(showChro , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); - setExpandAlignProperties(showMode , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties(showChro, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties(showMode, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); setExpandAlignProperties(scopeOptions, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - setExpandAlignProperties(showBAR , false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + setExpandAlignProperties(showBAR, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); setExpandAlignProperties(scopeOptions, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); setExpandAlignProperties(scopeHistBtn, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); setExpandAlignProperties(scopeHistRawBtn, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); @@ -361,9 +365,13 @@ HistogramPanel::HistogramPanel () : optionButtons->set_visible(options.histogramShowOptionButtons); type_changed(); - updateHistAreaOptions(); + + // Update histogramArea internal parameters from options + histogramArea->updateFromOptions(); + if (histogramRGBArea) { - updateHistRGBAreaOptions(); + // Update histogramRGBArea internal parameters from options + histogramRGBArea->updateFromOptions(); } brightness_changed_connection = histogramArea->getBrighnessChangedSignal().connect(sigc::mem_fun(*this, &HistogramPanel::brightnessUpdated)); @@ -392,7 +400,6 @@ HistogramPanel::~HistogramPanel () delete valueImage_g; delete chroImage_g; delete barImage_g; - } void HistogramPanel::showRGBBar() @@ -401,15 +408,6 @@ void HistogramPanel::showRGBBar() histogramRGBArea == histogramRGBAreaHori.get() && showBAR->get_active()); histogramRGBAreaVert->set_visible( histogramRGBArea == histogramRGBAreaVert.get() && showBAR->get_active()); - histogramRGBAreaHori->setShow(false); - histogramRGBAreaVert->setShow(false); - - if (!histogramRGBArea) { - return; - } - - setHistRGBInvalid(); - histogramRGBArea->setShow(showBAR->get_active()); } void HistogramPanel::resized (Gtk::Allocation& req) @@ -420,14 +418,15 @@ void HistogramPanel::resized (Gtk::Allocation& req) bool size_changed = old_height != req.get_height() || old_width != req.get_width(); - if (!histogramArea->updatePending() && size_changed) { - histogramArea->updateBackBuffer (); + // Set HistogramArea invalid + if (size_changed) { + histogramArea->updatePointer(-1, -1, -1); histogramArea->queue_draw (); } - // set histogramRGBArea invalid; + // Set HistogramRGBArea invalid if (histogramRGBArea && size_changed) { - histogramRGBArea->updateBackBuffer(-1, -1, -1); + histogramRGBArea->updatePointer(-1, -1, -1); histogramRGBArea->queue_draw (); } @@ -440,43 +439,65 @@ void HistogramPanel::resized (Gtk::Allocation& req) void HistogramPanel::red_toggled () { + // Update button image showRed->set_image(showRed->get_active() ? *redImage : *redImage_g); + // Update options value + options.histogramRed = showRed->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); } + void HistogramPanel::green_toggled () { + // Update button image showGreen->set_image(showGreen->get_active() ? *greenImage : *greenImage_g); + // Update options value + options.histogramGreen = showGreen->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); } + void HistogramPanel::blue_toggled () { + // Update button image showBlue->set_image(showBlue->get_active() ? *blueImage : *blueImage_g); + // Update options value + options.histogramBlue = showBlue->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); } void HistogramPanel::value_toggled () { - removeIfThere(showValue, valueImage, false); - removeIfThere(showValue, valueImage_g, false); + // Update button image showValue->set_image(showValue->get_active() ? *valueImage : *valueImage_g); + // Update options value + options.histogramLuma = showValue->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); } void HistogramPanel::chro_toggled () { - removeIfThere(showChro, chroImage, false); - removeIfThere(showChro, chroImage_g, false); + // Update button image showChro->set_image(showChro->get_active() ? *chroImage : *chroImage_g); + // Update options value + options.histogramChroma = showChro->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); } void HistogramPanel::mode_released () { + // Update options value options.histogramDrawMode = (options.histogramDrawMode + 1) % 3; - if (options.histogramDrawMode == 0) + // Update button image + if (options.histogramDrawMode == 0) { showMode->set_image(*mode0Image); - else if (options.histogramDrawMode == 1) + } else if (options.histogramDrawMode == 1) { showMode->set_image(*mode1Image); - else + } else { showMode->set_image(*mode2Image); + } + // Update drawing areas rgbv_toggled(); } @@ -495,12 +516,15 @@ void HistogramPanel::brightnessUpdated(float brightness) void HistogramPanel::scopeOptionsToggled() { + // Update options value options.histogramShowOptionButtons = scopeOptions->get_active(); + // Show/hide secondary buttons column optionButtons->set_visible(scopeOptions->get_active()); } void HistogramPanel::type_selected(Gtk::RadioButton* button) { + // Get radio button value ScopeType new_type = ScopeType::NONE; if (button == scopeHistBtn) { @@ -517,19 +541,35 @@ void HistogramPanel::type_selected(Gtk::RadioButton* button) new_type = ScopeType::VECTORSCOPE_HS; } + // Do not update if selected radio button is identical if (new_type == options.histogramScopeType) { return; } + // Update options value options.histogramScopeType = new_type; - + // Update histogram panel GUI based on scope type type_changed(); - updateHistAreaOptions(); + if (histogramRGBArea) { - updateHistRGBAreaOptions(); + // Update histogramRGBArea internal parameters from options + histogramRGBArea->updateFromOptions(); + // Set pointer invalid for histogramRGBArea + histogramRGBArea->updatePointer(-1, -1, -1); + // Update drawing area + histogramRGBArea->queue_draw (); } - histogramArea->setDirty(true); - histogramArea->queue_draw(); + + // Update histogramArea internal parameters from options + histogramArea->updateFromOptions(); + // Set pointer invalid for histogramArea + histogramArea->updatePointer(-1, -1, -1); + // Update drawing area + // Note: No need to call queue_draw as an update of histogram data + // is requested in the type_changed function: queue_draw call will + // be performed in update function when updated histogram data are + // provided + // histogramArea->queue_draw(); } void HistogramPanel::type_changed() @@ -588,42 +628,47 @@ void HistogramPanel::type_changed() break; } + // Request histogram data update if (panel_listener) { - updateHistAreaOptions(); panel_listener->scopeTypeChanged(options.histogramScopeType); } + // Update histogram bar visibility showRGBBar(); } void HistogramPanel::bar_toggled () { + // Update button image showBAR->set_image(showBAR->get_active() ? *barImage : *barImage_g); + // Update options value + options.histogramBar = showBAR->get_active() ? true : false; + // Update drawing areas rgbv_toggled(); + // Update histogram bar visibility showRGBBar(); } void HistogramPanel::rgbv_toggled () { // Update Display - updateHistAreaOptions(); - histogramArea->updateBackBuffer (); + // Update histogramArea internal parameters from options + histogramArea->updateFromOptions(); + // Set pointer invalid for histogramArea + histogramArea->updatePointer(-1, -1, -1); + // Update drawing area histogramArea->queue_draw (); if (histogramRGBArea) { - updateHistRGBAreaOptions(); - histogramRGBArea->updateBackBuffer(-1, -1, -1); + // Update histogramRGBArea internal parameters from options + histogramRGBArea->updateFromOptions(); + // Set pointer invalid for histogramRGBArea + histogramRGBArea->updatePointer(-1, -1, -1); + // Update drawing area histogramRGBArea->queue_draw (); } } -void HistogramPanel::setHistRGBInvalid () -{ - // do something to un-show vertical bars - histogramRGBArea->updateBackBuffer(-1, -1, -1); - histogramRGBArea->queue_draw (); -} - void HistogramPanel::pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw) { pointer_moved_delayed_call(validPos, profile, profileW, r, g, b); @@ -684,32 +729,6 @@ void HistogramPanel::setPanelListener(HistogramPanelListener* listener) } } -void HistogramPanel::updateHistAreaOptions() -{ - histogramArea->updateOptions( - showRed->get_active(), - showGreen->get_active(), - showBlue->get_active(), - showValue->get_active(), - showChro->get_active(), - options.histogramDrawMode, - options.histogramScopeType, - showBAR->get_active() - ); -} - -void HistogramPanel::updateHistRGBAreaOptions() -{ - histogramRGBArea->updateOptions( - showRed->get_active(), - showGreen->get_active(), - showBlue->get_active(), - showValue->get_active(), - showChro->get_active(), - showBAR->get_active() - ); -} - // // // @@ -725,31 +744,19 @@ double HistogramScaling::log(double vsize, double val) // // HistogramRGBArea HistogramRGBArea::HistogramRGBArea () : - val(0), r(0), g(0), b(0), valid(false), - needRed(options.histogramRed), needGreen(options.histogramGreen), needBlue(options.histogramBlue), - needLuma(options.histogramLuma), needChroma(options.histogramChroma), - showMode(options.histogramBar), barDisplayed(options.histogramBar), parent(nullptr) + // Saved pointer parameters + r(-1), g(-1), b(-1), lab_L(0.f), lab_a(0.f), lab_b(0.f), pointerValid(false), + // Drawing options (initialized at options file values) + needRed(options.histogramRed), needGreen(options.histogramGreen), + needBlue(options.histogramBlue), needLuma(options.histogramLuma), + needChroma(options.histogramChroma), scopeType(options.histogramScopeType), + scaleMode(options.histogramDrawMode), showBar(options.histogramBar) { get_style_context()->add_class("drawingarea"); set_name("HistogramRGBArea"); - - harih = new HistogramRGBAreaIdleHelper; - harih->harea = this; - harih->destroyed = false; - harih->pending = 0; -} - -HistogramRGBArea::~HistogramRGBArea () -{ - idle_register.destroy(); - - if (harih->pending) { - harih->destroyed = true; - } else { - delete harih; - } } +HistogramRGBArea::~HistogramRGBArea () {} void HistogramRGBArea::getPreferredThickness(int& min_thickness, int& natural_thickness) const { @@ -785,169 +792,137 @@ void HistogramRGBArea::getPreferredLengthForThickness(int thickness, int& min_le getPreferredLength(min_length, natural_length); } -bool HistogramRGBArea::getShow() +void HistogramRGBArea::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cc) { - return(showMode); -} - -void HistogramRGBArea::setShow(bool show) -{ - showMode = show; -} - -void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW) -{ - if (!get_realized () || !showMode || !( - options.histogramScopeType == ScopeType::HISTOGRAM - || options.histogramScopeType == ScopeType::PARADE - || options.histogramScopeType == ScopeType::WAVEFORM - )) { + // Do not update drawing area if widget is not realized + if (!get_realized ()) { return; } - // Mostly not necessary, but should be in some case - GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + // Do not update drawing area if bar is not visible + // (by user choice or according to scope type) + if (!showBar || scopeType == Options::ScopeType::HISTOGRAM_RAW || + scopeType == Options::ScopeType::VECTORSCOPE_HC || + scopeType == Options::ScopeType::VECTORSCOPE_HS) { + return; + } + + // Do not update drawing area if pointer is not valid + if (!pointerValid) { + return; + } + + // Note: updateDrawingArea is called by the on_draw function so its call does not need to be protected + // GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected Glib::RefPtr window = get_window(); int winx, winy, winw, winh; window->get_geometry(winx, winy, winw, winh); - const double s = RTScalable::scalePixelSize(1.); + cc->set_operator (Cairo::OPERATOR_OVER); + cc->set_antialias(Cairo::ANTIALIAS_NONE); + cc->set_line_width (1.0); - // This will create or update the size of the BackBuffer::surface - setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, winw, winh, true); - - if (surface) { - Cairo::RefPtr cc = Cairo::Context::create(surface); - - cc->set_source_rgba (0., 0., 0., 0.); - cc->set_operator (Cairo::OPERATOR_CLEAR); - cc->paint (); - cc->set_operator (Cairo::OPERATOR_OVER); - - cc->set_antialias(Cairo::ANTIALIAS_NONE); - cc->set_line_width (1.0 * s); - - if ( r != -1 && g != -1 && b != -1 ) { - if (needRed) { - // Red - cc->set_source_rgb(1.0, 0.0, 0.0); - drawBar(cc, r, 255.0, winw, winh, s); - } - - if (needGreen) { - // Green - cc->set_source_rgb(0.0, 1.0, 0.0); - drawBar(cc, g, 255.0, winw, winh, s); - } - - if (needBlue) { - // Blue - cc->set_source_rgb(0.0, 0.4, 1.0); - drawBar(cc, b, 255.0, winw, winh, s); - } - - if( - (needLuma || needChroma) - && (options.histogramScopeType == ScopeType::HISTOGRAM - || options.histogramScopeType == ScopeType::PARADE - || options.histogramScopeType == ScopeType::WAVEFORM) - ) { - float Lab_L, Lab_a, Lab_b; - rtengine::Color::rgb2lab01(profile, profileW, r / 255.f, g / 255.f, b / 255.f, Lab_L, Lab_a, Lab_b, options.rtSettings.HistogramWorking); - - if (needLuma) { - // Luma - cc->set_source_rgb(1.0, 1.0, 1.0); - drawBar(cc, Lab_L, 100.0, winw, winh, s); - } - - if (needChroma && options.histogramScopeType == ScopeType::HISTOGRAM) { - // Chroma - double chromaval = sqrt(Lab_a * Lab_a + Lab_b * Lab_b) / 1.8; - cc->set_source_rgb(0.9, 0.9, 0.0); - drawBar(cc, chromaval, 100.0, winw, winh, s); - } - } - } + if (needRed) { + // Red + cc->set_source_rgb(1.0, 0.0, 0.0); + drawBar(cc, r, 255.0, winw, winh); } - setDirty(false); + if (needGreen) { + // Green + cc->set_source_rgb(0.0, 1.0, 0.0); + drawBar(cc, g, 255.0, winw, winh); + } + + if (needBlue) { + // Blue + cc->set_source_rgb(0.0, 0.4, 1.0); + drawBar(cc, b, 255.0, winw, winh); + } + + if ((needLuma || needChroma) + && (scopeType == Options::ScopeType::HISTOGRAM + || scopeType == Options::ScopeType::PARADE + || scopeType == Options::ScopeType::WAVEFORM)) { + if (needLuma) { + // Luma + cc->set_source_rgb(1.0, 1.0, 1.0); + drawBar(cc, lab_L, 100.0, winw, winh); + } + + if (needChroma && scopeType == Options::ScopeType::HISTOGRAM) { + // Chroma + double chromaval = sqrt(lab_a * lab_a + lab_b * lab_b) / 1.8; + cc->set_source_rgb(0.9, 0.9, 0.0); + drawBar(cc, chromaval, 100.0, winw, winh); + } + } } -void HistogramRGBArea::update (int valh, int rh, int gh, int bh) +bool HistogramRGBArea::updatePointer (const int new_r, const int new_g, const int new_b, const Glib::ustring &profile, const Glib::ustring &profileW) { + // Do not update pointer values if bar is not visible + // (by user choice or according to scope type) + if (!showBar || scopeType == Options::ScopeType::HISTOGRAM_RAW || + scopeType == Options::ScopeType::VECTORSCOPE_HC || + scopeType == Options::ScopeType::VECTORSCOPE_HS) { + return false; + } - if (valh) { - val = valh; - r = rh; - g = gh; - b = bh; - valid = true; + // Do not update pointer values if values are identical + if (r == new_r && g == new_g && b == new_b) { + return false; + } + + // Set pointer parameters to invalid if r = g = b = -1 + if (new_r == -1 || new_g == -1 || new_b == -1) { + r = b = g = -1; + lab_L = lab_a = lab_b = 0.; + pointerValid = false; } else { - valid = false; + r = new_r; + g = new_g; + b = new_b; + Color::rgb2lab01(profile, profileW, + static_cast(r) / 255.f, + static_cast(g) / 255.f, + static_cast(b) / 255.f, + lab_L, lab_a, lab_b, options.rtSettings.HistogramWorking); + pointerValid = true; } - harih->pending++; - - idle_register.add( - [this]() -> bool - { - if (harih->destroyed) { - if (harih->pending == 1) { - delete harih; - } else { - --harih->pending; - } - - return false; - } - - harih->harea->updateBackBuffer(-1, -1, -1); - harih->harea->queue_draw (); - - --harih->pending; - - return false; - } - ); + return true; } -void HistogramRGBArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool bar) +void HistogramRGBArea::updateFromOptions () { - - options.histogramRed = needRed = r; - options.histogramGreen = needGreen = g; - options.histogramBlue = needBlue = b; - options.histogramLuma = needLuma = l; - options.histogramChroma = needChroma = c; - options.histogramBar = showMode = bar; - + needRed = options.histogramRed; + needGreen = options.histogramGreen; + needBlue = options.histogramBlue; + needLuma = options.histogramLuma; + needChroma = options.histogramChroma; + scopeType = options.histogramScopeType; + scaleMode = options.histogramDrawMode; + showBar = options.histogramBar; } void HistogramRGBArea::on_realize () { - Gtk::DrawingArea::on_realize(); add_events(Gdk::BUTTON_PRESS_MASK); } bool HistogramRGBArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - const Glib::RefPtr style = get_style_context(); - style->render_background(cr, 0, 0, get_width(), get_height()); + style->render_background(cr, 0., 0., static_cast(get_width()), static_cast(get_height())); - // on_realize & updateBackBuffer have to be called before - if (surface) { - if (isDirty()) { // not sure this could happen... - updateBackBuffer(-1, -1, -1); - } + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(cr); - copySurface(cr, NULL); - } - - style->render_frame (cr, 0, 0, get_width(), get_height()); + style->render_frame (cr, 0., 0., static_cast(get_width()), static_cast(get_height())); return true; } @@ -965,18 +940,22 @@ bool HistogramRGBArea::on_button_press_event (GdkEventButton* event) void HistogramRGBArea::factorChanged (double newFactor) { factor = newFactor; + // Request bar redraw (according to scope type) + if (scopeType == Options::ScopeType::HISTOGRAM) { + queue_draw(); + } } -void HistogramRGBAreaHori::drawBar(Cairo::RefPtr cc, double value, double max_value, int winw, int winh, double scale) +void HistogramRGBAreaHori::drawBar(const Cairo::RefPtr &cc, const double value, const double max_value, const int winw, const int winh) { double pos; if (options.histogramDrawMode < 2) { - pos = padding + value * (winw - padding * 2.0) / max_value + 0.5 * scale; + pos = padding + value * (winw - padding * 2.0) / max_value; } else { - pos = padding + HistogramScaling::log (max_value, value) * (winw - padding * 2.0) / max_value + 0.5 * scale; + pos = padding + HistogramScaling::log (max_value, value) * (winw - padding * 2.0) / max_value; } cc->move_to(pos, 0.0); - cc->line_to(pos, winh - 0.0); + cc->line_to(pos, static_cast(winh)); cc->stroke(); } @@ -1005,13 +984,13 @@ void HistogramRGBAreaHori::get_preferred_width_for_height_vfunc (int height, int getPreferredLengthForThickness(height, minimum_width, natural_width); } -void HistogramRGBAreaVert::drawBar(Cairo::RefPtr cc, double value, double max_value, int winw, int winh, double scale) +void HistogramRGBAreaVert::drawBar(const Cairo::RefPtr &cc, const double value, const double max_value, const int winw, const int winh) { double pos; if (options.histogramDrawMode < 2 || options.histogramScopeType == ScopeType::PARADE || options.histogramScopeType == ScopeType::WAVEFORM) { - pos = padding + value * (winh - padding * 2.0 - 1) / max_value + 0.5 * scale; + pos = padding + value * (winh - padding * 2.0 - 1) / max_value + 0.5; } else { - pos = padding + HistogramScaling::log (max_value, value) * (winh - padding * 2.0) / max_value + 0.5 * scale; + pos = padding + HistogramScaling::log (max_value, value) * (winh - padding * 2.0) / max_value + 0.5; } cc->move_to(0.0, winh - pos); cc->line_to(winw, winh - pos); @@ -1049,6 +1028,7 @@ void HistogramRGBAreaVert::get_preferred_width_for_height_vfunc (int height, int // // HistogramArea HistogramArea::HistogramArea (DrawModeListener *fml) : + // Histogram parameters vectorscope_scale(0), vect_hc(0, 0), vect_hs(0, 0), vect_hc_buffer_dirty(true), vect_hs_buffer_dirty(true), @@ -1056,18 +1036,22 @@ HistogramArea::HistogramArea (DrawModeListener *fml) : rwave(0, 0), gwave(0, 0),bwave(0, 0), lwave(0, 0), parade_buffer_r_dirty(true), parade_buffer_g_dirty(true), parade_buffer_b_dirty(true), wave_buffer_dirty(true), wave_buffer_luma_dirty(true), - valid(false), drawMode(options.histogramDrawMode), myDrawModeListener(fml), - scopeType(options.histogramScopeType), - oldwidth(-1), oldheight(-1), - trace_brightness(1.0), + LUT_valid(false), + // Intensity of waveform and vectorscope trace + trace_brightness(1.f), + // Saved pointer parameters + pointer_red(-1), pointer_green(-1), pointer_blue(-1), + pointer_a(0.f), pointer_b(0.f), + pointer_valid(false), + // Drawing options needRed(options.histogramRed), needGreen(options.histogramGreen), needBlue(options.histogramBlue), needLuma(options.histogramLuma), needChroma(options.histogramChroma), - isPressed(false), movingPosition(0.0), needPointer(options.histogramBar), - pointer_red(-1), pointer_green(-1), pointer_blue(-1), - pointer_a(0), pointer_b(0) + scopeType(options.histogramScopeType), + drawMode(options.histogramDrawMode), myDrawModeListener(fml), + // Motion event management + isPressed(false), movingPosition(0.0) { - rhist(256); ghist(256); bhist(256); @@ -1076,22 +1060,11 @@ HistogramArea::HistogramArea (DrawModeListener *fml) : get_style_context()->add_class("drawingarea"); set_name("HistogramArea"); - - haih = new HistogramAreaIdleHelper; - haih->harea = this; - haih->destroyed = false; - haih->pending = 0; } HistogramArea::~HistogramArea () { idle_register.destroy(); - - if (haih->pending) { - haih->destroyed = true; - } else { - delete haih; - } } Gtk::SizeRequestMode HistogramArea::get_request_mode_vfunc () const @@ -1122,23 +1095,19 @@ void HistogramArea::get_preferred_width_for_height_vfunc (int height, int &minim get_preferred_width_vfunc (minimum_width, natural_width); } -void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, int mode, ScopeType type, bool pointer) +void HistogramArea::updateFromOptions () { - wave_buffer_dirty = wave_buffer_dirty || needRed != r || needGreen != g || needBlue != b; + wave_buffer_dirty = wave_buffer_dirty || needRed != options.histogramRed || + needGreen != options.histogramGreen || needBlue != options.histogramBlue; - options.histogramRed = needRed = r; - options.histogramGreen = needGreen = g; - options.histogramBlue = needBlue = b; - options.histogramLuma = needLuma = l; - options.histogramChroma = needChroma = c; - options.histogramDrawMode = drawMode = mode; - options.histogramScopeType = scopeType = type; - options.histogramBar = needPointer = pointer; -} - -bool HistogramArea::updatePending(void) -{ - return haih->pending > 0 && !haih->destroyed; + needRed = options.histogramRed; + needGreen = options.histogramGreen; + needBlue = options.histogramBlue; + needLuma = options.histogramLuma; + needChroma = options.histogramChroma; + drawMode = options.histogramDrawMode; + scopeType = options.histogramScopeType; + needPointer = options.histogramBar; } void HistogramArea::update( @@ -1160,149 +1129,136 @@ void HistogramArea::update( const array2D& waveformLuma ) { - if (histRed) { - switch (scopeType) { - case ScopeType::HISTOGRAM: - rhist = histRed; - ghist = histGreen; - bhist = histBlue; - lhist = histLuma; - chist = histChroma; - break; - case ScopeType::HISTOGRAM_RAW: - rhistRaw = histRedRaw; - ghistRaw = histGreenRaw; - bhistRaw = histBlueRaw; - break; - case ScopeType::PARADE: - case ScopeType::WAVEFORM: { - MyWriterLock wave_lock(wave_mutex); - waveform_scale = waveformScale; - rwave = waveformRed; - gwave = waveformGreen; - bwave = waveformBlue; - lwave = waveformLuma; - parade_buffer_r_dirty = parade_buffer_g_dirty = parade_buffer_b_dirty = wave_buffer_dirty = wave_buffer_luma_dirty = true; - break; - } - case ScopeType::VECTORSCOPE_HS: - vectorscope_scale = vectorscopeScale; - vect_hs = vectorscopeHS; - vect_hs_buffer_dirty = true; - break; - case ScopeType::VECTORSCOPE_HC: - vectorscope_scale = vectorscopeScale; - vect_hc = vectorscopeHC; - vect_hc_buffer_dirty = true; - break; - case ScopeType::NONE: - break; - } - valid = true; - } else { - valid = false; - } - - haih->pending++; - - // Can be done outside of the GUI thread + // Note: This function is called outside of GUI threads idle_register.add( - [this]() -> bool - { - if (haih->destroyed) { - if (haih->pending == 1) { - delete haih; - } else { - --haih->pending; + [this, &histRed, &histGreen, &histBlue, &histLuma, &histChroma, &histRedRaw, + &histGreenRaw, &histBlueRaw, vectorscopeScale, &vectorscopeHC, + &vectorscopeHS, waveformScale, &waveformRed, &waveformGreen, + &waveformBlue, &waveformLuma]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + if (histRed) { + switch (scopeType) { + case ScopeType::HISTOGRAM: + rhist = histRed; + ghist = histGreen; + bhist = histBlue; + lhist = histLuma; + chist = histChroma; + break; + case ScopeType::HISTOGRAM_RAW: + rhistRaw = histRedRaw; + ghistRaw = histGreenRaw; + bhistRaw = histBlueRaw; + break; + case ScopeType::PARADE: + case ScopeType::WAVEFORM: { + MyWriterLock wave_lock(wave_mutex); + waveform_scale = waveformScale; + rwave = waveformRed; + gwave = waveformGreen; + bwave = waveformBlue; + lwave = waveformLuma; + parade_buffer_r_dirty = parade_buffer_g_dirty = parade_buffer_b_dirty = wave_buffer_dirty = wave_buffer_luma_dirty = true; + break; } - - return false; + case ScopeType::VECTORSCOPE_HS: + vectorscope_scale = vectorscopeScale; + vect_hs = vectorscopeHS; + vect_hs_buffer_dirty = true; + break; + case ScopeType::VECTORSCOPE_HC: + vectorscope_scale = vectorscopeScale; + vect_hc = vectorscopeHC; + vect_hc_buffer_dirty = true; + break; + case ScopeType::NONE: + break; } + LUT_valid = true; + } else { + LUT_valid = false; + } - haih->harea->setDirty(true); - haih->harea->updateBackBuffer(); - haih->harea->queue_draw(); + // Request GUI redraw + queue_draw(); - --haih->pending; - - return false; + return false; } ); } -void HistogramArea::updateBackBuffer () +void HistogramArea::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr) { + // Do not update drawing area if widget is not realized if (!get_realized ()) { return; } + // Note: updateDrawingArea is called by the on_draw function so its call does not need to be protected + // GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + Glib::RefPtr window = get_window(); int winx, winy, winw, winh; window->get_geometry(winx, winy, winw, winh); - // This will create or update the size of the BackBuffer::surface - setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, winw, winh, true); - - Cairo::RefPtr cr = Cairo::Context::create(surface); - const Glib::RefPtr style = get_style_context(); - - const double s = RTScalable::scalePixelSize(1.); + // const Glib::RefPtr style = get_style_context(); // Setup drawing - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); cr->set_operator (Cairo::OPERATOR_SOURCE); // Prepare drawing gridlines first cr->set_source_rgba (1., 1., 1., 0.25); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->set_antialias(Cairo::ANTIALIAS_NONE); cr->set_line_join(Cairo::LINE_JOIN_MITER); cr->set_line_cap(Cairo::LINE_CAP_BUTT); - std::valarray ch_ds (1); - ch_ds[0] = 4; + const std::valarray ch_ds = {4.}; cr->set_dash (ch_ds, 0); // determine the number of h-gridlines based on current h - int nrOfHGridPartitions = static_cast(rtengine::min (16.0, pow (2.0, floor ((h - 100) / 250) + 2))); + int nrOfHGridPartitions = static_cast(rtengine::min (16.0, pow (2.0, floor ((winh - 100) / 250) + 2))); int nrOfVGridPartitions = 8; // always show 8 stops (lines at 1,3,7,15,31,63,127) // draw vertical gridlines - if (options.histogramScopeType == ScopeType::HISTOGRAM || options.histogramScopeType == ScopeType::HISTOGRAM_RAW) { + if (scopeType == Options::ScopeType::HISTOGRAM || scopeType == Options::ScopeType::HISTOGRAM_RAW) { for (int i = 0; i <= nrOfVGridPartitions; i++) { double xpos = padding + 0.5; - if (options.histogramDrawMode < 2) { - xpos += (pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0; + if (drawMode < 2) { + xpos += (pow(2.0,i) - 1) * (winw - padding * 2.0) / 255.0; } else { - xpos += HistogramScaling::log (255, pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0; + xpos += HistogramScaling::log (255, pow(2.0,i) - 1) * (winw - padding * 2.0) / 255.0; } cr->move_to (xpos, 0.); - cr->line_to (xpos, h); + cr->line_to (xpos, winh); cr->stroke (); } } // draw horizontal gridlines - if (options.histogramScopeType == ScopeType::PARADE || options.histogramScopeType == ScopeType::WAVEFORM) { + if (scopeType == Options::ScopeType::PARADE || scopeType == Options::ScopeType::WAVEFORM) { for (int i = 0; i <= nrOfVGridPartitions; i++) { - const double ypos = h - padding - (pow(2.0,i) - 1) * (h - 2 * padding - 1) / 255.0; + const double ypos = winh - padding - (pow(2.0,i) - 1) * (winh - 2 * padding - 1) / 255.0; cr->move_to(0, ypos); - cr->line_to(w, ypos); + cr->line_to(winw, ypos); cr->stroke(); } - } else if (options.histogramScopeType == ScopeType::VECTORSCOPE_HC || options.histogramScopeType == ScopeType::VECTORSCOPE_HS) { + } else if (scopeType == Options::ScopeType::VECTORSCOPE_HC || scopeType == Options::ScopeType::VECTORSCOPE_HS) { // Vectorscope has no gridlines. - } else if (options.histogramDrawMode == 0) { + } else if (drawMode == 0) { for (int i = 1; i < nrOfHGridPartitions; i++) { - cr->move_to (padding, i * static_cast(h) / nrOfHGridPartitions + 0.5); - cr->line_to (w - padding, i * static_cast(h) / nrOfHGridPartitions + 0.5); + cr->move_to (padding, + i * static_cast(winh) / nrOfHGridPartitions + 0.5); + cr->line_to (winw - padding, + i * static_cast(winh) / nrOfHGridPartitions + 0.5); cr->stroke (); } } else { for (int i = 1; i < nrOfHGridPartitions; i++) { - cr->move_to (padding, h - HistogramScaling::log (h, i * static_cast(h) / nrOfHGridPartitions) + 0.5); - cr->line_to (w - padding, h - HistogramScaling::log (h, i * static_cast(h) / nrOfHGridPartitions) + 0.5); + cr->move_to (padding, + winh - HistogramScaling::log (winh, i * static_cast(winh) / nrOfHGridPartitions) + 0.5); + cr->line_to (winw - padding, + winh - HistogramScaling::log (winh, i * static_cast(winh) / nrOfHGridPartitions) + 0.5); cr->stroke (); } } @@ -1310,8 +1266,8 @@ void HistogramArea::updateBackBuffer () cr->unset_dash(); MyReaderLock wave_lock(wave_mutex); - if (valid && (scopeType == ScopeType::HISTOGRAM || scopeType == ScopeType::HISTOGRAM_RAW)) { - bool rawMode = scopeType == ScopeType::HISTOGRAM_RAW; + if (LUT_valid && (scopeType == Options::ScopeType::HISTOGRAM || scopeType == Options::ScopeType::HISTOGRAM_RAW)) { + const bool rawMode = (scopeType == Options::ScopeType::HISTOGRAM_RAW); // For RAW mode use the other hists LUTu& rh = rawMode ? rhistRaw : rhist; @@ -1323,24 +1279,24 @@ void HistogramArea::updateBackBuffer () unsigned int lhisttemp[256] ALIGNED16 {0}, chisttemp[256] ALIGNED16 {0}, rhtemp[256] ALIGNED16 {0}, ghtemp[256] ALIGNED16 {0}, bhtemp[256] ALIGNED16 {0}; const int scale = (rawMode ? 8 : 1); - for(int i = 0; i < 256; i++) { - if(needLuma) { + for (int i = 0; i < 256; i++) { + if (needLuma) { lhisttemp[i] = lhist[i]; } - if(needChroma) { + if (needChroma) { chisttemp[i] = chist[i]; } - if(needRed) { + if (needRed) { rhchanged[i] = rhtemp[i] = rh[i] / scale; } - if(needGreen) { + if (needGreen) { ghchanged[i] = ghtemp[i] = gh[i] / scale; } - if(needBlue) { + if (needBlue) { bhchanged[i] = bhtemp[i] = bh[i] / scale; } } @@ -1379,100 +1335,106 @@ void HistogramArea::updateBackBuffer () } cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->set_operator (Cairo::OPERATOR_OVER); int ui = 0, oi = 0; if (needLuma && !rawMode) { - drawCurve(cr, lhist, realhistheight, w, h); + drawCurve(cr, lhist, realhistheight, winw, winh); cr->set_source_rgba (0.65, 0.65, 0.65, 0.65); cr->fill (); - drawMarks(cr, lhist, realhistheight, w, ui, oi); + drawMarks(cr, lhist, realhistheight, winw, ui, oi); } if (needChroma && !rawMode) { - drawCurve(cr, chist, realhistheight, w, h); + drawCurve(cr, chist, realhistheight, winw, winh); cr->set_source_rgb (0.9, 0.9, 0.); cr->stroke (); - drawMarks(cr, chist, realhistheight, w, ui, oi); + drawMarks(cr, chist, realhistheight, winw, ui, oi); } if (needRed) { - drawCurve(cr, rhchanged, realhistheight, w, h); + drawCurve(cr, rhchanged, realhistheight, winw, winh); cr->set_source_rgb (1.0, 0.0, 0.0); cr->stroke (); - drawMarks(cr, rhchanged, realhistheight, w, ui, oi); + drawMarks(cr, rhchanged, realhistheight, winw, ui, oi); } if (needGreen) { - drawCurve(cr, ghchanged, realhistheight, w, h); + drawCurve(cr, ghchanged, realhistheight, winw, winh); cr->set_source_rgb (0.0, 1.0, 0.0); cr->stroke (); - drawMarks(cr, ghchanged, realhistheight, w, ui, oi); + drawMarks(cr, ghchanged, realhistheight, winw, ui, oi); } if (needBlue) { - drawCurve(cr, bhchanged, realhistheight, w, h); + drawCurve(cr, bhchanged, realhistheight, winw, winh); cr->set_source_rgb (0.0, 0.4, 1.0); cr->stroke (); - drawMarks(cr, bhchanged, realhistheight, w, ui, oi); + drawMarks(cr, bhchanged, realhistheight, winw, ui, oi); } - } else if (scopeType == ScopeType::PARADE && rwave.getWidth() > 0) { - drawParade(cr, w, h); - } else if (scopeType == ScopeType::WAVEFORM && rwave.getWidth() > 0) { - drawWaveform(cr, w, h); - } else if (scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS) { - drawVectorscope(cr, w, h); + } else if (scopeType == Options::ScopeType::PARADE && rwave.getWidth() > 0) { + drawParade(cr, winw, winh); + } else if (scopeType == Options::ScopeType::WAVEFORM && rwave.getWidth() > 0) { + drawWaveform(cr, winw, winh); + } else if (scopeType == Options::ScopeType::VECTORSCOPE_HC || scopeType == Options::ScopeType::VECTORSCOPE_HS) { + drawVectorscope(cr, winw, winh); } wave_lock.release(); - - // Draw the frame's border - style->render_frame(cr, 0, 0, surface->get_width(), surface->get_height()); - - oldwidth = w; - oldheight = h; - - setDirty(false); } -bool HistogramArea::updatePointer(int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW) +bool HistogramArea::updatePointer(const int r, const int g, const int b, const Glib::ustring &profile, const Glib::ustring &profileW) { - if (!needPointer || !(scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS)) { + // Do not update pointer values if pointer is not visible + // (by user choice or according to scope type) + if (!needPointer || + !(scopeType == Options::ScopeType::VECTORSCOPE_HC || scopeType == Options::ScopeType::VECTORSCOPE_HS)) { return false; } + + // Do not update pointer values if values are identical if (pointer_red == r && pointer_green == g && pointer_blue == b) { return false; } - float L; - pointer_red = r; - pointer_green = g; - pointer_blue = b; - Color::rgb2lab01(profile, profileW, r / 255.f, g / 255.f, b / 255.f, L, pointer_a, pointer_b, options.rtSettings.HistogramWorking); - updateBackBuffer(); + // Set pointer parameters to invalid if r = g = b = -1 + if (r == -1 || g == -1 || b == -1) { + pointer_red = pointer_green = pointer_green = -1; + pointer_a = pointer_b = 0.; + pointer_valid = false; + } else { + float L; // Unused + pointer_red = r; + pointer_green = g; + pointer_blue = b; + Color::rgb2lab01(profile, profileW, + static_cast(r) / 255.f, + static_cast(g) / 255.f, + static_cast(b) / 255.f, + L, pointer_a, pointer_b, options.rtSettings.HistogramWorking); + pointer_valid = true; + } + return true; } void HistogramArea::on_realize () { - Gtk::DrawingArea::on_realize(); add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); } -void HistogramArea::drawCurve(Cairo::RefPtr &cr, - const LUTu & data, double scale, int hsize, int vsize) +void HistogramArea::drawCurve(const Cairo::RefPtr &cr, + const LUTu & data, const double scale, const int hsize, const int vsize) { - const double s = RTScalable::scalePixelSize(1.); - - cr->set_line_width(s); + cr->set_line_width(1.); cr->move_to (padding, vsize - 1); - scale = scale <= 0.0 ? 0.001 : scale; // avoid division by zero and negative values + const double new_scale = scale <= 0.0 ? 0.001 : scale; // avoid division by zero and negative values for (int i = 0; i < 256; i++) { - double val = data[i] * static_cast(vsize) / scale; + double val = data[i] * static_cast(vsize) / new_scale; if (drawMode > 0) { // scale y for single and double log-scale val = HistogramScaling::log (static_cast(vsize), val); @@ -1492,23 +1454,21 @@ void HistogramArea::drawCurve(Cairo::RefPtr &cr, cr->line_to (hsize - padding, vsize - 1); } -void HistogramArea::drawMarks(Cairo::RefPtr &cr, - const LUTu & data, double scale, int hsize, int & ui, int & oi) +void HistogramArea::drawMarks(const Cairo::RefPtr &cr, + const LUTu & data, const double scale, const int wsize, int & ui, int & oi) { - const double s = RTScalable::scalePixelSize(1.); - if(data[0] > scale) { - cr->rectangle(padding, (ui++)*s, s, s); + cr->rectangle(padding, (ui++) * 8., 8., 8.); } if(data[255] > scale) { - cr->rectangle(hsize - s - padding, (oi++)*s, s, s); + cr->rectangle(wsize - 8. - padding, (oi++) * 8., 8., 8.); } cr->fill(); } -void HistogramArea::drawParade(Cairo::RefPtr &cr, int w, int h) +void HistogramArea::drawParade(const Cairo::RefPtr &cr, const int w, const int h) { // Arbitrary scale factor divided by current scale. const float scale = trace_brightness * 32.f * 255.f / waveform_scale; @@ -1612,7 +1572,7 @@ void HistogramArea::drawParade(Cairo::RefPtr &cr, int w, int h) cr->translate(i * display_wave_width, padding); cr->scale(display_wave_width / wave_width, (h - 2 * padding) / wave_height); surface = Cairo::ImageSurface::create( - buffers[i], Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); + buffers[i], Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); cr->set_source(surface, 0, 0); cr->set_operator(Cairo::OPERATOR_OVER); cr->paint(); @@ -1621,26 +1581,27 @@ void HistogramArea::drawParade(Cairo::RefPtr &cr, int w, int h) } } -void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, int h) +void HistogramArea::drawVectorscope(const Cairo::RefPtr &cr, const int w, const int h) { - if (scopeType != ScopeType::VECTORSCOPE_HC && scopeType != ScopeType::VECTORSCOPE_HS) { + if (scopeType != Options::ScopeType::VECTORSCOPE_HC && scopeType != Options::ScopeType::VECTORSCOPE_HS) { return; } - const auto& vect = (scopeType == ScopeType::VECTORSCOPE_HC) ? vect_hc : vect_hs; - auto& vect_buffer = (scopeType == ScopeType::VECTORSCOPE_HC) ? vect_hc_buffer : vect_hs_buffer; - auto& vect_buffer_dirty = (scopeType == ScopeType::VECTORSCOPE_HC) ? vect_hc_buffer_dirty : vect_hs_buffer_dirty; + const auto& vect = (scopeType == Options::ScopeType::VECTORSCOPE_HC) ? vect_hc : vect_hs; + auto& vect_buffer = (scopeType == Options::ScopeType::VECTORSCOPE_HC) ? vect_hc_buffer : vect_hs_buffer; + auto& vect_buffer_dirty = (scopeType == Options::ScopeType::VECTORSCOPE_HC) ? vect_hc_buffer_dirty : vect_hs_buffer_dirty; const int vect_width = vect.getWidth(); const int vect_height = vect.getHeight(); - // Arbitrary scale factor multiplied by vectorscope area and divided by - // current scale. - const float scale = trace_brightness * 8.f * vect_width * vect_height / vectorscope_scale; // See Cairo documentation on stride. const int cairo_stride = Cairo::ImageSurface::format_stride_for_width(Cairo::FORMAT_ARGB32, vect_width); if (vect_buffer_dirty && vectorscope_scale > 0) { + // Arbitrary scale factor multiplied by vectorscope area and divided by + // current scale. + const float scale = trace_brightness * 8.f * vect_width * vect_height / vectorscope_scale; + if (vect_buffer.size() != static_cast(cairo_stride) * vect_height) { vect_buffer.resize(static_cast(cairo_stride) * vect_height); } @@ -1663,24 +1624,23 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in const bool fit_width = vect_width * (h - 2 * padding) > vect_height * (w - 2 * padding); const float scope_scale = fit_width ? - (w - 2 * padding) / vect_width : (h - 2 * padding) / vect_height; + (w - 2 * padding) / vect_width : (h - 2 * padding) / vect_height; const float scope_size = (vectorscope_scale > 0) ? - scope_scale * std::max(vect_width, vect_height) : std::min(w, h) - 2 * padding; + scope_scale * std::max(vect_width, vect_height) : std::min(w, h) - 2 * padding; const float o_x = (w - scope_scale * vect_width) / 2; const float o_y = (h - scope_scale * vect_height) / 2; - const double s = RTScalable::scalePixelSize(1.); auto orig_matrix = cr->get_matrix(); const double line_length = scope_size / 2.0; std::valarray ch_ds(1); cr->translate(w / 2.0, h / 2.0); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); ch_ds[0] = 4; if (scopeType == ScopeType::VECTORSCOPE_HS) { // Hue-Saturation. // RYGCBM lines. - cr->set_line_width (2.0 * s); + cr->set_line_width (2.0); constexpr double color_labels[6][3] = { {1, 0, 0}, // R {0, 1, 0}, // G @@ -1702,7 +1662,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in cr->rotate_degrees(-120); cr->stroke(); } - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->set_source_rgba (1, 1, 1, 0.25); // 100% saturation circle. cr->arc(0, 0, scope_size / 2.0, 0, 2 * RT_PI); @@ -1722,7 +1682,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in } else if (scopeType == ScopeType::VECTORSCOPE_HC) { // Hue-Chroma. // a and b axes. Cairo::RefPtr gradient; - cr->set_line_width (2.0 * s); + cr->set_line_width (2.0); gradient = Cairo::LinearGradient::create(0, -line_length, 0, line_length); cr->set_source(gradient); gradient->add_color_stop_rgba(0, 1, 1, 0, 0.5); // "yellow" @@ -1744,7 +1704,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in cr->line_to(-line_length, 0); cr->stroke(); cr->set_source_rgba (1, 1, 1, 0.25); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); // 25%, 50%, 75%, and 100% of standard chroma range. cr->set_dash(ch_ds, 0); for (int i = 1; i <= 4; i++) { @@ -1764,7 +1724,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in // Vectorscope trace. if (vectorscope_scale > 0) { Cairo::RefPtr surface = Cairo::ImageSurface::create( - vect_buffer.data(), Cairo::FORMAT_ARGB32, vect_width, vect_height, cairo_stride); + vect_buffer.data(), Cairo::FORMAT_ARGB32, vect_width, vect_height, cairo_stride); cr->translate(o_x, o_y); cr->scale(scope_scale, scope_scale); cr->set_source(surface, 0, 0); @@ -1773,7 +1733,7 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in surface->finish(); cr->set_matrix(orig_matrix); - if (needPointer && pointer_red >= 0 && pointer_green >= 0 && pointer_blue >= 0) { + if (needPointer && pointer_valid) { float cx, cy; if (scopeType == ScopeType::VECTORSCOPE_HS) { float H, S, L; @@ -1785,24 +1745,24 @@ void HistogramArea::drawVectorscope(Cairo::RefPtr &cr, int w, in cx = w / 2.f + scope_size * pointer_a * ab_factor; cy = h / 2.f - scope_size * pointer_b * ab_factor; } - const float crosshair_size = 20.f * s; + const float crosshair_size = 20.f; cr->set_source_rgba(1, 1, 1, 0.5); cr->move_to(cx - crosshair_size, cy); cr->line_to(cx + crosshair_size, cy); cr->move_to(cx, cy - crosshair_size); cr->line_to(cx, cy + crosshair_size); cr->stroke(); - cr->arc(cx, cy, 3 * s, 0, 2 * RT_PI); + cr->arc(cx, cy, 3, 0, 2 * RT_PI); cr->set_source_rgb(1, 1, 1); cr->fill_preserve(); cr->set_source_rgb(0, 0, 0); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->stroke(); } } } -void HistogramArea::drawWaveform(Cairo::RefPtr &cr, int w, int h) +void HistogramArea::drawWaveform(const Cairo::RefPtr &cr, const int w, const int h) { // Arbitrary scale factor divided by current scale. const float scale = trace_brightness * 32.f * 255.f / waveform_scale; @@ -1860,7 +1820,7 @@ void HistogramArea::drawWaveform(Cairo::RefPtr &cr, int w, int h cr->scale(static_cast(w) / wave_width, (h - 2 * padding) / wave_height); if (needLuma) { surface = Cairo::ImageSurface::create( - wave_buffer_luma.data(), Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); + wave_buffer_luma.data(), Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); cr->set_source(surface, 0, 0); cr->set_operator(Cairo::OPERATOR_OVER); cr->paint(); @@ -1868,7 +1828,7 @@ void HistogramArea::drawWaveform(Cairo::RefPtr &cr, int w, int h } if (needRed || needGreen || needBlue) { surface = Cairo::ImageSurface::create( - wave_buffer.data(), Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); + wave_buffer.data(), Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride); cr->set_source(surface, 0, 0); cr->set_operator(Cairo::OPERATOR_OVER); cr->paint(); @@ -1879,14 +1839,13 @@ void HistogramArea::drawWaveform(Cairo::RefPtr &cr, int w, int h bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - - if (!updatePending() && (get_width() != oldwidth || get_height() != oldheight || isDirty())) { - updateBackBuffer (); - } - const Glib::RefPtr style = get_style_context(); style->render_background(cr, 0, 0, get_width(), get_height()); - copySurface(cr, NULL); + + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(cr); + style->render_frame (cr, 0, 0, get_width(), get_height()); return true; @@ -1909,7 +1868,6 @@ bool HistogramArea::on_button_press_event (GdkEventButton* event) myDrawModeListener->toggleButtonMode (); } - updateBackBuffer (); queue_draw (); } @@ -1946,7 +1904,6 @@ bool HistogramArea::on_motion_notify_event (GdkEventMotion* event) sigFactorChanged.emit(factor); - setDirty(true); queue_draw (); } else if ( scopeType == ScopeType::PARADE @@ -1975,7 +1932,6 @@ void HistogramArea::setBrightness(float brightness) if (brightness != trace_brightness) { parade_buffer_r_dirty = parade_buffer_g_dirty = parade_buffer_b_dirty = wave_buffer_dirty = wave_buffer_luma_dirty = vect_hc_buffer_dirty = vect_hs_buffer_dirty = true; trace_brightness = brightness; - setDirty(true); queue_draw(); signal_brightness_changed.emit(trace_brightness); diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index 26b744546..799cfb768 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -35,20 +35,6 @@ #include "../rtengine/LUT.h" #include "../rtengine/noncopyable.h" -class HistogramArea; - -struct HistogramAreaIdleHelper { - HistogramArea* harea; - bool destroyed; - int pending; -}; - -class HistogramRGBArea; -struct HistogramRGBAreaIdleHelper { - HistogramRGBArea* harea; - bool destroyed; - int pending; -}; class HistogramScaling { @@ -58,38 +44,39 @@ public: double log (double vsize, double val); }; -class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, protected HistogramScaling, public rtengine::NonCopyable +class HistogramRGBArea : public Gtk::DrawingArea, protected HistogramScaling, public rtengine::NonCopyable { -private: - typedef const double (*TMatrix)[3]; - - IdleRegister idle_register; - protected: - int val; + // Saved pointer parameters int r; int g; int b; + float lab_L; + float lab_a; + float lab_b; + bool pointerValid; - bool valid; - + // Drawing options bool needRed; bool needGreen; bool needBlue; bool needLuma; bool needChroma; - bool showMode; - bool barDisplayed; + Options::ScopeType scopeType; + int scaleMode; + bool showBar; - Gtk::Grid* parent; - - double padding = 5.0; + const double padding = 5.0; - HistogramRGBAreaIdleHelper* harih; + // Internal drawing functions + void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cc); + virtual void drawBar(const Cairo::RefPtr &cc, const double value, const double max_value, const int winw, const int winh) = 0; - /** Draw an indicator bar for the value. */ - virtual void drawBar(Cairo::RefPtr cc, double value, double max_value, int winw, int winh, double scale) = 0; + // GtkDrawingArea override functions + void on_realize() override; + bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; + // Widget size management functions void getPreferredThickness(int& min_thickness, int& natural_length) const; void getPreferredLength(int& min_length, int& natural_length) const; void getPreferredThicknessForLength(int length, int& min_thickness, int& natural_length) const; @@ -99,29 +86,23 @@ public: HistogramRGBArea(); ~HistogramRGBArea() override; - void updateBackBuffer (int r, int g, int b, const Glib::ustring &profile = "", const Glib::ustring &profileW = ""); - bool getShow (); - void setShow(bool show); - void setParent (Gtk::Grid* p) - { - parent = p; - }; + // Update pointer values: returns true if widget needs redrawing + bool updatePointer (const int new_r, const int new_g, const int new_b, const Glib::ustring &new_profile = "", const Glib::ustring &new_profileW = ""); + // Update internal parameters from options + void updateFromOptions (); - void update (int val, int rh, int gh, int bh); - void updateOptions (bool r, bool g, bool b, bool l, bool c, bool show); - - void on_realize() override; - bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; + // Event management functions bool on_button_press_event (GdkEventButton* event) override; void factorChanged (double newFactor); - }; class HistogramRGBAreaHori final : public HistogramRGBArea { private: - void drawBar(Cairo::RefPtr cc, double value, double max_value, int winw, int winh, double scale) override; + // Internal drawing function + void drawBar(const Cairo::RefPtr &cc, const double value, const double max_value, const int winw, const int winh) override; + // Widget size management functions Gtk::SizeRequestMode get_request_mode_vfunc () const override; void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; @@ -132,8 +113,10 @@ private: class HistogramRGBAreaVert final : public HistogramRGBArea { private: - void drawBar(Cairo::RefPtr cc, double value, double max_value, int winw, int winh, double scale) override; + // Internal drawing function + void drawBar(const Cairo::RefPtr &cc, const double value, const double max_value, const int winw, const int winh) override; + // Widget size management functions Gtk::SizeRequestMode get_request_mode_vfunc () const override; void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; @@ -148,7 +131,7 @@ public: virtual void toggleButtonMode() = 0; }; -class HistogramArea final : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable +class HistogramArea final : public Gtk::DrawingArea, private HistogramScaling, public rtengine::NonCopyable { public: typedef sigc::signal type_signal_factor_changed; @@ -161,8 +144,9 @@ private: type_signal_factor_changed sigFactorChanged; protected: + // Histogram parameters LUTu rhist, ghist, bhist, lhist, chist; - LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused? + LUTu rhistRaw, ghistRaw, bhistRaw; int vectorscope_scale; array2D vect_hc, vect_hs; std::vector vect_hc_buffer, vect_hs_buffer; @@ -177,36 +161,44 @@ protected: std::vector wave_buffer; std::vector wave_buffer_luma; bool wave_buffer_dirty, wave_buffer_luma_dirty; + bool LUT_valid; - bool valid; + // Intensity of waveform and vectorscope trace + float trace_brightness; + SignalBrightnessChanged signal_brightness_changed; + + // Saved pointer parameters + int pointer_red; + int pointer_green; + int pointer_blue; + float pointer_a; + float pointer_b; + bool pointer_valid; + + // Drawing options + bool needRed; + bool needGreen; + bool needBlue; + bool needLuma; + bool needChroma; + bool needPointer; + Options::ScopeType scopeType; int drawMode; DrawModeListener *myDrawModeListener; - Options::ScopeType scopeType; - int oldwidth, oldheight; - /// Intensity of waveform and vectorscope trace. - float trace_brightness; - bool needRed, needGreen, needBlue, needLuma, needChroma; + // Motion event management bool isPressed; double movingPosition; - bool needPointer; - + double padding = 5.0; - HistogramAreaIdleHelper* haih; - - int pointer_red, pointer_green, pointer_blue; - float pointer_a, pointer_b; - - SignalBrightnessChanged signal_brightness_changed; - public: explicit HistogramArea(DrawModeListener *fml = nullptr); ~HistogramArea() override; - void updateBackBuffer (); - /// Update pointer values. Returns true if widget needs redrawing. - bool updatePointer(int r, int g, int b, const Glib::ustring &profile = "", const Glib::ustring &profileW = ""); + // Update pointer values: returns true if widget needs redrawing + bool updatePointer(const int r, const int g, const int b, const Glib::ustring &profile = "", const Glib::ustring &profileW = ""); + // Update histogram data void update( const LUTu& histRed, const LUTu& histGreen, @@ -225,25 +217,36 @@ public: const array2D& waveformBlue, const array2D& waveformLuma ); - void updateOptions (bool r, bool g, bool b, bool l, bool c, int mode, Options::ScopeType type, bool pointer); - bool updatePending(); - void on_realize() override; - bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; + // Update internal parameters from options + void updateFromOptions(); + + // Event management functions bool on_button_press_event (GdkEventButton* event) override; bool on_button_release_event (GdkEventButton* event) override; bool on_motion_notify_event (GdkEventMotion* event) override; + + // Brightness management functions (nominal = 1) float getBrightness(void); - /** Set the trace brightness, with 1 being normal. */ void setBrightness(float brightness); SignalBrightnessChanged getBrighnessChangedSignal(void); + + // Factor management function type_signal_factor_changed signal_factor_changed(); private: - void drawCurve(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int vsize); - void drawMarks(Cairo::RefPtr &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi); - void drawParade(Cairo::RefPtr &cr, int hsize, int vsize); - void drawVectorscope(Cairo::RefPtr &cr, int hsize, int vsize); - void drawWaveform(Cairo::RefPtr &cr, int hsize, int vsize); + // GtkDrawingArea override functions + void on_realize() override; + bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; + + // Internal drawing functions + void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr); + void drawCurve(const Cairo::RefPtr &cr, const LUTu & data, const double scale, const int hsize, const int vsize); + void drawMarks(const Cairo::RefPtr &cr, const LUTu & data, const double scale, const int wsize, int & ui, int & oi); + void drawParade(const Cairo::RefPtr &cr, const int hsize, const int vsize); + void drawVectorscope(const Cairo::RefPtr &cr, const int hsize, const int vsize); + void drawWaveform(const Cairo::RefPtr &cr, const int hsize, const int vsize); + + // Widget size management functions Gtk::SizeRequestMode get_request_mode_vfunc () const override; void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override; void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override; @@ -311,10 +314,9 @@ protected: sigc::connection brightness_changed_connection; sigc::connection rconn; + void setHistInvalid (); void showRGBBar(); - void updateHistAreaOptions(); - void updateHistRGBAreaOptions(); public: @@ -345,9 +347,6 @@ public: // pointermotionlistener interface void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) override; - // TODO should be protected - void setHistRGBInvalid (); - void reorder (Gtk::PositionType position); void red_toggled (); void green_toggled (); From a0c3ef931cd650ed51da453124181d20bc852040 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Wed, 2 Nov 2022 16:32:48 +0100 Subject: [PATCH 008/291] Minor fixes for histogram panel hidpi support --- rtgui/histogrampanel.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 98a9a2789..5b802b70b 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -42,7 +42,7 @@ HistogramPanel::HistogramPanel () : pointer_moved_delayed_call( [this](bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int r, int g, int b) { - bool update_hist_area, update_hist_rgb_area; + bool update_hist_area = false, update_hist_rgb_area = false; if (!validPos) { // do something to un-show vertical bars @@ -1202,10 +1202,8 @@ void HistogramArea::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &c int winx, winy, winw, winh; window->get_geometry(winx, winy, winw, winh); - // const Glib::RefPtr style = get_style_context(); - // Setup drawing - cr->set_operator (Cairo::OPERATOR_SOURCE); + cr->set_operator (Cairo::OPERATOR_OVER); // Prepare drawing gridlines first cr->set_source_rgba (1., 1., 1., 0.25); @@ -1401,7 +1399,7 @@ bool HistogramArea::updatePointer(const int r, const int g, const int b, const G // Set pointer parameters to invalid if r = g = b = -1 if (r == -1 || g == -1 || b == -1) { - pointer_red = pointer_green = pointer_green = -1; + pointer_red = pointer_green = pointer_blue = -1; pointer_a = pointer_b = 0.; pointer_valid = false; } else { From 8e0fa1148b5d394498b877010ffc377b6d0a8d0f Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Thu, 3 Nov 2022 12:37:43 +0100 Subject: [PATCH 009/291] Other minor fixes for histogram panel - When loading an image, raw histogram data were incorrectly not set (but provided) - Fixes incorrect curve scaling in raw histogram mode (was incorrectly scaled using luma and chroma data) --- rtgui/histogrampanel.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 5b802b70b..a29416907 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -1147,9 +1147,7 @@ void HistogramArea::update( chist = histChroma; break; case ScopeType::HISTOGRAM_RAW: - rhistRaw = histRedRaw; - ghistRaw = histGreenRaw; - bhistRaw = histBlueRaw; + // Raw histogram data are always provided (refer below) break; case ScopeType::PARADE: case ScopeType::WAVEFORM: { @@ -1175,6 +1173,11 @@ void HistogramArea::update( case ScopeType::NONE: break; } + // Raw histogram data are always provided + rhistRaw = histRedRaw; + ghistRaw = histGreenRaw; + bhistRaw = histBlueRaw; + LUT_valid = true; } else { LUT_valid = false; @@ -1278,11 +1281,11 @@ void HistogramArea::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &c const int scale = (rawMode ? 8 : 1); for (int i = 0; i < 256; i++) { - if (needLuma) { + if (needLuma && !rawMode) { lhisttemp[i] = lhist[i]; } - if (needChroma) { + if (needChroma && !rawMode) { chisttemp[i] = chist[i]; } @@ -1305,11 +1308,11 @@ void HistogramArea::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &c unsigned int histheight = 0; for (int i = 1; i < 255; i++) { - if (needLuma && lhisttemp[i] > histheight) { + if (needLuma && !rawMode && lhisttemp[i] > histheight) { histheight = lhisttemp[i]; } - if (needChroma && chisttemp[i] > histheight) { + if (needChroma && !rawMode && chisttemp[i] > histheight) { histheight = chisttemp[i]; } From 344f64eab7a5606d345b2277cd51fd8fa1099ad2 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Thu, 3 Nov 2022 12:43:06 +0100 Subject: [PATCH 010/291] Fixes issue loading image cache data With some versions of Glib/Glibmm library on MacOS, Glib::KeyFile "load_from_file" function does not raise a Glib::Error but another exception. This causes cached data not saved on disk (and thumbnails not displayed in explorer). Adds robustness testing if file is present first before calling the function --- rtgui/cacheimagedata.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index d44ca28ec..8e20df2e3 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include "version.h" #include @@ -250,7 +251,9 @@ int CacheImageData::save (const Glib::ustring& fname) Glib::KeyFile keyFile; try { - keyFile.load_from_file (fname); + if (Glib::file_test(fname, Glib::FILE_TEST_EXISTS)) { + keyFile.load_from_file (fname); + } } catch (Glib::Error&) {} keyFile.set_string ("General", "MD5", md5); From cc48ad2aa17615732b909ec63163f79f8a7a5d6a Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Thu, 8 Dec 2022 10:03:45 +0100 Subject: [PATCH 011/291] Fixes hi-dpi on Linux - Fixes incorrect install path for icons - Fixes case-sensitive issues with names --- CMakeLists.txt | 6 +----- rtdata/CMakeLists.txt | 2 +- rtgui/rtwindow.cc | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5d54775f..edcfae943 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,11 +364,7 @@ endif() if(NOT DEFINED ICONSDIR) if(UNIX) if(BUILD_BUNDLE) - if(APPLE) - set(ICONSDIR "${DATADIR}/icons") - else() - set(ICONSDIR "${DATADIR}/share/icons") - endif() + set(ICONSDIR "${DATADIR}/icons") else() set(ICONSDIR "${CMAKE_INSTALL_PREFIX}/share/icons") endif() diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 5597f51b7..0f6c907fb 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -52,7 +52,7 @@ install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/empty.png" DESTINATION "${ICONSDIR}/rawtherapee/24x24/apps") install(FILES ${IMG_SVG} DESTINATION "${ICONSDIR}/rawtherapee/scalable/apps") -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/svg/Index.theme" DESTINATION "${ICONSDIR}/rawtherapee") +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/svg/index.theme" DESTINATION "${ICONSDIR}/rawtherapee") install(FILES ${IMG_ICO} DESTINATION "${DATADIR}/images") if(APPLE) diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 11d4087f3..1281c5c83 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -112,7 +112,7 @@ RTWindow::RTWindow () // Setting default theme and icon theme (bases for custom themes) Gtk::Settings::get_for_screen (screen)->property_gtk_theme_name() = "Adwaita"; Gtk::Settings::get_for_screen (screen)->property_gtk_application_prefer_dark_theme() = true; - Gtk::Settings::get_for_screen (screen)->property_gtk_icon_theme_name() = "RawTherapee"; + Gtk::Settings::get_for_screen (screen)->property_gtk_icon_theme_name() = "rawtherapee"; // Initialize RTScalable for Hi-DPI support RTScalable::init(this); From 21ebb81ece5bba7bda6dd4538f2f4e4c848c2511 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 9 Dec 2022 16:09:03 +0100 Subject: [PATCH 012/291] Stop using scale factor for font and pixel size scaling --- rtgui/cropwindow.cc | 9 +++------ rtgui/filebrowserentry.cc | 3 +-- rtgui/imagearea.cc | 3 +-- rtgui/lockablecolorpicker.cc | 3 +-- rtgui/preferences.cc | 4 ++-- rtgui/rtscalable.cc | 3 +-- rtgui/rtscalable.h | 5 +++-- rtgui/rtwindow.cc | 6 ++---- rtgui/shcselector.cc | 3 +-- rtgui/splash.cc | 3 +-- 10 files changed, 16 insertions(+), 26 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 110555251..c2019ba17 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -67,8 +67,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet const int fontSize = 8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c @@ -2467,8 +2466,7 @@ void CropWindow::drawDecoration (Cairo::RefPtr cr) const int fontSize = 8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c @@ -2544,8 +2542,7 @@ void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) const int fontSize = 8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 60691d8b6..504422d8d 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -792,8 +792,7 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) const int fontSize = 8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index d60232ff9..90deb6ba0 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -158,8 +158,7 @@ void ImageArea::setInfoText (Glib::ustring text) const int fontSize = 10; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 22760c6a2..bd3be37d1 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -51,8 +51,7 @@ void LockableColorPicker::updateBackBuffer () const int fontSize = options.CPFontFamily == "default" ? 8 : options.CPFontSize; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c1a85d0d7..805e64e28 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2494,9 +2494,9 @@ void Preferences::switchFontTo(const Glib::ustring &newFontFamily, const int new try { //GTK318 //#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 -// fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", newFontFamily, newFontSize * RTScalable::getScale())); +// fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", newFontFamily, newFontSize)); //#else - fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize * RTScalable::getScale())); + fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize)); //#endif //GTK318 } catch (Glib::Error &err) { diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 586d38dfa..0e90d34ad 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -267,8 +267,7 @@ int RTScalable::getScale () double RTScalable::getGlobalScale() { - return (RTScalable::getDPI() / RTScalable::baseDPI * - static_cast(RTScalable::getScale())); + return (RTScalable::getDPI() / RTScalable::baseDPI); } int RTScalable::scalePixelSize(const int pixel_size) diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index e96fdddfc..673ea5685 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -33,7 +33,7 @@ * - Absolute size (i.e. "px") * - Non-absolute size (i.e. "pt"): The default resolution is 72 DPI (i.e. pt per inch). To * convert the size to "px", use the following formula: - * "size in px" = "size in pt" * ("device resolution" / 72) * "device scale" + * "size in px" = "size in pt" * ("device resolution" / 72) * * Hi-DPI implementation according to the OS (source: GDK code): * - Windows: A default DPI of 96 is considered. Current DPI parameter is provided by the OS. @@ -41,7 +41,8 @@ * forced to 96. * - MacOS: Scale is calculated from OS parameters (= "Retina screen width" / "Virtual width"). * DPI is forced to 72. - * - Linux: DPI is calculated from OS parameter (= 96 * "text-scaling-factor"). + * - Linux: DPI is calculated from OS parameter (= 96 * "text-scaling-factor"). Note: "text-scaling-factor" + * is different from "device factor". */ class RTScalable { diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 1281c5c83..fcef8101e 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -170,8 +170,7 @@ RTWindow::RTWindow () Glib::ustring css; #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c @@ -206,8 +205,7 @@ RTWindow::RTWindow () #ifndef __APPLE__ // Guessing that pixel size is given for a 96 DPI reference: - const double newFontScale = RTScalable::getDPI() / RTScalable::baseDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double newFontScale = RTScalable::getDPI() / RTScalable::baseDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index 132a5f1ef..021c09914 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -199,8 +199,7 @@ void SHCSelector::updateBackBuffer() const double fontSize = static_cast(h) * 0.8; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c diff --git a/rtgui/splash.cc b/rtgui/splash.cc index 5019e6834..ea3cb59e7 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -46,8 +46,7 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) const int fontSize = 12; // pt // Converting font size to "px" based on DPI and scale #ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI - * static_cast(RTScalable::getScale()); // Refer to notes in rtscalable.h + const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h #else // On MacOS, font is already scaled by the System library // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c From 41a0bef2d82940d9b9a32de66a516ab447a7448e Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Tue, 13 Dec 2022 11:47:56 +0100 Subject: [PATCH 013/291] Fixes incorrect icon width on previewmodepanel toggle buttons --- rtgui/previewmodepanel.cc | 149 ++++++++++++++++++++++---------------- rtgui/previewmodepanel.h | 9 --- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc index 8bec03ee9..25167ae3b 100644 --- a/rtgui/previewmodepanel.cc +++ b/rtgui/previewmodepanel.cc @@ -19,10 +19,11 @@ #include "options.h" #include "multilangmgr.h" #include "imagearea.h" -#include "rtimage.h" PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia), + // Note: RTImage custom class only manages squared icon. To reduce toggle button width, + // toggle button image is managed by icon name nR("square-toggle-red-on-narrow"), ngR("square-toggle-red-off-narrow"), nG("square-toggle-green-on-narrow"), ngG("square-toggle-green-off-narrow"), nB("square-toggle-blue-on-narrow"), ngB("square-toggle-blue-off-narrow"), @@ -30,63 +31,55 @@ PreviewModePanel::PreviewModePanel (ImageArea* ia) : nBC0("square-toggle-theme-on-narrow"), ngBC0("square-toggle-theme-off-narrow"), nBC1("square-toggle-black-on-narrow"), ngBC1("square-toggle-black-off-narrow"), nBC2("square-toggle-white-on-narrow"), ngBC2("square-toggle-white-off-narrow"), - nBC3("square-toggle-gray-on-narrow"), ngBC3("square-toggle-gray-off-narrow"), - iR(Gtk::manage (new RTImage(ngR, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iG(Gtk::manage (new RTImage(ngG, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iB(Gtk::manage (new RTImage(ngB, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iL(Gtk::manage (new RTImage(ngL, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iBC0(Gtk::manage (new RTImage(options.bgcolor == 0 ? nBC0 : ngBC0, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iBC1(Gtk::manage (new RTImage(options.bgcolor == 1 ? nBC1 : ngBC1, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iBC2(Gtk::manage (new RTImage(options.bgcolor == 2 ? nBC2 : ngBC2, Gtk::ICON_SIZE_LARGE_TOOLBAR))), - iBC3(Gtk::manage (new RTImage(options.bgcolor == 3 ? nBC3 : ngBC3, Gtk::ICON_SIZE_LARGE_TOOLBAR))) + nBC3("square-toggle-gray-on-narrow"), ngBC3("square-toggle-gray-off-narrow") { backColor0 = Gtk::manage (new Gtk::ToggleButton ()); backColor0->get_style_context()->add_class("narrowbutton"); backColor0->set_relief(Gtk::RELIEF_NONE); backColor0->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR0")); - backColor0->set_image(*iBC0); + backColor0->set_image_from_icon_name(options.bgcolor == 0 ? nBC0 : ngBC0, Gtk::ICON_SIZE_LARGE_TOOLBAR); backColor1 = Gtk::manage (new Gtk::ToggleButton ()); backColor1->get_style_context()->add_class("narrowbutton"); backColor1->set_relief(Gtk::RELIEF_NONE); backColor1->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR1")); - backColor1->set_image(*iBC1); - - backColor3 = Gtk::manage (new Gtk::ToggleButton ()); - backColor3->get_style_context()->add_class("narrowbutton"); - backColor3->set_relief(Gtk::RELIEF_NONE); - backColor3->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR3")); - backColor3->set_image(*iBC3); + backColor1->set_image_from_icon_name(options.bgcolor == 1 ? nBC1 : ngBC1, Gtk::ICON_SIZE_LARGE_TOOLBAR); backColor2 = Gtk::manage (new Gtk::ToggleButton ()); backColor2->get_style_context()->add_class("narrowbutton"); backColor2->set_relief(Gtk::RELIEF_NONE); backColor2->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR2")); - backColor2->set_image(*iBC2); + backColor2->set_image_from_icon_name(options.bgcolor == 2 ? nBC2 : ngBC2, Gtk::ICON_SIZE_LARGE_TOOLBAR); + + backColor3 = Gtk::manage (new Gtk::ToggleButton ()); + backColor3->get_style_context()->add_class("narrowbutton"); + backColor3->set_relief(Gtk::RELIEF_NONE); + backColor3->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR3")); + backColor3->set_image_from_icon_name(options.bgcolor == 3 ? nBC3 : ngBC3, Gtk::ICON_SIZE_LARGE_TOOLBAR); previewR = Gtk::manage (new Gtk::ToggleButton ()); previewR->get_style_context()->add_class("narrowbutton"); previewR->set_relief(Gtk::RELIEF_NONE); previewR->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWR")); - previewR->set_image(*iR); + previewR->set_image_from_icon_name(ngR, Gtk::ICON_SIZE_LARGE_TOOLBAR); previewG = Gtk::manage (new Gtk::ToggleButton ()); previewG->get_style_context()->add_class("narrowbutton"); previewG->set_relief(Gtk::RELIEF_NONE); previewG->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWG")); - previewG->set_image(*iG); + previewG->set_image_from_icon_name(ngG, Gtk::ICON_SIZE_LARGE_TOOLBAR); previewB = Gtk::manage (new Gtk::ToggleButton ()); previewB->get_style_context()->add_class("narrowbutton"); previewB->set_relief(Gtk::RELIEF_NONE); previewB->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWB")); - previewB->set_image(*iB); + previewB->set_image_from_icon_name(ngB, Gtk::ICON_SIZE_LARGE_TOOLBAR); previewL = Gtk::manage (new Gtk::ToggleButton ()); previewL->get_style_context()->add_class("narrowbutton"); previewL->set_relief(Gtk::RELIEF_NONE); previewL->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWL")); - previewL->set_image(*iL); + previewL->set_image_from_icon_name(ngL, Gtk::ICON_SIZE_LARGE_TOOLBAR); previewR->set_active (false); previewG->set_active (false); @@ -162,35 +155,50 @@ void PreviewModePanel::togglebackColor3 () void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) { - connR.block(true); connG.block(true); connB.block(true); connL.block(true); - // control state of the buttons - // only 0 or 1 button at a time can remain pressed - if (tbpreview != previewR) { + // Control state of the others buttons: only 0 or 1 button at a time can remain pressed + // Note: Only refresh previously toggled button + if (previewR->get_active() && tbpreview != previewR) { previewR->set_active(false); + previewR->set_image_from_icon_name(ngR, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbpreview != previewG) { + if (previewG->get_active() && tbpreview != previewG) { previewG->set_active(false); + previewG->set_image_from_icon_name(ngG, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbpreview != previewB) { + if (previewB->get_active() && tbpreview != previewB) { previewB->set_active(false); + previewB->set_image_from_icon_name(ngB, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbpreview != previewL) { + if (previewL->get_active() && tbpreview != previewL) { previewL->set_active(false); + previewL->set_image_from_icon_name(ngL, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - // set image based on button's state - iR->set_from_icon_name(previewR->get_active() ? nR : ngR); - iG->set_from_icon_name(previewG->get_active() ? nG : ngG); - iB->set_from_icon_name(previewB->get_active() ? nB : ngB); - iL->set_from_icon_name(previewL->get_active() ? nL : ngL); + // Change image on activated button + // Note: Only refresh toggled button + if (tbpreview == previewR) { + previewR->set_image_from_icon_name(previewR->get_active() ? nR : ngR, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } + + if (tbpreview == previewG) { + previewG->set_image_from_icon_name(previewG->get_active() ? nG : ngG, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } + + if (tbpreview == previewB) { + previewB->set_image_from_icon_name(previewB->get_active() ? nB : ngB, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } + + if (tbpreview == previewL) { + previewL->set_image_from_icon_name(previewL->get_active() ? nL : ngL, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } connR.block(false); connG.block(false); @@ -246,51 +254,66 @@ void PreviewModePanel::togglebackColor() void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) { - connbackColor0.block(true); connbackColor1.block(true); connbackColor2.block(true); connbackColor3.block(true); - // control the state of the buttons - // Exactly 1 button at a time must remain pressed - 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 == backColor3 && !backColor3->get_active()) { - backColor3->set_active(true); - } - - if (tbbackColor != backColor0) { + // Control state of the others buttons: only 1 button at a time shall remain pressed + // Note: Only refresh previously toggled button + if (backColor0->get_active() && tbbackColor != backColor0) { backColor0->set_active(false); + backColor0->set_image_from_icon_name(ngBC0, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbbackColor != backColor1) { + if (backColor1->get_active() && tbbackColor != backColor1) { backColor1->set_active(false); + backColor1->set_image_from_icon_name(ngBC1, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbbackColor != backColor2) { + if (backColor2->get_active() && tbbackColor != backColor2) { backColor2->set_active(false); + backColor2->set_image_from_icon_name(ngBC2, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - if (tbbackColor != backColor3) { + if (backColor3->get_active() && tbbackColor != backColor3) { backColor3->set_active(false); + backColor3->set_image_from_icon_name(ngBC3, Gtk::ICON_SIZE_LARGE_TOOLBAR); } - // set image based on button's state - iBC0->set_from_icon_name(backColor0->get_active() ? nBC0 : ngBC0); - iBC1->set_from_icon_name(backColor1->get_active() ? nBC1 : ngBC1); - iBC2->set_from_icon_name(backColor2->get_active() ? nBC2 : ngBC2); - iBC3->set_from_icon_name(backColor3->get_active() ? nBC3 : ngBC3); + // Change image on toggled button + // Note: Only refresh toggled button if newly active (otherwise keep it active) + if (tbbackColor == backColor0) { + if (backColor0->get_active()) { + backColor0->set_image_from_icon_name(nBC0, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } else { + backColor0->set_active(true); + } + } + + if (tbbackColor == backColor1) { + if (backColor1->get_active()) { + backColor1->set_image_from_icon_name(nBC1, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } else { + backColor1->set_active(true); + } + } + + if (tbbackColor == backColor2) { + if (backColor2->get_active()) { + backColor2->set_image_from_icon_name(nBC2, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } else { + backColor2->set_active(true); + } + } + + if (tbbackColor == backColor3) { + if (backColor3->get_active()) { + backColor3->set_image_from_icon_name(nBC3, Gtk::ICON_SIZE_LARGE_TOOLBAR); + } else { + backColor3->set_active(true); + } + } connbackColor0.block(false); connbackColor1.block(false); diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h index b496958ab..6e869471d 100644 --- a/rtgui/previewmodepanel.h +++ b/rtgui/previewmodepanel.h @@ -20,7 +20,6 @@ #include class ImageArea; -class RTImage; class PreviewModePanel : public Gtk::Box @@ -45,14 +44,6 @@ protected: const Glib::ustring nBC1, ngBC1; const Glib::ustring nBC2, ngBC2; const Glib::ustring nBC3, ngBC3; - RTImage* const iR; - RTImage* const iG; - RTImage* const iB; - RTImage* const iL; - RTImage* const iBC0; - RTImage* const iBC1; - RTImage* const iBC2; - RTImage* const iBC3; public: explicit PreviewModePanel (ImageArea* ia); From 1a4de65f467fe9b586dcbc9f6d279722230e470c Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Tue, 13 Dec 2022 19:26:25 +0100 Subject: [PATCH 014/291] Fixes ornament icon not correctly rendered --- rtdata/images/{svg => }/ornament1.svg | 0 rtgui/exportpanel.cc | 5 +++-- rtgui/exportpanel.h | 3 +++ rtgui/filterpanel.cc | 6 +++--- rtgui/filterpanel.h | 4 ++++ rtgui/toolpanelcoord.cc | 4 ++-- rtgui/toolpanelcoord.h | 1 + 7 files changed, 16 insertions(+), 7 deletions(-) rename rtdata/images/{svg => }/ornament1.svg (100%) diff --git a/rtdata/images/svg/ornament1.svg b/rtdata/images/ornament1.svg similarity index 100% rename from rtdata/images/svg/ornament1.svg rename to rtdata/images/ornament1.svg diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc index f1927e9d8..573055650 100644 --- a/rtgui/exportpanel.cc +++ b/rtgui/exportpanel.cc @@ -21,13 +21,14 @@ #include "multilangmgr.h" #include "options.h" #include "rtimage.h" +#include "rtsurface.h" #include "../rtengine/procparams.h" using namespace rtengine; using namespace rtengine::procparams; -ExportPanel::ExportPanel () : listener (nullptr) +ExportPanel::ExportPanel () : listener (nullptr), ornamentSurface(new RTSurface("ornament1.svg")) { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -192,7 +193,7 @@ ExportPanel::ExportPanel () : listener (nullptr) // add panel ending Gtk::Box* vboxpe = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); Gtk::Separator* hseptpe = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - Gtk::Image* peImg = Gtk::manage (new RTImage ("ornament1")); + Gtk::Image* peImg = Gtk::manage (new Gtk::Image (ornamentSurface->get())); vboxpe->pack_start (*hseptpe, Gtk::PACK_SHRINK, 4); vboxpe->pack_start (*peImg); pack_start (*vboxpe, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h index 18c4bda49..45fd75e3c 100644 --- a/rtgui/exportpanel.h +++ b/rtgui/exportpanel.h @@ -23,6 +23,7 @@ #include "guiutils.h" +class RTSurface; class ExportPanelListener { public: @@ -103,6 +104,8 @@ protected: ExportPanelListener* listener; + std::shared_ptr ornamentSurface; + void bypassALL_Toggled(); void use_fast_pipeline_toggled(); void SaveSettingsAsDefault(); diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc index 1ea843e28..186dd68ce 100644 --- a/rtgui/filterpanel.cc +++ b/rtgui/filterpanel.cc @@ -19,11 +19,11 @@ #include "filterpanel.h" #include "multilangmgr.h" #include "../rtengine/rtengine.h" -#include "rtimage.h" +#include "rtsurface.h" using namespace rtengine; -FilterPanel::FilterPanel () : listener (nullptr) +FilterPanel::FilterPanel () : listener (nullptr), ornamentSurface(new RTSurface("ornament1.svg")) { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -138,7 +138,7 @@ FilterPanel::FilterPanel () : listener (nullptr) // add panel ending Gtk::Box* vboxpe = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); Gtk::Separator* hseptpe = Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); - Gtk::Image* peImg = Gtk::manage (new RTImage("ornament1")); + Gtk::Image* peImg = Gtk::manage (new Gtk::Image(ornamentSurface->get())); vboxpe->pack_start(*hseptpe, Gtk::PACK_SHRINK, 4); vboxpe->pack_start(*peImg); pack_start(*vboxpe, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h index 77c2d063e..4c4a8b0da 100644 --- a/rtgui/filterpanel.h +++ b/rtgui/filterpanel.h @@ -22,6 +22,8 @@ #include "exiffiltersettings.h" +class RTSurface; + class FilterPanelListener { public: @@ -61,6 +63,8 @@ protected: ExifFilterSettings curefs; FilterPanelListener* listener; + std::shared_ptr ornamentSurface; + public: FilterPanel (); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 859156801..731b70e68 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -32,7 +32,7 @@ using namespace rtengine::procparams; -ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr), photoLoadedOnce(false) +ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favoritePanelSW(nullptr), hasChanged (false), editDataProvider (nullptr), photoLoadedOnce(false), ornamentSurface(new RTSurface("ornament1.svg")) { favoritePanel = Gtk::manage (new ToolVBox ()); @@ -194,7 +194,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit // load panel endings for (int i = 0; i < 8; i++) { vbPanelEnd[i] = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); - imgPanelEnd[i] = Gtk::manage (new RTImage ("ornament1")); + imgPanelEnd[i] = Gtk::manage (new Gtk::Image (ornamentSurface->get())); imgPanelEnd[i]->show(); vbPanelEnd[i]->pack_start(*imgPanelEnd[i], Gtk::PACK_SHRINK); vbPanelEnd[i]->show_all(); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 65e2f1e8f..031c43459 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -220,6 +220,7 @@ private: EditDataProvider *editDataProvider; sigc::connection notebookconn; bool photoLoadedOnce; // Used to indicated that a photo has been loaded yet + std::shared_ptr ornamentSurface; Gtk::Widget* prevPage; public: From 3c348599dc63356bfe79a66d86ab97e869ab19d4 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Mon, 19 Dec 2022 20:16:02 +0100 Subject: [PATCH 015/291] Fixes incorrect cursor center position --- rtgui/cursormanager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index f683e9964..30649d707 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -41,8 +41,8 @@ void CursorManager::init (Glib::RefPtr mainWindow) auto cursor_surf = RTSurface(name, Gtk::ICON_SIZE_MENU); auto cursor = Gdk::Cursor::create(this->display, cursor_surf.get(), - cursor_surf.getWidth() / 2, - cursor_surf.getHeight() / 2); + cursor_surf.getWidth(), + cursor_surf.getHeight()); if (!cursor) { cursor = Gdk::Cursor::create(this->display, fb_cursor); From c48531448e119298a5ea47f861109f436786ccde Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sun, 25 Dec 2022 15:35:25 +0100 Subject: [PATCH 016/291] Add hidpi support for threshold selector and curves --- rtgui/coloredbar.cc | 94 +++--------- rtgui/coloredbar.h | 19 ++- rtgui/curveeditorgroup.cc | 2 +- rtgui/diagonalcurveeditorsubgroup.cc | 17 +-- rtgui/flatcurveeditorsubgroup.cc | 7 - rtgui/mycurve.cc | 24 +--- rtgui/mycurve.h | 4 +- rtgui/mydiagonalcurve.cc | 189 +++++++++--------------- rtgui/mydiagonalcurve.h | 2 +- rtgui/myflatcurve.cc | 208 ++++++++++----------------- rtgui/myflatcurve.h | 2 +- rtgui/shcselector.cc | 106 +++++--------- rtgui/shcselector.h | 4 +- rtgui/thresholdselector.cc | 177 +++++++++-------------- rtgui/thresholdselector.h | 13 +- 15 files changed, 302 insertions(+), 566 deletions(-) diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc index adafcbdde..0d28c335a 100644 --- a/rtgui/coloredbar.cc +++ b/rtgui/coloredbar.cc @@ -23,77 +23,20 @@ ColoredBar::ColoredBar (eRTOrientation orient) { orientation = orient; - dirty = true; this->x = this->y = this->w = this->h = 0; } -bool ColoredBar::setDrawRectangle(int newX, int newY, int newW, int newH, bool updateBackBufferSize) +void ColoredBar::setColoredBarSize(const int newX, const int newY, const int newW, const int newH) { - return BackBuffer::setDrawRectangle(Cairo::FORMAT_ARGB32, newX, newY, newW, newH, updateBackBufferSize); + this->x = newX; + this->y = newY; + this->w = newW; + this->h = newH; } -/* - * Redraw the bar to a Cairo::ImageSurface - */ -void ColoredBar::expose(Gtk::DrawingArea &drawingArea, Cairo::RefPtr destSurface) +void ColoredBar::updateColoredBar(const Cairo::RefPtr< Cairo::Context> &cr) { - // look out if the Surface has to be redrawn - if (!surfaceCreated() || !destSurface) { - return; - } - - updateBackBuffer(drawingArea); - Gdk::Rectangle rect(x, y, w, h); - copySurface(destSurface, &rect); -} - -/* - * Redraw the bar to a Gdk::Window - */ -void ColoredBar::expose(Gtk::DrawingArea &drawingArea, Glib::RefPtr destWindow) -{ - // look out if the Surface has to be redrawn - if (!surfaceCreated() || !destWindow) { - return; - } - - updateBackBuffer(drawingArea); - Gdk::Rectangle rect(x, y, w, h); - copySurface(destWindow, &rect); -} - -void ColoredBar::expose(Gtk::DrawingArea &drawingArea, const Cairo::RefPtr< Cairo::Context> &cr) -{ - // look out if the Surface has to be redrawn - if (!surfaceCreated()) { - return; - } - - updateBackBuffer(drawingArea); - Gdk::Rectangle rect(x, y, w, h); - copySurface(cr, &rect); -} - -/* - * Redraw the bar to a Gdk::Window - */ -void ColoredBar::expose(Gtk::DrawingArea &drawingArea, BackBuffer *backBuffer) -{ - // look out if the Surface has to be redrawn - if (!surfaceCreated() || !backBuffer) { - return; - } - - updateBackBuffer(drawingArea); - Gdk::Rectangle rect(x, y, w, h); - copySurface(backBuffer, &rect); -} - -void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) -{ - if (isDirty()) { - Cairo::RefPtr cr = getContext(); - + if (w > 0 && h > 0) { // the bar has to be drawn to the Surface first if (!bgGradient.empty()) { // a gradient has been set, we use it @@ -104,20 +47,20 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) switch (orientation) { case (RTO_Left2Right): - bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.); + bggradient = Cairo::LinearGradient::create (0., 0., static_cast(w), 0.); break; case (RTO_Right2Left): - bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.); + bggradient = Cairo::LinearGradient::create (static_cast(w), 0., 0., 0.); break; case (RTO_Bottom2Top): - bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.); + bggradient = Cairo::LinearGradient::create (0., static_cast(h), 0., 0.); break; case (RTO_Top2Bottom): default: - bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h)); + bggradient = Cairo::LinearGradient::create (0., 0., 0., static_cast(h)); break; } @@ -126,13 +69,13 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) } cr->set_source (bggradient); - cr->rectangle(0, 0, w, h); + cr->rectangle(static_cast(x), static_cast(y), static_cast(w), static_cast(h)); cr->fill(); } else { // ask the ColorProvider to provide colors :) for each pixels if (colorProvider) { - surface->flush(); - + // Create surface + const auto surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w, h); unsigned char *surfaceData = surface->get_data(); cr->set_antialias(Cairo::ANTIALIAS_NONE); @@ -205,25 +148,22 @@ void ColoredBar::updateBackBuffer(Gtk::DrawingArea &drawingArea) break; } - surface->mark_dirty(); + cr->set_source(surface, 0., 0.); + cr->rectangle(static_cast(x), static_cast(y), static_cast(w), static_cast(h)); + cr->fill(); } } - - // 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() diff --git a/rtgui/coloredbar.h b/rtgui/coloredbar.h index f5156129e..55ac8849e 100644 --- a/rtgui/coloredbar.h +++ b/rtgui/coloredbar.h @@ -30,11 +30,15 @@ * the bar itself, i.e. use render_background (depending on its Gtk::StyleContext) * */ -class ColoredBar final : private BackBuffer, public ColorCaller +class ColoredBar final : public ColorCaller { private: - void updateBackBuffer(Gtk::DrawingArea &drawingArea); + // ColoredBar position and size parameters + int x; + int y; + int w; + int h; protected: eRTOrientation orientation; @@ -42,12 +46,9 @@ protected: public: explicit ColoredBar (eRTOrientation orient); - bool setDrawRectangle(int newX, int newY, int newW, int newH, bool updateBackBufferSize = true); + void setColoredBarSize(const int newX, const int newY, const int newW, const int newH); // Note: updateColoredBar shall be called after to update the bar - void expose(Gtk::DrawingArea &drawingArea, Glib::RefPtr destWindow); - void expose(Gtk::DrawingArea &drawingArea, Cairo::RefPtr destSurface); - void expose(Gtk::DrawingArea &drawingArea, BackBuffer *backBuffer); - void expose(Gtk::DrawingArea &drawingArea, const Cairo::RefPtr< Cairo::Context> &cr); + void updateColoredBar(const Cairo::RefPtr< Cairo::Context> &cr); bool canGetColors(); @@ -56,8 +57,4 @@ public: // 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 (); - - void setDirty(bool isDirty) { - BackBuffer::setDirty(isDirty); - } }; diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index f348ac33b..5ce3765a2 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -442,7 +442,7 @@ void CurveEditorSubGroup::initButton (Gtk::Button &button, const Glib::ustring & vAlign = options.curvebboxpos == 0 || options.curvebboxpos == 2 ? Gtk::ALIGN_FILL : Gtk::ALIGN_END; } - button.add (*Gtk::manage (new RTImage(iconName, Gtk::ICON_SIZE_BUTTON))); + button.add (*Gtk::manage (new RTImage(iconName, Gtk::ICON_SIZE_LARGE_TOOLBAR))); button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT); if (!tooltip.empty()) { button.set_tooltip_text(M(tooltip)); diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index 55d6d457f..88d9a14c5 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -33,7 +33,6 @@ #include "rtimage.h" #include "options.h" #include "popuptogglebutton.h" -#include "rtscalable.h" #include "../rtengine/curves.h" @@ -429,7 +428,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff () prevState = editCustomConn.block(true); editCustom->set_active(false); customCurve->pipetteMouseOver(nullptr, nullptr, 0); - customCurve->setDirty(true); if (!prevState) { editCustomConn.block(false); @@ -438,7 +436,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff () prevState = editNURBSConn.block(true); editNURBS->set_active(false); NURBSCurve->pipetteMouseOver(nullptr, nullptr, 0); - NURBSCurve->setDirty(true); if (!prevState) { editNURBSConn.block(false); @@ -447,7 +444,6 @@ void DiagonalCurveEditorSubGroup::editModeSwitchedOff () prevState = editParamConn.block(true); editParam->set_active(false); paramCurve->pipetteMouseOver(nullptr, nullptr, 0); - paramCurve->setDirty(true); if (!prevState) { editParamConn.block(false); @@ -462,12 +458,10 @@ void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, i case (DCT_Spline): case (DCT_CatumullRom): customCurve->pipetteMouseOver(curveEditor, provider, modifierKey); - customCurve->setDirty(true); break; case (DCT_Parametric): { paramCurve->pipetteMouseOver(curveEditor, provider, modifierKey); - paramCurve->setDirty(true); float pipetteVal = 0.f; editedAdjuster = nullptr; int n = 0; @@ -518,7 +512,6 @@ void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, i case (DCT_NURBS): NURBSCurve->pipetteMouseOver(curveEditor, provider, modifierKey); - NURBSCurve->setDirty(true); break; default: // (DCT_Linear, DCT_Unchanged) @@ -765,8 +758,8 @@ void DiagonalCurveEditorSubGroup::switchGUI() shcSelector->coloredBar.setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); shcSelector->coloredBar.setBgGradient(bgGradient); shcSelector->setMargins( - (int)( RTScalable::scalePixelSize((leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5) ), - (int)( RTScalable::scalePixelSize(RADIUS - 1.5) ) + (int)( (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN + RADIUS : RADIUS) - 1.5 ), + (int)( RADIUS - 1.5 ) ); paramCurve->setColoredBar(leftBar, nullptr); paramCurve->queue_resize_no_redraw(); @@ -895,11 +888,9 @@ void DiagonalCurveEditorSubGroup::loadPressed () if (p[0] == (double)(DCT_Spline) || p[0] == (double)(DCT_CatumullRom)) { 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] ); @@ -908,7 +899,6 @@ void DiagonalCurveEditorSubGroup::loadPressed () darks->setValue (p[6]); shadows->setValue (p[7]); paramCurve->setPoints (p); - paramCurve->queue_draw (); paramCurve->notifyListener (); } } @@ -966,7 +956,6 @@ void DiagonalCurveEditorSubGroup::pastePressed () case DCT_Spline: // custom case DCT_CatumullRom: customCurve->setPoints (curve); - customCurve->queue_draw (); customCurve->notifyListener (); break; @@ -981,13 +970,11 @@ void DiagonalCurveEditorSubGroup::pastePressed () 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; diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 0cabd2f80..0cf522c55 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -206,7 +206,6 @@ void FlatCurveEditorSubGroup::editModeSwitchedOff () bool prevState = editCPointsConn.block(true); editCPoints->set_active(false); CPointsCurve->pipetteMouseOver(nullptr, nullptr, 0); - CPointsCurve->setDirty(true); if (!prevState) { editCPointsConn.block(false); @@ -220,7 +219,6 @@ void FlatCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, int m switch((FlatCurveType)(curveEditor->curveType->getSelected())) { case (FCT_MinMaxCPoints): CPointsCurve->pipetteMouseOver(curveEditor, provider, modifierKey); - CPointsCurve->setDirty(true); break; default: // (DCT_Linear, DCT_Unchanged) @@ -238,7 +236,6 @@ bool FlatCurveEditorSubGroup::pipetteButton1Pressed(EditDataProvider *provider, switch((FlatCurveType)(curveEditor->curveType->getSelected())) { case (FCT_MinMaxCPoints): isDragging = CPointsCurve->pipetteButton1Pressed(provider, modifierKey); - CPointsCurve->setDirty(true); break; default: // (DCT_Linear, DCT_Unchanged) @@ -256,7 +253,6 @@ void FlatCurveEditorSubGroup::pipetteButton1Released(EditDataProvider *provider) switch((FlatCurveType)(curveEditor->curveType->getSelected())) { case (FCT_MinMaxCPoints): CPointsCurve->pipetteButton1Released(provider); - CPointsCurve->setDirty(true); break; default: // (DCT_Linear, DCT_Unchanged) @@ -272,7 +268,6 @@ void FlatCurveEditorSubGroup::pipetteDrag(EditDataProvider *provider, int modifi switch((FlatCurveType)(curveEditor->curveType->getSelected())) { case (FCT_MinMaxCPoints): CPointsCurve->pipetteDrag(provider, modifierKey); - CPointsCurve->setDirty(true); break; default: // (DCT_Linear, DCT_Unchanged) @@ -441,7 +436,6 @@ void FlatCurveEditorSubGroup::loadPressed () if (p[0] == (double)(FCT_MinMaxCPoints)) { CPointsCurve->setPoints (p); - CPointsCurve->queue_draw (); CPointsCurve->notifyListener (); } } @@ -481,7 +475,6 @@ void FlatCurveEditorSubGroup::pastePressed () switch (type) { case FCT_MinMaxCPoints: // min/max control points CPointsCurve->setPoints (curve); - CPointsCurve->queue_draw (); CPointsCurve->notifyListener (); break; diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 851db0ec6..6fd689e32 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -41,7 +41,7 @@ MyCurve::MyCurve () : snapToValX(0.0), snapToValY(0.0) { - int pointDiameter = RTScalable::scalePixelSize((int)(RADIUS * 2.)); + int pointDiameter = (int)(RADIUS * 2.); graphW = get_allocation().get_width() - pointDiameter; graphH = get_allocation().get_height() - pointDiameter; prevGraphW = graphW; @@ -76,13 +76,12 @@ MyCurve::~MyCurve () void MyCurve::calcDimensions () { double newRequestedW, newRequestedH; - const double s = RTScalable::scalePixelSize(1.); newRequestedW = newRequestedH = get_allocation().get_width(); - graphX = ((double)RADIUS + (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN : 0.)) * s; - graphH = graphW = newRequestedW - graphX - (double)RADIUS * s; - graphY = (double)RADIUS * s + graphW; + graphX = (double)RADIUS + (leftBar ? (double)CBAR_WIDTH + 2. + (double)CBAR_MARGIN : 0.); + graphH = graphW = newRequestedW - graphX - (double)RADIUS; + graphY = (double)RADIUS + graphW; return; } @@ -109,11 +108,11 @@ void MyCurve::get_preferred_height_for_width_vfunc (int width, int &minimum_heig minimum_height = width; if (leftBar && !bottomBar) { - minimum_height -= RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN); + minimum_height -= CBAR_WIDTH + 2 + CBAR_MARGIN; } if (!leftBar && bottomBar) { - minimum_height += RTScalable::scalePixelSize(CBAR_WIDTH + 2 + CBAR_MARGIN); + minimum_height += CBAR_WIDTH + 2 + CBAR_MARGIN; } natural_height = minimum_height; @@ -185,22 +184,11 @@ float MyCurve::getVal(LUTf &curve, int x) void MyCurve::on_style_updated () { - setDirty(true); queue_draw (); } void MyCurve::refresh() { - if (leftBar != nullptr) { - leftBar->setDirty(true); - } - - if (bottomBar != nullptr) { - bottomBar->setDirty(true); - } - - setDirty(true); - Glib::RefPtr win = get_window(); if (win) { diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 6bdfe4b66..a6e375aac 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -57,7 +57,7 @@ class MyCurveIdleHelper; class CurveEditor; class EditDataProvider; -class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable +class MyCurve : public Gtk::DrawingArea, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable { friend class MyCurveIdleHelper; @@ -150,6 +150,6 @@ public: void clearPixmap () { - myCurve->setDirty(true); + myCurve->queue_draw(); } }; diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index a2ffbc905..4bf8580b5 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -23,7 +23,6 @@ #include "mydiagonalcurve.h" #include "editcallbacks.h" -#include "rtscalable.h" #include "../rtengine/curves.h" @@ -150,8 +149,7 @@ void MyDiagonalCurve::updateLocallabBackground(double ref) return false; } - mcih->clearPixmap(); - mcih->myCurve->queue_draw(); + mcih->clearPixmap(); --mcih->pending; @@ -250,24 +248,18 @@ void MyDiagonalCurve::interpolate () curveIsDirty = false; } -void MyDiagonalCurve::draw (int handle) +void MyDiagonalCurve::updateDrawingArea (const int handle, const ::Cairo::RefPtr< Cairo::Context> &cr) { - if (!isDirty()) { + if (!get_realized()) { return; } - if (!surfaceCreated()) { - return; - } - - const double s = RTScalable::scalePixelSize(1.); - // re-calculate curve if dimensions changed int currLUTSize = point.getUpperBound(); if (curveIsDirty - || (currLUTSize == (GRAPH_SIZE * s) && (graphW > (GRAPH_SIZE * s))) - || (currLUTSize > (GRAPH_SIZE * s) && (graphW <= (GRAPH_SIZE * s) || graphW != currLUTSize)) ) + || (currLUTSize == GRAPH_SIZE && (graphW > GRAPH_SIZE)) + || (currLUTSize > GRAPH_SIZE && (graphW <= GRAPH_SIZE || graphW != currLUTSize)) ) { interpolate (); } @@ -277,20 +269,17 @@ void MyDiagonalCurve::draw (int handle) Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL; Glib::RefPtr style = get_style_context(); - Cairo::RefPtr cr = getContext(); - cr->set_line_cap(Cairo::LINE_CAP_SQUARE); - // clear background - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); + // Setup drawing + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); cr->set_operator (Cairo::OPERATOR_OVER); + // Render background style->render_background(cr, graphX, graphY-graphH, graphW, graphH); Gdk::RGBA c; - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); // Draw Locallab reference value in the background if (locallabRef > 0.0) { @@ -309,28 +298,26 @@ void MyDiagonalCurve::draw (int handle) // draw the left colored bar if (leftBar) { // first the background - BackBuffer *bb = this; - leftBar->setDrawRectangle(1. * s, graphY - graphH - 0.5, CBAR_WIDTH * s, graphH); - leftBar->expose(*this, bb); + leftBar->setColoredBarSize(1., graphY - graphH - 0.5, CBAR_WIDTH, graphH); + leftBar->updateColoredBar(cr); // now the border c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(0.5 * s, graphY - graphH - 0.5 - 0.5 * s, (CBAR_WIDTH + 1) * s, (double)graphH + 1. + 1. * s); + cr->rectangle(0.5, graphY - graphH - 0.5 - 0.5, CBAR_WIDTH + 1, (double)graphH + 1. + 1.); cr->stroke(); } // draw the bottom colored bar if (bottomBar) { // first the background - BackBuffer *bb = this; - bottomBar->setDrawRectangle(graphX - 0.5, graphY + (RADIUS + CBAR_MARGIN + 1.) * s, graphW + 1., CBAR_WIDTH * s); - bottomBar->expose(*this, bb); + bottomBar->setColoredBarSize(graphX - 0.5, graphY + RADIUS + CBAR_MARGIN + 1., graphW + 1., CBAR_WIDTH); + bottomBar->updateColoredBar(cr); // now the border c = style->get_border_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + (RADIUS + CBAR_MARGIN + 0.5) * s, graphW + 1. + 0.5 * s, (CBAR_WIDTH + 1.) * s); + cr->rectangle(graphX - 0.5 - 0.5, graphY + CBAR_MARGIN + 0.5, graphW + 1. + 0.5, CBAR_WIDTH + 1.); cr->stroke(); } @@ -345,7 +332,7 @@ void MyDiagonalCurve::draw (int handle) } // draw histogram - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); double stepSize = graphW / 255.0; cr->move_to (graphX, graphY); c = style->get_color(state); @@ -367,18 +354,18 @@ void MyDiagonalCurve::draw (int handle) } // draw the grid lines: - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); c = style->get_border_color(state); cr->set_source_rgba (c.get_red(), c.get_green(), c.get_blue(), 0.3); cr->set_antialias (Cairo::ANTIALIAS_NONE); for (int i = 0; i <= 10; i++) { // horizontal lines - cr->move_to (graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s - (graphH + 1. + 1. * s) * (double)i / 10.); - cr->rel_line_to (graphW + 1. + 1. * s, 0.); + cr->move_to (graphX - 0.5 - 0.5, graphY + 0.5 + 0.5 - (graphH + 1. + 1.) * (double)i / 10.); + cr->rel_line_to (graphW + 1. + 1., 0.); // vertical lines - cr->move_to (graphX - 0.5 - 0.5 * s + (graphW + 1. + 1. * s) * (double)i / 10., graphY + 0.5 + 0.5 * s); - cr->rel_line_to (0., -graphH - 1. - 1. * s); + cr->move_to (graphX - 0.5 - 0.5 + (graphW + 1. + 1.) * (double)i / 10., graphY + 0.5 + 0.5); + cr->rel_line_to (0., -graphH - 1. - 1.); } cr->stroke (); @@ -390,16 +377,15 @@ void MyDiagonalCurve::draw (int handle) cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); } - std::valarray ds (1); - ds[0] = 4 * s; + const std::valarray ds = {4.}; cr->set_dash (ds, 0); - cr->move_to (graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s); - cr->rel_line_to (graphW + 1. + 1. * s, -(graphH + 1. + 1. * s)); + cr->move_to (graphX - 0.5 - 0.5, graphY + 0.5 + 0.5); + cr->rel_line_to (graphW + 1. + 1., -(graphH + 1. + 1.)); cr->stroke (); cr->unset_dash (); cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); // draw upper and lower bounds if (curve.type == DCT_Parametric && activeParam > 0 && lpoint.getUpperBound() > 1 && upoint.getUpperBound() > 1) { @@ -436,34 +422,34 @@ void MyDiagonalCurve::draw (int handle) if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } } if (pipetteVal > -1.f) { - cr->set_line_width (2. * s); + cr->set_line_width (2.); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); - cr->set_line_width (1. * s); + cr->set_line_width (1.); } } @@ -472,10 +458,9 @@ void MyDiagonalCurve::draw (int handle) // draw the cage of the NURBS curve if (curve.type == DCT_NURBS) { unsigned int nbPoints; - std::valarray ch_ds (1); - ch_ds[0] = 2 * s; + const std::valarray ch_ds = {2.}; cr->set_dash (ch_ds, 0); - cr->set_line_width (0.75 * s); + cr->set_line_width (0.75); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); std::vector points = getPoints(); nbPoints = ((int)points.size() - 1) / 2; @@ -501,7 +486,7 @@ void MyDiagonalCurve::draw (int handle) } cr->unset_dash (); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); } // draw curve @@ -542,40 +527,26 @@ void MyDiagonalCurve::draw (int handle) double x = graphX + graphW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); double y = graphY - graphH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); - cr->arc (x, y, RADIUS * s + 0.5, 0, 2 * rtengine::RT_PI); + cr->arc (x, y, RADIUS + 0.5, 0, 2 * rtengine::RT_PI); cr->fill (); if (i == edited_point) { - cr->set_line_width(2. * s); - cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI); + cr->set_line_width(2.); + cr->arc (x, y, RADIUS + 2., 0, 2 * rtengine::RT_PI); cr->stroke(); - cr->set_line_width(1. * s); + cr->set_line_width(1.); } } } - - setDirty(false); - queue_draw(); } bool MyDiagonalCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Gtk::Allocation allocation = get_allocation(); - allocation.set_x(0); - allocation.set_y(0); + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(lit_point, cr); - // setDrawRectangle will allocate the backbuffer Surface - if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) { - setDirty(true); - - if (prevGraphW > GRAPH_SIZE || graphW > GRAPH_SIZE) { - curveIsDirty = true; - } - } - - draw (lit_point); - copySurface(cr); return false; } @@ -594,10 +565,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) return false; } - const double s = RTScalable::scalePixelSize(1.); - - double minDistanceX = double(MIN_DISTANCE) / graphW * s; - double minDistanceY = double(MIN_DISTANCE) / graphH * s; + double minDistanceX = double(MIN_DISTANCE) / graphW; + double minDistanceY = double(MIN_DISTANCE) / graphH; switch (event->type) { case GDK_BUTTON_PRESS: @@ -644,8 +613,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) curve.y.at(closest_point) = clampedY; curveIsDirty = true; - setDirty(true); - draw (closest_point); + queue_draw(); notifyListener (); } @@ -680,8 +648,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) editedPos.at(1) = curve.y.at(edited_point); coordinateAdjuster->setPos(editedPos); coordinateAdjuster->startNumericalAdjustment(newBoundaries); - setDirty(true); - draw (lit_point); + queue_draw(); new_type = CSArrow; } } @@ -701,8 +668,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) if (lit_point != edited_point) { edited_point = lit_point; curveIsDirty = true; - setDirty(true); - draw (lit_point); + queue_draw(); std::vector newBoundaries; newBoundaries.resize(2); int size = curve.x.size(); @@ -774,8 +740,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) curve.x.push_back (0); curve.y.push_back (0); curveIsDirty = true; - setDirty(true); - draw (lit_point); + queue_draw(); } } @@ -788,8 +753,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) } if (lit_point != previous_lit_point) { - setDirty(true); - draw (lit_point); + queue_draw(); } grab_point = -1; @@ -809,8 +773,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) new_type = CSArrow; lit_point = -1; pipetteR = pipetteG = pipetteB = -1.f; - setDirty(true); - draw (lit_point); + queue_draw(); } } @@ -854,8 +817,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) } if (lit_point != previous_lit_point) { - setDirty(true); - draw (lit_point); + queue_draw(); if (lit_point > -1) { editedPos.at(0) = curve.x.at(lit_point); @@ -884,8 +846,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) } if (lit_point != previous_lit_point) { - setDirty(true); - draw (lit_point); + queue_draw(); } } } else { @@ -986,8 +947,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) { // we recalculate the curve only if we have to curveIsDirty = true; - setDirty(true); - draw (lit_point); + queue_draw(); notifyListener (); if (coordinateAdjuster->is_visible()) { @@ -1069,8 +1029,7 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi return; } - const double s = RTScalable::scalePixelSize(1.); - double minDistanceX = MIN_DISTANCE / graphW * s; + double minDistanceX = MIN_DISTANCE / graphW; if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS || curve.type == DCT_CatumullRom) { // get the pointer position @@ -1092,12 +1051,11 @@ void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provi } if (lit_point != previous_lit_point) { - setDirty(true); - draw (lit_point); + queue_draw(); } } } else { - draw(lit_point); + queue_draw(); } if (edited_point == -1) { @@ -1124,8 +1082,7 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi return false; } - const double s = RTScalable::scalePixelSize(1.); - double minDistanceX = double(MIN_DISTANCE) * s / graphW; + double minDistanceX = double(MIN_DISTANCE) / graphW; snapToElmt = -100; @@ -1172,8 +1129,7 @@ bool MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modi } curveIsDirty = true; - setDirty(true); - draw (lit_point); + queue_draw(); notifyListener (); } @@ -1201,8 +1157,7 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider) return; } - const double s = RTScalable::scalePixelSize(1.); - double minDistanceX = double(MIN_DISTANCE) * s / graphW; + double minDistanceX = double(MIN_DISTANCE) / graphW; snapToElmt = -100; @@ -1221,8 +1176,7 @@ void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider) } if (lit_point != previous_lit_point) { - setDirty(true); - draw (lit_point); + queue_draw(); } grab_point = -1; @@ -1309,8 +1263,7 @@ void MyDiagonalCurve::pipetteDrag(EditDataProvider *provider, int modifierKey) if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) { // we recalculate the curve only if we have to curveIsDirty = true; - setDirty(true); - draw (lit_point); + queue_draw(); notifyListener (); if (lit_point > -1 && coordinateAdjuster->is_visible()) { @@ -1505,7 +1458,6 @@ void MyDiagonalCurve::setPoints (const std::vector& p) } curveIsDirty = true; - setDirty(true); queue_draw (); } @@ -1520,8 +1472,7 @@ void MyDiagonalCurve::setPos(double pos, int chanIdx) } curveIsDirty = true; - setDirty(true); - draw(lit_point); + queue_draw(); notifyListener (); } @@ -1530,8 +1481,7 @@ void MyDiagonalCurve::stopNumericalAdjustment() if (edited_point > -1) { edited_point = grab_point = lit_point = -1; coordinateAdjuster->stopNumericalAdjustment(); - setDirty(true); - draw(lit_point); + queue_draw(); } } @@ -1539,13 +1489,12 @@ void MyDiagonalCurve::setType (DiagonalCurveType t) { curve.type = t; - setDirty(true); + queue_draw(); } void MyDiagonalCurve::setActiveParam (int ac) { activeParam = ac; - setDirty(true); queue_draw (); } @@ -1579,7 +1528,6 @@ void MyDiagonalCurve::updateBackgroundHistogram (const LUTu & hist) } mcih->clearPixmap(); - mcih->myCurve->queue_draw(); --mcih->pending; @@ -1632,6 +1580,5 @@ void MyDiagonalCurve::reset(const std::vector &resetCurve, double identi break; } - setDirty(true); - draw(-1); + queue_draw(); } diff --git a/rtgui/mydiagonalcurve.h b/rtgui/mydiagonalcurve.h index 0eb173f70..76c9c1ec0 100644 --- a/rtgui/mydiagonalcurve.h +++ b/rtgui/mydiagonalcurve.h @@ -64,7 +64,7 @@ protected: bool bghistvalid; double locallabRef; // Locallab reference value to display in the background - void draw (int handle); + void updateDrawingArea (const int handle, const ::Cairo::RefPtr< Cairo::Context> &cr); void interpolate (); void findClosestPoint(); CursorShape motionNotify(CursorShape type, double minDistanceX, double minDistanceY, int num); diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index e95faf3d4..dc79a400b 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -23,7 +23,6 @@ #include "myflatcurve.h" #include "editcallbacks.h" -#include "rtscalable.h" #include "../rtengine/curves.h" @@ -130,24 +129,18 @@ void MyFlatCurve::interpolate () curveIsDirty = false; } -void MyFlatCurve::draw () +void MyFlatCurve::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr) { - if (!isDirty()) { + if (!get_realized()) { return; } - if (!surfaceCreated()) { - return; - } - - const double s = RTScalable::scalePixelSize(1.); - // re-calculate curve if dimensions changed int currLUTSize = point.getUpperBound(); if (curveIsDirty - || (currLUTSize == (GRAPH_SIZE * s) && (graphW > (GRAPH_SIZE * s))) - || (currLUTSize > (GRAPH_SIZE * s) && (graphW <= (GRAPH_SIZE * s) || graphW != currLUTSize)) ) + || (currLUTSize == GRAPH_SIZE && (graphW > GRAPH_SIZE)) + || (currLUTSize > GRAPH_SIZE && (graphW <= GRAPH_SIZE || graphW != currLUTSize)) ) { interpolate (); } @@ -155,20 +148,17 @@ void MyFlatCurve::draw () Gtk::StateFlags state = !is_sensitive() ? Gtk::STATE_FLAG_INSENSITIVE : Gtk::STATE_FLAG_NORMAL; Glib::RefPtr style = get_style_context(); - Cairo::RefPtr cr = getContext(); - cr->set_line_cap(Cairo::LINE_CAP_SQUARE); - // clear background - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); + // Setup drawing + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); cr->set_operator (Cairo::OPERATOR_OVER); + // Render background style->render_background(cr, graphX, graphY-graphH, graphW, graphH); Gdk::RGBA c; - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); // Draw Locallab reference value in the background if (locallabRef > 0.0) { @@ -187,49 +177,46 @@ void MyFlatCurve::draw () // draw the left colored bar if (leftBar) { // first the background - BackBuffer *bb = this; - leftBar->setDrawRectangle(1. * s, graphY - graphH - 0.5, CBAR_WIDTH * s, graphH); - leftBar->expose(*this, bb); + leftBar->setColoredBarSize(1., graphY - graphH - 0.5, CBAR_WIDTH, graphH); + leftBar->updateColoredBar(cr); // now the border c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(0.5 * s, graphY - graphH - 0.5 - 0.5 * s, (CBAR_WIDTH + 1) * s, (double)graphH + 1. + 1. * s); + cr->rectangle(0.5, graphY - graphH - 0.5 - 0.5, CBAR_WIDTH + 1, (double)graphH + 1.); cr->stroke(); } // draw the bottom colored bar if (bottomBar) { // first the background - BackBuffer *bb = this; - bottomBar->setDrawRectangle(graphX - 0.5, graphY + (RADIUS + CBAR_MARGIN + 1.) * s, graphW + 1., CBAR_WIDTH * s); - bottomBar->expose(*this, bb); + bottomBar->setColoredBarSize(graphX - 0.5, graphY + RADIUS + CBAR_MARGIN + 1., graphW + 1., CBAR_WIDTH); + bottomBar->updateColoredBar(cr); // now the border c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + (RADIUS + CBAR_MARGIN + 0.5) * s, graphW + 1. + 0.5 * s, (CBAR_WIDTH + 1.) * s); + cr->rectangle(graphX - 0.5 - 0.5, graphY + RADIUS + CBAR_MARGIN + 0.5, graphW + 1. + 1., CBAR_WIDTH + 1.); cr->stroke(); } // draw f(x)=0.5 line c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - std::valarray ds (1); - ds[0] = 4 * s; + const std::valarray ds = {4.}; cr->set_dash (ds, 0); - cr->move_to (graphX - 1. * s, graphY - graphH / 2.); - cr->rel_line_to (graphW + 2 * s, 0.); + cr->move_to (graphX - 1., graphY - graphH / 2.); + cr->rel_line_to (graphW + 2, 0.); cr->stroke (); cr->unset_dash (); cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); cr->set_line_cap(Cairo::LINE_CAP_BUTT); // draw the pipette values if (pipetteR > -1.f || pipetteG > -1.f || pipetteB > -1.f) { - cr->set_line_width (0.75 * s); + cr->set_line_width (0.75); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); int n = 0; @@ -248,34 +235,34 @@ void MyFlatCurve::draw () if (n > 1) { if (pipetteR > -1.f) { cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteR), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } if (pipetteG > -1.f) { cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteG), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } if (pipetteB > -1.f) { cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! - cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteB), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); } } if (pipetteVal > -1.f) { - cr->set_line_width (2. * s); + cr->set_line_width (2.); c = style->get_color (state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1. * s); - cr->rel_line_to (0, -graphH - 1. * s); + cr->move_to (graphX + graphW * static_cast(pipetteVal), graphY + 1.); + cr->rel_line_to (0, -graphH - 1.); cr->stroke (); - cr->set_line_width (1. * s); + cr->set_line_width (1.); } } @@ -286,7 +273,7 @@ void MyFlatCurve::draw () for (int i = 0; i < (int)curve.x.size(); ++i) { if (curve.x.at(i) != -1.) { - double coloredLineWidth = rtengine::min( rtengine::max(75. * s, graphW) / (75. * s), 8. * s); + double coloredLineWidth = rtengine::min( rtengine::max(75., graphW) / 75., 8.); cr->set_line_width (coloredLineWidth); colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_VERTICAL_BAR, colorCallerId, this); @@ -296,8 +283,8 @@ void MyFlatCurve::draw () cr->set_line_width (2 * coloredLineWidth); } - cr->move_to (graphX + graphW * curve.x.at(i), graphY + 0.5 + 0.5 * s ); - cr->rel_line_to (0., -graphH - 1. - s); + cr->move_to (graphX + graphW * curve.x.at(i), graphY + 0.5 + 0.5); + cr->rel_line_to (0., -graphH - 1. - 1.); cr->stroke (); cr->set_line_width (coloredLineWidth); @@ -323,39 +310,39 @@ void MyFlatCurve::draw () colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_HORIZONTAL_BAR, colorCallerId, this); cr->set_source_rgb (ccRed, ccGreen, ccBlue); - cr->move_to (graphX - 0.5 - 0.5 * s , graphY - graphH * curve.y.at(point)); - cr->rel_line_to (graphW + 1. + s, 0.); + cr->move_to (graphX - 0.5 - 0.5 , graphY - graphH * curve.y.at(point)); + cr->rel_line_to (graphW + 1. + 1., 0.); cr->stroke (); } } } // endif - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); } else { cr->set_source_rgb (0.5, 0.0, 0.0); if (edited_point > -1 || ((lit_point > -1) && ((area & (FCT_Area_H | FCT_Area_V | FCT_Area_Point)) || editedHandle == FCT_EditedHandle_CPointUD)) ) { // draw the lit_point's vertical line if (edited_point > -1 || (editedHandle & (FCT_EditedHandle_CPointUD | FCT_EditedHandle_CPoint | FCT_EditedHandle_CPointY))) { - cr->set_line_width (2.0 * s); + cr->set_line_width (2.0); } int point = edited_point > -1 ? edited_point : lit_point; - cr->move_to (graphX + graphW * curve.x.at(point), graphY + 0.5 + 0.5 * s ); - cr->rel_line_to (0., -graphH - 1. - s); + cr->move_to (graphX + graphW * curve.x.at(point), graphY + 0.5 + 0.5); + cr->rel_line_to (0., -graphH - 1. - 1.); cr->stroke (); - cr->set_line_width (1.0 * s); + 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 * s); + cr->set_line_width (2.0); } - cr->move_to (graphX - 0.5 - 0.5 * s , graphY - graphH * curve.y.at(point)); - cr->rel_line_to (graphW + 1. + s, 0.); + cr->move_to (graphX - 0.5 - 0.5 , graphY - graphH * curve.y.at(point)); + cr->rel_line_to (graphW + 1. + 1., 0.); cr->stroke (); - cr->set_line_width (1.0 * s); + cr->set_line_width (1.0); } } @@ -364,10 +351,10 @@ void MyFlatCurve::draw () // draw the graph's borders: c = style->get_border_color(state); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->rectangle(graphX - 0.5 - 0.5 * s, graphY + 0.5 + 0.5 * s, graphW + 1. + 1. * s, -(graphH + 1. + 1. * s)); + cr->rectangle(graphX - 0.5 - 0.5, graphY + 0.5 + 0.5, graphW + 1. + 1., -(graphH + 1. + 1.)); cr->stroke (); - double lineMinLength = 1. / graphW * (double)(SQUARE) * 0.9 * s; + double lineMinLength = 1. / graphW * (double)(SQUARE) * 0.9; if (tanHandlesDisplayed && lit_point != -1 && getHandles(lit_point) && curve.x.at(lit_point) != -1.) { double x = graphX + graphW * curve.x.at(lit_point); @@ -398,9 +385,9 @@ void MyFlatCurve::draw () cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to (graphX - 0.5 - 0.5 * s, y); + cr->line_to (graphX - 0.5 - 0.5, y); cr->stroke (); - cr->move_to (graphX + graphW + 0.5 + 0.5 * s, y); + cr->move_to (graphX + graphW + 0.5 + 0.5, y); } cr->line_to (x2, y); @@ -408,7 +395,7 @@ void MyFlatCurve::draw () } // draw tangential knot - square = (area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE) * s; + square = (area == FCT_Area_LeftTan ? SQUARE * 2. : SQUARE); cr->rectangle(x2 - square, y - square, 2.*square, 2.*square); cr->fill(); @@ -434,9 +421,9 @@ void MyFlatCurve::draw () cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to (graphX + graphW + 0.5 + 0.5 * s, y); + cr->line_to (graphX + graphW + 0.5 + 0.5, y); cr->stroke (); - cr->move_to (graphX - 0.5 - 0.5 * s, y); + cr->move_to (graphX - 0.5 - 0.5, y); } cr->line_to (x2, y); @@ -444,7 +431,7 @@ void MyFlatCurve::draw () } // draw tangential knot - square = (area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE) * s; + square = (area == FCT_Area_RightTan ? SQUARE * 2. : SQUARE); cr->rectangle(x2 - square, y - square, 2.*square, 2.*square); cr->fill(); } @@ -483,15 +470,15 @@ void MyFlatCurve::draw () double x = graphX + graphW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); double y = graphY - graphH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); - cr->arc (x, y, RADIUS * s + 0.5, 0, 2 * rtengine::RT_PI); + cr->arc (x, y, RADIUS + 0.5, 0, 2 * rtengine::RT_PI); cr->fill (); if (i == edited_point) { cr->set_source_rgb (1.0, 0.0, 0.0); - cr->set_line_width(2. * s); - cr->arc (x, y, (RADIUS + 2.) * s, 0, 2 * rtengine::RT_PI); + cr->set_line_width(2.); + cr->arc (x, y, RADIUS + 2., 0, 2 * rtengine::RT_PI); cr->stroke(); - cr->set_line_width(1. * s); + cr->set_line_width(1.); } } @@ -524,30 +511,14 @@ void MyFlatCurve::draw () graphW * minDistanceY); cr->fill(); } - - setDirty(false); - queue_draw(); } bool MyFlatCurve::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Gtk::Allocation allocation = get_allocation(); - allocation.set_x(0); - allocation.set_y(0); + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(cr); - const int s = RTScalable::scalePixelSize(1); - - // setDrawRectangle will allocate the backbuffer Surface - if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) { - setDirty(true); - - if (prevGraphW > (GRAPH_SIZE * s) || graphW > (GRAPH_SIZE * s)) { - curveIsDirty = true; - } - } - - draw (); - copySurface(cr); return false; } @@ -619,10 +590,8 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) return false; } - const double s = RTScalable::scalePixelSize(1.); - - minDistanceX = double(MIN_DISTANCE) / graphW * s; - minDistanceY = double(MIN_DISTANCE) / graphH * s; + minDistanceX = double(MIN_DISTANCE) / graphW; + minDistanceY = double(MIN_DISTANCE) / graphH; switch (event->type) { @@ -680,8 +649,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) curve.rightTangent.at(closest_point) = 0.35; curveIsDirty = true; - setDirty(true); - draw (); + queue_draw(); notifyListener (); lit_point = closest_point; @@ -738,8 +706,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) new_type = CSArrow; tanHandlesDisplayed = false; edited_point = lit_point; - setDirty(true); - draw (); + queue_draw(); std::vector newBoundaries(4); int size = curve.x.size(); @@ -787,8 +754,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) // the cursor is close to an existing point if (lit_point != edited_point) { edited_point = lit_point; - setDirty(true); - draw (); + queue_draw(); std::vector newBoundaries(4); int size = curve.x.size(); @@ -910,8 +876,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) break; } - setDirty(true); - draw (); + queue_draw(); retval = true; //notifyListener (); } @@ -1042,8 +1007,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) } if ((lit_point != previous_lit_point) || (prevArea != area)) { - setDirty(true); - draw (); + queue_draw(); } if (coordinateAdjuster->is_visible() && edited_point == -1) { @@ -1121,8 +1085,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) if (curve.leftTangent.at(lit_point) != prevValue) { curveIsDirty = true; - setDirty(true); - draw (); + queue_draw(); notifyListener (); if (coordinateAdjuster->is_visible()) { @@ -1153,8 +1116,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) if (curve.rightTangent.at(lit_point) != prevValue) { curveIsDirty = true; - setDirty(true); - draw (); + queue_draw(); notifyListener (); editedPos.at(3) = curve.rightTangent.at(lit_point); coordinateAdjuster->setPos(editedPos); @@ -1198,8 +1160,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) lit_point = -1; tanHandlesDisplayed = false; pipetteR = pipetteG = pipetteB = -1.f; - setDirty(true); - draw (); + queue_draw(); } retval = true; @@ -1290,11 +1251,10 @@ void MyFlatCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, if (edited_point == -1) { if (editedHandle == FCT_EditedHandle_None && lit_point != previous_lit_point) { - setDirty(true); - draw (); + queue_draw(); } } else { - draw(); + queue_draw(); } if (edited_point == -1) { @@ -1321,13 +1281,11 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier // hide the tangent handles tanHandlesDisplayed = false; - const int s = RTScalable::scalePixelSize(1); - // Action on BUTTON_PRESS and no edited point switch (area) { case (FCT_Area_Insertion): { - rtengine::FlatCurve rtCurve(getPoints(), true, GRAPH_SIZE * s); + rtengine::FlatCurve rtCurve(getPoints(), true, GRAPH_SIZE); std::vector::iterator itx, ity, itlt, itrt; int num = (int)curve.x.size(); @@ -1364,8 +1322,7 @@ bool MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifier curve.rightTangent.at(closest_point) = 0.35; curveIsDirty = true; - setDirty(true); - draw (); + queue_draw(); notifyListener (); lit_point = closest_point; @@ -1407,8 +1364,7 @@ void MyFlatCurve::pipetteButton1Released(EditDataProvider *provider) getCursorPosition(Gdk::EventType(Gdk::BUTTON_PRESS), false, px, graphY, Gdk::ModifierType(0)); getMouseOverArea(); - setDirty(true); - draw (); + queue_draw(); //notifyListener (); } @@ -1633,8 +1589,7 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY, bool pipetteDrag) if (curve.x.at(lit_point) != prevPosX || curve.y.at(lit_point) != prevPosY) { // we recompute the curve only if we have to curveIsDirty = true; - setDirty(true); - draw (); + queue_draw(); notifyListener (); } } @@ -1842,7 +1797,6 @@ void MyFlatCurve::setPoints (const std::vector& p) } curveIsDirty = true; - setDirty(true); queue_draw (); } @@ -1869,8 +1823,7 @@ void MyFlatCurve::setPos(double pos, int chanIdx) } curveIsDirty = true; - setDirty(true); - draw(); + queue_draw(); notifyListener (); } @@ -1880,8 +1833,7 @@ void MyFlatCurve::stopNumericalAdjustment() edited_point = lit_point = -1; area = FCT_Area_None; coordinateAdjuster->stopNumericalAdjustment(); - setDirty(true); - draw(); + queue_draw(); } } @@ -1904,8 +1856,7 @@ void MyFlatCurve::updateLocallabBackground(double ref) return false; } - mcih->clearPixmap(); - mcih->myCurve->queue_draw(); + mcih->clearPixmap(); --mcih->pending; @@ -1918,7 +1869,7 @@ void MyFlatCurve::setType (FlatCurveType t) { curve.type = t; - setDirty(true); + queue_draw(); } void MyFlatCurve::reset(const std::vector &resetCurve, double identityValue) @@ -1946,8 +1897,7 @@ void MyFlatCurve::reset(const std::vector &resetCurve, double identityVa break; } - setDirty(true); - draw(); + queue_draw(); } void MyFlatCurve::defaultCurve (double iVal) diff --git a/rtgui/myflatcurve.h b/rtgui/myflatcurve.h index f51586567..18d284e7e 100644 --- a/rtgui/myflatcurve.h +++ b/rtgui/myflatcurve.h @@ -99,7 +99,7 @@ protected: enum MouseOverAreas area; double locallabRef; // Locallab reference value to display in the background - void draw (); + void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr); void movePoint(bool moveX, bool moveY, bool pipetteDrag = false); void defaultCurve (double iVal = 0.5); void interpolate (); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index 021c09914..2271f7cd5 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -112,64 +112,46 @@ void SHCSelector::on_realize() add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); } -void SHCSelector::updateBackBuffer() +void SHCSelector::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr) { - if (!get_realized() || !isDirty() || !get_width() || !get_height()) { + if (!get_realized() || !get_width() || !get_height()) { return; } - // This will create or update the size of the BackBuffer::surface - setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, get_width(), get_height(), true); - - if (!surface) { - return; - } - - Cairo::RefPtr cr = Cairo::Context::create(surface); Glib::RefPtr style = get_style_context(); - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); + // Setup drawing cr->set_operator (Cairo::OPERATOR_OVER); - int w = get_width () - leftMargin - rightMargin; - int h = get_height (); + // Get drawing area size + const int w = get_width () - leftMargin - rightMargin; + const int h = get_height (); - const double s = RTScalable::scalePixelSize(1.); + // Compute slider parameters + wslider = static_cast(std::max(h / 5, 10)); + const double hwslider = wslider / 2.; - wslider = (double)std::max(h / 5, 10) * s; - double hwslider = wslider / 2.; - - // clear bg - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); - cr->set_operator (Cairo::OPERATOR_OVER); - - - // set the box's colors - cr->set_line_width (1.0 * s); + // Set the box's colors + cr->set_line_width (1.0); cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); cr->set_line_cap(Cairo::LINE_CAP_BUTT); - int coloredBarHeight = (int)((double)h * 5.5 / 7. + 0.5); + int coloredBarHeight = static_cast(static_cast(h) * 5.5 / 7. + 0.5); if (is_sensitive() && coloredBar.canGetColors()) { - // gradient background - - // this will eventually create/update the off-screen BackBuffer - coloredBar.setDrawRectangle(leftMargin + 1 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s); - // that we're displaying here - coloredBar.expose(*this, cr); + // Gradient background + coloredBar.setColoredBarSize(leftMargin + 1, 1, w - 2, coloredBarHeight - 2); + coloredBar.updateColoredBar(cr); } else { - style->render_background(cr, leftMargin + 1 * (int)s, 1 * (int)s, w - 2 * (int)s, coloredBarHeight - 2 * (int)s); + // Style background + style->render_background(cr, leftMargin + 1, 1, w - 2, coloredBarHeight - 2); } - // draw the box's borders + + // Draw the box's borders style->render_frame(cr, leftMargin, 0, w, coloredBarHeight); - // draw sliders + // Draw sliders for (int i = 0; i < 3; i++) { if (i == movingPosition) { style->set_state(Gtk::STATE_FLAG_ACTIVE); @@ -180,11 +162,16 @@ void SHCSelector::updateBackBuffer() style->set_state(Gtk::STATE_FLAG_NORMAL); } - style->render_slider(cr, (double)leftMargin + 1. * s + ((double)w - 2. * s) * positions[i] - (double)hwslider, (double)vb * s, wslider, (double)h - (double)vb * s, Gtk::ORIENTATION_VERTICAL); + style->render_slider(cr, + static_cast(leftMargin) + 1. + (static_cast(w) - 2.) * positions[i] - static_cast(hwslider), + static_cast(vb), + wslider, + static_cast(h) - static_cast(vb), + Gtk::ORIENTATION_VERTICAL); style->set_state(Gtk::STATE_FLAG_NORMAL); } - // draw text for the slider that is being moved + // Draw text for the slider that is being moved if (movingPosition >= 0) { int i = movingPosition; int offset; @@ -193,7 +180,7 @@ void SHCSelector::updateBackBuffer() Glib::RefPtr context = get_pango_context () ; Pango::FontDescription fontd(get_style_context()->get_font()); - // update font + // Update font fontd.set_weight (Pango::WEIGHT_NORMAL); const double fontSize = static_cast(h) * 0.8; // pt @@ -213,17 +200,17 @@ void SHCSelector::updateBackBuffer() 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 * (int)s - hwslider : 1 * (int)s + hwslider; + offset = positions[i] > 0.5 ? -layout_width - 1 - hwslider : 1 + hwslider; cr->set_source_rgb (0., 0., 0.); - cr->set_line_width(3. * s); + cr->set_line_width(3.); cr->set_line_join(Cairo::LINE_JOIN_ROUND); cr->set_line_cap(Cairo::LINE_CAP_ROUND); - cr->move_to ((double)leftMargin + (double)w * positions[i] + (double)offset, 0.); + cr->move_to (static_cast(leftMargin) + static_cast(w) * positions[i] + static_cast(offset), 0.); layout->add_to_cairo_context (cr); cr->stroke_preserve(); - cr->set_line_width(0.5 * s); + cr->set_line_width(0.5); cr->set_source_rgb (1., 1., 1.); cr->fill (); } @@ -231,17 +218,9 @@ void SHCSelector::updateBackBuffer() bool SHCSelector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - - // on_realize & updateBackBuffer have to be called before - if (get_realized() && get_width() && get_height()) { - if (isDirty()) { - updateBackBuffer(); - } - - if (surface) { - copySurface(cr); - } - } + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(cr); return true; } @@ -250,14 +229,12 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event) { // check if a slider is under the cursor - double w = double(get_width () - leftMargin - rightMargin); + const double w = static_cast(get_width () - leftMargin - rightMargin); movingPosition = -1; - const double s = RTScalable::scalePixelSize(1.); - for (int i = 0; i < 3; i++) { - double currPos = double(leftMargin) + 1. * s + (w - 2. * s) * positions[i]; - double hwslider = wslider / 2.; + const double currPos = static_cast(leftMargin) + 1. + (w - 2.) * positions[i]; + const double hwslider = wslider / 2.; if (event->x >= currPos - hwslider && event->x <= currPos + hwslider) { movingPosition = i; tmpX = event->x; @@ -299,8 +276,7 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) { if (movingPosition >= 0) { - const double s = RTScalable::scalePixelSize(1.); - double innerw = double(get_width () - leftMargin - rightMargin) - 2. * s; + const double innerw = static_cast(get_width () - leftMargin - rightMargin) - 2.; positions[movingPosition] = tmpPos + (event->x - tmpX) / innerw; if (positions[movingPosition] < 0) { @@ -323,7 +299,6 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) cl->shcChanged (); } - setDirty(true); queue_draw (); } @@ -333,7 +308,6 @@ bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) void SHCSelector::styleChanged (const Glib::RefPtr& style) { - setDirty(true); queue_draw (); } @@ -347,7 +321,6 @@ bool SHCSelector::reset () // : movingPosition(-1), cl(NULL) { positions[0] = defaults[0]; positions[1] = defaults[1]; positions[2] = defaults[2]; - setDirty(true); queue_draw (); return true; } @@ -357,7 +330,6 @@ bool SHCSelector::reset () // : movingPosition(-1), cl(NULL) { 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 index 2422fdf56..bac1920fe 100644 --- a/rtgui/shcselector.h +++ b/rtgui/shcselector.h @@ -29,7 +29,7 @@ public: virtual void shcChanged() = 0; }; -class SHCSelector final : public Gtk::DrawingArea, BackBuffer +class SHCSelector final : public Gtk::DrawingArea { protected: @@ -61,7 +61,7 @@ protected: bool on_button_press_event (GdkEventButton* event) override; bool on_button_release_event (GdkEventButton* event) override; bool on_motion_notify_event (GdkEventMotion* event) override; - void updateBackBuffer(); + void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr); public: diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index 62694d086..53c1b33af 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -148,7 +148,6 @@ void ThresholdSelector::initValues () set_name("ThresholdSelector"); set_can_focus(false); set_app_paintable(true); - setDirty(true); updateTooltip(); } @@ -198,7 +197,7 @@ void ThresholdSelector::setPositions (double bottom, double top) setPositions(bottom, top, maxValBottom, maxValTop); if (updatePolicy == RTUP_DYNAMIC) { - setDirty(true); + queue_draw(); } } @@ -216,10 +215,6 @@ void ThresholdSelector::setPositions (double bottomLeft, double topLeft, double positions[TS_TOPRIGHT] = topRight; if (different) { - if (updatePolicy == RTUP_DYNAMIC) { - setDirty(true); - } - sig_val_changed.emit(); updateTooltip(); queue_draw (); @@ -246,75 +241,58 @@ void ThresholdSelector::setDefaults (double bottomLeft, double topLeft, double b void ThresholdSelector::on_realize() { - Gtk::DrawingArea::on_realize(); add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::LEAVE_NOTIFY_MASK); } -void ThresholdSelector::updateBackBuffer() +void ThresholdSelector::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr) { - - if (!get_realized() || !isDirty() || !get_allocated_width() || !get_allocated_height()) { + // on_realize has to be called before + if (!get_realized() || !get_allocated_width() || !get_allocated_height()) { return; } - // This will create or update the size of the BackBuffer::surface - setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, get_allocated_width(), get_allocated_height(), true); + // Get border padding + const Glib::RefPtr style = get_style_context(); + Gtk::Border padding = getPadding(style); - if (!surface) { - return; - } - - Cairo::RefPtr cr = Cairo::Context::create(surface); - Glib::RefPtr style = get_style_context(); - Gtk::Border padding = getPadding(style); // already scaled - - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); + // Setup drawing cr->set_operator (Cairo::OPERATOR_OVER); - const double s = RTScalable::scalePixelSize(1.); + // Get widget size + const int w = get_allocated_width (); + const int h = get_allocated_height (); - double positions01[4]; - int w = get_allocated_width (); - int h = get_allocated_height (); + // Compute slider parameters + const double wslider = sliderWidth; // constant must be an odd value + const double hwslider = wslider / 2.; + const double verticalSliderPadding = std::floor((static_cast(h) - static_cast(padding.get_top()) - static_cast(padding.get_bottom())) * verticalSliderPaddingFactor + 0.5); + // Get threshold selector positions + const double positions01[4] = {to01(TS_BOTTOMLEFT), to01(TS_TOPLEFT), to01(TS_BOTTOMRIGHT), to01(TS_TOPRIGHT)}; - double wslider = sliderWidth * s; // constant must be an odd value - double hwslider = wslider / 2.; - double verticalSliderPadding = std::floor(((double)h - (double)padding.get_top() - (double)padding.get_bottom()) * verticalSliderPaddingFactor + 0.5); + // Compute internal background position and size + const double innerBarX = static_cast(padding.get_left()) + hwslider - 0.5; + const double innerBarY = verticalSliderPadding + 1. + static_cast(padding.get_top()); + const double innerBarW = static_cast(w) - innerBarX - static_cast(padding.get_right()) - hwslider - 0.5; + const double innerBarH = static_cast(h) - innerBarY - verticalSliderPadding - 1. - static_cast(padding.get_bottom()); - positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT); - positions01[TS_TOPLEFT] = to01(TS_TOPLEFT); - positions01[TS_BOTTOMRIGHT] = to01(TS_BOTTOMRIGHT); - positions01[TS_TOPRIGHT] = to01(TS_TOPRIGHT); - - double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; - double innerBarY = verticalSliderPadding + 1. * s + (double)padding.get_top(); - double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; - double innerBarH = (double)h - innerBarY - verticalSliderPadding - 1. * s - (double)padding.get_bottom(); + // Render background (style one or colored bar one) if (is_sensitive() && coloredBar.canGetColors()) { - if (updatePolicy == RTUP_DYNAMIC) { - coloredBar.setDirty(true); - } - // this will eventually create/update the off-screen Surface for the gradient area only ! - coloredBar.setDrawRectangle(innerBarX, innerBarY, innerBarW, innerBarH); - // that we're displaying here - coloredBar.expose(*this, cr); + coloredBar.setColoredBarSize(innerBarX, innerBarY, innerBarW, innerBarH); + coloredBar.updateColoredBar(cr); } else { style->render_background(cr, innerBarX, innerBarY, innerBarW, innerBarH); } - // draw curve - - double yStart = innerBarY + innerBarH - 1. * s; - double yEnd = innerBarY + 1. * s; - double xStart = innerBarX; - double xEnd = innerBarX + innerBarW; - double iw = xEnd - xStart; - double ih = yEnd - yStart; + // Render curve + const double yStart = innerBarY + innerBarH - 1.; + const double yEnd = innerBarY + 1.; + const double xStart = innerBarX; + const double xEnd = innerBarX + innerBarW; + const double iw = xEnd - xStart; + const double ih = yEnd - yStart; if (bgCurveProvider) { @@ -390,26 +368,27 @@ void ThresholdSelector::updateBackBuffer() cr->set_line_cap(Cairo::LINE_CAP_BUTT); cr->set_line_join(Cairo::LINE_JOIN_BEVEL); + // Render surrounding curve (black) if (is_sensitive()) { - // draw surrounding curve (black) + cr->set_source_rgb (0., 0., 0.); - cr->set_line_width (4. * s); + cr->set_line_width (4.); cr->stroke_preserve(); } - // draw inner curve (white) + // Render inner curve (white) if (is_sensitive()) { cr->set_source_rgb (1., 1., 1.); } else { cr->set_source_rgba (0., 0., 0., 0.5); } - cr->set_line_width (2. * s); + cr->set_line_width (2.); cr->stroke (); - // draw the box's borders - style->render_frame(cr, innerBarX - 1. * s, innerBarY - 1. * s, innerBarW + 2. * s, innerBarH + 2. * s); + // Render the box's borders + style->render_frame(cr, innerBarX - 1., innerBarY - 1., innerBarW + 2., innerBarH + 2.); - // draw sliders + // Render sliders Gtk::StateFlags currState = style->get_state(); cr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL); @@ -426,9 +405,9 @@ void ThresholdSelector::updateBackBuffer() style->set_state(Gtk::STATE_FLAG_NORMAL); } - double posX = xStart + iw * positions01[i]; - double arrowY = i == 0 || i == 2 ? yStart - 3. * s : yEnd + 3. * s; - double baseY = i == 0 || i == 2 ? (double)h - (double)padding.get_bottom() - 0.5 * s : (double)padding.get_top() + 0.5 * s; + const double posX = xStart + iw * positions01[i]; + const double arrowY = i == 0 || i == 2 ? yStart - 3. : yEnd + 3.; + const double baseY = i == 0 || i == 2 ? static_cast(h) - static_cast(padding.get_bottom()) - 0.5 : static_cast(padding.get_top()) + 0.5; style->render_slider(cr, posX - hwslider, i == 0 || i == 2 ? arrowY : baseY, wslider, i == 0 || i == 2 ? baseY - arrowY : arrowY - baseY, Gtk::ORIENTATION_HORIZONTAL); } @@ -438,17 +417,9 @@ void ThresholdSelector::updateBackBuffer() bool ThresholdSelector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - - // on_realize & updateBackBuffer have to be called before - if (get_realized() && get_allocated_width() && get_allocated_height()) { - if (isDirty()) { - updateBackBuffer(); - } - - if (surface) { - copySurface(cr); - } - } + // Draw drawing area + // Note: As drawing area surface is updated inside on_draw function, hidpi is automatically supported + updateDrawingArea(cr); return true; } @@ -494,21 +465,19 @@ bool ThresholdSelector::on_leave_notify_event (GdkEventCrossing* event) bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) { + const int w = get_allocated_width (); + const Glib::RefPtr style = get_style_context(); + const Gtk::Border padding = getPadding(style); - int w = get_allocated_width (); - Glib::RefPtr style = get_style_context(); - Gtk::Border padding = getPadding(style); // already scaled + const double wslider = sliderWidth; // constant must be an odd value + const double hwslider = wslider / 2.; - const double s = RTScalable::scalePixelSize(1.); - double wslider = sliderWidth * s; // constant must be an odd value - double hwslider = wslider / 2.; + const double innerBarX = static_cast(padding.get_left()) + hwslider - 0.5; + const double innerBarW = static_cast(w) - innerBarX - static_cast(padding.get_right()) - hwslider - 0.5; - double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; - double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; - - double xStart = innerBarX + 0.5 * s; - double xEnd = innerBarX + innerBarW - 0.5 * s; - double iw = xEnd - xStart; + const double xStart = innerBarX + 0.5; + const double xEnd = innerBarX + innerBarW - 0.5; + const double iw = xEnd - xStart; findLitCursor(event->x, event->y); @@ -556,11 +525,6 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) // set the new reference value for the next move tmpX = event->x; - // ask to redraw the background - if (updatePolicy == RTUP_DYNAMIC) { - setDirty(true); - } - // update the tooltip updateTooltip(); @@ -581,27 +545,26 @@ bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) void ThresholdSelector::findLitCursor(int posX, int posY) { - int w = get_allocated_width (); - int h = get_allocated_height (); - Glib::RefPtr style = get_style_context(); - Gtk::Border padding = getPadding(style); // already scaled + const int w = get_allocated_width (); + const int h = get_allocated_height (); + const Glib::RefPtr style = get_style_context(); + const Gtk::Border padding = getPadding(style); - const double s = RTScalable::scalePixelSize(1.); - double wslider = sliderWidth * s; // constant must be an odd value - double hwslider = wslider / 2.; + const double wslider = sliderWidth; // constant must be an odd value + const double hwslider = wslider / 2.; - double innerBarX = (double)padding.get_left() + hwslider - 0.5 * s; - double innerBarW = (double)w - innerBarX - (double)padding.get_right() - hwslider - 0.5 * s; + const double innerBarX = static_cast(padding.get_left()) + hwslider - 0.5; + const double innerBarW = static_cast(w) - innerBarX - static_cast(padding.get_right()) - hwslider - 0.5; litCursor = TS_UNDEFINED; if (posY >= 0 && posY <= h / 2) { - if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) { + if (posX >= static_cast(innerBarX - hwslider) && posX <= static_cast(innerBarX + innerBarW + hwslider)) { 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 = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; + const double cursorX = (static_cast(posX) - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; if (cursorX > positions[TS_TOPRIGHT] || std::fabs(cursorX - positions[TS_TOPRIGHT]) < std::fabs(cursorX - positions[TS_TOPLEFT])) { litCursor = TS_TOPRIGHT; @@ -609,12 +572,12 @@ void ThresholdSelector::findLitCursor(int posX, int posY) } } } else if (posY > h / 2 && posY < h) { - if (posX >= (int)(innerBarX - hwslider) && posX <= (int)(innerBarX + innerBarW + hwslider)) { + if (posX >= static_cast(innerBarX - hwslider) && posX <= static_cast(innerBarX + innerBarW + hwslider)) { 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 = ((double)posX - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; + double cursorX = (static_cast(posX) - innerBarX) * (maxValTop - minValTop) / innerBarW + minValTop; if (cursorX > positions[TS_BOTTOMRIGHT] || std::fabs(cursorX - positions[TS_BOTTOMRIGHT]) < std::fabs(cursorX - positions[TS_BOTTOMLEFT])) { litCursor = TS_BOTTOMRIGHT; @@ -728,10 +691,6 @@ void ThresholdSelector::reset () positions[2] = defPos[2]; positions[3] = defPos[3]; - if (updatePolicy == RTUP_DYNAMIC) { - setDirty(true); - } - updateTooltip(); queue_draw (); } diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h index bf1d7c952..55ccce758 100644 --- a/rtgui/thresholdselector.h +++ b/rtgui/thresholdselector.h @@ -21,7 +21,6 @@ #include #include "coloredbar.h" -#include "guiutils.h" #include "../rtengine/procparams.h" @@ -61,7 +60,7 @@ public: * have to provide through the ThresholdCurveProvider interface * */ -class ThresholdSelector : public Gtk::DrawingArea, public BackBuffer +class ThresholdSelector : public Gtk::DrawingArea { public: @@ -109,16 +108,20 @@ protected: void findSecondaryMovedCursor(guint state); void findBoundaries(double &min, double &max); double to01(ThreshCursorId cursorId); + + // Internal drawing functions void updateTooltip(); - void updateBackBuffer(); + void updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr); + + // GtkDrawingArea override functions + void on_realize () override; + bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; Gtk::SizeRequestMode get_request_mode_vfunc () const override; void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const final; void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const final; void get_preferred_height_for_width_vfunc (int width, int &minimum_height, int &natural_height) const final; void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const final; - void on_realize () override; - bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; bool on_button_press_event (GdkEventButton* event) override; bool on_button_release_event (GdkEventButton* event) override; bool on_motion_notify_event (GdkEventMotion* event) override; From 0b67f1b7b42eab16f27a4a9f3aab3387068c4b29 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Tue, 27 Dec 2022 15:59:30 +0100 Subject: [PATCH 017/291] Add hidpi support for LabGrid --- rtgui/labgrid.cc | 508 ++++++++++++++++++++++------------------------- rtgui/labgrid.h | 12 +- 2 files changed, 238 insertions(+), 282 deletions(-) diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index fc34fb53a..0773b85c9 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -172,297 +172,254 @@ void LabGridArea::setListener(ToolPanelListener *l) void LabGridArea::on_style_updated () { - setDirty(true); queue_draw (); } -bool LabGridArea::on_draw(const ::Cairo::RefPtr &crf) +bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) { - Gtk::Allocation allocation = get_allocation(); - allocation.set_x(0); - allocation.set_y(0); - - // setDrawRectangle will allocate the backbuffer Surface - if (setDrawRectangle(Cairo::FORMAT_ARGB32, allocation)) { - setDirty(true); - } - - if (!isDirty() || !surfaceCreated()) { + // Do not update drawing area if widget is not realized + if (!get_realized()) { return true; } Glib::RefPtr style = get_style_context(); - Gtk::Border padding = getPadding(style); // already scaled - Cairo::RefPtr cr = getContext(); + Gtk::Border padding = getPadding(style); + // Retrieve drawing area size + Gtk::Allocation allocation = get_allocation(); + allocation.set_x(0); + allocation.set_y(0); + int width = allocation.get_width(); + int height = allocation.get_height(); - if (isDirty()) { - int width = allocation.get_width(); - int height = allocation.get_height(); + // Setup drawing + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + cr->set_operator (Cairo::OPERATOR_OVER); - const double s = RTScalable::scalePixelSize(1.); + // Render background + style->render_background(cr, + static_cast(inset + padding.get_left()) - 1., + static_cast(inset + padding.get_top()) - 1., + static_cast(width - 2 * inset - padding.get_right() - padding.get_left()) + 2., + static_cast(height - 2 * inset - padding.get_top() - padding.get_bottom()) + 2. + ); - cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + // Drawing the cells + cr->translate(static_cast(inset + padding.get_left()), + static_cast(inset + padding.get_top())); + cr->set_antialias(Cairo::ANTIALIAS_NONE); + width -= 2 * inset + padding.get_right() + padding.get_left(); + height -= 2 * inset + padding.get_top() + padding.get_bottom(); - // clear background - cr->set_source_rgba (0., 0., 0., 0.); - cr->set_operator (Cairo::OPERATOR_CLEAR); - cr->paint (); - cr->set_operator (Cairo::OPERATOR_OVER); - style->render_background(cr, - (int)(inset * s + padding.get_left() - s + 0.5), - (int)(inset * s + padding.get_top() - s + 0.5), - (int)(width - 2 * inset * s - padding.get_right() - padding.get_left() + 2 * s + 0.5), - (int)(height - 2 * inset * s - padding.get_top() - padding.get_bottom() + 2 * s + 0.5) - ); + // flip y: + cr->translate(0., static_cast(height)); + cr->scale(1., -1.); - // drawing the cells - cr->translate((int)(inset * s + padding.get_left() + 0.5), - (int)(inset * s + padding.get_top() + 0.5)); - cr->set_antialias(Cairo::ANTIALIAS_NONE); - width -= (int)(2 * inset * s + 0.5) + padding.get_right() + padding.get_left(); - height -= (int)(2 * inset * s + 0.5) + padding.get_top() + padding.get_bottom(); - - // flip y: - cr->translate(0, height); - cr->scale(1., -1.); - - if (! ciexy_enabled) {//draw cells for Labgrid - int cells = 8; - float step = 12000.f / float(cells/2); - double cellW = double(width) / double(cells); - double cellH = double(height) / double(cells); - double cellYMin = 0.; - double cellYMax = std::floor(cellH); - for (int j = 0; j < cells; j++) { - double cellXMin = 0.; - double cellXMax = std::floor(cellW); - for (int i = 0; i < cells; i++) { - float R, G, B; - float x, y, z; - int ii = i - cells/2; - int jj = j - cells/2; - float a = step * (ii + 0.5f); - float b = step * (jj + 0.5f); - Color::Lab2XYZ(25000.f, a, b, x, y, z); - Color::xyz2srgb(x, y, z, R, G, B); - cr->set_source_rgb(R / 65535.f, G / 65535.f, B / 65535.f); - cr->rectangle( - cellXMin, - cellYMin, - cellXMax - cellXMin - (i == cells-1 ? 0. : double(s)), - cellYMax - cellYMin - (j == cells-1 ? 0. : double(s)) - ); - cellXMin = cellXMax; - cellXMax = std::floor(cellW * double(i+2) + 0.01); - cr->fill(); - } - cellYMin = cellYMax; - cellYMax = std::floor(cellH * double(j+2) + 0.01); - } - } else {//cells for CIE xy - int cells = 600; - float step = 1.f / float(cells); - double cellW = double(width) / double(cells); - double cellH = double(height) / double(cells); - double cellYMin = 0.; - double cellYMax = std::floor(cellH); - //various approximations to simulate Ciexy curves graph - // this graph is not accurate...I replace curve by polygon or parabolic - float xa = 0.2653f / (0.7347f - 0.17f); - float xb = -0.17f * xa; - //linear values - // float ax = (0.1f - 0.6f) / 0.08f; - // float bx = 0.6f; - // float ax0 = -0.1f / (0.17f - 0.08f); - // float bx0 = -0.17f* ax0; - float axs = (0.2653f - 0.65f) / (0.7347f - 0.35f); - float bxs = 0.65f - axs * 0.35f; - // float axss = (0.7f - 0.83f) / (0.3f - 0.1f); - // float bxss = 0.7f - 0.3f * axss; - //float bxsss = 0.65f; - //float axsss = (0.83f - bxsss) / 0.05f; - //float bx4s = 0.83f; - float ay = 0.4f; - float by = 0.4f; - for (int j = 0; j < cells; j++) { - double cellXMin = 0.; - double cellXMax = std::floor(cellW); - for (int i = 0; i < cells; i++) { - float R, G, B; - float XX, YY, ZZ; - float x = 1.1f * step * i - 0.1f;//Graph CIExy with -0.1 to 1 - must be enough - float y = 1.1f * step * j - 0.1;//Graph CIExy with -0.1 to 1 - must be enough - if(y > 0.5f) { - YY = 0.6f; - } else { - YY = ay * y + by; - } - XX = (x * YY) / y; - ZZ = ((1.f - x - y)* YY) / y; - float yr = xa * x + xb; - // float y0 = ax0 * x + bx0; - // float y1 = ax * x + bx; - float y2 = axs * x + bxs; - // float y3 = axss * x + bxss; - // float y4 = axsss * x + bxsss; - // float y5 = bx4s; - float y6 = 22.52f * x * x - 7.652f * x + 0.65f;//parabolic passing in x=0.17 y=0 - x=0.1 y =0.11 - x=0 y= 0.65 - float y3 = -1.266666f * x * x -0.170002f * x + 0.859686f;//other parabolic for green passing in x=0.35 y=0.65 - x=0.20 y=0.775 - x=0.1 y=0.83 - float y4 = -60.71428f * x * x + 6.821428f * x + 0.65f;//other parabolic x=0 y=0.65 - x=0.03 y=0.8 - x=0.07 y=0.83 - //small difference in the connection of the 2 last parabolic - - Color::xyz2srgb(XX, YY, ZZ, R, G, B); - //replace color by gray - if(y < yr && x > 0.17f) { - R = 0.7f; G = 0.7f; B = 0.7f; - } - /* - if(y < y0 && x <= 0.17f && x >= 0.08f) { - R = 0.7f; G = 0.7f; B = 0.7f; - } - if(y < y1 && x < 0.08f) { - R = 0.7f; G = 0.7f; B = 0.7f; - } - */ - if(y < y6 && y < 0.65f && x < 0.17f) { - R = 0.7f; G = 0.7f; B = 0.7f; - } - - if(y > y2 && x > 0.35f) {//0.35 - R = 0.7f; G = 0.7f; B = 0.7f; - } - if(y > y3 && x <= 0.35f && x > 0.06f) {//0.35 - R = 0.7f; G = 0.7f; B = 0.7f; - } - if(y > y4 && x <= 0.06f) { - R = 0.7f; G = 0.7f; B = 0.7f; - } - // if(y > y5 && x >= 0.07f && x <= 0.1f) { - // R = 0.7f; G = 0.7f; B = 0.7f; - // } - - cr->set_source_rgb(R , G , B); - - cr->rectangle( - cellXMin, - cellYMin, - cellXMax - cellXMin - (i == cells-1 ? 0. : 0.f * double(s)), - cellYMax - cellYMin - (j == cells-1 ? 0. : 0.f * double(s)) - ); - cellXMin = cellXMax; - cellXMax = std::floor(cellW * double(i+2) + 0.001); - cr->fill(); - } - cellYMin = cellYMax; - cellYMax = std::floor(cellH * double(j+2) + 0.001); + if (! ciexy_enabled) {//draw cells for Labgrid + const int cells = 8; + const float step = 12000.f / static_cast(cells/2); + const double cellW = static_cast(width) / static_cast(cells); + const double cellH = static_cast(height) / static_cast(cells); + double cellYMin = 0.; + double cellYMax = std::floor(cellH); + for (int j = 0; j < cells; j++) { + double cellXMin = 0.; + double cellXMax = std::floor(cellW); + for (int i = 0; i < cells; i++) { + float R, G, B; + float x, y, z; + const int ii = i - cells/2; + const int jj = j - cells/2; + const float a = step * static_cast(ii + 0.5f); + const float b = step * static_cast(jj + 0.5f); + Color::Lab2XYZ(25000.f, a, b, x, y, z); + Color::xyz2srgb(x, y, z, R, G, B); + cr->set_source_rgb(R / 65535.f, G / 65535.f, B / 65535.f); + cr->rectangle( + cellXMin, + cellYMin, + cellXMax - cellXMin - (i == cells-1 ? 0. : 1.), + cellYMax - cellYMin - (j == cells-1 ? 0. : 1.) + ); + cellXMin = cellXMax; + cellXMax = std::floor(cellW * static_cast(i+2) + 0.01); + cr->fill(); } + cellYMin = cellYMax; + cellYMax = std::floor(cellH * static_cast(j+2) + 0.01); } - // drawing the connection line - cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); - float loa, hia, lob, hib, grx, gry, whx, why; - loa = .5 * (width + width * low_a); - hia = .5 * (width + width * high_a); - lob = .5 * (height + height * low_b); - hib = .5 * (height + height * high_b); - grx = .5 * (width + width * gre_x); - gry = .5 * (height + height * gre_y); - whx = .5 * (width + width * whi_x); - why = .5 * (height + height * whi_y); - cr->set_line_width(1.5f * double(s)); - cr->set_source_rgb(0.6, 0.6, 0.6); + } else {//cells for CIE xy + const int cells = 600; + const float step = 1.f / static_cast(cells); + const double cellW = static_cast(width) / static_cast(cells); + const double cellH = static_cast(height) / static_cast(cells); + double cellYMin = 0.; + double cellYMax = std::floor(cellH); + //various approximations to simulate Ciexy curves graph + // this graph is not accurate...I replace curve by polygon or parabolic + const float xa = 0.2653f / (0.7347f - 0.17f); + const float xb = -0.17f * xa; + //linear values + const float axs = (0.2653f - 0.65f) / (0.7347f - 0.35f); + const float bxs = 0.65f - axs * 0.35f; + const float ay = 0.4f; + const float by = 0.4f; + for (int j = 0; j < cells; j++) { + double cellXMin = 0.; + double cellXMax = std::floor(cellW); + for (int i = 0; i < cells; i++) { + float R, G, B; + float XX, YY, ZZ; + const float x = 1.1f * step * static_cast(i) - 0.1f;//Graph CIExy with -0.1 to 1 - must be enough + const float y = 1.1f * step * static_cast(j) - 0.1;//Graph CIExy with -0.1 to 1 - must be enough + if(y > 0.5f) { + YY = 0.6f; + } else { + YY = ay * y + by; + } + XX = (x * YY) / y; + ZZ = ((1.f - x - y)* YY) / y; + const float yr = xa * x + xb; + const float y2 = axs * x + bxs; + const float y6 = 22.52f * x * x - 7.652f * x + 0.65f;//parabolic passing in x=0.17 y=0 - x=0.1 y =0.11 - x=0 y= 0.65 + const float y3 = -1.266666f * x * x -0.170002f * x + 0.859686f;//other parabolic for green passing in x=0.35 y=0.65 - x=0.20 y=0.775 - x=0.1 y=0.83 + const float y4 = -60.71428f * x * x + 6.821428f * x + 0.65f;//other parabolic x=0 y=0.65 - x=0.03 y=0.8 - x=0.07 y=0.83 + //small difference in the connection of the 2 last parabolic + + Color::xyz2srgb(XX, YY, ZZ, R, G, B); + //replace color by gray + if(y < yr && x > 0.17f) { + R = 0.7f; G = 0.7f; B = 0.7f; + } + if(y < y6 && y < 0.65f && x < 0.17f) { + R = 0.7f; G = 0.7f; B = 0.7f; + } + if(y > y2 && x > 0.35f) {//0.35 + R = 0.7f; G = 0.7f; B = 0.7f; + } + if(y > y3 && x <= 0.35f && x > 0.06f) {//0.35 + R = 0.7f; G = 0.7f; B = 0.7f; + } + if(y > y4 && x <= 0.06f) { + R = 0.7f; G = 0.7f; B = 0.7f; + } + + cr->set_source_rgb(R , G , B); + cr->rectangle( + cellXMin, + cellYMin, + cellXMax - cellXMin, + cellYMax - cellYMin); + cellXMin = cellXMax; + cellXMax = std::floor(cellW * static_cast(i+2) + 0.001); + cr->fill(); + } + cellYMin = cellYMax; + cellYMax = std::floor(cellH * static_cast(j+2) + 0.001); + } + } + + // Drawing the connection line + cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); + const double loa = .5 * (static_cast(width) + static_cast(width) * low_a); + const double hia = .5 * (static_cast(width) + static_cast(width) * high_a); + const double lob = .5 * (static_cast(height) + static_cast(height) * low_b); + const double hib = .5 * (static_cast(height) + static_cast(height) * high_b); + const double grx = .5 * (static_cast(width) + static_cast(width) * gre_x); + const double gry = .5 * (static_cast(height) + static_cast(height) * gre_y); + const double whx = .5 * (static_cast(width) + static_cast(width) * whi_x); + const double why = .5 * (static_cast(height) + static_cast(height) * whi_y); + cr->set_line_width(1.5); + cr->set_source_rgb(0.6, 0.6, 0.6); + cr->move_to(loa, lob); + cr->line_to(hia, hib); + if (ciexy_enabled) { cr->move_to(loa, lob); + cr->line_to(grx, gry); + cr->move_to(grx, gry); cr->line_to(hia, hib); - if (ciexy_enabled) { - cr->move_to(loa, lob); - cr->line_to(grx, gry); - cr->move_to(grx, gry); - cr->line_to(hia, hib); + } + cr->stroke(); + + if (ciexy_enabled) { + cr->set_line_width(0.2); + cr->set_source_rgb(0.1, 0.1, 0.1); + //draw horiz and vertical lines + for(int i = 0; i < 22; i++) { + cr->move_to(0.04545 * static_cast(i * width), 0.); + cr->line_to(0.04545 * static_cast(i * width), static_cast(height)); } + for(int i = 0; i < 22; i++) { + cr->move_to(0., 0.04545 * static_cast(i * height)); + cr->line_to(static_cast(width), 0.04545 * static_cast(i * height)); + } + + cr->stroke(); + //draw abciss and ordonate + cr->set_line_width(1.); + cr->set_source_rgb(0.4, 0., 0.); + cr->move_to(0.04545 * static_cast(2 * width), 0.); + cr->line_to(0.04545 * static_cast(2 * width), static_cast(height)); + cr->move_to(0., 0.04545 * static_cast(2 * height)); + cr->line_to(static_cast(width), 0.04545 * static_cast(2 * height)); cr->stroke(); - if (ciexy_enabled) { - //to convert from / to Ciexy <=> area - // pos_area = 1.81818 * (x + 0.1) - 1 - // x = 0.55 * (pos_area + 1) - 0.1 - cr->set_line_width(0.2f * double(s)); - cr->set_source_rgb(0.1, 0.1, 0.1); - //draw horiz and vertical lines - for(int i = 0; i < 22; i++) { - cr->move_to(0.04545 * i * width, 0.); - cr->line_to(0.04545 * i * width, height); - } - for(int i = 0; i < 22; i++) { - cr->move_to(0., 0.04545 * i * height ); - cr->line_to(width, 0.04545 * i * height); - } + //draw 0 and 1 with circle and lines + cr->set_line_width(1.2); + cr->set_source_rgb(0.4, 0., 0.); + cr->arc(0.06 * static_cast(width), + 0.06 * static_cast(height), + 0.016 * static_cast(width), + 0., + 2. * rtengine::RT_PI); + cr->stroke(); + cr->set_line_width(1.5); + cr->set_source_rgb(0.4, 0., 0.); + cr->move_to(0.985 * static_cast(width), 0.08 * static_cast(height)); + cr->line_to(0.985 * static_cast(width), 0.055 * static_cast(height)); - cr->stroke(); - //draw abciss and ordonate - cr->set_line_width(1.f * double(s)); - cr->set_source_rgb(0.4, 0., 0.); - cr->move_to(0.04545 * 2 * width, 0.); - cr->line_to(0.04545 * 2 * width, height); - cr->move_to(0., 0.04545 * 2 * height ); - cr->line_to(width, 0.04545 * 2 * height); - cr->stroke(); + cr->move_to(0.07 * static_cast(width), 0.99 * static_cast(height)); + cr->line_to(0.07 * static_cast(width), 0.965 * static_cast(height)); - //draw 0 and 1 with circle and lines - cr->set_line_width(1.2f * double(s)); - cr->set_source_rgb(0.4, 0., 0.); - cr->arc(0.06 * width, 0.06 * height, 0.016 * width, 0, 2. * rtengine::RT_PI); - cr->stroke(); - cr->set_line_width(1.5f * double(s)); - cr->set_source_rgb(0.4, 0., 0.); - cr->move_to(0.985 * width, 0.08 * height); - cr->line_to(0.985 * width, 0.055 * height); + cr->stroke(); + } - cr->move_to(0.07 * width, 0.99 * height); - cr->line_to(0.07 * width, 0.965 * height); - - cr->stroke(); - - } - - - // drawing points - if (low_enabled) { - cr->set_source_rgb(0.1, 0.1, 0.1);//black for red in Ciexy - if (litPoint == LOW) { - cr->arc(loa, lob, 5 * s, 0, 2. * rtengine::RT_PI); - } else { - cr->arc(loa, lob, 3 * s, 0, 2. * rtengine::RT_PI); - } - cr->fill(); - } - - if (ciexy_enabled) { - cr->set_source_rgb(0.5, 0.5, 0.5);//gray for green - if (litPoint == GRE) { - cr->arc(grx, gry, 5 * s, 0, 2. * rtengine::RT_PI); - } else { - cr->arc(grx, gry, 3 * s, 0, 2. * rtengine::RT_PI); - } - cr->fill(); - } - - if (ciexy_enabled) {//White Point - cr->set_source_rgb(1., 1., 1.);//White - cr->arc(whx, why, 3 * s, 0, 2. * rtengine::RT_PI); - cr->fill(); - } - - cr->set_source_rgb(0.9, 0.9, 0.9);//white for blue en Ciexy - if (litPoint == HIGH) { - cr->arc(hia, hib, 5 * s, 0, 2. * rtengine::RT_PI); + // Drawing points + if (low_enabled) { + cr->set_source_rgb(0.1, 0.1, 0.1);//black for red in Ciexy + if (litPoint == LOW) { + cr->arc(loa, lob, 5., 0., 2. * rtengine::RT_PI); } else { - cr->arc(hia, hib, 3 * s, 0, 2. * rtengine::RT_PI); + cr->arc(loa, lob, 3., 0., 2. * rtengine::RT_PI); } cr->fill(); } - copySurface(crf); + if (ciexy_enabled) { + cr->set_source_rgb(0.5, 0.5, 0.5);//gray for green + if (litPoint == GRE) { + cr->arc(grx, gry, 5., 0., 2. * rtengine::RT_PI); + } else { + cr->arc(grx, gry, 3., 0., 2. * rtengine::RT_PI); + } + cr->fill(); + } + + if (ciexy_enabled) {//White Point + cr->set_source_rgb(1., 1., 1.);//White + cr->arc(whx, why, 3., 0., 2. * rtengine::RT_PI); + cr->fill(); + } + + cr->set_source_rgb(0.9, 0.9, 0.9);//white for blue en Ciexy + if (litPoint == HIGH) { + cr->arc(hia, hib, 5., 0., 2. * rtengine::RT_PI); + } else { + cr->arc(hia, hib, 3., 0., 2. * rtengine::RT_PI); + } + cr->fill(); + return false; } @@ -529,11 +486,10 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) State oldLitPoint = litPoint; - const double s = RTScalable::scalePixelSize(1.); - int width = (int)(get_allocated_width() - 2 * inset * s - padding.get_right() - padding.get_left() + 0.5); - int height = (int)(get_allocated_height() - 2 * inset * s - padding.get_top() - padding.get_bottom() + 0.5); - const float mouse_x = std::min(double(std::max(event->x - inset * s - padding.get_right(), 0.)), double(width)); - const float mouse_y = std::min(double(std::max(get_allocated_height() - 1 - event->y - inset * s - padding.get_bottom(), 0.)), double(height)); + const int width = get_allocated_width() - 2 * inset - padding.get_right() - padding.get_left(); + const int height = get_allocated_height() - 2 * inset - padding.get_top() - padding.get_bottom(); + const float mouse_x = std::min(double(std::max(event->x - inset - padding.get_right(), 0.)), double(width)); + const float mouse_y = std::min(double(std::max(get_allocated_height() - 1 - event->y - inset - padding.get_bottom(), 0.)), double(height)); const float ma = (2.f * mouse_x - width) / width; const float mb = (2.f * mouse_y - height) / height; if (isDragged) { @@ -557,12 +513,12 @@ bool LabGridArea::on_motion_notify_event(GdkEventMotion *event) queue_draw(); } else { litPoint = NONE; - float la = low_a; - float lb = low_b; - float ha = high_a; - float hb = high_b; - float gx = gre_x; - float gy = gre_y; + const float la = low_a; + const float lb = low_b; + const float ha = high_a; + const float hb = high_b; + const float gx = gre_x; + const float gy = gre_y; const float thrs = 0.05f; const float distlo = (la - ma) * (la - ma) + (lb - mb) * (lb - mb); const float disthi = (ha - ma) * (ha - ma) + (hb - mb) * (hb - mb); @@ -592,11 +548,11 @@ void LabGridArea::get_preferred_width_vfunc(int &minimum_width, int &natural_wid { Glib::RefPtr style = get_style_context(); Gtk::Border padding = getPadding(style); // already scaled - const double s = RTScalable::scalePixelSize(1.); - int p = padding.get_left() + padding.get_right(); + const int s = RTScalable::scalePixelSize(1); + const int p = padding.get_left() + padding.get_right(); - minimum_width = (int)(50 * s + p + 0.5); - natural_width = (int)(150 * s + p + 0.5); // same as GRAPH_SIZE from mycurve.h + minimum_width = 50 * s + p; + natural_width = 150 * s + p; // same as GRAPH_SIZE from mycurve.h } diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index 0ed4cdf98..d486574b4 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -1,5 +1,5 @@ /** -*- C++ -*- - * + * * This file is part of RawTherapee. * * Copyright (c) 2017 Alberto Griggio @@ -43,11 +43,11 @@ #include "toolpanel.h" -class LabGridArea final : public Gtk::DrawingArea, public BackBuffer { +class LabGridArea final : public Gtk::DrawingArea { private: rtengine::ProcEvent evt; Glib::ustring evtMsg; - + enum State { NONE, HIGH, LOW, GRE}; State litPoint; double low_a; @@ -58,7 +58,7 @@ private: double gre_y; double whi_x; double whi_y; - + double defaultLow_a; double defaultHigh_a; double defaultLow_b; @@ -96,7 +96,7 @@ public: bool ciexyEnabled() const; void setciexyEnabled(bool yes); - bool on_draw(const ::Cairo::RefPtr &crf) override; + bool on_draw(const ::Cairo::RefPtr &cr) override; void on_style_updated () override; bool on_button_press_event(GdkEventButton *event) override; bool on_button_release_event(GdkEventButton *event) override; @@ -112,7 +112,7 @@ private: LabGridArea grid; bool resetPressed(GdkEventButton *event); - + public: LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false); From 2338b8f36601e1c1fb72f5a46add6d97cb1eb86d Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 11 Mar 2023 11:03:19 +0100 Subject: [PATCH 018/291] Merge with "Beep6581/dev" 2 --- rtgui/externaleditorpreferences.cc | 7 +--- rtgui/popupcommon.h | 12 +++--- rtgui/rtimage.cc | 60 +++++++++++++++++++++++++++++- rtgui/rtimage.h | 4 ++ rtgui/toollocationpref.cc | 16 +++----- 5 files changed, 75 insertions(+), 24 deletions(-) diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index 79dac52d2..a1f6a2846 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -25,7 +25,6 @@ #include "externaleditorpreferences.h" #include "multilangmgr.h" -#include "rtimage.h" ExternalEditorPreferences::ExternalEditorPreferences(): @@ -52,12 +51,10 @@ ExternalEditorPreferences::ExternalEditorPreferences(): list_scroll_area.add(*list_view); // Toolbar buttons. - auto add_image = Gtk::manage(new RTImage("add-small.png")); - auto remove_image = Gtk::manage(new RTImage("remove-small.png")); button_add = Gtk::manage(new Gtk::Button()); button_remove = Gtk::manage(new Gtk::Button()); - button_add->set_image(*add_image); - button_remove->set_image(*remove_image); + button_add->set_image_from_icon_name("add-small"); + button_remove->set_image_from_icon_name("remove-small"); button_app_chooser = Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE"))); button_file_chooser = Gtk::manage(new Gtk::Button(M("PREFERENCES_EXTERNALEDITOR_CHANGE_FILE"))); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 9ca6b2030..cc83c4998 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -61,8 +61,8 @@ public: explicit PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); - bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); - bool insertEntry(int position, const Glib::ustring& fileName, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); + bool addEntry (const Glib::ustring& iconName, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); + bool insertEntry(int position, const Glib::ustring& iconName, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); bool insertEntry(int position, const Glib::RefPtr& gIcon, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup = nullptr); int getEntryCount () const; bool setSelected (int entryNum); @@ -78,7 +78,7 @@ private: type_signal_item_selected messageItemSelected; std::vector> imageIcons; - std::vector imageFilenames; + std::vector imageIconNames; std::vector images; Glib::ustring buttonHint; RTImage* buttonImage; @@ -90,15 +90,15 @@ private: bool hasMenu; void changeImage(int position); - void changeImage(const Glib::ustring& fileName, const Glib::RefPtr& gIcon); + void changeImage(const Glib::ustring& iconName, const Glib::RefPtr& gIcon); void entrySelected(Gtk::Widget* menuItem); - bool insertEntryImpl(int position, const Glib::ustring& fileName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup); + bool insertEntryImpl(int position, const Glib::ustring& iconName, const Glib::RefPtr& gIcon, RTImage* image, const Glib::ustring& label, Gtk::RadioButtonGroup* radioGroup); void showMenu(GdkEventButton* event); protected: virtual int posToIndex(int p) const { return p; } virtual int indexToPos(int i) const { return i; } - + void entrySelected (int i); }; diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 6096b9251..37044d1e6 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -58,7 +58,8 @@ RTImage::RTImage () {} RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) : Gtk::Image(), size(iconSize), - icon_name(iconName) + icon_name(iconName), + g_icon(Glib::RefPtr()) { // Set surface from icon cache surface = RTImageCache::getCachedSurface(this->icon_name, this->size); @@ -69,6 +70,16 @@ RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) : } } +RTImage::RTImage (const Glib::RefPtr& gIcon, const Gtk::IconSize iconSize) : + Gtk::Image(), + size(iconSize), + icon_name(""), + g_icon(Glib::RefPtr()) +{ + // Configure RTImage based on g_icon + set(this->g_icon, this->size); +} + void RTImage::set_from_icon_name(const Glib::ustring& iconName) { this->icon_name = iconName; @@ -80,6 +91,11 @@ void RTImage::set_from_icon_name(const Glib::ustring& iconName) if (surface) { set(surface->get()); } + + // Unset Gio::Icon if firstly exists + if (this->g_icon) { + g_icon = Glib::RefPtr(); + } } void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize) @@ -90,16 +106,54 @@ void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconS // Set surface from icon cache surface = RTImageCache::getCachedSurface(this->icon_name, this->size); - // Add it to the RTImage if surface exists + // Add it to the RTImage if previously chosen if (surface) { set(surface->get()); } + + // Unset Gio::Icon if previously chosen + if (this->g_icon) { + g_icon = Glib::RefPtr(); + } +} + +void RTImage::set_from_gicon(const Glib::RefPtr& gIcon) +{ + this->g_icon = gIcon; + + // Set image from Gio::Icon + set(this->g_icon, this->size); + + // Unset surface if previously chosen + this->icon_name = ""; + + if (surface) { + surface = std::shared_ptr(); + } +} + +void RTImage::set_from_gicon(const Glib::RefPtr& gIcon, const Gtk::IconSize iconSize) +{ + this->g_icon = gIcon; + this->size = iconSize; + + // Set image from Gio::Icon + set(this->g_icon, this->size); + + // Unset surface if previously chosen + this->icon_name = ""; + + if (surface) { + surface = std::shared_ptr(); + } } int RTImage::get_width() { if (surface) { return surface->getWidth(); + } else if (g_icon) { + Gtk::Image::get_width(); } return -1; @@ -109,6 +163,8 @@ int RTImage::get_height() { if (surface) { return surface->getHeight(); + } else if (g_icon) { + Gtk::Image::get_height(); } return -1; diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 0908683c8..3fe67eb8d 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -42,13 +42,17 @@ private: Gtk::IconSize size; Glib::ustring icon_name; std::shared_ptr surface; + Glib::RefPtr g_icon; public: RTImage (); explicit RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize = Gtk::ICON_SIZE_SMALL_TOOLBAR); + explicit RTImage (const Glib::RefPtr& gIcon, const Gtk::IconSize iconSize = Gtk::ICON_SIZE_SMALL_TOOLBAR); void set_from_icon_name(const Glib::ustring& iconName); void set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize); + void set_from_gicon(const Glib::RefPtr& gIcon); + void set_from_gicon(const Glib::RefPtr& gIcon, const Gtk::IconSize iconSize); int get_width(); int get_height(); diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index cf25dbc34..f6719e918 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -21,7 +21,6 @@ #include "guiutils.h" #include "options.h" -#include "rtimage.h" #include "rtscalable.h" #include "toollocationpref.h" #include "toolpanelcoord.h" @@ -277,12 +276,9 @@ ListEditButtons::ListEditButtons(Gtk::TreeView &list, Glib::RefPtrset_min_content_width( - 400 * (RTScalable::getTweakedDPI() / RTScalable::baseDPI)); + tool_list_scrolled_window->set_min_content_width(RTScalable::scalePixelSize(400)); layout_grid->attach_next_to(*tool_list_frame, Gtk::PositionType::POS_RIGHT, 1, 1); tool_list_frame->add(*tool_list_scrolled_window); tool_list_scrolled_window->add(*impl->toolListViewPtr); @@ -739,8 +734,7 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : Gtk::Box *favorites_box = Gtk::manage(new Gtk::Box()); Gtk::ScrolledWindow *favorites_list_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); - favorites_list_scrolled_window->set_min_content_width( - 300 * (RTScalable::getTweakedDPI() / RTScalable::baseDPI)); + favorites_list_scrolled_window->set_min_content_width(RTScalable::scalePixelSize(300)); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); favorites_box->pack_start(impl->favoritesListEditButtons, false, false); favorites_box->pack_start(*favorites_list_scrolled_window, false, false); From 23be310029290582bb81c1a23aab0d521eef8b7b Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 29 Apr 2023 11:06:58 +0200 Subject: [PATCH 019/291] Fixes issues following merge with 'dev' - External Editor: App icon not correctly managed in RTImage - Favorite preferences: Fixes widget sizes - Other fix: With some versions of Glib/Glibmm library on MacOS, Glib::KeyFile "load_from_file" function does not raise a Glib::Error but another exception. This causes crash opening preferences panel due to missing dynamic profiles configuration --- rtengine/dynamicprofile.cc | 6 +++++- rtgui/externaleditorpreferences.cc | 4 ++-- rtgui/rtimage.cc | 2 +- rtgui/toollocationpref.cc | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 6dbd2d0f0..2fa03f2ed 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include "rtengine.h" #include "../rtgui/options.h" @@ -173,9 +174,12 @@ bool DynamicProfileRules::loadRules() { dynamicRules.clear(); Glib::KeyFile kf; + const Glib::ustring fileName = Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"); try { - if (!kf.load_from_file (Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"))) { + if (Glib::file_test(fileName, Glib::FILE_TEST_EXISTS)) { + kf.load_from_file (fileName); + } else { return false; } } catch (Glib::Error &e) { diff --git a/rtgui/externaleditorpreferences.cc b/rtgui/externaleditorpreferences.cc index a1f6a2846..2f8755598 100644 --- a/rtgui/externaleditorpreferences.cc +++ b/rtgui/externaleditorpreferences.cc @@ -92,8 +92,8 @@ ExternalEditorPreferences::getEditors() const auto children = list_model->children(); for (auto rowIter = children.begin(); rowIter != children.end(); rowIter++) { - const Gio::Icon *const icon = rowIter->get_value(model_columns.icon).get(); - const auto &icon_serialized = icon == nullptr ? "" : icon->serialize().print(); + const auto icon = rowIter->get_value(model_columns.icon); + const auto &icon_serialized = !icon ? "" : icon->serialize().print(); editors.push_back(ExternalEditorPreferences::EditorInfo( rowIter->get_value(model_columns.name), rowIter->get_value(model_columns.command), diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 37044d1e6..9bd942c47 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -74,7 +74,7 @@ RTImage::RTImage (const Glib::RefPtr& gIcon, const Gtk::IconSiz Gtk::Image(), size(iconSize), icon_name(""), - g_icon(Glib::RefPtr()) + g_icon(gIcon) { // Configure RTImage based on g_icon set(this->g_icon, this->size); diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index f6719e918..358fe969b 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -734,7 +734,7 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : Gtk::Box *favorites_box = Gtk::manage(new Gtk::Box()); Gtk::ScrolledWindow *favorites_list_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow()); - favorites_list_scrolled_window->set_min_content_width(RTScalable::scalePixelSize(300)); + favorites_list_scrolled_window->set_min_content_width(RTScalable::scalePixelSize(400)); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); favorites_box->pack_start(impl->favoritesListEditButtons, false, false); favorites_box->pack_start(*favorites_list_scrolled_window, false, false); From 3120aea7ddf86dcaae63e8fc3275700fafab06d3 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Mon, 1 May 2023 11:18:07 +0200 Subject: [PATCH 020/291] Improves cursor hotspot location management --- rtgui/cursormanager.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 30649d707..fd777fd94 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -34,15 +34,21 @@ void CursorManager::init (Glib::RefPtr mainWindow) #endif - auto createCursor = [this] (const Glib::ustring &name, const Gdk::CursorType &fb_cursor) -> Glib::RefPtr + auto createCursor = [this] (const Glib::ustring &name, const Gdk::CursorType &fb_cursor, + const double offX = 0., const double offY = 0.) -> Glib::RefPtr { - // Gdk Cursor Theme is not supported on some OS (ex : MacOS) + // Notes: + // - Gdk Cursor Theme is not supported on some OS (ex : MacOS). // Cursor is retrieved from theme thanks to an RTSurface + // - By default, cursor hotspot is located at middle of surface. + // Use (offX, offY) between -1 and 0.99 to move cursor hotspot auto cursor_surf = RTSurface(name, Gtk::ICON_SIZE_MENU); + double offXb = std::min(std::max(-1., offX), 0.99); // offX should belong to (-1; 0.99) + double offYb = std::min(std::max(-1., offY), 0.99); // offY should belong to (-1; 0.99) auto cursor = Gdk::Cursor::create(this->display, cursor_surf.get(), - cursor_surf.getWidth(), - cursor_surf.getHeight()); + cursor_surf.getWidth() / 2 * (1. + offXb), + cursor_surf.getHeight() / 2 * (1. + offYb)); if (!cursor) { cursor = Gdk::Cursor::create(this->display, fb_cursor); @@ -52,7 +58,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) }; cAdd = createCursor("crosshair-small", Gdk::PLUS); - cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS); + cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS, -0.333, 0.75); cCropDraw = createCursor("crop-point-hicontrast", Gdk::DIAMOND_CROSS); cCrosshair = createCursor("crosshair-hicontrast", Gdk::CROSSHAIR); cEmpty = createCursor("empty", Gdk::BLANK_CURSOR); @@ -68,7 +74,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) cMoveXY = createCursor("node-move-xy-hicontrast", Gdk::FLEUR); cMoveY = createCursor("node-move-y-hicontrast", Gdk::SB_V_DOUBLE_ARROW); cRotate = createCursor("rotate-aroundnode-hicontrast", Gdk::EXCHANGE); - cWB = createCursor("color-picker-hicontrast", Gdk::TARGET); + cWB = createCursor("color-picker-hicontrast", Gdk::TARGET, -0.333, 0.75); cWait = createCursor("gears", Gdk::CLOCK); window = mainWindow; From 676ab8649bde38432907e0a29e5530fb7abd23d3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 10 Jun 2023 18:28:17 -0700 Subject: [PATCH 021/291] Add recursive sub-folder image browsing Add toggle button in the top toolbar of the file browser to activate or deactivate recursive browsing. Toggle state is saved in options. Limit recursion depth and explored directory count. --- rtdata/images/svg/folder-subfolder.svg | 98 +++++++++++++++ rtdata/languages/default | 1 + rtgui/filecatalog.cc | 159 ++++++++++++++++++------- rtgui/filecatalog.h | 14 ++- rtgui/options.cc | 18 +++ rtgui/options.h | 3 + 6 files changed, 246 insertions(+), 47 deletions(-) create mode 100644 rtdata/images/svg/folder-subfolder.svg diff --git a/rtdata/images/svg/folder-subfolder.svg b/rtdata/images/svg/folder-subfolder.svg new file mode 100644 index 000000000..f22d0da0f --- /dev/null +++ b/rtdata/images/svg/folder-subfolder.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/rtdata/languages/default b/rtdata/languages/default index 050836d21..c23410661 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -200,6 +200,7 @@ FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4-star.\nShortcut: 4 FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: 5 FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: 0 diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d6c440570..5c20aa5fe 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -19,6 +19,8 @@ */ #include "filecatalog.h" +#include +#include #include #include @@ -347,9 +349,17 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bCateg[19] = bOriginal->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bOriginal, true)); bOriginal->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); + bRecursive = Gtk::manage(new Gtk::ToggleButton()); + bRecursive->set_image(*Gtk::manage(new RTImage("folder-subfolder.png"))); + bRecursive->set_tooltip_text(M("FILEBROWSER_SHOWRECURSIVE")); + bRecursive->set_relief(Gtk::RELIEF_NONE); + bRecursive->set_active(options.browseRecursive); + bRecursive->signal_toggled().connect(sigc::mem_fun(*this, &FileCatalog::showRecursiveToggled)); + buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK); buttonBar->pack_start (*bNotTrash, Gtk::PACK_SHRINK); buttonBar->pack_start (*bOriginal, Gtk::PACK_SHRINK); + buttonBar->pack_start(*bRecursive, Gtk::PACK_SHRINK); buttonBar->pack_start (*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_SHRINK); fileBrowser->trash_changed().connect( sigc::mem_fun(*this, &FileCatalog::trashChanged) ); @@ -544,9 +554,7 @@ void FileCatalog::closeDir () exportPanel->set_sensitive (false); } - if (dirMonitor) { - dirMonitor->cancel (); - } + dirMonitors.clear(); // ignore old requests ++selectedDirectoryId; @@ -570,60 +578,73 @@ void FileCatalog::closeDir () redrawAll (); } -std::vector FileCatalog::getFileList() +std::vector FileCatalog::getFileList(std::vector> *dirs_explored) { std::vector names; const std::set& extensions = options.parsedExtensionsSet; - try { + static void (*getFilesRecursively)(const Glib::ustring &, int, int &, std::vector &, std::vector> *) = [](const Glib::ustring &dir_path, int max_depth, int &dir_quota, std::vector &file_names, std::vector> * directories_explored) { + try { - const auto dir = Gio::File::create_for_path(selectedDirectory); + const auto dir = Gio::File::create_for_path(dir_path); - auto enumerator = dir->enumerate_children("standard::name,standard::type,standard::is-hidden"); + auto enumerator = dir->enumerate_children("standard::name,standard::type,standard::is-hidden"); - while (true) { - try { - const auto file = enumerator->next_file(); - if (!file) { - break; - } + if (directories_explored) { + directories_explored->push_back(dir); + } - if (file->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { - continue; - } + while (true) { + try { + const auto file = enumerator->next_file(); + if (!file) { + break; + } - if (!options.fbShowHidden && file->is_hidden()) { - continue; - } + if (!options.fbShowHidden && file->is_hidden()) { + continue; + } - const Glib::ustring fname = file->get_name(); - const auto lastdot = fname.find_last_of('.'); + if (file->get_file_type() == Gio::FILE_TYPE_DIRECTORY) { + if (max_depth > 0 && dir_quota > 0) { + const Glib::ustring child_dir_path = Glib::build_filename(dir_path, file->get_name()); + getFilesRecursively(child_dir_path, max_depth - 1, --dir_quota, file_names, directories_explored); + } + continue; + } - if (lastdot >= fname.length() - 1) { - continue; - } + const Glib::ustring fname = file->get_name(); + const auto lastdot = fname.find_last_of('.'); - if (extensions.find(fname.substr(lastdot + 1).lowercase()) == extensions.end()) { - continue; - } + if (lastdot >= fname.length() - 1) { + continue; + } - names.push_back(Glib::build_filename(selectedDirectory, fname)); - } catch (Glib::Exception& exception) { - if (rtengine::settings->verbose) { - std::cerr << exception.what() << std::endl; + if (extensions.find(fname.substr(lastdot + 1).lowercase()) == extensions.end()) { + continue; + } + + file_names.emplace_back(Glib::build_filename(dir_path, fname)); + } catch (Glib::Exception& exception) { + if (rtengine::settings->verbose) { + std::cerr << exception.what() << std::endl; + } } } + + } catch (Glib::Exception& exception) { + + if (rtengine::settings->verbose) { + std::cerr << "Failed to list directory \"" << dir_path << "\": " << exception.what() << std::endl; + } + } + }; - } catch (Glib::Exception& exception) { - - if (rtengine::settings->verbose) { - std::cerr << "Failed to list directory \"" << selectedDirectory << "\": " << exception.what() << std::endl; - } - - } + int dirs_left = options.browseRecursive ? options.browseRecursiveMaxDirs : 0; + getFilesRecursively(selectedDirectory, options.browseRecursiveDepth, dirs_left, names, dirs_explored); return names; } @@ -649,9 +670,10 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring selectedDirectory = dir->get_parse_name(); + std::vector> allDirs; BrowsePath->set_text(selectedDirectory); buttonBrowsePath->set_image(*iRefreshWhite); - fileNameList = getFileList(); + fileNameList = getFileList(&allDirs); for (unsigned int i = 0; i < fileNameList.size(); i++) { if (openfile.empty() || fileNameList[i] != openfile) { // if we opened a file at the beginning don't add it again @@ -667,13 +689,45 @@ void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring filepanel->loadingThumbs(M("PROGRESSBAR_LOADINGTHUMBS"), 0); } - dirMonitor = dir->monitor_directory (); - dirMonitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::on_dir_changed), false)); + refreshDirectoryMonitors(allDirs); } catch (Glib::Exception& ex) { std::cout << ex.what(); } } +void FileCatalog::refreshDirectoryMonitors(const std::vector> &dirs_to_monitor) +{ + std::vector updated_dir_names; + std::transform( + dirs_to_monitor.cbegin(), dirs_to_monitor.cend(), + std::back_inserter(updated_dir_names), + [](const Glib::RefPtr &updated_dir) { return updated_dir->get_path(); }); + + // Remove monitors on directories that are no longer shown. + dirMonitors.erase( + std::remove_if(dirMonitors.begin(), dirMonitors.end(), + [&updated_dir_names](const FileMonitorInfo &fileMonitorInfo) { + return std::find(updated_dir_names.cbegin(), updated_dir_names.cend(), fileMonitorInfo.filePath) == updated_dir_names.cend(); + }), + dirMonitors.end()); + + // Add monitors that do not exist yet. + std::vector monitored_dir_names; + std::transform( + dirMonitors.cbegin(), dirMonitors.cend(), + std::back_inserter(monitored_dir_names), + [](const FileMonitorInfo &dir_monitor) { return dir_monitor.filePath; }); + for (const auto &dir_to_monitor : dirs_to_monitor) { + const auto dir_path = dir_to_monitor->get_path(); + if (std::find(monitored_dir_names.cbegin(), monitored_dir_names.cend(), dir_path) != monitored_dir_names.cend()) { + continue; // A monitor exists already. + } + auto dir_monitor = dir_to_monitor->monitor_directory(); + dir_monitor->signal_changed().connect(sigc::bind(sigc::mem_fun(*this, &FileCatalog::on_dir_changed), false)); + dirMonitors.emplace_back(dir_monitor, dir_path); + } +} + void FileCatalog::enableTabMode(bool enable) { inTabMode = enable; @@ -1581,6 +1635,12 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick } } +void FileCatalog::showRecursiveToggled() +{ + options.browseRecursive = bRecursive->get_active(); + reparseDirectory(); +} + BrowserFilter FileCatalog::getFilter () { @@ -1717,18 +1777,25 @@ void FileCatalog::reparseDirectory () // check if a thumbnailed file has been deleted const std::vector& t = fileBrowser->getEntries(); std::vector fileNamesToDel; + std::vector fileNamesToRemove; for (const auto& entry : t) { if (!Glib::file_test(entry->filename, Glib::FILE_TEST_EXISTS)) { fileNamesToDel.push_back(entry->filename); + fileNamesToRemove.push_back(entry->filename); + } + else if (!options.browseRecursive && Glib::path_get_dirname(entry->filename) != selectedDirectory) { + fileNamesToRemove.push_back(entry->filename); } } - for (const auto& toDelete : fileNamesToDel) { - delete fileBrowser->delEntry(toDelete); - cacheMgr->deleteEntry(toDelete); + for (const auto& toRemove : fileNamesToRemove) { + delete fileBrowser->delEntry(toRemove); --previewsLoaded; } + for (const auto& toDelete : fileNamesToDel) { + cacheMgr->deleteEntry(toDelete); + } if (!fileNamesToDel.empty()) { _refreshProgressBar(); @@ -1741,7 +1808,8 @@ void FileCatalog::reparseDirectory () oldNames.insert(oldName.collate_key()); } - fileNameList = getFileList(); + std::vector> allDirs; + fileNameList = getFileList(&allDirs); for (const auto& newName : fileNameList) { if (oldNames.find(newName.collate_key()) == oldNames.end()) { addFile(newName); @@ -1749,6 +1817,7 @@ void FileCatalog::reparseDirectory () } } + refreshDirectoryMonitors(allDirs); } void FileCatalog::on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal) diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 23d56af73..f41c42475 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -54,6 +54,13 @@ public: typedef sigc::slot DirSelectionSlot; private: + struct FileMonitorInfo { + FileMonitorInfo(const Glib::RefPtr &file_monitor, const Glib::ustring &file_path) : + fileMonitor(file_monitor), filePath(file_path) {} + Glib::RefPtr fileMonitor; + Glib::ustring filePath; + }; + FilePanel* filepanel; Gtk::Box* hBox; Glib::ustring selectedDirectory; @@ -95,6 +102,7 @@ private: Gtk::ToggleButton* bTrash; Gtk::ToggleButton* bNotTrash; Gtk::ToggleButton* bOriginal; + Gtk::ToggleButton* bRecursive; Gtk::ToggleButton* categoryButtons[20]; Gtk::ToggleButton* exifInfo; sigc::connection bCateg[20]; @@ -143,14 +151,15 @@ private: std::set editedFiles; guint modifierKey; // any modifiers held when rank button was pressed - Glib::RefPtr dirMonitor; + std::vector dirMonitors; IdleRegister idle_register; void addAndOpenFile (const Glib::ustring& fname); void addFile (const Glib::ustring& fName); - std::vector getFileList (); + std::vector getFileList(std::vector> *dirs_explored = nullptr); BrowserFilter getFilter (); + void refreshDirectoryMonitors(const std::vector> &dirs_to_monitor); void trashChanged (); public: @@ -240,6 +249,7 @@ public: void setExportPanel (ExportPanel* expanel); void exifInfoButtonToggled(); void categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick); + void showRecursiveToggled(); bool capture_event(GdkEventButton* event); void filterChanged (); void runFilterDialog (); diff --git a/rtgui/options.cc b/rtgui/options.cc index e89fcd647..ed6f03eb7 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -435,6 +435,9 @@ void Options::setDefaults() parseExtensionsEnabled.clear(); parsedExtensions.clear(); parsedExtensionsSet.clear(); + browseRecursive = false; + browseRecursiveDepth = 10; + browseRecursiveMaxDirs = 100; renameUseTemplates = false; renameTemplates.clear(); thumbnailZoomRatios.clear(); @@ -1342,6 +1345,18 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("File Browser", "SortDescending")) { sortDescending = keyFile.get_boolean("File Browser", "SortDescending"); } + + if (keyFile.has_key("File Browser", "BrowseRecursive")) { + browseRecursive = keyFile.get_boolean("File Browser", "BrowseRecursive"); + } + + if (keyFile.has_key("File Browser", "BrowseRecursiveDepth")) { + browseRecursiveDepth = keyFile.get_integer("File Browser", "BrowseRecursiveDepth"); + } + + if (keyFile.has_key("File Browser", "BrowseRecursiveMaxDirs")) { + browseRecursiveMaxDirs = keyFile.get_integer("File Browser", "BrowseRecursiveMaxDirs"); + } } if (keyFile.has_group("Clipping Indication")) { @@ -2410,6 +2425,9 @@ void Options::saveToFile(Glib::ustring fname) } keyFile.set_integer("File Browser", "SortMethod", sortMethod); keyFile.set_boolean("File Browser", "SortDescending", sortDescending); + keyFile.set_boolean("File Browser", "BrowseRecursive", browseRecursive); + keyFile.set_integer("File Browser", "BrowseRecursiveDepth", browseRecursiveDepth); + keyFile.set_integer("File Browser", "BrowseRecursiveMaxDirs", browseRecursiveMaxDirs); keyFile.set_integer("Clipping Indication", "HighlightThreshold", highlightThreshold); keyFile.set_integer("Clipping Indication", "ShadowThreshold", shadowThreshold); keyFile.set_boolean("Clipping Indication", "BlinkClipped", blinkClipped); diff --git a/rtgui/options.h b/rtgui/options.h index 78059357e..6380cdb56 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -315,6 +315,9 @@ public: std::vector parseExtensionsEnabled; // List of bool to retain extension or not std::vector parsedExtensions; // List containing all retained extensions (lowercase) std::set parsedExtensionsSet; // Set containing all retained extensions (lowercase) + bool browseRecursive; + int browseRecursiveDepth; + int browseRecursiveMaxDirs; std::vector tpOpen; bool autoSaveTpOpen; //std::vector crvOpen; From 660c9507cceb35c914af243ad476ce6cbf91f89f Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jun 2023 11:47:46 -0700 Subject: [PATCH 022/291] Add recursive browsing options to preferences Allow maximum recursion depth and maximum sub-directories to be configured in preferences. --- rtdata/languages/default | 2 ++ rtgui/preferences.cc | 22 ++++++++++++++++++++++ rtgui/preferences.h | 2 ++ 3 files changed, 26 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index c23410661..0b581d05d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1824,6 +1824,8 @@ PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustment PREFERENCES_BEHAVIOR;Behavior PREFERENCES_BEHSETALL;All to 'Set' PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. +PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders PREFERENCES_CACHECLEAR;Clear PREFERENCES_CACHECLEAR_ALL;Clear all cached files: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index c9737704e..025fbb3ae 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1389,6 +1389,24 @@ Gtk::Widget* Preferences::getFileBrowserPanel() maxRecentFolders->set_range(1, 25); vbro->pack_start(*hbrecent, Gtk::PACK_SHRINK, 4); + // Recursive browsing options. + Gtk::Box *hbBrowseRecursive = Gtk::manage(new Gtk::Box()); + Gtk::Label *labBrowseRecursiveDepth = Gtk::manage(new Gtk::Label(M("PREFERENCES_BROWSERECURSIVEDEPTH") + ":")); + browseRecursiveDepth = Gtk::manage(new Gtk::SpinButton()); + browseRecursiveDepth->set_digits(0); + browseRecursiveDepth->set_increments(1, 5); + browseRecursiveDepth->set_range(1, 999); + Gtk::Label *labBrowseRecursiveMaxDirs = Gtk::manage(new Gtk::Label(M("PREFERENCES_BROWSERECURSIVEMAXDIRS") + ":")); + browseRecursiveMaxDirs = Gtk::manage(new Gtk::SpinButton()); + browseRecursiveMaxDirs->set_digits(0); + browseRecursiveMaxDirs->set_increments(1, 5); + browseRecursiveMaxDirs->set_range(1, 999); + hbBrowseRecursive->pack_start(*labBrowseRecursiveDepth, Gtk::PACK_SHRINK, 4); + hbBrowseRecursive->pack_start(*browseRecursiveDepth, Gtk::PACK_SHRINK, 4); + hbBrowseRecursive->pack_start(*labBrowseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); + hbBrowseRecursive->pack_start(*browseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); + vbro->pack_start(*hbBrowseRecursive, Gtk::PACK_SHRINK, 0); + fro->add(*vbro); @@ -1864,6 +1882,8 @@ void Preferences::storePreferences() moptions.filmStripOverlayedFileNames = filmStripOverlayedFileNames->get_active(); moptions.sameThumbSize = sameThumbSize->get_active(); moptions.internalThumbIfUntouched = ckbInternalThumbIfUntouched->get_active(); + moptions.browseRecursiveDepth = static_cast(browseRecursiveDepth->get_value()); + moptions.browseRecursiveMaxDirs = static_cast(browseRecursiveMaxDirs->get_value()); auto save_where = saveParamsPreference->get_active_row_number(); moptions.saveParamsFile = save_where == 0 || save_where == 2; @@ -2089,6 +2109,8 @@ void Preferences::fillPreferences() filmStripOverlayedFileNames->set_active(moptions.filmStripOverlayedFileNames); sameThumbSize->set_active(moptions.sameThumbSize); ckbInternalThumbIfUntouched->set_active(moptions.internalThumbIfUntouched); + browseRecursiveDepth->set_value(moptions.browseRecursiveDepth); + browseRecursiveMaxDirs->set_value(moptions.browseRecursiveMaxDirs); saveParamsPreference->set_active(moptions.saveParamsFile ? (moptions.saveParamsCache ? 2 : 0) : 1); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 6e31761a4..829506894 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -194,6 +194,8 @@ class Preferences final : Gtk::CheckButton* overlayedFileNames; Gtk::CheckButton* filmStripOverlayedFileNames; Gtk::CheckButton* sameThumbSize; + Gtk::SpinButton* browseRecursiveDepth; + Gtk::SpinButton* browseRecursiveMaxDirs; Gtk::SpinButton* threadsSpinBtn; Gtk::SpinButton* clutCacheSizeSB; From eef54f0f2d7dcc51dd6bd4a2b8787a836b858a31 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jun 2023 17:22:40 -0700 Subject: [PATCH 023/291] Add option to disable symlinks in recursive browse --- rtdata/languages/default | 1 + rtgui/filecatalog.cc | 11 ++++++++++- rtgui/options.cc | 6 ++++++ rtgui/options.h | 1 + rtgui/preferences.cc | 4 ++++ rtgui/preferences.h | 1 + 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 0b581d05d..8362c1c15 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1825,6 +1825,7 @@ PREFERENCES_BEHAVIOR;Behavior PREFERENCES_BEHSETALL;All to 'Set' PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders PREFERENCES_CACHECLEAR;Clear PREFERENCES_CACHECLEAR_ALL;Clear all cached files: diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 5c20aa5fe..b01300d95 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -590,7 +590,16 @@ std::vector FileCatalog::getFileList(std::vectorenumerate_children("standard::name,standard::type,standard::is-hidden"); + static const auto enumerate_attrs = + std::string(G_FILE_ATTRIBUTE_STANDARD_NAME) + "," + + G_FILE_ATTRIBUTE_STANDARD_TYPE + "," + + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN + "," + + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET; + auto enumerator = dir->enumerate_children( + enumerate_attrs, + options.browseRecursiveFollowLinks + ? Gio::FileQueryInfoFlags::FILE_QUERY_INFO_NONE + : Gio::FileQueryInfoFlags::FILE_QUERY_INFO_NOFOLLOW_SYMLINKS); if (directories_explored) { directories_explored->push_back(dir); diff --git a/rtgui/options.cc b/rtgui/options.cc index ed6f03eb7..f8143996a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -438,6 +438,7 @@ void Options::setDefaults() browseRecursive = false; browseRecursiveDepth = 10; browseRecursiveMaxDirs = 100; + browseRecursiveFollowLinks = true; renameUseTemplates = false; renameTemplates.clear(); thumbnailZoomRatios.clear(); @@ -1357,6 +1358,10 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("File Browser", "BrowseRecursiveMaxDirs")) { browseRecursiveMaxDirs = keyFile.get_integer("File Browser", "BrowseRecursiveMaxDirs"); } + + if (keyFile.has_key("File Browser", "BrowseRecursiveFollowLinks")) { + browseRecursiveFollowLinks = keyFile.get_integer("File Browser", "BrowseRecursiveFollowLinks"); + } } if (keyFile.has_group("Clipping Indication")) { @@ -2428,6 +2433,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_boolean("File Browser", "BrowseRecursive", browseRecursive); keyFile.set_integer("File Browser", "BrowseRecursiveDepth", browseRecursiveDepth); keyFile.set_integer("File Browser", "BrowseRecursiveMaxDirs", browseRecursiveMaxDirs); + keyFile.set_boolean("File Browser", "BrowseRecursiveFollowLinks", browseRecursiveFollowLinks); keyFile.set_integer("Clipping Indication", "HighlightThreshold", highlightThreshold); keyFile.set_integer("Clipping Indication", "ShadowThreshold", shadowThreshold); keyFile.set_boolean("Clipping Indication", "BlinkClipped", blinkClipped); diff --git a/rtgui/options.h b/rtgui/options.h index 6380cdb56..2e2839723 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -318,6 +318,7 @@ public: bool browseRecursive; int browseRecursiveDepth; int browseRecursiveMaxDirs; + bool browseRecursiveFollowLinks; std::vector tpOpen; bool autoSaveTpOpen; //std::vector crvOpen; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 025fbb3ae..1838ee299 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1405,7 +1405,9 @@ Gtk::Widget* Preferences::getFileBrowserPanel() hbBrowseRecursive->pack_start(*browseRecursiveDepth, Gtk::PACK_SHRINK, 4); hbBrowseRecursive->pack_start(*labBrowseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); hbBrowseRecursive->pack_start(*browseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); + browseRecursiveFollowLinks = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_BROWSERECURSIVEFOLLOWLINKS"))); vbro->pack_start(*hbBrowseRecursive, Gtk::PACK_SHRINK, 0); + vbro->pack_start(*browseRecursiveFollowLinks, Gtk::PACK_SHRINK, 0); fro->add(*vbro); @@ -1884,6 +1886,7 @@ void Preferences::storePreferences() moptions.internalThumbIfUntouched = ckbInternalThumbIfUntouched->get_active(); moptions.browseRecursiveDepth = static_cast(browseRecursiveDepth->get_value()); moptions.browseRecursiveMaxDirs = static_cast(browseRecursiveMaxDirs->get_value()); + moptions.browseRecursiveFollowLinks = browseRecursiveFollowLinks->get_active(); auto save_where = saveParamsPreference->get_active_row_number(); moptions.saveParamsFile = save_where == 0 || save_where == 2; @@ -2111,6 +2114,7 @@ void Preferences::fillPreferences() ckbInternalThumbIfUntouched->set_active(moptions.internalThumbIfUntouched); browseRecursiveDepth->set_value(moptions.browseRecursiveDepth); browseRecursiveMaxDirs->set_value(moptions.browseRecursiveMaxDirs); + browseRecursiveFollowLinks->set_active(moptions.browseRecursiveFollowLinks); saveParamsPreference->set_active(moptions.saveParamsFile ? (moptions.saveParamsCache ? 2 : 0) : 1); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 829506894..c15ea71e8 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -196,6 +196,7 @@ class Preferences final : Gtk::CheckButton* sameThumbSize; Gtk::SpinButton* browseRecursiveDepth; Gtk::SpinButton* browseRecursiveMaxDirs; + Gtk::CheckButton* browseRecursiveFollowLinks; Gtk::SpinButton* threadsSpinBtn; Gtk::SpinButton* clutCacheSizeSB; From 051bbaf322543257bda3bc56ecba3e3a873b0300 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:28:16 -0700 Subject: [PATCH 024/291] Listen to changed dirs when browsing recursively Remove images in removed directories and rescan when new directories are added. --- rtgui/filecatalog.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index b01300d95..058236733 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1783,7 +1783,7 @@ void FileCatalog::reparseDirectory () return; } - // check if a thumbnailed file has been deleted + // check if a thumbnailed file has been deleted or is not in a directory of interest const std::vector& t = fileBrowser->getEntries(); std::vector fileNamesToDel; std::vector fileNamesToRemove; @@ -1832,8 +1832,10 @@ void FileCatalog::reparseDirectory () void FileCatalog::on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal) { - if (options.has_retained_extention(file->get_parse_name()) - && (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED)) { + if ((options.has_retained_extention(file->get_parse_name()) + && (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED)) + || (event_type == Gio::FILE_MONITOR_EVENT_CREATED && Glib::file_test(file->get_path(), Glib::FileTest::FILE_TEST_IS_DIR)) + || (event_type == Gio::FILE_MONITOR_EVENT_DELETED && std::find_if(dirMonitors.cbegin(), dirMonitors.cend(), [&file](const FileMonitorInfo &monitor) { return monitor.filePath == file->get_path(); }) != dirMonitors.cend())) { if (!internal) { GThreadLock lock; reparseDirectory (); From 473d50a0a320b4e80dfcf09195fe78ec054f75bd Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 15 Jul 2023 17:47:26 -0700 Subject: [PATCH 025/291] Add checkbox for disabling NR gain Option to disable noise reduction automatic gain for consistency between photographs. Fix automatic gain not being recalculated after changing the white level correction. --- rtdata/languages/default | 3 +++ rtengine/FTblockDN.cc | 4 ++-- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 2 +- rtgui/dirpyrdenoise.cc | 21 +++++++++++++++++++++ rtgui/dirpyrdenoise.h | 5 +++++ rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + 9 files changed, 44 insertions(+), 3 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 050836d21..376d65e68 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1405,6 +1405,7 @@ HISTORY_MSG_DEHAZE_ENABLED;Haze Removal HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength +HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_EDGEFFECT;Edge Attenuation response @@ -2405,6 +2406,8 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminance curve TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Detail recovery TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminance TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminance +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images. TP_DIRPYRDENOISE_MAIN_COLORSPACE;Color space TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 7477c5d08..19f5cd9c8 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -665,7 +665,7 @@ BENCHFUN Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f); } - const float gain = std::pow(2.0, expcomp); + const float gain = dnparams.autoGain ? static_cast(std::pow(2.0, expcomp)) : 1.f; const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor const float noisevar_Ldetail = SQR((SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail)) * TS * 0.5); @@ -3287,7 +3287,7 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); - const float gain = pow(2.0f, float(expcomp)); + const float gain = dnparams.autoGain ? pow(2.0f, float(expcomp)) : 1.f; int tilesize = 0; int overlap = 0; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a421be9b3..85c09a50a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1699,6 +1699,7 @@ DirPyrDenoiseParams::DirPyrDenoiseParams() : chroma(15), redchro(0), bluechro(0), + autoGain(true), gamma(1.7), dmethod("Lab"), Lmethod("SLI"), @@ -1726,6 +1727,7 @@ bool DirPyrDenoiseParams::operator ==(const DirPyrDenoiseParams& other) const && chroma == other.chroma && redchro == other.redchro && bluechro == other.bluechro + && autoGain == other.autoGain && gamma == other.gamma && dmethod == other.dmethod && Lmethod == other.Lmethod @@ -6334,6 +6336,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->dirpyrDenoise.methodmed, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.redchro, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.bluechro, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, keyFile); + saveToKeyfile(!pedited || pedited->dirpyrDenoise.gain, "Directional Pyramid Denoising", "AutoGain", dirpyrDenoise.autoGain, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.gamma, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.passes, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.lcurve, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, keyFile); @@ -8354,6 +8357,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", pedited, dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", pedited, dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "AutoGain", pedited, dirpyrDenoise.autoGain, pedited->dirpyrDenoise.gain); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", pedited, dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", pedited, dirpyrDenoise.passes, pedited->dirpyrDenoise.passes); } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6be2be54c..769101ce0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -776,6 +776,7 @@ struct DirPyrDenoiseParams { double chroma; double redchro; double bluechro; + bool autoGain; double gamma; Glib::ustring dmethod; Glib::ustring Lmethod; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 06aa701e8..044b6a3be 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1683,7 +1683,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le } } - if (prepareDenoise && dirpyrdenoiseExpComp == RT_INFINITY) { + if (prepareDenoise) { LUTu aehist; int aehistcompr; double clip = 0; diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index f2b780eba..4e487b184 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -26,9 +26,11 @@ #include "editbuffer.h" #include "guiutils.h" #include "options.h" +#include "eventmapper.h" #include "../rtengine/color.h" #include "../rtengine/procparams.h" +#include "../rtengine/refreshmap.h" using namespace rtengine; using namespace rtengine::procparams; @@ -37,6 +39,9 @@ const Glib::ustring DirPyrDenoise::TOOL_NAME = "dirpyrdenoise"; DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) { + const auto procEventMapper = ProcEventMapper::getInstance(); + EvDPDNGain = procEventMapper->newEvent(ALLNORAW, "HISTORY_MSG_DIRPYRDENOISE_GAIN"); + std::vector milestones; CurveListener::setMulti(true); nextnresid = 0.; @@ -229,6 +234,11 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPY pack_start( *hb11, Gtk::PACK_SHRINK, 1); smethodconn = smethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::smethodChanged) ); + autoGain = Gtk::manage(new CheckBox(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN"), multiImage)); + autoGain->set_tooltip_text(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP")); + autoGain->setCheckBoxListener(this); + pack_start(*autoGain, Gtk::PACK_SHRINK, 0); + gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_MAIN_GAMMA"), 1.0, 3.0, 0.01, 1.7)); gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP")); gamma->setAdjusterListener (this); @@ -570,6 +580,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited); bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited); + autoGain->set_inconsistent(!pedited->dirpyrDenoise.gain); gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); passes->setEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited); set_inconsistent (multiImage && !pedited->dirpyrDenoise.enabled); @@ -593,6 +604,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) redchro->setValue (pp->dirpyrDenoise.redchro); bluechro->setValue (pp->dirpyrDenoise.bluechro); + autoGain->setValue(pp->dirpyrDenoise.autoGain); gamma->setValue (pp->dirpyrDenoise.gamma); passes->setValue (pp->dirpyrDenoise.passes); lshape->setCurve (pp->dirpyrDenoise.lcurve); @@ -631,6 +643,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) pp->dirpyrDenoise.chroma = chroma->getValue (); pp->dirpyrDenoise.redchro = redchro->getValue (); pp->dirpyrDenoise.bluechro = bluechro->getValue (); + pp->dirpyrDenoise.autoGain = autoGain->get_active(); pp->dirpyrDenoise.gamma = gamma->getValue (); pp->dirpyrDenoise.passes = passes->getValue (); pp->dirpyrDenoise.enabled = getEnabled(); @@ -653,6 +666,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) pedited->dirpyrDenoise.chroma = chroma->getEditedState (); pedited->dirpyrDenoise.redchro = redchro->getEditedState (); pedited->dirpyrDenoise.bluechro = bluechro->getEditedState (); + pedited->dirpyrDenoise.gain = !autoGain->get_inconsistent(); pedited->dirpyrDenoise.gamma = gamma->getEditedState (); pedited->dirpyrDenoise.passes = passes->getEditedState (); pedited->dirpyrDenoise.enabled = !get_inconsistent(); @@ -992,6 +1006,13 @@ void DirPyrDenoise::adjusterChanged(Adjuster* a, double newval) } } +void DirPyrDenoise::checkBoxToggled(CheckBox* c, CheckValue newval) +{ + if (c == autoGain) { + listener->panelChanged(EvDPDNGain, c->getValueAsStr()); + } +} + void DirPyrDenoise::enabledChanged () { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index dadd96988..6e4e250d4 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -21,6 +21,7 @@ #include #include "adjuster.h" +#include "checkbox.h" #include "colorprovider.h" #include "curvelistener.h" #include "guiutils.h" @@ -34,6 +35,7 @@ class EditDataProvider; class DirPyrDenoise final : public ToolParamBlock, public AdjusterListener, + public CheckBoxListener, public FoldableToolPanel, public rtengine::AutoChromaListener, public CurveListener, @@ -54,6 +56,7 @@ public: void autoOpenCurve () override; void adjusterChanged (Adjuster* a, double newval) override; + void checkBoxToggled(CheckBox* c, CheckValue newval) override; void enabledChanged () override; void medianChanged (); void chromaChanged (double autchroma, double autred, double autblue) override; @@ -83,6 +86,7 @@ public: Glib::ustring getSettingString (); private: + rtengine::ProcEvent EvDPDNGain; CurveEditorGroup* NoiscurveEditorG; CurveEditorGroup* CCcurveEditorG; Adjuster* luma; @@ -90,6 +94,7 @@ private: Adjuster* chroma; Adjuster* redchro; Adjuster* bluechro; + CheckBox* autoGain; Adjuster* gamma; Adjuster* passes; FlatCurveEditor* lshape; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index adf462d84..2b66f4c57 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -301,6 +301,7 @@ void ParamsEdited::set(bool v) dirpyrDenoise.chroma = v; dirpyrDenoise.redchro = v; dirpyrDenoise.bluechro = v; + dirpyrDenoise.gain = v; dirpyrDenoise.gamma = v; dirpyrDenoise.passes = v; dirpyrDenoise.dmethod = v; @@ -1020,6 +1021,7 @@ void ParamsEdited::initFrom(const std::vector& dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma; dirpyrDenoise.redchro = dirpyrDenoise.redchro && p.dirpyrDenoise.redchro == other.dirpyrDenoise.redchro; dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro; + dirpyrDenoise.gain = dirpyrDenoise.gain && p.dirpyrDenoise.autoGain == other.dirpyrDenoise.autoGain; dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma; dirpyrDenoise.passes = dirpyrDenoise.passes && p.dirpyrDenoise.passes == other.dirpyrDenoise.passes; dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod; @@ -3167,6 +3169,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.dirpyrDenoise.bluechro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE] ? toEdit.dirpyrDenoise.bluechro + mods.dirpyrDenoise.bluechro : mods.dirpyrDenoise.bluechro; } + if (dirpyrDenoise.gain) { + toEdit.dirpyrDenoise.autoGain = mods.dirpyrDenoise.autoGain; + } + if (dirpyrDenoise.gamma) { toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3c8a70b74..509ad3000 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -330,6 +330,7 @@ struct DirPyrDenoiseParamsEdited { bool chroma; bool redchro; bool bluechro; + bool gain; bool gamma; bool lcurve; bool cccurve; From 5b2dc59fbf553e7f5f61914e479feadae4938dd1 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 12 Aug 2023 18:20:27 +0200 Subject: [PATCH 026/291] Fix incorrect icon names - Some icon names still had file extension indicated in their names - This commit also enable icon name debug messages on console --- rtgui/editorpanel.cc | 2 +- rtgui/rtscalable.cc | 16 ++++------------ rtgui/toneequalizer.cc | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index fd6acc185..4880ae0a8 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -904,7 +904,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) send_to_external = Gtk::manage(new PopUpButton("", false)); send_to_external->set_tooltip_text(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); - send_to_external->setEmptyImage("palette-brush.png"); + send_to_external->setEmptyImage("palette-brush"); setExpandAlignProperties(send_to_external->buttonGroup, false, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_FILL); updateExternalEditorWidget( options.externalEditorIndex >= 0 ? options.externalEditorIndex : options.externalEditors.size(), diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 0e90d34ad..b58da6d12 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -70,9 +70,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromIcon(const Glib::u const auto iconInfo = theme->lookup_icon(iconName, size); if (!iconInfo) { - if (rtengine::settings->verbose) { - std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; - } + std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; return surf; } @@ -80,9 +78,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromIcon(const Glib::u const auto iconPath = iconInfo.get_filename(); if (iconPath.empty()) { - if (rtengine::settings->verbose) { - std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; - } + std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl; return surf; } @@ -130,9 +126,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromPNG(const Glib::us if (Glib::file_test(path.c_str(), Glib::FILE_TEST_EXISTS)) { surf = Cairo::ImageSurface::create_from_png(path); } else { - if (rtengine::settings->verbose) { - std::cerr << "Failed to load PNG file \"" << fname << "\"" << std::endl; - } + std::cerr << "Failed to load PNG file \"" << fname << "\"" << std::endl; } return surf; @@ -230,9 +224,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us static_cast(RTScalable::getScale()), static_cast(RTScalable::getScale())); } else { - if (rtengine::settings->verbose) { - std::cerr << "Failed to load SVG file \"" << fname << "\"" << std::endl; - } + std::cerr << "Failed to load SVG file \"" << fname << "\"" << std::endl; } return surf; diff --git a/rtgui/toneequalizer.cc b/rtgui/toneequalizer.cc index d524bdc05..34c1c8a4e 100644 --- a/rtgui/toneequalizer.cc +++ b/rtgui/toneequalizer.cc @@ -44,7 +44,7 @@ ToneEqualizer::ToneEqualizer(): FoldableToolPanel(this, TOOL_NAME, M("TP_TONE_EQ "red" }; for (size_t i = 0; i < bands.size(); ++i) { - bands[i] = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_BAND_" + std::to_string(i)), -100, 100, 1, 0, Gtk::manage(new RTImage(Glib::ustring("circle-") + images[i] + "-small.png")))); + bands[i] = Gtk::manage(new Adjuster(M("TP_TONE_EQUALIZER_BAND_" + std::to_string(i)), -100, 100, 1, 0, Gtk::manage(new RTImage(Glib::ustring("circle-") + images[i] + "-small")))); bands[i]->setAdjusterListener(this); pack_start(*bands[i]); bands[i]->showIcons(false); From bb258e402442ef0faef26783cf3ab2896424d96f Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 12 Aug 2023 18:30:03 +0200 Subject: [PATCH 027/291] Delete now obsolete "pseudo-hidpi" preference --- rtdata/languages/default | 13 ++++++------- rtgui/options.cc | 22 ++++++++-------------- rtgui/options.h | 3 +-- rtgui/preferences.cc | 16 ++++------------ rtgui/preferences.h | 8 +++----- 5 files changed, 22 insertions(+), 40 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2f372bf42..74920c43c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1683,15 +1683,15 @@ 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; Batch Edit +MAIN_TAB_DEVELOP; Batch Edit MAIN_TAB_EXIF;Exif -MAIN_TAB_EXPORT; Fast Export +MAIN_TAB_EXPORT; Fast Export MAIN_TAB_EXPOSURE;Exposure MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e MAIN_TAB_FAVORITES;Favorites MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u -MAIN_TAB_FILTER; Filter -MAIN_TAB_INSPECT; Inspect +MAIN_TAB_FILTER; Filter +MAIN_TAB_INSPECT; Inspect MAIN_TAB_IPTC;IPTC MAIN_TAB_LOCALLAB;Local MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o @@ -1828,7 +1828,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Color picker font PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color PREFERENCES_APPEARANCE_MAINFONT;Main font PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator guide color -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode PREFERENCES_APPEARANCE_THEME;Theme PREFERENCES_APPLNEXTSTARTUP;restart required PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile @@ -1867,7 +1866,7 @@ PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extr PREFERENCES_WBANOPURP;No purple color used PREFERENCES_WBAPRECIS;Precision algorithm - scale used PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color -PREFERENCES_WBASORT;Sort in chroma order instead of histogram +PREFERENCES_WBASORT;Sort in chroma order instead of histogram PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs @@ -3208,7 +3207,7 @@ TP_LOCALLAB_MERTWO;Subtract TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. TP_LOCALLAB_LCLABELS;Residual noise levels TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. -TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 +TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 diff --git a/rtgui/options.cc b/rtgui/options.cc index 214dc5c67..5329da9d7 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -358,7 +358,6 @@ void Options::setDefaults() fontSize = 10; CPFontFamily = "default"; CPFontSize = 8; - pseudoHiDPISupport = false; lastScale = 5; lastShowAllExif = false; panAccelFactor = 5; @@ -576,7 +575,7 @@ void Options::setDefaults() rtSettings.flatFieldsPath = ""; rtSettings.cameraProfilesPath = ""; rtSettings.lensProfilesPath = ""; - + #ifdef WIN32 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" @@ -637,7 +636,7 @@ void Options::setDefaults() rtSettings.edghi = 3.0;//1.1 and 5. rtSettings.edglo = 0.5;//0.1 and 0.95 rtSettings.limrad = 20.;//1 and 60 - + rtSettings.protectred = 60; rtSettings.protectredh = 0.3; @@ -851,7 +850,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "CustomEditor")) { customEditorProg = keyFile.get_string("External Editor", "CustomEditor"); } - + if (keyFile.has_key("External Editor", "OutputDir")) { int v = keyFile.get_integer("External Editor", "OutputDir"); if (v < int(EDITOR_OUT_DIR_TEMP) || v > int(EDITOR_OUT_DIR_CUSTOM)) { @@ -872,7 +871,7 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("External Editor", "BypassOutputProfile")) { editor_bypass_output_profile = keyFile.get_boolean("External Editor", "BypassOutputProfile"); } - + } if (keyFile.has_group("External Editor")) { @@ -1550,10 +1549,6 @@ void Options::readFromFile(Glib::ustring fname) CPFontSize = keyFile.get_integer("GUI", "CPFontSize"); } - if (keyFile.has_key("GUI", "PseudoHiDPISupport")) { - pseudoHiDPISupport = keyFile.get_boolean("GUI", "PseudoHiDPISupport"); - } - if (keyFile.has_key("GUI", "LastPreviewScale")) { lastScale = keyFile.get_integer("GUI", "LastPreviewScale"); } @@ -1714,11 +1709,11 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("GUI", "CurveBBoxPosition")) { curvebboxpos = keyFile.get_integer("GUI", "CurveBBoxPosition"); } - + if (keyFile.has_key("GUI", "Complexity")) { complexity = keyFile.get_integer("GUI", "Complexity"); } - + if (keyFile.has_key("GUI", "InspectorWindow")) { inspectorWindow = keyFile.get_boolean("GUI", "InspectorWindow"); } @@ -1972,8 +1967,8 @@ void Options::readFromFile(Glib::ustring fname) } } - - + + if (keyFile.has_group("ICC Profile Creator")) { if (keyFile.has_key("ICC Profile Creator", "PimariesPreset")) { ICCPC_primariesPreset = keyFile.get_string("ICC Profile Creator", "PimariesPreset"); @@ -2515,7 +2510,6 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("GUI", "FontSize", fontSize); keyFile.set_string("GUI", "CPFontFamily", CPFontFamily); keyFile.set_integer("GUI", "CPFontSize", CPFontSize); - keyFile.set_boolean("GUI", "PseudoHiDPISupport", pseudoHiDPISupport); keyFile.set_integer("GUI", "LastPreviewScale", lastScale); keyFile.set_boolean("GUI", "LastShowAllExif", lastShowAllExif); keyFile.set_integer("GUI", "PanAccelFactor", panAccelFactor); diff --git a/rtgui/options.h b/rtgui/options.h index db44a5876..235b1b26f 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -254,7 +254,6 @@ public: int fontSize; // RT's main font size (units: pt) Glib::ustring CPFontFamily; // ColorPicker font family int CPFontSize; // ColorPicker font size (units: pt) - bool pseudoHiDPISupport; bool fbOnlyRaw; bool fbShowDateTime; bool fbShowBasicExif; @@ -306,7 +305,7 @@ public: Glib::ustring editor_custom_out_dir; bool editor_float32; bool editor_bypass_output_profile; - + int maxThumbnailHeight; int maxThumbnailWidth; std::size_t maxCacheEntries; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 28258060a..393744a1b 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -966,14 +966,14 @@ Gtk::Widget* Preferences::getColorManPanel () //------------White-Balance auto temperature correlation - + Gtk::Frame* fwbacorr = Gtk::manage(new Gtk::Frame(M("PREFERENCES_WBACORR"))); fwbacorr->set_tooltip_text(M("PREFERENCES_WBACORR_TOOLTIP")); fwbacorr->set_label_align(0.025, 0.5); Gtk::Box* wbaVB = Gtk::manage ( new Gtk::Box(Gtk::ORIENTATION_VERTICAL) ); Gtk::Box* wbah = Gtk::manage ( new Gtk::Box () ); wbah->set_spacing (4); - + mwbaena = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_WBAENA"))); setExpandAlignProperties(mwbaena, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); mwbaena->set_active(true); @@ -1192,9 +1192,6 @@ Gtk::Widget* Preferences::getGeneralPanel() navGuideColorCB = Gtk::manage(new Gtk::ColorButton()); navGuideColorCB->set_use_alpha(true); - pseudoHiDPI = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_APPEARANCE_PSEUDOHIDPI") + Glib::ustring (" (") + M ("PREFERENCES_APPLNEXTSTARTUP") + ")")); - setExpandAlignProperties(pseudoHiDPI, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); - Gtk::Separator *vSep = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)); @@ -1210,7 +1207,6 @@ Gtk::Widget* Preferences::getGeneralPanel() appearanceGrid->attach(*colorPickerFontFB, 1, 2, 1, 1); appearanceGrid->attach(*navGuideColorLbl, 3, 2, 1, 1); appearanceGrid->attach(*navGuideColorCB, 4, 2, 1, 1); - appearanceGrid->attach(*pseudoHiDPI, 0, 3, 5, 1); appearanceFrame->add(*appearanceGrid); vbGeneral->attach_next_to(*appearanceFrame, *flang, Gtk::POS_BOTTOM, 2, 1); @@ -1779,8 +1775,6 @@ void Preferences::storePreferences() moptions.CPFontSize = cpfd.get_size() / Pango::SCALE; } - moptions.pseudoHiDPISupport = pseudoHiDPI->get_active(); - const std::vector &editors = externalEditors->getEditors(); moptions.externalEditors.resize(editors.size()); moptions.externalEditorIndex = @@ -2059,8 +2053,6 @@ void Preferences::fillPreferences() colorPickerFontFB->set_font_name (Glib::ustring::compose ("%1 %2", options.CPFontFamily, options.CPFontSize)); } - pseudoHiDPI->set_active(options.pseudoHiDPISupport); - showDateTime->set_active(moptions.fbShowDateTime); showBasicExif->set_active(moptions.fbShowBasicExif); showExpComp->set_active(moptions.fbShowExpComp); @@ -2166,9 +2158,9 @@ void Preferences::fillPreferences() flatFieldChanged(); clutsDir->set_current_folder(moptions.clutsDir); - + cameraProfilesDir->set_current_folder(moptions.rtSettings.cameraProfilesPath); - + lensProfilesDir->set_current_folder(moptions.rtSettings.lensProfilesPath); addc.block(true); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index baa3543ae..e9f33a1f1 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -104,14 +104,14 @@ class Preferences final : Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; ExternalEditorPreferences *externalEditors; - + Gtk::RadioButton *editor_dir_temp; Gtk::RadioButton *editor_dir_current; Gtk::RadioButton *editor_dir_custom; MyFileChooserButton *editor_dir_custom_path; Gtk::CheckButton *editor_float32; Gtk::CheckButton *editor_bypass_output_profile; - + MyFileChooserButton* darkFrameDir; MyFileChooserButton* flatFieldDir; MyFileChooserButton* clutsDir; @@ -181,8 +181,6 @@ class Preferences final : Gtk::FontButton* colorPickerFontFB; Gtk::ColorButton* cropMaskColorCB; Gtk::ColorButton* navGuideColorCB; - Gtk::CheckButton* pseudoHiDPI; - Gtk::SpinButton* maxRecentFolders; Gtk::SpinButton* maxThumbHeightSB; @@ -318,7 +316,7 @@ public: void sndEnableToggled (); void langAutoDetectToggled (); void autocielabToggled (); - void observer10Toggled (); + void observer10Toggled (); void selectStartupDir (); void addExtPressed (); From 58b7d4169477aba1582fb6751c6b0d27a56d3889 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Wed, 16 Aug 2023 19:07:39 +0200 Subject: [PATCH 028/291] Cleanup of theme selection For hidpi support, Gtk min version has been increased to 3.24.3. Theme logics based on Gtk version is so now useless --- ...-GTK3-20_.css => RawTherapee - Legacy.css} | 2 +- rtdata/themes/RawTherapee-GTK3-_19.css | 525 ----------- ...wTherapee-GTK3-20_.css => RawTherapee.css} | 6 +- ...ht-GTK3-20_.css => TooWaBlue - Bright.css} | 2 +- ...Dark-GTK3-20_.css => TooWaBlue - Dark.css} | 2 +- rtdata/themes/TooWaBlue-GTK3-_19.css | 881 ------------------ .../{TooWaBlue-GTK3-20_.css => TooWaBlue.css} | 0 ..._.css => TooWaGrey - Average Surround.css} | 2 +- ...ht-GTK3-20_.css => TooWaGrey - Bright.css} | 2 +- ...Dark-GTK3-20_.css => TooWaGrey - Dark.css} | 2 +- .../{TooWaGrey-GTK3-20_.css => TooWaGrey.css} | 2 +- rtdata/themes/{ => common}/size - Legacy.css | 0 rtdata/themes/{ => common}/size.css | 0 .../svg/twb/checkbox-checked-disabled.svg | 124 --- .../images/svg/twb/checkbox-checked.svg | 124 --- .../twb/checkbox-inconsistent-disabled.svg | 124 --- .../images/svg/twb/checkbox-inconsistent.svg | 124 --- .../svg/twb/checkbox-unchecked-disabled.svg | 118 --- .../images/svg/twb/checkbox-unchecked.svg | 118 --- .../images/svg/twb/radio-checked-disabled.svg | 122 --- .../themes/images/svg/twb/radio-checked.svg | 122 --- .../svg/twb/radio-inconsistent-disabled.svg | 122 --- .../images/svg/twb/radio-inconsistent.svg | 122 --- .../svg/twb/radio-unchecked-disabled.svg | 116 --- .../themes/images/svg/twb/radio-unchecked.svg | 116 --- .../images/twb/checkbox-checked-disabled.png | Bin 378 -> 0 bytes rtdata/themes/images/twb/checkbox-checked.png | Bin 428 -> 0 bytes .../twb/checkbox-inconsistent-disabled.png | Bin 265 -> 0 bytes .../images/twb/checkbox-inconsistent.png | Bin 295 -> 0 bytes .../twb/checkbox-unchecked-disabled.png | Bin 247 -> 0 bytes .../themes/images/twb/checkbox-unchecked.png | Bin 272 -> 0 bytes .../images/twb/radio-checked-disabled.png | Bin 524 -> 0 bytes rtdata/themes/images/twb/radio-checked.png | Bin 593 -> 0 bytes .../twb/radio-inconsistent-disabled.png | Bin 556 -> 0 bytes .../themes/images/twb/radio-inconsistent.png | Bin 631 -> 0 bytes .../images/twb/radio-unchecked-disabled.png | Bin 438 -> 0 bytes rtdata/themes/images/twb/radio-unchecked.png | Bin 503 -> 0 bytes rtgui/options.h | 2 +- rtgui/preferences.cc | 60 +- rtgui/preferences.h | 13 +- rtgui/rtwindow.cc | 40 +- 41 files changed, 35 insertions(+), 2958 deletions(-) rename rtdata/themes/{RawTherapee - Legacy-GTK3-20_.css => RawTherapee - Legacy.css} (99%) delete mode 100644 rtdata/themes/RawTherapee-GTK3-_19.css rename rtdata/themes/{RawTherapee-GTK3-20_.css => RawTherapee.css} (99%) rename rtdata/themes/{TooWaBlue - Bright-GTK3-20_.css => TooWaBlue - Bright.css} (98%) rename rtdata/themes/{TooWaBlue - Dark-GTK3-20_.css => TooWaBlue - Dark.css} (98%) delete mode 100644 rtdata/themes/TooWaBlue-GTK3-_19.css rename rtdata/themes/{TooWaBlue-GTK3-20_.css => TooWaBlue.css} (100%) rename rtdata/themes/{TooWaGrey - Average Surround-GTK3-20_.css => TooWaGrey - Average Surround.css} (98%) rename rtdata/themes/{TooWaGrey - Bright-GTK3-20_.css => TooWaGrey - Bright.css} (98%) rename rtdata/themes/{TooWaGrey - Dark-GTK3-20_.css => TooWaGrey - Dark.css} (98%) rename rtdata/themes/{TooWaGrey-GTK3-20_.css => TooWaGrey.css} (98%) rename rtdata/themes/{ => common}/size - Legacy.css (100%) rename rtdata/themes/{ => common}/size.css (100%) delete mode 100644 rtdata/themes/images/svg/twb/checkbox-checked-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/checkbox-checked.svg delete mode 100644 rtdata/themes/images/svg/twb/checkbox-inconsistent-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/checkbox-inconsistent.svg delete mode 100644 rtdata/themes/images/svg/twb/checkbox-unchecked-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/checkbox-unchecked.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-checked-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-checked.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-inconsistent-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-inconsistent.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-unchecked-disabled.svg delete mode 100644 rtdata/themes/images/svg/twb/radio-unchecked.svg delete mode 100644 rtdata/themes/images/twb/checkbox-checked-disabled.png delete mode 100644 rtdata/themes/images/twb/checkbox-checked.png delete mode 100644 rtdata/themes/images/twb/checkbox-inconsistent-disabled.png delete mode 100644 rtdata/themes/images/twb/checkbox-inconsistent.png delete mode 100644 rtdata/themes/images/twb/checkbox-unchecked-disabled.png delete mode 100644 rtdata/themes/images/twb/checkbox-unchecked.png delete mode 100644 rtdata/themes/images/twb/radio-checked-disabled.png delete mode 100644 rtdata/themes/images/twb/radio-checked.png delete mode 100644 rtdata/themes/images/twb/radio-inconsistent-disabled.png delete mode 100644 rtdata/themes/images/twb/radio-inconsistent.png delete mode 100644 rtdata/themes/images/twb/radio-unchecked-disabled.png delete mode 100644 rtdata/themes/images/twb/radio-unchecked.png diff --git a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css b/rtdata/themes/RawTherapee - Legacy.css similarity index 99% rename from rtdata/themes/RawTherapee - Legacy-GTK3-20_.css rename to rtdata/themes/RawTherapee - Legacy.css index ba62fd366..2a8ae4adc 100644 --- a/rtdata/themes/RawTherapee - Legacy-GTK3-20_.css +++ b/rtdata/themes/RawTherapee - Legacy.css @@ -20,7 +20,7 @@ */ /***************************/ -/**/ @import "size - Legacy.css"; /**/ +/**/ @import url("./common/size - Legacy.css"); /**/ /***************************/ /* text-shadow causes a serious performance degradation in rendering the UI, diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css deleted file mode 100644 index f4bec23b1..000000000 --- a/rtdata/themes/RawTherapee-GTK3-_19.css +++ /dev/null @@ -1,525 +0,0 @@ -/* - This file is part of RawTherapee. - - Copyright (c) 2015-2017 DrSlony - Copyright (c) 2016-2017 Hombre - - RawTherapee is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - RawTherapee is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . -*/ - -* { - color: #AAAAAA; -} - -.view:selected { - color: #262626; - background-color: #AAAAAA -} - -/* The Places and Dir browser panels */ -.view { - background-color: #262626; -} -/* The headers of these panels */ -.view .button { - background-color: #363636; - padding: 2px; -} - -.plainback { - background-color: #404040; -} - -GtkBox { - border-width: 0; - border-style: none; - border-radius: 0; - margin: 0; - padding: 0; -} - -GtkGrid { - margin: 2px; - padding: 0; - border-width: 0; - border-style: none; - border-radius: 0; -} - -/* Affects all frames except in the toolbox */ -GtkFrame { - border-width: 0; - border-color: #303030; - border-radius: 0; - border-style: solid; - /*border-style: none none none solid;*/ - padding: 4px; -} - -GtkFrame > GtkLabel { - color: #D8D8D8; -} - -#FileBrowser { - padding: 10px; - margin: 10px; -} - -/* Frames in Preferences */ -#PrefNotebook GtkFrame { - background-color: #3B3B3B; - border: 1px solid #505050; - border-radius: 4px; -} - -/* Frames in the toolbox. Not MyExpander frames. */ -GtkEventBox .frame { - border-color: #565656; -} - -/*.EditorTopPanel .button, .ToolBarPanelFileBrowser .button, .EditorZoomPanel .button {*/ -.button { - padding: 1px; - margin: 1px; -} - -/* Adjusters */ -.text-button { - padding: 0; -} - -/* Any text-button which is a real button, unlike Slider label */ -.text-button.button { - padding: 4px; -} - -.separator { - color: #363636; -} - -GtkProgressBar { - -GtkProgressBar-min-vertical-bar-width: 10; - -GtkProgressBar-min-horizontal-bar-height: 10; -} - -GtkDrawingArea { - border-radius: 0; - background-color: #363636; - border: 1px solid #252525; -} - -GtkDrawingArea:selected { - background-color: #565656; - border-radius: 10px; -} - -GtkImage { - padding: 1px; -} - - - - - -GtkScale.slider { - margin: 1px; -} -GtkScale.slider:hover { - background-image: linear-gradient(#444444, #3E3E3E, #393939); -} -GtkScale.slider:insensitive { - background-image: none; - background-color: #444; - border-color: #282828; -} -GtkScale.trough { - background-color: #2A2A2A; -} -GtkScale.trough:insensitive { - background-color: #444; - border-color: #282828; -} - - - -GtkLabel { - margin: 0 1px; -} - - -GtkButton { - padding: 0; - margin: 1px; -} -GtkButton, GtkButton.flat:hover { - background-image: linear-gradient(#343434, #2E2E2E, #292929); -} - -GtkButton.flat, GtkCheckButton { - background-image: none; -} - -/* Vertical group of buttons in 1 column */ -GtkButton.Top { - border-radius: 10px 4px 0 0; - border-style: solid solid none solid; - margin-bottom: 0; -} -GtkButton.MiddleV { - border-radius: 0; - border-style: none solid none solid; - margin-top: 0; - margin-bottom: 0; -} -GtkButton.Bottom { - border-radius: 0 0 4px 4px; - border-style: none solid solid solid; - margin-top: 0; -} -/* end */ - -/* Horizontal group of buttons in 1 row */ -GtkButton.Left { - border-radius: 4px 0 0 4px; - border-style: solid none solid solid; - margin-right: 0; -} -GtkButton.MiddleH { - border-radius: 0; - border-style: solid none solid none; - margin-left: 0; - margin-right: 0; -} -GtkButton.Right { - border-radius: 0 4px 4px 0; - border-style: solid solid solid none; - margin-left: 0; -} -/* end */ - -/* [1.23[-][+]] */ -GtkEntry, GtkSpinButton { - background-color: #262626; -} - -GtkEntry:insensitive, GtkSpinButton:insensitive { - background-color: #363636; -} - -GtkEntry:hover, GtkSpinButton:hover { - background-color: #565656; -} - -GtkEntry:selected { - color: #262626; - background-color: #AAAAAA; -} - -/* Context menus */ -GtkMenu { - background-color: #262626; - color: #909090; -} - -/* Context menu item */ -.menuitem { - padding: 2px; -} - -#MyExpander { - margin: 10px; - padding: 5px; -} - -/* Tool background */ -#ExpanderBox { - background-color: #363636; - border-width: 1px; - border-style: solid; - border-radius: 4px; - border-color: #252525; - margin: 9px; - padding: 4px; -} - -#ExpanderBox GtkDrawingArea { - background-color: #363636; -} - -#ExpanderBox GtkFrame { - background-color: #3B3B3B; - border-style: solid; - border-width: 1px; - border-radius: 4px; - border-color: #313131; - margin: 3px; - padding: 2px; -} - -#ExpanderBox GtkFrame GtkDrawingArea { - background-color: #3B3B3B; -} - -#ExpanderBox GtkFrame GtkFrame { - background-color: #414141; - border: 1px solid #373737; - border-radius: 4px; - margin: 3px; - padding: 2px; -} - -#ExpanderBox GtkFrame GtkFrame GtkDrawingArea { - background-color: #414141; -} - -/* Sub-tool (MyExpander) background */ -#ExpanderBox2 { - background-color: #3B3B3B; - border: 1px solid #2A2A2A; - border-radius: 4px; - margin: 9px; - padding: 4px; -} - -#ExpanderBox2 GtkDrawingArea { - background-color: #3B3B3B; -} - -#ExpanderBox2 GtkFrame { - background-color: #414141; - border: 1px solid #373737; - border-radius: 4px; - margin: 3px; - padding: 2px; -} - -#ExpanderBox2 GtkFrame GtkDrawingArea { - background-color: #414141; -} - -#ExpanderBox2 GtkFrame GtkFrame { - background-color: #474747; - border: 1px solid #3D3D3D; - border-radius: 4px; - margin: 3px; - padding: 2px; -} - -#ExpanderBox2 GtkFrame GtkFrame GtkDrawingArea { - background-color: #474747; -} - -#MyExpanderTitle { - margin: 5px; - padding: 3px 1px 3px 1px; - font-size: 120%; -} -#MyExpanderTitle GtkLabel { - color: #CCCCCC; -} -#MyExpanderTitle:hover { - background-color: #202020; -} -#MyExpanderTitle GtkEventBox:hover GtkImage { - background-color: #202020; - border-radius: 3px; -} -#MyExpanderTitle:hover GtkLabel { - color: #D8D8D8; -} - -#ExpanderBox2 GtkSeparator, #ExpanderBox3 GtkSeparator { - color: #292929; -} - -/* Editor tab button */ -#MainNotebook > GtkGrid GtkLabel, #MainNotebook > GtkGrid GtkImage { - /* OK */ - padding: 1px; -} - -/* File Browser right side tabs - Toolbox, Inspector, Fast Export, Filter */ -GtkNotebook tab { - background-color: #383838; - border-width: 1px; - border-style: none; - border-color: #262626; - border-radius: 0; - padding: 3px; -} - -GtkNotebook tab:hover { - background-color: #505050; -} - -GtkNotebook tab:active { - border-width: 5px; - border-color: #989898; -} - -/* Get rid of shitty notebook header shadow */ -GtkNotebook.top tab { - border-bottom-style: solid; - padding-bottom: 8px; -} -GtkNotebook.right tab { - border-left-style: solid; - padding-left: 8px; -} -GtkNotebook.bottom tab { - border-top-style: solid; - padding-top: 8px; -} -GtkNotebook.left tab { - border-right-style: solid; - padding-right: 8px; -} - -/* Get rid of notebook frame border - too many borders */ -GtkNotebook.top.header, GtkNotebook.right.header, GtkNotebook.bottom.header, GtkNotebook.left.header { - box-shadow: none; - border-width: 1px; - border-color: #262626; - border-style: none; - border-radius: 0; - background-color: #383838; - padding: 0; -} -/* Get rid of notebook header border - too many borders */ -GtkNotebook.top.header { - /* OK */ - border-bottom-style: solid; -} -GtkNotebook.right.header { - /* OK */ - border-left-style: solid; -} -GtkNotebook.bottom.header { - /* OK */ - border-top-style: solid; -} -GtkNotebook.left.header { - /* OK */ - border-right-style: solid; -} -GtkNotebook.frame { - /* OK */ - border-radius: 0; - border-style: none; -} - -/* Pad notebooks, makes the other borders look nicer */ -GtkNotebook { - /* OK */ - background-color: #484848; - padding: 0; -} - - -#MainNotebook.header { - /* OK */ - background-color: #2A2A2A; -} -#MainNotebook > tab { - /* OK */ - background-color: #2A2A2A; -} -#MainNotebook > tab:hover { - /* OK */ - background-color: #505050; -} -#MainNotebook > tab:active { - /* OK */ - border-color: #989898; -} - -#RightNotebook.header { - /* OK */ - background-color: #2A2A2A; -} -#RightNotebook > tab { - /* OK */ - background-color: #2A2A2A; -} -#RightNotebook > tab:hover { - /* OK */ - background-color: #505050; -} -#RightNotebook > tab:active { - /* OK */ - border-color: #989898; -} - - -/* All tool panels have a frame except for Meta which unlike the rest is a notebook itself. - * So we use CSS to make it look like a frame. */ -#MetaPanelNotebook.frame { - border: 1px solid #262626; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-top-left-radius: 0; - border-top-right-radius: 0; - border-top-width: 0; -} - -#MetaPanelNotebook.header { - border: 1px solid #262626; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-width: 0; - padding: 5px; - margin: 5px; -} - -.tooltip { - padding: 0; -} - - -/* make the "partial profile" dialog a little bit more readable */ -#PartialPasteHeader { - margin: 1.5em 0 0 0; - padding: 0; - font-weight: bold; - color: #363636; -} - -#PartialPasteHeaderSep { - color: #D8D8D8; -} - - -#MyFileChooserButton { - padding-left: 3px; - padding-right: 3px; -} - -/* Better on/off state separation for text toggle buttons, e.g. auto-levels or histogram matching. */ -GtkToggleButton.button.text-button { - background-image: linear-gradient(to bottom, rgba(100,100,100,.3), rgba(30,30,30,.3)); -} - -GtkToggleButton.button.text-button:hover { - background-image: linear-gradient(to bottom, rgba(128,128,128,.3), rgba(64,64,64,.3)); -} - -GtkToggleButton.button.text-button:checked { - background-image: linear-gradient(to bottom, rgba(30,30,30,.3), rgba(0,0,0,.4)); -} - -GtkToggleButton.button.text-button:hover:checked { - background-image: linear-gradient(to bottom, rgba(48,48,48,.3), rgba(0,0,0,.3)); -} diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee.css similarity index 99% rename from rtdata/themes/RawTherapee-GTK3-20_.css rename to rtdata/themes/RawTherapee.css index e909eb33f..3a3162c4e 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee.css @@ -19,7 +19,7 @@ */ /***************************/ -/**/ @import "size.css"; /**/ /* TODO: Remove this weird dependency */ +/**/ @import url("./common/size.css"); /**/ /* TODO: Remove this weird dependency */ /***************************/ /** Set style defaults **/ @@ -1068,7 +1068,7 @@ dialog frame > label:not(.dummy) { } #ToolPanelNotebook viewport { - padding: 0; + padding: 0; } #ToolPanelNotebook .PanelEnding { @@ -1226,7 +1226,7 @@ dialog frame > label:not(.dummy) { border-top-width: 0.083333333333333333em; } -#Navigator box label { +#Navigator box label { margin: 0; padding: 0; } diff --git a/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css b/rtdata/themes/TooWaBlue - Bright.css similarity index 98% rename from rtdata/themes/TooWaBlue - Bright-GTK3-20_.css rename to rtdata/themes/TooWaBlue - Bright.css index 19e2eb049..6b12db47c 100644 --- a/rtdata/themes/TooWaBlue - Bright-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue - Bright.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css b/rtdata/themes/TooWaBlue - Dark.css similarity index 98% rename from rtdata/themes/TooWaBlue - Dark-GTK3-20_.css rename to rtdata/themes/TooWaBlue - Dark.css index 5875e2132..d9ca22dff 100644 --- a/rtdata/themes/TooWaBlue - Dark-GTK3-20_.css +++ b/rtdata/themes/TooWaBlue - Dark.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaBlue-GTK3-_19.css b/rtdata/themes/TooWaBlue-GTK3-_19.css deleted file mode 100644 index 31676ca8d..000000000 --- a/rtdata/themes/TooWaBlue-GTK3-_19.css +++ /dev/null @@ -1,881 +0,0 @@ -/* - This file is part of RawTherapee. - - Copyright (c) 2016 TooWaBoo (v1.19.5) - Many thanks to the RawTherapee Developer Team for this great piece of software - - RawTherapee is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - RawTherapee is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RawTherapee. If not, see . -*/ - -/*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ - -@define-color accent-color rgb(35,99,166); /*** Highlight/selected color for Tab indicator, List, Dropdown menu, Borders ... ***/ -@define-color text-hl-color rgb(210,210,210); /*** Highlight/selected text color ***/ - -@define-color accent-color2 rgb(35,99,166); /*** Slider, Progressbar, Scrollbar ***/ -@define-color accent-color4 rgb(35,99,166); /*** Slider knob ***/ - -@define-color accent-color3 rgb(35,99,166); /*** Selected thumbnail background color ***/ -@define-color text-hl-color3 rgb(210,210,210); /*** Selected thumbnail text color ***/ - -/*** Change me end ************************************************************************/ - -@define-color text-color rgb(180,180,180); -@define-color text-hl-color2 rgb(192,192,192); -@define-color text-tbEntry rgb(192,192,192); -@define-color bg-dark-grey rgb(36,36,36); -@define-color bg-grey rgb(70,70,70); -@define-color bg-light-grey rgb(88,88,88); -@define-color border-color rgba(255,255,255,.25); -@define-color bg-list-hover rgba(255,255,255,.065); -@define-color bg-scale-entry rgba(0,0,0,.14); -@define-color bg-button-border rgba(0,0,0,.48); -@define-color bg-button-border-hover rgba(0,0,0,.58); -@define-color bg-entry-border rgba(0,0,0,.40); -@define-color bg-button-hover rgba(0,0,0,.22); -@define-color bg-spin-button-hover rgba(0,0,0,.25); -@define-color bg-entry-IPTC @bg-dark-grey; -@define-color view-grid-border rgb(64,64,64); - -* { - color: @text-color; - transition: none; - text-shadow: none; - icon-shadow: none; - box-shadow: none; - outline-style: none; /* removes the ugly dotted focus line */ - border-image: none; - -GtkCheckButton-indicator-size: 16; - -GtkCheckMenuItem-indicator-size: 16; - -GtkCheckButton-indicator-spacing: 2; -} - -.undershoot { - background-image: none; /* removes the dotted scrollbar line */ -} -GtkWindow { - background-color: @bg-light-grey; -} -GtkDialog { - background-color: @bg-grey; - -GtkDialog-content-area-spacing: 7; - -GtkDialog-action-area-border: 0; - -GtkDialog-content-area-border: 8; -} - -GtkFontChooser, -GtkColorChooser { - -GtkDialog-action-area-border: 4; - -GtkDialog-content-area-border: 0; -} - -.frame { - border: none; -} -#PrefNotebook > .frame { - border: 1px solid rgba(0,0,0,.50); - border-top: none; -} -#BatchQueueButtonsMainContainer GtkFrame { - padding: 4px 4px 4px 10px; -} - -/*** Add space between buttons and image area***/ -#BeforeAfterContainer GtkFrame { - padding: 2px 0 4px; -} -/*** Add space between before/after image ***/ -#BeforeAfterContainer GtkContainer:nth-child(1) > GtkContainer:nth-child(2) GtkFrame { - padding-right: 14px; -} - -/*** Menu bubble box ***/ -GtkPopover { - background-color: @bg-grey; - border: 1px solid @accent-color; - border-radius: 0; -} - -.menu { - background-color: @bg-dark-grey; - border: 1px solid @accent-color; -} -.menu > .menuitem { - padding: 2px 4px; -} -.menu > .menuitem:hover { - background-color: @accent-color; -} -.menu > .menuitem:hover > * > *, -.menu > .menuitem:hover > * { - color: @text-hl-color; -} - -GtkNotebook { - padding: 4px; - background-color: @bg-light-grey; -} -GtkDialog GtkNotebook { - padding: 2px 0 0; -} -#PrefNotebook { - padding: 4px 8px; -} -#RightNotebook { - padding: 0 0 0 4px; -} - -GtkPaned { - -GtkPaned-handle-size: 4px; - background-color: transparent; -} -.pane-separator { - background-color: @bg-light-grey; -} -GtkDialog .pane-separator { - background-color: @bg-grey; -} - -/*** Separator ***/ -.separator { - color: @bg-light-grey; -} -GtkDialog .separator { - color: @border-color; -} -#RightNotebook .separator { - color: @bg-dark-grey; -} - /*** Navigator ***/ -#Navigator .separator { - color: @view-grid-border; -} -/*** end ***/ - -/*** Background color image area***/ -GtkDrawingArea { - background-color: @bg-grey; - border: 1px solid rgba(0,0,0,.32); -} -/*** Histogram ***/ -#HistogramPanel, -#HistogramArea { - background-color: @bg-dark-grey; - border: none; -} -/*** Histogram RGB-Bar***/ -#HistogramRGBArea { - background-color: rgb(128,128,128); - border: none; -} -/*** Navigator ***/ -#Navigator GtkDrawingArea { - background-color: @bg-dark-grey; - border: 1px solid @bg-dark-grey; -} -#Navigator { - background-color: @bg-dark-grey; - border-top: 156px solid @bg-light-grey; -} - -#RightNotebook GtkDrawingArea { - background-color: @bg-dark-grey; -} - -/*** Label ***/ - .label { - padding: 0 4px; -} - /*** Increase space between labels in navigater ***/ -#Navigator .label { - padding: 6px 0 3px; -} -#Navigator GtkTable .label { - padding: 0 0 4px; -} - /***/ -GtkDialog .label, -#ToolPanelNotebook .label, -.notebook tab .label { - padding: 0 1px; -} -.button .label { - padding: 0; -} - - /*** Add left and right space between frame and labels ***/ -.frame > .label, -#ToolPanelNotebook .frame > .label { - padding: 4px; -} -#BatchQueueButtonsMainContainer GtkFrame:nth-child(3) > .label{ - padding: 2px 0px 4px; -} - -#MyExpanderTitle .label { - padding: 2px 3px; -} -/*** end ***/ - -.tooltip { - border-radius: 0; - padding: 0; -} -.tooltip.background { - background-color: @bg-dark-grey; - border: 1px solid @accent-color; -} - -/*** PartialPaste ***/ -#PartialPaste:nth-child(2) { - background-color: @bg-light-grey; - border: 1px solid rgba(0,0,0,.50); -} -#PartialPaste > .frame { - padding: 8px 10px; -} -#PartialPasteHeaderSep { - color: rgb(192,192,192); -} -#PartialPasteHeader .label { - color: rgb(213,213,213); -} -/*** end ***/ - -/*** Scrollbar ***/ -.scrollbar.trough { - background-color: rgba(0,0,0,.38); - background-image: none; - border: none; -} -.scrollbar.slider:active { - background-color: shade(@accent-color2,1.12); -} - -/*** end ***/ - -/*** Scale & Progressbar ***/ -.scale { - box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px rgba(242, 242, 242, 0.1); - -GtkRange-trough-border: 6; - -GtkScale-slider-length: 15; - -GtkRange-slider-width: 15; -} -.scale.trough, -#ToolPanelNotebook .scale.trough { - background-color: @bg-scale-entry; - border-color: @bg-dark-grey; - box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px rgba(242, 242, 242, 0.1); -} -.scale.trough.highlight, -#ToolPanelNotebook .scale.trough.highlight { - box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px rgba(242, 242, 242, 0.1); - background-image: none; - background-color: @accent-color2; - border: 1px solid @bg-dark-grey; - color: @text-hl-color2; -} -.scale.slider, -#ToolPanelNotebook .scale.slider { - background-image: linear-gradient(to bottom, shade (@accent-color4,1.15), shade (@accent-color4,.85)); - border: 1px solid shade(@bg-dark-grey, 1.25); - box-shadow: none; -} -.scale.fine-tune { - -GtkRange-trough-border: 5; -} -.scale.scale-has-marks-below { - -GtkRange-trough-border: 6; - -GtkScale-slider-length: 6; - -GtkRange-slider-width: 19; -} -.scale.slider.scale-has-marks-below { - border-radius: 0 0 20px 20px; - border: 1px solid @bg-dark-grey; -} -.scale.fine-tune.scale-has-marks-below { - -GtkRange-trough-border: 5; -} -.scale.slider:hover, -#ToolPanelNotebook .scale.slider:hover { - background-image: linear-gradient(to bottom, shade (@accent-color4,1.25), shade (@accent-color4,.95)); -} - -.scale.slider:active, -#ToolPanelNotebook .scale.slider:active { - background-image: linear-gradient(to bottom, shade (@accent-color4,1.25), shade (@accent-color4,.95)); -} - -GtkProgressBar { - -GtkProgressBar-min-vertical-bar-width: 8; - -GtkProgressBar-min-horizontal-bar-height: 8; - -GtkProgressBar-yspacing: 4px; - border-radius: 10px; - box-shadow: inset 0 1px rgba(255, 255, 255, 0.1), 0 1px rgba(242, 242, 242, 0.1); -} -.progressbar { - background-image: none; - background-color: @accent-color2; - border-color: @bg-dark-grey; -} -GtkProgressBar.trough { - background-image: none; - background-color: @bg-scale-entry; -} -#MainNotebook > GtkGrid GtkProgressBar { - box-shadow: none; -} -#MainNotebook > GtkGrid GtkProgressBar.trough { - background-image: none; - background-color: @bg-dark-grey; - border-color: @bg-dark-grey; -} -/*** end ***/ - -/*** Load/Save ***/ -GtkFileChooserWidget { - background-color: @bg-grey; -} -GtkFileChooserWidget > GtkBox { - border-bottom-color: @bg-dark-grey; -} -GtkFileChooserWidget GtkBox { - background-color: transparent; -} -GtkFileChooserWidget GtkListBox * { - padding-top: 1px; - padding-bottom: 1px; -} -GtkFileChooserWidget GtkListBox { - background-color: @bg-dark-grey; -} -GtkFileChooserWidget .list-row * { - padding: 1px 4px; -} -GtkFileChooserWidget .list-row:hover { - background-color: @bg-list-hover; -} -GtkFileChooserWidget .list-row:hover * { - color: @text-hl-color2; -} -GtkFileChooserWidget .list-row:selected { - background-color: @accent-color; -} -GtkFileChooserWidget .list-row:selected * { - color: @text-hl-color; -} -/*** end ***/ - -/*** Tab Bars ***/ -.notebook tab, .notebook.header { - background-color: @bg-dark-grey; - border-color: @bg-dark-grey; -} -#MainNotebook tab { - padding: 5px; -} -.notebook tab.top { - border-width: 0 0 5px 0; -} -.notebook tab.left { - border-width: 0 5px 0 0; -} -#RightNotebook tab.left, -#PrefNotebook tab, -GtkDialog tab { - padding: 9px; -} -#ToolPanelNotebook tab { - padding: 10px 2px 7px; -} -#MetaPanelNotebook tab { - padding: 8px 4px; -} - -.notebook tab:active { - border-color: @accent-color; -} - -/*** end ***/ - -/*** File Browser ***/ -#FileBrowser GtkDrawingArea { - background-color: @bg-grey; -} -#FileBrowser GtkDrawingArea:selected { - background-color: @accent-color3; - color: @text-hl-color3; -} -/*** end ***/ - -/*** Image ***/ -GtkImage { - padding: 0; -} -#MainNotebook > GtkGrid GtkImage { - padding: 1px; -} - -#ToolPanelNotebook GtkImage{ - padding: 0 4px; -} -#MyExpanderTitle GtkImage{ - padding: 0; -} - -#ToolPanelNotebook tab GtkImage, -#ToolPanelNotebook .button GtkImage { - padding: 1px 0; -} - -GtkDialog .button GtkImage{ - padding: 0; -} -GtkFileChooserWidget .button GtkImage{ - padding: 0 4px; -} -/*** end ***/ - -/*** Toolpanel ***/ -#ToolPanelNotebook { - background-color: @bg-dark-grey; - padding: 0; - border-top: 4px solid @bg-dark-grey; -} - -#ToolPanelNotebook GtkScrolledWindow GtkViewport.frame { - padding: 0 4px; -} -#ToolPanelNotebook .separator { - color: transparent; -} -#ToolPanelNotebook GtkFrame, -#PrefNotebook GtkFrame { - border: 1px solid @border-color; - border-radius: 0; - padding: 5px; -} - -#ToolPanelNotebook GtkDrawingArea { - background-color: @bg-dark-grey; - border-color: @bg-light-grey; - color: @text-color; -} -#ToolPanelNotebook GtkDrawingArea { - border-radius: 1px; /* BUG: if 0, scale mini sliders look funny */ -} - -#ExpanderBox #ExpanderBox, -#ExpanderBox2, -#ExpanderBox3 { - border: 1px solid @border-color; -} - -#ExpanderBox, -#ExpanderBox2, -#ExpanderBox3 { - background-color: @bg-grey; - border-radius: 0; -} - -#MyExpanderTitle .label { - color: @text-color; -} -#MyExpanderTitle:hover .label { - color: @text-hl-color2; -} -/*** end ***/ - -/*** View ***/ -.view { - background-color: @bg-dark-grey; - border-color: @view-grid-border; -} -#PrefNotebook .view { - background-color: @bg-grey; -} -#MainNotebook .view.cell:nth-child(2) { - padding: 1px 0px 1px 4px; -} -.view row:hover { - background-color: @bg-list-hover; - color: @text-hl-color2; -} -#PrefNotebook .view row:hover { - background-color: @bg-light-grey; - color: @text-hl-color2; -} -.view row:selected { - color: @text-hl-color; - background-color: @accent-color; -} -#PrefNotebook .view row:selected { - color: @text-hl-color; - background-color: @accent-color; -} -/*** end ***/ - -/*** Metadata ***/ -#MetaPanelNotebook { - padding: 8px 11px 0; -} -#MetaPanelNotebook GtkScrolledWindow GtkViewport.frame { - padding: 8px 10px; -} -#MetaPanelNotebook.frame { - background-color: @bg-grey; - border-bottom: none; - border-top: 4px solid @bg-dark-grey; - border-left: 9px solid @bg-dark-grey; - border-right: 9px solid @bg-dark-grey; -} -#MetaPanelNotebook .separator { - color: @border-color; -} -#MetaPanelNotebook.header { - background-color: @bg-dark-grey; - -} -#MetaPanelNotebook GtkTreeView { - padding: 1px; - background-color: @bg-grey; -} -#MetaPanelNotebook .frame GtkTreeView { - padding: 0px; - background-color: @bg-entry-IPTC; -} -#MetaPanelNotebook GtkTreeView:hover, -#MetaPanelNotebook .frame GtkTreeView:hover { - background-color: @bg-list-hover; - color: @text-hl-color; -} -#MetaPanelNotebook GtkTreeView:selected, -#MetaPanelNotebook .frame GtkTreeView:selected { - color: @text-hl-color; - background-color: @accent-color; -} -#MetaPanelNotebook GtkTextView { - color: @text-color; - background-color: @bg-entry-IPTC; - padding: 2px 4px; -} -/*** end ***/ - -/*** Entry ***/ -.entry { - background-image: none; - background-color: @bg-scale-entry; - border: 1px solid @bg-entry-border; - border-radius: 0; - padding: 2px 4px; - color: @text-color; - box-shadow: inset 1px 1px rgba(0, 0, 0, 0.08), 0 1px rgba(242 , 242, 242, 0.1); -} -#FileBrowser .entry { - padding: 3px 4px; -} -.entry:focused:selected { - color: @text-hl-color; - background-color: @accent-color; -} -.entry:not(:focused):not(:insensitive) {/*Workaround*/ - color: @text-color; - background-color: transparent; -} -.entry:not(:selected):not(:insensitive) { - color: @text-color; - background-color: @bg-scale-entry; -} -#ToolPanelNotebook .entry { - padding: 0 4px 0 8px; - border-radius: 20px 0 0 20px; - background-color: rgba(255,255,255,.12); - border: 1px solid rgba(0,0,0,.46); - color: @text-tbEntry; - box-shadow: inset 1px 1px rgba(0, 0, 0, .12), 0 1px rgba(255 , 255, 255, 0.12); -} -#ToolPanelNotebook .entry:focused:selected { - color: @text-hl-color; - background-color: @accent-color; -} -#ToolPanelNotebook .entry:not(:focused):not(:insensitive) {/*Workaround*/ - color: @text-tbEntry; - background-color: transparent; -} -#ToolPanelNotebook .entry:not(:selected):not(:insensitive) { - color: @text-tbEntry; - background-color: rgba(255,255,255,.12); -} - -#MetaPanelNotebook .entry { - color: @text-color; - background-color: @bg-entry-IPTC; - border: none; - border-radius: 0; - padding: 2px 4px; - box-shadow: none; -} -#MetaPanelNotebook .entry:focused:selected { - color: @text-hl-color; - background-color: @accent-color; - box-shadow: none; -} -#MetaPanelNotebook .entry:not(:focused):not(:insensitive) {/*Workaround*/ - color: @text-color; - background-color: transparent; - box-shadow: none; -} -#MetaPanelNotebook .entry:not(:selected):not(:insensitive) { - color: @text-color; - background-color: @bg-entry-IPTC; - box-shadow: none; -} -/*** end ***/ - -/*** Buttons ***/ -.button { - background-color: transparent; - border: 1px solid @bg-button-border; - border-radius: 0; - padding: 3px 4px; - box-shadow: inset 0 1px rgba(242, 242, 242, 0.1), 0 1px rgba(242, 242, 242, 0.1); - background-image: linear-gradient(to bottom, rgba(0,0,0,.05), rgba(0,0,0,.14) 40%, rgba(0,0,0,.26)); -} -.message-dialog .dialog-action-area .button { - padding: 6px; - } - -.button.Left + .button:not(.image-button).Right { - border-left: none; -} -GtkComboBox .button { - padding: 4px 3px; -} -#ToolPanelNotebook .button, -GtkDialog .button, -#BatchQueueButtonsMainContainer .button { - padding: 0px 3px; -} -#BatchQueueButtons .button { - padding-top: 6px; - padding-bottom: 6px -} -#BeforeAfterContainer .button { - padding: 2px; -} - - /*** Fix: Space between first Retinex Comboboxes ***/ -GtkLabel + GtkComboBox + GtkComboBox { - padding-left: 4px; -} - -.text-button { - padding: 0 2px 0 0; -} -#PartialPaste .text-button { - padding: 0 8px 0 2px; - -GtkCheckButton-indicator-spacing: 1; -} -#ToolPanelNotebook GtkFrame > .text-button { - padding: 0 3px 0 0; -} - -.button.text-button { - padding: 5px 12px; -} -#ToolPanelNotebook .button.text-button, -#PrefNotebook .button.text-button, -GtkFileChooserWidget .button.text-button, -#RightNotebook .button.text-button { - padding: 3px 4px; -} -GtkPopover .button.text-button { - padding: 2px 4px; -} - -.spinbutton .button { - background-image: none; - background-color: transparent; - border: none; - border-radius: 0; - padding: 2px; - box-shadow: none; -} -#ToolPanelNotebook .spinbutton .button { - padding: 0; -} - -.button:hover { - background-color: rgba(0, 0, 0,.18); -} -#ToolPanelNotebook .spinbutton .button:hover { - background-color: @bg-spin-button-hover; -} - -.button:active, -.button:checked { - background-image: linear-gradient(to bottom, rgb(41,41,41), rgb(37,37,37) 40%, rgb(25,25,25)); - background-color: transparent; - border-color: black; -} - -#MainNotebook > GtkGrid .button { - padding: 2px; - border: 4px solid @bg-dark-grey; - background-color: transparent; - background-image: none; - box-shadow: none; -} -#MainNotebook tab .button { - padding: 1px; - border-top: 4px solid @bg-dark-grey; - border-bottom: 4px solid @bg-dark-grey; - border-left: none; - border-right: none; - background-color: transparent; - background-image: none; - box-shadow: none; -} -#MainNotebook > GtkGrid .button:hover, -#MainNotebook tab .button:hover { - background-color: rgba(255,255,255,.20); - box-shadow: inset 0 1px rgba(255, 255, 255, 0.12); - background-image: linear-gradient(to bottom, rgba(0,0,0,.05), rgba(0,0,0,.12) 40%, rgba(0,0,0,.24)); -} -#MainNotebook > GtkGrid .button:active, -#MainNotebook tab .button:active { - background-color: rgba(255,255,255,.27); - box-shadow: inset 0 1px rgba(255, 255, 255, 0.12); - background-image: linear-gradient(to bottom, rgba(0,0,0,.05), rgba(0,0,0,.12) 40%, rgba(0,0,0,.24)); -} -.view .button { - background-color: rgb(20,20,20); - padding: 1px 5px 2px; - background-image: none; - border-color: black; - box-shadow: none; -} -.menu .button.bottom, -.menu .button.bottom:insensitive { - background-color: rgb(20,20,20); - border-color: @accent-color; - border-width: 0 1px 1px 1px; - background-image: none; - box-shadow: none; -} -.menu .button.top, -.menu .button.top:insensitive { - background-color: rgb(20,20,20); - border-color: @accent-color; - border-width: 1px 1px 0 1px; - background-image: none; - box-shadow: none; -} -#fullButton, -#histButton { - padding: 5px; - border: none; - background-color: @bg-dark-grey; - background-image: none; - box-shadow: none; -} -/*** end ***/ - -/*** Check & Radio buttons ***/ -.check, -.check row { - -gtk-icon-source: url("images/twb/checkbox-unchecked.png"); -} -.check:checked, -.check row:checked { - -gtk-icon-source: url("images/twb/checkbox-checked.png"); -} -.check:insensitive, -.check row:insensitive { - -gtk-icon-source: url("images/twb/checkbox-unchecked-disabled.png"); -} -.check:checked:insensitive, -.check row:checked:insensitive { - -gtk-icon-source: url("images/twb/checkbox-checked-disabled.png"); -} -.check:inconsistent, -.check row:inconsistent { - -gtk-icon-source: url("images/twb/checkbox-inconsistent.png"); -} -.check:inconsistent:insensitive, -.check row:inconsistent:insensitive { - -gtk-icon-source: url("images/twb/checkbox-inconsistent-disabled.png"); -} - -.radio, -.radio row { - -gtk-icon-source: url("images/twb/radio-unchecked.png"); -} -.radio:checked, -.radio row:checked { - -gtk-icon-source: url("images/twb/radio-checked.png"); -} -.radio:insensitive, -.radio row:insensitive { - -gtk-icon-source: url("images/twb/radio-unchecked-disabled.png"); -} -.radio:checked:insensitive, -.radio row:checked:insensitive { - -gtk-icon-source: url("images/twb/radio-checked-disabled.png"); -} -.radio:inconsistent, -.radio row:inconsistent { - -gtk-icon-source: url("images/twb/radio-inconsistent.png"); -} -.radio:inconsistent:insensitive, -.radio row:inconsistent:insensitive { - -gtk-icon-source: url("images/twb/radio-inconsistent-disabled.png"); -} -/*** end ***/ - -/*** Disabled Items ***/ - -*:insensitive, -#ToolPanelNotebook *:insensitive { - color: rgb(128,128,128); - box-shadow: none; -} -#ToolPanelNotebook .entry:insensitive { - color: rgb(144,144,144); - background-color: rgba(255,255,255,.06); - box-shadow: none; -} -.button:insensitive { - background-image: none; - background-color: rgba(0,0,0,.10); - border-color: rgba(0,0,0,.30); - box-shadow: none; -} -.spinbutton .button:insensitive { - background-image: none; - background-color: transparent; - border: none; - box-shadow: none; -} -.scale.slider:insensitive, -.scale.trough.highlight:insensitive, -.scale.trough:insensitive, -#ToolPanelNotebook .scale.slider:insensitive, -#ToolPanelNotebook .scale.trough.highlight:insensitive, -#ToolPanelNotebook .scale.trough:insensitive { - background-color: rgb(65,65,65); - box-shadow: none; - background-image: none; -} -/*** end ***/ diff --git a/rtdata/themes/TooWaBlue-GTK3-20_.css b/rtdata/themes/TooWaBlue.css similarity index 100% rename from rtdata/themes/TooWaBlue-GTK3-20_.css rename to rtdata/themes/TooWaBlue.css diff --git a/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css b/rtdata/themes/TooWaGrey - Average Surround.css similarity index 98% rename from rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css rename to rtdata/themes/TooWaGrey - Average Surround.css index 8f045e206..1574edf03 100644 --- a/rtdata/themes/TooWaGrey - Average Surround-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Average Surround.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css b/rtdata/themes/TooWaGrey - Bright.css similarity index 98% rename from rtdata/themes/TooWaGrey - Bright-GTK3-20_.css rename to rtdata/themes/TooWaGrey - Bright.css index 579ca7a00..34120efe7 100644 --- a/rtdata/themes/TooWaGrey - Bright-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Bright.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css b/rtdata/themes/TooWaGrey - Dark.css similarity index 98% rename from rtdata/themes/TooWaGrey - Dark-GTK3-20_.css rename to rtdata/themes/TooWaGrey - Dark.css index 8d6d05152..9ef4dda31 100644 --- a/rtdata/themes/TooWaGrey - Dark-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey - Dark.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/TooWaGrey-GTK3-20_.css b/rtdata/themes/TooWaGrey.css similarity index 98% rename from rtdata/themes/TooWaGrey-GTK3-20_.css rename to rtdata/themes/TooWaGrey.css index 0b29ed2e7..ba3910d9c 100644 --- a/rtdata/themes/TooWaGrey-GTK3-20_.css +++ b/rtdata/themes/TooWaGrey.css @@ -20,7 +20,7 @@ /*****************************************/ -/**/ @import "TooWaBlue-GTK3-20_.css"; /**/ +/**/ @import "TooWaBlue.css"; /**/ /*****************************************/ /*** Change me *** rgb(red,green,blue) *** allowed values from 0 to 255 for each color ***/ diff --git a/rtdata/themes/size - Legacy.css b/rtdata/themes/common/size - Legacy.css similarity index 100% rename from rtdata/themes/size - Legacy.css rename to rtdata/themes/common/size - Legacy.css diff --git a/rtdata/themes/size.css b/rtdata/themes/common/size.css similarity index 100% rename from rtdata/themes/size.css rename to rtdata/themes/common/size.css diff --git a/rtdata/themes/images/svg/twb/checkbox-checked-disabled.svg b/rtdata/themes/images/svg/twb/checkbox-checked-disabled.svg deleted file mode 100644 index 1103ee917..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-checked-disabled.svg +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/checkbox-checked.svg b/rtdata/themes/images/svg/twb/checkbox-checked.svg deleted file mode 100644 index c7d28d45d..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-checked.svg +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/checkbox-inconsistent-disabled.svg b/rtdata/themes/images/svg/twb/checkbox-inconsistent-disabled.svg deleted file mode 100644 index ee55c4f6f..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-inconsistent-disabled.svg +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/checkbox-inconsistent.svg b/rtdata/themes/images/svg/twb/checkbox-inconsistent.svg deleted file mode 100644 index e0f5bd362..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-inconsistent.svg +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/checkbox-unchecked-disabled.svg b/rtdata/themes/images/svg/twb/checkbox-unchecked-disabled.svg deleted file mode 100644 index 635dae59b..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-unchecked-disabled.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/checkbox-unchecked.svg b/rtdata/themes/images/svg/twb/checkbox-unchecked.svg deleted file mode 100644 index 0adfe66cc..000000000 --- a/rtdata/themes/images/svg/twb/checkbox-unchecked.svg +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-checked-disabled.svg b/rtdata/themes/images/svg/twb/radio-checked-disabled.svg deleted file mode 100644 index f415b4be7..000000000 --- a/rtdata/themes/images/svg/twb/radio-checked-disabled.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-checked.svg b/rtdata/themes/images/svg/twb/radio-checked.svg deleted file mode 100644 index c6f9b4ee8..000000000 --- a/rtdata/themes/images/svg/twb/radio-checked.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-inconsistent-disabled.svg b/rtdata/themes/images/svg/twb/radio-inconsistent-disabled.svg deleted file mode 100644 index e41f3ff9c..000000000 --- a/rtdata/themes/images/svg/twb/radio-inconsistent-disabled.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-inconsistent.svg b/rtdata/themes/images/svg/twb/radio-inconsistent.svg deleted file mode 100644 index 65ea2a8e8..000000000 --- a/rtdata/themes/images/svg/twb/radio-inconsistent.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-unchecked-disabled.svg b/rtdata/themes/images/svg/twb/radio-unchecked-disabled.svg deleted file mode 100644 index 60098048f..000000000 --- a/rtdata/themes/images/svg/twb/radio-unchecked-disabled.svg +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/rtdata/themes/images/svg/twb/radio-unchecked.svg b/rtdata/themes/images/svg/twb/radio-unchecked.svg deleted file mode 100644 index 8b448f3cf..000000000 --- a/rtdata/themes/images/svg/twb/radio-unchecked.svg +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/rtdata/themes/images/twb/checkbox-checked-disabled.png b/rtdata/themes/images/twb/checkbox-checked-disabled.png deleted file mode 100644 index 8458b5987ff7050bfa6fa4733ac1fdb6c00b8092..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4Xgt=Z zV||aM?)TSwXR^xFPBI=>QOdNvdN%rpwJJlJ?MHEJ;>XkBwCQX}Er=siLBrCK`?fspE_9wcm zhaYe`b58L8dXo3wq<{V~9=EtHo{OcKiOslqTv7OUf%*-G diff --git a/rtdata/themes/images/twb/checkbox-checked.png b/rtdata/themes/images/twb/checkbox-checked.png deleted file mode 100644 index 83d3744d3c627a13cc04fab355088f9547c3f4cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 428 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4nhK;|bxBQuX(3GB>SSHDk)AewS05Vq|9(YNpQbs0(6Zi2QsZsz0eG`2Ans z$Z6X5cqEdipR=63>CE%b-0%NNH!uqBWst~c1q!WNwNO^$|D07^ch`f#=KW!>m5H&}12s)^IIUDHw(Q*O*#5+pmAN|n#&iY=`C01H zb0+07E4uh=mWl{CeR1N*b>w(BxucJ(ERo^Cu^GKnKK-e0{h!oxbIz%fXX3VXJqlm0 S1bYHQmci52&t;ucLK6TJt)}Jx diff --git a/rtdata/themes/images/twb/checkbox-inconsistent-disabled.png b/rtdata/themes/images/twb/checkbox-inconsistent-disabled.png deleted file mode 100644 index 96c5fbe5f2a09eb89d3eb9b25ab3b0e545de3067..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4f;?skDA$93k5ia$#`{n=>KoF^QW144 zE@uvy9VuVLx?rM-%ua?WlWxWMGk7we{Kw%?#Azd09)2);(jSYxhi3n^KFG~b?Oh`N zEr*HW=`W8v;+IwP7(ajhvvj8=^P;8wg`pqY(pT#roTYhPyLh?~&_xWMu6{1-oD!M< DHcDHP diff --git a/rtdata/themes/images/twb/checkbox-inconsistent.png b/rtdata/themes/images/twb/checkbox-inconsistent.png deleted file mode 100644 index 373f218be58be281a9fe270ec7d946e83f556ef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4<` zTx6M>^h_u@#M?z!$*zjgrG&ZR=({$v~Fd+PR-U-&MYEzjb@P^dH6ryN;}G{kyHPIL}AZl=-%59aBiDUHpxy=YU>3eJ1s{ hL~PQtOS4zLVqI2d+!}eeM;Pc{22WQ%mvv4FO#s^ZYrOyf diff --git a/rtdata/themes/images/twb/checkbox-unchecked-disabled.png b/rtdata/themes/images/twb/checkbox-unchecked-disabled.png deleted file mode 100644 index 985dd07cc239709ac9f75c1a3c37ac9c54ae0d41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4b|U3J0F9t_qWH*PQRaU$~!nfzl=K-8KxfOl|fv z@F+d2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR43D3D49S*8GfEG9~WazOPL#Cay<{&iFof7p zHAQnoP3*`Bx|)}e|7g2{(zN2kb%lJ)3@OH|e<$-Krj?o$pJbnWO>d6Y6ebs-!x%hW L{an^LB{Ts5)@5O6 diff --git a/rtdata/themes/images/twb/radio-checked-disabled.png b/rtdata/themes/images/twb/radio-checked-disabled.png deleted file mode 100644 index 0947a5e06a5a9b67e40811f66ce3071b45f5e41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 524 zcmV+n0`vWeP)ZQcDvI+1*ie1z?P)J_*|TV zwSXDmqojUH{{`$h=MKF0?U487RRy8!ePBUSUs4rl0Q0~N(3EuOoXdOfe*hcfb|Qe# zvy;@f)~*5_;1e(fECL;C?OKu~&&C*+t{@7&3>*WDMx%OmP(iN+e*%2Y0zLqbA)fme zAhbiFQ1~74UjhEcaXcO3y9t0>fL^ax0{&zHXM@3D1;7}i2>=Ta^3Jk=9iZl%%QqU0 zBV$YzxCZ*bl`*C&>DW1!2a+g?cE^D9NBR!T=5o39BuSpL*M}!;1NV|P$9noBZ2>Ls z{ZDJ{c9`}9Py#C6`vf=wzNNu$c0tk-kluwy;5>?=-Fm%#IblBk(Ov)m=$0F&t&1f9 O0000Vr3`+raI1IeaGTNO-LsOZhCe4?)lz3 z-N8SGEGE)4ZHvgJst%oZt4(-$Igr7X*PQ52mmIxxmGJljM8Dr}EEbD2v=ZhUgh7DjJAkXuzaStn%$_ntv_>SQL zaII``4mh#=qT#UJZvRS>2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR42P&@K&#R-R_+gPNut)-({q`okIk@Ru6 z!sfedC&SseP33G(NssU67+L?{Zfw2#gS+cdhvk=7uD$+RdI8&!1MCLOzmz_05mrzV zd%-B~a6QVp?{S6U{PWrlvKdUm3lx`jAG3KY?xdgFax>@Hfl9#w79D=Z zDW{*7&!5j+6Pc~u&JeabRP=`q)3VH2adJ!_DlaQ7;5V6DytFoL|9pvLHp>S2lP;m{ zyA|qMoD;5OZJoEd;>QFj2mjFc+i%OR-~Yz6f~hprw?VK#x~cvztDq(Gq5T_J(vHn= etoZc*q8RU^pm3E32rm#Lxr37|cP{e) zL9)`pBS4FwNtKSq&B}K%ohAM}K=KSJ-~v^A=f;|)@gbihEK4-}s?lhF-^^-e;Ej^i zM3N+J5jhMYw1E%6UlF-c)$?w*d;2P2GMTtM&(DB;;AB3Zk6W$QeU@e0su}~wz*Q7Q zgHES2FMX~I7UqvdQGDw6`_rW&e}M1a`%CBCaPjVIrGq3%+Q5&ZD0WxO6?yNQ*4keo zgfHcH41kCn0;lWD0KH!CpNO1_$V&$XAcW91#{67oE~TntV6OrIwx-i*wh6#m`v7dM z0-kEM+V&=Z5W)`dSOJL0wR7%Z6M(870M`|Os-6SK-uvb{v-iF!B1guUiwa;dk}K!j z@HL3{zUiDBh7i&?j_=C+%OXWlG|2P(%v$?9P16%q9nWU7`+B{;1H>Y7q^fD7(fGCu t{_hq>qtWNZUX-_x0XN2&i{;AiN6)!|l0CFKsgM8w002ovPDHLkV1jeD;Q{~v diff --git a/rtgui/options.h b/rtgui/options.h index 235b1b26f..ccde54256 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -37,7 +37,7 @@ #define STARTUPDIR_CUSTOM 2 #define STARTUPDIR_LAST 3 -#define THEMEREGEXSTR "^(.+)-GTK3-(\\d{1,2})?_(\\d{1,2})?\\.css$" +#define THEMEREGEXSTR "^(.+)\\.css$" // Default bundled profile name to use for Raw images #ifdef WIN32 diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 393744a1b..4dd6eae4f 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -139,14 +139,11 @@ Preferences::~Preferences() get_size(options.preferencesWidth, options.preferencesHeight); } -int Preferences::getThemeRowNumber (const Glib::ustring& longThemeFName) +int Preferences::getThemeRowNumber (const Glib::ustring& name) { - - if (regex->match(longThemeFName + ".css", matchInfo)) { - for (size_t i = 0 ; i < themeFNames.size(); ++i) { - if (themeFNames.at(i).longFName == longThemeFName) { - return (int)i; - } + for (size_t i = 0 ; i < themeNames.size(); ++i) { + if (themeNames.at(i) == name) { + return (int)i; } } @@ -1154,8 +1151,8 @@ Gtk::Widget* Preferences::getGeneralPanel() themeCBT = Gtk::manage(new Gtk::ComboBoxText()); themeCBT->set_active(0); parseThemeDir(Glib::build_filename(argv0, "themes")); - for (size_t i = 0; i < themeFNames.size(); i++) { - themeCBT->append(themeFNames.at(i).shortFName); + for (size_t i = 0; i < themeNames.size(); i++) { + themeCBT->append(themeNames.at(i)); } Gtk::Label* mainFontLbl = Gtk::manage(new Gtk::Label(M("PREFERENCES_APPEARANCE_MAINFONT"))); @@ -1665,7 +1662,7 @@ void Preferences::parseThemeDir(Glib::ustring dirname) return; } - // process directory + // Process directory Glib::Dir* dir = nullptr; try { @@ -1675,40 +1672,17 @@ void Preferences::parseThemeDir(Glib::ustring dirname) } for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - Glib::ustring fname = Glib::build_filename(dirname, *i); - Glib::ustring sname = *i; + Glib::ustring fname = *i; - // ignore directories and filter out unsupported theme - if (regex->match(sname, matchInfo) && !Glib::file_test(fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= 4) { - bool keepIt = false; - Glib::ustring fname2 = matchInfo.fetch(1); - Glib::ustring minMinor = matchInfo.fetch(2); - Glib::ustring maxMinor = matchInfo.fetch(3); - - if (!minMinor.empty()) { - guint64 minMinorVal = g_ascii_strtoll(minMinor.c_str(), 0, 0); - - if ((guint64)GTK_MINOR_VERSION >= minMinorVal) { - keepIt = true; - } - } - - if (!maxMinor.empty()) { - guint64 maxMinorVal = g_ascii_strtoll(maxMinor.c_str(), 0, 0); - - if ((guint64)GTK_MINOR_VERSION <= maxMinorVal) { - keepIt = true; - } - } - - if (keepIt) { - themeFNames.push_back(ThemeFilename(matchInfo.fetch(1), sname.substr(0, sname.size() - 4))); - } + // Ignore directories and filter to keep css files only + if (regex->match(fname, matchInfo) && !Glib::file_test(fname, Glib::FILE_TEST_IS_DIR) && fname.size() >= 4) { + themeNames.push_back(fname.substr(0, fname.size() - 4)); } } - std::sort(themeFNames.begin(), themeFNames.end(), [](const ThemeFilename & firstDir, const ThemeFilename & secondDir) { - return firstDir.longFName < secondDir.longFName; + // Sort theme by names + std::sort(themeNames.begin(), themeNames.end(), [](const Glib::ustring & first, const Glib::ustring & second) { + return first < second; }); delete dir; @@ -1747,7 +1721,7 @@ void Preferences::storePreferences() moptions.shadowThreshold = (int)shThresh->get_value(); moptions.language = languages->get_active_id(); moptions.languageAutoDetect = ckbLangAutoDetect->get_active(); - moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName; + moptions.theme = themeNames.at (themeCBT->get_active_row_number ()); Gdk::RGBA cropCol = cropMaskColorCB->get_rgba(); moptions.cutOverlayBrush[0] = cropCol.get_red(); @@ -2262,7 +2236,7 @@ void Preferences::okPressed() void Preferences::cancelPressed() { // set the initial theme back - if (themeFNames.at (themeCBT->get_active_row_number ()).longFName != options.theme) { + if (themeNames.at (themeCBT->get_active_row_number ()) != options.theme) { switchThemeTo(options.theme); } @@ -2318,7 +2292,7 @@ void Preferences::aboutPressed() void Preferences::themeChanged() { - moptions.theme = themeFNames.at (themeCBT->get_active_row_number ()).longFName; + moptions.theme = themeNames.at (themeCBT->get_active_row_number ()); switchThemeTo(moptions.theme); } diff --git a/rtgui/preferences.h b/rtgui/preferences.h index e9f33a1f1..331e02fdb 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -70,18 +70,9 @@ class Preferences final : } }; - class ThemeFilename - { - public: - Glib::ustring shortFName; - Glib::ustring longFName; - - ThemeFilename (Glib::ustring sfname, Glib::ustring lfname) : shortFName (sfname), longFName (lfname) {} - }; - Glib::RefPtr behModel; BehavColumns behavColumns; - std::vector themeFNames; + std::vector themeNames; Glib::RefPtr regex; Glib::MatchInfo matchInfo; Splash* splash; @@ -279,7 +270,7 @@ class Preferences final : void switchFontTo (const Glib::ustring &newFontFamily, const int newFontSize); bool splashClosed (GdkEventAny* event); - int getThemeRowNumber (const Glib::ustring& longThemeFName); + int getThemeRowNumber (const Glib::ustring& name); void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 1d5a921f3..ef2e58934 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -118,41 +118,11 @@ RTWindow::RTWindow () RTScalable::init(this); // Look for theme and set it - Glib::RefPtr regex = Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); - Glib::ustring filename; - Glib::MatchInfo mInfo; - bool match = regex->match(options.theme + ".css", mInfo); - if (match) { - // save old theme (name + version) - Glib::ustring initialTheme(options.theme); - - // update version - auto pos = options.theme.find("-GTK3-"); - Glib::ustring themeRootName(options.theme.substr(0, pos)); - if (GTK_MINOR_VERSION < 20) { - options.theme = themeRootName + "-GTK3-_19"; - } else { - options.theme = themeRootName + "-GTK3-20_"; - } - // check if this version exist - if (!Glib::file_test(Glib::build_filename(argv0, "themes", options.theme + ".css"), Glib::FILE_TEST_EXISTS)) { - // set back old theme version if the actual one doesn't exist yet - options.theme = initialTheme; - } - } - filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); - - if (!match || !Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { - options.theme = "RawTherapee-GTK"; - - // We're not testing GTK_MAJOR_VERSION == 3 here, since this branch requires Gtk3 only - if (GTK_MINOR_VERSION < 20) { - options.theme = options.theme + "3-_19"; - } else { - options.theme = options.theme + "3-20_"; - } - - filename = Glib::build_filename (argv0, "themes", options.theme + ".css"); + // Check if the current theme name in options exists, otherwise set it to default one (i.e. "RawTherapee.css") + auto filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); + if (!Glib::file_test(filename, Glib::FILE_TEST_EXISTS)) { + options.theme = "RawTherapee"; + filename = Glib::build_filename(argv0, "themes", options.theme + ".css"); } cssRT = Gtk::CssProvider::create(); From bf988ad2744865f151611a2761a91c9d90f7ba83 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Wed, 23 Aug 2023 13:43:07 +0200 Subject: [PATCH 029/291] Updates font management for hidpi Improvements: - Cleanup of default options files to use OS font by default - Comments updates - Simplify font size management as Pango/Gtk directly manage pt/px conversions Bug fix: - If Preference panel is closed by "cancel", font size was not reinitialized to previously saved one - Font size was specified in "RawTherapee.css" theme and so user choice could be ignored --- rtdata/CMakeLists.txt | 4 -- rtdata/fonts/DroidSansMonoSlashed.ttf | Bin 117744 -> 0 bytes rtdata/options/options.osx | 5 -- rtdata/themes/RawTherapee.css | 1 - rtgui/cropwindow.cc | 51 ++++------------ rtgui/filebrowserentry.cc | 17 ++---- rtgui/filecatalog.cc | 2 +- rtgui/imagearea.cc | 15 +---- rtgui/lockablecolorpicker.cc | 17 ++---- rtgui/preferences.cc | 76 +++++++++++++----------- rtgui/rtscalable.h | 5 ++ rtgui/rtwindow.cc | 82 ++++++++------------------ rtgui/splash.cc | 17 ++---- rtgui/thumbbrowserentrybase.cc | 4 +- 14 files changed, 99 insertions(+), 197 deletions(-) delete mode 100644 rtdata/fonts/DroidSansMonoSlashed.ttf diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 0f6c907fb..7a0190e15 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -3,7 +3,6 @@ file(GLOB SOUNDFILES "sounds/*") file(GLOB INPUTICCFILES "iccprofiles/input/*") file(GLOB OUTPUTICCFILES "iccprofiles/output/*") file(GLOB DCPFILES "dcpprofiles/*") -file(GLOB FONTS "fonts/*") set(PROFILESDIR "profiles") set(THEMEDIR "themes") @@ -43,9 +42,6 @@ install(FILES ${INPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/input") install(FILES ${OUTPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/output") install(FILES ${DCPFILES} DESTINATION "${DATADIR}/dcpprofiles") install(FILES ${OPTIONSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME options) -if(WIN32) - install(FILES ${FONTS} DESTINATION "${DATADIR}/fonts") -endif() install(DIRECTORY "${PROFILESDIR}" DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") diff --git a/rtdata/fonts/DroidSansMonoSlashed.ttf b/rtdata/fonts/DroidSansMonoSlashed.ttf deleted file mode 100644 index 8c44b47edc5882630da72658926f5d295717ad62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117744 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 context = parent->get_pango_context () ; - Pango::FontDescription fontd = context->get_font_description (); + Pango::FontDescription fontd = parent->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); const int fontSize = 8; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * Pango::SCALE); context->set_font_description (fontd); Glib::RefPtr cllayout = parent->create_pango_layout("1000%"); @@ -2461,21 +2452,12 @@ 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 (); + Pango::FontDescription fontd = iarea->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); const int fontSize = 8; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * Pango::SCALE); context->set_font_description (fontd); Glib::RefPtr cllayout = iarea->create_pango_layout(cropLabel); int iw, ih; @@ -2537,21 +2519,12 @@ void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) } Glib::RefPtr context = iarea->get_pango_context () ; - Pango::FontDescription fontd = context->get_font_description (); + Pango::FontDescription fontd = iarea->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); const int fontSize = 8; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * 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))); diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index b3742ac8f..f889d3b20 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -784,21 +784,12 @@ void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) } Glib::RefPtr context = parent->getDrawingArea()->get_pango_context () ; - Pango::FontDescription fontd = context->get_font_description (); + Pango::FontDescription fontd = parent->getDrawingArea()->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); const int fontSize = 8; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * 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))); diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index b01d83223..fd928c7b2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -525,7 +525,7 @@ void FileCatalog::on_realize() { Gtk::Box::on_realize(); - Pango::FontDescription fontd = get_pango_context()->get_font_description (); + Pango::FontDescription fontd = get_style_context()->get_font(); fileBrowser->get_pango_context()->set_font_description (fontd); // batchQueue->get_pango_context()->set_font_description (fontd); } diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 90deb6ba0..a1387db02 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -156,18 +156,9 @@ void ImageArea::setInfoText (Glib::ustring text) // update font fontd.set_weight (Pango::WEIGHT_BOLD); const int fontSize = 10; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * Pango::SCALE); context->set_font_description (fontd); // create text layout diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 0133199e8..4a8529c38 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -53,22 +53,13 @@ void LockableColorPicker::updateBackBuffer () Gtk::DrawingArea *iArea = cropWindow->getImageArea(); Glib::RefPtr pangoContext = iArea->get_pango_context (); - Pango::FontDescription fontd = pangoContext->get_font_description(); + Pango::FontDescription fontd = iArea->get_style_context()->get_font(); // set font family and size fontd.set_family(options.CPFontFamily == "default" ? "sans" : options.CPFontFamily); const int fontSize = options.CPFontFamily == "default" ? 8 : options.CPFontSize; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size (fontSize * Pango::SCALE); fontd.set_weight(Pango::WEIGHT_NORMAL); pangoContext->set_font_description (fontd); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4dd6eae4f..6e9028bce 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -82,9 +82,22 @@ Preferences::Preferences(RTWindow *rtwindow) set_size_request(650, -1); set_default_size(options.preferencesWidth, options.preferencesHeight); - Pango::FontDescription defaultFont = get_style_context()->get_font(); - initialFontFamily = defaultFont.get_family(); - initialFontSize = defaultFont.get_size() / Pango::SCALE; + // Request default font and size from Gtk::Settings + const auto defaultSettings = Gtk::Settings::get_default(); + Glib::ustring defaultFont; + defaultSettings->get_property("gtk-font-name", defaultFont); + const Pango::FontDescription defaultFontDesc = Pango::FontDescription(defaultFont); + initialFontFamily = defaultFontDesc.get_family(); +#if defined(__APPLE__) + // Default MacOS font (i.e. "") is not correctly handled + // in Gtk css. Replacing it by "-apple-system" to avoid this + if (initialFontFamily == ".AppleSystemUIFont") { + initialFontFamily = "-apple-system"; + } +#endif + initialFontSize = defaultFontDesc.get_size() / Pango::SCALE; // Font size is managed in ()"pt" * Pango::SCALE) by Pango (also refer to notes in rtscalable.h) + + printf("initialFont: %s %d\n", initialFontFamily.c_str(), initialFontSize); Gtk::Box* mainBox = get_content_area(); //GTK318 @@ -2016,15 +2029,15 @@ void Preferences::fillPreferences() navGuideColorCB->set_alpha ( (unsigned short) (moptions.navGuideBrush[3] * 65535.0)); if (options.fontFamily == "default") { - mainFontFB->set_font_name (Glib::ustring::compose ("%1 %2", initialFontFamily, initialFontSize)); + mainFontFB->set_font_name (Glib::ustring::compose ("%1, %2", initialFontFamily, initialFontSize)); } else { - mainFontFB->set_font_name (Glib::ustring::compose ("%1 %2", options.fontFamily, options.fontSize)); + mainFontFB->set_font_name (Glib::ustring::compose ("%1, %2", options.fontFamily, options.fontSize)); } if (options.CPFontFamily == "default") { - colorPickerFontFB->set_font_name (Glib::ustring::compose ("%1 %2", initialFontFamily, initialFontSize)); + colorPickerFontFB->set_font_name (Glib::ustring::compose ("%1, %2", initialFontFamily, initialFontSize)); } else { - colorPickerFontFB->set_font_name (Glib::ustring::compose ("%1 %2", options.CPFontFamily, options.CPFontSize)); + colorPickerFontFB->set_font_name (Glib::ustring::compose ("%1, %2", options.CPFontFamily, options.CPFontSize)); } showDateTime->set_active(moptions.fbShowDateTime); @@ -2243,7 +2256,7 @@ void Preferences::cancelPressed() // set the initial font back Pango::FontDescription fd (mainFontFB->get_font_name()); - if (fd.get_family() != options.fontFamily && (fd.get_size() / Pango::SCALE) != options.fontSize) { + if (fd.get_family() != options.fontFamily || (fd.get_size() / Pango::SCALE) != options.fontSize) { if (options.fontFamily == "default") { switchFontTo(initialFontFamily, initialFontSize); } else { @@ -2446,6 +2459,7 @@ void Preferences::fontChanged() { newFont = true; Pango::FontDescription fd (mainFontFB->get_font_name()); + printf("test: %s\n", mainFontFB->get_font_name().c_str()); switchFontTo(fd.get_family(), fd.get_size() / Pango::SCALE); } @@ -2457,34 +2471,26 @@ void Preferences::cpFontChanged() void Preferences::switchFontTo(const Glib::ustring &newFontFamily, const int newFontSize) { - - if (newFontFamily != "default") { - if (!fontcss) { - fontcss = Gtk::CssProvider::create(); - Glib::RefPtr screen = Gdk::Screen::get_default(); - Gtk::StyleContext::add_provider_for_screen(screen, fontcss, GTK_STYLE_PROVIDER_PRIORITY_USER); - } - - try { - //GTK318 -//#if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 -// fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2px }", newFontFamily, newFontSize)); -//#else - fontcss->load_from_data (Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize)); -//#endif - //GTK318 - } catch (Glib::Error &err) { - printf("Error: \"%s\"\n", err.what().c_str()); - } catch (...) { - printf("Error: Can't find the font named \"%s\"\n", newFontFamily.c_str()); - } - } else { - if (fontcss) { - fontcss = Gtk::CssProvider::create(); - Glib::RefPtr screen = Gdk::Screen::get_default(); - Gtk::StyleContext::remove_provider_for_screen(screen, fontcss); - } + // Create CssProvider if not existing + if (!fontcss) { + fontcss = Gtk::CssProvider::create(); + Glib::RefPtr screen = Gdk::Screen::get_default(); + Gtk::StyleContext::add_provider_for_screen(screen, fontcss, GTK_STYLE_PROVIDER_PRIORITY_USER); } + + // Create css to load based on new font name and size + const auto css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt }", newFontFamily, newFontSize); + + // Load css to update font name and size + try { + fontcss->load_from_data (css); + } catch (Glib::Error &err) { + printf("Error: \"%s\"\n", err.what().c_str()); + } catch (...) { + printf("Error: Can't load the desired font correctly\n"); + } + + printf("switchFontTo: %s\n", css.c_str()); } void Preferences::workflowUpdate() diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index 673ea5685..6913515aa 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -34,6 +34,11 @@ * - Non-absolute size (i.e. "pt"): The default resolution is 72 DPI (i.e. pt per inch). To * convert the size to "px", use the following formula: * "size in px" = "size in pt" * ("device resolution" / 72) + * Notes: + * - By default, size is expressed in non-absolute size (i.e. "pt"). Conversion between absolute + * and non-absolute size is ensured by Pango. + * - On MacOS, font is already scaled by the System library (i.e. "size in px" = "size in pt" * 1.). + * Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c * * Hi-DPI implementation according to the OS (source: GDK code): * - Windows: A default DPI of 96 is considered. Current DPI parameter is provided by the OS. diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index ef2e58934..7899fb250 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -139,71 +139,35 @@ RTWindow::RTWindow () // Set the font face and size Glib::ustring css; -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - auto style = get_pango_context(); - if (options.fontFamily != "default") { // Set font and size according to user choice - // Scale font size based on DPI and Scale - const int scaledFontSize = static_cast(options.fontSize * fontScale + 0.5); + // Set font and size in css from options + css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt}", + options.fontFamily, + options.fontSize); // Font size is in "pt" in options + } else { // Set font and size according to default values + // Retrieve default style values from Gtk::Settings + const auto defaultSettings = Gtk::Settings::get_default(); + Glib::ustring defaultFont; + defaultSettings->get_property("gtk-font-name", defaultFont); + const Pango::FontDescription defaultFontDesc = Pango::FontDescription(defaultFont); // Set font and size in css - css = Glib::ustring::compose ("* { font-family: %1; font-size: %2px}", options.fontFamily, scaledFontSize); - - if (rtengine::settings->verbose) { - printf("\"Non-Default\" font size in pt(%d) * scale(%.3f) = font size in px(%d)\n", options.fontSize, fontScale, scaledFontSize); + auto defaultFontFamily = defaultFontDesc.get_family(); + const int defaultFontSize = defaultFontDesc.get_size() / Pango::SCALE; // Font size is managed in ()"pt" * Pango::SCALE) by Pango (also refer to notes in rtscalable.h) +#if defined(__APPLE__) + // Default MacOS font (i.e. "") is not correctly handled + // in Gtk css. Replacing it by "-apple-system" to avoid this + if (defaultFontFamily == ".AppleSystemUIFont") { + defaultFontFamily = "-apple-system"; } - } else { // Set font and size according to default values - // Retrieve default style values - Glib::RefPtr style = Gtk::StyleContext::create(); - Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); - - if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { - int fontSize = pfd.get_size(); - const bool isAbsoluteFontSize = pfd.get_size_is_absolute(); - int newFontSize; - - if (isAbsoluteFontSize) { - // Absolute size is defined in "Pango units" and shall be divided by - // Pango::SCALE to get "px" - fontSize = fontSize / Pango::SCALE; - -#ifndef __APPLE__ - // Guessing that pixel size is given for a 96 DPI reference: - const double newFontScale = RTScalable::getDPI() / RTScalable::baseDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double newFontScale = 1.; #endif - newFontSize = static_cast(fontSize * newFontScale + 0.5); - - if (rtengine::settings->verbose) { - printf("\"Default\" absolute font size(%d)\n", newFontSize); - } - } else { - // Non-absolute size is defined in "Pango units" and shall be divided by - // Pango::SCALE to get "px" - fontSize = fontSize / Pango::SCALE; - - // Non-absolute size is defined in "pt" and shall be converted to "px" - newFontSize = static_cast(fontSize * fontScale + 0.5); - - if (rtengine::settings->verbose) { - printf("\"Default\" non-absolute font size in pt(%d) * scale(%.3f) = font size in px(%d)\n", fontSize, fontScale, newFontSize); - } - } - - // Set font and size in css - css = Glib::ustring::compose ("* { font-size: %1px}", newFontSize); - } + css = Glib::ustring::compose ("* { font-family: %1; font-size: %2pt}", + defaultFontFamily, + defaultFontSize); } + printf("test : %s\n", css.c_str()); + // Load custom CSS for font if (!css.empty()) { if (rtengine::settings->verbose) { @@ -218,7 +182,7 @@ RTWindow::RTWindow () } catch (Glib::Error &err) { printf ("Error: \"%s\"\n", err.what().c_str()); } catch (...) { - printf ("Error: Can't find the font named \"%s\"\n", options.fontFamily.c_str()); + printf ("Error: Can't load the desired font correctly\n"); } } } diff --git a/rtgui/splash.cc b/rtgui/splash.cc index ea3cb59e7..0015c4864 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -41,21 +41,12 @@ bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) 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 (); + Pango::FontDescription fontd = get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_LIGHT); const int fontSize = 12; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px - // Absolute size is defined in "Pango units" and shall be multiplied by - // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + // Non-absolute size is defined in "Pango units" and shall be multiplied by + // Pango::SCALE from "pt": + fontd.set_size(fontSize * Pango::SCALE); context->set_font_description (fontd); int w, h; diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index 424b04680..2f9fb4b47 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -376,7 +376,7 @@ void ThumbBrowserEntryBase::updateBackBuffer () // draw file name Glib::RefPtr context = w->get_pango_context () ; - Pango::FontDescription fontd = context->get_font_description (); + Pango::FontDescription fontd = w->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); if (italicstyle) { @@ -442,7 +442,7 @@ void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) // filename: - Pango::FontDescription fontd = context->get_font_description (); + Pango::FontDescription fontd = w->get_style_context()->get_font(); fontd.set_weight (Pango::WEIGHT_BOLD); context->set_font_description (fontd); Glib::RefPtr fn = w->create_pango_layout(dispname); From ce5f77ffc269cda30bcf5efeb4b1c9173170cac7 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Wed, 23 Aug 2023 13:48:39 +0200 Subject: [PATCH 030/291] Removes debug printf --- rtgui/preferences.cc | 5 ----- rtgui/rtwindow.cc | 2 -- 2 files changed, 7 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 6e9028bce..e327ff435 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -97,8 +97,6 @@ Preferences::Preferences(RTWindow *rtwindow) #endif initialFontSize = defaultFontDesc.get_size() / Pango::SCALE; // Font size is managed in ()"pt" * Pango::SCALE) by Pango (also refer to notes in rtscalable.h) - printf("initialFont: %s %d\n", initialFontFamily.c_str(), initialFontSize); - Gtk::Box* mainBox = get_content_area(); //GTK318 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20 @@ -2459,7 +2457,6 @@ void Preferences::fontChanged() { newFont = true; Pango::FontDescription fd (mainFontFB->get_font_name()); - printf("test: %s\n", mainFontFB->get_font_name().c_str()); switchFontTo(fd.get_family(), fd.get_size() / Pango::SCALE); } @@ -2489,8 +2486,6 @@ void Preferences::switchFontTo(const Glib::ustring &newFontFamily, const int new } catch (...) { printf("Error: Can't load the desired font correctly\n"); } - - printf("switchFontTo: %s\n", css.c_str()); } void Preferences::workflowUpdate() diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 7899fb250..45dd625cd 100755 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -166,8 +166,6 @@ RTWindow::RTWindow () defaultFontSize); } - printf("test : %s\n", css.c_str()); - // Load custom CSS for font if (!css.empty()) { if (rtengine::settings->verbose) { From e32ad15fe570d8fa1e29f01c3808894cf9ce91c6 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sun, 27 Aug 2023 18:35:13 +0200 Subject: [PATCH 031/291] Review of rtdata files tree for icons/images --- rtdata/CMakeLists.txt | 21 ++++-------------- .../128x128/app_icons/rawtherapee.png} | Bin .../16x16/app_icons/rawtherapee.png} | Bin .../24x24/app_icons/rawtherapee.png} | Bin .../rawtherapee/24x24/apps}/empty.png | Bin .../256x256/app_icons/rawtherapee.png} | Bin .../32x32/app_icons/rawtherapee.png} | Bin .../48x48/app_icons/rawtherapee.png} | Bin .../64x64/app_icons/rawtherapee.png} | Bin .../svg => icons/rawtherapee}/index.theme | 0 .../scalable/app_icons/rawtherapee.svg} | 0 .../rawtherapee/scalable/apps}/add-small.svg | 0 .../rawtherapee/scalable/apps}/add.svg | 0 .../rawtherapee/scalable/apps}/aperture.svg | 0 .../scalable/apps}/arrow-down-small.svg | 0 .../scalable/apps}/arrow-left-small.svg | 0 .../scalable/apps}/arrow-right-small.svg | 0 .../scalable/apps}/arrow-up-small.svg | 0 .../scalable/apps}/arrow-updown.svg | 0 .../scalable/apps}/arrow2-left.svg | 0 .../scalable/apps}/arrow2-right.svg | 0 .../rawtherapee/scalable/apps}/atom.svg | 0 .../rawtherapee/scalable/apps}/bayer.svg | 0 .../scalable/apps}/beforeafter.svg | 0 ...irectional-arrow-horizontal-hicontrast.svg | 0 ...idirectional-arrow-horizontal-prelight.svg | 0 ...idirectional-arrow-vertical-hicontrast.svg | 0 .../bidirectional-arrow-vertical-prelight.svg | 0 .../rawtherapee/scalable/apps}/box.svg | 0 .../scalable/apps}/cancel-small.svg | 0 .../rawtherapee/scalable/apps}/cancel.svg | 0 .../scalable/apps}/circle-black-small.svg | 0 .../apps}/circle-blue-green-small.svg | 0 .../scalable/apps}/circle-blue-red-small.svg | 0 .../scalable/apps}/circle-blue-small.svg | 0 .../apps}/circle-blue-yellow-small.svg | 0 .../scalable/apps}/circle-cyan-red-small.svg | 0 .../scalable/apps}/circle-cyan-small.svg | 0 .../scalable/apps}/circle-darkgray-small.svg | 0 .../apps}/circle-empty-blue-small.svg | 0 .../apps}/circle-empty-darkgray-small.svg | 0 .../apps}/circle-empty-gray-small.svg | 0 .../apps}/circle-empty-green-small.svg | 0 .../apps}/circle-empty-purple-small.svg | 0 .../scalable/apps}/circle-empty-red-small.svg | 0 .../apps}/circle-empty-yellow-small.svg | 0 .../scalable/apps}/circle-gray-blue-small.svg | 0 .../apps}/circle-gray-green-small.svg | 0 .../scalable/apps}/circle-gray-red-small.svg | 0 .../scalable/apps}/circle-gray-small.svg | 0 .../apps}/circle-green-blue-small.svg | 0 .../scalable/apps}/circle-green-red-small.svg | 0 .../scalable/apps}/circle-green-small.svg | 0 .../scalable/apps}/circle-magenta-small.svg | 0 .../scalable/apps}/circle-orange-small.svg | 0 .../scalable/apps}/circle-purple-small.svg | 0 .../scalable/apps}/circle-red-blue-small.svg | 0 .../scalable/apps}/circle-red-cyan-small.svg | 0 .../scalable/apps}/circle-red-green-small.svg | 0 .../scalable/apps}/circle-red-small.svg | 0 .../scalable/apps}/circle-white-small.svg | 0 .../apps}/circle-yellow-blue-small.svg | 0 .../scalable/apps}/circle-yellow-small.svg | 0 .../scalable/apps}/color-circles.svg | 0 .../apps}/color-picker-add-hicontrast.svg | 0 .../scalable/apps}/color-picker-add.svg | 0 .../scalable/apps}/color-picker-bars.svg | 0 .../apps}/color-picker-hicontrast.svg | 0 .../scalable/apps}/color-picker-hide.svg | 0 .../scalable/apps}/color-picker-small.svg | 0 .../scalable/apps}/color-picker.svg | 0 .../scalable/apps}/contrastmask-off.svg | 0 .../scalable/apps}/contrastmask-on.svg | 0 .../rawtherapee/scalable/apps}/copy.svg | 0 .../scalable/apps}/crop-auto-small.svg | 0 .../rawtherapee/scalable/apps}/crop-auto.svg | 0 .../scalable/apps}/crop-point-hicontrast.svg | 0 .../rawtherapee/scalable/apps}/crop-small.svg | 0 .../rawtherapee/scalable/apps}/crop.svg | 0 .../scalable/apps}/crossed-arrows-in.svg | 0 .../scalable/apps}/crossed-arrows-out.svg | 0 .../scalable/apps}/crosshair-adjust.svg | 0 .../scalable/apps}/crosshair-hicontrast.svg | 0 .../scalable/apps}/crosshair-node-curve.svg | 0 .../scalable/apps}/crosshair-small.svg | 0 .../scalable/apps}/curve-catmullrom-small.svg | 0 .../scalable/apps}/curve-catmullrom.svg | 0 .../apps}/curve-controlpoints-small.svg | 0 .../scalable/apps}/curve-controlpoints.svg | 0 .../scalable/apps}/curve-flat-small.svg | 0 .../rawtherapee/scalable/apps}/curve-flat.svg | 0 .../scalable/apps}/curve-linear-small.svg | 0 .../scalable/apps}/curve-linear.svg | 0 .../scalable/apps}/curve-nurbs-small.svg | 0 .../scalable/apps}/curve-nurbs.svg | 0 .../scalable/apps}/curve-parametric-small.svg | 0 .../scalable/apps}/curve-parametric.svg | 0 .../scalable/apps}/curve-spline-small.svg | 0 .../scalable/apps}/curve-spline.svg | 0 .../rawtherapee/scalable/apps}/detail.svg | 0 .../scalable/apps}/device-floppy.svg | 0 .../rawtherapee/scalable/apps}/device-hdd.svg | 0 .../scalable/apps}/device-network.svg | 0 .../scalable/apps}/device-optical.svg | 0 .../rawtherapee/scalable/apps}/device-usb.svg | 0 .../scalable/apps}/distortion-auto-small.svg | 0 .../scalable/apps}/distortion-auto.svg | 0 .../apps}/distortion-barrel-small.svg | 0 .../scalable/apps}/distortion-barrel.svg | 0 .../apps}/distortion-pincushion-small.svg | 0 .../scalable/apps}/distortion-pincushion.svg | 0 .../rawtherapee/scalable/apps}/draw.svg | 0 .../rawtherapee/scalable/apps}/edit-point.svg | 0 .../rawtherapee/scalable/apps}/edit-small.svg | 0 .../rawtherapee/scalable/apps}/edit.svg | 0 .../scalable/apps}/equilizer-narrow.svg | 0 .../scalable/apps}/equilizer-wide.svg | 0 .../scalable/apps}/expander-closed-small.svg | 0 .../scalable/apps}/expander-open-small.svg | 0 .../rawtherapee/scalable/apps}/exposure.svg | 0 .../scalable/apps}/filetype-hdr.svg | 0 .../scalable/apps}/filetype-ps.svg | 0 .../scalable/apps}/filter-clear.svg | 0 .../scalable/apps}/filter-original.svg | 0 .../scalable/apps}/filter-original2.svg | 0 .../rawtherapee/scalable/apps}/filter.svg | 0 .../scalable/apps}/flip-horizontal.svg | 0 .../scalable/apps}/flip-vertical.svg | 0 .../scalable/apps}/focusscreen-off.svg | 0 .../scalable/apps}/focusscreen-on.svg | 0 .../apps}/folder-closed-home-small.svg | 0 .../scalable/apps}/folder-closed-home.svg | 0 .../apps}/folder-closed-recent-small.svg | 0 .../scalable/apps}/folder-closed-recent.svg | 0 .../scalable/apps}/folder-closed-small.svg | 0 .../scalable/apps}/folder-closed.svg | 0 .../apps}/folder-open-recent-small.svg | 0 .../scalable/apps}/folder-open-recent.svg | 0 .../scalable/apps}/folder-open-small.svg | 0 .../scalable/apps}/folder-open.svg | 0 .../scalable/apps}/fullscreen-enter.svg | 0 .../scalable/apps}/fullscreen-leave.svg | 0 .../rawtherapee/scalable/apps}/gamut-hist.svg | 0 .../rawtherapee/scalable/apps}/gamut-plus.svg | 0 .../scalable/apps}/gamut-softproof.svg | 0 .../scalable/apps}/gamut-warning.svg | 0 .../scalable/apps}/gamut_srgb_prophoto_xy.svg | 0 .../scalable/apps}/gears-pause.svg | 0 .../rawtherapee/scalable/apps}/gears-play.svg | 0 .../scalable/apps}/gears-small.svg | 0 .../rawtherapee/scalable/apps}/gears.svg | 0 .../scalable/apps}/goto-end-small.svg | 0 .../scalable/apps}/goto-start-small.svg | 0 .../scalable/apps}/hand-closed-hicontrast.svg | 0 .../scalable/apps}/hand-open-hicontrast.svg | 0 .../rawtherapee/scalable/apps}/hand-open.svg | 0 .../apps}/histogram-bar-off-small.svg | 0 .../scalable/apps}/histogram-bar-on-small.svg | 0 .../apps}/histogram-blue-off-small.svg | 0 .../apps}/histogram-blue-on-small.svg | 0 .../apps}/histogram-ellipsis-small.svg | 0 .../apps}/histogram-gold-off-small.svg | 0 .../apps}/histogram-gold-on-small.svg | 0 .../apps}/histogram-green-off-small.svg | 0 .../apps}/histogram-green-on-small.svg | 0 .../apps}/histogram-mode-linear-small.svg | 0 .../apps}/histogram-mode-logx-small.svg | 0 .../apps}/histogram-mode-logxy-small.svg | 0 .../apps}/histogram-red-off-small.svg | 0 .../scalable/apps}/histogram-red-on-small.svg | 0 .../apps}/histogram-silver-off-small.svg | 0 .../apps}/histogram-silver-on-small.svg | 0 .../histogram-type-histogram-raw-small.svg | 0 .../apps}/histogram-type-histogram-small.svg | 0 .../apps}/histogram-type-parade-small.svg | 0 .../histogram-type-vectorscope-hc-small.svg | 0 .../histogram-type-vectorscope-hs-small.svg | 0 .../apps}/histogram-type-waveform-small.svg | 0 .../rawtherapee/scalable/apps}/info.svg | 0 .../scalable/apps}/intent-absolute.svg | 0 .../scalable/apps}/intent-perceptual.svg | 0 .../scalable/apps}/intent-relative.svg | 0 .../scalable/apps}/intent-saturation.svg | 0 .../scalable/apps}/magnifier-1to1-small.svg | 0 .../scalable/apps}/magnifier-1to1.svg | 0 .../scalable/apps}/magnifier-crop.svg | 0 .../scalable/apps}/magnifier-fit.svg | 0 .../scalable/apps}/magnifier-minus-small.svg | 0 .../scalable/apps}/magnifier-minus.svg | 0 .../scalable/apps}/magnifier-plus-small.svg | 0 .../scalable/apps}/magnifier-plus.svg | 0 .../rawtherapee/scalable/apps}/magnifier.svg | 0 .../rawtherapee/scalable/apps}/metadata.svg | 0 .../apps}/node-move-nw-se-hicontrast.svg | 0 .../apps}/node-move-sw-ne-hicontrast.svg | 0 .../scalable/apps}/node-move-x-hicontrast.svg | 0 .../apps}/node-move-xy-hicontrast.svg | 0 .../scalable/apps}/node-move-y-hicontrast.svg | 0 .../scalable/apps}/one-to-one-small.svg | 0 .../scalable/apps}/padlock-locked-small.svg | 0 .../scalable/apps}/padlock-unlocked-small.svg | 0 .../scalable/apps}/palette-brush.svg | 0 .../scalable/apps}/panel-to-bottom.svg | 0 .../scalable/apps}/panel-to-left.svg | 0 .../scalable/apps}/panel-to-right.svg | 0 .../scalable/apps}/panel-to-top.svg | 0 .../rawtherapee/scalable/apps}/paste.svg | 0 .../perspective-horizontal-left-small.svg | 0 .../apps}/perspective-horizontal-left.svg | 0 .../perspective-horizontal-right-small.svg | 0 .../apps}/perspective-horizontal-right.svg | 0 .../apps}/perspective-horizontal-vertical.svg | 0 .../perspective-vertical-bottom-small.svg | 0 .../apps}/perspective-vertical-bottom.svg | 0 .../apps}/perspective-vertical-top-small.svg | 0 .../apps}/perspective-vertical-top.svg | 0 .../apps}/power-inconsistent-small.svg | 0 .../scalable/apps}/power-off-small.svg | 0 .../scalable/apps}/power-on-small.svg | 0 .../scalable/apps}/preferences.svg | 0 .../scalable/apps}/profile-filled.svg | 0 .../scalable/apps}/profile-partial.svg | 0 .../scalable/apps}/questionmark.svg | 0 .../rawtherapee/scalable/apps}/redo-all.svg | 0 .../rawtherapee/scalable/apps}/redo-small.svg | 0 .../rawtherapee/scalable/apps}/redo.svg | 0 .../scalable/apps}/refresh-red-small.svg | 0 .../scalable/apps}/refresh-small.svg | 0 .../rawtherapee/scalable/apps}/refresh.svg | 0 .../scalable/apps}/remove-small.svg | 0 .../rawtherapee/scalable/apps}/remove.svg | 0 .../apps}/rotate-aroundnode-hicontrast.svg | 0 .../scalable/apps}/rotate-aroundnode.svg | 0 .../scalable/apps}/rotate-left-90.svg | 0 .../scalable/apps}/rotate-left-small.svg | 0 .../scalable/apps}/rotate-left.svg | 0 .../scalable/apps}/rotate-right-90.svg | 0 .../scalable/apps}/rotate-right-small.svg | 0 .../scalable/apps}/rotate-right.svg | 0 .../apps}/rotate-straighten-small.svg | 0 .../scalable/apps}/rotate-straighten.svg | 0 .../rawtherapee/scalable/apps}/save-small.svg | 0 .../rawtherapee/scalable/apps}/save.svg | 0 .../scalable/apps}/saved-no-small.svg | 0 .../scalable/apps}/saved-yes-small.svg | 0 .../scalable/apps}/spot-active.svg | 0 .../scalable/apps}/spot-normal.svg | 0 .../scalable/apps}/spot-prelight.svg | 0 .../apps}/square-toggle-black-off-narrow.svg | 0 .../apps}/square-toggle-black-on-narrow.svg | 0 .../apps}/square-toggle-blue-off-narrow.svg | 0 .../apps}/square-toggle-blue-on-narrow.svg | 0 .../apps}/square-toggle-gray-off-narrow.svg | 0 .../apps}/square-toggle-gray-on-narrow.svg | 0 .../apps}/square-toggle-green-off-narrow.svg | 0 .../apps}/square-toggle-green-on-narrow.svg | 0 .../square-toggle-luminosity-off-narrow.svg | 0 .../square-toggle-luminosity-on-narrow.svg | 0 .../apps}/square-toggle-red-off-narrow.svg | 0 .../apps}/square-toggle-red-on-narrow.svg | 0 .../apps}/square-toggle-theme-off-narrow.svg | 0 .../apps}/square-toggle-theme-on-narrow.svg | 0 .../apps}/square-toggle-white-off-narrow.svg | 0 .../apps}/square-toggle-white-on-narrow.svg | 0 .../apps}/star-gold-hollow-narrow.svg | 0 .../scalable/apps}/star-gold-hollow-small.svg | 0 .../scalable/apps}/star-gold-narrow.svg | 0 .../scalable/apps}/star-gold-small.svg | 0 .../scalable/apps}/star-hollow-narrow.svg | 0 .../scalable/apps}/star-hollow-small.svg | 0 .../scalable/apps}/star-narrow.svg | 0 .../rawtherapee/scalable/apps}/star-small.svg | 0 .../rawtherapee/scalable/apps}/star.svg | 0 .../scalable/apps}/template-16.svg | 0 .../scalable/apps}/template-24.svg | 0 .../scalable/apps}/template-narrow.svg | 0 .../apps}/tick-green-hollow-small.svg | 0 .../scalable/apps}/tick-green-hollow.svg | 0 .../scalable/apps}/tick-green-small.svg | 0 .../rawtherapee/scalable/apps}/tick-green.svg | 0 .../scalable/apps}/tick-hollow-small.svg | 0 .../rawtherapee/scalable/apps}/tick-small.svg | 0 .../rawtherapee/scalable/apps}/tick.svg | 0 .../rawtherapee/scalable/apps}/transform.svg | 0 .../scalable/apps}/trash-delete.svg | 0 .../scalable/apps}/trash-empty-show.svg | 0 .../scalable/apps}/trash-empty.svg | 0 .../scalable/apps}/trash-full-show.svg | 0 .../rawtherapee/scalable/apps}/trash-full.svg | 0 .../scalable/apps}/trash-hide-deleted.svg | 0 .../scalable/apps}/trash-remove-small.svg | 0 .../scalable/apps}/trash-remove.svg | 0 .../scalable/apps}/trash-small.svg | 0 .../rawtherapee/scalable/apps}/undo-all.svg | 0 .../rawtherapee/scalable/apps}/undo-small.svg | 0 .../rawtherapee/scalable/apps}/undo.svg | 0 .../scalable/apps}/warning-highlights.svg | 0 .../scalable/apps}/warning-shadows.svg | 0 .../rawtherapee/scalable/apps}/warning.svg | 0 .../rawtherapee/scalable/apps}/wavelets.svg | 0 .../scalable/apps}/wb-auto-small.svg | 0 .../rawtherapee/scalable/apps}/wb-auto.svg | 0 .../scalable/apps}/wb-camera-small.svg | 0 .../rawtherapee/scalable/apps}/wb-camera.svg | 0 .../scalable/apps}/wb-cloudy-small.svg | 0 .../rawtherapee/scalable/apps}/wb-cloudy.svg | 0 .../scalable/apps}/wb-custom-small.svg | 0 .../rawtherapee/scalable/apps}/wb-custom.svg | 0 .../scalable/apps}/wb-flash-small.svg | 0 .../rawtherapee/scalable/apps}/wb-flash.svg | 0 .../scalable/apps}/wb-fluorescent-small.svg | 0 .../scalable/apps}/wb-fluorescent.svg | 0 .../scalable/apps}/wb-lamp-small.svg | 0 .../rawtherapee/scalable/apps}/wb-lamp.svg | 0 .../scalable/apps}/wb-led-small.svg | 0 .../rawtherapee/scalable/apps}/wb-led.svg | 0 .../scalable/apps}/wb-shade-small.svg | 0 .../rawtherapee/scalable/apps}/wb-shade.svg | 0 .../scalable/apps}/wb-sun-small.svg | 0 .../rawtherapee/scalable/apps}/wb-sun.svg | 0 .../scalable/apps}/wb-tungsten-small.svg | 0 .../scalable/apps}/wb-tungsten.svg | 0 .../scalable/apps}/wb-water-small.svg | 0 .../rawtherapee/scalable/apps}/wb-water.svg | 0 .../rawtherapee/scalable/apps}/window-add.svg | 0 325 files changed, 4 insertions(+), 17 deletions(-) rename rtdata/{images/png/rawtherapee-logo-128.png => icons/rawtherapee/128x128/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png/rawtherapee-logo-16.png => icons/rawtherapee/16x16/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png/rawtherapee-logo-24.png => icons/rawtherapee/24x24/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png => icons/rawtherapee/24x24/apps}/empty.png (100%) rename rtdata/{images/png/rawtherapee-logo-256.png => icons/rawtherapee/256x256/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png/rawtherapee-logo-32.png => icons/rawtherapee/32x32/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png/rawtherapee-logo-48.png => icons/rawtherapee/48x48/app_icons/rawtherapee.png} (100%) rename rtdata/{images/png/rawtherapee-logo-64.png => icons/rawtherapee/64x64/app_icons/rawtherapee.png} (100%) rename rtdata/{images/svg => icons/rawtherapee}/index.theme (100%) rename rtdata/{images/rt-logo.svg => icons/rawtherapee/scalable/app_icons/rawtherapee.svg} (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/add-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/add.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/aperture.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow-down-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow-left-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow-right-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow-up-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow-updown.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow2-left.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/arrow2-right.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/atom.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/bayer.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/beforeafter.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/bidirectional-arrow-horizontal-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/bidirectional-arrow-horizontal-prelight.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/bidirectional-arrow-vertical-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/bidirectional-arrow-vertical-prelight.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/box.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/cancel-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/cancel.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-black-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-blue-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-blue-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-blue-yellow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-cyan-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-cyan-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-darkgray-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-darkgray-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-gray-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-purple-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-empty-yellow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-gray-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-gray-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-gray-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-gray-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-green-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-green-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-magenta-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-orange-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-purple-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-red-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-red-cyan-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-red-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-white-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-yellow-blue-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/circle-yellow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-circles.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-add-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-add.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-bars.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-hide.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/color-picker.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/contrastmask-off.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/contrastmask-on.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/copy.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crop-auto-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crop-auto.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crop-point-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crop-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crop.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crossed-arrows-in.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crossed-arrows-out.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crosshair-adjust.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crosshair-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crosshair-node-curve.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/crosshair-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-catmullrom-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-catmullrom.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-controlpoints-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-controlpoints.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-flat-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-flat.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-linear-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-linear.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-nurbs-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-nurbs.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-parametric-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-parametric.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-spline-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/curve-spline.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/detail.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/device-floppy.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/device-hdd.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/device-network.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/device-optical.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/device-usb.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-auto-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-auto.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-barrel-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-barrel.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-pincushion-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/distortion-pincushion.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/draw.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/edit-point.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/edit-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/edit.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/equilizer-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/equilizer-wide.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/expander-closed-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/expander-open-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/exposure.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filetype-hdr.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filetype-ps.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filter-clear.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filter-original.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filter-original2.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/filter.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/flip-horizontal.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/flip-vertical.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/focusscreen-off.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/focusscreen-on.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed-home-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed-home.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed-recent-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed-recent.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-closed.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-open-recent-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-open-recent.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-open-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/folder-open.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/fullscreen-enter.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/fullscreen-leave.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gamut-hist.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gamut-plus.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gamut-softproof.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gamut-warning.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gamut_srgb_prophoto_xy.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gears-pause.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gears-play.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gears-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/gears.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/goto-end-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/goto-start-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/hand-closed-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/hand-open-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/hand-open.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-bar-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-bar-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-blue-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-blue-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-ellipsis-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-gold-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-gold-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-green-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-green-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-mode-linear-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-mode-logx-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-mode-logxy-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-red-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-red-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-silver-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-silver-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-histogram-raw-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-histogram-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-parade-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-vectorscope-hc-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-vectorscope-hs-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/histogram-type-waveform-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/info.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/intent-absolute.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/intent-perceptual.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/intent-relative.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/intent-saturation.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-1to1-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-1to1.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-crop.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-fit.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-minus-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-minus.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-plus-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier-plus.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/magnifier.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/metadata.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/node-move-nw-se-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/node-move-sw-ne-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/node-move-x-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/node-move-xy-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/node-move-y-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/one-to-one-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/padlock-locked-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/padlock-unlocked-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/palette-brush.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/panel-to-bottom.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/panel-to-left.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/panel-to-right.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/panel-to-top.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/paste.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-horizontal-left-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-horizontal-left.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-horizontal-right-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-horizontal-right.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-horizontal-vertical.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-vertical-bottom-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-vertical-bottom.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-vertical-top-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/perspective-vertical-top.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/power-inconsistent-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/power-off-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/power-on-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/preferences.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/profile-filled.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/profile-partial.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/questionmark.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/redo-all.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/redo-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/redo.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/refresh-red-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/refresh-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/refresh.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/remove-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/remove.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-aroundnode-hicontrast.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-aroundnode.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-left-90.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-left-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-left.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-right-90.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-right-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-right.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-straighten-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/rotate-straighten.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/save-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/save.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/saved-no-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/saved-yes-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/spot-active.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/spot-normal.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/spot-prelight.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-black-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-black-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-blue-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-blue-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-gray-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-gray-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-green-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-green-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-luminosity-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-luminosity-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-red-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-red-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-theme-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-theme-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-white-off-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/square-toggle-white-on-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-gold-hollow-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-gold-hollow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-gold-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-gold-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-hollow-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-hollow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/star.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/template-16.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/template-24.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/template-narrow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-green-hollow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-green-hollow.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-green-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-green.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-hollow-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/tick.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/transform.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-delete.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-empty-show.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-empty.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-full-show.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-full.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-hide-deleted.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-remove-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-remove.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/trash-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/undo-all.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/undo-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/undo.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/warning-highlights.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/warning-shadows.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/warning.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wavelets.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-auto-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-auto.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-camera-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-camera.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-cloudy-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-cloudy.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-custom-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-custom.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-flash-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-flash.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-fluorescent-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-fluorescent.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-lamp-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-lamp.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-led-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-led.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-shade-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-shade.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-sun-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-sun.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-tungsten-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-tungsten.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-water-small.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/wb-water.svg (100%) rename rtdata/{images/svg => icons/rawtherapee/scalable/apps}/window-add.svg (100%) diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 7a0190e15..8d7c14573 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -6,9 +6,8 @@ file(GLOB DCPFILES "dcpprofiles/*") set(PROFILESDIR "profiles") set(THEMEDIR "themes") - -file(GLOB IMG_SVG LIST_DIRECTORIES false "images/svg/*.svg") -file(GLOB IMG_ICO LIST_DIRECTORIES false "images/*") +set(ICONSDIR "icons") +set(IMAGESDIR "images") if(WIN32) set(OPTIONSFILE "options/options.win") @@ -27,15 +26,6 @@ if(UNIX) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR}) endif() -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-16.png" DESTINATION "${ICONSDIR}/rawtherapee/16x16/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-24.png" DESTINATION "${ICONSDIR}/rawtherapee/24x24/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-32.png" DESTINATION "${ICONSDIR}/rawtherapee/32x32/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-48.png" DESTINATION "${ICONSDIR}/rawtherapee/48x48/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-64.png" DESTINATION "${ICONSDIR}/rawtherapee/64x64/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-128.png" DESTINATION "${ICONSDIR}/rawtherapee/128x128/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/rawtherapee-logo-256.png" DESTINATION "${ICONSDIR}/rawtherapee/256x256/app_icons" RENAME rawtherapee.png) -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/rt-logo.svg" DESTINATION "${ICONSDIR}/rawtherapee/scalable/app_icons" RENAME rawtherapee.svg) - install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") install(FILES ${SOUNDFILES} DESTINATION "${DATADIR}/sounds") install(FILES ${INPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/input") @@ -45,11 +35,8 @@ install(FILES ${OPTIONSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OW install(DIRECTORY "${PROFILESDIR}" DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") - -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/png/empty.png" DESTINATION "${ICONSDIR}/rawtherapee/24x24/apps") -install(FILES ${IMG_SVG} DESTINATION "${ICONSDIR}/rawtherapee/scalable/apps") -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/images/svg/index.theme" DESTINATION "${ICONSDIR}/rawtherapee") -install(FILES ${IMG_ICO} DESTINATION "${DATADIR}/images") +install(DIRECTORY "${ICONSDIR}" DESTINATION "${DATADIR}") +install(DIRECTORY "${IMAGESDIR}" DESTINATION "${DATADIR}") if(APPLE) # CMake escapes first item quote character. Do not remove 'DUMMY_VARIABLE=' diff --git a/rtdata/images/png/rawtherapee-logo-128.png b/rtdata/icons/rawtherapee/128x128/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-128.png rename to rtdata/icons/rawtherapee/128x128/app_icons/rawtherapee.png diff --git a/rtdata/images/png/rawtherapee-logo-16.png b/rtdata/icons/rawtherapee/16x16/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-16.png rename to rtdata/icons/rawtherapee/16x16/app_icons/rawtherapee.png diff --git a/rtdata/images/png/rawtherapee-logo-24.png b/rtdata/icons/rawtherapee/24x24/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-24.png rename to rtdata/icons/rawtherapee/24x24/app_icons/rawtherapee.png diff --git a/rtdata/images/png/empty.png b/rtdata/icons/rawtherapee/24x24/apps/empty.png similarity index 100% rename from rtdata/images/png/empty.png rename to rtdata/icons/rawtherapee/24x24/apps/empty.png diff --git a/rtdata/images/png/rawtherapee-logo-256.png b/rtdata/icons/rawtherapee/256x256/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-256.png rename to rtdata/icons/rawtherapee/256x256/app_icons/rawtherapee.png diff --git a/rtdata/images/png/rawtherapee-logo-32.png b/rtdata/icons/rawtherapee/32x32/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-32.png rename to rtdata/icons/rawtherapee/32x32/app_icons/rawtherapee.png diff --git a/rtdata/images/png/rawtherapee-logo-48.png b/rtdata/icons/rawtherapee/48x48/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-48.png rename to rtdata/icons/rawtherapee/48x48/app_icons/rawtherapee.png diff --git a/rtdata/images/png/rawtherapee-logo-64.png b/rtdata/icons/rawtherapee/64x64/app_icons/rawtherapee.png similarity index 100% rename from rtdata/images/png/rawtherapee-logo-64.png rename to rtdata/icons/rawtherapee/64x64/app_icons/rawtherapee.png diff --git a/rtdata/images/svg/index.theme b/rtdata/icons/rawtherapee/index.theme similarity index 100% rename from rtdata/images/svg/index.theme rename to rtdata/icons/rawtherapee/index.theme diff --git a/rtdata/images/rt-logo.svg b/rtdata/icons/rawtherapee/scalable/app_icons/rawtherapee.svg similarity index 100% rename from rtdata/images/rt-logo.svg rename to rtdata/icons/rawtherapee/scalable/app_icons/rawtherapee.svg diff --git a/rtdata/images/svg/add-small.svg b/rtdata/icons/rawtherapee/scalable/apps/add-small.svg similarity index 100% rename from rtdata/images/svg/add-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/add-small.svg diff --git a/rtdata/images/svg/add.svg b/rtdata/icons/rawtherapee/scalable/apps/add.svg similarity index 100% rename from rtdata/images/svg/add.svg rename to rtdata/icons/rawtherapee/scalable/apps/add.svg diff --git a/rtdata/images/svg/aperture.svg b/rtdata/icons/rawtherapee/scalable/apps/aperture.svg similarity index 100% rename from rtdata/images/svg/aperture.svg rename to rtdata/icons/rawtherapee/scalable/apps/aperture.svg diff --git a/rtdata/images/svg/arrow-down-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg similarity index 100% rename from rtdata/images/svg/arrow-down-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg diff --git a/rtdata/images/svg/arrow-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg similarity index 100% rename from rtdata/images/svg/arrow-left-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg diff --git a/rtdata/images/svg/arrow-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg similarity index 100% rename from rtdata/images/svg/arrow-right-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg diff --git a/rtdata/images/svg/arrow-up-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg similarity index 100% rename from rtdata/images/svg/arrow-up-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg diff --git a/rtdata/images/svg/arrow-updown.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg similarity index 100% rename from rtdata/images/svg/arrow-updown.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg diff --git a/rtdata/images/svg/arrow2-left.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg similarity index 100% rename from rtdata/images/svg/arrow2-left.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg diff --git a/rtdata/images/svg/arrow2-right.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg similarity index 100% rename from rtdata/images/svg/arrow2-right.svg rename to rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg diff --git a/rtdata/images/svg/atom.svg b/rtdata/icons/rawtherapee/scalable/apps/atom.svg similarity index 100% rename from rtdata/images/svg/atom.svg rename to rtdata/icons/rawtherapee/scalable/apps/atom.svg diff --git a/rtdata/images/svg/bayer.svg b/rtdata/icons/rawtherapee/scalable/apps/bayer.svg similarity index 100% rename from rtdata/images/svg/bayer.svg rename to rtdata/icons/rawtherapee/scalable/apps/bayer.svg diff --git a/rtdata/images/svg/beforeafter.svg b/rtdata/icons/rawtherapee/scalable/apps/beforeafter.svg similarity index 100% rename from rtdata/images/svg/beforeafter.svg rename to rtdata/icons/rawtherapee/scalable/apps/beforeafter.svg diff --git a/rtdata/images/svg/bidirectional-arrow-horizontal-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-hicontrast.svg similarity index 100% rename from rtdata/images/svg/bidirectional-arrow-horizontal-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-hicontrast.svg diff --git a/rtdata/images/svg/bidirectional-arrow-horizontal-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg similarity index 100% rename from rtdata/images/svg/bidirectional-arrow-horizontal-prelight.svg rename to rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg diff --git a/rtdata/images/svg/bidirectional-arrow-vertical-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg similarity index 100% rename from rtdata/images/svg/bidirectional-arrow-vertical-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg diff --git a/rtdata/images/svg/bidirectional-arrow-vertical-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg similarity index 100% rename from rtdata/images/svg/bidirectional-arrow-vertical-prelight.svg rename to rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg diff --git a/rtdata/images/svg/box.svg b/rtdata/icons/rawtherapee/scalable/apps/box.svg similarity index 100% rename from rtdata/images/svg/box.svg rename to rtdata/icons/rawtherapee/scalable/apps/box.svg diff --git a/rtdata/images/svg/cancel-small.svg b/rtdata/icons/rawtherapee/scalable/apps/cancel-small.svg similarity index 100% rename from rtdata/images/svg/cancel-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/cancel-small.svg diff --git a/rtdata/images/svg/cancel.svg b/rtdata/icons/rawtherapee/scalable/apps/cancel.svg similarity index 100% rename from rtdata/images/svg/cancel.svg rename to rtdata/icons/rawtherapee/scalable/apps/cancel.svg diff --git a/rtdata/images/svg/circle-black-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg similarity index 100% rename from rtdata/images/svg/circle-black-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg diff --git a/rtdata/images/svg/circle-blue-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-blue-green-small.svg similarity index 100% rename from rtdata/images/svg/circle-blue-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-blue-green-small.svg diff --git a/rtdata/images/svg/circle-blue-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-blue-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-blue-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-blue-red-small.svg diff --git a/rtdata/images/svg/circle-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-blue-small.svg diff --git a/rtdata/images/svg/circle-blue-yellow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-blue-yellow-small.svg similarity index 100% rename from rtdata/images/svg/circle-blue-yellow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-blue-yellow-small.svg diff --git a/rtdata/images/svg/circle-cyan-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-cyan-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-cyan-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-cyan-red-small.svg diff --git a/rtdata/images/svg/circle-cyan-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-cyan-small.svg similarity index 100% rename from rtdata/images/svg/circle-cyan-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-cyan-small.svg diff --git a/rtdata/images/svg/circle-darkgray-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-darkgray-small.svg similarity index 100% rename from rtdata/images/svg/circle-darkgray-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-darkgray-small.svg diff --git a/rtdata/images/svg/circle-empty-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-blue-small.svg diff --git a/rtdata/images/svg/circle-empty-darkgray-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-darkgray-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-darkgray-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-darkgray-small.svg diff --git a/rtdata/images/svg/circle-empty-gray-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-gray-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-gray-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-gray-small.svg diff --git a/rtdata/images/svg/circle-empty-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-green-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-green-small.svg diff --git a/rtdata/images/svg/circle-empty-purple-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-purple-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-purple-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-purple-small.svg diff --git a/rtdata/images/svg/circle-empty-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-red-small.svg diff --git a/rtdata/images/svg/circle-empty-yellow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-empty-yellow-small.svg similarity index 100% rename from rtdata/images/svg/circle-empty-yellow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-empty-yellow-small.svg diff --git a/rtdata/images/svg/circle-gray-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-gray-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-gray-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-gray-blue-small.svg diff --git a/rtdata/images/svg/circle-gray-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-gray-green-small.svg similarity index 100% rename from rtdata/images/svg/circle-gray-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-gray-green-small.svg diff --git a/rtdata/images/svg/circle-gray-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-gray-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-gray-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-gray-red-small.svg diff --git a/rtdata/images/svg/circle-gray-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-gray-small.svg similarity index 100% rename from rtdata/images/svg/circle-gray-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-gray-small.svg diff --git a/rtdata/images/svg/circle-green-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-green-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-green-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-green-blue-small.svg diff --git a/rtdata/images/svg/circle-green-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-green-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-green-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-green-red-small.svg diff --git a/rtdata/images/svg/circle-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-green-small.svg similarity index 100% rename from rtdata/images/svg/circle-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-green-small.svg diff --git a/rtdata/images/svg/circle-magenta-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-magenta-small.svg similarity index 100% rename from rtdata/images/svg/circle-magenta-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-magenta-small.svg diff --git a/rtdata/images/svg/circle-orange-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-orange-small.svg similarity index 100% rename from rtdata/images/svg/circle-orange-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-orange-small.svg diff --git a/rtdata/images/svg/circle-purple-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-purple-small.svg similarity index 100% rename from rtdata/images/svg/circle-purple-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-purple-small.svg diff --git a/rtdata/images/svg/circle-red-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-red-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-red-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-red-blue-small.svg diff --git a/rtdata/images/svg/circle-red-cyan-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-red-cyan-small.svg similarity index 100% rename from rtdata/images/svg/circle-red-cyan-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-red-cyan-small.svg diff --git a/rtdata/images/svg/circle-red-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-red-green-small.svg similarity index 100% rename from rtdata/images/svg/circle-red-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-red-green-small.svg diff --git a/rtdata/images/svg/circle-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-red-small.svg similarity index 100% rename from rtdata/images/svg/circle-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-red-small.svg diff --git a/rtdata/images/svg/circle-white-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-white-small.svg similarity index 100% rename from rtdata/images/svg/circle-white-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-white-small.svg diff --git a/rtdata/images/svg/circle-yellow-blue-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-yellow-blue-small.svg similarity index 100% rename from rtdata/images/svg/circle-yellow-blue-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-yellow-blue-small.svg diff --git a/rtdata/images/svg/circle-yellow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-yellow-small.svg similarity index 100% rename from rtdata/images/svg/circle-yellow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/circle-yellow-small.svg diff --git a/rtdata/images/svg/color-circles.svg b/rtdata/icons/rawtherapee/scalable/apps/color-circles.svg similarity index 100% rename from rtdata/images/svg/color-circles.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-circles.svg diff --git a/rtdata/images/svg/color-picker-add-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg similarity index 100% rename from rtdata/images/svg/color-picker-add-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg diff --git a/rtdata/images/svg/color-picker-add.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg similarity index 100% rename from rtdata/images/svg/color-picker-add.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg diff --git a/rtdata/images/svg/color-picker-bars.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg similarity index 100% rename from rtdata/images/svg/color-picker-bars.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg diff --git a/rtdata/images/svg/color-picker-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg similarity index 100% rename from rtdata/images/svg/color-picker-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg diff --git a/rtdata/images/svg/color-picker-hide.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg similarity index 100% rename from rtdata/images/svg/color-picker-hide.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg diff --git a/rtdata/images/svg/color-picker-small.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg similarity index 100% rename from rtdata/images/svg/color-picker-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg diff --git a/rtdata/images/svg/color-picker.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker.svg similarity index 100% rename from rtdata/images/svg/color-picker.svg rename to rtdata/icons/rawtherapee/scalable/apps/color-picker.svg diff --git a/rtdata/images/svg/contrastmask-off.svg b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg similarity index 100% rename from rtdata/images/svg/contrastmask-off.svg rename to rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg diff --git a/rtdata/images/svg/contrastmask-on.svg b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg similarity index 100% rename from rtdata/images/svg/contrastmask-on.svg rename to rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg diff --git a/rtdata/images/svg/copy.svg b/rtdata/icons/rawtherapee/scalable/apps/copy.svg similarity index 100% rename from rtdata/images/svg/copy.svg rename to rtdata/icons/rawtherapee/scalable/apps/copy.svg diff --git a/rtdata/images/svg/crop-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg similarity index 100% rename from rtdata/images/svg/crop-auto-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg diff --git a/rtdata/images/svg/crop-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg similarity index 100% rename from rtdata/images/svg/crop-auto.svg rename to rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg diff --git a/rtdata/images/svg/crop-point-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg similarity index 100% rename from rtdata/images/svg/crop-point-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg diff --git a/rtdata/images/svg/crop-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-small.svg similarity index 100% rename from rtdata/images/svg/crop-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/crop-small.svg diff --git a/rtdata/images/svg/crop.svg b/rtdata/icons/rawtherapee/scalable/apps/crop.svg similarity index 100% rename from rtdata/images/svg/crop.svg rename to rtdata/icons/rawtherapee/scalable/apps/crop.svg diff --git a/rtdata/images/svg/crossed-arrows-in.svg b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg similarity index 100% rename from rtdata/images/svg/crossed-arrows-in.svg rename to rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg diff --git a/rtdata/images/svg/crossed-arrows-out.svg b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg similarity index 100% rename from rtdata/images/svg/crossed-arrows-out.svg rename to rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg diff --git a/rtdata/images/svg/crosshair-adjust.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg similarity index 100% rename from rtdata/images/svg/crosshair-adjust.svg rename to rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg diff --git a/rtdata/images/svg/crosshair-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg similarity index 100% rename from rtdata/images/svg/crosshair-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg diff --git a/rtdata/images/svg/crosshair-node-curve.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg similarity index 100% rename from rtdata/images/svg/crosshair-node-curve.svg rename to rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg diff --git a/rtdata/images/svg/crosshair-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg similarity index 100% rename from rtdata/images/svg/crosshair-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg diff --git a/rtdata/images/svg/curve-catmullrom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg similarity index 100% rename from rtdata/images/svg/curve-catmullrom-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg diff --git a/rtdata/images/svg/curve-catmullrom.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg similarity index 100% rename from rtdata/images/svg/curve-catmullrom.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg diff --git a/rtdata/images/svg/curve-controlpoints-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg similarity index 100% rename from rtdata/images/svg/curve-controlpoints-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg diff --git a/rtdata/images/svg/curve-controlpoints.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg similarity index 100% rename from rtdata/images/svg/curve-controlpoints.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg diff --git a/rtdata/images/svg/curve-flat-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg similarity index 100% rename from rtdata/images/svg/curve-flat-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg diff --git a/rtdata/images/svg/curve-flat.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg similarity index 100% rename from rtdata/images/svg/curve-flat.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg diff --git a/rtdata/images/svg/curve-linear-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg similarity index 100% rename from rtdata/images/svg/curve-linear-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg diff --git a/rtdata/images/svg/curve-linear.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg similarity index 100% rename from rtdata/images/svg/curve-linear.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg diff --git a/rtdata/images/svg/curve-nurbs-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg similarity index 100% rename from rtdata/images/svg/curve-nurbs-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg diff --git a/rtdata/images/svg/curve-nurbs.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg similarity index 100% rename from rtdata/images/svg/curve-nurbs.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg diff --git a/rtdata/images/svg/curve-parametric-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg similarity index 100% rename from rtdata/images/svg/curve-parametric-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg diff --git a/rtdata/images/svg/curve-parametric.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-parametric.svg similarity index 100% rename from rtdata/images/svg/curve-parametric.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-parametric.svg diff --git a/rtdata/images/svg/curve-spline-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg similarity index 100% rename from rtdata/images/svg/curve-spline-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg diff --git a/rtdata/images/svg/curve-spline.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-spline.svg similarity index 100% rename from rtdata/images/svg/curve-spline.svg rename to rtdata/icons/rawtherapee/scalable/apps/curve-spline.svg diff --git a/rtdata/images/svg/detail.svg b/rtdata/icons/rawtherapee/scalable/apps/detail.svg similarity index 100% rename from rtdata/images/svg/detail.svg rename to rtdata/icons/rawtherapee/scalable/apps/detail.svg diff --git a/rtdata/images/svg/device-floppy.svg b/rtdata/icons/rawtherapee/scalable/apps/device-floppy.svg similarity index 100% rename from rtdata/images/svg/device-floppy.svg rename to rtdata/icons/rawtherapee/scalable/apps/device-floppy.svg diff --git a/rtdata/images/svg/device-hdd.svg b/rtdata/icons/rawtherapee/scalable/apps/device-hdd.svg similarity index 100% rename from rtdata/images/svg/device-hdd.svg rename to rtdata/icons/rawtherapee/scalable/apps/device-hdd.svg diff --git a/rtdata/images/svg/device-network.svg b/rtdata/icons/rawtherapee/scalable/apps/device-network.svg similarity index 100% rename from rtdata/images/svg/device-network.svg rename to rtdata/icons/rawtherapee/scalable/apps/device-network.svg diff --git a/rtdata/images/svg/device-optical.svg b/rtdata/icons/rawtherapee/scalable/apps/device-optical.svg similarity index 100% rename from rtdata/images/svg/device-optical.svg rename to rtdata/icons/rawtherapee/scalable/apps/device-optical.svg diff --git a/rtdata/images/svg/device-usb.svg b/rtdata/icons/rawtherapee/scalable/apps/device-usb.svg similarity index 100% rename from rtdata/images/svg/device-usb.svg rename to rtdata/icons/rawtherapee/scalable/apps/device-usb.svg diff --git a/rtdata/images/svg/distortion-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg similarity index 100% rename from rtdata/images/svg/distortion-auto-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg diff --git a/rtdata/images/svg/distortion-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg similarity index 100% rename from rtdata/images/svg/distortion-auto.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg diff --git a/rtdata/images/svg/distortion-barrel-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg similarity index 100% rename from rtdata/images/svg/distortion-barrel-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg diff --git a/rtdata/images/svg/distortion-barrel.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg similarity index 100% rename from rtdata/images/svg/distortion-barrel.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg diff --git a/rtdata/images/svg/distortion-pincushion-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg similarity index 100% rename from rtdata/images/svg/distortion-pincushion-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg diff --git a/rtdata/images/svg/distortion-pincushion.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg similarity index 100% rename from rtdata/images/svg/distortion-pincushion.svg rename to rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg diff --git a/rtdata/images/svg/draw.svg b/rtdata/icons/rawtherapee/scalable/apps/draw.svg similarity index 100% rename from rtdata/images/svg/draw.svg rename to rtdata/icons/rawtherapee/scalable/apps/draw.svg diff --git a/rtdata/images/svg/edit-point.svg b/rtdata/icons/rawtherapee/scalable/apps/edit-point.svg similarity index 100% rename from rtdata/images/svg/edit-point.svg rename to rtdata/icons/rawtherapee/scalable/apps/edit-point.svg diff --git a/rtdata/images/svg/edit-small.svg b/rtdata/icons/rawtherapee/scalable/apps/edit-small.svg similarity index 100% rename from rtdata/images/svg/edit-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/edit-small.svg diff --git a/rtdata/images/svg/edit.svg b/rtdata/icons/rawtherapee/scalable/apps/edit.svg similarity index 100% rename from rtdata/images/svg/edit.svg rename to rtdata/icons/rawtherapee/scalable/apps/edit.svg diff --git a/rtdata/images/svg/equilizer-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg similarity index 100% rename from rtdata/images/svg/equilizer-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg diff --git a/rtdata/images/svg/equilizer-wide.svg b/rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg similarity index 100% rename from rtdata/images/svg/equilizer-wide.svg rename to rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg diff --git a/rtdata/images/svg/expander-closed-small.svg b/rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg similarity index 100% rename from rtdata/images/svg/expander-closed-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg diff --git a/rtdata/images/svg/expander-open-small.svg b/rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg similarity index 100% rename from rtdata/images/svg/expander-open-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg diff --git a/rtdata/images/svg/exposure.svg b/rtdata/icons/rawtherapee/scalable/apps/exposure.svg similarity index 100% rename from rtdata/images/svg/exposure.svg rename to rtdata/icons/rawtherapee/scalable/apps/exposure.svg diff --git a/rtdata/images/svg/filetype-hdr.svg b/rtdata/icons/rawtherapee/scalable/apps/filetype-hdr.svg similarity index 100% rename from rtdata/images/svg/filetype-hdr.svg rename to rtdata/icons/rawtherapee/scalable/apps/filetype-hdr.svg diff --git a/rtdata/images/svg/filetype-ps.svg b/rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg similarity index 100% rename from rtdata/images/svg/filetype-ps.svg rename to rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg diff --git a/rtdata/images/svg/filter-clear.svg b/rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg similarity index 100% rename from rtdata/images/svg/filter-clear.svg rename to rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg diff --git a/rtdata/images/svg/filter-original.svg b/rtdata/icons/rawtherapee/scalable/apps/filter-original.svg similarity index 100% rename from rtdata/images/svg/filter-original.svg rename to rtdata/icons/rawtherapee/scalable/apps/filter-original.svg diff --git a/rtdata/images/svg/filter-original2.svg b/rtdata/icons/rawtherapee/scalable/apps/filter-original2.svg similarity index 100% rename from rtdata/images/svg/filter-original2.svg rename to rtdata/icons/rawtherapee/scalable/apps/filter-original2.svg diff --git a/rtdata/images/svg/filter.svg b/rtdata/icons/rawtherapee/scalable/apps/filter.svg similarity index 100% rename from rtdata/images/svg/filter.svg rename to rtdata/icons/rawtherapee/scalable/apps/filter.svg diff --git a/rtdata/images/svg/flip-horizontal.svg b/rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg similarity index 100% rename from rtdata/images/svg/flip-horizontal.svg rename to rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg diff --git a/rtdata/images/svg/flip-vertical.svg b/rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg similarity index 100% rename from rtdata/images/svg/flip-vertical.svg rename to rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg diff --git a/rtdata/images/svg/focusscreen-off.svg b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg similarity index 100% rename from rtdata/images/svg/focusscreen-off.svg rename to rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg diff --git a/rtdata/images/svg/focusscreen-on.svg b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg similarity index 100% rename from rtdata/images/svg/focusscreen-on.svg rename to rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg diff --git a/rtdata/images/svg/folder-closed-home-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg similarity index 100% rename from rtdata/images/svg/folder-closed-home-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg diff --git a/rtdata/images/svg/folder-closed-home.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg similarity index 100% rename from rtdata/images/svg/folder-closed-home.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg diff --git a/rtdata/images/svg/folder-closed-recent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg similarity index 100% rename from rtdata/images/svg/folder-closed-recent-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg diff --git a/rtdata/images/svg/folder-closed-recent.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg similarity index 100% rename from rtdata/images/svg/folder-closed-recent.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg diff --git a/rtdata/images/svg/folder-closed-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg similarity index 100% rename from rtdata/images/svg/folder-closed-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg diff --git a/rtdata/images/svg/folder-closed.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg similarity index 100% rename from rtdata/images/svg/folder-closed.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg diff --git a/rtdata/images/svg/folder-open-recent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg similarity index 100% rename from rtdata/images/svg/folder-open-recent-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg diff --git a/rtdata/images/svg/folder-open-recent.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg similarity index 100% rename from rtdata/images/svg/folder-open-recent.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg diff --git a/rtdata/images/svg/folder-open-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg similarity index 100% rename from rtdata/images/svg/folder-open-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg diff --git a/rtdata/images/svg/folder-open.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open.svg similarity index 100% rename from rtdata/images/svg/folder-open.svg rename to rtdata/icons/rawtherapee/scalable/apps/folder-open.svg diff --git a/rtdata/images/svg/fullscreen-enter.svg b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg similarity index 100% rename from rtdata/images/svg/fullscreen-enter.svg rename to rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg diff --git a/rtdata/images/svg/fullscreen-leave.svg b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg similarity index 100% rename from rtdata/images/svg/fullscreen-leave.svg rename to rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg diff --git a/rtdata/images/svg/gamut-hist.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg similarity index 100% rename from rtdata/images/svg/gamut-hist.svg rename to rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg diff --git a/rtdata/images/svg/gamut-plus.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg similarity index 100% rename from rtdata/images/svg/gamut-plus.svg rename to rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg diff --git a/rtdata/images/svg/gamut-softproof.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg similarity index 100% rename from rtdata/images/svg/gamut-softproof.svg rename to rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg diff --git a/rtdata/images/svg/gamut-warning.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg similarity index 100% rename from rtdata/images/svg/gamut-warning.svg rename to rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg diff --git a/rtdata/images/svg/gamut_srgb_prophoto_xy.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg similarity index 100% rename from rtdata/images/svg/gamut_srgb_prophoto_xy.svg rename to rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg diff --git a/rtdata/images/svg/gears-pause.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg similarity index 100% rename from rtdata/images/svg/gears-pause.svg rename to rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg diff --git a/rtdata/images/svg/gears-play.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-play.svg similarity index 100% rename from rtdata/images/svg/gears-play.svg rename to rtdata/icons/rawtherapee/scalable/apps/gears-play.svg diff --git a/rtdata/images/svg/gears-small.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-small.svg similarity index 100% rename from rtdata/images/svg/gears-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/gears-small.svg diff --git a/rtdata/images/svg/gears.svg b/rtdata/icons/rawtherapee/scalable/apps/gears.svg similarity index 100% rename from rtdata/images/svg/gears.svg rename to rtdata/icons/rawtherapee/scalable/apps/gears.svg diff --git a/rtdata/images/svg/goto-end-small.svg b/rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg similarity index 100% rename from rtdata/images/svg/goto-end-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg diff --git a/rtdata/images/svg/goto-start-small.svg b/rtdata/icons/rawtherapee/scalable/apps/goto-start-small.svg similarity index 100% rename from rtdata/images/svg/goto-start-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/goto-start-small.svg diff --git a/rtdata/images/svg/hand-closed-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/hand-closed-hicontrast.svg similarity index 100% rename from rtdata/images/svg/hand-closed-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/hand-closed-hicontrast.svg diff --git a/rtdata/images/svg/hand-open-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg similarity index 100% rename from rtdata/images/svg/hand-open-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg diff --git a/rtdata/images/svg/hand-open.svg b/rtdata/icons/rawtherapee/scalable/apps/hand-open.svg similarity index 100% rename from rtdata/images/svg/hand-open.svg rename to rtdata/icons/rawtherapee/scalable/apps/hand-open.svg diff --git a/rtdata/images/svg/histogram-bar-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-bar-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg diff --git a/rtdata/images/svg/histogram-bar-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-bar-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-bar-on-small.svg diff --git a/rtdata/images/svg/histogram-blue-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-blue-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-blue-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-blue-off-small.svg diff --git a/rtdata/images/svg/histogram-blue-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-blue-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-blue-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-blue-on-small.svg diff --git a/rtdata/images/svg/histogram-ellipsis-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-ellipsis-small.svg similarity index 100% rename from rtdata/images/svg/histogram-ellipsis-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-ellipsis-small.svg diff --git a/rtdata/images/svg/histogram-gold-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-gold-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-gold-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-gold-off-small.svg diff --git a/rtdata/images/svg/histogram-gold-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-gold-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-gold-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-gold-on-small.svg diff --git a/rtdata/images/svg/histogram-green-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-green-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-green-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-green-off-small.svg diff --git a/rtdata/images/svg/histogram-green-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-green-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-green-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-green-on-small.svg diff --git a/rtdata/images/svg/histogram-mode-linear-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-linear-small.svg similarity index 100% rename from rtdata/images/svg/histogram-mode-linear-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-mode-linear-small.svg diff --git a/rtdata/images/svg/histogram-mode-logx-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg similarity index 100% rename from rtdata/images/svg/histogram-mode-logx-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg diff --git a/rtdata/images/svg/histogram-mode-logxy-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg similarity index 100% rename from rtdata/images/svg/histogram-mode-logxy-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg diff --git a/rtdata/images/svg/histogram-red-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-red-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg diff --git a/rtdata/images/svg/histogram-red-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-red-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-red-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-red-on-small.svg diff --git a/rtdata/images/svg/histogram-silver-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-silver-off-small.svg similarity index 100% rename from rtdata/images/svg/histogram-silver-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-silver-off-small.svg diff --git a/rtdata/images/svg/histogram-silver-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-silver-on-small.svg similarity index 100% rename from rtdata/images/svg/histogram-silver-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-silver-on-small.svg diff --git a/rtdata/images/svg/histogram-type-histogram-raw-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-histogram-raw-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-histogram-raw-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-histogram-raw-small.svg diff --git a/rtdata/images/svg/histogram-type-histogram-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-histogram-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-histogram-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-histogram-small.svg diff --git a/rtdata/images/svg/histogram-type-parade-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-parade-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-parade-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-parade-small.svg diff --git a/rtdata/images/svg/histogram-type-vectorscope-hc-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-vectorscope-hc-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg diff --git a/rtdata/images/svg/histogram-type-vectorscope-hs-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-vectorscope-hs-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg diff --git a/rtdata/images/svg/histogram-type-waveform-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg similarity index 100% rename from rtdata/images/svg/histogram-type-waveform-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg diff --git a/rtdata/images/svg/info.svg b/rtdata/icons/rawtherapee/scalable/apps/info.svg similarity index 100% rename from rtdata/images/svg/info.svg rename to rtdata/icons/rawtherapee/scalable/apps/info.svg diff --git a/rtdata/images/svg/intent-absolute.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg similarity index 100% rename from rtdata/images/svg/intent-absolute.svg rename to rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg diff --git a/rtdata/images/svg/intent-perceptual.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg similarity index 100% rename from rtdata/images/svg/intent-perceptual.svg rename to rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg diff --git a/rtdata/images/svg/intent-relative.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg similarity index 100% rename from rtdata/images/svg/intent-relative.svg rename to rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg diff --git a/rtdata/images/svg/intent-saturation.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg similarity index 100% rename from rtdata/images/svg/intent-saturation.svg rename to rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg diff --git a/rtdata/images/svg/magnifier-1to1-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg similarity index 100% rename from rtdata/images/svg/magnifier-1to1-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg diff --git a/rtdata/images/svg/magnifier-1to1.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1.svg similarity index 100% rename from rtdata/images/svg/magnifier-1to1.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1.svg diff --git a/rtdata/images/svg/magnifier-crop.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg similarity index 100% rename from rtdata/images/svg/magnifier-crop.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg diff --git a/rtdata/images/svg/magnifier-fit.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg similarity index 100% rename from rtdata/images/svg/magnifier-fit.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg diff --git a/rtdata/images/svg/magnifier-minus-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg similarity index 100% rename from rtdata/images/svg/magnifier-minus-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg diff --git a/rtdata/images/svg/magnifier-minus.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg similarity index 100% rename from rtdata/images/svg/magnifier-minus.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg diff --git a/rtdata/images/svg/magnifier-plus-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg similarity index 100% rename from rtdata/images/svg/magnifier-plus-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg diff --git a/rtdata/images/svg/magnifier-plus.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg similarity index 100% rename from rtdata/images/svg/magnifier-plus.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg diff --git a/rtdata/images/svg/magnifier.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier.svg similarity index 100% rename from rtdata/images/svg/magnifier.svg rename to rtdata/icons/rawtherapee/scalable/apps/magnifier.svg diff --git a/rtdata/images/svg/metadata.svg b/rtdata/icons/rawtherapee/scalable/apps/metadata.svg similarity index 100% rename from rtdata/images/svg/metadata.svg rename to rtdata/icons/rawtherapee/scalable/apps/metadata.svg diff --git a/rtdata/images/svg/node-move-nw-se-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg similarity index 100% rename from rtdata/images/svg/node-move-nw-se-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg diff --git a/rtdata/images/svg/node-move-sw-ne-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg similarity index 100% rename from rtdata/images/svg/node-move-sw-ne-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg diff --git a/rtdata/images/svg/node-move-x-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg similarity index 100% rename from rtdata/images/svg/node-move-x-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg diff --git a/rtdata/images/svg/node-move-xy-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg similarity index 100% rename from rtdata/images/svg/node-move-xy-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg diff --git a/rtdata/images/svg/node-move-y-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg similarity index 100% rename from rtdata/images/svg/node-move-y-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg diff --git a/rtdata/images/svg/one-to-one-small.svg b/rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg similarity index 100% rename from rtdata/images/svg/one-to-one-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg diff --git a/rtdata/images/svg/padlock-locked-small.svg b/rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg similarity index 100% rename from rtdata/images/svg/padlock-locked-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg diff --git a/rtdata/images/svg/padlock-unlocked-small.svg b/rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg similarity index 100% rename from rtdata/images/svg/padlock-unlocked-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg diff --git a/rtdata/images/svg/palette-brush.svg b/rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg similarity index 100% rename from rtdata/images/svg/palette-brush.svg rename to rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg diff --git a/rtdata/images/svg/panel-to-bottom.svg b/rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg similarity index 100% rename from rtdata/images/svg/panel-to-bottom.svg rename to rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg diff --git a/rtdata/images/svg/panel-to-left.svg b/rtdata/icons/rawtherapee/scalable/apps/panel-to-left.svg similarity index 100% rename from rtdata/images/svg/panel-to-left.svg rename to rtdata/icons/rawtherapee/scalable/apps/panel-to-left.svg diff --git a/rtdata/images/svg/panel-to-right.svg b/rtdata/icons/rawtherapee/scalable/apps/panel-to-right.svg similarity index 100% rename from rtdata/images/svg/panel-to-right.svg rename to rtdata/icons/rawtherapee/scalable/apps/panel-to-right.svg diff --git a/rtdata/images/svg/panel-to-top.svg b/rtdata/icons/rawtherapee/scalable/apps/panel-to-top.svg similarity index 100% rename from rtdata/images/svg/panel-to-top.svg rename to rtdata/icons/rawtherapee/scalable/apps/panel-to-top.svg diff --git a/rtdata/images/svg/paste.svg b/rtdata/icons/rawtherapee/scalable/apps/paste.svg similarity index 100% rename from rtdata/images/svg/paste.svg rename to rtdata/icons/rawtherapee/scalable/apps/paste.svg diff --git a/rtdata/images/svg/perspective-horizontal-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg similarity index 100% rename from rtdata/images/svg/perspective-horizontal-left-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg diff --git a/rtdata/images/svg/perspective-horizontal-left.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg similarity index 100% rename from rtdata/images/svg/perspective-horizontal-left.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg diff --git a/rtdata/images/svg/perspective-horizontal-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg similarity index 100% rename from rtdata/images/svg/perspective-horizontal-right-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg diff --git a/rtdata/images/svg/perspective-horizontal-right.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg similarity index 100% rename from rtdata/images/svg/perspective-horizontal-right.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg diff --git a/rtdata/images/svg/perspective-horizontal-vertical.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg similarity index 100% rename from rtdata/images/svg/perspective-horizontal-vertical.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg diff --git a/rtdata/images/svg/perspective-vertical-bottom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg similarity index 100% rename from rtdata/images/svg/perspective-vertical-bottom-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg diff --git a/rtdata/images/svg/perspective-vertical-bottom.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg similarity index 100% rename from rtdata/images/svg/perspective-vertical-bottom.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg diff --git a/rtdata/images/svg/perspective-vertical-top-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg similarity index 100% rename from rtdata/images/svg/perspective-vertical-top-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg diff --git a/rtdata/images/svg/perspective-vertical-top.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg similarity index 100% rename from rtdata/images/svg/perspective-vertical-top.svg rename to rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg diff --git a/rtdata/images/svg/power-inconsistent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg similarity index 100% rename from rtdata/images/svg/power-inconsistent-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg diff --git a/rtdata/images/svg/power-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/power-off-small.svg similarity index 100% rename from rtdata/images/svg/power-off-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/power-off-small.svg diff --git a/rtdata/images/svg/power-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg similarity index 100% rename from rtdata/images/svg/power-on-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg diff --git a/rtdata/images/svg/preferences.svg b/rtdata/icons/rawtherapee/scalable/apps/preferences.svg similarity index 100% rename from rtdata/images/svg/preferences.svg rename to rtdata/icons/rawtherapee/scalable/apps/preferences.svg diff --git a/rtdata/images/svg/profile-filled.svg b/rtdata/icons/rawtherapee/scalable/apps/profile-filled.svg similarity index 100% rename from rtdata/images/svg/profile-filled.svg rename to rtdata/icons/rawtherapee/scalable/apps/profile-filled.svg diff --git a/rtdata/images/svg/profile-partial.svg b/rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg similarity index 100% rename from rtdata/images/svg/profile-partial.svg rename to rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg diff --git a/rtdata/images/svg/questionmark.svg b/rtdata/icons/rawtherapee/scalable/apps/questionmark.svg similarity index 100% rename from rtdata/images/svg/questionmark.svg rename to rtdata/icons/rawtherapee/scalable/apps/questionmark.svg diff --git a/rtdata/images/svg/redo-all.svg b/rtdata/icons/rawtherapee/scalable/apps/redo-all.svg similarity index 100% rename from rtdata/images/svg/redo-all.svg rename to rtdata/icons/rawtherapee/scalable/apps/redo-all.svg diff --git a/rtdata/images/svg/redo-small.svg b/rtdata/icons/rawtherapee/scalable/apps/redo-small.svg similarity index 100% rename from rtdata/images/svg/redo-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/redo-small.svg diff --git a/rtdata/images/svg/redo.svg b/rtdata/icons/rawtherapee/scalable/apps/redo.svg similarity index 100% rename from rtdata/images/svg/redo.svg rename to rtdata/icons/rawtherapee/scalable/apps/redo.svg diff --git a/rtdata/images/svg/refresh-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg similarity index 100% rename from rtdata/images/svg/refresh-red-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg diff --git a/rtdata/images/svg/refresh-small.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg similarity index 100% rename from rtdata/images/svg/refresh-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg diff --git a/rtdata/images/svg/refresh.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh.svg similarity index 100% rename from rtdata/images/svg/refresh.svg rename to rtdata/icons/rawtherapee/scalable/apps/refresh.svg diff --git a/rtdata/images/svg/remove-small.svg b/rtdata/icons/rawtherapee/scalable/apps/remove-small.svg similarity index 100% rename from rtdata/images/svg/remove-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/remove-small.svg diff --git a/rtdata/images/svg/remove.svg b/rtdata/icons/rawtherapee/scalable/apps/remove.svg similarity index 100% rename from rtdata/images/svg/remove.svg rename to rtdata/icons/rawtherapee/scalable/apps/remove.svg diff --git a/rtdata/images/svg/rotate-aroundnode-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg similarity index 100% rename from rtdata/images/svg/rotate-aroundnode-hicontrast.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg diff --git a/rtdata/images/svg/rotate-aroundnode.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg similarity index 100% rename from rtdata/images/svg/rotate-aroundnode.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg diff --git a/rtdata/images/svg/rotate-left-90.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-left-90.svg similarity index 100% rename from rtdata/images/svg/rotate-left-90.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-left-90.svg diff --git a/rtdata/images/svg/rotate-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg similarity index 100% rename from rtdata/images/svg/rotate-left-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg diff --git a/rtdata/images/svg/rotate-left.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg similarity index 100% rename from rtdata/images/svg/rotate-left.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg diff --git a/rtdata/images/svg/rotate-right-90.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg similarity index 100% rename from rtdata/images/svg/rotate-right-90.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg diff --git a/rtdata/images/svg/rotate-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg similarity index 100% rename from rtdata/images/svg/rotate-right-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg diff --git a/rtdata/images/svg/rotate-right.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg similarity index 100% rename from rtdata/images/svg/rotate-right.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg diff --git a/rtdata/images/svg/rotate-straighten-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg similarity index 100% rename from rtdata/images/svg/rotate-straighten-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg diff --git a/rtdata/images/svg/rotate-straighten.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg similarity index 100% rename from rtdata/images/svg/rotate-straighten.svg rename to rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg diff --git a/rtdata/images/svg/save-small.svg b/rtdata/icons/rawtherapee/scalable/apps/save-small.svg similarity index 100% rename from rtdata/images/svg/save-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/save-small.svg diff --git a/rtdata/images/svg/save.svg b/rtdata/icons/rawtherapee/scalable/apps/save.svg similarity index 100% rename from rtdata/images/svg/save.svg rename to rtdata/icons/rawtherapee/scalable/apps/save.svg diff --git a/rtdata/images/svg/saved-no-small.svg b/rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg similarity index 100% rename from rtdata/images/svg/saved-no-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg diff --git a/rtdata/images/svg/saved-yes-small.svg b/rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg similarity index 100% rename from rtdata/images/svg/saved-yes-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg diff --git a/rtdata/images/svg/spot-active.svg b/rtdata/icons/rawtherapee/scalable/apps/spot-active.svg similarity index 100% rename from rtdata/images/svg/spot-active.svg rename to rtdata/icons/rawtherapee/scalable/apps/spot-active.svg diff --git a/rtdata/images/svg/spot-normal.svg b/rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg similarity index 100% rename from rtdata/images/svg/spot-normal.svg rename to rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg diff --git a/rtdata/images/svg/spot-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg similarity index 100% rename from rtdata/images/svg/spot-prelight.svg rename to rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg diff --git a/rtdata/images/svg/square-toggle-black-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-black-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-black-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-black-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-blue-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-blue-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-blue-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-blue-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-gray-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-gray-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-gray-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-gray-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-green-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-green-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-green-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-green-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-luminosity-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-luminosity-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-luminosity-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-luminosity-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-red-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-red-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-red-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-red-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-theme-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-theme-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-theme-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-theme-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg diff --git a/rtdata/images/svg/square-toggle-white-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-white-off-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg diff --git a/rtdata/images/svg/square-toggle-white-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg similarity index 100% rename from rtdata/images/svg/square-toggle-white-on-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg diff --git a/rtdata/images/svg/star-gold-hollow-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg similarity index 100% rename from rtdata/images/svg/star-gold-hollow-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg diff --git a/rtdata/images/svg/star-gold-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg similarity index 100% rename from rtdata/images/svg/star-gold-hollow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg diff --git a/rtdata/images/svg/star-gold-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg similarity index 100% rename from rtdata/images/svg/star-gold-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg diff --git a/rtdata/images/svg/star-gold-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg similarity index 100% rename from rtdata/images/svg/star-gold-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg diff --git a/rtdata/images/svg/star-hollow-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg similarity index 100% rename from rtdata/images/svg/star-hollow-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg diff --git a/rtdata/images/svg/star-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg similarity index 100% rename from rtdata/images/svg/star-hollow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg diff --git a/rtdata/images/svg/star-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg similarity index 100% rename from rtdata/images/svg/star-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg diff --git a/rtdata/images/svg/star-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-small.svg similarity index 100% rename from rtdata/images/svg/star-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/star-small.svg diff --git a/rtdata/images/svg/star.svg b/rtdata/icons/rawtherapee/scalable/apps/star.svg similarity index 100% rename from rtdata/images/svg/star.svg rename to rtdata/icons/rawtherapee/scalable/apps/star.svg diff --git a/rtdata/images/svg/template-16.svg b/rtdata/icons/rawtherapee/scalable/apps/template-16.svg similarity index 100% rename from rtdata/images/svg/template-16.svg rename to rtdata/icons/rawtherapee/scalable/apps/template-16.svg diff --git a/rtdata/images/svg/template-24.svg b/rtdata/icons/rawtherapee/scalable/apps/template-24.svg similarity index 100% rename from rtdata/images/svg/template-24.svg rename to rtdata/icons/rawtherapee/scalable/apps/template-24.svg diff --git a/rtdata/images/svg/template-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg similarity index 100% rename from rtdata/images/svg/template-narrow.svg rename to rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg diff --git a/rtdata/images/svg/tick-green-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg similarity index 100% rename from rtdata/images/svg/tick-green-hollow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg diff --git a/rtdata/images/svg/tick-green-hollow.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg similarity index 100% rename from rtdata/images/svg/tick-green-hollow.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg diff --git a/rtdata/images/svg/tick-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg similarity index 100% rename from rtdata/images/svg/tick-green-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg diff --git a/rtdata/images/svg/tick-green.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green.svg similarity index 100% rename from rtdata/images/svg/tick-green.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-green.svg diff --git a/rtdata/images/svg/tick-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg similarity index 100% rename from rtdata/images/svg/tick-hollow-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg diff --git a/rtdata/images/svg/tick-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-small.svg similarity index 100% rename from rtdata/images/svg/tick-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick-small.svg diff --git a/rtdata/images/svg/tick.svg b/rtdata/icons/rawtherapee/scalable/apps/tick.svg similarity index 100% rename from rtdata/images/svg/tick.svg rename to rtdata/icons/rawtherapee/scalable/apps/tick.svg diff --git a/rtdata/images/svg/transform.svg b/rtdata/icons/rawtherapee/scalable/apps/transform.svg similarity index 100% rename from rtdata/images/svg/transform.svg rename to rtdata/icons/rawtherapee/scalable/apps/transform.svg diff --git a/rtdata/images/svg/trash-delete.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg similarity index 100% rename from rtdata/images/svg/trash-delete.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg diff --git a/rtdata/images/svg/trash-empty-show.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg similarity index 100% rename from rtdata/images/svg/trash-empty-show.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg diff --git a/rtdata/images/svg/trash-empty.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg similarity index 100% rename from rtdata/images/svg/trash-empty.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg diff --git a/rtdata/images/svg/trash-full-show.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg similarity index 100% rename from rtdata/images/svg/trash-full-show.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg diff --git a/rtdata/images/svg/trash-full.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-full.svg similarity index 100% rename from rtdata/images/svg/trash-full.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-full.svg diff --git a/rtdata/images/svg/trash-hide-deleted.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg similarity index 100% rename from rtdata/images/svg/trash-hide-deleted.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg diff --git a/rtdata/images/svg/trash-remove-small.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg similarity index 100% rename from rtdata/images/svg/trash-remove-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg diff --git a/rtdata/images/svg/trash-remove.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg similarity index 100% rename from rtdata/images/svg/trash-remove.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg diff --git a/rtdata/images/svg/trash-small.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-small.svg similarity index 100% rename from rtdata/images/svg/trash-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/trash-small.svg diff --git a/rtdata/images/svg/undo-all.svg b/rtdata/icons/rawtherapee/scalable/apps/undo-all.svg similarity index 100% rename from rtdata/images/svg/undo-all.svg rename to rtdata/icons/rawtherapee/scalable/apps/undo-all.svg diff --git a/rtdata/images/svg/undo-small.svg b/rtdata/icons/rawtherapee/scalable/apps/undo-small.svg similarity index 100% rename from rtdata/images/svg/undo-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/undo-small.svg diff --git a/rtdata/images/svg/undo.svg b/rtdata/icons/rawtherapee/scalable/apps/undo.svg similarity index 100% rename from rtdata/images/svg/undo.svg rename to rtdata/icons/rawtherapee/scalable/apps/undo.svg diff --git a/rtdata/images/svg/warning-highlights.svg b/rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg similarity index 100% rename from rtdata/images/svg/warning-highlights.svg rename to rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg diff --git a/rtdata/images/svg/warning-shadows.svg b/rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg similarity index 100% rename from rtdata/images/svg/warning-shadows.svg rename to rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg diff --git a/rtdata/images/svg/warning.svg b/rtdata/icons/rawtherapee/scalable/apps/warning.svg similarity index 100% rename from rtdata/images/svg/warning.svg rename to rtdata/icons/rawtherapee/scalable/apps/warning.svg diff --git a/rtdata/images/svg/wavelets.svg b/rtdata/icons/rawtherapee/scalable/apps/wavelets.svg similarity index 100% rename from rtdata/images/svg/wavelets.svg rename to rtdata/icons/rawtherapee/scalable/apps/wavelets.svg diff --git a/rtdata/images/svg/wb-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg similarity index 100% rename from rtdata/images/svg/wb-auto-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg diff --git a/rtdata/images/svg/wb-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg similarity index 100% rename from rtdata/images/svg/wb-auto.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg diff --git a/rtdata/images/svg/wb-camera-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg similarity index 100% rename from rtdata/images/svg/wb-camera-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg diff --git a/rtdata/images/svg/wb-camera.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg similarity index 100% rename from rtdata/images/svg/wb-camera.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg diff --git a/rtdata/images/svg/wb-cloudy-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg similarity index 100% rename from rtdata/images/svg/wb-cloudy-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg diff --git a/rtdata/images/svg/wb-cloudy.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg similarity index 100% rename from rtdata/images/svg/wb-cloudy.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg diff --git a/rtdata/images/svg/wb-custom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg similarity index 100% rename from rtdata/images/svg/wb-custom-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg diff --git a/rtdata/images/svg/wb-custom.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg similarity index 100% rename from rtdata/images/svg/wb-custom.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg diff --git a/rtdata/images/svg/wb-flash-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg similarity index 100% rename from rtdata/images/svg/wb-flash-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg diff --git a/rtdata/images/svg/wb-flash.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg similarity index 100% rename from rtdata/images/svg/wb-flash.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg diff --git a/rtdata/images/svg/wb-fluorescent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg similarity index 100% rename from rtdata/images/svg/wb-fluorescent-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg diff --git a/rtdata/images/svg/wb-fluorescent.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg similarity index 100% rename from rtdata/images/svg/wb-fluorescent.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg diff --git a/rtdata/images/svg/wb-lamp-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg similarity index 100% rename from rtdata/images/svg/wb-lamp-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg diff --git a/rtdata/images/svg/wb-lamp.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg similarity index 100% rename from rtdata/images/svg/wb-lamp.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg diff --git a/rtdata/images/svg/wb-led-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg similarity index 100% rename from rtdata/images/svg/wb-led-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg diff --git a/rtdata/images/svg/wb-led.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-led.svg similarity index 100% rename from rtdata/images/svg/wb-led.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-led.svg diff --git a/rtdata/images/svg/wb-shade-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg similarity index 100% rename from rtdata/images/svg/wb-shade-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg diff --git a/rtdata/images/svg/wb-shade.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg similarity index 100% rename from rtdata/images/svg/wb-shade.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg diff --git a/rtdata/images/svg/wb-sun-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg similarity index 100% rename from rtdata/images/svg/wb-sun-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg diff --git a/rtdata/images/svg/wb-sun.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg similarity index 100% rename from rtdata/images/svg/wb-sun.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg diff --git a/rtdata/images/svg/wb-tungsten-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten-small.svg similarity index 100% rename from rtdata/images/svg/wb-tungsten-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-tungsten-small.svg diff --git a/rtdata/images/svg/wb-tungsten.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg similarity index 100% rename from rtdata/images/svg/wb-tungsten.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg diff --git a/rtdata/images/svg/wb-water-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg similarity index 100% rename from rtdata/images/svg/wb-water-small.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg diff --git a/rtdata/images/svg/wb-water.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-water.svg similarity index 100% rename from rtdata/images/svg/wb-water.svg rename to rtdata/icons/rawtherapee/scalable/apps/wb-water.svg diff --git a/rtdata/images/svg/window-add.svg b/rtdata/icons/rawtherapee/scalable/apps/window-add.svg similarity index 100% rename from rtdata/images/svg/window-add.svg rename to rtdata/icons/rawtherapee/scalable/apps/window-add.svg From d8c0b521ab98a76064cd032e75aecadf5d899093 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Mon, 28 Aug 2023 17:10:23 +0200 Subject: [PATCH 032/291] Modify icons color - Update icon from color "2a7fff" to "cccccc" - Update .svg files with last Inkscape version --- .../rawtherapee/scalable/apps/add-small.svg | 71 +--- .../icons/rawtherapee/scalable/apps/add.svg | 74 +---- .../rawtherapee/scalable/apps/aperture.svg | 247 ++++---------- .../scalable/apps/arrow-down-small.svg | 111 ++----- .../scalable/apps/arrow-left-small.svg | 114 ++----- .../scalable/apps/arrow-right-small.svg | 114 ++----- .../scalable/apps/arrow-up-small.svg | 114 ++----- .../scalable/apps/arrow-updown.svg | 69 +--- .../rawtherapee/scalable/apps/arrow2-left.svg | 69 +--- .../scalable/apps/arrow2-right.svg | 69 +--- .../icons/rawtherapee/scalable/apps/atom.svg | 73 +---- .../icons/rawtherapee/scalable/apps/bayer.svg | 83 ++--- .../rawtherapee/scalable/apps/beforeafter.svg | 64 +--- ...irectional-arrow-horizontal-hicontrast.svg | 79 +---- ...idirectional-arrow-horizontal-prelight.svg | 79 +---- ...idirectional-arrow-vertical-hicontrast.svg | 79 +---- .../bidirectional-arrow-vertical-prelight.svg | 75 +---- .../icons/rawtherapee/scalable/apps/box.svg | 57 +--- .../scalable/apps/cancel-small.svg | 73 +---- .../rawtherapee/scalable/apps/cancel.svg | 76 +---- .../scalable/apps/circle-black-small.svg | 55 +--- .../scalable/apps/circle-blue-green-small.svg | 53 +-- .../scalable/apps/circle-blue-red-small.svg | 53 +-- .../scalable/apps/circle-blue-small.svg | 53 +-- .../apps/circle-blue-yellow-small.svg | 55 +--- .../scalable/apps/circle-cyan-red-small.svg | 55 +--- .../scalable/apps/circle-cyan-small.svg | 55 +--- .../scalable/apps/circle-darkgray-small.svg | 57 +--- .../scalable/apps/circle-empty-blue-small.svg | 53 +-- .../apps/circle-empty-darkgray-small.svg | 55 +--- .../scalable/apps/circle-empty-gray-small.svg | 53 +-- .../apps/circle-empty-green-small.svg | 53 +-- .../apps/circle-empty-purple-small.svg | 55 +--- .../scalable/apps/circle-empty-red-small.svg | 53 +-- .../apps/circle-empty-yellow-small.svg | 53 +-- .../scalable/apps/circle-gray-blue-small.svg | 55 +--- .../scalable/apps/circle-gray-green-small.svg | 55 +--- .../scalable/apps/circle-gray-red-small.svg | 55 +--- .../scalable/apps/circle-gray-small.svg | 55 +--- .../scalable/apps/circle-green-blue-small.svg | 53 +-- .../scalable/apps/circle-green-red-small.svg | 53 +-- .../scalable/apps/circle-green-small.svg | 53 +-- .../scalable/apps/circle-magenta-small.svg | 55 +--- .../scalable/apps/circle-orange-small.svg | 55 +--- .../scalable/apps/circle-purple-small.svg | 55 +--- .../scalable/apps/circle-red-blue-small.svg | 55 +--- .../scalable/apps/circle-red-cyan-small.svg | 55 +--- .../scalable/apps/circle-red-green-small.svg | 55 +--- .../scalable/apps/circle-red-small.svg | 53 +-- .../scalable/apps/circle-white-small.svg | 54 +-- .../apps/circle-yellow-blue-small.svg | 53 +-- .../scalable/apps/circle-yellow-small.svg | 53 +-- .../scalable/apps/color-circles.svg | 114 ++----- .../apps/color-picker-add-hicontrast.svg | 86 +---- .../scalable/apps/color-picker-add.svg | 77 +---- .../scalable/apps/color-picker-bars.svg | 81 +---- .../scalable/apps/color-picker-hicontrast.svg | 75 +---- .../scalable/apps/color-picker-hide.svg | 77 +---- .../scalable/apps/color-picker-small.svg | 73 +---- .../scalable/apps/color-picker.svg | 75 +---- .../scalable/apps/contrastmask-off.svg | 98 +----- .../scalable/apps/contrastmask-on.svg | 98 +----- .../icons/rawtherapee/scalable/apps/copy.svg | 132 ++------ .../scalable/apps/crop-auto-small.svg | 77 +---- .../rawtherapee/scalable/apps/crop-auto.svg | 77 +---- .../scalable/apps/crop-point-hicontrast.svg | 100 ++---- .../rawtherapee/scalable/apps/crop-small.svg | 67 +--- .../icons/rawtherapee/scalable/apps/crop.svg | 65 +--- .../scalable/apps/crossed-arrows-in.svg | 65 +--- .../scalable/apps/crossed-arrows-out.svg | 77 +---- .../scalable/apps/crosshair-adjust.svg | 70 +--- .../scalable/apps/crosshair-hicontrast.svg | 97 ++---- .../scalable/apps/crosshair-node-curve.svg | 79 +---- .../scalable/apps/crosshair-small.svg | 109 ++---- .../scalable/apps/curve-catmullrom-small.svg | 90 +---- .../scalable/apps/curve-catmullrom.svg | 75 +---- .../apps/curve-controlpoints-small.svg | 68 +--- .../scalable/apps/curve-controlpoints.svg | 106 ++---- .../scalable/apps/curve-flat-small.svg | 66 +--- .../rawtherapee/scalable/apps/curve-flat.svg | 60 +--- .../scalable/apps/curve-linear-small.svg | 66 +--- .../scalable/apps/curve-linear.svg | 60 +--- .../scalable/apps/curve-nurbs-small.svg | 69 +--- .../rawtherapee/scalable/apps/curve-nurbs.svg | 67 +--- .../scalable/apps/curve-parametric-small.svg | 71 +--- .../scalable/apps/curve-parametric.svg | 67 +--- .../scalable/apps/curve-spline-small.svg | 69 +--- .../scalable/apps/curve-spline.svg | 70 +--- .../rawtherapee/scalable/apps/detail.svg | 115 ++----- .../scalable/apps/device-floppy.svg | 69 +--- .../rawtherapee/scalable/apps/device-hdd.svg | 64 +--- .../scalable/apps/device-network.svg | 61 +--- .../scalable/apps/device-optical.svg | 64 +--- .../rawtherapee/scalable/apps/device-usb.svg | 59 +--- .../scalable/apps/distortion-auto-small.svg | 84 +---- .../scalable/apps/distortion-auto.svg | 64 +--- .../scalable/apps/distortion-barrel-small.svg | 78 +---- .../scalable/apps/distortion-barrel.svg | 60 +--- .../apps/distortion-pincushion-small.svg | 74 +---- .../scalable/apps/distortion-pincushion.svg | 60 +--- .../icons/rawtherapee/scalable/apps/draw.svg | 62 +--- .../rawtherapee/scalable/apps/edit-point.svg | 90 ++--- .../rawtherapee/scalable/apps/edit-small.svg | 73 +---- .../icons/rawtherapee/scalable/apps/edit.svg | 84 +---- .../scalable/apps/equilizer-narrow.svg | 310 ++++++------------ .../scalable/apps/equilizer-wide.svg | 217 ++++-------- .../scalable/apps/expander-closed-small.svg | 73 +---- .../scalable/apps/expander-open-small.svg | 78 +---- .../rawtherapee/scalable/apps/exposure.svg | 67 +--- .../scalable/apps/filetype-hdr.svg | 85 ++--- .../rawtherapee/scalable/apps/filetype-ps.svg | 78 +---- .../scalable/apps/filter-clear.svg | 74 +---- .../scalable/apps/filter-original.svg | 71 +--- .../scalable/apps/filter-original2.svg | 73 +---- .../rawtherapee/scalable/apps/filter.svg | 73 +---- .../scalable/apps/flip-horizontal.svg | 91 +---- .../scalable/apps/flip-vertical.svg | 92 +----- .../scalable/apps/focusscreen-off.svg | 69 +--- .../scalable/apps/focusscreen-on.svg | 65 +--- .../apps/folder-closed-home-small.svg | 71 +--- .../scalable/apps/folder-closed-home.svg | 88 +---- .../apps/folder-closed-recent-small.svg | 68 +--- .../scalable/apps/folder-closed-recent.svg | 82 +---- .../scalable/apps/folder-closed-small.svg | 67 +--- .../scalable/apps/folder-closed.svg | 63 +--- .../apps/folder-open-recent-small.svg | 76 +---- .../scalable/apps/folder-open-recent.svg | 93 +----- .../scalable/apps/folder-open-small.svg | 73 +---- .../rawtherapee/scalable/apps/folder-open.svg | 71 +--- .../scalable/apps/fullscreen-enter.svg | 78 +---- .../scalable/apps/fullscreen-leave.svg | 78 +---- .../rawtherapee/scalable/apps/gamut-hist.svg | 68 +--- .../rawtherapee/scalable/apps/gamut-plus.svg | 64 +--- .../scalable/apps/gamut-softproof.svg | 69 +--- .../scalable/apps/gamut-warning.svg | 65 +--- .../scalable/apps/gamut_srgb_prophoto_xy.svg | 66 +--- .../rawtherapee/scalable/apps/gears-pause.svg | 92 ++---- .../rawtherapee/scalable/apps/gears-play.svg | 101 ++---- .../rawtherapee/scalable/apps/gears-small.svg | 71 +--- .../icons/rawtherapee/scalable/apps/gears.svg | 75 +---- .../scalable/apps/goto-end-small.svg | 69 +--- .../scalable/apps/goto-start-small.svg | 69 +--- .../scalable/apps/hand-closed-hicontrast.svg | 93 +----- .../scalable/apps/hand-open-hicontrast.svg | 76 +---- .../rawtherapee/scalable/apps/hand-open.svg | 74 +---- .../scalable/apps/histogram-bar-off-small.svg | 63 +--- .../scalable/apps/histogram-bar-on-small.svg | 63 +--- .../apps/histogram-blue-off-small.svg | 57 +--- .../scalable/apps/histogram-blue-on-small.svg | 57 +--- .../apps/histogram-ellipsis-small.svg | 66 +--- .../apps/histogram-gold-off-small.svg | 57 +--- .../scalable/apps/histogram-gold-on-small.svg | 57 +--- .../apps/histogram-green-off-small.svg | 57 +--- .../apps/histogram-green-on-small.svg | 57 +--- .../apps/histogram-mode-linear-small.svg | 59 +--- .../apps/histogram-mode-logx-small.svg | 59 +--- .../apps/histogram-mode-logxy-small.svg | 59 +--- .../scalable/apps/histogram-red-off-small.svg | 57 +--- .../scalable/apps/histogram-red-on-small.svg | 57 +--- .../apps/histogram-silver-off-small.svg | 57 +--- .../apps/histogram-silver-on-small.svg | 57 +--- .../histogram-type-histogram-raw-small.svg | 65 +--- .../apps/histogram-type-histogram-small.svg | 63 +--- .../apps/histogram-type-parade-small.svg | 66 +--- .../histogram-type-vectorscope-hc-small.svg | 68 +--- .../histogram-type-vectorscope-hs-small.svg | 70 +--- .../apps/histogram-type-waveform-small.svg | 65 +--- .../icons/rawtherapee/scalable/apps/info.svg | 62 +--- .../scalable/apps/intent-absolute.svg | 205 +++--------- .../scalable/apps/intent-perceptual.svg | 213 ++++-------- .../scalable/apps/intent-relative.svg | 205 +++--------- .../scalable/apps/intent-saturation.svg | 215 ++++-------- .../scalable/apps/magnifier-1to1-small.svg | 84 +---- .../scalable/apps/magnifier-1to1.svg | 75 +---- .../scalable/apps/magnifier-crop.svg | 76 +---- .../scalable/apps/magnifier-fit.svg | 83 +---- .../scalable/apps/magnifier-minus-small.svg | 72 +--- .../scalable/apps/magnifier-minus.svg | 71 +--- .../scalable/apps/magnifier-plus-small.svg | 72 +--- .../scalable/apps/magnifier-plus.svg | 71 +--- .../rawtherapee/scalable/apps/magnifier.svg | 61 +--- .../rawtherapee/scalable/apps/metadata.svg | 86 ++--- .../apps/node-move-nw-se-hicontrast.svg | 75 +---- .../apps/node-move-sw-ne-hicontrast.svg | 75 +---- .../scalable/apps/node-move-x-hicontrast.svg | 75 +---- .../scalable/apps/node-move-xy-hicontrast.svg | 103 ++---- .../scalable/apps/node-move-y-hicontrast.svg | 75 +---- .../scalable/apps/one-to-one-small.svg | 180 +++------- .../scalable/apps/padlock-locked-small.svg | 67 +--- .../scalable/apps/padlock-unlocked-small.svg | 69 +--- .../scalable/apps/palette-brush.svg | 86 +---- .../scalable/apps/panel-to-bottom.svg | 65 +--- .../scalable/apps/panel-to-left.svg | 65 +--- .../scalable/apps/panel-to-right.svg | 65 +--- .../scalable/apps/panel-to-top.svg | 65 +--- .../icons/rawtherapee/scalable/apps/paste.svg | 77 +---- .../perspective-horizontal-left-small.svg | 74 +---- .../apps/perspective-horizontal-left.svg | 63 +--- .../perspective-horizontal-right-small.svg | 74 +---- .../apps/perspective-horizontal-right.svg | 64 +--- .../apps/perspective-horizontal-vertical.svg | 68 +--- .../perspective-vertical-bottom-small.svg | 76 +---- .../apps/perspective-vertical-bottom.svg | 64 +--- .../apps/perspective-vertical-top-small.svg | 76 +---- .../apps/perspective-vertical-top.svg | 64 +--- .../apps/power-inconsistent-small.svg | 65 +--- .../scalable/apps/power-off-small.svg | 66 +--- .../scalable/apps/power-on-small.svg | 85 +---- .../rawtherapee/scalable/apps/preferences.svg | 65 +--- .../scalable/apps/profile-filled.svg | 71 +--- .../scalable/apps/profile-partial.svg | 73 +---- .../scalable/apps/questionmark.svg | 66 +--- .../rawtherapee/scalable/apps/redo-all.svg | 76 +---- .../rawtherapee/scalable/apps/redo-small.svg | 59 +--- .../icons/rawtherapee/scalable/apps/redo.svg | 72 +--- .../scalable/apps/refresh-red-small.svg | 80 +---- .../scalable/apps/refresh-small.svg | 74 +---- .../rawtherapee/scalable/apps/refresh.svg | 86 +---- .../scalable/apps/remove-small.svg | 73 +---- .../rawtherapee/scalable/apps/remove.svg | 76 +---- .../apps/rotate-aroundnode-hicontrast.svg | 66 +--- .../scalable/apps/rotate-aroundnode.svg | 76 +---- .../scalable/apps/rotate-left-90.svg | 95 ++---- .../scalable/apps/rotate-left-small.svg | 99 +----- .../rawtherapee/scalable/apps/rotate-left.svg | 91 +---- .../scalable/apps/rotate-right-90.svg | 98 ++---- .../scalable/apps/rotate-right-small.svg | 97 +----- .../scalable/apps/rotate-right.svg | 89 +---- .../scalable/apps/rotate-straighten-small.svg | 81 +---- .../scalable/apps/rotate-straighten.svg | 137 ++------ .../rawtherapee/scalable/apps/save-small.svg | 84 +---- .../icons/rawtherapee/scalable/apps/save.svg | 231 ++++--------- .../scalable/apps/saved-no-small.svg | 94 ++---- .../scalable/apps/saved-yes-small.svg | 83 +---- .../rawtherapee/scalable/apps/spot-active.svg | 43 +-- .../rawtherapee/scalable/apps/spot-normal.svg | 47 +-- .../scalable/apps/spot-prelight.svg | 38 +-- .../apps/square-toggle-black-off-narrow.svg | 61 +--- .../apps/square-toggle-black-on-narrow.svg | 61 +--- .../apps/square-toggle-blue-off-narrow.svg | 61 +--- .../apps/square-toggle-blue-on-narrow.svg | 61 +--- .../apps/square-toggle-gray-off-narrow.svg | 61 +--- .../apps/square-toggle-gray-on-narrow.svg | 61 +--- .../apps/square-toggle-green-off-narrow.svg | 59 +--- .../apps/square-toggle-green-on-narrow.svg | 59 +--- .../square-toggle-luminosity-off-narrow.svg | 68 +--- .../square-toggle-luminosity-on-narrow.svg | 68 +--- .../apps/square-toggle-red-off-narrow.svg | 61 +--- .../apps/square-toggle-red-on-narrow.svg | 61 +--- .../apps/square-toggle-theme-off-narrow.svg | 68 +--- .../apps/square-toggle-theme-on-narrow.svg | 68 +--- .../apps/square-toggle-white-off-narrow.svg | 61 +--- .../apps/square-toggle-white-on-narrow.svg | 61 +--- .../scalable/apps/star-gold-hollow-narrow.svg | 78 +---- .../scalable/apps/star-gold-hollow-small.svg | 76 +---- .../scalable/apps/star-gold-narrow.svg | 78 +---- .../scalable/apps/star-gold-small.svg | 76 +---- .../scalable/apps/star-hollow-narrow.svg | 78 +---- .../scalable/apps/star-hollow-small.svg | 76 +---- .../rawtherapee/scalable/apps/star-narrow.svg | 78 +---- .../rawtherapee/scalable/apps/star-small.svg | 76 +---- .../icons/rawtherapee/scalable/apps/star.svg | 73 +---- .../rawtherapee/scalable/apps/template-16.svg | 53 +-- .../rawtherapee/scalable/apps/template-24.svg | 55 +--- .../scalable/apps/template-narrow.svg | 62 +--- .../scalable/apps/tick-green-hollow-small.svg | 59 +--- .../scalable/apps/tick-green-hollow.svg | 59 +--- .../scalable/apps/tick-green-small.svg | 57 +--- .../rawtherapee/scalable/apps/tick-green.svg | 59 +--- .../scalable/apps/tick-hollow-small.svg | 59 +--- .../rawtherapee/scalable/apps/tick-small.svg | 59 +--- .../icons/rawtherapee/scalable/apps/tick.svg | 59 +--- .../rawtherapee/scalable/apps/transform.svg | 75 +---- .../scalable/apps/trash-delete.svg | 213 +++--------- .../scalable/apps/trash-empty-show.svg | 140 ++------ .../rawtherapee/scalable/apps/trash-empty.svg | 133 ++------ .../scalable/apps/trash-full-show.svg | 144 +++----- .../rawtherapee/scalable/apps/trash-full.svg | 147 ++------- .../scalable/apps/trash-hide-deleted.svg | 146 ++------- .../scalable/apps/trash-remove-small.svg | 62 +--- .../scalable/apps/trash-remove.svg | 147 +++------ .../rawtherapee/scalable/apps/trash-small.svg | 64 +--- .../rawtherapee/scalable/apps/undo-all.svg | 76 +---- .../rawtherapee/scalable/apps/undo-small.svg | 60 +--- .../icons/rawtherapee/scalable/apps/undo.svg | 70 +--- .../scalable/apps/warning-highlights.svg | 81 +---- .../scalable/apps/warning-shadows.svg | 81 +---- .../rawtherapee/scalable/apps/warning.svg | 81 +---- .../rawtherapee/scalable/apps/wavelets.svg | 87 +---- .../scalable/apps/wb-auto-small.svg | 57 +--- .../rawtherapee/scalable/apps/wb-auto.svg | 61 +--- .../scalable/apps/wb-camera-small.svg | 58 +--- .../rawtherapee/scalable/apps/wb-camera.svg | 60 +--- .../scalable/apps/wb-cloudy-small.svg | 61 +--- .../rawtherapee/scalable/apps/wb-cloudy.svg | 63 +--- .../scalable/apps/wb-custom-small.svg | 65 +--- .../rawtherapee/scalable/apps/wb-custom.svg | 67 +--- .../scalable/apps/wb-flash-small.svg | 61 +--- .../rawtherapee/scalable/apps/wb-flash.svg | 63 +--- .../scalable/apps/wb-fluorescent-small.svg | 107 ++---- .../scalable/apps/wb-fluorescent.svg | 113 ++----- .../scalable/apps/wb-lamp-small.svg | 107 ++---- .../rawtherapee/scalable/apps/wb-lamp.svg | 113 ++----- .../scalable/apps/wb-led-small.svg | 71 +--- .../rawtherapee/scalable/apps/wb-led.svg | 73 +---- .../scalable/apps/wb-shade-small.svg | 71 +--- .../rawtherapee/scalable/apps/wb-shade.svg | 89 ++--- .../scalable/apps/wb-sun-small.svg | 105 ++---- .../rawtherapee/scalable/apps/wb-sun.svg | 107 ++---- .../scalable/apps/wb-tungsten-small.svg | 94 ++---- .../rawtherapee/scalable/apps/wb-tungsten.svg | 100 ++---- .../scalable/apps/wb-water-small.svg | 59 +--- .../rawtherapee/scalable/apps/wb-water.svg | 63 +--- .../rawtherapee/scalable/apps/window-add.svg | 68 +--- rtdata/images/ornament1.svg | 76 +---- 315 files changed, 4202 insertions(+), 20328 deletions(-) diff --git a/rtdata/icons/rawtherapee/scalable/apps/add-small.svg b/rtdata/icons/rawtherapee/scalable/apps/add-small.svg index 13abbdc25..9d5cb01c6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/add-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/add-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 2.5213637,16.478636 H 12.521364 m -5.0000003,-5 v 10" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/add.svg b/rtdata/icons/rawtherapee/scalable/apps/add.svg index 41fa7cc39..b8c21fdae 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/add.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/add.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:0.53333285;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:3.33607316;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 12.447464,4.4346736 0,15.1306544 M 5,12 19.89493,12" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/aperture.svg b/rtdata/icons/rawtherapee/scalable/apps/aperture.svg index 5820ee283..c08244c62 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/aperture.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/aperture.svg @@ -2,68 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -107,289 +55,224 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0.95796239;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + id="path870" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + id="path1175" /> + id="path1171" /> + id="path1167" /> + id="path1163" /> + id="path1159" /> + id="path994" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#ff8181;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#dfb220;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#20df20;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#20dfdf;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#2020df;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#ef8fef;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg index d17ba4329..2911187fc 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow-down-small.svg @@ -2,181 +2,122 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -188,7 +129,7 @@ image/svg+xml - + Maciej Dworak @@ -222,11 +163,9 @@ diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg index 54eafbc29..cb5194185 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow-left-small.svg @@ -2,181 +2,122 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -188,7 +129,7 @@ image/svg+xml - + Maciej Dworak @@ -222,13 +163,10 @@ + id="rect1539" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg index 43bfdd4e8..1b6d484e8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow-right-small.svg @@ -2,181 +2,122 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -188,7 +129,7 @@ image/svg+xml - + Maciej Dworak @@ -222,13 +163,10 @@ + id="rect1539" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg index b5609c5d7..7f3314246 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow-up-small.svg @@ -2,181 +2,122 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -188,7 +129,7 @@ image/svg+xml - + Maciej Dworak @@ -222,13 +163,10 @@ + id="rect1539" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg index d5b6c22a5..ed82879a5 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow-updown.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,20 +55,14 @@ + id="layer1"> + id="path2876" /> + id="path4746" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg index f71ee83e3..817901f8e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow2-left.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -102,14 +55,10 @@ + id="layer1"> + id="path3895" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg b/rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg index 8c3f60554..4a8922d3a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/arrow2-right.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -102,14 +55,10 @@ + id="layer1"> + id="path3895" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/atom.svg b/rtdata/icons/rawtherapee/scalable/apps/atom.svg index 72fb97532..22533a9b4 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/atom.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/atom.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -71,7 +30,7 @@ - + RawTherapee icon. @@ -96,26 +55,20 @@ + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" + d="M 6.4236453,1.0007171 C 5.1242162,1.0661783 4.2818956,1.3551405 3.4072861,2.1680463 2.0313377,3.6604057 2.0510559,6.0656441 2.8621368,8.5546635 3.6732254,11.043598 5.310644,13.766734 7.6001256,16.249906 c 2.2894736,2.483171 4.8041564,4.263447 7.0989664,5.143206 2.294838,0.879717 4.512477,0.901128 5.888414,-0.591274 1.459941,-1.892872 1.173357,-4.178274 0.629276,-6.11277 l -1.304751,1.308627 c 0.13995,1.28267 0.485305,2.529387 -0.444943,3.586763 -0.742315,0.805094 -2.239588,0.951586 -4.238937,0.184773 C 13.228945,19.002904 10.867343,17.361104 8.7224918,15.034753 6.5776052,12.708445 5.0659363,10.14926 4.3592931,7.9807808 3.8278563,5.7699345 3.7373603,4.2400511 5.122903,3.0223486 5.9515725,2.6063205 7.1829376,2.5856846 8.7705933,3.1940787 9.8156548,3.5945426 10.958198,4.2581661 12.117649,5.1091942 14.341642,6.72193 15.771084,8.4243253 17.384754,10.761068 L 18.45501,9.4589633 C 17.216394,7.4326758 15.418359,5.7024185 13.799195,4.3896672 12.282374,3.1596706 10.75444,2.1300889 9.2997088,1.5724257 8.2993769,1.1887878 7.3233517,0.98582573 6.4236453,1.0007171 Z" /> + id="ellipse4751" /> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:3.77952719;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/bayer.svg b/rtdata/icons/rawtherapee/scalable/apps/bayer.svg index 1718ce5c4..10bd21541 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/bayer.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/bayer.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.22222233;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.22222233;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.22222233;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#d03030;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#30d043;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path857" /> + id="path853" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg index 6382cc546..1692d094f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-horizontal-prelight.svg @@ -1,68 +1,15 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path857" /> + id="path853" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg index 93cb21a43..9ea09d595 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-hicontrast.svg @@ -1,68 +1,15 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path857" /> + id="path853" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg index 76f4312cb..b2658187a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/bidirectional-arrow-vertical-prelight.svg @@ -1,68 +1,15 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="fill:#ff6400;fill-opacity:1.0;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0" /> + style="fill:#ff6400;fill-opacity:1.0;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1.0" /> + style="fill:#ff6400;fill-opacity:1.0;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:round;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/box.svg b/rtdata/icons/rawtherapee/scalable/apps/box.svg index 2ebee4b8c..bf31f9860 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/box.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/box.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,32 +56,22 @@ + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 3.9858298,12.943102 7.0710682,7.071068 m 0,-7.071068 -7.0710682,7.071068" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/cancel.svg b/rtdata/icons/rawtherapee/scalable/apps/cancel.svg index c42837e61..899e2a5ec 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/cancel.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/cancel.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,26 +55,20 @@ + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:0.53333285;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 18.363961,5.636039 5.636039,18.363961 m 0,-12.727922 12.727922,12.727922" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg index 2b314c556..3cfc3579b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/circle-black-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,120 +55,99 @@ + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.55;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.35;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.1;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.45;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.65;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.8;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.86396921;marker:none;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg index 09870ff48..93b68b655 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add-hicontrast.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="rect2927" /> + id="path17041-7" /> + id="path822" /> + id="path3821" /> + id="path3823" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg index b42b8371d..f35c8346a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-add.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.32020855" /> + id="path6419-3-9-4-4" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.32020855" /> + id="path822" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg index f6c57ea40..0be923d08 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-bars.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.32020855" /> + id="path6419-3-9-4-4" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.32020855" /> + id="path822" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg index 20ece03b7..8e70dc54f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hicontrast.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path17041-7" /> + id="path3821" /> + id="path3823" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg index be180885e..bf6d31680 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-hide.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path9921-9-3-9-8" /> + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:1.00151598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1.0" /> + id="path17041" /> + id="path822" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg index d83400653..f085e9c2d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker-small.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -99,21 +56,15 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:1.00151598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1.0" /> + id="path822" /> @@ -121,13 +72,11 @@ id="path17041" transform="translate(0,8)" d="M 8.5996094,4.6132812 C 7.9891853,5.2309506 7.3674012,5.8422033 6.7597656,6.4707031 6.0490574,7.1848845 5.3334202,7.8974278 4.6464844,8.6445312 a 0.2448101,0.24497104 0 0 0 -0.035156,0.048828 C 4.4758783,8.9404628 4.4084807,9.1951286 4.328125,9.4121094 4.2477692,9.6290908 4.1597161,9.8016252 4.0136719,9.9238281 a 0.2448101,0.24497104 0 0 0 -0.037109,0.041016 c -0.414866,0.5579799 -0.1942661,1.3358159 0.3261715,1.7128899 0.4295663,0.352432 1.0465094,0.292563 1.4453125,-0.04492 l -0.017578,0.01367 c 0.2791087,-0.197793 0.554147,-0.364305 0.8417968,-0.414062 A 0.2448101,0.24497104 0 0 0 6.625,11.216797 C 7.4370634,10.886847 7.886835,10.1655 8.4121094,9.7011719 a 0.2448101,0.24497104 0 0 0 0.00977,-0.011719 C 9.3185591,8.7927604 10.214748,7.8962737 11.111328,7 11.098918,7.0008725 11.088758,7.00741 11.076168,7.00781 10.6583,6.9873298 10.291674,6.8102187 9.9609375,6.5683594 8.7783993,7.7536562 7.6035634,8.9481747 6.4023438,10.103516 c -0.1447329,0.07969 -0.3434276,0.127975 -0.5703126,0.193359 -0.2332819,0.06723 -0.5032928,0.164694 -0.7011718,0.408203 a 0.2448101,0.24497104 0 0 0 -0.013672,0.01953 c -0.018269,0.02776 -0.066987,0.06555 -0.1015625,0.07617 -0.034575,0.01062 -0.034649,0.0086 -0.044922,0 a 0.2448101,0.24497104 0 0 0 -0.035156,-0.02539 c -0.022238,-0.01269 -0.062217,-0.06429 -0.070312,-0.103516 -0.0081,-0.03923 -0.0087,-0.03651 0.00781,-0.04883 a 0.2448101,0.24497104 0 0 0 0.027344,-0.02149 c 0.2194594,-0.216848 0.450492,-0.497389 0.5,-0.8769526 L 5.3984375,9.75 C 5.4691719,9.4499134 5.5532474,9.1916878 5.7363281,9.0585938 A 0.2448101,0.24497104 0 0 0 5.765625,9.0332031 C 6.8638741,7.924874 7.9727833,6.823097 9.0761719,5.7167969 8.8267121,5.4055299 8.599334,5.0104373 8.5996094,4.6132812 Z" - style="opacity:0.7;fill:#2a7fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.3266921" - inkscape:connector-curvature="0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.3266921" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.3266921" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/color-picker.svg b/rtdata/icons/rawtherapee/scalable/apps/color-picker.svg index d52d96633..22f4cda36 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/color-picker.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/color-picker.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.32020855" /> + id="path6419-3-9-4-4" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.32020855" /> + id="path822" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg index ed76efbbb..ae3d093ce 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-off.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,58 +55,31 @@ + id="layer1"> + d="m -28,3 10.392305,18 -20.78461,0 z" /> + id="path1669" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg index 9e3504128..24432898e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/contrastmask-on.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,58 +55,31 @@ + id="layer1"> + d="m -28,3 10.392305,18 -20.78461,0 z" /> + id="path1669" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/copy.svg b/rtdata/icons/rawtherapee/scalable/apps/copy.svg index 9471e1ea7..3903eae8c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/copy.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/copy.svg @@ -2,209 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -249,29 +186,26 @@ + id="layer1"> + id="path8807" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg index 6d8ac3ea7..5624463e2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crop-auto-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,35 +56,27 @@ + id="rect1324" /> + id="path879" /> + id="path877" /> + style="display:inline;opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:0.04999533" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg index bc662e9ea..c74bc4a64 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crop-auto.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.97660822;paint-order:normal" /> + id="path849" /> + id="path847" /> + style="display:inline;opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:0.04999533" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg index 4a06bfcba..7ddece7e0 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crop-point-hicontrast.svg @@ -2,60 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + id="path865" /> + id="path867" /> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crop-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crop-small.svg index 94c0b43df..0266ae19e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crop-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crop-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,20 +56,14 @@ + id="rect1322" /> + id="rect1324" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crop.svg b/rtdata/icons/rawtherapee/scalable/apps/crop.svg index 8fd598f60..72653e0c0 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crop.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crop.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,18 +55,14 @@ + id="layer1"> + id="rect1324" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg index 8a4c71dc8..17c4ea79a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-in.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg index 5eb5ba4b1..6aa419d86 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crossed-arrows-out.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2876" /> + id="path2866" /> + id="path2864" /> + id="path2893" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg index 4cde3415a..26e394a0f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crosshair-adjust.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,23 +55,18 @@ + id="layer1"> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + id="path1448-3" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg index a4dcc2592..e27a576a8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crosshair-hicontrast.svg @@ -2,77 +2,25 @@ - - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path3792" /> image/svg+xml - + Maciej Dworak @@ -116,24 +64,19 @@ + id="layer1"> + id="rect1419" /> + id="rect1440" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" + id="path1448" /> + style="opacity:1;fill:#ff0000;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + id="path1481" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg index d72c2a929..9630c0bd6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crosshair-node-curve.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,39 +55,33 @@ + id="layer1"> + id="rect825" /> + id="rect829" /> + id="path853" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none"> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg b/rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg index 2e5e6596a..d86658cac 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/crosshair-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 22.521364,16.478636 h 10 m -5,-5 v 10" /> + id="path4981" /> + id="path1509" /> + id="path1505" /> + id="path1503" /> + id="path840" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg index bc6378bb4..137ad3e13 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom-small.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -106,54 +56,46 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.9;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.80000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.9;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + id="circle4399" /> + id="circle4405" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg index b59954885..2b9f2f9e8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-catmullrom.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -101,16 +55,13 @@ + id="layer1"> + id="circle817" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg index fc85b8774..104d5ffc9 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> @@ -116,17 +67,16 @@ cy="19" cx="-15" id="circle828" - style="opacity:0.7;fill:#2a7fff;fill-opacity:1;fill-rule:nonzero;stroke:#2a7fff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg index 2d432264c..c3121e735 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-controlpoints.svg @@ -2,65 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,16 +55,13 @@ + id="path15207" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + id="path15253" /> + id="path15255" /> + style="opacity:0.5;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.5;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.5;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg index 59585c64a..377a73269 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-flat-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,13 +56,10 @@ + id="path1480" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg index 89888b4d1..47d5af103 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-flat.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path814" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg index c2a3f7915..286c9207b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-linear-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,13 +56,10 @@ + id="path1501" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg index b016121aa..34a7207b8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-linear.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path7133" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg index 1ff3a1a76..6519af88b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,23 +56,19 @@ + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg index 1d7ef10ce..e4b73b9ed 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-nurbs.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path4882" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg index 2334def2d..0b2f22b9b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-parametric-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,31 +56,27 @@ + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path4163" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg b/rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg index 990df0c0d..63633af65 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/curve-spline-small.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path818" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path815" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/detail.svg b/rtdata/icons/rawtherapee/scalable/apps/detail.svg index 89aab821b..9b1fe5acd 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/detail.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/detail.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-rule:evenodd;stroke:none;fill-opacity:1.0" /> + style="opacity:0.1;fill:#cccccc;fill-rule:evenodd;stroke:none;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-rule:evenodd;stroke:none;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:0.02394956;fill-opacity:1.0" /> + style="opacity:0.2;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:0.02394956;fill-opacity:1.0" /> + style="opacity:0.2;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:0.02394956;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke-width:0.75" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke-width:0.5" /> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;stroke-width:0.75" /> + style="opacity:0.1;fill:#cccccc;fill-opacity:1.0;stroke-width:0.5" /> + style="opacity:0.1;fill:#cccccc;fill-opacity:1.0;stroke-width:0.5" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -99,17 +55,14 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -99,15 +55,13 @@ + id="layer1"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,11 +55,9 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/device-optical.svg b/rtdata/icons/rawtherapee/scalable/apps/device-optical.svg index de73e9422..5b374de3a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/device-optical.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/device-optical.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,21 +55,18 @@ + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/device-usb.svg b/rtdata/icons/rawtherapee/scalable/apps/device-usb.svg index 116a6e1f5..bc68214eb 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/device-usb.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/device-usb.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg index 6a8ac0a03..dd9726fb6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto-small.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -106,36 +56,28 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path1207" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path838" /> + style="display:inline;opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:0.04999533" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg index 8cfadb130..2d14f873f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-auto.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:'Bitstream Vera Sans';-inkscape-font-specification:'Bitstream Vera Sans';text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.72779661;marker:none;enable-background:accumulate" /> + style="display:inline;opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:0.04999533" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg index b769bd0aa..70bdae4ec 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel-small.svg @@ -2,68 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -108,20 +56,14 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path1207" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="m 1.5,17.5 c 4.3333333,0.666667 8.666667,0.666667 13,0 m -13,-3 c 4.3333333,-0.666667 8.666667,-0.666667 13,0 m -4,-4 c 0.650292,3.616036 0.682877,7.280165 0,11 m -5,-11 c -0.6584443,3.641034 -0.6748477,7.307062 0,11 M 2,11.5 c 4.2825076,-1.305586 7.61369,-1.360845 12,0 0.666667,3 0.666667,6 0,9 -4.413583,1.374278 -7.7421039,1.291863 -12,0 -0.676645,-3.026341 -0.6566267,-6.025562 0,-9 z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg index 012651e87..762f0771b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-barrel.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,13 +55,10 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg index 8c26277d2..8f262e176 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion-small.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path1207" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="M 2.8112464,17.975283 C 7.1188978,17.315578 8.8287055,17.32088 13.188262,17.99448 M 2.7853074,13.943943 c 4.3076514,0.659705 6.0609769,0.7413 10.4205336,0.0677 m -2.922632,-2.196722 c -0.6422099,3.591664 -0.6435523,4.629432 0.04721,8.376771 M 5.7102407,11.813858 c 0.6666667,3.666667 0.5279002,4.730262 -0.1387665,8.396929 M 1.5,10.5 c 4.3333333,2 8.666667,2 13,0 -1.90259,3.567911 -2.095481,7.224565 0,11 -4.413626,-2.041021 -8.7421418,-1.958561 -13,0 2.0486318,-3.719835 1.9508767,-7.383964 0,-11 z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg index c893eb99a..50b3a923c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/distortion-pincushion.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,15 +55,12 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/draw.svg b/rtdata/icons/rawtherapee/scalable/apps/draw.svg index 30ea04ea4..db922ba0c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/draw.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/draw.svg @@ -1,57 +1,15 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path1658" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/edit-point.svg b/rtdata/icons/rawtherapee/scalable/apps/edit-point.svg index 9f686d6e9..24374ed02 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/edit-point.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/edit-point.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,60 +55,51 @@ + id="layer1"> + id="path1658" /> + id="path1658-3" /> + id="path1682" /> + id="path1686" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/edit-small.svg b/rtdata/icons/rawtherapee/scalable/apps/edit-small.svg index 6306f06df..359c1973f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/edit-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/edit-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,32 +56,22 @@ + id="path1658" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/edit.svg b/rtdata/icons/rawtherapee/scalable/apps/edit.svg index 71f3d0b06..c569c5ea0 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/edit.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/edit.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,40 +55,31 @@ + id="layer1"> + id="path1658" /> + id="path1658-3" /> + id="path1682" /> + id="path1686" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg index 52dcaed4b..758d248d1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/equilizer-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path6665" /> + id="path6663" /> + id="path6661" /> + id="path6659" /> + id="path6657" /> + id="path6655" /> + id="path6653" /> + id="path6651" /> + id="path6649" /> + id="path6647" /> + id="path6645" /> + id="path6643" /> + id="path6641" /> + id="path6639" /> + id="path6637" /> + id="path6635" /> + id="path6633" /> + id="path6631" /> + id="path6629" /> + id="path6627" /> + id="path6625" /> + id="path6623" /> + id="path6621" /> + id="path6619" /> + id="path6617" /> + id="path6615" /> + id="path6613" /> + id="path6611" /> + id="path6609" /> + id="path6607" /> + id="path6605" /> + id="path6603" /> + id="path6601" /> + id="path6599" /> + id="path6597" /> + id="path6164" /> + id="path6767" /> + id="path6765" /> + id="path6763" /> + id="path6761" /> + id="path6759" /> + id="path6757" /> + id="path6755" /> + id="path6753" /> + id="path6751" /> + id="path6749" /> + id="path6747" /> + id="path6745" /> + id="path6743" /> + id="path6741" /> + id="path6166" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg b/rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg index 594cca2ab..8662e4bcb 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/equilizer-wide.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,168 +55,134 @@ + id="layer1"> + id="path6216" /> + id="path6214" /> + id="path6212" /> + id="path6210" /> + id="path6208" /> + id="path6206" /> + id="path6204" /> + id="path6202" /> + id="path6200" /> + id="path6198" /> + id="path6196" /> + id="path6194" /> + id="path6192" /> + id="path6190" /> + id="path6188" /> + id="path6186" /> + id="path6184" /> + id="path6182" /> + id="path6180" /> + id="path6178" /> + id="path6176" /> + id="path6174" /> + id="rect3950" /> + id="path6234" /> + id="path6232" /> + id="path6230" /> + id="path6228" /> + id="path6226" /> + id="path6224" /> + id="path6222" /> + id="path6220" /> + id="path6162" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg b/rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg index e9cea3b4d..f050fd36e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/expander-closed-small.svg @@ -2,63 +2,20 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="linearGradient2452"> + transform="matrix(0.65240305,0,0,0.6780646,3.6765428,4.488834)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg b/rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg index 8355bc2f3..957366a06 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/expander-open-small.svg @@ -2,68 +2,20 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="linearGradient2452"> + transform="matrix(0,0.65244888,-0.6780646,0,19.511166,12.676186)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/exposure.svg b/rtdata/icons/rawtherapee/scalable/apps/exposure.svg index c0edc9e9b..cbcf4df6f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/exposure.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/exposure.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,24 +55,20 @@ + id="layer1"> + id="rect977" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.38199139px;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';fill:#ffffff;fill-opacity:1.0;stroke-width:0.99999994px" + d="M 2.2878589,9.0000003 H 4.1418834 V 11.099591 H 6.1678042 V 9.0000003 h 1.86221 V 15 h -1.86221 V 12.572988 H 4.1418834 V 15 H 2.2878589 Z" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.38199139px;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';fill:#ffffff;fill-opacity:1.0;stroke-width:0.99999994px" + d="m 9.2946799,9.0000003 h 2.7544341 q 0.814461,0 1.313779,0.2210095 0.50341,0.2210096 0.830832,0.6343793 0.327421,0.4133699 0.474761,0.9618009 0.14734,0.548431 0.14734,1.162346 0,0.961801 -0.22101,1.493861 -0.216917,0.527967 -0.60573,0.888131 -0.388813,0.356071 -0.834925,0.474761 Q 12.544339,15 12.049114,15 H 9.2946799 Z M 11.148704,10.3588 v 3.278308 h 0.454298 q 0.581173,0 0.826739,-0.126876 0.245566,-0.130969 0.38472,-0.450205 0.139155,-0.323328 0.139155,-1.043656 0,-0.953615 -0.311051,-1.305593 Q 12.331515,10.3588 11.611187,10.3588 Z" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.38199139px;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';fill:#ffffff;fill-opacity:1.0;stroke-width:0.99999994px" + d="M 15.810368,15 V 9.0000003 h 3.090041 q 0.859481,0 1.313779,0.1473397 0.454297,0.1473397 0.732605,0.5484311 0.278309,0.3969989 0.278309,0.9699859 0,0.499318 -0.212824,0.863575 -0.212824,0.360163 -0.585266,0.585266 -0.237381,0.143247 -0.650751,0.23738 0.331515,0.110505 0.482947,0.22101 0.102319,0.07367 0.294679,0.315143 0.196453,0.241473 0.261938,0.372442 L 21.712141,15 h -2.095498 l -0.99045,-1.833561 Q 18.437926,12.810368 18.290586,12.703956 18.09004,12.564802 17.836289,12.564802 H 17.672578 V 15 Z m 1.86221,-3.568895 h 0.781719 q 0.126876,0 0.491132,-0.08186 0.184175,-0.03683 0.298772,-0.188268 0.118691,-0.151432 0.118691,-0.347885 0,-0.290587 -0.184175,-0.446112 -0.184175,-0.155525 -0.691678,-0.155525 h -0.814461 z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg b/rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg index f10eabffd..56ecde611 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/filetype-ps.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.10554028px;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';fill:#ffffff;fill-opacity:1.0;stroke-width:0.99999982px" + d="m 6.591689,9.098945 h 2.9802109 q 0.9736151,0 1.4564641,0.4630606 0.486808,0.4630604 0.486808,1.3179414 0,0.878628 -0.530343,1.373351 -0.526386,0.494723 -1.6108183,0.494723 H 8.3924805 v 2.153034 H 6.591689 Z m 1.8007915,2.473615 h 0.4393139 q 0.5184696,0 0.7282321,-0.178101 0.2097626,-0.182058 0.2097626,-0.46306 0,-0.273087 -0.1820581,-0.463061 -0.182058,-0.189974 -0.6846965,-0.189974 h -0.510554 z" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.10554028px;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';fill:#ffffff;fill-opacity:1.0;stroke-width:0.99999982px" + d="m 12.144459,12.98153 1.705804,-0.10686 q 0.05541,0.415568 0.225594,0.633246 0.277045,0.352242 0.791557,0.352242 0.383905,0 0.58971,-0.1781 0.209762,-0.182058 0.209762,-0.419525 0,-0.225594 -0.197889,-0.403694 -0.197889,-0.1781 -0.918206,-0.336411 -1.179419,-0.265172 -1.682058,-0.704486 -0.506596,-0.439314 -0.506596,-1.120053 0,-0.447229 0.257256,-0.8430074 0.261214,-0.3997361 0.779683,-0.6253298 0.522428,-0.2295514 1.42876,-0.2295514 1.112137,0 1.693931,0.4155672 0.585752,0.4116095 0.69657,1.3139844 l -1.689973,0.09894 q -0.06728,-0.39182 -0.284961,-0.569921 -0.21372,-0.1781 -0.593667,-0.1781 -0.312665,0 -0.470976,0.134565 -0.158312,0.130607 -0.158312,0.32058 0,0.138523 0.130607,0.249341 0.126649,0.114775 0.601583,0.21372 1.175462,0.253298 1.682058,0.514512 0.510554,0.257256 0.740105,0.641161 0.23351,0.383905 0.23351,0.858839 0,0.558047 -0.308707,1.029023 -0.308707,0.470977 -0.862797,0.716359 Q 15.682717,15 14.839709,15 13.359498,15 12.789578,14.430079 12.219657,13.860158 12.144459,12.98153 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg b/rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg index 27af953db..6ecaae628 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/filter-clear.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,17 +55,13 @@ + id="layer1"> + style="fill:none;fill-rule:evenodd;stroke:#c00000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 22,10 12,20 m 0,-10 10,10" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/filter-original.svg b/rtdata/icons/rawtherapee/scalable/apps/filter-original.svg index c14a57a99..6c5b68cb6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/filter-original.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/filter-original.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,23 +55,17 @@ + id="layer1"> + id="path1049" /> + id="path1052" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,11 +55,9 @@ + id="layer1"> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04394949" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04394949" /> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04394949" /> + id="rect1095" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/filter.svg b/rtdata/icons/rawtherapee/scalable/apps/filter.svg index 684ffc35e..c106ea0d2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/filter.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/filter.svg @@ -2,67 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path816" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg b/rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg index 67465657f..53011fcd1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/flip-horizontal.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path828" /> + style="fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0;opacity:0.7" /> + id="path832" /> + style="fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0;opacity:0.7" /> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg b/rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg index 39771286a..a8bb5a435 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/flip-vertical.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path828" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0" /> + id="path832" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0" /> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg index 0197b8b5d..88694a939 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-off.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,24 +55,20 @@ + id="layer1"> + id="path8457" /> + id="path8455" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg index b6a6149f7..6d585c82d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/focusscreen-on.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,9 +55,7 @@ + id="layer1"> + style="opacity:0.3;fill:#1ce434;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:0.8;fill:#1ce434;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:0.5;fill:#1ce434;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg index e2988a681..ab30d780c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home-small.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.85361719;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.7568562;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="display:inline;opacity:0.5;fill:#ffffff;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:4.52244794pt" + d="M 4,21 H 6.9090909 V 17.363636 H 9.0909091 V 21 H 12 v -3.636364 h 1.454545 L 8,14 2.5454545,17.363636 H 4 C 3.99789,18.81946 3.927319,19.546354 4,21 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg index d4bf64e15..3fb5168b3 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-home.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path1047" /> + id="rect1030" /> + style="display:inline;opacity:0.5;fill:#ffffff;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:4.52244794pt" + d="m 6,19 h 4 v -5 h 3 v 5 h 4 v -5 h 2 L 11.5,8 4,14 h 2 c -0.0029,2.001757 -0.099937,3.001237 0,5 z" /> + style="opacity:0.5;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:1.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="display:inline;opacity:0.7;fill:#ffffff;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:4.52244794pt" + id="path828" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg index e412e386c..b78ce69f0 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent-small.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.85361719;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.7568562;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg index 84da8e236..8fab002eb 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-recent.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path1047" /> + id="rect1030" /> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:1.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:#ffffff;fill-opacity:1.0;stroke:none;stroke-width:1;enable-background:new" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg index f86f2157f..b35e607ca 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed-small.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -101,25 +56,19 @@ + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.85361719;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.7568562;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg index 74166166c..14aec7062 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-closed.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.85864949;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.79562616;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg index dc2f2ec3f..b6f98a566 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent-small.svg @@ -2,65 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path1026" /> + id="rect1030-7" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg index c0baf0ccf..6c787a733 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-open-recent.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="display:inline;opacity:0.7;fill:#ffffff;fill-opacity:1.0;stroke:none;stroke-width:1;enable-background:new" /> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + id="path1026" /> + id="rect1030" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg index f25394737..cd46e4db6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-open-small.svg @@ -2,65 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path1026" /> + id="rect1030-7" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-open.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-open.svg index 324a4bb9e..21545f938 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-open.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-open.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path1026" /> + id="rect1030" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg index 33e8bf568..7f0d34909 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-enter.svg @@ -2,60 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + id="path3607" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg index 3eee818a9..e5f4fef5d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/fullscreen-leave.svg @@ -2,60 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + id="path3607" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg index 289dbf396..ae9fbbc6c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gamut-hist.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,19 +55,14 @@ + id="layer1"> + id="path17368" /> + id="rect18347" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg index c27796b70..cf3a74db3 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gamut-plus.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,16 +55,13 @@ + id="layer1"> + id="path17368" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg index ca37ca2a0..5898265a3 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gamut-softproof.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,15 +55,11 @@ + id="layer1"> + id="path4674" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.02833264px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.5;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.02833264px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg index 9924857c3..a4d3bac09 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gamut-warning.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> ! + style="fill:#cccccc;fill-opacity:1;stroke-width:0.95393">! diff --git a/rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg b/rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg index 951b6611d..9297e0b0d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gamut_srgb_prophoto_xy.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,28 +55,23 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.03138535px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.03138535px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.03138535px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg index b472a82f4..abcec7081 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gears-pause.svg @@ -2,58 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1" /> + id="path6600" /> + id="rect1457" /> + id="path6613" /> + id="path1555" /> + id="path1557" /> + id="rect3267" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gears-play.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-play.svg index 83c23557d..ebd5472cf 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gears-play.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gears-play.svg @@ -2,65 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1" /> + id="path6684" /> + id="path6691" /> + transform="matrix(-0.55642817,-1.3172307,1.3172307,-0.55642817,9.8702419,42.575431)" /> + transform="matrix(-0.55642817,-1.3172307,1.3172307,-0.55642817,9.8702419,42.575431)" /> + id="path1557" /> + style="display:inline;opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:0.04999533" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gears-small.svg b/rtdata/icons/rawtherapee/scalable/apps/gears-small.svg index 60cfdc609..89032cd2b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gears-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gears-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ + id="rect3267" /> + id="rect1457" /> + style="display:block;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.38783646;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.08768296;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/gears.svg b/rtdata/icons/rawtherapee/scalable/apps/gears.svg index 3a7785a6f..18f4008b7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/gears.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/gears.svg @@ -2,58 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,33 +55,28 @@ + id="layer1" /> + style="display:block;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.54668486;marker:none;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path1555" /> + id="path1557" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg b/rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg index 26d805c5d..d1d961a17 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/goto-end-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="rect2901" /> + id="path840" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" /> + id="path852" /> + id="path844" /> + id="path861" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg index 310eda2d1..996213632 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/hand-open-hicontrast.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,30 +55,22 @@ + id="layer1"> + id="path2954" /> + style="opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:markers fill stroke" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path825" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/hand-open.svg b/rtdata/icons/rawtherapee/scalable/apps/hand-open.svg index a7597b482..d0dad0da7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/hand-open.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/hand-open.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2954" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path825" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg index 76016bf46..7361523db 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-bar-off-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,32 +56,30 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,32 +56,30 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg index 0eb016d00..cc1574aed 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logx-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg index e0b69c4e5..7f72b1e55 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-mode-logxy-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg index ec4200483..60b67ddec 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-red-off-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,11 +56,9 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,18 +56,16 @@ + style="opacity:1;fill:#d03030;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#30d043;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path851" /> + style="opacity:0.3;fill:#cccccc;stroke-linecap:square;fill-opacity:1.0" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Lawrence Lee @@ -96,11 +54,9 @@ diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg index ef2e8b51f..056197557 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hc-small.svg @@ -1,57 +1,15 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Lawrence Lee @@ -96,8 +54,6 @@ + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0" /> + style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg index 62bbf9586..46901f74c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-vectorscope-hs-small.svg @@ -1,57 +1,15 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Lawrence Lee @@ -96,8 +54,6 @@ + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="fill:none;stroke:#cccccc;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0" /> + style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg index 5147ab2fc..1ea706e50 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/histogram-type-waveform-small.svg @@ -1,57 +1,15 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Lawrence Lee @@ -96,27 +54,24 @@ + style="fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.3;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/info.svg b/rtdata/icons/rawtherapee/scalable/apps/info.svg index 8805fcad4..e18ec4f98 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/info.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/info.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> i + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18.522px;font-family:Georgia;-inkscape-font-specification:'Georgia Bold';fill:#ffffff;fill-opacity:1;stroke-width:1px">i diff --git a/rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg index 055759ad1..ba059358e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/intent-absolute.svg @@ -2,67 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path1194" /> + id="path1196" /> + id="path1198" /> + id="path1200" /> + id="path1202" /> + id="path1204" /> + id="path1206" /> + id="path1208" /> + id="path1210" /> + id="path1212" /> + id="path1214" /> + id="path1216" /> + id="path1234" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path1326" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg index 2e845cd39..4640e737f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/intent-perceptual.svg @@ -2,67 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path1194" /> + id="path1196" /> + id="path1198" /> + id="path1200" /> + id="path1202" /> + id="path1204" /> + id="path1206" /> + id="path1208" /> + id="path1210" /> + id="path1212" /> + id="path1214" /> + id="path1216" /> + id="path1234" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path1322" /> + id="path1324" /> + id="path1326" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg index 04e553796..0ba10bbf8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/intent-relative.svg @@ -2,67 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path1194" /> + id="path1196" /> + id="path1198" /> + id="path1200" /> + id="path1202" /> + id="path1204" /> + id="path1206" /> + id="path1208" /> + id="path1210" /> + id="path1212" /> + id="path1214" /> + id="path1216" /> + id="path1234" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path1326" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg b/rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg index 569c54962..4ffd0c108 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/intent-saturation.svg @@ -2,67 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path1194" /> + id="path1196" /> + id="path1198" /> + id="path1200" /> + id="path1202" /> + id="path1204" /> + id="path1206" /> + id="path1208" /> + id="path1210" /> + id="path1212" /> + id="path1214" /> + id="path1216" /> + id="path1234" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path1322" /> + id="path1324" /> + id="path1326" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg index 68aa7d6c2..f75599891 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-1to1-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,46 +56,36 @@ + id="circle818" /> + id="path846" /> + id="path848" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + id="path848" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg index 54d6e3e9e..0578d3f2d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-crop.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + id="rect1322" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.97660822;paint-order:normal" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.97660822;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg index 1d531e2d7..41ecf8f96 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-fit.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + id="rect921" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.9;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + id="path819" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.9;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg index 08871ed77..cf8e5e61f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,24 +56,20 @@ + id="circle818" /> + style="opacity:0.9;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 4.0142425,15 H 9.9857576" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg index 567845d57..7580620c2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-minus.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,11 +55,9 @@ + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.9;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 6,10 h 8" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg index a93e8cd8e..99828597e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,24 +56,20 @@ + id="circle818" /> + style="opacity:0.9;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 4.0142425,15 H 9.9857576 M 7.0000001,12.014242 v 5.971515" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg index a98c19bad..8ff545e7a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier-plus.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,11 +55,9 @@ + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.9;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 6,10 h 8 M 10,6 v 8" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/magnifier.svg b/rtdata/icons/rawtherapee/scalable/apps/magnifier.svg index 3b7ae2fd2..2e216d703 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/magnifier.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/magnifier.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/metadata.svg b/rtdata/icons/rawtherapee/scalable/apps/metadata.svg index 695d2af1a..78c9d8836 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/metadata.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/metadata.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,9 +55,7 @@ + id="layer1"> @@ -108,16 +65,16 @@ height="310.3132" width="51.57206" id="rect3325-3" - style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#2a7fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg index 375c8ea27..e577c6293 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/node-move-nw-se-hicontrast.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -100,32 +55,24 @@ + id="layer1"> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + id="path886" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg index fdda47505..707895b3b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/node-move-sw-ne-hicontrast.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -100,32 +55,24 @@ + id="layer1"> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + id="path886" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg index a24af10ef..f62f5368e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/node-move-x-hicontrast.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -100,28 +55,20 @@ + id="layer1"> + id="path2866-6" /> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg index 05d291870..7d0bd110d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/node-move-xy-hicontrast.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + id="path886" /> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path991" /> + id="path2866" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + id="path2866-3" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg index 615f3f94a..f0718b688 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/node-move-y-hicontrast.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -100,32 +55,24 @@ + id="layer1"> + style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1.0;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1.0;paint-order:normal" /> + id="path886" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg b/rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg index 8b08f99d0..7ff044aff 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/one-to-one-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="M 5.6806,21.24916 H 3.7403 v -7.37477 c -0.7089,0.66854 -0.8974,0.72796 -1.8595,1.04829 v -1.77579 c 0.5064,-0.16713 0.4095,-0.0478 1.0033,-0.51208 0.5938,-0.46889 1.0012,-1.0144 1.2222,-1.63651 h 1.5743 v 10.25086" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path11693" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path11687" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="M 7,17.95685 V 16 h 1.9403 v 1.95685 H 7" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="M 26.3822,20.10325 H 24.882 v -5.70208 c -0.5481,0.51691 -0.6939,0.56285 -1.4378,0.81053 v -1.37302 c 0.3916,-0.12922 0.3166,-0.037 0.7758,-0.39593 0.4591,-0.36254 0.7741,-0.78432 0.9449,-1.26533 h 1.2173 v 7.92583" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path42317" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path42319" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="m 27.3807,17.55768 v -1.51301 h 1.5002 v 1.51301 h -1.5002" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="m -14.5192,19.51664 v -1.33606 h 1.336 v 1.33606 h -1.336" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path11695-3" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="m -10.2779,20.01486 h -1.5465 v -7.78227 h 1.5465 v 7.78227" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path3061" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path3861" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="m -34.7301,17.15962 v -1.83786 h 1.8378 v 1.83786 h -1.8378" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + id="path3865" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:550px;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-60px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02110476;stroke-opacity:1" + d="m -36.5992,21.47631 h -2.1273 V 10.77115 h 2.1273 v 10.70516" /> + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Arial;-inkscape-font-specification:'Arial Bold';letter-spacing:-2px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> + id="path848" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.7" /> + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L';letter-spacing:0px;word-spacing:0px;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;opacity:0.7" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg b/rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg index 27f1bc510..1ab5c85d4 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/padlock-locked-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.17045528;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg b/rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg index 0c282c8cf..8e0f284c8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/padlock-unlocked-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,31 +56,23 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.17045528;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg b/rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg index 30eaac0d6..79614edf9 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/palette-brush.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -102,31 +55,22 @@ + id="layer1"> + id="path3964" /> + id="rect886" /> + id="rect889" /> + id="path892" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg b/rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg index 8e63c0309..63494a4a4 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/panel-to-bottom.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg index c4797a6a2..1a386806a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,26 +56,18 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path1207" /> + id="rect1209" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="m 6.6071429,11.622449 v 8.755102 m 5.1937041,-8.013144 v 7.271186 M 14.15,17.269231 2.3313953,17.918605 M 14.15,14.730769 2.3313953,14.081395 M 14.15,19.3 2.3313953,20.988372 V 11.011628 L 14.15,12.7 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg index 18ce37ea3..3c7939410 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-left.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg index 4721117c8..e10aa2880 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,26 +56,18 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path1207" /> + id="rect1209" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.00157475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="m 9.8742524,11.622449 v 8.755102 M 4.6805483,12.364407 v 7.271186 M 2.3313953,17.269231 14.15,17.918605 M 2.3313953,14.730769 14.15,14.081395 M 2.3313953,19.3 14.15,20.988372 V 11.011628 L 2.3313953,12.7 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg index 809e94123..9e16927ae 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-right.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg index 0c5046879..fe267866f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-horizontal-vertical.svg @@ -2,57 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,21 +55,14 @@ + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg index 80f023b74..14e4c4474 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom-small.svg @@ -2,58 +2,16 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,26 +56,18 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="m 21.5,18.5 h 13 m -13,-5 h 13 m -4,-3 v 11 m -5,-11 v 11 m -4,-11 h 13 v 11 h -13 z" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path992" /> + id="path1014" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg index 4cc5bf0f3..aec86fbcd 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-bottom.svg @@ -2,57 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg index 1ec0fafa7..ba15938ce 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top-small.svg @@ -2,58 +2,16 @@ - - - + width="16" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,26 +56,18 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + d="m 21.5,18.5 h 13 m -13,-5 h 13 m -4,-3 v 11 m -5,-11 v 11 m -4,-11 h 13 v 11 h -13 z" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1.0;paint-order:normal" + id="path992" /> + id="path1014" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg index 34f75fe7f..d2fe215f7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/perspective-vertical-top.svg @@ -2,57 +2,16 @@ - - - + width="24px" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.7;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 56,2 V 22 M 48,2 V 22 M 42,16 H 62 M 42,8 H 62 M 42,2 H 62 V 22 H 42 Z" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg index 305f504cd..4f3fc18d2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/power-inconsistent-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path5608" /> + id="path2553" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,18 +54,14 @@ + id="path5608" /> + id="path2553" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg b/rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg index 271c8e53e..a8b6e559a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/power-on-small.svg @@ -1,60 +1,15 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + transform="translate(0,-8)"> + id="path5608-3" /> + id="path2553-6" /> + id="path5608-36" /> + id="path2553-7" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/preferences.svg b/rtdata/icons/rawtherapee/scalable/apps/preferences.svg index db6794736..e742d74a7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/preferences.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/preferences.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,15 +55,13 @@ + id="layer1"> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.03404313" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04394949" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.03930962" /> + id="rect1095" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg b/rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg index 90d22c74a..5d58013ba 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/profile-partial.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,11 +55,9 @@ + id="layer1"> + style="opacity:0.2;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.03404313" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04394949" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.03930962" /> + id="rect1095" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/questionmark.svg b/rtdata/icons/rawtherapee/scalable/apps/questionmark.svg index 4c4b59590..855873047 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/questionmark.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/questionmark.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,27 +55,24 @@ + id="layer1"> ? + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:18.522px;font-family:Georgia;-inkscape-font-specification:'Georgia Bold';fill:#ffffff;fill-opacity:1;stroke-width:1px">? diff --git a/rtdata/icons/rawtherapee/scalable/apps/redo-all.svg b/rtdata/icons/rawtherapee/scalable/apps/redo-all.svg index f9dbaad23..0d9dac982 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/redo-all.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/redo-all.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,28 +55,22 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.58443224;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.35;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.58443224;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.35;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.58443224;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/redo-small.svg b/rtdata/icons/rawtherapee/scalable/apps/redo-small.svg index 639aebb42..6c0fabd46 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/redo-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/redo-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path815" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/redo.svg b/rtdata/icons/rawtherapee/scalable/apps/redo.svg index 14f9f7c00..394ae22e2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/redo.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/redo.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,14 +55,10 @@ + id="layer1"> + id="path815" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg index 498faafe8..22222eb69 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/refresh-red-small.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -102,39 +56,27 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c00000;stroke-width:2.13567448;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c00000;stroke-width:2.13567448;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="display:inline;opacity:0.7;fill:#c00000;fill-opacity:1.0;stroke:none;stroke-width:0.03718871" /> + id="path829" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg index d9ca603ef..d1c6c821f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/refresh-small.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.04338683" /> + id="path829" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/refresh.svg b/rtdata/icons/rawtherapee/scalable/apps/refresh.svg index 3b0b0cb72..8d4aa1c73 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/refresh.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/refresh.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -101,34 +55,22 @@ + id="layer1"> + id="path853" /> + id="path846" /> + id="path2876" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/remove-small.svg b/rtdata/icons/rawtherapee/scalable/apps/remove-small.svg index 1bffa469c..796a415a7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/remove-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/remove-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,32 +56,22 @@ + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 2.5213637,16.478636 H 12.521364" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/remove.svg b/rtdata/icons/rawtherapee/scalable/apps/remove.svg index bccfdb160..b3487a896 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/remove.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/remove.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -103,26 +55,20 @@ + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:0.53333285;fill-rule:nonzero;stroke:#cccccc;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="M 3,12 H 21" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg index fda645c55..28d0eecf3 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode-hicontrast.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -101,17 +55,15 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg index 67ac406fa..a515aae6a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-aroundnode.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path1597" /> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.5;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2866" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:10;stroke-opacity:1.0;paint-order:normal" /> 90° + id="tspan16">90° diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg index d85b5e8ea..fad01fe23 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-left-small.svg @@ -2,65 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,49 +56,33 @@ + id="path1029" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.54308969" /> + id="path1085" /> + id="path1096" /> + id="path1103" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg index c66020379..7c1e5fa1c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-left.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -100,40 +55,30 @@ + id="layer1"> + id="path7246" /> + id="path7240" /> + id="path7236" /> + id="path7234" /> + id="path9832" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.99999994" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg index bb2e66482..edc9afa38 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-90.svg @@ -2,63 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path2866" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:10;stroke-opacity:1.0;paint-order:normal" /> + id="path1734" /> 90° + id="tspan16">90° diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg index 89e6d4ac2..ba1410815 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-right-small.svg @@ -2,65 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,48 +56,34 @@ + id="path1029" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.54308969" /> + id="path1085" /> + id="path1096" /> + id="path1103" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg index 26a46a3f6..4d5763e1e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-right.svg @@ -2,61 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path7246" /> + id="path7240" /> + id="path7236" /> + id="path7234" /> + id="path9832" /> + style="opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.99999994" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg index 00da936f8..5a63b665e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,36 +56,26 @@ + id="path886" /> + id="path888" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0216444" /> + id="path937" /> + id="path942" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg index 34765aa2b..e833ae8b1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/rotate-straighten.svg @@ -2,68 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> @@ -117,13 +63,11 @@ transform="matrix(-1,0,0,1,-2,0)" id="g1732"> + id="path2866" /> @@ -131,107 +75,86 @@ id="text1716" y="21.884642" x="-25.32762" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.45023155px;line-height:125%;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';letter-spacing:0px;word-spacing:0px;opacity:0.7;fill:#2a7fff;fill-opacity:1;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.45023px;line-height:125%;font-family:'Arial Black';-inkscape-font-specification:'Arial Black, ';letter-spacing:0px;word-spacing:0px;opacity:0.7;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" xml:space="preserve">90° + id="tspan1714">90° + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:10;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 2;stroke-dashoffset:0;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path2866-3" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 2;stroke-dashoffset:0;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + id="path886" /> + id="path888" /> + style="display:inline;opacity:0.9;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.0348262" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:1;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/save-small.svg b/rtdata/icons/rawtherapee/scalable/apps/save-small.svg index 3398e27c8..94de504b8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/save-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/save-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path1601" /> + transform="matrix(1.4285714,0,0,-1.4285714,60.571429,23.428571)" /> + transform="matrix(1.4285714,0,0,-1.4285714,60.571429,23.428571)" /> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.14285719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/save.svg b/rtdata/icons/rawtherapee/scalable/apps/save.svg index eae40ed09..818b8d52d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/save.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/save.svg @@ -2,60 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path35160" /> + id="path35158" /> + id="path35156" /> + id="rect34888" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path8807-3" /> + id="path35172" /> + transform="matrix(1,0,0,-1,-20,24)" /> + transform="matrix(1,0,0,-1,-20,24)" /> + style="opacity:1;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:1.71428573;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + id="path35202" /> + transform="matrix(1,0,0,-1,-100,24)" /> + transform="matrix(1,0,0,-1,-100,24)" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2.55999184;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + id="path35191" /> + transform="matrix(1,0,0,-1,-60,24)" /> + id="path35000" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path35006" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.83998775;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> @@ -343,30 +266,26 @@ height="5" width="3" id="rect35070" - style="opacity:0.7;fill:#2a7fff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path35084" /> + id="path35092" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:1.28571427;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg b/rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg index 02b245aa1..20b6dfb43 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/saved-no-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path1631" /> + id="path1629" /> + id="path1627" /> + id="path1610" /> + style="fill:none;fill-rule:evenodd;stroke:#c00000;stroke-width:1.88826501;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 10.832397,10.667603 -5.6647946,5.664794 m 0,-5.664794 5.6647946,5.664794" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg b/rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg index f545e9b18..3dee64650 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/saved-yes-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,8 +56,6 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:1.45144057" /> + id="path1677" /> + id="path1664" /> + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - @@ -43,13 +21,11 @@ image/svg+xml - + + style="fill:#ffffff;fill-opacity:0.58823532;stroke:none" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg b/rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg index d0320e31f..67b954642 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/spot-normal.svg @@ -2,39 +2,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - @@ -48,26 +26,19 @@ + id="path818" /> + id="rect2989" /> + style="fill:#ffffff;fill-opacity:1.0;stroke:none" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg b/rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg index 9cfc1acfa..e53acfcbf 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/spot-prelight.svg @@ -2,39 +2,17 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - @@ -48,8 +26,6 @@ + style="fill:#ffffff;fill-opacity:1.0;stroke:none" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg index 23d835032..86c7fa8c7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#1a1a1a;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg index 431f8bd58..43f6cee0e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-black-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#1a1a1a;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg index 4da563f36..201df582a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#3030d0;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg index 6aa7e2cb1..3e6d90887 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-blue-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#3030d0;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg index 3bc716d8e..779ec1b6e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#777777;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg index 6e3ddb2ed..cd7b044e8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-gray-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#777777;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg index 814feedf6..695e41e04 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,9 +55,7 @@ + id="layer1"> + style="opacity:1;fill:#30d043;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg index ed178b3b0..e381a32f0 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-green-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,9 +55,7 @@ + id="layer1"> + style="opacity:1;fill:#30d043;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg index 9d5ad85ed..45dfafd9c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> L + id="tspan16">L diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg index f7e83e8bb..7422df22c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-luminosity-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> L + id="tspan12">L diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg index b05b91ae5..7ccb866f2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#d03030;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg index 52382d0df..b5a36ac78 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-red-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#d03030;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg index 311552709..b7a2f6ec1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> T + id="tspan12">T diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg index 3c8efd85b..16983479e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-theme-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> T + id="tspan12">T diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg index 99e675f83..5290de8a6 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-off-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#e6e6e6;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg index 97b5e5e41..15155f1ae 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/square-toggle-white-on-narrow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,11 +55,9 @@ + id="layer1"> + style="opacity:1;fill:#e6e6e6;fill-opacity:1.0;stroke:none;stroke-width:0;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg index 82ab83a4a..e3f7b74d9 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-narrow.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,25 +56,11 @@ + transform="matrix(0.56919272,-0.18374267,0.18494192,0.56550181,-2.5126125,8.8701237)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg index ecdcf65f7..9914f9869 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-gold-hollow-small.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + transform="matrix(0.86350439,-0.28029946,0.28056958,0.86267304,-3.3971484,4.0671628)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg index ee54c8214..56b18d5ae 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-gold-narrow.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,25 +56,11 @@ + transform="matrix(0.56980386,-0.18402433,0.18514049,0.56636866,-2.5206787,8.8590542)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg index 48694c3f1..fa588ae59 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-gold-small.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + transform="matrix(0.86350439,-0.28029946,0.28056958,0.86267304,-3.3971484,4.0671628)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg index 66b1c233c..b305a320b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-narrow.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,25 +56,11 @@ + transform="matrix(0.56919272,-0.18374267,0.18494192,0.56550181,-2.5126125,8.8701237)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg index 6d63a6e8b..03dd8e8b1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-hollow-small.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + transform="matrix(0.86350439,-0.28029946,0.28056958,0.86267304,-3.3971484,4.0671628)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg index 90add16d5..8c8400439 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-narrow.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,25 +56,11 @@ + transform="matrix(0.56924178,-0.18383994,0.18495787,0.56580117,-2.5132602,8.8663162)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star-small.svg b/rtdata/icons/rawtherapee/scalable/apps/star-small.svg index cd7a9b8ef..a1e44d60c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star-small.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + transform="matrix(0.86350439,-0.28029946,0.28056958,0.86267304,-3.3971484,4.0671624)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/star.svg b/rtdata/icons/rawtherapee/scalable/apps/star.svg index af9ca870e..e5304fdf5 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/star.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/star.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + transform="matrix(1.5183042,-0.49285198,0.49332694,1.5168424,-8.0396646,-7.2232632)" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/template-16.svg b/rtdata/icons/rawtherapee/scalable/apps/template-16.svg index d38151609..2af54c644 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/template-16.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/template-16.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/template-24.svg b/rtdata/icons/rawtherapee/scalable/apps/template-24.svg index 88d934fc5..9d95f52af 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/template-24.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/template-24.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg b/rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg index 9a6321317..dc8602564 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/template-narrow.svg @@ -2,64 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -104,7 +56,5 @@ diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg index fcac2954d..9ff9cbde8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,14 +56,10 @@ + style="opacity:0.7;fill:none;fill-opacity:1;stroke:#008000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg index 9b1eca47d..0286260eb 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-green-hollow.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:none;fill-opacity:1;stroke:#008000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg index edf2dd4b4..afe11e7c5 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-green-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="opacity:0.7;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:2.30911016" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-green.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-green.svg index fa250d9fe..158fd7d8b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-green.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-green.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:2.30911016" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg index 010fba31e..044caa1b5 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-hollow-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,14 +56,10 @@ + style="opacity:0.7;fill:none;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick-small.svg b/rtdata/icons/rawtherapee/scalable/apps/tick-small.svg index 943c61d76..0ed45e432 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,14 +56,10 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2.30911016" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/tick.svg b/rtdata/icons/rawtherapee/scalable/apps/tick.svg index dd4ab4bdd..287d4121f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/tick.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/tick.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:2.30911016" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/transform.svg b/rtdata/icons/rawtherapee/scalable/apps/transform.svg index 09b55309d..357504a7f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/transform.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/transform.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,9 +55,7 @@ + id="layer1"> + id="path1459-8-6" /> + id="path1452-5-3" /> + id="path5382" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.01634204" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg index 7593e6001..941db86c8 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-delete.svg @@ -2,228 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -268,101 +186,78 @@ + id="layer1"> + id="path976" /> + id="path974" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path1002" /> + id="path1014" /> + id="path1007" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.80579805;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.88275099;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path1017" /> + id="path1019" /> + style="opacity:0.9;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.21462178;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> + id="path1028" /> + style="opacity:0.9;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.46620023;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg index 366b15bd6..2d618c7ac 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-empty-show.svg @@ -2,210 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -250,38 +186,32 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:39.57666016;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:39.57666016;fill-opacity:1.0" /> + id="path992" /> + id="path3803" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg index 47ceae609..c943d8934 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-empty.svg @@ -2,210 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -217,7 +153,7 @@ image/svg+xml - + Maciej Dworak @@ -250,29 +186,24 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:39.57666016;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:39.57666016;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:39.57666016;fill-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg index 8ec3f9092..215e41a11 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-full-show.svg @@ -2,211 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -218,7 +153,7 @@ image/svg+xml - + Maciej Dworak @@ -251,41 +186,38 @@ + id="layer1"> + id="path3803" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-full.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-full.svg index eae5920e3..07a4a1e3e 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-full.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-full.svg @@ -2,211 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -218,7 +153,7 @@ image/svg+xml - + Maciej Dworak @@ -251,39 +186,27 @@ + id="layer1"> + id="path5310" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg index e70aa21e1..ff090598f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-hide-deleted.svg @@ -2,210 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -250,43 +186,33 @@ + id="layer1"> + style="opacity:0.1;fill:#cccccc;stroke:none;stroke-width:1.34910131;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:1.34910131;fill-opacity:1.0" /> + style="opacity:1;fill:none;fill-rule:evenodd;stroke:#c00000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 18.58579,12.41421 -6.34316,6.343152 m 0,-6.343152 6.34316,6.343152" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg index a58bafd39..0afdaef37 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-remove-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path8807" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg index 31ca65a56..7d755261c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-remove.svg @@ -2,210 +2,146 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + style="overflow:visible"> + style="overflow:visible"> + id="ExperimentalArrow"> + style="fill:context-stroke;stroke:#000000;stroke-opacity:1.0" /> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> + style="overflow:visible"> @@ -217,7 +153,7 @@ image/svg+xml - + Maciej Dworak @@ -250,39 +186,30 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:1.34910131;fill-opacity:1.0" /> + style="opacity:1;fill:#008000;fill-opacity:1.0;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" /> + d="M 20.551716,6.2800579 C 20.245041,5.5113706 19.590094,4.8663289 18.801432,4.5424787 18.403538,4.3782733 17.622605,4.2903615 17.270188,4.3661609 L 17,4.4242737 l 1.997606,9.2876033 1.997608,9.287602 0.205577,-0.04422 c 1.233464,-0.265297 2.27384,-1.628329 2.273116,-2.974575 6.52e-4,-0.225556 -0.420075,-2.267378 -1.43164,-6.941943 -0.788636,-3.6380797 -1.46127,-6.6796912 -1.490551,-6.7586861 z" /> + id="path5310-3" /> + id="rect1539-6" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/trash-small.svg b/rtdata/icons/rawtherapee/scalable/apps/trash-small.svg index 3d2e674c6..405ae1baa 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/trash-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/trash-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,29 +56,24 @@ + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:62.19189453;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:62.19189453;fill-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;stroke:none;stroke-width:62.19189453;fill-opacity:1.0" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/undo-all.svg b/rtdata/icons/rawtherapee/scalable/apps/undo-all.svg index e648588ef..82d3abaee 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/undo-all.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/undo-all.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -105,21 +55,17 @@ + id="layer1"> + id="path815" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/undo-small.svg b/rtdata/icons/rawtherapee/scalable/apps/undo-small.svg index f06c73392..5d290f41b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/undo-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/undo-small.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path815" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/undo.svg b/rtdata/icons/rawtherapee/scalable/apps/undo.svg index bc4282693..2552d5b73 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/undo.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/undo.svg @@ -2,66 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path815" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg b/rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg index c7aaf80ce..346385d6a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/warning-highlights.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,37 +55,21 @@ + id="layer1"> + d="M 12,3 22.392305,21 1.6076952,21 Z" /> + style="opacity:0.7;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0.99999988" /> + style="opacity:0.7;fill:#000000;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.18797946" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg b/rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg index f9baa36c1..137cdebd2 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/warning-shadows.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,37 +55,21 @@ + id="layer1"> + d="M 12,3 22.392305,21 1.6076952,21 Z" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0.99999988" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.18797946" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/warning.svg b/rtdata/icons/rawtherapee/scalable/apps/warning.svg index c24ba0653..74a7d1d23 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/warning.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/warning.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,37 +55,21 @@ + id="layer1"> + d="M 12,3 22.392305,21 1.6076952,21 Z" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0.99999988" /> + style="opacity:0.9;fill:#ffffff;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.18797946" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wavelets.svg b/rtdata/icons/rawtherapee/scalable/apps/wavelets.svg index 1d6de039c..9d92638ce 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wavelets.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wavelets.svg @@ -2,62 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -101,35 +55,26 @@ + id="layer1"> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-mid:none;enable-background:accumulate" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-mid:none;enable-background:accumulate" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-mid:none;enable-background:accumulate" /> + style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:52.94812775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-mid:none;enable-background:accumulate" /> + id="path4443" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg index 23e55f560..b0de28748 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-auto-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg index 5914ee63e..7011cfe03 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-auto.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,16 +55,14 @@ + id="layer1"> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg index 2521d513e..19a241f64 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-camera-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,13 +56,10 @@ + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:37.76315689;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg index f83342b6b..1f4d0d87d 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-camera.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,13 +55,10 @@ + id="layer1"> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:37.76315689;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg index 0197eab4e..bc9e70be3 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,14 +56,10 @@ + id="path10598" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg index 5762fa37b..2d4fed852 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-cloudy.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,14 +55,10 @@ + id="layer1"> + id="path10598" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg index f176458a8..f7f66a447 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-custom-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,29 +56,25 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:3.11111116;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path936" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:3.11111116;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg index f1d2ec8f7..199b55ad1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-custom.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,28 +55,24 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + id="path936" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg index 634912538..13fb88b4b 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-flash-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,14 +56,10 @@ + id="path3360" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg index fb4b0ca66..cafc33867 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-flash.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,14 +55,10 @@ + id="layer1"> + id="path3360" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg index 67c86ec71..2b1598da1 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,76 +56,54 @@ + id="path10544" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7762" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7792" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7764" /> + id="path7794" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.54013252;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg index 8746978e1..e2274b902 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-fluorescent.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,72 +55,50 @@ + id="layer1"> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10560" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7786" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7798" /> + id="path10566" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7800" /> + id="rect7802" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg index 32c172d7f..c553fafae 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,76 +56,54 @@ + id="path10544" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7762" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7792" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7764" /> + id="path7794" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none;stroke-width:0.02588202" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg index 39f2ccb94..59fd8777a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-lamp.svg @@ -2,59 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -98,72 +55,50 @@ + id="layer1"> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10560" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7786" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7798" /> + id="path10566" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="display:inline;opacity:0.7;fill:none;stroke:#cccccc;stroke-width:1.54013252;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path7800" /> + id="rect3191" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg index 7e20c4576..c4aadfc8f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-led-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,17 +55,15 @@ + id="layer1"> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg index 78ed1e6c6..e5c3514fb 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-shade-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,36 +56,26 @@ + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> + style="opacity:0.7;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg index 3ac24bd80..d9d775895 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-shade.svg @@ -2,64 +2,23 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -141,32 +100,22 @@ + id="layer1"> + id="path916" /> + id="path926" /> + id="path928" /> + id="path930" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg index 94abad681..3758cc387 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-sun-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ + id="path10542" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.93516922;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10560" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10566" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.93516922;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10572" /> + id="path10576" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10582" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg index b9c71a3dc..0ea859e7c 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-sun.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,75 +55,61 @@ + id="layer1"> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.9351689;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10544" /> + id="path10558" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10564" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10570" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.9351689;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10578" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10584" /> - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.93516922;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10560" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10566" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.93516922;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10572" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10582" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137787;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + style="opacity:0.7;fill:#cccccc;fill-opacity:1.0;fill-rule:nonzero;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.00314951;stroke-opacity:1.0;paint-order:normal" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg index 0dabc0935..28030eea7 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-tungsten.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,63 +55,50 @@ + id="layer1"> + id="path10544" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10564" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10570" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:55.9351689;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10578" /> + style="opacity:0.7;fill:none;stroke:#cccccc;stroke-width:41.95137668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" /> + id="path10584" /> + id="path1023" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg index 2cb62298a..a4d45eeab 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-water-small.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -97,8 +56,6 @@ + style="display:inline;opacity:0.7;fill:#cccccc;fill-opacity:1.0;stroke:none" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/wb-water.svg b/rtdata/icons/rawtherapee/scalable/apps/wb-water.svg index 55a98f099..c716f542f 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/wb-water.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/wb-water.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> image/svg+xml - + Maciej Dworak @@ -96,18 +55,14 @@ + id="layer1"> + id="path5961" /> diff --git a/rtdata/icons/rawtherapee/scalable/apps/window-add.svg b/rtdata/icons/rawtherapee/scalable/apps/window-add.svg index da0651444..11982690a 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/window-add.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/window-add.svg @@ -2,58 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="layer1"> + id="path850" /> + style="opacity:0.9;fill:none;fill-rule:evenodd;stroke:#cccccc;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1.0" + d="m 3,17 h 8 M 7,13 v 8" /> diff --git a/rtdata/images/ornament1.svg b/rtdata/images/ornament1.svg index af3d729e5..592caac39 100644 --- a/rtdata/images/ornament1.svg +++ b/rtdata/images/ornament1.svg @@ -2,57 +2,16 @@ - - - + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + id="path4462" /> + id="path4462-1" /> + id="path4462-18" /> + id="path4462-1-3" /> From a618efe7826f725b26389698f2fd9922c0fa7293 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 3 Sep 2023 15:30:42 -0700 Subject: [PATCH 033/291] Fix Lensfun corrections not available Also search by exact match of lens model and name. --- rtengine/rtlensfun.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 58f3d12a3..3b5124947 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -455,6 +455,16 @@ LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) c LFLens ret; if (data_ && !name.empty()) { MyMutex::MyLock lock(lfDBMutex); + if (!camera.data_) { + // Only the lens name provided. Try to find exact match by name. + LFLens candidate; + for (auto lens_list = data_->GetLenses(); lens_list[0]; lens_list++) { + candidate.data_ = lens_list[0]; + if (name == candidate.getLens()) { + return candidate; + } + } + } auto found = data_->FindLenses(camera.data_, nullptr, name.c_str()); for (size_t pos = 0; !found && pos < name.size(); ) { // try to split the maker from the model of the lens -- we have to From f69e04c50e01479984a4a4c907f444a960d1bf04 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Tue, 5 Sep 2023 12:45:32 +0200 Subject: [PATCH 034/291] Fixes column width in Favorite Preferences panel --- rtgui/toollocationpref.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rtgui/toollocationpref.cc b/rtgui/toollocationpref.cc index c03c2fd24..b66f74536 100644 --- a/rtgui/toollocationpref.cc +++ b/rtgui/toollocationpref.cc @@ -536,12 +536,10 @@ ToolLocationPreference::Impl::Impl(Options &options) : // Tool list. toolListViewPtr->append_column(toolListViewColumnToolName); toolListViewColumnToolName.pack_start(toolListCellRendererToolName); - toolListViewColumnToolName.set_expand(); toolListViewColumnToolName.set_renderer( toolListCellRendererToolName, toolListColumns.toolName); toolListViewPtr->append_column(toolListViewColumnFavorite); - toolListViewColumnFavorite.pack_start(toolListCellRendererFavorite); - toolListViewColumnFavorite.set_expand(false); + toolListViewColumnFavorite.pack_start(toolListCellRendererFavorite, false); toolListViewColumnFavorite.set_renderer( toolListCellRendererFavorite, toolListColumns.isFavorite); toolListViewColumnFavorite.add_attribute( @@ -716,7 +714,8 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : Gtk::Grid *layout_grid = Gtk::manage(new Gtk::Grid()); layout_grid->set_column_spacing(4); layout_grid->set_row_spacing(4); - add(*layout_grid); + layout_grid->set_column_homogeneous(true); + pack_start(*layout_grid); // Tool list. Gtk::Frame *tool_list_frame = Gtk::manage(new Gtk::Frame( @@ -728,7 +727,7 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : tool_list_frame->add(*tool_list_scrolled_window); tool_list_scrolled_window->add(*impl->toolListViewPtr); setExpandAlignProperties( - tool_list_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); + tool_list_frame, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); // Favorites list. Gtk::Frame *favorites_frame = Gtk::manage(new Gtk::Frame( @@ -739,11 +738,11 @@ ToolLocationPreference::ToolLocationPreference(Options &options) : favorites_list_scrolled_window->set_min_content_width(RTScalable::scalePixelSize(400)); layout_grid->attach_next_to(*favorites_frame, Gtk::PositionType::POS_RIGHT, 1, 1); favorites_box->pack_start(impl->favoritesListEditButtons, false, false); - favorites_box->pack_start(*favorites_list_scrolled_window, false, false); + favorites_box->pack_start(*favorites_list_scrolled_window, true, true); favorites_frame->add(*favorites_box); favorites_list_scrolled_window->add(*impl->favoritesViewPtr); setExpandAlignProperties( - favorites_frame, false, true, Gtk::ALIGN_START, Gtk::ALIGN_FILL); + favorites_frame, true, true, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL); // General options. layout_grid->attach_next_to( From 6f5b01dc45e7166e5eb6d9a31b0d302e1f1256a2 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 8 Sep 2023 17:51:31 +0200 Subject: [PATCH 035/291] Fixes AppImage CI Update Librsvg to version v2.52.2 from source --- .github/workflows/appimage.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 0d3c76399..7c7ad26d7 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -48,6 +48,26 @@ jobs: echo "Building and installing." sudo make -j$(nproc) install + - name: Install Librsvg required min. version + # Required min. version is not available for Ubuntu 20.04 LTS (but is for 22.04 LTS) so needs to be built manually + run: | + LIBRSVG2_VERSION='2.52.2' + echo "Cloning Librsvg2 $LIBRSVG2_VERSION." + git clone --depth 1 --branch "$LIBRSVG2_VERSION" https://gitlab.gnome.org/GNOME/librsvg.git ext/librsvg2 + + echo "Installing required dependencies with apt." + DEBIAN_FRONTEND=noninteractive sudo apt install -y rustc cargo gtk-doc-tools libgirepository1.0-dev + + echo "Updating PATH." + export PATH="$PATH:/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0" + + echo "Configuring build." + cd ext/librsvg2 + sh autogen.sh + + echo "Building and installing." + sudo make install + - name: Configure build run: | export REF_NAME_FILTERED="$(echo '${{github.ref_name}}' | sed 's/[^A-z0-9_.-]//g')" From 5da07d8658a0a18bfee239cb726c800d079fd070 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Fri, 8 Sep 2023 18:09:05 +0200 Subject: [PATCH 036/291] Auto white balance - change label and tooltip --- rtdata/languages/default | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 27062ff1b..11191bedd 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -4173,7 +4173,7 @@ TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - near Pointer's gamut TP_WBALANCE_ITCWB_PRIM_JDCMAX;Close to full CIE diagram TP_WBALANCE_ITCWB_PRIM_REC;High sampling -TP_WBALANCE_ITCWB_PRIM_SRGB;Low sampling & No use Camera settings +TP_WBALANCE_ITCWB_PRIM_SRGB;Low sampling & Ignore Camera settings TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ matrix TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax after Camera XYZ matrix TP_WBALANCE_ITCWB_RGREEN;Green range @@ -4185,7 +4185,7 @@ TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. TP_WBALANCE_ITCWGREEN;Green refinement TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and No use camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) not to use camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. +TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;White Balance From 97e181bd58061f0d9d8b2746bbfc9bd144823850 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 9 Sep 2023 14:59:14 -0700 Subject: [PATCH 037/291] Fix automatic distortion correction crash Closes #6840. --- rtengine/rtthumbnail.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index e3f85615a..bc832661a 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -643,10 +643,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens tpp->blueMultiplier = ri->get_pre_mul (2); bool isMono = - (ri->getSensorType() == ST_FUJI_XTRANS && - rawParams->xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) || - (ri->getSensorType() == ST_BAYER && - rawParams->bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO)); + rawParams && + ((ri->getSensorType() == ST_FUJI_XTRANS && + rawParams->xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO)) || + (ri->getSensorType() == ST_BAYER && + rawParams->bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::MONO))); float pre_mul[4], scale_mul[4], cblack[4]; ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false); adjustBlackLevels(cblack, sensorType, rawParams); From 730704f3b2e5d9f3228cb14cb24363c4cb1c0278 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 9 Sep 2023 15:22:04 -0700 Subject: [PATCH 038/291] Fix startup crash in debug build Do not throw error when trying to get mutex lock. --- rtgui/threadutils.cc | 7 ++++++- rtgui/threadutils.h | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rtgui/threadutils.cc b/rtgui/threadutils.cc index fd3aeda47..070cd2e3c 100644 --- a/rtgui/threadutils.cc +++ b/rtgui/threadutils.cc @@ -29,9 +29,13 @@ MyMutex::MyMutex() : locked(false) {} -void MyMutex::checkLock () +bool MyMutex::checkLock (bool noError) { if (locked) { + if (noError) { + return false; + } + std::cerr << "MyMutex already locked!" << std::endl; #ifdef _WIN32 @@ -42,6 +46,7 @@ void MyMutex::checkLock () } locked = true; + return true; } void MyMutex::checkUnlock () diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index 401660b93..b4b12ac19 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -59,7 +59,7 @@ public: private: bool locked; - void checkLock (); + bool checkLock (bool noError=false); void checkUnlock (); #endif }; @@ -172,10 +172,10 @@ inline bool MyMutex::trylock () { if (MyMutexBase::try_lock ()) { #if STRICT_MUTEX && !NDEBUG - checkLock (); -#endif - + return checkLock(true); +#else return true; +#endif } return false; From 7ebbac25cab48ba2323ad094354f07ee561a5186 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 10 Sep 2023 14:29:17 -0700 Subject: [PATCH 039/291] Format code --- rtgui/threadutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index b4b12ac19..71c57e347 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -59,7 +59,7 @@ public: private: bool locked; - bool checkLock (bool noError=false); + bool checkLock (bool noError = false); void checkUnlock (); #endif }; From e255a77fcd9cc0344e751bfa911b9415bc85ceb1 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Tue, 12 Sep 2023 11:59:43 +0200 Subject: [PATCH 040/291] Fixes AppImage build - RawTherapee app icon should be installed in hicolor theme provided in AppImage package - Fix wrong searching path for SVG/PNG images in rtscalable.h --- CMakeLists.txt | 8 +-- rtdata/CMakeLists.txt | 5 +- .../128x128/apps}/rawtherapee.png | Bin .../16x16/apps}/rawtherapee.png | Bin .../24x24/apps}/rawtherapee.png | Bin .../256x256/apps}/rawtherapee.png | Bin .../32x32/apps}/rawtherapee.png | Bin .../48x48/apps}/rawtherapee.png | Bin .../64x64/apps}/rawtherapee.png | Bin rtdata/icons/hicolor/index.theme | 48 ++++++++++++++++++ .../scalable/apps}/rawtherapee.svg | 0 rtdata/icons/rawtherapee/index.theme | 43 ++-------------- rtgui/rtscalable.cc | 7 +-- 13 files changed, 63 insertions(+), 48 deletions(-) rename rtdata/icons/{rawtherapee/128x128/app_icons => hicolor/128x128/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/16x16/app_icons => hicolor/16x16/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/24x24/app_icons => hicolor/24x24/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/256x256/app_icons => hicolor/256x256/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/32x32/app_icons => hicolor/32x32/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/48x48/app_icons => hicolor/48x48/apps}/rawtherapee.png (100%) rename rtdata/icons/{rawtherapee/64x64/app_icons => hicolor/64x64/apps}/rawtherapee.png (100%) create mode 100644 rtdata/icons/hicolor/index.theme rename rtdata/icons/{rawtherapee/scalable/app_icons => hicolor/scalable/apps}/rawtherapee.svg (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c97d4b16..5445bdff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -366,12 +366,14 @@ endif() if(NOT DEFINED ICONSDIR) if(UNIX) if(BUILD_BUNDLE) - set(ICONSDIR "${DATADIR}/icons") + if(APPLE) + set(ICONSDIR "${DATADIR}/icons") + else() + set(ICONSDIR "${DATADIR}/share/icons") + endif() else() set(ICONSDIR "${CMAKE_INSTALL_PREFIX}/share/icons") endif() - else() - set(ICONSDIR "${DATADIR}/icons") endif() endif() diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index 8d7c14573..e14862d7f 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB DCPFILES "dcpprofiles/*") set(PROFILESDIR "profiles") set(THEMEDIR "themes") -set(ICONSDIR "icons") +set(ICONTHEMEDIR "icons") set(IMAGESDIR "images") if(WIN32) @@ -24,6 +24,7 @@ endif() if(UNIX) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rawtherapee.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR}) + install(DIRECTORY "${ICONTHEMEDIR}/hicolor" DESTINATION "${ICONSDIR}") endif() install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") @@ -35,7 +36,7 @@ install(FILES ${OPTIONSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OW install(DIRECTORY "${PROFILESDIR}" DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") install(DIRECTORY "${THEMEDIR}" DESTINATION "${DATADIR}") -install(DIRECTORY "${ICONSDIR}" DESTINATION "${DATADIR}") +install(DIRECTORY "${ICONTHEMEDIR}/rawtherapee" DESTINATION "${DATADIR}/${ICONTHEMEDIR}") install(DIRECTORY "${IMAGESDIR}" DESTINATION "${DATADIR}") if(APPLE) diff --git a/rtdata/icons/rawtherapee/128x128/app_icons/rawtherapee.png b/rtdata/icons/hicolor/128x128/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/128x128/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/128x128/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/16x16/app_icons/rawtherapee.png b/rtdata/icons/hicolor/16x16/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/16x16/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/16x16/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/24x24/app_icons/rawtherapee.png b/rtdata/icons/hicolor/24x24/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/24x24/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/24x24/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/256x256/app_icons/rawtherapee.png b/rtdata/icons/hicolor/256x256/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/256x256/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/256x256/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/32x32/app_icons/rawtherapee.png b/rtdata/icons/hicolor/32x32/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/32x32/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/32x32/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/48x48/app_icons/rawtherapee.png b/rtdata/icons/hicolor/48x48/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/48x48/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/48x48/apps/rawtherapee.png diff --git a/rtdata/icons/rawtherapee/64x64/app_icons/rawtherapee.png b/rtdata/icons/hicolor/64x64/apps/rawtherapee.png similarity index 100% rename from rtdata/icons/rawtherapee/64x64/app_icons/rawtherapee.png rename to rtdata/icons/hicolor/64x64/apps/rawtherapee.png diff --git a/rtdata/icons/hicolor/index.theme b/rtdata/icons/hicolor/index.theme new file mode 100644 index 000000000..1215a9989 --- /dev/null +++ b/rtdata/icons/hicolor/index.theme @@ -0,0 +1,48 @@ +[Icon Theme] +Name=Hicolor +Comment=RawTherapee app icon +Hidden=true +Directories=16x16/apps,24x24/apps,32x32/apps,48x48/apps,64x64/apps,128x128/apps,256x256/apps,scalable/apps + + +[16x16/apps] +Size=16 +Context=ApplicationIcons +Type=Threshold + +[24x24/apps] +Size=24 +Context=ApplicationIcons +Type=Threshold + +[32x32/apps] +Size=32 +Context=ApplicationIcons +Type=Threshold + +[48x48/apps] +Size=48 +Context=ApplicationIcons +Type=Threshold + +[64x64/apps] +Size=64 +Context=ApplicationIcons +Type=Threshold + +[128x128/apps] +Size=128 +Context=ApplicationIcons +Type=Threshold + +[256x256/apps] +Size=256 +Context=ApplicationIcons +Type=Threshold + +[scalable/apps] +MinSize=16 +Size=128 +MaxSize=256 +Context=ApplicationIcons +Type=Scalable diff --git a/rtdata/icons/rawtherapee/scalable/app_icons/rawtherapee.svg b/rtdata/icons/hicolor/scalable/apps/rawtherapee.svg similarity index 100% rename from rtdata/icons/rawtherapee/scalable/app_icons/rawtherapee.svg rename to rtdata/icons/hicolor/scalable/apps/rawtherapee.svg diff --git a/rtdata/icons/rawtherapee/index.theme b/rtdata/icons/rawtherapee/index.theme index c862ff01f..1095b2219 100644 --- a/rtdata/icons/rawtherapee/index.theme +++ b/rtdata/icons/rawtherapee/index.theme @@ -2,51 +2,14 @@ Name=RawTherapee Comment=RawTherapee icon theme Inherits=Adwaita -Directories=16x16/app_icons,24x24/app_icons,32x32/app_icons,48x48/app_icons,64x64/app_icons,128x128/app_icons,256x256/app_icons,scalable/app_icons,scalable/apps +Directories=24x24/apps,scalable/apps -[16x16/app_icons] -Size=16 -Context=ApplicationIcons -Type=Threshold - -[24x24/app_icons] +[24x24/apps] Size=24 -Context=ApplicationIcons +Context=Applications Type=Threshold -[32x32/app_icons] -Size=32 -Context=ApplicationIcons -Type=Threshold - -[48x48/app_icons] -Size=48 -Context=ApplicationIcons -Type=Threshold - -[64x64/app_icons] -Size=64 -Context=ApplicationIcons -Type=Threshold - -[128x128/app_icons] -Size=128 -Context=ApplicationIcons -Type=Threshold - -[256x256/app_icons] -Size=256 -Context=ApplicationIcons -Type=Threshold - -[scalable/app_icons] -MinSize=16 -Size=128 -MaxSize=256 -Context=ApplicationIcons -Type=Scalable - [scalable/apps] MinSize=16 Size=128 diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index b58da6d12..5e61e8655 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -24,9 +24,10 @@ #include #include "../rtengine/settings.h" -#include "config.h" #include "guiutils.h" +extern Glib::ustring argv0; + // Default static parameter values double RTScalable::dpi = 96.; int RTScalable::scale = 1; @@ -118,7 +119,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromPNG(const Glib::us path = fname; } else { // Look for PNG file in "images" folder - Glib::ustring imagesFolder = Glib::build_filename(DATA_SEARCH_PATH, "images"); + Glib::ustring imagesFolder = Glib::build_filename(argv0, "images"); path = Glib::build_filename(imagesFolder, fname); } @@ -145,7 +146,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us path = fname; } else { // Look for SVG file in "images" folder - Glib::ustring imagesFolder = Glib::build_filename(DATA_SEARCH_PATH, "images"); + Glib::ustring imagesFolder = Glib::build_filename(argv0, "images"); path = Glib::build_filename(imagesFolder, fname); } From 2a87c65a1459fa989b1ca5fb05105389a1602f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 15 Sep 2023 15:24:24 +0200 Subject: [PATCH 041/291] Fix UB in ProcParams::load() and the resulting Clang 15+ miscompilation Fixes #6847. --- rtengine/procparams.cc | 2543 ++++++++++++++++++++-------------------- 1 file changed, 1268 insertions(+), 1275 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2c954598f..05788399e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -17,7 +17,7 @@ * along with RawTherapee. If not, see . */ -#include +#include #include @@ -248,7 +248,6 @@ bool assignFromKeyfile( const Glib::KeyFile& keyfile, const Glib::ustring& group_name, const Glib::ustring& key, - bool has_params_edited, T& value, bool& params_edited_value ) @@ -256,9 +255,7 @@ bool assignFromKeyfile( if (keyfile.has_key(group_name, key)) { getFromKeyfile(keyfile, group_name, key, value); - if (has_params_edited) { - params_edited_value = true; - } + params_edited_value = true; return true; } @@ -271,7 +268,6 @@ bool assignFromKeyfile( const Glib::KeyFile& keyfile, const Glib::ustring& group_name, const Glib::ustring& key, - bool has_params_edited, const std::map& mapping, T& value, bool& params_edited_value @@ -289,9 +285,7 @@ bool assignFromKeyfile( return false; } - if (has_params_edited) { - params_edited_value = true; - } + params_edited_value = true; return true; } @@ -7854,8 +7848,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) Glib::KeyFile keyFile; try { + std::unique_ptr dummy_pedited; + if (pedited) { pedited->set(false); + } else { + dummy_pedited.reset(new ParamsEdited()); + + pedited = dummy_pedited.get(); } if (!Glib::file_test(fname, Glib::FILE_TEST_EXISTS) || @@ -7877,27 +7877,27 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("General")) { - assignFromKeyfile(keyFile, "General", "Rank", pedited, rank, pedited->general.rank); - assignFromKeyfile(keyFile, "General", "ColorLabel", pedited, colorlabel, pedited->general.colorlabel); - assignFromKeyfile(keyFile, "General", "InTrash", pedited, inTrash, pedited->general.intrash); + assignFromKeyfile(keyFile, "General", "Rank", rank, pedited->general.rank); + assignFromKeyfile(keyFile, "General", "ColorLabel", colorlabel, pedited->general.colorlabel); + assignFromKeyfile(keyFile, "General", "InTrash", inTrash, pedited->general.intrash); } if (keyFile.has_group("Exposure")) { if (ppVersion < PPVERSION_AEXP) { toneCurve.autoexp = false; // prevent execution of autoexp when opening file created with earlier versions of autoexp algorithm } else { - assignFromKeyfile(keyFile, "Exposure", "Auto", pedited, toneCurve.autoexp, pedited->toneCurve.autoexp); + assignFromKeyfile(keyFile, "Exposure", "Auto", toneCurve.autoexp, pedited->toneCurve.autoexp); } - assignFromKeyfile(keyFile, "Exposure", "Clip", pedited, toneCurve.clip, pedited->toneCurve.clip); - assignFromKeyfile(keyFile, "Exposure", "Compensation", pedited, toneCurve.expcomp, pedited->toneCurve.expcomp); - assignFromKeyfile(keyFile, "Exposure", "Brightness", pedited, toneCurve.brightness, pedited->toneCurve.brightness); - assignFromKeyfile(keyFile, "Exposure", "Contrast", pedited, toneCurve.contrast, pedited->toneCurve.contrast); - assignFromKeyfile(keyFile, "Exposure", "Saturation", pedited, toneCurve.saturation, pedited->toneCurve.saturation); - assignFromKeyfile(keyFile, "Exposure", "Black", pedited, toneCurve.black, pedited->toneCurve.black); - assignFromKeyfile(keyFile, "Exposure", "HighlightCompr", pedited, toneCurve.hlcompr, pedited->toneCurve.hlcompr); - assignFromKeyfile(keyFile, "Exposure", "HighlightComprThreshold", pedited, toneCurve.hlcomprthresh, pedited->toneCurve.hlcomprthresh); - assignFromKeyfile(keyFile, "Exposure", "ShadowCompr", pedited, toneCurve.shcompr, pedited->toneCurve.shcompr); + assignFromKeyfile(keyFile, "Exposure", "Clip", toneCurve.clip, pedited->toneCurve.clip); + assignFromKeyfile(keyFile, "Exposure", "Compensation", toneCurve.expcomp, pedited->toneCurve.expcomp); + assignFromKeyfile(keyFile, "Exposure", "Brightness", toneCurve.brightness, pedited->toneCurve.brightness); + assignFromKeyfile(keyFile, "Exposure", "Contrast", toneCurve.contrast, pedited->toneCurve.contrast); + assignFromKeyfile(keyFile, "Exposure", "Saturation", toneCurve.saturation, pedited->toneCurve.saturation); + assignFromKeyfile(keyFile, "Exposure", "Black", toneCurve.black, pedited->toneCurve.black); + assignFromKeyfile(keyFile, "Exposure", "HighlightCompr", toneCurve.hlcompr, pedited->toneCurve.hlcompr); + assignFromKeyfile(keyFile, "Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh, pedited->toneCurve.hlcomprthresh); + assignFromKeyfile(keyFile, "Exposure", "ShadowCompr", toneCurve.shcompr, pedited->toneCurve.shcompr); if (toneCurve.shcompr > 100) { toneCurve.shcompr = 100; // older pp3 files can have values above 100. @@ -7912,36 +7912,36 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) {"Perceptual", ToneCurveMode::PERCEPTUAL} }; - assignFromKeyfile(keyFile, "Exposure", "CurveMode", pedited, tc_mapping, toneCurve.curveMode, pedited->toneCurve.curveMode); - assignFromKeyfile(keyFile, "Exposure", "CurveMode2", pedited, tc_mapping, toneCurve.curveMode2, pedited->toneCurve.curveMode2); + assignFromKeyfile(keyFile, "Exposure", "CurveMode", tc_mapping, toneCurve.curveMode, pedited->toneCurve.curveMode); + assignFromKeyfile(keyFile, "Exposure", "CurveMode2", tc_mapping, toneCurve.curveMode2, pedited->toneCurve.curveMode2); if (ppVersion > 200) { - assignFromKeyfile(keyFile, "Exposure", "Curve", pedited, toneCurve.curve, pedited->toneCurve.curve); - assignFromKeyfile(keyFile, "Exposure", "Curve2", pedited, toneCurve.curve2, pedited->toneCurve.curve2); + assignFromKeyfile(keyFile, "Exposure", "Curve", toneCurve.curve, pedited->toneCurve.curve); + assignFromKeyfile(keyFile, "Exposure", "Curve2", toneCurve.curve2, pedited->toneCurve.curve2); } - assignFromKeyfile(keyFile, "Exposure", "HistogramMatching", pedited, toneCurve.histmatching, pedited->toneCurve.histmatching); + assignFromKeyfile(keyFile, "Exposure", "HistogramMatching", toneCurve.histmatching, pedited->toneCurve.histmatching); if (ppVersion < 340) { toneCurve.fromHistMatching = false; if (pedited) { pedited->toneCurve.fromHistMatching = true; } } else { - assignFromKeyfile(keyFile, "Exposure", "CurveFromHistogramMatching", pedited, toneCurve.fromHistMatching, pedited->toneCurve.fromHistMatching); + assignFromKeyfile(keyFile, "Exposure", "CurveFromHistogramMatching", toneCurve.fromHistMatching, pedited->toneCurve.fromHistMatching); } - assignFromKeyfile(keyFile, "Exposure", "ClampOOG", pedited, toneCurve.clampOOG, pedited->toneCurve.clampOOG); + assignFromKeyfile(keyFile, "Exposure", "ClampOOG", toneCurve.clampOOG, pedited->toneCurve.clampOOG); } if (keyFile.has_group("HLRecovery")) { - assignFromKeyfile(keyFile, "HLRecovery", "Enabled", pedited, toneCurve.hrenabled, pedited->toneCurve.hrenabled); - assignFromKeyfile(keyFile, "HLRecovery", "Method", pedited, toneCurve.method, pedited->toneCurve.method); - assignFromKeyfile(keyFile, "HLRecovery", "Hlbl", pedited, toneCurve.hlbl, pedited->toneCurve.hlbl); - assignFromKeyfile(keyFile, "HLRecovery", "Hlth", pedited, toneCurve.hlth, pedited->toneCurve.hlth); + assignFromKeyfile(keyFile, "HLRecovery", "Enabled", toneCurve.hrenabled, pedited->toneCurve.hrenabled); + assignFromKeyfile(keyFile, "HLRecovery", "Method", toneCurve.method, pedited->toneCurve.method); + assignFromKeyfile(keyFile, "HLRecovery", "Hlbl", toneCurve.hlbl, pedited->toneCurve.hlbl); + assignFromKeyfile(keyFile, "HLRecovery", "Hlth", toneCurve.hlth, pedited->toneCurve.hlth); } if (keyFile.has_group("Channel Mixer")) { if (ppVersion >= 329) { - assignFromKeyfile(keyFile, "Channel Mixer", "Enabled", pedited, chmixer.enabled, pedited->chmixer.enabled); + assignFromKeyfile(keyFile, "Channel Mixer", "Enabled", chmixer.enabled, pedited->chmixer.enabled); } else { chmixer.enabled = true; @@ -7977,33 +7977,32 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Black & White")) { - assignFromKeyfile(keyFile, "Black & White", "Enabled", pedited, blackwhite.enabled, pedited->blackwhite.enabled); - assignFromKeyfile(keyFile, "Black & White", "Method", pedited, blackwhite.method, pedited->blackwhite.method); - assignFromKeyfile(keyFile, "Black & White", "Auto", pedited, blackwhite.autoc, pedited->blackwhite.autoc); - assignFromKeyfile(keyFile, "Black & White", "ComplementaryColors", pedited, blackwhite.enabledcc, pedited->blackwhite.enabledcc); - assignFromKeyfile(keyFile, "Black & White", "MixerRed", pedited, blackwhite.mixerRed, pedited->blackwhite.mixerRed); - assignFromKeyfile(keyFile, "Black & White", "MixerOrange", pedited, blackwhite.mixerOrange, pedited->blackwhite.mixerOrange); - assignFromKeyfile(keyFile, "Black & White", "MixerYellow", pedited, blackwhite.mixerYellow, pedited->blackwhite.mixerYellow); - assignFromKeyfile(keyFile, "Black & White", "MixerGreen", pedited, blackwhite.mixerGreen, pedited->blackwhite.mixerGreen); - assignFromKeyfile(keyFile, "Black & White", "MixerCyan", pedited, blackwhite.mixerCyan, pedited->blackwhite.mixerCyan); - assignFromKeyfile(keyFile, "Black & White", "MixerBlue", pedited, blackwhite.mixerBlue, pedited->blackwhite.mixerBlue); - assignFromKeyfile(keyFile, "Black & White", "MixerMagenta", pedited, blackwhite.mixerMagenta, pedited->blackwhite.mixerMagenta); - assignFromKeyfile(keyFile, "Black & White", "MixerPurple", pedited, blackwhite.mixerPurple, pedited->blackwhite.mixerPurple); - assignFromKeyfile(keyFile, "Black & White", "GammaRed", pedited, blackwhite.gammaRed, pedited->blackwhite.gammaRed); - assignFromKeyfile(keyFile, "Black & White", "GammaGreen", pedited, blackwhite.gammaGreen, pedited->blackwhite.gammaGreen); - assignFromKeyfile(keyFile, "Black & White", "GammaBlue", pedited, blackwhite.gammaBlue, pedited->blackwhite.gammaBlue); - assignFromKeyfile(keyFile, "Black & White", "Filter", pedited, blackwhite.filter, pedited->blackwhite.filter); - assignFromKeyfile(keyFile, "Black & White", "Setting", pedited, blackwhite.setting, pedited->blackwhite.setting); - assignFromKeyfile(keyFile, "Black & White", "LuminanceCurve", pedited, blackwhite.luminanceCurve, pedited->blackwhite.luminanceCurve); + assignFromKeyfile(keyFile, "Black & White", "Enabled", blackwhite.enabled, pedited->blackwhite.enabled); + assignFromKeyfile(keyFile, "Black & White", "Method", blackwhite.method, pedited->blackwhite.method); + assignFromKeyfile(keyFile, "Black & White", "Auto", blackwhite.autoc, pedited->blackwhite.autoc); + assignFromKeyfile(keyFile, "Black & White", "ComplementaryColors", blackwhite.enabledcc, pedited->blackwhite.enabledcc); + assignFromKeyfile(keyFile, "Black & White", "MixerRed", blackwhite.mixerRed, pedited->blackwhite.mixerRed); + assignFromKeyfile(keyFile, "Black & White", "MixerOrange", blackwhite.mixerOrange, pedited->blackwhite.mixerOrange); + assignFromKeyfile(keyFile, "Black & White", "MixerYellow", blackwhite.mixerYellow, pedited->blackwhite.mixerYellow); + assignFromKeyfile(keyFile, "Black & White", "MixerGreen", blackwhite.mixerGreen, pedited->blackwhite.mixerGreen); + assignFromKeyfile(keyFile, "Black & White", "MixerCyan", blackwhite.mixerCyan, pedited->blackwhite.mixerCyan); + assignFromKeyfile(keyFile, "Black & White", "MixerBlue", blackwhite.mixerBlue, pedited->blackwhite.mixerBlue); + assignFromKeyfile(keyFile, "Black & White", "MixerMagenta", blackwhite.mixerMagenta, pedited->blackwhite.mixerMagenta); + assignFromKeyfile(keyFile, "Black & White", "MixerPurple", blackwhite.mixerPurple, pedited->blackwhite.mixerPurple); + assignFromKeyfile(keyFile, "Black & White", "GammaRed", blackwhite.gammaRed, pedited->blackwhite.gammaRed); + assignFromKeyfile(keyFile, "Black & White", "GammaGreen", blackwhite.gammaGreen, pedited->blackwhite.gammaGreen); + assignFromKeyfile(keyFile, "Black & White", "GammaBlue", blackwhite.gammaBlue, pedited->blackwhite.gammaBlue); + assignFromKeyfile(keyFile, "Black & White", "Filter", blackwhite.filter, pedited->blackwhite.filter); + assignFromKeyfile(keyFile, "Black & White", "Setting", blackwhite.setting, pedited->blackwhite.setting); + assignFromKeyfile(keyFile, "Black & White", "LuminanceCurve", blackwhite.luminanceCurve, pedited->blackwhite.luminanceCurve); - assignFromKeyfile(keyFile, "Black & White", "BeforeCurve", pedited, blackwhite.beforeCurve, pedited->blackwhite.beforeCurve); + assignFromKeyfile(keyFile, "Black & White", "BeforeCurve", blackwhite.beforeCurve, pedited->blackwhite.beforeCurve); - assignFromKeyfile(keyFile, "Black & White", "Algorithm", pedited, blackwhite.algo, pedited->blackwhite.algo); + assignFromKeyfile(keyFile, "Black & White", "Algorithm", blackwhite.algo, pedited->blackwhite.algo); assignFromKeyfile( keyFile, "Black & White", "BeforeCurveMode", - pedited, { {"Standard", BlackWhiteParams::TcMode::STD_BW}, {"FilmLike", BlackWhiteParams::TcMode::FILMLIKE_BW}, @@ -8014,12 +8013,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->blackwhite.beforeCurveMode ); - assignFromKeyfile(keyFile, "Black & White", "AfterCurve", pedited, blackwhite.afterCurve, pedited->blackwhite.afterCurve); + assignFromKeyfile(keyFile, "Black & White", "AfterCurve", blackwhite.afterCurve, pedited->blackwhite.afterCurve); assignFromKeyfile( keyFile, "Black & White", "AfterCurveMode", - pedited, { {"Standard", BlackWhiteParams::TcMode::STD_BW}, {"WeightedStd", BlackWhiteParams::TcMode::WEIGHTEDSTD_BW} @@ -8030,10 +8028,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Retinex")) { - assignFromKeyfile(keyFile, "Retinex", "Median", pedited, retinex.medianmap, pedited->retinex.medianmap); + assignFromKeyfile(keyFile, "Retinex", "Median", retinex.medianmap, pedited->retinex.medianmap); if (keyFile.has_key("Retinex", "complexMethod")) { - assignFromKeyfile(keyFile, "Retinex", "complexMethod", pedited, retinex.complexmethod, pedited->retinex.complexmethod); + assignFromKeyfile(keyFile, "Retinex", "complexMethod", retinex.complexmethod, pedited->retinex.complexmethod); } else if (retinex.enabled) { retinex.complexmethod = "expert"; if (pedited) { @@ -8041,57 +8039,57 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Retinex", "RetinexMethod", pedited, retinex.retinexMethod, pedited->retinex.retinexMethod); - assignFromKeyfile(keyFile, "Retinex", "mapMethod", pedited, retinex.mapMethod, pedited->retinex.mapMethod); - assignFromKeyfile(keyFile, "Retinex", "viewMethod", pedited, retinex.viewMethod, pedited->retinex.viewMethod); + assignFromKeyfile(keyFile, "Retinex", "RetinexMethod", retinex.retinexMethod, pedited->retinex.retinexMethod); + assignFromKeyfile(keyFile, "Retinex", "mapMethod", retinex.mapMethod, pedited->retinex.mapMethod); + assignFromKeyfile(keyFile, "Retinex", "viewMethod", retinex.viewMethod, pedited->retinex.viewMethod); - assignFromKeyfile(keyFile, "Retinex", "Retinexcolorspace", pedited, retinex.retinexcolorspace, pedited->retinex.retinexcolorspace); - assignFromKeyfile(keyFile, "Retinex", "Gammaretinex", pedited, retinex.gammaretinex, pedited->retinex.gammaretinex); - assignFromKeyfile(keyFile, "Retinex", "Enabled", pedited, retinex.enabled, pedited->retinex.enabled); - assignFromKeyfile(keyFile, "Retinex", "Neigh", pedited, retinex.neigh, pedited->retinex.neigh); - assignFromKeyfile(keyFile, "Retinex", "Str", pedited, retinex.str, pedited->retinex.str); - assignFromKeyfile(keyFile, "Retinex", "Scal", pedited, retinex.scal, pedited->retinex.scal); - assignFromKeyfile(keyFile, "Retinex", "Iter", pedited, retinex.iter, pedited->retinex.iter); - assignFromKeyfile(keyFile, "Retinex", "Grad", pedited, retinex.grad, pedited->retinex.grad); - assignFromKeyfile(keyFile, "Retinex", "Grads", pedited, retinex.grads, pedited->retinex.grads); - assignFromKeyfile(keyFile, "Retinex", "Gam", pedited, retinex.gam, pedited->retinex.gam); - assignFromKeyfile(keyFile, "Retinex", "Slope", pedited, retinex.slope, pedited->retinex.slope); - assignFromKeyfile(keyFile, "Retinex", "Offs", pedited, retinex.offs, pedited->retinex.offs); - assignFromKeyfile(keyFile, "Retinex", "Vart", pedited, retinex.vart, pedited->retinex.vart); - assignFromKeyfile(keyFile, "Retinex", "Limd", pedited, retinex.limd, pedited->retinex.limd); - assignFromKeyfile(keyFile, "Retinex", "highl", pedited, retinex.highl, pedited->retinex.highl); - assignFromKeyfile(keyFile, "Retinex", "skal", pedited, retinex.skal, pedited->retinex.skal); - assignFromKeyfile(keyFile, "Retinex", "CDCurve", pedited, retinex.cdcurve, pedited->retinex.cdcurve); + assignFromKeyfile(keyFile, "Retinex", "Retinexcolorspace", retinex.retinexcolorspace, pedited->retinex.retinexcolorspace); + assignFromKeyfile(keyFile, "Retinex", "Gammaretinex", retinex.gammaretinex, pedited->retinex.gammaretinex); + assignFromKeyfile(keyFile, "Retinex", "Enabled", retinex.enabled, pedited->retinex.enabled); + assignFromKeyfile(keyFile, "Retinex", "Neigh", retinex.neigh, pedited->retinex.neigh); + assignFromKeyfile(keyFile, "Retinex", "Str", retinex.str, pedited->retinex.str); + assignFromKeyfile(keyFile, "Retinex", "Scal", retinex.scal, pedited->retinex.scal); + assignFromKeyfile(keyFile, "Retinex", "Iter", retinex.iter, pedited->retinex.iter); + assignFromKeyfile(keyFile, "Retinex", "Grad", retinex.grad, pedited->retinex.grad); + assignFromKeyfile(keyFile, "Retinex", "Grads", retinex.grads, pedited->retinex.grads); + assignFromKeyfile(keyFile, "Retinex", "Gam", retinex.gam, pedited->retinex.gam); + assignFromKeyfile(keyFile, "Retinex", "Slope", retinex.slope, pedited->retinex.slope); + assignFromKeyfile(keyFile, "Retinex", "Offs", retinex.offs, pedited->retinex.offs); + assignFromKeyfile(keyFile, "Retinex", "Vart", retinex.vart, pedited->retinex.vart); + assignFromKeyfile(keyFile, "Retinex", "Limd", retinex.limd, pedited->retinex.limd); + assignFromKeyfile(keyFile, "Retinex", "highl", retinex.highl, pedited->retinex.highl); + assignFromKeyfile(keyFile, "Retinex", "skal", retinex.skal, pedited->retinex.skal); + assignFromKeyfile(keyFile, "Retinex", "CDCurve", retinex.cdcurve, pedited->retinex.cdcurve); - assignFromKeyfile(keyFile, "Retinex", "MAPCurve", pedited, retinex.mapcurve, pedited->retinex.mapcurve); + assignFromKeyfile(keyFile, "Retinex", "MAPCurve", retinex.mapcurve, pedited->retinex.mapcurve); - assignFromKeyfile(keyFile, "Retinex", "CDHCurve", pedited, retinex.cdHcurve, pedited->retinex.cdHcurve); + assignFromKeyfile(keyFile, "Retinex", "CDHCurve", retinex.cdHcurve, pedited->retinex.cdHcurve); - assignFromKeyfile(keyFile, "Retinex", "LHCurve", pedited, retinex.lhcurve, pedited->retinex.lhcurve); + assignFromKeyfile(keyFile, "Retinex", "LHCurve", retinex.lhcurve, pedited->retinex.lhcurve); - assignFromKeyfile(keyFile, "Retinex", "Highlights", pedited, retinex.highlights, pedited->retinex.highlights); - assignFromKeyfile(keyFile, "Retinex", "HighlightTonalWidth", pedited, retinex.htonalwidth, pedited->retinex.htonalwidth); - assignFromKeyfile(keyFile, "Retinex", "Shadows", pedited, retinex.shadows, pedited->retinex.shadows); - assignFromKeyfile(keyFile, "Retinex", "ShadowTonalWidth", pedited, retinex.stonalwidth, pedited->retinex.stonalwidth); + assignFromKeyfile(keyFile, "Retinex", "Highlights", retinex.highlights, pedited->retinex.highlights); + assignFromKeyfile(keyFile, "Retinex", "HighlightTonalWidth", retinex.htonalwidth, pedited->retinex.htonalwidth); + assignFromKeyfile(keyFile, "Retinex", "Shadows", retinex.shadows, pedited->retinex.shadows); + assignFromKeyfile(keyFile, "Retinex", "ShadowTonalWidth", retinex.stonalwidth, pedited->retinex.stonalwidth); - assignFromKeyfile(keyFile, "Retinex", "Radius", pedited, retinex.radius, pedited->retinex.radius); + assignFromKeyfile(keyFile, "Retinex", "Radius", retinex.radius, pedited->retinex.radius); - assignFromKeyfile(keyFile, "Retinex", "TransmissionCurve", pedited, retinex.transmissionCurve, pedited->retinex.transmissionCurve); + assignFromKeyfile(keyFile, "Retinex", "TransmissionCurve", retinex.transmissionCurve, pedited->retinex.transmissionCurve); - assignFromKeyfile(keyFile, "Retinex", "GainTransmissionCurve", pedited, retinex.gaintransmissionCurve, pedited->retinex.gaintransmissionCurve); + assignFromKeyfile(keyFile, "Retinex", "GainTransmissionCurve", retinex.gaintransmissionCurve, pedited->retinex.gaintransmissionCurve); } if (keyFile.has_group("Local Contrast")) { - assignFromKeyfile(keyFile, "Local Contrast", "Enabled", pedited, localContrast.enabled, pedited->localContrast.enabled); - assignFromKeyfile(keyFile, "Local Contrast", "Radius", pedited, localContrast.radius, pedited->localContrast.radius); - assignFromKeyfile(keyFile, "Local Contrast", "Amount", pedited, localContrast.amount, pedited->localContrast.amount); - assignFromKeyfile(keyFile, "Local Contrast", "Darkness", pedited, localContrast.darkness, pedited->localContrast.darkness); - assignFromKeyfile(keyFile, "Local Contrast", "Lightness", pedited, localContrast.lightness, pedited->localContrast.lightness); + assignFromKeyfile(keyFile, "Local Contrast", "Enabled", localContrast.enabled, pedited->localContrast.enabled); + assignFromKeyfile(keyFile, "Local Contrast", "Radius", localContrast.radius, pedited->localContrast.radius); + assignFromKeyfile(keyFile, "Local Contrast", "Amount", localContrast.amount, pedited->localContrast.amount); + assignFromKeyfile(keyFile, "Local Contrast", "Darkness", localContrast.darkness, pedited->localContrast.darkness); + assignFromKeyfile(keyFile, "Local Contrast", "Lightness", localContrast.lightness, pedited->localContrast.lightness); } if (keyFile.has_group("Luminance Curve")) { if (ppVersion >= 329) { - assignFromKeyfile(keyFile, "Luminance Curve", "Enabled", pedited, labCurve.enabled, pedited->labCurve.enabled); + assignFromKeyfile(keyFile, "Luminance Curve", "Enabled", labCurve.enabled, pedited->labCurve.enabled); } else { labCurve.enabled = true; @@ -8100,15 +8098,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Luminance Curve", "Brightness", pedited, labCurve.brightness, pedited->labCurve.brightness); - assignFromKeyfile(keyFile, "Luminance Curve", "Contrast", pedited, labCurve.contrast, pedited->labCurve.contrast); + assignFromKeyfile(keyFile, "Luminance Curve", "Brightness", labCurve.brightness, pedited->labCurve.brightness); + assignFromKeyfile(keyFile, "Luminance Curve", "Contrast", labCurve.contrast, pedited->labCurve.contrast); if (ppVersion < 303) { // transform Saturation into Chromaticity // if Saturation == 0, should we set BWToning on? - assignFromKeyfile(keyFile, "Luminance Curve", "Saturation", pedited, labCurve.chromaticity, pedited->labCurve.chromaticity); + assignFromKeyfile(keyFile, "Luminance Curve", "Saturation", labCurve.chromaticity, pedited->labCurve.chromaticity); // transform AvoidColorClipping into AvoidColorShift -// assignFromKeyfile(keyFile, "Luminance Curve", "AvoidColorClipping", pedited, labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift); +// assignFromKeyfile(keyFile, "Luminance Curve", "AvoidColorClipping", labCurve.avoidcolorshift, pedited->labCurve.avoidcolorshift); } else { if (keyFile.has_key("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer("Luminance Curve", "Chromaticity"); @@ -8122,10 +8120,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Luminance Curve", "RedAndSkinTonesProtection", pedited, labCurve.rstprotection, pedited->labCurve.rstprotection); + assignFromKeyfile(keyFile, "Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection, pedited->labCurve.rstprotection); } - assignFromKeyfile(keyFile, "Luminance Curve", "LCredsk", pedited, labCurve.lcredsk, pedited->labCurve.lcredsk); + assignFromKeyfile(keyFile, "Luminance Curve", "LCredsk", labCurve.lcredsk, pedited->labCurve.lcredsk); if (ppVersion < 314) { // Backward compatibility: If BWtoning is true, Chromaticity has to be set to -100, which will produce the same effect @@ -8141,17 +8139,17 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Luminance Curve", "LCurve", pedited, labCurve.lcurve, pedited->labCurve.lcurve); - assignFromKeyfile(keyFile, "Luminance Curve", "aCurve", pedited, labCurve.acurve, pedited->labCurve.acurve); - assignFromKeyfile(keyFile, "Luminance Curve", "bCurve", pedited, labCurve.bcurve, pedited->labCurve.bcurve); - assignFromKeyfile(keyFile, "Luminance Curve", "ccCurve", pedited, labCurve.cccurve, pedited->labCurve.cccurve); - assignFromKeyfile(keyFile, "Luminance Curve", "chCurve", pedited, labCurve.chcurve, pedited->labCurve.chcurve); - assignFromKeyfile(keyFile, "Luminance Curve", "lhCurve", pedited, labCurve.lhcurve, pedited->labCurve.lhcurve); - assignFromKeyfile(keyFile, "Luminance Curve", "hhCurve", pedited, labCurve.hhcurve, pedited->labCurve.hhcurve); - assignFromKeyfile(keyFile, "Luminance Curve", "LcCurve", pedited, labCurve.lccurve, pedited->labCurve.lccurve); - assignFromKeyfile(keyFile, "Luminance Curve", "ClCurve", pedited, labCurve.clcurve, pedited->labCurve.clcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "LCurve", labCurve.lcurve, pedited->labCurve.lcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "aCurve", labCurve.acurve, pedited->labCurve.acurve); + assignFromKeyfile(keyFile, "Luminance Curve", "bCurve", labCurve.bcurve, pedited->labCurve.bcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "ccCurve", labCurve.cccurve, pedited->labCurve.cccurve); + assignFromKeyfile(keyFile, "Luminance Curve", "chCurve", labCurve.chcurve, pedited->labCurve.chcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "lhCurve", labCurve.lhcurve, pedited->labCurve.lhcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "hhCurve", labCurve.hhcurve, pedited->labCurve.hhcurve); + assignFromKeyfile(keyFile, "Luminance Curve", "LcCurve", labCurve.lccurve, pedited->labCurve.lccurve); + assignFromKeyfile(keyFile, "Luminance Curve", "ClCurve", labCurve.clcurve, pedited->labCurve.clcurve); if (keyFile.has_key("Luminance Curve", "Gamutmunse")) { - assignFromKeyfile(keyFile, "Luminance Curve", "Gamutmunse", pedited, labCurve.gamutmunselmethod, pedited->labCurve.gamutmunselmethod); + assignFromKeyfile(keyFile, "Luminance Curve", "Gamutmunse", labCurve.gamutmunselmethod, pedited->labCurve.gamutmunselmethod); } else { if (ppVersion < 303) { if (keyFile.has_key("Luminance Curve", "AvoidColorClipping")) { @@ -8172,10 +8170,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Sharpening")) { - assignFromKeyfile(keyFile, "Sharpening", "Enabled", pedited, sharpening.enabled, pedited->sharpening.enabled); + assignFromKeyfile(keyFile, "Sharpening", "Enabled", sharpening.enabled, pedited->sharpening.enabled); if (ppVersion >= 334) { - assignFromKeyfile(keyFile, "Sharpening", "Contrast", pedited, sharpening.contrast, pedited->sharpening.contrast); + assignFromKeyfile(keyFile, "Sharpening", "Contrast", sharpening.contrast, pedited->sharpening.contrast); } else { sharpening.contrast = 0; @@ -8184,9 +8182,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Sharpening", "Radius", pedited, sharpening.radius, pedited->sharpening.radius); - assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", pedited, sharpening.blurradius, pedited->sharpening.blurradius); - assignFromKeyfile(keyFile, "Sharpening", "Amount", pedited, sharpening.amount, pedited->sharpening.amount); + assignFromKeyfile(keyFile, "Sharpening", "Radius", sharpening.radius, pedited->sharpening.radius); + assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", sharpening.blurradius, pedited->sharpening.blurradius); + assignFromKeyfile(keyFile, "Sharpening", "Amount", sharpening.amount, pedited->sharpening.amount); if (keyFile.has_key("Sharpening", "Threshold")) { if (ppVersion < 302) { @@ -8205,32 +8203,32 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Sharpening", "OnlyEdges", pedited, sharpening.edgesonly, pedited->sharpening.edgesonly); - assignFromKeyfile(keyFile, "Sharpening", "EdgedetectionRadius", pedited, sharpening.edges_radius, pedited->sharpening.edges_radius); - assignFromKeyfile(keyFile, "Sharpening", "EdgeTolerance", pedited, sharpening.edges_tolerance, pedited->sharpening.edges_tolerance); - assignFromKeyfile(keyFile, "Sharpening", "HalocontrolEnabled", pedited, sharpening.halocontrol, pedited->sharpening.halocontrol); - assignFromKeyfile(keyFile, "Sharpening", "HalocontrolAmount", pedited, sharpening.halocontrol_amount, pedited->sharpening.halocontrol_amount); - assignFromKeyfile(keyFile, "Sharpening", "Method", pedited, sharpening.method, pedited->sharpening.method); - assignFromKeyfile(keyFile, "Sharpening", "DeconvRadius", pedited, sharpening.deconvradius, pedited->sharpening.deconvradius); - assignFromKeyfile(keyFile, "Sharpening", "DeconvAmount", pedited, sharpening.deconvamount, pedited->sharpening.deconvamount); - assignFromKeyfile(keyFile, "Sharpening", "DeconvDamping", pedited, sharpening.deconvdamping, pedited->sharpening.deconvdamping); - assignFromKeyfile(keyFile, "Sharpening", "DeconvIterations", pedited, sharpening.deconviter, pedited->sharpening.deconviter); + assignFromKeyfile(keyFile, "Sharpening", "OnlyEdges", sharpening.edgesonly, pedited->sharpening.edgesonly); + assignFromKeyfile(keyFile, "Sharpening", "EdgedetectionRadius", sharpening.edges_radius, pedited->sharpening.edges_radius); + assignFromKeyfile(keyFile, "Sharpening", "EdgeTolerance", sharpening.edges_tolerance, pedited->sharpening.edges_tolerance); + assignFromKeyfile(keyFile, "Sharpening", "HalocontrolEnabled", sharpening.halocontrol, pedited->sharpening.halocontrol); + assignFromKeyfile(keyFile, "Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount, pedited->sharpening.halocontrol_amount); + assignFromKeyfile(keyFile, "Sharpening", "Method", sharpening.method, pedited->sharpening.method); + assignFromKeyfile(keyFile, "Sharpening", "DeconvRadius", sharpening.deconvradius, pedited->sharpening.deconvradius); + assignFromKeyfile(keyFile, "Sharpening", "DeconvAmount", sharpening.deconvamount, pedited->sharpening.deconvamount); + assignFromKeyfile(keyFile, "Sharpening", "DeconvDamping", sharpening.deconvdamping, pedited->sharpening.deconvdamping); + assignFromKeyfile(keyFile, "Sharpening", "DeconvIterations", sharpening.deconviter, pedited->sharpening.deconviter); } if (keyFile.has_group("SharpenEdge")) { - assignFromKeyfile(keyFile, "SharpenEdge", "Enabled", pedited, sharpenEdge.enabled, pedited->sharpenEdge.enabled); - assignFromKeyfile(keyFile, "SharpenEdge", "Passes", pedited, sharpenEdge.passes, pedited->sharpenEdge.passes); - assignFromKeyfile(keyFile, "SharpenEdge", "Strength", pedited, sharpenEdge.amount, pedited->sharpenEdge.amount); - assignFromKeyfile(keyFile, "SharpenEdge", "ThreeChannels", pedited, sharpenEdge.threechannels, pedited->sharpenEdge.threechannels); + assignFromKeyfile(keyFile, "SharpenEdge", "Enabled", sharpenEdge.enabled, pedited->sharpenEdge.enabled); + assignFromKeyfile(keyFile, "SharpenEdge", "Passes", sharpenEdge.passes, pedited->sharpenEdge.passes); + assignFromKeyfile(keyFile, "SharpenEdge", "Strength", sharpenEdge.amount, pedited->sharpenEdge.amount); + assignFromKeyfile(keyFile, "SharpenEdge", "ThreeChannels", sharpenEdge.threechannels, pedited->sharpenEdge.threechannels); } if (keyFile.has_group("SharpenMicro")) { - assignFromKeyfile(keyFile, "SharpenMicro", "Enabled", pedited, sharpenMicro.enabled, pedited->sharpenMicro.enabled); - assignFromKeyfile(keyFile, "SharpenMicro", "Matrix", pedited, sharpenMicro.matrix, pedited->sharpenMicro.matrix); - assignFromKeyfile(keyFile, "SharpenMicro", "Strength", pedited, sharpenMicro.amount, pedited->sharpenMicro.amount); + assignFromKeyfile(keyFile, "SharpenMicro", "Enabled", sharpenMicro.enabled, pedited->sharpenMicro.enabled); + assignFromKeyfile(keyFile, "SharpenMicro", "Matrix", sharpenMicro.matrix, pedited->sharpenMicro.matrix); + assignFromKeyfile(keyFile, "SharpenMicro", "Strength", sharpenMicro.amount, pedited->sharpenMicro.amount); if (ppVersion >= 334) { - assignFromKeyfile(keyFile, "SharpenMicro", "Contrast", pedited, sharpenMicro.contrast, pedited->sharpenMicro.contrast); + assignFromKeyfile(keyFile, "SharpenMicro", "Contrast", sharpenMicro.contrast, pedited->sharpenMicro.contrast); } else { sharpenMicro.contrast = 0; @@ -8239,18 +8237,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } if (ppVersion >= 346) { - assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", pedited, sharpenMicro.uniformity, pedited->sharpenMicro.uniformity); + assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", sharpenMicro.uniformity, pedited->sharpenMicro.uniformity); } else { double temp = 50.0; - assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", pedited, temp, pedited->sharpenMicro.uniformity); + assignFromKeyfile(keyFile, "SharpenMicro", "Uniformity", temp, pedited->sharpenMicro.uniformity); sharpenMicro.uniformity = temp / 10; } } if (keyFile.has_group("Vibrance")) { - assignFromKeyfile(keyFile, "Vibrance", "Enabled", pedited, vibrance.enabled, pedited->vibrance.enabled); - assignFromKeyfile(keyFile, "Vibrance", "Pastels", pedited, vibrance.pastels, pedited->vibrance.pastels); - assignFromKeyfile(keyFile, "Vibrance", "Saturated", pedited, vibrance.saturated, pedited->vibrance.saturated); + assignFromKeyfile(keyFile, "Vibrance", "Enabled", vibrance.enabled, pedited->vibrance.enabled); + assignFromKeyfile(keyFile, "Vibrance", "Pastels", vibrance.pastels, pedited->vibrance.pastels); + assignFromKeyfile(keyFile, "Vibrance", "Saturated", vibrance.saturated, pedited->vibrance.saturated); if (keyFile.has_key("Vibrance", "PSThreshold")) { if (ppVersion < 302) { @@ -8269,10 +8267,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Vibrance", "ProtectSkins", pedited, vibrance.protectskins, pedited->vibrance.protectskins); - assignFromKeyfile(keyFile, "Vibrance", "AvoidColorShift", pedited, vibrance.avoidcolorshift, pedited->vibrance.avoidcolorshift); - assignFromKeyfile(keyFile, "Vibrance", "PastSatTog", pedited, vibrance.pastsattog, pedited->vibrance.pastsattog); - assignFromKeyfile(keyFile, "Vibrance", "SkinTonesCurve", pedited, vibrance.skintonescurve, pedited->vibrance.skintonescurve); + assignFromKeyfile(keyFile, "Vibrance", "ProtectSkins", vibrance.protectskins, pedited->vibrance.protectskins); + assignFromKeyfile(keyFile, "Vibrance", "AvoidColorShift", vibrance.avoidcolorshift, pedited->vibrance.avoidcolorshift); + assignFromKeyfile(keyFile, "Vibrance", "PastSatTog", vibrance.pastsattog, pedited->vibrance.pastsattog); + assignFromKeyfile(keyFile, "Vibrance", "SkinTonesCurve", vibrance.skintonescurve, pedited->vibrance.skintonescurve); } if (ppVersion <= 346) { // 5.8 and earlier. wb.observer = StandardObserver::TWO_DEGREES; @@ -8286,39 +8284,39 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } if (keyFile.has_group("White Balance")) { - assignFromKeyfile(keyFile, "White Balance", "Enabled", pedited, wb.enabled, pedited->wb.enabled); - assignFromKeyfile(keyFile, "White Balance", "Setting", pedited, wb.method, pedited->wb.method); + assignFromKeyfile(keyFile, "White Balance", "Enabled", wb.enabled, pedited->wb.enabled); + assignFromKeyfile(keyFile, "White Balance", "Setting", wb.method, pedited->wb.method); if (wb.method == "Auto") { wb.method = "autold"; } - assignFromKeyfile(keyFile, "White Balance", "Temperature", pedited, wb.temperature, pedited->wb.temperature); - assignFromKeyfile(keyFile, "White Balance", "Green", pedited, wb.green, pedited->wb.green); - assignFromKeyfile(keyFile, "White Balance", "Equal", pedited, wb.equal, pedited->wb.equal); - assignFromKeyfile(keyFile, "White Balance", "TemperatureBias", pedited, wb.tempBias, pedited->wb.tempBias); + assignFromKeyfile(keyFile, "White Balance", "Temperature", wb.temperature, pedited->wb.temperature); + assignFromKeyfile(keyFile, "White Balance", "Green", wb.green, pedited->wb.green); + assignFromKeyfile(keyFile, "White Balance", "Equal", wb.equal, pedited->wb.equal); + assignFromKeyfile(keyFile, "White Balance", "TemperatureBias", wb.tempBias, pedited->wb.tempBias); Glib::ustring standard_observer; - assignFromKeyfile(keyFile, "White Balance", "StandardObserver", pedited, standard_observer, pedited->wb.observer); + assignFromKeyfile(keyFile, "White Balance", "StandardObserver", standard_observer, pedited->wb.observer); if (standard_observer == "TEN_DEGREES") { wb.observer = StandardObserver::TEN_DEGREES; } else if (standard_observer == "TWO_DEGREES") { wb.observer = StandardObserver::TWO_DEGREES; } - assignFromKeyfile(keyFile, "White Balance", "Itcwb_green", pedited, wb.itcwb_green, pedited->wb.itcwb_green); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_rangegreen", pedited, wb.itcwb_rgreen, pedited->wb.itcwb_rgreen); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_nopurple", pedited, wb.itcwb_nopurple, pedited->wb.itcwb_nopurple); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_alg", pedited, wb.itcwb_alg, pedited->wb.itcwb_alg); - assignFromKeyfile(keyFile, "White Balance", "Itcwb_prim", pedited, wb.itcwb_prim, pedited->wb.itcwb_prim); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_green", wb.itcwb_green, pedited->wb.itcwb_green); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_rangegreen", wb.itcwb_rgreen, pedited->wb.itcwb_rgreen); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_nopurple", wb.itcwb_nopurple, pedited->wb.itcwb_nopurple); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_alg", wb.itcwb_alg, pedited->wb.itcwb_alg); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_prim", wb.itcwb_prim, pedited->wb.itcwb_prim); if (ppVersion <= 349) { // 5.9 and earlier. wb.itcwb_sampling = true; if (pedited) { pedited->wb.itcwb_sampling = true; } } - assignFromKeyfile(keyFile, "White Balance", "Itcwb_sampling", pedited, wb.itcwb_sampling, pedited->wb.itcwb_sampling); + assignFromKeyfile(keyFile, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, pedited->wb.itcwb_sampling); } if (keyFile.has_group("Defringing")) { - assignFromKeyfile(keyFile, "Defringing", "Enabled", pedited, defringe.enabled, pedited->defringe.enabled); - assignFromKeyfile(keyFile, "Defringing", "Radius", pedited, defringe.radius, pedited->defringe.radius); + assignFromKeyfile(keyFile, "Defringing", "Enabled", defringe.enabled, pedited->defringe.enabled); + assignFromKeyfile(keyFile, "Defringing", "Radius", defringe.radius, pedited->defringe.radius); if (keyFile.has_key("Defringing", "Threshold")) { defringe.threshold = (float)keyFile.get_integer("Defringing", "Threshold"); @@ -8332,19 +8330,19 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) defringe.threshold = sqrt(defringe.threshold * 33.f / 5.f); } - assignFromKeyfile(keyFile, "Defringing", "HueCurve", pedited, defringe.huecurve, pedited->defringe.huecurve); + assignFromKeyfile(keyFile, "Defringing", "HueCurve", defringe.huecurve, pedited->defringe.huecurve); } if (keyFile.has_group("Color appearance")) { - assignFromKeyfile(keyFile, "Color appearance", "Enabled", pedited, colorappearance.enabled, pedited->colorappearance.enabled); - assignFromKeyfile(keyFile, "Color appearance", "Degree", pedited, colorappearance.degree, pedited->colorappearance.degree); - assignFromKeyfile(keyFile, "Color appearance", "AutoDegree", pedited, colorappearance.autodegree, pedited->colorappearance.autodegree); - assignFromKeyfile(keyFile, "Color appearance", "Degreeout", pedited, colorappearance.degreeout, pedited->colorappearance.degreeout); + assignFromKeyfile(keyFile, "Color appearance", "Enabled", colorappearance.enabled, pedited->colorappearance.enabled); + assignFromKeyfile(keyFile, "Color appearance", "Degree", colorappearance.degree, pedited->colorappearance.degree); + assignFromKeyfile(keyFile, "Color appearance", "AutoDegree", colorappearance.autodegree, pedited->colorappearance.autodegree); + assignFromKeyfile(keyFile, "Color appearance", "Degreeout", colorappearance.degreeout, pedited->colorappearance.degreeout); - assignFromKeyfile(keyFile, "Color appearance", "AutoDegreeout", pedited, colorappearance.autodegreeout, pedited->colorappearance.autodegreeout); + assignFromKeyfile(keyFile, "Color appearance", "AutoDegreeout", colorappearance.autodegreeout, pedited->colorappearance.autodegreeout); if (keyFile.has_key("Color appearance", "complex")) { - assignFromKeyfile(keyFile, "Color appearance", "complex", pedited, colorappearance.complexmethod, pedited->colorappearance.complexmethod); + assignFromKeyfile(keyFile, "Color appearance", "complex", colorappearance.complexmethod, pedited->colorappearance.complexmethod); } else if (colorappearance.enabled) { colorappearance.complexmethod = "expert"; if (pedited) { @@ -8353,58 +8351,57 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_key("Color appearance", "ModelCat")) { - assignFromKeyfile(keyFile, "Color appearance", "ModelCat", pedited, colorappearance.modelmethod, pedited->colorappearance.modelmethod); + assignFromKeyfile(keyFile, "Color appearance", "ModelCat", colorappearance.modelmethod, pedited->colorappearance.modelmethod); } else if (colorappearance.enabled) { colorappearance.modelmethod = "02"; if (pedited) { pedited->colorappearance.modelmethod = true; } } - assignFromKeyfile(keyFile, "Color appearance", "CatCat", pedited, colorappearance.catmethod, pedited->colorappearance.catmethod); + assignFromKeyfile(keyFile, "Color appearance", "CatCat", colorappearance.catmethod, pedited->colorappearance.catmethod); - assignFromKeyfile(keyFile, "Color appearance", "Surround", pedited, colorappearance.surround, pedited->colorappearance.surround); - assignFromKeyfile(keyFile, "Color appearance", "Surrsrc", pedited, colorappearance.surrsrc, pedited->colorappearance.surrsrc); - assignFromKeyfile(keyFile, "Color appearance", "AdaptLum", pedited, colorappearance.adaplum, pedited->colorappearance.adaplum); - assignFromKeyfile(keyFile, "Color appearance", "Badpixsl", pedited, colorappearance.badpixsl, pedited->colorappearance.badpixsl); - assignFromKeyfile(keyFile, "Color appearance", "Model", pedited, colorappearance.wbmodel, pedited->colorappearance.wbmodel); - assignFromKeyfile(keyFile, "Color appearance", "Illum", pedited, colorappearance.illum, pedited->colorappearance.illum); - assignFromKeyfile(keyFile, "Color appearance", "Algorithm", pedited, colorappearance.algo, pedited->colorappearance.algo); - assignFromKeyfile(keyFile, "Color appearance", "J-Light", pedited, colorappearance.jlight, pedited->colorappearance.jlight); - assignFromKeyfile(keyFile, "Color appearance", "Q-Bright", pedited, colorappearance.qbright, pedited->colorappearance.qbright); - assignFromKeyfile(keyFile, "Color appearance", "C-Chroma", pedited, colorappearance.chroma, pedited->colorappearance.chroma); - assignFromKeyfile(keyFile, "Color appearance", "S-Chroma", pedited, colorappearance.schroma, pedited->colorappearance.schroma); - assignFromKeyfile(keyFile, "Color appearance", "M-Chroma", pedited, colorappearance.mchroma, pedited->colorappearance.mchroma); - assignFromKeyfile(keyFile, "Color appearance", "RSTProtection", pedited, colorappearance.rstprotection, pedited->colorappearance.rstprotection); - assignFromKeyfile(keyFile, "Color appearance", "J-Contrast", pedited, colorappearance.contrast, pedited->colorappearance.contrast); - assignFromKeyfile(keyFile, "Color appearance", "Q-Contrast", pedited, colorappearance.qcontrast, pedited->colorappearance.qcontrast); - assignFromKeyfile(keyFile, "Color appearance", "H-Hue", pedited, colorappearance.colorh, pedited->colorappearance.colorh); - assignFromKeyfile(keyFile, "Color appearance", "AdaptScene", pedited, colorappearance.adapscen, pedited->colorappearance.adapscen); - assignFromKeyfile(keyFile, "Color appearance", "AutoAdapscen", pedited, colorappearance.autoadapscen, pedited->colorappearance.autoadapscen); - assignFromKeyfile(keyFile, "Color appearance", "YbScene", pedited, colorappearance.ybscen, pedited->colorappearance.ybscen); - assignFromKeyfile(keyFile, "Color appearance", "Autoybscen", pedited, colorappearance.autoybscen, pedited->colorappearance.autoybscen); - assignFromKeyfile(keyFile, "Color appearance", "SurrSource", pedited, colorappearance.surrsource, pedited->colorappearance.surrsource); - assignFromKeyfile(keyFile, "Color appearance", "Gamut", pedited, colorappearance.gamut, pedited->colorappearance.gamut); - assignFromKeyfile(keyFile, "Color appearance", "Tempout", pedited, colorappearance.tempout, pedited->colorappearance.tempout); - assignFromKeyfile(keyFile, "Color appearance", "Autotempout", pedited, colorappearance.autotempout, pedited->colorappearance.autotempout); - assignFromKeyfile(keyFile, "Color appearance", "Greenout", pedited, colorappearance.greenout, pedited->colorappearance.greenout); - assignFromKeyfile(keyFile, "Color appearance", "Tempsc", pedited, colorappearance.tempsc, pedited->colorappearance.tempsc); - assignFromKeyfile(keyFile, "Color appearance", "Greensc", pedited, colorappearance.greensc, pedited->colorappearance.greensc); - assignFromKeyfile(keyFile, "Color appearance", "Ybout", pedited, colorappearance.ybout, pedited->colorappearance.ybout); - assignFromKeyfile(keyFile, "Color appearance", "Datacie", pedited, colorappearance.datacie, pedited->colorappearance.datacie); - assignFromKeyfile(keyFile, "Color appearance", "Tonecie", pedited, colorappearance.tonecie, pedited->colorappearance.tonecie); + assignFromKeyfile(keyFile, "Color appearance", "Surround", colorappearance.surround, pedited->colorappearance.surround); + assignFromKeyfile(keyFile, "Color appearance", "Surrsrc", colorappearance.surrsrc, pedited->colorappearance.surrsrc); + assignFromKeyfile(keyFile, "Color appearance", "AdaptLum", colorappearance.adaplum, pedited->colorappearance.adaplum); + assignFromKeyfile(keyFile, "Color appearance", "Badpixsl", colorappearance.badpixsl, pedited->colorappearance.badpixsl); + assignFromKeyfile(keyFile, "Color appearance", "Model", colorappearance.wbmodel, pedited->colorappearance.wbmodel); + assignFromKeyfile(keyFile, "Color appearance", "Illum", colorappearance.illum, pedited->colorappearance.illum); + assignFromKeyfile(keyFile, "Color appearance", "Algorithm", colorappearance.algo, pedited->colorappearance.algo); + assignFromKeyfile(keyFile, "Color appearance", "J-Light", colorappearance.jlight, pedited->colorappearance.jlight); + assignFromKeyfile(keyFile, "Color appearance", "Q-Bright", colorappearance.qbright, pedited->colorappearance.qbright); + assignFromKeyfile(keyFile, "Color appearance", "C-Chroma", colorappearance.chroma, pedited->colorappearance.chroma); + assignFromKeyfile(keyFile, "Color appearance", "S-Chroma", colorappearance.schroma, pedited->colorappearance.schroma); + assignFromKeyfile(keyFile, "Color appearance", "M-Chroma", colorappearance.mchroma, pedited->colorappearance.mchroma); + assignFromKeyfile(keyFile, "Color appearance", "RSTProtection", colorappearance.rstprotection, pedited->colorappearance.rstprotection); + assignFromKeyfile(keyFile, "Color appearance", "J-Contrast", colorappearance.contrast, pedited->colorappearance.contrast); + assignFromKeyfile(keyFile, "Color appearance", "Q-Contrast", colorappearance.qcontrast, pedited->colorappearance.qcontrast); + assignFromKeyfile(keyFile, "Color appearance", "H-Hue", colorappearance.colorh, pedited->colorappearance.colorh); + assignFromKeyfile(keyFile, "Color appearance", "AdaptScene", colorappearance.adapscen, pedited->colorappearance.adapscen); + assignFromKeyfile(keyFile, "Color appearance", "AutoAdapscen", colorappearance.autoadapscen, pedited->colorappearance.autoadapscen); + assignFromKeyfile(keyFile, "Color appearance", "YbScene", colorappearance.ybscen, pedited->colorappearance.ybscen); + assignFromKeyfile(keyFile, "Color appearance", "Autoybscen", colorappearance.autoybscen, pedited->colorappearance.autoybscen); + assignFromKeyfile(keyFile, "Color appearance", "SurrSource", colorappearance.surrsource, pedited->colorappearance.surrsource); + assignFromKeyfile(keyFile, "Color appearance", "Gamut", colorappearance.gamut, pedited->colorappearance.gamut); + assignFromKeyfile(keyFile, "Color appearance", "Tempout", colorappearance.tempout, pedited->colorappearance.tempout); + assignFromKeyfile(keyFile, "Color appearance", "Autotempout", colorappearance.autotempout, pedited->colorappearance.autotempout); + assignFromKeyfile(keyFile, "Color appearance", "Greenout", colorappearance.greenout, pedited->colorappearance.greenout); + assignFromKeyfile(keyFile, "Color appearance", "Tempsc", colorappearance.tempsc, pedited->colorappearance.tempsc); + assignFromKeyfile(keyFile, "Color appearance", "Greensc", colorappearance.greensc, pedited->colorappearance.greensc); + assignFromKeyfile(keyFile, "Color appearance", "Ybout", colorappearance.ybout, pedited->colorappearance.ybout); + assignFromKeyfile(keyFile, "Color appearance", "Datacie", colorappearance.datacie, pedited->colorappearance.datacie); + assignFromKeyfile(keyFile, "Color appearance", "Tonecie", colorappearance.tonecie, pedited->colorappearance.tonecie); const std::map tc_mapping = { {"Lightness", ColorAppearanceParams::TcMode::LIGHT}, {"Brightness", ColorAppearanceParams::TcMode::BRIGHT} }; - assignFromKeyfile(keyFile, "Color appearance", "CurveMode", pedited, tc_mapping, colorappearance.curveMode, pedited->colorappearance.curveMode); - assignFromKeyfile(keyFile, "Color appearance", "CurveMode2", pedited, tc_mapping, colorappearance.curveMode2, pedited->colorappearance.curveMode2); + assignFromKeyfile(keyFile, "Color appearance", "CurveMode", tc_mapping, colorappearance.curveMode, pedited->colorappearance.curveMode); + assignFromKeyfile(keyFile, "Color appearance", "CurveMode2", tc_mapping, colorappearance.curveMode2, pedited->colorappearance.curveMode2); assignFromKeyfile( keyFile, "Color appearance", "CurveMode3", - pedited, { {"Chroma", ColorAppearanceParams::CtcMode::CHROMA}, {"Saturation", ColorAppearanceParams::CtcMode::SATUR}, @@ -8415,78 +8412,78 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) ); if (ppVersion > 200) { - assignFromKeyfile(keyFile, "Color appearance", "Curve", pedited, colorappearance.curve, pedited->colorappearance.curve); - assignFromKeyfile(keyFile, "Color appearance", "Curve2", pedited, colorappearance.curve2, pedited->colorappearance.curve2); - assignFromKeyfile(keyFile, "Color appearance", "Curve3", pedited, colorappearance.curve3, pedited->colorappearance.curve3); + assignFromKeyfile(keyFile, "Color appearance", "Curve", colorappearance.curve, pedited->colorappearance.curve); + assignFromKeyfile(keyFile, "Color appearance", "Curve2", colorappearance.curve2, pedited->colorappearance.curve2); + assignFromKeyfile(keyFile, "Color appearance", "Curve3", colorappearance.curve3, pedited->colorappearance.curve3); } } if (keyFile.has_group("Impulse Denoising")) { - assignFromKeyfile(keyFile, "Impulse Denoising", "Enabled", pedited, impulseDenoise.enabled, pedited->impulseDenoise.enabled); - assignFromKeyfile(keyFile, "Impulse Denoising", "Threshold", pedited, impulseDenoise.thresh, pedited->impulseDenoise.thresh); + assignFromKeyfile(keyFile, "Impulse Denoising", "Enabled", impulseDenoise.enabled, pedited->impulseDenoise.enabled); + assignFromKeyfile(keyFile, "Impulse Denoising", "Threshold", impulseDenoise.thresh, pedited->impulseDenoise.thresh); } if (keyFile.has_group("Directional Pyramid Denoising")) { //TODO: No longer an accurate description for FT denoise - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enabled", pedited, dirpyrDenoise.enabled, pedited->dirpyrDenoise.enabled); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enhance", pedited, dirpyrDenoise.enhance, pedited->dirpyrDenoise.enhance); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Median", pedited, dirpyrDenoise.median, pedited->dirpyrDenoise.median); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Luma", pedited, dirpyrDenoise.luma, pedited->dirpyrDenoise.luma); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Ldetail", pedited, dirpyrDenoise.Ldetail, pedited->dirpyrDenoise.Ldetail); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Chroma", pedited, dirpyrDenoise.chroma, pedited->dirpyrDenoise.chroma); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Method", pedited, dirpyrDenoise.dmethod, pedited->dirpyrDenoise.dmethod); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LMethod", pedited, dirpyrDenoise.Lmethod, pedited->dirpyrDenoise.Lmethod); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CMethod", pedited, dirpyrDenoise.Cmethod, pedited->dirpyrDenoise.Cmethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled, pedited->dirpyrDenoise.enabled); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance, pedited->dirpyrDenoise.enhance); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Median", dirpyrDenoise.median, pedited->dirpyrDenoise.median); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma, pedited->dirpyrDenoise.luma); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail, pedited->dirpyrDenoise.Ldetail); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma, pedited->dirpyrDenoise.chroma); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod, pedited->dirpyrDenoise.dmethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LMethod", dirpyrDenoise.Lmethod, pedited->dirpyrDenoise.Lmethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CMethod", dirpyrDenoise.Cmethod, pedited->dirpyrDenoise.Cmethod); if (dirpyrDenoise.Cmethod == "PRE") { dirpyrDenoise.Cmethod = "MAN"; // Never load 'auto chroma preview mode' from pp3 } - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "C2Method", pedited, dirpyrDenoise.C2method, pedited->dirpyrDenoise.C2method); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "C2Method", dirpyrDenoise.C2method, pedited->dirpyrDenoise.C2method); if (dirpyrDenoise.C2method == "PREV") { dirpyrDenoise.C2method = "MANU"; } - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "SMethod", pedited, dirpyrDenoise.smethod, pedited->dirpyrDenoise.smethod); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MedMethod", pedited, dirpyrDenoise.medmethod, pedited->dirpyrDenoise.medmethod); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MethodMed", pedited, dirpyrDenoise.methodmed, pedited->dirpyrDenoise.methodmed); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "RGBMethod", pedited, dirpyrDenoise.rgbmethod, pedited->dirpyrDenoise.rgbmethod); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LCurve", pedited, dirpyrDenoise.lcurve, pedited->dirpyrDenoise.lcurve); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "SMethod", dirpyrDenoise.smethod, pedited->dirpyrDenoise.smethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod, pedited->dirpyrDenoise.medmethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, pedited->dirpyrDenoise.methodmed); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "RGBMethod", dirpyrDenoise.rgbmethod, pedited->dirpyrDenoise.rgbmethod); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, pedited->dirpyrDenoise.lcurve); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CCCurve", pedited, dirpyrDenoise.cccurve, pedited->dirpyrDenoise.cccurve); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "CCCurve", dirpyrDenoise.cccurve, pedited->dirpyrDenoise.cccurve); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", pedited, dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", pedited, dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", pedited, dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma); - assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", pedited, dirpyrDenoise.passes, pedited->dirpyrDenoise.passes); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma); + assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, pedited->dirpyrDenoise.passes); } if (keyFile.has_group("EPD")) { - assignFromKeyfile(keyFile, "EPD", "Enabled", pedited, epd.enabled, pedited->epd.enabled); - assignFromKeyfile(keyFile, "EPD", "Strength", pedited, epd.strength, pedited->epd.strength); - assignFromKeyfile(keyFile, "EPD", "Gamma", pedited, epd.gamma, pedited->epd.gamma); - assignFromKeyfile(keyFile, "EPD", "EdgeStopping", pedited, epd.edgeStopping, pedited->epd.edgeStopping); - assignFromKeyfile(keyFile, "EPD", "Scale", pedited, epd.scale, pedited->epd.scale); - assignFromKeyfile(keyFile, "EPD", "ReweightingIterates", pedited, epd.reweightingIterates, pedited->epd.reweightingIterates); + assignFromKeyfile(keyFile, "EPD", "Enabled", epd.enabled, pedited->epd.enabled); + assignFromKeyfile(keyFile, "EPD", "Strength", epd.strength, pedited->epd.strength); + assignFromKeyfile(keyFile, "EPD", "Gamma", epd.gamma, pedited->epd.gamma); + assignFromKeyfile(keyFile, "EPD", "EdgeStopping", epd.edgeStopping, pedited->epd.edgeStopping); + assignFromKeyfile(keyFile, "EPD", "Scale", epd.scale, pedited->epd.scale); + assignFromKeyfile(keyFile, "EPD", "ReweightingIterates", epd.reweightingIterates, pedited->epd.reweightingIterates); } if (keyFile.has_group("FattalToneMapping")) { - assignFromKeyfile(keyFile, "FattalToneMapping", "Enabled", pedited, fattal.enabled, pedited->fattal.enabled); - assignFromKeyfile(keyFile, "FattalToneMapping", "Threshold", pedited, fattal.threshold, pedited->fattal.threshold); - assignFromKeyfile(keyFile, "FattalToneMapping", "Amount", pedited, fattal.amount, pedited->fattal.amount); - assignFromKeyfile(keyFile, "FattalToneMapping", "Anchor", pedited, fattal.anchor, pedited->fattal.anchor); + assignFromKeyfile(keyFile, "FattalToneMapping", "Enabled", fattal.enabled, pedited->fattal.enabled); + assignFromKeyfile(keyFile, "FattalToneMapping", "Threshold", fattal.threshold, pedited->fattal.threshold); + assignFromKeyfile(keyFile, "FattalToneMapping", "Amount", fattal.amount, pedited->fattal.amount); + assignFromKeyfile(keyFile, "FattalToneMapping", "Anchor", fattal.anchor, pedited->fattal.anchor); } if (keyFile.has_group("Shadows & Highlights") && ppVersion >= 333) { - assignFromKeyfile(keyFile, "Shadows & Highlights", "Enabled", pedited, sh.enabled, pedited->sh.enabled); - assignFromKeyfile(keyFile, "Shadows & Highlights", "Highlights", pedited, sh.highlights, pedited->sh.highlights); - assignFromKeyfile(keyFile, "Shadows & Highlights", "HighlightTonalWidth", pedited, sh.htonalwidth, pedited->sh.htonalwidth); - assignFromKeyfile(keyFile, "Shadows & Highlights", "Shadows", pedited, sh.shadows, pedited->sh.shadows); - assignFromKeyfile(keyFile, "Shadows & Highlights", "ShadowTonalWidth", pedited, sh.stonalwidth, pedited->sh.stonalwidth); - assignFromKeyfile(keyFile, "Shadows & Highlights", "Radius", pedited, sh.radius, pedited->sh.radius); + assignFromKeyfile(keyFile, "Shadows & Highlights", "Enabled", sh.enabled, pedited->sh.enabled); + assignFromKeyfile(keyFile, "Shadows & Highlights", "Highlights", sh.highlights, pedited->sh.highlights); + assignFromKeyfile(keyFile, "Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth, pedited->sh.htonalwidth); + assignFromKeyfile(keyFile, "Shadows & Highlights", "Shadows", sh.shadows, pedited->sh.shadows); + assignFromKeyfile(keyFile, "Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth, pedited->sh.stonalwidth); + assignFromKeyfile(keyFile, "Shadows & Highlights", "Radius", sh.radius, pedited->sh.radius); if (ppVersion >= 344) { - assignFromKeyfile(keyFile, "Shadows & Highlights", "Lab", pedited, sh.lab, pedited->sh.lab); + assignFromKeyfile(keyFile, "Shadows & Highlights", "Lab", sh.lab, pedited->sh.lab); } else { sh.lab = true; } @@ -8514,18 +8511,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("ToneEqualizer")) { - assignFromKeyfile(keyFile, "ToneEqualizer", "Enabled", pedited, toneEqualizer.enabled, pedited->toneEqualizer.enabled); + assignFromKeyfile(keyFile, "ToneEqualizer", "Enabled", toneEqualizer.enabled, pedited->toneEqualizer.enabled); for (size_t i = 0; i < toneEqualizer.bands.size(); ++i) { - assignFromKeyfile(keyFile, "ToneEqualizer", "Band" + std::to_string(i), pedited, toneEqualizer.bands[i], pedited->toneEqualizer.bands[i]); + assignFromKeyfile(keyFile, "ToneEqualizer", "Band" + std::to_string(i), toneEqualizer.bands[i], pedited->toneEqualizer.bands[i]); } - assignFromKeyfile(keyFile, "ToneEqualizer", "Regularization", pedited, toneEqualizer.regularization, pedited->toneEqualizer.regularization); - assignFromKeyfile(keyFile, "ToneEqualizer", "Pivot", pedited, toneEqualizer.pivot, pedited->toneEqualizer.pivot); + assignFromKeyfile(keyFile, "ToneEqualizer", "Regularization", toneEqualizer.regularization, pedited->toneEqualizer.regularization); + assignFromKeyfile(keyFile, "ToneEqualizer", "Pivot", toneEqualizer.pivot, pedited->toneEqualizer.pivot); } if (keyFile.has_group("Crop")) { - assignFromKeyfile(keyFile, "Crop", "Enabled", pedited, crop.enabled, pedited->crop.enabled); - assignFromKeyfile(keyFile, "Crop", "X", pedited, crop.x, pedited->crop.x); - assignFromKeyfile(keyFile, "Crop", "Y", pedited, crop.y, pedited->crop.y); + assignFromKeyfile(keyFile, "Crop", "Enabled", crop.enabled, pedited->crop.enabled); + assignFromKeyfile(keyFile, "Crop", "X", crop.x, pedited->crop.x); + assignFromKeyfile(keyFile, "Crop", "Y", crop.y, pedited->crop.y); if (keyFile.has_key("Crop", "W")) { crop.w = std::max(keyFile.get_integer("Crop", "W"), 1); @@ -8543,9 +8540,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Crop", "FixedRatio", pedited, crop.fixratio, pedited->crop.fixratio); + assignFromKeyfile(keyFile, "Crop", "FixedRatio", crop.fixratio, pedited->crop.fixratio); - if (assignFromKeyfile(keyFile, "Crop", "Ratio", pedited, crop.ratio, pedited->crop.ratio)) { + if (assignFromKeyfile(keyFile, "Crop", "Ratio", crop.ratio, pedited->crop.ratio)) { //backwards compatibility for crop.ratio if (crop.ratio == "DIN") { crop.ratio = "1.414 - DIN EN ISO 216"; @@ -8560,12 +8557,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Crop", "Orientation", pedited, crop.orientation, pedited->crop.orientation); + assignFromKeyfile(keyFile, "Crop", "Orientation", crop.orientation, pedited->crop.orientation); assignFromKeyfile( keyFile, "Crop", "Guide", - pedited, { {"None", CropParams::Guide::NONE}, {"Frame", CropParams::Guide::FRAME}, @@ -8584,26 +8580,26 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Coarse Transformation")) { - assignFromKeyfile(keyFile, "Coarse Transformation", "Rotate", pedited, coarse.rotate, pedited->coarse.rotate); - assignFromKeyfile(keyFile, "Coarse Transformation", "HorizontalFlip", pedited, coarse.hflip, pedited->coarse.hflip); - assignFromKeyfile(keyFile, "Coarse Transformation", "VerticalFlip", pedited, coarse.vflip, pedited->coarse.vflip); + assignFromKeyfile(keyFile, "Coarse Transformation", "Rotate", coarse.rotate, pedited->coarse.rotate); + assignFromKeyfile(keyFile, "Coarse Transformation", "HorizontalFlip", coarse.hflip, pedited->coarse.hflip); + assignFromKeyfile(keyFile, "Coarse Transformation", "VerticalFlip", coarse.vflip, pedited->coarse.vflip); } if (keyFile.has_group("Rotation")) { - assignFromKeyfile(keyFile, "Rotation", "Degree", pedited, rotate.degree, pedited->rotate.degree); + assignFromKeyfile(keyFile, "Rotation", "Degree", rotate.degree, pedited->rotate.degree); } if (keyFile.has_group("Common Properties for Transformations")) { if (keyFile.has_key("Common Properties for Transformations", "Method")) { - assignFromKeyfile(keyFile, "Common Properties for Transformations", "Method", pedited, commonTrans.method, pedited->commonTrans.method); + assignFromKeyfile(keyFile, "Common Properties for Transformations", "Method", commonTrans.method, pedited->commonTrans.method); } else { commonTrans.method = "lin"; } - assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", pedited, commonTrans.autofill, pedited->commonTrans.autofill); + assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, pedited->commonTrans.autofill); } if (keyFile.has_group("Distortion")) { - assignFromKeyfile(keyFile, "Distortion", "Amount", pedited, distortion.amount, pedited->distortion.amount); + assignFromKeyfile(keyFile, "Distortion", "Amount", distortion.amount, pedited->distortion.amount); } if (keyFile.has_group("LensProfile")) { @@ -8627,9 +8623,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "LensProfile", "UseDistortion", pedited, lensProf.useDist, pedited->lensProf.useDist); - assignFromKeyfile(keyFile, "LensProfile", "UseVignette", pedited, lensProf.useVign, pedited->lensProf.useVign); - assignFromKeyfile(keyFile, "LensProfile", "UseCA", pedited, lensProf.useCA, pedited->lensProf.useCA); + assignFromKeyfile(keyFile, "LensProfile", "UseDistortion", lensProf.useDist, pedited->lensProf.useDist); + assignFromKeyfile(keyFile, "LensProfile", "UseVignette", lensProf.useVign, pedited->lensProf.useVign); + assignFromKeyfile(keyFile, "LensProfile", "UseCA", lensProf.useCA, pedited->lensProf.useCA); if (keyFile.has_key("LensProfile", "LFCameraMake")) { lensProf.lfCameraMake = keyFile.get_string("LensProfile", "LFCameraMake"); @@ -8657,21 +8653,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Perspective")) { - assignFromKeyfile(keyFile, "Perspective", "Method", pedited, perspective.method, pedited->perspective.method); - assignFromKeyfile(keyFile, "Perspective", "Horizontal", pedited, perspective.horizontal, pedited->perspective.horizontal); - assignFromKeyfile(keyFile, "Perspective", "Vertical", pedited, perspective.vertical, pedited->perspective.vertical); - assignFromKeyfile(keyFile, "Perspective", "CameraShiftHorizontal", pedited, perspective.camera_shift_horiz, pedited->perspective.camera_shift_horiz); - assignFromKeyfile(keyFile, "Perspective", "CameraShiftVertical", pedited, perspective.camera_shift_vert, pedited->perspective.camera_shift_vert); - assignFromKeyfile(keyFile, "Perspective", "CameraPitch", pedited, perspective.camera_pitch, pedited->perspective.camera_pitch); - assignFromKeyfile(keyFile, "Perspective", "CameraRoll", pedited, perspective.camera_roll, pedited->perspective.camera_roll); - assignFromKeyfile(keyFile, "Perspective", "CameraCropFactor", pedited, perspective.camera_crop_factor, pedited->perspective.camera_crop_factor); - assignFromKeyfile(keyFile, "Perspective", "CameraFocalLength", pedited, perspective.camera_focal_length, pedited->perspective.camera_focal_length); - assignFromKeyfile(keyFile, "Perspective", "CameraYaw", pedited, perspective.camera_yaw, pedited->perspective.camera_yaw); - assignFromKeyfile(keyFile, "Perspective", "ProjectionPitch", pedited, perspective.projection_pitch, pedited->perspective.projection_pitch); - assignFromKeyfile(keyFile, "Perspective", "ProjectionRotate", pedited, perspective.projection_rotate, pedited->perspective.projection_rotate); - assignFromKeyfile(keyFile, "Perspective", "ProjectionShiftHorizontal", pedited, perspective.projection_shift_horiz, pedited->perspective.projection_shift_horiz); - assignFromKeyfile(keyFile, "Perspective", "ProjectionShiftVertical", pedited, perspective.projection_shift_vert, pedited->perspective.projection_shift_vert); - assignFromKeyfile(keyFile, "Perspective", "ProjectionYaw", pedited, perspective.projection_yaw, pedited->perspective.projection_yaw); + assignFromKeyfile(keyFile, "Perspective", "Method", perspective.method, pedited->perspective.method); + assignFromKeyfile(keyFile, "Perspective", "Horizontal", perspective.horizontal, pedited->perspective.horizontal); + assignFromKeyfile(keyFile, "Perspective", "Vertical", perspective.vertical, pedited->perspective.vertical); + assignFromKeyfile(keyFile, "Perspective", "CameraShiftHorizontal", perspective.camera_shift_horiz, pedited->perspective.camera_shift_horiz); + assignFromKeyfile(keyFile, "Perspective", "CameraShiftVertical", perspective.camera_shift_vert, pedited->perspective.camera_shift_vert); + assignFromKeyfile(keyFile, "Perspective", "CameraPitch", perspective.camera_pitch, pedited->perspective.camera_pitch); + assignFromKeyfile(keyFile, "Perspective", "CameraRoll", perspective.camera_roll, pedited->perspective.camera_roll); + assignFromKeyfile(keyFile, "Perspective", "CameraCropFactor", perspective.camera_crop_factor, pedited->perspective.camera_crop_factor); + assignFromKeyfile(keyFile, "Perspective", "CameraFocalLength", perspective.camera_focal_length, pedited->perspective.camera_focal_length); + assignFromKeyfile(keyFile, "Perspective", "CameraYaw", perspective.camera_yaw, pedited->perspective.camera_yaw); + assignFromKeyfile(keyFile, "Perspective", "ProjectionPitch", perspective.projection_pitch, pedited->perspective.projection_pitch); + assignFromKeyfile(keyFile, "Perspective", "ProjectionRotate", perspective.projection_rotate, pedited->perspective.projection_rotate); + assignFromKeyfile(keyFile, "Perspective", "ProjectionShiftHorizontal", perspective.projection_shift_horiz, pedited->perspective.projection_shift_horiz); + assignFromKeyfile(keyFile, "Perspective", "ProjectionShiftVertical", perspective.projection_shift_vert, pedited->perspective.projection_shift_vert); + assignFromKeyfile(keyFile, "Perspective", "ProjectionYaw", perspective.projection_yaw, pedited->perspective.projection_yaw); if (keyFile.has_key("Perspective", "ControlLineValues") && keyFile.has_key("Perspective", "ControlLineTypes")) { perspective.control_line_values = keyFile.get_integer_list("Perspective", "ControlLineValues"); perspective.control_line_types = keyFile.get_integer_list("Perspective", "ControlLineTypes"); @@ -8682,23 +8678,23 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("Gradient")) { - assignFromKeyfile(keyFile, "Gradient", "Enabled", pedited, gradient.enabled, pedited->gradient.enabled); - assignFromKeyfile(keyFile, "Gradient", "Degree", pedited, gradient.degree, pedited->gradient.degree); - assignFromKeyfile(keyFile, "Gradient", "Feather", pedited, gradient.feather, pedited->gradient.feather); - assignFromKeyfile(keyFile, "Gradient", "Strength", pedited, gradient.strength, pedited->gradient.strength); - assignFromKeyfile(keyFile, "Gradient", "CenterX", pedited, gradient.centerX, pedited->gradient.centerX); - assignFromKeyfile(keyFile, "Gradient", "CenterY", pedited, gradient.centerY, pedited->gradient.centerY); + assignFromKeyfile(keyFile, "Gradient", "Enabled", gradient.enabled, pedited->gradient.enabled); + assignFromKeyfile(keyFile, "Gradient", "Degree", gradient.degree, pedited->gradient.degree); + assignFromKeyfile(keyFile, "Gradient", "Feather", gradient.feather, pedited->gradient.feather); + assignFromKeyfile(keyFile, "Gradient", "Strength", gradient.strength, pedited->gradient.strength); + assignFromKeyfile(keyFile, "Gradient", "CenterX", gradient.centerX, pedited->gradient.centerX); + assignFromKeyfile(keyFile, "Gradient", "CenterY", gradient.centerY, pedited->gradient.centerY); } if (keyFile.has_group("Locallab")) { - assignFromKeyfile(keyFile, "Locallab", "Enabled", pedited, locallab.enabled, pedited->locallab.enabled); - assignFromKeyfile(keyFile, "Locallab", "Selspot", pedited, locallab.selspot, pedited->locallab.selspot); + assignFromKeyfile(keyFile, "Locallab", "Enabled", locallab.enabled, pedited->locallab.enabled); + assignFromKeyfile(keyFile, "Locallab", "Selspot", locallab.selspot, pedited->locallab.selspot); Glib::ustring ppName; bool peName; int i = 0; - while (assignFromKeyfile(keyFile, "Locallab", "Name_" + std::to_string(i), pedited, ppName, peName)) { + while (assignFromKeyfile(keyFile, "Locallab", "Name_" + std::to_string(i), ppName, peName)) { const std::string index_str = std::to_string(i); // Create new LocallabSpot and LocallabParamsEdited @@ -8708,17 +8704,17 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.name = peName; // Control spot settings - assignFromKeyfile(keyFile, "Locallab", "Isvisible_" + index_str, pedited, spot.isvisible, spotEdited.isvisible); - assignFromKeyfile(keyFile, "Locallab", "PrevMethod_" + index_str, pedited, spot.prevMethod, spotEdited.prevMethod); - assignFromKeyfile(keyFile, "Locallab", "Shape_" + index_str, pedited, spot.shape, spotEdited.shape); - assignFromKeyfile(keyFile, "Locallab", "SpotMethod_" + index_str, pedited, spot.spotMethod, spotEdited.spotMethod); - assignFromKeyfile(keyFile, "Locallab", "wavMethod_" + index_str, pedited, spot.wavMethod, spotEdited.wavMethod); - assignFromKeyfile(keyFile, "Locallab", "SensiExclu_" + index_str, pedited, spot.sensiexclu, spotEdited.sensiexclu); - assignFromKeyfile(keyFile, "Locallab", "StructExclu_" + index_str, pedited, spot.structexclu, spotEdited.structexclu); - assignFromKeyfile(keyFile, "Locallab", "Struc_" + index_str, pedited, spot.struc, spotEdited.struc); - assignFromKeyfile(keyFile, "Locallab", "ShapeMethod_" + index_str, pedited, spot.shapeMethod, spotEdited.shapeMethod); + assignFromKeyfile(keyFile, "Locallab", "Isvisible_" + index_str, spot.isvisible, spotEdited.isvisible); + assignFromKeyfile(keyFile, "Locallab", "PrevMethod_" + index_str, spot.prevMethod, spotEdited.prevMethod); + assignFromKeyfile(keyFile, "Locallab", "Shape_" + index_str, spot.shape, spotEdited.shape); + assignFromKeyfile(keyFile, "Locallab", "SpotMethod_" + index_str, spot.spotMethod, spotEdited.spotMethod); + assignFromKeyfile(keyFile, "Locallab", "wavMethod_" + index_str, spot.wavMethod, spotEdited.wavMethod); + assignFromKeyfile(keyFile, "Locallab", "SensiExclu_" + index_str, spot.sensiexclu, spotEdited.sensiexclu); + assignFromKeyfile(keyFile, "Locallab", "StructExclu_" + index_str, spot.structexclu, spotEdited.structexclu); + assignFromKeyfile(keyFile, "Locallab", "Struc_" + index_str, spot.struc, spotEdited.struc); + assignFromKeyfile(keyFile, "Locallab", "ShapeMethod_" + index_str, spot.shapeMethod, spotEdited.shapeMethod); if (keyFile.has_key("Locallab", "AvoidgamutMethod_" + index_str)) { - assignFromKeyfile(keyFile, "Locallab", "AvoidgamutMethod_" + index_str, pedited, spot.avoidgamutMethod, spotEdited.avoidgamutMethod); + assignFromKeyfile(keyFile, "Locallab", "AvoidgamutMethod_" + index_str, spot.avoidgamutMethod, spotEdited.avoidgamutMethod); } else if (keyFile.has_key("Locallab", "Avoid_" + index_str)) { const bool avoid = keyFile.get_boolean("Locallab", "Avoid_" + index_str); const bool munsell = keyFile.has_key("Locallab", "Avoidmun_" + index_str) && keyFile.get_boolean("Locallab", "Avoidmun_" + index_str); @@ -8727,103 +8723,103 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.avoidgamutMethod = true; } } - assignFromKeyfile(keyFile, "Locallab", "Loc_" + index_str, pedited, spot.loc, spotEdited.loc); - assignFromKeyfile(keyFile, "Locallab", "CenterX_" + index_str, pedited, spot.centerX, spotEdited.centerX); - assignFromKeyfile(keyFile, "Locallab", "CenterY_" + index_str, pedited, spot.centerY, spotEdited.centerY); - assignFromKeyfile(keyFile, "Locallab", "Circrad_" + index_str, pedited, spot.circrad, spotEdited.circrad); - assignFromKeyfile(keyFile, "Locallab", "QualityMethod_" + index_str, pedited, spot.qualityMethod, spotEdited.qualityMethod); - assignFromKeyfile(keyFile, "Locallab", "ComplexMethod_" + index_str, pedited, spot.complexMethod, spotEdited.complexMethod); - assignFromKeyfile(keyFile, "Locallab", "Transit_" + index_str, pedited, spot.transit, spotEdited.transit); - assignFromKeyfile(keyFile, "Locallab", "Feather_" + index_str, pedited, spot.feather, spotEdited.feather); - assignFromKeyfile(keyFile, "Locallab", "Thresh_" + index_str, pedited, spot.thresh, spotEdited.thresh); - assignFromKeyfile(keyFile, "Locallab", "Iter_" + index_str, pedited, spot.iter, spotEdited.iter); - assignFromKeyfile(keyFile, "Locallab", "Balan_" + index_str, pedited, spot.balan, spotEdited.balan); - assignFromKeyfile(keyFile, "Locallab", "Balanh_" + index_str, pedited, spot.balanh, spotEdited.balanh); - assignFromKeyfile(keyFile, "Locallab", "Colorde_" + index_str, pedited, spot.colorde, spotEdited.colorde); - assignFromKeyfile(keyFile, "Locallab", "Colorscope_" + index_str, pedited, spot.colorscope, spotEdited.colorscope); - assignFromKeyfile(keyFile, "Locallab", "Avoidrad_" + index_str, pedited, spot.avoidrad, spotEdited.avoidrad); - assignFromKeyfile(keyFile, "Locallab", "Transitweak_" + index_str, pedited, spot.transitweak, spotEdited.transitweak); - assignFromKeyfile(keyFile, "Locallab", "Transitgrad_" + index_str, pedited, spot.transitgrad, spotEdited.transitgrad); - assignFromKeyfile(keyFile, "Locallab", "Hishow_" + index_str, pedited, spot.hishow, spotEdited.hishow); - assignFromKeyfile(keyFile, "Locallab", "Activ_" + index_str, pedited, spot.activ, spotEdited.activ); - assignFromKeyfile(keyFile, "Locallab", "Blwh_" + index_str, pedited, spot.blwh, spotEdited.blwh); - assignFromKeyfile(keyFile, "Locallab", "Recurs_" + index_str, pedited, spot.recurs, spotEdited.recurs); - assignFromKeyfile(keyFile, "Locallab", "Laplac_" + index_str, pedited, spot.laplac, spotEdited.laplac); - assignFromKeyfile(keyFile, "Locallab", "Deltae_" + index_str, pedited, spot.deltae, spotEdited.deltae); - assignFromKeyfile(keyFile, "Locallab", "Shortc_" + index_str, pedited, spot.shortc, spotEdited.shortc); - assignFromKeyfile(keyFile, "Locallab", "Savrest_" + index_str, pedited, spot.savrest, spotEdited.savrest); - assignFromKeyfile(keyFile, "Locallab", "Scopemask_" + index_str, pedited, spot.scopemask, spotEdited.scopemask); - assignFromKeyfile(keyFile, "Locallab", "Denoichmask_" + index_str, pedited, spot.denoichmask, spotEdited.denoichmask); - assignFromKeyfile(keyFile, "Locallab", "Lumask_" + index_str, pedited, spot.lumask, spotEdited.lumask); + assignFromKeyfile(keyFile, "Locallab", "Loc_" + index_str, spot.loc, spotEdited.loc); + assignFromKeyfile(keyFile, "Locallab", "CenterX_" + index_str, spot.centerX, spotEdited.centerX); + assignFromKeyfile(keyFile, "Locallab", "CenterY_" + index_str, spot.centerY, spotEdited.centerY); + assignFromKeyfile(keyFile, "Locallab", "Circrad_" + index_str, spot.circrad, spotEdited.circrad); + assignFromKeyfile(keyFile, "Locallab", "QualityMethod_" + index_str, spot.qualityMethod, spotEdited.qualityMethod); + assignFromKeyfile(keyFile, "Locallab", "ComplexMethod_" + index_str, spot.complexMethod, spotEdited.complexMethod); + assignFromKeyfile(keyFile, "Locallab", "Transit_" + index_str, spot.transit, spotEdited.transit); + assignFromKeyfile(keyFile, "Locallab", "Feather_" + index_str, spot.feather, spotEdited.feather); + assignFromKeyfile(keyFile, "Locallab", "Thresh_" + index_str, spot.thresh, spotEdited.thresh); + assignFromKeyfile(keyFile, "Locallab", "Iter_" + index_str, spot.iter, spotEdited.iter); + assignFromKeyfile(keyFile, "Locallab", "Balan_" + index_str, spot.balan, spotEdited.balan); + assignFromKeyfile(keyFile, "Locallab", "Balanh_" + index_str, spot.balanh, spotEdited.balanh); + assignFromKeyfile(keyFile, "Locallab", "Colorde_" + index_str, spot.colorde, spotEdited.colorde); + assignFromKeyfile(keyFile, "Locallab", "Colorscope_" + index_str, spot.colorscope, spotEdited.colorscope); + assignFromKeyfile(keyFile, "Locallab", "Avoidrad_" + index_str, spot.avoidrad, spotEdited.avoidrad); + assignFromKeyfile(keyFile, "Locallab", "Transitweak_" + index_str, spot.transitweak, spotEdited.transitweak); + assignFromKeyfile(keyFile, "Locallab", "Transitgrad_" + index_str, spot.transitgrad, spotEdited.transitgrad); + assignFromKeyfile(keyFile, "Locallab", "Hishow_" + index_str, spot.hishow, spotEdited.hishow); + assignFromKeyfile(keyFile, "Locallab", "Activ_" + index_str, spot.activ, spotEdited.activ); + assignFromKeyfile(keyFile, "Locallab", "Blwh_" + index_str, spot.blwh, spotEdited.blwh); + assignFromKeyfile(keyFile, "Locallab", "Recurs_" + index_str, spot.recurs, spotEdited.recurs); + assignFromKeyfile(keyFile, "Locallab", "Laplac_" + index_str, spot.laplac, spotEdited.laplac); + assignFromKeyfile(keyFile, "Locallab", "Deltae_" + index_str, spot.deltae, spotEdited.deltae); + assignFromKeyfile(keyFile, "Locallab", "Shortc_" + index_str, spot.shortc, spotEdited.shortc); + assignFromKeyfile(keyFile, "Locallab", "Savrest_" + index_str, spot.savrest, spotEdited.savrest); + assignFromKeyfile(keyFile, "Locallab", "Scopemask_" + index_str, spot.scopemask, spotEdited.scopemask); + assignFromKeyfile(keyFile, "Locallab", "Denoichmask_" + index_str, spot.denoichmask, spotEdited.denoichmask); + assignFromKeyfile(keyFile, "Locallab", "Lumask_" + index_str, spot.lumask, spotEdited.lumask); // Color & Light - spot.visicolor = assignFromKeyfile(keyFile, "Locallab", "Expcolor_" + index_str, pedited, spot.expcolor, spotEdited.expcolor); + spot.visicolor = assignFromKeyfile(keyFile, "Locallab", "Expcolor_" + index_str, spot.expcolor, spotEdited.expcolor); if (spot.visicolor) { spotEdited.visicolor = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexcolor_" + index_str, pedited, spot.complexcolor, spotEdited.complexcolor); - assignFromKeyfile(keyFile, "Locallab", "Curvactiv_" + index_str, pedited, spot.curvactiv, spotEdited.curvactiv); - assignFromKeyfile(keyFile, "Locallab", "Lightness_" + index_str, pedited, spot.lightness, spotEdited.lightness); - assignFromKeyfile(keyFile, "Locallab", "Reparcol_" + index_str, pedited, spot.reparcol, spotEdited.reparcol); - assignFromKeyfile(keyFile, "Locallab", "Gamc_" + index_str, pedited, spot.gamc, spotEdited.gamc); - assignFromKeyfile(keyFile, "Locallab", "Contrast_" + index_str, pedited, spot.contrast, spotEdited.contrast); - assignFromKeyfile(keyFile, "Locallab", "Chroma_" + index_str, pedited, spot.chroma, spotEdited.chroma); - assignFromKeyfile(keyFile, "Locallab", "labgridALow_" + index_str, pedited, spot.labgridALow, spotEdited.labgridALow); - assignFromKeyfile(keyFile, "Locallab", "labgridBLow_" + index_str, pedited, spot.labgridBLow, spotEdited.labgridBLow); - assignFromKeyfile(keyFile, "Locallab", "labgridAHigh_" + index_str, pedited, spot.labgridAHigh, spotEdited.labgridAHigh); - assignFromKeyfile(keyFile, "Locallab", "labgridBHigh_" + index_str, pedited, spot.labgridBHigh, spotEdited.labgridBHigh); - assignFromKeyfile(keyFile, "Locallab", "labgridALowmerg_" + index_str, pedited, spot.labgridALowmerg, spotEdited.labgridALowmerg); - assignFromKeyfile(keyFile, "Locallab", "labgridBLowmerg_" + index_str, pedited, spot.labgridBLowmerg, spotEdited.labgridBLowmerg); - assignFromKeyfile(keyFile, "Locallab", "labgridAHighmerg_" + index_str, pedited, spot.labgridAHighmerg, spotEdited.labgridAHighmerg); - assignFromKeyfile(keyFile, "Locallab", "labgridBHighmerg_" + index_str, pedited, spot.labgridBHighmerg, spotEdited.labgridBHighmerg); - assignFromKeyfile(keyFile, "Locallab", "Strengthgrid_" + index_str, pedited, spot.strengthgrid, spotEdited.strengthgrid); - assignFromKeyfile(keyFile, "Locallab", "Sensi_" + index_str, pedited, spot.sensi, spotEdited.sensi); - assignFromKeyfile(keyFile, "Locallab", "Structcol_" + index_str, pedited, spot.structcol, spotEdited.structcol); - assignFromKeyfile(keyFile, "Locallab", "Strcol_" + index_str, pedited, spot.strcol, spotEdited.strcol); - assignFromKeyfile(keyFile, "Locallab", "Strcolab_" + index_str, pedited, spot.strcolab, spotEdited.strcolab); - assignFromKeyfile(keyFile, "Locallab", "Strcolh_" + index_str, pedited, spot.strcolh, spotEdited.strcolh); - assignFromKeyfile(keyFile, "Locallab", "Angcol_" + index_str, pedited, spot.angcol, spotEdited.angcol); - assignFromKeyfile(keyFile, "Locallab", "Blurcolde_" + index_str, pedited, spot.blurcolde, spotEdited.blurcolde); - assignFromKeyfile(keyFile, "Locallab", "Blurcol_" + index_str, pedited, spot.blurcol, spotEdited.blurcol); - assignFromKeyfile(keyFile, "Locallab", "Contcol_" + index_str, pedited, spot.contcol, spotEdited.contcol); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskcol_" + index_str, pedited, spot.blendmaskcol, spotEdited.blendmaskcol); - assignFromKeyfile(keyFile, "Locallab", "Radmaskcol_" + index_str, pedited, spot.radmaskcol, spotEdited.radmaskcol); - assignFromKeyfile(keyFile, "Locallab", "Chromaskcol_" + index_str, pedited, spot.chromaskcol, spotEdited.chromaskcol); - assignFromKeyfile(keyFile, "Locallab", "Gammaskcol_" + index_str, pedited, spot.gammaskcol, spotEdited.gammaskcol); - assignFromKeyfile(keyFile, "Locallab", "Slomaskcol_" + index_str, pedited, spot.slomaskcol, spotEdited.slomaskcol); - assignFromKeyfile(keyFile, "Locallab", "shadmaskcol_" + index_str, pedited, spot.shadmaskcol, spotEdited.shadmaskcol); - assignFromKeyfile(keyFile, "Locallab", "strumaskcol_" + index_str, pedited, spot.strumaskcol, spotEdited.strumaskcol); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskcol_" + index_str, pedited, spot.lapmaskcol, spotEdited.lapmaskcol); - assignFromKeyfile(keyFile, "Locallab", "QualityCurveMethod_" + index_str, pedited, spot.qualitycurveMethod, spotEdited.qualitycurveMethod); - assignFromKeyfile(keyFile, "Locallab", "gridMethod_" + index_str, pedited, spot.gridMethod, spotEdited.gridMethod); - assignFromKeyfile(keyFile, "Locallab", "Merg_Method_" + index_str, pedited, spot.merMethod, spotEdited.merMethod); - assignFromKeyfile(keyFile, "Locallab", "ToneMethod_" + index_str, pedited, spot.toneMethod, spotEdited.toneMethod); - assignFromKeyfile(keyFile, "Locallab", "mergecolMethod_" + index_str, pedited, spot.mergecolMethod, spotEdited.mergecolMethod); - assignFromKeyfile(keyFile, "Locallab", "LLCurve_" + index_str, pedited, spot.llcurve, spotEdited.llcurve); - assignFromKeyfile(keyFile, "Locallab", "LCCurve_" + index_str, pedited, spot.lccurve, spotEdited.lccurve); - assignFromKeyfile(keyFile, "Locallab", "CCCurve_" + index_str, pedited, spot.cccurve, spotEdited.cccurve); - assignFromKeyfile(keyFile, "Locallab", "CLCurve_" + index_str, pedited, spot.clcurve, spotEdited.clcurve); - assignFromKeyfile(keyFile, "Locallab", "RGBCurve_" + index_str, pedited, spot.rgbcurve, spotEdited.rgbcurve); - assignFromKeyfile(keyFile, "Locallab", "LHCurve_" + index_str, pedited, spot.LHcurve, spotEdited.LHcurve); - assignFromKeyfile(keyFile, "Locallab", "HHCurve_" + index_str, pedited, spot.HHcurve, spotEdited.HHcurve); - assignFromKeyfile(keyFile, "Locallab", "CHCurve_" + index_str, pedited, spot.CHcurve, spotEdited.CHcurve); - assignFromKeyfile(keyFile, "Locallab", "Invers_" + index_str, pedited, spot.invers, spotEdited.invers); - assignFromKeyfile(keyFile, "Locallab", "Special_" + index_str, pedited, spot.special, spotEdited.special); - assignFromKeyfile(keyFile, "Locallab", "Toolcol_" + index_str, pedited, spot.toolcol, spotEdited.toolcol); - assignFromKeyfile(keyFile, "Locallab", "EnaColorMask_" + index_str, pedited, spot.enaColorMask, spotEdited.enaColorMask); - assignFromKeyfile(keyFile, "Locallab", "FftColorMask_" + index_str, pedited, spot.fftColorMask, spotEdited.fftColorMask); - assignFromKeyfile(keyFile, "Locallab", "CCmaskCurve_" + index_str, pedited, spot.CCmaskcurve, spotEdited.CCmaskcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskCurve_" + index_str, pedited, spot.LLmaskcurve, spotEdited.LLmaskcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskCurve_" + index_str, pedited, spot.HHmaskcurve, spotEdited.HHmaskcurve); - assignFromKeyfile(keyFile, "Locallab", "HHhmaskCurve_" + index_str, pedited, spot.HHhmaskcurve, spotEdited.HHhmaskcurve); - assignFromKeyfile(keyFile, "Locallab", "Softradiuscol_" + index_str, pedited, spot.softradiuscol, spotEdited.softradiuscol); - assignFromKeyfile(keyFile, "Locallab", "Opacol_" + index_str, pedited, spot.opacol, spotEdited.opacol); - assignFromKeyfile(keyFile, "Locallab", "Mercol_" + index_str, pedited, spot.mercol, spotEdited.mercol); - assignFromKeyfile(keyFile, "Locallab", "Merlucol_" + index_str, pedited, spot.merlucol, spotEdited.merlucol); - assignFromKeyfile(keyFile, "Locallab", "Conthrcol_" + index_str, pedited, spot.conthrcol, spotEdited.conthrcol); - assignFromKeyfile(keyFile, "Locallab", "LmaskCurve_" + index_str, pedited, spot.Lmaskcurve, spotEdited.Lmaskcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskcolCurvewav_" + index_str, pedited, spot.LLmaskcolcurvewav, spotEdited.LLmaskcolcurvewav); + assignFromKeyfile(keyFile, "Locallab", "Complexcolor_" + index_str, spot.complexcolor, spotEdited.complexcolor); + assignFromKeyfile(keyFile, "Locallab", "Curvactiv_" + index_str, spot.curvactiv, spotEdited.curvactiv); + assignFromKeyfile(keyFile, "Locallab", "Lightness_" + index_str, spot.lightness, spotEdited.lightness); + assignFromKeyfile(keyFile, "Locallab", "Reparcol_" + index_str, spot.reparcol, spotEdited.reparcol); + assignFromKeyfile(keyFile, "Locallab", "Gamc_" + index_str, spot.gamc, spotEdited.gamc); + assignFromKeyfile(keyFile, "Locallab", "Contrast_" + index_str, spot.contrast, spotEdited.contrast); + assignFromKeyfile(keyFile, "Locallab", "Chroma_" + index_str, spot.chroma, spotEdited.chroma); + assignFromKeyfile(keyFile, "Locallab", "labgridALow_" + index_str, spot.labgridALow, spotEdited.labgridALow); + assignFromKeyfile(keyFile, "Locallab", "labgridBLow_" + index_str, spot.labgridBLow, spotEdited.labgridBLow); + assignFromKeyfile(keyFile, "Locallab", "labgridAHigh_" + index_str, spot.labgridAHigh, spotEdited.labgridAHigh); + assignFromKeyfile(keyFile, "Locallab", "labgridBHigh_" + index_str, spot.labgridBHigh, spotEdited.labgridBHigh); + assignFromKeyfile(keyFile, "Locallab", "labgridALowmerg_" + index_str, spot.labgridALowmerg, spotEdited.labgridALowmerg); + assignFromKeyfile(keyFile, "Locallab", "labgridBLowmerg_" + index_str, spot.labgridBLowmerg, spotEdited.labgridBLowmerg); + assignFromKeyfile(keyFile, "Locallab", "labgridAHighmerg_" + index_str, spot.labgridAHighmerg, spotEdited.labgridAHighmerg); + assignFromKeyfile(keyFile, "Locallab", "labgridBHighmerg_" + index_str, spot.labgridBHighmerg, spotEdited.labgridBHighmerg); + assignFromKeyfile(keyFile, "Locallab", "Strengthgrid_" + index_str, spot.strengthgrid, spotEdited.strengthgrid); + assignFromKeyfile(keyFile, "Locallab", "Sensi_" + index_str, spot.sensi, spotEdited.sensi); + assignFromKeyfile(keyFile, "Locallab", "Structcol_" + index_str, spot.structcol, spotEdited.structcol); + assignFromKeyfile(keyFile, "Locallab", "Strcol_" + index_str, spot.strcol, spotEdited.strcol); + assignFromKeyfile(keyFile, "Locallab", "Strcolab_" + index_str, spot.strcolab, spotEdited.strcolab); + assignFromKeyfile(keyFile, "Locallab", "Strcolh_" + index_str, spot.strcolh, spotEdited.strcolh); + assignFromKeyfile(keyFile, "Locallab", "Angcol_" + index_str, spot.angcol, spotEdited.angcol); + assignFromKeyfile(keyFile, "Locallab", "Blurcolde_" + index_str, spot.blurcolde, spotEdited.blurcolde); + assignFromKeyfile(keyFile, "Locallab", "Blurcol_" + index_str, spot.blurcol, spotEdited.blurcol); + assignFromKeyfile(keyFile, "Locallab", "Contcol_" + index_str, spot.contcol, spotEdited.contcol); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskcol_" + index_str, spot.blendmaskcol, spotEdited.blendmaskcol); + assignFromKeyfile(keyFile, "Locallab", "Radmaskcol_" + index_str, spot.radmaskcol, spotEdited.radmaskcol); + assignFromKeyfile(keyFile, "Locallab", "Chromaskcol_" + index_str, spot.chromaskcol, spotEdited.chromaskcol); + assignFromKeyfile(keyFile, "Locallab", "Gammaskcol_" + index_str, spot.gammaskcol, spotEdited.gammaskcol); + assignFromKeyfile(keyFile, "Locallab", "Slomaskcol_" + index_str, spot.slomaskcol, spotEdited.slomaskcol); + assignFromKeyfile(keyFile, "Locallab", "shadmaskcol_" + index_str, spot.shadmaskcol, spotEdited.shadmaskcol); + assignFromKeyfile(keyFile, "Locallab", "strumaskcol_" + index_str, spot.strumaskcol, spotEdited.strumaskcol); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskcol_" + index_str, spot.lapmaskcol, spotEdited.lapmaskcol); + assignFromKeyfile(keyFile, "Locallab", "QualityCurveMethod_" + index_str, spot.qualitycurveMethod, spotEdited.qualitycurveMethod); + assignFromKeyfile(keyFile, "Locallab", "gridMethod_" + index_str, spot.gridMethod, spotEdited.gridMethod); + assignFromKeyfile(keyFile, "Locallab", "Merg_Method_" + index_str, spot.merMethod, spotEdited.merMethod); + assignFromKeyfile(keyFile, "Locallab", "ToneMethod_" + index_str, spot.toneMethod, spotEdited.toneMethod); + assignFromKeyfile(keyFile, "Locallab", "mergecolMethod_" + index_str, spot.mergecolMethod, spotEdited.mergecolMethod); + assignFromKeyfile(keyFile, "Locallab", "LLCurve_" + index_str, spot.llcurve, spotEdited.llcurve); + assignFromKeyfile(keyFile, "Locallab", "LCCurve_" + index_str, spot.lccurve, spotEdited.lccurve); + assignFromKeyfile(keyFile, "Locallab", "CCCurve_" + index_str, spot.cccurve, spotEdited.cccurve); + assignFromKeyfile(keyFile, "Locallab", "CLCurve_" + index_str, spot.clcurve, spotEdited.clcurve); + assignFromKeyfile(keyFile, "Locallab", "RGBCurve_" + index_str, spot.rgbcurve, spotEdited.rgbcurve); + assignFromKeyfile(keyFile, "Locallab", "LHCurve_" + index_str, spot.LHcurve, spotEdited.LHcurve); + assignFromKeyfile(keyFile, "Locallab", "HHCurve_" + index_str, spot.HHcurve, spotEdited.HHcurve); + assignFromKeyfile(keyFile, "Locallab", "CHCurve_" + index_str, spot.CHcurve, spotEdited.CHcurve); + assignFromKeyfile(keyFile, "Locallab", "Invers_" + index_str, spot.invers, spotEdited.invers); + assignFromKeyfile(keyFile, "Locallab", "Special_" + index_str, spot.special, spotEdited.special); + assignFromKeyfile(keyFile, "Locallab", "Toolcol_" + index_str, spot.toolcol, spotEdited.toolcol); + assignFromKeyfile(keyFile, "Locallab", "EnaColorMask_" + index_str, spot.enaColorMask, spotEdited.enaColorMask); + assignFromKeyfile(keyFile, "Locallab", "FftColorMask_" + index_str, spot.fftColorMask, spotEdited.fftColorMask); + assignFromKeyfile(keyFile, "Locallab", "CCmaskCurve_" + index_str, spot.CCmaskcurve, spotEdited.CCmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskCurve_" + index_str, spot.LLmaskcurve, spotEdited.LLmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskCurve_" + index_str, spot.HHmaskcurve, spotEdited.HHmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "HHhmaskCurve_" + index_str, spot.HHhmaskcurve, spotEdited.HHhmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "Softradiuscol_" + index_str, spot.softradiuscol, spotEdited.softradiuscol); + assignFromKeyfile(keyFile, "Locallab", "Opacol_" + index_str, spot.opacol, spotEdited.opacol); + assignFromKeyfile(keyFile, "Locallab", "Mercol_" + index_str, spot.mercol, spotEdited.mercol); + assignFromKeyfile(keyFile, "Locallab", "Merlucol_" + index_str, spot.merlucol, spotEdited.merlucol); + assignFromKeyfile(keyFile, "Locallab", "Conthrcol_" + index_str, spot.conthrcol, spotEdited.conthrcol); + assignFromKeyfile(keyFile, "Locallab", "LmaskCurve_" + index_str, spot.Lmaskcurve, spotEdited.Lmaskcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskcolCurvewav_" + index_str, spot.LLmaskcolcurvewav, spotEdited.LLmaskcolcurvewav); if (keyFile.has_key("Locallab", "CSThresholdcol_" + index_str)) { const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdcol_" + index_str); @@ -8834,124 +8830,124 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.csthresholdcol = true; } - assignFromKeyfile(keyFile, "Locallab", "Recothresc_" + index_str, pedited, spot.recothresc, spotEdited.recothresc); - assignFromKeyfile(keyFile, "Locallab", "Lowthresc_" + index_str, pedited, spot.lowthresc, spotEdited.lowthresc); - assignFromKeyfile(keyFile, "Locallab", "Higthresc_" + index_str, pedited, spot.higthresc, spotEdited.higthresc); - assignFromKeyfile(keyFile, "Locallab", "Decayc_" + index_str, pedited, spot.decayc, spotEdited.decayc); + assignFromKeyfile(keyFile, "Locallab", "Recothresc_" + index_str, spot.recothresc, spotEdited.recothresc); + assignFromKeyfile(keyFile, "Locallab", "Lowthresc_" + index_str, spot.lowthresc, spotEdited.lowthresc); + assignFromKeyfile(keyFile, "Locallab", "Higthresc_" + index_str, spot.higthresc, spotEdited.higthresc); + assignFromKeyfile(keyFile, "Locallab", "Decayc_" + index_str, spot.decayc, spotEdited.decayc); // Exposure - spot.visiexpose = assignFromKeyfile(keyFile, "Locallab", "Expexpose_" + index_str, pedited, spot.expexpose, spotEdited.expexpose); + spot.visiexpose = assignFromKeyfile(keyFile, "Locallab", "Expexpose_" + index_str, spot.expexpose, spotEdited.expexpose); if (spot.visiexpose) { spotEdited.visiexpose = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexexpose_" + index_str, pedited, spot.complexexpose, spotEdited.complexexpose); - assignFromKeyfile(keyFile, "Locallab", "Expcomp_" + index_str, pedited, spot.expcomp, spotEdited.expcomp); - assignFromKeyfile(keyFile, "Locallab", "Hlcompr_" + index_str, pedited, spot.hlcompr, spotEdited.hlcompr); - assignFromKeyfile(keyFile, "Locallab", "Hlcomprthresh_" + index_str, pedited, spot.hlcomprthresh, spotEdited.hlcomprthresh); - assignFromKeyfile(keyFile, "Locallab", "Black_" + index_str, pedited, spot.black, spotEdited.black); - assignFromKeyfile(keyFile, "Locallab", "Shadex_" + index_str, pedited, spot.shadex, spotEdited.shadex); - assignFromKeyfile(keyFile, "Locallab", "Shcompr_" + index_str, pedited, spot.shcompr, spotEdited.shcompr); - assignFromKeyfile(keyFile, "Locallab", "Expchroma_" + index_str, pedited, spot.expchroma, spotEdited.expchroma); - assignFromKeyfile(keyFile, "Locallab", "Sensiex_" + index_str, pedited, spot.sensiex, spotEdited.sensiex); - assignFromKeyfile(keyFile, "Locallab", "Structexp_" + index_str, pedited, spot.structexp, spotEdited.structexp); - assignFromKeyfile(keyFile, "Locallab", "Blurexpde_" + index_str, pedited, spot.blurexpde, spotEdited.blurexpde); - assignFromKeyfile(keyFile, "Locallab", "Gamex_" + index_str, pedited, spot.gamex, spotEdited.gamex); - assignFromKeyfile(keyFile, "Locallab", "Strexp_" + index_str, pedited, spot.strexp, spotEdited.strexp); - assignFromKeyfile(keyFile, "Locallab", "Angexp_" + index_str, pedited, spot.angexp, spotEdited.angexp); - assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + index_str, pedited, spot.excurve, spotEdited.excurve); - assignFromKeyfile(keyFile, "Locallab", "Norm_" + index_str, pedited, spot.norm, spotEdited.norm); - assignFromKeyfile(keyFile, "Locallab", "Inversex_" + index_str, pedited, spot.inversex, spotEdited.inversex); - assignFromKeyfile(keyFile, "Locallab", "EnaExpMask_" + index_str, pedited, spot.enaExpMask, spotEdited.enaExpMask); - assignFromKeyfile(keyFile, "Locallab", "EnaExpMaskaft_" + index_str, pedited, spot.enaExpMaskaft, spotEdited.enaExpMaskaft); - assignFromKeyfile(keyFile, "Locallab", "CCmaskexpCurve_" + index_str, pedited, spot.CCmaskexpcurve, spotEdited.CCmaskexpcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskexpCurve_" + index_str, pedited, spot.LLmaskexpcurve, spotEdited.LLmaskexpcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskexpCurve_" + index_str, pedited, spot.HHmaskexpcurve, spotEdited.HHmaskexpcurve); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskexp_" + index_str, pedited, spot.blendmaskexp, spotEdited.blendmaskexp); - assignFromKeyfile(keyFile, "Locallab", "Radmaskexp_" + index_str, pedited, spot.radmaskexp, spotEdited.radmaskexp); - assignFromKeyfile(keyFile, "Locallab", "Chromaskexp_" + index_str, pedited, spot.chromaskexp, spotEdited.chromaskexp); - assignFromKeyfile(keyFile, "Locallab", "Gammaskexp_" + index_str, pedited, spot.gammaskexp, spotEdited.gammaskexp); - assignFromKeyfile(keyFile, "Locallab", "Slomaskexp_" + index_str, pedited, spot.slomaskexp, spotEdited.slomaskexp); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskexp_" + index_str, pedited, spot.lapmaskexp, spotEdited.lapmaskexp); - assignFromKeyfile(keyFile, "Locallab", "Strmaskexp_" + index_str, pedited, spot.strmaskexp, spotEdited.strmaskexp); - assignFromKeyfile(keyFile, "Locallab", "Angmaskexp_" + index_str, pedited, spot.angmaskexp, spotEdited.angmaskexp); - assignFromKeyfile(keyFile, "Locallab", "Softradiusexp_" + index_str, pedited, spot.softradiusexp, spotEdited.softradiusexp); - assignFromKeyfile(keyFile, "Locallab", "LmaskexpCurve_" + index_str, pedited, spot.Lmaskexpcurve, spotEdited.Lmaskexpcurve); - assignFromKeyfile(keyFile, "Locallab", "ExpMethod_" + index_str, pedited, spot.expMethod, spotEdited.expMethod); - assignFromKeyfile(keyFile, "Locallab", "ExnoiseMethod_" + index_str, pedited, spot.exnoiseMethod, spotEdited.exnoiseMethod); - assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, pedited, spot.laplacexp, spotEdited.laplacexp); - assignFromKeyfile(keyFile, "Locallab", "Reparexp_" + index_str, pedited, spot.reparexp, spotEdited.reparexp); - assignFromKeyfile(keyFile, "Locallab", "Balanexp_" + index_str, pedited, spot.balanexp, spotEdited.balanexp); - assignFromKeyfile(keyFile, "Locallab", "Linearexp_" + index_str, pedited, spot.linear, spotEdited.linear); - assignFromKeyfile(keyFile, "Locallab", "Gamm_" + index_str, pedited, spot.gamm, spotEdited.gamm); - assignFromKeyfile(keyFile, "Locallab", "Fatamount_" + index_str, pedited, spot.fatamount, spotEdited.fatamount); - assignFromKeyfile(keyFile, "Locallab", "Fatdetail_" + index_str, pedited, spot.fatdetail, spotEdited.fatdetail); - assignFromKeyfile(keyFile, "Locallab", "Fatanchor_" + index_str, pedited, spot.fatanchor, spotEdited.fatanchor); - assignFromKeyfile(keyFile, "Locallab", "Fatlevel_" + index_str, pedited, spot.fatlevel, spotEdited.fatlevel); - assignFromKeyfile(keyFile, "Locallab", "Recothrese_" + index_str, pedited, spot.recothrese, spotEdited.recothrese); - assignFromKeyfile(keyFile, "Locallab", "Lowthrese_" + index_str, pedited, spot.lowthrese, spotEdited.lowthrese); - assignFromKeyfile(keyFile, "Locallab", "Higthrese_" + index_str, pedited, spot.higthrese, spotEdited.higthrese); - assignFromKeyfile(keyFile, "Locallab", "Decaye_" + index_str, pedited, spot.decaye, spotEdited.decaye); + assignFromKeyfile(keyFile, "Locallab", "Complexexpose_" + index_str, spot.complexexpose, spotEdited.complexexpose); + assignFromKeyfile(keyFile, "Locallab", "Expcomp_" + index_str, spot.expcomp, spotEdited.expcomp); + assignFromKeyfile(keyFile, "Locallab", "Hlcompr_" + index_str, spot.hlcompr, spotEdited.hlcompr); + assignFromKeyfile(keyFile, "Locallab", "Hlcomprthresh_" + index_str, spot.hlcomprthresh, spotEdited.hlcomprthresh); + assignFromKeyfile(keyFile, "Locallab", "Black_" + index_str, spot.black, spotEdited.black); + assignFromKeyfile(keyFile, "Locallab", "Shadex_" + index_str, spot.shadex, spotEdited.shadex); + assignFromKeyfile(keyFile, "Locallab", "Shcompr_" + index_str, spot.shcompr, spotEdited.shcompr); + assignFromKeyfile(keyFile, "Locallab", "Expchroma_" + index_str, spot.expchroma, spotEdited.expchroma); + assignFromKeyfile(keyFile, "Locallab", "Sensiex_" + index_str, spot.sensiex, spotEdited.sensiex); + assignFromKeyfile(keyFile, "Locallab", "Structexp_" + index_str, spot.structexp, spotEdited.structexp); + assignFromKeyfile(keyFile, "Locallab", "Blurexpde_" + index_str, spot.blurexpde, spotEdited.blurexpde); + assignFromKeyfile(keyFile, "Locallab", "Gamex_" + index_str, spot.gamex, spotEdited.gamex); + assignFromKeyfile(keyFile, "Locallab", "Strexp_" + index_str, spot.strexp, spotEdited.strexp); + assignFromKeyfile(keyFile, "Locallab", "Angexp_" + index_str, spot.angexp, spotEdited.angexp); + assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + index_str, spot.excurve, spotEdited.excurve); + assignFromKeyfile(keyFile, "Locallab", "Norm_" + index_str, spot.norm, spotEdited.norm); + assignFromKeyfile(keyFile, "Locallab", "Inversex_" + index_str, spot.inversex, spotEdited.inversex); + assignFromKeyfile(keyFile, "Locallab", "EnaExpMask_" + index_str, spot.enaExpMask, spotEdited.enaExpMask); + assignFromKeyfile(keyFile, "Locallab", "EnaExpMaskaft_" + index_str, spot.enaExpMaskaft, spotEdited.enaExpMaskaft); + assignFromKeyfile(keyFile, "Locallab", "CCmaskexpCurve_" + index_str, spot.CCmaskexpcurve, spotEdited.CCmaskexpcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskexpCurve_" + index_str, spot.LLmaskexpcurve, spotEdited.LLmaskexpcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskexpCurve_" + index_str, spot.HHmaskexpcurve, spotEdited.HHmaskexpcurve); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskexp_" + index_str, spot.blendmaskexp, spotEdited.blendmaskexp); + assignFromKeyfile(keyFile, "Locallab", "Radmaskexp_" + index_str, spot.radmaskexp, spotEdited.radmaskexp); + assignFromKeyfile(keyFile, "Locallab", "Chromaskexp_" + index_str, spot.chromaskexp, spotEdited.chromaskexp); + assignFromKeyfile(keyFile, "Locallab", "Gammaskexp_" + index_str, spot.gammaskexp, spotEdited.gammaskexp); + assignFromKeyfile(keyFile, "Locallab", "Slomaskexp_" + index_str, spot.slomaskexp, spotEdited.slomaskexp); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskexp_" + index_str, spot.lapmaskexp, spotEdited.lapmaskexp); + assignFromKeyfile(keyFile, "Locallab", "Strmaskexp_" + index_str, spot.strmaskexp, spotEdited.strmaskexp); + assignFromKeyfile(keyFile, "Locallab", "Angmaskexp_" + index_str, spot.angmaskexp, spotEdited.angmaskexp); + assignFromKeyfile(keyFile, "Locallab", "Softradiusexp_" + index_str, spot.softradiusexp, spotEdited.softradiusexp); + assignFromKeyfile(keyFile, "Locallab", "LmaskexpCurve_" + index_str, spot.Lmaskexpcurve, spotEdited.Lmaskexpcurve); + assignFromKeyfile(keyFile, "Locallab", "ExpMethod_" + index_str, spot.expMethod, spotEdited.expMethod); + assignFromKeyfile(keyFile, "Locallab", "ExnoiseMethod_" + index_str, spot.exnoiseMethod, spotEdited.exnoiseMethod); + assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); + assignFromKeyfile(keyFile, "Locallab", "Reparexp_" + index_str, spot.reparexp, spotEdited.reparexp); + assignFromKeyfile(keyFile, "Locallab", "Balanexp_" + index_str, spot.balanexp, spotEdited.balanexp); + assignFromKeyfile(keyFile, "Locallab", "Linearexp_" + index_str, spot.linear, spotEdited.linear); + assignFromKeyfile(keyFile, "Locallab", "Gamm_" + index_str, spot.gamm, spotEdited.gamm); + assignFromKeyfile(keyFile, "Locallab", "Fatamount_" + index_str, spot.fatamount, spotEdited.fatamount); + assignFromKeyfile(keyFile, "Locallab", "Fatdetail_" + index_str, spot.fatdetail, spotEdited.fatdetail); + assignFromKeyfile(keyFile, "Locallab", "Fatanchor_" + index_str, spot.fatanchor, spotEdited.fatanchor); + assignFromKeyfile(keyFile, "Locallab", "Fatlevel_" + index_str, spot.fatlevel, spotEdited.fatlevel); + assignFromKeyfile(keyFile, "Locallab", "Recothrese_" + index_str, spot.recothrese, spotEdited.recothrese); + assignFromKeyfile(keyFile, "Locallab", "Lowthrese_" + index_str, spot.lowthrese, spotEdited.lowthrese); + assignFromKeyfile(keyFile, "Locallab", "Higthrese_" + index_str, spot.higthrese, spotEdited.higthrese); + assignFromKeyfile(keyFile, "Locallab", "Decaye_" + index_str, spot.decaye, spotEdited.decaye); // Shadow highlight - spot.visishadhigh = assignFromKeyfile(keyFile, "Locallab", "Expshadhigh_" + index_str, pedited, spot.expshadhigh, spotEdited.expshadhigh); + spot.visishadhigh = assignFromKeyfile(keyFile, "Locallab", "Expshadhigh_" + index_str, spot.expshadhigh, spotEdited.expshadhigh); if (spot.visishadhigh) { spotEdited.visishadhigh = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexshadhigh_" + index_str, pedited, spot.complexshadhigh, spotEdited.complexshadhigh); - assignFromKeyfile(keyFile, "Locallab", "ShMethod_" + index_str, pedited, spot.shMethod, spotEdited.shMethod); + assignFromKeyfile(keyFile, "Locallab", "Complexshadhigh_" + index_str, spot.complexshadhigh, spotEdited.complexshadhigh); + assignFromKeyfile(keyFile, "Locallab", "ShMethod_" + index_str, spot.shMethod, spotEdited.shMethod); for (int j = 0; j < 5; j ++) { - assignFromKeyfile(keyFile, "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, pedited, spot.multsh[j], spotEdited.multsh[j]); + assignFromKeyfile(keyFile, "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, spot.multsh[j], spotEdited.multsh[j]); } - assignFromKeyfile(keyFile, "Locallab", "Expshadhigh_" + index_str, pedited, spot.expshadhigh, spotEdited.expshadhigh); - assignFromKeyfile(keyFile, "Locallab", "highlights_" + index_str, pedited, spot.highlights, spotEdited.highlights); - assignFromKeyfile(keyFile, "Locallab", "h_tonalwidth_" + index_str, pedited, spot.h_tonalwidth, spotEdited.h_tonalwidth); - assignFromKeyfile(keyFile, "Locallab", "shadows_" + index_str, pedited, spot.shadows, spotEdited.shadows); - assignFromKeyfile(keyFile, "Locallab", "s_tonalwidth_" + index_str, pedited, spot.s_tonalwidth, spotEdited.s_tonalwidth); - assignFromKeyfile(keyFile, "Locallab", "sh_radius_" + index_str, pedited, spot.sh_radius, spotEdited.sh_radius); - assignFromKeyfile(keyFile, "Locallab", "sensihs_" + index_str, pedited, spot.sensihs, spotEdited.sensihs); - assignFromKeyfile(keyFile, "Locallab", "EnaSHMask_" + index_str, pedited, spot.enaSHMask, spotEdited.enaSHMask); - assignFromKeyfile(keyFile, "Locallab", "CCmaskSHCurve_" + index_str, pedited, spot.CCmaskSHcurve, spotEdited.CCmaskSHcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskSHCurve_" + index_str, pedited, spot.LLmaskSHcurve, spotEdited.LLmaskSHcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskSHCurve_" + index_str, pedited, spot.HHmaskSHcurve, spotEdited.HHmaskSHcurve); - assignFromKeyfile(keyFile, "Locallab", "BlendmaskSH_" + index_str, pedited, spot.blendmaskSH, spotEdited.blendmaskSH); - assignFromKeyfile(keyFile, "Locallab", "RadmaskSH_" + index_str, pedited, spot.radmaskSH, spotEdited.radmaskSH); - assignFromKeyfile(keyFile, "Locallab", "BlurSHde_" + index_str, pedited, spot.blurSHde, spotEdited.blurSHde); - assignFromKeyfile(keyFile, "Locallab", "StrSH_" + index_str, pedited, spot.strSH, spotEdited.strSH); - assignFromKeyfile(keyFile, "Locallab", "AngSH_" + index_str, pedited, spot.angSH, spotEdited.angSH); - assignFromKeyfile(keyFile, "Locallab", "Inverssh_" + index_str, pedited, spot.inverssh, spotEdited.inverssh); - assignFromKeyfile(keyFile, "Locallab", "ChromaskSH_" + index_str, pedited, spot.chromaskSH, spotEdited.chromaskSH); - assignFromKeyfile(keyFile, "Locallab", "GammaskSH_" + index_str, pedited, spot.gammaskSH, spotEdited.gammaskSH); - assignFromKeyfile(keyFile, "Locallab", "SlomaskSH_" + index_str, pedited, spot.slomaskSH, spotEdited.slomaskSH); - assignFromKeyfile(keyFile, "Locallab", "LapmaskSH_" + index_str, pedited, spot.lapmaskSH, spotEdited.lapmaskSH); - assignFromKeyfile(keyFile, "Locallab", "DetailSH_" + index_str, pedited, spot.detailSH, spotEdited.detailSH); - assignFromKeyfile(keyFile, "Locallab", "TePivot_" + index_str, pedited, spot.tePivot, spotEdited.tePivot); - assignFromKeyfile(keyFile, "Locallab", "Reparsh_" + index_str, pedited, spot.reparsh, spotEdited.reparsh); - assignFromKeyfile(keyFile, "Locallab", "LmaskSHCurve_" + index_str, pedited, spot.LmaskSHcurve, spotEdited.LmaskSHcurve); - assignFromKeyfile(keyFile, "Locallab", "FatamountSH_" + index_str, pedited, spot.fatamountSH, spotEdited.fatamountSH); - assignFromKeyfile(keyFile, "Locallab", "FatanchorSH_" + index_str, pedited, spot.fatanchorSH, spotEdited.fatanchorSH); - assignFromKeyfile(keyFile, "Locallab", "GamSH_" + index_str, pedited, spot.gamSH, spotEdited.gamSH); - assignFromKeyfile(keyFile, "Locallab", "SloSH_" + index_str, pedited, spot.sloSH, spotEdited.sloSH); - assignFromKeyfile(keyFile, "Locallab", "Recothress_" + index_str, pedited, spot.recothress, spotEdited.recothress); - assignFromKeyfile(keyFile, "Locallab", "Lowthress_" + index_str, pedited, spot.lowthress, spotEdited.lowthress); - assignFromKeyfile(keyFile, "Locallab", "Higthress_" + index_str, pedited, spot.higthress, spotEdited.higthress); - assignFromKeyfile(keyFile, "Locallab", "Decays_" + index_str, pedited, spot.decays, spotEdited.decays); + assignFromKeyfile(keyFile, "Locallab", "Expshadhigh_" + index_str, spot.expshadhigh, spotEdited.expshadhigh); + assignFromKeyfile(keyFile, "Locallab", "highlights_" + index_str, spot.highlights, spotEdited.highlights); + assignFromKeyfile(keyFile, "Locallab", "h_tonalwidth_" + index_str, spot.h_tonalwidth, spotEdited.h_tonalwidth); + assignFromKeyfile(keyFile, "Locallab", "shadows_" + index_str, spot.shadows, spotEdited.shadows); + assignFromKeyfile(keyFile, "Locallab", "s_tonalwidth_" + index_str, spot.s_tonalwidth, spotEdited.s_tonalwidth); + assignFromKeyfile(keyFile, "Locallab", "sh_radius_" + index_str, spot.sh_radius, spotEdited.sh_radius); + assignFromKeyfile(keyFile, "Locallab", "sensihs_" + index_str, spot.sensihs, spotEdited.sensihs); + assignFromKeyfile(keyFile, "Locallab", "EnaSHMask_" + index_str, spot.enaSHMask, spotEdited.enaSHMask); + assignFromKeyfile(keyFile, "Locallab", "CCmaskSHCurve_" + index_str, spot.CCmaskSHcurve, spotEdited.CCmaskSHcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskSHCurve_" + index_str, spot.LLmaskSHcurve, spotEdited.LLmaskSHcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskSHCurve_" + index_str, spot.HHmaskSHcurve, spotEdited.HHmaskSHcurve); + assignFromKeyfile(keyFile, "Locallab", "BlendmaskSH_" + index_str, spot.blendmaskSH, spotEdited.blendmaskSH); + assignFromKeyfile(keyFile, "Locallab", "RadmaskSH_" + index_str, spot.radmaskSH, spotEdited.radmaskSH); + assignFromKeyfile(keyFile, "Locallab", "BlurSHde_" + index_str, spot.blurSHde, spotEdited.blurSHde); + assignFromKeyfile(keyFile, "Locallab", "StrSH_" + index_str, spot.strSH, spotEdited.strSH); + assignFromKeyfile(keyFile, "Locallab", "AngSH_" + index_str, spot.angSH, spotEdited.angSH); + assignFromKeyfile(keyFile, "Locallab", "Inverssh_" + index_str, spot.inverssh, spotEdited.inverssh); + assignFromKeyfile(keyFile, "Locallab", "ChromaskSH_" + index_str, spot.chromaskSH, spotEdited.chromaskSH); + assignFromKeyfile(keyFile, "Locallab", "GammaskSH_" + index_str, spot.gammaskSH, spotEdited.gammaskSH); + assignFromKeyfile(keyFile, "Locallab", "SlomaskSH_" + index_str, spot.slomaskSH, spotEdited.slomaskSH); + assignFromKeyfile(keyFile, "Locallab", "LapmaskSH_" + index_str, spot.lapmaskSH, spotEdited.lapmaskSH); + assignFromKeyfile(keyFile, "Locallab", "DetailSH_" + index_str, spot.detailSH, spotEdited.detailSH); + assignFromKeyfile(keyFile, "Locallab", "TePivot_" + index_str, spot.tePivot, spotEdited.tePivot); + assignFromKeyfile(keyFile, "Locallab", "Reparsh_" + index_str, spot.reparsh, spotEdited.reparsh); + assignFromKeyfile(keyFile, "Locallab", "LmaskSHCurve_" + index_str, spot.LmaskSHcurve, spotEdited.LmaskSHcurve); + assignFromKeyfile(keyFile, "Locallab", "FatamountSH_" + index_str, spot.fatamountSH, spotEdited.fatamountSH); + assignFromKeyfile(keyFile, "Locallab", "FatanchorSH_" + index_str, spot.fatanchorSH, spotEdited.fatanchorSH); + assignFromKeyfile(keyFile, "Locallab", "GamSH_" + index_str, spot.gamSH, spotEdited.gamSH); + assignFromKeyfile(keyFile, "Locallab", "SloSH_" + index_str, spot.sloSH, spotEdited.sloSH); + assignFromKeyfile(keyFile, "Locallab", "Recothress_" + index_str, spot.recothress, spotEdited.recothress); + assignFromKeyfile(keyFile, "Locallab", "Lowthress_" + index_str, spot.lowthress, spotEdited.lowthress); + assignFromKeyfile(keyFile, "Locallab", "Higthress_" + index_str, spot.higthress, spotEdited.higthress); + assignFromKeyfile(keyFile, "Locallab", "Decays_" + index_str, spot.decays, spotEdited.decays); // Vibrance - spot.visivibrance = assignFromKeyfile(keyFile, "Locallab", "Expvibrance_" + index_str, pedited, spot.expvibrance, spotEdited.expvibrance); + spot.visivibrance = assignFromKeyfile(keyFile, "Locallab", "Expvibrance_" + index_str, spot.expvibrance, spotEdited.expvibrance); if (spot.visivibrance) { spotEdited.visivibrance = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexvibrance_" + index_str, pedited, spot.complexvibrance, spotEdited.complexvibrance); - assignFromKeyfile(keyFile, "Locallab", "Saturated_" + index_str, pedited, spot.saturated, spotEdited.saturated); - assignFromKeyfile(keyFile, "Locallab", "Pastels_" + index_str, pedited, spot.pastels, spotEdited.pastels); - assignFromKeyfile(keyFile, "Locallab", "Vibgam_" + index_str, pedited, spot.vibgam, spotEdited.vibgam); - assignFromKeyfile(keyFile, "Locallab", "Warm_" + index_str, pedited, spot.warm, spotEdited.warm); + assignFromKeyfile(keyFile, "Locallab", "Complexvibrance_" + index_str, spot.complexvibrance, spotEdited.complexvibrance); + assignFromKeyfile(keyFile, "Locallab", "Saturated_" + index_str, spot.saturated, spotEdited.saturated); + assignFromKeyfile(keyFile, "Locallab", "Pastels_" + index_str, spot.pastels, spotEdited.pastels); + assignFromKeyfile(keyFile, "Locallab", "Vibgam_" + index_str, spot.vibgam, spotEdited.vibgam); + assignFromKeyfile(keyFile, "Locallab", "Warm_" + index_str, spot.warm, spotEdited.warm); if (keyFile.has_key("Locallab", "PSThreshold_" + index_str)) { const std::vector thresh = keyFile.get_integer_list("Locallab", "PSThreshold_" + index_str); @@ -8963,123 +8959,123 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.psthreshold = true; } - assignFromKeyfile(keyFile, "Locallab", "ProtectSkins_" + index_str, pedited, spot.protectskins, spotEdited.protectskins); - assignFromKeyfile(keyFile, "Locallab", "AvoidColorShift_" + index_str, pedited, spot.avoidcolorshift, spotEdited.avoidcolorshift); - assignFromKeyfile(keyFile, "Locallab", "PastSatTog_" + index_str, pedited, spot.pastsattog, spotEdited.pastsattog); - assignFromKeyfile(keyFile, "Locallab", "Sensiv_" + index_str, pedited, spot.sensiv, spotEdited.sensiv); - assignFromKeyfile(keyFile, "Locallab", "SkinTonesCurve_" + index_str, pedited, spot.skintonescurve, spotEdited.skintonescurve); - assignFromKeyfile(keyFile, "Locallab", "CCmaskvibCurve_" + index_str, pedited, spot.CCmaskvibcurve, spotEdited.CCmaskvibcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskvibCurve_" + index_str, pedited, spot.LLmaskvibcurve, spotEdited.LLmaskvibcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskvibCurve_" + index_str, pedited, spot.HHmaskvibcurve, spotEdited.HHmaskvibcurve); - assignFromKeyfile(keyFile, "Locallab", "EnavibMask_" + index_str, pedited, spot.enavibMask, spotEdited.enavibMask); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskvib_" + index_str, pedited, spot.blendmaskvib, spotEdited.blendmaskvib); - assignFromKeyfile(keyFile, "Locallab", "Radmaskvib_" + index_str, pedited, spot.radmaskvib, spotEdited.radmaskvib); - assignFromKeyfile(keyFile, "Locallab", "Chromaskvib_" + index_str, pedited, spot.chromaskvib, spotEdited.chromaskvib); - assignFromKeyfile(keyFile, "Locallab", "Gammaskvib_" + index_str, pedited, spot.gammaskvib, spotEdited.gammaskvib); - assignFromKeyfile(keyFile, "Locallab", "Slomaskvib_" + index_str, pedited, spot.slomaskvib, spotEdited.slomaskvib); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskvib_" + index_str, pedited, spot.lapmaskvib, spotEdited.lapmaskvib); - assignFromKeyfile(keyFile, "Locallab", "Strvib_" + index_str, pedited, spot.strvib, spotEdited.strvib); - assignFromKeyfile(keyFile, "Locallab", "Strvibab_" + index_str, pedited, spot.strvibab, spotEdited.strvibab); - assignFromKeyfile(keyFile, "Locallab", "Strvibh_" + index_str, pedited, spot.strvibh, spotEdited.strvibh); - assignFromKeyfile(keyFile, "Locallab", "Angvib_" + index_str, pedited, spot.angvib, spotEdited.angvib); - assignFromKeyfile(keyFile, "Locallab", "LmaskvibCurve_" + index_str, pedited, spot.Lmaskvibcurve, spotEdited.Lmaskvibcurve); - assignFromKeyfile(keyFile, "Locallab", "Recothresv_" + index_str, pedited, spot.recothresv, spotEdited.recothresv); - assignFromKeyfile(keyFile, "Locallab", "Lowthresv_" + index_str, pedited, spot.lowthresv, spotEdited.lowthresv); - assignFromKeyfile(keyFile, "Locallab", "Higthresv_" + index_str, pedited, spot.higthresv, spotEdited.higthresv); - assignFromKeyfile(keyFile, "Locallab", "Decayv_" + index_str, pedited, spot.decayv, spotEdited.decayv); + assignFromKeyfile(keyFile, "Locallab", "ProtectSkins_" + index_str, spot.protectskins, spotEdited.protectskins); + assignFromKeyfile(keyFile, "Locallab", "AvoidColorShift_" + index_str, spot.avoidcolorshift, spotEdited.avoidcolorshift); + assignFromKeyfile(keyFile, "Locallab", "PastSatTog_" + index_str, spot.pastsattog, spotEdited.pastsattog); + assignFromKeyfile(keyFile, "Locallab", "Sensiv_" + index_str, spot.sensiv, spotEdited.sensiv); + assignFromKeyfile(keyFile, "Locallab", "SkinTonesCurve_" + index_str, spot.skintonescurve, spotEdited.skintonescurve); + assignFromKeyfile(keyFile, "Locallab", "CCmaskvibCurve_" + index_str, spot.CCmaskvibcurve, spotEdited.CCmaskvibcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskvibCurve_" + index_str, spot.LLmaskvibcurve, spotEdited.LLmaskvibcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskvibCurve_" + index_str, spot.HHmaskvibcurve, spotEdited.HHmaskvibcurve); + assignFromKeyfile(keyFile, "Locallab", "EnavibMask_" + index_str, spot.enavibMask, spotEdited.enavibMask); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskvib_" + index_str, spot.blendmaskvib, spotEdited.blendmaskvib); + assignFromKeyfile(keyFile, "Locallab", "Radmaskvib_" + index_str, spot.radmaskvib, spotEdited.radmaskvib); + assignFromKeyfile(keyFile, "Locallab", "Chromaskvib_" + index_str, spot.chromaskvib, spotEdited.chromaskvib); + assignFromKeyfile(keyFile, "Locallab", "Gammaskvib_" + index_str, spot.gammaskvib, spotEdited.gammaskvib); + assignFromKeyfile(keyFile, "Locallab", "Slomaskvib_" + index_str, spot.slomaskvib, spotEdited.slomaskvib); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskvib_" + index_str, spot.lapmaskvib, spotEdited.lapmaskvib); + assignFromKeyfile(keyFile, "Locallab", "Strvib_" + index_str, spot.strvib, spotEdited.strvib); + assignFromKeyfile(keyFile, "Locallab", "Strvibab_" + index_str, spot.strvibab, spotEdited.strvibab); + assignFromKeyfile(keyFile, "Locallab", "Strvibh_" + index_str, spot.strvibh, spotEdited.strvibh); + assignFromKeyfile(keyFile, "Locallab", "Angvib_" + index_str, spot.angvib, spotEdited.angvib); + assignFromKeyfile(keyFile, "Locallab", "LmaskvibCurve_" + index_str, spot.Lmaskvibcurve, spotEdited.Lmaskvibcurve); + assignFromKeyfile(keyFile, "Locallab", "Recothresv_" + index_str, spot.recothresv, spotEdited.recothresv); + assignFromKeyfile(keyFile, "Locallab", "Lowthresv_" + index_str, spot.lowthresv, spotEdited.lowthresv); + assignFromKeyfile(keyFile, "Locallab", "Higthresv_" + index_str, spot.higthresv, spotEdited.higthresv); + assignFromKeyfile(keyFile, "Locallab", "Decayv_" + index_str, spot.decayv, spotEdited.decayv); // Soft Light - spot.visisoft = assignFromKeyfile(keyFile, "Locallab", "Expsoft_" + index_str, pedited, spot.expsoft, spotEdited.expsoft); + spot.visisoft = assignFromKeyfile(keyFile, "Locallab", "Expsoft_" + index_str, spot.expsoft, spotEdited.expsoft); if (spot.visisoft) { spotEdited.visisoft = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexsoft_" + index_str, pedited, spot.complexsoft, spotEdited.complexsoft); - assignFromKeyfile(keyFile, "Locallab", "Streng_" + index_str, pedited, spot.streng, spotEdited.streng); - assignFromKeyfile(keyFile, "Locallab", "Sensisf_" + index_str, pedited, spot.sensisf, spotEdited.sensisf); - assignFromKeyfile(keyFile, "Locallab", "Laplace_" + index_str, pedited, spot.laplace, spotEdited.laplace); - assignFromKeyfile(keyFile, "Locallab", "SoftMethod_" + index_str, pedited, spot.softMethod, spotEdited.softMethod); + assignFromKeyfile(keyFile, "Locallab", "Complexsoft_" + index_str, spot.complexsoft, spotEdited.complexsoft); + assignFromKeyfile(keyFile, "Locallab", "Streng_" + index_str, spot.streng, spotEdited.streng); + assignFromKeyfile(keyFile, "Locallab", "Sensisf_" + index_str, spot.sensisf, spotEdited.sensisf); + assignFromKeyfile(keyFile, "Locallab", "Laplace_" + index_str, spot.laplace, spotEdited.laplace); + assignFromKeyfile(keyFile, "Locallab", "SoftMethod_" + index_str, spot.softMethod, spotEdited.softMethod); // Blur & Noise - spot.visiblur = assignFromKeyfile(keyFile, "Locallab", "Expblur_" + index_str, pedited, spot.expblur, spotEdited.expblur); + spot.visiblur = assignFromKeyfile(keyFile, "Locallab", "Expblur_" + index_str, spot.expblur, spotEdited.expblur); if (spot.visiblur) { spotEdited.visiblur = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexblur_" + index_str, pedited, spot.complexblur, spotEdited.complexblur); - assignFromKeyfile(keyFile, "Locallab", "Radius_" + index_str, pedited, spot.radius, spotEdited.radius); - assignFromKeyfile(keyFile, "Locallab", "Strength_" + index_str, pedited, spot.strength, spotEdited.strength); - assignFromKeyfile(keyFile, "Locallab", "Sensibn_" + index_str, pedited, spot.sensibn, spotEdited.sensibn); - assignFromKeyfile(keyFile, "Locallab", "Iteramed_" + index_str, pedited, spot.itera, spotEdited.itera); - assignFromKeyfile(keyFile, "Locallab", "Guidbl_" + index_str, pedited, spot.guidbl, spotEdited.guidbl); - assignFromKeyfile(keyFile, "Locallab", "Strbl_" + index_str, pedited, spot.strbl, spotEdited.strbl); - assignFromKeyfile(keyFile, "Locallab", "Recothres_" + index_str, pedited, spot.recothres, spotEdited.recothres); - assignFromKeyfile(keyFile, "Locallab", "Lowthres_" + index_str, pedited, spot.lowthres, spotEdited.lowthres); - assignFromKeyfile(keyFile, "Locallab", "Higthres_" + index_str, pedited, spot.higthres, spotEdited.higthres); - assignFromKeyfile(keyFile, "Locallab", "Recothresd_" + index_str, pedited, spot.recothresd, spotEdited.recothresd); - assignFromKeyfile(keyFile, "Locallab", "Lowthresd_" + index_str, pedited, spot.lowthresd, spotEdited.lowthresd); - assignFromKeyfile(keyFile, "Locallab", "Midthresd_" + index_str, pedited, spot.midthresd, spotEdited.midthresd); - assignFromKeyfile(keyFile, "Locallab", "Midthresdch_" + index_str, pedited, spot.midthresdch, spotEdited.midthresdch); - assignFromKeyfile(keyFile, "Locallab", "Higthresd_" + index_str, pedited, spot.higthresd, spotEdited.higthresd); - assignFromKeyfile(keyFile, "Locallab", "Decayd_" + index_str, pedited, spot.decayd, spotEdited.decayd); - assignFromKeyfile(keyFile, "Locallab", "Isogr_" + index_str, pedited, spot.isogr, spotEdited.isogr); - assignFromKeyfile(keyFile, "Locallab", "Strengr_" + index_str, pedited, spot.strengr, spotEdited.strengr); - assignFromKeyfile(keyFile, "Locallab", "Scalegr_" + index_str, pedited, spot.scalegr, spotEdited.scalegr); - assignFromKeyfile(keyFile, "Locallab", "Divgr_" + index_str, pedited, spot.divgr, spotEdited.divgr); - assignFromKeyfile(keyFile, "Locallab", "Epsbl_" + index_str, pedited, spot.epsbl, spotEdited.epsbl); - assignFromKeyfile(keyFile, "Locallab", "BlMethod_" + index_str, pedited, spot.blMethod, spotEdited.blMethod); - assignFromKeyfile(keyFile, "Locallab", "ChroMethod_" + index_str, pedited, spot.chroMethod, spotEdited.chroMethod); - assignFromKeyfile(keyFile, "Locallab", "QuaMethod_" + index_str, pedited, spot.quamethod, spotEdited.quamethod); - assignFromKeyfile(keyFile, "Locallab", "BlurMethod_" + index_str, pedited, spot.blurMethod, spotEdited.blurMethod); - assignFromKeyfile(keyFile, "Locallab", "Usemaskb_" + index_str, pedited, spot.usemask, spotEdited.usemask); - assignFromKeyfile(keyFile, "Locallab", "Invmaskd_" + index_str, pedited, spot.invmaskd, spotEdited.invmaskd); - assignFromKeyfile(keyFile, "Locallab", "Invmask_" + index_str, pedited, spot.invmask, spotEdited.invmask); - assignFromKeyfile(keyFile, "Locallab", "Levelthr_" + index_str, pedited, spot.levelthr, spotEdited.levelthr); - assignFromKeyfile(keyFile, "Locallab", "Lnoiselow_" + index_str, pedited, spot.lnoiselow, spotEdited.lnoiselow); - assignFromKeyfile(keyFile, "Locallab", "Levelthrlow_" + index_str, pedited, spot.levelthrlow, spotEdited.levelthrlow); - assignFromKeyfile(keyFile, "Locallab", "MedMethod_" + index_str, pedited, spot.medMethod, spotEdited.medMethod); - assignFromKeyfile(keyFile, "Locallab", "activlum_" + index_str, pedited, spot.activlum, spotEdited.activlum); - assignFromKeyfile(keyFile, "Locallab", "noiselumf_" + index_str, pedited, spot.noiselumf, spotEdited.noiselumf); - assignFromKeyfile(keyFile, "Locallab", "noiselumf0_" + index_str, pedited, spot.noiselumf0, spotEdited.noiselumf0); - assignFromKeyfile(keyFile, "Locallab", "noiselumf2_" + index_str, pedited, spot.noiselumf2, spotEdited.noiselumf2); - assignFromKeyfile(keyFile, "Locallab", "noiselumc_" + index_str, pedited, spot.noiselumc, spotEdited.noiselumc); - assignFromKeyfile(keyFile, "Locallab", "noiselumdetail_" + index_str, pedited, spot.noiselumdetail, spotEdited.noiselumdetail); - assignFromKeyfile(keyFile, "Locallab", "noiselequal_" + index_str, pedited, spot.noiselequal, spotEdited.noiselequal); - assignFromKeyfile(keyFile, "Locallab", "noisegam_" + index_str, pedited, spot.noisegam, spotEdited.noisegam); - assignFromKeyfile(keyFile, "Locallab", "noisechrof_" + index_str, pedited, spot.noisechrof, spotEdited.noisechrof); - assignFromKeyfile(keyFile, "Locallab", "noisechroc_" + index_str, pedited, spot.noisechroc, spotEdited.noisechroc); - assignFromKeyfile(keyFile, "Locallab", "noisechrodetail_" + index_str, pedited, spot.noisechrodetail, spotEdited.noisechrodetail); - assignFromKeyfile(keyFile, "Locallab", "Adjblur_" + index_str, pedited, spot.adjblur, spotEdited.adjblur); - assignFromKeyfile(keyFile, "Locallab", "Bilateral_" + index_str, pedited, spot.bilateral, spotEdited.bilateral); - assignFromKeyfile(keyFile, "Locallab", "Nlstr_" + index_str, pedited, spot.nlstr, spotEdited.nlstr); - assignFromKeyfile(keyFile, "Locallab", "Nldet_" + index_str, pedited, spot.nldet, spotEdited.nldet); - assignFromKeyfile(keyFile, "Locallab", "Nlpat_" + index_str, pedited, spot.nlpat, spotEdited.nlpat); - assignFromKeyfile(keyFile, "Locallab", "Nlrad_" + index_str, pedited, spot.nlrad, spotEdited.nlrad); - assignFromKeyfile(keyFile, "Locallab", "Nlgam_" + index_str, pedited, spot.nlgam, spotEdited.nlgam); - assignFromKeyfile(keyFile, "Locallab", "Sensiden_" + index_str, pedited, spot.sensiden, spotEdited.sensiden); - assignFromKeyfile(keyFile, "Locallab", "Reparden_" + index_str, pedited, spot.reparden, spotEdited.reparden); - assignFromKeyfile(keyFile, "Locallab", "Detailthr_" + index_str, pedited, spot.detailthr, spotEdited.detailthr); - assignFromKeyfile(keyFile, "Locallab", "LocwavCurveden_" + index_str, pedited, spot.locwavcurveden, spotEdited.locwavcurveden); - assignFromKeyfile(keyFile, "Locallab", "LocwavCurvehue_" + index_str, pedited, spot.locwavcurvehue, spotEdited.locwavcurvehue); - assignFromKeyfile(keyFile, "Locallab", "Showmasktyp_" + index_str, pedited, spot.showmaskblMethodtyp, spotEdited.showmaskblMethodtyp); - assignFromKeyfile(keyFile, "Locallab", "CCmaskblCurve_" + index_str, pedited, spot.CCmaskblcurve, spotEdited.CCmaskblcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskblCurve_" + index_str, pedited, spot.LLmaskblcurve, spotEdited.LLmaskblcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskblCurve_" + index_str, pedited, spot.HHmaskblcurve, spotEdited.HHmaskblcurve); - assignFromKeyfile(keyFile, "Locallab", "EnablMask_" + index_str, pedited, spot.enablMask, spotEdited.enablMask); - assignFromKeyfile(keyFile, "Locallab", "Fftwbl_" + index_str, pedited, spot.fftwbl, spotEdited.fftwbl); - assignFromKeyfile(keyFile, "Locallab", "Invbl_" + index_str, pedited, spot.invbl, spotEdited.invbl); - assignFromKeyfile(keyFile, "Locallab", "Toolbl_" + index_str, pedited, spot.toolbl, spotEdited.toolbl); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskbl_" + index_str, pedited, spot.blendmaskbl, spotEdited.blendmaskbl); - assignFromKeyfile(keyFile, "Locallab", "Radmaskbl_" + index_str, pedited, spot.radmaskbl, spotEdited.radmaskbl); - assignFromKeyfile(keyFile, "Locallab", "Chromaskbl_" + index_str, pedited, spot.chromaskbl, spotEdited.chromaskbl); - assignFromKeyfile(keyFile, "Locallab", "Gammaskbl_" + index_str, pedited, spot.gammaskbl, spotEdited.gammaskbl); - assignFromKeyfile(keyFile, "Locallab", "Slomaskbl_" + index_str, pedited, spot.slomaskbl, spotEdited.slomaskbl); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskbl_" + index_str, pedited, spot.lapmaskbl, spotEdited.lapmaskbl); - assignFromKeyfile(keyFile, "Locallab", "shadmaskbl_" + index_str, pedited, spot.shadmaskbl, spotEdited.shadmaskbl); - assignFromKeyfile(keyFile, "Locallab", "shadmaskblsha_" + index_str, pedited, spot.shadmaskblsha, spotEdited.shadmaskblsha); - assignFromKeyfile(keyFile, "Locallab", "strumaskbl_" + index_str, pedited, spot.strumaskbl, spotEdited.strumaskbl); - assignFromKeyfile(keyFile, "Locallab", "LmaskblCurve_" + index_str, pedited, spot.Lmaskblcurve, spotEdited.Lmaskblcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskblCurvewav_" + index_str, pedited, spot.LLmaskblcurvewav, spotEdited.LLmaskblcurvewav); + assignFromKeyfile(keyFile, "Locallab", "Complexblur_" + index_str, spot.complexblur, spotEdited.complexblur); + assignFromKeyfile(keyFile, "Locallab", "Radius_" + index_str, spot.radius, spotEdited.radius); + assignFromKeyfile(keyFile, "Locallab", "Strength_" + index_str, spot.strength, spotEdited.strength); + assignFromKeyfile(keyFile, "Locallab", "Sensibn_" + index_str, spot.sensibn, spotEdited.sensibn); + assignFromKeyfile(keyFile, "Locallab", "Iteramed_" + index_str, spot.itera, spotEdited.itera); + assignFromKeyfile(keyFile, "Locallab", "Guidbl_" + index_str, spot.guidbl, spotEdited.guidbl); + assignFromKeyfile(keyFile, "Locallab", "Strbl_" + index_str, spot.strbl, spotEdited.strbl); + assignFromKeyfile(keyFile, "Locallab", "Recothres_" + index_str, spot.recothres, spotEdited.recothres); + assignFromKeyfile(keyFile, "Locallab", "Lowthres_" + index_str, spot.lowthres, spotEdited.lowthres); + assignFromKeyfile(keyFile, "Locallab", "Higthres_" + index_str, spot.higthres, spotEdited.higthres); + assignFromKeyfile(keyFile, "Locallab", "Recothresd_" + index_str, spot.recothresd, spotEdited.recothresd); + assignFromKeyfile(keyFile, "Locallab", "Lowthresd_" + index_str, spot.lowthresd, spotEdited.lowthresd); + assignFromKeyfile(keyFile, "Locallab", "Midthresd_" + index_str, spot.midthresd, spotEdited.midthresd); + assignFromKeyfile(keyFile, "Locallab", "Midthresdch_" + index_str, spot.midthresdch, spotEdited.midthresdch); + assignFromKeyfile(keyFile, "Locallab", "Higthresd_" + index_str, spot.higthresd, spotEdited.higthresd); + assignFromKeyfile(keyFile, "Locallab", "Decayd_" + index_str, spot.decayd, spotEdited.decayd); + assignFromKeyfile(keyFile, "Locallab", "Isogr_" + index_str, spot.isogr, spotEdited.isogr); + assignFromKeyfile(keyFile, "Locallab", "Strengr_" + index_str, spot.strengr, spotEdited.strengr); + assignFromKeyfile(keyFile, "Locallab", "Scalegr_" + index_str, spot.scalegr, spotEdited.scalegr); + assignFromKeyfile(keyFile, "Locallab", "Divgr_" + index_str, spot.divgr, spotEdited.divgr); + assignFromKeyfile(keyFile, "Locallab", "Epsbl_" + index_str, spot.epsbl, spotEdited.epsbl); + assignFromKeyfile(keyFile, "Locallab", "BlMethod_" + index_str, spot.blMethod, spotEdited.blMethod); + assignFromKeyfile(keyFile, "Locallab", "ChroMethod_" + index_str, spot.chroMethod, spotEdited.chroMethod); + assignFromKeyfile(keyFile, "Locallab", "QuaMethod_" + index_str, spot.quamethod, spotEdited.quamethod); + assignFromKeyfile(keyFile, "Locallab", "BlurMethod_" + index_str, spot.blurMethod, spotEdited.blurMethod); + assignFromKeyfile(keyFile, "Locallab", "Usemaskb_" + index_str, spot.usemask, spotEdited.usemask); + assignFromKeyfile(keyFile, "Locallab", "Invmaskd_" + index_str, spot.invmaskd, spotEdited.invmaskd); + assignFromKeyfile(keyFile, "Locallab", "Invmask_" + index_str, spot.invmask, spotEdited.invmask); + assignFromKeyfile(keyFile, "Locallab", "Levelthr_" + index_str, spot.levelthr, spotEdited.levelthr); + assignFromKeyfile(keyFile, "Locallab", "Lnoiselow_" + index_str, spot.lnoiselow, spotEdited.lnoiselow); + assignFromKeyfile(keyFile, "Locallab", "Levelthrlow_" + index_str, spot.levelthrlow, spotEdited.levelthrlow); + assignFromKeyfile(keyFile, "Locallab", "MedMethod_" + index_str, spot.medMethod, spotEdited.medMethod); + assignFromKeyfile(keyFile, "Locallab", "activlum_" + index_str, spot.activlum, spotEdited.activlum); + assignFromKeyfile(keyFile, "Locallab", "noiselumf_" + index_str, spot.noiselumf, spotEdited.noiselumf); + assignFromKeyfile(keyFile, "Locallab", "noiselumf0_" + index_str, spot.noiselumf0, spotEdited.noiselumf0); + assignFromKeyfile(keyFile, "Locallab", "noiselumf2_" + index_str, spot.noiselumf2, spotEdited.noiselumf2); + assignFromKeyfile(keyFile, "Locallab", "noiselumc_" + index_str, spot.noiselumc, spotEdited.noiselumc); + assignFromKeyfile(keyFile, "Locallab", "noiselumdetail_" + index_str, spot.noiselumdetail, spotEdited.noiselumdetail); + assignFromKeyfile(keyFile, "Locallab", "noiselequal_" + index_str, spot.noiselequal, spotEdited.noiselequal); + assignFromKeyfile(keyFile, "Locallab", "noisegam_" + index_str, spot.noisegam, spotEdited.noisegam); + assignFromKeyfile(keyFile, "Locallab", "noisechrof_" + index_str, spot.noisechrof, spotEdited.noisechrof); + assignFromKeyfile(keyFile, "Locallab", "noisechroc_" + index_str, spot.noisechroc, spotEdited.noisechroc); + assignFromKeyfile(keyFile, "Locallab", "noisechrodetail_" + index_str, spot.noisechrodetail, spotEdited.noisechrodetail); + assignFromKeyfile(keyFile, "Locallab", "Adjblur_" + index_str, spot.adjblur, spotEdited.adjblur); + assignFromKeyfile(keyFile, "Locallab", "Bilateral_" + index_str, spot.bilateral, spotEdited.bilateral); + assignFromKeyfile(keyFile, "Locallab", "Nlstr_" + index_str, spot.nlstr, spotEdited.nlstr); + assignFromKeyfile(keyFile, "Locallab", "Nldet_" + index_str, spot.nldet, spotEdited.nldet); + assignFromKeyfile(keyFile, "Locallab", "Nlpat_" + index_str, spot.nlpat, spotEdited.nlpat); + assignFromKeyfile(keyFile, "Locallab", "Nlrad_" + index_str, spot.nlrad, spotEdited.nlrad); + assignFromKeyfile(keyFile, "Locallab", "Nlgam_" + index_str, spot.nlgam, spotEdited.nlgam); + assignFromKeyfile(keyFile, "Locallab", "Sensiden_" + index_str, spot.sensiden, spotEdited.sensiden); + assignFromKeyfile(keyFile, "Locallab", "Reparden_" + index_str, spot.reparden, spotEdited.reparden); + assignFromKeyfile(keyFile, "Locallab", "Detailthr_" + index_str, spot.detailthr, spotEdited.detailthr); + assignFromKeyfile(keyFile, "Locallab", "LocwavCurveden_" + index_str, spot.locwavcurveden, spotEdited.locwavcurveden); + assignFromKeyfile(keyFile, "Locallab", "LocwavCurvehue_" + index_str, spot.locwavcurvehue, spotEdited.locwavcurvehue); + assignFromKeyfile(keyFile, "Locallab", "Showmasktyp_" + index_str, spot.showmaskblMethodtyp, spotEdited.showmaskblMethodtyp); + assignFromKeyfile(keyFile, "Locallab", "CCmaskblCurve_" + index_str, spot.CCmaskblcurve, spotEdited.CCmaskblcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskblCurve_" + index_str, spot.LLmaskblcurve, spotEdited.LLmaskblcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskblCurve_" + index_str, spot.HHmaskblcurve, spotEdited.HHmaskblcurve); + assignFromKeyfile(keyFile, "Locallab", "EnablMask_" + index_str, spot.enablMask, spotEdited.enablMask); + assignFromKeyfile(keyFile, "Locallab", "Fftwbl_" + index_str, spot.fftwbl, spotEdited.fftwbl); + assignFromKeyfile(keyFile, "Locallab", "Invbl_" + index_str, spot.invbl, spotEdited.invbl); + assignFromKeyfile(keyFile, "Locallab", "Toolbl_" + index_str, spot.toolbl, spotEdited.toolbl); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskbl_" + index_str, spot.blendmaskbl, spotEdited.blendmaskbl); + assignFromKeyfile(keyFile, "Locallab", "Radmaskbl_" + index_str, spot.radmaskbl, spotEdited.radmaskbl); + assignFromKeyfile(keyFile, "Locallab", "Chromaskbl_" + index_str, spot.chromaskbl, spotEdited.chromaskbl); + assignFromKeyfile(keyFile, "Locallab", "Gammaskbl_" + index_str, spot.gammaskbl, spotEdited.gammaskbl); + assignFromKeyfile(keyFile, "Locallab", "Slomaskbl_" + index_str, spot.slomaskbl, spotEdited.slomaskbl); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskbl_" + index_str, spot.lapmaskbl, spotEdited.lapmaskbl); + assignFromKeyfile(keyFile, "Locallab", "shadmaskbl_" + index_str, spot.shadmaskbl, spotEdited.shadmaskbl); + assignFromKeyfile(keyFile, "Locallab", "shadmaskblsha_" + index_str, spot.shadmaskblsha, spotEdited.shadmaskblsha); + assignFromKeyfile(keyFile, "Locallab", "strumaskbl_" + index_str, spot.strumaskbl, spotEdited.strumaskbl); + assignFromKeyfile(keyFile, "Locallab", "LmaskblCurve_" + index_str, spot.Lmaskblcurve, spotEdited.Lmaskblcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskblCurvewav_" + index_str, spot.LLmaskblcurvewav, spotEdited.LLmaskblcurvewav); if (keyFile.has_key("Locallab", "CSThresholdblur_" + index_str)) { const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdblur_" + index_str); @@ -9091,175 +9087,175 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.csthresholdblur = true; } // Tone Mapping - spot.visitonemap = assignFromKeyfile(keyFile, "Locallab", "Exptonemap_" + index_str, pedited, spot.exptonemap, spotEdited.exptonemap); + spot.visitonemap = assignFromKeyfile(keyFile, "Locallab", "Exptonemap_" + index_str, spot.exptonemap, spotEdited.exptonemap); if (spot.visitonemap) { spotEdited.visitonemap = true; } - assignFromKeyfile(keyFile, "Locallab", "Complextonemap_" + index_str, pedited, spot.complextonemap, spotEdited.complextonemap); - assignFromKeyfile(keyFile, "Locallab", "Stren_" + index_str, pedited, spot.stren, spotEdited.stren); - assignFromKeyfile(keyFile, "Locallab", "Gamma_" + index_str, pedited, spot.gamma, spotEdited.gamma); - assignFromKeyfile(keyFile, "Locallab", "Estop_" + index_str, pedited, spot.estop, spotEdited.estop); - assignFromKeyfile(keyFile, "Locallab", "Scaltm_" + index_str, pedited, spot.scaltm, spotEdited.scaltm); - assignFromKeyfile(keyFile, "Locallab", "Repartm_" + index_str, pedited, spot.repartm, spotEdited.repartm); - assignFromKeyfile(keyFile, "Locallab", "Rewei_" + index_str, pedited, spot.rewei, spotEdited.rewei); - assignFromKeyfile(keyFile, "Locallab", "Satur_" + index_str, pedited, spot.satur, spotEdited.satur); - assignFromKeyfile(keyFile, "Locallab", "Sensitm_" + index_str, pedited, spot.sensitm, spotEdited.sensitm); - assignFromKeyfile(keyFile, "Locallab", "Softradiustm_" + index_str, pedited, spot.softradiustm, spotEdited.softradiustm); - assignFromKeyfile(keyFile, "Locallab", "Amount_" + index_str, pedited, spot.amount, spotEdited.amount); - assignFromKeyfile(keyFile, "Locallab", "Equiltm_" + index_str, pedited, spot.equiltm, spotEdited.equiltm); - assignFromKeyfile(keyFile, "Locallab", "CCmasktmCurve_" + index_str, pedited, spot.CCmasktmcurve, spotEdited.CCmasktmcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmasktmCurve_" + index_str, pedited, spot.LLmasktmcurve, spotEdited.LLmasktmcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmasktmCurve_" + index_str, pedited, spot.HHmasktmcurve, spotEdited.HHmasktmcurve); - assignFromKeyfile(keyFile, "Locallab", "EnatmMask_" + index_str, pedited, spot.enatmMask, spotEdited.enatmMask); - assignFromKeyfile(keyFile, "Locallab", "EnatmMaskaft_" + index_str, pedited, spot.enatmMaskaft, spotEdited.enatmMaskaft); - assignFromKeyfile(keyFile, "Locallab", "Blendmasktm_" + index_str, pedited, spot.blendmasktm, spotEdited.blendmasktm); - assignFromKeyfile(keyFile, "Locallab", "Radmasktm_" + index_str, pedited, spot.radmasktm, spotEdited.radmasktm); - assignFromKeyfile(keyFile, "Locallab", "Chromasktm_" + index_str, pedited, spot.chromasktm, spotEdited.chromasktm); - assignFromKeyfile(keyFile, "Locallab", "Gammasktm_" + index_str, pedited, spot.gammasktm, spotEdited.gammasktm); - assignFromKeyfile(keyFile, "Locallab", "Slomasktm_" + index_str, pedited, spot.slomasktm, spotEdited.slomasktm); - assignFromKeyfile(keyFile, "Locallab", "Lapmasktm_" + index_str, pedited, spot.lapmasktm, spotEdited.lapmasktm); - assignFromKeyfile(keyFile, "Locallab", "LmasktmCurve_" + index_str, pedited, spot.Lmasktmcurve, spotEdited.Lmasktmcurve); - assignFromKeyfile(keyFile, "Locallab", "Recothrest_" + index_str, pedited, spot.recothrest, spotEdited.recothrest); - assignFromKeyfile(keyFile, "Locallab", "Lowthrest_" + index_str, pedited, spot.lowthrest, spotEdited.lowthrest); - assignFromKeyfile(keyFile, "Locallab", "Higthrest_" + index_str, pedited, spot.higthrest, spotEdited.higthrest); - assignFromKeyfile(keyFile, "Locallab", "Decayt_" + index_str, pedited, spot.decayt, spotEdited.decayt); + assignFromKeyfile(keyFile, "Locallab", "Complextonemap_" + index_str, spot.complextonemap, spotEdited.complextonemap); + assignFromKeyfile(keyFile, "Locallab", "Stren_" + index_str, spot.stren, spotEdited.stren); + assignFromKeyfile(keyFile, "Locallab", "Gamma_" + index_str, spot.gamma, spotEdited.gamma); + assignFromKeyfile(keyFile, "Locallab", "Estop_" + index_str, spot.estop, spotEdited.estop); + assignFromKeyfile(keyFile, "Locallab", "Scaltm_" + index_str, spot.scaltm, spotEdited.scaltm); + assignFromKeyfile(keyFile, "Locallab", "Repartm_" + index_str, spot.repartm, spotEdited.repartm); + assignFromKeyfile(keyFile, "Locallab", "Rewei_" + index_str, spot.rewei, spotEdited.rewei); + assignFromKeyfile(keyFile, "Locallab", "Satur_" + index_str, spot.satur, spotEdited.satur); + assignFromKeyfile(keyFile, "Locallab", "Sensitm_" + index_str, spot.sensitm, spotEdited.sensitm); + assignFromKeyfile(keyFile, "Locallab", "Softradiustm_" + index_str, spot.softradiustm, spotEdited.softradiustm); + assignFromKeyfile(keyFile, "Locallab", "Amount_" + index_str, spot.amount, spotEdited.amount); + assignFromKeyfile(keyFile, "Locallab", "Equiltm_" + index_str, spot.equiltm, spotEdited.equiltm); + assignFromKeyfile(keyFile, "Locallab", "CCmasktmCurve_" + index_str, spot.CCmasktmcurve, spotEdited.CCmasktmcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmasktmCurve_" + index_str, spot.LLmasktmcurve, spotEdited.LLmasktmcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmasktmCurve_" + index_str, spot.HHmasktmcurve, spotEdited.HHmasktmcurve); + assignFromKeyfile(keyFile, "Locallab", "EnatmMask_" + index_str, spot.enatmMask, spotEdited.enatmMask); + assignFromKeyfile(keyFile, "Locallab", "EnatmMaskaft_" + index_str, spot.enatmMaskaft, spotEdited.enatmMaskaft); + assignFromKeyfile(keyFile, "Locallab", "Blendmasktm_" + index_str, spot.blendmasktm, spotEdited.blendmasktm); + assignFromKeyfile(keyFile, "Locallab", "Radmasktm_" + index_str, spot.radmasktm, spotEdited.radmasktm); + assignFromKeyfile(keyFile, "Locallab", "Chromasktm_" + index_str, spot.chromasktm, spotEdited.chromasktm); + assignFromKeyfile(keyFile, "Locallab", "Gammasktm_" + index_str, spot.gammasktm, spotEdited.gammasktm); + assignFromKeyfile(keyFile, "Locallab", "Slomasktm_" + index_str, spot.slomasktm, spotEdited.slomasktm); + assignFromKeyfile(keyFile, "Locallab", "Lapmasktm_" + index_str, spot.lapmasktm, spotEdited.lapmasktm); + assignFromKeyfile(keyFile, "Locallab", "LmasktmCurve_" + index_str, spot.Lmasktmcurve, spotEdited.Lmasktmcurve); + assignFromKeyfile(keyFile, "Locallab", "Recothrest_" + index_str, spot.recothrest, spotEdited.recothrest); + assignFromKeyfile(keyFile, "Locallab", "Lowthrest_" + index_str, spot.lowthrest, spotEdited.lowthrest); + assignFromKeyfile(keyFile, "Locallab", "Higthrest_" + index_str, spot.higthrest, spotEdited.higthrest); + assignFromKeyfile(keyFile, "Locallab", "Decayt_" + index_str, spot.decayt, spotEdited.decayt); // Retinex - spot.visireti = assignFromKeyfile(keyFile, "Locallab", "Expreti_" + index_str, pedited, spot.expreti, spotEdited.expreti); + spot.visireti = assignFromKeyfile(keyFile, "Locallab", "Expreti_" + index_str, spot.expreti, spotEdited.expreti); if (spot.visireti) { spotEdited.visireti = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexreti_" + index_str, pedited, spot.complexreti, spotEdited.complexreti); - assignFromKeyfile(keyFile, "Locallab", "retinexMethod_" + index_str, pedited, spot.retinexMethod, spotEdited.retinexMethod); - assignFromKeyfile(keyFile, "Locallab", "Str_" + index_str, pedited, spot.str, spotEdited.str); - assignFromKeyfile(keyFile, "Locallab", "Chrrt_" + index_str, pedited, spot.chrrt, spotEdited.chrrt); - assignFromKeyfile(keyFile, "Locallab", "Neigh_" + index_str, pedited, spot.neigh, spotEdited.neigh); - assignFromKeyfile(keyFile, "Locallab", "Vart_" + index_str, pedited, spot.vart, spotEdited.vart); - assignFromKeyfile(keyFile, "Locallab", "Offs_" + index_str, pedited, spot.offs, spotEdited.offs); - assignFromKeyfile(keyFile, "Locallab", "Dehaz_" + index_str, pedited, spot.dehaz, spotEdited.dehaz); - assignFromKeyfile(keyFile, "Locallab", "Depth_" + index_str, pedited, spot.depth, spotEdited.depth); - assignFromKeyfile(keyFile, "Locallab", "Sensih_" + index_str, pedited, spot.sensih, spotEdited.sensih); - assignFromKeyfile(keyFile, "Locallab", "TgainCurve_" + index_str, pedited, spot.localTgaincurve, spotEdited.localTgaincurve); - assignFromKeyfile(keyFile, "Locallab", "TtransCurve_" + index_str, pedited, spot.localTtranscurve, spotEdited.localTtranscurve); - assignFromKeyfile(keyFile, "Locallab", "Inversret_" + index_str, pedited, spot.inversret, spotEdited.inversret); - assignFromKeyfile(keyFile, "Locallab", "Equilret_" + index_str, pedited, spot.equilret, spotEdited.equilret); - assignFromKeyfile(keyFile, "Locallab", "Loglin_" + index_str, pedited, spot.loglin, spotEdited.loglin); - assignFromKeyfile(keyFile, "Locallab", "dehazeSaturation" + index_str, pedited, spot.dehazeSaturation, spotEdited.dehazeSaturation); - assignFromKeyfile(keyFile, "Locallab", "Softradiusret_" + index_str, pedited, spot.softradiusret, spotEdited.softradiusret); - assignFromKeyfile(keyFile, "Locallab", "CCmaskretiCurve_" + index_str, pedited, spot.CCmaskreticurve, spotEdited.CCmaskreticurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskretiCurve_" + index_str, pedited, spot.LLmaskreticurve, spotEdited.LLmaskreticurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskretiCurve_" + index_str, pedited, spot.HHmaskreticurve, spotEdited.HHmaskreticurve); - assignFromKeyfile(keyFile, "Locallab", "EnaretiMask_" + index_str, pedited, spot.enaretiMask, spotEdited.enaretiMask); - assignFromKeyfile(keyFile, "Locallab", "EnaretiMasktmap_" + index_str, pedited, spot.enaretiMasktmap, spotEdited.enaretiMasktmap); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskreti_" + index_str, pedited, spot.blendmaskreti, spotEdited.blendmaskreti); - assignFromKeyfile(keyFile, "Locallab", "Radmaskreti_" + index_str, pedited, spot.radmaskreti, spotEdited.radmaskreti); - assignFromKeyfile(keyFile, "Locallab", "Chromaskreti_" + index_str, pedited, spot.chromaskreti, spotEdited.chromaskreti); - assignFromKeyfile(keyFile, "Locallab", "Gammaskreti_" + index_str, pedited, spot.gammaskreti, spotEdited.gammaskreti); - assignFromKeyfile(keyFile, "Locallab", "Slomaskreti_" + index_str, pedited, spot.slomaskreti, spotEdited.slomaskreti); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskreti_" + index_str, pedited, spot.lapmaskreti, spotEdited.lapmaskreti); - assignFromKeyfile(keyFile, "Locallab", "Scalereti_" + index_str, pedited, spot.scalereti, spotEdited.scalereti); - assignFromKeyfile(keyFile, "Locallab", "Darkness_" + index_str, pedited, spot.darkness, spotEdited.darkness); - assignFromKeyfile(keyFile, "Locallab", "Lightnessreti_" + index_str, pedited, spot.lightnessreti, spotEdited.lightnessreti); - assignFromKeyfile(keyFile, "Locallab", "Limd_" + index_str, pedited, spot.limd, spotEdited.limd); - assignFromKeyfile(keyFile, "Locallab", "Cliptm_" + index_str, pedited, spot.cliptm, spotEdited.cliptm); - assignFromKeyfile(keyFile, "Locallab", "Fftwreti_" + index_str, pedited, spot.fftwreti, spotEdited.fftwreti); - assignFromKeyfile(keyFile, "Locallab", "LmaskretiCurve_" + index_str, pedited, spot.Lmaskreticurve, spotEdited.Lmaskreticurve); - assignFromKeyfile(keyFile, "Locallab", "Recothresr_" + index_str, pedited, spot.recothresr, spotEdited.recothresr); - assignFromKeyfile(keyFile, "Locallab", "Lowthresr_" + index_str, pedited, spot.lowthresr, spotEdited.lowthresr); - assignFromKeyfile(keyFile, "Locallab", "Higthresr_" + index_str, pedited, spot.higthresr, spotEdited.higthresr); - assignFromKeyfile(keyFile, "Locallab", "Decayr_" + index_str, pedited, spot.decayr, spotEdited.decayr); + assignFromKeyfile(keyFile, "Locallab", "Complexreti_" + index_str, spot.complexreti, spotEdited.complexreti); + assignFromKeyfile(keyFile, "Locallab", "retinexMethod_" + index_str, spot.retinexMethod, spotEdited.retinexMethod); + assignFromKeyfile(keyFile, "Locallab", "Str_" + index_str, spot.str, spotEdited.str); + assignFromKeyfile(keyFile, "Locallab", "Chrrt_" + index_str, spot.chrrt, spotEdited.chrrt); + assignFromKeyfile(keyFile, "Locallab", "Neigh_" + index_str, spot.neigh, spotEdited.neigh); + assignFromKeyfile(keyFile, "Locallab", "Vart_" + index_str, spot.vart, spotEdited.vart); + assignFromKeyfile(keyFile, "Locallab", "Offs_" + index_str, spot.offs, spotEdited.offs); + assignFromKeyfile(keyFile, "Locallab", "Dehaz_" + index_str, spot.dehaz, spotEdited.dehaz); + assignFromKeyfile(keyFile, "Locallab", "Depth_" + index_str, spot.depth, spotEdited.depth); + assignFromKeyfile(keyFile, "Locallab", "Sensih_" + index_str, spot.sensih, spotEdited.sensih); + assignFromKeyfile(keyFile, "Locallab", "TgainCurve_" + index_str, spot.localTgaincurve, spotEdited.localTgaincurve); + assignFromKeyfile(keyFile, "Locallab", "TtransCurve_" + index_str, spot.localTtranscurve, spotEdited.localTtranscurve); + assignFromKeyfile(keyFile, "Locallab", "Inversret_" + index_str, spot.inversret, spotEdited.inversret); + assignFromKeyfile(keyFile, "Locallab", "Equilret_" + index_str, spot.equilret, spotEdited.equilret); + assignFromKeyfile(keyFile, "Locallab", "Loglin_" + index_str, spot.loglin, spotEdited.loglin); + assignFromKeyfile(keyFile, "Locallab", "dehazeSaturation" + index_str, spot.dehazeSaturation, spotEdited.dehazeSaturation); + assignFromKeyfile(keyFile, "Locallab", "Softradiusret_" + index_str, spot.softradiusret, spotEdited.softradiusret); + assignFromKeyfile(keyFile, "Locallab", "CCmaskretiCurve_" + index_str, spot.CCmaskreticurve, spotEdited.CCmaskreticurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskretiCurve_" + index_str, spot.LLmaskreticurve, spotEdited.LLmaskreticurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskretiCurve_" + index_str, spot.HHmaskreticurve, spotEdited.HHmaskreticurve); + assignFromKeyfile(keyFile, "Locallab", "EnaretiMask_" + index_str, spot.enaretiMask, spotEdited.enaretiMask); + assignFromKeyfile(keyFile, "Locallab", "EnaretiMasktmap_" + index_str, spot.enaretiMasktmap, spotEdited.enaretiMasktmap); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskreti_" + index_str, spot.blendmaskreti, spotEdited.blendmaskreti); + assignFromKeyfile(keyFile, "Locallab", "Radmaskreti_" + index_str, spot.radmaskreti, spotEdited.radmaskreti); + assignFromKeyfile(keyFile, "Locallab", "Chromaskreti_" + index_str, spot.chromaskreti, spotEdited.chromaskreti); + assignFromKeyfile(keyFile, "Locallab", "Gammaskreti_" + index_str, spot.gammaskreti, spotEdited.gammaskreti); + assignFromKeyfile(keyFile, "Locallab", "Slomaskreti_" + index_str, spot.slomaskreti, spotEdited.slomaskreti); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskreti_" + index_str, spot.lapmaskreti, spotEdited.lapmaskreti); + assignFromKeyfile(keyFile, "Locallab", "Scalereti_" + index_str, spot.scalereti, spotEdited.scalereti); + assignFromKeyfile(keyFile, "Locallab", "Darkness_" + index_str, spot.darkness, spotEdited.darkness); + assignFromKeyfile(keyFile, "Locallab", "Lightnessreti_" + index_str, spot.lightnessreti, spotEdited.lightnessreti); + assignFromKeyfile(keyFile, "Locallab", "Limd_" + index_str, spot.limd, spotEdited.limd); + assignFromKeyfile(keyFile, "Locallab", "Cliptm_" + index_str, spot.cliptm, spotEdited.cliptm); + assignFromKeyfile(keyFile, "Locallab", "Fftwreti_" + index_str, spot.fftwreti, spotEdited.fftwreti); + assignFromKeyfile(keyFile, "Locallab", "LmaskretiCurve_" + index_str, spot.Lmaskreticurve, spotEdited.Lmaskreticurve); + assignFromKeyfile(keyFile, "Locallab", "Recothresr_" + index_str, spot.recothresr, spotEdited.recothresr); + assignFromKeyfile(keyFile, "Locallab", "Lowthresr_" + index_str, spot.lowthresr, spotEdited.lowthresr); + assignFromKeyfile(keyFile, "Locallab", "Higthresr_" + index_str, spot.higthresr, spotEdited.higthresr); + assignFromKeyfile(keyFile, "Locallab", "Decayr_" + index_str, spot.decayr, spotEdited.decayr); // Sharpening - spot.visisharp = assignFromKeyfile(keyFile, "Locallab", "Expsharp_" + index_str, pedited, spot.expsharp, spotEdited.expsharp); + spot.visisharp = assignFromKeyfile(keyFile, "Locallab", "Expsharp_" + index_str, spot.expsharp, spotEdited.expsharp); if (spot.visisharp) { spotEdited.visisharp = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexsharp_" + index_str, pedited, spot.complexsharp, spotEdited.complexsharp); - assignFromKeyfile(keyFile, "Locallab", "Sharcontrast_" + index_str, pedited, spot.sharcontrast, spotEdited.sharcontrast); - assignFromKeyfile(keyFile, "Locallab", "Sharradius_" + index_str, pedited, spot.sharradius, spotEdited.sharradius); - assignFromKeyfile(keyFile, "Locallab", "Sharamount_" + index_str, pedited, spot.sharamount, spotEdited.sharamount); - assignFromKeyfile(keyFile, "Locallab", "Shardamping_" + index_str, pedited, spot.shardamping, spotEdited.shardamping); - assignFromKeyfile(keyFile, "Locallab", "Shariter_" + index_str, pedited, spot.shariter, spotEdited.shariter); - assignFromKeyfile(keyFile, "Locallab", "Sharblur_" + index_str, pedited, spot.sharblur, spotEdited.sharblur); - assignFromKeyfile(keyFile, "Locallab", "Shargam_" + index_str, pedited, spot.shargam, spotEdited.shargam); - assignFromKeyfile(keyFile, "Locallab", "Sensisha_" + index_str, pedited, spot.sensisha, spotEdited.sensisha); - assignFromKeyfile(keyFile, "Locallab", "Inverssha_" + index_str, pedited, spot.inverssha, spotEdited.inverssha); + assignFromKeyfile(keyFile, "Locallab", "Complexsharp_" + index_str, spot.complexsharp, spotEdited.complexsharp); + assignFromKeyfile(keyFile, "Locallab", "Sharcontrast_" + index_str, spot.sharcontrast, spotEdited.sharcontrast); + assignFromKeyfile(keyFile, "Locallab", "Sharradius_" + index_str, spot.sharradius, spotEdited.sharradius); + assignFromKeyfile(keyFile, "Locallab", "Sharamount_" + index_str, spot.sharamount, spotEdited.sharamount); + assignFromKeyfile(keyFile, "Locallab", "Shardamping_" + index_str, spot.shardamping, spotEdited.shardamping); + assignFromKeyfile(keyFile, "Locallab", "Shariter_" + index_str, spot.shariter, spotEdited.shariter); + assignFromKeyfile(keyFile, "Locallab", "Sharblur_" + index_str, spot.sharblur, spotEdited.sharblur); + assignFromKeyfile(keyFile, "Locallab", "Shargam_" + index_str, spot.shargam, spotEdited.shargam); + assignFromKeyfile(keyFile, "Locallab", "Sensisha_" + index_str, spot.sensisha, spotEdited.sensisha); + assignFromKeyfile(keyFile, "Locallab", "Inverssha_" + index_str, spot.inverssha, spotEdited.inverssha); // Local Contrast - spot.visicontrast = assignFromKeyfile(keyFile, "Locallab", "Expcontrast_" + index_str, pedited, spot.expcontrast, spotEdited.expcontrast); + spot.visicontrast = assignFromKeyfile(keyFile, "Locallab", "Expcontrast_" + index_str, spot.expcontrast, spotEdited.expcontrast); if (spot.visicontrast) { spotEdited.visicontrast = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexcontrast_" + index_str, pedited, spot.complexcontrast, spotEdited.complexcontrast); - assignFromKeyfile(keyFile, "Locallab", "Lcradius_" + index_str, pedited, spot.lcradius, spotEdited.lcradius); - assignFromKeyfile(keyFile, "Locallab", "Lcamount_" + index_str, pedited, spot.lcamount, spotEdited.lcamount); - assignFromKeyfile(keyFile, "Locallab", "Lcdarkness_" + index_str, pedited, spot.lcdarkness, spotEdited.lcdarkness); - assignFromKeyfile(keyFile, "Locallab", "Lclightness_" + index_str, pedited, spot.lclightness, spotEdited.lclightness); - assignFromKeyfile(keyFile, "Locallab", "Sigmalc_" + index_str, pedited, spot.sigmalc, spotEdited.sigmalc); - assignFromKeyfile(keyFile, "Locallab", "Levelwav_" + index_str, pedited, spot.levelwav, spotEdited.levelwav); - assignFromKeyfile(keyFile, "Locallab", "Residcont_" + index_str, pedited, spot.residcont, spotEdited.residcont); - assignFromKeyfile(keyFile, "Locallab", "Residsha_" + index_str, pedited, spot.residsha, spotEdited.residsha); - assignFromKeyfile(keyFile, "Locallab", "Residshathr_" + index_str, pedited, spot.residshathr, spotEdited.residshathr); - assignFromKeyfile(keyFile, "Locallab", "Residhi_" + index_str, pedited, spot.residhi, spotEdited.residhi); - assignFromKeyfile(keyFile, "Locallab", "Gamlc_" + index_str, pedited, spot.gamlc, spotEdited.gamlc); - assignFromKeyfile(keyFile, "Locallab", "Residhithr_" + index_str, pedited, spot.residhithr, spotEdited.residhithr); - assignFromKeyfile(keyFile, "Locallab", "Residgam_" + index_str, pedited, spot.residgam, spotEdited.residgam); - assignFromKeyfile(keyFile, "Locallab", "Residslop_" + index_str, pedited, spot.residslop, spotEdited.residslop); - assignFromKeyfile(keyFile, "Locallab", "Residblur_" + index_str, pedited, spot.residblur, spotEdited.residblur); - assignFromKeyfile(keyFile, "Locallab", "Levelblur_" + index_str, pedited, spot.levelblur, spotEdited.levelblur); - assignFromKeyfile(keyFile, "Locallab", "Sigmabl_" + index_str, pedited, spot.sigmabl, spotEdited.sigmabl); - assignFromKeyfile(keyFile, "Locallab", "Residchro_" + index_str, pedited, spot.residchro, spotEdited.residchro); - assignFromKeyfile(keyFile, "Locallab", "Residcomp_" + index_str, pedited, spot.residcomp, spotEdited.residcomp); - assignFromKeyfile(keyFile, "Locallab", "Sigma_" + index_str, pedited, spot.sigma, spotEdited.sigma); - assignFromKeyfile(keyFile, "Locallab", "Offset_" + index_str, pedited, spot.offset, spotEdited.offset); - assignFromKeyfile(keyFile, "Locallab", "Sigmadr_" + index_str, pedited, spot.sigmadr, spotEdited.sigmadr); - assignFromKeyfile(keyFile, "Locallab", "Threswav_" + index_str, pedited, spot.threswav, spotEdited.threswav); - assignFromKeyfile(keyFile, "Locallab", "Chromalev_" + index_str, pedited, spot.chromalev, spotEdited.chromalev); - assignFromKeyfile(keyFile, "Locallab", "Chromablu_" + index_str, pedited, spot.chromablu, spotEdited.chromablu); - assignFromKeyfile(keyFile, "Locallab", "sigmadc_" + index_str, pedited, spot.sigmadc, spotEdited.sigmadc); - assignFromKeyfile(keyFile, "Locallab", "deltad_" + index_str, pedited, spot.deltad, spotEdited.deltad); - assignFromKeyfile(keyFile, "Locallab", "Fatres_" + index_str, pedited, spot.fatres, spotEdited.fatres); - assignFromKeyfile(keyFile, "Locallab", "ClariLres_" + index_str, pedited, spot.clarilres, spotEdited.clarilres); - assignFromKeyfile(keyFile, "Locallab", "ClariCres_" + index_str, pedited, spot.claricres, spotEdited.claricres); - assignFromKeyfile(keyFile, "Locallab", "Clarisoft_" + index_str, pedited, spot.clarisoft, spotEdited.clarisoft); - assignFromKeyfile(keyFile, "Locallab", "Sigmalc2_" + index_str, pedited, spot.sigmalc2, spotEdited.sigmalc2); - assignFromKeyfile(keyFile, "Locallab", "Strwav_" + index_str, pedited, spot.strwav, spotEdited.strwav); - assignFromKeyfile(keyFile, "Locallab", "Angwav_" + index_str, pedited, spot.angwav, spotEdited.angwav); - assignFromKeyfile(keyFile, "Locallab", "Strengthw_" + index_str, pedited, spot.strengthw, spotEdited.strengthw); - assignFromKeyfile(keyFile, "Locallab", "Sigmaed_" + index_str, pedited, spot.sigmaed, spotEdited.sigmaed); - assignFromKeyfile(keyFile, "Locallab", "Radiusw_" + index_str, pedited, spot.radiusw, spotEdited.radiusw); - assignFromKeyfile(keyFile, "Locallab", "Detailw_" + index_str, pedited, spot.detailw, spotEdited.detailw); - assignFromKeyfile(keyFile, "Locallab", "Gradw_" + index_str, pedited, spot.gradw, spotEdited.gradw); - assignFromKeyfile(keyFile, "Locallab", "Tloww_" + index_str, pedited, spot.tloww, spotEdited.tloww); - assignFromKeyfile(keyFile, "Locallab", "Thigw_" + index_str, pedited, spot.thigw, spotEdited.thigw); - assignFromKeyfile(keyFile, "Locallab", "Edgw_" + index_str, pedited, spot.edgw, spotEdited.edgw); - assignFromKeyfile(keyFile, "Locallab", "Basew_" + index_str, pedited, spot.basew, spotEdited.basew); - assignFromKeyfile(keyFile, "Locallab", "Sensilc_" + index_str, pedited, spot.sensilc, spotEdited.sensilc); - assignFromKeyfile(keyFile, "Locallab", "Reparw_" + index_str, pedited, spot.reparw, spotEdited.reparw); - assignFromKeyfile(keyFile, "Locallab", "Fftwlc_" + index_str, pedited, spot.fftwlc, spotEdited.fftwlc); - assignFromKeyfile(keyFile, "Locallab", "Blurlc_" + index_str, pedited, spot.blurlc, spotEdited.blurlc); - assignFromKeyfile(keyFile, "Locallab", "Wavblur_" + index_str, pedited, spot.wavblur, spotEdited.wavblur); - assignFromKeyfile(keyFile, "Locallab", "Wavedg_" + index_str, pedited, spot.wavedg, spotEdited.wavedg); - assignFromKeyfile(keyFile, "Locallab", "Waveshow_" + index_str, pedited, spot.waveshow, spotEdited.waveshow); - assignFromKeyfile(keyFile, "Locallab", "Wavcont_" + index_str, pedited, spot.wavcont, spotEdited.wavcont); - assignFromKeyfile(keyFile, "Locallab", "Wavcomp_" + index_str, pedited, spot.wavcomp, spotEdited.wavcomp); - assignFromKeyfile(keyFile, "Locallab", "Wavgradl_" + index_str, pedited, spot.wavgradl, spotEdited.wavgradl); - assignFromKeyfile(keyFile, "Locallab", "Wavcompre_" + index_str, pedited, spot.wavcompre, spotEdited.wavcompre); - assignFromKeyfile(keyFile, "Locallab", "Origlc_" + index_str, pedited, spot.origlc, spotEdited.origlc); - assignFromKeyfile(keyFile, "Locallab", "localcontMethod_" + index_str, pedited, spot.localcontMethod, spotEdited.localcontMethod); - assignFromKeyfile(keyFile, "Locallab", "localedgMethod_" + index_str, pedited, spot.localedgMethod, spotEdited.localedgMethod); - assignFromKeyfile(keyFile, "Locallab", "localneiMethod_" + index_str, pedited, spot.localneiMethod, spotEdited.localneiMethod); - assignFromKeyfile(keyFile, "Locallab", "LocwavCurve_" + index_str, pedited, spot.locwavcurve, spotEdited.locwavcurve); - assignFromKeyfile(keyFile, "Locallab", "LoclevwavCurve_" + index_str, pedited, spot.loclevwavcurve, spotEdited.loclevwavcurve); - assignFromKeyfile(keyFile, "Locallab", "LocconwavCurve_" + index_str, pedited, spot.locconwavcurve, spotEdited.locconwavcurve); - assignFromKeyfile(keyFile, "Locallab", "LoccompwavCurve_" + index_str, pedited, spot.loccompwavcurve, spotEdited.loccompwavcurve); - assignFromKeyfile(keyFile, "Locallab", "LoccomprewavCurve_" + index_str, pedited, spot.loccomprewavcurve, spotEdited.loccomprewavcurve); - assignFromKeyfile(keyFile, "Locallab", "LocedgwavCurve_" + index_str, pedited, spot.locedgwavcurve, spotEdited.locedgwavcurve); + assignFromKeyfile(keyFile, "Locallab", "Complexcontrast_" + index_str, spot.complexcontrast, spotEdited.complexcontrast); + assignFromKeyfile(keyFile, "Locallab", "Lcradius_" + index_str, spot.lcradius, spotEdited.lcradius); + assignFromKeyfile(keyFile, "Locallab", "Lcamount_" + index_str, spot.lcamount, spotEdited.lcamount); + assignFromKeyfile(keyFile, "Locallab", "Lcdarkness_" + index_str, spot.lcdarkness, spotEdited.lcdarkness); + assignFromKeyfile(keyFile, "Locallab", "Lclightness_" + index_str, spot.lclightness, spotEdited.lclightness); + assignFromKeyfile(keyFile, "Locallab", "Sigmalc_" + index_str, spot.sigmalc, spotEdited.sigmalc); + assignFromKeyfile(keyFile, "Locallab", "Levelwav_" + index_str, spot.levelwav, spotEdited.levelwav); + assignFromKeyfile(keyFile, "Locallab", "Residcont_" + index_str, spot.residcont, spotEdited.residcont); + assignFromKeyfile(keyFile, "Locallab", "Residsha_" + index_str, spot.residsha, spotEdited.residsha); + assignFromKeyfile(keyFile, "Locallab", "Residshathr_" + index_str, spot.residshathr, spotEdited.residshathr); + assignFromKeyfile(keyFile, "Locallab", "Residhi_" + index_str, spot.residhi, spotEdited.residhi); + assignFromKeyfile(keyFile, "Locallab", "Gamlc_" + index_str, spot.gamlc, spotEdited.gamlc); + assignFromKeyfile(keyFile, "Locallab", "Residhithr_" + index_str, spot.residhithr, spotEdited.residhithr); + assignFromKeyfile(keyFile, "Locallab", "Residgam_" + index_str, spot.residgam, spotEdited.residgam); + assignFromKeyfile(keyFile, "Locallab", "Residslop_" + index_str, spot.residslop, spotEdited.residslop); + assignFromKeyfile(keyFile, "Locallab", "Residblur_" + index_str, spot.residblur, spotEdited.residblur); + assignFromKeyfile(keyFile, "Locallab", "Levelblur_" + index_str, spot.levelblur, spotEdited.levelblur); + assignFromKeyfile(keyFile, "Locallab", "Sigmabl_" + index_str, spot.sigmabl, spotEdited.sigmabl); + assignFromKeyfile(keyFile, "Locallab", "Residchro_" + index_str, spot.residchro, spotEdited.residchro); + assignFromKeyfile(keyFile, "Locallab", "Residcomp_" + index_str, spot.residcomp, spotEdited.residcomp); + assignFromKeyfile(keyFile, "Locallab", "Sigma_" + index_str, spot.sigma, spotEdited.sigma); + assignFromKeyfile(keyFile, "Locallab", "Offset_" + index_str, spot.offset, spotEdited.offset); + assignFromKeyfile(keyFile, "Locallab", "Sigmadr_" + index_str, spot.sigmadr, spotEdited.sigmadr); + assignFromKeyfile(keyFile, "Locallab", "Threswav_" + index_str, spot.threswav, spotEdited.threswav); + assignFromKeyfile(keyFile, "Locallab", "Chromalev_" + index_str, spot.chromalev, spotEdited.chromalev); + assignFromKeyfile(keyFile, "Locallab", "Chromablu_" + index_str, spot.chromablu, spotEdited.chromablu); + assignFromKeyfile(keyFile, "Locallab", "sigmadc_" + index_str, spot.sigmadc, spotEdited.sigmadc); + assignFromKeyfile(keyFile, "Locallab", "deltad_" + index_str, spot.deltad, spotEdited.deltad); + assignFromKeyfile(keyFile, "Locallab", "Fatres_" + index_str, spot.fatres, spotEdited.fatres); + assignFromKeyfile(keyFile, "Locallab", "ClariLres_" + index_str, spot.clarilres, spotEdited.clarilres); + assignFromKeyfile(keyFile, "Locallab", "ClariCres_" + index_str, spot.claricres, spotEdited.claricres); + assignFromKeyfile(keyFile, "Locallab", "Clarisoft_" + index_str, spot.clarisoft, spotEdited.clarisoft); + assignFromKeyfile(keyFile, "Locallab", "Sigmalc2_" + index_str, spot.sigmalc2, spotEdited.sigmalc2); + assignFromKeyfile(keyFile, "Locallab", "Strwav_" + index_str, spot.strwav, spotEdited.strwav); + assignFromKeyfile(keyFile, "Locallab", "Angwav_" + index_str, spot.angwav, spotEdited.angwav); + assignFromKeyfile(keyFile, "Locallab", "Strengthw_" + index_str, spot.strengthw, spotEdited.strengthw); + assignFromKeyfile(keyFile, "Locallab", "Sigmaed_" + index_str, spot.sigmaed, spotEdited.sigmaed); + assignFromKeyfile(keyFile, "Locallab", "Radiusw_" + index_str, spot.radiusw, spotEdited.radiusw); + assignFromKeyfile(keyFile, "Locallab", "Detailw_" + index_str, spot.detailw, spotEdited.detailw); + assignFromKeyfile(keyFile, "Locallab", "Gradw_" + index_str, spot.gradw, spotEdited.gradw); + assignFromKeyfile(keyFile, "Locallab", "Tloww_" + index_str, spot.tloww, spotEdited.tloww); + assignFromKeyfile(keyFile, "Locallab", "Thigw_" + index_str, spot.thigw, spotEdited.thigw); + assignFromKeyfile(keyFile, "Locallab", "Edgw_" + index_str, spot.edgw, spotEdited.edgw); + assignFromKeyfile(keyFile, "Locallab", "Basew_" + index_str, spot.basew, spotEdited.basew); + assignFromKeyfile(keyFile, "Locallab", "Sensilc_" + index_str, spot.sensilc, spotEdited.sensilc); + assignFromKeyfile(keyFile, "Locallab", "Reparw_" + index_str, spot.reparw, spotEdited.reparw); + assignFromKeyfile(keyFile, "Locallab", "Fftwlc_" + index_str, spot.fftwlc, spotEdited.fftwlc); + assignFromKeyfile(keyFile, "Locallab", "Blurlc_" + index_str, spot.blurlc, spotEdited.blurlc); + assignFromKeyfile(keyFile, "Locallab", "Wavblur_" + index_str, spot.wavblur, spotEdited.wavblur); + assignFromKeyfile(keyFile, "Locallab", "Wavedg_" + index_str, spot.wavedg, spotEdited.wavedg); + assignFromKeyfile(keyFile, "Locallab", "Waveshow_" + index_str, spot.waveshow, spotEdited.waveshow); + assignFromKeyfile(keyFile, "Locallab", "Wavcont_" + index_str, spot.wavcont, spotEdited.wavcont); + assignFromKeyfile(keyFile, "Locallab", "Wavcomp_" + index_str, spot.wavcomp, spotEdited.wavcomp); + assignFromKeyfile(keyFile, "Locallab", "Wavgradl_" + index_str, spot.wavgradl, spotEdited.wavgradl); + assignFromKeyfile(keyFile, "Locallab", "Wavcompre_" + index_str, spot.wavcompre, spotEdited.wavcompre); + assignFromKeyfile(keyFile, "Locallab", "Origlc_" + index_str, spot.origlc, spotEdited.origlc); + assignFromKeyfile(keyFile, "Locallab", "localcontMethod_" + index_str, spot.localcontMethod, spotEdited.localcontMethod); + assignFromKeyfile(keyFile, "Locallab", "localedgMethod_" + index_str, spot.localedgMethod, spotEdited.localedgMethod); + assignFromKeyfile(keyFile, "Locallab", "localneiMethod_" + index_str, spot.localneiMethod, spotEdited.localneiMethod); + assignFromKeyfile(keyFile, "Locallab", "LocwavCurve_" + index_str, spot.locwavcurve, spotEdited.locwavcurve); + assignFromKeyfile(keyFile, "Locallab", "LoclevwavCurve_" + index_str, spot.loclevwavcurve, spotEdited.loclevwavcurve); + assignFromKeyfile(keyFile, "Locallab", "LocconwavCurve_" + index_str, spot.locconwavcurve, spotEdited.locconwavcurve); + assignFromKeyfile(keyFile, "Locallab", "LoccompwavCurve_" + index_str, spot.loccompwavcurve, spotEdited.loccompwavcurve); + assignFromKeyfile(keyFile, "Locallab", "LoccomprewavCurve_" + index_str, spot.loccomprewavcurve, spotEdited.loccomprewavcurve); + assignFromKeyfile(keyFile, "Locallab", "LocedgwavCurve_" + index_str, spot.locedgwavcurve, spotEdited.locedgwavcurve); if (keyFile.has_key("Locallab", "CSThreshold_" + index_str)) { @@ -9272,128 +9268,128 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.csthreshold = true; } - assignFromKeyfile(keyFile, "Locallab", "CCmasklcCurve_" + index_str, pedited, spot.CCmasklccurve, spotEdited.CCmasklccurve); - assignFromKeyfile(keyFile, "Locallab", "LLmasklcCurve_" + index_str, pedited, spot.LLmasklccurve, spotEdited.LLmasklccurve); - assignFromKeyfile(keyFile, "Locallab", "HHmasklcCurve_" + index_str, pedited, spot.HHmasklccurve, spotEdited.HHmasklccurve); - assignFromKeyfile(keyFile, "Locallab", "EnalcMask_" + index_str, pedited, spot.enalcMask, spotEdited.enalcMask); - assignFromKeyfile(keyFile, "Locallab", "Blendmasklc_" + index_str, pedited, spot.blendmasklc, spotEdited.blendmasklc); - assignFromKeyfile(keyFile, "Locallab", "Radmasklc_" + index_str, pedited, spot.radmasklc, spotEdited.radmasklc); - assignFromKeyfile(keyFile, "Locallab", "Chromasklc_" + index_str, pedited, spot.chromasklc, spotEdited.chromasklc); - assignFromKeyfile(keyFile, "Locallab", "LmasklcCurve_" + index_str, pedited, spot.Lmasklccurve, spotEdited.Lmasklccurve); - assignFromKeyfile(keyFile, "Locallab", "Recothresw_" + index_str, pedited, spot.recothresw, spotEdited.recothresw); - assignFromKeyfile(keyFile, "Locallab", "Lowthresw_" + index_str, pedited, spot.lowthresw, spotEdited.lowthresw); - assignFromKeyfile(keyFile, "Locallab", "Higthresw_" + index_str, pedited, spot.higthresw, spotEdited.higthresw); - assignFromKeyfile(keyFile, "Locallab", "Decayw_" + index_str, pedited, spot.decayw, spotEdited.decayw); + assignFromKeyfile(keyFile, "Locallab", "CCmasklcCurve_" + index_str, spot.CCmasklccurve, spotEdited.CCmasklccurve); + assignFromKeyfile(keyFile, "Locallab", "LLmasklcCurve_" + index_str, spot.LLmasklccurve, spotEdited.LLmasklccurve); + assignFromKeyfile(keyFile, "Locallab", "HHmasklcCurve_" + index_str, spot.HHmasklccurve, spotEdited.HHmasklccurve); + assignFromKeyfile(keyFile, "Locallab", "EnalcMask_" + index_str, spot.enalcMask, spotEdited.enalcMask); + assignFromKeyfile(keyFile, "Locallab", "Blendmasklc_" + index_str, spot.blendmasklc, spotEdited.blendmasklc); + assignFromKeyfile(keyFile, "Locallab", "Radmasklc_" + index_str, spot.radmasklc, spotEdited.radmasklc); + assignFromKeyfile(keyFile, "Locallab", "Chromasklc_" + index_str, spot.chromasklc, spotEdited.chromasklc); + assignFromKeyfile(keyFile, "Locallab", "LmasklcCurve_" + index_str, spot.Lmasklccurve, spotEdited.Lmasklccurve); + assignFromKeyfile(keyFile, "Locallab", "Recothresw_" + index_str, spot.recothresw, spotEdited.recothresw); + assignFromKeyfile(keyFile, "Locallab", "Lowthresw_" + index_str, spot.lowthresw, spotEdited.lowthresw); + assignFromKeyfile(keyFile, "Locallab", "Higthresw_" + index_str, spot.higthresw, spotEdited.higthresw); + assignFromKeyfile(keyFile, "Locallab", "Decayw_" + index_str, spot.decayw, spotEdited.decayw); // Contrast by detail levels - spot.visicbdl = assignFromKeyfile(keyFile, "Locallab", "Expcbdl_" + index_str, pedited, spot.expcbdl, spotEdited.expcbdl); + spot.visicbdl = assignFromKeyfile(keyFile, "Locallab", "Expcbdl_" + index_str, spot.expcbdl, spotEdited.expcbdl); if (spot.visicbdl) { spotEdited.visicbdl = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexcbdl_" + index_str, pedited, spot.complexcbdl, spotEdited.complexcbdl); + assignFromKeyfile(keyFile, "Locallab", "Complexcbdl_" + index_str, spot.complexcbdl, spotEdited.complexcbdl); for (int j = 0; j < 6; j ++) { - assignFromKeyfile(keyFile, "Locallab", "Mult" + std::to_string(j) + "_" + index_str, pedited, spot.mult[j], spotEdited.mult[j]); + assignFromKeyfile(keyFile, "Locallab", "Mult" + std::to_string(j) + "_" + index_str, spot.mult[j], spotEdited.mult[j]); } - assignFromKeyfile(keyFile, "Locallab", "Chromacbdl_" + index_str, pedited, spot.chromacbdl, spotEdited.chromacbdl); - assignFromKeyfile(keyFile, "Locallab", "Threshold_" + index_str, pedited, spot.threshold, spotEdited.threshold); - assignFromKeyfile(keyFile, "Locallab", "Sensicb_" + index_str, pedited, spot.sensicb, spotEdited.sensicb); - assignFromKeyfile(keyFile, "Locallab", "Clarityml_" + index_str, pedited, spot.clarityml, spotEdited.clarityml); - assignFromKeyfile(keyFile, "Locallab", "Contresid_" + index_str, pedited, spot.contresid, spotEdited.contresid); - assignFromKeyfile(keyFile, "Locallab", "Softradiuscb_" + index_str, pedited, spot.softradiuscb, spotEdited.softradiuscb); - assignFromKeyfile(keyFile, "Locallab", "EnacbMask_" + index_str, pedited, spot.enacbMask, spotEdited.enacbMask); - assignFromKeyfile(keyFile, "Locallab", "CCmaskcbCurve_" + index_str, pedited, spot.CCmaskcbcurve, spotEdited.CCmaskcbcurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskcbCurve_" + index_str, pedited, spot.LLmaskcbcurve, spotEdited.LLmaskcbcurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskcbCurve_" + index_str, pedited, spot.HHmaskcbcurve, spotEdited.HHmaskcbcurve); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskcb_" + index_str, pedited, spot.blendmaskcb, spotEdited.blendmaskcb); - assignFromKeyfile(keyFile, "Locallab", "Radmaskcb_" + index_str, pedited, spot.radmaskcb, spotEdited.radmaskcb); - assignFromKeyfile(keyFile, "Locallab", "Chromaskcb_" + index_str, pedited, spot.chromaskcb, spotEdited.chromaskcb); - assignFromKeyfile(keyFile, "Locallab", "Gammaskcb_" + index_str, pedited, spot.gammaskcb, spotEdited.gammaskcb); - assignFromKeyfile(keyFile, "Locallab", "Slomaskcb_" + index_str, pedited, spot.slomaskcb, spotEdited.slomaskcb); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskcb_" + index_str, pedited, spot.lapmaskcb, spotEdited.lapmaskcb); - assignFromKeyfile(keyFile, "Locallab", "LmaskcbCurve_" + index_str, pedited, spot.Lmaskcbcurve, spotEdited.Lmaskcbcurve); - assignFromKeyfile(keyFile, "Locallab", "Recothrescb_" + index_str, pedited, spot.recothrescb, spotEdited.recothrescb); - assignFromKeyfile(keyFile, "Locallab", "Lowthrescb_" + index_str, pedited, spot.lowthrescb, spotEdited.lowthrescb); - assignFromKeyfile(keyFile, "Locallab", "Higthrescb_" + index_str, pedited, spot.higthrescb, spotEdited.higthrescb); - assignFromKeyfile(keyFile, "Locallab", "Decaycb_" + index_str, pedited, spot.decaycb, spotEdited.decaycb); + assignFromKeyfile(keyFile, "Locallab", "Chromacbdl_" + index_str, spot.chromacbdl, spotEdited.chromacbdl); + assignFromKeyfile(keyFile, "Locallab", "Threshold_" + index_str, spot.threshold, spotEdited.threshold); + assignFromKeyfile(keyFile, "Locallab", "Sensicb_" + index_str, spot.sensicb, spotEdited.sensicb); + assignFromKeyfile(keyFile, "Locallab", "Clarityml_" + index_str, spot.clarityml, spotEdited.clarityml); + assignFromKeyfile(keyFile, "Locallab", "Contresid_" + index_str, spot.contresid, spotEdited.contresid); + assignFromKeyfile(keyFile, "Locallab", "Softradiuscb_" + index_str, spot.softradiuscb, spotEdited.softradiuscb); + assignFromKeyfile(keyFile, "Locallab", "EnacbMask_" + index_str, spot.enacbMask, spotEdited.enacbMask); + assignFromKeyfile(keyFile, "Locallab", "CCmaskcbCurve_" + index_str, spot.CCmaskcbcurve, spotEdited.CCmaskcbcurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskcbCurve_" + index_str, spot.LLmaskcbcurve, spotEdited.LLmaskcbcurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskcbCurve_" + index_str, spot.HHmaskcbcurve, spotEdited.HHmaskcbcurve); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskcb_" + index_str, spot.blendmaskcb, spotEdited.blendmaskcb); + assignFromKeyfile(keyFile, "Locallab", "Radmaskcb_" + index_str, spot.radmaskcb, spotEdited.radmaskcb); + assignFromKeyfile(keyFile, "Locallab", "Chromaskcb_" + index_str, spot.chromaskcb, spotEdited.chromaskcb); + assignFromKeyfile(keyFile, "Locallab", "Gammaskcb_" + index_str, spot.gammaskcb, spotEdited.gammaskcb); + assignFromKeyfile(keyFile, "Locallab", "Slomaskcb_" + index_str, spot.slomaskcb, spotEdited.slomaskcb); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskcb_" + index_str, spot.lapmaskcb, spotEdited.lapmaskcb); + assignFromKeyfile(keyFile, "Locallab", "LmaskcbCurve_" + index_str, spot.Lmaskcbcurve, spotEdited.Lmaskcbcurve); + assignFromKeyfile(keyFile, "Locallab", "Recothrescb_" + index_str, spot.recothrescb, spotEdited.recothrescb); + assignFromKeyfile(keyFile, "Locallab", "Lowthrescb_" + index_str, spot.lowthrescb, spotEdited.lowthrescb); + assignFromKeyfile(keyFile, "Locallab", "Higthrescb_" + index_str, spot.higthrescb, spotEdited.higthrescb); + assignFromKeyfile(keyFile, "Locallab", "Decaycb_" + index_str, spot.decaycb, spotEdited.decaycb); // Log encoding - spot.visilog = assignFromKeyfile(keyFile, "Locallab", "Explog_" + index_str, pedited, spot.explog, spotEdited.explog); + spot.visilog = assignFromKeyfile(keyFile, "Locallab", "Explog_" + index_str, spot.explog, spotEdited.explog); if (spot.visilog) { spotEdited.visilog = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexlog_" + index_str, pedited, spot.complexlog, spotEdited.complexlog); + assignFromKeyfile(keyFile, "Locallab", "Complexlog_" + index_str, spot.complexlog, spotEdited.complexlog); - assignFromKeyfile(keyFile, "Locallab", "Autocompute_" + index_str, pedited, spot.autocompute, spotEdited.autocompute); - assignFromKeyfile(keyFile, "Locallab", "SourceGray_" + index_str, pedited, spot.sourceGray, spotEdited.sourceGray); - assignFromKeyfile(keyFile, "Locallab", "Sourceabs_" + index_str, pedited, spot.sourceabs, spotEdited.sourceabs); - assignFromKeyfile(keyFile, "Locallab", "Targabs_" + index_str, pedited, spot.targabs, spotEdited.targabs); - assignFromKeyfile(keyFile, "Locallab", "TargetGray_" + index_str, pedited, spot.targetGray, spotEdited.targetGray); - assignFromKeyfile(keyFile, "Locallab", "Catad_" + index_str, pedited, spot.catad, spotEdited.catad); - assignFromKeyfile(keyFile, "Locallab", "Saturl_" + index_str, pedited, spot.saturl, spotEdited.saturl); - assignFromKeyfile(keyFile, "Locallab", "Chroml_" + index_str, pedited, spot.chroml, spotEdited.chroml); - assignFromKeyfile(keyFile, "Locallab", "Lightl_" + index_str, pedited, spot.lightl, spotEdited.lightl); - assignFromKeyfile(keyFile, "Locallab", "Brightq_" + index_str, pedited, spot.lightq, spotEdited.lightq); - assignFromKeyfile(keyFile, "Locallab", "Contl_" + index_str, pedited, spot.contl, spotEdited.contl); - assignFromKeyfile(keyFile, "Locallab", "Contthres_" + index_str, pedited, spot.contthres, spotEdited.contthres); - assignFromKeyfile(keyFile, "Locallab", "Contq_" + index_str, pedited, spot.contq, spotEdited.contq); - assignFromKeyfile(keyFile, "Locallab", "Colorfl_" + index_str, pedited, spot.colorfl, spotEdited.colorfl); - assignFromKeyfile(keyFile, "Locallab", "LCurveL_" + index_str, pedited, spot.LcurveL, spotEdited.LcurveL); - assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, pedited, spot.Autogray, spotEdited.Autogray); - assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, pedited, spot.fullimage, spotEdited.fullimage); - assignFromKeyfile(keyFile, "Locallab", "Repart_" + index_str, pedited, spot.repar, spotEdited.repar); - assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, pedited, spot.ciecam, spotEdited.ciecam); - assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, pedited, spot.blackEv, spotEdited.blackEv); - assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, pedited, spot.whiteEv, spotEdited.whiteEv); - assignFromKeyfile(keyFile, "Locallab", "Detail_" + index_str, pedited, spot.detail, spotEdited.detail); - assignFromKeyfile(keyFile, "Locallab", "Sensilog_" + index_str, pedited, spot.sensilog, spotEdited.sensilog); - assignFromKeyfile(keyFile, "Locallab", "Baselog_" + index_str, pedited, spot.baselog, spotEdited.baselog); - assignFromKeyfile(keyFile, "Locallab", "Sursour_" + index_str, pedited, spot.sursour, spotEdited.sursour); - assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, pedited, spot.surround, spotEdited.surround); - assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, pedited, spot.strlog, spotEdited.strlog); - assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, pedited, spot.anglog, spotEdited.anglog); - assignFromKeyfile(keyFile, "Locallab", "CCmaskCurveL_" + index_str, pedited, spot.CCmaskcurveL, spotEdited.CCmaskcurveL); - assignFromKeyfile(keyFile, "Locallab", "LLmaskCurveL_" + index_str, pedited, spot.LLmaskcurveL, spotEdited.LLmaskcurveL); - assignFromKeyfile(keyFile, "Locallab", "HHmaskCurveL_" + index_str, pedited, spot.HHmaskcurveL, spotEdited.HHmaskcurveL); - assignFromKeyfile(keyFile, "Locallab", "EnaLMask_" + index_str, pedited, spot.enaLMask, spotEdited.enaLMask); - assignFromKeyfile(keyFile, "Locallab", "blendmaskL_" + index_str, pedited, spot.blendmaskL, spotEdited.blendmaskL); - assignFromKeyfile(keyFile, "Locallab", "radmaskL_" + index_str, pedited, spot.radmaskL, spotEdited.radmaskL); - assignFromKeyfile(keyFile, "Locallab", "chromaskL_" + index_str, pedited, spot.chromaskL, spotEdited.chromaskL); - assignFromKeyfile(keyFile, "Locallab", "LmaskCurveL_" + index_str, pedited, spot.LmaskcurveL, spotEdited.LmaskcurveL); - assignFromKeyfile(keyFile, "Locallab", "Recothresl_" + index_str, pedited, spot.recothresl, spotEdited.recothresl); - assignFromKeyfile(keyFile, "Locallab", "Lowthresl_" + index_str, pedited, spot.lowthresl, spotEdited.lowthresl); - assignFromKeyfile(keyFile, "Locallab", "Higthresl_" + index_str, pedited, spot.higthresl, spotEdited.higthresl); - assignFromKeyfile(keyFile, "Locallab", "Decayl_" + index_str, pedited, spot.decayl, spotEdited.decayl); + assignFromKeyfile(keyFile, "Locallab", "Autocompute_" + index_str, spot.autocompute, spotEdited.autocompute); + assignFromKeyfile(keyFile, "Locallab", "SourceGray_" + index_str, spot.sourceGray, spotEdited.sourceGray); + assignFromKeyfile(keyFile, "Locallab", "Sourceabs_" + index_str, spot.sourceabs, spotEdited.sourceabs); + assignFromKeyfile(keyFile, "Locallab", "Targabs_" + index_str, spot.targabs, spotEdited.targabs); + assignFromKeyfile(keyFile, "Locallab", "TargetGray_" + index_str, spot.targetGray, spotEdited.targetGray); + assignFromKeyfile(keyFile, "Locallab", "Catad_" + index_str, spot.catad, spotEdited.catad); + assignFromKeyfile(keyFile, "Locallab", "Saturl_" + index_str, spot.saturl, spotEdited.saturl); + assignFromKeyfile(keyFile, "Locallab", "Chroml_" + index_str, spot.chroml, spotEdited.chroml); + assignFromKeyfile(keyFile, "Locallab", "Lightl_" + index_str, spot.lightl, spotEdited.lightl); + assignFromKeyfile(keyFile, "Locallab", "Brightq_" + index_str, spot.lightq, spotEdited.lightq); + assignFromKeyfile(keyFile, "Locallab", "Contl_" + index_str, spot.contl, spotEdited.contl); + assignFromKeyfile(keyFile, "Locallab", "Contthres_" + index_str, spot.contthres, spotEdited.contthres); + assignFromKeyfile(keyFile, "Locallab", "Contq_" + index_str, spot.contq, spotEdited.contq); + assignFromKeyfile(keyFile, "Locallab", "Colorfl_" + index_str, spot.colorfl, spotEdited.colorfl); + assignFromKeyfile(keyFile, "Locallab", "LCurveL_" + index_str, spot.LcurveL, spotEdited.LcurveL); + assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, spot.Autogray, spotEdited.Autogray); + assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, spot.fullimage, spotEdited.fullimage); + assignFromKeyfile(keyFile, "Locallab", "Repart_" + index_str, spot.repar, spotEdited.repar); + assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, spot.ciecam, spotEdited.ciecam); + assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, spot.blackEv, spotEdited.blackEv); + assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, spotEdited.whiteEv); + assignFromKeyfile(keyFile, "Locallab", "Detail_" + index_str, spot.detail, spotEdited.detail); + assignFromKeyfile(keyFile, "Locallab", "Sensilog_" + index_str, spot.sensilog, spotEdited.sensilog); + assignFromKeyfile(keyFile, "Locallab", "Baselog_" + index_str, spot.baselog, spotEdited.baselog); + assignFromKeyfile(keyFile, "Locallab", "Sursour_" + index_str, spot.sursour, spotEdited.sursour); + assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, spot.surround, spotEdited.surround); + assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, spot.strlog, spotEdited.strlog); + assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, spot.anglog, spotEdited.anglog); + assignFromKeyfile(keyFile, "Locallab", "CCmaskCurveL_" + index_str, spot.CCmaskcurveL, spotEdited.CCmaskcurveL); + assignFromKeyfile(keyFile, "Locallab", "LLmaskCurveL_" + index_str, spot.LLmaskcurveL, spotEdited.LLmaskcurveL); + assignFromKeyfile(keyFile, "Locallab", "HHmaskCurveL_" + index_str, spot.HHmaskcurveL, spotEdited.HHmaskcurveL); + assignFromKeyfile(keyFile, "Locallab", "EnaLMask_" + index_str, spot.enaLMask, spotEdited.enaLMask); + assignFromKeyfile(keyFile, "Locallab", "blendmaskL_" + index_str, spot.blendmaskL, spotEdited.blendmaskL); + assignFromKeyfile(keyFile, "Locallab", "radmaskL_" + index_str, spot.radmaskL, spotEdited.radmaskL); + assignFromKeyfile(keyFile, "Locallab", "chromaskL_" + index_str, spot.chromaskL, spotEdited.chromaskL); + assignFromKeyfile(keyFile, "Locallab", "LmaskCurveL_" + index_str, spot.LmaskcurveL, spotEdited.LmaskcurveL); + assignFromKeyfile(keyFile, "Locallab", "Recothresl_" + index_str, spot.recothresl, spotEdited.recothresl); + assignFromKeyfile(keyFile, "Locallab", "Lowthresl_" + index_str, spot.lowthresl, spotEdited.lowthresl); + assignFromKeyfile(keyFile, "Locallab", "Higthresl_" + index_str, spot.higthresl, spotEdited.higthresl); + assignFromKeyfile(keyFile, "Locallab", "Decayl_" + index_str, spot.decayl, spotEdited.decayl); // mask - spot.visimask = assignFromKeyfile(keyFile, "Locallab", "Expmask_" + index_str, pedited, spot.expmask, spotEdited.expmask); - assignFromKeyfile(keyFile, "Locallab", "Complexmask_" + index_str, pedited, spot.complexmask, spotEdited.complexmask); - assignFromKeyfile(keyFile, "Locallab", "Sensimask_" + index_str, pedited, spot.sensimask, spotEdited.sensimask); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskmask_" + index_str, pedited, spot.blendmask, spotEdited.blendmask); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskmaskab_" + index_str, pedited, spot.blendmaskab, spotEdited.blendmaskab); - assignFromKeyfile(keyFile, "Locallab", "Softradiusmask_" + index_str, pedited, spot.softradiusmask, spotEdited.softradiusmask); - assignFromKeyfile(keyFile, "Locallab", "Enamask_" + index_str, pedited, spot.enamask, spotEdited.enamask); - assignFromKeyfile(keyFile, "Locallab", "Fftmask_" + index_str, pedited, spot.fftmask, spotEdited.fftmask); - assignFromKeyfile(keyFile, "Locallab", "Blurmask_" + index_str, pedited, spot.blurmask, spotEdited.blurmask); - assignFromKeyfile(keyFile, "Locallab", "Contmask_" + index_str, pedited, spot.contmask, spotEdited.contmask); - assignFromKeyfile(keyFile, "Locallab", "CCmask_Curve_" + index_str, pedited, spot.CCmask_curve, spotEdited.CCmask_curve); - assignFromKeyfile(keyFile, "Locallab", "LLmask_Curve_" + index_str, pedited, spot.LLmask_curve, spotEdited.LLmask_curve); - assignFromKeyfile(keyFile, "Locallab", "HHmask_Curve_" + index_str, pedited, spot.HHmask_curve, spotEdited.HHmask_curve); - assignFromKeyfile(keyFile, "Locallab", "Strumaskmask_" + index_str, pedited, spot.strumaskmask, spotEdited.strumaskmask); - assignFromKeyfile(keyFile, "Locallab", "Toolmask_" + index_str, pedited, spot.toolmask, spotEdited.toolmask); - assignFromKeyfile(keyFile, "Locallab", "Radmask_" + index_str, pedited, spot.radmask, spotEdited.radmask); - assignFromKeyfile(keyFile, "Locallab", "Lapmask_" + index_str, pedited, spot.lapmask, spotEdited.lapmask); - assignFromKeyfile(keyFile, "Locallab", "Chromask_" + index_str, pedited, spot.chromask, spotEdited.chromask); - assignFromKeyfile(keyFile, "Locallab", "Gammask_" + index_str, pedited, spot.gammask, spotEdited.gammask); - assignFromKeyfile(keyFile, "Locallab", "Slopmask_" + index_str, pedited, spot.slopmask, spotEdited.slopmask); - assignFromKeyfile(keyFile, "Locallab", "Shadmask_" + index_str, pedited, spot.shadmask, spotEdited.shadmask); - assignFromKeyfile(keyFile, "Locallab", "Str_mask_" + index_str, pedited, spot.str_mask, spotEdited.str_mask); - assignFromKeyfile(keyFile, "Locallab", "Ang_mask_" + index_str, pedited, spot.ang_mask, spotEdited.ang_mask); - assignFromKeyfile(keyFile, "Locallab", "HHhmask_Curve_" + index_str, pedited, spot.HHhmask_curve, spotEdited.HHhmask_curve); - assignFromKeyfile(keyFile, "Locallab", "Lmask_Curve_" + index_str, pedited, spot.Lmask_curve, spotEdited.Lmask_curve); - assignFromKeyfile(keyFile, "Locallab", "LLmask_Curvewav_" + index_str, pedited, spot.LLmask_curvewav, spotEdited.LLmask_curvewav); + spot.visimask = assignFromKeyfile(keyFile, "Locallab", "Expmask_" + index_str, spot.expmask, spotEdited.expmask); + assignFromKeyfile(keyFile, "Locallab", "Complexmask_" + index_str, spot.complexmask, spotEdited.complexmask); + assignFromKeyfile(keyFile, "Locallab", "Sensimask_" + index_str, spot.sensimask, spotEdited.sensimask); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskmask_" + index_str, spot.blendmask, spotEdited.blendmask); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskmaskab_" + index_str, spot.blendmaskab, spotEdited.blendmaskab); + assignFromKeyfile(keyFile, "Locallab", "Softradiusmask_" + index_str, spot.softradiusmask, spotEdited.softradiusmask); + assignFromKeyfile(keyFile, "Locallab", "Enamask_" + index_str, spot.enamask, spotEdited.enamask); + assignFromKeyfile(keyFile, "Locallab", "Fftmask_" + index_str, spot.fftmask, spotEdited.fftmask); + assignFromKeyfile(keyFile, "Locallab", "Blurmask_" + index_str, spot.blurmask, spotEdited.blurmask); + assignFromKeyfile(keyFile, "Locallab", "Contmask_" + index_str, spot.contmask, spotEdited.contmask); + assignFromKeyfile(keyFile, "Locallab", "CCmask_Curve_" + index_str, spot.CCmask_curve, spotEdited.CCmask_curve); + assignFromKeyfile(keyFile, "Locallab", "LLmask_Curve_" + index_str, spot.LLmask_curve, spotEdited.LLmask_curve); + assignFromKeyfile(keyFile, "Locallab", "HHmask_Curve_" + index_str, spot.HHmask_curve, spotEdited.HHmask_curve); + assignFromKeyfile(keyFile, "Locallab", "Strumaskmask_" + index_str, spot.strumaskmask, spotEdited.strumaskmask); + assignFromKeyfile(keyFile, "Locallab", "Toolmask_" + index_str, spot.toolmask, spotEdited.toolmask); + assignFromKeyfile(keyFile, "Locallab", "Radmask_" + index_str, spot.radmask, spotEdited.radmask); + assignFromKeyfile(keyFile, "Locallab", "Lapmask_" + index_str, spot.lapmask, spotEdited.lapmask); + assignFromKeyfile(keyFile, "Locallab", "Chromask_" + index_str, spot.chromask, spotEdited.chromask); + assignFromKeyfile(keyFile, "Locallab", "Gammask_" + index_str, spot.gammask, spotEdited.gammask); + assignFromKeyfile(keyFile, "Locallab", "Slopmask_" + index_str, spot.slopmask, spotEdited.slopmask); + assignFromKeyfile(keyFile, "Locallab", "Shadmask_" + index_str, spot.shadmask, spotEdited.shadmask); + assignFromKeyfile(keyFile, "Locallab", "Str_mask_" + index_str, spot.str_mask, spotEdited.str_mask); + assignFromKeyfile(keyFile, "Locallab", "Ang_mask_" + index_str, spot.ang_mask, spotEdited.ang_mask); + assignFromKeyfile(keyFile, "Locallab", "HHhmask_Curve_" + index_str, spot.HHhmask_curve, spotEdited.HHhmask_curve); + assignFromKeyfile(keyFile, "Locallab", "Lmask_Curve_" + index_str, spot.Lmask_curve, spotEdited.Lmask_curve); + assignFromKeyfile(keyFile, "Locallab", "LLmask_Curvewav_" + index_str, spot.LLmask_curvewav, spotEdited.LLmask_curvewav); if (keyFile.has_key("Locallab", "CSThresholdmask_" + index_str)) { const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdmask_" + index_str); @@ -9410,64 +9406,64 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } // ciecam - spot.visicie = assignFromKeyfile(keyFile, "Locallab", "Expcie_" + index_str, pedited, spot.expcie, spotEdited.expcie); + spot.visicie = assignFromKeyfile(keyFile, "Locallab", "Expcie_" + index_str, spot.expcie, spotEdited.expcie); if (spot.visicie) { spotEdited.visicie = true; } - assignFromKeyfile(keyFile, "Locallab", "Complexcie_" + index_str, pedited, spot.complexcie, spotEdited.complexcie); - assignFromKeyfile(keyFile, "Locallab", "Reparcie_" + index_str, pedited, spot.reparcie, spotEdited.reparcie); - assignFromKeyfile(keyFile, "Locallab", "Sensicie_" + index_str, pedited, spot.sensicie, spotEdited.sensicie); - assignFromKeyfile(keyFile, "Locallab", "AutoGraycie_" + index_str, pedited, spot.Autograycie, spotEdited.Autograycie); - assignFromKeyfile(keyFile, "Locallab", "Forcejz_" + index_str, pedited, spot.forcejz, spotEdited.forcejz); - assignFromKeyfile(keyFile, "Locallab", "Forcebw_" + index_str, pedited, spot.forcebw, spotEdited.forcebw); - assignFromKeyfile(keyFile, "Locallab", "Qtoj_" + index_str, pedited, spot.qtoj, spotEdited.qtoj); - assignFromKeyfile(keyFile, "Locallab", "jabcie_" + index_str, pedited, spot.jabcie, spotEdited.jabcie); - assignFromKeyfile(keyFile, "Locallab", "sigmoidqjcie_" + index_str, pedited, spot.sigmoidqjcie, spotEdited.sigmoidqjcie); - assignFromKeyfile(keyFile, "Locallab", "logcie_" + index_str, pedited, spot.logcie, spotEdited.logcie); - assignFromKeyfile(keyFile, "Locallab", "Logjz_" + index_str, pedited, spot.logjz, spotEdited.logjz); - assignFromKeyfile(keyFile, "Locallab", "Sigjz_" + index_str, pedited, spot.sigjz, spotEdited.sigjz); - assignFromKeyfile(keyFile, "Locallab", "Sigq_" + index_str, pedited, spot.sigq, spotEdited.sigq); - assignFromKeyfile(keyFile, "Locallab", "chjzcie_" + index_str, pedited, spot.chjzcie, spotEdited.chjzcie); - assignFromKeyfile(keyFile, "Locallab", "SourceGraycie_" + index_str, pedited, spot.sourceGraycie, spotEdited.sourceGraycie); - assignFromKeyfile(keyFile, "Locallab", "Sourceabscie_" + index_str, pedited, spot.sourceabscie, spotEdited.sourceabscie); - assignFromKeyfile(keyFile, "Locallab", "Sursourcie_" + index_str, pedited, spot.sursourcie, spotEdited.sursourcie); - assignFromKeyfile(keyFile, "Locallab", "Modecie_" + index_str, pedited, spot.modecie, spotEdited.modecie); - assignFromKeyfile(keyFile, "Locallab", "Modecam_" + index_str, pedited, spot.modecam, spotEdited.modecam); - assignFromKeyfile(keyFile, "Locallab", "Saturlcie_" + index_str, pedited, spot.saturlcie, spotEdited.saturlcie); - assignFromKeyfile(keyFile, "Locallab", "Rstprotectcie_" + index_str, pedited, spot.rstprotectcie, spotEdited.rstprotectcie); - assignFromKeyfile(keyFile, "Locallab", "Chromlcie_" + index_str, pedited, spot.chromlcie, spotEdited.chromlcie); - assignFromKeyfile(keyFile, "Locallab", "Huecie_" + index_str, pedited, spot.huecie, spotEdited.huecie); - assignFromKeyfile(keyFile, "Locallab", "ToneMethodcie_" + index_str, pedited, spot.toneMethodcie, spotEdited.toneMethodcie); - assignFromKeyfile(keyFile, "Locallab", "Ciecurve_" + index_str, pedited, spot.ciecurve, spotEdited.ciecurve); - assignFromKeyfile(keyFile, "Locallab", "ToneMethodcie2_" + index_str, pedited, spot.toneMethodcie2, spotEdited.toneMethodcie2); - assignFromKeyfile(keyFile, "Locallab", "Ciecurve2_" + index_str, pedited, spot.ciecurve2, spotEdited.ciecurve2); - assignFromKeyfile(keyFile, "Locallab", "Chromjzcie_" + index_str, pedited, spot.chromjzcie, spotEdited.chromjzcie); - assignFromKeyfile(keyFile, "Locallab", "Saturjzcie_" + index_str, pedited, spot.saturjzcie, spotEdited.saturjzcie); - assignFromKeyfile(keyFile, "Locallab", "Huejzcie_" + index_str, pedited, spot.huejzcie, spotEdited.huejzcie); - assignFromKeyfile(keyFile, "Locallab", "Softjzcie_" + index_str, pedited, spot.softjzcie, spotEdited.softjzcie); - assignFromKeyfile(keyFile, "Locallab", "strSoftjzcie_" + index_str, pedited, spot.strsoftjzcie, spotEdited.strsoftjzcie); - assignFromKeyfile(keyFile, "Locallab", "Thrhjzcie_" + index_str, pedited, spot.thrhjzcie, spotEdited.thrhjzcie); - assignFromKeyfile(keyFile, "Locallab", "JzCurve_" + index_str, pedited, spot.jzcurve, spotEdited.jzcurve); - assignFromKeyfile(keyFile, "Locallab", "CzCurve_" + index_str, pedited, spot.czcurve, spotEdited.czcurve); - assignFromKeyfile(keyFile, "Locallab", "CzJzCurve_" + index_str, pedited, spot.czjzcurve, spotEdited.czjzcurve); - assignFromKeyfile(keyFile, "Locallab", "HHCurvejz_" + index_str, pedited, spot.HHcurvejz, spotEdited.HHcurvejz); - assignFromKeyfile(keyFile, "Locallab", "CHCurvejz_" + index_str, pedited, spot.CHcurvejz, spotEdited.CHcurvejz); - assignFromKeyfile(keyFile, "Locallab", "LHCurvejz_" + index_str, pedited, spot.LHcurvejz, spotEdited.LHcurvejz); - assignFromKeyfile(keyFile, "Locallab", "Lightlcie_" + index_str, pedited, spot.lightlcie, spotEdited.lightlcie); - assignFromKeyfile(keyFile, "Locallab", "Lightjzcie_" + index_str, pedited, spot.lightjzcie, spotEdited.lightjzcie); - assignFromKeyfile(keyFile, "Locallab", "Brightqcie_" + index_str, pedited, spot.lightqcie, spotEdited.lightqcie); - assignFromKeyfile(keyFile, "Locallab", "Contlcie_" + index_str, pedited, spot.contlcie, spotEdited.contlcie); - assignFromKeyfile(keyFile, "Locallab", "Contjzcie_" + index_str, pedited, spot.contjzcie, spotEdited.contjzcie); - assignFromKeyfile(keyFile, "Locallab", "Adapjzcie_" + index_str, pedited, spot.adapjzcie, spotEdited.adapjzcie); - assignFromKeyfile(keyFile, "Locallab", "Jz100_" + index_str, pedited, spot.jz100, spotEdited.jz100); - assignFromKeyfile(keyFile, "Locallab", "PQremap_" + index_str, pedited, spot.pqremap, spotEdited.pqremap); - assignFromKeyfile(keyFile, "Locallab", "PQremapcam16_" + index_str, pedited, spot.pqremapcam16, spotEdited.pqremapcam16); - assignFromKeyfile(keyFile, "Locallab", "Hljzcie_" + index_str, pedited, spot.hljzcie, spotEdited.hljzcie); - assignFromKeyfile(keyFile, "Locallab", "Hlthjzcie_" + index_str, pedited, spot.hlthjzcie, spotEdited.hlthjzcie); - assignFromKeyfile(keyFile, "Locallab", "Shjzcie_" + index_str, pedited, spot.shjzcie, spotEdited.shjzcie); - assignFromKeyfile(keyFile, "Locallab", "Shthjzcie_" + index_str, pedited, spot.shthjzcie, spotEdited.shthjzcie); - assignFromKeyfile(keyFile, "Locallab", "Radjzcie_" + index_str, pedited, spot.radjzcie, spotEdited.radjzcie); + assignFromKeyfile(keyFile, "Locallab", "Complexcie_" + index_str, spot.complexcie, spotEdited.complexcie); + assignFromKeyfile(keyFile, "Locallab", "Reparcie_" + index_str, spot.reparcie, spotEdited.reparcie); + assignFromKeyfile(keyFile, "Locallab", "Sensicie_" + index_str, spot.sensicie, spotEdited.sensicie); + assignFromKeyfile(keyFile, "Locallab", "AutoGraycie_" + index_str, spot.Autograycie, spotEdited.Autograycie); + assignFromKeyfile(keyFile, "Locallab", "Forcejz_" + index_str, spot.forcejz, spotEdited.forcejz); + assignFromKeyfile(keyFile, "Locallab", "Forcebw_" + index_str, spot.forcebw, spotEdited.forcebw); + assignFromKeyfile(keyFile, "Locallab", "Qtoj_" + index_str, spot.qtoj, spotEdited.qtoj); + assignFromKeyfile(keyFile, "Locallab", "jabcie_" + index_str, spot.jabcie, spotEdited.jabcie); + assignFromKeyfile(keyFile, "Locallab", "sigmoidqjcie_" + index_str, spot.sigmoidqjcie, spotEdited.sigmoidqjcie); + assignFromKeyfile(keyFile, "Locallab", "logcie_" + index_str, spot.logcie, spotEdited.logcie); + assignFromKeyfile(keyFile, "Locallab", "Logjz_" + index_str, spot.logjz, spotEdited.logjz); + assignFromKeyfile(keyFile, "Locallab", "Sigjz_" + index_str, spot.sigjz, spotEdited.sigjz); + assignFromKeyfile(keyFile, "Locallab", "Sigq_" + index_str, spot.sigq, spotEdited.sigq); + assignFromKeyfile(keyFile, "Locallab", "chjzcie_" + index_str, spot.chjzcie, spotEdited.chjzcie); + assignFromKeyfile(keyFile, "Locallab", "SourceGraycie_" + index_str, spot.sourceGraycie, spotEdited.sourceGraycie); + assignFromKeyfile(keyFile, "Locallab", "Sourceabscie_" + index_str, spot.sourceabscie, spotEdited.sourceabscie); + assignFromKeyfile(keyFile, "Locallab", "Sursourcie_" + index_str, spot.sursourcie, spotEdited.sursourcie); + assignFromKeyfile(keyFile, "Locallab", "Modecie_" + index_str, spot.modecie, spotEdited.modecie); + assignFromKeyfile(keyFile, "Locallab", "Modecam_" + index_str, spot.modecam, spotEdited.modecam); + assignFromKeyfile(keyFile, "Locallab", "Saturlcie_" + index_str, spot.saturlcie, spotEdited.saturlcie); + assignFromKeyfile(keyFile, "Locallab", "Rstprotectcie_" + index_str, spot.rstprotectcie, spotEdited.rstprotectcie); + assignFromKeyfile(keyFile, "Locallab", "Chromlcie_" + index_str, spot.chromlcie, spotEdited.chromlcie); + assignFromKeyfile(keyFile, "Locallab", "Huecie_" + index_str, spot.huecie, spotEdited.huecie); + assignFromKeyfile(keyFile, "Locallab", "ToneMethodcie_" + index_str, spot.toneMethodcie, spotEdited.toneMethodcie); + assignFromKeyfile(keyFile, "Locallab", "Ciecurve_" + index_str, spot.ciecurve, spotEdited.ciecurve); + assignFromKeyfile(keyFile, "Locallab", "ToneMethodcie2_" + index_str, spot.toneMethodcie2, spotEdited.toneMethodcie2); + assignFromKeyfile(keyFile, "Locallab", "Ciecurve2_" + index_str, spot.ciecurve2, spotEdited.ciecurve2); + assignFromKeyfile(keyFile, "Locallab", "Chromjzcie_" + index_str, spot.chromjzcie, spotEdited.chromjzcie); + assignFromKeyfile(keyFile, "Locallab", "Saturjzcie_" + index_str, spot.saturjzcie, spotEdited.saturjzcie); + assignFromKeyfile(keyFile, "Locallab", "Huejzcie_" + index_str, spot.huejzcie, spotEdited.huejzcie); + assignFromKeyfile(keyFile, "Locallab", "Softjzcie_" + index_str, spot.softjzcie, spotEdited.softjzcie); + assignFromKeyfile(keyFile, "Locallab", "strSoftjzcie_" + index_str, spot.strsoftjzcie, spotEdited.strsoftjzcie); + assignFromKeyfile(keyFile, "Locallab", "Thrhjzcie_" + index_str, spot.thrhjzcie, spotEdited.thrhjzcie); + assignFromKeyfile(keyFile, "Locallab", "JzCurve_" + index_str, spot.jzcurve, spotEdited.jzcurve); + assignFromKeyfile(keyFile, "Locallab", "CzCurve_" + index_str, spot.czcurve, spotEdited.czcurve); + assignFromKeyfile(keyFile, "Locallab", "CzJzCurve_" + index_str, spot.czjzcurve, spotEdited.czjzcurve); + assignFromKeyfile(keyFile, "Locallab", "HHCurvejz_" + index_str, spot.HHcurvejz, spotEdited.HHcurvejz); + assignFromKeyfile(keyFile, "Locallab", "CHCurvejz_" + index_str, spot.CHcurvejz, spotEdited.CHcurvejz); + assignFromKeyfile(keyFile, "Locallab", "LHCurvejz_" + index_str, spot.LHcurvejz, spotEdited.LHcurvejz); + assignFromKeyfile(keyFile, "Locallab", "Lightlcie_" + index_str, spot.lightlcie, spotEdited.lightlcie); + assignFromKeyfile(keyFile, "Locallab", "Lightjzcie_" + index_str, spot.lightjzcie, spotEdited.lightjzcie); + assignFromKeyfile(keyFile, "Locallab", "Brightqcie_" + index_str, spot.lightqcie, spotEdited.lightqcie); + assignFromKeyfile(keyFile, "Locallab", "Contlcie_" + index_str, spot.contlcie, spotEdited.contlcie); + assignFromKeyfile(keyFile, "Locallab", "Contjzcie_" + index_str, spot.contjzcie, spotEdited.contjzcie); + assignFromKeyfile(keyFile, "Locallab", "Adapjzcie_" + index_str, spot.adapjzcie, spotEdited.adapjzcie); + assignFromKeyfile(keyFile, "Locallab", "Jz100_" + index_str, spot.jz100, spotEdited.jz100); + assignFromKeyfile(keyFile, "Locallab", "PQremap_" + index_str, spot.pqremap, spotEdited.pqremap); + assignFromKeyfile(keyFile, "Locallab", "PQremapcam16_" + index_str, spot.pqremapcam16, spotEdited.pqremapcam16); + assignFromKeyfile(keyFile, "Locallab", "Hljzcie_" + index_str, spot.hljzcie, spotEdited.hljzcie); + assignFromKeyfile(keyFile, "Locallab", "Hlthjzcie_" + index_str, spot.hlthjzcie, spotEdited.hlthjzcie); + assignFromKeyfile(keyFile, "Locallab", "Shjzcie_" + index_str, spot.shjzcie, spotEdited.shjzcie); + assignFromKeyfile(keyFile, "Locallab", "Shthjzcie_" + index_str, spot.shthjzcie, spotEdited.shthjzcie); + assignFromKeyfile(keyFile, "Locallab", "Radjzcie_" + index_str, spot.radjzcie, spotEdited.radjzcie); if (keyFile.has_key("Locallab", "CSThresholdjz_" + index_str)) { const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdjz_" + index_str); @@ -9478,54 +9474,54 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.csthresholdjz = true; } - assignFromKeyfile(keyFile, "Locallab", "Sigmalcjz_" + index_str, pedited, spot.sigmalcjz, spotEdited.sigmalcjz); - assignFromKeyfile(keyFile, "Locallab", "Clarilresjz_" + index_str, pedited, spot.clarilresjz, spotEdited.clarilresjz); - assignFromKeyfile(keyFile, "Locallab", "Claricresjz_" + index_str, pedited, spot.claricresjz, spotEdited.claricresjz); - assignFromKeyfile(keyFile, "Locallab", "Clarisoftjz_" + index_str, pedited, spot.clarisoftjz, spotEdited.clarisoftjz); - assignFromKeyfile(keyFile, "Locallab", "LocwavCurvejz_" + index_str, pedited, spot.locwavcurvejz, spotEdited.locwavcurvejz); - assignFromKeyfile(keyFile, "Locallab", "Contthrescie_" + index_str, pedited, spot.contthrescie, spotEdited.contthrescie); - assignFromKeyfile(keyFile, "Locallab", "Contthrescie_" + index_str, pedited, spot.contthrescie, spotEdited.contthrescie); - assignFromKeyfile(keyFile, "Locallab", "BlackEvjz_" + index_str, pedited, spot.blackEvjz, spotEdited.blackEvjz); - assignFromKeyfile(keyFile, "Locallab", "WhiteEvjz_" + index_str, pedited, spot.whiteEvjz, spotEdited.whiteEvjz); - assignFromKeyfile(keyFile, "Locallab", "Targetjz_" + index_str, pedited, spot.targetjz, spotEdited.targetjz); - assignFromKeyfile(keyFile, "Locallab", "Sigmoidthcie_" + index_str, pedited, spot.sigmoidthcie, spotEdited.sigmoidthcie); - assignFromKeyfile(keyFile, "Locallab", "Sigmoidblcie_" + index_str, pedited, spot.sigmoidblcie, spotEdited.sigmoidblcie); - assignFromKeyfile(keyFile, "Locallab", "Sigmoidldajzcie_" + index_str, pedited, spot.sigmoidldajzcie, spotEdited.sigmoidldajzcie); - assignFromKeyfile(keyFile, "Locallab", "Sigmoidthjzcie_" + index_str, pedited, spot.sigmoidthjzcie, spotEdited.sigmoidthjzcie); - assignFromKeyfile(keyFile, "Locallab", "Sigmoidbljzcie_" + index_str, pedited, spot.sigmoidbljzcie, spotEdited.sigmoidbljzcie); - assignFromKeyfile(keyFile, "Locallab", "Contqcie_" + index_str, pedited, spot.contqcie, spotEdited.contqcie); - assignFromKeyfile(keyFile, "Locallab", "Colorflcie_" + index_str, pedited, spot.colorflcie, spotEdited.colorflcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmalcjz_" + index_str, spot.sigmalcjz, spotEdited.sigmalcjz); + assignFromKeyfile(keyFile, "Locallab", "Clarilresjz_" + index_str, spot.clarilresjz, spotEdited.clarilresjz); + assignFromKeyfile(keyFile, "Locallab", "Claricresjz_" + index_str, spot.claricresjz, spotEdited.claricresjz); + assignFromKeyfile(keyFile, "Locallab", "Clarisoftjz_" + index_str, spot.clarisoftjz, spotEdited.clarisoftjz); + assignFromKeyfile(keyFile, "Locallab", "LocwavCurvejz_" + index_str, spot.locwavcurvejz, spotEdited.locwavcurvejz); + assignFromKeyfile(keyFile, "Locallab", "Contthrescie_" + index_str, spot.contthrescie, spotEdited.contthrescie); + assignFromKeyfile(keyFile, "Locallab", "Contthrescie_" + index_str, spot.contthrescie, spotEdited.contthrescie); + assignFromKeyfile(keyFile, "Locallab", "BlackEvjz_" + index_str, spot.blackEvjz, spotEdited.blackEvjz); + assignFromKeyfile(keyFile, "Locallab", "WhiteEvjz_" + index_str, spot.whiteEvjz, spotEdited.whiteEvjz); + assignFromKeyfile(keyFile, "Locallab", "Targetjz_" + index_str, spot.targetjz, spotEdited.targetjz); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidthcie_" + index_str, spot.sigmoidthcie, spotEdited.sigmoidthcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidblcie_" + index_str, spot.sigmoidblcie, spotEdited.sigmoidblcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidldajzcie_" + index_str, spot.sigmoidldajzcie, spotEdited.sigmoidldajzcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidthjzcie_" + index_str, spot.sigmoidthjzcie, spotEdited.sigmoidthjzcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidbljzcie_" + index_str, spot.sigmoidbljzcie, spotEdited.sigmoidbljzcie); + assignFromKeyfile(keyFile, "Locallab", "Contqcie_" + index_str, spot.contqcie, spotEdited.contqcie); + assignFromKeyfile(keyFile, "Locallab", "Colorflcie_" + index_str, spot.colorflcie, spotEdited.colorflcie); /* - assignFromKeyfile(keyFile, "Locallab", "Lightlzcam_" + index_str, pedited, spot.lightlzcam, spotEdited.lightlzcam); - assignFromKeyfile(keyFile, "Locallab", "Lightqzcam_" + index_str, pedited, spot.lightqzcam, spotEdited.lightqzcam); - assignFromKeyfile(keyFile, "Locallab", "Contlzcam_" + index_str, pedited, spot.contlzcam, spotEdited.contlzcam); - assignFromKeyfile(keyFile, "Locallab", "Contqzcam_" + index_str, pedited, spot.contqzcam, spotEdited.contqzcam); - assignFromKeyfile(keyFile, "Locallab", "Contthreszcam_" + index_str, pedited, spot.contthreszcam, spotEdited.contthreszcam); + assignFromKeyfile(keyFile, "Locallab", "Lightlzcam_" + index_str, spot.lightlzcam, spotEdited.lightlzcam); + assignFromKeyfile(keyFile, "Locallab", "Lightqzcam_" + index_str, spot.lightqzcam, spotEdited.lightqzcam); + assignFromKeyfile(keyFile, "Locallab", "Contlzcam_" + index_str, spot.contlzcam, spotEdited.contlzcam); + assignFromKeyfile(keyFile, "Locallab", "Contqzcam_" + index_str, spot.contqzcam, spotEdited.contqzcam); + assignFromKeyfile(keyFile, "Locallab", "Contthreszcam_" + index_str, spot.contthreszcam, spotEdited.contthreszcam); */ - assignFromKeyfile(keyFile, "Locallab", "Targabscie_" + index_str, pedited, spot.targabscie, spotEdited.targabscie); - assignFromKeyfile(keyFile, "Locallab", "TargetGraycie_" + index_str, pedited, spot.targetGraycie, spotEdited.targetGraycie); - assignFromKeyfile(keyFile, "Locallab", "Catadcie_" + index_str, pedited, spot.catadcie, spotEdited.catadcie); - assignFromKeyfile(keyFile, "Locallab", "Detailcie_" + index_str, pedited, spot.detailcie, spotEdited.detailcie); + assignFromKeyfile(keyFile, "Locallab", "Targabscie_" + index_str, spot.targabscie, spotEdited.targabscie); + assignFromKeyfile(keyFile, "Locallab", "TargetGraycie_" + index_str, spot.targetGraycie, spotEdited.targetGraycie); + assignFromKeyfile(keyFile, "Locallab", "Catadcie_" + index_str, spot.catadcie, spotEdited.catadcie); + assignFromKeyfile(keyFile, "Locallab", "Detailcie_" + index_str, spot.detailcie, spotEdited.detailcie); /* - assignFromKeyfile(keyFile, "Locallab", "Colorflzcam_" + index_str, pedited, spot.colorflzcam, spotEdited.colorflzcam); - assignFromKeyfile(keyFile, "Locallab", "Saturzcam_" + index_str, pedited, spot.saturzcam, spotEdited.saturzcam); - assignFromKeyfile(keyFile, "Locallab", "Chromzcam_" + index_str, pedited, spot.chromzcam, spotEdited.chromzcam); + assignFromKeyfile(keyFile, "Locallab", "Colorflzcam_" + index_str, spot.colorflzcam, spotEdited.colorflzcam); + assignFromKeyfile(keyFile, "Locallab", "Saturzcam_" + index_str, spot.saturzcam, spotEdited.saturzcam); + assignFromKeyfile(keyFile, "Locallab", "Chromzcam_" + index_str, spot.chromzcam, spotEdited.chromzcam); */ - assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, pedited, spot.enacieMask, spotEdited.enacieMask); - assignFromKeyfile(keyFile, "Locallab", "CCmaskcieCurve_" + index_str, pedited, spot.CCmaskciecurve, spotEdited.CCmaskciecurve); - assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurve_" + index_str, pedited, spot.LLmaskciecurve, spotEdited.LLmaskciecurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskcieCurve_" + index_str, pedited, spot.HHmaskciecurve, spotEdited.HHmaskciecurve); - assignFromKeyfile(keyFile, "Locallab", "Blendmaskcie_" + index_str, pedited, spot.blendmaskcie, spotEdited.blendmaskcie); - assignFromKeyfile(keyFile, "Locallab", "Radmaskcie_" + index_str, pedited, spot.radmaskcie, spotEdited.radmaskcie); - assignFromKeyfile(keyFile, "Locallab", "Chromaskcie_" + index_str, pedited, spot.chromaskcie, spotEdited.chromaskcie); - assignFromKeyfile(keyFile, "Locallab", "Lapmaskcie_" + index_str, pedited, spot.lapmaskcie, spotEdited.lapmaskcie); - assignFromKeyfile(keyFile, "Locallab", "Gammaskcie_" + index_str, pedited, spot.gammaskcie, spotEdited.gammaskcie); - assignFromKeyfile(keyFile, "Locallab", "Slomaskcie_" + index_str, pedited, spot.slomaskcie, spotEdited.slomaskcie); - assignFromKeyfile(keyFile, "Locallab", "LmaskcieCurve_" + index_str, pedited, spot.Lmaskciecurve, spotEdited.Lmaskciecurve); - assignFromKeyfile(keyFile, "Locallab", "Recothrescie_" + index_str, pedited, spot.recothrescie, spotEdited.recothrescie); - assignFromKeyfile(keyFile, "Locallab", "Lowthrescie_" + index_str, pedited, spot.lowthrescie, spotEdited.lowthrescie); - assignFromKeyfile(keyFile, "Locallab", "Higthrescie_" + index_str, pedited, spot.higthrescie, spotEdited.higthrescie); - assignFromKeyfile(keyFile, "Locallab", "Decaycie_" + index_str, pedited, spot.decaycie, spotEdited.decaycie); + assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, spotEdited.enacieMask); + assignFromKeyfile(keyFile, "Locallab", "CCmaskcieCurve_" + index_str, spot.CCmaskciecurve, spotEdited.CCmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurve_" + index_str, spot.LLmaskciecurve, spotEdited.LLmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskcieCurve_" + index_str, spot.HHmaskciecurve, spotEdited.HHmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "Blendmaskcie_" + index_str, spot.blendmaskcie, spotEdited.blendmaskcie); + assignFromKeyfile(keyFile, "Locallab", "Radmaskcie_" + index_str, spot.radmaskcie, spotEdited.radmaskcie); + assignFromKeyfile(keyFile, "Locallab", "Chromaskcie_" + index_str, spot.chromaskcie, spotEdited.chromaskcie); + assignFromKeyfile(keyFile, "Locallab", "Lapmaskcie_" + index_str, spot.lapmaskcie, spotEdited.lapmaskcie); + assignFromKeyfile(keyFile, "Locallab", "Gammaskcie_" + index_str, spot.gammaskcie, spotEdited.gammaskcie); + assignFromKeyfile(keyFile, "Locallab", "Slomaskcie_" + index_str, spot.slomaskcie, spotEdited.slomaskcie); + assignFromKeyfile(keyFile, "Locallab", "LmaskcieCurve_" + index_str, spot.Lmaskciecurve, spotEdited.Lmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "Recothrescie_" + index_str, spot.recothrescie, spotEdited.recothrescie); + assignFromKeyfile(keyFile, "Locallab", "Lowthrescie_" + index_str, spot.lowthrescie, spotEdited.lowthrescie); + assignFromKeyfile(keyFile, "Locallab", "Higthrescie_" + index_str, spot.higthrescie, spotEdited.higthrescie); + assignFromKeyfile(keyFile, "Locallab", "Decaycie_" + index_str, spot.decaycie, spotEdited.decaycie); // Append LocallabSpot and LocallabParamsEdited locallab.spots.push_back(spot); @@ -9540,37 +9536,37 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("PCVignette")) { - assignFromKeyfile(keyFile, "PCVignette", "Enabled", pedited, pcvignette.enabled, pedited->pcvignette.enabled); - assignFromKeyfile(keyFile, "PCVignette", "Strength", pedited, pcvignette.strength, pedited->pcvignette.strength); - assignFromKeyfile(keyFile, "PCVignette", "Feather", pedited, pcvignette.feather, pedited->pcvignette.feather); - assignFromKeyfile(keyFile, "PCVignette", "Roundness", pedited, pcvignette.roundness, pedited->pcvignette.roundness); + assignFromKeyfile(keyFile, "PCVignette", "Enabled", pcvignette.enabled, pedited->pcvignette.enabled); + assignFromKeyfile(keyFile, "PCVignette", "Strength", pcvignette.strength, pedited->pcvignette.strength); + assignFromKeyfile(keyFile, "PCVignette", "Feather", pcvignette.feather, pedited->pcvignette.feather); + assignFromKeyfile(keyFile, "PCVignette", "Roundness", pcvignette.roundness, pedited->pcvignette.roundness); } if (keyFile.has_group("CACorrection")) { - assignFromKeyfile(keyFile, "CACorrection", "Red", pedited, cacorrection.red, pedited->cacorrection.red); - assignFromKeyfile(keyFile, "CACorrection", "Blue", pedited, cacorrection.blue, pedited->cacorrection.blue); + assignFromKeyfile(keyFile, "CACorrection", "Red", cacorrection.red, pedited->cacorrection.red); + assignFromKeyfile(keyFile, "CACorrection", "Blue", cacorrection.blue, pedited->cacorrection.blue); } if (keyFile.has_group("Vignetting Correction")) { - assignFromKeyfile(keyFile, "Vignetting Correction", "Amount", pedited, vignetting.amount, pedited->vignetting.amount); - assignFromKeyfile(keyFile, "Vignetting Correction", "Radius", pedited, vignetting.radius, pedited->vignetting.radius); - assignFromKeyfile(keyFile, "Vignetting Correction", "Strength", pedited, vignetting.strength, pedited->vignetting.strength); - assignFromKeyfile(keyFile, "Vignetting Correction", "CenterX", pedited, vignetting.centerX, pedited->vignetting.centerX); - assignFromKeyfile(keyFile, "Vignetting Correction", "CenterY", pedited, vignetting.centerY, pedited->vignetting.centerY); + assignFromKeyfile(keyFile, "Vignetting Correction", "Amount", vignetting.amount, pedited->vignetting.amount); + assignFromKeyfile(keyFile, "Vignetting Correction", "Radius", vignetting.radius, pedited->vignetting.radius); + assignFromKeyfile(keyFile, "Vignetting Correction", "Strength", vignetting.strength, pedited->vignetting.strength); + assignFromKeyfile(keyFile, "Vignetting Correction", "CenterX", vignetting.centerX, pedited->vignetting.centerX); + assignFromKeyfile(keyFile, "Vignetting Correction", "CenterY", vignetting.centerY, pedited->vignetting.centerY); } if (keyFile.has_group("Resize")) { - assignFromKeyfile(keyFile, "Resize", "Enabled", pedited, resize.enabled, pedited->resize.enabled); - assignFromKeyfile(keyFile, "Resize", "Scale", pedited, resize.scale, pedited->resize.scale); - assignFromKeyfile(keyFile, "Resize", "AppliesTo", pedited, resize.appliesTo, pedited->resize.appliesTo); - assignFromKeyfile(keyFile, "Resize", "Method", pedited, resize.method, pedited->resize.method); - assignFromKeyfile(keyFile, "Resize", "DataSpecified", pedited, resize.dataspec, pedited->resize.dataspec); - assignFromKeyfile(keyFile, "Resize", "Width", pedited, resize.width, pedited->resize.width); - assignFromKeyfile(keyFile, "Resize", "Height", pedited, resize.height, pedited->resize.height); - assignFromKeyfile(keyFile, "Resize", "LongEdge", pedited, resize.longedge, pedited->resize.longedge); - assignFromKeyfile(keyFile, "Resize", "ShortEdge", pedited, resize.shortedge, pedited->resize.shortedge); + assignFromKeyfile(keyFile, "Resize", "Enabled", resize.enabled, pedited->resize.enabled); + assignFromKeyfile(keyFile, "Resize", "Scale", resize.scale, pedited->resize.scale); + assignFromKeyfile(keyFile, "Resize", "AppliesTo", resize.appliesTo, pedited->resize.appliesTo); + assignFromKeyfile(keyFile, "Resize", "Method", resize.method, pedited->resize.method); + assignFromKeyfile(keyFile, "Resize", "DataSpecified", resize.dataspec, pedited->resize.dataspec); + assignFromKeyfile(keyFile, "Resize", "Width", resize.width, pedited->resize.width); + assignFromKeyfile(keyFile, "Resize", "Height", resize.height, pedited->resize.height); + assignFromKeyfile(keyFile, "Resize", "LongEdge", resize.longedge, pedited->resize.longedge); + assignFromKeyfile(keyFile, "Resize", "ShortEdge", resize.shortedge, pedited->resize.shortedge); if (ppVersion >= 339) { - assignFromKeyfile(keyFile, "Resize", "AllowUpscaling", pedited, resize.allowUpscaling, pedited->resize.allowUpscaling); + assignFromKeyfile(keyFile, "Resize", "AllowUpscaling", resize.allowUpscaling, pedited->resize.allowUpscaling); } else { resize.allowUpscaling = false; if (pedited) { @@ -9580,7 +9576,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group ("Spot removal")) { - assignFromKeyfile(keyFile, "Spot removal", "Enabled", pedited, spot.enabled, pedited->spot.enabled); + assignFromKeyfile(keyFile, "Spot removal", "Enabled", spot.enabled, pedited->spot.enabled); int i = 0; do { std::stringstream ss; @@ -9608,21 +9604,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (keyFile.has_group("PostDemosaicSharpening")) { - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pedited, pdsharpening.enabled, pedited->pdsharpening.enabled); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pedited, pdsharpening.contrast, pedited->pdsharpening.contrast); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pedited, pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pedited, pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pedited, pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pedited, pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterCheck", pedited, pdsharpening.deconvitercheck, pedited->pdsharpening.deconvitercheck); - assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pedited, pdsharpening.deconviter, pedited->pdsharpening.deconviter); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Enabled", pdsharpening.enabled, pedited->pdsharpening.enabled); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "Contrast", pdsharpening.contrast, pedited->pdsharpening.contrast); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoContrast", pdsharpening.autoContrast, pedited->pdsharpening.autoContrast); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "AutoRadius", pdsharpening.autoRadius, pedited->pdsharpening.autoRadius); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadius", pdsharpening.deconvradius, pedited->pdsharpening.deconvradius); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvRadiusOffset", pdsharpening.deconvradiusOffset, pedited->pdsharpening.deconvradiusOffset); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterCheck", pdsharpening.deconvitercheck, pedited->pdsharpening.deconvitercheck); + assignFromKeyfile(keyFile, "PostDemosaicSharpening", "DeconvIterations", pdsharpening.deconviter, pedited->pdsharpening.deconviter); } if (keyFile.has_group("PostResizeSharpening")) { - assignFromKeyfile(keyFile, "PostResizeSharpening", "Enabled", pedited, prsharpening.enabled, pedited->prsharpening.enabled); - assignFromKeyfile(keyFile, "PostResizeSharpening", "Contrast", pedited, prsharpening.contrast, pedited->prsharpening.contrast); - assignFromKeyfile(keyFile, "PostResizeSharpening", "Radius", pedited, prsharpening.radius, pedited->prsharpening.radius); - assignFromKeyfile(keyFile, "PostResizeSharpening", "Amount", pedited, prsharpening.amount, pedited->prsharpening.amount); + assignFromKeyfile(keyFile, "PostResizeSharpening", "Enabled", prsharpening.enabled, pedited->prsharpening.enabled); + assignFromKeyfile(keyFile, "PostResizeSharpening", "Contrast", prsharpening.contrast, pedited->prsharpening.contrast); + assignFromKeyfile(keyFile, "PostResizeSharpening", "Radius", prsharpening.radius, pedited->prsharpening.radius); + assignFromKeyfile(keyFile, "PostResizeSharpening", "Amount", prsharpening.amount, pedited->prsharpening.amount); if (keyFile.has_key("PostResizeSharpening", "Threshold")) { if (ppVersion < 302) { @@ -9641,16 +9637,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "PostResizeSharpening", "OnlyEdges", pedited, prsharpening.edgesonly, pedited->prsharpening.edgesonly); - assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgedetectionRadius", pedited, prsharpening.edges_radius, pedited->prsharpening.edges_radius); - assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgeTolerance", pedited, prsharpening.edges_tolerance, pedited->prsharpening.edges_tolerance); - assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolEnabled", pedited, prsharpening.halocontrol, pedited->prsharpening.halocontrol); - assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolAmount", pedited, prsharpening.halocontrol_amount, pedited->prsharpening.halocontrol_amount); - assignFromKeyfile(keyFile, "PostResizeSharpening", "Method", pedited, prsharpening.method, pedited->prsharpening.method); - assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvRadius", pedited, prsharpening.deconvradius, pedited->prsharpening.deconvradius); - assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvAmount", pedited, prsharpening.deconvamount, pedited->prsharpening.deconvamount); - assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvDamping", pedited, prsharpening.deconvdamping, pedited->prsharpening.deconvdamping); - assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvIterations", pedited, prsharpening.deconviter, pedited->prsharpening.deconviter); + assignFromKeyfile(keyFile, "PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly, pedited->prsharpening.edgesonly); + assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius, pedited->prsharpening.edges_radius); + assignFromKeyfile(keyFile, "PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance, pedited->prsharpening.edges_tolerance); + assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol, pedited->prsharpening.halocontrol); + assignFromKeyfile(keyFile, "PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount, pedited->prsharpening.halocontrol_amount); + assignFromKeyfile(keyFile, "PostResizeSharpening", "Method", prsharpening.method, pedited->prsharpening.method); + assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius, pedited->prsharpening.deconvradius); + assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount, pedited->prsharpening.deconvamount); + assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping, pedited->prsharpening.deconvdamping); + assignFromKeyfile(keyFile, "PostResizeSharpening", "DeconvIterations", prsharpening.deconviter, pedited->prsharpening.deconviter); } if (keyFile.has_group("Color Management")) { @@ -9661,18 +9657,17 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->icm.inputProfile = true; } } - assignFromKeyfile(keyFile, "Color Management", "ToneCurve", pedited, icm.toneCurve, pedited->icm.toneCurve); - assignFromKeyfile(keyFile, "Color Management", "ApplyLookTable", pedited, icm.applyLookTable, pedited->icm.applyLookTable); - assignFromKeyfile(keyFile, "Color Management", "ApplyBaselineExposureOffset", pedited, icm.applyBaselineExposureOffset, pedited->icm.applyBaselineExposureOffset); - assignFromKeyfile(keyFile, "Color Management", "ApplyHueSatMap", pedited, icm.applyHueSatMap, pedited->icm.applyHueSatMap); - assignFromKeyfile(keyFile, "Color Management", "DCPIlluminant", pedited, icm.dcpIlluminant, pedited->icm.dcpIlluminant); - assignFromKeyfile(keyFile, "Color Management", "WorkingProfile", pedited, icm.workingProfile, pedited->icm.workingProfile); + assignFromKeyfile(keyFile, "Color Management", "ToneCurve", icm.toneCurve, pedited->icm.toneCurve); + assignFromKeyfile(keyFile, "Color Management", "ApplyLookTable", icm.applyLookTable, pedited->icm.applyLookTable); + assignFromKeyfile(keyFile, "Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset, pedited->icm.applyBaselineExposureOffset); + assignFromKeyfile(keyFile, "Color Management", "ApplyHueSatMap", icm.applyHueSatMap, pedited->icm.applyHueSatMap); + assignFromKeyfile(keyFile, "Color Management", "DCPIlluminant", icm.dcpIlluminant, pedited->icm.dcpIlluminant); + assignFromKeyfile(keyFile, "Color Management", "WorkingProfile", icm.workingProfile, pedited->icm.workingProfile); if ( !assignFromKeyfile( keyFile, "Color Management", "WorkingTRC", - pedited, { {"none", ColorManagementParams::WorkingTrc::NONE}, {"Custom", ColorManagementParams::WorkingTrc::CUSTOM}, @@ -9696,7 +9691,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) keyFile, "Color Management", "Will", - pedited, { {"def", ColorManagementParams::Illuminant::DEFAULT}, {"D41", ColorManagementParams::Illuminant::D41}, @@ -9724,7 +9718,6 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) keyFile, "Color Management", "Wprim", - pedited, { {"def", ColorManagementParams::Primaries::DEFAULT}, {"srgb", ColorManagementParams::Primaries::SRGB}, @@ -9750,26 +9743,26 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->icm.wprim = true; } } - assignFromKeyfile(keyFile, "Color Management", "WorkingTRCGamma", pedited, icm.workingTRCGamma, pedited->icm.workingTRCGamma); - assignFromKeyfile(keyFile, "Color Management", "WorkingTRCSlope", pedited, icm.workingTRCSlope, pedited->icm.workingTRCSlope); + assignFromKeyfile(keyFile, "Color Management", "WorkingTRCGamma", icm.workingTRCGamma, pedited->icm.workingTRCGamma); + assignFromKeyfile(keyFile, "Color Management", "WorkingTRCSlope", icm.workingTRCSlope, pedited->icm.workingTRCSlope); - assignFromKeyfile(keyFile, "Color Management", "Redx", pedited, icm.redx, pedited->icm.redx); - assignFromKeyfile(keyFile, "Color Management", "Redy", pedited, icm.redy, pedited->icm.redy); - assignFromKeyfile(keyFile, "Color Management", "Grex", pedited, icm.grex, pedited->icm.grex); - assignFromKeyfile(keyFile, "Color Management", "Grey", pedited, icm.grey, pedited->icm.grey); - assignFromKeyfile(keyFile, "Color Management", "Blux", pedited, icm.blux, pedited->icm.blux); - assignFromKeyfile(keyFile, "Color Management", "Bluy", pedited, icm.bluy, pedited->icm.bluy); - assignFromKeyfile(keyFile, "Color Management", "Preser", pedited, icm.preser, pedited->icm.preser); - assignFromKeyfile(keyFile, "Color Management", "Fbw", pedited, icm.fbw, pedited->icm.fbw); - assignFromKeyfile(keyFile, "Color Management", "Gamut", pedited, icm.gamut, pedited->icm.gamut); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieALow", pedited, icm.labgridcieALow, pedited->icm.labgridcieALow); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieBLow", pedited, icm.labgridcieBLow, pedited->icm.labgridcieBLow); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieAHigh", pedited, icm.labgridcieAHigh, pedited->icm.labgridcieAHigh); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieBHigh", pedited, icm.labgridcieBHigh, pedited->icm.labgridcieBHigh); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieGx", pedited, icm.labgridcieGx, pedited->icm.labgridcieGx); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieGy", pedited, icm.labgridcieGy, pedited->icm.labgridcieGy); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieWx", pedited, icm.labgridcieWx, pedited->icm.labgridcieWx); - assignFromKeyfile(keyFile, "Color Management", "LabGridcieWy", pedited, icm.labgridcieWy, pedited->icm.labgridcieWy); + assignFromKeyfile(keyFile, "Color Management", "Redx", icm.redx, pedited->icm.redx); + assignFromKeyfile(keyFile, "Color Management", "Redy", icm.redy, pedited->icm.redy); + assignFromKeyfile(keyFile, "Color Management", "Grex", icm.grex, pedited->icm.grex); + assignFromKeyfile(keyFile, "Color Management", "Grey", icm.grey, pedited->icm.grey); + assignFromKeyfile(keyFile, "Color Management", "Blux", icm.blux, pedited->icm.blux); + assignFromKeyfile(keyFile, "Color Management", "Bluy", icm.bluy, pedited->icm.bluy); + assignFromKeyfile(keyFile, "Color Management", "Preser", icm.preser, pedited->icm.preser); + assignFromKeyfile(keyFile, "Color Management", "Fbw", icm.fbw, pedited->icm.fbw); + assignFromKeyfile(keyFile, "Color Management", "Gamut", icm.gamut, pedited->icm.gamut); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieALow", icm.labgridcieALow, pedited->icm.labgridcieALow); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieBLow", icm.labgridcieBLow, pedited->icm.labgridcieBLow); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieAHigh", icm.labgridcieAHigh, pedited->icm.labgridcieAHigh); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieBHigh", icm.labgridcieBHigh, pedited->icm.labgridcieBHigh); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieGx", icm.labgridcieGx, pedited->icm.labgridcieGx); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieGy", icm.labgridcieGy, pedited->icm.labgridcieGy); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieWx", icm.labgridcieWx, pedited->icm.labgridcieWx); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieWy", icm.labgridcieWy, pedited->icm.labgridcieWy); if (keyFile.has_key("Color Management", "aIntent")) { Glib::ustring intent = keyFile.get_string("Color Management", "aIntent"); @@ -9788,7 +9781,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Color Management", "OutputProfile", pedited, icm.outputProfile, pedited->icm.outputProfile); + assignFromKeyfile(keyFile, "Color Management", "OutputProfile", icm.outputProfile, pedited->icm.outputProfile); if (ppVersion < 341) { if (icm.outputProfile == "RT_Medium_gsRGB") { icm.outputProfile = "RTv4_Medium"; @@ -9827,73 +9820,73 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->icm.outputIntent = true; } } - assignFromKeyfile(keyFile, "Color Management", "OutputBPC", pedited, icm.outputBPC, pedited->icm.outputBPC); + assignFromKeyfile(keyFile, "Color Management", "OutputBPC", icm.outputBPC, pedited->icm.outputBPC); } if (keyFile.has_group("Wavelet")) { - assignFromKeyfile(keyFile, "Wavelet", "Enabled", pedited, wavelet.enabled, pedited->wavelet.enabled); - assignFromKeyfile(keyFile, "Wavelet", "Strength", pedited, wavelet.strength, pedited->wavelet.strength); - assignFromKeyfile(keyFile, "Wavelet", "Balance", pedited, wavelet.balance, pedited->wavelet.balance); - assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", pedited, wavelet.sigmafin, pedited->wavelet.sigmafin); - assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", pedited, wavelet.sigmaton, pedited->wavelet.sigmaton); - assignFromKeyfile(keyFile, "Wavelet", "Sigmacol", pedited, wavelet.sigmacol, pedited->wavelet.sigmacol); - assignFromKeyfile(keyFile, "Wavelet", "Sigmadir", pedited, wavelet.sigmadir, pedited->wavelet.sigmadir); - assignFromKeyfile(keyFile, "Wavelet", "Rangeab", pedited, wavelet.rangeab, pedited->wavelet.rangeab); - assignFromKeyfile(keyFile, "Wavelet", "Protab", pedited, wavelet.protab, pedited->wavelet.protab); - assignFromKeyfile(keyFile, "Wavelet", "Iter", pedited, wavelet.iter, pedited->wavelet.iter); - assignFromKeyfile(keyFile, "Wavelet", "Median", pedited, wavelet.median, pedited->wavelet.median); - assignFromKeyfile(keyFile, "Wavelet", "Medianlev", pedited, wavelet.medianlev, pedited->wavelet.medianlev); - assignFromKeyfile(keyFile, "Wavelet", "Linkedg", pedited, wavelet.linkedg, pedited->wavelet.linkedg); - assignFromKeyfile(keyFile, "Wavelet", "CBenab", pedited, wavelet.cbenab, pedited->wavelet.cbenab); - assignFromKeyfile(keyFile, "Wavelet", "CBgreenhigh", pedited, wavelet.greenhigh, pedited->wavelet.greenhigh); - assignFromKeyfile(keyFile, "Wavelet", "CBgreenmed", pedited, wavelet.greenmed, pedited->wavelet.greenmed); - assignFromKeyfile(keyFile, "Wavelet", "CBgreenlow", pedited, wavelet.greenlow, pedited->wavelet.greenlow); - assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh); - assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed); - assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow); - assignFromKeyfile(keyFile, "Wavelet", "Ballum", pedited, wavelet.ballum, pedited->wavelet.ballum); - assignFromKeyfile(keyFile, "Wavelet", "Sigm", pedited, wavelet.sigm, pedited->wavelet.sigm); - assignFromKeyfile(keyFile, "Wavelet", "Levden", pedited, wavelet.levden, pedited->wavelet.levden); - assignFromKeyfile(keyFile, "Wavelet", "Thrden", pedited, wavelet.thrden, pedited->wavelet.thrden); - assignFromKeyfile(keyFile, "Wavelet", "Limden", pedited, wavelet.limden, pedited->wavelet.limden); - assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom); - assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi); - assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco); - assignFromKeyfile(keyFile, "Wavelet", "MergeL", pedited, wavelet.mergeL, pedited->wavelet.mergeL); - assignFromKeyfile(keyFile, "Wavelet", "MergeC", pedited, wavelet.mergeC, pedited->wavelet.mergeC); - assignFromKeyfile(keyFile, "Wavelet", "Softrad", pedited, wavelet.softrad, pedited->wavelet.softrad); - assignFromKeyfile(keyFile, "Wavelet", "Softradend", pedited, wavelet.softradend, pedited->wavelet.softradend); - assignFromKeyfile(keyFile, "Wavelet", "Strend", pedited, wavelet.strend, pedited->wavelet.strend); - assignFromKeyfile(keyFile, "Wavelet", "Detend", pedited, wavelet.detend, pedited->wavelet.detend); - assignFromKeyfile(keyFile, "Wavelet", "Thrend", pedited, wavelet.thrend, pedited->wavelet.thrend); - assignFromKeyfile(keyFile, "Wavelet", "Lipst", pedited, wavelet.lipst, pedited->wavelet.lipst); - assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", pedited, wavelet.avoid, pedited->wavelet.avoid); - assignFromKeyfile(keyFile, "Wavelet", "Showmask", pedited, wavelet.showmask, pedited->wavelet.showmask); - assignFromKeyfile(keyFile, "Wavelet", "Oldsh", pedited, wavelet.oldsh, pedited->wavelet.oldsh); - assignFromKeyfile(keyFile, "Wavelet", "TMr", pedited, wavelet.tmr, pedited->wavelet.tmr); - assignFromKeyfile(keyFile, "Wavelet", "LabGridALow", pedited, wavelet.labgridALow, pedited->wavelet.labgridALow); - assignFromKeyfile(keyFile, "Wavelet", "LabGridBLow", pedited, wavelet.labgridBLow, pedited->wavelet.labgridBLow); - assignFromKeyfile(keyFile, "Wavelet", "LabGridAHigh", pedited, wavelet.labgridAHigh, pedited->wavelet.labgridAHigh); - assignFromKeyfile(keyFile, "Wavelet", "LabGridBHigh", pedited, wavelet.labgridBHigh, pedited->wavelet.labgridBHigh); + assignFromKeyfile(keyFile, "Wavelet", "Enabled", wavelet.enabled, pedited->wavelet.enabled); + assignFromKeyfile(keyFile, "Wavelet", "Strength", wavelet.strength, pedited->wavelet.strength); + assignFromKeyfile(keyFile, "Wavelet", "Balance", wavelet.balance, pedited->wavelet.balance); + assignFromKeyfile(keyFile, "Wavelet", "Sigmafin", wavelet.sigmafin, pedited->wavelet.sigmafin); + assignFromKeyfile(keyFile, "Wavelet", "Sigmaton", wavelet.sigmaton, pedited->wavelet.sigmaton); + assignFromKeyfile(keyFile, "Wavelet", "Sigmacol", wavelet.sigmacol, pedited->wavelet.sigmacol); + assignFromKeyfile(keyFile, "Wavelet", "Sigmadir", wavelet.sigmadir, pedited->wavelet.sigmadir); + assignFromKeyfile(keyFile, "Wavelet", "Rangeab", wavelet.rangeab, pedited->wavelet.rangeab); + assignFromKeyfile(keyFile, "Wavelet", "Protab", wavelet.protab, pedited->wavelet.protab); + assignFromKeyfile(keyFile, "Wavelet", "Iter", wavelet.iter, pedited->wavelet.iter); + assignFromKeyfile(keyFile, "Wavelet", "Median", wavelet.median, pedited->wavelet.median); + assignFromKeyfile(keyFile, "Wavelet", "Medianlev", wavelet.medianlev, pedited->wavelet.medianlev); + assignFromKeyfile(keyFile, "Wavelet", "Linkedg", wavelet.linkedg, pedited->wavelet.linkedg); + assignFromKeyfile(keyFile, "Wavelet", "CBenab", wavelet.cbenab, pedited->wavelet.cbenab); + assignFromKeyfile(keyFile, "Wavelet", "CBgreenhigh", wavelet.greenhigh, pedited->wavelet.greenhigh); + assignFromKeyfile(keyFile, "Wavelet", "CBgreenmed", wavelet.greenmed, pedited->wavelet.greenmed); + assignFromKeyfile(keyFile, "Wavelet", "CBgreenlow", wavelet.greenlow, pedited->wavelet.greenlow); + assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", wavelet.bluehigh, pedited->wavelet.bluehigh); + assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", wavelet.bluemed, pedited->wavelet.bluemed); + assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", wavelet.bluelow, pedited->wavelet.bluelow); + assignFromKeyfile(keyFile, "Wavelet", "Ballum", wavelet.ballum, pedited->wavelet.ballum); + assignFromKeyfile(keyFile, "Wavelet", "Sigm", wavelet.sigm, pedited->wavelet.sigm); + assignFromKeyfile(keyFile, "Wavelet", "Levden", wavelet.levden, pedited->wavelet.levden); + assignFromKeyfile(keyFile, "Wavelet", "Thrden", wavelet.thrden, pedited->wavelet.thrden); + assignFromKeyfile(keyFile, "Wavelet", "Limden", wavelet.limden, pedited->wavelet.limden); + assignFromKeyfile(keyFile, "Wavelet", "Balchrom", wavelet.balchrom, pedited->wavelet.balchrom); + assignFromKeyfile(keyFile, "Wavelet", "Chromfine", wavelet.chromfi, pedited->wavelet.chromfi); + assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", wavelet.chromco, pedited->wavelet.chromco); + assignFromKeyfile(keyFile, "Wavelet", "MergeL", wavelet.mergeL, pedited->wavelet.mergeL); + assignFromKeyfile(keyFile, "Wavelet", "MergeC", wavelet.mergeC, pedited->wavelet.mergeC); + assignFromKeyfile(keyFile, "Wavelet", "Softrad", wavelet.softrad, pedited->wavelet.softrad); + assignFromKeyfile(keyFile, "Wavelet", "Softradend", wavelet.softradend, pedited->wavelet.softradend); + assignFromKeyfile(keyFile, "Wavelet", "Strend", wavelet.strend, pedited->wavelet.strend); + assignFromKeyfile(keyFile, "Wavelet", "Detend", wavelet.detend, pedited->wavelet.detend); + assignFromKeyfile(keyFile, "Wavelet", "Thrend", wavelet.thrend, pedited->wavelet.thrend); + assignFromKeyfile(keyFile, "Wavelet", "Lipst", wavelet.lipst, pedited->wavelet.lipst); + assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", wavelet.avoid, pedited->wavelet.avoid); + assignFromKeyfile(keyFile, "Wavelet", "Showmask", wavelet.showmask, pedited->wavelet.showmask); + assignFromKeyfile(keyFile, "Wavelet", "Oldsh", wavelet.oldsh, pedited->wavelet.oldsh); + assignFromKeyfile(keyFile, "Wavelet", "TMr", wavelet.tmr, pedited->wavelet.tmr); + assignFromKeyfile(keyFile, "Wavelet", "LabGridALow", wavelet.labgridALow, pedited->wavelet.labgridALow); + assignFromKeyfile(keyFile, "Wavelet", "LabGridBLow", wavelet.labgridBLow, pedited->wavelet.labgridBLow); + assignFromKeyfile(keyFile, "Wavelet", "LabGridAHigh", wavelet.labgridAHigh, pedited->wavelet.labgridAHigh); + assignFromKeyfile(keyFile, "Wavelet", "LabGridBHigh", wavelet.labgridBHigh, pedited->wavelet.labgridBHigh); if (ppVersion < 331) { // wavelet.Lmethod was a string before version 331 Glib::ustring temp; - assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, temp, pedited->wavelet.Lmethod); + assignFromKeyfile(keyFile, "Wavelet", "LevMethod", temp, pedited->wavelet.Lmethod); try { wavelet.Lmethod = std::stoi(temp); } catch (...) { } } else { - assignFromKeyfile(keyFile, "Wavelet", "LevMethod", pedited, wavelet.Lmethod, pedited->wavelet.Lmethod); + assignFromKeyfile(keyFile, "Wavelet", "LevMethod", wavelet.Lmethod, pedited->wavelet.Lmethod); } - assignFromKeyfile(keyFile, "Wavelet", "ChoiceLevMethod", pedited, wavelet.CLmethod, pedited->wavelet.CLmethod); - assignFromKeyfile(keyFile, "Wavelet", "BackMethod", pedited, wavelet.Backmethod, pedited->wavelet.Backmethod); - assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", pedited, wavelet.Tilesmethod, pedited->wavelet.Tilesmethod); + assignFromKeyfile(keyFile, "Wavelet", "ChoiceLevMethod", wavelet.CLmethod, pedited->wavelet.CLmethod); + assignFromKeyfile(keyFile, "Wavelet", "BackMethod", wavelet.Backmethod, pedited->wavelet.Backmethod); + assignFromKeyfile(keyFile, "Wavelet", "TilesMethod", wavelet.Tilesmethod, pedited->wavelet.Tilesmethod); if (keyFile.has_key("Wavelet", "complexMethod")) { - assignFromKeyfile(keyFile, "Wavelet", "complexMethod", pedited, wavelet.complexmethod, pedited->wavelet.complexmethod); + assignFromKeyfile(keyFile, "Wavelet", "complexMethod", wavelet.complexmethod, pedited->wavelet.complexmethod); } else if (wavelet.enabled) { wavelet.complexmethod = "expert"; if (pedited) { @@ -9901,67 +9894,67 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - //assignFromKeyfile(keyFile, "Wavelet", "denMethod", pedited, wavelet.denmethod, pedited->wavelet.denmethod); - assignFromKeyfile(keyFile, "Wavelet", "mixMethod", pedited, wavelet.mixmethod, pedited->wavelet.mixmethod); - assignFromKeyfile(keyFile, "Wavelet", "sliMethod", pedited, wavelet.slimethod, pedited->wavelet.slimethod); - assignFromKeyfile(keyFile, "Wavelet", "quaMethod", pedited, wavelet.quamethod, pedited->wavelet.quamethod); - assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", pedited, wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod); - assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", pedited, wavelet.CHmethod, pedited->wavelet.CHmethod); - assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", pedited, wavelet.Medgreinf, pedited->wavelet.Medgreinf); - assignFromKeyfile(keyFile, "Wavelet", "Ushamethod", pedited, wavelet.ushamethod, pedited->wavelet.ushamethod); - assignFromKeyfile(keyFile, "Wavelet", "CHSLromaMethod", pedited, wavelet.CHSLmethod, pedited->wavelet.CHSLmethod); - assignFromKeyfile(keyFile, "Wavelet", "EDMethod", pedited, wavelet.EDmethod, pedited->wavelet.EDmethod); - assignFromKeyfile(keyFile, "Wavelet", "NPMethod", pedited, wavelet.NPmethod, pedited->wavelet.NPmethod); - assignFromKeyfile(keyFile, "Wavelet", "BAMethod", pedited, wavelet.BAmethod, pedited->wavelet.BAmethod); - assignFromKeyfile(keyFile, "Wavelet", "TMMethod", pedited, wavelet.TMmethod, pedited->wavelet.TMmethod); - assignFromKeyfile(keyFile, "Wavelet", "HSMethod", pedited, wavelet.HSmethod, pedited->wavelet.HSmethod); - assignFromKeyfile(keyFile, "Wavelet", "DirMethod", pedited, wavelet.Dirmethod, pedited->wavelet.Dirmethod); - assignFromKeyfile(keyFile, "Wavelet", "Sigma", pedited, wavelet.sigma, pedited->wavelet.sigma); - assignFromKeyfile(keyFile, "Wavelet", "Offset", pedited, wavelet.offset, pedited->wavelet.offset); - assignFromKeyfile(keyFile, "Wavelet", "Lowthr", pedited, wavelet.lowthr, pedited->wavelet.lowthr); - assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", pedited, wavelet.rescon, pedited->wavelet.rescon); - assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", pedited, wavelet.resconH, pedited->wavelet.resconH); - assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", pedited, wavelet.reschro, pedited->wavelet.reschro); - assignFromKeyfile(keyFile, "Wavelet", "Residualblur", pedited, wavelet.resblur, pedited->wavelet.resblur); - assignFromKeyfile(keyFile, "Wavelet", "Residualblurc", pedited, wavelet.resblurc, pedited->wavelet.resblurc); - assignFromKeyfile(keyFile, "Wavelet", "ResidualTM", pedited, wavelet.tmrs, pedited->wavelet.tmrs); - assignFromKeyfile(keyFile, "Wavelet", "ResidualEDGS", pedited, wavelet.edgs, pedited->wavelet.edgs); - assignFromKeyfile(keyFile, "Wavelet", "ResidualSCALE", pedited, wavelet.scale, pedited->wavelet.scale); - assignFromKeyfile(keyFile, "Wavelet", "Residualgamma", pedited, wavelet.gamma, pedited->wavelet.gamma); - assignFromKeyfile(keyFile, "Wavelet", "ContExtra", pedited, wavelet.sup, pedited->wavelet.sup); - assignFromKeyfile(keyFile, "Wavelet", "HueRangeResidual", pedited, wavelet.sky, pedited->wavelet.sky); - assignFromKeyfile(keyFile, "Wavelet", "MaxLev", pedited, wavelet.thres, pedited->wavelet.thres); - assignFromKeyfile(keyFile, "Wavelet", "ThresholdHighlight", pedited, wavelet.threshold, pedited->wavelet.threshold); - assignFromKeyfile(keyFile, "Wavelet", "ThresholdShadow", pedited, wavelet.threshold2, pedited->wavelet.threshold2); - assignFromKeyfile(keyFile, "Wavelet", "Edgedetect", pedited, wavelet.edgedetect, pedited->wavelet.edgedetect); - assignFromKeyfile(keyFile, "Wavelet", "Edgedetectthr", pedited, wavelet.edgedetectthr, pedited->wavelet.edgedetectthr); - assignFromKeyfile(keyFile, "Wavelet", "EdgedetectthrHi", pedited, wavelet.edgedetectthr2, pedited->wavelet.edgedetectthr2); - assignFromKeyfile(keyFile, "Wavelet", "Edgesensi", pedited, wavelet.edgesensi, pedited->wavelet.edgesensi); - assignFromKeyfile(keyFile, "Wavelet", "Edgeampli", pedited, wavelet.edgeampli, pedited->wavelet.edgeampli); - assignFromKeyfile(keyFile, "Wavelet", "ThresholdChroma", pedited, wavelet.chroma, pedited->wavelet.chroma); - assignFromKeyfile(keyFile, "Wavelet", "ChromaLink", pedited, wavelet.chro, pedited->wavelet.chro); - assignFromKeyfile(keyFile, "Wavelet", "Contrast", pedited, wavelet.contrast, pedited->wavelet.contrast); - assignFromKeyfile(keyFile, "Wavelet", "Edgrad", pedited, wavelet.edgrad, pedited->wavelet.edgrad); - assignFromKeyfile(keyFile, "Wavelet", "Edgeffect", pedited, wavelet.edgeffect, pedited->wavelet.edgeffect); - assignFromKeyfile(keyFile, "Wavelet", "Edgval", pedited, wavelet.edgval, pedited->wavelet.edgval); - assignFromKeyfile(keyFile, "Wavelet", "ThrEdg", pedited, wavelet.edgthresh, pedited->wavelet.edgthresh); - assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidShadow", pedited, wavelet.thr, pedited->wavelet.thr); - assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidHighLight", pedited, wavelet.thrH, pedited->wavelet.thrH); - assignFromKeyfile(keyFile, "Wavelet", "Residualradius", pedited, wavelet.radius, pedited->wavelet.radius); - assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", pedited, wavelet.ccwcurve, pedited->wavelet.ccwcurve); - assignFromKeyfile(keyFile, "Wavelet", "blcurve", pedited, wavelet.blcurve, pedited->wavelet.blcurve); - assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", pedited, wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); - //assignFromKeyfile(keyFile, "Wavelet", "Levalshc", pedited, wavelet.opacityCurveSH, pedited->wavelet.opacityCurveSH); - assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", pedited, wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); - assignFromKeyfile(keyFile, "Wavelet", "wavdenoise", pedited, wavelet.wavdenoise, pedited->wavelet.wavdenoise); - assignFromKeyfile(keyFile, "Wavelet", "wavdenoiseh", pedited, wavelet.wavdenoiseh, pedited->wavelet.wavdenoiseh); - assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", pedited, wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); - assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", pedited, wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL); - assignFromKeyfile(keyFile, "Wavelet", "HHcurve", pedited, wavelet.hhcurve, pedited->wavelet.hhcurve); - assignFromKeyfile(keyFile, "Wavelet", "Wavguidcurve", pedited, wavelet.wavguidcurve, pedited->wavelet.wavguidcurve); - assignFromKeyfile(keyFile, "Wavelet", "Wavhuecurve", pedited, wavelet.wavhuecurve, pedited->wavelet.wavhuecurve); - assignFromKeyfile(keyFile, "Wavelet", "CHcurve", pedited, wavelet.Chcurve, pedited->wavelet.Chcurve); - assignFromKeyfile(keyFile, "Wavelet", "WavclCurve", pedited, wavelet.wavclCurve, pedited->wavelet.wavclCurve); + //assignFromKeyfile(keyFile, "Wavelet", "denMethod", wavelet.denmethod, pedited->wavelet.denmethod); + assignFromKeyfile(keyFile, "Wavelet", "mixMethod", wavelet.mixmethod, pedited->wavelet.mixmethod); + assignFromKeyfile(keyFile, "Wavelet", "sliMethod", wavelet.slimethod, pedited->wavelet.slimethod); + assignFromKeyfile(keyFile, "Wavelet", "quaMethod", wavelet.quamethod, pedited->wavelet.quamethod); + assignFromKeyfile(keyFile, "Wavelet", "DaubMethod", wavelet.daubcoeffmethod, pedited->wavelet.daubcoeffmethod); + assignFromKeyfile(keyFile, "Wavelet", "CHromaMethod", wavelet.CHmethod, pedited->wavelet.CHmethod); + assignFromKeyfile(keyFile, "Wavelet", "Medgreinf", wavelet.Medgreinf, pedited->wavelet.Medgreinf); + assignFromKeyfile(keyFile, "Wavelet", "Ushamethod", wavelet.ushamethod, pedited->wavelet.ushamethod); + assignFromKeyfile(keyFile, "Wavelet", "CHSLromaMethod", wavelet.CHSLmethod, pedited->wavelet.CHSLmethod); + assignFromKeyfile(keyFile, "Wavelet", "EDMethod", wavelet.EDmethod, pedited->wavelet.EDmethod); + assignFromKeyfile(keyFile, "Wavelet", "NPMethod", wavelet.NPmethod, pedited->wavelet.NPmethod); + assignFromKeyfile(keyFile, "Wavelet", "BAMethod", wavelet.BAmethod, pedited->wavelet.BAmethod); + assignFromKeyfile(keyFile, "Wavelet", "TMMethod", wavelet.TMmethod, pedited->wavelet.TMmethod); + assignFromKeyfile(keyFile, "Wavelet", "HSMethod", wavelet.HSmethod, pedited->wavelet.HSmethod); + assignFromKeyfile(keyFile, "Wavelet", "DirMethod", wavelet.Dirmethod, pedited->wavelet.Dirmethod); + assignFromKeyfile(keyFile, "Wavelet", "Sigma", wavelet.sigma, pedited->wavelet.sigma); + assignFromKeyfile(keyFile, "Wavelet", "Offset", wavelet.offset, pedited->wavelet.offset); + assignFromKeyfile(keyFile, "Wavelet", "Lowthr", wavelet.lowthr, pedited->wavelet.lowthr); + assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", wavelet.rescon, pedited->wavelet.rescon); + assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", wavelet.resconH, pedited->wavelet.resconH); + assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", wavelet.reschro, pedited->wavelet.reschro); + assignFromKeyfile(keyFile, "Wavelet", "Residualblur", wavelet.resblur, pedited->wavelet.resblur); + assignFromKeyfile(keyFile, "Wavelet", "Residualblurc", wavelet.resblurc, pedited->wavelet.resblurc); + assignFromKeyfile(keyFile, "Wavelet", "ResidualTM", wavelet.tmrs, pedited->wavelet.tmrs); + assignFromKeyfile(keyFile, "Wavelet", "ResidualEDGS", wavelet.edgs, pedited->wavelet.edgs); + assignFromKeyfile(keyFile, "Wavelet", "ResidualSCALE", wavelet.scale, pedited->wavelet.scale); + assignFromKeyfile(keyFile, "Wavelet", "Residualgamma", wavelet.gamma, pedited->wavelet.gamma); + assignFromKeyfile(keyFile, "Wavelet", "ContExtra", wavelet.sup, pedited->wavelet.sup); + assignFromKeyfile(keyFile, "Wavelet", "HueRangeResidual", wavelet.sky, pedited->wavelet.sky); + assignFromKeyfile(keyFile, "Wavelet", "MaxLev", wavelet.thres, pedited->wavelet.thres); + assignFromKeyfile(keyFile, "Wavelet", "ThresholdHighlight", wavelet.threshold, pedited->wavelet.threshold); + assignFromKeyfile(keyFile, "Wavelet", "ThresholdShadow", wavelet.threshold2, pedited->wavelet.threshold2); + assignFromKeyfile(keyFile, "Wavelet", "Edgedetect", wavelet.edgedetect, pedited->wavelet.edgedetect); + assignFromKeyfile(keyFile, "Wavelet", "Edgedetectthr", wavelet.edgedetectthr, pedited->wavelet.edgedetectthr); + assignFromKeyfile(keyFile, "Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2, pedited->wavelet.edgedetectthr2); + assignFromKeyfile(keyFile, "Wavelet", "Edgesensi", wavelet.edgesensi, pedited->wavelet.edgesensi); + assignFromKeyfile(keyFile, "Wavelet", "Edgeampli", wavelet.edgeampli, pedited->wavelet.edgeampli); + assignFromKeyfile(keyFile, "Wavelet", "ThresholdChroma", wavelet.chroma, pedited->wavelet.chroma); + assignFromKeyfile(keyFile, "Wavelet", "ChromaLink", wavelet.chro, pedited->wavelet.chro); + assignFromKeyfile(keyFile, "Wavelet", "Contrast", wavelet.contrast, pedited->wavelet.contrast); + assignFromKeyfile(keyFile, "Wavelet", "Edgrad", wavelet.edgrad, pedited->wavelet.edgrad); + assignFromKeyfile(keyFile, "Wavelet", "Edgeffect", wavelet.edgeffect, pedited->wavelet.edgeffect); + assignFromKeyfile(keyFile, "Wavelet", "Edgval", wavelet.edgval, pedited->wavelet.edgval); + assignFromKeyfile(keyFile, "Wavelet", "ThrEdg", wavelet.edgthresh, pedited->wavelet.edgthresh); + assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidShadow", wavelet.thr, pedited->wavelet.thr); + assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidHighLight", wavelet.thrH, pedited->wavelet.thrH); + assignFromKeyfile(keyFile, "Wavelet", "Residualradius", wavelet.radius, pedited->wavelet.radius); + assignFromKeyfile(keyFile, "Wavelet", "ContrastCurve", wavelet.ccwcurve, pedited->wavelet.ccwcurve); + assignFromKeyfile(keyFile, "Wavelet", "blcurve", wavelet.blcurve, pedited->wavelet.blcurve); + assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveRG", wavelet.opacityCurveRG, pedited->wavelet.opacityCurveRG); + //assignFromKeyfile(keyFile, "Wavelet", "Levalshc", wavelet.opacityCurveSH, pedited->wavelet.opacityCurveSH); + assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveBY", wavelet.opacityCurveBY, pedited->wavelet.opacityCurveBY); + assignFromKeyfile(keyFile, "Wavelet", "wavdenoise", wavelet.wavdenoise, pedited->wavelet.wavdenoise); + assignFromKeyfile(keyFile, "Wavelet", "wavdenoiseh", wavelet.wavdenoiseh, pedited->wavelet.wavdenoiseh); + assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveW", wavelet.opacityCurveW, pedited->wavelet.opacityCurveW); + assignFromKeyfile(keyFile, "Wavelet", "OpacityCurveWL", wavelet.opacityCurveWL, pedited->wavelet.opacityCurveWL); + assignFromKeyfile(keyFile, "Wavelet", "HHcurve", wavelet.hhcurve, pedited->wavelet.hhcurve); + assignFromKeyfile(keyFile, "Wavelet", "Wavguidcurve", wavelet.wavguidcurve, pedited->wavelet.wavguidcurve); + assignFromKeyfile(keyFile, "Wavelet", "Wavhuecurve", wavelet.wavhuecurve, pedited->wavelet.wavhuecurve); + assignFromKeyfile(keyFile, "Wavelet", "CHcurve", wavelet.Chcurve, pedited->wavelet.Chcurve); + assignFromKeyfile(keyFile, "Wavelet", "WavclCurve", wavelet.wavclCurve, pedited->wavelet.wavclCurve); if (keyFile.has_key("Wavelet", "Hueskin")) { const std::vector thresh = keyFile.get_integer_list("Wavelet", "Hueskin"); @@ -10119,11 +10112,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", pedited, wavelet.skinprotect, pedited->wavelet.skinprotect); - assignFromKeyfile(keyFile, "Wavelet", "chrwav", pedited, wavelet.chrwav, pedited->wavelet.chrwav); - assignFromKeyfile(keyFile, "Wavelet", "bluwav", pedited, wavelet.bluwav, pedited->wavelet.bluwav); - assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", pedited, wavelet.expcontrast, pedited->wavelet.expcontrast); - assignFromKeyfile(keyFile, "Wavelet", "Expchroma", pedited, wavelet.expchroma, pedited->wavelet.expchroma); + assignFromKeyfile(keyFile, "Wavelet", "Skinprotect", wavelet.skinprotect, pedited->wavelet.skinprotect); + assignFromKeyfile(keyFile, "Wavelet", "chrwav", wavelet.chrwav, pedited->wavelet.chrwav); + assignFromKeyfile(keyFile, "Wavelet", "bluwav", wavelet.bluwav, pedited->wavelet.bluwav); + assignFromKeyfile(keyFile, "Wavelet", "Expcontrast", wavelet.expcontrast, pedited->wavelet.expcontrast); + assignFromKeyfile(keyFile, "Wavelet", "Expchroma", wavelet.expchroma, pedited->wavelet.expchroma); for (int i = 0; i < 9; ++i) { std::stringstream ss; @@ -10151,19 +10144,19 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Wavelet", "Expedge", pedited, wavelet.expedge, pedited->wavelet.expedge); - assignFromKeyfile(keyFile, "Wavelet", "expbl", pedited, wavelet.expbl, pedited->wavelet.expbl); - assignFromKeyfile(keyFile, "Wavelet", "Expresid", pedited, wavelet.expresid, pedited->wavelet.expresid); - assignFromKeyfile(keyFile, "Wavelet", "Expfinal", pedited, wavelet.expfinal, pedited->wavelet.expfinal); - assignFromKeyfile(keyFile, "Wavelet", "Exptoning", pedited, wavelet.exptoning, pedited->wavelet.exptoning); - assignFromKeyfile(keyFile, "Wavelet", "Expnoise", pedited, wavelet.expnoise, pedited->wavelet.expnoise); - assignFromKeyfile(keyFile, "Wavelet", "Expclari", pedited, wavelet.expclari, pedited->wavelet.expclari); + assignFromKeyfile(keyFile, "Wavelet", "Expedge", wavelet.expedge, pedited->wavelet.expedge); + assignFromKeyfile(keyFile, "Wavelet", "expbl", wavelet.expbl, pedited->wavelet.expbl); + assignFromKeyfile(keyFile, "Wavelet", "Expresid", wavelet.expresid, pedited->wavelet.expresid); + assignFromKeyfile(keyFile, "Wavelet", "Expfinal", wavelet.expfinal, pedited->wavelet.expfinal); + assignFromKeyfile(keyFile, "Wavelet", "Exptoning", wavelet.exptoning, pedited->wavelet.exptoning); + assignFromKeyfile(keyFile, "Wavelet", "Expnoise", wavelet.expnoise, pedited->wavelet.expnoise); + assignFromKeyfile(keyFile, "Wavelet", "Expclari", wavelet.expclari, pedited->wavelet.expclari); } if (keyFile.has_group("Directional Pyramid Equalizer")) { - assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Enabled", pedited, dirpyrequalizer.enabled, pedited->dirpyrequalizer.enabled); - assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Gamutlab", pedited, dirpyrequalizer.gamutlab, pedited->dirpyrequalizer.gamutlab); - assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "cbdlMethod", pedited, dirpyrequalizer.cbdlMethod, pedited->dirpyrequalizer.cbdlMethod); + assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled, pedited->dirpyrequalizer.enabled); + assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab, pedited->dirpyrequalizer.gamutlab); + assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod, pedited->dirpyrequalizer.cbdlMethod); if (keyFile.has_key("Directional Pyramid Equalizer", "Hueskin")) { const std::vector thresh = keyFile.get_integer_list("Directional Pyramid Equalizer", "Hueskin"); @@ -10215,21 +10208,21 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Threshold", pedited, dirpyrequalizer.threshold, pedited->dirpyrequalizer.threshold); - assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Skinprotect", pedited, dirpyrequalizer.skinprotect, pedited->dirpyrequalizer.skinprotect); + assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold, pedited->dirpyrequalizer.threshold); + assignFromKeyfile(keyFile, "Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect, pedited->dirpyrequalizer.skinprotect); } } if (keyFile.has_group("SoftLight")) { - assignFromKeyfile(keyFile, "SoftLight", "Enabled", pedited, softlight.enabled, pedited->softlight.enabled); - assignFromKeyfile(keyFile, "SoftLight", "Strength", pedited, softlight.strength, pedited->softlight.strength); + assignFromKeyfile(keyFile, "SoftLight", "Enabled", softlight.enabled, pedited->softlight.enabled); + assignFromKeyfile(keyFile, "SoftLight", "Strength", softlight.strength, pedited->softlight.strength); } if (keyFile.has_group("Dehaze")) { - assignFromKeyfile(keyFile, "Dehaze", "Enabled", pedited, dehaze.enabled, pedited->dehaze.enabled); - assignFromKeyfile(keyFile, "Dehaze", "Strength", pedited, dehaze.strength, pedited->dehaze.strength); - assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", pedited, dehaze.showDepthMap, pedited->dehaze.showDepthMap); - assignFromKeyfile(keyFile, "Dehaze", "Depth", pedited, dehaze.depth, pedited->dehaze.depth); + assignFromKeyfile(keyFile, "Dehaze", "Enabled", dehaze.enabled, pedited->dehaze.enabled); + assignFromKeyfile(keyFile, "Dehaze", "Strength", dehaze.strength, pedited->dehaze.strength); + assignFromKeyfile(keyFile, "Dehaze", "ShowDepthMap", dehaze.showDepthMap, pedited->dehaze.showDepthMap); + assignFromKeyfile(keyFile, "Dehaze", "Depth", dehaze.depth, pedited->dehaze.depth); if (ppVersion < 349 && dehaze.enabled && keyFile.has_key("Dehaze", "Luminance")) { const bool luminance = keyFile.get_boolean("Dehaze", "Luminance"); dehaze.saturation = luminance ? 0 : 100; @@ -10237,13 +10230,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->dehaze.saturation = true; } } else { - assignFromKeyfile(keyFile, "Dehaze", "Saturation", pedited, dehaze.saturation, pedited->dehaze.saturation); + assignFromKeyfile(keyFile, "Dehaze", "Saturation", dehaze.saturation, pedited->dehaze.saturation); } } if (keyFile.has_group("Film Simulation")) { - assignFromKeyfile(keyFile, "Film Simulation", "Enabled", pedited, filmSimulation.enabled, pedited->filmSimulation.enabled); - assignFromKeyfile(keyFile, "Film Simulation", "ClutFilename", pedited, filmSimulation.clutFilename, pedited->filmSimulation.clutFilename); + assignFromKeyfile(keyFile, "Film Simulation", "Enabled", filmSimulation.enabled, pedited->filmSimulation.enabled); + assignFromKeyfile(keyFile, "Film Simulation", "ClutFilename", filmSimulation.clutFilename, pedited->filmSimulation.clutFilename); #if defined (_WIN32) // if this is Windows, replace any "/" in the filename with "\\" size_t pos = filmSimulation.clutFilename.find("/"); @@ -10276,7 +10269,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("HSV Equalizer")) { if (ppVersion >= 329) { - assignFromKeyfile(keyFile, "HSV Equalizer", "Enabled", pedited, hsvequalizer.enabled, pedited->hsvequalizer.enabled); + assignFromKeyfile(keyFile, "HSV Equalizer", "Enabled", hsvequalizer.enabled, pedited->hsvequalizer.enabled); } else { hsvequalizer.enabled = true; @@ -10286,15 +10279,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } if (ppVersion >= 300) { - assignFromKeyfile(keyFile, "HSV Equalizer", "HCurve", pedited, hsvequalizer.hcurve, pedited->hsvequalizer.hcurve); - assignFromKeyfile(keyFile, "HSV Equalizer", "SCurve", pedited, hsvequalizer.scurve, pedited->hsvequalizer.scurve); - assignFromKeyfile(keyFile, "HSV Equalizer", "VCurve", pedited, hsvequalizer.vcurve, pedited->hsvequalizer.vcurve); + assignFromKeyfile(keyFile, "HSV Equalizer", "HCurve", hsvequalizer.hcurve, pedited->hsvequalizer.hcurve); + assignFromKeyfile(keyFile, "HSV Equalizer", "SCurve", hsvequalizer.scurve, pedited->hsvequalizer.scurve); + assignFromKeyfile(keyFile, "HSV Equalizer", "VCurve", hsvequalizer.vcurve, pedited->hsvequalizer.vcurve); } } if (keyFile.has_group("RGB Curves")) { if (ppVersion >= 329) { - assignFromKeyfile(keyFile, "RGB Curves", "Enabled", pedited, rgbCurves.enabled, pedited->rgbCurves.enabled); + assignFromKeyfile(keyFile, "RGB Curves", "Enabled", rgbCurves.enabled, pedited->rgbCurves.enabled); } else { rgbCurves.enabled = true; @@ -10303,23 +10296,23 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RGB Curves", "LumaMode", pedited, rgbCurves.lumamode, pedited->rgbCurves.lumamode); - assignFromKeyfile(keyFile, "RGB Curves", "rCurve", pedited, rgbCurves.rcurve, pedited->rgbCurves.rcurve); - assignFromKeyfile(keyFile, "RGB Curves", "gCurve", pedited, rgbCurves.gcurve, pedited->rgbCurves.gcurve); - assignFromKeyfile(keyFile, "RGB Curves", "bCurve", pedited, rgbCurves.bcurve, pedited->rgbCurves.bcurve); + assignFromKeyfile(keyFile, "RGB Curves", "LumaMode", rgbCurves.lumamode, pedited->rgbCurves.lumamode); + assignFromKeyfile(keyFile, "RGB Curves", "rCurve", rgbCurves.rcurve, pedited->rgbCurves.rcurve); + assignFromKeyfile(keyFile, "RGB Curves", "gCurve", rgbCurves.gcurve, pedited->rgbCurves.gcurve); + assignFromKeyfile(keyFile, "RGB Curves", "bCurve", rgbCurves.bcurve, pedited->rgbCurves.bcurve); } if (keyFile.has_group("ColorToning")) { - assignFromKeyfile(keyFile, "ColorToning", "Enabled", pedited, colorToning.enabled, pedited->colorToning.enabled); - assignFromKeyfile(keyFile, "ColorToning", "Method", pedited, colorToning.method, pedited->colorToning.method); - assignFromKeyfile(keyFile, "ColorToning", "Lumamode", pedited, colorToning.lumamode, pedited->colorToning.lumamode); - assignFromKeyfile(keyFile, "ColorToning", "Twocolor", pedited, colorToning.twocolor, pedited->colorToning.twocolor); - assignFromKeyfile(keyFile, "ColorToning", "OpacityCurve", pedited, colorToning.opacityCurve, pedited->colorToning.opacityCurve); - assignFromKeyfile(keyFile, "ColorToning", "ColorCurve", pedited, colorToning.colorCurve, pedited->colorToning.colorCurve); - assignFromKeyfile(keyFile, "ColorToning", "Autosat", pedited, colorToning.autosat, pedited->colorToning.autosat); - assignFromKeyfile(keyFile, "ColorToning", "SatProtectionThreshold", pedited, colorToning.satProtectionThreshold, pedited->colorToning.satprotectionthreshold); - assignFromKeyfile(keyFile, "ColorToning", "SaturatedOpacity", pedited, colorToning.saturatedOpacity, pedited->colorToning.saturatedopacity); - assignFromKeyfile(keyFile, "ColorToning", "Strength", pedited, colorToning.strength, pedited->colorToning.strength); + assignFromKeyfile(keyFile, "ColorToning", "Enabled", colorToning.enabled, pedited->colorToning.enabled); + assignFromKeyfile(keyFile, "ColorToning", "Method", colorToning.method, pedited->colorToning.method); + assignFromKeyfile(keyFile, "ColorToning", "Lumamode", colorToning.lumamode, pedited->colorToning.lumamode); + assignFromKeyfile(keyFile, "ColorToning", "Twocolor", colorToning.twocolor, pedited->colorToning.twocolor); + assignFromKeyfile(keyFile, "ColorToning", "OpacityCurve", colorToning.opacityCurve, pedited->colorToning.opacityCurve); + assignFromKeyfile(keyFile, "ColorToning", "ColorCurve", colorToning.colorCurve, pedited->colorToning.colorCurve); + assignFromKeyfile(keyFile, "ColorToning", "Autosat", colorToning.autosat, pedited->colorToning.autosat); + assignFromKeyfile(keyFile, "ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold, pedited->colorToning.satprotectionthreshold); + assignFromKeyfile(keyFile, "ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity, pedited->colorToning.saturatedopacity); + assignFromKeyfile(keyFile, "ColorToning", "Strength", colorToning.strength, pedited->colorToning.strength); if (keyFile.has_key("ColorToning", "HighlightsColorSaturation")) { const std::vector thresh = keyFile.get_integer_list("ColorToning", "HighlightsColorSaturation"); @@ -10345,25 +10338,25 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "ColorToning", "ClCurve", pedited, colorToning.clcurve, pedited->colorToning.clcurve); - assignFromKeyfile(keyFile, "ColorToning", "Cl2Curve", pedited, colorToning.cl2curve, pedited->colorToning.cl2curve); - assignFromKeyfile(keyFile, "ColorToning", "Redlow", pedited, colorToning.redlow, pedited->colorToning.redlow); - assignFromKeyfile(keyFile, "ColorToning", "Greenlow", pedited, colorToning.greenlow, pedited->colorToning.greenlow); - assignFromKeyfile(keyFile, "ColorToning", "Bluelow", pedited, colorToning.bluelow, pedited->colorToning.bluelow); - assignFromKeyfile(keyFile, "ColorToning", "Satlow", pedited, colorToning.satlow, pedited->colorToning.satlow); - assignFromKeyfile(keyFile, "ColorToning", "Balance", pedited, colorToning.balance, pedited->colorToning.balance); - assignFromKeyfile(keyFile, "ColorToning", "Sathigh", pedited, colorToning.sathigh, pedited->colorToning.sathigh); - assignFromKeyfile(keyFile, "ColorToning", "Redmed", pedited, colorToning.redmed, pedited->colorToning.redmed); - assignFromKeyfile(keyFile, "ColorToning", "Greenmed", pedited, colorToning.greenmed, pedited->colorToning.greenmed); - assignFromKeyfile(keyFile, "ColorToning", "Bluemed", pedited, colorToning.bluemed, pedited->colorToning.bluemed); - assignFromKeyfile(keyFile, "ColorToning", "Redhigh", pedited, colorToning.redhigh, pedited->colorToning.redhigh); - assignFromKeyfile(keyFile, "ColorToning", "Greenhigh", pedited, colorToning.greenhigh, pedited->colorToning.greenhigh); - assignFromKeyfile(keyFile, "ColorToning", "Bluehigh", pedited, colorToning.bluehigh, pedited->colorToning.bluehigh); + assignFromKeyfile(keyFile, "ColorToning", "ClCurve", colorToning.clcurve, pedited->colorToning.clcurve); + assignFromKeyfile(keyFile, "ColorToning", "Cl2Curve", colorToning.cl2curve, pedited->colorToning.cl2curve); + assignFromKeyfile(keyFile, "ColorToning", "Redlow", colorToning.redlow, pedited->colorToning.redlow); + assignFromKeyfile(keyFile, "ColorToning", "Greenlow", colorToning.greenlow, pedited->colorToning.greenlow); + assignFromKeyfile(keyFile, "ColorToning", "Bluelow", colorToning.bluelow, pedited->colorToning.bluelow); + assignFromKeyfile(keyFile, "ColorToning", "Satlow", colorToning.satlow, pedited->colorToning.satlow); + assignFromKeyfile(keyFile, "ColorToning", "Balance", colorToning.balance, pedited->colorToning.balance); + assignFromKeyfile(keyFile, "ColorToning", "Sathigh", colorToning.sathigh, pedited->colorToning.sathigh); + assignFromKeyfile(keyFile, "ColorToning", "Redmed", colorToning.redmed, pedited->colorToning.redmed); + assignFromKeyfile(keyFile, "ColorToning", "Greenmed", colorToning.greenmed, pedited->colorToning.greenmed); + assignFromKeyfile(keyFile, "ColorToning", "Bluemed", colorToning.bluemed, pedited->colorToning.bluemed); + assignFromKeyfile(keyFile, "ColorToning", "Redhigh", colorToning.redhigh, pedited->colorToning.redhigh); + assignFromKeyfile(keyFile, "ColorToning", "Greenhigh", colorToning.greenhigh, pedited->colorToning.greenhigh); + assignFromKeyfile(keyFile, "ColorToning", "Bluehigh", colorToning.bluehigh, pedited->colorToning.bluehigh); - assignFromKeyfile(keyFile, "ColorToning", "LabGridALow", pedited, colorToning.labgridALow, pedited->colorToning.labgridALow); - assignFromKeyfile(keyFile, "ColorToning", "LabGridBLow", pedited, colorToning.labgridBLow, pedited->colorToning.labgridBLow); - assignFromKeyfile(keyFile, "ColorToning", "LabGridAHigh", pedited, colorToning.labgridAHigh, pedited->colorToning.labgridAHigh); - assignFromKeyfile(keyFile, "ColorToning", "LabGridBHigh", pedited, colorToning.labgridBHigh, pedited->colorToning.labgridBHigh); + assignFromKeyfile(keyFile, "ColorToning", "LabGridALow", colorToning.labgridALow, pedited->colorToning.labgridALow); + assignFromKeyfile(keyFile, "ColorToning", "LabGridBLow", colorToning.labgridBLow, pedited->colorToning.labgridBLow); + assignFromKeyfile(keyFile, "ColorToning", "LabGridAHigh", colorToning.labgridAHigh, pedited->colorToning.labgridAHigh); + assignFromKeyfile(keyFile, "ColorToning", "LabGridBHigh", colorToning.labgridBHigh, pedited->colorToning.labgridBHigh); if (ppVersion < 337) { const double scale = ColorToningParams::LABGRID_CORR_SCALE; colorToning.labgridALow *= scale; @@ -10378,47 +10371,47 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) ColorToningParams::LabCorrectionRegion cur; done = true; std::string n = std::to_string(i); - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionA_") + n, pedited, cur.a, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionA_") + n, cur.a, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionB_") + n, pedited, cur.b, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionB_") + n, cur.b, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSaturation_") + n, pedited, cur.saturation, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSaturation_") + n, cur.saturation, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSlope_") + n, pedited, cur.slope, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionSlope_") + n, cur.slope, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionOffset_") + n, pedited, cur.offset, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionOffset_") + n, cur.offset, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionPower_") + n, pedited, cur.power, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionPower_") + n, cur.power, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionHueMask_") + n, pedited, cur.hueMask, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionHueMask_") + n, cur.hueMask, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChromaticityMask_") + n, pedited, cur.chromaticityMask, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChromaticityMask_") + n, cur.chromaticityMask, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionLightnessMask_") + n, pedited, cur.lightnessMask, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionLightnessMask_") + n, cur.lightnessMask, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, pedited, cur.maskBlur, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionMaskBlur_") + n, cur.maskBlur, pedited->colorToning.labregions)) { found = true; done = false; } - if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChannel_") + n, pedited, cur.channel, pedited->colorToning.labregions)) { + if (assignFromKeyfile(keyFile, "ColorToning", Glib::ustring("LabRegionChannel_") + n, cur.channel, pedited->colorToning.labregions)) { found = true; done = false; } @@ -10429,7 +10422,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (found) { colorToning.labregions = std::move(lg); } - assignFromKeyfile(keyFile, "ColorToning", "LabRegionsShowMask", pedited, colorToning.labregionsShowMask, pedited->colorToning.labregionsShowMask); + assignFromKeyfile(keyFile, "ColorToning", "LabRegionsShowMask", colorToning.labregionsShowMask, pedited->colorToning.labregionsShowMask); } if (keyFile.has_group("RAW")) { @@ -10440,7 +10433,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->raw.darkFrame = true; } } - assignFromKeyfile(keyFile, "RAW", "DarkFrameAuto", pedited, raw.df_autoselect, pedited->raw.df_autoselect); + assignFromKeyfile(keyFile, "RAW", "DarkFrameAuto", raw.df_autoselect, pedited->raw.df_autoselect); if (keyFile.has_key("RAW", "FlatFieldFile")) { raw.ff_file = expandRelativePath2(fname, options.rtSettings.flatFieldsPath, "", keyFile.get_string("RAW", "FlatFieldFile")); @@ -10448,66 +10441,66 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->raw.ff_file = true; } } - assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", pedited, raw.ff_AutoSelect, pedited->raw.ff_AutoSelect); - assignFromKeyfile(keyFile, "RAW", "FlatFieldFromMetaData", pedited, raw.ff_FromMetaData, pedited->raw.ff_FromMetaData); - assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", pedited, raw.ff_BlurRadius, pedited->raw.ff_BlurRadius); - assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", pedited, raw.ff_BlurType, pedited->raw.ff_BlurType); - assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoClipControl", pedited, raw.ff_AutoClipControl, pedited->raw.ff_AutoClipControl); + assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect, pedited->raw.ff_AutoSelect); + assignFromKeyfile(keyFile, "RAW", "FlatFieldFromMetaData", raw.ff_FromMetaData, pedited->raw.ff_FromMetaData); + assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius, pedited->raw.ff_BlurRadius); + assignFromKeyfile(keyFile, "RAW", "FlatFieldBlurType", raw.ff_BlurType, pedited->raw.ff_BlurType); + assignFromKeyfile(keyFile, "RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl, pedited->raw.ff_AutoClipControl); if (ppVersion < 328) { // With ppversion < 328 this value was stored as a boolean, which is nonsense. // To avoid annoying warnings we skip reading and assume 0. raw.ff_clipControl = 0; } else { - assignFromKeyfile(keyFile, "RAW", "FlatFieldClipControl", pedited, raw.ff_clipControl, pedited->raw.ff_clipControl); + assignFromKeyfile(keyFile, "RAW", "FlatFieldClipControl", raw.ff_clipControl, pedited->raw.ff_clipControl); } - assignFromKeyfile(keyFile, "RAW", "CA", pedited, raw.ca_autocorrect, pedited->raw.ca_autocorrect); + assignFromKeyfile(keyFile, "RAW", "CA", raw.ca_autocorrect, pedited->raw.ca_autocorrect); if (ppVersion >= 342) { - assignFromKeyfile(keyFile, "RAW", "CAAutoIterations", pedited, raw.caautoiterations, pedited->raw.caautoiterations); + assignFromKeyfile(keyFile, "RAW", "CAAutoIterations", raw.caautoiterations, pedited->raw.caautoiterations); } else { raw.caautoiterations = 1; } if (ppVersion >= 343) { - assignFromKeyfile(keyFile, "RAW", "CAAvoidColourshift", pedited, raw.ca_avoidcolourshift, pedited->raw.ca_avoidcolourshift); + assignFromKeyfile(keyFile, "RAW", "CAAvoidColourshift", raw.ca_avoidcolourshift, pedited->raw.ca_avoidcolourshift); } else { raw.ca_avoidcolourshift = false; } - assignFromKeyfile(keyFile, "RAW", "CARed", pedited, raw.cared, pedited->raw.cared); - assignFromKeyfile(keyFile, "RAW", "CABlue", pedited, raw.cablue, pedited->raw.cablue); + assignFromKeyfile(keyFile, "RAW", "CARed", raw.cared, pedited->raw.cared); + assignFromKeyfile(keyFile, "RAW", "CABlue", raw.cablue, pedited->raw.cablue); // For compatibility to elder pp3 versions - assignFromKeyfile(keyFile, "RAW", "HotDeadPixels", pedited, raw.hotPixelFilter, pedited->raw.hotPixelFilter); + assignFromKeyfile(keyFile, "RAW", "HotDeadPixels", raw.hotPixelFilter, pedited->raw.hotPixelFilter); raw.deadPixelFilter = raw.hotPixelFilter; if (pedited) { pedited->raw.deadPixelFilter = pedited->raw.hotPixelFilter; } - assignFromKeyfile(keyFile, "RAW", "HotPixelFilter", pedited, raw.hotPixelFilter, pedited->raw.hotPixelFilter); - assignFromKeyfile(keyFile, "RAW", "DeadPixelFilter", pedited, raw.deadPixelFilter, pedited->raw.deadPixelFilter); - assignFromKeyfile(keyFile, "RAW", "HotDeadPixelThresh", pedited, raw.hotdeadpix_thresh, pedited->raw.hotdeadpix_thresh); - assignFromKeyfile(keyFile, "RAW", "PreExposure", pedited, raw.expos, pedited->raw.exPos); + assignFromKeyfile(keyFile, "RAW", "HotPixelFilter", raw.hotPixelFilter, pedited->raw.hotPixelFilter); + assignFromKeyfile(keyFile, "RAW", "DeadPixelFilter", raw.deadPixelFilter, pedited->raw.deadPixelFilter); + assignFromKeyfile(keyFile, "RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh, pedited->raw.hotdeadpix_thresh); + assignFromKeyfile(keyFile, "RAW", "PreExposure", raw.expos, pedited->raw.exPos); if (ppVersion < 320) { - assignFromKeyfile(keyFile, "RAW", "Method", pedited, raw.bayersensor.method, pedited->raw.bayersensor.method); - assignFromKeyfile(keyFile, "RAW", "CcSteps", pedited, raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps); - assignFromKeyfile(keyFile, "RAW", "LineDenoise", pedited, raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise); - assignFromKeyfile(keyFile, "RAW", "GreenEqThreshold", pedited, raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq); - assignFromKeyfile(keyFile, "RAW", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); - assignFromKeyfile(keyFile, "RAW", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); - assignFromKeyfile(keyFile, "RAW", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); - assignFromKeyfile(keyFile, "RAW", "PreBlackzero", pedited, raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0); - assignFromKeyfile(keyFile, "RAW", "PreBlackone", pedited, raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1); - assignFromKeyfile(keyFile, "RAW", "PreBlacktwo", pedited, raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2); - assignFromKeyfile(keyFile, "RAW", "PreBlackthree", pedited, raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3); - assignFromKeyfile(keyFile, "RAW", "PreTwoGreen", pedited, raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen); + assignFromKeyfile(keyFile, "RAW", "Method", raw.bayersensor.method, pedited->raw.bayersensor.method); + assignFromKeyfile(keyFile, "RAW", "CcSteps", raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps); + assignFromKeyfile(keyFile, "RAW", "LineDenoise", raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise); + assignFromKeyfile(keyFile, "RAW", "GreenEqThreshold", raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq); + assignFromKeyfile(keyFile, "RAW", "DCBIterations", raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); + assignFromKeyfile(keyFile, "RAW", "DCBEnhance", raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); + assignFromKeyfile(keyFile, "RAW", "LMMSEIterations", raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); + assignFromKeyfile(keyFile, "RAW", "PreBlackzero", raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0); + assignFromKeyfile(keyFile, "RAW", "PreBlackone", raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1); + assignFromKeyfile(keyFile, "RAW", "PreBlacktwo", raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2); + assignFromKeyfile(keyFile, "RAW", "PreBlackthree", raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3); + assignFromKeyfile(keyFile, "RAW", "PreTwoGreen", raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen); } } if (keyFile.has_group("RAW Bayer")) { - assignFromKeyfile(keyFile, "RAW Bayer", "Method", pedited, raw.bayersensor.method, pedited->raw.bayersensor.method); - assignFromKeyfile(keyFile, "RAW Bayer", "Border", pedited, raw.bayersensor.border, pedited->raw.bayersensor.border); + assignFromKeyfile(keyFile, "RAW Bayer", "Method", raw.bayersensor.method, pedited->raw.bayersensor.method); + assignFromKeyfile(keyFile, "RAW Bayer", "Border", raw.bayersensor.border, pedited->raw.bayersensor.border); if (keyFile.has_key("RAW Bayer", "ImageNum")) { raw.bayersensor.imageNum = keyFile.get_integer("RAW Bayer", "ImageNum") - 1; @@ -10517,13 +10510,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RAW Bayer", "CcSteps", pedited, raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps); - assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack0", pedited, raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0); - assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack1", pedited, raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1); - assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack2", pedited, raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2); - assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack3", pedited, raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3); - assignFromKeyfile(keyFile, "RAW Bayer", "PreTwoGreen", pedited, raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen); - assignFromKeyfile(keyFile, "RAW Bayer", "LineDenoise", pedited, raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise); + assignFromKeyfile(keyFile, "RAW Bayer", "CcSteps", raw.bayersensor.ccSteps, pedited->raw.bayersensor.ccSteps); + assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack0", raw.bayersensor.black0, pedited->raw.bayersensor.exBlack0); + assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack1", raw.bayersensor.black1, pedited->raw.bayersensor.exBlack1); + assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack2", raw.bayersensor.black2, pedited->raw.bayersensor.exBlack2); + assignFromKeyfile(keyFile, "RAW Bayer", "PreBlack3", raw.bayersensor.black3, pedited->raw.bayersensor.exBlack3); + assignFromKeyfile(keyFile, "RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen, pedited->raw.bayersensor.exTwoGreen); + assignFromKeyfile(keyFile, "RAW Bayer", "LineDenoise", raw.bayersensor.linenoise, pedited->raw.bayersensor.linenoise); if (keyFile.has_key("RAW Bayer", "LineDenoiseDirection")) { raw.bayersensor.linenoiseDirection = RAWParams::BayerSensor::LineNoiseDirection(keyFile.get_integer("RAW Bayer", "LineDenoiseDirection")); @@ -10533,18 +10526,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RAW Bayer", "GreenEqThreshold", pedited, raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq); - assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", pedited, raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); - assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", pedited, raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); - assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", pedited, raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); - assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicAutoContrast", pedited, raw.bayersensor.dualDemosaicAutoContrast, pedited->raw.bayersensor.dualDemosaicAutoContrast); + assignFromKeyfile(keyFile, "RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh, pedited->raw.bayersensor.greenEq); + assignFromKeyfile(keyFile, "RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations, pedited->raw.bayersensor.dcbIterations); + assignFromKeyfile(keyFile, "RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance, pedited->raw.bayersensor.dcbEnhance); + assignFromKeyfile(keyFile, "RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations, pedited->raw.bayersensor.lmmseIterations); + assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicAutoContrast", raw.bayersensor.dualDemosaicAutoContrast, pedited->raw.bayersensor.dualDemosaicAutoContrast); if (ppVersion < 345) { raw.bayersensor.dualDemosaicAutoContrast = false; if (pedited) { pedited->raw.bayersensor.dualDemosaicAutoContrast = true; } } - assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", pedited, raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast); + assignFromKeyfile(keyFile, "RAW Bayer", "DualDemosaicContrast", raw.bayersensor.dualDemosaicContrast, pedited->raw.bayersensor.dualDemosaicContrast); if (keyFile.has_key("RAW Bayer", "PixelShiftMotionCorrectionMethod")) { raw.bayersensor.pixelShiftMotionCorrectionMethod = (RAWParams::BayerSensor::PSMotionCorrectionMethod)keyFile.get_integer("RAW Bayer", "PixelShiftMotionCorrectionMethod"); @@ -10554,24 +10547,24 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", pedited, raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso); + assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftEperIso", raw.bayersensor.pixelShiftEperIso, pedited->raw.bayersensor.pixelShiftEperIso); if (ppVersion < 332) { raw.bayersensor.pixelShiftEperIso += 1.0; } - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", pedited, raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", pedited, raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); - assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", pedited, raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", pedited, raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", pedited, raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftAverage", pedited, raw.bayersensor.pixelShiftAverage, pedited->raw.bayersensor.pixelShiftAverage); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftGreen", pedited, raw.bayersensor.pixelShiftGreen, pedited->raw.bayersensor.pixelShiftGreen); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftBlur", pedited, raw.bayersensor.pixelShiftBlur, pedited->raw.bayersensor.pixelShiftBlur); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", pedited, raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", pedited, raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", pedited, raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel); - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", pedited, raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross); + assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftSigma", raw.bayersensor.pixelShiftSigma, pedited->raw.bayersensor.pixelShiftSigma); + assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotion", raw.bayersensor.pixelShiftShowMotion, pedited->raw.bayersensor.pixelShiftShowMotion); + assignFromKeyfile(keyFile, "RAW Bayer", "PixelShiftShowMotionMaskOnly", raw.bayersensor.pixelShiftShowMotionMaskOnly, pedited->raw.bayersensor.pixelShiftShowMotionMaskOnly); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftHoleFill", raw.bayersensor.pixelShiftHoleFill, pedited->raw.bayersensor.pixelShiftHoleFill); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftMedian", raw.bayersensor.pixelShiftMedian, pedited->raw.bayersensor.pixelShiftMedian); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftAverage", raw.bayersensor.pixelShiftAverage, pedited->raw.bayersensor.pixelShiftAverage); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftGreen", raw.bayersensor.pixelShiftGreen, pedited->raw.bayersensor.pixelShiftGreen); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftBlur", raw.bayersensor.pixelShiftBlur, pedited->raw.bayersensor.pixelShiftBlur); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftSmoothFactor", raw.bayersensor.pixelShiftSmoothFactor, pedited->raw.bayersensor.pixelShiftSmooth); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBright", raw.bayersensor.pixelShiftEqualBright, pedited->raw.bayersensor.pixelShiftEqualBright); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftEqualBrightChannel", raw.bayersensor.pixelShiftEqualBrightChannel, pedited->raw.bayersensor.pixelShiftEqualBrightChannel); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftNonGreenCross", raw.bayersensor.pixelShiftNonGreenCross, pedited->raw.bayersensor.pixelShiftNonGreenCross); if (ppVersion < 336) { if (keyFile.has_key("RAW Bayer", "pixelShiftLmmse")) { @@ -10588,34 +10581,34 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } } else { - assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftDemosaicMethod", pedited, raw.bayersensor.pixelShiftDemosaicMethod, pedited->raw.bayersensor.pixelShiftDemosaicMethod); + assignFromKeyfile(keyFile, "RAW Bayer", "pixelShiftDemosaicMethod", raw.bayersensor.pixelShiftDemosaicMethod, pedited->raw.bayersensor.pixelShiftDemosaicMethod); } - assignFromKeyfile(keyFile, "RAW Bayer", "PDAFLinesFilter", pedited, raw.bayersensor.pdafLinesFilter, pedited->raw.bayersensor.pdafLinesFilter); + assignFromKeyfile(keyFile, "RAW Bayer", "PDAFLinesFilter", raw.bayersensor.pdafLinesFilter, pedited->raw.bayersensor.pdafLinesFilter); } if (keyFile.has_group("RAW X-Trans")) { - assignFromKeyfile(keyFile, "RAW X-Trans", "Method", pedited, raw.xtranssensor.method, pedited->raw.xtranssensor.method); - assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicAutoContrast", pedited, raw.xtranssensor.dualDemosaicAutoContrast, pedited->raw.xtranssensor.dualDemosaicAutoContrast); + assignFromKeyfile(keyFile, "RAW X-Trans", "Method", raw.xtranssensor.method, pedited->raw.xtranssensor.method); + assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicAutoContrast", raw.xtranssensor.dualDemosaicAutoContrast, pedited->raw.xtranssensor.dualDemosaicAutoContrast); if (ppVersion < 345) { raw.xtranssensor.dualDemosaicAutoContrast = false; if (pedited) { pedited->raw.xtranssensor.dualDemosaicAutoContrast = true; } } - assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", pedited, raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast); - assignFromKeyfile(keyFile, "RAW X-Trans", "Border", pedited, raw.xtranssensor.border, pedited->raw.xtranssensor.border); - assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", pedited, raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps); - assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", pedited, raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed); - assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackGreen", pedited, raw.xtranssensor.blackgreen, pedited->raw.xtranssensor.exBlackGreen); - assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", pedited, raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue); + assignFromKeyfile(keyFile, "RAW X-Trans", "DualDemosaicContrast", raw.xtranssensor.dualDemosaicContrast, pedited->raw.xtranssensor.dualDemosaicContrast); + assignFromKeyfile(keyFile, "RAW X-Trans", "Border", raw.xtranssensor.border, pedited->raw.xtranssensor.border); + assignFromKeyfile(keyFile, "RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps, pedited->raw.xtranssensor.ccSteps); + assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred, pedited->raw.xtranssensor.exBlackRed); + assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen, pedited->raw.xtranssensor.exBlackGreen); + assignFromKeyfile(keyFile, "RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue, pedited->raw.xtranssensor.exBlackBlue); } if (keyFile.has_group("Film Negative")) { - assignFromKeyfile(keyFile, "Film Negative", "Enabled", pedited, filmNegative.enabled, pedited->filmNegative.enabled); - assignFromKeyfile(keyFile, "Film Negative", "RedRatio", pedited, filmNegative.redRatio, pedited->filmNegative.redRatio); - assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", pedited, filmNegative.greenExp, pedited->filmNegative.greenExp); - assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", pedited, filmNegative.blueRatio, pedited->filmNegative.blueRatio); + assignFromKeyfile(keyFile, "Film Negative", "Enabled", filmNegative.enabled, pedited->filmNegative.enabled); + assignFromKeyfile(keyFile, "Film Negative", "RedRatio", filmNegative.redRatio, pedited->filmNegative.redRatio); + assignFromKeyfile(keyFile, "Film Negative", "GreenExponent", filmNegative.greenExp, pedited->filmNegative.greenExp); + assignFromKeyfile(keyFile, "Film Negative", "BlueRatio", filmNegative.blueRatio, pedited->filmNegative.blueRatio); if (ppVersion < 347) { // Backwards compatibility with RT v5.8 @@ -10630,9 +10623,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } else if (!keyFile.has_key("Film Negative", "RefInput")) { // Backwards compatibility with intermediate dev version (after v5.8) using film base values bool r, g, b; - assignFromKeyfile(keyFile, "Film Negative", "RedBase", pedited, filmNegative.refInput.r, r); - assignFromKeyfile(keyFile, "Film Negative", "GreenBase", pedited, filmNegative.refInput.g, g); - assignFromKeyfile(keyFile, "Film Negative", "BlueBase", pedited, filmNegative.refInput.b, b); + assignFromKeyfile(keyFile, "Film Negative", "RedBase", filmNegative.refInput.r, r); + assignFromKeyfile(keyFile, "Film Negative", "GreenBase", filmNegative.refInput.g, g); + assignFromKeyfile(keyFile, "Film Negative", "BlueBase", filmNegative.refInput.b, b); if (pedited) { pedited->filmNegative.refInput = r || g || b; pedited->filmNegative.refOutput = r || g || b; @@ -10647,11 +10640,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } else { // current version - assignFromKeyfile(keyFile, "Film Negative", "RefInput", pedited, filmNegative.refInput, pedited->filmNegative.refInput); - assignFromKeyfile(keyFile, "Film Negative", "RefOutput", pedited, filmNegative.refOutput, pedited->filmNegative.refOutput); + assignFromKeyfile(keyFile, "Film Negative", "RefInput", filmNegative.refInput, pedited->filmNegative.refInput); + assignFromKeyfile(keyFile, "Film Negative", "RefOutput", filmNegative.refOutput, pedited->filmNegative.refOutput); int cs = toUnderlying(filmNegative.colorSpace); - assignFromKeyfile(keyFile, "Film Negative", "ColorSpace", pedited, cs, pedited->filmNegative.colorSpace); + assignFromKeyfile(keyFile, "Film Negative", "ColorSpace", cs, pedited->filmNegative.colorSpace); filmNegative.colorSpace = static_cast(cs); if (keyFile.has_key("Film Negative", "BackCompat")) { @@ -10673,13 +10666,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("MetaData")) { int mode = int(MetaDataParams::EDIT); - assignFromKeyfile(keyFile, "MetaData", "Mode", pedited, mode, pedited->metadata.mode); + assignFromKeyfile(keyFile, "MetaData", "Mode", mode, pedited->metadata.mode); if (mode >= int(MetaDataParams::TUNNEL) && mode <= int(MetaDataParams::STRIP)) { metadata.mode = static_cast(mode); } - assignFromKeyfile(keyFile, "MetaData", "ExifKeys", pedited, metadata.exifKeys, pedited->metadata.exifKeys); + assignFromKeyfile(keyFile, "MetaData", "ExifKeys", metadata.exifKeys, pedited->metadata.exifKeys); } if (keyFile.has_group("Exif")) { From a35b320f1a8b2238a126edcb478d0512c538360a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 17 Sep 2023 15:27:19 -0700 Subject: [PATCH 042/291] Fix color toning layers being hidden Request resizing of tool widgets after being attached to the tool panel. --- rtgui/toolpanelcoord.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 77ac26d57..c957f605a 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -856,10 +856,15 @@ ToolPanelCoordinator::updateToolPanel( } FoldableToolPanel *tool_panel = getFoldableToolPanel(*new_tool_trees_iter); - if (tool_panel->getParent()) { + const bool reparent = tool_panel->getParent(); + if (reparent) { tool_panel->getParent()->remove(*tool_panel->getExpander()); } addPanel(panelBox, tool_panel, level); + if (!reparent) { + // If attaching for the first time, update the widget sizes. + tool_panel->getExpander()->check_resize(); + } } // Update the child tools. From ea92cb866402d5cf6652c6ed0226a3b0bceb35da Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 22 Sep 2023 20:24:30 +0200 Subject: [PATCH 043/291] Include Adwaita icon theme (partially) into AppImage To avoid crash at startup if some icons are missing in the desktop environment --- .github/workflows/appimage.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 7c7ad26d7..57b6905bf 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -32,7 +32,7 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full - name: Install Exiv2 run: | @@ -124,6 +124,27 @@ jobs: echo "Copying Lensfun database to the build directory." cp -R ~/.local/share/lensfun/updates/* build/AppDir/usr/share/lensfun/ + - name: Include Adwaita icon theme (partial) + run: | + mkdir build/AppDir/usr/bin/icons/Adwaita + icons_dir=('actions' 'devices' 'mimetypes' 'places' 'status' 'ui' 'devices') + for dir in "${icons_dir[@]}"; do + find_res=$(find /usr/share/icons/Adwaita -name "${dir}" -type d) + if [ -z "$find_res" ] + then + echo "-Warning: Icons folder '"${dir}"' not found in Adwaita theme." + else + new_dir=($(echo "$find_res" | awk -F/ '{print $(NF-1)"/"$NF}')) + for d in "${new_dir[@]}"; do + echo "-Copying '"${d}"' into 'AppDir/usr/bin/icons/Adwaita'." + mkdir -p "build/AppDir/usr/bin/icons/Adwaita/${d}" + cp -R "/usr/share/icons/Adwaita/${d}/." "build/AppDir/usr/bin/icons/Adwaita/${d}" + done + fi + done + echo "-Copying 'index.theme' into 'AppDir/usr/bin/icons/Adwaita'." + cp /usr/share/icons/Adwaita/index.theme build/AppDir/usr/bin/icons/Adwaita + - name: Restore AppImage tools from cache id: appimage-tools-cache uses: actions/cache@v3 From 3341668d51a6d8370c4accc4d3ebe592c110fd46 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 22 Sep 2023 20:27:21 +0200 Subject: [PATCH 044/291] MacOS bundle: copy all Adwaita icon theme (especially scalable ones) --- tools/osx/macosx_bundle.sh | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 970611e90..9423d9025 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -63,14 +63,14 @@ if [[ -x $(which git) && -d $PROJECT_SOURCE_DIR/.git ]]; then # Depending on whether you checked out a branch (dev) or a tag (release), # "git describe" will return "5.0-gtk2-2-g12345678" or "5.0-gtk2", respectively. gitDescribe="$(git describe --tags --always)" - + # Apple requires a numeric version of the form n.n.n # https://goo.gl/eWDQv6 - + # Get number of commits since tagging. This is what gitDescribe uses. # Works when checking out branch, tag or commit. gitCommitsSinceTag="$(git rev-list --count HEAD --not $(git tag --merged HEAD))" - + # Create numeric version. # This version is nonsense, either don't use it at all or use it only where you have no other choice, e.g. Inno Setup's VersionInfoVersion. # Strip everything after hyphen, e.g. "5.0-gtk2" -> "5.0", "5.1-rc1" -> "5.1" (ergo BS). @@ -81,7 +81,7 @@ if [[ -x $(which git) && -d $PROJECT_SOURCE_DIR/.git ]]; then gitVersionNumericBS="${gitVersionNumericBS}.${gitCommitsSinceTag}" # Remove everything until after first hyphen: 5.0 fi ### Copy end. - + PROJECT_FULL_VERSION="$gitDescribe" PROJECT_VERSION="$gitVersionNumericBS" fi @@ -257,12 +257,8 @@ ditto {"${LOCAL_PREFIX}","${RESOURCES}"}/share/themes/Default/gtk-3.0/gtk-keys.c # Adwaita icons msg "Copy Adwaita icons" -iconfolders=("16x16/actions" "16x16/devices" "16x16/mimetypes" "16x16/places" "16x16/status" "16x16/ui" "48x48/devices") -for f in "${iconfolders[@]}"; do - mkdir -p ${RESOURCES}/share/icons/Adwaita/${f} - cp -RL ${LOCAL_PREFIX}/share/icons/Adwaita/${f}/* "${RESOURCES}"/share/icons/Adwaita/${f} -done -cp -RL {"${LOCAL_PREFIX}","${RESOURCES}"}/share/icons/Adwaita/index.theme +mkdir -p ${RESOURCES}/share/icons/Adwaita +cp -RL ${LOCAL_PREFIX}/share/icons/Adwaita/* "${RESOURCES}"/share/icons/Adwaita/ "${LOCAL_PREFIX}/bin/gtk-update-icon-cache" "${RESOURCES}/share/icons/Adwaita" || "${LOCAL_PREFIX}/bin/gtk-update-icon-cache-3.0" "${RESOURCES}/share/icons/Adwaita" cp -RL "${LOCAL_PREFIX}/share/icons/hicolor" "${RESOURCES}/share/icons/hicolor" @@ -384,12 +380,12 @@ fi function CreateDmg { local srcDir="$(mktemp -dt $$.XXXXXXXXXXXX)" - + msg "Preparing disk image sources at ${srcDir}:" cp -R "${APP}" "${srcDir}" cp "${RESOURCES}"/LICENSE "${srcDir}" ln -s /Applications "${srcDir}" - + # Web bookmarks function CreateWebloc { defaults write "${srcDir}/$1" URL "$2" @@ -399,7 +395,7 @@ function CreateDmg { CreateWebloc 'Documentation' 'https://rawpedia.rawtherapee.com/' CreateWebloc 'Forum' 'https://discuss.pixls.us/c/software/rawtherapee' CreateWebloc 'Report Bug' 'https://github.com/Beep6581/RawTherapee/issues/new' - + # Disk image name if [[ -n $UNIVERSAL_URL ]]; then arch="Universal" @@ -409,7 +405,7 @@ function CreateDmg { if [[ $lower_build_type != release ]]; then dmg_name="${dmg_name}_${lower_build_type}" fi - + msg "Creating disk image:" if [[ ! -z $FANCY_DMG ]]; then echo "Building Fancy .dmg" @@ -429,13 +425,13 @@ function CreateDmg { else hdiutil create -format UDBZ -fs HFS+ -srcdir "${srcDir}" -volname "${PROJECT_NAME}_${PROJECT_FULL_VERSION}" "${dmg_name}.dmg" fi - + # Sign disk image if [[ -n $CODESIGNID ]]; then msg "Signing disk image" codesign --deep --force -v -s "${CODESIGNID}" --timestamp "${dmg_name}.dmg" fi - + # Notarize the dmg if ! test -z "$NOTARY"; then msg "Notarizing the dmg:" @@ -443,7 +439,7 @@ function CreateDmg { echo "Uploading..." sudo xcrun notarytool submit "${dmg_name}.dmg.zip" ${NOTARY} --wait fi - + # Zip disk image for redistribution msg "Zipping disk image for redistribution:" mkdir "${PROJECT_NAME}_macOS_${MINIMUM_SYSTEM_VERSION}_${arch}_${PROJECT_FULL_VERSION}_folder" From d276a56b1006d18863dd6745f274dbd90a8fe59c Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 12 Oct 2023 06:59:33 +0200 Subject: [PATCH 045/291] Local adjustments - improvment Dehaze with black (#6860) * Local Dehaze black * Enable black * Change threshold black - publish_pre_dev_labels ladehazeblack --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 2 ++ rtengine/improcfun.h | 4 +++- rtengine/ipdehaze.cc | 9 ++++++++- rtengine/iplocallab.cc | 30 +++++++++++++++++++++++++++++- rtengine/procparams.cc | 6 +++++- rtengine/procparams.h | 1 + rtgui/locallabtools.h | 3 +++ rtgui/locallabtools2.cc | 17 +++++++++++++++++ rtgui/paramsedited.cc | 7 +++++++ rtgui/paramsedited.h | 1 + 12 files changed, 78 insertions(+), 6 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 0d3c76399..c9965b9b3 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladehazeblack"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8b73d7548..8080f64b1 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladehazeblack"]' jobs: build: diff --git a/rtdata/languages/default b/rtdata/languages/default index 11191bedd..185191bcd 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1447,6 +1447,7 @@ HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze - black HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2876,6 +2877,7 @@ TP_LOCALLAB_DARKRETI;Darkness TP_LOCALLAB_DEHAFRA;Dehaze TP_LOCALLAB_DEHAZ;Strength TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. +TP_LOCALLAB_DEHAZE_BLACK;Black TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. TP_LOCALLAB_DELTAD;Delta balance TP_LOCALLAB_DELTAEC;ΔE Image mask diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index ea11e40bd..62dfba0a0 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -364,6 +364,8 @@ enum class BlurType { float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46); + + void tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -489,7 +491,7 @@ enum class BlurType { void BadpixelsLab(LabImage * lab, double radius, int thresh, float chrom); void dehaze(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams); - void dehazeloc(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams); + void dehazeloc(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams, int sk, int sp); void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo); void localContrast(LabImage *lab, float **destination, const procparams::LocalContrastParams &localContrastParams, bool fftwlc, double scale); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 5ccec4a1e..b5403080e 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -454,7 +454,7 @@ void ImProcFunctions::dehaze(Imagefloat *img, const DehazeParams &dehazeParams) } } -void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParams) +void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParams, int sk, int sp) { //J.Desmis 12 2019 - this version derived from ART, is slower than the main from maximum 10% - probably use of SSE //Probably Ingo could solved this problem in some times @@ -476,6 +476,13 @@ void ImProcFunctions::dehazeloc(Imagefloat *img, const DehazeParams &dehazeParam float ambient[3]; float maxDistance = 0.f; + int whit = 0; + int blac = params->locallab.spots.at(sp).dehazeblack; + + if(blac != 0) { + ImProcFunctions::tone_eqdehaz(this, img, whit, blac, params->icm.workingProfile, sk, multiThread); + } + { array2D& R = dark; // R and dark can safely use the same buffer, which is faster and reduces memory allocations/deallocations array2D G(W, H); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 75bb03267..bf7d1a391 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -2303,6 +2303,34 @@ void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float } } +void ImProcFunctions::tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread) +{ + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + double blred = 0.4; + params.bands[0] = blred * blacks; + int bla = abs(blacks); + int threshblawhi = 50; + int threshblawhi2 = 85; + if(bla > threshblawhi) { + params.bands[1] = blred * sign(blacks) * (bla - threshblawhi); + } + if(bla > threshblawhi2) { + params.bands[2] = blred * sign(blacks) * (bla - threshblawhi2); + } + + params.bands[4] = whits; + int whi = abs(whits); + if(whi > threshblawhi) { + params.bands[3] = sign(whits) * (whi - threshblawhi); + } + + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); +} + + void sigmoidla (float &valj, float thresj, float lambda) { //thres : shifts the action of sigmoid to darker tones or lights @@ -14412,7 +14440,7 @@ void ImProcFunctions::Lab_Local( dehazeParams.saturation = lp.dehazeSaturation; dehazeParams.depth = lp.depth; lab2rgb(*bufexpfin, *tmpImage.get(), params->icm.workingProfile); - dehazeloc(tmpImage.get(), dehazeParams); + dehazeloc(tmpImage.get(), dehazeParams, sk, sp); rgb2lab(*tmpImage.get(), *bufexpfin, params->icm.workingProfile); transit_shapedetect2(sp, 0.f, 0.f, call, 30, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 05788399e..f029b88b0 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3828,6 +3828,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : equilret(false), loglin(true), dehazeSaturation(50.0), + dehazeblack(0.0), softradiusret(40.0), CCmaskreticurve{ static_cast(FCT_MinMaxCPoints), @@ -5043,6 +5044,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && equilret == other.equilret && loglin == other.loglin && dehazeSaturation == other.dehazeSaturation + && dehazeblack == other.dehazeblack && softradiusret == other.softradiusret && CCmaskreticurve == other.CCmaskreticurve && LLmaskreticurve == other.LLmaskreticurve @@ -6927,6 +6929,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->equilret, "Locallab", "Equilret_" + index_str, spot.equilret, keyFile); saveToKeyfile(!pedited || spot_edited->loglin, "Locallab", "Loglin_" + index_str, spot.loglin, keyFile); saveToKeyfile(!pedited || spot_edited->dehazeSaturation, "Locallab", "dehazeSaturation_" + index_str, spot.dehazeSaturation, keyFile); + saveToKeyfile(!pedited || spot_edited->dehazeblack, "Locallab", "dehazeblack_" + index_str, spot.dehazeblack, keyFile); saveToKeyfile(!pedited || spot_edited->softradiusret, "Locallab", "Softradiusret_" + index_str, spot.softradiusret, keyFile); saveToKeyfile(!pedited || spot_edited->CCmaskreticurve, "Locallab", "CCmaskretiCurve_" + index_str, spot.CCmaskreticurve, keyFile); saveToKeyfile(!pedited || spot_edited->LLmaskreticurve, "Locallab", "LLmaskretiCurve_" + index_str, spot.LLmaskreticurve, keyFile); @@ -9143,7 +9146,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Inversret_" + index_str, spot.inversret, spotEdited.inversret); assignFromKeyfile(keyFile, "Locallab", "Equilret_" + index_str, spot.equilret, spotEdited.equilret); assignFromKeyfile(keyFile, "Locallab", "Loglin_" + index_str, spot.loglin, spotEdited.loglin); - assignFromKeyfile(keyFile, "Locallab", "dehazeSaturation" + index_str, spot.dehazeSaturation, spotEdited.dehazeSaturation); + assignFromKeyfile(keyFile, "Locallab", "dehazeSaturation_" + index_str, spot.dehazeSaturation, spotEdited.dehazeSaturation); + assignFromKeyfile(keyFile, "Locallab", "dehazeblack_" + index_str, spot.dehazeblack, spotEdited.dehazeblack); assignFromKeyfile(keyFile, "Locallab", "Softradiusret_" + index_str, spot.softradiusret, spotEdited.softradiusret); assignFromKeyfile(keyFile, "Locallab", "CCmaskretiCurve_" + index_str, spot.CCmaskreticurve, spotEdited.CCmaskreticurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskretiCurve_" + index_str, spot.LLmaskreticurve, spotEdited.LLmaskreticurve); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 7390ddc1e..f2c63ea2d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1403,6 +1403,7 @@ struct LocallabParams { bool equilret; bool loglin; double dehazeSaturation; + double dehazeblack; double softradiusret; std::vector CCmaskreticurve; std::vector LLmaskreticurve; diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1664d1839..627be34bd 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -940,6 +940,7 @@ private: Adjuster* const dehaz; Adjuster* const depth; Adjuster* const dehazeSaturation; + Adjuster* const dehazeblack; Gtk::Frame* const retiFrame; Adjuster* const str; Gtk::CheckButton* const loglin; @@ -991,6 +992,8 @@ private: DiagonalCurveEditor* const Lmaskretishape; Gtk::CheckButton* const inversret; + rtengine::ProcEvent Evlocallabdehazeblack; + sigc::connection loglinConn, retinexMethodConn, fftwretiConn, equilretConn, showmaskretiMethodConn, enaretiMaskConn, enaretiMasktmapConn, inversretConn; public: diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index a2c18ee08..252f95caf 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -796,6 +796,7 @@ LocallabRetinex::LocallabRetinex(): dehaz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEHAZ"), -100, 100, 1, 0))), depth(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEPTH"), 0, 100, 1, 25))), dehazeSaturation(Gtk::manage(new Adjuster(M("TP_DEHAZE_SATURATION"), 0, 100, 1, 50))), + dehazeblack(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEHAZE_BLACK"), -65., 100., 1., 0.))), retiFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_RETIFRA")))), str(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STR"), 0., 100., 0.2, 0.))), loglin(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LOGLIN")))), @@ -848,6 +849,10 @@ LocallabRetinex::LocallabRetinex(): Lmaskretishape(static_cast(mask2retiCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), inversret(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))) { + + auto m = ProcEventMapper::getInstance(); + Evlocallabdehazeblack = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_DEHAZE_BLACK"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -857,6 +862,7 @@ LocallabRetinex::LocallabRetinex(): dehazeSaturation->setAdjusterListener(this); depth->setAdjusterListener(this); + dehazeblack->setAdjusterListener(this); retiFrame->set_label_align(0.025, 0.5); @@ -991,6 +997,7 @@ LocallabRetinex::LocallabRetinex(): dehaBox->pack_start(*dehaz); dehaBox->pack_start(*depth); dehaBox->pack_start(*dehazeSaturation); + dehaBox->pack_start(*dehazeblack); dehaFrame->add(*dehaBox); auxBox->add(*dehaFrame); ToolParamBlock* const deharetiBox = Gtk::manage(new ToolParamBlock()); @@ -1247,6 +1254,7 @@ void LocallabRetinex::read(const rtengine::procparams::ProcParams* pp, const Par dehaz->setValue((double)spot.dehaz); depth->setValue((double)spot.depth); dehazeSaturation->setValue((double)spot.dehazeSaturation); + dehazeblack->setValue((double)spot.dehazeblack); str->setValue(spot.str); loglin->set_active(spot.loglin); sensih->setValue((double)spot.sensih); @@ -1325,6 +1333,7 @@ void LocallabRetinex::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.dehaz = dehaz->getIntValue(); spot.depth = depth->getIntValue(); spot.dehazeSaturation = dehazeSaturation->getIntValue(); + spot.dehazeblack = dehazeblack->getValue(); spot.str = str->getValue(); spot.loglin = loglin->get_active(); spot.sensih = sensih->getIntValue(); @@ -1383,6 +1392,7 @@ void LocallabRetinex::setDefaults(const rtengine::procparams::ProcParams* defPar // Set default values for adjuster widgets dehaz->setDefault((double)defSpot.dehaz); dehazeSaturation->setDefault((double)defSpot.dehazeSaturation); + dehazeblack->setDefault((double)defSpot.dehazeblack); depth->setDefault((double)defSpot.depth); str->setDefault(defSpot.str); sensih->setDefault((double)defSpot.sensih); @@ -1438,6 +1448,13 @@ void LocallabRetinex::adjusterChanged(Adjuster* a, double newval) } } + if (a == dehazeblack) { + if (listener) { + listener->panelChanged(Evlocallabdehazeblack, + dehazeblack->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == depth) { if (listener) { listener->panelChanged(Evlocallabdepth, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 7516d9a4a..fe88b70c7 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1478,6 +1478,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).equilret = locallab.spots.at(j).equilret && pSpot.equilret == otherSpot.equilret; locallab.spots.at(j).loglin = locallab.spots.at(j).loglin && pSpot.loglin == otherSpot.loglin; locallab.spots.at(j).dehazeSaturation = locallab.spots.at(j).dehazeSaturation && pSpot.dehazeSaturation == otherSpot.dehazeSaturation; + locallab.spots.at(j).dehazeblack = locallab.spots.at(j).dehazeblack && pSpot.dehazeblack == otherSpot.dehazeblack; locallab.spots.at(j).softradiusret = locallab.spots.at(j).softradiusret && pSpot.softradiusret == otherSpot.softradiusret; locallab.spots.at(j).CCmaskreticurve = locallab.spots.at(j).CCmaskreticurve && pSpot.CCmaskreticurve == otherSpot.CCmaskreticurve; locallab.spots.at(j).LLmaskreticurve = locallab.spots.at(j).LLmaskreticurve && pSpot.LLmaskreticurve == otherSpot.LLmaskreticurve; @@ -4933,6 +4934,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).dehazeSaturation = mods.locallab.spots.at(i).dehazeSaturation; } + if (locallab.spots.at(i).dehazeblack) { + toEdit.locallab.spots.at(i).dehazeblack = mods.locallab.spots.at(i).dehazeblack; + } + if (locallab.spots.at(i).softradiusret) { toEdit.locallab.spots.at(i).softradiusret = mods.locallab.spots.at(i).softradiusret; } @@ -7864,6 +7869,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : equilret(v), loglin(v), dehazeSaturation(v), + dehazeblack(v), softradiusret(v), CCmaskreticurve(v), LLmaskreticurve(v), @@ -8559,6 +8565,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) equilret = v; loglin = v; dehazeSaturation = v; + dehazeblack = v; softradiusret = v; CCmaskreticurve = v; LLmaskreticurve = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 7013da788..2a776f87b 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -776,6 +776,7 @@ public: bool equilret; bool loglin; bool dehazeSaturation; + bool dehazeblack; bool softradiusret; bool CCmaskreticurve; bool LLmaskreticurve; From ae236073e2b146f443d69ef9d1a543cfa901ea24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Komar=C4=8Devi=C4=87?= <4973094+kmilos@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:28:56 +0200 Subject: [PATCH 046/291] Streamline Windows build action Use pacboy for msystem independent install Use build directory directly from CMake Remove lensfun patch (included upstream) --- .github/workflows/windows.yml | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8080f64b1..e926b9cab 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -35,21 +35,22 @@ jobs: with: location: C:\msys2 update: true + msystem: MINGW64 install: | gzip git intltool - mingw-w64-x86_64-gcc - mingw-w64-x86_64-make - mingw-w64-x86_64-pkg-config - mingw-w64-x86_64-cmake - mingw-w64-x86_64-ninja - mingw-w64-x86_64-gtkmm3 - mingw-w64-x86_64-lcms2 - mingw-w64-x86_64-fftw - mingw-w64-x86_64-lensfun - mingw-w64-x86_64-libiptcdata - mingw-w64-x86_64-exiv2 + pacboy: | + cc:p + pkgconf:p + cmake:p + ninja:p + gtkmm3:p + lcms2:p + fftw:p + lensfun:p + libiptcdata:p + exiv2:p - name: Configure build run: | @@ -63,11 +64,6 @@ jobs: echo "Cache suffix is '$CACHE_SUFFIX'." fi - echo "Making build directory." - mkdir build - echo "Changing working directory to the build directory." - cd build - echo "Running CMake configure." cmake \ -G "Ninja" \ @@ -75,21 +71,18 @@ jobs: -DCACHE_NAME_SUFFIX="$CACHE_SUFFIX" \ -DPROC_TARGET_NUMBER="1" \ -DLENSFUNDBDIR="share/lensfun" \ - .. + -S . -B build echo "Recording filtered ref name." echo "REF_NAME_FILTERED=$REF_NAME_FILTERED" >> "$(cygpath -u $GITHUB_ENV)" - name: Build RawTherapee - working-directory: ./build run: | echo "Running CMake install." - cmake --build . --target install + cmake --build build --target install - name: Include Lensfun run: | - echo "Patching lensfun-update-data script." - sed -i 's/HTTPError\(, ValueError\)/URLError\1/' $(which lensfun-update-data) echo "Updating Lensfun database." lensfun-update-data echo "Creating Lensfun directory in the build directory." From 488a15747678df4253403081b32c548b499b8816 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 13 Oct 2023 11:12:37 +0200 Subject: [PATCH 047/291] Fixing review comments --- rtengine/dynamicprofile.cc | 4 +--- rtgui/batchqueuebuttonset.cc | 6 +++--- rtgui/batchqueuepanel.cc | 6 +++--- rtgui/cursormanager.cc | 10 ++++------ rtgui/filterpanel.h | 2 +- rtgui/lensprofile.cc | 2 +- rtgui/rtimage.cc | 27 ++------------------------- rtgui/rtscalable.cc | 8 +++++--- rtgui/rtscalable.h | 2 +- rtgui/rtsurface.cc | 30 +++++++++++++++--------------- rtgui/rtsurface.h | 10 +++++----- 11 files changed, 41 insertions(+), 66 deletions(-) diff --git a/rtengine/dynamicprofile.cc b/rtengine/dynamicprofile.cc index 1b1cd4833..3ae009537 100644 --- a/rtengine/dynamicprofile.cc +++ b/rtengine/dynamicprofile.cc @@ -178,9 +178,7 @@ bool DynamicProfileRules::loadRules() const Glib::ustring fileName = Glib::build_filename (Options::rtdir, "dynamicprofile.cfg"); try { - if (Glib::file_test(fileName, Glib::FILE_TEST_EXISTS)) { - kf.load_from_file (fileName); - } else { + if (!(Glib::file_test(fileName, Glib::FILE_TEST_EXISTS) && kf.load_from_file (fileName))) { return false; } } catch (Glib::Error &e) { diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc index f68a7b4e7..1f4de2286 100644 --- a/rtgui/batchqueuebuttonset.cc +++ b/rtgui/batchqueuebuttonset.cc @@ -25,9 +25,9 @@ bool BatchQueueButtonSet::iconsLoaded = false; -std::shared_ptr BatchQueueButtonSet::cancelIcon = std::shared_ptr(nullptr); -std::shared_ptr BatchQueueButtonSet::headIcon = std::shared_ptr(nullptr); -std::shared_ptr BatchQueueButtonSet::tailIcon = std::shared_ptr(nullptr); +std::shared_ptr BatchQueueButtonSet::cancelIcon; +std::shared_ptr BatchQueueButtonSet::headIcon; +std::shared_ptr BatchQueueButtonSet::tailIcon; Glib::ustring BatchQueueButtonSet::moveHeadToolTip; Glib::ustring BatchQueueButtonSet::moveEndToolTip; diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index f44c54cd0..1de5613c5 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -228,13 +228,13 @@ void BatchQueuePanel::updateTab (int qsize, int forceOrientation) } } else { if (!qsize ) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") )), Gtk::POS_RIGHT, 1, 1); } else if (qStartStop->get_active()) { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-play", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]" )), Gtk::POS_RIGHT, 1, 1); } else { - grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause")), Gtk::POS_RIGHT, 1, 1); + grid->attach_next_to(*Gtk::manage (new RTImage ("gears-pause", Gtk::ICON_SIZE_LARGE_TOOLBAR)), Gtk::POS_RIGHT, 1, 1); grid->attach_next_to(*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_QUEUE") + " [" + Glib::ustring::format( qsize ) + "]" )), Gtk::POS_RIGHT, 1, 1); } diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 12eb0fa37..4cecc6756 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -43,12 +43,10 @@ void CursorManager::init (Glib::RefPtr mainWindow) // - By default, cursor hotspot is located at middle of surface. // Use (offX, offY) between -1 and 0.99 to move cursor hotspot auto cursor_surf = RTSurface(name, Gtk::ICON_SIZE_MENU); - double offXb = std::min(std::max(-1., offX), 0.99); // offX should belong to (-1; 0.99) - double offYb = std::min(std::max(-1., offY), 0.99); // offY should belong to (-1; 0.99) auto cursor = Gdk::Cursor::create(this->display, cursor_surf.get(), - cursor_surf.getWidth() / 2 * (1. + offXb), - cursor_surf.getHeight() / 2 * (1. + offYb)); + std::min(std::max(cursor_surf.getWidth() / 2 * (1. + offX), 0.), static_cast(cursor_surf.getWidth())), + std::min(std::max(cursor_surf.getHeight() / 2 * (1. + offY), 0.), static_cast(cursor_surf.getHeight()))); if (!cursor) { cursor = Gdk::Cursor::create(this->display, fb_cursor); @@ -58,7 +56,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) }; cAdd = createCursor("crosshair-hicontrast", Gdk::PLUS); - cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS, -0.333, 0.75); + cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS, -0.666, 0.75); cCropDraw = createCursor("crop-point-hicontrast", Gdk::DIAMOND_CROSS); cCrosshair = createCursor("crosshair-hicontrast", Gdk::CROSSHAIR); cEmpty = createCursor("empty", Gdk::BLANK_CURSOR); @@ -74,7 +72,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) cMoveXY = createCursor("node-move-xy-hicontrast", Gdk::FLEUR); cMoveY = createCursor("node-move-y-hicontrast", Gdk::SB_V_DOUBLE_ARROW); cRotate = createCursor("rotate-aroundnode-hicontrast", Gdk::EXCHANGE); - cWB = createCursor("color-picker-hicontrast", Gdk::TARGET, -0.333, 0.75); + cWB = createCursor("color-picker-hicontrast", Gdk::TARGET, -0.666, 0.75); cWait = createCursor("gears", Gdk::CLOCK); window = mainWindow; diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h index 4c4a8b0da..32592bbd0 100644 --- a/rtgui/filterpanel.h +++ b/rtgui/filterpanel.h @@ -63,7 +63,7 @@ protected: ExifFilterSettings curefs; FilterPanelListener* listener; - std::shared_ptr ornamentSurface; + std::unique_ptr ornamentSurface; public: FilterPanel (); diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index c0d2a8fa2..d4640a71b 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -64,7 +64,7 @@ LensProfilePanel::LensProfilePanel() : lensfunCameras(Gtk::manage((new MyComboBox()))), lensfunLensesLbl(Gtk::manage((new Gtk::Label(M("EXIFFILTER_LENS"))))), lensfunLenses(Gtk::manage((new MyComboBox()))), - warning(Gtk::manage(new RTImage("warning"))), + warning(Gtk::manage(new RTImage("warning", Gtk::ICON_SIZE_LARGE_TOOLBAR))), ckbUseDist(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_GEOMETRIC"))))), ckbUseVign(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_VIGNETTING"))))), ckbUseCA(Gtk::manage((new Gtk::CheckButton(M("TP_LENSPROFILE_USE_CA"))))) diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index 9bd942c47..bcfa9ad55 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -82,20 +82,7 @@ RTImage::RTImage (const Glib::RefPtr& gIcon, const Gtk::IconSiz void RTImage::set_from_icon_name(const Glib::ustring& iconName) { - this->icon_name = iconName; - - // Set surface from icon cache - surface = RTImageCache::getCachedSurface(this->icon_name, this->size); - - // Add it to the RTImage if surface exists - if (surface) { - set(surface->get()); - } - - // Unset Gio::Icon if firstly exists - if (this->g_icon) { - g_icon = Glib::RefPtr(); - } + set_from_icon_name(iconName, this->size); } void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize) @@ -119,17 +106,7 @@ void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconS void RTImage::set_from_gicon(const Glib::RefPtr& gIcon) { - this->g_icon = gIcon; - - // Set image from Gio::Icon - set(this->g_icon, this->size); - - // Unset surface if previously chosen - this->icon_name = ""; - - if (surface) { - surface = std::shared_ptr(); - } + set_from_gicon(gIcon, this->size); } void RTImage::set_from_gicon(const Glib::RefPtr& gIcon, const Gtk::IconSize iconSize) diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index 5e61e8655..58b67ed52 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -32,7 +32,7 @@ extern Glib::ustring argv0; double RTScalable::dpi = 96.; int RTScalable::scale = 1; -void RTScalable::updateDPInScale(const Gtk::Window* window, double &newDPI, int &newScale) +void RTScalable::getDPInScale(const Gtk::Window* window, double &newDPI, int &newScale) { if (window) { const auto screen = window->get_screen(); @@ -169,6 +169,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us if (error) { std::cerr << "Failed to load SVG file \"" << fname << "\": " << std::endl << Glib::ustring(error->message) << std::endl; + free(error); return surf; } @@ -215,6 +216,7 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us if (!success && error) { std::cerr << "Failed to load SVG file \"" << fname << "\": " << std::endl << Glib::ustring(error->message) << std::endl; + free(error); return surf; } @@ -234,12 +236,12 @@ Cairo::RefPtr RTScalable::loadSurfaceFromSVG(const Glib::us void RTScalable::init(const Gtk::Window* window) { // Retrieve DPI and Scale paremeters from OS - updateDPInScale(window, dpi, scale); + getDPInScale(window, dpi, scale); } void RTScalable::setDPInScale (const Gtk::Window* window) { - updateDPInScale(window, dpi, scale); + getDPInScale(window, dpi, scale); } void RTScalable::setDPInScale (const double newDPI, const int newScale) diff --git a/rtgui/rtscalable.h b/rtgui/rtscalable.h index 6913515aa..80312adef 100644 --- a/rtgui/rtscalable.h +++ b/rtgui/rtscalable.h @@ -54,7 +54,7 @@ class RTScalable private: static double dpi; static int scale; - static void updateDPInScale(const Gtk::Window* window, double &newDPI, int &newScale); + static void getDPInScale(const Gtk::Window* window, double &newDPI, int &newScale); protected: static Cairo::RefPtr loadSurfaceFromIcon(const Glib::ustring &icon_name, const Gtk::IconSize iconSize = Gtk::ICON_SIZE_SMALL_TOOLBAR); diff --git a/rtgui/rtsurface.cc b/rtgui/rtsurface.cc index d26f2cb02..a4015494a 100644 --- a/rtgui/rtsurface.cc +++ b/rtgui/rtsurface.cc @@ -32,7 +32,7 @@ RTSurface::RTSurface() : scaleBack = RTScalable::getScale(); // Initialize other private parameters - type = RTSurface::InvalidType; + type = RTSurfaceType::InvalidType; name = ""; icon_size = Gtk::ICON_SIZE_INVALID; } @@ -45,7 +45,7 @@ RTSurface::RTSurface(const Glib::ustring &icon_name, const Gtk::IconSize iconSiz if (surface) { // Save private parameters - type = RTSurface::IconType; + type = RTSurfaceType::IconType; name = icon_name; icon_size = iconSize; } @@ -67,7 +67,7 @@ RTSurface::RTSurface(const Glib::ustring &fname) : if (surface) { // Save private parameter - type = RTSurface::PNGType; + type = RTSurfaceType::PNGType; name = fname; } } @@ -79,7 +79,7 @@ RTSurface::RTSurface(const Glib::ustring &fname) : if (surface) { // Save private parameter - type = RTSurface::SVGType; + type = RTSurfaceType::SVGType; name = fname; } } @@ -92,7 +92,7 @@ int RTSurface::getWidth() if (hasSurface()) { switch (type) { - case RTSurface::IconType: + case RTSurfaceType::IconType: // Get width from Gtk::IconSize if (!Gtk::IconSize::lookup(icon_size, w, h)) { // Size in invalid w = h = -1; // Invalid case @@ -100,15 +100,15 @@ int RTSurface::getWidth() return w; - case RTSurface::PNGType: + case RTSurfaceType::PNGType: // Directly return surface width return surface->get_width(); - case RTSurface::SVGType: + case RTSurfaceType::SVGType: // Returned size shall consider the scaling return (surface->get_width() / RTScalable::getScale()); - case RTSurface::InvalidType: + case RTSurfaceType::InvalidType: default: // Invalid case return -1; @@ -125,7 +125,7 @@ int RTSurface::getHeight() if (hasSurface()) { switch (type) { - case RTSurface::IconType: + case RTSurfaceType::IconType: // Get width from Gtk::IconSize if (!Gtk::IconSize::lookup(icon_size, w, h)) { // Size in invalid w = h = -1; // Invalid case @@ -133,15 +133,15 @@ int RTSurface::getHeight() return h; - case RTSurface::PNGType: + case RTSurfaceType::PNGType: // Directly return surface width return surface->get_height(); - case RTSurface::SVGType: + case RTSurfaceType::SVGType: // Returned size shall consider the scaling return (surface->get_height() / RTScalable::getScale()); - case RTSurface::InvalidType: + case RTSurfaceType::InvalidType: default: // Invalid case return -1; @@ -175,13 +175,13 @@ void RTSurface::updateSurface() { // Update surface based on the scale switch (type) { - case RTSurface::IconType : + case RTSurfaceType::IconType : surface = RTScalable::loadSurfaceFromIcon(name, icon_size); break; - case RTSurface::PNGType : + case RTSurfaceType::PNGType : surface = RTScalable::loadSurfaceFromPNG(name); break; - case RTSurface::SVGType : + case RTSurfaceType::SVGType : surface = RTScalable::loadSurfaceFromSVG(name); break; default : diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index 629a07a83..515b079c7 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -27,11 +27,11 @@ class RTSurface final : public RTScalable { public: - enum RTSurfaceType { - InvalidType = 1, - IconType = 2, - PNGType = 3, - SVGType = 4 + enum class RTSurfaceType { + InvalidType, + IconType, + PNGType, + SVGType }; private: From 0495b9b151378d7e8f4a437a5f6028f37b1d024b Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 13 Oct 2023 19:10:21 +0200 Subject: [PATCH 048/291] Fixing last review comments --- .../scalable/apps/circle-multicolor-small.svg | 671 ++++++++++++++++++ rtgui/controlspotpanel.cc | 4 +- rtgui/editwindow.cc | 4 +- rtgui/shcselector.cc | 14 +- 4 files changed, 678 insertions(+), 15 deletions(-) create mode 100644 rtdata/icons/rawtherapee/scalable/apps/circle-multicolor-small.svg diff --git a/rtdata/icons/rawtherapee/scalable/apps/circle-multicolor-small.svg b/rtdata/icons/rawtherapee/scalable/apps/circle-multicolor-small.svg new file mode 100644 index 000000000..ba109a903 --- /dev/null +++ b/rtdata/icons/rawtherapee/scalable/apps/circle-multicolor-small.svg @@ -0,0 +1,671 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Maciej Dworak + + + + + + + + RawTherapee icon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index c3f09eb75..70e4ffbfd 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -74,8 +74,8 @@ ControlSpotPanel::ControlSpotPanel(): struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))), thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 10.0, 0.1, 2.0))), iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0.2, 10.0, 0.1, 2.0))), - balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee")), Gtk::manage(new RTImage("circle-white-small"))))), - balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("rawtherapee")), Gtk::manage(new RTImage("circle-red-green-small"))))), + balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("circle-multicolor-small")), Gtk::manage(new RTImage("circle-white-small"))))), + balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("circle-multicolor-small")), Gtk::manage(new RTImage("circle-red-green-small"))))), colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-gray-green-small"))))), colorscope_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORSCOPE"), 0., 100.0, 1., 30.))), avoidrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_AVOIDRAD"), 0., 30.0, 0.1, 0.))), diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc index ac4d9d24e..d2ea0f8a2 100644 --- a/rtgui/editwindow.cc +++ b/rtgui/editwindow.cc @@ -62,8 +62,10 @@ EditWindow::EditWindow (RTWindow* p) , isClosed(true) , isMinimized(false) { - // Set window icon + // For UNIX system, set app icon +#ifndef _WIN32 set_default_icon_name("rawtherapee"); +#endif set_title_decorated(""); set_modal(false); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index 2011271fe..504c209f7 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -183,20 +183,10 @@ void SHCSelector::updateDrawingArea (const ::Cairo::RefPtr< Cairo::Context> &cr) // Update font fontd.set_weight (Pango::WEIGHT_NORMAL); - - const double fontSize = static_cast(h) * 0.8; // pt - // Converting font size to "px" based on DPI and scale -#ifndef __APPLE__ - const double fontScale = RTScalable::getDPI() / RTScalable::pangoDPI; // Refer to notes in rtscalable.h -#else - // On MacOS, font is already scaled by the System library - // Refer to https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/quartz/gdkscreen-quartz.c - const double fontScale = 1.; -#endif - const double absoluteFontSize = static_cast(fontSize) * fontScale; // px + const double fontSize = static_cast(h) * 0.8; // px // Absolute size is defined in "Pango units" and shall be multiplied by // Pango::SCALE from "px": - fontd.set_absolute_size (absoluteFontSize * static_cast(Pango::SCALE)); + fontd.set_absolute_size (fontSize * static_cast(Pango::SCALE)); context->set_font_description (fontd); Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); From 72bf271214cdfb2648ef3eeb8852d8c861a625d8 Mon Sep 17 00:00:00 2001 From: Morgan Hardwood Date: Fri, 13 Oct 2023 23:04:33 +0200 Subject: [PATCH 049/291] Removed gzip from windows.yml workflow #6864 gzip is now included as part of the MSYS2 base install. --- .github/workflows/windows.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e926b9cab..1143c948d 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -37,7 +37,6 @@ jobs: update: true msystem: MINGW64 install: | - gzip git intltool pacboy: | From 29748d057a6d3be0013824e10de8c15eb78ef508 Mon Sep 17 00:00:00 2001 From: CarVac Date: Sat, 14 Oct 2023 15:22:08 -0400 Subject: [PATCH 050/291] Update camconst.json white levels for 1DxII --- rtengine/camconst.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 998ddff19..59a2110b2 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -389,13 +389,18 @@ Camera constants: "ranges": { // black levels are read from raw masked pixels // white levels are same for all colors all ISOs, but safety margin vary on ISO + // actually not, 160 & 320 & 640 seem to have different white levels per color "white": [ { "iso": 50, "levels": 16350 }, // typical for all ISOs: 16383, stdev 2.25 { "iso": 100, "levels": 16350 }, // stdev 2.25 - { "iso": [ 125, 160, 200, 250 ], "levels": 16340 }, // stdev 2.5 - { "iso": [ 320, 400, 500 ], "levels": 16330 }, // stdev 2.95 - { "iso": [ 640, 800, 1000 ], "levels": 16320 }, // stdev x, 4.0 , x - { "iso": [ 1250, 1600, 2000 ], "levels": 16300 }, // stdev x, 6.0 , x + { "iso": [ 125, 200, 250 ], "levels": 16340 }, // stdev 2.5 + { "iso": 160, "levels": [ 16340, 14450, 15600 ] }, // based on CarVac's testing + { "iso": [ 400, 500 ], "levels": 16330 }, // stdev 2.95 + { "iso": 320, "levels": [ 16330, 16000, 16330 ] }, // based on CarVac's testing + { "iso": [ 800, 1000 ], "levels": 16320 }, // stdev x, 4.0 , x + { "iso": 640, "levels": [ 16320, 15800, 16320 ] }, // based on CarVac's testing + { "iso": [ 1600, 2000 ], "levels": 16300 }, // stdev x, 6.0 , x + { "iso": 1250, "levels": [ 16300, 16050, 16300 ] }, // based on CarVac's testing { "iso": [ 2500, 3200, 4000 ], "levels": 16250 }, // STDEV x, 9.8 , x { "iso": [ 5000, 6400, 8000 ], "levels": 16150 }, // stdev x, 17, x { "iso": [ 10000, 12800, 16000 ], "levels": 16100 }, // stdev x, 34 , x From 1efa06e8871dd7bdc68a3bea61d25c158eae2551 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 14 Oct 2023 21:18:04 -0700 Subject: [PATCH 051/291] Fix Lensfun camera mismatch Work around a Lensfun bug that finds the wrong camera when given an exact name of certain cameras. --- rtengine/rtlensfun.cc | 14 ++++++++++++-- rtengine/rtlensfun.h | 2 +- rtgui/lensprofile.cc | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 3b5124947..fc5bb0017 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -435,11 +435,21 @@ std::vector LFDatabase::getLenses() const } -LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring &model) const +LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring &model, bool autoMatch) const { LFCamera ret; if (data_ && !make.empty()) { MyMutex::MyLock lock(lfDBMutex); + if (!autoMatch) { + // Try to find exact match by name. + for (auto camera_list = data_->GetCameras(); camera_list[0]; camera_list++) { + const auto camera = camera_list[0]; + if (make == camera->Maker && model == camera->Model) { + ret.data_ = camera; + return ret; + } + } + } auto found = data_->FindCamerasExt(make.c_str(), model.c_str()); if (found) { ret.data_ = found[0]; @@ -551,7 +561,7 @@ std::unique_ptr LFDatabase::findModifier( return nullptr; } - const LFCamera c = findCamera(make, model); + const LFCamera c = findCamera(make, model, lensProf.lfAutoMatch()); const LFLens l = findLens( lensProf.lfAutoMatch() ? c diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 51212c9b9..bcce77f34 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -120,7 +120,7 @@ public: std::vector getCameras() const; std::vector getLenses() const; - LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model) const; + LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model, bool autoMatch) const; LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const; std::unique_ptr findModifier( diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 784c49f15..58ea1df1d 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -242,7 +242,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa if (pp->lensProf.lfAutoMatch()) { if (metadata) { - c = db->findCamera(metadata->getMake(), metadata->getModel()); + c = db->findCamera(metadata->getMake(), metadata->getModel(), true); setLensfunCamera(c.getMake(), c.getModel()); } } else if (pp->lensProf.lfManual()) { @@ -521,7 +521,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) setLensfunLens(""); } else if (metadata) { const LFDatabase* const db = LFDatabase::getInstance(); - const LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel()); + const LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel(), true); const LFLens l = db->findLens(c, metadata->getLens()); setLensfunCamera(c.getMake(), c.getModel()); setLensfunLens(l.getLens()); @@ -801,7 +801,7 @@ void LensProfilePanel::updateLensfunWarning() return; } - const LFCamera c = db->findCamera((*itc)[lf->lensfunModelCam.make], (*itc)[lf->lensfunModelCam.model]); + const LFCamera c = db->findCamera((*itc)[lf->lensfunModelCam.make], (*itc)[lf->lensfunModelCam.model], false); const auto itl = lensfunLenses->get_active(); if (!itl) { From b6f3ea421e3e5c826f40443cc088342073d86eca Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 17 Oct 2023 21:20:18 -0700 Subject: [PATCH 052/291] Remove recursive symlink browsing for Windows Windows doesn't have symbolic links, so the preference should not be shown. --- rtgui/preferences.cc | 12 +++++++++--- rtgui/preferences.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 1838ee299..07f6e5fd6 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1405,9 +1405,11 @@ Gtk::Widget* Preferences::getFileBrowserPanel() hbBrowseRecursive->pack_start(*browseRecursiveDepth, Gtk::PACK_SHRINK, 4); hbBrowseRecursive->pack_start(*labBrowseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); hbBrowseRecursive->pack_start(*browseRecursiveMaxDirs, Gtk::PACK_SHRINK, 4); - browseRecursiveFollowLinks = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_BROWSERECURSIVEFOLLOWLINKS"))); vbro->pack_start(*hbBrowseRecursive, Gtk::PACK_SHRINK, 0); +#ifndef _WIN32 + browseRecursiveFollowLinks = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_BROWSERECURSIVEFOLLOWLINKS"))); vbro->pack_start(*browseRecursiveFollowLinks, Gtk::PACK_SHRINK, 0); +#endif fro->add(*vbro); @@ -1886,7 +1888,9 @@ void Preferences::storePreferences() moptions.internalThumbIfUntouched = ckbInternalThumbIfUntouched->get_active(); moptions.browseRecursiveDepth = static_cast(browseRecursiveDepth->get_value()); moptions.browseRecursiveMaxDirs = static_cast(browseRecursiveMaxDirs->get_value()); - moptions.browseRecursiveFollowLinks = browseRecursiveFollowLinks->get_active(); + if (browseRecursiveFollowLinks) { + moptions.browseRecursiveFollowLinks = browseRecursiveFollowLinks->get_active(); + } auto save_where = saveParamsPreference->get_active_row_number(); moptions.saveParamsFile = save_where == 0 || save_where == 2; @@ -2114,7 +2118,9 @@ void Preferences::fillPreferences() ckbInternalThumbIfUntouched->set_active(moptions.internalThumbIfUntouched); browseRecursiveDepth->set_value(moptions.browseRecursiveDepth); browseRecursiveMaxDirs->set_value(moptions.browseRecursiveMaxDirs); - browseRecursiveFollowLinks->set_active(moptions.browseRecursiveFollowLinks); + if (browseRecursiveFollowLinks) { + browseRecursiveFollowLinks->set_active(moptions.browseRecursiveFollowLinks); + } saveParamsPreference->set_active(moptions.saveParamsFile ? (moptions.saveParamsCache ? 2 : 0) : 1); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index c15ea71e8..8ee67bf69 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -196,7 +196,7 @@ class Preferences final : Gtk::CheckButton* sameThumbSize; Gtk::SpinButton* browseRecursiveDepth; Gtk::SpinButton* browseRecursiveMaxDirs; - Gtk::CheckButton* browseRecursiveFollowLinks; + Gtk::CheckButton* browseRecursiveFollowLinks{nullptr}; Gtk::SpinButton* threadsSpinBtn; Gtk::SpinButton* clutCacheSizeSB; From e3062e21e24e4eb04e7599dd4a3e8195cde08851 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Fri, 20 Oct 2023 13:02:43 +0200 Subject: [PATCH 053/291] Fixing CropDraw cursor offsets --- rtgui/cursormanager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 4cecc6756..ae56b1361 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -57,7 +57,7 @@ void CursorManager::init (Glib::RefPtr mainWindow) cAdd = createCursor("crosshair-hicontrast", Gdk::PLUS); cAddPicker = createCursor("color-picker-add-hicontrast", Gdk::PLUS, -0.666, 0.75); - cCropDraw = createCursor("crop-point-hicontrast", Gdk::DIAMOND_CROSS); + cCropDraw = createCursor("crop-point-hicontrast", Gdk::DIAMOND_CROSS, -0.75, 0.75); cCrosshair = createCursor("crosshair-hicontrast", Gdk::CROSSHAIR); cEmpty = createCursor("empty", Gdk::BLANK_CURSOR); cHandClosed = createCursor("hand-closed-hicontrast", Gdk::HAND1); From 0e835e8c0064e331a3af10bd3801a299672ce366 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 29 Oct 2023 16:20:12 -0700 Subject: [PATCH 054/291] Fix crash in noise reduction Fix upper bound for array access while building histogram of absolute values in mean absolute deviation (MAD) calculation. Fixes #6871. --- rtengine/FTblockDN.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 7477c5d08..278c6806f 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -2106,7 +2106,7 @@ float ImProcFunctions::Mad(const float * DataList, const int datalen) //calculate histogram of absolute values of wavelet coeffs for (int i = 0; i < datalen; ++i) { - histo[static_cast(rtengine::min(32768.f, fabsf(DataList[i])))]++; + histo[static_cast(rtengine::min(32767.f, fabsf(DataList[i])))]++; } //find median of histogram From de82b9fc7a7db13c06d03dcca6530567e6893e1d Mon Sep 17 00:00:00 2001 From: Alexander Gruzintsev <0v3rt1r3d@gmail.com> Date: Mon, 30 Oct 2023 08:18:33 +0100 Subject: [PATCH 055/291] Fix warnings: conversion to double/float, unused variables, register keyword --- CMakeLists.txt | 4 ++++ rtengine/dfmanager.cc | 1 - rtengine/rawimagesource.cc | 4 ++-- rtgui/dirbrowser.cc | 5 ++++- rtgui/editwindow.h | 2 +- rtgui/flatfield.cc | 2 +- rtgui/lockablecolorpicker.h | 2 +- rtgui/pointermotionlistener.h | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index abb86a108..7b7c797d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -538,6 +538,10 @@ pkg_check_modules(LCMS REQUIRED lcms2>=2.6) pkg_check_modules(EXPAT REQUIRED expat>=2.1) pkg_check_modules(FFTW3F REQUIRED fftw3f) +# By default little-cms2 uses 'register' keyword which is deprecated and removed in c++17 +# This definition forces not to use it +add_definitions("-DCMS_NO_REGISTER_KEYWORD") + #Set the appropriate FFTW flags on macOS if(APPLE AND OPTION_OMP) set(EXTRA_LIB "-L${LOCAL_PREFIX}/lib -lfftw3f_omp -lfftw3f -lm") diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index 52de10339..5ad664b52 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -317,7 +317,6 @@ private: 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); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index eabeb2fc9..38d22a5b9 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -5307,8 +5307,8 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double Glib::ustring profuse; profuse = "JDCmax"; - int limx = 0.05f; - int limy = 0.04f; + float limx = 0.05f; + float limy = 0.04f; if (wbpar.itcwb_prim == "srgb") { profuse = "sRGB"; diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc index 7f5a4c3e3..925fdc606 100644 --- a/rtgui/dirbrowser.cc +++ b/rtgui/dirbrowser.cc @@ -393,7 +393,9 @@ Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) char* dcpy = strdup (absDirPath.c_str()); char* dir = strtok (dcpy, "/\\"); +#ifdef _WIN32 int count = 0; +#endif expandSuccess = true; #ifndef _WIN32 @@ -436,8 +438,9 @@ Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) ++ix; ++i; } - +#ifdef _WIN32 count++; +#endif dir = strtok(nullptr, "/\\"); } diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h index a5932c081..02b7cd23b 100644 --- a/rtgui/editwindow.h +++ b/rtgui/editwindow.h @@ -24,7 +24,7 @@ #include "guiutils.h" class EditorPanel; -class ExternalEditor; +struct ExternalEditor; class RTWindow; class EditWindow : diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 21cdb4315..5246381c3 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -445,7 +445,7 @@ void FlatField::setGainMap(bool enabled) { flatFieldFromMetaData->set_sensitive(enabled); if (!enabled) { idle_register.add( - [this, enabled]() -> bool + [this]() -> bool { disableListener(); flatFieldFromMetaData->setValue(false); diff --git a/rtgui/lockablecolorpicker.h b/rtgui/lockablecolorpicker.h index b18a56028..3de6256e9 100644 --- a/rtgui/lockablecolorpicker.h +++ b/rtgui/lockablecolorpicker.h @@ -30,7 +30,7 @@ namespace rtengine namespace procparams { -class ColorManagementParams; +struct ColorManagementParams; } diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h index f9fda419c..2f19ae0b9 100644 --- a/rtgui/pointermotionlistener.h +++ b/rtgui/pointermotionlistener.h @@ -28,7 +28,7 @@ namespace rtengine namespace procparams { -class ColorManagementParams; +struct ColorManagementParams; } From 4291c33fe4df4464f81fcf4d258caa25c3695e04 Mon Sep 17 00:00:00 2001 From: Alexander Gruzintsev <0v3rt1r3d@gmail.com> Date: Mon, 30 Oct 2023 09:55:14 +0100 Subject: [PATCH 056/291] Add zoom limit feature --- rtdata/languages/default | 1 + rtgui/cropwindow.cc | 33 ++++++++++++++++++++++++++++++++- rtgui/options.cc | 9 +++++++-- rtgui/options.h | 16 ++++++++++++++++ rtgui/preferences.cc | 27 ++++++++++++++++++++++++++- rtgui/preferences.h | 2 ++ 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 185191bcd..bfa585705 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1943,6 +1943,7 @@ PREFERENCES_LENSFUNDBDIR;Lensfun database directory PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. PREFERENCES_LENSPROFILESDIR;Lens profiles directory PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index ef2b7a52b..1649034f8 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -43,6 +43,32 @@ using namespace rtengine; +namespace { + inline double zoomLimitToFraction(Options::MaxZoom z) { + switch (z) { + case Options::MaxZoom::PERCENTS_100: + return 1.; + case Options::MaxZoom::PERCENTS_200: + return 2.; + case Options::MaxZoom::PERCENTS_300: + return 3.; + case Options::MaxZoom::PERCENTS_400: + return 4.; + case Options::MaxZoom::PERCENTS_500: + return 5.; + case Options::MaxZoom::PERCENTS_600: + return 6.; + case Options::MaxZoom::PERCENTS_700: + return 7.; + case Options::MaxZoom::PERCENTS_800: + return 8.; + case Options::MaxZoom::PERCENTS_1600: + default: + return 16.; + } + } +} + bool CropWindow::initialized = false; Glib::ustring CropWindow::zoomOuttt; @@ -2284,13 +2310,18 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) } void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery, bool needsRedraw) { - if (zoom < 0) { zoom = 0; } else if (zoom > int(zoomSteps.size())-1) { zoom = int(zoomSteps.size())-1; } + // Limit zoom according to user preferences + double zoomLimit = zoomLimitToFraction(options.maxZoomLimit); + while(zoomSteps[zoom].zoom > zoomLimit && zoom != 0) { + --zoom; + } + cropZoom = zoom; cropLabel = zoomSteps[cropZoom].label; diff --git a/rtgui/options.cc b/rtgui/options.cc index 61d67f9b6..2da791cd8 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -368,6 +368,7 @@ void Options::setDefaults() fbShowDateTime = true; fbShowBasicExif = true; fbShowExpComp = false; + maxZoomLimit = MaxZoom::PERCENTS_1600; #ifdef _WIN32 // use windows setting for visibility of hidden files/folders SHELLFLAGSTATE sft = { 0 }; @@ -574,8 +575,8 @@ void Options::setDefaults() rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; - rtSettings.cameraProfilesPath = ""; - rtSettings.lensProfilesPath = ""; + rtSettings.cameraProfilesPath = ""; + rtSettings.lensProfilesPath = ""; #ifdef _WIN32 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" @@ -1729,6 +1730,9 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("GUI", "ZoomOnScroll")) { zoomOnScroll = keyFile.get_boolean("GUI", "ZoomOnScroll"); } + if (keyFile.has_key("GUI", "MaxZoom")) { + maxZoomLimit = static_cast(keyFile.get_integer("GUI", "MaxZoom")); + } } if (keyFile.has_group("Crop Settings")) { @@ -2582,6 +2586,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("GUI", "Complexity", complexity); keyFile.set_boolean("GUI", "InspectorWindow", inspectorWindow); keyFile.set_boolean("GUI", "ZoomOnScroll", zoomOnScroll); + keyFile.set_integer("GUI", "MaxZoom", static_cast(maxZoomLimit)); //Glib::ArrayHandle crvopen = crvOpen; //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); diff --git a/rtgui/options.h b/rtgui/options.h index 7c6f1d9fb..72d2b2462 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -368,6 +368,22 @@ public: CropGuidesMode cropGuides; bool cropAutoFit; + // Other options + + // Maximum zoom + enum class MaxZoom: int { + PERCENTS_100 = 0, + PERCENTS_200, + PERCENTS_300, + PERCENTS_400, + PERCENTS_500, + PERCENTS_600, + PERCENTS_700, + PERCENTS_800, + PERCENTS_1600, + }; + MaxZoom maxZoomLimit; + // Performance options Glib::ustring clutsDir; int rgbDenoiseThreadLimit; // maximum number of threads for the denoising tool ; 0 = use the maximum available diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 103075274..ba7fb2de0 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -697,7 +697,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () dirgrid->attach_next_to(*cameraProfilesDirLabel, *clutsDirLabel, Gtk::POS_BOTTOM, 1, 1); dirgrid->attach_next_to(*cameraProfilesDir, *cameraProfilesDirLabel, Gtk::POS_RIGHT, 1, 1); - //Lens Profiles Dir + //Lens Profiles Dir Gtk::Label *lensProfilesDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSPROFILESDIR") + ":")); lensProfilesDirLabel->set_tooltip_text(M("PREFERENCES_LENSPROFILESDIR_TOOLTIP")); setExpandAlignProperties(lensProfilesDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -744,6 +744,29 @@ Gtk::Widget* Preferences::getImageProcessingPanel () cropFrame->add(*cropGrid); vbImageProcessing->pack_start(*cropFrame, Gtk::PACK_SHRINK, 4); + // Other: max zoom + { + Gtk::Frame *frame = Gtk::manage(new Gtk::Frame(M("GENERAL_OTHER"))); + frame->set_label_align (0.025, 0.5); + Gtk::Grid *grid = Gtk::manage(new Gtk::Grid()); + + Gtk::Label *label = Gtk::manage(new Gtk::Label(M("PREFERENCES_MAX_ZOOM_TITLE") + ": ", Gtk::ALIGN_START)); + label->set_line_wrap(true); + grid->attach(*label, 0, 0); + + maxZoomCombo = Gtk::manage(new Gtk::ComboBoxText()); + + // Labels order matches to Options::MaxZoom enum + for (int i = 1; i <= 8; ++i) { + maxZoomCombo->append(Glib::ustring::compose("%100%%", i)); + } + maxZoomCombo->append("1600%"); + + grid->attach(*maxZoomCombo, 1, 0, 1, 1); + frame->add(*grid); + vbImageProcessing->pack_start(*frame, Gtk::PACK_SHRINK, 4); + } + swImageProcessing->add(*vbImageProcessing); return swImageProcessing; @@ -1994,6 +2017,7 @@ void Preferences::storePreferences() moptions.cropGuides = Options::CropGuidesMode(cropGuidesCombo->get_active_row_number()); moptions.cropAutoFit = cropAutoFitCB->get_active(); + moptions.maxZoomLimit = Options::MaxZoom(maxZoomCombo->get_active_row_number()); toolLocationPreference->updateOptions(); @@ -2228,6 +2252,7 @@ void Preferences::fillPreferences() cropGuidesCombo->set_active(moptions.cropGuides); cropAutoFitCB->set_active(moptions.cropAutoFit); + maxZoomCombo->set_active(static_cast(options.maxZoomLimit)); addc.block(false); setc.block(false); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 219844d55..bc8dc0d22 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -249,6 +249,8 @@ class Preferences final : Gtk::ComboBoxText *cropGuidesCombo; Gtk::CheckButton *cropAutoFitCB; + Gtk::ComboBoxText *maxZoomCombo; + Gtk::ComboBoxText *metadataSyncCombo; Gtk::ComboBoxText *xmpSidecarCombo; From 831a9bbd55ff3cbdd6c4712131339fa0dbf44ff5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 3 Nov 2023 21:48:21 -0700 Subject: [PATCH 057/291] Fix crash when opening image in editor Do not access uninitialized raw image data. The raw data is requested when the demosaic mode is set to None and the cursor is moved over the image in the editor. It can occur before the raw data is loaded. --- rtengine/rawimagesource.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index eabeb2fc9..9b987e9f5 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -16,6 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include #include #include @@ -743,6 +744,8 @@ void RawImageSource::getWBMults(const ColorTemp &ctemp, const RAWParams &raw, st void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + MyMutex::MyLock lock(getImageMutex); tran = defTransform(ri, tran); @@ -1744,6 +1747,8 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + MyTime t1, t2; t1.set(); @@ -3837,6 +3842,8 @@ void RawImageSource::hlRecovery(const std::string &method, float* red, float* gr void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + // BENCHFUN histcompr = 3; @@ -7481,6 +7488,8 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, double & greenref, double & tempitc, double & greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double & rm, double & gm, double & bm, const WBParams & wbpar, const ColorManagementParams & cmp, const RAWParams & raw, const ToneCurveParams &hrp) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + // BENCHFUN constexpr double clipHigh = 64000.0; @@ -7710,6 +7719,8 @@ void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, doubl void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + // BENCHFUN constexpr double clipHigh = 64000.0; @@ -7926,6 +7937,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); int x; int y; @@ -8265,7 +8277,7 @@ void RawImageSource::init() void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { - if (d1x) { // Nikon D1x has special sensor. We just skip it + if (rawData.getWidth() != W || rawData.getHeight() != H || d1x) { // Nikon D1x has special sensor. We just skip it R = G = B = 0; return; } @@ -8313,6 +8325,8 @@ bool RawImageSource::isGainMapSupported() const void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) { + assert(rawData.getHeight() == H && rawData.getWidth() == W); + // now we can apply each gain map to raw_data array2D mvals[2][2]; From 5acf1c0a7f8d7f22e68168401213938de91e133e Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 7 Nov 2023 07:38:13 +0100 Subject: [PATCH 058/291] White Balance - temperature correlation in batch mode - issue #6867 (#6877) * Change Itcwb in simpleprocess * Change for auto RGBgrey * remove unnecessary code --- rtengine/simpleprocess.cc | 248 +++++++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 3 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 2484eb554..319ba7f3b 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -271,17 +271,260 @@ private: // set the color temperature currWB = ColorTemp(params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method, params.wb.observer); + ColorTemp currWBitc; + if (params.wb.method == "autitcgreen" && flush) { + imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw, params.wb); + } + const bool autowb = params.wb.method == "autitcgreen"; + ColorTemp autoWB; + int dread = 0; + int bia = 1; + float studgood = 1000.f; + int nocam = 0; + int kcam = 0; + float minchrom = 1000.f; + float delta = 0.f; + int kmin = 20; + float minhist = 1000000000.f; + float maxhist = -1000.f; + double tempitc = 5000.f; + double greenitc = 1.; + float temp0 = 5000.f; + bool extra = false; + bool forcewbgrey = false; if (!params.wb.enabled) { currWB = ColorTemp(); } else if (params.wb.method == "Camera") { currWB = imgsrc->getWB(); - } else if (params.wb.method == "autold") { + } else if (params.wb.method == "autold") {//for Auto RGB double rm, gm, bm; imgsrc->getAutoWBMultipliers(rm, gm, bm); currWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); - } + } else if (autowb && flush) {//for auto Itcwb - flush to enable only when batch + //code similar to that present in improccoordinator.cc + float tem = 5000.f; + float gre = 1.f; + double tempref0bias = 5000.; + tempitc = 5000.f; + bool autowb1 = true; + double green_thres = 0.8; + + { + currWBitc = imgsrc->getWB(); + + double greenref = currWBitc.getGreen(); + double tempref0bias0 = currWBitc.getTemp(); + + if (greenref > green_thres && params.wb.itcwb_prim == "srgb") { + forcewbgrey = true; + } + + if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 + if (settings->verbose) { + printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); + } + + autowb1 = true; + kcam = 1; + } + + if (autowb1) { + //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera + // kcam = 0; + params.wb.method = "autold"; + double rm, gm, bm; + tempitc = 5000.f; + greenitc = 1.; + currWBitc = imgsrc->getWB(); + tempref0bias = currWBitc.getTemp(); + double greenref = currWBitc.getGreen(); + bool pargref = true; + bool pargre = true; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust... + imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + imgsrc->wbMul2Camera(rm, gm, bm); + imgsrc->wbCamera2Mul(rm, gm, bm); + ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); + tem = ct.getTemp(); + gre = ct.getGreen(); + + if (gre > 1.3f) { + pargre = false; + } + + if (greenref > 1.3f) { + pargref = false; + } + + double deltemp = tem - tempref0bias; + + if (gre > 1.5f && !forcewbgrey) { //probable wrong value + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out + } else { + if (!forcewbgrey) { + gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + nocam = 0; + } else {//set temp and green to init itcwb algorithm + double grepro = LIM(greenref, green_thres, 1.15); + gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey + + if (abs(deltemp) < 400.) { //arbitraries thresholds to refine + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 1; + } else { + nocam = 2; + } + } else if (abs(deltemp) < 900.) { //other arbitrary threshold + tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 3; + } else { + nocam = 4; + } + } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 5; + } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 6; + } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { + if (tem >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 7; + } else { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 8; + } + } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { + if (tem >= 10000.f) { + tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 9; + } else { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 10; + } + } else { + tem = 0.4 * tem + 0.6 * tempref0bias; + nocam = 11; + } + } + } + + tempitc = tem ; + + extra = true; + + if (settings->verbose) { + printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); + } + } + } + + params.wb.method = "autitcgreen"; + + } + + float greenitc_low = 1.f; + float tempitc_low = 5000.f; + { + double rm, gm, bm; + greenitc = 1.; + currWBitc = imgsrc->getWB(); + currWBitc = currWBitc.convertObserver(params.wb.observer);//change the temp/green couple with the same multipliers + + double tempref = currWBitc.getTemp() * (1. + params.wb.tempBias); + double greenref = currWBitc.getGreen(); + greenitc = greenref; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? + tempref = tem * (1. + params.wb.tempBias); + greenref = gre; + } else { + + } + + if(params.wb.itcwb_sampling) { + greenitc_low = greenref; + tempitc_low = tempref; + } + + if (settings->verbose && params.wb.method == "autitcgreen") { + printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); + } + + imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + + + params.wb.temperature = tempitc; + params.wb.green = greenitc; + + if(params.wb.itcwb_sampling) { + params.wb.temperature = tempitc_low; + params.wb.green = greenitc_low; + } + + currWB = ColorTemp(params.wb.temperature, params.wb.green, 1., params.wb.method, params.wb.observer); + currWB.getMultipliers(rm, gm, bm); + autoWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); + + } + + currWB = autoWB; + } + //end WB auto + calclum = nullptr ; params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); autoNR = (float) settings->nrauto;// @@ -2116,7 +2359,6 @@ IImagefloat* processImage(ProcessingJob* pjob, int& errorCode, ProgressListener* void batchProcessingThread(ProcessingJob* job, BatchProcessingListener* bpl) { - ProcessingJob* currentJob = job; while (currentJob) { From 638ecc4cde79b0296f2e04f683ca4cb881c28f36 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 12 Nov 2023 11:49:00 -0800 Subject: [PATCH 059/291] Squashed 'rtengine/libraw/' content from commit cccb97647 git-subtree-dir: rtengine/libraw git-subtree-split: cccb97647fcee56801fa68231fa8a38aa8b52ef7 --- .clang-format | 4 + COPYRIGHT | 27 + Changelog.txt | 2744 +++++++++++ DEVELOPER-NOTES | 20 + GoPro/dng-sdk-1_4-allow-VC5-validate.diff | 21 + GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff | 15 + GoPro/dng-sdk-allow-VC5-validate.diff | 21 + GoPro/gpr_read_image.cpp.diff | 29 + GoPro/gpr_read_image.h.diff | 12 + INSTALL | 51 + LICENSE.CDDL | 340 ++ LICENSE.LGPL | 458 ++ LibRaw.pro | 19 + LibRaw.sln | 123 + Makefile.am | 140 + Makefile.devel | 496 ++ Makefile.devel.nopp | 230 + Makefile.devel.noppr2i | 227 + Makefile.dist | 501 ++ Makefile.mingw | 297 ++ Makefile.msvc | 628 +++ README.DNGSDK.txt | 43 + README.GoPro.txt | 112 + README.RawSpeed.txt | 62 + README.cmake | 9 + README.demosaic-packs | 17 + README.md | 106 + RawSpeed/rawspeed.cpucount-unix.patch | 15 + RawSpeed/rawspeed.qmake-pro-files.patch | 84 + RawSpeed/rawspeed.samsung-decoder.patch | 39 + .../rawspeed.uncompressed-color-dng.patch | 13 + RawSpeed/rawspeed.win32-dll.patch | 186 + RawSpeed/rawspeed_xmldata.cpp | 4115 +++++++++++++++++ RawSpeed3/README.md | 69 + .../patches/01.CameraMeta-extensibility.patch | 13 + .../patches/02.Makernotes-processing.patch | 36 + .../03.remove-limits-and-logging.patch | 245 + .../patches/04.clang-cl-compatibility.patch | 37 + RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp | 251 + RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h | 83 + .../rawspeed3_c_api/rawspeed3_capi_test.cpp | 71 + RawSpeed3/rawspeed3_c_api/rsxml2c.sh | 5 + bin/.keep_me | 2 + buildfiles/4channels.pro | 5 + buildfiles/4channels.vcxproj | 145 + buildfiles/4channels.vcxproj.filters | 18 + buildfiles/dcraw_emu.pro | 6 + buildfiles/dcraw_emu.vcxproj | 145 + buildfiles/dcraw_emu.vcxproj.filters | 18 + buildfiles/dcraw_half.pro | 6 + buildfiles/dcraw_half.vcxproj | 145 + buildfiles/dcraw_half.vcxproj.filters | 18 + buildfiles/half_mt.pro | 10 + buildfiles/libraw-common-lib.pro | 28 + buildfiles/libraw-common.pro | 8 + buildfiles/libraw.pro | 70 + buildfiles/libraw.vcxproj | 234 + buildfiles/libraw.vcxproj.filters | 295 ++ buildfiles/mem_image.pro | 6 + buildfiles/mem_image.vcxproj | 145 + buildfiles/mem_image.vcxproj.filters | 18 + buildfiles/multirender_test.pro | 6 + buildfiles/multirender_test.vcxproj | 145 + buildfiles/multirender_test.vcxproj.filters | 18 + buildfiles/openbayer_sample.pro | 6 + buildfiles/openbayer_sample.vcxproj | 145 + buildfiles/openbayer_sample.vcxproj.filters | 18 + buildfiles/postprocessing_benchmark.pro | 4 + buildfiles/postprocessing_benchmark.vcxproj | 145 + .../postprocessing_benchmark.vcxproj.filters | 18 + buildfiles/raw-identify.pro | 6 + buildfiles/raw-identify.vcxproj | 145 + buildfiles/raw-identify.vcxproj.filters | 18 + buildfiles/rawtextdump.pro | 6 + buildfiles/rawtextdump.vcxproj | 145 + buildfiles/rawtextdump.vcxproj.filters | 18 + buildfiles/simple_dcraw.pro | 6 + buildfiles/simple_dcraw.vcxproj | 145 + buildfiles/simple_dcraw.vcxproj.filters | 18 + buildfiles/unprocessed_raw.pro | 6 + buildfiles/unprocessed_raw.vcxproj | 145 + buildfiles/unprocessed_raw.vcxproj.filters | 18 + clist2c.pl | 12 + clist2html.pl | 54 + configure.ac | 153 + doc/API-C.html | 187 + doc/API-CXX.html | 881 ++++ doc/API-datastruct.html | 1335 ++++++ doc/API-notes.html | 305 ++ doc/API-overview.html | 66 + doc/Install-LibRaw.html | 124 + doc/Samples-LibRaw.html | 213 + doc/Why-LibRaw.html | 65 + doc/index.html | 38 + export-dist.sh | 28 + internal/dcraw_defs.h | 66 + internal/dcraw_fileio_defs.h | 25 + internal/defines.h | 193 + internal/dmp_include.h | 27 + internal/libraw_cameraids.h | 320 ++ internal/libraw_cxx_defs.h | 133 + internal/libraw_internal_funcs.h | 412 ++ internal/var_defines.h | 215 + internal/x3f_tools.h | 539 +++ lib/Makefile | 3 + libraw.pc.in | 12 + libraw/libraw.h | 534 +++ libraw/libraw_alloc.h | 148 + libraw/libraw_const.h | 810 ++++ libraw/libraw_datastream.h | 410 ++ libraw/libraw_internal.h | 341 ++ libraw/libraw_types.h | 1175 +++++ libraw/libraw_version.h | 63 + libraw_r.pc.in | 12 + m4/ax_openmp.m4 | 99 + mkdist.sh | 18 + object/.keep_me | 0 rsxml2c.sh | 6 + samples/4channels.cpp | 174 + samples/Makefile | 2 + samples/dcraw_emu.cpp | 670 +++ samples/dcraw_half.c | 78 + samples/half_mt.c | 178 + samples/half_mt_win32.c | 212 + samples/mem_image_sample.cpp | 282 ++ samples/multirender_test.cpp | 107 + samples/openbayer_sample.cpp | 65 + samples/postprocessing_benchmark.cpp | 223 + samples/raw-identify.cpp | 739 +++ samples/rawtextdump.cpp | 144 + samples/simple_dcraw.cpp | 217 + samples/unprocessed_raw.cpp | 319 ++ shlib-version.sh | 11 + src/Makefile | 2 + src/decoders/canon_600.cpp | 225 + src/decoders/crx.cpp | 2781 +++++++++++ src/decoders/decoders_dcraw.cpp | 1799 +++++++ src/decoders/decoders_libraw.cpp | 861 ++++ src/decoders/decoders_libraw_dcrdefs.cpp | 411 ++ src/decoders/dng.cpp | 278 ++ src/decoders/fp_dng.cpp | 689 +++ src/decoders/fuji_compressed.cpp | 1210 +++++ src/decoders/generic.cpp | 101 + src/decoders/kodak_decoders.cpp | 524 +++ src/decoders/load_mfbacks.cpp | 915 ++++ src/decoders/smal.cpp | 181 + src/decoders/unpack.cpp | 493 ++ src/decoders/unpack_thumb.cpp | 385 ++ src/demosaic/aahd_demosaic.cpp | 781 ++++ src/demosaic/ahd_demosaic.cpp | 355 ++ src/demosaic/dcb_demosaic.cpp | 900 ++++ src/demosaic/dht_demosaic.cpp | 1033 +++++ src/demosaic/misc_demosaic.cpp | 420 ++ src/demosaic/xtrans_demosaic.cpp | 430 ++ src/integration/dngsdk_glue.cpp | 414 ++ src/integration/rawspeed_glue.cpp | 286 ++ src/libraw_c_api.cpp | 457 ++ src/libraw_datastream.cpp | 1046 +++++ src/metadata/adobepano.cpp | 154 + src/metadata/canon.cpp | 1335 ++++++ src/metadata/ciff.cpp | 411 ++ src/metadata/cr3_parser.cpp | 896 ++++ src/metadata/epson.cpp | 96 + src/metadata/exif_gps.cpp | 430 ++ src/metadata/fuji.cpp | 1427 ++++++ src/metadata/hasselblad_model.cpp | 538 +++ src/metadata/identify.cpp | 3167 +++++++++++++ src/metadata/identify_tools.cpp | 140 + src/metadata/kodak.cpp | 363 ++ src/metadata/leica.cpp | 375 ++ src/metadata/makernotes.cpp | 786 ++++ src/metadata/mediumformat.cpp | 521 +++ src/metadata/minolta.cpp | 110 + src/metadata/misc_parsers.cpp | 694 +++ src/metadata/nikon.cpp | 1051 +++++ src/metadata/normalize_model.cpp | 1451 ++++++ src/metadata/olympus.cpp | 685 +++ src/metadata/p1.cpp | 192 + src/metadata/pentax.cpp | 675 +++ src/metadata/samsung.cpp | 182 + src/metadata/sony.cpp | 2316 ++++++++++ src/metadata/tiff.cpp | 2188 +++++++++ src/postprocessing/aspect_ratio.cpp | 113 + src/postprocessing/dcraw_process.cpp | 259 ++ src/postprocessing/mem_image.cpp | 292 ++ src/postprocessing/postprocessing_aux.cpp | 406 ++ src/postprocessing/postprocessing_ph.cpp | 31 + src/postprocessing/postprocessing_utils.cpp | 190 + .../postprocessing_utils_dcrdefs.cpp | 308 ++ src/preprocessing/ext_preprocess.cpp | 127 + src/preprocessing/preprocessing_ph.cpp | 24 + src/preprocessing/raw2image.cpp | 558 +++ src/preprocessing/subtract_black.cpp | 91 + src/tables/cameralist.cpp | 1269 +++++ src/tables/colorconst.cpp | 57 + src/tables/colordata.cpp | 1841 ++++++++ src/tables/wblists.cpp | 217 + src/utils/curves.cpp | 151 + src/utils/decoder_info.cpp | 413 ++ src/utils/init_close_utils.cpp | 340 ++ src/utils/open.cpp | 1259 +++++ src/utils/phaseone_processing.cpp | 101 + src/utils/read_utils.cpp | 176 + src/utils/thumb_utils.cpp | 328 ++ src/utils/utils_dcraw.cpp | 330 ++ src/utils/utils_libraw.cpp | 673 +++ src/write/apply_profile.cpp | 76 + src/write/file_write.cpp | 338 ++ src/write/tiff_writer.cpp | 73 + src/write/write_ph.cpp | 39 + src/x3f/x3f_parse_process.cpp | 708 +++ src/x3f/x3f_utils_patched.cpp | 2119 +++++++++ version.sh | 16 + 213 files changed, 77043 insertions(+) create mode 100644 .clang-format create mode 100644 COPYRIGHT create mode 100644 Changelog.txt create mode 100644 DEVELOPER-NOTES create mode 100644 GoPro/dng-sdk-1_4-allow-VC5-validate.diff create mode 100644 GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff create mode 100644 GoPro/dng-sdk-allow-VC5-validate.diff create mode 100644 GoPro/gpr_read_image.cpp.diff create mode 100644 GoPro/gpr_read_image.h.diff create mode 100644 INSTALL create mode 100644 LICENSE.CDDL create mode 100644 LICENSE.LGPL create mode 100644 LibRaw.pro create mode 100644 LibRaw.sln create mode 100644 Makefile.am create mode 100644 Makefile.devel create mode 100644 Makefile.devel.nopp create mode 100644 Makefile.devel.noppr2i create mode 100644 Makefile.dist create mode 100644 Makefile.mingw create mode 100644 Makefile.msvc create mode 100644 README.DNGSDK.txt create mode 100644 README.GoPro.txt create mode 100644 README.RawSpeed.txt create mode 100644 README.cmake create mode 100644 README.demosaic-packs create mode 100644 README.md create mode 100644 RawSpeed/rawspeed.cpucount-unix.patch create mode 100644 RawSpeed/rawspeed.qmake-pro-files.patch create mode 100644 RawSpeed/rawspeed.samsung-decoder.patch create mode 100644 RawSpeed/rawspeed.uncompressed-color-dng.patch create mode 100644 RawSpeed/rawspeed.win32-dll.patch create mode 100644 RawSpeed/rawspeed_xmldata.cpp create mode 100644 RawSpeed3/README.md create mode 100644 RawSpeed3/patches/01.CameraMeta-extensibility.patch create mode 100644 RawSpeed3/patches/02.Makernotes-processing.patch create mode 100644 RawSpeed3/patches/03.remove-limits-and-logging.patch create mode 100644 RawSpeed3/patches/04.clang-cl-compatibility.patch create mode 100644 RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp create mode 100644 RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h create mode 100644 RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp create mode 100644 RawSpeed3/rawspeed3_c_api/rsxml2c.sh create mode 100644 bin/.keep_me create mode 100644 buildfiles/4channels.pro create mode 100644 buildfiles/4channels.vcxproj create mode 100644 buildfiles/4channels.vcxproj.filters create mode 100644 buildfiles/dcraw_emu.pro create mode 100644 buildfiles/dcraw_emu.vcxproj create mode 100644 buildfiles/dcraw_emu.vcxproj.filters create mode 100644 buildfiles/dcraw_half.pro create mode 100644 buildfiles/dcraw_half.vcxproj create mode 100644 buildfiles/dcraw_half.vcxproj.filters create mode 100644 buildfiles/half_mt.pro create mode 100644 buildfiles/libraw-common-lib.pro create mode 100644 buildfiles/libraw-common.pro create mode 100644 buildfiles/libraw.pro create mode 100644 buildfiles/libraw.vcxproj create mode 100644 buildfiles/libraw.vcxproj.filters create mode 100644 buildfiles/mem_image.pro create mode 100644 buildfiles/mem_image.vcxproj create mode 100644 buildfiles/mem_image.vcxproj.filters create mode 100644 buildfiles/multirender_test.pro create mode 100644 buildfiles/multirender_test.vcxproj create mode 100644 buildfiles/multirender_test.vcxproj.filters create mode 100644 buildfiles/openbayer_sample.pro create mode 100644 buildfiles/openbayer_sample.vcxproj create mode 100644 buildfiles/openbayer_sample.vcxproj.filters create mode 100644 buildfiles/postprocessing_benchmark.pro create mode 100644 buildfiles/postprocessing_benchmark.vcxproj create mode 100644 buildfiles/postprocessing_benchmark.vcxproj.filters create mode 100644 buildfiles/raw-identify.pro create mode 100644 buildfiles/raw-identify.vcxproj create mode 100644 buildfiles/raw-identify.vcxproj.filters create mode 100644 buildfiles/rawtextdump.pro create mode 100644 buildfiles/rawtextdump.vcxproj create mode 100644 buildfiles/rawtextdump.vcxproj.filters create mode 100644 buildfiles/simple_dcraw.pro create mode 100644 buildfiles/simple_dcraw.vcxproj create mode 100644 buildfiles/simple_dcraw.vcxproj.filters create mode 100644 buildfiles/unprocessed_raw.pro create mode 100644 buildfiles/unprocessed_raw.vcxproj create mode 100644 buildfiles/unprocessed_raw.vcxproj.filters create mode 100755 clist2c.pl create mode 100755 clist2html.pl create mode 100644 configure.ac create mode 100644 doc/API-C.html create mode 100644 doc/API-CXX.html create mode 100644 doc/API-datastruct.html create mode 100644 doc/API-notes.html create mode 100644 doc/API-overview.html create mode 100644 doc/Install-LibRaw.html create mode 100644 doc/Samples-LibRaw.html create mode 100644 doc/Why-LibRaw.html create mode 100644 doc/index.html create mode 100755 export-dist.sh create mode 100644 internal/dcraw_defs.h create mode 100644 internal/dcraw_fileio_defs.h create mode 100644 internal/defines.h create mode 100644 internal/dmp_include.h create mode 100644 internal/libraw_cameraids.h create mode 100644 internal/libraw_cxx_defs.h create mode 100644 internal/libraw_internal_funcs.h create mode 100644 internal/var_defines.h create mode 100644 internal/x3f_tools.h create mode 100644 lib/Makefile create mode 100644 libraw.pc.in create mode 100644 libraw/libraw.h create mode 100644 libraw/libraw_alloc.h create mode 100644 libraw/libraw_const.h create mode 100644 libraw/libraw_datastream.h create mode 100644 libraw/libraw_internal.h create mode 100644 libraw/libraw_types.h create mode 100644 libraw/libraw_version.h create mode 100644 libraw_r.pc.in create mode 100644 m4/ax_openmp.m4 create mode 100755 mkdist.sh create mode 100644 object/.keep_me create mode 100755 rsxml2c.sh create mode 100644 samples/4channels.cpp create mode 100644 samples/Makefile create mode 100644 samples/dcraw_emu.cpp create mode 100644 samples/dcraw_half.c create mode 100644 samples/half_mt.c create mode 100644 samples/half_mt_win32.c create mode 100644 samples/mem_image_sample.cpp create mode 100644 samples/multirender_test.cpp create mode 100644 samples/openbayer_sample.cpp create mode 100644 samples/postprocessing_benchmark.cpp create mode 100644 samples/raw-identify.cpp create mode 100644 samples/rawtextdump.cpp create mode 100644 samples/simple_dcraw.cpp create mode 100644 samples/unprocessed_raw.cpp create mode 100755 shlib-version.sh create mode 100644 src/Makefile create mode 100644 src/decoders/canon_600.cpp create mode 100644 src/decoders/crx.cpp create mode 100644 src/decoders/decoders_dcraw.cpp create mode 100644 src/decoders/decoders_libraw.cpp create mode 100644 src/decoders/decoders_libraw_dcrdefs.cpp create mode 100644 src/decoders/dng.cpp create mode 100644 src/decoders/fp_dng.cpp create mode 100644 src/decoders/fuji_compressed.cpp create mode 100644 src/decoders/generic.cpp create mode 100644 src/decoders/kodak_decoders.cpp create mode 100644 src/decoders/load_mfbacks.cpp create mode 100644 src/decoders/smal.cpp create mode 100644 src/decoders/unpack.cpp create mode 100644 src/decoders/unpack_thumb.cpp create mode 100644 src/demosaic/aahd_demosaic.cpp create mode 100644 src/demosaic/ahd_demosaic.cpp create mode 100644 src/demosaic/dcb_demosaic.cpp create mode 100644 src/demosaic/dht_demosaic.cpp create mode 100644 src/demosaic/misc_demosaic.cpp create mode 100644 src/demosaic/xtrans_demosaic.cpp create mode 100644 src/integration/dngsdk_glue.cpp create mode 100644 src/integration/rawspeed_glue.cpp create mode 100644 src/libraw_c_api.cpp create mode 100644 src/libraw_datastream.cpp create mode 100644 src/metadata/adobepano.cpp create mode 100644 src/metadata/canon.cpp create mode 100644 src/metadata/ciff.cpp create mode 100644 src/metadata/cr3_parser.cpp create mode 100644 src/metadata/epson.cpp create mode 100644 src/metadata/exif_gps.cpp create mode 100644 src/metadata/fuji.cpp create mode 100644 src/metadata/hasselblad_model.cpp create mode 100644 src/metadata/identify.cpp create mode 100644 src/metadata/identify_tools.cpp create mode 100644 src/metadata/kodak.cpp create mode 100644 src/metadata/leica.cpp create mode 100644 src/metadata/makernotes.cpp create mode 100644 src/metadata/mediumformat.cpp create mode 100644 src/metadata/minolta.cpp create mode 100644 src/metadata/misc_parsers.cpp create mode 100644 src/metadata/nikon.cpp create mode 100644 src/metadata/normalize_model.cpp create mode 100644 src/metadata/olympus.cpp create mode 100644 src/metadata/p1.cpp create mode 100644 src/metadata/pentax.cpp create mode 100644 src/metadata/samsung.cpp create mode 100644 src/metadata/sony.cpp create mode 100644 src/metadata/tiff.cpp create mode 100644 src/postprocessing/aspect_ratio.cpp create mode 100644 src/postprocessing/dcraw_process.cpp create mode 100644 src/postprocessing/mem_image.cpp create mode 100644 src/postprocessing/postprocessing_aux.cpp create mode 100644 src/postprocessing/postprocessing_ph.cpp create mode 100644 src/postprocessing/postprocessing_utils.cpp create mode 100644 src/postprocessing/postprocessing_utils_dcrdefs.cpp create mode 100644 src/preprocessing/ext_preprocess.cpp create mode 100644 src/preprocessing/preprocessing_ph.cpp create mode 100644 src/preprocessing/raw2image.cpp create mode 100644 src/preprocessing/subtract_black.cpp create mode 100644 src/tables/cameralist.cpp create mode 100644 src/tables/colorconst.cpp create mode 100644 src/tables/colordata.cpp create mode 100644 src/tables/wblists.cpp create mode 100644 src/utils/curves.cpp create mode 100644 src/utils/decoder_info.cpp create mode 100644 src/utils/init_close_utils.cpp create mode 100644 src/utils/open.cpp create mode 100644 src/utils/phaseone_processing.cpp create mode 100644 src/utils/read_utils.cpp create mode 100644 src/utils/thumb_utils.cpp create mode 100644 src/utils/utils_dcraw.cpp create mode 100644 src/utils/utils_libraw.cpp create mode 100644 src/write/apply_profile.cpp create mode 100644 src/write/file_write.cpp create mode 100644 src/write/tiff_writer.cpp create mode 100644 src/write/write_ph.cpp create mode 100644 src/x3f/x3f_parse_process.cpp create mode 100644 src/x3f/x3f_utils_patched.cpp create mode 100755 version.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..d01efd4b3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +BreakBeforeBraces: Allman +ColumnLimit: 120 +SortIncludes: false +TabWidth: 4 diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 000000000..89e8bc528 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,27 @@ + ** LibRaw: Raw images processing library ** + +Copyright (C) 2008-2021 LibRaw LLC (http://www.libraw.org, info@libraw.org) + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, +dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. +LibRaw do not use RESTRICTED code from dcraw.c + +LibRaw uses DCB demosaic and FBDD denoise licensed under BSD-like 3-clause license +DCB and FBDD are Copyright (C) 2010, Jacek Gozdz (cuniek@kft.umcs.lublin.pl) + +LibRaw uses X3F library to unpack Foveon Files, licensed BSD-style license +Copyright (c) 2010, Roland Karlsson (roland@proxel.se) +All rights reserved. + +LibRaw uses pieces of code from Adobe DNG SDK 1.4, +Copyright (c) 2005 Adobe Systems Incorporated, licensed under MIT license + diff --git a/Changelog.txt b/Changelog.txt new file mode 100644 index 000000000..7534563b6 --- /dev/null +++ b/Changelog.txt @@ -0,0 +1,2744 @@ +2023-01-05 Alex Tutubalin + LibRaw 0.21.1-Release + * fixed typo in panasonic metadata parser + +2022-12-18 Alex Tutubalin + LibRaw 0.21-Release + + * Multiple fixes inspired by oss-fuzz project + +2022-07-01 Alex Tutubalin + + LibRaw 0.21-Beta1 + + == Camera format support == + * Phase One/Leaf IIQ-S v2 support + * Canon CR3 filmrolls + * Canon CRM (movie) files + * Tiled bit-packed (and 16-bit unpacked) DNGs + * (non-standard) Deflate-compressed integer DNG files are allowed + +== Camera support == + + * Canon EOS R3, R7 and R10 + * Fujifilm X-H2S, X-T30 II + * OM System OM-1 + * Leica M11 + * Sony A7-IV (ILCE-7M4) + * DJI Mavic 3 + * Nikon Z9: standard compression formats only + + == Multiple (resolution) thumbnails support == + + * New imgdata.thumbs_list data item with data fields: + + int thumbcount: thumbnail count + libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT]: list of thumbnails + + libraw_thumbnail_item_t fields: + + enum LibRaw_internal_thumbnail_formats tformat: internal thumbnail format + (this is not PPM/JPEG, but internal type related to thumbnail reading/unpacking method) + + ushort twidth, theight: thumbnail image size. + + ushort tflip: image rotation (see notes below) + + unsigned tlength: on-disk data size (not uncompressed for compressed formats) + + unsigned tmisc: bit depth and channel count: (color << 5) | bitsperpixel + + INT64 toffset: Thumbnail data offset in file + + Notes: + - Only TIFF-based and CR3 files are parsed for thumbnail list, other formats will have + thumbcount = 1 (or 0 if no thumbnail found in file). + + - Thumbnail image size may be unknown (not recorded in metadata), in this case twidth and theight are zero. + Usually small(er) thumbnails will always have twidth/theight filled, while largest one may have these fields set to zero. + + - Thumbnail rotation (tflip) is filled only for TIFF-based RAWs (if Orientation tag is not present in IFD, default zero value is used) + For non-tiff images, tflip is initialized to 0xffff (not known...) + + - There is no code to select thumbnail based on some criteria (e.g. minimal resolution), it is left to user to implement such a criteria, if needed + (see unpack_thumb_ex() call below) + + - If you want to get largest possible thumbnail: just use old unpack_thumb() call to get it. + + * new API call: LibRaw::unpack_thumb_ex(int i): + Unpacks i-th thumbnail if it exists into imgdata.thumbnail structure + i should be non-zero and less then imgdata.thumbs_list.thumbcount. + + * samples/simple_dcraw.cpp: new -E command line switch to extract all thumbnails from input file(s) + + == (Experimental) RawSpeed "version 3" (develop branch) support. == + + Build with -DUSE_RAWSPEED3, see details in RawSpeed3/README.md + + LibRaw::capabilities will set bit LIBRAW_CAPS_RAWSPEED3 if compiled w/ + RawSpeed-v3 support + + If file was processed (or tried to process) via RawSpeed-v3, these bits + are raised in imgdata.process_warnings: + LIBRAW_WARN_RAWSPEED3_PROCESSED - processed via RawSpeed v3 + LIBRAW_WARN_RAWSPEED3_PROBLEM - not processed (due to exception in RawSpeed library) + LIBRAW_WARN_RAWSPEED3_UNSUPPORTED - unsupported file + LIBRAW_WARN_RAWSPEED3_NOTLISTED - file not listed in cameras.xml data + + RawSpeed-v3 support is controlled via libraw_decoder_info.t->flags + (LIBRAW_DECODER_TRYRAWSPEED3 bit). + The bit is set for: + - lossless jpeg decoder + - Canon sRAW decoder + - lossless compressed and packed-compressed DNG decoders + - Pentax decoder + - Nikon (compressed) decoder + - Phase One Compressed and Hasselblad/Compressed decoders + - bitpacked decoder + - Panasonic (old 12-bit compression) decoder + - Olympus decoder + - Sony ARW (v1 and v2) decoders + - Samsung (version 1) decoder + + * (Experimental) Fine control of RawSpeed version selection/use. + To enable, build LibRaw with -DUSE_RAWSPEED_BITS + LibRaw::capabilities will set bit LIBRAW_CAPS_RAWSPEED_BITS if compiled + with this flag. + If enabled: + imgdata.rawparams.use_rawspeed becomes bit-field (instead of 0/1 off/on) + with bits: + LIBRAW_RAWSPEEDV1_USE - use RawSpeed Version 1 (if compiled with) + LIBRAW_RAWSPEEDV1_FAILONUNKNOWN - do not process unknown files + (not listed in RawSpeed v1 camera definitions file) + LIBRAW_RAWSPEEDV1_IGNOREERRORS - ignore mirror decoding errors (out of range data,etc) + + LIBRAW_RAWSPEEDV3_USE - Use RawSpeed Version 3 (if compiled with) + LIBRAW_RAWSPEEDV3_FAILONUNKNOWN - do not process unknown files + LIBRAW_RAWSPEEDV3_IGNOREERRORS - ignore minor decoding errors + + == Misc changes/improvements == + * New compile time define LIBRAW_OWN_SWAB + to use on platforms without swab() in C/C++ runtime + + * New imgdata.rawparams.options bit: LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION + If set: image orientation is set based on TIFF/IFD0:Orientation tag, + makernotes orientation data is ignored + + * Nikon makernotes: read NEFCompression tag for HE/HE* files + + * Nikon orientation tag: more fixed offsets for known cameras + + * Adobe DNG SDK 1.6 support (meaning, just an additional patch for GPR SDK) + + * removed LibRaw::memerr(), memory allocation failures are already handled + in LibRaw_memmgr::*alloc w/ exception thrown + + * removed memory error callback, out-of-memory error should be handled via + returned error code check, all related parameters (e.g. LibRaw constructor + option to not set such callback) is also removed + + * imgdata.params.adjust_maximum_thr is settable via C-API libraw_set_adjust_maximum_thr(..) + + * New rawoptions/processing flags for DNG processing if compiled + with Adobe DNG SDK: + LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT,LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT + If these flag(s) are set: Stage2/Stage3 processing will be performed + only if OpcodeList2/OpcodeList3 tags are present in the input DNG file + Old (hard) flags (LIBRAW_RAWOPTIONS_DNG_STAGE2 and + LIBRAW_RAWOPTIONS_DNG_STAGE3) are not removed and will force Stage2/3 + processing if set (regardless of input file tags) + + * New imgdata.rawparams.options bit: LIBRAW_RAWOPTIONS_DNG_ADD_MASKS + If set: DNG Transparency Masks will be extracted (if selected via shot_select) + + * New decoder flag: LIBRAW_DECODER_UNSUPPORTED_FORMAT + + == Bugs fixed == + + * Fixed possible out-of-buffer read in Nikon orientation tag parser + + * Windows datastream: fixed logic errors (not showing up in real life) + + * Out-of-range read-only array access in postprocessing if output_color is set to 0 (raw color) + + * Minolta Z2 was not recognized correctly on 32-bit systems + + * Fixed possible buffer overflow in Kodak C330 decoder + + * dcraw_process(): check for buffer allocation results to avoid NULL deref + +2021-10-11 Alex Tutubalin + * Camera support: + Apple iPhone 13 Pro + GoPro HERO10 (if compiled w/ USE_GPR_SDK) + Ricoh GR III + Sony Xperia 1 III + + * Fuji RAF files: XMP block extraction + + * Fixed a typo in LIBRAW_OPTIONS_* flag names + (was LIBRAW_OPIONS, old flags names not removed due to compatibility) + + * samples/raw-identify.cpp: -v flag documented in usage print. + +2021-09-14 Alex Tutubalin + * Camera support: + Fujifilm GFX 50S II + Nikon Z fc + Sony A7R-IIIA (ILCE-7RM3A), A7R-IVA (ILCE-7RM4A) + + * API/datastruct Changes: + - imgdata.params.shot_select moved to imgdata.rawparams.shot_select + (because this is decode-time option, not postprocessing option) + + - libraw_open_bayer(...) added to C-API + + - imgdata.makernotes.canon: separate SensorLeftBorder,SensorTopBorder.... + (and many other datafields) are united in libraw_area_t (rectangle) + groups for crop areas and optical black areas. + + * src/libraw_cxx.cpp completely removed from source tree to not confuse users. + (also all mentions are removed from Makefiles) + + * Better Olympus makernotes parsing: LiveND mode, Panorama mode tags. + + * clang-cl compatibility: + - defines _MSC_VER, but _forceinline is not supported + - warnings eliminated in Windows buffered datastream + + * Canon/12-bit files: adjust color.linear_max and makernotes.canon values + to match data range. + +2021-08-04 Alex Tutubalin + * Camera support: + Sony ZV-E10 + * DNG/Floating point: additional metadata check to refuse ambiguous/corrupted files. + * DNG/Floating point: correct handling of striped files (never seen in wild) + * Rawspeed support: disallow Nikon D6/Compressed processing + * Bug fixed: raw_inset_crops[] ctop/cheight was not adjusted right if vendor-specified + ctop equals to 1. + +2021-07-20 Alex Tutubalin + * Camera support: + Olympus E-P7 + +2021-07-08 Alex Tutubalin + * Camera support: + Panasonic GH5 Mark II + Pentax K3 Mark III + several phones w/ DNG files (checked) + + * Camera format support: Panasonic v6/12 bit + * Compile-time raw size limits implemented: + LIBRAW_MAX_NONDNG_RAW_FILE_SIZE - max file size for non-DNG files (default: 2GB - 1 byte) + LIBRAW_MAX_DNG_RAW_FILE_SIZE - max DNG file size limit (4GB-1 if compiled w/ DNG SDK, 2GB-1 otherwise) + + * ACES output: color conversion changed to provide D65 white point + + * Fix for Canon 5D Mark II/sRAW1 incorrect camera provided crop + +2021-05-07 Alex Tutubalin + * Camera support: + Fujifilm GFX 100S, X-E4: improved color data + Canon EOS M50 Mark II was supported but not listed in camera list + DJI Mavic Air 2S + GOPRO Hero9 + * Support for RaspberryPi HQ camera (if compiled w/ USE_6BY9RPI) + * Improved support for RPi V1/V2 cameras: + - white balance data extraction + - color matrix extracted to imgdata.color.cmatrix to use with + use_camera_matrix. + - full-size thumbnail/preview support for JPEG+RAW files (raspistill -r) + * Fuji GFX100/GFX100S: PixelShift metadata extraction. + * RawSpeed (master): fixed bug in old Samsung/compressed decoder, + apply this patch to RawSpeed: RawSpeed/rawspeed.samsung-decoder.patch + * DCI-P3 and Rec 2020 output colorspaces + * Eliminated multiple signed/unsigned mismatch warnings (reported by gcc11) + * fixed possible 1-byte stack underrun while handling text tags with zero length + * XMP block size in CR3 files limited to 1MB + * Preview block size in CR3 files limited to 100MB + * Fixed wrong handling of linear DNG files created from Pentax out-of-camera + DNGs + +2021-02-18 Alex Tutubalin + * Improved Phase One Compressed defects masking, thanks to Alexey Danilchenko + * Sony ILCE-1/Lossless compressed support + +2021-02-16 Alex Tutubalin + * Additional fields in libraw_internal_data.unpacker_data: + - INT64: exif_offset: base offset of 1st EXIF IFD in file + - INT64: ifd0_offset: base offset of 1st TIFF IFD (IFD0) in file + - unsigned cr3_exif_length, cr3_ifd0_lenght : CR3-specific length of + exif and ifd0 sections. + +2021-02-08 Alex Tutubalin + * CRX (CR3) decoder: fixed typo in constant; this does not affect any + known still photo (CR3) sample(s), but allows to use the decoder with + some video (CRM) files. + + * Imported user-contributed improvements to OpenMP postprocessing + (AHD and X-Trans demosaic) + + * Bugfix: overwrite (wrong) TIFF/Orientation tag value with Metadata/Camera Orientation + value for EOS 40D only. + +2021-02-04 Alex Tutubalin + * imgdata.sizes.raw_inset_crop rearranged: + now it is imgdata.sizes.raw_inset_crops[2]: + - item at [0] is the same as imgdatra.sizes.raw_inset_crop in previous + versions + - item at [1] is 'user crop', in particular: + -- set by DNG DefaultUserCrop tag + -- or set via raw aspect ratio tags (e.g. 16:9 aspect on Fujifilm cameras) + raw_inset_crops[1] is filled only if aspect ratio tags provides different + aspect ratio compared to raw_inset_crops[0]. + + There are no flags to check if raw_inset_crops[Nth] is filled; to see if it is filled check + the values of: + ctop/cleft < 0xffff (0xffff => standard values if not initialized) + ctop+cheight <= sizes.raw_height + cleft+cwidth <= sizes.raw_width + + Note: raw_inset_crops may be fooled by metadata (makernotes), use some correctness check before use. + + * LIBRAW_RAWOPTIONS_USE_DNG_DEFAULT_CROP processing flag removed, + DNG DefaultCrop* tags are parsed into raw_inset_crops[0] + + * new LibRaw call LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop = 0.55f) + Promotes imgdata.sizes.raw_inset_crops[] values to + imgdata.sizes.*margin and imgdata.sizes.width/height fields + + mask: if bit 1 is set: prefer raw_inset_crops[1] + if bit 0 is set: prefer raw_inset_crops[0] + + maxcrop: limits crop to not less than (original width/height)*maxcrop; if raw_inset_crops[i] + data results in tighter crop, than this item is ignored. + + return value: index in raw_inset_crops[] used increased by one, so + 0: no changes made + 1: [0]th data used + 2: [1]th data used + + Note: this call SHOULD be used after LibRaw::unpack(), otherwise black level + calculation from masked area may be fooled resulting in wrong black levels. + +2021-01-21 Alex Tutubalin + + == LibRaw snapshot 202101 == + + = Camera format support: = + Lossy compressed CR3 files + Lossy compressed RAF files + Uncompressed floating point DNG files (16-24-32 bit) + Deflate compressed striped DNG files + XMP and HEIF-preview extraction from CR3 files + + = Camera support = + Apple iPhone 12 Max, iPhone 12 Max Pro + Canon EOS R5, EOS R6, EOS 850D, EOS-1D X Mark III (lossy compressed files) + FujiFilm X-S10 + Hasselblad CFV II 50C", + Leica M10-R, Q2 Monochrom, S3, SL2-S + Nikon Z 5, Z 6 II, Z 7 II + Olympus E-M10 Mark IV + Panasonic DC-G100 / G110, DC-S5 + Sony ILCE-7C (A7C), ILCE-7SM3 (A7S III) + Zeiss ZX1 + Plus multiple DNG-recording cameraphones/drones/etc. + + = Almost dropped camera support: = + Old/partially supported video/cinema cameras support is available only if + LibRaw is compiled with USE_OLD_VIDEOCAMS defined (this #define is + converted internally to LIBRAW_OLD_VIDEO_SUPPORT defined). + This affects: + Arri cameras + Canon C500 + RED Cine cameras + We plan to keep the support in LibRaw 0.21 (if compiled with define + mentioned above) and completely drop the support after 0.21. + If you're using LibRaw to decode RED Cine files, see LibRaw*datastreams + section below (in short: you'll need to use old fstream-based datastream + under Windows). + Cinema DNG files are not affected by this. + + = API/ABI changes = + + * Decoding parameters + imgdata.params is split into + imgdata.rawparams: parameters used for metadata/raw data decoding + imgdata.params: parameters used at postprocessing stage + + imgdata.params.raw_processing options are split into two sub-options sets + imgdata.rawparams.options: raw processing flags, useful for normal + operations + imgdata.rawparams.specials: special modes (e.g decoding only delta + pixels from Sony ARW) + + Old LIBRAW_PROCESSING_* flags are renamed to LIBRAW_RAWOPTIONS_* and + LIBRAW_RAWSPECIAL* + LIBRAW_PROCESSING_DP2Q_INTERPOLATE... flags are renamed to + LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATE with inverted meaning (with the + goal to have zero imgdata.rawparams.specials in normal use). + + * New processing flag LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB + If set (default is not), and when applicable, color.cam_mul[] and + color.WB_Coeffs/WBCT_Coeffs will contain WB settings for a + non-standard workflow. + Right now only Sony DSC-F828 is affected: camera-recorded white balance + can't be directly applied to raw data because WB is for RGB, while raw + data is RGBE. + + * New processing flag: LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT + If set (default is not), LibRaw::dcraw_process() will fallback to + daylight WB (excluding some very specific cases like Canon D30). + This is how LibRaw 0.19 (and older) works. + If not set: LibRaw::dcraw_process() will fallback to calculated auto WB if + camera WB is requested, but appropriate white balance was not found in + metadata. + + * Removed LIBRAW_PROCESSING_SKIP_MAKERNOTES processing flag: with new + Windows(-handle) datastreams metadata parsing performance is enough + to not skip makernotes parsing. + + * new output parameter: imgdata.params.output_flags and new + enum LibRaw_output_flags + Right now the only flag is implemented: LIBRAW_OUTPUT_FLAGS_PPMMETA + setting it will result into metadata written to PPM/PGM output file + + * LibRaw_*datastreams change and corresponding open_file() parameters change + LibRaw_file_datastream (based on iostreams) is moved under + #ifdef LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM + Standard datastreams are: + LibRaw_bigfile_datastream (FILE* based) for POSIX systems + LibRaw_bigfile_buffered_datastream - for use with Win32 syscalls + API changes: + if LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM is NOT defined, than + LibRaw::open_file() and similar calls drops the last INT64 max_buffered_sz + parameter which defines automatic selection between iostreams and + FILE* based datasteams. + + Note: LibRaw_bigfile_buffered_datastream does NOT implements + make_jas_stream() call, so RED Cine file decoding is not possible with + this datastream. Use deprecaded iostreams implementation instead. + + We plan to keep LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM up to + LibRaw 0.21 and drop in 0.22. + + * Fuji decoder: + fuji_decode_loop/fuji_decode_strip parameters has changed; look into source + code for details if you're implementing your own fuji_decode_loop() + call in subclass to provide parallel fuji decoding. + + * Canon CR3 H265 (HEIF) preview limited support: + - new format value: LIBRAW_THUMBNAIL_H265 + - this thumbnail is NOT extracted by LibRaw::make_mem_thumb() yet; + + * LibRaw::capabilities + Two bits added: + LIBRAW_CAPS_ZLIB if compiled with USE_ZLIB + LIBRAW_CAPS_JPEG if compiled with USE_JPEG + + + * Windows datastreams: CreateFile2 is used if compiled for UWP. + + * API-datastruct: clarified behavior with use_camera_wb=1 setting. + + * identify(): restored the differentiation between fsize and flen. + + * New compile-time LIBRAW_FORCE_OPENMP to skip compiler version check + (if LibRaw user is absolutely sure that OpenMP is supported by compiler) + +2020-10-14 Alex Tutubalin + + * LibRaw 0.20.2 + Reverted 0.20.1 change: + - const buffer for open_buffer() and open_bayer() calls + Because of 0.20.0 ABI break + +2020-10-14 Alex Tutubalin + + * LibRaw 0.20.1 + * Improvements: + - exif callback is called on EXIF GPS and EXIF Interop IFDs + - open_bayer call documented + - Canon (ColorDatsSubver==32): parse Specular White instead of hardcoded value + * Fixes for normal files processing: + - Olympus XZ-1: do not provide linear_max (it is wrong in metadata) + - Nikon Z cameras: added space in camera list + - raw-identify: fixed wb-preset print + - Pentax Optio 33WR: maker index was incorrect + - dcraw_emu: corrected help line for -6 option. + - raw-identify: corrected range check for color matrices print + - use_camera_matrix option: fixed a bug introduced when making + compiler more happy. + + * Fixes for damaged/special crafted files processing: + - Fix for truncated CR3 files parsing + - DNG metadata merger: all color loops are limited to MIN(4,colors) + - Check for marings: should be less than raw image size + - Check for xmpdata present in Samsung Lens ID assignment + - Check for column range in leaf_hdr decoder + - Additional checks in Hasselblad model parser + - Fuji rotate: better limits check + - DNG files: limit tiff_samples + + * Not fixes, but makes ASAN/compilers/etc happy: + - corrected GPS EXIF output + - const buffer for open_buffer() and open_bayer() calls + + +2020-07-23 Alex Tutubalin + + * LibRaw 0.20 + +== Camera Format support == + Canon CR3 + GoPro (via GPR SDK) + Panasonic 14-bit + Fujifilm compressed/16bit + Rapsberry Pi RAW+JPEG format (if USE_6BY9RPI defined) + Foveon X3F support changed: it is supported only if USE_X3FTOOLS defined + at build (see below for 'Imported code policy changed') + +== Camera support (+59, 1131 total) == + Canon: PowerShot G5 X Mark II, G7 X Mark III, SX70 HS, + EOS R, EOS RP, EOS 90D, EOS 250D, EOS M6 Mark II, EOS M50, EOS M200 + EOS 1DX Mark III (lossless files only) + DJI Mavic Air, Osmo Action + FujiFilm GFX 100, X-A7, X-Pro3, X100V, X-T4 (uncompressed/lossless compressed only), X-T200 + GoPro Fusion, HERO5, HERO6, HERO7, HERO8 + Hasselblad L1D-20c, X1D II 50C + Leica D-LUX7, Q-P, Q2, V-LUX5, C-Lux / CAM-DC25, SL2, M10 Monochrom + Nikon D780, Z50, P950 + Olympus TG-6, E-M5 Mark III, E-PL10, E-M1 Mark III, + Panasonic DC-FZ1000 II, DC-G90, DC-S1, DC-S1R, DC-S1H, DC-TZ95 + PhaseOne IQ4 150MP + Ricoh GR III + Sony A7R IV, A9 II, ILCE-6100, ILCE-6600, RX0 II, RX100 VII + Zenit M + +also multiple smartphones (the tested ones are listed in LibRaw::cameraList) + +== Source code re-arranged == + * dcraw.c is not used in the generation and build processes + * dcraw_common.cpp and libraw_cxx.cpp are split into multiple code chunks + placed in separate subfolders (decoders/ for raw data decoders, + metadata/ for metadata parsers, etc) + * dcraw_common.cpp and libraw_cxx.cpp remain to preserve existing + build environments (these files are now just a bunch of #include directives). + * It is possible to build LibRaw + a)without postprocessing functions (dcraw_process() and called function) + b)without postprocessing and LibRaw::raw2image() call (and called function). + It may be useful to reduce library memory/code footprint. + See Makefile.devel.nopp and Makefile.devel.noppr2i for the list of source + files needed to build reduced/stripped library. + +== Normalized make/model == + +There is a huge number of identical cameras sold under different names, +depending on the market (e.g. multiple Panasonic or Canon models) +and even some identical cameras sold under different brands +(Panasonic -> Leica, Sony -> Hasselblad). + +To reduce clutter, a normalization mechanism has been implemented in LibRaw: + +In imgdata.idata: + char normalized_make[64]; - primary vendor name (e.g. Panasonic for + Leica re-branded cameras) + char normalized_model[64]; - primary camera model name + unsigned maker_index; - primary vendor name in indexed form (enum + LibRaw_cameramaker_index, LIBRAW_CAMERAMAKER_* constant). +These fields are always filled upon LibRaw::open_file()/open_buffer() calls. + +const char* LibRaw::cameramakeridx2maker(int index): converts maker_index +to normalized_make. + +We recommend that you use these normalized names in a variety of data tables +(color profiles, etc.) to reduce the number of duplicate entries. + +New vendor index values will be added strictly to the end of the +LibRaw_cameramaker_index table, ensuring that the numbers assigned to +vendors that are already known to LibRaw will not change. + +== DNG frame selection == + + DNG frames selection code re-worked: + - by default all frames w/ the NewSubfileType tag equal to 0 + (high-res image) are added to the list of available images (selection + performed via imgdata.params.shot_select field, as usual) + - the special case for Fuju SuperCCD (SamplesPerPixel == 2) works as + before: shot_select=1 will extract second sub-image. + - Additional flags to imgdata.params.raw_processing_options: + LIBRAW_PROCESSING_DNG_ADD_ENHANCED - will add Enhanced DNG frame + (NewSubfileType == 16) to the list of available frames + LIBRAW_PROCESSING_DNG_ADD_PREVIEWS - will add previews + (NewSubfileType == 1) to the list. + + - By default, DNG frames are not reordered and are available in same order + as in DNG (LibRaw traverses IFD/Sub-IFD trees in deep-first order). + To prioritize the largest image, set LIBRAW_PROCESSING_DNG_PREFER_LARGEST_IMAGE + bit in imgdata.params.raw_processing_options. + + - DNG Stage2/Stage3 processing via DNG SDK (request via flags in + raw_processing_options) + +== Imported code policy disclaimer == + + We've changed the policy regarding 3rd party code imported into LibRaw. + + We (like other authors of open-source RAW parsers) gladly import support + code for various RAW formats from other projects (if the license allows it). + This is done to expand camera support. + Unfortunately, not all imported code can tolerate truncated or otherwise + damaged raw files, as well as arbitrary conditions or arbitrary data; + not all authors handle rejecting unexpected input well. + + LibRaw is now widely used in various projects, including ImageMagick, which, + in turn, is often used on web sites to process any input images, including + arbitrary data from unknown users. + This opens up wide possibilities for exploiting the various vulnerabilities + present in the code borrowed from other projects into LibRaw. In order to + avoid such security risks, - the borrowed code will no longer compile + by default. + We are not able to support it in general case, and the authors refuse + to add code to reject unexpected input. + + Thus, if you use some kind of camera for which the support is disabled + by default, you need to recompile LibRaw for your specific case. + + Formats currently affected: + X3F (Foveon) file format. + Code is imported from Kalpanika X3F tools: https://github.com/Kalpanika/x3f + To turn the support on, define USE_X3FTOOLS + + Rapsberry Pi RAW+JPEG format. + Code is imported from https://github.com/6by9/dcraw/, + To turn the support on, define USE_6BY9RPI + Format support is indicated via LibRaw::capabilities() call with flags: + LIBRAW_CAPS_X3FTOOLS - Foveon support + LIBRAW_CAPS_RPI6BY9 - RPi RAW+JPEG support + +== GoPro .gpr format support == + GoPro format supported via open-source GPR SDK + See README.GoPro.txt for details. + +== Windows support/Windows unicode (wchar_t*) filenames support == + +* (old) LibRaw's WIN32 external define split into 3 defines to fine tune + compiler/api compatibility: + LIBRAW_WIN32_DLLDEFS - use to compile DLLs (__dllimport/__dllexport attributes) + LIBRAW_WIN32_UNICODEPATHS - indicates that runtime has calls/datatypes for wchar_t filenames + LIBRAW_WIN32_CALLS - use Win32 calls where appropriative (binary mode for files, LibRaw_windows_datastream, _snprintf instead of snprintf, etc). + + If the (old) WIN32 macro is defined at compile time, all three new defines are defined in libraw.h + If not, these defines are defined based on compiler version/libc++ defines + +* LibRaw::open_file(wchar_t*) is always compiled in under Windows, but + if LIBRAW_WIN32_UNICODEPATHS (see above) is not defined, this call will + return LIBRAW_NOT_IMPLEMENTED. + Use (LibRaw::capabilities() & LIBRAW_CAPS_UNICODEPATHS) on runtime + to check that this call was really implemented (or check for #ifdef LIBRAW_WIN32_UNICODEPATHS after #include ) + +== LibRaw*datastream simplified == + + * tempbuffer_open, subfile_open are not used, so removed from + LibRaw_abstract_datastream and derived classes. + + * jpeg_src() call implemented using ->read() call and own buffering + (16k buffer). + * buffering_off() call added. It should be used in derived classes + to switch from buffered reads to unbuffered. + +== minor/unsorted changes == + * new flag LIBRAW_WARN_DNGSDK_PROCESSED to indicate decoder used + * LibRaw::open() call, max_buf_size special meaning: + == 1 => open using bigfile_datastream + == 2 => open using file_datastream + * Add support for zlib during configure + * Fixed multiple problems found by OSS-Fuzz + * Lots of changes in imgdata.makernotes (hope someone will document it) + * DNG SDK could be used (if enabled) to unpack multi-image DNG files. + * DNG whitelevel calculated via BitsPerSample if not set via tags. + * DNG: support for LinearDNG w/ BlackLevelRepeat.. pattern + * Generic Arri camera format replaced w/ list of specific camera models in supported cameras list. + * new samples/rawtextdump sample: allows one to dump (small selection) of RAW data in text format. + * samples/raw-identify: + * +M/-M params (same as in dcraw_emu) + * -L parameter to get file list from a file + * -m paramerer to use mmap'ed IO. + * -t parameter for timing + * samples/dcraw_emu: fixed +M handling + * better support for Nikon Coolscan 16-bit NEF files. + * Visual Studio project files: re-generated to .vcxproj (Visual Studio 2019), different + intermediate folders for different sub-projects to allow 1-step rebuild. + * imgdata.makernotes...cameraspecific: removed the vendor name prefix from variables. + * Bayer images: ensure that even margins have the same COLOR() for both the active sensor area and the full sensor area. + * raw processing flag bit LIBRAW_PROCESSING_CHECK_DNG_ILLUMINANT inverted and renamed to + LIBRAW_PROCESSING_DONT_CHECK_DNG_ILLUMINANT. If not set, DNG illuminant will be checked. + * New libraw_decoder_t flags: + LIBRAW_DECODER_FLATDATA - in-file data could be used as is (if byte order matches), e.g. via mmap() + LIBRAW_DECODER_FLAT_BG2_SWAPPED - special flag for Sony ARQ: indicates R-G-G2-B channel + order in 4-color data + * Camera-recorded image crop data is parsed into imgdata.sizes.raw_inset_crop structure: + ctop,cleft,cwidth,cheight - crop size. + aspect - LibRawImageAspects enum (3to2, 4to3, etc) + * New define LIBRAW_NO_WINSOCK2 to not include winsock2.h on compile + + * New processing flag LIBRAW_PROCESSING_PROVIDE_NONSTANDARD_WB + If set (default is not), and when applicable, color.cam_mul[] and + color.WB_Coeffs/WBCT_Coeffs will contain WB settings for a non-standard + workflow. + Right now only Sony DSC-F828 is affected: camera-recorded white balance + can't be directly applied to raw data because WB is for RGB, while raw + data is RGBE. + + * New processing flag: LIBRAW_PROCESSING_CAMERAWB_FALLBACK_TO_DAYLIGHT + If set (default is not), LibRaw::dcraw_process() will fallback to + daylight WB (excluding some very specific cases like Canon D30). + This is how LibRaw 0.19 (and older) works. + If not set: LibRaw::dcraw_process() will fallback to calculated auto WB if + camera WB is requested, but appropriate white balance was not found in + metadata. + + * Google changes cherry-picked (thanks to Jamie Pinheiro) + * speedup: ppg interpolate: const loop invariant + + * Bugs fixed + -Fixed several UBs found by OSS Fuzz + -Fixed several problems found by other fuzzers. + - Thumbnail size range check (CVE-2020-15503) + Thanks to Jennifer Gehrke of Recurity Labs GmbH for problem report. + - fixed possible overflows in canon and sigma makernotes parsers + - fixed possible buffer overrun in crx (cr3) decoder + - fixed memory leak in crx decoder (if compiled with LIBRAW_NO_CR3_MEMPOOL) + - fixed possible overrun in Sony SRF and SR2 metadata parsers + + * Fixed typo in longitude (member of parsed GPS structure), update required for code that uses it. + + +2019-03-05 Alex Tutubalin + * Camera support + Canon A560 (CHDK hack) + FujiFilm X-T30 + Nikon Coolpix A1000 + Olympus E-M1X + Sony ILCE-6400 + Several dng files from phones and drones was tested + and added to built-in camera list too. + + * Multiple names for same Panasonic cameras are processed via + aliaces mechanics, no multiple duplicate fields in adobe_coeffs() table + + * Better makernotes parsing for many cameras + + * Better parsing of makernotes embedded into DNG files created by + Adobe DNG Converter + + * New imgdata.params.raw_processing_options value: LIBRAW_PROCESSING_ZEROFILTERS_FOR_MONOCHROMETIFFS + - If this bit is set + - and TIFF file contains SamplesPerPixel == 1 + - and filters value was not guessed from metadata parsing + LibRaw will assume the file is monochrome, not bayer. + This option is needed for monochrome scan processing (Imacon X1 etc). + This option may broke old TIF-like RAW files processing (Kodak 760,etc) + use with care (it is better to let user choose). + +2018-12-12 Alex Tutubalin + * Camera support: + Canon: PowerShot A480 (CHDK hack), EOS 2000D, EOS 4000D + Eyedeas E1 + FujiFilm: GFX 50R, XF10, X-T3, X-T100, DBP680 + GITUP G3 DUO (16:9 mode only, use custom camera for 4:3) + Kodak PIXPRO AZ901 + Leica M10-D, M10-P + Nikon D3500, Z6, Z7, P1000 + Panasonic LX100M2 + Pentax K-1 II + Sony A7 III, HX95, HX99, RX100-VA, RX100-VI + + * Fixed long standing bug in remove_zeroes: first two rows/cols was unprocessed + * Better parsing for NEF files modified (damaged) by NikonTransfer + * Better parsing for floating point DNG black levels (into color.dnglevels.fblack and dng_fcblack[], similar + to color.black and color.cblack[] for other formats). + * More flexible limit for RAW decoding memory usage: + imgdata.params.max_raw_memory_mb (default is LIBRAW_MAX_ALLOC_MB_DEFAULT) + + * New flags for imgdata.params.raw_processing_options: + LIBRAW_PROCESSING_CHECK_DNG_ILLUMINANT - will check DNG illuminant field when selecting color matrix + (note: incompatibility with previous versions, so default is not set). + LIBRAW_PROCESSING_DNGSDK_ZEROCOPY - will not copy data from Adobe DNG SDK decoded buffer, but use it as is + + * Switched from auto_ptr to unique_ptr, to get back define LIBRAW_USE_AUTOPTR + + * dcraw_emu: it is now possible to create output filename in a more flexible manner, via -Z switch: + -Z - will output to stdout + -Z ext will output into inputfilename.ext + -Z .ext will output into inputfilename.inputext.ext + + +2018-11-22 Alex Tutubalin + * Finally: got Sinar 4shot sample, works fine now + * OpenMP critical sections for malloc/free; extra #ifdefs removed; bin/dcraw_dist could be built again using Makefile.devel + * additional checks in parse_phase_one() + * more checks on file offsets/tag len in parse_minolta + * more checks in parse_ciff + * Mempool check reworked + * Old Leaf (16bit/3color/TIFF) support + * Fix cameraWB->autoWB fallback + * Polaroid x530 channel swap; get metadata pointer for Foveon files + * Fixed Secunia Advisory SA86384 + - possible infinite loop in unpacked_load_raw() + - possible infinite loop in parse_rollei() + - possible infinite loop in parse_sinar_ia() + Credits: Laurent Delosieres, Secunia Research at Flexera + + * LibRaw 0.19.1-Release + +2018-06-28 Alex Tutubalin + * changed wrong fix for Canon D30 white balance + * fixed possible stack overrun while reading zero-sized strings + * fixed possible integer overflow + * LibRaw 0.19.0-Release + +2018-06-11 Alex Tutubalin + * Sony uncompressed/untiled DNGs: do not set bits-per-sample to 14 bit + * Do not change tiff_bps for DNG files + * Another possible stack overflow in kodak radc reader + * Secunia Advisory SA83507, credits Kasper Leigh Haabb, + Secunia Research at Flexera" + - parse_qt: possible integer overflow + - reject broken/crafted NOKIARAW files + * LibRaw 0.19-Beta6 + +2018-05-10 Alex Tutubalin + * Put rogue printf's behind #ifdef DCRAW_VERBOSE + * Exceptions was not caught in x3f_new_from_file resulting in x3f handle leak + * packed_load_raw(): EOF check on each row + * define LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC to use ::calloc instead of + ::malloc in LibRaw_mem_mgr malloc calls; + Note: realloc is not changed, so only partial fix + * Fixed possible div by zero in EOS D30 WB data parse + * U-suffix for filter-var manipulation consts + * restored static specifier for utf2char() lost in previous bugfix + * Fixed stack overrun in kodak_radc_load_raw + * Secunia Advisory SA83050: possible infinite loop in parse_minolta() + * LibRaw 0.19-Beta5 + +2018-05-03 Alex Tutubalin + * CVE-2018-10529 fixed: out of bounds read in X3F parser + * CVE-2018-10528 fixed: possible stack overrun in X3F parser + * LibRaw 0.19-Beta4 + +2018-04-24 Alex Tutubalin + * LibRaw 0.19-Beta3 + * fixed lot of bugs reported by ImageMagic/oss-fuzz + * fixed several bugs reported by Secunia team (adv 81800, + Credit: Laurent Delosieres, Secunia Research at Flexera) + +2018-03-22 Alex Tutubalin + * LibRaw 0.19-Beta2 + * Better handling of broken JPEG thumbnails + * Panasonic GH5S/G9-hires decoder, thanks to Alexey Danilchenko + Note: ABI has changed due to this patch, so shlib version increased + * Fujifilm X-A5/A20 metadata parsing fix + * New error code LIBRAW_TOO_BIG: image data size excess LIBRAW_MAX_ALLOC_MB + * winsock2 included before windows.h to make MinGW happy + +2018-02-23 Alex Tutubalin + + * LibRaw 0.19-Beta1 + + * 84 cameras added compared to 0.18 (1014 total): + Apple + iPhone 8(*), iPhone 8 plus, iPhone X + BlackMagic + URSA Mini 4k, URSA Mini 4.6k, URSA Mini Pro 4.6k + Canon CHDK hack + PowerShot A410, A540, D10, ELPH 130 IS, ELPH 160 IS, SD750, + SX100 IS,SX130 IS, SX160 IS, SX510 HS, SX10 IS, IXUS 900Ti + Canon + PowerShot G1 X Mark III, G9 X Mark II, EOS 6D Mark II, EOS 77D, + EOS 200D, EOS 800D, EOS M6, EOS M100 + Casio EX-ZR4100/5100 + DJI + Phantom4 Pro/Pro+, Zenmuse X5, Zenmuse X5R + FujiFilm + S6500fd, GFX 50S, X100f, X-A3, X-A5, X-A10, X-A20, X-E3, X-H1, X-T20 + GITUP GIT2P + Hasselblad + H6D-100c, A6D-100c + Huawei + P9 (EVA-L09/AL00), Honor6a, Honor9, Mate10 (BLA-L29) + Leica + CL, M10, TL2 + LG + V20 (F800K), VS995, + Nikon + D850, D5600, D7500, Coolpix B700 + Olympus + E-PL9, E-M10 Mark III, TG-5 + OnePlus + One, A3303, A5000 + Panasonic + DMC-FZ45, DMC-FZ72, DC-FZ80/82, DC-G9 (std. res mode only), DC-GF10/GF90, + DC-GH5, DC-GX9, DC-GX800/850/GF9, DMC-LX1, DC-ZS70 (DC-TZ90/91/92, DC-T93), + DC-TZ100/101/ZS100, DC-TZ200/ZS200 + PARROT + Bebop 2, Bebop Drone + Pentax KP + PhaseOne IQ3 100MP Trichromatic + Samsung + Galaxy Nexus, Galaxy S3, S6 (SM-G920F), S7, S7 Edge, S8 (SM-G950U), + Sony + A7R III, A9, DSC-RX0, DSC-RX10IV + Yi M1 + YUNEEC + CGO3, CGO3P + Xiaoyi YIAC3 (YI 4k) + + Note(*): for mobile phones with DNG format recording, only really tested cameras + are added to supported camera list. Really LibRaw should support any correct DNG. + + * No more built-in support for LibRaw demosaic packs (GPL2/GPL3). + We're unable to support this (very old code), so we'll be happy to transfer this + code to some maintainer who wish to work with it. + + In LibRaw 0.19 we provide extension API: user-settable callbacks to be called in + code points where demosaic pack code was called. + + - int callbacks.pre_identify_cb(void *) => to be called in LibRaw::open_datastream + before call to (standard) identify() function. If this call returns 1, this means + that RAW file is identified and all metadata fields are set, so no need to run + standard identify code. + - void callbacks.post_identify_cb(void*) => called just after identify(), but before + any cleanup code; + - dcraw_process() callbacks are called before dcraw_process phases (name speaks for itself): + pre_subtractblack_cb, pre_scalecolors_cb, pre_preinterpolate_cb, pre_interpolate_cb, + interpolate_bayer_cb, interpolate_xtrans_cb, post_interpolate_cb, pre_converttorgb_cb, + post_converttorgb_cb + + All these new callbacks are called with (this) as the only arg. + To continue LibRaw-demosaic-pack-GPLx support one need to subclass LibRaw, set needed + callbacks in (e.g.) constructor code, than these callbacks to be called + + * Better DNG parser: + - support for DefaultCrop Origin/Size tags (add LIBRAW_PROCESSING_USE_DNG_DEFAULT_CROP to raw_processing_options to enable) + - better parsing for nested DNG tags (use tag from RAW IFD, fallback to IFD0 if no tag in current IFD) + - DNG PreviewColorspace extracted into dng_levels.preview_colorspace + + * Metadata extraction: + - Better extraction of camera measured balance (LIBRAW_WBI_Auto and WBI_Measured), + this not the same as 'as shot' if some preset/manual tune is used. + - Extraction of camera custom balances (LIBRAW_WBI_CustomN) + - Nikon data compression tag extracted into makernotes.nikon.NEFCompression + - Hasselblad BaseISO and Gain extracted into makernotes.hasselblad + - Canon multishot params extracted into makernotes.canon.multishot + - lot of other vendor-specific makernotes data (see data structures definitions for details). + + * New LibRaw::open_bayer call allows to pass sensor dump w/o metadata directly to LibRaw: + virtual int open_bayer(unsigned char *data, unsigned datalen, + ushort _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, + ushort _right_margin, ushort _bottom_margin, + unsigned char procflags, unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, + unsigned black_level); + Parameters: + data, datalen - buffer passed + width/height/margins - speaks for itself + procflags: + for 10-bit format: + 1: "4 pixels in 5 bytes" packing is used + 0: "6 pixels in 8 bytes" packing is used + for 16-bit format: + 1: Big-endian data + bayer_pattern: one of LIBRAW_OPENBAYER_RGGB,LIBRAW_OPENBAYER_BGGR, + LIBRAW_OPENBAYER_GRBG,LIBRAW_OPENBAYER_GBRG + unused_bits: count of upper zero bits + otherflags: + Bit 1 - filter (average neighbors) for pixels with values of zero + Bits 2-4 - the orientation of the image (0=do not rotate, 3=180, 5=90CCW, 6=90CW) + black_level: file black level (it also may be specified via imgdata.params) + + see samples/openbayer_sample.cpp for usage sample (note, this sample is 'sample only', suited for + Kodak KAI-0340 sensor, you'll need change open_bayer() params for your data). + + * Color data added/updated/fixed for many cameras + + * Correct data maximum for Fuji X-* cameras + + * Thumbnail processing: + - JPEG thumbnails: if compiled with libjpeg, color count is extracted into imgdata.thumbnail.tcolors + - PPM (bitmap) thumbnails: color count is set according to thumbnail IFD tag + - PPM16 thumbnails: if LIBRAW_PROCESSING_USE_PPM16_THUMBS set in raw_processing_options, than thumbnail will be extracted + as is, not converted to 8 bit. thumbnail.tformat is set to LIBRAW_THUMBNAIL_BITMAP16 in this case. + Untested, because it is hard to find RAWs with 16-bit bitmaps. + +== Compatibility fixes + + * struct tiff_tag renamed to libraw_tiff_tag + * pow64f renamed to libraw_pow64f + +== Bugs fixed: + + * COLOR(r,c) works correctly on X-Trans files + +== Security fixes: +Secunia #81000: +Credit: Laurent Delosieres, Secunia Research at Flexera + * leaf_hdr_load_raw: check for image pointer for demosaiced raw + * NOKIARAW parser: check image dimensions readed from file + * quicktake_100_load_raw: check width/height limits + +Secunia #79000: +Credit: Laurent Delosieres, Secunia Research at Flexera + * All legacy (RGB raw) image loaders checks for imgdata.image is not NULL + * kodak_radc_load_raw: check image size before processing + * legacy memory allocator: allocate max(widh,raw_width)*max(height,raw_height) + +Secunia #76000: + * Fixed fuji_width handling if file is neither fuji nor DNG + * Fixed xtrans interpolate for broken xtrans pattern + * Fixed panasonic decoder + * LibRaw 0.18.6 + +Other fixes: + * Checks for width+left_margin/height+top_margin not larger than 64k + * LIBRAW_MAX_ALLOC_MB define limits maximum image/raw_image allocation + (default is 2048 so 2Gb per array) + * LibRaw::read_shorts item count is now unsigned + * Fixed possible out of bound access in Kodak 65000 loader + * CVE-2017-14348: Fix for possible heap overrun in Canon makernotes parser + Credit: Henri Salo from Nixu Corporation + * Fix for CVE-2017-13735 + * CVE-2017-14265: Additional check for X-Trans CFA pattern data + * Fixed several errors (Secunia advisory SA75000) + * ACES colorspace output option included in dcraw_emu help page + * Avoided possible 32-bit overflows in Sony metadata parser + * Phase One flat field code called even for half-size + + +2016-12-27 Alex Tutubalin + * Licensing changes: + - there is no 'LibRaw Software License 27032010' licensing anymore (and all signed + agreements have expired) + - LibRaw is now dual-licensed: LGPL 2.1 or CDDL 1.0 + + * Camera support (+87): + Apple: iPad Pro, iPhone SE, iPhone 6s, iPhone 6 plus, iPhone 7, iPhone 7 plus + BlackMagic Micro Cinema Camera, URSA, URSA Mini + Canon PowerShot G5 X, PowerShot G7 X Mark II, PowerShot G9 X, + IXUS 160 (CHDK hack), EOS 5D Mark IV, EOS 80D, EOS 1300D, EOS M10, EOS M5, + EOS-1D X Mark II + Casio EX-ZR4000/5000 + DXO One, + FujiFilm X-Pro2, X70, X-E2S, X-T2 + Gione E7 + GITUP GIT2 + Google Pixel,Pixel XL + Hasselblad X1D, True Zoom + HTC MyTouch 4G, One (A9), One (M9), 10 + Huawei P9 + Leica M (Typ 262), M-D (Typ 262), S (Typ 007), SL (Typ 601), X-U (Typ 113), TL + LG G3, G4 + Meizy MX4 + Nikon D5, D500, D3400 + Olympus E-PL8, E-M10 Mark II, Pen F, SH-3, E-M1-II + Panasonic DMC-G8/80/81/85, DMC-GX80/85, DMC-TZ80/81/85/ZS60, DMC-TZ100/101/ZS100,DMC-LX9/10/15, FZ2000/FZ2500 + Pentax K-1, K-3 II, K-70 + PhaseOne IQ3 100MP + RaspberryPi Camera, Camera V2 + Ricoh GR II + Samsung Galaxy S7, S7 Edge + Sigma sd Quattro + Sony A7S II, ILCA-68 (A68),ILCE-6300,DSC-RX1R II,DSC-RX10III, DSC-RX100V,ILCA-99M2 (A99-II), a6500 + IMX214, IMX219, IMX230, IMX298-mipi 16mp, IMX219-mipi 8mp, Xperia L + PtGrey GRAS-50S5C + YUNEEC CGO4 + Xiaomi MI3, RedMi Note3 Pro + + * Floating point DNG support: + - new data fields: + imgdata.rawdata.float_image - bayer float data + imgdata.rawdata.float3_image - 3-component float data + imgdata.rawdata.float4_image - 4-component float data + imgdata.color.fmaximum - float data maximum (calculated from real data, + rounded to 1.0 if below 1.0) + - new raw processing flag + LIBRAW_PROCESSING_CONVERTFLOAT_TO_INT - converts float data to 16-bit + integer immediately after decoding with default parameters + - new API Calls: + int LibRaw::is_floating_point() returns non-zero if RAW file contains + floating point data + int LibRaw::have_fpdata() returns non-zero if rawdata.float*_image is not + null (so FP data has been unpacked but not converted to integrer, see below). + LibRaw::convertFloatToInt(float dmin=4096.f, float dmax=32767.f, float dtarget = 16383.f) + converts float/float3/float4_image to raw_image/color3/color4_image with or without scaling: + - if both real data maximum and metadata maximum are within the range ( >= dmin && <=dmax), float + data is just converted to integer + - if data is out of the range given above, values are scaled so real data maximum becomes dtarget + - if data was rescaled (normalized), scale multiplier is stored in imgdata.color.fnorm + + * LibRaw can be built with Adobe DNG SDK support to decode exotic DNG formats (e.g. 8 bit). + See README.DNGSDK.txt for details + + * New API calls + unsigned LibRaw::capabilities and C-API libraw_capabilities() + allows developers to determine LibRaw compile flags at runtime. + Returns ORed bit fields: + LIBRAW_CAPS_RAWSPEED - LibRaw was compiled with RawSpeed Support + LIBRAW_CAPS_DNGSDK - LibRaw was compiled with Adobe DNG SDK + LIBRAW_CAPS_DEMOSAICSGPL2, LIBRAW_CAPS_DEMOSAICSGPL3 - LibRaw was compiled with demosaic packs (GPL2/GPL3) + + * More metadata parsed: + - White balance coefficients stored in the raw file are extracted into: + int imgdata.color.WBCoeffs[256][4] - array indexed by EXIF lightsource type + for example, WBCoeffs[21][..] contains coefficients for D65 lightsource + float imgdata.color.WBCT_Coeffs[64][5] contains white balance data specified + for given color temperature: WBCT_Coeffs[i][0] contains temperature value, + and [1]..[4] are WB coefficients. + - DNG analog balance, per-channel black/white level, and forward matrix + - vendor specific metadata stored in vendor-specific data structures + + * new C-API calls: + void libraw_set_user_mul(libraw_data_t *lr,int index, float val); + void libraw_set_ca_correction(libraw_data_t *lr,int ca_correc, float ca_red, float ca_blue); + void libraw_set_cfalinenoise(libraw_data_t *lr,int cfaline, float linenoise); + void libraw_set_wf_debanding(libraw_data_t *lr, int wf_debanding, float wfd0, float wfd1, float wfd2, float wfd3); + void libraw_set_interpolation_passes(libraw_data_t *lr,int passes); + + * Existing API changes: + imgdata.params fields (all very specific purpose): sony_arw2_options, sraw_ycc, and params.x3f_flags + replaced with single bit-field raw_processing_options + See LIBRAW_PROCESSING_* bits in documentation. + + * zlib library is optional + Use -DUSE_ZLIB to compile with zlib (to provide deflate DNG support) + * libjpeg version: jpeg_mem_src() is mandatory, so use libjpeg-turbo + or libjpeg 8+ + * Fixes in vng_interpolate to make modern compilers happy + * Fixed bug in Sony SR2 files black level + * DNG files with BlackLevel both in vendor makernotes and BlackLevel: + BlackLevel tag always takes precedence + * strlen replaced with strnlen in most cases, added local version of strnlen + * ChannelBlackLevel added to canon makernotes + * unpack_thumb() data size/offset check against file size + +2015-08-15 Alex Tutubalin + + * LibRaw 0.17 + + * Fixed dcraw.c ljpeg_start possibly buffer overrun + + * fixed several bugs detected by using American Fuzzy Lop + + * C-API extension to support 3DLut Creator + + * More metadata parsing/extraction: + - XMP packet extracted (if exists) + - DNG Color information parsed + - GPS data (partially) parsed + - EXIF/Makernotes parsed for used optics (for both RAW files and DNG converted by Adobe convertor). + + * Exif/Makernotes parser callback (called for each processed tag) + + * Sony ARW2.3 decoder: + - params.sony_arw2_hack removed, decoded data are always in 0...17k range (note the difference with dcraw!) + - Additional processing options for Sony lossy compression technical analysis. + + * Dcraw 9.26 imported (but some changes not approved because Libraw do it better) with some exceptions: + - no Pentax K3-II frame selection code + - no built-in JPEG decompressor + + * Many improvements in data decoding/processing: + - Correct decoding of black level values from metadata for many formats, LibRaw do not rely on hardcoded black levels. + + * 224 camera models added to supported camera list. + Some of them are new (released since LibRaw 0.16 come out), some was supported before, but missed from the list. + Added cameras are: + + Alcatel 5035D + BlackMagic Pocket Cinema Camera, Production Camera 4k + Canon PowerShot A550, A3300 IS, G1 X Mark II, G7 X, SD950, SX60 HS, EOS 7D Mark II, EOS 20Da, EOS 60Da, EOS 1200D, EOS-1D C, 5DS, 5DS R, 750D, 760D, M2, M3, G3 X + Casio EX-FC300S, EX-FC400S, EX-Z1080, EX-ZR700, EX-ZR710, EX-ZR750, EX-ZR800, EX-ZR850, EX-ZR1000, EX-ZR1100, ZR1200, ZR1300, EX-ZR1500, EX-100, EX-10 + Digital Bolex D16,D16M + DJI 4384x3288, + Epson R-D1s, R-D1x + FujiFilm E505,S1,S205EXR,HS10,HS11,HS22EXR,HS33EXR,HS35EXR,F505EXR,F605EXR,F775EXR,F900EXR,X100T,X30,X-T1,X-T1 Graphite Silver, XQ2, X-A2, X-T10 + Hasselblad H5D-60, H5D-50,H5D-50c,H5D-40,H4D-60,H4D-50,H4D-40,H4D-31,H3DII-22,H3DII-31,H3DII-39,H3DII-50,H3D-22,H3D-31,H3D-39,H2D-22,H2D-39,CF-22,CF-31,CF-39,Stellar II,HV + HTC UltraPixel + Imacon Ixpress 96, 96C, 384, 384C (single shot only),132C, 528C (single shot only) + ISG 2020x1520 + Ikonoskop A-Cam dII Panchromatic, A-Cam dII + Kinefinity KineMINI, KineRAW Mini, KineRAW S35 + Kodak DCS460D, S-1 + Leaf Credo 50 + Lenovo a820 + Leica Digital-Modul-R, D-Lux (Typ 109), M (Typ 240), Monochrom (Typ 240), M-E, M-P, R8, S, T (Typ 701), X (Typ 113), X2, X-E (Typ 102), V-Lux (Typ 114), Monochrom (Typ 246), Q + Matrix 4608x3288 + Nikon D4s, D600, D610, D750, D800, D800E, D810, D3300, D5500, Df, 1 J4, 1 S2, 1 V3, Coolpix P340, Coolscan NEF, D7200, 1 J5,D810A + Nokia 1200x1600 + Olympus E-450, E-600, E-PL6, E-PL7, E-M1, E-M10, E-M5 Mark II, SP565UZ, STYLUS1s, SH-2, TG-4, AIR-A01 + Panasonic DMC-CM1, DMC-FZ7, DMC-FZ70, DMC-FZ1000, DMC-GF7, DMC-GH4, AG-GH4, DMC-GM1s, DMC-GM5, DMC-LX100, DMC-TZ60/61/SZ40, DMC-TZ70, FZ300/330, GX8 + Pentax GR, K110D, K-01, K-S1, Q, QS-1, 645Z, K-S2, K3 II + PhaseOne IQ250, IQ260, IQ260 Achromatic, IQ280, Achromatic+, P 20+, P 21, P 25+, P 30+, P 40+ + Ricoh GXR MOUNT A12, GXR MOUNT A16 24-85mm F3.5-5.5, GXR, S10 24-72mm F2.5-4.4 VC, GXR, GR A12 50mm F2.5 MACRO, GXR, GR LENS A12 28mm F2.5, GXR, GXR P10 + Samsung GX-1L, NX1, NX5, NX1000, NX1100, NX30, NX300, NX300M, NX3000, NX mini, Galaxy S3, Galaxy Nexus, NX500 + Sigma dp1 Quattro, dp2 Quattro, dp3 Quattro, dp0 Quattro + Sinar eMotion 22, eMotion 54, eSpirit 65, eMotion 75, eVolution 75, Sinarback 54 + Sony A7 II, A7S, ILCA-77M2 (A77-II), ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1, DSC-RX100III, DSLR-A560, NEX-VG20, NEX-VG30, NEX-VG900, IMX135-mipi 13mp, IMX135-QCOM, IMX072-mipi, RX100-IV, A7R-II, RX10-II + + * Fujifilm F700/S20Pro second frame support + +2014-02-01 Alex Tutubalin + * Updated Oly E-M10 & Panasonic TZ60/61 color data + * Updated foveon SD9-14 white level + * Support for 1x1 BlackLevelRepeatDim + +2014-01-31 Alex Tutubalin + * imported dcraw 1.461: fixed error in BlackLevelDim handling + * Accurate work with pattern black-level (cblack[6+]) + * Support for Olympus E-M10 and Fujifilm X-T1 + * Adjusted possible maximum value for Sigma SD9 small raws + +2014-01-27 Alex Tutubalin + * dcraw 1.460: Nikon D3300, Panasonic DMC-TZ61, Sony ILCE-5000 +2014-01-25 Alex Tutubalin + * PhaseOne IQ250 support (both compressed and uncompressed) +2014-01-21 Alex Tutubalin + * imgdata.params.sony_arw2_hack removed. + It always on for ARW2-files. + * New imgdata.params.sony_arw2_options processing flags + Values: + LIBRAW_SONYARW2_NONE - normal processing + LIBRAW_SONYARW2_BASEONLY - BASE pixels outputeed, delta pixels set to 0 + LIBRAW_SONYARW2_DELTAONLY - Delta pixels written to raw data, base pixels zeroed + LIBRAW_SONYARW2_DELTAZEROBASE - Only deltas written without base offset + +2014-01-20 Alex Tutubalin + * Imported dcraw 9.20: + - Support for DNG BlackLevelRepeatDim tags + - imgdata.color.cblack[] holds variable BlackLevel for DNG files (up to ~4k values) + - imgdata.params.use_camera_matrix is now ON by default. Set it to 3 if you want + to force use of DNG embedded matrix. + - Tone curve for Canon RMF format supported + - Color data for Canon C500 + * Additional camera support: + Alcatel 5035D + DJI 4384x3288 + Fujifilm F900EXR + Kodak 12MP + Matrix 4608x3288 + Nokia 1200x1600 + Olympus E-PL6 + Panasonic DMC-FZ7 + +2014-01-17 Alex Tutubalin + * Camera support: + Added: Fujifilm XE2, XQ1 + Color data updated: Nikon D4 1 AW1/J3, Fuji X-M2 + Fixes: Nikon D610 visible image area, Canon A3300 bayer + pattern + * RawSpeed support: enabled processing for cameras, + unknown to RawSpeed + * Fixed error in LibRaw::unpack_thumb() + * little improve performance in my_strcasestr + * Fix compiler errors for VS2012/OpenMP + * Fixed typo which prevents to use Demosaic Pack GPL2 + * LibRaw 0.16.0-Release + +2013-11-15 Alex Tutubalin + * New cameras supported + Leica C, X VARIO + Nikon D5300, D610, Df, 1 AW1 + Nokia Lumia 1020, 1520 + Olympus STYLUS1 + Pentax K-3 + Sony RX10, A3000 (ILCE-3000), + * Color data updated: + Canon S120 + Nikon P7800, 1 J3 + Olympus E-M1 + * Corrected image visible area sizes + Canon G16 + Sigma pre-Merrill cameras: small and medium-sized RAWs + + * Better EXIF parsing: + - ISO values for new Nikon cameras (D4, D800) + - black level extraction for Nikon D5300 + - correct Olympus color data conversion + + * Better Visual Studio compatibility (esp. old versions) + * Cmake build: added ws2_32 library for MinGW builds + * LibRaw 0.16.0-Beta1 + +2013-10-22 Alex Tutubalin + * Support for new cameras: + Sony A7, A7R + Panasonic GM1 + + * Sony RX1R and RX100M2 color data updated. + + * Sony cameras model name is set by SonyModelID EXIF tag + + * Sony ARW2: black level and color matrix extracted from EXIF data + + * Samsung: black level and color matrix extracted from EXIF; + Camera multipliers are now extracted correctly even if black is not 0 + + * Better source compatibility with Mac OS X compilation + + * Better source compatibility with Win32 compilation + + * DNG without Compression tag assumed uncompressed + + * Better X3F-tools based Foveon support: + - new Foveon metadata parser based on X3F-tools. So, if LibRaw compiled + without demosaic-pack-GPL2, then no dcraw Foveon code used. + - Support for Medium resolution RAWs from DPx Merrill and SD1 cameras. + RAW data extracted as is (4800x1600 pixels), aspect ratio is set to + 0.5, so these RAWs are processed to full-size 4800x3200 RGB. + - Support for Foveon thumbnail extraction. Only JPEG and bitmap + thumbnails extracted, but 'foveon' (RAW) thumbnails are really not used + in production cameras. + - New imgdata.params.force_foveon_x3f flag + Forces use of x3f-tools based code for Foveon processing if LibRaw + compiled with demosaic-pack-GPL2 (and does nothing if LibRaw compiled + without this pack). + New flag -disadcf added to dcraw_emu sample to use this flag. + - LibRaw do not calls exit() on broken Foveon files. + + * API/ABI changed, so all code using LibRaw should be recompiled. + + * LibRaw 0.16.0-Alpha3 + + +2013-10-16 Alex Tutubalin + * Support for new cameras: + Canon S120 (preliminary color data), G16 + Fujifilm X-A1 (preliminary color data) + Hasselblad Lunar, Stellar + Nikon P7800 (preliminary color data) + Pentax K50, K500, Q7 + Samsung Galaxy NX (EK-GN120) + Sony NEX-5T + + * Updated color data for: + Samsung NX300 + Sony RX1R + Sigma SD1, SD1 Merrill, DPxx (only if non-GPL2 foveon decoder used) + + * Image dimensions table for Foveon cameras (only if + non-GPL2 foveon decoder used) + + * Fixed memory leak in x3f-tools code (new Foveon decoder) + * Fixed DHT-demosaic incompatibility with MS VisualStudio in OpenMP directives + * Additional image size checks. + * LibRaw 0.16-Alpha2 + +2013-09-22 Alex Tutubalin + * Support for new cameras: + Baumer TXG14 + Blackmagic Cinema + Canon EOS 70D, C500 + Fujifilm X-M1 + Nikon D5200 + Olympus E-P5,E-M1 + OmniVision OV5647 (Raspberry Pi) + Panasonic LF1, GX7, GF6 + Richon GR + Samsung NX300, NX1100, NX2000 + Sony RX100II, RX1R, NEX-3N + + * Support for Foveon sensor based on X3F code by Roland Karlsson + BSD-like license, so included in main LibRaw code. + No 'foveon interpolation', so no way to get good colors from + old Sigma cameras (SD9, SD14, Polaroid x530). For modern Foveon cameras + one may try to create ICC profile (not supplied). + + TODO: thumbnail extraction, fast cancellation + + Old foveon_*_load_raw (from dcraw) code is used if compiled with + LIBRAW_DEMOSAIC_PACK_GPL2 + + * API Changes: + + + New parameters in imgdata.params: + - imgdata.params.no_interpolation - disables interpolation step in + LibRaw::dcraw_process() call. + - imgdata.params.no_auto_scale - disables call to scale_colors() in + LibRaw::dcraw_process() call. + - imgdata.params.sraw_ycc - disables Canon sRAW YCbCr to RGB conversion + in LibRaw::unpack() call (use for RAW analyzers + + + New Fuji X-Trans handling: + - imgdata.iparams.filters value is now 9 for Fuji X-Trans (instead of 2) + - imgdata.iparams.xtrans[6][6] matrix contains row/col to color mapping + for Fuji X-Trans sensor. + + + LibRaw::setCancelFlag() - use for fast decoder termination + + + LibRaw_abstract_datastream::make_byte_buffer() call is not needed more. + + + New demosaic code: DHT Demosaic by Anton Petrusevich + Set params.user_qual=11 to use. + + + New demosaic code: Modified AHD Demosaic by Anton Petrusevich + Set params.user_qual=12 to use. + + + New C-API call libraw_COLOR(libraw_data_t *t, int row,int col) + (so LibRaw::COLOR(row,col) exposed to C-API users) + + * Removed faster lossless jpeg decoder ported from RawSpeed library + some years ago. Build LibRaw with RawSpeed to get fast decoding. + + * Fixed decoding error for some Canon sRAW files. + + * Disabled RawSpeed's bad pixel processing if RawSpeed used. + + * EOS M and EOS 70D added to unique Canon ID table + + * Canon EOS model name normalized by unique ID table + + * Backported 0.15.4 input data checks + + * Support for CMake builds + + * Updated RawSpeed supported camera list + + * Internals changed, so all code using LibRaw should be recompiled. + + * LibRaw 0.16.0-Alpha1 + +2013-05-23 Alex Tutubalin + + LibRaw 0.15-Release + + New camera/format support: + * Adobe DNG: fast Load DNG (LightRoom 4.x), support for + lossy-compressed DNG (LR 4.x, requires libjpeg 6+) + * Canon: G1 X, SX220 HS, EOS 5D Mark III, EOS 650D, EOS 1D-X, + 100D (Rebel SL1), 700D (Rebel T5i), 6D, EOS M, G15, S110, SX50 + * Casio: EX-ZR100,EX-Z8 + * Fujifilm: X-S1, HS30EXR, X1-Pro,X-E1, X20, X100S, SL1000, HS50EXR, + F800EXR, XF1 + * Leica: D-LUX6 and V-LUX4 + * Nikon: D4, D3200, D800, D800E, 1 J2, 1 V2, D600, 1 J3, 1 S1, Coolpix A, + Coolpix P330, Coolpix P7700, D7100 + * Olympus: E-M5, XZ-2, XZ-10, E-PL5, E-PM2 + * Panasonic: G5, G6, DMC-GF5, FZ200, GH3, LX7 + * Pentax: MX-1, K-5 II, K-5 IIs, K-30, Q10 + * Samsung: EX2F, NX20, NX210, support for the new firmware for NX100 + * Sigma: SD15, SD1, SD1 Merill, DP1, DP1S, DP1X, DP2, DP2S, DP2X + (only with Demosaic-pack-GPL2) + * Sony: SLT-A58, RX-1, SLT-A99, NEX-5R, NEX-6, NEX-F3, SLT-A37, SLT-A57 + * Multishot files: Imacon Ixpress 39Mpix + +API changes: + 1. dcraw_process() can now be called several times with different parameters + without re-opening and unpacking the file for second and consecutive + calls to dcraw_process + + 2. deleted (nobody uses those) + - LibRaw::dcraw_document_mode_processing (and respective C-API) + - imgdata.color.color_flags data field + + 3. LibRaw::unpack() now decodes data into different buffers, the buffer + depends on the raw data type + - imgdata.rawdata.raw_image - 1 color component per pixel, + for b/w and Bayer type sensors + - imgdata.rawdata.color3_image - 3 color components per pixel, + sRAW/mRAW files, RawSpeed decoding + - imgdata.rawdata.color4_image - 4 components per pixel, the 4th + component can be void + + 4. Support for compiling with RawSpeed library, http://rawstudio.org/blog/?p=800 + details are in README.RawSpeed + + 5. Suppression of banding + + 6. New API calls + - recycle_datastream(), + - open_file(wchar_t*) (Win32) + + +2012-04-05 Alex Tutubalin + * Casio EX-Z500 support + * (possible) I/O exceptions on file open caught in open_datastream + * Fixed possible read-after-buffer in Sony ARW2 decoder + * Fixed mingw32 errors when compiling LibRaw_windows_datastream + * Makefile.msvc: support of OpenMP and LCMS (uncomment to use) + * Fixed decoding of some Leaf Aptus II files + * LibRaw 0.14.6-Release + +2011-12-24 Alex Tutubalin + * Fixed bug (uninitialized variable) in SMAL format decoding. + + * Imported new dcraw 9.12 (1.446): support for Leica V-LUX 3, + updated color data for Canon S100, Fujifilm X10, Nikon 1 J1/V1, + Panasonic GX1, Samsung NX200, Sony NEX-7 + + * LibRaw 0.14.5-Release + +2011-12-12 Alex Tutubalin + + * Fixes to Panasonic/Leica file parser to prevent crash + on broken jpegs. + + * Fixes to include order in src/libraw_datastream.cpp to + better compile with KDEWIN + + * Floating-point DNGs are rejected on early processing stage. + + * Support for new cameras: Canon S100, Fuji X10, Panasonic GX1, + Samsung NX200, Sony NEX-7. + + * LibRaw 0.14.4-Release + + +2011-10-26 Alex Tutubalin + * Bug fixes in black level subtraction code for PhaseOne files + + * New API call LibRaw::get_internal_data_pointer() for developers + who need access to libraw_internal_data fields (i.e. + Fuji SuperCCD layout). + + * doc/API-overview fixes to reflect 0.14 changes + + * LibRaw 0.14.3-Release + +2011-10-19 Alex Tutubalin + * Fixed bug in Canon 1D and 1Ds files decoding. + * New decoder information bit DECODER_HASRAWCURVE + * LibRaw 0.14.2-Release + +2011-10-11 Alex Tutubalin + * Imported dcraw 9.11/1.445: + + Support for new cameras added: Fujifilm F600EXR, Nikon P7100, + Olympus E-PL3 and E-PM1, Panasonic DMC-FZ150, Sony NEX-5N, + A65 and A77. + + Changed color data for: Olympus E-P3, Panasonic G3 and GF3, + PhaseOne H25, P40 and P65, Sony NEX-C3, NEX-5, NEX-3, A35 and A55. + + Support for dark frame extraction on Sony cameras. + + * DCB demosaicing: reserving 6 pixels instead of 3 to suppress + colored image frame. + * LibRaw 0.14.1-Release + +2011-09-21 Alex Tutubalin + * Cosmetic changes to make Visual C++/OpenMP more happy + * Fix megapixel calculation for postprocessing_benchmark in half mode + * Shlib version number increment + * LibRaw 0.14.0-Release + +2011-09-04 Alex Tutubalin + * Fixed bug with Kodak thumbnail extraction + * raw2image_ex() always return value + * LibRaw 0.14.0-Beta2 + +2011-09-02 Alex Tutubalin + * Cosmetic changes to LibRaw_file_datastream interface + + * OpenMP speedup of postprocessing steps (up to 50% for + half mode and 4-core machine) + + * LibRaw 0.14.0-Beta1 + +2011-08-20 Alex Tutubalin + + * Patch to dcraw_emu for SunStudio compiler compatibility + + * Fixed crash in unprocessed_raw sample due to uninitialized + timestamp variable. + + * Fixed crash in raw decoding if raw_width/raw_height is + less than resulting image width/height. + + * imgdata.sizes.flip is set from user_flip only on + postprocessing and/or adjust_sizes_info_only() + + * Fixed buffer overrun for some LJPEG-compressed files + + * Most of LibRaw_datastream function bodies are moved to + separate source file + + * LibRaw_windows_datastream is merged to main sourcetree + + * LibRaw 0.14.0-Alpha5 + +2011-08-11 Alex Tutubalin + * Imported dcraw 9.10 (1.444), support for new cameras added: + ARRIRAW format, Canon SX30 IS, Leica D-LUX 5 and V-LUX2, + Olympus E-P3, Panasonic G3 and GF3, Sony NEX-C3 and SLT-A35 + + * Support for RedOne digital movie cameras (R3D format). + To enable this support you should: + + install libjasper JPEG2000 support library + + + compile LibRaw with -DUSE_JASPER compiler switch (./configure + will do it for you) + + + If you use own LibRaw_datastream implementation, you should + implement make_jas_stream() call for your datastream. See + bottom of src/libraw_cxx.cpp for implementations in datafile + and mem-buffer LibRaw streams. + + * Bugfix: green matching is turned off if output image is shrinked + due to wavelet filtering or aberration correction. + + * fixed open_file()/adjust_sizes_info_only() code path + + * Removed imgdata.sizes.bottom_margin and right_margin data fields + use imgdata.sizes.raw_width - width - left_margin to get right one, + the same with bottom_margin. + + * minor ./configure cleanup + + * Qmake files and Visual Studio Project files are updated. + + * New version check macros: + For use at runtime checks: + LIBRAW_RUNTIME_CHECK_VERSION_EXACT() - checks that runtime + major/minor version numbers are same with compile-time values. + + LIBRAW_RUNTIME_CHECK_VERSION_NOTLESS() - checks that runtime + version is not less that compile-time one. + + For use at compile-time in preprocessor directives: + LIBRAW_COMPILE_CHECK_VERSION_EXACT(major,minor) - Compile-time + check that LibRaw version is exact major.minor. + + LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(major,minor) - Compile-time + check that version is not less than major.minor. + + * all client code should be recompiled due to internals change. + + * LibRaw 0.14.0-Alpha4 + +2011-07-19 Alex Tutubalin + * New sample samples/postprocessing_benchmark.cpp + This sample measures postprocessing speed. + All demosaic methods, averaged white balance, median + filtering, wavelet filtration, highlight recovery, and + cropping are supported. + + * Removed LibRaw::rotate_fuji_raw() call and corresponding C-API call. + + * The LibRaw::adjust_sizes_info_only() call may be called repeated + and mixed with dcraw_process() call. + + * Postprocessing speedup and optimization, especially if cropping set. + + * Cropping works for FujiCCD raws. For the technical reasons, the position + of top-left corner of crop area will be rounded to the nearest + multiple of 4 (the corner is shifted top-left). + + * LibRaw 0.14.0-Alpha3 + +2011-07-15 Alex Tutubalin + * imported cropping code from 0.13 branch + +2011-07-12 Alex Tutubalin + * samples/multirender_test - check for different clip settings + +2011-07-11 Alex Tutubalin + * New call LibRaw::free_image(), deallocates imgdata.image buffer. + Use this call if current postprocessing results are not + needed, but it is to early to call recycle() because + dcraw_process() may be called later. + + * New C-API calls + libraw_raw2image() - C API for LibRaw::raw2image() + libraw_free_image() - C API for LibRaw::free_image() + libraw_get_decoder_info() - C API for LibRaw::get_decoder_info() + + * Bugfix: change of params.user_flip aftee open()/unpack() + calls should work. + + * LibRaw 0.14.0-Alpha2 + +2011-07-10 Alex Tutubalin + * Multiple rendering (LibRaw::dcraw_process() calls) allowed + without re-opening RAW file thrfough the sequence of open()/unpack() + calls. + You should be able to change any processing parameters (except + shot_select parameter) between dcraw_process() calls. + + + New sample in samples/multirender_test.cpp: renders data 4 times: + in half and full modes with different white balance settings. + + + Unprocessed RAW data is stored in separate data buffer: + (2 bytes per pixel for all Bayer-pattern images, + 8 bytes per pixel for Foveon, sRAW, and other full-color raw + formats), so now LibRaw uses 25% more memory for full processing of + most common Bayer images; while for just unpack memory is reduced + 4 times. + + + New call LibRaw::raw2image() fills imgdata.image array + with fresh copy of data. + There is no need to call raw2image() separately if you use + dcraw_process() or dcraw_document_mode_processing() calls. + + + New call LibRaw::get_decoder_info() to determine raw data + storage layout. See samples/unprocessed_raw.cpp for an example + of how to use it. + + If your code uses usual open()/unpack()/dcraw_process() call + sequence, then NOTHING CHANGED: your program should produce same + results. For interactive programs you may skip open()/unpack() + calls after adjusting processing parameters, so user should see + image refreshed much faster. + + If your code uses raw data (open+unpack calls), you need to call + LibRaw::raw2image(), and imgdata.image will contain same bitmap + as in LibRaw 0.13.x + + If you code uses access to masked borders data, you need to + rewrite it. See samples/unprocessed_raw.cpp as a sample. + + Unfortunately, documentation is untouched yet. This problem will be + fixed in next Alpha release. + + Other changes: + + * No separate imgdata.masked_pixels buffers, Bayer raw formats are read + to buffer with borders. So, no ugly add_masked_border_to_bitmap() + call. + + * No filtering_mode parameter. Raw tone curve is applied + at unpack() stage; zero pixels removed on postprocessing stage. + + * unprocessed_raw and 4colors samples are adjusted to use + new RAW data storage layout. + + * all client code should be recompiled due to internals change. + + * LibRaw 0.14.0-Alpha1 + +2011-07-03 Alex Tutubalin + * Cosmetic cleanup in Libraw_memmgr code + + * Permit OpenMP support on MS VS2008 + + * More general mem_image interface: + + New call get_mem_image_format returns bitmap size and bit depth + + New call copy_mem_image can copy bitmap into buffer with + different color order (RGB/BGR) and line stride + + dcraw_make_mem_image() uses calls mentioned above + + see documentation for info on these function parameters. + + * libraw/librawwindows.h implements LibRaw_datastream class based + on Windows memory mapped files.Win32/64-only + Thanks to Linc Brookes. + + * Fixed parallel make errors in configure/Makefile.am + + * LibRaw 0.13.6-Release + + +2011-05-18 Alex Tutubalin + * Imported new dcraw 9.08/1.443: + + New color data for Canon 600D and 1100D, Fuji S200EXR + + New camera supported: Fuji HS20EXR and F550EXR, Kodak Z990, + Nikon D5100, Olympus E-PL1s and XZ-1, + Samsung NX11, Sony A230 and 290. + * LibRaw 0.13.5-Release + +2011-04-02 Alex Tutubalin + * Imported new dcraw 9.07/1.442: + + Support for Canon 600D and 1100D, Hasselblad H4D-60, + Olympus E-PL2 + * Color data for Leaf Aptus II and Canon Powershot S2 IS + * LibRaw 0.13.4-Release + +2011-03-30 Alex Tutubalin + * Preliminary support for Leaf Aptus II cameras (no color data yet): + Leaf Aptus II 6,7,8,10 and 12 are tested, Aptus II 5 should work. + * Preliminary support for Fujifilm X100 camera (again, no color data). + * Fixed possible after the end of buffer read when working with + in-memory data. + * Fixed possible loss of JPEG stream sync marks in LJPEG decoder + (this bug was found only for Leaf Aptus II RAWs). + * LibRaw 0.13.3-Release + +2011-03-08 Alex Tutubalin + * Fixed broken camera white balance reading for some Sony cameras + * LibRaw 0.13.2-Release + +2011-02-25 Alex Tutubalin + * Sony A390 support (colordata from A380) + * Leica D-LUX 4: fixed typo in camera name in colordata + +2011-02-15 Alex Tutubalin + * New -mem option for dcraw_emu: I/O via allocated buffer + * Removed debug printf from LibRaw_memory_buffer code + * Preliminary shared library support + +2011-02-12 Alex Tutubalin + * Added qmake .pro and Visual Studio 2008 sln/vcproj project files +2011-02-07 Alex Tutubalin + * dcraw_emu documentation updated + * ./configure stuff changed for correct linking on some systems + * FBDD denoising is disabled for full-color images and 4-color bayer + data (including forced 4-color via four_color_rgb option) + * LibRaw 0.13.1-Release + +2011-02-05 Alex Tutubalin + * ./configure fixes for PACKAGE_REQUIRES + * Makefile.msvc: correct compiler flags for demosaic packs + * dcraw.c 9.06/1.440 imported: + + New camera support: Canon S95, Casio EX-Z1080, Panasonic GF2 + and GH2, Samsung NX100, Sony A-580 + + New color data for: Canon G12, Nikon D3100, D7000 and P7000, + Olympus E-5, Pentax K-r and K-5, Samsung NX10 and WB2000 + * green_matching() code is disabled for half-size processing + * LibRaw 0.13.0-Release + +2011-01-15 Alex Tutubalin + * Fallback to old huffman decoder for Sony files with unspecified + data length (Sony A100) + * Fixed incomplete data fields reset in LibRaw::recycle() + * LibRaw 0.13.0-Beta3 + +2011-01-13 Alex Tutubalin + * Better parsing of unknown command-line params in dcraw_emu sample + * Brigtness table in ahd_demosaic is calculated in reversed order + to prevent possible (very unlikely) multithreaded app problem. + * New exposure correction code based on linear-cubic root combination. + New working correction range is from 0.25 (-2 stops) to 8 (+3 stops) + * LibRaw 0.13.0-Beta2 + +2011-01-10 Alex Tutubalin + * Fixed file extension in half_mt.c sample + +2011-01-10 Alex Tutubalin + * Three patches provided by Jacques Desmis: + - Exposure correction before demosaic (demosaic pack GPL3) + - OpenMP speed-up in median filters (demosaic pack GPL2) + - OpenMP speed-up in green equilibration (demosaic pack GPL3) + * Merged 0.12.2-0.12.3 changes: + - Patches for ./configure system for better LCMS2 support + - Patches for ./configure system + - math.h included before any other includes to make KDE compile + with Visual C++ happy + - Fuji FinePix S5500 size adjusted to ignore (rare?) garbage + at top of frame. + * all client code should be recompiled due to internals change. + * LibRaw 0.13.0-Beta1 + +2010-12-22 Alex Tutubalin + * Zero copy huffman buffer for LibRaw_buffer_datastream + * Fixed memory leak in compressed NEFs handling + * LibRaw 0.13.0-Alpha2 + +2010-12-20 Alex Tutubalin + * Demosaic-pack-GPL3 changes: + + New noise reduction methods before demosaic + - Banding suppression + - High-frequency noise suppression + - Green channel equalization + + New chromatic aberration correction. + All three methods are written by Emil Martinec for Raw Therapee. + Adapted to LibRaw by Jacques Desmis + + * Merged Foveon code fix from LibRaw 0.12.1 + + * LJPEG decompressor speed-up (about 1.5 times for Canon cameras + and slightly less for others). Some ideas are from RawSpeed library. + + * all client code should be recompiled due to internals change. + + * LibRaw 0.13.0-Alpha1 + +2010-12-12 Alex Tutubalin + * Thread-safe and demosaic packs support for MinGW build + * Demosaic packs support for MS VC build + * LibRaw 0.12.0-Release + +2010-12-09 Alex Tutubalin + * Fixed bug in add_masked_borders_to_bitmap() call for cameras + with odd pixels border. + * New command line options for unprocessed_raw sample: + -B - subtract black level, -M - add masked pixels to bitmap. + * Foveon-sensor cameras added to supported camera list if + compiled with demosaic pack GPL2 + * LibRaw 0.12.0-Beta4 + +2010-12-05 Alex Tutubalin + * Demosaic packs support in Makefile.dist + * Foveon support in LibRaw demosaic pack GPL2 + * all client code should be recompiled due to internals change. + * LibRaw 0.12.0-Beta3 + +2010-11-27 Alex Tutubalin + * Fixed allocation bug in lmmse_interpolation (demosaic-pack-GPL2) + * In LMMSE and AMaZE interpolators allocation changed to calloc + to make valgrind happy with uninitialized values + * Changes in distribution-making scripts + * LibRaw 0.12.0-Beta2 + +2010-11-21 Alex Tutubalin + * Fixes to green_matching code by Sergey Pavlov + +2010-11-20 Alex Tutubalin + * Update for new demosaic-pack-GPL3 + * LibRaw 0.12.0-Beta1 + +2010-11-19 Alex Tutubalin + * Demosaic pack(s) supported via ./configure + +2010-11-17 Alex Tutubalin + * LCMS2 support + * afd_interpolate(2,1) instead of (5,0) + * dcraw_emu sample command line keys added and reordered + to reflect changes in LibRaw 0.12. + * Nikon P7000: color matrix data and black level patch for ISO >=400 + Thanks to Gunnar Thorburn + * Support for several industrial cameras based on Sony ICX 625/655 + sensor: JAI BB500CL/GE, SVS625CL, ptGrey GRAS-50S5C + Thanks to kaare + +2010-11-15 Alex Tutubalin + + * Several demosaic algorithms, found in other open-source RAW processing + packages are implemented in LibRaw. + + 1) DCB demosaic and FBDD denoise by Jacek Gozdz are included in + main LibRaw source. + 2) GPL2 demosaic pack with these demosaic methods: + * AFD and LMMSE implementations from PerfectRaw by Manuel Llorens + * VCD, Modified AHD, post-demosaic refinemend and median + filters by Paul Lee + 3) GPL3 demosaic pack with AMaZe interpolation by Emil Martinec + + See more details in README.demosaic-packs + + * Current implementation of dcraw_emu sample allows only selection + of demosaic method (via -q) options. All other parameters change + will be implemented later. + + * LibRaw 0.12-alpha1 + +2010-11-11 Alex Tutubalin + * Imported 0.11(2) version changes: + + Fixed dcraw_emu command line processing code + + OpenMP is completely disabled on MacOS X if compiled with -pthread + due to well-known MacOS problem. + + dcraw 9.05 (1.439) imported, many new cameras supported: + Canon: G12, SX120, 60D, + Hasselblad H4D, Nokia X2, Olympus E-5, + Nikon: D3100, D7000, P7000, + Panasonic: FZ40, FZ100, LX5, + Pentax: K-r, K-5, 645D, + Samsung GX20, WB2000 + * LibRaw 0.12-alpha0 + +2010-11-08 Alex Tutubalin + * Fixes for Sun Studio compiler compatibility + * Fixes for Visual Studio 2010 compatibility + * All russian-language files are converted to UTF-8 + * LibRaw 0.11.0-Release + +2010-10-18 Alex Tutubalin + * Disabled OpenMP for wavelet_denoise under Mac OS X + * More Visual C++ 2003 warnings cleaned in libraw/*h files + * LibRaw 0.11-Beta7 + +2010-10-16 Alex Tutubalin + * internal/dcraw_fileio.c can be compiled with -DDCRAW_VERBOSE again + * fixed comment style in libraw_datastream.h + * LibRaw 0.11-Beta6 + +2010-10-15 Alex Tutubalin + + * New changes to I/O layer. Three LibRaw_*datastream clasees are + exists: + + LibRaw_buffer_datastream - buffer reaging + + LibRaw_file_datastream - file reading using iostreams + (large files are no supported on some systems) + + LibRaw_bigfile_datastream - FILE*-based file I/O + + * file/bigfile_datastream is selected automatically by + LibRaw::open_file based on input file size. + By default, files larger than 250Mb are opened using + bigfile interface, you may change this behaviour + by using second optional parameter of open_file() + + * There is no way to use default parameter values in C API, + so new call libraw_open_file_ex added with two parameters + (file name and minimal file size for bigfile_datastream use). + + * all client code should be recompiled due to internals change. + + * All LibRaw_abstract_datastream functions are virtual again. You may + (again) use your own I/O layer. + + * new -d key for dcraw_emu sample: print timings of processing stages + + * simple_dcraw sample simplified: no mmap code + + * LibRaw 0.11-Beta5 + +2010-10-08 Alex Tutubalin + * Fixed bug in exception handling in OpenMP sections in + AHD interpolation code. + + * LibRaw_datastreams are now C++ iostreams based instead of old + plain FILE* calls. + LibRaw::open_file() in multithreaded programs are WAY faster + on many OSes (Linux, Windows, MacOSX) because of no extra locks. + + * all client code should be recompiled due to internals change. + + * LibRaw 0.11-Beta4 + + +2010-10-01 Alex Tutubalin + * Fixed bug in LibRaw::dcraw_process() code: for half_size + processing, params.four_color_rgb was set to 1 internally + and not returned back after postprocessing. + + * Several Visual Studio 2003 compatibility fixes + + * AHD interpolation refactored. Now it is about 10% faster than + dcraw in single-process mode and up to 1.5 times faster on + 4-core and OpenMP (total execution time counted, not AHD itself) + Thanks to Adam Hooper + * AHD interpolation refactored. Now it is about 10% faster than + dcraw in single-process mode and up to 1.5 times faster on + 4-core and OpenMP (total execution time counted, not AHD itself) + Thanks to Adam Hooper + + * LibRaw 0.11-Beta3 + +2010-09-07 Alex Tutubalin + * Phase One files: LibRaw::unpack() sets colordata.black to + approximately correct value. + + * Fixed minor error in setting colordata.maximum value + for Phase One files. + + * LibRaw::subtract_black() sets colordata.black and + colordata.cblack[] to zero to preserve data integrity. + + * LibRaw 0.11-Beta2 + + +2010-09-04 Alex Tutubalin + + * It is now possible to crop output image on postprocessing + stage (dcraw_process). Coordinates and size of the output box + are set via imgdata.params.cropbox[4] parameter. Look into + LibRaw documentation for more details. + + + New fatal error code LIBRAW_BAD_CROP + + + New dcraw_emu sample command line switch: -B x y w h + (sets cropbox) + + Thanks to Patrick and Jan. + + * Processing pipeline has changed: the black level is subtracted + from data on postprocessing stage either automatically + (on dcraw_process() stage) or by special LibRaw API call: + + + New API calls: LibRaw::subtract_black() (C++ API) and + libraw_subtract_black (C API). + If you use dcraw_process() or dcraw_document_mode_processing() + calls YOU DON'T NEED to call subtract_black() directly. + + + The raw preprocessing mode LIBRAW_FILTERING_NOBLACKS + is deprecated and removed from LibRaw. + + * New ./configure script. + Use ./configure -h for usage details. + Thanks to Siddhesh Poyarekar + + * New API cals static LibRaw::dcraw_clear_mem() (C++ API) + and libraw_dcraw_clear_mem(..) (C API). + This calls are used to free memory, allocated by + dcraw_make_mem_image() and dcraw_make_mem_thumb() instead + of free() call. + + In some cases LibRaw and calling process have different + memory managers, so free() of make_mem_image() data + results to program crash (especially in Win32/VisualStudio + environment). + + * LibRaw::free() is now private instead of public (again). + + * Minor changes and bugfixes: + + + Memory allocation exceptions (std::bad_alloc) are caught, + so LibRaw API calls will return reasonable error codes + instead of C++ exception (possibly unhandled). + This problem is very unlikely to see in wild: if application + cannot allocate small data for internal structure, it will + always fail on allocation for RAW image data. + + + WIN32/VisualStudio 2008/2010: fopen,fscanf and sscanf calls + in Libraw_datastream code are changed to *_s (secure) ones. + + + Debug print removed from fatal error handler. + + + Mmaped I/O for dcraw_emu sample is turned on via -E switch + now (because old -B switch is used for setting cropbox). + + * all client code should be recompiled due to structures size change + + * LibRaw 0.11-Beta1 + + +2010-07-31 Alex Tutubalin + * dcraw 9.04 (1.438) imported: changes in tiff metadata parser, + fixed a typo in Canon A720 model name + * small patch in Sony ARW2 unpacking code to make valgrind happy + * LibRaw 0.10.0-Beta3. + +2010-07-05 Alex Tutubalin + * dcraw 9.03 (1.437) imported: + + New cameras: Canon SX20, Nikon D3s, Olympus E-P2, Panasoni DMC-GF1, + Samsung EX1, Sony A450 + + Color data changed for some cameras + + * LibRaw 0.10.0-Beta2. + +2010-06-06 Alex Tutubalin + * dcraw 9.01 (1.434) imported: + + Separate black levels for each color channel. + + New cameras: Canon 550D, Casio EX-Z1050, Fuji HS10/HS11, + Kodak Z981, Panasonic G2 and G10, Phase One P65, + Samsung NX-10 and WB550, Sony NEX-3 and NEX-5. + + Fixed file descriptor leak in dark frame subtraction processing + + * Fixed dcraw 9.01's bug in DNG black level processing + + * Preliminary support for Sony A450 camera. + + * New command-line switch -h in mem_image sample (half_size support) + + * Some patches by Johannes Hanika (darktable author): + + OpenMP speedup for PPG-interpolation + + green_matching - suppress of 'color maze' on cameras with + different green channel sensitivity. This option is turns on + by filed with same name in imgdata.params + + * all client code should be recompiled due to structures size + change + + * LibRaw::free() is now public instead of private. + + * LibRaw 0.10.0-Beta1. + +2010-05-15 Alex Tutubalin + * Fixed bug in 8-bit RAW processing code + * LibRaw 0.9.1-Release + +2010-04-26 Alex Tutubalin + * OpenMP support: OpenMP is possible under MinGW (untested) + * LibRaw 0.9.0-Release + +2010-04-21 Alex Tutubalin + * Finally fixed inconsistency in Fuji files processing + * New COLOR(row,col) call to get bayer color index in image[] array + * Old FC() call is deprecated and will be removed in future releases + * unprocessed_raw sample switched to COLOR() call + * LibRaw 0.9.0-Beta5 + + +2010-04-10 Alex Tutubalin + * Fixed bug in unpacking DNG files made from Fuji RAFs. + * LibRaw 0.9.0-Beta4 + +2010-04-09 Alex Tutubalin + + * Fixed typecast error (problem reported only on gcc 4.2.1/32bit) + in CRW files processing. + + * C++ API call LibRaw::adjust_maximum() is now deprecated and + de-documented, use params.adjust_maximum_thr instead (on by default) + + * C-API call libraw_adjust_maximum() removed. + + * New postprocessing parameter params.adjust_maximum_thr + This parameter replaces LibRaw::adjust_maximum(), but more flexible + Defaults are reasonable (0.75, same as in old adjust_maximum), + look into documentation for more details. + + * Removed last OpenMP warning + + * dcraw_emu's -c parameter now wants numeric (float) argument. This value + is assigned to params.adjust_maximum_thr. + Use -c 0.0 for dcraw compatibility. + + * all client code should be recompiled due to structures size + change + + * LibRaw 0.9.0-Beta3 + + +2010-03-29 Alex Tutubalin + * Fixed a bug in channel_maximum[] calculation for + Panasonic cameras. + * channel_maximum[] data now calculated for ALL cameras. + * OpenMP warnings suppressed. + * Documented the -c command-line switch for dcraw_emu sample. + * Removed extra messages from dcraw_emu sample. + * LibRaw 0.9.0-Beta2 + +2010-03-28 Alex Tutubalin + + New licensing: + + * Triple licensing (selected by LibRaw user): + + + LGPL 2.1 (http://www.gnu.org/licenses/lgpl-2.1.html) + + CDDL 1.0 (http://www.opensource.org/licenses/cddl1.txt) + + LibRaw Software License (27 March 2010 version) + (http://www.libraw.org/data/LICENSE.LibRaw.pdf) + + * There is no separate LibRaw-Lite and LibRaw-Commercial versions, + only single LibRaw. + Current LibRaw-Lite and LibRaw-Commercial users should switch + to LibRaw without loss of functionality. + It is possible to change licensig too (e.g. from LGPL to CDDL + for LibRaw-Lite users and from LibRaw License to LGPL or CDDL + for LibRaw-Commercial users). + + * No Foveon support :( + It is not possible to get good color from Foveon sensors with + *any* converter. So, there is no need to support these cameras. + Dcraw's Foveon-processing code is too strict licensed (GPL), + so we choose to drop it. + + New Features: + + * New data field colordata.channel_maximum[4] - per channel data + maximum (calculated for most cameras, 0 for others). + + * New call LibRaw::adjust_maximum() (and libraw_adjust_maximum() in C API). + This call changes hardcoded colordata.maximum value to calculated + at unpack stage. This helps suppress false color in highlights + (magenta clouds and so). + + * New command line parameter -c for dcraw_emu sample. Calls adjust_maximum() + for each processed file. + + * all client code should be recompiled due to structures size + change + + * LibRaw 0.9.0-Beta1 + +2010-02-06 Alex Tutubalin + * Fixed ambiguity in pow/sqrt calls (to make Sun C++ compiler happy) + * OpenMP is not supported under MS Visual Studio + * Masked a bug in RIFF format parser + * LibRaw 0.8.6 + +2009-12-30 Alex Tutubalin + * Fixed bug in simple_dcraw sample parameters processing + * Imported dcraw 8.99 (1.432): + + New cameras: Canon: 1D mk IV, Canon S90; Casio Z750, + Nikon D3S, Pentax K-x, Sony A-500/550, Fuji S200EXR + + New color data for Canon G11 and Sony A850 + + Changes in Canon sRAW processing + + Changes in Kodak metadata processing + + Changes in uncompressed Fuji files processing (FinePix S5xxx) + * LibRaw 0.8.5 + +2009-11-21 Alex Tutubalin + + Fixed a bug in processing of uncompressed Phase One files + * LibRaw 0.8.4 + +2009-10-24 Alex Tutubalin + + Imported dcraw 8.98/1.431: + * New Cameras: Canon 7D, Panasonic GF1, Sony A850 and A380, + Casio Z850, Nikon D300s + + changes in libraw_datastream.h to make compilers more happy + * LibRaw 0.8.3 + +2009-09-02 Alex Tutubalin + + Fixed bug in Hasselblad .3FR unpacking code + * Imported dcraw 8.97/1.428: Nikon D3000 image width fix + * LibRaw 0.8.2 + +2009-08-31 Alex Tutubalin + + Enum LibRaw_thumbnail_formats (LIBRAW_IMAGE_*) values changed to + match values in enum LibRaw_image_formats (LIBRAW_THUMBNAIL_*). + You need to recompile all sources using these constants. + +2009-08-30 Alex Tutubalin + * Imported dcraw 8.97/1.427: + + new cameras: Canon A470, Canon G11 (without color data), + Nikon D3000, Olympus E-P1, Panasonic DMC-FZ35/FZ38 + + some changes in decoding code. + * Fixes for Microsoft Visual C++ 6.0 compatibility + * C-API dcraw_make_mem_thumb() call finally exported in API + * LibRaw 0.8.1 + +2009-08-24 Alex Tutubalin + * Imported dcraw 8.96/1.426 + + New cameras: Casio EX-Z60 and EX-Z75, Kodak Z980, + Nikon D5000, Olympus X200, D560Z,C350Z,E620, + Pentax K7, Sony A330. + + New color data for many cameras + + Generalized unpacker code for Canon and Casio P&S cameras + * LibRaw 0.8.0-Release + +2009-08-13 Alex Tutubalin + * RAW files larger than 2Gb are supported on: + - Unix (all supported: FreeBSD, MacOS X, Linux) + - Windows (with C runtime version >= 8.0) + * bzero replaced with memset to make Solaris users happy + * All applications on 32-bit systems should be recompiled + due to data structures size changes. + * Minor fixes in windows makefile + * LibRaw 0.8.0-Beta5 + +2009-07-21 Alex Tutubalin + * Imported dcraw 8.95 (1.425): + + new huffman tree code + + New cameras supported: AGFAPHOTO DC-833m, Casio EX-S20, + Phase One P65, Samsung S850 + + Removed hardcoded white-balance data for many P&S cameras. + It is recommended to set params.use_camera_wb to 1 for + safe WB. + * Fixes for Nikon D5000 files: no pink stripe at + right side of frame + * C-wrapper: added missed calls + libraw_dcraw_make_mem_image + libraw_dcraw_ make_mem_thumb + * Minor fixes to make non-gcc compilers more happy + * Internal structures changed, full recompilation of all client + code is needed. + * LibRaw 0.8.0-Beta4 + +2009-06-08 Alex Tutubalin + * Fixes: gamma curve processing was not performed in + dcraw_write_mem_image() + * Fixes: gamma curve processing was not performed for + Kodak thumbnails + * LibRaw 0.8.0-Beta3 + +2009-06-05 Alex Tutubalin + * Fixes in documentation: params.gamm[] described more precisely + * Fixes in version number, 0.8-beta1 was mistakenly 0.0.0-beta1 + * LibRaw 0.8.0-Beta2 + +2009-06-04 Alex Tutubalin + * Imported dcraw 8.94 (1.423): + + New camera support: + Canon: SX1, 500D/Rebel T1i, A570, A590, SX110 + Kodak Z1015, Motorola PIXL, Olympus E30, Panasonic DMC-GH1 + + Improved color data for Nikon D3X + + New gamma curve model + + Many changes in RAW unpacking code + + Canon cameras: black level is not subtracted if set + params.document_mode > 1 + + * API changed: params.gamma_16bit field removed. Gamma curve is + set via params.gamm[0]/gamm[1] values (see documentation and + samples for details) + * LibRaw::identify() split to avoid MS VS2008 bug (too many + nested blocks) + + * Samples: dcraw_emu and mem_image samples supports new dcraw + 16bit/gamma semantics: + -6: set 16 bit output + -4: set 16 bit output and linear gamma curve and no auto + brightness + * LibRaw 0.8.0-Beta1 + +2009-04-28 Alex Tutubalin + * Identify sample renamed to raw-identify (name conflict + with ImageMagic) + * Copyright notice changes + * Many compiler warnings removed + +2009-04-07 Alex Tutubalin + * More accurate types conversion in libraw_datastream.h + * New postprocessing parameter auto_bright_thr: set portion of + clipped pixels for auto brightening code (instead of + dcraw-derived hardcoded 1%) + * -U option for dcraw_emu sample sets auto_bright_thr parameter + * all client code should be recompiled due to structures size + change + * LibRaw 0.7.2-Release + +2009-03-22 Alex Tutubalin + * Fixed typo in OpenMP support code + * MinGW support + * dcraw source is included in distribution + * LibRaw 0.7.1-Release + +2009-03-15 Alex Tutubalin + * Fuji SuperCCD RAWs: color channels unshuffled on RAW + read stage (moved from postprocessing stage) + + * LibRaw 0.7.0-Release + +2009-03-13 Alex Tutubalin + * dcraw 8.93/1.421 imported: + + more accurate pentax dSLR support + + fixes in Kodak 620x/720x identification + + faster identification procedure for some formats. + * LibRaw 0.7.0-Beta5 + + +2009-03-08 Alex Tutubalin + * dcraw 8.92/1.420 imported: + + user-specified gamma curve + + Pentax K2000/Km support + + Changes in Canon sRAW processing (support for 5D2 fw 1.07) + + * all client code should be recompiled + + * LibRaw 0.7.0-Beta4 + +2009-02-13 Alex Tutubalin + * bugfix: 4channels sample finally subtracts black by default + * dcraw 8.91/1.419 imported: + + fixes in RIFF files parsing + + * LibRaw 0.7.0-Beta3 + +2009-02-12 Alex Tutubalin + * Black level was not calculated for Canon RAWs in + some filtering modes + + * 4channels sample prints calculated black level + (scaled if autoscaling used). + Also output file names for this sample now includes + color channel name (R/G/B/G2 or C/M/Y/G) + + * LibRaw 0.7.0-Beta2 + +2009-02-09 Alex Tutubalin + * New sample 4channels: splits RAW color channels into four + separate TIFFs + + * LibRaw 0.7.0-Beta1 + +2009-02-07 Alex Tutubalin + * Fixed bug in external jpeg metadata reading code. + + * Cleaned some C++ warnings + + * dcraw 8.91/1.418 imported + + Hasselblad V96C support + + * You need to clean and recompile client code which + uses LibRaw_*_datastream classes. + + * LibRaw 0.7.0-Alpha6 + +2009-01-30 Alex Tutubalin + + * New data input framework is created. It is possible now to + easyly implement your own data input interface for LibRaw + (e.g. for reading RAW data from network data stream) + + * All older programs using previous LibRaw versions are + compatible at source code level. + + * LibRaw can read RAW data from memory buffer via + new LibRaw::open_buffer() API call (implemented on top of + new input framework). + This call used in sample application dcraw_emu and simple_dcraw + (with -B command-line switch) to test new API. + + * Error handling callback functions now can be called with + NULL filename passed (if underlying data stream object + does not know file name). + So, client error handling callbacks should work with NULL + filename. + + * All client code should be recompiled + + * Imported dcraw 8.90/1.417: + + Support for loading White Balance data from + Sony ARW files edited with Sony IDC software. + + * LibRaw 0.7.0-Alpha5 + +2009-01-17 Alex Tutubalin + * Raw filtering mode LIBRAW_FILTERING_NOPOSTPROCESS has renamed + to LIBRAW_FILTERING_NORAWCURVE for better reflect its purpose. + This filtering_mode bit turns off tone curve applying on + RAW data on bayer-pattern cameras with raw tone curve: + + Adobe DNG (only RAW with bayer pattern) + + Nikon compressed NEF + + Some Kodak cameras + + Sony A700/A900 (tone curve applied to 8-bit raws) + + * unprocessed_raw sample: added command-line key -N, this key + turns on LIBRAW_FILTERING_NORAWCURVE filtering mode. + + * New scheme of Fuji RAW processing (introduced in 0.7-Alpha3) + supports DNG files generated from Fuji RAF. + + * Imported dcraw 8.90/1.416: + + better support for Samsung S85 + + fixed possible integer overflow in wavelet denoising code + + * LibRaw 0.7.0-Alpha4 + + +2009-01-14 Alex Tutubalin + * Black mask extraction supported for all files with bayer data + (one component per pixel). Black mask data not available + for multi-component data (Foveon, Canon sRAW, Sinar 4-shot, + Kodak YCC/YRGB). + + * Black level subtraction can be turned off for all bayer + cameras (added support for PhaseOne backs). + + * Fujifilm camera processing model changed: + + RAW data is extracted without 45-degree rotation + + dcraw-compatible rotation is performed on postptocessing stage + + it is possible to rotate RAW data without postprocessing + by LibRaw::rotate_fuji_raw() call. + + * New filtering mode setting: LIBRAW_FILTERING_NOPOSTPROCESS + This bits turns off RAW tone curve processing based on tone curve + readed from RAW metadata. + This mode supported only for PhaseOne backs now (to be supported + on all relevant cameras in nearest future releases) + + * Black level data (got from RAW data) are stored for PhaseOne backs. + + * Black level subtraction bug (derived from dcraw) fixed + for PhaseOne files. + + * Fixed processing of -s parameter for dcraw_emu sample + + * Parameter -s N (select shot number) added to + unprocessed_raw sample. + + * Imported dcraw 8.90/1.414: + + changes in QuickTake 100 metadata processing + + changes in external jpeg processing code + + Samsung S85 support + + * All client code should be recompiled + + * LibRaw 0.7.0-Alpha3 released + +2009-01-10 Alex Tutubalin + * Fixed bug in add_masked_borders: crash if output dimensions + is already larger than raw dimensions + * Fixed out of bounds in samples/unprocessed_raw.cpp for files + with non-square pixels + + * LibRaw 0.7.0-Alpha2 released + +2009-01-08 Alex Tutubalin + * Fixed bug in 0.7.0-a0: black frame size has not reset, + so in batch processing there is an error in black frame + size for files without black frame. + + * Implemented reading of black/masked pixels data for + near all cameras with masked pixels, exclding: + + Canon sRAW, Leaf (MOS), Sinar 4-shot - more than one + color component in black frame (redesign of black frame + data structures required). + + Fuji SuperCCD: need to design right methods of extraction + (should we rotate and resize black pixels as active ones??) + + * Tested for most dSLR data formats with masked pixels: 7 of 9 + untested formats are from old P&S cameras. + + * New call LibRaw::unpack_function_name() returns unpack function name + (useful for testers only) + + * New identify sample parameters (useful for test-suite builders + to check test coverage): + -u - print unpack function name + -f - print masked frame size + These parameters works only for identify run without -v parameter + + * Imported dcraw 8.89/1.411 + + changes in Panasonic FZ50 files parsing + + * LibRaw 0.7.0-Alpha1 released + + +2009-01-05 Alex Tutubalin + * It is possible to turn off RAW data filtration (black level + subtraction, zero pixels averaging): + + supported on all cameras except Foveon and Phase One + + filtraction controlled by new parameter "filtering_mode" + + it is possible to expand API by filtering procedures + built for specific camera model. + + * Black border (masked pixels) extraction: + + API (data structures) for storing black mask. + + Black mask extraction supported only for limited list of + data formats: + - Canon .CRW, .CR2 (with exception of sRAW),A600, A5 + - Adobe DNG (both converted RAW and native DNG) + - Nikon NEF (compressed only) + this list to be expanded in future LibRaw versions + * New call add_masked_borders_to_bitmap makes full bitmap + 'masked border' + image + * Usage sample for functionality listed above: + samples/unprocessed_raw + * Imported dcraw 8.89/1.410: + + fixed bugs in Hasselblad .fff decoding + + fixes in Imacon metadata decoding + * Documentation changes + * All client code should be recompiled + * LibRaw 0.7.0-Alpha0 + + +2009-01-01 Alex Tutubalin + * Fixed a bug (filedescriptor and buffer memory leak) in thumbnail + extraction when called before metadata analysis. + Thanks to Albert Astalis Cid. + * LibRaw 0.6.4 Release + +2008-12-11 Alex Tutubalin + * Imported new edition of dcraw 8.89 (version 1.409) + * Nikon NEF decoding changed + * LibRaw 0.6.3 Release + +2008-12-03 Alex Tutubalin + * fixed bug in Panasonic .RW2 processing (only for thread-safe version, + single-threaded version was not affected) + * All client code should be recompiled + * LibRaw 0.6.2 Release + +2008-12-03 Alex Tutubalin + * Imported dcraw 8.89 (version 1.407) + * New cameras: + Canon G10 & 5D Mk2, Leaf AFi 7, Leica D-LUX4, Panasonic FX150 & G1, + Fujifilm IS Pro, + * Changed camera support (color conversion tables): + Canon 50D, Nikon D90 & P6000, Panasonic LX3 & FZ28, Sony A900 + * LibRaw 0.6.2 beta + +2008-09-25 Alex Tutubalin + * Added new data field float LibRaw::imgdata.color.cam_xyz[4][3]. + This field contains constant table (different for each camera) for + Camera RGB->XYZ conversion. + * All client code should be recompiled + * LibRaw 0.6.1 Release + +2008-09-18 Alex Tutubalin + * dcraw 8.88 imported: + - new cameras (Canon 50D, Sony A900, Nikon D90 & P6000, + Panasonic LX3 FZ28) + - new method of black point subtraction for Canon cameras, + preliminary banding suppression. + * Stack memory usage lowered (some thread data moved to dynamic + memory) + * some patches for MSVC compatibility + * LibRaw 0.6.0 Release + +2008-09-16 Alex Tutubalin + * Enum definitions changed to make gcc -pedantic happy + * Compiler/preprocessor flags does not affects LibRaw class field set + (i.e. structure for thread local storage is always allocated) + * Default library compilation mode (i.e. sources imported in another + project) is thread-safe + +2008-09-14 Alex Tutubalin + * OpenMP support for most CPU consuming steps of processing: + ahd_interpolation. wavelet_denoise + 10-30% speed-up of full processing pipe on 2-core CPU + OpenMP supported only on gcc (Linux/FreeBSD and Mac OS X) + + * LibRaw 0.6.0-Beta-1 + +2008-09-10 Alex Tutubalin + * All set_**handler accepts additional void* pointer, which should point to + callback private data. This pointer passed to user callback when it called. + + * LibRaw 0.6.0-alpha5 + + * All client code should be recompiled + +2008-09-10 Alex Tutubalin + * New processing stages in enum LibRaw_progress: + LIBRAW_PROGRESS_BAD_PIXELS LIBRAW_PROGRESS_DARK_FRAME + (reserved stages LIBRAW_PROGRESS_RESERVED_PRE1-PRE2 has removed) + * libraw_strprogress() - convert progress code into string + + * Added progress/cancellation user callbacks + + new fatal error code: CANCELLED_BY_CALLBACK + + sample usage in samples/dcraw_emu.cpp (try run it with -v -v -v opts) + + * LibRaw 0.6.0-alpha4 + + * All client code should be recompiled + +2008-09-08 Alex Tutubalin + * ICC-profiles support (same as in dcraw) + + input/output profiles (specified as path to 'icc' file or 'embed' for + embedded input profile) + + additional warnings + + LCMS library used + + * support of bad pixel map (caller should specify path to bad pixel file + in dcraw-compatible format) + + * dark frame subtraction support (caller should supply path to 16-bit PGM + map). samples/simple_dcraw.cpp - -4 option added for dark frame file + generation + + * support of bad pixeld map (dcraw-compatible format) + + * the dcraw_emu sample supports all new features (ICC, dark frame, bad + pixels) + + * libraw/libraw_version.h, defines, calls and macros for version checks: + + LibRaw::version(), LibRaw::versionNumber(), LIBRAW_CHECK_VERSION() + + * List of supported cameras: + + LibRaw::cameraCount() + + LibRaw::cameraList() + + * fixed error in adjust_sizes_info_only + + * documentation changes + + * LibRaw 0.6.0-alpha3 + +2008-09-07 Alex Tutubalin + * samples/mem_image.c - bitwise equal output with dcraw -4 + (PPMs outputted with network byte order) + * LibRaw 0.6.0-alpha2 + +2008-09-06 Alex Tutubalin + * Added calls dcraw_make_mem_image and dcraw_make_mem_image: + + functions (and supporting code) + + documentation changed + + new sample code samples/mem_image.cpp + * Added processing parameter LibRaw::imgdata.params.gamma_16bit + (set to 1 to make gamma correction for 16-bit output) + * LibRaw 0.6.0-alpha1 + +2008-08-28 Alex Tutubalin + * dcraw 1.404 (8.87) imported: + - 6 new cameras supported (Canon 1000D, A720, SD300; + Nikon D700, Oly E-520,Kodak C603) + * Licensing changed to GPL v2 + +2008-05-02 Alex Tutubalin + * mmap/malloc+read IO-layer removed due to no performance gain. + FILE I/O returned + +2008-05-02 Alex Tutubalin + * dcraw 1.403 imported + - changes in ljpeg decompression (index values cut to 12 bit) + - changes in parse_foveon() jpeg thumbnail extraction + * LibRaw 0.5.3 released + +2008-04-24 Alex Tutubalin + * Linux build of samples/identify fixed + * documentation editorial + * LibRaw 0.5.2 released + +2008-04-21 Alex Tutubalin + * All documentation translated to English + * English changelog started :) + * minor bug (include path) fixed in samples/half_mt + * LibRaw 0.5.1 released diff --git a/DEVELOPER-NOTES b/DEVELOPER-NOTES new file mode 100644 index 000000000..1434d83bd --- /dev/null +++ b/DEVELOPER-NOTES @@ -0,0 +1,20 @@ + +=== Notes for LibRaw contributor === + +0. Repository + LibRaw public repository is located on GitHub + URL: + http://github.com/LibRaw/LibRaw - main page + git://github.com/LibRaw/LibRaw.git - git URL + +If you wish to participate in LibRaw development please use GitHub fork. + +LibRaw distribution files are prepared by ./mkdist.sh script + This script + - generates ./configure script from autotools stuff + - removes developer Makefile + - fetches 'Official' dcraw.c from Dave Coffin's site + - removes itself + +Feel free to contact us (info@libraw.org or Contact form on www.libraw.org) if +you have any questions or suggestions. diff --git a/GoPro/dng-sdk-1_4-allow-VC5-validate.diff b/GoPro/dng-sdk-1_4-allow-VC5-validate.diff new file mode 100644 index 000000000..354567e34 --- /dev/null +++ b/GoPro/dng-sdk-1_4-allow-VC5-validate.diff @@ -0,0 +1,21 @@ +diff --git a/source/dng_ifd.cpp b/source/dng_ifd.cpp +index 174f18f..2974323 100644 +--- a/source/dng_ifd.cpp ++++ b/source/dng_ifd.cpp +@@ -3168,6 +3168,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, + case ccUncompressed: + break; + ++ case 9: /* VC5 compression support */ + case ccJPEG: + { + +@@ -3202,7 +3203,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, + break; + + } +- ++ + case ccLossyJPEG: + { + diff --git a/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff b/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff new file mode 100644 index 000000000..63a2fba1e --- /dev/null +++ b/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff @@ -0,0 +1,15 @@ +diff --git a/gpr_sdk/private/gpr_read_image.cpp b/gpr_sdk/private/gpr_read_image.cpp +index c611b3f..9200a5b 100644 +--- a/gpr_sdk/private/gpr_read_image.cpp ++++ b/gpr_sdk/private/gpr_read_image.cpp +@@ -68,8 +68,10 @@ gpr_read_image::gpr_read_image( gpr_buffer_auto* vc5_buffer ) : _vc5_buffer(vc5_ + } + + #if GPR_WRITING || GPR_READING ++#ifndef qDNG_1_6 + const int ccVc5 = 9; // Vc5 compression type + #endif ++#endif + + void gpr_read_image::ReadTile (dng_host &host, + const dng_ifd &ifd, diff --git a/GoPro/dng-sdk-allow-VC5-validate.diff b/GoPro/dng-sdk-allow-VC5-validate.diff new file mode 100644 index 000000000..354567e34 --- /dev/null +++ b/GoPro/dng-sdk-allow-VC5-validate.diff @@ -0,0 +1,21 @@ +diff --git a/source/dng_ifd.cpp b/source/dng_ifd.cpp +index 174f18f..2974323 100644 +--- a/source/dng_ifd.cpp ++++ b/source/dng_ifd.cpp +@@ -3168,6 +3168,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, + case ccUncompressed: + break; + ++ case 9: /* VC5 compression support */ + case ccJPEG: + { + +@@ -3202,7 +3203,7 @@ bool dng_ifd::IsValidDNG (dng_shared &shared, + break; + + } +- ++ + case ccLossyJPEG: + { + diff --git a/GoPro/gpr_read_image.cpp.diff b/GoPro/gpr_read_image.cpp.diff new file mode 100644 index 000000000..1761abc01 --- /dev/null +++ b/GoPro/gpr_read_image.cpp.diff @@ -0,0 +1,29 @@ +--- gpr_read_image.cpp.orig 2019-08-30 12:20:00.326653300 +0300 ++++ gpr_read_image.cpp 2019-08-31 10:43:26.568184100 +0300 +@@ -67,6 +67,10 @@ + fDecodeVC5 = true; + } + + void gpr_read_image::ReadTile (dng_host &host, + const dng_ifd &ifd, + dng_stream &stream, +@@ -77,7 +81,8 @@ + uint32 tileByteCount, + AutoPtr &compressedBuffer, + AutoPtr &uncompressedBuffer, +- AutoPtr &subTileBlockBuffer) ++ AutoPtr &subTileBlockBuffer, ++ bool usingMultipleThreads) + { + + if( ifd.fCompression == ccVc5 ) +@@ -122,7 +127,8 @@ + tileByteCount, + compressedBuffer, + uncompressedBuffer, +- subTileBlockBuffer); ++ subTileBlockBuffer, ++ usingMultipleThreads); + } + } + diff --git a/GoPro/gpr_read_image.h.diff b/GoPro/gpr_read_image.h.diff new file mode 100644 index 000000000..413b55a51 --- /dev/null +++ b/GoPro/gpr_read_image.h.diff @@ -0,0 +1,12 @@ +--- gpr_read_image.h.orig 2019-08-30 12:20:00.326653300 +0300 ++++ gpr_read_image.h 2019-08-30 20:56:11.138246800 +0300 +@@ -56,7 +56,8 @@ + uint32 tileByteCount, + AutoPtr &compressedBuffer, + AutoPtr &uncompressedBuffer, +- AutoPtr &subTileBlockBuffer); ++ AutoPtr &subTileBlockBuffer, ++ bool usingMultipleThreads ); + }; + + #endif // GPR_READING diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..b575753d7 --- /dev/null +++ b/INSTALL @@ -0,0 +1,51 @@ + +========= Installing LibRaw ======== + +I. Installation steps + +1. Unpack the distribution file: + + $ tar xzvf LibRaw-0.xx.yy.tar.gz + +2. Go to LibRaw folder and run ./configure and make: + + $ cd LibRaw-0.xx.yy + $ ./configure [...optional args...] + $ make + +3. install by run make install as root: + + $ sudo make install + +If you're using Github snapshot, create ./configure script: + autoreconf --install +before using it (you'll need autotools installed). + +Alternatively, you may use pre-created Makefiles (Makefile.dist for Unix, +Makefile.msvc for Windows/VisualStudio) and add/remove options by editing +these Makefiles + + +II. ./configure options + +--enable-openmp +--disable-openmp + + Enable/disable OpenMP support if compiler supports it. + OpenMP is enabled by default. + + +--enable-lcms +--disable-lcms + + Enable/disable LCMS color engine support. If enabled, ./configure will try to + find lcms library. Both LCMS-1.x and LCMS-2.x are supported + LCMS support is enabled by default + + +--enable-examples +--disable-examples + + Enables/disables examples compilation and installation. Enabled by default + + diff --git a/LICENSE.CDDL b/LICENSE.CDDL new file mode 100644 index 000000000..8ee560c09 --- /dev/null +++ b/LICENSE.CDDL @@ -0,0 +1,340 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + +1. Definitions. + +1.1. Contributor means each individual or entity that creates or +contributes to the creation of Modifications. + +1.2. Contributor Version means the combination of the Original +Software, prior Modifications used by a Contributor (if any), +and the Modifications made by that particular Contributor. + +1.3. Covered Software means (a) the Original Software, or (b) +Modifications, or (c) the combination of files containing +Original Software with files containing Modifications, in each +case including portions thereof. + +1.4. Executable means the Covered Software in any form other +than Source Code. + +1.5. Initial Developer means the individual or entity that first +makes Original Software available under this License. + +1.6. Larger Workmeans a work which combines Covered Software or +portions thereof with code not governed by the terms of this +License. + +1.7. License means this document. + +1.8. Licensable means having the right to grant, to the maximum +extent possible, whether at the time of the initial grant or +subsequently acquired, any and all of the rights conveyed herein. + +1.9. Modifications means the Source Code and Executable form of +any of the following: A. Any file that results from an addition +to, deletion from or modification of the contents of a file +containing Original Software or previous Modifications; B. Any +new file that contains any part of the Original Software or +previous Modification; or C. Any new file that is contributed or +otherwise made available under the terms of this License. + +1.10. Original Software means the Source Code and Executable +form of computer software code that is originally released under +this License. + +1.11. Patent Claims means any patent claim(s), now owned or +hereafter acquired, including without limitation, method, +process, and apparatus claims, in any patent Licensable by +grantor. + +1.12. Source Code means (a) the common form of computer software +code in which modifications are made and (b) associated +documentation included in or with such code. + +1.13. You (or Your) means an individual or a legal entity +exercising rights under, and complying with all of the terms of, +this License. For legal entities, You includes any entity which +controls, is controlled by, or is under common control with You. +For purposes of this definition, control means (a) the power, +direct or indirect, to cause the direction or management of such +entity, whether by contract or otherwise, or (b) ownership of +more than fifty percent (50%) of the outstanding shares or +beneficial ownership of such entity. + +2. License Grants. + +2.1. The Initial Developer Grant. Conditioned upon Your +compliance with Section 3.1 below and subject to third party +intellectual property claims, the Initial Developer hereby +grants You a world-wide, royalty-free, non-exclusive license: + +(a) under intellectual property rights (other than patent or +trademark) Licensable by Initial Developer, to use, reproduce, +modify, display, perform, sublicense and distribute the Original +Software (or portions thereof), with or without Modifications, +and/or as part of a Larger Work; and + +(b) under Patent Claims infringed by the making, using or +selling of Original Software, to make, have made, use, practice, +sell, and offer for sale, and/or otherwise dispose of the +Original Software (or portions thereof); + +(c) The licenses granted in Sections 2.1(a) and (b) are +effective on the date Initial Developer first distributes or +otherwise makes the Original Software available to a third party +under the terms of this License; + +(d) Notwithstanding Section 2.1(b) above, no patent license is +granted: (1) for code that You delete from the Original +Software, or (2) for infringements caused by: (i) the +modification of the Original Software, or (ii) the combination +of the Original Software with other software or devices. + +2.2. Contributor Grant. Conditioned upon Your compliance with +Section 3.1 below and subject to third party intellectual +property claims, each Contributor hereby grants You a +world-wide, royalty-free, non-exclusive license: + +(a) under intellectual property rights (other than patent or +trademark) Licensable by Contributor to use, reproduce, modify, +display, perform, sublicense and distribute the Modifications +created by such Contributor (or portions thereof), either on an +unmodified basis, with other Modifications, as Covered Software +and/or as part of a Larger Work; and + +(b) under Patent Claims infringed by the making, using, or +selling of Modifications made by that Contributor either alone +and/or in combination with its Contributor Version (or portions +of such combination), to make, use, sell, offer for sale, have +made, and/or otherwise dispose of: (1) Modifications made by +that Contributor (or portions thereof); and (2) the combination +of Modifications made by that Contributor with its Contributor +Version (or portions of such combination). + +(c) The licenses granted in Sections 2.2(a) and 2.2(b) +areeffective on the date Contributor first distributes or +otherwise makes the Modifications available to a third party. + +(d) Notwithstanding Section 2.2(b) above, no patent license is +granted: (1) for any code that Contributor has deleted from the +Contributor Version; (2) for infringements caused by: (i) third +party modifications of Contributor Version, or (ii) the +combination of Modifications made by that Contributor with other +software (except as part of the Contributor Version) or other +devices; or (3) under Patent Claims infringed by Covered +Software in the absence of Modifications made by that +Contributor. + +3. Distribution Obligations. + +3.1. Availability of Source Code. Any Covered Software that You +distribute or otherwise make available in Executable form must +also be made available in Source Code form and that Source Code +form must be distributed only under the terms of this License. +You must include a copy of this License with every copy of the +Source Code form of the Covered Software You distribute or +otherwise make available. You must inform recipients of any such +Covered Software in Executable form as to how they can obtain +such Covered Software in Source Code form in a reasonable manner +on or through a medium customarily used for software exchange. + +3.2. Modifications. The Modifications that You create or to +which You contribute are governed by the terms of this License. +You represent that You believe Your Modifications are Your +original creation(s) and/or You have sufficient rights to grant +the rights conveyed by this License. + +3.3. Required Notices. You must include a notice in each of Your +Modifications that identifies You as the Contributor of the +Modification. You may not remove or alter any copyright, patent +or trademark notices contained within the Covered Software, or +any notices of licensing or any descriptive text giving +attribution to any Contributor or the Initial Developer. + +3.4. Application of Additional Terms. You may not offer or +impose any terms on any Covered Software in Source Code form +that alters or restricts the applicable version of this License +or the recipients rights hereunder. You may choose to offer, and +to charge a fee for, warranty, support, indemnity or liability +obligations to one or more recipients of Covered +Software. However, you may do so only on Your own behalf, and +not on behalf of the Initial Developer or any Contributor. You +must make it absolutely clear that any such warranty, support, +indemnity or liability obligation is offered by You alone, and +You hereby agree to indemnify the Initial Developer and every +Contributor for any liability incurred by the Initial Developer +or such Contributor as a result of warranty, support, indemnity +or liability terms You offer. + +3.5. Distribution of Executable Versions. You may distribute the +Executable form of the Covered Software under the terms of this +License or under the terms of a license of Your choice, which +may contain terms different from this License, provided that You +are in compliance with the terms of this License and that the +license for the Executable form does not attempt to limit or +alter the recipients rights in the Source Code form from the +rights set forth in this License. If You distribute the Covered +Software in Executable form under a different license, You must +make it absolutely clear that any terms which differ from this +License are offered by You alone, not by the Initial Developer +or Contributor. You hereby agree to indemnify the Initial +Developer and every Contributor for any liability incurred by +the Initial Developer or such Contributor as a result of any +such terms You offer. + +3.6. Larger Works. You may create a Larger Work by combining +Covered Software with other code not governed by the terms of +this License and distribute the Larger Work as a single product. +In such a case, You must make sure the requirements of this +License are fulfilled for the Covered Software. + +4. Versions of the License. + +4.1. New Versions. Sun Microsystems, Inc. is the initial license +steward and may publish revised and/or new versions of this +License from time to time. Each version will be given a +distinguishing version number. Except as provided in Section +4.3, no one other than the license steward has the right to +modify this License. + +4.2. Effect of New Versions. You may always continue to use, +distribute or otherwise make the Covered Software available +under the terms of the version of the License under which You +originally received the Covered Software. If the Initial +Developer includes a notice in the Original Software prohibiting +it from being distributed or otherwise made available under any +subsequent version of the License, You must distribute and make +the Covered Software available under the terms of the version of +the License under which You originally received the Covered +Software. Otherwise, You may also choose to use, distribute or +otherwise make the Covered Software available under the terms of +any subsequent version of the License published by the license +steward. + +4.3. Modified Versions. When You are an Initial Developer and +You want to create a new license for Your Original Software, You +may create and use a modified version of this License if You: +(a) rename the license and remove any references to the name of +the license steward (except to note that the license differs +from this License); and (b) otherwise make it clear that the +license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. COVERED SOFTWARE IS PROVIDED UNDER +THIS LICENSE ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, +WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, +MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. +THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE +DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY +OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, +REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN +ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE +IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will +terminate automatically if You fail to comply with terms herein +and fail to cure such breach within 30 days of becoming aware of +the breach. Provisions which, by their nature, must remain in +effect beyond the termination of this License shall survive. + +6.2. If You assert a patent infringement claim (excluding +declaratory judgment actions) against Initial Developer or a +Contributor (the Initial Developer or Contributor against whom +You assert such claim is referred to as Participant) alleging +that the Participant Software (meaning the Contributor Version +where the Participant is a Contributor or the Original Software +where the Participant is the Initial Developer) directly or +indirectly infringes any patent, then any and all rights granted +directly or indirectly to You by such Participant, the Initial +Developer (if the Initial Developer is not the Participant) and +all Contributors under Sections 2.1 and/or 2.2 of this License +shall, upon 60 days notice from Participant terminate +prospectively and automatically at the expiration of such 60 day +notice period, unless if within such 60 day period You withdraw +Your claim with respect to the Participant Software against such +Participant either unilaterally or pursuant to a written +agreement with Participant. + +6.3. In the event of termination under Sections 6.1 or 6.2 +above, all end user licenses that have been validly granted by +You or any distributor hereunder prior to termination (excluding +licenses granted to You by any distributor) shall survive +termination. + +7. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO +LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR +OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER +CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY +SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY +INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY +CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST +PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR +MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, +EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY +OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO +LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH +PARTYS NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH +LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR +LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS +EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. The Covered Software is a +commercial item, as that term is defined in 48 C.F.R. 2.101 +(Oct. 1995), consisting of commercial computer software (as that +term is defined at 48 C.F.R. 252.227-7014(a)(1)) and commercial +computer software documentation as such terms are used in 48 +C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and +48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all +U.S. Government End Users acquire Covered Software with only +those rights set forth herein. This U.S. Government Rights +clause is in lieu of, and supersedes, any other FAR, DFAR, or +other clause or provision that addresses Government rights in +computer software under this License. + +9. MISCELLANEOUS. This License represents the complete agreement +concerning subject matter hereof. If any provision of this +License is held to be unenforceable, such provision shall be +reformed only to the extent necessary to make it enforceable. +This License shall be governed by the law of the jurisdiction +specified in a notice contained within the Original Software +(except to the extent applicable law, if any, provides +otherwise), excluding such jurisdictions conflict-of-law +provisions. Any litigation relating to this License shall be +subject to the jurisdiction of the courts located in the +jurisdiction and venue specified in a notice contained within +the Original Software, with the losing party responsible for +costs, including, without limitation, court costs and reasonable +attorneys fees and expenses. The application of the United +Nations Convention on Contracts for the International Sale of +Goods is expressly excluded. Any law or regulation which +provides that the language of a contract shall be construed +against the drafter shall not apply to this License. You agree +that You alone are responsible for compliance with the United +States export administration regulations (and the export control +laws and regulation of any other countries) when You use, +distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and +the Contributors, each party is responsible for claims and +damages arising, directly or indirectly, out of its utilization +of rights under this License and You agree to work with Initial +Developer and Contributors to distribute such responsibility on +an equitable basis. Nothing herein is intended or shall be +deemed to constitute any admission of liability. + +---------------------------------------------------------------- + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND +DISTRIBUTION LICENSE (CDDL): This code is released under the +CDDL and shall be governed by the laws of the State of +California (excluding conflict-of-law provisions). Any +litigation relating to this License shall be subject to the +jurisdiction of the Federal Courts of the Northern District of +California and the state courts of the State of California, with +venue lying in Santa Clara County, California. + +---------------------------------------------------------------- + diff --git a/LICENSE.LGPL b/LICENSE.LGPL new file mode 100644 index 000000000..3b204400c --- /dev/null +++ b/LICENSE.LGPL @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/LibRaw.pro b/LibRaw.pro new file mode 100644 index 000000000..09cda53c6 --- /dev/null +++ b/LibRaw.pro @@ -0,0 +1,19 @@ +TEMPLATE=subdirs +CONFIG+=ordered +SUBDIRS= \ + buildfiles/dcraw_emu.pro \ + buildfiles/libraw.pro \ + buildfiles/postprocessing_benchmark.pro \ + buildfiles/dcraw_half.pro \ +# buildfiles/half_mt.pro \ + buildfiles/mem_image.pro \ + buildfiles/raw-identify.pro \ + buildfiles/simple_dcraw.pro \ + buildfiles/multirender_test.pro \ + buildfiles/unprocessed_raw.pro \ + buildfiles/4channels.pro \ + buildfiles/rawtextdump.pro \ + buildfiles/openbayer_sample.pro + +CONFIG-=qt + diff --git a/LibRaw.sln b/LibRaw.sln new file mode 100644 index 000000000..405887b69 --- /dev/null +++ b/LibRaw.sln @@ -0,0 +1,123 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcraw_emu", "buildfiles\dcraw_emu.vcxproj", "{48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libraw", "buildfiles\libraw.vcxproj", "{A71D2131-F425-381F-8A9A-29D60132A046}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "postprocessing_benchmark", "buildfiles\postprocessing_benchmark.vcxproj", "{5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dcraw_half", "buildfiles\dcraw_half.vcxproj", "{C6EACFA3-9FC5-393B-BCF6-2874B05E4581}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mem_image", "buildfiles\mem_image.vcxproj", "{BF8A2750-B847-3BA6-9EAF-05F43380F46C}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raw-identify", "buildfiles\raw-identify.vcxproj", "{7C4F61DB-717E-36C9-B20E-36F8E218AB51}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_dcraw", "buildfiles\simple_dcraw.vcxproj", "{AD1E31D8-A022-3672-982F-C8280A0D6458}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multirender_test", "buildfiles\multirender_test.vcxproj", "{30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unprocessed_raw", "buildfiles\unprocessed_raw.vcxproj", "{1333E21E-D3B5-3640-9A4D-D8955082B855}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "4channels", "buildfiles\4channels.vcxproj", "{F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rawtextdump", "buildfiles\rawtextdump.vcxproj", "{53A1E3F0-8032-348E-B3BF-3E540A45005F}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openbayer_sample", "buildfiles\openbayer_sample.vcxproj", "{EF67FEF1-4B19-3765-A660-9F8E9333DEF3}" + ProjectSection(ProjectDependencies) = postProject + {A71D2131-F425-381F-8A9A-29D60132A046} = {A71D2131-F425-381F-8A9A-29D60132A046} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Debug|x64.ActiveCfg = Debug|x64 + {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Debug|x64.Build.0 = Debug|x64 + {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Release|x64.ActiveCfg = Release|x64 + {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2}.Release|x64.Build.0 = Release|x64 + {A71D2131-F425-381F-8A9A-29D60132A046}.Debug|x64.ActiveCfg = Debug|x64 + {A71D2131-F425-381F-8A9A-29D60132A046}.Debug|x64.Build.0 = Debug|x64 + {A71D2131-F425-381F-8A9A-29D60132A046}.Release|x64.ActiveCfg = Release|x64 + {A71D2131-F425-381F-8A9A-29D60132A046}.Release|x64.Build.0 = Release|x64 + {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Debug|x64.ActiveCfg = Debug|x64 + {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Debug|x64.Build.0 = Debug|x64 + {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Release|x64.ActiveCfg = Release|x64 + {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC}.Release|x64.Build.0 = Release|x64 + {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Debug|x64.ActiveCfg = Debug|x64 + {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Debug|x64.Build.0 = Debug|x64 + {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Release|x64.ActiveCfg = Release|x64 + {C6EACFA3-9FC5-393B-BCF6-2874B05E4581}.Release|x64.Build.0 = Release|x64 + {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Debug|x64.ActiveCfg = Debug|x64 + {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Debug|x64.Build.0 = Debug|x64 + {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Release|x64.ActiveCfg = Release|x64 + {BF8A2750-B847-3BA6-9EAF-05F43380F46C}.Release|x64.Build.0 = Release|x64 + {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Debug|x64.ActiveCfg = Debug|x64 + {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Debug|x64.Build.0 = Debug|x64 + {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Release|x64.ActiveCfg = Release|x64 + {7C4F61DB-717E-36C9-B20E-36F8E218AB51}.Release|x64.Build.0 = Release|x64 + {AD1E31D8-A022-3672-982F-C8280A0D6458}.Debug|x64.ActiveCfg = Debug|x64 + {AD1E31D8-A022-3672-982F-C8280A0D6458}.Debug|x64.Build.0 = Debug|x64 + {AD1E31D8-A022-3672-982F-C8280A0D6458}.Release|x64.ActiveCfg = Release|x64 + {AD1E31D8-A022-3672-982F-C8280A0D6458}.Release|x64.Build.0 = Release|x64 + {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Debug|x64.ActiveCfg = Debug|x64 + {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Debug|x64.Build.0 = Debug|x64 + {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Release|x64.ActiveCfg = Release|x64 + {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73}.Release|x64.Build.0 = Release|x64 + {1333E21E-D3B5-3640-9A4D-D8955082B855}.Debug|x64.ActiveCfg = Debug|x64 + {1333E21E-D3B5-3640-9A4D-D8955082B855}.Debug|x64.Build.0 = Debug|x64 + {1333E21E-D3B5-3640-9A4D-D8955082B855}.Release|x64.ActiveCfg = Release|x64 + {1333E21E-D3B5-3640-9A4D-D8955082B855}.Release|x64.Build.0 = Release|x64 + {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Debug|x64.ActiveCfg = Debug|x64 + {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Debug|x64.Build.0 = Debug|x64 + {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Release|x64.ActiveCfg = Release|x64 + {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52}.Release|x64.Build.0 = Release|x64 + {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Debug|x64.ActiveCfg = Debug|x64 + {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Debug|x64.Build.0 = Debug|x64 + {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Release|x64.ActiveCfg = Release|x64 + {53A1E3F0-8032-348E-B3BF-3E540A45005F}.Release|x64.Build.0 = Release|x64 + {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Debug|x64.ActiveCfg = Debug|x64 + {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Debug|x64.Build.0 = Debug|x64 + {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Release|x64.ActiveCfg = Release|x64 + {EF67FEF1-4B19-3765-A660-9F8E9333DEF3}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FB319846-66B9-4F61-8285-5EA4D2F09634} + EndGlobalSection +EndGlobal diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..19166b75e --- /dev/null +++ b/Makefile.am @@ -0,0 +1,140 @@ +# autoconf macros +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS=subdir-objects + +LIBRAW_SHLIB_VER = @LIBRAW_SHLIB_VERSION@ +LIBRAW_RELEASE_VER = @LIBRAW_RELEASE_VERSION@ + +# Headers +nobase_include_HEADERS = libraw/libraw.h \ + libraw/libraw_alloc.h \ + libraw/libraw_const.h \ + libraw/libraw_datastream.h \ + libraw/libraw_internal.h \ + libraw/libraw_types.h \ + libraw/libraw_version.h + +# Docs +doc_DATA = COPYRIGHT \ + LICENSE.CDDL \ + LICENSE.LGPL \ + Changelog.txt + +# pkg-config .pc files +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libraw.pc libraw_r.pc + +# Libraries +lib_LTLIBRARIES = lib/libraw.la lib/libraw_r.la + +lib_libraw_a_CPPFLAGS = -DLIBRAW_NOTHREADS -w +lib_libraw_a_SOURCES = src/libraw_c_api.cpp \ + src/libraw_datastream.cpp src/decoders/canon_600.cpp \ + src/decoders/crx.cpp src/decoders/decoders_dcraw.cpp \ + src/decoders/decoders_libraw_dcrdefs.cpp \ + src/decoders/decoders_libraw.cpp src/decoders/dng.cpp \ + src/decoders/fp_dng.cpp src/decoders/fuji_compressed.cpp \ + src/decoders/generic.cpp src/decoders/kodak_decoders.cpp \ + src/decoders/load_mfbacks.cpp src/decoders/smal.cpp \ + src/decoders/unpack_thumb.cpp src/decoders/unpack.cpp \ + src/demosaic/aahd_demosaic.cpp src/demosaic/ahd_demosaic.cpp \ + src/demosaic/dcb_demosaic.cpp src/demosaic/dht_demosaic.cpp \ + src/demosaic/misc_demosaic.cpp src/demosaic/xtrans_demosaic.cpp \ + src/integration/dngsdk_glue.cpp src/integration/rawspeed_glue.cpp\ + src/metadata/adobepano.cpp src/metadata/canon.cpp \ + src/metadata/ciff.cpp src/metadata/cr3_parser.cpp \ + src/metadata/epson.cpp src/metadata/exif_gps.cpp \ + src/metadata/fuji.cpp src/metadata/identify_tools.cpp \ + src/metadata/identify.cpp src/metadata/kodak.cpp \ + src/metadata/leica.cpp src/metadata/makernotes.cpp \ + src/metadata/mediumformat.cpp src/metadata/minolta.cpp \ + src/metadata/misc_parsers.cpp src/metadata/nikon.cpp \ + src/metadata/normalize_model.cpp src/metadata/olympus.cpp \ + src/metadata/hasselblad_model.cpp \ + src/metadata/p1.cpp src/metadata/pentax.cpp src/metadata/samsung.cpp \ + src/metadata/sony.cpp src/metadata/tiff.cpp \ + src/postprocessing/aspect_ratio.cpp \ + src/postprocessing/dcraw_process.cpp src/postprocessing/mem_image.cpp \ + src/postprocessing/postprocessing_aux.cpp \ + src/postprocessing/postprocessing_utils_dcrdefs.cpp \ + src/postprocessing/postprocessing_utils.cpp \ + src/preprocessing/ext_preprocess.cpp src/preprocessing/raw2image.cpp \ + src/preprocessing/subtract_black.cpp src/tables/cameralist.cpp \ + src/tables/colorconst.cpp src/tables/colordata.cpp \ + src/tables/wblists.cpp src/utils/curves.cpp \ + src/utils/decoder_info.cpp src/utils/init_close_utils.cpp \ + src/utils/open.cpp src/utils/phaseone_processing.cpp \ + src/utils/read_utils.cpp src/utils/thumb_utils.cpp \ + src/utils/utils_dcraw.cpp src/utils/utils_libraw.cpp \ + src/write/apply_profile.cpp src/write/file_write.cpp \ + src/write/tiff_writer.cpp src/x3f/x3f_parse_process.cpp \ + src/x3f/x3f_utils_patched.cpp + + +lib_libraw_r_a_CXXFLAGS = -pthread -w +lib_libraw_r_a_CFLAGS = -pthread -w +lib_libraw_la_SOURCES = $(lib_libraw_a_SOURCES) +lib_libraw_r_la_SOURCES = $(lib_libraw_a_SOURCES) + +lib_libraw_la_LDFLAGS = -no-undefined -version-info $(LIBRAW_SHLIB_VER) +lib_libraw_r_la_LDFLAGS = -no-undefined -version-info $(LIBRAW_SHLIB_VER) + + +# Sample binaries +if EXAMPLES +bin_PROGRAMS = bin/raw-identify \ + bin/unprocessed_raw \ + bin/4channels \ + bin/rawtextdump \ + bin/simple_dcraw \ + bin/mem_image \ + bin/dcraw_half \ + bin/half_mt \ + bin/multirender_test \ + bin/postprocessing_benchmark \ + bin/dcraw_emu +endif + +bin_raw_identify_SOURCES = samples/raw-identify.cpp +bin_raw_identify_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_raw_identify_LDADD = lib/libraw.la + +bin_unprocessed_raw_SOURCES = samples/unprocessed_raw.cpp +bin_unprocessed_raw_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_unprocessed_raw_LDADD = lib/libraw.la + +bin_rawtextdump_SOURCES = samples/rawtextdump.cpp +bin_rawtextdump_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_rawtextdump_LDADD = lib/libraw.la + +bin_4channels_SOURCES = samples/4channels.cpp +bin_4channels_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_4channels_LDADD = lib/libraw.la + +bin_simple_dcraw_SOURCES = samples/simple_dcraw.cpp +bin_simple_dcraw_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_simple_dcraw_LDADD = lib/libraw.la + +bin_multirender_test_SOURCES = samples/multirender_test.cpp +bin_multirender_test_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_multirender_test_LDADD = lib/libraw.la + +bin_postprocessing_benchmark_SOURCES = samples/postprocessing_benchmark.cpp +bin_postprocessing_benchmark_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_postprocessing_benchmark_LDADD = lib/libraw.la + +bin_mem_image_SOURCES = samples/mem_image_sample.cpp +bin_mem_image_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_mem_image_LDADD = lib/libraw.la + +bin_dcraw_half_SOURCES = samples/dcraw_half.c +bin_dcraw_half_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_dcraw_half_LDADD = lib/libraw.la + +bin_half_mt_SOURCES = samples/half_mt.c +bin_half_mt_CFLAGS = $(lib_libraw_r_a_CXXFLAGS) +bin_half_mt_LDADD = lib/libraw_r.la + +bin_dcraw_emu_SOURCES = samples/dcraw_emu.cpp +bin_dcraw_emu_CPPFLAGS = $(lib_libraw_a_CPPFLAGS) +bin_dcraw_emu_LDADD = lib/libraw.la diff --git a/Makefile.devel b/Makefile.devel new file mode 100644 index 000000000..f82c007e5 --- /dev/null +++ b/Makefile.devel @@ -0,0 +1,496 @@ +all: library all_samples + +CC=clang +CXX=clang++ + +#CC=gcc +#CXX=g++ + +LDADD+=-lz + +CFLAGS=-DLIBRAW_USE_AUTOPTR +CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 + +# macOS dual arch +# CFLAGS+=-arch x86_64 -arch arm64 + +# RawSpeed Support +# CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 +# LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 +# RAWSPEED_DATA=../RawSpeed/data/cameras.xml + +# RawSpeed3 Support +#CFLAGS+=-DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS -I./RawSpeed3/ +#LDADD+=-L../RawSpeed-v3/release -lrawspeed3 -L/usr/local/lib -ljpeg -lz + + +# DNG SDK Support +# CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source +# LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz + +# LCMS support +# For lcms2 set -DUSE_LCMS2 +#CFLAGS+=-DUSE_LCMS2 -I/opt/local/include +#LDADD+=-L/opt/local/lib -llcms + +# Jasper support for RedCine +#CFLAGS+=-DUSE_JASPER -I/opt/local/include +#LDADD+=-L/opt/local/lib -ljasper + +# ZLIB support (FP dng) +CFLAGS+=-DUSE_ZLIB +LDADD+=-lz + +# JPEG support for DNG and Kodak +CFLAGS+=-DUSE_JPEG -I/usr/local/include +LDADD+=-L/usr/local/lib -ljpeg + +# LIBJPEG8: +CFLAGS+=-DUSE_JPEG8 + +CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS +HEADERS=libraw/libraw.h libraw/libraw_alloc.h libraw/libraw_const.h \ + libraw/libraw_datastream.h libraw/libraw_internal.h \ + libraw/libraw_types.h libraw/libraw_version.h \ + internal/dcraw_defs.h internal/dcraw_fileio_defs.h internal/defines.h \ + internal/dmp_include.h internal/libraw_cameraids.h internal/libraw_cxx_defs.h \ + internal/libraw_internal_funcs.h internal/var_defines.h internal/x3f_tools.h + +LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ + object/cameralist.o object/fuji_compressed.o \ + object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/unpack.o object/unpack_thumb.o \ + object/rawspeed_glue.o object/dngsdk_glue.o \ + object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ + object/decoder_info.o object/open.o object/phaseone_processing.o \ + object/thumb_utils.o \ + object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ + object/dcraw_process.o object/raw2image.o object/mem_image.o \ + object/x3f_utils_patched.o object/x3f_parse_process.o \ + object/read_utils.o object/curves.o object/utils_dcraw.o \ + object/colordata.o \ + object/canon_600.o object/decoders_dcraw.o \ + object/decoders_libraw_dcrdefs.o object/generic.o \ + object/kodak_decoders.o object/dng.o object/smal.o \ + object/load_mfbacks.o \ + object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ + object/canon.o object/epson.o object/olympus.o object/leica.o \ + object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ + object/makernotes.o object/exif_gps.o object/kodak.o \ + object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ + object/identify_tools.o \ + object/hasselblad_model.o object/normalize_model.o object/identify.o \ + object/misc_parsers.o object/wblists.o \ + object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ + object/aspect_ratio.o \ + object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ + object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ + object/file_write.o \ + object/ext_preprocess.o object/apply_profile.o + + +LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ + object/cameralist.mt.o object/fuji_compressed.mt.o \ + object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ + object/unpack.mt.o object/unpack_thumb.mt.o \ + object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ + object/colorconst.mt.o object/utils_libraw.mt.o \ + object/init_close_utils.mt.o \ + object/decoder_info.mt.o object/open.mt.o object/phaseone_processing.mt.o \ + object/thumb_utils.mt.o \ + object/tiff_writer.mt.o object/subtract_black.mt.o \ + object/postprocessing_utils.mt.o object/dcraw_process.mt.o \ + object/raw2image.mt.o object/mem_image.mt.o \ + object/x3f_utils_patched.mt.o object/x3f_parse_process.mt.o \ + object/read_utils.mt.o object/curves.mt.o object/utils_dcraw.mt.o \ + object/colordata.mt.o \ + object/canon_600.mt.o object/decoders_dcraw.mt.o \ + object/decoders_libraw_dcrdefs.mt.o object/generic.mt.o \ + object/kodak_decoders.mt.o object/dng.mt.o object/smal.mt.o \ + object/load_mfbacks.mt.o \ + object/sony.mt.o object/nikon.mt.o object/samsung.mt.o \ + object/cr3_parser.mt.o object/canon.mt.o object/epson.mt.o \ + object/olympus.mt.o object/leica.mt.o \ + object/fuji.mt.o object/adobepano.mt.o object/pentax.mt.o object/p1.mt.o \ + object/makernotes.mt.o object/exif_gps.mt.o object/kodak.mt.o \ + object/tiff.mt.o object/ciff.mt.o object/mediumformat.mt.o \ + object/minolta.mt.o \ + object/identify_tools.mt.o \ + object/hasselblad_model.mt.o object/normalize_model.mt.o object/identify.mt.o \ + object/misc_parsers.mt.o object/wblists.mt.o \ + object/postprocessing_aux.mt.o object/postprocessing_utils_dcrdefs.mt.o \ + object/aspect_ratio.mt.o \ + object/misc_demosaic.mt.o object/xtrans_demosaic.mt.o \ + object/ahd_demosaic.mt.o object/dht_demosaic.mt.o \ + object/aahd_demosaic.mt.o object/dcb_demosaic.mt.o \ + object/file_write.mt.o \ + object/ext_preprocess.mt.o object/apply_profile.mt.o + + +LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ + libraw/libraw_const.h libraw/libraw_datastream.h \ + libraw/libraw_internal.h libraw/libraw_types.h \ + libraw/libraw_version.h + +library: lib/libraw.a lib/libraw_r.a + +all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu \ + bin/dcraw_half bin/half_mt bin/mem_image \ + bin/unprocessed_raw bin/4channels bin/multirender_test \ + bin/postprocessing_benchmark bin/rawtextdump + +## RawSpeed xml file + +RawSpeed/rawspeed_xmldata.cpp: ${RAWSPEED_DATA} + ./rsxml2c.sh ${RAWSPEED_DATA} > RawSpeed/rawspeed_xmldata.cpp + +## Samples ## +bin/raw-identify: lib/libraw.a samples/raw-identify.cpp $(HEADERS) + $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lm ${LDADD} + +bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp $(HEADERS) + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lm ${LDADD} + +bin/multirender_test: lib/libraw.a samples/multirender_test.cpp $(HEADERS) + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lm ${LDADD} + +bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp $(HEADERS) + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lm ${LDADD} + +bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp $(HEADERS) + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lm ${LDADD} + +bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp $(HEADERS) + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lm ${LDADD} + +bin/4channels: lib/libraw.a samples/4channels.cpp $(HEADERS) + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lm ${LDADD} + +bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp $(HEADERS) + $(CXX) ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lm ${LDADD} + +bin/dcraw_half: lib/libraw.a samples/dcraw_half.c $(HEADERS) + $(CC) ${CFLAGS} -o bin/dcraw_half samples/dcraw_half.c -L./lib -lraw -lm -lstdc++ ${LDADD} + +bin/half_mt: lib/libraw_r.a samples/half_mt.c $(HEADERS) + $(CC) -pthread ${CFLAGS} -o bin/half_mt samples/half_mt.c -L./lib -lraw_r -lm -lstdc++ ${LDADD} + +bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp $(HEADERS) + $(CXX) ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw_r -lm ${LDADD} + +lib/libraw.a: ${LIB_OBJECTS} + rm -f lib/libraw.a + ar crv lib/libraw.a ${LIB_OBJECTS} + ranlib lib/libraw.a + +lib/libraw_r.a: ${LIB_MT_OBJECTS} + rm -f lib/libraw_r.a + ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} + ranlib lib/libraw_r.a + +clean: + rm -fr bin/*.dSYM + rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o object/*.mto dcraw/*~ doc/*~ bin/*~ src/*/*~ + +## script-created rules +object/libraw_c_api.o: src/libraw_c_api.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp +object/libraw_c_api.mt.o: src/libraw_c_api.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/libraw_c_api.mt.o src/libraw_c_api.cpp + +object/libraw_datastream.o: src/libraw_datastream.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp +object/libraw_datastream.mt.o: src/libraw_datastream.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/libraw_datastream.mt.o src/libraw_datastream.cpp +object/canon_600.o: src/decoders/canon_600.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp +object/canon_600.mt.o: src/decoders/canon_600.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/canon_600.mt.o src/decoders/canon_600.cpp +object/crx.o: src/decoders/crx.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/crx.mt.o: src/decoders/crx.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp +object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp +object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/decoders_dcraw.mt.o src/decoders/decoders_dcraw.cpp +object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw_dcrdefs.mt.o: src/decoders/decoders_libraw_dcrdefs.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/decoders_libraw_dcrdefs.mt.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw.o: src/decoders/decoders_libraw.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp +object/decoders_libraw.mt.o: src/decoders/decoders_libraw.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/decoders_libraw.mt.o src/decoders/decoders_libraw.cpp +object/dng.o: src/decoders/dng.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp +object/dng.mt.o: src/decoders/dng.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/dng.mt.o src/decoders/dng.cpp +object/fp_dng.o: src/decoders/fp_dng.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp +object/fp_dng.mt.o: src/decoders/fp_dng.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/fp_dng.mt.o src/decoders/fp_dng.cpp +object/fuji_compressed.o: src/decoders/fuji_compressed.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp +object/fuji_compressed.mt.o: src/decoders/fuji_compressed.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/fuji_compressed.mt.o src/decoders/fuji_compressed.cpp +object/generic.o: src/decoders/generic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp +object/generic.mt.o: src/decoders/generic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/generic.mt.o src/decoders/generic.cpp +object/kodak_decoders.o: src/decoders/kodak_decoders.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp +object/kodak_decoders.mt.o: src/decoders/kodak_decoders.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/kodak_decoders.mt.o src/decoders/kodak_decoders.cpp +object/load_mfbacks.o: src/decoders/load_mfbacks.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp +object/load_mfbacks.mt.o: src/decoders/load_mfbacks.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/load_mfbacks.mt.o src/decoders/load_mfbacks.cpp +object/smal.o: src/decoders/smal.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp +object/smal.mt.o: src/decoders/smal.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/smal.mt.o src/decoders/smal.cpp +object/unpack_thumb.o: src/decoders/unpack_thumb.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp +object/unpack_thumb.mt.o: src/decoders/unpack_thumb.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/unpack_thumb.mt.o src/decoders/unpack_thumb.cpp +object/unpack.o: src/decoders/unpack.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp +object/unpack.mt.o: src/decoders/unpack.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/unpack.mt.o src/decoders/unpack.cpp +object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp +object/aahd_demosaic.mt.o: src/demosaic/aahd_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/aahd_demosaic.mt.o src/demosaic/aahd_demosaic.cpp +object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp +object/ahd_demosaic.mt.o: src/demosaic/ahd_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/ahd_demosaic.mt.o src/demosaic/ahd_demosaic.cpp +object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp +object/dcb_demosaic.mt.o: src/demosaic/dcb_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/dcb_demosaic.mt.o src/demosaic/dcb_demosaic.cpp +object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp +object/dht_demosaic.mt.o: src/demosaic/dht_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/dht_demosaic.mt.o src/demosaic/dht_demosaic.cpp +object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp +object/misc_demosaic.mt.o: src/demosaic/misc_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/misc_demosaic.mt.o src/demosaic/misc_demosaic.cpp +object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp +object/xtrans_demosaic.mt.o: src/demosaic/xtrans_demosaic.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/xtrans_demosaic.mt.o src/demosaic/xtrans_demosaic.cpp +object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp +object/dngsdk_glue.mt.o: src/integration/dngsdk_glue.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/dngsdk_glue.mt.o src/integration/dngsdk_glue.cpp +object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp +object/rawspeed_glue.mt.o: src/integration/rawspeed_glue.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/rawspeed_glue.mt.o src/integration/rawspeed_glue.cpp +object/adobepano.o: src/metadata/adobepano.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp +object/adobepano.mt.o: src/metadata/adobepano.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/adobepano.mt.o src/metadata/adobepano.cpp +object/canon.o: src/metadata/canon.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp +object/canon.mt.o: src/metadata/canon.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/canon.mt.o src/metadata/canon.cpp +object/ciff.o: src/metadata/ciff.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp +object/ciff.mt.o: src/metadata/ciff.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/ciff.mt.o src/metadata/ciff.cpp +object/cr3_parser.o: src/metadata/cr3_parser.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp +object/cr3_parser.mt.o: src/metadata/cr3_parser.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/cr3_parser.mt.o src/metadata/cr3_parser.cpp +object/epson.o: src/metadata/epson.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp +object/epson.mt.o: src/metadata/epson.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/epson.mt.o src/metadata/epson.cpp +object/exif_gps.o: src/metadata/exif_gps.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp +object/exif_gps.mt.o: src/metadata/exif_gps.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/exif_gps.mt.o src/metadata/exif_gps.cpp +object/fuji.o: src/metadata/fuji.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp +object/fuji.mt.o: src/metadata/fuji.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/fuji.mt.o src/metadata/fuji.cpp +object/identify_tools.o: src/metadata/identify_tools.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp +object/identify_tools.mt.o: src/metadata/identify_tools.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/identify_tools.mt.o src/metadata/identify_tools.cpp +object/identify.o: src/metadata/identify.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp +object/identify.mt.o: src/metadata/identify.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/identify.mt.o src/metadata/identify.cpp +object/kodak.o: src/metadata/kodak.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp +object/kodak.mt.o: src/metadata/kodak.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/kodak.mt.o src/metadata/kodak.cpp +object/leica.o: src/metadata/leica.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp +object/leica.mt.o: src/metadata/leica.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/leica.mt.o src/metadata/leica.cpp +object/makernotes.o: src/metadata/makernotes.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp +object/makernotes.mt.o: src/metadata/makernotes.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/makernotes.mt.o src/metadata/makernotes.cpp +object/mediumformat.o: src/metadata/mediumformat.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp +object/mediumformat.mt.o: src/metadata/mediumformat.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/mediumformat.mt.o src/metadata/mediumformat.cpp +object/minolta.o: src/metadata/minolta.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp +object/minolta.mt.o: src/metadata/minolta.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/minolta.mt.o src/metadata/minolta.cpp +object/misc_parsers.o: src/metadata/misc_parsers.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp +object/misc_parsers.mt.o: src/metadata/misc_parsers.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/misc_parsers.mt.o src/metadata/misc_parsers.cpp +object/nikon.o: src/metadata/nikon.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp +object/nikon.mt.o: src/metadata/nikon.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/nikon.mt.o src/metadata/nikon.cpp +object/hasselblad_model.o: src/metadata/hasselblad_model.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp +object/hasselblad_model.mt.o: src/metadata/hasselblad_model.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/hasselblad_model.mt.o src/metadata/hasselblad_model.cpp +object/normalize_model.o: src/metadata/normalize_model.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp +object/normalize_model.mt.o: src/metadata/normalize_model.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/normalize_model.mt.o src/metadata/normalize_model.cpp +object/olympus.o: src/metadata/olympus.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp +object/olympus.mt.o: src/metadata/olympus.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/olympus.mt.o src/metadata/olympus.cpp +object/p1.o: src/metadata/p1.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp +object/p1.mt.o: src/metadata/p1.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/p1.mt.o src/metadata/p1.cpp +object/pentax.o: src/metadata/pentax.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp +object/pentax.mt.o: src/metadata/pentax.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/pentax.mt.o src/metadata/pentax.cpp +object/samsung.o: src/metadata/samsung.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp +object/samsung.mt.o: src/metadata/samsung.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/samsung.mt.o src/metadata/samsung.cpp +object/sony.o: src/metadata/sony.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp +object/sony.mt.o: src/metadata/sony.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/sony.mt.o src/metadata/sony.cpp +object/tiff.o: src/metadata/tiff.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp +object/tiff.mt.o: src/metadata/tiff.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/tiff.mt.o src/metadata/tiff.cpp +object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp +object/aspect_ratio.mt.o: src/postprocessing/aspect_ratio.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/aspect_ratio.mt.o src/postprocessing/aspect_ratio.cpp +object/dcraw_process.o: src/postprocessing/dcraw_process.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp +object/dcraw_process.mt.o: src/postprocessing/dcraw_process.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/dcraw_process.mt.o src/postprocessing/dcraw_process.cpp +object/mem_image.o: src/postprocessing/mem_image.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp +object/mem_image.mt.o: src/postprocessing/mem_image.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/mem_image.mt.o src/postprocessing/mem_image.cpp +object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp +object/postprocessing_aux.mt.o: src/postprocessing/postprocessing_aux.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/postprocessing_aux.mt.o src/postprocessing/postprocessing_aux.cpp +object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp +object/postprocessing_utils_dcrdefs.mt.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/postprocessing_utils_dcrdefs.mt.o src/postprocessing/postprocessing_utils_dcrdefs.cpp +object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp +object/postprocessing_utils.mt.o: src/postprocessing/postprocessing_utils.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/postprocessing_utils.mt.o src/postprocessing/postprocessing_utils.cpp +object/raw2image.o: src/preprocessing/raw2image.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp +object/raw2image.mt.o: src/preprocessing/raw2image.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/raw2image.mt.o src/preprocessing/raw2image.cpp +object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp +object/ext_preprocess.mt.o: src/preprocessing/ext_preprocess.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/ext_preprocess.mt.o src/preprocessing/ext_preprocess.cpp +object/subtract_black.o: src/preprocessing/subtract_black.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp +object/subtract_black.mt.o: src/preprocessing/subtract_black.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/subtract_black.mt.o src/preprocessing/subtract_black.cpp +object/cameralist.o: src/tables/cameralist.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp +object/cameralist.mt.o: src/tables/cameralist.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/cameralist.mt.o src/tables/cameralist.cpp +object/colorconst.o: src/tables/colorconst.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp +object/colorconst.mt.o: src/tables/colorconst.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/colorconst.mt.o src/tables/colorconst.cpp +object/colordata.o: src/tables/colordata.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp +object/colordata.mt.o: src/tables/colordata.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/colordata.mt.o src/tables/colordata.cpp +object/wblists.o: src/tables/wblists.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp +object/wblists.mt.o: src/tables/wblists.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/wblists.mt.o src/tables/wblists.cpp +object/curves.o: src/utils/curves.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp +object/curves.mt.o: src/utils/curves.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/curves.mt.o src/utils/curves.cpp +object/decoder_info.o: src/utils/decoder_info.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp +object/decoder_info.mt.o: src/utils/decoder_info.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/decoder_info.mt.o src/utils/decoder_info.cpp +object/init_close_utils.o: src/utils/init_close_utils.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp +object/init_close_utils.mt.o: src/utils/init_close_utils.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/init_close_utils.mt.o src/utils/init_close_utils.cpp +object/open.o: src/utils/open.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp +object/open.mt.o: src/utils/open.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/open.mt.o src/utils/open.cpp +object/phaseone_processing.o: src/utils/phaseone_processing.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp +object/phaseone_processing.mt.o: src/utils/phaseone_processing.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/phaseone_processing.mt.o src/utils/phaseone_processing.cpp +object/read_utils.o: src/utils/read_utils.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp +object/read_utils.mt.o: src/utils/read_utils.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/read_utils.mt.o src/utils/read_utils.cpp +object/thumb_utils.o: src/utils/thumb_utils.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp +object/thumb_utils.mt.o: src/utils/thumb_utils.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/thumb_utils.mt.o src/utils/thumb_utils.cpp +object/utils_dcraw.o: src/utils/utils_dcraw.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp +object/utils_dcraw.mt.o: src/utils/utils_dcraw.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/utils_dcraw.mt.o src/utils/utils_dcraw.cpp +object/utils_libraw.o: src/utils/utils_libraw.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp +object/utils_libraw.mt.o: src/utils/utils_libraw.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/utils_libraw.mt.o src/utils/utils_libraw.cpp +object/apply_profile.o: src/write/apply_profile.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp +object/apply_profile.mt.o: src/write/apply_profile.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/apply_profile.mt.o src/write/apply_profile.cpp +object/file_write.o: src/write/file_write.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp +object/file_write.mt.o: src/write/file_write.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/file_write.mt.o src/write/file_write.cpp +object/tiff_writer.o: src/write/tiff_writer.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp +object/tiff_writer.mt.o: src/write/tiff_writer.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/tiff_writer.mt.o src/write/tiff_writer.cpp +object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp +object/x3f_parse_process.mt.o: src/x3f/x3f_parse_process.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/x3f_parse_process.mt.o src/x3f/x3f_parse_process.cpp +object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp $(HEADERS) + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp +object/x3f_utils_patched.mt.o: src/x3f/x3f_utils_patched.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/x3f_utils_patched.mt.o src/x3f/x3f_utils_patched.cpp diff --git a/Makefile.devel.nopp b/Makefile.devel.nopp new file mode 100644 index 000000000..6ece7e9e8 --- /dev/null +++ b/Makefile.devel.nopp @@ -0,0 +1,230 @@ +all: library all_samples + +CC=clang +CXX=clang++ + +#CC=gcc +#CXX=g++ + +LDADD+=-lz + +CFLAGS=-DLIBRAW_USE_AUTOPTR +CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 + +# RawSpeed Support +# CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 +# LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 +# RAWSPEED_DATA=../RawSpeed/data/cameras.xml + +# DNG SDK Support +# CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source +# LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz + +# LCMS support +# For lcms2 set -DUSE_LCMS2 +#CFLAGS+=-DUSE_LCMS2 -I/opt/local/include +#LDADD+=-L/opt/local/lib -llcms + +# Jasper support for RedCine +#CFLAGS+=-DUSE_JASPER -I/opt/local/include +#LDADD+=-L/opt/local/lib -ljasper + +# JPEG support for DNG and Kodak +CFLAGS+=-DUSE_JPEG -I/usr/local/include +LDADD+=-L/usr/local/lib -ljpeg + +# LIBJPEG8: +CFLAGS+=-DUSE_JPEG8 + +CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS + +LIB_OBJECTS= object/libraw_datastream.o \ + object/cameralist.o object/fuji_compressed.o \ + object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/unpack.o object/unpack_thumb.o \ + object/rawspeed_glue.o object/dngsdk_glue.o \ + object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ + object/decoder_info.o object/open.o object/phaseone_processing.o \ + object/thumb_utils.o \ + object/tiff_writer.o object/subtract_black.o \ + object/raw2image.o \ + object/x3f_utils_patched.o object/x3f_parse_process.o \ + object/read_utils.o object/curves.o object/utils_dcraw.o \ + object/colordata.o \ + object/canon_600.o object/decoders_dcraw.o \ + object/decoders_libraw_dcrdefs.o object/generic.o \ + object/kodak_decoders.o object/dng.o object/smal.o \ + object/load_mfbacks.o \ + object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ + object/canon.o object/epson.o object/olympus.o object/leica.o \ + object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ + object/makernotes.o object/exif_gps.o object/kodak.o \ + object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ + object/identify_tools.o \ + object/hasselblad_model.o object/normalize_model.o object/identify.o \ + object/misc_parsers.o object/wblists.o \ + object/file_write.o \ + object/ext_preprocess.o \ + object/postprocessing_ph.o \ + + + +LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ + libraw/libraw_const.h libraw/libraw_datastream.h \ + libraw/libraw_internal.h libraw/libraw_types.h \ + libraw/libraw_version.h + +LRLIB=lib/libraw_nopp.a + +library: $(LRLIB) + +all_samples: bin/raw-identify bin/unprocessed_raw bin/4channels + +## Samples ## +bin/raw-identify: $(LRLIB) samples/raw-identify.cpp + $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw_nopp -lm ${LDADD} + +bin/unprocessed_raw: $(LRLIB) samples/unprocessed_raw.cpp + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw_nopp -lm ${LDADD} + +bin/4channels: $(LRLIB) samples/4channels.cpp + $(CXX) -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw_nopp -lm ${LDADD} + +$(LRLIB): ${LIB_OBJECTS} + rm -f $(LRLIB) + ar crv $(LRLIB) ${LIB_OBJECTS} + ranlib $(LRLIB) + +clean: + rm -fr bin/*.dSYM + rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o dcraw/*~ doc/*~ bin/*~ src/*/*~ + +## script-created rules +object/libraw_c_api.o: src/libraw_c_api.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp +object/libraw_datastream.o: src/libraw_datastream.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp +object/canon_600.o: src/decoders/canon_600.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp +object/crx.o: src/decoders/crx.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp +object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw.o: src/decoders/decoders_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp +object/dng.o: src/decoders/dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp +object/fp_dng.o: src/decoders/fp_dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp +object/fuji_compressed.o: src/decoders/fuji_compressed.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp +object/generic.o: src/decoders/generic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp +object/kodak_decoders.o: src/decoders/kodak_decoders.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp +object/load_mfbacks.o: src/decoders/load_mfbacks.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp +object/smal.o: src/decoders/smal.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp +object/unpack_thumb.o: src/decoders/unpack_thumb.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp +object/unpack.o: src/decoders/unpack.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp +object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp +object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp +object/adobepano.o: src/metadata/adobepano.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp +object/canon.o: src/metadata/canon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp +object/ciff.o: src/metadata/ciff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp +object/cr3_parser.o: src/metadata/cr3_parser.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp +object/epson.o: src/metadata/epson.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp +object/exif_gps.o: src/metadata/exif_gps.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp +object/fuji.o: src/metadata/fuji.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp +object/identify_tools.o: src/metadata/identify_tools.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp +object/identify.o: src/metadata/identify.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp +object/kodak.o: src/metadata/kodak.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp +object/leica.o: src/metadata/leica.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp +object/makernotes.o: src/metadata/makernotes.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp +object/mediumformat.o: src/metadata/mediumformat.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp +object/minolta.o: src/metadata/minolta.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp +object/misc_parsers.o: src/metadata/misc_parsers.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp +object/nikon.o: src/metadata/nikon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp +object/hasselblad_model.o: src/metadata/hasselblad_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp +object/normalize_model.o: src/metadata/normalize_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp +object/olympus.o: src/metadata/olympus.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp +object/p1.o: src/metadata/p1.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp +object/pentax.o: src/metadata/pentax.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp +object/samsung.o: src/metadata/samsung.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp +object/sony.o: src/metadata/sony.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp +object/tiff.o: src/metadata/tiff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp + +object/postprocessing_ph.o: src/postprocessing/postprocessing_ph.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_ph.o src/postprocessing/postprocessing_ph.cpp + +object/raw2image.o: src/preprocessing/raw2image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp +object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp +object/subtract_black.o: src/preprocessing/subtract_black.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp +object/cameralist.o: src/tables/cameralist.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp +object/colorconst.o: src/tables/colorconst.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp +object/colordata.o: src/tables/colordata.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp +object/wblists.o: src/tables/wblists.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp +object/curves.o: src/utils/curves.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp +object/decoder_info.o: src/utils/decoder_info.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp +object/init_close_utils.o: src/utils/init_close_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp +object/open.o: src/utils/open.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp +object/phaseone_processing.o: src/utils/phaseone_processing.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp +object/read_utils.o: src/utils/read_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp +object/thumb_utils.o: src/utils/thumb_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp +object/utils_dcraw.o: src/utils/utils_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp +object/utils_libraw.o: src/utils/utils_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp +object/file_write.o: src/write/file_write.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp +object/tiff_writer.o: src/write/tiff_writer.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp +object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp +object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp diff --git a/Makefile.devel.noppr2i b/Makefile.devel.noppr2i new file mode 100644 index 000000000..69372877f --- /dev/null +++ b/Makefile.devel.noppr2i @@ -0,0 +1,227 @@ +all: library all_samples + +CC=clang +CXX=clang++ + +#CC=gcc +#CXX=g++ + +LDADD+=-lz + +CFLAGS=-DLIBRAW_USE_AUTOPTR +CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 + +# RawSpeed Support +# CFLAGS+=-DUSE_RAWSPEED -I../RawSpeed -I/opt/local/include/libxml2 +# LDADD+=-L../RawSpeed/RawSpeed/release -lrawspeed -L/opt/local/include -ljpeg -lxml2 +# RAWSPEED_DATA=../RawSpeed/data/cameras.xml + +# DNG SDK Support +# CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source +# LDADDD+=-L../dng_sdk/release -ldng -ljpeg -lz + +# LCMS support +# For lcms2 set -DUSE_LCMS2 +#CFLAGS+=-DUSE_LCMS2 -I/opt/local/include +#LDADD+=-L/opt/local/lib -llcms + +# Jasper support for RedCine +#CFLAGS+=-DUSE_JASPER -I/opt/local/include +#LDADD+=-L/opt/local/lib -ljasper + +# JPEG support for DNG and Kodak +CFLAGS+=-DUSE_JPEG -I/usr/local/include +LDADD+=-L/usr/local/lib -ljpeg + +# LIBJPEG8: +CFLAGS+=-DUSE_JPEG8 + +CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS + +LIB_OBJECTS= object/libraw_datastream.o \ + object/cameralist.o object/fuji_compressed.o \ + object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/unpack.o object/unpack_thumb.o \ + object/rawspeed_glue.o object/dngsdk_glue.o \ + object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ + object/decoder_info.o object/open.o object/phaseone_processing.o \ + object/thumb_utils.o \ + object/x3f_utils_patched.o object/x3f_parse_process.o \ + object/read_utils.o object/curves.o object/utils_dcraw.o \ + object/colordata.o \ + object/canon_600.o object/decoders_dcraw.o \ + object/decoders_libraw_dcrdefs.o object/generic.o \ + object/kodak_decoders.o object/dng.o object/smal.o \ + object/load_mfbacks.o \ + object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ + object/canon.o object/epson.o object/olympus.o object/leica.o \ + object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ + object/makernotes.o object/exif_gps.o object/kodak.o \ + object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ + object/identify_tools.o \ + object/hasselblad_model.o object/normalize_model.o object/identify.o \ + object/misc_parsers.o object/wblists.o \ + object/write_ph.o \ + object/postprocessing_ph.o \ + object/preprocessing_ph.o \ + + + +LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ + libraw/libraw_const.h libraw/libraw_datastream.h \ + libraw/libraw_internal.h libraw/libraw_types.h \ + libraw/libraw_version.h + +LRLIB=lib/libraw_noppr2i.a + +library: $(LRLIB) + +all_samples: bin/raw-identify + +## Samples ## +bin/raw-identify: $(LRLIB) samples/raw-identify.cpp + $(CXX) ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw_noppr2i -lm ${LDADD} + +$(LRLIB): ${LIB_OBJECTS} + rm -f $(LRLIB) + ar crv $(LRLIB) ${LIB_OBJECTS} + ranlib $(LRLIB) + +clean: + rm -fr bin/*.dSYM + rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*.o dcraw/*~ doc/*~ bin/*~ src/*/*~ + +## script-created rules +object/libraw_c_api.o: src/libraw_c_api.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp +object/libraw_datastream.o: src/libraw_datastream.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp +object/canon_600.o: src/decoders/canon_600.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp +object/crx.o: src/decoders/crx.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp +object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw.o: src/decoders/decoders_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp +object/dng.o: src/decoders/dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp +object/fp_dng.o: src/decoders/fp_dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp +object/fuji_compressed.o: src/decoders/fuji_compressed.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp +object/generic.o: src/decoders/generic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp +object/kodak_decoders.o: src/decoders/kodak_decoders.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp +object/load_mfbacks.o: src/decoders/load_mfbacks.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp +object/smal.o: src/decoders/smal.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp +object/unpack_thumb.o: src/decoders/unpack_thumb.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp +object/unpack.o: src/decoders/unpack.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp +object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp +object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp +object/adobepano.o: src/metadata/adobepano.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp +object/canon.o: src/metadata/canon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp +object/ciff.o: src/metadata/ciff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp +object/cr3_parser.o: src/metadata/cr3_parser.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp +object/epson.o: src/metadata/epson.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp +object/exif_gps.o: src/metadata/exif_gps.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp +object/fuji.o: src/metadata/fuji.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp +object/identify_tools.o: src/metadata/identify_tools.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp +object/identify.o: src/metadata/identify.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp +object/kodak.o: src/metadata/kodak.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp +object/leica.o: src/metadata/leica.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp +object/makernotes.o: src/metadata/makernotes.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp +object/mediumformat.o: src/metadata/mediumformat.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp +object/minolta.o: src/metadata/minolta.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp +object/misc_parsers.o: src/metadata/misc_parsers.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp +object/nikon.o: src/metadata/nikon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp +object/hasselblad_model.o: src/metadata/hasselblad_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp +object/normalize_model.o: src/metadata/normalize_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp +object/olympus.o: src/metadata/olympus.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp +object/p1.o: src/metadata/p1.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp +object/pentax.o: src/metadata/pentax.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp +object/samsung.o: src/metadata/samsung.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp +object/sony.o: src/metadata/sony.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp +object/tiff.o: src/metadata/tiff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp + +object/preprocessing_ph.o: src/preprocessing/preprocessing_ph.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/preprocessing_ph.o src/preprocessing/preprocessing_ph.cpp + +object/postprocessing_ph.o: src/postprocessing/postprocessing_ph.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_ph.o src/postprocessing/postprocessing_ph.cpp + +object/raw2image.o: src/preprocessing/raw2image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp +object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp +object/subtract_black.o: src/preprocessing/subtract_black.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp +object/cameralist.o: src/tables/cameralist.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp +object/colorconst.o: src/tables/colorconst.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp +object/colordata.o: src/tables/colordata.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp +object/wblists.o: src/tables/wblists.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp +object/curves.o: src/utils/curves.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp +object/decoder_info.o: src/utils/decoder_info.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp +object/init_close_utils.o: src/utils/init_close_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp +object/open.o: src/utils/open.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp +object/phaseone_processing.o: src/utils/phaseone_processing.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp +object/read_utils.o: src/utils/read_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp +object/thumb_utils.o: src/utils/thumb_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp +object/utils_dcraw.o: src/utils/utils_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp +object/utils_libraw.o: src/utils/utils_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp +object/write_ph.o: src/write/write_ph.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/write_ph.o src/write/write_ph.cpp +object/file_write.o: src/write/file_write.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp +object/tiff_writer.o: src/write/tiff_writer.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp +object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp +object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp diff --git a/Makefile.dist b/Makefile.dist new file mode 100644 index 000000000..9c3e3f1c1 --- /dev/null +++ b/Makefile.dist @@ -0,0 +1,501 @@ +all: library all_samples + +#CFLAGS=-arch i386 -arch x86_64 -O3 -I. -w +CFLAGS=-O3 -I. -w +CC=gcc +CXX=g++ + +# OpenMP support +#CFLAGS+=-fopenmp + +# RawSpeed Support +#CFLAGS+=-pthread -DUSE_RAWSPEED -I../RawSpeed -I/usr/local/include/libxml2 +#LDADD+=-L../RawSpeed/RawSpeed -lrawspeed -L/usr/local/lib -ljpeg -lxml2 +#RAWSPEED_DATA=../RawSpeed/data/cameras.xml + +# RawSpeed3 Support +#CFLAGS+=-DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS -I./RawSpeed3/ +#LDADD+=-L../RawSpeed-v3/release -lrawspeed3 -L/usr/local/lib -ljpeg -lz + +# DNG SDK Support +# CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source +# LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz + +# Jasper support for RedCine +#CFLAGS+=-DUSE_JASPER -I/usr/local/include +#LDADD+=-L/usr/local/lib -ljasper + +# ZLIB support (FP dng) +CFLAGS+=-DUSE_ZLIB +LDADD+=-lz + +# JPEG support for lossy DNG +#CFLAGS+=-DUSE_JPEG -I/usr/local/include +#LDADD+=-L/usr/local/lib -ljpeg +# LIBJPEG8: +#CFLAGS+=-DUSE_JPEG8 + +# LCMS support +#CFLAGS+=-DUSE_LCMS -I/usr/local/include +#LDADD+=-L/usr/local/lib -llcms + +# LCMS2.x support +#CFLAGS+=-DUSE_LCMS2 -I/usr/local/include +#LDADD+=-L/usr/local/lib -llcms2 + +CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS + +LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ + object/cameralist.o object/fuji_compressed.o \ + object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/unpack.o object/unpack_thumb.o \ + object/rawspeed_glue.o object/dngsdk_glue.o \ + object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ + object/decoder_info.o object/open.o object/phaseone_processing.o \ + object/thumb_utils.o \ + object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ + object/dcraw_process.o object/raw2image.o object/mem_image.o \ + object/x3f_utils_patched.o object/x3f_parse_process.o \ + object/read_utils.o object/curves.o object/utils_dcraw.o \ + object/colordata.o \ + object/canon_600.o object/decoders_dcraw.o \ + object/decoders_libraw_dcrdefs.o object/generic.o \ + object/kodak_decoders.o object/dng.o object/smal.o \ + object/load_mfbacks.o \ + object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ + object/canon.o object/epson.o object/olympus.o object/leica.o \ + object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ + object/makernotes.o object/exif_gps.o object/kodak.o \ + object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ + object/identify_tools.o \ + object/hasselblad_model.o object/normalize_model.o object/identify.o \ + object/misc_parsers.o object/wblists.o \ + object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ + object/aspect_ratio.o \ + object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ + object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ + object/file_write.o \ + object/ext_preprocess.o object/apply_profile.o + + +LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ + object/cameralist.mt.o object/fuji_compressed.mt.o \ + object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ + object/unpack.mt.o object/unpack_thumb.mt.o \ + object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ + object/colorconst.mt.o object/utils_libraw.mt.o \ + object/init_close_utils.mt.o \ + object/decoder_info.mt.o object/open.mt.o object/phaseone_processing.mt.o \ + object/thumb_utils.mt.o \ + object/tiff_writer.mt.o object/subtract_black.mt.o \ + object/postprocessing_utils.mt.o object/dcraw_process.mt.o \ + object/raw2image.mt.o object/mem_image.mt.o \ + object/x3f_utils_patched.mt.o object/x3f_parse_process.mt.o \ + object/read_utils.mt.o object/curves.mt.o object/utils_dcraw.mt.o \ + object/colordata.mt.o \ + object/canon_600.mt.o object/decoders_dcraw.mt.o \ + object/decoders_libraw_dcrdefs.mt.o object/generic.mt.o \ + object/kodak_decoders.mt.o object/dng.mt.o object/smal.mt.o \ + object/load_mfbacks.mt.o \ + object/sony.mt.o object/nikon.mt.o object/samsung.mt.o \ + object/cr3_parser.mt.o object/canon.mt.o object/epson.mt.o \ + object/olympus.mt.o object/leica.mt.o \ + object/fuji.mt.o object/adobepano.mt.o object/pentax.mt.o object/p1.mt.o \ + object/makernotes.mt.o object/exif_gps.mt.o object/kodak.mt.o \ + object/tiff.mt.o object/ciff.mt.o object/mediumformat.mt.o \ + object/minolta.mt.o \ + object/identify_tools.mt.o \ + object/hasselblad_model.o object/normalize_model.mt.o object/identify.mt.o \ + object/misc_parsers.mt.o object/wblists.mt.o \ + object/postprocessing_aux.mt.o object/postprocessing_utils_dcrdefs.mt.o \ + object/aspect_ratio.mt.o \ + object/misc_demosaic.mt.o object/xtrans_demosaic.mt.o \ + object/ahd_demosaic.mt.o object/dht_demosaic.mt.o \ + object/aahd_demosaic.mt.o object/dcb_demosaic.mt.o \ + object/file_write.mt.o \ + object/ext_preprocess.mt.o object/apply_profile.mt.o + + +LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ + libraw/libraw_const.h libraw/libraw_datastream.h \ + libraw/libraw_internal.h libraw/libraw_types.h \ + libraw/libraw_version.h + +library: lib/libraw.a lib/libraw_r.a + +all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu bin/dcraw_half bin/half_mt bin/mem_image \ + bin/unprocessed_raw bin/4channels bin/multirender_test bin/postprocessing_benchmark \ + bin/rawtextdump + +install: library + @if [ -d /usr/local/include ] ; then cp -R libraw /usr/local/include/ ; else echo 'no /usr/local/include' ; fi + @if [ -d /usr/local/lib ] ; then cp lib/libraw.a lib/libraw_r.a /usr/local/lib/ ; else echo 'no /usr/local/lib' ; fi + +install-binaries: all_samples + @if [ -d /usr/local/bin ] ; then cp bin/[a-z]* /usr/local/bin/ ; else echo 'no /usr/local/bin' ; fi + + +## RawSpeed xml file + +RawSpeed/rawspeed_xmldata.cpp: ${RAWSPEED_DATA} + ./rsxml2c.sh ${RAWSPEED_DATA} > RawSpeed/rawspeed_xmldata.cpp + +#binaries + +bin/raw-identify: lib/libraw.a samples/raw-identify.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lm ${LDADD} + +bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lm ${LDADD} + +bin/4channels: lib/libraw.a samples/4channels.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lm ${LDADD} + +bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lm ${LDADD} + +bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lm ${LDADD} + +bin/multirender_test: lib/libraw.a samples/multirender_test.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lm ${LDADD} + +bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lm ${LDADD} + +bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lm ${LDADD} + +bin/dcraw_half: lib/libraw.a object/dcraw_half.o + ${CC} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_half object/dcraw_half.o -L./lib -lraw -lm -lstdc++ ${LDADD} + +bin/half_mt: lib/libraw_r.a object/half_mt.o + ${CC} -pthread ${CFLAGS} -o bin/half_mt object/half_mt.o -L./lib -lraw_r -lm -lstdc++ ${LDADD} + +bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw -lm ${LDADD} + +#objects + +object/dcraw_half.o: samples/dcraw_half.c + ${CC} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_half.o samples/dcraw_half.c + +object/half_mt.o: samples/half_mt.c + ${CC} -c -pthread ${CFLAGS} -o object/half_mt.o samples/half_mt.c + + +lib/libraw.a: ${LIB_OBJECTS} + rm -f lib/libraw.a + ar crv lib/libraw.a ${LIB_OBJECTS} + ranlib lib/libraw.a + +lib/libraw_r.a: ${LIB_MT_OBJECTS} + rm -f lib/libraw_r.a + ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} + ranlib lib/libraw_r.a + +clean: + rm -fr bin/*.dSYM + rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*o dcraw/*~ doc/*~ bin/*~ src/*/*~ + +### generated +object/libraw_c_api.o: src/libraw_c_api.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp +object/libraw_c_api.mt.o: src/libraw_c_api.cpp + ${CXX} -c ${CFLAGS} -o object/libraw_c_api.mt.o src/libraw_c_api.cpp +object/libraw_datastream.o: src/libraw_datastream.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp +object/libraw_datastream.mt.o: src/libraw_datastream.cpp + ${CXX} -c ${CFLAGS} -o object/libraw_datastream.mt.o src/libraw_datastream.cpp +object/canon_600.o: src/decoders/canon_600.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp +object/canon_600.mt.o: src/decoders/canon_600.cpp + ${CXX} -c ${CFLAGS} -o object/canon_600.mt.o src/decoders/canon_600.cpp +object/crx.o: src/decoders/crx.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/crx.mt.o: src/decoders/crx.cpp + ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp +object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp +object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c ${CFLAGS} -o object/decoders_dcraw.mt.o src/decoders/decoders_dcraw.cpp +object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw_dcrdefs.mt.o: src/decoders/decoders_libraw_dcrdefs.cpp + ${CXX} -c ${CFLAGS} -o object/decoders_libraw_dcrdefs.mt.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw.o: src/decoders/decoders_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp +object/decoders_libraw.mt.o: src/decoders/decoders_libraw.cpp + ${CXX} -c ${CFLAGS} -o object/decoders_libraw.mt.o src/decoders/decoders_libraw.cpp +object/dng.o: src/decoders/dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp +object/dng.mt.o: src/decoders/dng.cpp + ${CXX} -c ${CFLAGS} -o object/dng.mt.o src/decoders/dng.cpp +object/fp_dng.o: src/decoders/fp_dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp +object/fp_dng.mt.o: src/decoders/fp_dng.cpp + ${CXX} -c ${CFLAGS} -o object/fp_dng.mt.o src/decoders/fp_dng.cpp +object/fuji_compressed.o: src/decoders/fuji_compressed.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp +object/fuji_compressed.mt.o: src/decoders/fuji_compressed.cpp + ${CXX} -c ${CFLAGS} -o object/fuji_compressed.mt.o src/decoders/fuji_compressed.cpp +object/generic.o: src/decoders/generic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp +object/generic.mt.o: src/decoders/generic.cpp + ${CXX} -c ${CFLAGS} -o object/generic.mt.o src/decoders/generic.cpp +object/kodak_decoders.o: src/decoders/kodak_decoders.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp +object/kodak_decoders.mt.o: src/decoders/kodak_decoders.cpp + ${CXX} -c ${CFLAGS} -o object/kodak_decoders.mt.o src/decoders/kodak_decoders.cpp +object/load_mfbacks.o: src/decoders/load_mfbacks.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp +object/load_mfbacks.mt.o: src/decoders/load_mfbacks.cpp + ${CXX} -c ${CFLAGS} -o object/load_mfbacks.mt.o src/decoders/load_mfbacks.cpp +object/smal.o: src/decoders/smal.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp +object/smal.mt.o: src/decoders/smal.cpp + ${CXX} -c ${CFLAGS} -o object/smal.mt.o src/decoders/smal.cpp +object/unpack_thumb.o: src/decoders/unpack_thumb.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp +object/unpack_thumb.mt.o: src/decoders/unpack_thumb.cpp + ${CXX} -c ${CFLAGS} -o object/unpack_thumb.mt.o src/decoders/unpack_thumb.cpp +object/unpack.o: src/decoders/unpack.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp +object/unpack.mt.o: src/decoders/unpack.cpp + ${CXX} -c ${CFLAGS} -o object/unpack.mt.o src/decoders/unpack.cpp +object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp +object/aahd_demosaic.mt.o: src/demosaic/aahd_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/aahd_demosaic.mt.o src/demosaic/aahd_demosaic.cpp +object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp +object/ahd_demosaic.mt.o: src/demosaic/ahd_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/ahd_demosaic.mt.o src/demosaic/ahd_demosaic.cpp +object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp +object/dcb_demosaic.mt.o: src/demosaic/dcb_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/dcb_demosaic.mt.o src/demosaic/dcb_demosaic.cpp +object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp +object/dht_demosaic.mt.o: src/demosaic/dht_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/dht_demosaic.mt.o src/demosaic/dht_demosaic.cpp +object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp +object/misc_demosaic.mt.o: src/demosaic/misc_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/misc_demosaic.mt.o src/demosaic/misc_demosaic.cpp +object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp +object/xtrans_demosaic.mt.o: src/demosaic/xtrans_demosaic.cpp + ${CXX} -c ${CFLAGS} -o object/xtrans_demosaic.mt.o src/demosaic/xtrans_demosaic.cpp +object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp +object/dngsdk_glue.mt.o: src/integration/dngsdk_glue.cpp + ${CXX} -c ${CFLAGS} -o object/dngsdk_glue.mt.o src/integration/dngsdk_glue.cpp +object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp +object/rawspeed_glue.mt.o: src/integration/rawspeed_glue.cpp + ${CXX} -c ${CFLAGS} -o object/rawspeed_glue.mt.o src/integration/rawspeed_glue.cpp +object/adobepano.o: src/metadata/adobepano.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp +object/adobepano.mt.o: src/metadata/adobepano.cpp + ${CXX} -c ${CFLAGS} -o object/adobepano.mt.o src/metadata/adobepano.cpp +object/canon.o: src/metadata/canon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp +object/canon.mt.o: src/metadata/canon.cpp + ${CXX} -c ${CFLAGS} -o object/canon.mt.o src/metadata/canon.cpp +object/ciff.o: src/metadata/ciff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp +object/ciff.mt.o: src/metadata/ciff.cpp + ${CXX} -c ${CFLAGS} -o object/ciff.mt.o src/metadata/ciff.cpp +object/cr3_parser.o: src/metadata/cr3_parser.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp +object/cr3_parser.mt.o: src/metadata/cr3_parser.cpp + ${CXX} -c ${CFLAGS} -o object/cr3_parser.mt.o src/metadata/cr3_parser.cpp +object/epson.o: src/metadata/epson.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp +object/epson.mt.o: src/metadata/epson.cpp + ${CXX} -c ${CFLAGS} -o object/epson.mt.o src/metadata/epson.cpp +object/exif_gps.o: src/metadata/exif_gps.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp +object/exif_gps.mt.o: src/metadata/exif_gps.cpp + ${CXX} -c ${CFLAGS} -o object/exif_gps.mt.o src/metadata/exif_gps.cpp +object/fuji.o: src/metadata/fuji.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp +object/fuji.mt.o: src/metadata/fuji.cpp + ${CXX} -c ${CFLAGS} -o object/fuji.mt.o src/metadata/fuji.cpp +object/identify_tools.o: src/metadata/identify_tools.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp +object/identify_tools.mt.o: src/metadata/identify_tools.cpp + ${CXX} -c ${CFLAGS} -o object/identify_tools.mt.o src/metadata/identify_tools.cpp +object/identify.o: src/metadata/identify.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp +object/identify.mt.o: src/metadata/identify.cpp + ${CXX} -c ${CFLAGS} -o object/identify.mt.o src/metadata/identify.cpp +object/kodak.o: src/metadata/kodak.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp +object/kodak.mt.o: src/metadata/kodak.cpp + ${CXX} -c ${CFLAGS} -o object/kodak.mt.o src/metadata/kodak.cpp +object/leica.o: src/metadata/leica.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp +object/leica.mt.o: src/metadata/leica.cpp + ${CXX} -c ${CFLAGS} -o object/leica.mt.o src/metadata/leica.cpp +object/makernotes.o: src/metadata/makernotes.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp +object/makernotes.mt.o: src/metadata/makernotes.cpp + ${CXX} -c ${CFLAGS} -o object/makernotes.mt.o src/metadata/makernotes.cpp +object/mediumformat.o: src/metadata/mediumformat.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp +object/mediumformat.mt.o: src/metadata/mediumformat.cpp + ${CXX} -c ${CFLAGS} -o object/mediumformat.mt.o src/metadata/mediumformat.cpp +object/minolta.o: src/metadata/minolta.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp +object/minolta.mt.o: src/metadata/minolta.cpp + ${CXX} -c ${CFLAGS} -o object/minolta.mt.o src/metadata/minolta.cpp +object/misc_parsers.o: src/metadata/misc_parsers.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp +object/misc_parsers.mt.o: src/metadata/misc_parsers.cpp + ${CXX} -c ${CFLAGS} -o object/misc_parsers.mt.o src/metadata/misc_parsers.cpp +object/nikon.o: src/metadata/nikon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp +object/nikon.mt.o: src/metadata/nikon.cpp + ${CXX} -c ${CFLAGS} -o object/nikon.mt.o src/metadata/nikon.cpp +object/hasselblad_model.o: src/metadata/hasselblad_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp +object/hasselblad_model.mt.o: src/metadata/hasselblad_model.cpp + ${CXX} -c ${CFLAGS} -o object/hasselblad_model.mt.o src/metadata/hasselblad_model.cpp +object/normalize_model.o: src/metadata/normalize_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp +object/normalize_model.mt.o: src/metadata/normalize_model.cpp + ${CXX} -c ${CFLAGS} -o object/normalize_model.mt.o src/metadata/normalize_model.cpp +object/olympus.o: src/metadata/olympus.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp +object/olympus.mt.o: src/metadata/olympus.cpp + ${CXX} -c ${CFLAGS} -o object/olympus.mt.o src/metadata/olympus.cpp +object/p1.o: src/metadata/p1.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp +object/p1.mt.o: src/metadata/p1.cpp + ${CXX} -c ${CFLAGS} -o object/p1.mt.o src/metadata/p1.cpp +object/pentax.o: src/metadata/pentax.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp +object/pentax.mt.o: src/metadata/pentax.cpp + ${CXX} -c ${CFLAGS} -o object/pentax.mt.o src/metadata/pentax.cpp +object/samsung.o: src/metadata/samsung.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp +object/samsung.mt.o: src/metadata/samsung.cpp + ${CXX} -c ${CFLAGS} -o object/samsung.mt.o src/metadata/samsung.cpp +object/sony.o: src/metadata/sony.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp +object/sony.mt.o: src/metadata/sony.cpp + ${CXX} -c ${CFLAGS} -o object/sony.mt.o src/metadata/sony.cpp +object/tiff.o: src/metadata/tiff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp +object/tiff.mt.o: src/metadata/tiff.cpp + ${CXX} -c ${CFLAGS} -o object/tiff.mt.o src/metadata/tiff.cpp +object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp +object/aspect_ratio.mt.o: src/postprocessing/aspect_ratio.cpp + ${CXX} -c ${CFLAGS} -o object/aspect_ratio.mt.o src/postprocessing/aspect_ratio.cpp +object/dcraw_process.o: src/postprocessing/dcraw_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp +object/dcraw_process.mt.o: src/postprocessing/dcraw_process.cpp + ${CXX} -c ${CFLAGS} -o object/dcraw_process.mt.o src/postprocessing/dcraw_process.cpp +object/mem_image.o: src/postprocessing/mem_image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp +object/mem_image.mt.o: src/postprocessing/mem_image.cpp + ${CXX} -c ${CFLAGS} -o object/mem_image.mt.o src/postprocessing/mem_image.cpp +object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp +object/postprocessing_aux.mt.o: src/postprocessing/postprocessing_aux.cpp + ${CXX} -c ${CFLAGS} -o object/postprocessing_aux.mt.o src/postprocessing/postprocessing_aux.cpp +object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp +object/postprocessing_utils_dcrdefs.mt.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp + ${CXX} -c ${CFLAGS} -o object/postprocessing_utils_dcrdefs.mt.o src/postprocessing/postprocessing_utils_dcrdefs.cpp +object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp +object/postprocessing_utils.mt.o: src/postprocessing/postprocessing_utils.cpp + ${CXX} -c ${CFLAGS} -o object/postprocessing_utils.mt.o src/postprocessing/postprocessing_utils.cpp +object/raw2image.o: src/preprocessing/raw2image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp +object/raw2image.mt.o: src/preprocessing/raw2image.cpp + ${CXX} -c ${CFLAGS} -o object/raw2image.mt.o src/preprocessing/raw2image.cpp +object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp +object/ext_preprocess.mt.o: src/preprocessing/ext_preprocess.cpp + ${CXX} -c ${CFLAGS} -o object/ext_preprocess.mt.o src/preprocessing/ext_preprocess.cpp +object/subtract_black.o: src/preprocessing/subtract_black.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp +object/subtract_black.mt.o: src/preprocessing/subtract_black.cpp + ${CXX} -c ${CFLAGS} -o object/subtract_black.mt.o src/preprocessing/subtract_black.cpp +object/cameralist.o: src/tables/cameralist.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp +object/cameralist.mt.o: src/tables/cameralist.cpp + ${CXX} -c ${CFLAGS} -o object/cameralist.mt.o src/tables/cameralist.cpp +object/colorconst.o: src/tables/colorconst.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp +object/colorconst.mt.o: src/tables/colorconst.cpp + ${CXX} -c ${CFLAGS} -o object/colorconst.mt.o src/tables/colorconst.cpp +object/colordata.o: src/tables/colordata.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp +object/colordata.mt.o: src/tables/colordata.cpp + ${CXX} -c ${CFLAGS} -o object/colordata.mt.o src/tables/colordata.cpp +object/wblists.o: src/tables/wblists.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp +object/wblists.mt.o: src/tables/wblists.cpp + ${CXX} -c ${CFLAGS} -o object/wblists.mt.o src/tables/wblists.cpp +object/curves.o: src/utils/curves.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp +object/curves.mt.o: src/utils/curves.cpp + ${CXX} -c ${CFLAGS} -o object/curves.mt.o src/utils/curves.cpp +object/decoder_info.o: src/utils/decoder_info.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp +object/decoder_info.mt.o: src/utils/decoder_info.cpp + ${CXX} -c ${CFLAGS} -o object/decoder_info.mt.o src/utils/decoder_info.cpp +object/init_close_utils.o: src/utils/init_close_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp +object/init_close_utils.mt.o: src/utils/init_close_utils.cpp + ${CXX} -c ${CFLAGS} -o object/init_close_utils.mt.o src/utils/init_close_utils.cpp +object/open.o: src/utils/open.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp +object/open.mt.o: src/utils/open.cpp + ${CXX} -c ${CFLAGS} -o object/open.mt.o src/utils/open.cpp +object/phaseone_processing.o: src/utils/phaseone_processing.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp +object/phaseone_processing.mt.o: src/utils/phaseone_processing.cpp + ${CXX} -c ${CFLAGS} -o object/phaseone_processing.mt.o src/utils/phaseone_processing.cpp +object/read_utils.o: src/utils/read_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp +object/read_utils.mt.o: src/utils/read_utils.cpp + ${CXX} -c ${CFLAGS} -o object/read_utils.mt.o src/utils/read_utils.cpp +object/thumb_utils.o: src/utils/thumb_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp +object/thumb_utils.mt.o: src/utils/thumb_utils.cpp + ${CXX} -c ${CFLAGS} -o object/thumb_utils.mt.o src/utils/thumb_utils.cpp +object/utils_dcraw.o: src/utils/utils_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp +object/utils_dcraw.mt.o: src/utils/utils_dcraw.cpp + ${CXX} -c ${CFLAGS} -o object/utils_dcraw.mt.o src/utils/utils_dcraw.cpp +object/utils_libraw.o: src/utils/utils_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp +object/utils_libraw.mt.o: src/utils/utils_libraw.cpp + ${CXX} -c ${CFLAGS} -o object/utils_libraw.mt.o src/utils/utils_libraw.cpp +object/apply_profile.o: src/write/apply_profile.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp +object/apply_profile.mt.o: src/write/apply_profile.cpp + ${CXX} -c ${CFLAGS} -o object/apply_profile.mt.o src/write/apply_profile.cpp +object/file_write.o: src/write/file_write.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp +object/file_write.mt.o: src/write/file_write.cpp + ${CXX} -c ${CFLAGS} -o object/file_write.mt.o src/write/file_write.cpp +object/tiff_writer.o: src/write/tiff_writer.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp +object/tiff_writer.mt.o: src/write/tiff_writer.cpp + ${CXX} -c ${CFLAGS} -o object/tiff_writer.mt.o src/write/tiff_writer.cpp +object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp +object/x3f_parse_process.mt.o: src/x3f/x3f_parse_process.cpp + ${CXX} -c ${CFLAGS} -o object/x3f_parse_process.mt.o src/x3f/x3f_parse_process.cpp +object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp +object/x3f_utils_patched.mt.o: src/x3f/x3f_utils_patched.cpp + ${CXX} -c ${CFLAGS} -o object/x3f_utils_patched.mt.o src/x3f/x3f_utils_patched.cpp diff --git a/Makefile.mingw b/Makefile.mingw new file mode 100644 index 000000000..f2c291e21 --- /dev/null +++ b/Makefile.mingw @@ -0,0 +1,297 @@ +all: library all_samples + +CFLAGS=-O3 -I. -w +CC=gcc +CXX=g++ + +# OpenMP support +#CFLAGS+=-fopenmp + +# RawSpeed Support +#CFLAGS+=-pthread -DUSE_RAWSPEED -I../RawSpeed -I/usr/local/include/libxml2 +#LDADD+=-L../RawSpeed/RawSpeed -lrawspeed -L/usr/local/lib -ljpeg -lxml2 +#RAWSPEED_DATA=../RawSpeed/data/cameras.xml + +# DNG SDK Support +# CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source +# LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz + +# Jasper support for RedCine +#CFLAGS+=-DUSE_JASPER -I/usr/local/include +#LDADD+=-L/usr/local/lib -ljasper + +# JPEG support for lossy DNG +#CFLAGS+=-DUSE_JPEG -I/usr/local/include +#LDADD+=-L/usr/local/lib -ljpeg +# LIBJPEG8: +#CFLAGS+=-DUSE_JPEG8 + +# LCMS support +#CFLAGS+=-DUSE_LCMS -I/usr/local/include +#LDADD+=-L/usr/local/lib -llcms + +# LCMS2.x support +#CFLAGS+=-DUSE_LCMS2 -I/usr/local/include +#LDADD+=-L/usr/local/lib -llcms2 + +CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS + +LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ + object/cameralist.o object/fuji_compressed.o \ + object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/unpack.o object/unpack_thumb.o \ + object/rawspeed_glue.o object/dngsdk_glue.o \ + object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ + object/decoder_info.o object/open.o object/phaseone_processing.o \ + object/thumb_utils.o \ + object/tiff_writer.o object/subtract_black.o object/postprocessing_utils.o \ + object/dcraw_process.o object/raw2image.o object/mem_image.o \ + object/x3f_utils_patched.o object/x3f_parse_process.o \ + object/read_utils.o object/curves.o object/utils_dcraw.o \ + object/colordata.o \ + object/canon_600.o object/decoders_dcraw.o \ + object/decoders_libraw_dcrdefs.o object/generic.o \ + object/kodak_decoders.o object/dng.o object/smal.o \ + object/load_mfbacks.o \ + object/sony.o object/nikon.o object/samsung.o object/cr3_parser.o \ + object/canon.o object/epson.o object/olympus.o object/leica.o \ + object/fuji.o object/adobepano.o object/pentax.o object/p1.o \ + object/makernotes.o object/exif_gps.o object/kodak.o \ + object/tiff.o object/ciff.o object/mediumformat.o object/minolta.o \ + object/identify_tools.o \ + object/hasselblad_model.o object/normalize_model.o object/identify.o \ + object/misc_parsers.o object/wblists.o \ + object/postprocessing_aux.o object/postprocessing_utils_dcrdefs.o \ + object/aspect_ratio.o \ + object/misc_demosaic.o object/xtrans_demosaic.o object/ahd_demosaic.o \ + object/dht_demosaic.o object/aahd_demosaic.o object/dcb_demosaic.o \ + object/file_write.o \ + object/ext_preprocess.o object/apply_profile.o + + + +LR_INCLUDES=libraw/libraw.h libraw/libraw_alloc.h \ + libraw/libraw_const.h libraw/libraw_datastream.h \ + libraw/libraw_internal.h libraw/libraw_types.h \ + libraw/libraw_version.h + +library: lib/libraw.a + +all_samples: bin/raw-identify bin/simple_dcraw bin/dcraw_emu bin/dcraw_half bin/mem_image \ + bin/unprocessed_raw bin/4channels bin/multirender_test bin/postprocessing_benchmark \ + bin/rawtextdump + +install: library + @if [ -d /usr/local/include ] ; then cp -R libraw /usr/local/include/ ; else echo 'no /usr/local/include' ; fi + @if [ -d /usr/local/lib ] ; then cp lib/libraw.a lib/libraw_r.a /usr/local/lib/ ; else echo 'no /usr/local/lib' ; fi + +install-binaries: all_samples + @if [ -d /usr/local/bin ] ; then cp bin/[a-z]* /usr/local/bin/ ; else echo 'no /usr/local/bin' ; fi + + +#binaries + +bin/raw-identify: lib/libraw.a samples/raw-identify.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/raw-identify samples/raw-identify.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/unprocessed_raw: lib/libraw.a samples/unprocessed_raw.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/unprocessed_raw samples/unprocessed_raw.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/4channels: lib/libraw.a samples/4channels.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/4channels samples/4channels.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/rawtextdump: lib/libraw.a samples/rawtextdump.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/rawtextdump samples/rawtextdump.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/simple_dcraw: lib/libraw.a samples/simple_dcraw.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/simple_dcraw samples/simple_dcraw.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/multirender_test: lib/libraw.a samples/multirender_test.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/multirender_test samples/multirender_test.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/postprocessing_benchmark: lib/libraw.a samples/postprocessing_benchmark.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/postprocessing_benchmark samples/postprocessing_benchmark.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/mem_image: lib/libraw.a samples/mem_image_sample.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/mem_image samples/mem_image_sample.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +bin/dcraw_half: lib/libraw.a object/dcraw_half.o + ${CC} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_half object/dcraw_half.o -L./lib -lraw -lws2_32 -lm -lstdc++ ${LDADD} + +bin/dcraw_emu: lib/libraw.a samples/dcraw_emu.cpp + ${CXX} -DLIBRAW_NOTHREADS ${CFLAGS} -o bin/dcraw_emu samples/dcraw_emu.cpp -L./lib -lraw -lws2_32 -lm ${LDADD} + +#objects + +object/dcraw_half.o: samples/dcraw_half.c + ${CC} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_half.o samples/dcraw_half.c + +object/half_mt.o: samples/half_mt.c + ${CC} -c -pthread ${CFLAGS} -o object/half_mt.o samples/half_mt.c + + +lib/libraw.a: ${LIB_OBJECTS} + rm -f lib/libraw.a + ar crv lib/libraw.a ${LIB_OBJECTS} + ranlib lib/libraw.a + +lib/libraw_r.a: ${LIB_MT_OBJECTS} + rm -f lib/libraw_r.a + ar crv lib/libraw_r.a ${LIB_MT_OBJECTS} + ranlib lib/libraw_r.a + +clean: + rm -fr bin/*.dSYM + rm -f *.o *~ src/*~ samples/*~ internal/*~ libraw/*~ lib/lib*.a bin/[4a-z]* object/*o dcraw/*~ doc/*~ bin/*~ src/*/*~ + +### generated +object/libraw_c_api.o: src/libraw_c_api.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_c_api.o src/libraw_c_api.cpp +object/libraw_datastream.o: src/libraw_datastream.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/libraw_datastream.o src/libraw_datastream.cpp +object/canon_600.o: src/decoders/canon_600.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp +object/crx.o: src/decoders/crx.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp +object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw_dcrdefs.o src/decoders/decoders_libraw_dcrdefs.cpp +object/decoders_libraw.o: src/decoders/decoders_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_libraw.o src/decoders/decoders_libraw.cpp +object/dng.o: src/decoders/dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dng.o src/decoders/dng.cpp +object/fp_dng.o: src/decoders/fp_dng.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fp_dng.o src/decoders/fp_dng.cpp +object/fuji_compressed.o: src/decoders/fuji_compressed.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji_compressed.o src/decoders/fuji_compressed.cpp +object/generic.o: src/decoders/generic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/generic.o src/decoders/generic.cpp +object/kodak_decoders.o: src/decoders/kodak_decoders.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak_decoders.o src/decoders/kodak_decoders.cpp +object/load_mfbacks.o: src/decoders/load_mfbacks.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/load_mfbacks.o src/decoders/load_mfbacks.cpp +object/smal.o: src/decoders/smal.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/smal.o src/decoders/smal.cpp +object/unpack_thumb.o: src/decoders/unpack_thumb.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack_thumb.o src/decoders/unpack_thumb.cpp +object/unpack.o: src/decoders/unpack.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/unpack.o src/decoders/unpack.cpp +object/aahd_demosaic.o: src/demosaic/aahd_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aahd_demosaic.o src/demosaic/aahd_demosaic.cpp +object/ahd_demosaic.o: src/demosaic/ahd_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ahd_demosaic.o src/demosaic/ahd_demosaic.cpp +object/dcb_demosaic.o: src/demosaic/dcb_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcb_demosaic.o src/demosaic/dcb_demosaic.cpp +object/dht_demosaic.o: src/demosaic/dht_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dht_demosaic.o src/demosaic/dht_demosaic.cpp +object/misc_demosaic.o: src/demosaic/misc_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_demosaic.o src/demosaic/misc_demosaic.cpp +object/xtrans_demosaic.o: src/demosaic/xtrans_demosaic.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/xtrans_demosaic.o src/demosaic/xtrans_demosaic.cpp +object/dngsdk_glue.o: src/integration/dngsdk_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dngsdk_glue.o src/integration/dngsdk_glue.cpp +object/rawspeed_glue.o: src/integration/rawspeed_glue.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/rawspeed_glue.o src/integration/rawspeed_glue.cpp +object/adobepano.o: src/metadata/adobepano.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/adobepano.o src/metadata/adobepano.cpp +object/canon.o: src/metadata/canon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon.o src/metadata/canon.cpp +object/ciff.o: src/metadata/ciff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ciff.o src/metadata/ciff.cpp +object/cr3_parser.o: src/metadata/cr3_parser.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cr3_parser.o src/metadata/cr3_parser.cpp +object/epson.o: src/metadata/epson.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/epson.o src/metadata/epson.cpp +object/exif_gps.o: src/metadata/exif_gps.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/exif_gps.o src/metadata/exif_gps.cpp +object/fuji.o: src/metadata/fuji.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/fuji.o src/metadata/fuji.cpp +object/identify_tools.o: src/metadata/identify_tools.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify_tools.o src/metadata/identify_tools.cpp +object/identify.o: src/metadata/identify.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/identify.o src/metadata/identify.cpp +object/kodak.o: src/metadata/kodak.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/kodak.o src/metadata/kodak.cpp +object/leica.o: src/metadata/leica.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/leica.o src/metadata/leica.cpp +object/makernotes.o: src/metadata/makernotes.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/makernotes.o src/metadata/makernotes.cpp +object/mediumformat.o: src/metadata/mediumformat.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mediumformat.o src/metadata/mediumformat.cpp +object/minolta.o: src/metadata/minolta.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/minolta.o src/metadata/minolta.cpp +object/misc_parsers.o: src/metadata/misc_parsers.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/misc_parsers.o src/metadata/misc_parsers.cpp +object/nikon.o: src/metadata/nikon.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/nikon.o src/metadata/nikon.cpp +object/hasselblad_model.o: src/metadata/hasselblad_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/hasselblad_model.o src/metadata/hasselblad_model.cpp +object/normalize_model.o: src/metadata/normalize_model.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/normalize_model.o src/metadata/normalize_model.cpp +object/olympus.o: src/metadata/olympus.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/olympus.o src/metadata/olympus.cpp +object/p1.o: src/metadata/p1.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/p1.o src/metadata/p1.cpp +object/pentax.o: src/metadata/pentax.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pentax.o src/metadata/pentax.cpp +object/samsung.o: src/metadata/samsung.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/samsung.o src/metadata/samsung.cpp +object/sony.o: src/metadata/sony.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sony.o src/metadata/sony.cpp +object/tiff.o: src/metadata/tiff.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff.o src/metadata/tiff.cpp +object/aspect_ratio.o: src/postprocessing/aspect_ratio.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/aspect_ratio.o src/postprocessing/aspect_ratio.cpp +object/dcraw_process.o: src/postprocessing/dcraw_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/dcraw_process.o src/postprocessing/dcraw_process.cpp +object/mem_image.o: src/postprocessing/mem_image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/mem_image.o src/postprocessing/mem_image.cpp +object/postprocessing_aux.o: src/postprocessing/postprocessing_aux.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_aux.o src/postprocessing/postprocessing_aux.cpp +object/postprocessing_utils_dcrdefs.o: src/postprocessing/postprocessing_utils_dcrdefs.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils_dcrdefs.o src/postprocessing/postprocessing_utils_dcrdefs.cpp +object/postprocessing_utils.o: src/postprocessing/postprocessing_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/postprocessing_utils.o src/postprocessing/postprocessing_utils.cpp +object/raw2image.o: src/preprocessing/raw2image.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/raw2image.o src/preprocessing/raw2image.cpp +object/ext_preprocess.o: src/preprocessing/ext_preprocess.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/ext_preprocess.o src/preprocessing/ext_preprocess.cpp +object/subtract_black.o: src/preprocessing/subtract_black.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/subtract_black.o src/preprocessing/subtract_black.cpp +object/cameralist.o: src/tables/cameralist.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/cameralist.o src/tables/cameralist.cpp +object/colorconst.o: src/tables/colorconst.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colorconst.o src/tables/colorconst.cpp +object/colordata.o: src/tables/colordata.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/colordata.o src/tables/colordata.cpp +object/wblists.o: src/tables/wblists.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/wblists.o src/tables/wblists.cpp +object/curves.o: src/utils/curves.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/curves.o src/utils/curves.cpp +object/decoder_info.o: src/utils/decoder_info.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoder_info.o src/utils/decoder_info.cpp +object/init_close_utils.o: src/utils/init_close_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/init_close_utils.o src/utils/init_close_utils.cpp +object/open.o: src/utils/open.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/open.o src/utils/open.cpp +object/phaseone_processing.o: src/utils/phaseone_processing.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/phaseone_processing.o src/utils/phaseone_processing.cpp +object/read_utils.o: src/utils/read_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/read_utils.o src/utils/read_utils.cpp +object/thumb_utils.o: src/utils/thumb_utils.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/thumb_utils.o src/utils/thumb_utils.cpp +object/utils_dcraw.o: src/utils/utils_dcraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_dcraw.o src/utils/utils_dcraw.cpp +object/utils_libraw.o: src/utils/utils_libraw.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/utils_libraw.o src/utils/utils_libraw.cpp +object/apply_profile.o: src/write/apply_profile.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/apply_profile.o src/write/apply_profile.cpp +object/file_write.o: src/write/file_write.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/file_write.o src/write/file_write.cpp +object/tiff_writer.o: src/write/tiff_writer.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/tiff_writer.o src/write/tiff_writer.cpp +object/x3f_parse_process.o: src/x3f/x3f_parse_process.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_parse_process.o src/x3f/x3f_parse_process.cpp +object/x3f_utils_patched.o: src/x3f/x3f_utils_patched.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/x3f_utils_patched.o src/x3f/x3f_utils_patched.cpp diff --git a/Makefile.msvc b/Makefile.msvc new file mode 100644 index 000000000..c06b35f05 --- /dev/null +++ b/Makefile.msvc @@ -0,0 +1,628 @@ +# Additional compiler flags (OpenMP, SSEx, AVX, ...) + +#COPT_OPT=/arch:SSE2 /arch:AVX + +# Compile with RawSpeed support +#CFLAGS_RAWSPEED=/DUSE_RAWSPEED /I"..\\RawSpeed" /I"..\\RawSpeed\include" /I"..\\RawSpeed\include\libjpeg" +#LDFLAGS_RAWSPEED=..\RawSpeed\lib\rawspeed.lib ..\RawSpeed\lib\libxml2.lib ..\RawSpeed\lib\iconv.lib ..\RawSpeed\lib\charset.lib ..\RawSpeed\lib\turbojpeg-static.lib + +# Compile with DNG SDK support +#CFLAGS_DNG=/DUSE_DNGSDK /I"..\\dng_sdk\\source" +#LDFLAGS_DNG=..\\dng_sdk\\release\\libdng.lib ..\\dng_sdk\\release\\XMPCore.lib +# you may also need to specify zlib.lib and jpeg.lib in the line above + +# LCMS 1.x support +#LCMS_DEF=/DUSE_LCMS /DCMS_DLL /I..\lcms-1.19\include +#LCMS_LIB=..\lcms-1.19\bin\lcms.lib + +# LCMS 2.x support +#LCMS_DEF=/DUSE_LCMS2 /DCMS_DLL /I..\lcms2-2.3\include +#LCMS_LIB=..\lcms2-2.3\bin\lcms2_dll.lib + +# JPEG support for DNG +#JPEG_DEF=/DUSE_JPEG /I..\jpeg-8d +#JPEG_LIB=..\jpeg-8d\Release\jpeg.lib + + +SAMPLES=bin\raw-identify.exe bin\simple_dcraw.exe bin\dcraw_emu.exe bin\dcraw_half.exe \ + bin\half_mt.exe bin\mem_image.exe bin\unprocessed_raw.exe bin\4channels.exe \ + bin\multirender_test.exe bin\postprocessing_benchmark.exe bin\openbayer_sample.exe \ + bin\rawtextdump.exe + +LIBSTATIC=lib\libraw_static.lib +DLL=bin\libraw.dll +LIBDLL=lib\libraw.lib + +all: $(DLL) $(LIBSTATIC) $(SAMPLES) + +$(LIBDLL): $(DLL) + +# Guess LIBPATH from $INCLUDE + +LIB_OBJECTS= object\libraw_datastream_st.obj object\libraw_c_api_st.obj \ + object\cameralist_st.obj object\fuji_compressed_st.obj \ + object\crx_st.obj object\fp_dng_st.obj object\decoders_libraw_st.obj \ + object\unpack_st.obj object\unpack_thumb_st.obj \ + object\rawspeed_glue_st.obj object\dngsdk_glue_st.obj \ + object\colorconst_st.obj object\utils_libraw_st.obj object\init_close_utils_st.obj \ + object\decoder_info_st.obj object\open_st.obj object\phaseone_processing_st.obj \ + object\thumb_utils_st.obj \ + object\tiff_writer_st.obj object\subtract_black_st.obj object\postprocessing_utils_st.obj \ + object\dcraw_process_st.obj object\raw2image_st.obj object\mem_image_st.obj \ + object\x3f_utils_patched_st.obj object\x3f_parse_process_st.obj \ + object\read_utils_st.obj object\curves_st.obj object\utils_dcraw_st.obj \ + object\colordata_st.obj \ + object\canon_600_st.obj object\decoders_dcraw_st.obj \ + object\decoders_libraw_dcrdefs_st.obj object\generic_st.obj \ + object\kodak_decoders_st.obj object\dng_st.obj object\smal_st.obj \ + object\load_mfbacks_st.obj \ + object\sony_st.obj object\nikon_st.obj object\samsung_st.obj object\cr3_parser_st.obj \ + object\canon_st.obj object\epson_st.obj object\olympus_st.obj object\leica_st.obj \ + object\fuji_st.obj object\adobepano_st.obj object\pentax_st.obj object\p1_st.obj \ + object\makernotes_st.obj object\exif_gps_st.obj object\kodak_st.obj \ + object\tiff_st.obj object\ciff_st.obj object\mediumformat_st.obj object\minolta_st.obj \ + object\identify_tools_st.obj \ + object\hasselblad_model_st.obj object\normalize_model_st.obj object\identify_st.obj \ + object\misc_parsers_st.obj object\wblists_st.obj \ + object\postprocessing_aux_st.obj object\postprocessing_utils_dcrdefs_st.obj \ + object\aspect_ratio_st.obj \ + object\misc_demosaic_st.obj object\xtrans_demosaic_st.obj object\ahd_demosaic_st.obj \ + object\dht_demosaic_st.obj object\aahd_demosaic_st.obj object\dcb_demosaic_st.obj \ + object\file_write_st.obj \ + object\ext_preprocess_st.obj object\apply_profile_st.obj + + +DLL_OBJECTS= object\libraw_datastream.obj object\libraw_c_api.obj \ + object\cameralist.obj object\fuji_compressed.obj \ + object\crx.obj object\fp_dng.obj object\decoders_libraw.obj \ + object\unpack.obj object\unpack_thumb.obj \ + object\rawspeed_glue.obj object\dngsdk_glue.obj \ + object\colorconst.obj object\utils_libraw.obj \ + object\init_close_utils.obj \ + object\decoder_info.obj object\open.obj object\phaseone_processing.obj \ + object\thumb_utils.obj \ + object\tiff_writer.obj object\subtract_black.obj \ + object\postprocessing_utils.obj object\dcraw_process.obj \ + object\raw2image.obj object\mem_image.obj \ + object\x3f_utils_patched.obj object\x3f_parse_process.obj \ + object\read_utils.obj object\curves.obj object\utils_dcraw.obj \ + object\colordata.obj \ + object\canon_600.obj object\decoders_dcraw.obj \ + object\decoders_libraw_dcrdefs.obj object\generic.obj \ + object\kodak_decoders.obj object\dng.obj object\smal.obj \ + object\load_mfbacks.obj \ + object\sony.obj object\nikon.obj object\samsung.obj \ + object\cr3_parser.obj object\canon.obj object\epson.obj \ + object\olympus.obj object\leica.obj \ + object\fuji.obj object\adobepano.obj object\pentax.obj object\p1.obj \ + object\makernotes.obj object\exif_gps.obj object\kodak.obj \ + object\tiff.obj object\ciff.obj object\mediumformat.obj \ + object\minolta.obj \ + object\identify_tools.obj \ + object\hasselblad_model.obj object\normalize_model.obj object\identify.obj \ + object\misc_parsers.obj object\wblists.obj \ + object\postprocessing_aux.obj object\postprocessing_utils_dcrdefs.obj \ + object\aspect_ratio.obj \ + object\misc_demosaic.obj object\xtrans_demosaic.obj \ + object\ahd_demosaic.obj object\dht_demosaic.obj \ + object\aahd_demosaic.obj object\dcb_demosaic.obj \ + object\file_write.obj \ + object\ext_preprocess.obj object\apply_profile.obj + + +CC=cl.exe +COPT=/EHsc /MP /MD /I. /DWIN32 /O2 /W0 /nologo $(COPT_OPT) $(CFLAGSG2) $(CFLAGSG3) $(LCMS_DEF) $(JPEG_DEF) $(CFLAGS_RAWSPEED) $(CFLAGS_DNG) + +LINKLIB=$(LIBDLL) $(LDFLAGS_RAWSPEED) $(LDFLAGS_DNG) + + + +# Samples - default to dynamic (DLL) link, uncomment next lines +#CFLAGS2=/DLIBRAW_NODLL +#LINKLIB=$(LIBSTATIC) + +bin\raw-identify.exe: $(LINKLIB) samples\raw-identify.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\raw-identify.exe" /Fo"object\\" samples\raw-identify.cpp $(LINKLIB) + +bin\unprocessed_raw.exe: $(LINKLIB) samples\unprocessed_raw.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\unprocessed_raw.exe" /Fo"object\\" samples\unprocessed_raw.cpp $(LINKLIB) ws2_32.lib + +bin\4channels.exe: $(LINKLIB) samples\4channels.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\4channels.exe" /Fo"object\\" samples\4channels.cpp $(LINKLIB) + +bin\rawtextdump.exe: $(LINKLIB) samples\rawtextdump.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\rawtextdump.exe" /Fo"object\\" samples\rawtextdump.cpp $(LINKLIB) + +bin\simple_dcraw.exe: $(LINKLIB) samples\simple_dcraw.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\simple_dcraw.exe" /Fo"object\\" samples\simple_dcraw.cpp $(LINKLIB) + +bin\postprocessing_benchmark.exe: $(LINKLIB) samples\postprocessing_benchmark.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\postprocessing_benchmark.exe" /Fo"object\\" samples\postprocessing_benchmark.cpp $(LINKLIB) + +bin\multirender_test.exe: $(LINKLIB) samples\multirender_test.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\multirender_test.exe" /Fo"object\\" samples\multirender_test.cpp $(LINKLIB) + +bin\openbayer_sample.exe: $(LINKLIB) samples\openbayer_sample.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\openbayer_sample.exe" /Fo"object\\" samples\openbayer_sample.cpp $(LINKLIB) + +bin\mem_image.exe: $(LINKLIB) samples\mem_image_sample.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\mem_image.exe" /Fo"object\\" samples\mem_image_sample.cpp $(LINKLIB) + +bin\dcraw_emu.exe: $(LINKLIB) samples\dcraw_emu.cpp + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\dcraw_emu.exe" /Fo"object\\" samples\dcraw_emu.cpp $(LINKLIB) + +bin\dcraw_half.exe: $(LINKLIB) samples\dcraw_half.c + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\dcraw_half.exe" /Fo"object\\" samples\dcraw_half.c $(LINKLIB) + +bin\half_mt.exe: $(LINKLIB) samples\half_mt_win32.c + $(CC) $(COPT) $(CFLAGS2) /Fe"bin\\half_mt.exe" /Fo"object\\" samples\half_mt_win32.c $(LINKLIB) + +# DLL build + +$(DLL): $(DLL_OBJECTS) + -del /f $(DLL) $(LIBDLL) + cl $(COPT) /LD $(DLL_OBJECTS) $(LDFLAGS_RAWSPEED) $(LDFLAGS_DNG) $(LCMS_LIB) $(JPEG_LIB) /link /out:"$(DLL)" /implib:"$(LIBDLL)" + +# LIBRARY BUILD +$(LIBSTATIC): $(LIB_OBJECTS) + -del /f $(LIBSTATIC) + lib /OUT:$(LIBSTATIC) /LTCG $(LIB_OBJECTS) + +# clean +clean: + -del $(LIBSTATIC) $(LIBDLL) lib\*.exp + -del $(LIB_OBJECTS) $(DLL_OBJECTS) + -del object\*.o + -del $(DLL) $(SAMPLES) + +# OBJ generation rules +object\canon_600_st.obj: src\decoders\canon_600.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\canon_600_st.obj" /c src\decoders\canon_600.cpp + +object\canon_600.obj: src\decoders\canon_600.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\canon_600.obj" /c src\decoders\canon_600.cpp + +object\crx_st.obj: src\decoders\crx.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\crx_st.obj" /c src\decoders\crx.cpp + +object\crx.obj: src\decoders\crx.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\crx.obj" /c src\decoders\crx.cpp + +object\decoders_dcraw_st.obj: src\decoders\decoders_dcraw.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_dcraw_st.obj" /c src\decoders\decoders_dcraw.cpp + +object\decoders_dcraw.obj: src\decoders\decoders_dcraw.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_dcraw.obj" /c src\decoders\decoders_dcraw.cpp + +object\decoders_libraw_dcrdefs_st.obj: src\decoders\decoders_libraw_dcrdefs.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_dcrdefs_st.obj" /c src\decoders\decoders_libraw_dcrdefs.cpp + +object\decoders_libraw_dcrdefs.obj: src\decoders\decoders_libraw_dcrdefs.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_dcrdefs.obj" /c src\decoders\decoders_libraw_dcrdefs.cpp + +object\decoders_libraw_st.obj: src\decoders\decoders_libraw.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw_st.obj" /c src\decoders\decoders_libraw.cpp + +object\decoders_libraw.obj: src\decoders\decoders_libraw.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoders_libraw.obj" /c src\decoders\decoders_libraw.cpp + +object\dng_st.obj: src\decoders\dng.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dng_st.obj" /c src\decoders\dng.cpp + +object\dng.obj: src\decoders\dng.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dng.obj" /c src\decoders\dng.cpp + +object\fp_dng_st.obj: src\decoders\fp_dng.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fp_dng_st.obj" /c src\decoders\fp_dng.cpp + +object\fp_dng.obj: src\decoders\fp_dng.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fp_dng.obj" /c src\decoders\fp_dng.cpp + +object\fuji_compressed_st.obj: src\decoders\fuji_compressed.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fuji_compressed_st.obj" /c src\decoders\fuji_compressed.cpp + +object\fuji_compressed.obj: src\decoders\fuji_compressed.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fuji_compressed.obj" /c src\decoders\fuji_compressed.cpp + +object\generic_st.obj: src\decoders\generic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\generic_st.obj" /c src\decoders\generic.cpp + +object\generic.obj: src\decoders\generic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\generic.obj" /c src\decoders\generic.cpp + +object\kodak_decoders_st.obj: src\decoders\kodak_decoders.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\kodak_decoders_st.obj" /c src\decoders\kodak_decoders.cpp + +object\kodak_decoders.obj: src\decoders\kodak_decoders.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\kodak_decoders.obj" /c src\decoders\kodak_decoders.cpp + +object\load_mfbacks_st.obj: src\decoders\load_mfbacks.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\load_mfbacks_st.obj" /c src\decoders\load_mfbacks.cpp + +object\load_mfbacks.obj: src\decoders\load_mfbacks.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\load_mfbacks.obj" /c src\decoders\load_mfbacks.cpp + +object\smal_st.obj: src\decoders\smal.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\smal_st.obj" /c src\decoders\smal.cpp + +object\smal.obj: src\decoders\smal.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\smal.obj" /c src\decoders\smal.cpp + +object\unpack_thumb_st.obj: src\decoders\unpack_thumb.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\unpack_thumb_st.obj" /c src\decoders\unpack_thumb.cpp + +object\unpack_thumb.obj: src\decoders\unpack_thumb.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\unpack_thumb.obj" /c src\decoders\unpack_thumb.cpp + +object\unpack_st.obj: src\decoders\unpack.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\unpack_st.obj" /c src\decoders\unpack.cpp + +object\unpack.obj: src\decoders\unpack.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\unpack.obj" /c src\decoders\unpack.cpp + +object\aahd_demosaic_st.obj: src\demosaic\aahd_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\aahd_demosaic_st.obj" /c src\demosaic\aahd_demosaic.cpp + +object\aahd_demosaic.obj: src\demosaic\aahd_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\aahd_demosaic.obj" /c src\demosaic\aahd_demosaic.cpp + +object\ahd_demosaic_st.obj: src\demosaic\ahd_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ahd_demosaic_st.obj" /c src\demosaic\ahd_demosaic.cpp + +object\ahd_demosaic.obj: src\demosaic\ahd_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ahd_demosaic.obj" /c src\demosaic\ahd_demosaic.cpp + +object\dcb_demosaic_st.obj: src\demosaic\dcb_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dcb_demosaic_st.obj" /c src\demosaic\dcb_demosaic.cpp + +object\dcb_demosaic.obj: src\demosaic\dcb_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dcb_demosaic.obj" /c src\demosaic\dcb_demosaic.cpp + +object\dht_demosaic_st.obj: src\demosaic\dht_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dht_demosaic_st.obj" /c src\demosaic\dht_demosaic.cpp + +object\dht_demosaic.obj: src\demosaic\dht_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dht_demosaic.obj" /c src\demosaic\dht_demosaic.cpp + +object\misc_demosaic_st.obj: src\demosaic\misc_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\misc_demosaic_st.obj" /c src\demosaic\misc_demosaic.cpp + +object\misc_demosaic.obj: src\demosaic\misc_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\misc_demosaic.obj" /c src\demosaic\misc_demosaic.cpp + +object\xtrans_demosaic_st.obj: src\demosaic\xtrans_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\xtrans_demosaic_st.obj" /c src\demosaic\xtrans_demosaic.cpp + +object\xtrans_demosaic.obj: src\demosaic\xtrans_demosaic.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\xtrans_demosaic.obj" /c src\demosaic\xtrans_demosaic.cpp + +object\dngsdk_glue_st.obj: src\integration\dngsdk_glue.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dngsdk_glue_st.obj" /c src\integration\dngsdk_glue.cpp + +object\dngsdk_glue.obj: src\integration\dngsdk_glue.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dngsdk_glue.obj" /c src\integration\dngsdk_glue.cpp + +object\rawspeed_glue_st.obj: src\integration\rawspeed_glue.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\rawspeed_glue_st.obj" /c src\integration\rawspeed_glue.cpp + +object\rawspeed_glue.obj: src\integration\rawspeed_glue.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\rawspeed_glue.obj" /c src\integration\rawspeed_glue.cpp + +object\adobepano_st.obj: src\metadata\adobepano.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\adobepano_st.obj" /c src\metadata\adobepano.cpp + +object\adobepano.obj: src\metadata\adobepano.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\adobepano.obj" /c src\metadata\adobepano.cpp + +object\canon_st.obj: src\metadata\canon.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\canon_st.obj" /c src\metadata\canon.cpp + +object\canon.obj: src\metadata\canon.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\canon.obj" /c src\metadata\canon.cpp + +object\ciff_st.obj: src\metadata\ciff.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ciff_st.obj" /c src\metadata\ciff.cpp + +object\ciff.obj: src\metadata\ciff.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ciff.obj" /c src\metadata\ciff.cpp + +object\cr3_parser_st.obj: src\metadata\cr3_parser.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\cr3_parser_st.obj" /c src\metadata\cr3_parser.cpp + +object\cr3_parser.obj: src\metadata\cr3_parser.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\cr3_parser.obj" /c src\metadata\cr3_parser.cpp + +object\epson_st.obj: src\metadata\epson.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\epson_st.obj" /c src\metadata\epson.cpp + +object\epson.obj: src\metadata\epson.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\epson.obj" /c src\metadata\epson.cpp + +object\exif_gps_st.obj: src\metadata\exif_gps.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\exif_gps_st.obj" /c src\metadata\exif_gps.cpp + +object\exif_gps.obj: src\metadata\exif_gps.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\exif_gps.obj" /c src\metadata\exif_gps.cpp + +object\fuji_st.obj: src\metadata\fuji.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\fuji_st.obj" /c src\metadata\fuji.cpp + +object\fuji.obj: src\metadata\fuji.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\fuji.obj" /c src\metadata\fuji.cpp + +object\identify_tools_st.obj: src\metadata\identify_tools.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\identify_tools_st.obj" /c src\metadata\identify_tools.cpp + +object\identify_tools.obj: src\metadata\identify_tools.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\identify_tools.obj" /c src\metadata\identify_tools.cpp + +object\identify_st.obj: src\metadata\identify.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\identify_st.obj" /c src\metadata\identify.cpp + +object\identify.obj: src\metadata\identify.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\identify.obj" /c src\metadata\identify.cpp + +object\kodak_st.obj: src\metadata\kodak.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\kodak_st.obj" /c src\metadata\kodak.cpp + +object\kodak.obj: src\metadata\kodak.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\kodak.obj" /c src\metadata\kodak.cpp + +object\leica_st.obj: src\metadata\leica.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\leica_st.obj" /c src\metadata\leica.cpp + +object\leica.obj: src\metadata\leica.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\leica.obj" /c src\metadata\leica.cpp + +object\makernotes_st.obj: src\metadata\makernotes.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\makernotes_st.obj" /c src\metadata\makernotes.cpp + +object\makernotes.obj: src\metadata\makernotes.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\makernotes.obj" /c src\metadata\makernotes.cpp + +object\mediumformat_st.obj: src\metadata\mediumformat.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\mediumformat_st.obj" /c src\metadata\mediumformat.cpp + +object\mediumformat.obj: src\metadata\mediumformat.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\mediumformat.obj" /c src\metadata\mediumformat.cpp + +object\minolta_st.obj: src\metadata\minolta.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\minolta_st.obj" /c src\metadata\minolta.cpp + +object\minolta.obj: src\metadata\minolta.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\minolta.obj" /c src\metadata\minolta.cpp + +object\misc_parsers_st.obj: src\metadata\misc_parsers.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\misc_parsers_st.obj" /c src\metadata\misc_parsers.cpp + +object\misc_parsers.obj: src\metadata\misc_parsers.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\misc_parsers.obj" /c src\metadata\misc_parsers.cpp + +object\nikon_st.obj: src\metadata\nikon.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\nikon_st.obj" /c src\metadata\nikon.cpp + +object\nikon.obj: src\metadata\nikon.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\nikon.obj" /c src\metadata\nikon.cpp + +object\hasselblad_model_st.obj: src\metadata\hasselblad_model.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\hasselblad_model_st.obj" /c src\metadata\hasselblad_model.cpp + +object\hasselblad_model.obj: src\metadata\hasselblad_model.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\hasselblad_model.obj" /c src\metadata\hasselblad_model.cpp + +object\normalize_model_st.obj: src\metadata\normalize_model.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\normalize_model_st.obj" /c src\metadata\normalize_model.cpp + +object\normalize_model.obj: src\metadata\normalize_model.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\normalize_model.obj" /c src\metadata\normalize_model.cpp + +object\olympus_st.obj: src\metadata\olympus.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\olympus_st.obj" /c src\metadata\olympus.cpp + +object\olympus.obj: src\metadata\olympus.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\olympus.obj" /c src\metadata\olympus.cpp + +object\p1_st.obj: src\metadata\p1.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\p1_st.obj" /c src\metadata\p1.cpp + +object\p1.obj: src\metadata\p1.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\p1.obj" /c src\metadata\p1.cpp + +object\pentax_st.obj: src\metadata\pentax.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\pentax_st.obj" /c src\metadata\pentax.cpp + +object\pentax.obj: src\metadata\pentax.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\pentax.obj" /c src\metadata\pentax.cpp + +object\samsung_st.obj: src\metadata\samsung.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\samsung_st.obj" /c src\metadata\samsung.cpp + +object\samsung.obj: src\metadata\samsung.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\samsung.obj" /c src\metadata\samsung.cpp + +object\sony_st.obj: src\metadata\sony.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\sony_st.obj" /c src\metadata\sony.cpp + +object\sony.obj: src\metadata\sony.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\sony.obj" /c src\metadata\sony.cpp + +object\tiff_st.obj: src\metadata\tiff.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\tiff_st.obj" /c src\metadata\tiff.cpp + +object\tiff.obj: src\metadata\tiff.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\tiff.obj" /c src\metadata\tiff.cpp + +object\aspect_ratio_st.obj: src\postprocessing\aspect_ratio.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\aspect_ratio_st.obj" /c src\postprocessing\aspect_ratio.cpp + +object\aspect_ratio.obj: src\postprocessing\aspect_ratio.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\aspect_ratio.obj" /c src\postprocessing\aspect_ratio.cpp + +object\dcraw_process_st.obj: src\postprocessing\dcraw_process.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\dcraw_process_st.obj" /c src\postprocessing\dcraw_process.cpp + +object\dcraw_process.obj: src\postprocessing\dcraw_process.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\dcraw_process.obj" /c src\postprocessing\dcraw_process.cpp + +object\mem_image_st.obj: src\postprocessing\mem_image.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\mem_image_st.obj" /c src\postprocessing\mem_image.cpp + +object\mem_image.obj: src\postprocessing\mem_image.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\mem_image.obj" /c src\postprocessing\mem_image.cpp + +object\postprocessing_aux_st.obj: src\postprocessing\postprocessing_aux.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_aux_st.obj" /c src\postprocessing\postprocessing_aux.cpp + +object\postprocessing_aux.obj: src\postprocessing\postprocessing_aux.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_aux.obj" /c src\postprocessing\postprocessing_aux.cpp + +object\postprocessing_utils_dcrdefs_st.obj: src\postprocessing\postprocessing_utils_dcrdefs.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_dcrdefs_st.obj" /c src\postprocessing\postprocessing_utils_dcrdefs.cpp + +object\postprocessing_utils_dcrdefs.obj: src\postprocessing\postprocessing_utils_dcrdefs.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_dcrdefs.obj" /c src\postprocessing\postprocessing_utils_dcrdefs.cpp + +object\postprocessing_utils_st.obj: src\postprocessing\postprocessing_utils.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils_st.obj" /c src\postprocessing\postprocessing_utils.cpp + +object\postprocessing_utils.obj: src\postprocessing\postprocessing_utils.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\postprocessing_utils.obj" /c src\postprocessing\postprocessing_utils.cpp + +object\ext_preprocess_st.obj: src\preprocessing\ext_preprocess.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\ext_preprocess_st.obj" /c src\preprocessing\ext_preprocess.cpp + +object\ext_preprocess.obj: src\preprocessing\ext_preprocess.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\ext_preprocess.obj" /c src\preprocessing\ext_preprocess.cpp + +object\raw2image_st.obj: src\preprocessing\raw2image.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\raw2image_st.obj" /c src\preprocessing\raw2image.cpp + +object\raw2image.obj: src\preprocessing\raw2image.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\raw2image.obj" /c src\preprocessing\raw2image.cpp + +object\subtract_black_st.obj: src\preprocessing\subtract_black.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\subtract_black_st.obj" /c src\preprocessing\subtract_black.cpp + +object\subtract_black.obj: src\preprocessing\subtract_black.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\subtract_black.obj" /c src\preprocessing\subtract_black.cpp + +object\cameralist_st.obj: src\tables\cameralist.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\cameralist_st.obj" /c src\tables\cameralist.cpp + +object\cameralist.obj: src\tables\cameralist.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\cameralist.obj" /c src\tables\cameralist.cpp + +object\colorconst_st.obj: src\tables\colorconst.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\colorconst_st.obj" /c src\tables\colorconst.cpp + +object\colorconst.obj: src\tables\colorconst.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\colorconst.obj" /c src\tables\colorconst.cpp + +object\colordata_st.obj: src\tables\colordata.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\colordata_st.obj" /c src\tables\colordata.cpp + +object\colordata.obj: src\tables\colordata.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\colordata.obj" /c src\tables\colordata.cpp + +object\wblists_st.obj: src\tables\wblists.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\wblists_st.obj" /c src\tables\wblists.cpp + +object\wblists.obj: src\tables\wblists.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\wblists.obj" /c src\tables\wblists.cpp + +object\curves_st.obj: src\utils\curves.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\curves_st.obj" /c src\utils\curves.cpp + +object\curves.obj: src\utils\curves.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\curves.obj" /c src\utils\curves.cpp + +object\decoder_info_st.obj: src\utils\decoder_info.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoder_info_st.obj" /c src\utils\decoder_info.cpp + +object\decoder_info.obj: src\utils\decoder_info.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\decoder_info.obj" /c src\utils\decoder_info.cpp + +object\init_close_utils_st.obj: src\utils\init_close_utils.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\init_close_utils_st.obj" /c src\utils\init_close_utils.cpp + +object\init_close_utils.obj: src\utils\init_close_utils.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\init_close_utils.obj" /c src\utils\init_close_utils.cpp + +object\open_st.obj: src\utils\open.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\open_st.obj" /c src\utils\open.cpp + +object\open.obj: src\utils\open.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\open.obj" /c src\utils\open.cpp + +object\phaseone_processing_st.obj: src\utils\phaseone_processing.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\phaseone_processing_st.obj" /c src\utils\phaseone_processing.cpp + +object\phaseone_processing.obj: src\utils\phaseone_processing.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\phaseone_processing.obj" /c src\utils\phaseone_processing.cpp + +object\read_utils_st.obj: src\utils\read_utils.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\read_utils_st.obj" /c src\utils\read_utils.cpp + +object\read_utils.obj: src\utils\read_utils.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\read_utils.obj" /c src\utils\read_utils.cpp + +object\thumb_utils_st.obj: src\utils\thumb_utils.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\thumb_utils_st.obj" /c src\utils\thumb_utils.cpp + +object\thumb_utils.obj: src\utils\thumb_utils.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\thumb_utils.obj" /c src\utils\thumb_utils.cpp + +object\utils_dcraw_st.obj: src\utils\utils_dcraw.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\utils_dcraw_st.obj" /c src\utils\utils_dcraw.cpp + +object\utils_dcraw.obj: src\utils\utils_dcraw.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\utils_dcraw.obj" /c src\utils\utils_dcraw.cpp + +object\utils_libraw_st.obj: src\utils\utils_libraw.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\utils_libraw_st.obj" /c src\utils\utils_libraw.cpp + +object\utils_libraw.obj: src\utils\utils_libraw.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\utils_libraw.obj" /c src\utils\utils_libraw.cpp + +object\apply_profile_st.obj: src\write\apply_profile.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\apply_profile_st.obj" /c src\write\apply_profile.cpp + +object\apply_profile.obj: src\write\apply_profile.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\apply_profile.obj" /c src\write\apply_profile.cpp + +object\file_write_st.obj: src\write\file_write.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\file_write_st.obj" /c src\write\file_write.cpp + +object\file_write.obj: src\write\file_write.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\file_write.obj" /c src\write\file_write.cpp + +object\tiff_writer_st.obj: src\write\tiff_writer.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\tiff_writer_st.obj" /c src\write\tiff_writer.cpp + +object\tiff_writer.obj: src\write\tiff_writer.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\tiff_writer.obj" /c src\write\tiff_writer.cpp + +object\x3f_parse_process_st.obj: src\x3f\x3f_parse_process.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\x3f_parse_process_st.obj" /c src\x3f\x3f_parse_process.cpp + +object\x3f_parse_process.obj: src\x3f\x3f_parse_process.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\x3f_parse_process.obj" /c src\x3f\x3f_parse_process.cpp + +object\x3f_utils_patched_st.obj: src\x3f\x3f_utils_patched.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\x3f_utils_patched_st.obj" /c src\x3f\x3f_utils_patched.cpp + +object\x3f_utils_patched.obj: src\x3f\x3f_utils_patched.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\x3f_utils_patched.obj" /c src\x3f\x3f_utils_patched.cpp + +object\libraw_c_api_st.obj: src\libraw_c_api.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\libraw_c_api_st.obj" /c src\libraw_c_api.cpp + +object\libraw_c_api.obj: src\libraw_c_api.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\libraw_c_api.obj" /c src\libraw_c_api.cpp + +object\libraw_datastream_st.obj: src\libraw_datastream.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\libraw_datastream_st.obj" /c src\libraw_datastream.cpp + +object\libraw_datastream.obj: src\libraw_datastream.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\libraw_datastream.obj" /c src\libraw_datastream.cpp + diff --git a/README.DNGSDK.txt b/README.DNGSDK.txt new file mode 100644 index 000000000..1eeabcac9 --- /dev/null +++ b/README.DNGSDK.txt @@ -0,0 +1,43 @@ +LibRaw can decode most common DNG formats (Bayer/Linear, 16-bit integer and +floating point) by itself (you need to use zlib for deflate decompression +support and libjpeg for lossy compressed DNGs). + +Some rare flavours of DNG files (e.g. for 8-bit files) are not implemented in +LibRaw. These files never come from camera or DNG files created by +Adobe DNG Converter, but created by some processing software that uses DNG as +intermediate format. + +To decode such files you need to compile LibRaw with Adobe DNG SDK. This SDK +to be used internally, standard LibRaw API remains untouched (you may specify +what kinds of DNG files you want to decode via Adobe code, see below). + +To build LibRaw with DNG SDK specify USE_DNGSDK in defines and adjust +include/linker path settings to point to DNG SDK's include and library folders. + +DNG SDK Version compatibility: + - Since LibRaw 0.20, DNG SDK 1.4 is required (DNG SDK 1.5 may work too, but + have not tested w/ LibRaw). + - There are several DNG SDK 1.4 versions circulated, the oldest known is + dated May 2012, you'll need the last one (dated June 2015). + - This version is available from Adobe site: + http://download.adobe.com/pub/adobe/dng/dng_sdk_1_4.zip + +In your application + + * create dng_host object (or derived object, e.g. with multithreaded) entity in your program; + * pass it to LibRaw via LibRaw::set_dng_host(dng_host *) call to enable DNG SDK use on runtime + * adjust imgdata.rawparams.use_dngsdk parameter with one of this values + (ORed bitwise): + LIBRAW_DNG_NONE - do not use DNG SDK for DNG processing + LIBRAW_DNG_FLOAT - process floating point DNGs via Adobe DNG SDK + LIBRAW_DNG_LINEAR - process 'linear DNG' (i.e. demosaiced) + LIBRAW_DNG_DEFLATE - process DNGs compressed with deflate (gzip) + LIBRAW_DNG_XTRANS - process Fuji X-Trans DNGs (6x6 CFA) + LIBRAW_DNG_OTHER - process other files (so usual 2x2 bayer) + LIBRAW_DNG_8BIT - process 8bit DNGs (e.g. JPEG compressed ones) + + Default value for this field: + LIBRAW_DNG_DEFAULT=LIBRAW_DNG_FLOAT|LIBRAW_DNG_LINEAR|LIBRAW_DNG_DEFLATE | LIBRAW_DNG_8BIT + + You also may use this macro to pass all supported DNGs to Adobe SDK: + LIBRAW_DNG_ALL = LIBRAW_DNG_FLOAT|LIBRAW_DNG_LINEAR|LIBRAW_DNG_XTRANS|LIBRAW_DNG_OTHER | LIBRAW_DNG_8BIT diff --git a/README.GoPro.txt b/README.GoPro.txt new file mode 100644 index 000000000..77ae15aed --- /dev/null +++ b/README.GoPro.txt @@ -0,0 +1,112 @@ +GoPro HERO/Fusion .GPR files are DNG files by nature, but with own wavelet-based codec. + +GoPro provides GPR SDK for reading these files, available at https://github.com/gopro/gpr + +LibRaw is able to use this GPR SDK to read GoPro HERO/Fusion files. + +To enable this support: + +1. Build GPR SDK (see NOTES section below) +2. Build LibRaw with -DUSE_DNGSDK and -DUSE_GPRSDK compiler flags + (you'll need to adjust INCLUDE path and linker flags to add GPR SDK files to compile/link). + + +NOTES: +I. GPR SDK comes with (patched) Adobe DNG SDK source (v1.4 but outdated). + This DNG SDK is *NOT* compatible with LibRaw since 0.20 due to + internals change . + +II. So, you need to patch latest Adobe DNG SDK v1.4 (dated 2015), this version + is available from Adobe: + http://download.adobe.com/pub/adobe/dng/dng_sdk_1_4.zip + or use Adobe DNG SDK v1.6 + + (most likely, this apply for v1.5 too, but not tested/checked): + + a) For Adobe DNG SDK v1.4 you'll need to enable dng_ifd.fCompression value == 9 in + dng_ifd::IsValidCFA() call + Use provided patch: LibRaw/GoPro/dng-sdk-1_4-allow-VC5-validate.diff + (it may not apply to any Adobe DNG SDK version, if so apply it by hands). + + This compression type is already handled (passed via validation) + in Adobe DNG SDK v1.6 + + b) Adobe DNG SDK v1.6 defines the ccVc5 constant in dng_tag_values.h + so GPR SDK's gpr_read_image.cpp will not compile due to constant redefinition + so use provided patch: LibRaw/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff + to use Adobe's definitiion + + c) Newer (than supplied w/ GPR SDK) Adobe SDK versions changes + dng_read_image::ReadTile interface, please apply patches + LibRaw/GoPro/gpr_read_image.cpp.diff + and LibRaw/GoPro/gpr_read_image.h.diff to your GPR SDK code + + d) GPR SDK's gpr_sdk/private/gpr.cpp uses own (added) dng_host method + GetGPMFPayload so it will not compile with Adobes (not patched) + dng_host.h + LibRaw does not use high-level interface provided by gpr.cpp, so + possible problem solutions are: + - either compile GPR SDK without gpr_sdk/private/gpr.cpp file + - or provide GPR's dng_host.h while building GPR SDK. + (in our software we use 1st method). + + See Note VII below for detailed GPR SDK build instructions w/ Cmake + +III. LibRaw uses private gpr_read_image() interface + So you'll need to add PATH_TO/gpr_sdk/gpr_sdk/private to -I compiler flags. + +IV. -DUSE_GPRSDK LibRaw build flag requires -DUSE_DNGSDK. LibRaw will not + compile if USE_GPRSDK is set, but USE_DNGSDK is not + +V. LibRaw will use DNG SDK to unpack GoPro files even if imgdata.params.use_dng_sdk is set to 0. + +VI. If LibRaw is built with -DUSE_GPRSDK, LibRaw::capabilities will return LIBRAW_CAPS_GPRSDK flag. + +VII. GPR SDK build using cmake (contributed by our user, great thanks) + +1. replace gopro's toplevel CMakeLists.txt with this one (this builds only a subset of the libraries): +------------------------------------ +# minimum required cmake version +cmake_minimum_required( VERSION 3.5 FATAL_ERROR ) + +set(CMAKE_SUPPRESS_REGENERATION true) +set(CMAKE_C_FLAGS "-std=c99") + +# project name +project( gpr ) + +option(DNGINCLUDEDIR "Adobe DNG toolkit include directory") +INCLUDE_DIRECTORIES( ${DNGINCLUDEDIR} ) + +# DNG toolkit requires C++11 minimum: +set_property(GLOBAL PROPERTY CXX_STANDARD 17) + +# add needed subdirectories +add_subdirectory( "source/lib/common" ) +add_subdirectory( "source/lib/vc5_common" ) +add_subdirectory( "source/lib/vc5_decoder" ) +add_subdirectory( "source/lib/gpr_sdk" ) + +set_property(TARGET gpr_sdk PROPERTY CXX_STANDARD 17) + +IF (WIN32) +TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=1 -DqMacOS=0 -DqLinux=0) +ELSEIF (APPLE) +TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=0 -DqMacOS=1 -DqLinux=0) +ELSE() +TARGET_COMPILE_DEFINITIONS( gpr_sdk PUBLIC -DqWinOS=0 -DqMacOS=0 -DqLinux=1) +ENDIF() +---------------------------------------- + +2. apply the two patches of README.GoPro.txt section II b. +the patch of section IIa is not needed with libdng1.5. + +3. delete these two files: +/source/lib/gpr_sdk/private/gpr.cpp +/source/lib/gpr_sdk/private/gpr_image_writer.cpp + +4. run CMAKE with -DDNGINCLUDEDIR, pointing to the headers from Adobe dng 1.5. + +5. build. You get 4 libraries "gpr_sdk", "vc5_common", "vc5_decoder", "common", the rest is ignored. + + diff --git a/README.RawSpeed.txt b/README.RawSpeed.txt new file mode 100644 index 000000000..fb4b94c93 --- /dev/null +++ b/README.RawSpeed.txt @@ -0,0 +1,62 @@ +================= Compile LibRaw with RawSpeed support ======================== + +0) RawSpeed version: + LibRaw supports 'master' version of RawSpeed library: https://github.com/darktable-org/rawspeed/tree/master + + Although this version is really outdated, newer versions does not looks stable enough for production + use (for example, this critical issue not fixed for 10+ months: https://github.com/darktable-org/rawspeed/issues/100 ) + +1) Prerequisites + +To build RawSpeed you need libxml2, iconv, and JPEG library installed on your +system. + +2) Build RawSpeed: + + -- consult http://rawstudio.org/blog/?p=800 for details + + -- Win32: you need POSIX Threads for Win32 installed on your system + (http://sources.redhat.com/pthreads-win32/) + + -- use provided RawSpeed/rawspeed.samsung-decoder.patch to fix + old Samsung decoder bug + + -- you may use qmake .pro files supplied in LibRaw distribution + (RawSpeed/rawspeed.qmake-pro-files.patch) + Adjust path to libraries/includes according to your setup. + + -- Win32: you need to add __declspec(..) to external C++ classes. + Use patch provided with LibRaw (RawSpeed/rawspeed.win32-dll.patch) + + -- Unix: you need to define rawspeed_get_number_of_processor_cores() call + For most unix systems (Linux, MacOS X 10.4+, FreeBSD) patch provided + with LibRaw (RawSpeed/rawspeed.cpucount-unix.patch) should work. + +3) Build LibRaw with RawSpeed support: + + Win32: + --Uncomment CFLAGS_RAWSPEED and LDFLAGS_RAWSPEED lines in + Makefile.msvc. Adjust paths to libraries/includes if needed. + -- run nmake -f Makefile.msvc + + Unix/MacOS: + -- Uncomment CFLAGS/LDADD lines in RawSpeed section in Makefile.dist + -- Uncomment RAWSPEED_DATA line if you wish to rebuild + internal copy of RawSpeed's cameras.xml + -- run make -f Makefile.dist + + Compile options: + -- You may specify -DNOSONY_RAWSPEED define if you do not want to use + RawSpeed's Sony formats decoder (because result of this decoder is + different from LibRaw's built-in decoder) + +4) Build/run your Apps with LibRaw+RawSpeed + + -- Build as usual, no changes required in your apps unless you + access LibRaw::imgdata.rawdata.raw_image[] directly + + -- you may turn off RawSpeed support on runtime by setting + imgdata.params.use_rawspeed to 0. + + -- You'll need all shared libraries you linked to at runtime (libxml2, + iconv, LibJPEG, and posix threads on Win32). diff --git a/README.cmake b/README.cmake new file mode 100644 index 000000000..0fc6d4adb --- /dev/null +++ b/README.cmake @@ -0,0 +1,9 @@ +Due to inability to support (user contributed) Cmake scripts, +the cmake builds are not officially supported by LibRaw team +since October 23, 2014 + +The scripts are moved to separate github repository +github.com:LibRaw/LibRaw-cmake.git + +Checkout from this repo if you want to use Cmake to build LibRaw. + diff --git a/README.demosaic-packs b/README.demosaic-packs new file mode 100644 index 000000000..8e1077eea --- /dev/null +++ b/README.demosaic-packs @@ -0,0 +1,17 @@ +======================= LibRaw demosaic pack(s) =============================== + +We were forced to stop supporting LibRaw demosaic packs: the contributed code +is out of date for several years, initial contributors has no interest in it. + +We too: we (LibRaw team) focused on RAW decode and metadata extraction, but not +on postprocessing (demosaic, noise suppression, etc). + +So, LibRaw-demosaic-pack-GPLn are abandoned now. We will be happy to convey +their support and development to any developer who will show interest. + +LibRaw 0.19 contains callback calls placed instead of calls to demosaic pack routines. +So, adaptation of demosaic packs to new LibRaw should be easy (and, of course, we'll +provide some support and/or implement additional callbacks if needed). + + + diff --git a/README.md b/README.md new file mode 100644 index 000000000..d7cedbe57 --- /dev/null +++ b/README.md @@ -0,0 +1,106 @@ +# LibRaw +## Library for reading and processing of RAW digicam images + + The LibRaw library provides a simple and unified interface for extracting out of RAW files generated by digital photo cameras the following: + +* RAW data (_pixel values)_ +* Metadata necessary for processing RAW (_geometry, CFA / Bayer pattern, black level, white balance, etc.)_ +* Embedded preview / thumbnail. + +The library is intended for use with programs that work with RAW files, such as: + +* RAW viewers +* RAW converters +* RAW data analyzers +* Software for stitching and compositing multi-frame aggregates like panoramas and image stacks. + +Using the LibRaw library allows one to focus on the substantive part of processing the data contained in RAW files, without getting distracted by the wide variety of RAW file and metadata formats, compression algorithms, etc. + +The library’s development is focused on: + +* Support for new cameras and formats +* Improving extraction of metadata necessary for RAW processing +* Providing an interface for reading other types of metadata. + +Additionally, the LibRaw library offers some basic RAW conversion, intended for cases when such conversion is not the main function of the LibRaw-using application _(for example: a viewer for 500+ graphic file formats, including RAW)._ These methods are inherited from the Dave Coffin’s dcraw.c utility _(see below the “Project history” section);_ their further development is not currently planned, because we do not consider production-quality rendering to be in the scope of LibRaw’s functionality _(the methods are retained for compatibility with prior versions and for rapid-fire testing of RAW support and other aspects)._ + +## Licensing + + +The LibRaw library is distributed free of charge and with open-source code subject to two licenses: + +1\. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + +2\. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + +To use the LibRaw library in an application, you can choose the license that better suits your needs. + +If you modify/add/improve the LibRaw source code, then your patches can only be included into the library’s official source code if you agree to it being distributed under both of the above licenses. + +We do not guarantee that the licensing will not change in future versions of LibRaw. + +## Update policy + + +### Major/minor releases + +* Major releases _(for example, 0.20)_ are published once every year and a half to two years. +* When the first public beta version of a major release is published, the list of supported cameras and formats is frozen; we try (but do not guarantee) to freeze the API/ABI as well. +* The public major release contains only that code which has been sufficiently tested on a wide user base (including in our commercial products). Something very new may not be included in it (but it will probably be included in a public snapshot, see below). +* Minor updates _(0.20.1, 0.20.2…)_ do not change the API/ABI and new cameras are not added; generally they are just bugfixes. +* Bugfixes are published as soon as possible in the [public GitHub repository](https://github.com/LibRaw/LibRaw). +* Minor version increments: these are generally published if a serious error has been fixed, one that potentially affects many library users (for example, a possible stack overflow). + +### Public snapshots + +* Public snapshots are published every 7-9 months in the [public GitHub repository](https://github.com/LibRaw/LibRaw). +* These versions contain support for new cameras that was added after the previous major release. The API/ABI of public snapshots is not frozen, and may change. +* Public snapshots are always tested on a fairly large user base, and may be considered suitable for use in programs that work with files with known origins (that is, recorded directly by users’ digital cameras). However, public snapshots should not be considered sufficiently reliable for processing files that are specially constructed for vulnerability testing; that is, they should not be used in public services that allow for anonymous processing of files of unknown provenance + +## Support and feedback + +* You can submit a bug report in one of the following ways: + * [Issues](https://github.com/LibRaw/LibRaw/issues) on GitHub + * The libraw.org [forum](https://www.libraw.org/forum) + * [Feedback form](https://www.libraw.org/contact) on libraw.org + * E-mail us at [info@libraw.org](mailto:info@libraw.org) +* Questions can be asked on the forum, through the feedback form, and via the email indicated above. + Please do not use Issues on GitHub for questions; it is intended specifically for problem reports. +* We prefer to process additions to the source code via the [Pull Requests](https://github.com/LibRaw/LibRaw/pulls) on GitHub. + +We cannot guarantee any response to requests submitted via the above methods. If you need a guaranteed response for a bug report and/or for extending technical support, please use the Extended Support option. + +## Project history + + +The LibRaw project was launched in 2008, based on the [dcraw.c](https://www.dechifro.org/dcraw/) (Dave Coffin) utility, with its goals being to: + +* Convert dcraw.c into a library that could be used by other programs, while also somewhat improving the structure of dcraw.c (removing global variables, making it thread-safe, etc.) +* Import changes made to dcraw.c +* Improve/expand the extraction of metadata. + +Unfortunately, support for dcraw.c was reduced to a minimum in 2015, and completely ceased in 2018. Since then, support for new cameras (including support for new formats) has been done entirely by the LibRaw team. + +The code that implements rendering of RAW to RGB is inherited from dcraw.c, without major changes (though a set of changes was implemented to speed up and parallelize this code). + +In the early-to-mid 2010s, we gladly expanded post-processing implemented in LibRaw, and readily accepted the input of outside developers (new/improved methods for debayerization/demosaicing, systematic noise reduction etc.). + +Experience has shown that the LibRaw team cannot support this added code on their own, while contributors do not provide support and development of the code they suggest and it ends up abandoned. As such, the majority of the modifications that are implemented by people outside the LibRaw team was moved to the [LibRaw-demosaic-pack-….](https://github.com/LibRaw?tab=repositories), where they remain in their original form (but these projects are still present in our GitHub). + +Thus, we arrive at our current status, described in the first part of this text. + +## Copyrights and Acknowledgements + +Copyright (C) 2008-2021 LibRaw LLC + +LibRaw uses code from Dave Coffin’s dcraw.c utility (without RESTRICTED/GPL2 code): + +Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net + +LibRaw uses DCB demosaic code by Jaceck Gozdz distributed under BSD license: + +Copyright (C) 2010, Jacek Gozdz (mailto:cuniek@kft.umcs.lublin.pl) + +LibRaw uses Roland Karlsson’s X3F tools source code, licensed under BSD license: + +Copyright (c) 2010, Roland Karlsson (roland@proxel.se) \ No newline at end of file diff --git a/RawSpeed/rawspeed.cpucount-unix.patch b/RawSpeed/rawspeed.cpucount-unix.patch new file mode 100644 index 000000000..4ddbdeae6 --- /dev/null +++ b/RawSpeed/rawspeed.cpucount-unix.patch @@ -0,0 +1,15 @@ +diff --git a/RawSpeed/Common.cpp b/RawSpeed/Common.cpp +index abec232..6990c04 100644 +--- a/RawSpeed/Common.cpp ++++ b/RawSpeed/Common.cpp +@@ -31,5 +31,10 @@ void* _aligned_malloc(size_t bytes, size_t alignment) { + else + return NULL; + } ++#include ++int rawspeed_get_number_of_processor_cores() ++{ ++ return sysconf( _SC_NPROCESSORS_ONLN ); ++} + + #endif diff --git a/RawSpeed/rawspeed.qmake-pro-files.patch b/RawSpeed/rawspeed.qmake-pro-files.patch new file mode 100644 index 000000000..d77db7c4c --- /dev/null +++ b/RawSpeed/rawspeed.qmake-pro-files.patch @@ -0,0 +1,84 @@ +diff --git a/RawSpeed/rawspeed-lib.pro b/RawSpeed/rawspeed-lib.pro +new file mode 100644 +index 0000000..1599ddf +--- /dev/null ++++ b/RawSpeed/rawspeed-lib.pro +@@ -0,0 +1,42 @@ ++TEMPLATE=lib ++TARGET=rawspeed ++ ++win32:INCLUDEPATH+=d:/Qt/iconv/include d:/Qt/libxml2/include/libxml2 d:/Qt/pthreads/include d:/Qt/libjpeg-turbo/include ++win32:LIBS+=-Ld:/Qt/iconv/lib/x86 -liconv -Ld:/Qt/libxml2/lib/x86 -llibxml2 -Ld:/Qt/pthreads/lib/x86 -lpthreadVC2 -Ld:/Qt/libjpeg-turbo/lib/x86 -ljpeg8 ++ ++unix:INCLUDEPATH+=/usr/local/include /usr/local/include/libxml2 ++unix:CONFIG+=staticlib ++ ++INCLUDEPATH+=. ++ ++HEADERS = ArwDecoder.h BitPumpJPEG.h BitPumpMSB.h BitPumpMSB32.h \ ++ BitPumpPlain.h BlackArea.h ByteStream.h ByteStreamSwap.h \ ++ Camera.h CameraMetaData.h CameraMetadataException.h \ ++ CameraSensorInfo.h ColorFilterArray.h Common.h Cr2Decoder.h \ ++ DngDecoder.h DngDecoderSlices.h DngOpcodes.h FileIOException.h \ ++ FileMap.h FileReader.h IOException.h LJpegDecompressor.h \ ++ LJpegPlain.h NefDecoder.h NikonDecompressor.h OrfDecoder.h \ ++ PefDecoder.h PentaxDecompressor.h Point.h RawDecoder.h \ ++ RawDecoderException.h RawImage.h RawParser.h Rw2Decoder.h SrwDecoder.h \ ++ StdAfx.h TiffEntry.h TiffEntryBE.h TiffIFD.h TiffIFDBE.h TiffParser.h \ ++ TiffParserException.h TiffParserHeaderless.h TiffParserOlympus.h \ ++ TiffTag.h dlldef.h ++ ++SOURCES = \ ++ ArwDecoder.cpp BitPumpJPEG.cpp BitPumpMSB.cpp BitPumpMSB32.cpp \ ++ BitPumpPlain.cpp BlackArea.cpp ByteStream.cpp ByteStreamSwap.cpp \ ++ Camera.cpp CameraMetaData.cpp CameraMetadataException.cpp \ ++ CameraSensorInfo.cpp ColorFilterArray.cpp Common.cpp Cr2Decoder.cpp \ ++ DngDecoder.cpp DngDecoderSlices.cpp DngOpcodes.cpp \ ++ FileIOException.cpp FileMap.cpp FileReader.cpp IOException.cpp \ ++ LJpegDecompressor.cpp LJpegPlain.cpp NefDecoder.cpp \ ++ NikonDecompressor.cpp OrfDecoder.cpp PefDecoder.cpp \ ++ PentaxDecompressor.cpp RawDecoder.cpp RawDecoderException.cpp \ ++ RawImage.cpp RawImageDataFloat.cpp RawImageDataU16.cpp RawParser.cpp \ ++ Rw2Decoder.cpp SrwDecoder.cpp TiffEntry.cpp TiffEntryBE.cpp\ ++ TiffIFD.cpp TiffIFDBE.cpp TiffParser.cpp TiffParserException.cpp \ ++ TiffParserHeaderless.cpp TiffParserOlympus.cpp ++ ++DEFINES+=RAWSPEED_BUILDLIB ++CONFIG-=qt ++win32:QMAKE_CXXFLAGS+=/O2 /arch:SSE2 /fp:fast /MP +diff --git a/RawSpeed/rawspeed-test.pro b/RawSpeed/rawspeed-test.pro +new file mode 100644 +index 0000000..518aa98 +--- /dev/null ++++ b/RawSpeed/rawspeed-test.pro +@@ -0,0 +1,21 @@ ++TEMPLATE=app ++TARGET=rawspeed-test ++ ++SOURCES=RawSpeed.cpp ++ ++win32:CONFIG(debug,debug|release) { ++ LIBDIR = debug ++} else { ++ LIBDIR = release ++} ++ ++ ++INCLUDEPATH+=../ ++ ++unix:INCLUDEPATH+=/usr/local/include /usr/local/include/libxml2 ++unix:LIBS+=-L. -lrawspeed -L/usr/local/lib -lxml2 -ljpeg ++win32:LIBS+=-L$$LIBDIR -llibrawspeed ++win32:LIBS+=-Ld:/Qt/iconv/lib/x86 -liconv -Ld:/Qt/libxml2/lib/x86 -llibxml2a -Ld:/Qt/pthreads/lib/x86 -lpthreadVC2 -Ld:/Qt/libjpeg-turbo/lib/x86 -ljpeg8 ++win32:INCLUDEPATH+=d:/Qt/iconv/include d:/Qt/libxml2/include/libxml2 d:/Qt/pthreads/include d:/Qt/libjpeg-turbo/include ++CONFIG-=qt ++CONFIG+=console +diff --git a/RawSpeed/rawspeed.pro b/RawSpeed/rawspeed.pro +new file mode 100644 +index 0000000..df2a0b9 +--- /dev/null ++++ b/RawSpeed/rawspeed.pro +@@ -0,0 +1,3 @@ ++TEMPLATE=subdirs ++SUBDIRS=rawspeed-lib.pro rawspeed-test.pro ++ diff --git a/RawSpeed/rawspeed.samsung-decoder.patch b/RawSpeed/rawspeed.samsung-decoder.patch new file mode 100644 index 000000000..f62754a83 --- /dev/null +++ b/RawSpeed/rawspeed.samsung-decoder.patch @@ -0,0 +1,39 @@ +diff --git a/RawSpeed/SrwDecoder.cpp b/RawSpeed/SrwDecoder.cpp +index fa46499..1aff689 100644 +--- a/RawSpeed/SrwDecoder.cpp ++++ b/RawSpeed/SrwDecoder.cpp +@@ -141,7 +141,7 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) + // First we decode even pixels + for (int c = 0; c < 16; c += 2) { + int b = len[(c >> 3)]; +- int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); ++ int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; + img[c] = adj + img_up[c]; + } + // Now we decode odd pixels +@@ -149,7 +149,7 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) + // is beyond me, it will hurt compression a deal. + for (int c = 1; c < 16; c += 2) { + int b = len[2 | (c >> 3)]; +- int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); ++ int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; + img[c] = adj + img_up2[c]; + } + } else { +@@ -158,14 +158,14 @@ void SrwDecoder::decodeCompressed( TiffIFD* raw ) + int pred_left = x ? img[-2] : 128; + for (int c = 0; c < 16; c += 2) { + int b = len[(c >> 3)]; +- int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); ++ int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; + img[c] = adj + pred_left; + } + // Now we decode odd pixels + pred_left = x ? img[-1] : 128; + for (int c = 1; c < 16; c += 2) { + int b = len[2 | (c >> 3)]; +- int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b)); ++ int32 adj = b > 0 ? ((int32) bits.getBits(b) << (32-b) >> (32-b)) :0; + img[c] = adj + pred_left; + } + } diff --git a/RawSpeed/rawspeed.uncompressed-color-dng.patch b/RawSpeed/rawspeed.uncompressed-color-dng.patch new file mode 100644 index 000000000..ebabdfd08 --- /dev/null +++ b/RawSpeed/rawspeed.uncompressed-color-dng.patch @@ -0,0 +1,13 @@ +diff --git a/RawSpeed/DngDecoder.cpp b/RawSpeed/DngDecoder.cpp +index 56c701b..98f2474 100644 +--- a/RawSpeed/DngDecoder.cpp ++++ b/RawSpeed/DngDecoder.cpp +@@ -216,7 +216,7 @@ RawImage DngDecoder::decodeRawInternal() { + if (bps != 8 && bps != 16) + big_endian = true; + try { +- readUncompressedRaw(in, size, pos, width*bps / 8, bps, big_endian ? BitOrder_Jpeg : BitOrder_Plain); ++ readUncompressedRaw(in, size, pos, mRaw->getCpp()*width*bps / 8, bps, big_endian ? BitOrder_Jpeg : BitOrder_Plain); + } catch(IOException &ex) { + if (i > 0) + mRaw->setError(ex.what()); diff --git a/RawSpeed/rawspeed.win32-dll.patch b/RawSpeed/rawspeed.win32-dll.patch new file mode 100644 index 000000000..4cb90194a --- /dev/null +++ b/RawSpeed/rawspeed.win32-dll.patch @@ -0,0 +1,186 @@ +diff --git a/RawSpeed/Camera.h b/RawSpeed/Camera.h +index 7b3045d..4363c1b 100644 +--- a/RawSpeed/Camera.h ++++ b/RawSpeed/Camera.h +@@ -6,6 +6,7 @@ + #include + #include "BlackArea.h" + #include "CameraMetadataException.h" ++#include "dlldef.h" + /* + RawSpeed - RAW file decoder. + +@@ -30,7 +31,7 @@ + + namespace RawSpeed { + +-class Camera ++class DllDef Camera + { + public: + Camera(xmlDocPtr doc, xmlNodePtr cur); +diff --git a/RawSpeed/CameraMetaData.h b/RawSpeed/CameraMetaData.h +index 616b2bb..c6b8031 100644 +--- a/RawSpeed/CameraMetaData.h ++++ b/RawSpeed/CameraMetaData.h +@@ -27,9 +27,10 @@ + http://www.klauspost.com + */ + ++#include "dlldef.h" + namespace RawSpeed { + +-class CameraMetaData ++class DllDef CameraMetaData + { + public: + CameraMetaData(); +diff --git a/RawSpeed/CameraMetadataException.h b/RawSpeed/CameraMetadataException.h +index 55a2814..52d5ea1 100644 +--- a/RawSpeed/CameraMetadataException.h ++++ b/RawSpeed/CameraMetadataException.h +@@ -22,10 +22,11 @@ + #ifndef CAMERA_METADATA_EXCEPTION_H + #define CAMERA_METADATA_EXCEPTION_H + ++#include "dlldef.h" + + namespace RawSpeed { + +-void ThrowCME(const char* fmt, ...); ++void DllDef ThrowCME(const char* fmt, ...); + + class CameraMetadataException : + public std::runtime_error +diff --git a/RawSpeed/FileMap.h b/RawSpeed/FileMap.h +index 5c15918..bcd2a79 100644 +--- a/RawSpeed/FileMap.h ++++ b/RawSpeed/FileMap.h +@@ -25,6 +25,7 @@ + */ + + #include "IOException.h" ++#include "dlldef.h" + + namespace RawSpeed { + +@@ -36,7 +37,7 @@ namespace RawSpeed { + * This can also be done as a MemMap + * + *****************************/ +-class FileMap ++class DllDef FileMap + { + public: + FileMap(uint32 _size); // Allocates the data array itself +diff --git a/RawSpeed/FileReader.h b/RawSpeed/FileReader.h +index 7448ec2..fb42ac0 100644 +--- a/RawSpeed/FileReader.h ++++ b/RawSpeed/FileReader.h +@@ -24,10 +24,11 @@ + + #include "FileIOException.h" + #include "FileMap.h" ++#include "dlldef.h" + + namespace RawSpeed { + +-class FileReader ++class DllDef FileReader + { + public: + FileReader(LPCWSTR filename); +diff --git a/RawSpeed/RawDecoder.h b/RawSpeed/RawDecoder.h +index a6c4708..b35cae5 100644 +--- a/RawSpeed/RawDecoder.h ++++ b/RawSpeed/RawDecoder.h +@@ -9,6 +9,7 @@ + #include "BitPumpPlain.h" + #include "CameraMetaData.h" + #include "TiffIFD.h" ++#include "dlldef.h" + + /* + RawSpeed - RAW file decoder. +@@ -48,7 +49,7 @@ class RawDecoderThread + RawDecoder* parent; + }; + +-class RawDecoder ++class DllDef RawDecoder + { + public: + /* Construct decoder instance - FileMap is a filemap of the file to be decoded */ +diff --git a/RawSpeed/RawImage.h b/RawSpeed/RawImage.h +index 5741760..74cea96 100644 +--- a/RawSpeed/RawImage.h ++++ b/RawSpeed/RawImage.h +@@ -26,13 +26,15 @@ + http://www.klauspost.com + */ + ++#include "dlldef.h" ++ + namespace RawSpeed { + + class RawImage; + class RawImageWorker; + typedef enum {TYPE_USHORT16, TYPE_FLOAT32} RawImageType; + +-class RawImageData ++class DllDef RawImageData + { + friend class RawImageWorker; + public: +@@ -125,7 +127,7 @@ protected: + int end_y; + }; + +- class RawImage { ++ class DllDef RawImage { + public: + static RawImage create(RawImageType type = TYPE_USHORT16); + static RawImage create(iPoint2D dim, RawImageType type = TYPE_USHORT16, uint32 componentsPerPixel = 1); +diff --git a/RawSpeed/RawParser.h b/RawSpeed/RawParser.h +index 9ef86e3..1b3cb83 100644 +--- a/RawSpeed/RawParser.h ++++ b/RawSpeed/RawParser.h +@@ -25,10 +25,11 @@ + + #include "FileMap.h" + #include "RawDecoder.h" ++#include "dlldef.h" + + namespace RawSpeed { + +-class RawParser ++class DllDef RawParser + { + public: + RawParser(FileMap* input); +diff --git a/RawSpeed/dlldef.h b/RawSpeed/dlldef.h +new file mode 100644 +index 0000000..c806451 +--- /dev/null ++++ b/RawSpeed/dlldef.h +@@ -0,0 +1,20 @@ ++#ifndef DLLDEF_H ++#define DLLDEF_H ++ ++#ifdef _WIN32 ++#ifdef _MSC_VER ++#pragma warning( disable: 4251 ) ++#endif ++#ifdef RAWSPEED_NODLL ++# define DllDef ++#else ++# ifdef RAWSPEED_BUILDLIB ++# define DllDef __declspec( dllexport ) ++# else ++# define DllDef __declspec( dllimport ) ++# endif ++#endif ++#else ++# define DllDef ++#endif ++#endif diff --git a/RawSpeed/rawspeed_xmldata.cpp b/RawSpeed/rawspeed_xmldata.cpp new file mode 100644 index 000000000..9e629ccb6 --- /dev/null +++ b/RawSpeed/rawspeed_xmldata.cpp @@ -0,0 +1,4115 @@ +const char *_rawspeed_data_xml[]={ +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"\n", +"]>\n", +"\n", +"\n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL SL1\n", +" Canon EOS Kiss X7\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS DIGITAL REBEL XT\n", +" Canon EOS Kiss Digital N\n", +" Canon EOS 350D\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS DIGITAL REBEL XSi\n", +" Canon EOS Kiss Digital X2\n", +" Canon EOS Kiss X2\n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T5i\n", +" Canon EOS Kiss X7i\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T1i\n", +" Canon EOS Kiss X3\n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T2i\n", +" Canon EOS Kiss X4\n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T3i\n", +" Canon EOS Kiss X5\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T4i\n", +" Canon EOS Kiss X6i\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS DIGITAL REBEL XS\n", +" Canon EOS Kiss Digital F\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T3\n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS REBEL T5\n", +" Canon EOS Kiss X70\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" Canon EOS DIGITAL REBEL XTi\n", +" Canon EOS Kiss Digital X\n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" NIKON D800E\n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +"\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\t\t\t\t\n", +"\t\t\t\t\t\t\t\t\n", +"\t\t\t\t\t\t\t\t\t\t\t\tRED\n", +"\t\t\t\t\t\t\t\t\t\t\t\tGREEN\n", +"\t\t\t\t\t\t\t\t\t\t\t\tGREEN\n", +"\t\t\t\t\t\t\t\t\t\t\t\tBLUE\n", +"\t\t\t\t\t\t\t\t\n", +"\t\t\t\t\t\t\t\t\n", +"\t\t\t\t\t\t\t\t\n", +"\t\t\t\t\n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ38\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ38\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ40\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ40\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ72\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" DMC-FZ72\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" BLUE\n", +" RED\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" GREEN\n", +" RED\n", +" BLUE\n", +" GREEN\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" BLUE\n", +" GREEN\n", +" GREEN\n", +" RED\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" RED\n", +" GREEN\n", +" GREEN\n", +" BLUE\n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +" \n", +"\n", +0 +}; diff --git a/RawSpeed3/README.md b/RawSpeed3/README.md new file mode 100644 index 000000000..6dd21146c --- /dev/null +++ b/RawSpeed3/README.md @@ -0,0 +1,69 @@ +# About RawSpeed v3 + +The current version of the RawSpeed library (https://github.com/darktable-org/rawspeed ) does not have a version number, we call it "version 3" to distinguish it from RawSpeed/master, the version number is taken from darktable 3.x (which uses this library). + +This library provides faster decoding of some RAW formats (even faster than RawSpeed v1), the difference can be tens of percent (without using OpenMP) for Huffman-compressed files (Canon CR2, Nikon NEF, etc). + +Unfortunately, the RawSpeed-v3 source code is constantly changing and this is due not so much to the development of the library (support for new cameras, formats, etc.), but to the fact that the current maintainer is using it as an aid in self-development as a programmer. + +They are extremely reluctant to accept 3rd-party patches to this library, therefore, the fixes necessary for correct work with LibRaw have been added to the LibRaw distribution (see below). All our patches, of course, are suitable only for a specific version (commit-id) of RawSpeed-v3, if you want to use a different version, you will have to adjust them. + +# Building RawSpeed v3 and C-API wrapper + +## Preparing the source +1. Take a specific commit from github + https://github.com/darktable-org/rawspeed/commit/de70ef5fbc62cde91009c8cff7a206272abe631e + +2. Apply the following patches from LibRaw/RawSpeed3/patches folder: + * **01.CameraMeta-extensibility.patch** - allows derived classes from CameraMeta, which allows loading camera descriptions not only from a disk file. + * **02.Makernotes-processing.patch** - fixes an error in processing the Makernotes tag. + * **03.remove-limits-and-logging.patch** - removes debug printing and file size limits. This patch is optional, but if you are going to decode files from cameras that were not available at the time a particular version of RawSpeed was created, then this patch can be useful. + * **04.clang-cl-compatibility.patch -** fixes for compatibility with Microsoft C++ library. + +## Building the RawSpeed-v3 library + +We **do not** offer advice on building RawSpeed3, if you need such advice please contact the maintainer of the library. At a minimum, it **can be** compiled with Clang (XCode) on macOS and clang-cl (MSVC) on Windows. + +Use your favorite build system. Files for CMake come with RawSpeed, but any other build system can be used (in that case you probably will need to create your own rawspeedconfig.h instead of one created via CMake). + +In our projects we use RawSpeed-v3 without OpenMP. + +## Building the C-API wrapper +To simplify the integration with LibRaw, we have implemented a simple wrapper with a C interface, which hides everything unnecessary, thus: +* To build LibRaw (with RawSpeed-v3 support) you do not need access to RawSpeed .h-files +* When building LibRaw and RawSpeed-v3 using different compilers there is no issue with C++ name mangling. + +The wrapper sources are in the **LibRaw/RawSpeed3/rawspeed3_c_api folder**, they include four files: +1. **rawspeed3_capi.h** - header file +2. **rawspeed3_capi.cpp** - wrapper sources +3. **rsxml2c.sh** - shell script that will convert RawSpeed/data/cameras.xml to a C++ file containing camera definitions +4. **rawspeed3_capi_test.cpp** - test program for checking the build correctness and operation ability. + +The wrapper provides simple *decode only* interface (init library, decode RAW passed via buffer, free decoded file buffer, release the library) it is self-documented via comments in the rawspeed3_capi.h file. + +To make a file with camera definitions, run the command (you can add it to the build system): +`sh ./rawspeed3_c_api/rsxml2c.sh < path/to/RawSpeed/data/cameras.xml > rawspeed3_c_api/cameras.cpp` + +The **rsxml2c.sh** script requires **cat**, **tr**, and **sed** unix command-line utilities installed, there is no specific version requirements. + +Add the resulting file (LibRaw/RawSpeed3/rawspeed3_c_api/cameras.cpp) and LibRaw/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp, to the build of the RawSpeed-v3 (dynamic) library, which you learned to build in the previous step. +If building Windows DLL: rawspeed3_capi.cpp should be compiled with -DRAWSPEED_BUILDLIB to create dll export entries automatically. + +To check that everything works, you can use the LibRaw/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp test program, it should be possible to build it and link with RawSpeed-v3 (+ C-API); and after that this test program should be ready to decode RAW files passed to it from command line. + +# Building LibRaw with RawSpeed-v3 support +When building, specify the following parameters +* LibRaw/RawSpeed3/rawspeed3_c_api to the search path for include files +* Specify preprocessor flags -DUSE_RAWSPEED3 -DUSE_RAWSPEED_BITS: + * USE_RAWSPEED3 enables the use of RawSpeed-v3 + * USE_RAWSPEED_BITS enables (a more granulated) control of RawSpeed-v3 / RawSpeed processing +* set the RawSpeed-v3 (+ C-API) library, obtained in the previous steps, as an input linker file + +# Using LibRaw with RawSpeed-v3 Support +Use LibRaw as usual. Enable RawSpeed3 use by setting bits in imgdata.rawparams.userawspeed (LIBRAW_RAWSPEEDV3_USE, LIBRAW_RAWSPEEDV3_IGNOREERRORS, LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) +If RawSpeed was set as the decoder the following bits will be set in imgdata.processwarnings: +* LIBRAW_WARN_RAWSPEED3_PROCESSED - if decoding was successful +* LIBRAW_WARN_RAWSPEED3_PROBLEM - if decoding attempt failed +(flags and bits are described in LibRaw's Changelog) + +With RawSpeed-v3, the entire RAW file is read into the memory buffer (as it is with RawSpeed version 1), so it increases LibRaw memory footprint. diff --git a/RawSpeed3/patches/01.CameraMeta-extensibility.patch b/RawSpeed3/patches/01.CameraMeta-extensibility.patch new file mode 100644 index 000000000..1ee6057e2 --- /dev/null +++ b/RawSpeed3/patches/01.CameraMeta-extensibility.patch @@ -0,0 +1,13 @@ +diff --git a/src/librawspeed/metadata/CameraMetaData.h b/src/librawspeed/metadata/CameraMetaData.h +index c2f6f1dd..13cab9c9 100644 +--- a/src/librawspeed/metadata/CameraMetaData.h ++++ b/src/librawspeed/metadata/CameraMetaData.h +@@ -41,7 +41,7 @@ struct CameraId { + } + }; + +-class CameraMetaData { ++class CameraMetaData final { + public: + CameraMetaData() = default; + diff --git a/RawSpeed3/patches/02.Makernotes-processing.patch b/RawSpeed3/patches/02.Makernotes-processing.patch new file mode 100644 index 000000000..25e7b13f3 --- /dev/null +++ b/RawSpeed3/patches/02.Makernotes-processing.patch @@ -0,0 +1,36 @@ +diff --git a/src/librawspeed/tiff/TiffIFD.cpp b/src/librawspeed/tiff/TiffIFD.cpp +index e732eae2..05251dd9 100644 +--- a/src/librawspeed/tiff/TiffIFD.cpp ++++ b/src/librawspeed/tiff/TiffIFD.cpp +@@ -143,6 +143,7 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, + string make = makeEntry != nullptr ? trimSpaces(makeEntry->getString()) : ""; + + ByteStream bs = t->getData(); ++ auto bufbegin = bs.begin() + bs.getPosition(); + + // helper function for easy setup of ByteStream buffer for the different maker note types + // 'rebase' means position 0 of new stream equals current position +@@ -159,7 +160,9 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, + bs.skipBytes(newPosition); + }; + +- if (bs.hasPrefix("AOC\0", 4)) { ++ if (bs.hasPrefix("LSI1\0", 5)) { // Skip LSI1 makernotes ++ return std::make_unique(this, ifds, bs, UINT32_MAX); // UINT32_MAX offset => special handling, empty IFD ++ } else if (bs.hasPrefix("AOC\0", 4)) { + setup(false, 6, 4, "Pentax makernote"); + } else if (bs.hasPrefix("PENTAX", 6)) { + setup(true, 10, 8, "Pentax makernote"); +@@ -197,6 +200,12 @@ TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet* ifds, + } + } + ++ auto readed = bs.begin() - bufbegin + bs.getPosition(); ++ ByteStream bscheck(bs); ++ const auto IFDSize = 6 + 12 * bscheck.getU16(); ++ ++ if(IFDSize > t->count - readed) // IFDSize too big, probably binary Makernotes dir, not TIFF-like, could not be handled by TiffRootIFD reader ++ return std::make_unique(this, ifds, bs, UINT32_MAX); // // UINT32_MAX offset => special handling, empty IFD + // Attempt to parse the rest as an IFD + return std::make_unique(this, ifds, bs, bs.getPosition()); + } diff --git a/RawSpeed3/patches/03.remove-limits-and-logging.patch b/RawSpeed3/patches/03.remove-limits-and-logging.patch new file mode 100644 index 000000000..c1fb7b591 --- /dev/null +++ b/RawSpeed3/patches/03.remove-limits-and-logging.patch @@ -0,0 +1,245 @@ +diff --git a/src/librawspeed/common/Common.cpp b/src/librawspeed/common/Common.cpp +index 8c8c5663..d9b5e463 100644 +--- a/src/librawspeed/common/Common.cpp ++++ b/src/librawspeed/common/Common.cpp +@@ -36,6 +36,7 @@ writeLog(DEBUG_PRIO priority, const char* format, ...) { + #else + + void writeLog(DEBUG_PRIO priority, const char* format, ...) { ++#if 0 + #ifndef _DEBUG + if (priority < DEBUG_PRIO_INFO) + #endif // _DEBUG +@@ -55,6 +56,7 @@ void writeLog(DEBUG_PRIO priority, const char* format, ...) { + if (priority < DEBUG_PRIO_INFO) + #endif // _DEBUG + fprintf(stdout, "%s", "\n"); ++#endif + } + + #endif +diff --git a/src/librawspeed/common/RawspeedException.h b/src/librawspeed/common/RawspeedException.h +index 33b9cc29..a9f503a7 100644 +--- a/src/librawspeed/common/RawspeedException.h ++++ b/src/librawspeed/common/RawspeedException.h +@@ -45,12 +45,13 @@ template + "Don't have thread-local-storage! Exception text may be garbled if used multithreaded" + static char buf[bufSize]; + #endif +- ++#if 0 + va_list val; + va_start(val, fmt); + vsnprintf(buf.data(), sizeof(buf), fmt, val); + va_end(val); + writeLog(DEBUG_PRIO_EXTRA, "EXCEPTION: %s", buf.data()); ++#endif + throw T(buf.data()); + } + +diff --git a/src/librawspeed/decoders/ArwDecoder.cpp b/src/librawspeed/decoders/ArwDecoder.cpp +index f1d5a63c..2025d260 100644 +--- a/src/librawspeed/decoders/ArwDecoder.cpp ++++ b/src/librawspeed/decoders/ArwDecoder.cpp +@@ -186,8 +186,8 @@ RawImage ArwDecoder::decodeRawInternal() { + } + } + +- if (width == 0 || height == 0 || height % 2 != 0 || width > 9600 || +- height > 6376) ++ if (width == 0 || height == 0 || height % 2 != 0 /* || width > 9600 || ++ height > 6376 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + bool arw1 = uint64_t(counts->getU32()) * 8 != width * height * bitPerPixel; +@@ -241,7 +241,7 @@ void ArwDecoder::DecodeUncompressed(const TiffIFD* raw) { + + mRaw->dim = iPoint2D(width, height); + +- if (width == 0 || height == 0 || width > 9600 || height > 6376) ++ if (width == 0 || height == 0 /* || width > 9600 || height > 6376 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + if (c2 == 0) +diff --git a/src/librawspeed/decoders/IiqDecoder.cpp b/src/librawspeed/decoders/IiqDecoder.cpp +index 31c460d9..61b04e1a 100644 +--- a/src/librawspeed/decoders/IiqDecoder.cpp ++++ b/src/librawspeed/decoders/IiqDecoder.cpp +@@ -185,7 +185,7 @@ RawImage IiqDecoder::decodeRawInternal() { + } + + // FIXME: could be wrong. max "active pixels" in "Sensor+" mode - "101 MP" +- if (width == 0 || height == 0 || width > 11976 || height > 8854) ++ if (width == 0 || height == 0 /* || width > 11976 || height > 8854 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + if (split_col > width || split_row > height) +diff --git a/src/librawspeed/decoders/MosDecoder.cpp b/src/librawspeed/decoders/MosDecoder.cpp +index 9f01a11c..db4b8f50 100644 +--- a/src/librawspeed/decoders/MosDecoder.cpp ++++ b/src/librawspeed/decoders/MosDecoder.cpp +@@ -113,7 +113,7 @@ RawImage MosDecoder::decodeRawInternal() { + uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); + + // FIXME: could be wrong. max "active pixels" - "80 MP" +- if (width == 0 || height == 0 || width > 10328 || height > 7760) ++ if (width == 0 || height == 0 /* || width > 10328 || height > 7760 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + mRaw->dim = iPoint2D(width, height); +diff --git a/src/librawspeed/decoders/NefDecoder.cpp b/src/librawspeed/decoders/NefDecoder.cpp +index 222c62f0..7314ca15 100644 +--- a/src/librawspeed/decoders/NefDecoder.cpp ++++ b/src/librawspeed/decoders/NefDecoder.cpp +@@ -214,7 +214,7 @@ void NefDecoder::DecodeUncompressed() { + + mRaw->dim = iPoint2D(width, height); + +- if (width == 0 || height == 0 || width > 8288 || height > 5520) ++ if (width == 0 || height == 0 /* || width > 8288 || height > 5520 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + if (counts->count != offsets->count) { +@@ -370,8 +370,8 @@ void NefDecoder::DecodeSNefUncompressed() { + uint32_t width = raw->getEntry(IMAGEWIDTH)->getU32(); + uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); + +- if (width == 0 || height == 0 || width % 2 != 0 || width > 3680 || +- height > 2456) ++ if (width == 0 || height == 0 || width % 2 != 0 /* || width > 3680 || ++ height > 2456 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + mRaw->dim = iPoint2D(width, height); +diff --git a/src/librawspeed/decoders/OrfDecoder.cpp b/src/librawspeed/decoders/OrfDecoder.cpp +index 7eb1a901..de557d5f 100644 +--- a/src/librawspeed/decoders/OrfDecoder.cpp ++++ b/src/librawspeed/decoders/OrfDecoder.cpp +@@ -109,7 +109,7 @@ RawImage OrfDecoder::decodeRawInternal() { + uint32_t width = raw->getEntry(IMAGEWIDTH)->getU32(); + uint32_t height = raw->getEntry(IMAGELENGTH)->getU32(); + +- if (!width || !height || width % 2 != 0 || width > 10400 || height > 7796) ++ if (!width || !height || width % 2 != 0 /* || width > 10400 || height > 7796 */ ) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + mRaw->dim = iPoint2D(width, height); +diff --git a/src/librawspeed/decoders/RafDecoder.cpp b/src/librawspeed/decoders/RafDecoder.cpp +index 5baf02b9..27e67e7a 100644 +--- a/src/librawspeed/decoders/RafDecoder.cpp ++++ b/src/librawspeed/decoders/RafDecoder.cpp +@@ -79,7 +79,7 @@ RawImage RafDecoder::decodeRawInternal() { + } else + ThrowRDE("Unable to locate image size"); + +- if (width == 0 || height == 0 || width > 11808 || height > 8754) ++ if (width == 0 || height == 0 /* || width > 11808 || height > 8754 */ ) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + if (raw->hasEntry(FUJI_LAYOUT)) { +@@ -334,7 +334,7 @@ int RafDecoder::isCompressed() { + } else + ThrowRDE("Unable to locate image size"); + +- if (width == 0 || height == 0 || width > 11808 || height > 8754) ++ if (width == 0 || height == 0 /* || width > 11808 || height > 8754 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + uint32_t count = raw->getEntry(FUJI_STRIPBYTECOUNTS)->getU32(); +diff --git a/src/librawspeed/decoders/RawDecoder.cpp b/src/librawspeed/decoders/RawDecoder.cpp +index a69727f6..e5315a42 100644 +--- a/src/librawspeed/decoders/RawDecoder.cpp ++++ b/src/librawspeed/decoders/RawDecoder.cpp +@@ -62,7 +62,7 @@ void RawDecoder::decodeUncompressed(const TiffIFD *rawIFD, BitOrder order) { + uint32_t height = rawIFD->getEntry(IMAGELENGTH)->getU32(); + uint32_t bitPerPixel = rawIFD->getEntry(BITSPERSAMPLE)->getU32(); + +- if (width == 0 || height == 0 || width > 5632 || height > 3720) ++ if (width == 0 || height == 0 /* || width > 5632 || height > 3720 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + mRaw->dim = iPoint2D(width, height); +diff --git a/src/librawspeed/decoders/Rw2Decoder.cpp b/src/librawspeed/decoders/Rw2Decoder.cpp +index 0e9d111d..a54de998 100644 +--- a/src/librawspeed/decoders/Rw2Decoder.cpp ++++ b/src/librawspeed/decoders/Rw2Decoder.cpp +@@ -72,7 +72,7 @@ RawImage Rw2Decoder::decodeRawInternal() { + uint32_t width = raw->getEntry(static_cast(2))->getU16(); + + if (isOldPanasonic) { +- if (width == 0 || height == 0 || width > 4330 || height > 2751) ++ if (width == 0 || height == 0 /* || width > 4330 || height > 2751 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height); + + TiffEntry *offsets = raw->getEntry(STRIPOFFSETS); +diff --git a/src/librawspeed/decompressors/HasselbladDecompressor.cpp b/src/librawspeed/decompressors/HasselbladDecompressor.cpp +index 0d650065..aaa70fb5 100644 +--- a/src/librawspeed/decompressors/HasselbladDecompressor.cpp ++++ b/src/librawspeed/decompressors/HasselbladDecompressor.cpp +@@ -41,8 +41,8 @@ HasselbladDecompressor::HasselbladDecompressor(const ByteStream& bs, + ThrowRDE("Unexpected component count / data type"); + + // FIXME: could be wrong. max "active pixels" - "100 MP" +- if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 || +- mRaw->dim.x > 12000 || mRaw->dim.y > 8816) { ++ if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 /* || ++ mRaw->dim.x > 12000 || mRaw->dim.y > 8816 */) { + ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, + mRaw->dim.y); + } +diff --git a/src/librawspeed/decompressors/NikonDecompressor.cpp b/src/librawspeed/decompressors/NikonDecompressor.cpp +index ca39cd0a..54568243 100644 +--- a/src/librawspeed/decompressors/NikonDecompressor.cpp ++++ b/src/librawspeed/decompressors/NikonDecompressor.cpp +@@ -442,8 +442,8 @@ NikonDecompressor::NikonDecompressor(const RawImage& raw, ByteStream metadata, + mRaw->getBpp() != sizeof(uint16_t)) + ThrowRDE("Unexpected component count / data type"); + +- if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 || +- mRaw->dim.x > 8288 || mRaw->dim.y > 5520) ++ if (mRaw->dim.x == 0 || mRaw->dim.y == 0 || mRaw->dim.x % 2 != 0 /* || ++ mRaw->dim.x > 8288 || mRaw->dim.y > 5520 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, + mRaw->dim.y); + +diff --git a/src/librawspeed/decompressors/OlympusDecompressor.cpp b/src/librawspeed/decompressors/OlympusDecompressor.cpp +index b859b562..dc8aa0bc 100644 +--- a/src/librawspeed/decompressors/OlympusDecompressor.cpp ++++ b/src/librawspeed/decompressors/OlympusDecompressor.cpp +@@ -56,7 +56,7 @@ OlympusDecompressor::OlympusDecompressor(const RawImage& img) : mRaw(img) { + const uint32_t w = mRaw->dim.x; + const uint32_t h = mRaw->dim.y; + +- if (w == 0 || h == 0 || w % 2 != 0 || w > 10400 || h > 7792) ++ if (w == 0 || h == 0 || w % 2 != 0 /* || w > 10400 || h > 7792 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", w, h); + } + +diff --git a/src/librawspeed/decompressors/PentaxDecompressor.cpp b/src/librawspeed/decompressors/PentaxDecompressor.cpp +index 11b1d677..c2adc2e6 100644 +--- a/src/librawspeed/decompressors/PentaxDecompressor.cpp ++++ b/src/librawspeed/decompressors/PentaxDecompressor.cpp +@@ -49,8 +49,8 @@ PentaxDecompressor::PentaxDecompressor(const RawImage& img, + mRaw->getBpp() != sizeof(uint16_t)) + ThrowRDE("Unexpected component count / data type"); + +- if (!mRaw->dim.x || !mRaw->dim.y || mRaw->dim.x % 2 != 0 || +- mRaw->dim.x > 8384 || mRaw->dim.y > 6208) { ++ if (!mRaw->dim.x || !mRaw->dim.y || mRaw->dim.x % 2 != 0 /* || ++ mRaw->dim.x > 8384 || mRaw->dim.y > 6208 */) { + ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x, + mRaw->dim.y); + } +diff --git a/src/librawspeed/decompressors/SonyArw2Decompressor.cpp b/src/librawspeed/decompressors/SonyArw2Decompressor.cpp +index 8f935d9c..3cbc7e26 100644 +--- a/src/librawspeed/decompressors/SonyArw2Decompressor.cpp ++++ b/src/librawspeed/decompressors/SonyArw2Decompressor.cpp +@@ -45,7 +45,7 @@ SonyArw2Decompressor::SonyArw2Decompressor(const RawImage& img, + const uint32_t w = mRaw->dim.x; + const uint32_t h = mRaw->dim.y; + +- if (w == 0 || h == 0 || w % 32 != 0 || w > 9600 || h > 6376) ++ if (w == 0 || h == 0 || w % 32 != 0 /* || w > 9600 || h > 6376 */) + ThrowRDE("Unexpected image dimensions found: (%u; %u)", w, h); + + // 1 byte per pixel diff --git a/RawSpeed3/patches/04.clang-cl-compatibility.patch b/RawSpeed3/patches/04.clang-cl-compatibility.patch new file mode 100644 index 000000000..b4879d068 --- /dev/null +++ b/RawSpeed3/patches/04.clang-cl-compatibility.patch @@ -0,0 +1,37 @@ +diff --git a/src/librawspeed/common/DefaultInitAllocatorAdaptor.h b/src/librawspeed/common/DefaultInitAllocatorAdaptor.h +index 2ff8969e..fa18c312 100644 +--- a/src/librawspeed/common/DefaultInitAllocatorAdaptor.h ++++ b/src/librawspeed/common/DefaultInitAllocatorAdaptor.h +@@ -27,8 +27,12 @@ + namespace rawspeed { + + template , +- typename = std::enable_if_t::value>> +-class DefaultInitAllocatorAdaptor { ++#ifdef _MSC_VER ++ typename = std::enable_if_t> ++#else ++ typename = std::enable_if_t::value >> ++#endif ++ class DefaultInitAllocatorAdaptor { + public: + using allocator_traits = std::allocator_traits; + +diff --git a/src/librawspeed/decompressors/VC5Decompressor.cpp b/src/librawspeed/decompressors/VC5Decompressor.cpp +index c498ac3a..de4ae412 100644 +--- a/src/librawspeed/decompressors/VC5Decompressor.cpp ++++ b/src/librawspeed/decompressors/VC5Decompressor.cpp +@@ -398,7 +398,12 @@ VC5Decompressor::VC5Decompressor(ByteStream bs, const RawImage& img) + wavelet.height = waveletHeight; + + wavelet.bands.resize( +- &wavelet == channel.wavelets.begin() ? 1 : Wavelet::maxBands); ++#ifdef _MSC_VER ++ Wavelet::maxBands ++#else ++ &wavelet == channel.wavelets.begin() ? 1 : Wavelet::maxBands ++#endif ++ ); + } + } + diff --git a/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp new file mode 100644 index 000000000..1394aeb3c --- /dev/null +++ b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp @@ -0,0 +1,251 @@ +#include "rawspeed3_capi.h" +#include "RawSpeed-API.h" +#define HAVE_PUGIXML +#include <../pugixml/pugixml.hpp> // for xml_document, xml_pars... + +extern const char* _rawspeed3_data_xml; + +class rawspeed3_handle_data +{ +public: + rawspeed3_handle_data(const char* cameradefs, bool is_file); + void release(); + int decodefile(rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown); + ~rawspeed3_handle_data(); +private: + std::unique_ptr cameraMeta; + std::unique_ptr rawParser; + std::unique_ptr rawDecoder; +}; + + +/* API calls */ + +extern "C" +{ + +/* + void rawspeed3_clearresult(rawspeed3_ret_t* r) + + Clears (inits) results structure +*/ +DllDef void rawspeed3_clearresult(rawspeed3_ret_t* r) +{ + if(!r) return; + r->width = r->height = r->bpp = r->cpp = 0; + r->status = rawspeed_inited; + r->pitch = r->filters = 0; + r->pixeldata = nullptr; +} + +/* + rawspeed3_init() + Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success + Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true) +*/ + +DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file) +{ + /* Create rawspeed3_handle_data and return it as void document */ + if(!cameradefs) return nullptr; + try + { + /* code */ + auto *handle = new rawspeed3_handle_data(cameradefs, is_file); + return (void*)handle; + } + catch(const std::exception& e) + { + return nullptr; + } +} + +/* + rawspeed3_initdefault() + Init rawspeed3 Cameradefs with built-in cameras.xml (converted to _rawspeed3_data_xml), + returns: 0 on failure, pointer to data block on success +*/ + +DllDef rawspeed3_handle_t rawspeed3_initdefault() +{ + return rawspeed3_init(_rawspeed3_data_xml,false); +} + +/* + rawspeed3_decodefile(..) + parse/decode RAW file passed via memory + Parameters: + handle - rawspeed3_handle_t => handle created by rawspeed3_init() + resultp -> pointer to rawspeed3_ret_t to be filled with + data -> data buffer with raw file + datasize -> size of this buffer + allowunknown -> allow to process unknown cameras (not listed in cameras.xml) + Return values: + 0 -> OK + >=1 -> decode error + -1 -> Incorrect parameters passed (handle, or data, or datasize) +*/ + +DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp, + const void *data, size_t datasize, bool allowunknown) +{ + if(!handle || !resultp || !data || datasize > 2UL * 1024UL * 1024UL * 1024UL) + { + if(resultp) + resultp->status = rawspeed3_param_error; + return -1; + } + rawspeed3_clearresult(resultp); + auto *p = static_cast(handle); + return p->decodefile(resultp,data,datasize,allowunknown); +} + +/* + void rawspeed3_release(rawspeed3_handle_t handle) + + release internal raw data buffer and error code; +*/ + +/* release internal raw data buffer and errmessage (if any) */ +DllDef void rawspeed3_release(rawspeed3_handle_t handle) +{ + if(!handle) return; + auto *p = static_cast(handle); + p->release(); +} + +/* close handle: release all internal data */ +DllDef void rawspeed3_close(rawspeed3_handle_t handle) +{ + if(!handle) return; + auto *p = static_cast(handle); + delete p; +} + +} /* extern "C" */ + +// == Implementation + +int rawspeed3_handle_data::decodefile(rawspeed3_ret_t* resultp, + const void *data, size_t datasize, bool allowunknown) +{ + if(!cameraMeta) + { + resultp->status = rawspeed3_not_inited; + return rawspeed3_not_inited; + } + try + { + rawspeed::Buffer buffer( static_cast(data),datasize); + release(); + rawParser = std::make_unique(buffer); + auto d(rawParser->getDecoder(cameraMeta.get())); + if(!d) + { + resultp->status = rawspeed3_no_decoder; + return rawspeed3_no_decoder; + } + + d->applyCrop = false; + d->failOnUnknown = !allowunknown; + d->interpolateBadPixels = false; + d->applyStage1DngOpcodes = false; + d->fujiRotate = false; + d->applyCrop = false; + + try { + d->checkSupport(cameraMeta.get()); + } catch (...) { + release(); + resultp->status = rawspeed3_not_supported; + return resultp->status; + } + + rawspeed::RawImage r = d->mRaw; + d->decodeMetaData(cameraMeta.get()); + + d->checkSupport(cameraMeta.get()); + d->decodeRaw(); + d->decodeMetaData(cameraMeta.get()); + r = d->mRaw; + + rawDecoder = std::move(d); + // we're here w/o exceptions: success + const rawspeed::iPoint2D dimUncropped = r->getUncroppedDim(); + resultp->width = dimUncropped.x; + resultp->height = dimUncropped.y; + resultp->filters = r->cfa.getDcrawFilter(); + resultp->cpp = r->getCpp(); + resultp->bpp = r->getBpp(); + resultp->pitch = r->pitch; + resultp->pixeldata = r->getDataUncropped(0,0); + const auto errors = r->getErrors(); + resultp->status = errors.empty()? rawspeed3_ok : rawspeed3_ok_warnings; + return resultp->status; + /* code */ + } + catch(...) + { + resultp->status = rawspeed3_processing_error; + return rawspeed3_processing_error; + } +} + +namespace rawspeed +{ + class CameraMetaDataFromMem : public CameraMetaData + { + public: + explicit CameraMetaDataFromMem(const char* xmlstring); + }; +} + + +rawspeed3_handle_data::rawspeed3_handle_data(const char* cameradefs, bool is_file) + : rawParser(nullptr) +{ + cameraMeta = is_file ? std::make_unique(cameradefs) + : std::make_unique (cameradefs); +} +rawspeed3_handle_data::~rawspeed3_handle_data() +{ + release(); + cameraMeta.reset(); +} + +void rawspeed3_handle_data::release() +{ + if(rawDecoder) + rawDecoder.reset(); + if (rawParser) + rawParser.reset(); +} + +// Camera metadata from mem +namespace rawspeed +{ + CameraMetaDataFromMem::CameraMetaDataFromMem(const char* document) + { + using pugi::xml_node; + using pugi::xml_document; + using pugi::xml_parse_result; + + xml_document doc; + xml_parse_result result = doc.load_string(document); + + if (!result) + throw "Camera definitions parse error"; + + for (xml_node camera : doc.child("Cameras").children("Camera")) + { + const auto* cam = addCamera(std::make_unique(camera)); + + if (cam == nullptr) + continue; + + // Create cameras for aliases. + for (auto i = 0UL; i < cam->aliases.size(); i++) + addCamera(std::make_unique(cam, i)); + } + } +} // namespace rawspeed diff --git a/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h new file mode 100644 index 000000000..fb2b55100 --- /dev/null +++ b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h @@ -0,0 +1,83 @@ +#pragma once +#include +#include + +#ifdef _MSC_VER +#ifdef RAWSPEED_BUILDLIB +#define DllDef __declspec(dllexport) +#else +#define DllDef __declspec(dllimport) +#endif +#else +#define DllDef +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum rawspeed3_error_codes +{ + rawspeed_inited = -2, + rawspeed3_param_error = -1, + rawspeed3_ok = 0, + rawspeed3_ok_warnings = 1, + rawspeed3_not_inited = 2, + rawspeed3_processing_error = 3, + rawspeed3_no_decoder = 4, + rawspeed3_not_supported = 5, +}; + +typedef void *rawspeed3_handle_t; + +/* RAW file parsing results */ +typedef struct +{ + int status; /* -1: param error, 0 => OK, >=1 error code */ + uint16_t width, height, bpp, cpp; + unsigned pitch, filters; + const void *pixeldata; +}rawspeed3_ret_t; + +/* API calls */ +DllDef void rawspeed3_clearresult(rawspeed3_ret_t*); +/* + rawspeed3_init() + Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success + Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true) +*/ +DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file); + +/* init with built-in cameras.xml */ +DllDef rawspeed3_handle_t rawspeed3_initdefault(); + +/* + rawspeed3_decodefile(..) + parse/decode RAW file passed via memory + Parameters: + handle - rawspeed3_handle_t => handle created by rawspeed3_init() + resultp -> pointer to rawspeed3_ret_t to be filled with + data -> data buffer with raw file + datasize -> size of this buffer + allowunknown -> allow to process unknown cameras (not listed in cameras.xml) + Return values: + 0 -> OK + 1 -> decode warnings (not fatal) + >1 -> error code + -1 -> Incorrect parameters passed (handle, or data, or datasize) +*/ +DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp, + const void *data, size_t datasize, bool allowunknown); + +/* release internal raw data buffer */ +DllDef void rawspeed3_release(rawspeed3_handle_t handle); + +/* close handle: release all internal data */ +DllDef void rawspeed3_close(rawspeed3_handle_t handle); + + +#ifdef __cplusplus +} /* Extern C */ +#endif diff --git a/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp new file mode 100644 index 000000000..a56ac1e16 --- /dev/null +++ b/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp @@ -0,0 +1,71 @@ +#include "rawspeed3_capi.h" +#include +#include +#include +#include + + + +std::vector readfile(char *fn) +{ + std::ifstream is(fn,std::ifstream::binary); + if(is) + { + is.seekg(0, is.end); + size_t length = is.tellg(); + is.seekg(0, is.beg); + std::vector ret; + ret.resize(length+1); + is.read ((char*)ret.data(),length); + is.close(); + ret[length] = 0; // zero terminated + std::cout << "File: " << fn << " size:" << ret.size() << std::endl; + return ret; + } + else + return std::vector(); +} + + +int main(int ac, char *av[]) +{ + if(ac < 2) + { + std::cout << "Usage: " << av[0] << " rawfile rawfile2 ...." << std::endl; + return 1; + } + rawspeed3_handle_t handle = rawspeed3_initdefault(); + if(!handle) + { + std::cerr << "Unable to init rs3" << std::endl; + return 2; + } + + for(int i = 1; i < ac; i++) + { + std::vector rawdata = readfile(av[i]); + if (rawdata.size() < 100) { + std::cerr << "Input file " << av[i] << " too small or nonexistent" << std::endl; + continue; + } + rawspeed3_ret_t result; + int q = rawspeed3_decodefile(handle, &result, rawdata.data(), + rawdata.size(), true); + if (q >= rawspeed3_ok && q <= rawspeed3_ok_warnings) { + std::cout << "File decoded code=" << result.status <<" width=" << result.width + << " height=" << result.height + << " pitch=" << result.pitch + << " filters=" << std::hex << result.filters << std::dec + << " channels=" << result.cpp + << " bpp=" << result.bpp + << std::endl; + } else + std::cout << "RawSpeed wrapper error code:" << result.status + << std::endl; + + rawspeed3_release(handle); + } + + rawspeed3_close(handle); + +} \ No newline at end of file diff --git a/RawSpeed3/rawspeed3_c_api/rsxml2c.sh b/RawSpeed3/rawspeed3_c_api/rsxml2c.sh new file mode 100644 index 000000000..32b6b4612 --- /dev/null +++ b/RawSpeed3/rawspeed3_c_api/rsxml2c.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "const char *_rawspeed3_data_xml=" +cat $1 | tr -d '\015' | sed -e 's/\\/\\\\/g;s/"/\\"/g;s/ /\\t/g;s/^/"/;s/$/\\n"/' +echo "\"\\0\";" diff --git a/bin/.keep_me b/bin/.keep_me new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/bin/.keep_me @@ -0,0 +1,2 @@ + + diff --git a/buildfiles/4channels.pro b/buildfiles/4channels.pro new file mode 100644 index 000000000..d200a3821 --- /dev/null +++ b/buildfiles/4channels.pro @@ -0,0 +1,5 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +SOURCES=../samples/4channels.cpp diff --git a/buildfiles/4channels.vcxproj b/buildfiles/4channels.vcxproj new file mode 100644 index 000000000..50855bd49 --- /dev/null +++ b/buildfiles/4channels.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {F68CBE78-B27A-3A05-BCD3-293E8CAC1C52} + 4channels + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\4channels.obj\ + 4channels + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\4channels.obj\ + 4channels + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\4channels.obj\ + 4channels + true + release-x86_64\ + release-x86_64\4channels.obj\ + 4channels + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\4channels.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\4channels.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\4channels.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\4channels.obj\ + false + None + Sync + true + release-x86_64\4channels.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\4channels.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/4channels.vcxproj.filters b/buildfiles/4channels.vcxproj.filters new file mode 100644 index 000000000..db3096c98 --- /dev/null +++ b/buildfiles/4channels.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/dcraw_emu.pro b/buildfiles/dcraw_emu.pro new file mode 100644 index 000000000..5dce5a378 --- /dev/null +++ b/buildfiles/dcraw_emu.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/dcraw_emu.cpp diff --git a/buildfiles/dcraw_emu.vcxproj b/buildfiles/dcraw_emu.vcxproj new file mode 100644 index 000000000..053cbe4fb --- /dev/null +++ b/buildfiles/dcraw_emu.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {48688DB8-559A-3DE2-ADDE-5BD27BFEDDA2} + dcraw_emu + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\dcraw_emu.obj\ + dcraw_emu + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\dcraw_emu.obj\ + dcraw_emu + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\dcraw_emu.obj\ + dcraw_emu + true + release-x86_64\ + release-x86_64\dcraw_emu.obj\ + dcraw_emu + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\dcraw_emu.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\dcraw_emu.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\dcraw_emu.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\dcraw_emu.obj\ + false + None + Sync + true + release-x86_64\dcraw_emu.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\dcraw_emu.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/dcraw_emu.vcxproj.filters b/buildfiles/dcraw_emu.vcxproj.filters new file mode 100644 index 000000000..6ba9db16c --- /dev/null +++ b/buildfiles/dcraw_emu.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/dcraw_half.pro b/buildfiles/dcraw_half.pro new file mode 100644 index 000000000..fef2a3059 --- /dev/null +++ b/buildfiles/dcraw_half.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/dcraw_half.c diff --git a/buildfiles/dcraw_half.vcxproj b/buildfiles/dcraw_half.vcxproj new file mode 100644 index 000000000..f528fc2f9 --- /dev/null +++ b/buildfiles/dcraw_half.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {C6EACFA3-9FC5-393B-BCF6-2874B05E4581} + dcraw_half + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\dcraw_half.obj\ + dcraw_half + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\dcraw_half.obj\ + dcraw_half + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\dcraw_half.obj\ + dcraw_half + true + release-x86_64\ + release-x86_64\dcraw_half.obj\ + dcraw_half + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\dcraw_half.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\dcraw_half.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\dcraw_half.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\dcraw_half.obj\ + false + None + Sync + true + release-x86_64\dcraw_half.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\dcraw_half.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/dcraw_half.vcxproj.filters b/buildfiles/dcraw_half.vcxproj.filters new file mode 100644 index 000000000..53de0eaaa --- /dev/null +++ b/buildfiles/dcraw_half.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/half_mt.pro b/buildfiles/half_mt.pro new file mode 100644 index 000000000..4d0bfba56 --- /dev/null +++ b/buildfiles/half_mt.pro @@ -0,0 +1,10 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +win32 { + SOURCES=../samples/half_mt_win32.c +} else { + SOURCES=../samples/half_mt.c +} diff --git a/buildfiles/libraw-common-lib.pro b/buildfiles/libraw-common-lib.pro new file mode 100644 index 000000000..34eff4954 --- /dev/null +++ b/buildfiles/libraw-common-lib.pro @@ -0,0 +1,28 @@ +win32 { + QMAKE_CXXFLAGS+=/MP + !contains(QMAKE_HOST.arch, x86_64) { + SUFF="x86" + } else { + ## Windows x64 (64bit) specific build here + SUFF="x86_64" + } +} + +CONFIG(debug,debug|release) { + win32:OUTD=debug-$$SUFF + win32:OUTDE=debug-$$SUFF + macx:OUTD=debug +} else { + win32:OUTD=release-$$SUFF + win32:OUTDE=release-$$SUFF + macx:OUTD=release +} + +INCLUDEPATH+=../ +OBJECTS_DIR = $$OUTD/$${TARGET}.obj +MOC_DIR = $$OUTD/ +RCC_DIR = $$OUTD/ +UI_DIR = $$OUTD/ +DESTDIR = $$OUTD/ +LIBS+=-L$$OUTD +CONFIG+=warn_off \ No newline at end of file diff --git a/buildfiles/libraw-common.pro b/buildfiles/libraw-common.pro new file mode 100644 index 000000000..c1638b3a9 --- /dev/null +++ b/buildfiles/libraw-common.pro @@ -0,0 +1,8 @@ +win32:CONFIG+=console +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +win32-g++: +{ + LIBS += -lws2_32 +} +include (libraw-common-lib.pro) \ No newline at end of file diff --git a/buildfiles/libraw.pro b/buildfiles/libraw.pro new file mode 100644 index 000000000..1a5c56cee --- /dev/null +++ b/buildfiles/libraw.pro @@ -0,0 +1,70 @@ +TEMPLATE=lib +TARGET=libraw +INCLUDEPATH+=../ +include (libraw-common-lib.pro) + +HEADERS=../libraw/libraw.h \ + ../libraw/libraw_alloc.h \ + ../libraw/libraw_const.h \ + ../libraw/libraw_datastream.h \ + ../libraw/libraw_types.h \ + ../libraw/libraw_internal.h \ + ../libraw/libraw_version.h \ + ../internal/defines.h \ + ../internal/var_defines.h \ + ../internal/libraw_internal_funcs.h \ + ../internal/dcraw_defs.h ../internal/dcraw_fileio_defs.h \ + ../internal/dmp_include.h ../internal/libraw_cxx_defs.h \ + ../internal/x3f_tools.h + +CONFIG +=precompiled_headers + +CONFIG-=qt +CONFIG+=warn_off +CONFIG+=debug_and_release +macx: CONFIG+= static x86 x86_64 +macx: QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.5 +DEFINES+=LIBRAW_BUILDLIB + +SOURCES+= ../src/libraw_datastream.cpp ../src/decoders/canon_600.cpp \ + ../src/decoders/crx.cpp ../src/decoders/decoders_dcraw.cpp \ + ../src/decoders/decoders_libraw_dcrdefs.cpp \ + ../src/decoders/decoders_libraw.cpp ../src/decoders/dng.cpp \ + ../src/decoders/fp_dng.cpp ../src/decoders/fuji_compressed.cpp \ + ../src/decoders/generic.cpp ../src/decoders/kodak_decoders.cpp \ + ../src/decoders/load_mfbacks.cpp ../src/decoders/smal.cpp \ + ../src/decoders/unpack_thumb.cpp ../src/decoders/unpack.cpp \ + ../src/demosaic/aahd_demosaic.cpp ../src/demosaic/ahd_demosaic.cpp \ + ../src/demosaic/dcb_demosaic.cpp ../src/demosaic/dht_demosaic.cpp \ + ../src/demosaic/misc_demosaic.cpp ../src/demosaic/xtrans_demosaic.cpp \ + ../src/integration/dngsdk_glue.cpp ../src/integration/rawspeed_glue.cpp \ + ../src/metadata/adobepano.cpp ../src/metadata/canon.cpp \ + ../src/metadata/ciff.cpp ../src/metadata/cr3_parser.cpp \ + ../src/metadata/epson.cpp ../src/metadata/exif_gps.cpp \ + ../src/metadata/fuji.cpp ../src/metadata/identify_tools.cpp \ + ../src/metadata/hasselblad_model.cpp \ + ../src/metadata/identify.cpp ../src/metadata/kodak.cpp \ + ../src/metadata/leica.cpp ../src/metadata/makernotes.cpp \ + ../src/metadata/mediumformat.cpp ../src/metadata/minolta.cpp \ + ../src/metadata/misc_parsers.cpp ../src/metadata/nikon.cpp \ + ../src/metadata/normalize_model.cpp ../src/metadata/olympus.cpp \ + ../src/metadata/p1.cpp ../src/metadata/pentax.cpp \ + ../src/metadata/samsung.cpp ../src/metadata/sony.cpp \ + ../src/metadata/tiff.cpp ../src/postprocessing/aspect_ratio.cpp \ + ../src/postprocessing/dcraw_process.cpp ../src/postprocessing/mem_image.cpp \ + ../src/postprocessing/postprocessing_aux.cpp \ + ../src/postprocessing/postprocessing_utils_dcrdefs.cpp \ + ../src/postprocessing/postprocessing_utils.cpp \ + ../src/preprocessing/ext_preprocess.cpp ../src/preprocessing/raw2image.cpp \ + ../src/preprocessing/subtract_black.cpp ../src/tables/cameralist.cpp \ + ../src/tables/colorconst.cpp ../src/tables/colordata.cpp \ + ../src/tables/wblists.cpp ../src/utils/curves.cpp \ + ../src/utils/decoder_info.cpp ../src/utils/init_close_utils.cpp \ + ../src/utils/open.cpp ../src/utils/phaseone_processing.cpp \ + ../src/utils/read_utils.cpp ../src/utils/thumb_utils.cpp \ + ../src/utils/utils_dcraw.cpp ../src/utils/utils_libraw.cpp \ + ../src/write/apply_profile.cpp ../src/write/file_write.cpp \ + ../src/write/tiff_writer.cpp ../src/x3f/x3f_parse_process.cpp \ + ../src/x3f/x3f_utils_patched.cpp \ + ../src/libraw_c_api.cpp + diff --git a/buildfiles/libraw.vcxproj b/buildfiles/libraw.vcxproj new file mode 100644 index 000000000..574f710bc --- /dev/null +++ b/buildfiles/libraw.vcxproj @@ -0,0 +1,234 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {A71D2131-F425-381F-8A9A-29D60132A046} + libraw + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + DynamicLibrary + debug-x86_64\libraw.obj\ + libraw + + + v142 + release-x86_64\ + false + NotSet + DynamicLibrary + release-x86_64\libraw.obj\ + libraw + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\libraw.obj\ + libraw + true + release-x86_64\ + release-x86_64\libraw.obj\ + libraw + true + false + + + + .;..;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\libraw.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\libraw.obj\ + Disabled + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + debug-x86_64;%(AdditionalLibraryDirectories) + true + true + true + true + $(OutDir)\libraw.dll + true + Windows + true + + + Unsigned + None + 0 + + + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\libraw.obj\ + false + None + Sync + true + release-x86_64\libraw.obj\ + MaxSpeed + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + release-x86_64;%(AdditionalLibraryDirectories) + true + false + true + true + false + true + $(OutDir)\libraw.dll + true + Windows + true + + + Unsigned + None + 0 + + + _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;LIBRAW_BUILDLIB;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/buildfiles/libraw.vcxproj.filters b/buildfiles/libraw.vcxproj.filters new file mode 100644 index 000000000..e4daa9442 --- /dev/null +++ b/buildfiles/libraw.vcxproj.filters @@ -0,0 +1,295 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/buildfiles/mem_image.pro b/buildfiles/mem_image.pro new file mode 100644 index 000000000..8b3c38ce9 --- /dev/null +++ b/buildfiles/mem_image.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/mem_image_sample.cpp diff --git a/buildfiles/mem_image.vcxproj b/buildfiles/mem_image.vcxproj new file mode 100644 index 000000000..a242e32e3 --- /dev/null +++ b/buildfiles/mem_image.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {BF8A2750-B847-3BA6-9EAF-05F43380F46C} + mem_image + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\mem_image.obj\ + mem_image + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\mem_image.obj\ + mem_image + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\mem_image.obj\ + mem_image + true + release-x86_64\ + release-x86_64\mem_image.obj\ + mem_image + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\mem_image.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\mem_image.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\mem_image.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\mem_image.obj\ + false + None + Sync + true + release-x86_64\mem_image.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\mem_image.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/mem_image.vcxproj.filters b/buildfiles/mem_image.vcxproj.filters new file mode 100644 index 000000000..45631183a --- /dev/null +++ b/buildfiles/mem_image.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/multirender_test.pro b/buildfiles/multirender_test.pro new file mode 100644 index 000000000..653437ebc --- /dev/null +++ b/buildfiles/multirender_test.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/multirender_test.cpp diff --git a/buildfiles/multirender_test.vcxproj b/buildfiles/multirender_test.vcxproj new file mode 100644 index 000000000..729f3adab --- /dev/null +++ b/buildfiles/multirender_test.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {30D21208-219A-3AA8-ADCF-E6B1FFAF6A73} + multirender_test + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\multirender_test.obj\ + multirender_test + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\multirender_test.obj\ + multirender_test + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\multirender_test.obj\ + multirender_test + true + release-x86_64\ + release-x86_64\multirender_test.obj\ + multirender_test + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\multirender_test.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\multirender_test.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\multirender_test.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\multirender_test.obj\ + false + None + Sync + true + release-x86_64\multirender_test.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\multirender_test.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/multirender_test.vcxproj.filters b/buildfiles/multirender_test.vcxproj.filters new file mode 100644 index 000000000..ffad024b3 --- /dev/null +++ b/buildfiles/multirender_test.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/openbayer_sample.pro b/buildfiles/openbayer_sample.pro new file mode 100644 index 000000000..fb14035b3 --- /dev/null +++ b/buildfiles/openbayer_sample.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/openbayer_sample.cpp diff --git a/buildfiles/openbayer_sample.vcxproj b/buildfiles/openbayer_sample.vcxproj new file mode 100644 index 000000000..92cfcf6e7 --- /dev/null +++ b/buildfiles/openbayer_sample.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {EF67FEF1-4B19-3765-A660-9F8E9333DEF3} + openbayer_sample + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\openbayer_sample.obj\ + openbayer_sample + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\openbayer_sample.obj\ + openbayer_sample + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\openbayer_sample.obj\ + openbayer_sample + true + release-x86_64\ + release-x86_64\openbayer_sample.obj\ + openbayer_sample + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\openbayer_sample.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\openbayer_sample.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\openbayer_sample.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\openbayer_sample.obj\ + false + None + Sync + true + release-x86_64\openbayer_sample.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\openbayer_sample.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/openbayer_sample.vcxproj.filters b/buildfiles/openbayer_sample.vcxproj.filters new file mode 100644 index 000000000..914c2fecd --- /dev/null +++ b/buildfiles/openbayer_sample.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/postprocessing_benchmark.pro b/buildfiles/postprocessing_benchmark.pro new file mode 100644 index 000000000..145037dda --- /dev/null +++ b/buildfiles/postprocessing_benchmark.pro @@ -0,0 +1,4 @@ +include (libraw-common.pro) +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/postprocessing_benchmark.cpp diff --git a/buildfiles/postprocessing_benchmark.vcxproj b/buildfiles/postprocessing_benchmark.vcxproj new file mode 100644 index 000000000..a94e078b6 --- /dev/null +++ b/buildfiles/postprocessing_benchmark.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {5C66A8FA-D211-3E2F-A2F1-0C3C665689CC} + postprocessing_benchmark + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\postprocessing_benchmark.obj\ + postprocessing_benchmark + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\postprocessing_benchmark.obj\ + postprocessing_benchmark + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\postprocessing_benchmark.obj\ + postprocessing_benchmark + true + release-x86_64\ + release-x86_64\postprocessing_benchmark.obj\ + postprocessing_benchmark + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\postprocessing_benchmark.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\postprocessing_benchmark.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + libraw.lib;ws2_32.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\postprocessing_benchmark.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\postprocessing_benchmark.obj\ + false + None + Sync + true + release-x86_64\postprocessing_benchmark.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + libraw.lib;ws2_32.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\postprocessing_benchmark.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/postprocessing_benchmark.vcxproj.filters b/buildfiles/postprocessing_benchmark.vcxproj.filters new file mode 100644 index 000000000..66b0fc6b4 --- /dev/null +++ b/buildfiles/postprocessing_benchmark.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/raw-identify.pro b/buildfiles/raw-identify.pro new file mode 100644 index 000000000..539a14d0b --- /dev/null +++ b/buildfiles/raw-identify.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/raw-identify.cpp diff --git a/buildfiles/raw-identify.vcxproj b/buildfiles/raw-identify.vcxproj new file mode 100644 index 000000000..a31613727 --- /dev/null +++ b/buildfiles/raw-identify.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {7C4F61DB-717E-36C9-B20E-36F8E218AB51} + raw-identify + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\raw-identify.obj\ + raw-identify + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\raw-identify.obj\ + raw-identify + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\raw-identify.obj\ + raw-identify + true + release-x86_64\ + release-x86_64\raw-identify.obj\ + raw-identify + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\raw-identify.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\raw-identify.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\raw-identify.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\raw-identify.obj\ + false + None + Sync + true + release-x86_64\raw-identify.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\raw-identify.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/raw-identify.vcxproj.filters b/buildfiles/raw-identify.vcxproj.filters new file mode 100644 index 000000000..0762ede28 --- /dev/null +++ b/buildfiles/raw-identify.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/rawtextdump.pro b/buildfiles/rawtextdump.pro new file mode 100644 index 000000000..f7afd2151 --- /dev/null +++ b/buildfiles/rawtextdump.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/rawtextdump.cpp diff --git a/buildfiles/rawtextdump.vcxproj b/buildfiles/rawtextdump.vcxproj new file mode 100644 index 000000000..a2c44589b --- /dev/null +++ b/buildfiles/rawtextdump.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {53A1E3F0-8032-348E-B3BF-3E540A45005F} + rawtextdump + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\rawtextdump.obj\ + rawtextdump + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\rawtextdump.obj\ + rawtextdump + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\rawtextdump.obj\ + rawtextdump + true + release-x86_64\ + release-x86_64\rawtextdump.obj\ + rawtextdump + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\rawtextdump.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\rawtextdump.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\rawtextdump.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\rawtextdump.obj\ + false + None + Sync + true + release-x86_64\rawtextdump.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\rawtextdump.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/rawtextdump.vcxproj.filters b/buildfiles/rawtextdump.vcxproj.filters new file mode 100644 index 000000000..33dedcd60 --- /dev/null +++ b/buildfiles/rawtextdump.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/simple_dcraw.pro b/buildfiles/simple_dcraw.pro new file mode 100644 index 000000000..f28a6ef67 --- /dev/null +++ b/buildfiles/simple_dcraw.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/simple_dcraw.cpp diff --git a/buildfiles/simple_dcraw.vcxproj b/buildfiles/simple_dcraw.vcxproj new file mode 100644 index 000000000..4d1529dee --- /dev/null +++ b/buildfiles/simple_dcraw.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {AD1E31D8-A022-3672-982F-C8280A0D6458} + simple_dcraw + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\simple_dcraw.obj\ + simple_dcraw + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\simple_dcraw.obj\ + simple_dcraw + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\simple_dcraw.obj\ + simple_dcraw + true + release-x86_64\ + release-x86_64\simple_dcraw.obj\ + simple_dcraw + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\simple_dcraw.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\simple_dcraw.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\simple_dcraw.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\simple_dcraw.obj\ + false + None + Sync + true + release-x86_64\simple_dcraw.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\simple_dcraw.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/simple_dcraw.vcxproj.filters b/buildfiles/simple_dcraw.vcxproj.filters new file mode 100644 index 000000000..3f714b9d7 --- /dev/null +++ b/buildfiles/simple_dcraw.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/buildfiles/unprocessed_raw.pro b/buildfiles/unprocessed_raw.pro new file mode 100644 index 000000000..b9e0df77d --- /dev/null +++ b/buildfiles/unprocessed_raw.pro @@ -0,0 +1,6 @@ +include (libraw-common.pro) +win32:LIBS+=libraw.lib +unix:LIBS+=-lraw +CONFIG-=qt +CONFIG+=debug_and_release +SOURCES=../samples/unprocessed_raw.cpp diff --git a/buildfiles/unprocessed_raw.vcxproj b/buildfiles/unprocessed_raw.vcxproj new file mode 100644 index 000000000..11c64d335 --- /dev/null +++ b/buildfiles/unprocessed_raw.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {1333E21E-D3B5-3640-9A4D-D8955082B855} + unprocessed_raw + Qt4VSv1.0 + 10.0.18362.0 + 10.0.18362.0 + + + + v142 + debug-x86_64\ + false + NotSet + Application + debug-x86_64\unprocessed_raw.obj\ + unprocessed_raw + + + v142 + release-x86_64\ + false + NotSet + Application + release-x86_64\unprocessed_raw.obj\ + unprocessed_raw + + + + + + + + + + + + debug-x86_64\ + debug-x86_64\unprocessed_raw.obj\ + unprocessed_raw + true + release-x86_64\ + release-x86_64\unprocessed_raw.obj\ + unprocessed_raw + true + false + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + debug-x86_64\unprocessed_raw.obj\ + false + ProgramDatabase + Sync + true + debug-x86_64\unprocessed_raw.obj\ + Disabled + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + debug-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + true + true + $(OutDir)\unprocessed_raw.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;_DEBUG;%(PreprocessorDefinitions) + + + + + .;..;%(AdditionalIncludeDirectories) + -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus %(AdditionalOptions) + release-x86_64\unprocessed_raw.obj\ + false + None + Sync + true + release-x86_64\unprocessed_raw.obj\ + MaxSpeed + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + false + + MultiThreadedDLL + true + true + TurnOffAllWarnings + + + ws2_32.lib;libraw.lib;%(AdditionalDependencies) + release-x86_64;%(AdditionalLibraryDirectories) + "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) + true + false + true + false + true + $(OutDir)\unprocessed_raw.exe + true + Console + true + + + Unsigned + None + 0 + + + _CONSOLE;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;WIN64;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/buildfiles/unprocessed_raw.vcxproj.filters b/buildfiles/unprocessed_raw.vcxproj.filters new file mode 100644 index 000000000..5a9b32589 --- /dev/null +++ b/buildfiles/unprocessed_raw.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/clist2c.pl b/clist2c.pl new file mode 100755 index 000000000..622a5a65f --- /dev/null +++ b/clist2c.pl @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +while (<>) + { + chomp; + s/^\s+//; + s/^\s+\*\s+//; + s/^\s+//; + s/\"/\\\"/g; + s/\s+$//; + print "\"$_\",\n"; + } diff --git a/clist2html.pl b/clist2html.pl new file mode 100755 index 000000000..70da7375e --- /dev/null +++ b/clist2html.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl +use Data::Dumper; + +@makes=( "AgfaPhoto", "Canon", "Casio", "Digital Bolex", "Epson", "Fujifilm", "Imacon", + "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", "Hasselblad", + "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", + "Samsung", "Sigma", "Sinar", "Sony" ); + +MAINLOOP: +while(<>) +{ + chomp; + $cname = $_; + $cname=~s/^\s+//g; + $cname=~s/\s+$//g; + for my $camera (@makes) + { + if ($cname=~/\Q$camera\E\s+(.*)/) + { + + $model = $1; + push @{$cameralist->{$camera}},$model; + next MAINLOOP; + } + } + if($cname=~/(\S+)\s+(.*)/) + { + ($make,$model) = ($1,$2); + push @{$cameralist->{$make}},$model; + next MAINLOOP; + } + push @{$cameralist->{$make}},"NO MODEL"; + +} +my $havenx1=0; +print "
    \n"; +for my $make (sort keys %$cameralist) +{ + if( $#{$cameralist->{$make}} < 1) + { + print "
  • $make $cameralist->{$make}->[0]
  • \n"; + + } + else + { + print "
  • $make\n
      \n"; + for my $model (@{$cameralist->{$make}}) + { + print "
    • $model
    • \n"; + } + print "
    \n
  • \n"; + } +} +print "
\n"; diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..7bf5fdfd7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,153 @@ +# Initialization +AC_INIT([LibRaw], m4_esyscmd([./version.sh]), [info@libraw.org], [], [http://www.libraw.org]) +AM_INIT_AUTOMAKE([foreign no-define]) +#AM_SILENT_RULES([yes]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CANONICAL_HOST + +# Tools to use +AC_PROG_CXX +AC_PROG_CC +AC_PROG_LIBTOOL +AC_ENABLE_SHARED +AC_ENABLE_STATIC +AC_LIBTOOL_WIN32_DLL +AC_LIBTOOL_SETUP +AC_SUBST(LIBTOOL_DEPS) + +# Config files to generate + +AC_CONFIG_FILES([ + Makefile + libraw.pc + libraw_r.pc +]) + +# check if we want OpenMP support +AC_ARG_ENABLE([openmp], + [ --enable-openmp Enable OpenMP support], + [case "${enableval}" in + yes) openmp=true ;; + no) openmp=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-openmp]) ;; + esac],[openmp=true]) + +if test x$openmp = xtrue ; then + AX_OPENMP([ + CXXFLAGS="$CXXFLAGS $OPENMP_CFLAGS" + CFLAGS="$CFLAGS $OPENMP_CFLAGS" + AC_SUBST([PC_OPENMP],[" $OPENMP_CFLAGS"]) + ],[ + AC_MSG_WARN([OpenMP support cannot be enabled because your system doesn't support it.]) + ]) +fi + +# check for libjpeg v8 +AC_ARG_ENABLE([jpeg], + [ --enable-jpeg Enable JPEG support for Lossy compressed DNG files], + [case "${enableval}" in + yes) jpeg=true ;; + no) jpeg=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-jpeg]) ;; + esac],[jpeg=true]) + +if test x$jpeg = xtrue; then + AC_CHECK_LIB([jpeg], [jpeg_mem_src], + [ + AC_CHECK_HEADERS([jpeglib.h], [ + CPPFLAGS="$CPPFLAGS -DUSE_JPEG -DUSE_JPEG8" + LIBS="$LIBS -ljpeg" + AC_SUBST([PACKAGE_LIBS_PRIVATE],"-ljpeg $PACKAGE_LIBS_PRIVATE") + ], AC_MSG_WARN([no jpeg headers found])) + ], + AC_MSG_WARN([libjpeg not found]) + ) +fi + +# check for Jasper (JPEG2000) support +AC_ARG_ENABLE([jasper], + [ --enable-jasper Enable Jasper (JPEG2000) support for RedCine files], + [case "${enableval}" in + yes) jasper=true ;; + no) jasper=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-jasper]) ;; + esac],[jasper=true]) + +if test x$jasper = xtrue; then + AC_CHECK_LIB([jasper], [jas_init], + [ + AC_CHECK_HEADERS([jasper/jasper.h], [ + CPPFLAGS="$CPPFLAGS -DUSE_JASPER" + LIBS="$LIBS -ljasper" + AC_SUBST([PACKAGE_LIBS_PRIVATE],"-ljasper $PACKAGE_LIBS_PRIVATE") + ], AC_MSG_WARN([no jasper headers found])) + ], + AC_MSG_WARN([libjasper not found]) + ) +fi + +# check if we want zlib support +AC_ARG_ENABLE([zlib], + [ --enable-zlib Enable zlib support for deflate compressed DNG files], + [case "${enableval}" in + yes) zlib=true ;; + no) zlib=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-zlib]) ;; + esac],[zlib=true]) + +if test x$zlib = xtrue; then + PKG_CHECK_MODULES([ZLIB],[zlib],[ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS -DUSE_ZLIB" + LIBS="$LIBS $ZLIB_LIBS" + AC_SUBST([PACKAGE_REQUIRES],[zlib]) + ], + AC_MSG_WARN([zlib support cannot be enabled]) + ) +fi + +# check if we want LCMS support +AC_ARG_ENABLE([lcms], + [ --enable-lcms Enable LCMS support], + [case "${enableval}" in + yes) lcms=true ;; + no) lcms=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-lcms]) ;; + esac],[lcms=true]) + +if test x$lcms = xtrue; then + PKG_CHECK_MODULES([LCMS2],[lcms2],[ + CPPFLAGS="$CPPFLAGS $LCMS2_CFLAGS -DUSE_LCMS2" + LIBS="$LIBS $LCMS2_LIBS" + AC_SUBST([PACKAGE_REQUIRES],[lcms2]) + ],[ + PKG_CHECK_MODULES([LCMS],[lcms],[ + CPPFLAGS="$CPPFLAGS $LCMS_CFLAGS -DUSE_LCMS" + LIBS="$LIBS $LCMS_LIBS" + AC_SUBST([PACKAGE_REQUIRES],[lcms]) + ],[ + AC_MSG_WARN([LCMS support cannot be enabled]) + ]) + ]) +fi + +# check if we want build examples +AC_ARG_ENABLE([examples], + [ --enable-examples Enable building of examples], + [case "${enableval}" in + yes) examples=true ;; + no) examples=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-examples]) ;; + esac],[examples=true]) +AM_CONDITIONAL([EXAMPLES], [test x$examples = xtrue]) + +LIBS="$LIBS -lm" + +case "${host_os}" in + *mingw32*) LIBS="$LIBS -lws2_32" ;; +esac + +AC_SUBST([LIBRAW_SHLIB_VERSION],m4_esyscmd([./shlib-version.sh])) +AC_SUBST([LIBRAW_RELEASE_VERSION],m4_esyscmd([./version.sh])) + +AC_OUTPUT + diff --git a/doc/API-C.html b/doc/API-C.html new file mode 100644 index 000000000..952e54d9b --- /dev/null +++ b/doc/API-C.html @@ -0,0 +1,187 @@ + + + + + +

LibRaw: C API[back to Index]

+

LibRaw: C API

+

LibRaw C API is a wrapper around C++ API; therefore, virtually all + documentation to C API functions is represented by a set of hyperlinks to + the corresponding places in the description of C++ + API.

+

Contents

+
    +
  1. Initialization and denitialization
  2. +
  3. Returned values
  4. +
  5. Data loading
  6. +
  7. Parameters getters/setters
  8. +
  9. Auxiliary Functions
  10. +
  11. Data Postprocessing, Emulation of dcraw Behavior + +
  12. +
  13. Writing to Output Files
  14. +
  15. Writing processing results to memory buffer
  16. +
+

+

Initialization and denitialization

+
+
libraw_data_t *libraw_init(unsigned int flags);
+
The function returns the pointer to the instance + of libraw_data_t structure.
+ The resultant pointer should be passed as the first argument to all C + API functions (except for libraw_strerror).
+ Returns NULL in case of error, pointer to the structure in all other + cases.
+
void libraw_close(libraw_data_t *);
+
Closes libraw_data_t handler and deallocates all memory.
+
+

+

Returned values

+

Functions of C API return EINVAL (see errno.h) if the null pointer was + passed to them as the first argument. In all other cases, the C++ + API return code is returned.

+

+

Data Loading from a File/Buffer

+
+
int libraw_open_file(libraw_data_t*, const char *)
+
int libraw_open_file_ex(libraw_data_t*, const char *,INT64 + bigfile_size)
+
WIN32: int libraw_open_wfile(libraw_data_t*, const wchar_t *)
+
WIN32: int libraw_open_wfile_ex(libraw_data_t*, const wchar_t *,INT64 + bigfile_size)
+
See LibRaw::open_file()
+
int libraw_open_buffer(libraw_data_t*, void *buffer, size_t bufsize)
+
See LibRaw::open_buffer()
+
int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, unsigned + datalen, ushort _raw_width, ushort _raw_height, ushort _left_margin, + ushort _top_margin, ushort _right_margin, ushort _bottom_margin, + unsigned char procflags, unsigned char bayer_battern, unsigned + unused_bits, unsigned otherflags, unsigned black_level)
+
See LibRaw::open_bayer()
+
int libraw_unpack(libraw_data_t*);
+
See LibRaw::unpack()
+
int libraw_unpack_thumb(libraw_data_t*);
+
See LibRaw::unpack_thumb()
+
int libraw_unpack_thumb_ex(libraw_data_t*,int);
+
See LibRaw::unpack_thumb_ex()
+
+

+

Parameters setters/getters

+

These functions provides interface to imgdata.params, .sizes and .color + fields which works regardless of LibRaw versions used when building + calling app and the library itself.

+
    +
  • int libraw_get_raw_height(libraw_data_t *lr);
  • +
  • int libraw_get_raw_width(libraw_data_t *lr);
  • +
  • int libraw_get_iheight(libraw_data_t *lr);
  • +
  • int libraw_get_iwidth(libraw_data_t *lr);
  • +
  • float libraw_get_cam_mul(libraw_data_t *lr,int index);
  • +
  • float libraw_get_pre_mul(libraw_data_t *lr,int index);
  • +
  • float libraw_get_rgb_cam(libraw_data_t *lr,int index1, int index2);
  • +
  • libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr);
  • +
  • libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr);
  • +
  • libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr);
  • +
  • int libraw_get_color_maximum(libraw_data_t *lr);
  • +
  • void libraw_set_user_mul(libraw_data_t *lr,int index, float val);
  • +
  • void libraw_set_demosaic(libraw_data_t *lr,int value);
  • +
  • void libraw_set_adjust_maximum_thr(libraw_data_t *lr,float value);
  • +
  • void libraw_set_output_color(libraw_data_t *lr,int value);
  • +
  • void libraw_set_output_bps(libraw_data_t *lr,int value);
  • +
  • void libraw_set_gamma(libraw_data_t *lr,int index, float value);
  • +
  • void libraw_set_no_auto_bright(libraw_data_t *lr,int value);
  • +
  • void libraw_set_bright(libraw_data_t *lr,float value);
  • +
  • void libraw_set_highlight(libraw_data_t *lr,int value);
  • +
  • void libraw_set_fbdd_noiserd(libraw_data_t *lr,int value);
  • +
+

+

Auxiliary Functions

+
+
const char* libraw_version()
+
See LibRaw::version()
+
int libraw_versionNumber()
+
See LibRaw::versionNumber()
+
+
See LibRaw::versionNumber()
+
bool LIBRAW_CHECK_VERSION(major,minor,patch)
+
See LIBRAW_CHECK_VERSION
+
unsigned libraw_capabilities()
+
See LibRaw::capabilities()
+
int libraw_cameraCount()
+
See LibRaw::cameraCount()
+
const char* libraw_cameraList()
+
See LibRaw::cameraList()
+
int libraw_get_decoder_info(libraw_data_t*,libraw_decoder_info_t *);
+
See LibRaw::get_decoder_info()
+
const char* libraw_unpack_function_name(libraw_data_t*);
+
See LibRaw::unpack_function_name()
+
int libraw_COLOR(libraw_data_t*,int row,int col);
+
See LibRaw::COLOR()
+
void libraw_subtract_black(libraw_data_t*);
+
See LibRaw::subtract_black()
+
void libraw_recycle_datastream(libraw_data_t*);
+
See LibRaw::recycle_datastream()
+
void libraw_recycle(libraw_data_t*);
+
See LibRaw::recycle()
+
const char *libraw_strerror(int errorcode);
+
See LibRaw::strerror
+
const char *libraw_strprogress(enum LibRaw_progress);
+
See LibRaw::strprogress
+
void libraw_set_dataerror_handler(libraw_data_t*,data_callback func, + void *);
+
See LibRaw::set_dataerror_handler()
+
void libraw_set_progress_handler(libraw_data_t*,progress_callback + func, void *);
+
See LibRaw::set_progress_handler()
+
+

+

Data Postprocessing, Emulation of dcraw Behavior

+

+

Setting of Parameters

+

The postprocessing parameters for the calls described below are set, just + as for C++ API, via setting of fields in the libraw_output_params_t + structure:

+
 libraw_data_t *ptr = libraw_init(0);
+ ptr->params.output_tiff = 1; //  output to TIFF
+    
+

Fields of this structure are described in the documentation + to libraw_output_params_t. For notes on their use, see API + notes.

+

+

Emulation of dcraw Behavior

+
+
int libraw_raw2image(libraw_data_t*);
+
See LibRaw::raw2image
+
int libraw_free_image(libraw_data_t*);
+
See LibRaw::free_image
+
int libraw_adjust_sizes_info_only(libraw_data_t*);
+
See LibRaw::adjust_sizes_info_only()
+
int libraw_dcraw_process(libraw_data_t* lr);
+
See LibRaw::dcraw_process()
+
+

Writing to Output Files

+
+
int libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char + *filename);
+
See LibRaw::dcraw_ppm_tiff_writer()
+
int libraw_dcraw_thumb_writer(libraw_data_t* lr,const char *fname);
+
See LibRaw::dcraw_thumb_writer()
+
+

Writing processing results to memory buffer

+
+
libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t* + lr,int * errcode)
+
See LibRaw::dcraw_make_mem_image()
+
libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t* + lr,int * errcode)
+
See LibRaw::dcraw_make_mem_thumb()
+
void libraw_dcraw_clear_mem(libraw_processed_image_t *);
+
See LibRaw::dcraw_clear_mem()
+

+
+
+

[back to Index]

+ + diff --git a/doc/API-CXX.html b/doc/API-CXX.html new file mode 100644 index 000000000..b58ecbd3d --- /dev/null +++ b/doc/API-CXX.html @@ -0,0 +1,881 @@ + + + + + +

LibRaw C++ API[back to Index]

+

LibRaw C++ API

+

Contents

+
    +
  1. LibRaw Objects
  2. +
  3. Returned values
  4. +
  5. Methods Loading Data from a File + +
  6. +
  7. Auxiliary Functions + +
  8. +
  9. Data Postprocessing: Emulation of dcraw Behavior + +
  10. +
  11. Data Output to Files: Emulation of dcraw Behavior + +
  12. +
  13. Copying unpacked data into memory buffer + +
  14. +
  15. Input layer abstraction + +
  16. +
+

+

LibRaw Objects

+

The main LibRaw object (class) is created either without parameters or + with flags determining the object behavior.

+
#include "libraw/libraw.h"
...

LibRaw ImageProcessor(unsigned int flags=0);
...
+

Flags (several flags are combined via operator |, i.e., bitwise OR):

+
    +
  • LIBRAW_OPTIONS_NO_DATAERR_CALLBACK: do not set the + standard file read error handler (standard + handler outputs the error report in stderr).
  • +
+

Three groups of methods are used for image processing

+ +

The results of processing are placed in the imgdata field of type libraw_data_t; + the same data set contains fields that control the postprocessing and + output.

+

+

Returned Values

+

All LibRaw API functions return an integer number in accordance with the + return code convention. Please read + the descriptions of this convention + and LibRaw behavior in cases of fatal errors.

+

+

Methods Loading Data from a File

+

+

int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)

+

Opens a datastream with RAW data, reads metadata (EXIF) from it, and + fills the following structures:

+ +

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

Before file opening, recycle() is always called; + hence, if several images are processed in the batch mode, there is no need + to call recycle() at the end of each processing cycle.

+

Input data: pointer to object, derived from LibRaw_abstract_datastream + class. This object should be initialized and ready to read. This object + should be destroyed in calling application after use.

+

+

int LibRaw::open_file(const char *filename[,INT64 bigfile_size])

+

Win32 only: int LibRaw::open_file(const wchar_t *filename[,INT64 + bigfile_size])

+

Creates an LibRaw_file_datastream object, + calls open_datastream(). If succeed, sets + internal flag which signals to destroy internal datastream object on recycle(). + On failure, just created file_datastream destroyed immediately.

+

Second optional parameter bigfile_size controls + background I/O interface used for file operations. For files smaller than + bigfile_size the LibRaw_file_datastream + will be used and the LibRaw_bigfile_datastream + otherwise.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

int LibRaw::open_buffer(void *buffer, size_t bufsize)

+

Created an LibRaw_buffer_datastream + object, calls open_datastream(). If + succeed, sets internal flag which signals to destroy internal datastream + object on recycle(). On failure, just created + file_datastream destroyed immediately.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

int LibRaw::open_bayer(unsigned char *data, unsigned datalen, ushort + _raw_width, ushort _raw_height, ushort _left_margin, ushort _top_margin, + ushort _right_margin, ushort _bottom_margin, unsigned char procflags, + unsigned char bayer_pattern, unsigned unused_bits, unsigned otherflags, + unsigned black_level)

+

Parameters:

+
    +
  • data, datalen - buffer passed
  • +
  • _raw_width/_raw_height/*margin - image size and margins
  • +
  • procflags: +
      +
    • for 10-bit format: +
        +
      • 1: "4 pixels in 5 bytes" packing is used
      • +
      • 0: "6 pixels in 8 bytes" packing is used
      • +
      +
    • +
    • for 16-bit format: +
        +
      • 1: Big-endian data
      • +
      +
    • +
    +
  • +
  • bayer_pattern: one of LIBRAW_OPENBAYER_RGGB,LIBRAW_OPENBAYER_BGGR, + LIBRAW_OPENBAYER_GRBG,LIBRAW_OPENBAYER_GBRG
  • +
  • unused_bits: count of upper zero bits
  • +
  • otherflags: +
      +
    • Bit 1 - filter (average neighbors) for pixels with values of zero +
    • +
    • Bits 2-4 - the orientation of the image (0=do not rotate, 3=180, + 5=90CCW, 6=90CW)
    • +
    +
  • +
  • black_level: file black level (it also may be specified via + imgdata.params)
  • +
+ See samples/openbayer_sample.cpp for usage sample (note, this sample is + 'sample only', suited for Kodak KAI-0340 sensor, you'll need change + open_bayer() params for your data). +

+

int LibRaw::unpack(void)

+

Unpacks the RAW files of the image, calculates the black level (not for + all formats). The results are placed in imgdata.image.

+

Data reading is sometimes (not frequently) affected by settings made in + imgdata.params (libraw_output_params_t); + see API notes for details.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

int LibRaw::unpack_thumb(void)

+

int LibRaw::unpack_thumb_ex(int i)

+

+

unpack_thumb(): reads (or unpacks) the default (largest) image preview + (thumbnail), placing the result into the imgdata.thumbnail.thumb buffer.

+

unpack_thumb_ex(int i): reads i-th thumbnail (thumbnails list is + available in imgdata.thumbs_list structure).

+

JPEG previews are placed into this buffer without any changes (with the + header etc.). Other preview formats are placed into the buffer in the form + of the unpacked bitmap image (three components, 8 bits per component).
+ The thumbnail format is written to the imgdata.thumbnail.tformat field; + for the possible values, see description + of constants and data structures.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

+

+

Auxiliary Functions

+

Library version check

+

+

const char* LibRaw::version()

+

Returns string representation of LibRaw version in + MAJOR.MINOR.PATCH-Status format (i.e. 0.6.0-Alpha2 or 0.6.1-Release).

+

+

int LibRaw::versionNumber()

+

Returns integer representation of LibRaw version. During LibRaw + development, the version number is always increase .

+

+

bool LIBRAW_CHECK_VERSION(major,minor,patch)

+

Macro for version check in caller applications. Returns 'true' if current + library version is greater or equal to set in macro parameters. This macro + executes at runtime (not at compile time) and may be used for checking + version of dynamically loaded LibRaw (from DLL/shared library).

+

List of supported RAW formats (cameras)

+

+

int LibRaw::cameraCount()

+

Returns count of cameras supported.

+

+

const char** LibRaw::cameraList()

+

Returns list of supported cameras. Latest item of list is set to NULL + (for easy printing).

+

+

int LibRaw::set_rawspeed_camerafile(char *path_to_cameras_xml)

+

(Only if LibRaw was built with RawSpeed support).

+

Loads XML file with RawSpeed camera description data (cameras.xml) + specified by path_to_cameras_xml. Returns 0 on success, nonzero on error. +

+

int LibRaw::get_decoder_info(libraw_decoder_info_t *)

+

The function fills libraw_decoder_info_t + structure by passed pointer with current raw decoder data.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

const char* LibRaw::unpack_function_name()

+

Returns function name of file unpacking function. Intended only for + LibRaw test suite designers to use in test coverage evaluation.

+

+

void LibRaw::setCancelFlag()

+

This call sets internal fast cancel flags. If set, current Raw decoder + will be terminated ASAP. This call is useful if you need to cancel all + LibRaw decoders in multithreaded program (e.g. for fast program + termination or just for cancel current processing).

+

+

void LibRaw::clearCancelFlag()

+

This call clears internal fast cancel flags, so (early) terminated LibRaw + decoder may work again.

+

+

int LibRaw::COLOR(int row, int col)

+

This call returns pixel color (color component number) in bayer pattern at + row,col. The returned value is in 0..3 range for 4-component Bayer (RGBG2, + CMYG and so on) and in 0..2 range for 3-color data.

+

Color indexes returned could be used as index in imgdata.idata.cdesc + string to get color 'name'.

+

+

int LibRaw::error_count()

+

This call returns count of non-fatal data errors (out of range, etc) + occurred in unpack() stage.

+

+

int LibRaw::subtract_black()

+

This call will subtract black level values from RAW data (for suitable + RAW data). colordata.data_maximum + and colordata.maximum and black level data (colordata.black + and colordata.cblack) will be adjusted too.

+

This call should be used if you postprocess RAW data by your own code. + LibRaw postprocessing functions will call subtract_black() + by oneself.

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+ +

int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop = + 0.55f)

+

Promotes imgdata.sizes.raw_inset_crops[] values to imgdata.sizes.*margin + and imgdata.sizes.width/height fields

+

Parameters
+ mask:

+
    +
  • if bit 1 is set: prefer raw_inset_crops[1]
  • +
  • if bit 0 is set: prefer raw_inset_crops[0]
  • +
+

maxcrop: limits crop to not less than (original width/height)*maxcrop; if + raw_inset_crops[i] data results in tighter crop, than this item is + ignored.

+

return value: index in raw_inset_crops[] used increased by one, so

+
    +
  • 0: no changes made
  • +
  • 1: [0]th data used
  • +
  • 2: [1]th data used
  • +
+

Note: this call SHOULD be used after LibRaw::unpack(), otherwise black + level calculation from masked area may be fooled resulting in wrong black + levels.

+

+

Support for floating point data

+

Libraw can read floating point DNG files (no other RAW formats may use + floating point) with or without conversion to integer data. Floating point + values are stored in imgdata.rawdata buffers:

+
    +
  • float * float_image (if + not NULL) points to floating point bayer data
  • +
  • float (*float3_image)[3] + (if not NULL) points to floating point 3-channel buffer
  • +
  • float (*float4_image)[4] + (if not NULL) points to floating point 4-channel buffer
  • +
+

Function calls for floating point support:

+
    +
  • int LibRaw::is_floating_point(); + function will return 1 if file contains floating point data
  • +
  • int LibRaw::have_fpdata(); + function will return 1 if FP data has read (decoded) into memory and not + converted to integer data
  • +
  • int LibRaw::convertFloatToInt(float dmin=4096.f, float dmax=32767.f, + float dtarget = 16383.f) converts floating point data to integer. If + data maximum is out of dmin..dmax range, than data scaled to set maximum + to dtarget
  • +
+

+

Support for YCC formats (Canon sRAW/mRAW and Nikon Small NEF)

+
       int LibRaw::is_sraw();
int LibRaw::is_nikon_sraw();
int LibRaw::sraw_midpoint()
+
    +
  • is_sraw() call returns nonzero if current image is YCC-based.
  • +
  • is_nikon_sraw() call returns nonzero for Nikon Small NEF files
  • +
  • sraw_midpoint() call returns neutral (gray) point for color channels
  • +
+

+

void LibRaw::set_dng_host(void* p)

+

If LibRaw is compiled with Adobe DNG SDK support and you wish to use this + support:

+
    +
  • you need to create own dng_host object
  • +
  • and pass it to LibRaw object using this function
  • +
+

void LibRaw::recycle_datastream(void)

+

This call closes input datastream with associated data buffer and + unblocks opened file.

+

void LibRaw::recycle(void)

+

Frees the allocated data of LibRaw instance, enabling one to process the + next file using the same processor. Repeated calls of recycle() are quite + possible and do not conflict with anything.

+

+

LibRaw::~LibRaw()

+

Destructor, which consists in calling recycle().

+

+

const char* LibRaw::strprogress(enum LibRaw_progress code)

+

Converts progress stage code to description string (in English).

+

+

const char* LibRaw::strerror(int errorcode)

+

Analog of strerror(3) function: outputs the text descriptions of LibRaw + error codes (in English).

+

+

Setting Error Notification Functions

+

In process of RAW conversion LibRaw can call user-setted callback. This + callback can be used for:

+
    +
  • Dynamic status update (progress bar and so on).
  • +
  • Cancel of processing (for example, user pressed Cancel button).
  • +
+

Also, work of the library may cause two types of exceptional situations + that require notification of the calling application:

+
    +
  • Memory shortage
  • +
  • Data read error.
  • +
+

An application may set its own callbacks that will be called in the cases + mentioned above to notify the user (or the calling program).

+

+

Progress indication/processing termination

+
        typedef int (*progress_callback)(void *callback_data,enum LibRaw_progress stage, int iteration, int expected);
void LibRaw::set_progress_handler(progress_callback func,void *callback_data);
+

LibRaw user can set own callback which will be called 10-50 times during + RAW postprocessing by dcraw_process().

+

This callback may terminate current image processing by returning of + non-zero value. In such case all processing will be cancelled immediately + and all resources will be returned to system by recycle() call. Current + call of dcraw_process() will return error code + LIBRAW_CANCELLED_BY_CALLBACK.

+

Callback parameters:

+
+
void *callback_data
+
void*-pointer, passed as 2nd argument to set_progress_handler(). This + pointer should be used to pass additional data to callback (i.e. thread + local data and so on).
+
enum LibRaw_progress stage
+
Current processing stage. This number can be converted to string by + call to LibRaw::strprogress. Not all + processing stages are covered by callback calls.
+
int iteration
+
Iteration number within current stage (from 0 to expected-1).
+
int expected
+
Expected number of iterations on current stage.
+
+

Callback should return value of: 0 for continue + processing and non-zero for immediate cancel of + processing.

+

 

+

If LibRaw compiled with OpenMP support, iteration parameter may not + always increase within one stage. Out of order callback calls are + possible.

+

Callback code sample:

+
int my_progress_callback(void *data,enum LibRaw_progress p,int iteration, int expected)
{
char *passed_string = (char *data);
printf("Callback: %s pass %d of %d, data passed: %s\n",libraw_strprogress(p),iteration,expected,passed_string);
if(timeout || key_pressed )
return 1; // cancel processing immediately
else
return 0; // can continue
}
+

+

User-specified exif tag parser callback

+
       typedef void (*exif_parser_callback) (void *context, int tag, int type, int len,unsigned int ord, void *ifp);
void LibRaw::set_exifparser_handler( exif_parser_callback cb,void *context);
+

Callback to be called on each parsed EXIF/Makernotes tag with parameters:

+
    +
  • context - pointer to context passed to set_exifparser_handler();
  • +
  • tag - EXIF/Makernotes tag value
  • +
  • type - TIFF(EXIF) tag type
  • +
  • len - tag length
  • +
  • ord - byte order (II or MM)
  • +
  • void *ifp - pointer to LibRaw_abstract_datastream, positioned to tag + data
  • +
+

+

File Read Error Notifier

+
        typedef void (*data_callback)(void *callback_data,const char *file, const int offset);
void LibRaw::set_dataerror_handler(data_callback func, void *callback_data);
+

The user can define his or her own function to be called in the case of + error in the input data. It is a void function receiving two parameters:

+
    +
  • void *callback_data - void*-pointer, passed as 2nd + argument to set_progress_handler(). This pointer should be used to pass + additional data to callback (i.e. thread local data and so on).
  • +
  • file is the name of the RAW file whose processing + evoked the file read error. This name can be NULL if + underlying data input layer does not know the name. So, if calling + application sets own callback, this callback should work with NULL file + name.
  • +
  • offset is -1 at end-of-file (if LibRaw expects more + data) or a positive number equal to the file position (bytes from file + beginning) where the unpacking error occurred.
  • +
+

The callback function is intended for information purposes: it notifies + the user or the program code that processing is impossible.

+

If the user does not set his or her own handler, the standard one (output + of error message in stderr) will be used.

+

One can set the null handler by passing NULL to set_dataerror_handler; + then no notifier function will be called. The same effect can be achieved + by creating a LibRaw object with the LIBRAW_OPTIONS_NO_DATAERR_CALLBACK + flag in the constructor.

+

In the case of error in the input data, processing of the current file is + terminated and a notifier is called; all allocated resources are freed, + and recycle() is performed. The current call will + return LIBRAW_IO_ERROR.
+ At an attempt to continue data processing, all subsequent calls will + return LIBRAW_OUT_OF_ORDER_CALL. Processing of a new file may be started + in the usual way, by calling LibRaw::open_file().

+

+

Data Postprocessing: Emulation of dcraw Behavior

+

Instead of writing one's own Bayer pattern postprocessing, one can use + the dcraw functions, which are called after the calls of open_file() + + unpack() /+ unpack_thumb()/

+

+

Parameter Setting

+

Virtually all parameters that can be set through the dcraw command line + are specified by assigning values to fields of the LibRaw::imgdata.params + structure. The type of this structure is libraw_output_params_t; + all fields are listed and described in sufficient detail in the description + of data structures.

+

+

int LibRaw::raw2image

+

This function allocates buffer for postprocessing (imgdata.image) and + fills it with data layout compatible with LibRaw 0.13/0.14 and below. If + the buffer is already allocated, it will be free()ed and allocated again.

+

This function should be called only if your code do postprocessing stage. + If you use LibRaw's postprocessing calls (see below) you don't need to + call raw2image().

+

The function returns an integer number in accordance with the return + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

void LibRaw::free_image

+

This function releases the imgdata.image buffer allocated by raw2image();

+

This method should be called if current postprocessing results are not + needed by the program (e.g. already copied somewhere), but new + postprocessing calls (with another settings) are possible, so it is to + early to call recycle().

+

+

int LibRaw::adjust_sizes_info_only(void)

+

The function calculates the correct size of the output image + (imgdata.sizes.iwidth and imgdata.sizes.iheight) for the following cases:

+
    +
  • Files from Fuji cameras (with a 45-degree rotation)
  • +
  • Files from cameras with non-square pixels
  • +
  • Images shot by a rotated camera.
  • +
+

In the aforementioned cases, the function changes the fields of the image + output size; note that this change cannot be repeated again.

+

+

int LibRaw::dcraw_process(void)

+

The function emulates the postprocessing capabilities available in dcraw.
+ Called after calling LibRaw::unpack();

+

The entire functionality of dcraw (set via the field values in imgdata.params) + is supported, except for

+
    +
  • Dark frame subtraction
  • +
  • Work with bad pixels.
  • +
+

The function is intended solely for demonstration and testing purposes; + it is assumed that its source code will be used in most real applications + as the reference material concerning the order of RAW data processing.

+

The function returns an integer number in accordance with the error + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

Data Output to Files: Emulation of dcraw Behavior

+

In spite of the abundance of libraries for file output in any formats, + LibRaw includes calls that emulate the file output provided by dcraw. This + is done primarily for easier verification of library work: the resultant + files must be binary identical.

+

+

int LibRaw::dcraw_ppm_tiff_writer(const char *outfile)

+

The function outputs the postprocessing results to a file in the PPM/PGM + or TIFF format (the format is set via imgdata.params.output_tiff). The + results are binary identical to those provided by dcraw.

+

If "-" is passed as outfile, the function will write to standard output + (stdout).

+

The function returns an integer number in accordance with the error + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

int LibRaw::dcraw_thumb_writer(const char *thumbfile)

+

Writes the thumbnail to a file in the PPM format for bitmap thumbnails + and in the JPEG format for JPEG thumbnails, i.e., in the format completely + identical to the results provided by dcraw.

+

The function returns an integer number in accordance with the error + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

Copying unpacked data into memory buffer

+

There is several function calls for store unpacked data into memory + buffer (after using dcraw_process() and so on):

+
    +
  • get_mem_image_format - get resulting bitmap size and + bit depth.
  • +
  • copy_mem_image - copy postprocessed data into some + memory buffer with different color order and line stride.
  • +
  • dcraw_make_mem_image - store processed image data + into allocated buffer;
  • +
  • dcraw_make_mem_thumb - store extracted thumbnail into + buffer as JPEG-file image (for most cameras) or as RGB-bitmap.
  • +
+

For usage primer see samples/mem_image.c sample.

+

 

+

+

void get_mem_image_format(int *widthp, int *heightp, int *colorsp, int + *bpp) const - return processing bitmap size

+

This function returns size of postprocessed image:

+
    +
  • Image width is returned in *widthp;
  • +
  • Bitmap height is returned in *heightp;
  • +
  • Image color count is returned in *colorsp;
  • +
  • Bits per pixel (8 or 16) is returned in *bpp;
  • +
+

+

int LibRaw::copy_mem_image(void* scan0, int stride, int bgr) - copies + postprocessed bitmap data into buffer

+

Function parameters:

+
    +
  • void *scan0 - pointer to buffer to copy data to. The buffer should be + at least stride*image_height bytes;
  • +
  • int stride - stride of each other image line (row) in bytes. Usually + image_width*(bit_per_pixel/8)*image_colors, but may be more if you wish + to align image rows to, for example, 8 or 16 or 32 bytes to make CPU + more happy.
  • +
  • int bgr - pixel copy order. RGB if bgr==0 and BGR otherwise.
  • +
+

The function returns an integer number in accordance with the error + code convention: positive if any system call has returned an error, + negative (from the LibRaw + error list) if there has been an error situation within LibRaw.

+

+

libraw_processed_image_t *dcraw_make_mem_image(int *errorcode=NULL) - + store unpacked and processed image into memory buffer as RGB-bitmap

+

This function allocates memory buffer and stores unpacked-preprocessed + image into this buffer. Function returns allocated structure libraw_processed_image_t + with filled fields. Always returns data as RGB bitmap (i.e. type + field is equal to LIBRAW_IMAGE_BITMAP).

+

dcraw_process() should be called before dcraw_make_mem_image();

+

Returns NULL in case of an error. If caller has passed not-NULL value as + errorcode parameter, than *errorcode will be set to error code according + to error code convention.

+

NOTE! Memory, allocated for return value will not be + fried at destructor or LibRaw::recycle calls. Caller of + dcraw_make_mem_image should free this memory by call to LibRaw::dcraw_clear_mem().

+

+

libraw_processed_image_t *dcraw_make_mem_thumb(int *errorcode=NULL) - + store unpacked thumbnail into memory buffer

+

This function allocates memory buffer and stores thumbnail data in it. + Function returns allocated structure libraw_processed_image_t + with filled fields. For most RAW images allocated structure will contains + JPEG image (i.e. type field is equal to + LIBRAW_IMAGE_JPEG). For some cameras with RGB-bitmap thumbnail (Kodak + SLRs) returned structure contains RGB bitmap (type field + is equal to LIBRAW_IMAGE_JPEG, see structure description for details).

+

unpack_thumb() should be called before dcraw_make_mem_thumb();

+

Returns NULL in case of an error. If caller has passed not-NULL value as + errorcode parameter, than *errorcode will be set to error code according + to ñ error code convention.

+

NOTE! Memory, allocated for return value will not be + fried at destructor or LibRaw::recycle calls. Caller of + dcraw_make_mem_image should free this memory by call to LibRaw::dcraw_clear_mem().

+

void LibRaw::dcraw_clear_mem(libraw_processed_image_t *)

+

This function will free the memory allocated by dcraw_make_mem_image + or dcraw_make_mem_thumb.

+

This is static class member, so call syntax should be + LibRaw::dcraw_clear_mem(...).

+

This call translates directly to free() system function, but it is better + to use dcraw_clear_mem because LibRaw (DLL) may be compiled with memory + manager other than in calling application.

+

+

Input layer abstraction

+

+

class LibRaw_abstract_datastream - abstract RAW read interface

+

LibRaw reads RAW-data by calling (virtual) methods of C++ object derived + from LibRaw_abstract_datastream. This C++ class does not + implement any read, but defines interface to be called. Call to base class + methods always results in error.

+

+

LibRaw_abstract_datastream class methods

+

+
Object verification
+
+
virtual int valid()
+
Checks input datastream validity. Returns 1 on valid stream and 0 if + datastream was created on non-valid input parameters (wrong filename for + file stream and so on).
+
+

+
Stream read and positioning
+

This group of methods implements file object (FILE*) semantics.

+
+
virtual int read(void * ptr,size_t size, size_t nmemb)
+
Similar to fread(ptr,size,nmemb,file).
+
virtual int seek(off_t o, int whence)
+
Similar to fseek(file,o,whence).
+
virtual int tell(
+
Similar to ftell(file).
+
virtual int get_char()
+
Similar to getc(file)/fgetc(file).
+
virtual char* gets(char *s, int n)
+
Similar to fgets(s,n,file).
+
virtual int eof()
+
Similar to feof(file).
+
virtual int scanf_one(const char *fmt, void *val)
+
Simplified variant of fscanf(file,fmt,val): format string is always + contains one argument to read. So, variable args call is not needed and + only one pointer to data passed.
+
virtual int jpeg_src(void * p);
+
Initializes read structures in j_decompress_ptr object passed as *p. + This object is used by libjpeg for JPEG data reading from datastream. +

Returns -1 on error and 0 on success.

+
+
virtual void * make_jas_stream();
+
Creates LibJasper input stream (for JPEG2000 decoding). +

returns NULL on error or data pointer on success.

+
+
+

+
Other methods
+

This group of methods includes several supplementary calls. These calls + are used to temporary switch to another data stream (file and/or memory + buffer).

+
+
virtual const char* fname()
+
Returns name of opened file if datastream object knows it (for + example, LibRaw_file_datastream used). Filename used + in: +
    +
  • error notification callbacks;
  • +
  • generation of filename of JPEG-file with metadata when needed + (i.e. cameras with 'Diag RAW hack').
  • +
+
+
virtual int subfile_open(const char *fn)
+
This call temporary switches input to file fn. + Returns 0 on success and error code on error.
+ The function used to read metadata from external JPEG file (on cameras + with "Diag RAW hack").
+ This call is not implemented for LibRaw_buffer_datastream, + so external JPEG processing is not possible when buffer datastream used. +
+ This function should be implemented in real input class, base class call + always return error.
+ Working implementation sample can be found in LibRaw_file_datastream + implementation in libraw/libraw_datastream.h file.
+
virtual void subfile_close()
+
This call switches input stream from temporary open file back to main + data stream.
+
virtual int tempbuffer_open(void *buf, size_t size)
+
This call temporary switches input to LibRaw_buffer_datastream + object, created from buf.
+ This method is needed for Sony encrypted metadata parser. +

This call implemented in base class (LibRaw_abstract_datastream), + there is no need to reimplement in in derived classes.
+ Possible activity of temporary datastream requires very accurate + programming when implementing datastreams derived from base LibRaw_abstract_datastream. + See below for more details.

+
+
virtual void tempbuffer_close()
+
This call switch input back from temporary datastream to main stream. + This call implemented in base LibRaw_abstract_datastream + class.
+
+

+

Derived input classes included in LibRaw

+

There is three "standard" input classes in LibRaw distribution:

+ +

LibRaw C++ interface users can implement their own input classes and use + them via LibRaw::open_datastream call. + Requirements and implementation specifics are described below.

+

+

class LibRaw_file_datastream - file input interface

+

This class implements input from file.

+

Class methods:

+
+
LibRaw_file_datastream(const char *fname)
+
This constructor creates LibRaw_file_datastream + object from file fname.
+ Unfortunately, C++ constructor cannot return an error. So if bad + filename passed (e.g. nonexistent file) object is created as non-valid + (valid() call returns zero).
+
+

All other class methods are described + above.
+ This class implements all possible methods, including fname() and + subfile_open().

+

+

class LibRaw_bigfile_datastream - file input interface

+

This class implements input from file.

+

Class methods:

+
+
LibRaw_bigfile_datastream(const char *fname)
+
This constructor creates LibRaw_bigfile_datastream + object from file fname.
+ Unfortunately, C++ constructor cannot return an error. So if bad + filename passed (e.g. nonexistent file) object is created as non-valid + (valid() call returns zero).
+
+

The difference between file and bigfile + datastreams are obvious from class name: bigfile one supports large files + (more than 2Gb) on all supported systems. File one uses streambuf + interface which is limited to 2Gb on many systems.

+

All other class methods are described + above.
+ This class implements all possible methods, including fname() and + subfile_open().

+

+

class LibRaw_buffer_datastream - memory buffer input interface

+

This class implements input from memory buffer.

+

Class methods:

+
+
LibRaw_buffer_datastream(void *buffer, size_t bsize)
+
This constructor creates datastream object from buffer + with size bsize.
+ It is not possibly to verify the pointer passed, so buffer address is + checked against 0 and -1 only.
+
+

All other class methods are described + above.
+ This class does not implement fname() and subfile_open() calls, so + external JPEG metadata parsing is not possible.

+

+

Own datastream derived classes

+

To create own read interface LibRaw user should implement C++ class + derived from LibRaw_abstract_datastream with all read + methods.
+ LibRaw standard implementations may be used as reference. See libraw/libraw_datastream.h + file for details (all standard LibRaw input classes are implemented using + inline functions only).

+

+

[back to Index]

+ + diff --git a/doc/API-datastruct.html b/doc/API-datastruct.html new file mode 100644 index 000000000..09c05ac76 --- /dev/null +++ b/doc/API-datastruct.html @@ -0,0 +1,1335 @@ + + + + LibRaw: Data Structures and Constants + + +

LibRaw: Data Structures and Constants [back to + Index]

+

LibRaw: Data Structures and Constants

+

LibRaw data structures are defined in header file libraw/libraw_types.h
+ Constants used in its work are defined in file libraw/libraw_const.h

+

Contents:

+
    +
  1. Data structures +
      +
    1. libraw_data_t: Main Data Structure in + LibRaw
    2. +
    3. Structure libraw_iparams_t: Main + Parameters of the Image
    4. +
    5. Structure libraw_image_sizes_t: + Image Dimensions
    6. +
    7. Structure libraw_colordata_t: Color + Information
    8. +
    9. Structure libraw_imgother_t: Other + Parameters of the Image
    10. +
    11. Structure libraw_rawdata_t: holds + unpacked RAW data
    12. +
    13. Structure libraw_thumbnail_t: + Description of extracted Thumbnail
    14. +
    15. Structure + libraw_thumbnail_list_t: Description of file's thumbnail list
    16. +
    17. Structure libraw_lensinfo_t - lens + data, extracted from EXIF/Makernotes
    18. +
    19. Structure + libraw_raw_unpack_params_t: metadata and raw decoding options and + flags
    20. +
    21. Structure + libraw_output_params_t: Management of dcraw-style postprocessing
    22. +
    23. Structure libraw_callbacks_t: + user-settable callbacks
    24. +
    25. Structure + libraw_processed_image_t - result set for + dcraw_make_mem_image()/dcraw_make_mem_thumb() functions
    26. +
    +
  2. +
  3. Input abstraction layer + +
  4. +
  5. Constants +
      +
    1. enum LibRaw_errors: Error Codes
    2. +
    3. enum LibRaw_decoder_flags - RAW data + format description
    4. +
    5. enum LibRaw_progress: Current State of LibRaw + Object
    6. +
    7. enum + LibRaw_thumbnail_formats: Thumbnail Data Formats
    8. +
    9. Nonstandard Situations (Warnings) during RAW + Data Processing
    10. +
    11. enum LibRaw_image_formats - + possible types of data, contains in libraw_processed_image_t + structure
    12. +
    13. enum + LibRaw_processing_options - flags that affects extracted RAW data
    14. +
    15. enum LibRaw_rawspecial_t - special + raw extraction modes
    16. +
    +
  6. +
+

+

Data Structures

+

+

libraw_data_t: Main Data Structure of LibRaw

+

Structure libraw_data_t is a "wrapping" for data structures accessible to + the user of the library.
+ When one uses C++ API, it is accessible as LibRaw::imgdata + (class_instance.imgdata). The data in this structure appear after a file + is opened through open_file (and other open_ calls), except for the image + itself (filled by unpack()) and data containing the preview information + (filled by calling unpack_thumb()).

+

Data fields:

+
+
unsigned int progress_flags;
+
This field records the past phases of image + processing .
+
unsigned int process_warnings;
+
This field records suspicious situations + (warnings) that have emerged during image processing.
+
libraw_iparams_t idata;
+
The structure describes the main image parameters retrieved from the + RAW file. Fields of this structure are described in detail + below .
+
libraw_image_sizes_t sizes;
+
The structure describes the geometrical parameters of the image. + Fields of this structure are described in detail + below .
+
libraw_lensinfo_t lens;
+
The structure describes lens used for the shot. Fields of this + structure are described in detail below + .
+
libraw_makernotes_t makernotes;
+
The structure contains camera/vendor specific metadata extracted from + file. No description provided, sorry, if you're interested in particular + tag/camera/vendor - use Exiftool documentation as a reference
+
libraw_colordata_t color;
+
The structure contains color data retrieved from the file. Fields of + this structure are described in detail + below .
+
libraw_imgother_t other;
+
Data structure for information purposes: it contains the image + parameters that have been extracted from the file but are not needed in + further file processing. Fields of this structure are described in + detail below .
+
libraw_thumbnail_t thumbnail;
+
Data structure containing information on the preview and the preview + data themselves. All fields of this structure but thumbnail itself are + filled when open_file() is called. Thumbnail read by unpack_thumb() + call. The fields are described in detail + below .
+
libraw_rawdata_t rawdata;
+
Data structure with pointer to raw-data buffer. Details are described + below .
+
ushort (*image)[4];
+
The memory area that contains the image pixels per se. It is filled + when raw2image() or dcraw_process() is called.
+
libraw_output_params_t params;
+
Data structure intended for management of image postprocessing (using + the dcraw emulator). Fields of this structure are described in detail below .
+
libraw_callbacks_t callbacks;
+
user-settable callbacks
+
+

+

Structure libraw_iparams_t: Main Parameters of the Image

+
+
char make[64];
+
Camera manufacturer.
+
char model[64];
+
Camera model.
+
normalized_make[64]
+
There is a huge number of identical cameras sold under different + names, depending on the market (e.g. multiple Panasonic or Canon models) + and even some identical cameras sold under different brands (Panasonic + -> Leica, Sony -> Hasselblad). normalized_make contains primary + vendor name (e.g. Panasonic for Leica re-branded cameras).
+
normalized_model[64]
+
Primary camera model name.
+
unsigned maker_index
+
Primary vendor name in indexed form (enum LibRaw_cameramaker_index, + LIBRAW_CAMERAMAKER_* constant)
+
char software[64];
+
Softwary name/version (mostly for DNG files, to distinguish in-camera + DNGs from Adobe DNG Converter produced ones).
+
unsigned raw_count;
+
Number of RAW images in file (0 means that the file has not been + recognized).
+
unsigned is_foveon;
+
Nonzero for Sigma Foveon images
+
unsigned dng_version;
+
DNG version (for the DNG format).
+
int colors;
+
Number of colors in the file.
+
unsigned filters;
+
Bit mask describing the order of color pixels in the matrix (0 for + full-color images). 32 bits of this field describe 16 pixels (8 rows + with two pixels in each, from left to right and from top to bottom). + Each two bits have values 0 to 3, which correspond to four possible + colors. Convenient work with this field is ensured by the + COLOR(row,column) function, which returns the number of the active color + for a given pixel.
+ Values less than 1000 are reserved as special cases: +
    +
  • 1 - Leaf Catchlight with 16x16 bayer matrix;
  • +
  • 9 - Fuji X-Trans (6x6 matrix)
  • +
  • 3..8 and 10..999 - are unused.
  • +
+
+
char xtrans[6][6];
+
char xtrans_abs[6][6];
+
These matrices contains Fuji X-Trans row/col to color mapping. First + one is relative to visible area, while second is positioned relative to + sensor edges.
+
char cdesc[5];
+
Description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG).
+
unsigned xmplen; char *xmpdata;
+
XMP packed data length and pointer to extracted XMP packet.
+
+

+

Structure libraw_image_sizes_t: Image Dimensions

+

Structure libraw_image_sizes_t is a collection of all file data that + describe the size of the image.

+

Data fields:

+
+
ushort raw_height, raw_width;
+
Full size of RAW image (including the frame) in pixels.
+
ushort height, width;
+
Size of visible ("meaningful") part of the image (without the frame).
+
ushort top_margin, left_margin;
+
Coordinates of the top left corner of the frame (the second corner is + calculated from the full size of the image and size of its visible + part).
+
ushort iheight, iwidth;
+
Size of the output image (may differ from height/width for cameras + that require image rotation or have non-square pixels).
+
unsigned raw_pitch;
+
Full size of raw data row in bytes .
+
double pixel_aspect;
+
Pixel width/height ratio. If it is not unity, scaling of the image + along one of the axes is required during output.
+
int flip;
+
Image orientation (0 if does not require rotation; 3 if requires + 180-deg rotation; 5 if 90 deg counterclockwise, 6 if 90 deg clockwise).
+
libraw_raw_inset_crop_t raw_inset_crops[2];
+
(libraw_raw_inset_crop_t: ushort cleft, ctop, + cwidth, cheight;) +
    +
  • item at[0] contains standard crop data parsed from camera metadata + (DNG: DefaultCrop* tags, other formats: vendor specific tags)
  • +
  • item at [1] is 'user crop', in particular:
    + - set by DNG DefaultUserCrop tag
    + - or set via raw aspect ratio tags (e.g. 16:9 aspect on Fujifilm + cameras) raw_inset_crops[1] is filled only if aspect ratio tags + provides different aspect ratio compared to raw_inset_crops[0].
  • +
+
+
+

+

Structure libraw_colordata_t: Color Information

+

Structure libraw_colordata_t unites all color data, both retrieved from + the RAW file and calculated on the basis of the image itself. For + different cameras, there are different ways of color handling.

+

Data fields:

+
+
ushort curve[0x10000];
+
Camera tone curve. May be read from file as is, or calculated, + depending on file format;
+
unsigned black;
+
Black level. Depending on the camera, it may be zero (this means that + black has been subtracted at the unpacking stage or by the camera + itself), calculated at the unpacking stage, read from the RAW file, or + hardcoded.
+
unsigned cblack[4102];
+
Per-channel black level correction. First 4 values are per-channel + correction, next two are black level pattern block size, than + cblack[4]*cblack[5] correction values (for indexes + [6....6+cblack[4]*cblack[5]).
+
unsigned data_maximum;
+
Maximum pixel value in current file. Calculated at raw2image or + dcraw_process() calls.
+
unsigned maximum;
+
Maximum pixel value. Calculated from the data for most cameras, + hardcoded for others. This value may be changed on postprocessing stage + (when black subtraction performed) and by automated maximum adjustment + (this adjustment performed if params.adjust_maximum_thr + is set to nonzero).
+
unsigned linear_max[4];
+
Per-channel linear data maximum read from file metadata. If RAW file + does not contains this data, linear_max[] is set to zero. Black value is + not subtracted
+
float fmaximum;
+
Maximum pixel value in real image for floating data files.
+
float fnorm;
+
Normalization coefficient used while converting floating point raw + data to integer.
+
ushort white[8][8];
+
Block of white pixels extracted from files CIFF/CRW. Not extracted for + other formats. Used to calculate white balance coefficients.
+
float cam_xyz[4][3];
+
Camera RGB - XYZ conversion matrix. This matrix is constant (different + for different models). Last row is zero for RGB cameras and non-zero for + different color models (CMYG and so on).
+
float cam_mul[4];
+
White balance coefficients (as shot). Either read from file or + calculated.
+
float pre_mul[4];
+
White balance coefficients for daylight (daylight balance). Either + read from file, or calculated on the basis of file data, or taken from + hardcoded constants.
+
float cmatrix[3][4];
+
Camera color data read from RAW file (if any)
+
float rgb_cam[3][4];
+
Camera to sRGB conversion matrix
+
float ccm[3][4];
+
Camera color correction matrix read from file metadata (uniform + matrix if no such data in file)
+
ph1_t phase_one_data;
+
Color data block that is read for Phase One cameras.
+
float flash_used;
+
float canon_ev;
+
Fields used for white balance calculations (for some P&S Canon + cameras).
+
char model2[64];
+
Firmware revision (for some cameras).
+
char UniqueCameraModel[64],LocalizedCameraModel[64];
+
Values from DNG tags with same names.
+
void *profile;
+
Pointer to the retrieved ICC profile (if it is present in the RAW + file).
+
unsigned profile_length;
+
Length of ICC profile in bytes.
+
unsigned black_stat[8];
+
Black level statistics if calculated from masked area: 4 sum of pixel + values, than 4 pixel counts (per channel).
+
libraw_dng_color_t dng_color[2];
+
Color data read from DNG: illuminant, calibration matrix and color + matrix for two light sources. (see DNG specs for details).
+
libraw_dng_levels_t dng_levels
+
DNG black/white levels, analog balance, WB for active IFD. See DNG + specs for details.
+
int WB_Coeffs[256][4]
+
Index: EXIF color source value, [i][0..3] WB Coeffs
+
float WBCT_Coeffs[64][5]
+
Color temperature in [i][0], WB coeffs in [i][1..4]
+
int as_shot_wb_applied
+
Set to 1 if WB already applied in camera (multishot modes; small raw)
+
libraw_P1_color_t P1_color[2]
+
Phase-one specific color data
+
unsigned raw_bps
+
RAW bits per pixel (PhaseOne: Raw format used)
+
int ExifColorSpace
+
EXIF color space parsed from EXIF tags: LIBRAW_COLORSPACE_Unknown, + LIBRAW_COLORSPACE_sRGB, or LIBRAW_COLORSPACE_Adobe
+
+

+

Structure libraw_imgother_t: Other Parameters of the Image

+

Data fields:

+
+
float iso_speed;
+
ISO sensitivity.
+
float shutter;
+
Shutter speed.
+
float aperture;
+
Aperture.
+
float focal_len;
+
Focal length.
+
time_t timestamp;
+
Date of shooting.
+
unsigned shot_order;
+
Serial number of image.
+
unsigned gpsdata[32];
+
GPS data (unparsed block, to write to output as is).
+
libraw_gps_info_t parsed_gps;
+
Parsed GPS-data: longitude/latitude/altitude and time stamp.
+
char desc[512];
+
Image description.
+
char artist[64];
+
Author of image.
+
float FlashEC;
+
Flash exposure compensation.
+
+

+

Structure libraw_rawdata_t: holds unpacked RAW data

+

Structure libraw_rawdata_t holds:

+
    +
  • RAW-data from sensor, read and unpacked by the + unpack() call.
  • +
  • "backup" copy of color and over data modified during postprocessing. + When postprocessing calls repeats, the needed data is restored from this + backup.
  • +
+

Data fields:

+
+
void *raw_alloc;
+
Buffer allocated to hold RAW-data
+
unsigned short *raw_image;
+
Pointer to buffer with one-component (bayer) data.
+
unsigned short (*color3_image)[3];
+
Pointer to 3-component pixel array.
+
unsigned short (*color4_image)[4];
+
Pointer to buffer with 4-component pixel data data
+
float *float_image;
+
Pointer to buffer with one-component (bayer) data in FP-format.
+
float (*float3_image)[3];
+
Pointer to 3-component FP pixel array.
+
float (*float4_image)[4];
+
Pointer to buffer with 4-component pixel data data
+
+

After call to unpack() only one of + these fields is non-NULL.

+

All other fields of this structure are for internal use and should not be + touched by user code.

+

Structure libraw_thumbnail_t: Description of Thumbnail

+

Structure libraw_thumbnail_t describes all parameters associated with the + preview saved in the RAW file.

+

Data fields:

+
+
LibRaw_thumbnail_formats tformat;
+
Thumbnail data format. One of the values among enum + LibRaw_thumbnail_formats .
+
ushort twidth, theight;
+
Dimensions of the preview image in pixels.
+
unsigned tlength;
+
Thumbnail length in bytes.
+
int tcolors;
+
Number of colors in the preview.
+
char *thumb;
+
Pointer to thumbmail, extracted from the data file.
+
+

+

Structure libraw_thumbnail_list_t: thumbnails present in the RAW file

+

libraw_thumbnail_list_t holds list of thumbnails (previews) present in + RAW file.

+

Data fields:

+
+
int thumbcount;
+
Thumbnail count
+
libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT];
+
Array of libraw_thumbnail_item_t, one for each thumbnail: +
+
enum LibRaw_internal_thumbnail_formats tformat
+
Internal thumbnail format (this field stores thumbnail decoder + needed for thumbnail extraction)
+
ushort twidth, theight
+
Thumbnail image size. Note: these fields may be zero (so, image + size is unknown at parse phase)
+
ushort tflip
+
Thumbnail image rotation, it may differ from main image rotation. + This field may be set to 0xffff, this means 'rotation is not known'
+
unsigned tlength;
+
Thumbnail on-disk data size
+
unsigned tmisc;
+
Bits per pixel and color count: (color << 5) | bits
+
INT64 toffset;
+
Thumbnail data offset in file
+
+
+
+

+

Structure libraw_lensinfo_t: parsed lens data

+

The following parameters are extracted from Makernotes and EXIF, to help + identify which lens was mounted on the camera. If the value is missing in + Makernotes or EXIF, the parameter is set to zero with some exceptions + noted below. In some cases the values for the fields like CameraFormat and + CameraMount are set based on the camera model and/or camera ID.

+

libraw_makernotes_lens_t structure:

+
    +
  • LensID (if not -1) and CamID + (camera id, if non-zero) values are compatible with those used in + exiftool, like |0x0010 CanonModelID| and |22 LensType| see http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html + or 0x0207/CameraType and 0x0201/LensType (see http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Olympus.html + )
  • +
  • Lens string, if not empty, contains the lens name + present in Makernotes.
  • +
  • LensFormat and CameraFormat + currently provide one of value from enum LibRaw_camera_formats;
  • +
  • In a similar manner, values for LensMount and CameraMount + follow the enum LibRaw_camera_mounts;
  • +
  • In some cases, the Makernotes for MF cameras contain either an id for + the body, or a string containing the name of the body. The name is + copied to body field, while the id is converted to the + appropriate body name and also copied to 'body' field. In other cases + the 'body' field is empty.
  • +
  • FocalType is set based on Makernotes tag, if present. + The values are:
  • +
      +
    • -1 Undefined
    • +
    • 0 Unknown;
    • +
    • 1 Fixed focal length lens
    • +
    • 2 Zoom lens
    • +
    +
  • LensFeatures_pre - lens name prefix and LensFeatures_suf + - lens name suffix: (if not empty) some cameras record alphabet soup + that characterizes the lens in separate Makernote tags (see, for + example, 0xb02a LensSpec at http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Sony.html + ), and for some lenses those acronyms can be derived from the 'Lens' + field itself (see processCanonCameraInfo). Those can also help better + lens identification.
  • +
  • MinFocal and MaxFocal , if + non-zero, contain the minimum and maximum focal lengths for the lens + mounted on the camera.
  • +
  • MaxAp4MinFocal, MaxAp4MaxFocal, MinAp4MinFocal, + MinAp4MaxFocal - if non-zero, contain maximum aperture + available at minimal focal length, maximum aperture available at maximum + focal length, minimum aperture available at minimal focal length, + minimum aperture available at maximum focal length, respectively.
  • +
  • MaxAp and MinAp, if non-zero, + contain the maximum aperture for the lens (usually it is the maximum + aperture for minimal focal length) and the minimum aperture across the + focal length range. For zooms with variable maximum aperture this is + usually the minimum aperture for the maximum focal length.
  • +
  • CurFocal, if non-zero, is current focal length - that + is the focal length used to take the shot.
  • +
  • CurAp, if non-zero, is current aperture.
  • +
  • MaxAp4CurFocal and MinAp4CurFocal, + if non-zero, contain the minimum and maximum apertures for the current + focal length.
  • +
  • LensFStops - if non-zero, contains the number of + aperture "clicks" or the number of f-stops, depending on the model of + the camera.
  • +
  • TeleconverterID, AdapterID, AttachmentID, + if non-zero, are the numbers extracted from Makernotes to identify lens + accessories used to take the shot.
  • +
  • Teleconverter, Adapter, Attachment, + if non-empty, are the strings containing the names of the accessories as + they appear in Makernotes, or for some cameras, decoded from a numeric + field in Makernotes.
  • +
  • FocalUnits - an auxiliary field, should not be needed + most of the cases. See Canon.pm module in exiftool for more information + on this value.
  • +
  • FocalLengthIn35mmFormat, if non-zero: for some reason + certain Samsung cameras record this value in Makernotes instead of the + EXIF proper. Also used for Sigma cameras.
  • +
+

libraw_nikonlens_t structure:

+

Contains additional parameters needed to identify the lens on a Nikon + camera using a table - please see Nikon LensID Values at http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html

+

libraw_dnglens_t structure:

+

Contains minimum focal length, maximum focal length, maximum aperture + available at minimal focal length, and maximum aperture available at + maximum focal length, extracted from EXIF field of a DNG raw file.

+

libraw_lensinfo_t structure:

+

Contains all the structures described above, plus parameters extracted + directly from EXIF fields:

+
    +
  • MinFocal and MaxFocal , if + non-zero, contain the minimum and maximum focal lengths for the lens + mounted on the camera.
  • +
  • MaxAp4MinFocal, MaxAp4MaxFocal - if + non-zero, contain maximum aperture available at minimal focal length and + maximum aperture available at maximum focal length
  • +
  • LensMake, if not empty, contains a string with the + lens manufacturer name.
  • +
  • Lens, if not empty, contains the lens name as + recorded in EXIF
  • +
  • FocalLengthIn35mmFormat - if non-zero, same as + FocalLengthIn35mmFilm in EXIF standard, tag 0xa405.
  • +
  • EXIF_MaxAp - if non-zero, contains the value derived + from EXIF tag 0x9205.
  • +
+

+

Structure libraw_raw_unpack_params_t: RAW decoding options and flags

+

Structure libraw_raw_unpack_params_t contains fields/flags that affects + RAWdata and metadata decoding

+
+
int options
+
Processing options used on unpack() phase for specific image formats, + see below for possible values: + LibRaw_processing_options
+
unsigned shot_select;
+
dcraw keys: -s
+ Selection of image number for processing (for formats that contain + several RAW images in one file).
+
int specials
+
Special processing mode (e.g. omit YCC to RGB conversion), see below + for possible values. + LibRaw_rawspecial_t
+
int max_raw_memory_mb
+
Stop processing if raw buffer size grows larger than that value (in + megabytes). Default is LIBRAW_MAX_ALLOC_MB_DEFAULT (2048Mb)
+
int sony_arw2_posterization_thr
+
If LIBRAW_PROCESSING_SONYARW2_DELTATOVALUE used for + raw_processing_options, sets the level to suppress posterization display + in shadows.
+
float coolscan_nef_gamma;
+
Gamma value for Coolscan NEF decoding (no way to get if from file, it + should be set by calling application).
+
char p4shot_order[5];
+
Shot order for Pentax 4shot files. Default is "3102".
+
+

+

Structure libraw_output_params_t: management of dcraw-style + postprocessing

+

Structure libraw_output_params_t (imgdata.params) is used for management + of dcraw-compatible calls dcraw_process(), dcraw_ppm_tiff_writer(), and + dcraw_thumb_writer(). Fields of this structure correspond to command line + keys of dcraw.

+

Data fields:

+
+
unsigned greybox[4];
+
dcraw keys: -A x y w h
+ 4 numbers corresponding to the coordinates (in pixels) of the rectangle + that is used to calculate the white balance. X and Y are coordinates of + the left-top rectangle corner; w and h are the rectangle's width and + height, respectively.
+
unsigned cropbox[4];
+
dcraw keys: none
+ This field sets the image cropping rectangle. Cropbox[0] and cropbox[1] + are the rectangle's top-left corner coordinates, remaining two values + are width and height respectively. All coordinates are applied before + any image rotation.
+
double aber[4];
+
dcraw keys: -C
+ Correction of chromatic aberrations; the only specified values are
+ aber[0], the red multiplier
+ aber[2], the blue multiplier. For some formats, it affects + RAW data reading , since correction of aberrations changes the + output size.
+
double gamm[6];
+
dcraw keys: -g power toe_slope
+ Sets user gamma-curve. Library user should set first two fields of gamm + array:
+ gamm[0] - inverted gamma value)
+ gamm[1] - slope for linear part (so called toe slope). Set to zero for + simple power curve.
+ Remaining 4 values are filled automatically.
+ By default settings for rec. BT.709 are used: power 2.222 (i.e. + gamm[0]=1/2.222) and slope 4.5. For sRGB curve use gamm[0]=1/2.4 and + gamm[1]=12.92, for linear curve set gamm[0]/gamm[1] to 1.0.
+
float user_mul[4];
+
dcraw keys: -r mul0 mul1 mul2 mul3
+ 4 multipliers (r,g,b,g) of the user's white balance.
+
float bright;
+
dcraw keys: -b
+ Brightness (default 1.0).
+
float threshold;
+
dcraw keys: -n
+ Parameter for noise reduction through wavelet denoising.
+
int half_size;
+
dcraw keys: -h
+ Outputs the image in 50% size. For some formats, it affects + RAW data reading .
+
int four_color_rgb;
+
dcraw keys: -f
+ Switches on separate interpolations for two green components.
+
int highlight;
+
dcraw keys: -H
+ 0-9: Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild).
+
int use_auto_wb;
+
dcraw keys: -a
+ Use automatic white balance obtained after averaging over the entire + image.
+
int use_camera_wb;
+
dcraw keys: -w
+ If possible, use the white balance from the camera. +

If camera-recorded WB is not available, dcraw_process() will + fallback to:

+
    +
  • Auto-WB if bit LIBRAW_PROCESSING_CAMERAWB_FALLBACK_TO_DAYLIGHT is + not set in params.raw_processing_options (or for the rare specific + case: no valid WB index was parsed from CRW file)
  • +
  • Daylight-WB if abovementioned bit is not set.
  • +
+
+
int use_camera_matrix;
+
dcraw keys: +M/-M
+
    +
  • 0: do not use embedded color profile
  • +
  • 1 (default): use embedded color profile (if present) for DNG files + (always); for other files only if use_camera_wb is set;
  • +
  • 3: use embedded color data (if present) regardless of white + balance setting.
  • +
+
+
int output_color;
+
dcraw keys: -o
+ [0-8] Output colorspace (raw, sRGB, Adobe, Wide, ProPhoto, XYZ, ACES, + DCI-P3, Rec. 2020).
+
char* output_profile;
+
dcraw keys: -o filename
+ Path to output profile ICC file (used only if LibRaw compiled with LCMS + support)
+
char* camera_profile;
+
dcraw keys: -p file
+ Path to input (camera) profile ICC file (or 'embed' for embedded + profile). Used only if LCMS support compiled in.
+
char* bad_pixels;
+
dcraw keys: -P file
+ Path to file with bad pixels map (in dcraw format: "column row + date-of-pixel-death-in-UNIX-format", one pixel per row).
+
char* dark_frame;
+
dcraw keys: -K file
+ Path to dark frame file (in 16-bit PGM format)
+
int output_bps;
+
dcraw keys: -4
+ 8 bit (default)/16 bit (key -4).
+
int output_tiff;
+
dcraw keys: -T
+ 0/1: output PPM/TIFF.
+
int output_flags;
+
dcraw keys: none
+ Bitfield that allows to set output file options: +
    +
  • LIBRAW_OUTPUT_FLAGS_PPMMETA - write additional + metadata into PPM/PGM output files
  • +
+
+
int user_flip;
+
dcraw keys: -t
+ [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW). Default -1, which + means taking the corresponding value from RAW.
+ For some formats, affects RAW data reading + , e.g., unpacking of thumbnails from Kodak cameras.
+
int user_qual;
+
dcraw keys: -q
+ 0-10: interpolation quality: +
    +
  • 0 - linear interpolation
  • +
  • 1 - VNG interpolation
  • +
  • 2 - PPG interpolation
  • +
  • 3 - AHD interpolation
  • +
  • 4 - DCB interpolation
  • +
  • 11 - DHT interpolation
  • +
  • 12 - Modified AHD interpolation (by Anton Petrusevich)
  • +
+
+
int user_black;
+
dcraw keys: -k
+ User black level.
+
int user_cblack[4];
+
dcraw keys: none
+ Per-channel corrections to user_black.
+
int user_sat;
+
dcraw keys: -S
+ Saturation adjustment.
+
int med_passes;
+
dcraw keys: -m
+ Number of median filter passes.
+
int no_auto_bright;
+
dcraw keys: -W
+ Don't use automatic increase of brightness by histogram.
+
float auto_bright_thr;
+
dcraw keys: none
+ Portion of clipped pixels when auto brightness increase is used. Default + value is 0.01 (1%) for dcraw compatibility. Recommended value for modern + low-noise multimegapixel cameras depends on shooting style. Values in + 0.001-0.00003 range looks reasonable.
+
float adjust_maximum_thr;
+
dcraw keys: none
+ This parameters controls auto-adjusting of maximum value based on + channel_maximum[] data, calculated from real frame data. If calculated + maximum is greater than adjust_maximum_thr*maximum, than maximum is set + to calculated_maximum.
+ Default: 0.75. If you set this value above 0.99999, than default value + will be used. If you set this value below 0.00001, than no maximum + adjustment will be performed.
+ Adjusting maximum should not damage any picture (esp. if you use default + value) and is very useful for correcting channel overflow problems + (magenta clouds on landscape shots, green-blue highlights for indoor + shots).
+
int use_fuji_rotate;
+
dcraw keys: -j
+ Default -1 (use), 0 - don't use rotation for cameras on a Fuji sensor.
+
int green_matching;
+
Turns on fixing of green channels disbalance. dcraw keys: + none
+ Default: 0 (not use), 1 - turns on this postprocessing stage. + green_matching requires additional memory for image data.
+
int dcb_iterations
+
dcraw keys: none
+ Number of DCB correction passes. Default is -1 (no correction). Useful + only for DCB interpolation.
+
int dcb_enhance_fl
+
dcraw keys: none
+ nonzero: DCB interpolation with enhance interpolated colors.
+
int fbdd_noiserd
+
dcraw keys: none
+ Controls FBDD noise reduction before demosaic. +
    +
  • 0 - do not use FBDD noise reduction
  • +
  • 1 - light FBDD reduction
  • +
  • 2 (and more) - full FBDD reduction
  • +
+
+
int exp_correc; float exp_shift,exp_preser;
+
Exposure correction before demosaic.
+
    +
  • exp_correc: positive value turns the feature on (default: off).
  • +
  • exp_shift: exposure shift in linear scale. Usable range from 0.25 + (2-stop darken) to 8.0 (3-stop lighter). Default: 1.0 (no exposure + shift).
  • +
  • exp_preser: preserve highlights when lighten the image. Usable + range from 0.0 (no preservation) to 1.0 (full preservation). 0.0 is + the default value.
  • +
+
+
int use_rawspeed;
+
Turns on using RawSpeed library for data unpacking (only if RawSpeed + support compiled in).
+
int use_dng_sdk;
+
Turns on using Adobe DNG SDK (if compiled with it and dng host is set: +
+
    +
  • 0 - do not use
  • +
  • 1 - use for speciality formats (Float, Linear DNG, deflate + compression, 8 bit)
  • +
  • 2 - use for all DNG files
  • +
+
+
int no_auto_scale;
+
Disables pixel values scaling (call to LibRaw::scale_colors()) in + LibRaw::dcraw_process().
+ This is special use value because white balance is + performed in scale_colors(), so skipping it will result in non-balanced + image.
+ This setting is targeted to use with no_interpolation, or with own + interpolation callback call.
+
int no_interpolation;
+
Disables call to demosaic code in LibRaw::dcraw_process()
+
+

+

Structure libraw_callbacks_t: user-settable callbacks

+
+
data_callback data_cb
+
Called on data error, settable via set_dataerror_handler. See C++ + API for details.
+
progress_callback progress_cb
+
Called on process callback, settable via set_progress_handler. See C++ API for details.
+
exif_parser_callback exif_cb, params: (void *context, int tag, int + type, int len, unsigned int ord, void *ifp)
+
Called by EXIF/TIFF IFD parsers on each processed tag.
+ Parameters: +
    +
  • context: user-specified context, set via set_exifparser_handler()
  • +
  • tag: 16-bit of TIFF/EXIF tag or'ed with +
      +
    • 0 - for EXIF parsing
    • +
    • 0x20000 - for Kodak makernotes parsing
    • +
    • 0x30000 - for Panasonic makernotes parsing
    • +
    • 0x40000 - for EXIF Interop IFD parsing
    • +
    • 0x50000 - for EXIF GPS IFD parsing
    • +
    • (ifdN + 1) << 20) - for TIFF ifdN
    • +
    +
  • +
  • type: tag type (see TIFF/EXIF specs)
  • +
  • len: tag length
  • +
  • ord: byte order: 0x4949 for intel, 0x4d4d for motorola
  • +
  • ifp: pointer to LibRaw_abstract_datastream input stream, + positioned to start of data. There is no need to restore data + position in callback.
  • +
+
+
int pre_identify_cb(void *)
+
Called with this pointer as the only arg before calling to + LibRaw::identify. If this callback return non-zero value, that means + that identify() is not needed and all internal data fields are filled + with values.
+
void post_identify_cb(void *)
+
Called after identify() from open_datastream(). May be used to tune + internal variables after metadata parse.
+
dcraw_process() callbacks
+
These callbacks are called before/after dcraw_process phases, the only + passed parameter is this pointer +
    +
  • pre_subtractblack_cb - called before black subtraction
  • +
  • pre_scalecolors_cb - called before scale_colors() call
  • +
  • pre_preinterpolate_cb - called before interpolaton (demosaic)
  • +
  • interpolate_bayer_cb - if set, called for bayer demosaic + (regardless of params.user_qual value)
  • +
  • interpolate_xtrans_cb - if set, called for X-Trans demosaic
  • +
  • post_interpolate_cb - called after demosaic step. Note: if this + callback is set, standard median_filter() is not called. So, if you + need median filtering you should call it from callback function.
  • +
  • pre_converttorgb_cb - called after convert_to_rgb()
  • +
  • post_converttorgb_cb - called after convert_to_rgb(), so very last + processing step.
  • +
+
+
+

+

Structure libraw_decoder_info_t: RAW decoder name and data format

+

This structure describes RAW format decoder name and data format:

+
+
const char *decoder_name
+
Decoder function name
+
unsigned decoder_flags
+
Decoder data format. See list of + LibRaw_decoder_flags for details.
+
+

+

Structure libraw_processed_image_t - result set for + dcraw_make_mem_image()/dcraw_make_mem_thumb() functions

+

Structure libraw_processed_image_t is produced by call of + dcraw_make_mem_image()/dcraw_make_mem_thumb() and contains in-memory image + of interpolated data or thumbnail.

+

Data fields:

+
+
LibRaw_image_formats type
+
This field records type of data, containing in remaining fields of + structure. +
    +
  • LIBRAW_IMAGE_BITMAP - structure contains RGB + bitmap. All metadata fields (see below) are valid and describes + image data.
  • +
  • LIBRAW_IMAGE_JPEG - structure contain + in-memory image of JPEG file. Only type, data_size and data fields + are valid (and nonzero);
  • +
+
+
ushort height,width
+
Image size (in pixels). Valid only if type==LIBRAW_IMAGE_BITMAP.
+
ushort colors, bits
+
Number of colors components (1 or 3) and color depth in bits (8 or + 16). These fields are valid only if type==LIBRAW_IMAGE_BITMAP.
+
ushort gamma_corrected
+
Is bitmap data gamma-corrected (always 1 for 8-bit data, may be 0 or 1 + for 16-bit). Valid only if type==LIBRAW_IMAGE_BITMAP.
+
unsigned int data_size
+
Size of data field (in bytes). For bitmap image + equal to (height*width*colors * (bits/8)). For JPEG image - exact JPEG + size (i.e. extracted thnumbnail size + JPEG header + EXIF header).
+
unsigned char data[]
+
Data array itself. Should be interpreted as RGB triplets for bitmap + type and as JPEG file for JPEG type.
+
+

+

Input abstraction layer

+

RAW data input (read) in LibRaw implemented by calling methods of object + derived from LibRaw_abstract_datastream abstract + class. Full list of methods is described in + href="API-CXX.html#datastream">C++ API reference.

+

There is two ready to use implementations of datastream objects:

+ +

LibRaw user can create own datastream object derived from + LibRaw_abstract_datastream . For example, such object may + implement reading RAW data directly from camera (by remote interface). + LibRaw can use these objects via + LibRaw::open_datastream() interface.

+

Datastreams can be used either via + LibRaw::open_datastream() call (in this case datastream object + should be created an maintained by user) or via + LibRaw::open_file() and + LibRaw::open_buffer() shortcuts.

+

Only C++ API users may use object-oriented + interface and implement own input interfaces. For C + API users only built-on + libraw_open_file()/libraw_open_buffer() shortcuts are + available.

+

+

Data fields

+

Definition:

+
	class LibRaw_abstract_datastream {...protected: LibRaw_abstract_datastream *substream;}
+
+

Description: Objects derived from + LibRaw_abstract_datastream always contains pointer to secondary data + stream (substream). This substream initialized internally when needed + (really used only for Sony RAW data) and used for temporary switch input + stream to temporary memory buffer allocated internally in LibRaw.

+

Substream usage details described more precisely in + own datastream objects creation guide .

+

+

Constants

+

+

enum LibRaw_errors: Error Codes

+

All functions returning integer numbers must return either errno or one + of the following error codes (see also + error code conventions ).

+

Fatal errors (return of such an error code implies + that file processing has to be terminated, since the state of data + structures is unknown).

+
+
LIBRAW_UNSUFFICIENT_MEMORY
+
Attempt to get memory from the system has failed.
+ All allocated resources will be freed, + recycle() will be called, and the LibRaw object will be brought + to the state "right after creation."
+
LIBRAW_DATA_ERROR
+
A fatal error emerged during data unpacking.
+ All allocated resources will be freed, + recycle() will be called, and the LibRaw object will be brought + to the state "right after creation."
+
LIBRAW_IO_ERROR
+
A fatal error emerged during file reading (premature end-of-file + encountered or file is corrupt).
+ All allocated resources will be freed, + recycle() will be called, and the LibRaw object will be brought + to the state "right after creation."
+
LIBRAW_CANCELLED_BY_CALLBACK
+
Processing cancelled due to calling application demand (by returning + nonzero code from progress callback + ).
+ All allocated resources will be freed, + recycle() will be called, and the LibRaw object will be brought + to the state "right after creation."
+
LIBRAW_BAD_CROP
+
The incorrect cropping coordinates are set via params.cropbox[]: the + left-top corner of cropping rectangle is outside the image. The + processing will be cancelled, all allocated resources will be freed, LIBRAW_TOO_BIG
+
Raw data size exceeds data limit.
+ +
+ +

Non-Fatal Errors

+
+
+
LIBRAW_SUCCESS=0
+
No error; function terminated successfully.
+
LIBRAW_UNSPECIFIED_ERROR
+
An unknown error has been encountered. This code should never be + generated.
+
LIBRAW_FILE_UNSUPPORTED
+
Unsupported file format (attempt to open a RAW file with a format + unknown to the program).
+
LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE
+
Attempt to retrieve a RAW image with a number absent in the data + file (only for formats supporting storage of several images in a + file).
+
LIBRAW_OUT_OF_ORDER_CALL
+
API functions have been called in wrong order (e.g., unpack() before + open_file() ) or the previous stage has ended with an error + (e.g., unpack() is called after open_file() has returned an + error).
+
LIBRAW_NO_THUMBNAIL
+
Returned upon an attempt to retrieve a thumbnail from a file + containing no preview.
+
LIBRAW_UNSUPPORTED_THUMBNAIL
+
RAW file contains a preview of unsupported format.
+
LIBRAW_INPUT_CLOSED
+
Input stream is not available for reading.
+
LIBRAW_NOT_IMPLEMENTED
+
Decoder for specific RAW storage/compression format is not + implemented.
+
LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL
+
Attempt to retrieve a non-existent thumbnail by (invalid) index.
+
+

+

enum LibRaw_decoder_flags - RAW data format description

+

Depending of capabilities of given data format, the buffer with RAW data + may have different layouts:

+
+
LIBRAW_DECODER_HASCURVE
+
This flag is set if decoder uses RAW tone curve and curve data may be + modified before call to decoder (i.e. curve values are not read or + calculated within decoder).
+
LIBRAW_DECODER_SONYARW2
+
This flag is set if file format is Sony ARW2.3, so sony_arw2_options + is applicable.
+
LIBRAW_DECODER_TRYRAWSPEED
+
This flag is set if file format is (possibly) supported by RawSpeed + library, so unpack() will try to use it.
+
LIBRAW_DECODER_FIXEDMAXC
+
Do not use automated maximum calculation for this data format.
+
LIBRAW_DECODER_OWNALLOC
+
Decoder allocates data, no need to pass allocated memory to decoder.
+
LIBRAW_DECODER_ADOBECOPYPIXEL
+
Internal flag, special to adobe DNG decoder.
+
LIBRAW_DECODER_LEGACY_WITH_MARGINS
+
Special flag uset for 4-channel (legacy) decoders with black/masked + areas
+
LIBRAW_DECODER_3CHANNEL
+
3-component full-color data (not usual 4-component)
+
+

+

enum LibRaw_progress: Current State of LibRaw Object

+

LibRaw::imgdata.progress_flags contains a bit mask describing all stages + of file processing that have already been performed.

+

File opening and RAW data extraction phase.

+
+
LIBRAW_PROGRESS_START=0
+
Object just created, no processing carried out.
+
LIBRAW_PROGRESS_OPEN
+
File to be processed has been opened.
+
LIBRAW_PROGRESS_IDENTIFY
+
Data identification performed, format recognized, metadata extracted.
+
LIBRAW_PROGRESS_SIZE_ADJUST
+
Data sizes adjusted (for files that require such adjustment, namely, + certain files from Kodak cameras).
+
LIBRAW_PROGRESS_LOAD_RAW
+
RAW data loaded.
+
+

The following flags are set during usage of image processing + that has been taken from dcraw.

+
+
LIBRAW_PROGRESS_RAW2_IMAGE
+
imgdata.image array allocated and filled with data.
+
LIBRAW_PROGRESS_REMOVE_ZEROES
+
Zero values removed for cameras that require such removal (Panasonic + cameras).
+
LIBRAW_PROGRESS_BAD_PIXELS
+
Bad (dead) pixels removed.
+
LIBRAW_PROGRESS_DARK_FRAME
+
Dark frame subtracted from RAW data.
+
LIBRAW_PROGRESS_FOVEON_INTERPOLATE
+
Interpolation for cameras with a Foveon sensor performed.
+
LIBRAW_PROGRESS_SCALE_COLORS
+
White balance performed.
+
LIBRAW_PROGRESS_PRE_INTERPOLATE
+
Image size reduction (for the half_size mode) performed, as well as + copying of 2nd green channel to the 1st one in points where the second + channel is present and the first one is absent.
+
LIBRAW_PROGRESS_INTERPOLATE
+
Interpolation (debayer) performed.
+
LIBRAW_PROGRESS_MIX_GREEN
+
Averaging of green channels performed.
+
LIBRAW_PROGRESS_MEDIAN_FILTER
+
Median filtration performed.
+
LIBRAW_PROGRESS_HIGHLIGHTS
+
Work with highlights performed.
+
LIBRAW_PROGRESS_FUJI_ROTATE
+
For images from Fuji cameras, rotation performed (or + adjust_sizes_info_only() called).
+
LIBRAW_PROGRESS_FLIP
+
Dimensions recalculated for images shot with a rotated camera + (sizes.iwidth/sizes.iheight swapped).
+
LIBRAW_PROGRESS_CONVERT_RGB
+
Conversion into output RGB space performed.
+
LIBRAW_PROGRESS_STRETCH
+
Image dimensions changed for cameras with non-square pixels.
+
LIBRAW_PROGRESS_STAGE17 - LIBRAW_PROGRESS_STAGE27
+
Reserved for possible appearance of other processing stages.
+
+

The following flags are set during loading of thumbnails.

+

LIBRAW_PROGRESS_THUMB_LOAD Thumbnail data have been + loaded (for Kodak cameras, the necessary conversions have also been made). + LIBRAW_PROGRESS_TRESERVED1 - LIBRAW_PROGRESS_TRESERVED3 + Reserved for possible future processing stages.

+

+

enum LibRaw_whitebalance_code - names for standard light sources

+

LIBRAW_WBI_lightsource_name, where name and value are standard EXIF light + sources.

+

enum LibRaw_camera_mounts - codes for camera mounts

+

Constant name (e.g. LIBRAW_MOUNT_Leica_SL) speaks for itself

+

enum LibRaw_runtime_capabilities - libraw capabilities set at build

+
    +
  • LIBRAW_CAPS_RAWSPEED - compiled with RawSpeed
  • +
  • LIBRAW_CAPS_DNGSDK - compiled with Adobe DNG SDK
  • +
  • LIBRAW_CAPS_GPRSDK - compiled w/ GoPro GPR SDK
  • +
  • LIBRAW_CAPS_UNICODEPATHS - compiled with Windows + unicode (wchar_t*) filenames support
  • +
+

+

enum LibRaw_thumbnail_formats: Thumbnail Data Formats

+

Thumbnail data format is written in the imgdata.thumbnail.tformat data + field.
+ Presently LibRaw knows about four thumbnail formats, among which two are + unpacked:

+
+
LIBRAW_THUMBNAIL_UNKNOWN
+
Format unknown or thumbnail not yet read.
+
LIBRAW_THUMBNAIL_JPEG
+
The thumbnail buffer contains a JPEG file (read from the RAW file "as + is," without any manipulations performed on it).
+
LIBRAW_THUMBNAIL_BITMAP
+
The thumbnail buffer contains the gamma-adjusted RGB bitmap (for Kodak + cameras, the gamma correction is performed with allowance for maximum + values and the white balance is set in accordance with the camera + settings).
+ In this format, each pixel of the image is represented by a 8-bit RGB + triplet.
+
LIBRAW_THUMBNAIL_BITMAP16
+
The thumbnail buffer contains the gamma-adjusted 16-bit RGB bitmap. To + get this format instead of LIBRAW_THUMBNAIL_BITMAP you + need to set LIBRAW_PROCESSING_USE_PPM16_THUMBS in + processing options.
+
LIBRAW_THUMBNAIL_LAYER
+
Data format is presently recognized upon opening of RAW file but not + supported: not unpacked into LibRaw::unpack_thumb.
+
LIBRAW_THUMBNAIL_ROLLEI
+
Data format is presently recognized upon opening of RAW file but not + supported: not unpacked into LibRaw::unpack_thumb.
+
LIBRAW_THUMBNAIL_H265
+
The thumbnail buffer contains a H.265 data frame (read from RAW file + as is, no manipulations performed on it).
+
+

+

Nonstandard Situations (Warnings) during RAW Data Processing

+

Some suspicious situations emerging during image processing are not fatal + but may affect the result of data retrieval or postprocessing. Such states + are indicated by setting a bit in the imgdata.process_warnings field.

+
+
LIBRAW_WARN_BAD_CAMERA_WB
+
Postprocessing must use white balance of the camera but this balance + is not suitable for use.
+
LIBRAW_WARN_NO_METADATA
+
Only for cameras where the metadata are taken from an external JPEG + file: metadata extraction has failed.
+
LIBRAW_WARN_NO_JPEGLIB
+
Only for P&S Kodak cameras: data in JPEG format. At the same time, + open_file() will return LIBRAW_FILE_UNSUPPORTED.
+
LIBRAW_WARN_NO_EMBEDDED_PROFILE
+
(only if LCMS support compiled in). Caller set embedded input profile + use, but no such profile exists in RAW.
+
LIBRAW_WARN_NO_INPUT_PROFILE
+
(only if LCMS support compiled in). Error when opening input profile + ICC file.
+
LIBRAW_WARN_BAD_OUTPUT_PROFILE
+
(only if LCMS support compiled in). Error when opening output profile + ICC file.
+
LIBRAW_WARN_NO_BADPIXELMAP
+
Error when opening bad pixels map file.
+
LIBRAW_WARN_BAD_DARKFRAME_FILE
+
Error when opening dark frame file.
+
LIBRAW_WARN_BAD_DARKFRAME_DIM
+
Dark frame file either differs in dimensions from RAW-file processed, + or have wrong format. Dark frame should be in 16-bit PGM format (one can + generate it using simple_dcraw -4 -D).
+
LIBRAW_WARN_RAWSPEED_PROBLEM
+
Problems detected in RawSpeed decompressor. The image data processed + by LibRaw own decoder.
+
LIBRAW_WARN_RAWSPEED_UNSUPPORTED
+
This file not supported by RawSpeed (although compatible decoder + exists).
+
LIBRAW_WARN_RAWSPEED_PROCESSED
+
Not warning, but information. The file was decoded by RawSpeed.
+
LIBRAW_WARN_FALLBACK_TO_AHD
+
Incorrect/unsupported user_qual was set, AHD demosaic used instead.
+
LIBRAW_WARN_PARSEFUJI_PROCESSED
+
Not really a warning, but flag that fuji parser was used.
+
LIBRAW_DNGSDK_PROCESSED
+
Not really a warning: image was decoded by DNG SDK
+
LIBRAW_DNG_IMAGES_REORDERED
+
DNG sub0images was reordered
+
LIBRAW_DNG_STAGE2_APPLIED
+
DNG Stage2 conversion was performed
+
LIBRAW_DNG_STAGE3_APPLIED
+
DNG Stage3 conversion was performed
+
+
+
+

+

enum LibRaw_image_formats - possible types of data, contains in + libraw_processed_image_t structure

+

type field of libraw_processed_image_t structure may + have one of these values:

+
+
LIBRAW_IMAGE_BITMAP
+
The structure contains RGB-bitmap, metadata described in other fields + of libraw_processed_image_t.
+
LIBRAW_IMAGE_JPEG
+
libraw_processed_image_t structure contains JPEG image (in memory). + Only data_size field is meaningful.
+
+

+

enum enum LibRaw_processing_options - bit that affects RAW data + extraction

+ These flags could be OR'ed with imgdata.params.raw_processing_options: +

Pentax 4-shot options:

+
    +
  • LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES - merge all frames for + Pentax 4-shot files
  • +
+

Floating point DNG files:

+
    +
  • LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT - convert FP data to + 16-bit integer
  • +
+

Sony ARQ Files:

+
    +
  • LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP - do not perform Sony + ARQ channel swap to RGBG channel format, but use RGGB original channel + order
  • +
+

DNG processing flags:

+
    +
  • LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT - skip DNG + illuminant check when parsing DNG color data (use for compatibility w/ + older LibRaw versions).
  • +
  • LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY - do not copy data extracted + by Adobe DNG SDK into separate buffer, but use DNG SDK buffer as is.
  • +
  • LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED - if set, LibRaw will add + Enhanced DNG frame (NewSubfileType == 16) to the list of available + frames.
  • +
  • LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS - if set, LibRaw will add + previews (NewSubfileType == 1) to the frames list.
  • +
  • LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE- By default, DNG + frames are not reordered and are available in same order as in DNG  + (LibRaw traverses IFD/Sub-IFD trees in deep-first order).This bit will + prioritize the largest image
  • +
  • LIBRAW_RAWOPTIONS_DNG_STAGE2 - request DNG Stage2 + processing (by DNG SDK)
  • +
  • LIBRAW_RAWOPTIONS_DNG_STAGE3 - request DNG Stage3 + processing
  • +
  • LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE - by default, + if image size parsed by DNG SDK does not match image dimensions parsed + by LibRaw, processing will stop with LIBRAW_DATA_ERROR code. This flags + allows size change in LibRaw::unpack() stage.
  • +
  • LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST - by default, + for DNG images with different per-channel maximums WB adjustment + procedure is performed. This flag disables such adjustment.
  • +
+ Other flags +
    +
  • LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS - disable + auto-rotation for Kodak PPM bitmaps
  • +
  • LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS - enable 16-bit PPM + thumbnails
  • +
  • LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS - by default, + LibRaw assigns bayer pattern for Monochrome TIFF files (e.g. images from + Kodak 760).This does not work as expected if input file is really + monochrome (e.g. scan from Imacon X1 in monochrome mode).This flag will + force monochrome mode for TIFF RAWs w/o bayer filter tags (so, it will + break old Kodak processing). It is better to make it settable via user + interaction.
  • +
  • LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB - If set and + when applicable, color.cam_mul[] and color.WB_Coeffs/WBCT_Coeffs will + contain WB settings for a non-standard workflow. Right now only Sony + DSC-F828 is affected: camera-recorded white balance can't be directly + applied to raw data because WB is for RGB, while raw data is RGBE.
  • +
  • LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT - if + use_camera_wb is set, but no camera-recorded white balance present in + metadata, then fallback to daylight WB (default: fallback to + auto-balance).
  • +
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS - + Some cameras (e.g.Ricoh) may record broken thumbnail in file:data offset + plus data size is beyond filecontents. This flag enforces size+offset + checks for files from known vendors (this will result into correct but + smaller thumbnail selected).
  • +
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS - same + is above, but check is performed regardless of vendor (Make tag).
  • +
+
    +
+

+

enum LibRaw_rawspecial_t - special/non standard RAW extraction modes

+ These flags are applied to imgdata.rawparams: +

Sony ARW2.3 processing options: (for more details see + http://www.rawdigger.com/howtouse/sony-craw-arw2-posterization-detection)

+
    +
  • LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY - decode only base pixels, + leave delta pixels as zero;
  • +
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY - decode only delta pixels + with base pixels zeroed;
  • +
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE - decode delta pixels, + do not add base value;
  • +
  • LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE - show possible + posterization areas;
  • +
+

Sigma Quattro decoding flags:

+
    +
  • LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG - disable R/G channels + interpolation
  • +
  • LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF - disable data + interpolation of low-sensitivity (AF or overexposure control) points on + Quattro sensors.
  • +
+

Canon/Nikon small RAW (YCC) decoding flags (do not use both at same + time):

+
    +
  • LIBRAW_RAWSPECIAL_SRAW_NO_RGB - disable YCC to RGB conversion
  • +
  • LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE - disable missing color + values interpolation
  • +
+ [back to Index] + + diff --git a/doc/API-notes.html b/doc/API-notes.html new file mode 100644 index 000000000..68dc72d65 --- /dev/null +++ b/doc/API-notes.html @@ -0,0 +1,305 @@ + + + + + +

LibRaw: General Notes on API[back to Index]

+

LibRaw: General Notes on API

+

Contents

+
    +
  1. LibRaw editions
  2. +
  3. Error Code Conventions and Error Handling
  4. +
  5. Nonstandard Situations That Are Not Errors
  6. +
  7. Input Layer Abstraction
  8. +
  9. Thread Safety
  10. +
  11. The Use of C++
  12. +
  13. Parameters of the LibRaw::imgdata.params + Structure Affecting the Behavior of open_file/unpack/unpack_thumb
  14. +
  15. Memory Usage +
      +
    1. Stack Usage
    2. +
    3. Dynamic Memory Management
    4. +
    5. Dynamic Memory Usage +
        +
      1. Memory Buffer for the RAW Image
      2. +
      3. Memory for the Postprocessed Image
      4. +
      5. Memory for the Decoded Thumbnail
      6. +
      7. Memory for RAW Unpacking
      8. +
      9. Memory for Postprocessing
      10. +
      11. Memory for File Writing
      12. +
      13. Unpacking into memory buffer
      14. +
      +
    6. +
    +
  16. +
  17. Incompatibilities with dcraw +
      +
    1. Automatic maximum search/brightness + adjustment
    2. +
    3. Processing of Thumbnails from Kodak + cameras
    4. +
    +
  18. +
+

+

LibRaw Versions

+

Since version 0.9, there is only one LibRaw variants. Older versions have + three separate editions (normal, -Lite and -Commercial versions).

+

+

Error Code Conventions and Error Handling

+

The following conventions concern the returned errors:

+
    +
  1. All functions that can return an error code have integer type of + return data.
  2. +
  3. If there is no error, the return value is 0 (LIBRAW_SUCCESS).
  4. +
  5. If an error has happened in a system call, the return value is errno + (a positive number), which can be analyzed using strerror() or similar + means.
  6. +
  7. All LibRaw's own error codes are negative; each of these errors + belongs to one of two types: +
    +
    Non-fatal errors
    +
    Non-fatal errors do not forbid execution of other functions in the + processing succession (e.g., unpack_thumb() + can easily return the code corresponding to "preview is absent" but + this does not prevent further call of unpack().
    +
    Fatal errors
    +
    In the case of fatal errors (memory shortage, input data error, + data unpacking failure), the current stage of processing is + terminated and all allocated resources are freed.
    + If an attempt to continue processing is made, all subsequent API + calls will return the LIBRAW_OUT_OF_ORDER_CALL error.
    + At the same time, the LibRaw instance in which a fatal error has + occurred can process the next RAW files in the usual way (by calling + open_file() (or other input + methods), then unpack(), etc.).
    +
    +
  8. +
  9. The macro LIBRAW_FATAL_ERROR(error code) checks if an error is fatal + or not.
  10. +
  11. The error codes are listed and + deciphered here.
  12. +
+

+

Nonstandard Situations That Are Not Errors

+

If the program has encountered a nonstandard situation that does not + prevent retrieval of some data from a file, it sends a signal by setting + the corresponding bit in imgdata.process_warnings. + The possible types of warnings are listed + and deciphered here.

+

+

Input Layer Abstraction

+

LibRaw uses objects derived from LibRaw_abstract_datastream + for data input. Semantics of these objects is similar to 'file with + arbitrary seek' object: both read and seek operations are used.

+

Some RAW formats requires temporary switch to another data stream created + on top on memory buffer for metadata read. Methods for doing so are + implemented in base class LibRaw_abstract_datastream + by internal data field substream. Look into source code + of LibRaw_file_datastream + class in libraw/libraw_datastream.h file for more + details.
+ When implementing own datastream classes, you need to take substream + into account and pass control to methods of this field if it is active + (not NULL).

+

If datastream implementation knows name of input file, it should provide + fname() call. This name will be used in error + callbacks and in guessing name of JPEG file with metadata (for RAW + files with external metadata).

+

For external metadata support input class should implement subfile_open()/subfile_close() + methods. âîçâðàøàþò êîä îøèáêè.
+ Sample of these methods implementation may be found in LibRaw_file_datastream + class (look into libraw/libraw_datastream.h file for + details).

+

+

Thread safety

+

Thread safety is ensured if a LibRaw object is created and used within + one thread. At the same time, the number of threads (each with its own + LibRaw object) is not limited in any way (except by memory requirements).

+

If a LibRaw object is created in one execution thread and used in + another, external synchronization is necessary.

+

There is two libraries under Unix environment (Linux/FreeBSD/MacOS): + libraw_r.a (thread-safe) and libraw.a (single-threaded, slightly faster).

+

Thread-safe library version stores intermediate unpacker data into LibRaw + class data. So, several copies of LibRaw, working in parallel, is + possible.

+

Not thread-safe library uses global variable for intermediate data store + which is faster but not reenterant. This non-thread-safe library still may + be used in multi-threaded apps, but only if exactly one LibRaw class copy + exists in program.

+

Windows version is similar to multi-threaded Unix one.

+

+

The Use of C++

+

Exception situations within LibRaw are handled using the C++ exception + mechanism. All exceptions are caught inside the library functions and + should not penetrate outside.

+

Memory is allocated/freed using functions malloc(calloc)/free rather than + new/delete.

+

If C API is used, references to C++ calls new/delete still remain, and so + linking with libstdc++(Unix)/....(Windows) is necessary.

+

+

Parameters of the LibRaw::imgdata.params Structure Affecting the + Behavior of open_file/unpack/unpack_thumb

+

Most data fields of structure LibRaw::imgdata.params affect only data + postprocessing, but there are some exceptions, which have been + inherited by the current version of LibRaw from/ dcraw source texts (these + dependences will be gradually removed).

+
+
imgdata.params.use_camera_matrix and + imgdata.params.use_camera_wb
+
These fields affect loading of RAW data for cameras with a color + matrix.
+ Attention! If parameter imgdata.params.use_camera_matrix + is not set by the user, it is copied from imgdata.params.use_camera_wb + at the stage of file opening.
+
imgdata.params.user_flip
+
If this parameter is greater than or equal to zero, assignment imgdata.sizes.flip + = imgdata.params.user_flip is performed at the open_file() + stage.
+
imgdata.params.shot_select
+
This parameter makes it possible to select the number of the extracted + image for data formats in which storage of several RAW images in one + data file is possible.
+
imgdata.params.half_size
+
Affects RAW data loading for Phase One and Sinar backs. Also, it this + parameter is set then image bitmap will be reduced by half in each + dimension. In later case, all 4 components of bitmap will be filled + during data extraction phase.
+
imgdata.params.threshold, imgdata.params.aber
+
If these parameters used, then half-sized bitmap will be used for data + unpacking. See above for details.
+
imgdata.params.use_camera_wb
+
Affects loading of white balance matrix for Leaf backs.
+
+

+

Memory Usage

+

+

Stack Usage

+

An instance of the LibRaw class has its own size about 800 Kb; + if constructions like LibRaw imageProcessor; are used, this + memory is stack-allocated.

+

Methods of class LibRaw (and C API calls) may allocate up to 130-140 Kb + of data on the stack (to place auto variables) during their work.

+

Thus, the work of one LibRaw instance may require about 1MB + of stack memory. This is not a problem for most contemporary + architectures. However, when working in a multithreaded environment, one + should not forget to allocate a sufficient amount of memory for the thread + stack.

+

In the case of dynamic allocation (LibRaw *iProcessor = new LibRaw;), + the requirements to stack memory will decrease by ~800 Kb, which is the + size of a class instance). If C API is used, the + LibRaw instance is allocated dynamically.

+

+

Dynamic Memory Management

+

LibRaw keeps record of all allocated dynamic memory blocks; in the case + of an exceptional situation (fatal error), they are all freed. The code + for keeping this record is fairly primitive and not designed to consider + allocation of many blocks (in the normal situation, allocation takes place + from 2 to 6 times during file processing); this fact should be taken into + account by developers trying to add new methods to LibRaw.

+

+

Dynamic Memory Usage

+

LibRaw uses dynamic memory

+
    +
  • for the decoded image;
  • +
  • for the decoded thumbnail;
  • +
  • for the postprocessed image;
  • +
  • for the ICC profile retrieved from the RAW file (if available);
  • +
  • for temporary data at the stage of RAW file unpacking;
  • +
  • for temporary data at the stage of postprocessing and result output;
  • +
  • for reading of the RAW source file (only under Win32).
  • +
+

+

Memory buffer for the RAW image

+

Decoded RAW data are stored:

+
    +
  • one 16-bit value per pixel for "bayer" images. The masked pixels + (black or dark or masked frame) are stored with image data.
  • +
  • Free or four 16-bit values for full-color images (Foveon, Linear DNG, + Canon sRAW etc.).
  • +
  • one,three, or four 32-bit floating point values per pixel for + floating-point data.
  • +
+

The buffer for RAW data is allocated by unpack() + call and freed upon calling recycle().

+

+

Memory for the Postprocessed Image

+

On postprocessing stage each pixel contains four 16-bit values, one for + each possible color channel (some sensors are actually 4-color).

+

The buffer for the decoded image is allocated upon calling raw2image() + or dcraw_process()

+

The buffer freed upon calling recycle() + or free_image() calls.

+

+

Memory for the Decoded Thumbnail

+

Memory for the thumbmail is allocated upon calling unpack_thumb() + and freed upon calling recycle(). The + size of the allocated buffer is precisely adjusted to the thumbnail size, + i.e., up to several Mb.

+

+

+

Memory for RAW Unpacking

+

Memory for temporary buffer needed during RAW data unpacking may be + allocated during the work of unpack() + and freed before completion of this function. The sizes of the allocated + buffers are small, up to tens of Kb.

+

+

Memory for Postprocessing

+

During image postprocessing (inherited from dcraw), memory for the + histogram (128 Kb) is allocated. This memory is allocated upon calling dcraw_process() and freed upon + calling recycle().

+

In addition, during the work of dcraw_process() + and during the usage of some available possibilities, like

+
    +
  • rotation of images from FUJI cameras;
  • +
  • correction of chromatic aberrations;
  • +
  • image size changes (including correction of non-square pixels);
  • +
  • highlight recovery;
  • +
+

a temporary buffer with the size equal to the size of the resultant image + (6-8 bytes per pixel for various processing stages) will be allocated. As + soon as the intermediate substage of processing is completed, the buffer + with the previous copy of the image will be freed.
+ If postprocessing is not used, then temporary buffers are not allocated.

+

+

Memory for File Writing

+

Upon calling dcraw_ppm_tiff_writer(), + memory for a single row of the output image is allocated. The allocated + memory is freed before the end of this call.

+

+

Unpacking into memory buffer

+

Functions dcraw_make_mem_image() + dcraw_make_mem_thumb() + (and complementary calls in C-API) allocates memory for entire output + datasets (full RGB bitmap and thumbnail, respectively).To free allocated + memory use dcraw_clear_mem() + function.

+

+

Incompatibilities with dcraw

+

+

Automatic maximum search/brightness adjustment

+

Many camera formats really use less data range, than possible by format + nature (bit count). If data maximum estimated incorrectly (too low) this + may resuls in colored highlights ('pink clouds') because of data cut at + wrong level.

+

To prevent this, LibRaw uses real data maximum from current file if this + maximum is larger than format maximum multiplied by + imdata.params.adjust_maximum_thr value (default is 0.75).

+

To turn off this feature (and repeat dcraw.c pink clouds) set + imdata.params.adjust_maximum_thr to 0.0

+

+

Processing of Thumbnails from Kodak cameras

+

In some Kodak cameras, the preview (thumbnail) is stored in the form of + uncorrected image. During its extraction using dcraw -e, + the white balance, color conversion, and other settings are the same as + those used for extraction of the main RAW data (including defect removal + and dark frame subtraction, which is erroneous, since the image size is + different).
+ In LibRaw::unpack_thumb() calls, the white balance taken from the camera + ("as shot") is used and no settings from imgdata.params are considered.

+

For all other cameras, thumbnails are extracted "as is," without any + color conversions, both in dcraw and in LibRaw.

+

[back to Index]

+ + diff --git a/doc/API-overview.html b/doc/API-overview.html new file mode 100644 index 000000000..a29014aa9 --- /dev/null +++ b/doc/API-overview.html @@ -0,0 +1,66 @@ + + + + Overview of LibRaw API (C++) + + + + [back to Index] +

Overview of LibRaw API (C++)

+

General Remarks

+
    +
  1. The entire processing is carried out by an instance of the LibRaw class, which is an image processor.
  2. +
  3. One image processor can simultaneously process only one data source file, but consecutive processing of any number of files +is possible.
  4. +
  5. There may be several simultaneously working image processors in a software program (e.g., in different threads), although one +should remember that each image processor may require much memory.
  6. +
  7. Reading of source data from the RAW file requires virtually no customization (see API Notes for exceptions to this rule).
  8. +
  9. All data extracted from the RAW file are accessible through data fields of the image processor (LibRaw class instance).
  10. +
  11. Although LibRaw is not intended for RAW data postprocessing, the library includes calls that enable complete +emulation of the dcraw utility. +
  12. All customization for the processing is performed via data fields of the LibRaw class.
  13. +
+ +

Brief Demonstration

+

+ The example below contains no error processing for the sake of brevity. +

+
+#include "libraw/libraw.h"
+int process_image(char *file)
+{
+        // Let us create an image processor
+        LibRaw iProcessor;
+
+        // Open the file and read the metadata
+        iProcessor.open_file(file);
+
+        // The metadata are accessible through data fields of the class
+        printf("Image size: %d x %d\n",iProcessor.imgdata.sizes.width,iProcessor.imgdata.sizes.height);
+
+        // Let us unpack the image
+        iProcessor.unpack();
+
+        // Convert from imgdata.rawdata to imgdata.image:
+        iProcessor.raw2image();
+
+        // And let us print its dump; the data are accessible through data fields of the class
+        for(i = 0;i lt; iProcessor.imgdata.sizes.iwidth *  iProcessor.imgdata.sizes.iheight; i++)
+           printf("i=%d R=%d G=%d B=%d G2=%d\n",
+                        i,
+                        iProcessor.imgdata.image[i][0],
+                        iProcessor.imgdata.image[i][1],
+                        iProcessor.imgdata.image[i][2],
+                        iProcessor.imgdata.image[i][3]
+                );
+
+        // Finally, let us free the image processor for work with the next image
+        iProcessor.recycle();
+}
+
+ + + [back to Index] + + diff --git a/doc/Install-LibRaw.html b/doc/Install-LibRaw.html new file mode 100644 index 000000000..a65e812be --- /dev/null +++ b/doc/Install-LibRaw.html @@ -0,0 +1,124 @@ + + + + + LibRaw Compilation and Installation + + [back to Index] +

LibRaw Compilation and Installation

+

LibRaw is distributed in the form of source codes. For further use, they + should be compiled (and, if desired, placed into system folders with + libraries and include-files).

+ +

Unix Systems (FreeBSD, Linux, Mac OS X)

+

To build the library, you will need a working C++ compiler (gcc 3+ and + clang 2+ are OK) and the make utility.

+

Additional libraries (optional):

+
    +
  • zlib (used to decode deflated DNGs)
  • +
  • libjasper (used to decode RED files)
  • +
  • libjpeg8 (used to decode lossy DNGs and several old Kodak cameras)
  • +
+

LibRaw has been tested on 32- and 64-bit Unix systems working on x86- + (and AMD64-) compatible processors. Building and work on other + architectures have not been tested.

+

Compilation of Library and Examples

+

Unpack the downloaded distribution package.

+
        tar xzvf LibRaw-X.YY.tar.gz
+
+

For GitHub downloads (clones), perform ./configure script generation via

+
        autoreconf --install
+

Go to LibRaw directory and run ./configure and make:

+
cd LibRaw-X.YY
+./configure # with optional args
+make
+    
+

As a result, you will compile

+
    +
  • Library libraw.a in the lib/ folder
  • +
  • Examples in the bin/ folder (source + codes of examples are in the samples/ folder).
  • +
+

In the current version, only static libraries are built:

+
    +
  • libraw.a: non-thread-safe version
  • +
  • libraw_r.a: thread-safe
  • +
+

Build parameters

+

./configure script have some non-standard parameters:

+
+
--enable-openmp
+ --disable-openmp
+
Enable/disable OpenMP support if compiler supports it. OpenMP is + enabled by default.
+
--enable-lcms
+ --disable-lcms
+
Enable/disable LCMS color engine support. If enabled, ./configure + will try to find lcms library. Both LCMS-1.x and LCMS-2.x are supported + LCMS support is enabled by default
+
--enable-examples
+ --disable-examples
+
Enables/disables examples compilation and installation. Enabled by + default
+
+

Installation and Usage

+

To install the library, run

+
    sudo make install
+    
+

It will place the libraries in /usr/local/lib, the include-files + in /usr/local/include (subfolder of libraw) and LibRaw samples to + /usr/local/bin. You can override installation path by using + ./configure script.
+ To use LibRaw, add the following parameters to the compiler call (when + building your own projects):

+
    +
  • Path to include-files: -I/usr/local/include
  • +
  • Path to libraries: -L/usr/local/lib
  • +
  • Library: -lraw (ordinary version) or -lraw_r (thread-safe version).
  • +
+

Windows: Building under Cygwin

+

Building and installation are completely similar to building + and installation under Unix systems.

+

Windows: Native Building

+

Building under Windows has three steps:

+
    +
  • Unpack the distribution package (if you have got no tar+gzip, take the + LibRaw distribution package in the .ZIP format) and go to folder + LibRaw-X.YYY.
  • +
  • Set the environment parameters so that the compiler/linker would find + the libraries and include-files. For Visual C++, this is done by running + vcvars32.bat.
  • +
  • Run
    + nmake -f Makefile.msvc
    +
  • +
+

You may need to edit Makefile.msvc to provide libjpeg/zlib/libjasper + paths to INCLUDE/LIB.

+

If all paths are set correctly and the include-files/libraries have been + found, then the following will be compiled:

+
    +
  • Library libraw_static.lib in folder lib
  • +
  • Dynamic library bin/libraw.dll and linking library for it + lib/libraw.lib
  • +
  • Examples in folder bin/.
  • +
+

Only the thread-safe library is built under Win32, but it can be used + with non-threaded applications as well. All examples are linked with the + dynamic library (DLL); if static linking is necessary, one should link + applications with library libraw_static.lib and set the preprocessor + option /DLIBRAW_NODLL during compilation.

+

Windows-version compiles without LCMS support for now.

+

During building of DLL, all public functions are exported; further, the + exported subset may be reduced.

+

Unfortunately, paths to include/ libraries depend on the way Visual C + (or other compiler) is installed; therefore, it is impossible to specify + some standard paths in Makefile.msvc.

+

Windows Installation

+

No installation under Windows is supported. It is assumed that all DLLs + will be supplied together with the software using them (and this software + will perform the installation). Accordingly, in building of programs using + LibRaw, the paths to libraries, DLLs, and include-files should be + specified manually.

+ [back to Index] + + diff --git a/doc/Samples-LibRaw.html b/doc/Samples-LibRaw.html new file mode 100644 index 000000000..c72a3f945 --- /dev/null +++ b/doc/Samples-LibRaw.html @@ -0,0 +1,213 @@ + + + + + +

LibRaw: Usage Examples[back to Index]

+

LibRaw: Usage Examples

+

Overview of Examples in the Distribution Package (samples/*)

+

The LibRaw package contains several examples illustrating the use of this + library. Their source codes are located in the samples/ folder, and after + library build they will be in the bin/ folder:

+
    +
  • raw-identify The only LibRaw call it uses is open_file(); + further code prints the values of the fields of the imgdata structure.
    +
    raw-identify -v provides extensive dump of + metadata/
    + Command line key -u shows unpacking function name, + while -u -f prints function name and masked are sizes.
    + raw-identify -w will print white balance tables stored + in RAW file.
  • +
  • simple_dcraw A simple "emulation" of dcraw + reproducing the behavior of dcraw [-e] [-v] [-T].  + A simplified version of this example is considered + below.
    + -B command-line switch turns on use of open_buffer() + API call used via mmap() of input file (Unix only).
  • +
  • dcraw_half Demonstrates the use of C + API. The example emulates the behavior of dcraw -h + (no other control parameters can be specified in this example).
  • +
  • dcraw_emu Almost complete emulation of dcraw (except for + keys -D -d -E -i -v -e, which are considered in other usage examples). + Of most interest is processing of command line keys (copied from dcraw). +
    +

    This sample supports additional command-line parameters absent in + original dcraw:

    +
    +
    -mmap
    +
    Use open_buffer() + interface. Buffer prepared by mmap() call. This option not supported + under Win32.
    +
    -meme
    +
    Use open_buffer() + interface. Buffer prepared by malloc()+read() calls.
    +
    -c float-value
    +
    This key sets params.adjust_maximum_thr + parameter.
    + Use -c 0 to completely disable automatic maximum calculation.
    + Default value: 0.75
    +
    -timing
    +
    Turns on detailed timing print.
    +
    -G
    +
    Turns on "green_matching" mode to suppress color mazes on cameras + with different green channels.
    +
    -B x y w h
    +
    Crops output to rectangle with width w, height h and x,y + coordinates of left upper corner. All coordinates applied before any + image rotation.
    +
    -F
    +
    Will use FILE I/O (bigfile_datastream) instead on standard + LibRaw_file_datastream.
    +
    -dcbi N
    +
    Sets number of additional DCB-demosaic iterations (option valid + only for -q 4, i.e. for DCB demosaic).
    +
    -dcbe
    +
    Turns on DCB color enhance mode (only for DCB demosaic, -q 4).
    +
    -aexpo e p
    +
    Turns on exposure correction. e is exposure shift in linear scale + from 0.25 (darken 2 stops) to 8.0 (lighten 3 stops). p is highlights + preservation amount from 0.0 (no preservation, full clipping) to 1.0 + (full preservation, S-like curve in highlights).
    +
    -apentax4shot
    +
    Will merge 4 frames from Pentax 4-shot RAWs
    +
    -apentax4shotorder abce
    +
    Order of frames in pentax 4-shot files (default is 3102)
    +
    -mmap
    +
    Use mmap + memory IO instead of file IO (unix only)
    +
    -disars
    +
    Disable RawSpeed library (if compiled with this library)
    +
    -doutputflags N
    +
    set imgdata.params.output_flags to N
    +
    -disinterp
    +
    Do not run interpolation step
    +
    -dsrawrgb1
    +
    Disable YCbCr to RGB conversion for sRAW (Cb/Cr interpolation + enabled)
    +
    -dsrawrgb2
    +
    Disable YCbCr to RGB conversion for sRAW (Cb/Cr interpolation + disabled)
    +
    +
  • +
  • half_mt Emulation of dcraw -h. It + "understands" the following keys: -a (automatic white balance over the + entire image), -w (white balance of the camera), -T (output in the tiff + format), and -J n (number of parallel threads launched for image + processing).
    + On multiprocessor/multicore computers, the speed gain is notable in the + case of mass processing. On a Win32 machine, the example is assembled + from the initial file half_mt_win32.c, since work with threads under + Windows is fundamentally different and it it easier to copy simple + source codes than write one complex code.
  • +
  • mem_image This sample uses dcraw_make_mem_image + and dcraw_make_mem_thumb + calls, than writes data in PPM format.
  • +
  • unprocessed_raw This sample extracts (mostly) + unaltered RAW data including masked pixels data (on supported cameras). + If black frame exists and black frame extraction is supported for given + format, masked pixels data is added to resulting .TIFF file. Command + line options: -q - be quiet, -A - + autoscale data (integer multiplier), -g + gamma-correction (gamma 2.2) for data (instead of precise linear one), -B + turns on black level subtraction
  • +
  • 4channnels - splits RAW-file into four separate + 16-bit grayscale TIFFs (per RAW channel).
    + Command line switches: +
      +
    • -s N selects N-th image from RAW with multiple + images
    • +
    • -g gamma correction (gamma 2.2)
    • +
    • -A values autoscale by auto-calculated integer + factor
    • +
    • -B turn off black subtraction
    • +
    • -N no RAW curve
    • +
    +
  • +
  • multirender_test - very simple example of multiple + rendering on one file without reopen.
  • +
  • postprocessing_benchmark - will print timings of RAW + processing steps
  • +
+

Example of docmode

+

Below we consider the samples/simple_dcraw.cpp example, which emulates + the behavior of dcraw [-e][-v][-t]. To save space, let + us assume that keys -t -v are always specified (to avoid comments on + command line parsing) and there is always one parameter (name of file), + which is the only one and always passed to the program.

+
int main(int ac, char *av[])
+{
+ int i, ret, verbose=0, output_thumbs=0;
+ char outfn[1024],thumbfn[1024];
+ // Creation of image processing object
+ LibRaw RawProcessor;
+ // The date in TIFF is written in the local format; let us specify the timezone for compatibility with dcraw
+ putenv ((char*)"TZ=UTC");
+// Let us define variables for convenient access to fields of RawProcessor
+#define P1 RawProcessor.imgdata.idata
+#define S RawProcessor.imgdata.sizes
+#define C RawProcessor.imgdata.color
+#define T RawProcessor.imgdata.thumbnail
+#define P2 RawProcessor.imgdata.other
+#define OUT RawProcessor.imgdata.params
+ OUT.output_tiff = 1; // Let us output TIFF
+ // Let us open the file
+ if( (ret = RawProcessor.open_file(av[1])) != LIBRAW_SUCCESS)
+ {
+ fprintf(stderr,"Cannot open %s: %s\n",av[i],libraw_strerror(ret));
+ // recycle() is needed only if we want to free the resources right now.
+ // If we process files in a cycle, the next open_file()
+ // will also call recycle(). If a fatal error has happened, it means that recycle()
+ // has already been called (repeated call will not cause any harm either).
+ RawProcessor.recycle();
+ goto end;
+ }
+ // Let us unpack the image
+ if( (ret = RawProcessor.unpack() ) != LIBRAW_SUCCESS)
+ {
+ fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
+ if(LIBRAW_FATAL_ERROR(ret))
+ goto end;
+ // if there has been a non-fatal error, we will try to continue
+ }
+ // Let us unpack the thumbnail
+ if( (ret = RawProcessor.unpack_thumb() ) != LIBRAW_SUCCESS)
+ {
+ // error processing is completely similar to the previous case
+ fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
+ if(LIBRAW_FATAL_ERROR(ret))
+ goto end;
+ }
+ else // We have successfully unpacked the thumbnail, now let us write it to a file
+ {
+ snprintf(thumbfn,sizeof(thumbfn),"%s.%s",av[i],T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg" : "thumb.ppm");
+ if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_thumb_writer(thumbfn)))
+ {
+ fprintf(stderr,"Cannot write %s: %s\n",thumbfn,libraw_strerror(ret));
+ // in the case of fatal error, we should terminate processing of the current file
+ if(LIBRAW_FATAL_ERROR(ret))
+ goto end;
+ }
+ }
+ // Data unpacking
+ ret = RawProcessor.dcraw_process();
+ if(LIBRAW_SUCCESS != ret ) // error at the previous step
+ {
+ fprintf(stderr,"Cannot do postprocessing on %s: %s\n",av[i],libraw_strerror(ret));
+ if(LIBRAW_FATAL_ERROR(ret))
+ goto end;
+ }
+ else // Successful document processing
+ {
+ snprintf(outfn,sizeof(outfn),"%s.%s", av[i], "tiff");
+ if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
+ fprintf(stderr,"Cannot write %s: error %d\n",outfn,ret);
+ }
+ // we don't evoke recycle() or call the destructor; C++ will do everything for us
+ return 0;
+end:
+ // got here after an error
+ return 1;
+}
+
+

[back to Index]

+ + diff --git a/doc/Why-LibRaw.html b/doc/Why-LibRaw.html new file mode 100644 index 000000000..90105a871 --- /dev/null +++ b/doc/Why-LibRaw.html @@ -0,0 +1,65 @@ + + + + + +

Purpose and Objectives[back to Index]

+

LibRaw Project Goals and Objectives

+

Who May Be Interested in This Project

+

The proposed project and the software products generated within this project are intended for:

+
    +
  • Developers of RAW converters, including current and new developments
  • +
  • Developers of applications that need access to decoded RAW data (for pre-processing, stitching, stacking, color profiling, etc.)
  • +
  • Those willing to write their own graphic interface for RAW file processing
  • +
  • Developers and enthusiasts creating their own primary and auxiliary data processing algorithms, including +
      +
    • Interpolation (demosaic),
    • +
    • Noise reduction
    • +
    • White balance
    • +
    • Correction of aberrations and distortions
    • +
    • RAW data analysis
    • +
    • Comparison of cameras and lenses
    • +
    • and so on...
    • +
    +
  • +
+

Some History

+

The LibRaw project started in 2008. At that time dcraw was very popular as a method of accessing RAW data. It was hard to find a more or less popular camera that was not supported by this utility; while the implementation of RAW data extraction in dcraw was of a very high quality.

+

However, developers and enthusiasts were experiencing a number of difficulties when using dcraw. First, the author of dcraw refused to turn his product into a handy library. Besides, dcraw contains a number of questionable features that may hinder its use without modifications, as well as instances of distortions in the photographic sense of it. As a result, once every several months, with each new release of dcraw, virtually all developers, part of them listed on the dcraw Web site, were to check the differences, figure out the patches, and apply those patches to their dcraw-based code and libraries.

+

As for enthusiasts, the "entry cost" of verifying their own ideas and implementing their own algorithms in such an environment is often unreasonably high: they have to either use the dcraw command line, thus being forced to use the unavoidable early processing stages, or understand the source code and maintain their own library based on it.

+

Thus, the inconveniences of dcraw make the developers' community quite small and halt further evolution and improvement of RAW format converters.

+

Our project started with the idea to get a library based on dcraw, only better. Today we are well past that initial goal, not in the least because dcraw is not actively supported since 2015, and the latest release was published nearly 2 years ago, in May 2016. Since then several distinctly different RAW formats (introduced by Fujifilm, Nikon, Pentax, Samsung, Sigma, Sony) emerged, none of which is supported by dcraw. Additionally, we see it necessary to extract more metadata to help better interpretation of RAW data and to add flexibility to the RAW conversion process.

+

Goals and Objectives

+

We are maintaining LibRaw as a library providing access to decoded raw data and metadata useful for correct interpretation of the said data. Thus:

+
    +
  1. To keep on adding RAW decoding for new and previously unsupported cameras
  2. +
  3. To continue the development of a stable and consistent API suitable for other applications (RAW converters, data analyzers, panorama stitchers, etc.)
  4. +
  5. To have RAW processing as separate independent parts (groups of API calls) +
      +
    • Reading, decoding, and unpacking of RAW data: this is the main functionality of LibRaw
    • +
    • Data conversions: interpolation, white balance, etc.: this part of LibRaw is frozen: we ported dcraw functionality, but expect that library users will create own postprocessing code.
    • +
    • File output of the processing results. This part is very primitive, only tiff and ppm output is supported.
    • +
    +
  6. +
+

The latter two groups of functions are maintained to provide some postprocessing/saving ability from scratch, without writing own code. We do not have any plans to extend/improve this code.

+
    +
  1. To improve the procedures of RAW data retrieval and decoding.
  2. +
  3. To supply other developers with a "framework" (freeware and open-source), e.g., for experimenting with their own methods of RAW data processing (interpolation, noise reduction, white balance, etc.; some directions of the possible efforts are listed above), so that they could create their own GUI programs and interfaces without developing the entire RAW converter.
  4. +
+

LibRaw Release Schedule

+
    +
  1. Production releases will be published at intervals of 1-1.5 years. Production releases will be maintained through bugfixes. New cameras will not be added to production releases, but only to snapshots and non-stable/beta releases. Patch (bugfix) releases of production releases should provide API/ABI consistency (so, version 0.21.5 should be binary compatible with 0.21.0).
  2. +
  3. Snapshots are planned to be released every 2-3 quarters. Snapshots will include support for new cameras, stable and tested in our own applications. API calls and internal routines may be changed. No binary compatibility maintained, to upgrade to newer snapshot one need to recompile application that uses it.
  4. +
  5. Non-stable/beta releases with new features, like initial support for some new RAW format that needs extensive testing by the community.  No exact schedule, to be published as needed.
  6. +
+

How You Can Help/Participate

+

We welcome any help, however:

+
    +
  1. If you are submitting any core functionality extensions/improvements, that is, something that has to do with the decoding of RAW and/or metadata, that would be highly valuable and we will maintain your submission on our own, if necessary; you don’t need to be committed.
  2. +
  3. If your contribution adds to post-processing, please be committed to supporting and maintaining such a contribution. Our previous experience with such contributions has been less than positive, exactly because of the lack of maintenance on the part of the contributors. We are unable to maintain such contributions on our own, because our primary goal is to maintain RAW and metadata decoding.
  4. +
+

[back to Index]

+ + diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 000000000..f58e89c03 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,38 @@ + + + + + LibRaw: better dcraw (library) + + +

LibRaw: RAW image decoding/processing library

+

LibRaw is a library for reading RAW files from digital photo cameras (CRW/CR2, NEF, RAF, DNG, MOS, KDC, DCR, etc.; virtually all RAW formats are supported). It pays special attention to correct retrieval of data required for subsequent RAW conversion.

+

The library is intended for embedding in RAW converters, data analyzers, and other programs using RAW files as the initial data.

+

Contents

+
    +
  1. Copyright
  2. +
  3. Purpose and Objectives
  4. +
  5. Overview of LibRaw API (C++)
  6. +
  7. Compilation and Installation
  8. +
  9. Data Structures, Error Codes, and Constants
  10. +
  11. C++ API
  12. +
  13. C API
  14. +
  15. Notes on API (error code conventions, memory usage)
  16. +
  17. Examples
  18. +
+ +

Copyright

+

LibRaw library, Copyright (C) 2008-2021 LibRaw LLC (info@libraw.org)
+ The library includes source code from
+ dcraw.c, Dave Coffin's raw photo decoder
+ Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net
+

+

LibRaw is distributed for free under two different licenses:

+ + You may use one of these licensing modes and switch between them. +

+ + diff --git a/export-dist.sh b/export-dist.sh new file mode 100755 index 000000000..a462558be --- /dev/null +++ b/export-dist.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +DEST=$1 +VERSION=$2 +if test x$VERSION = x ; then + VERSION=`./version.sh` + echo VERSION set to $VERSION +fi + +if test -d $DEST ; then + echo Using $DEST/$VERSION +else + echo Usage: $0 destination-dir + exit 1 +fi +cd .. +for dir in LibRaw +do + cd $dir + git pull origin + cd .. +done +for dir in LibRaw +do + cd $dir + git archive --prefix=$dir-$VERSION/ $VERSION | (cd $DEST; tar xvf - ) + cd .. +done diff --git a/internal/dcraw_defs.h b/internal/dcraw_defs.h new file mode 100644 index 000000000..574f3a8bd --- /dev/null +++ b/internal/dcraw_defs.h @@ -0,0 +1,66 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef DCRAW_DEFS_H +#define DCRAW_DEFS_H + +#include +#define LIBRAW_LIBRARY_BUILD +#define LIBRAW_IO_REDEFINED +#include "libraw/libraw.h" +#include "libraw/libraw_types.h" +#include "internal/defines.h" +#include "internal/var_defines.h" + +#define stmread(buf, maxlen, fp) stread(buf, MIN(maxlen, sizeof(buf)), fp) +#define strbuflen(buf) strnlen(buf, sizeof(buf) - 1) +#define makeIs(idx) (maker_index == idx) +#define strnXcat(buf, string) \ + strncat(buf, string, LIM(sizeof(buf) - strbuflen(buf) - 1, 0, sizeof(buf))) + +// DNG was written by: +#define nonDNG 0 +#define CameraDNG 1 +#define AdobeDNG 2 + +// Makernote tag type: +#define is_0x927c 0 /* most cameras */ +#define is_0xc634 2 /* Adobe DNG, Sony SR2, Pentax */ + +// abbreviations +#define ilm imgdata.lens.makernotes +#define icWBC imgdata.color.WB_Coeffs +#define icWBCCTC imgdata.color.WBCT_Coeffs +#define imCanon imgdata.makernotes.canon +#define imFuji imgdata.makernotes.fuji +#define imHassy imgdata.makernotes.hasselblad +#define imKodak imgdata.makernotes.kodak +#define imNikon imgdata.makernotes.nikon +#define imOly imgdata.makernotes.olympus +#define imPana imgdata.makernotes.panasonic +#define imPentax imgdata.makernotes.pentax +#define imPhaseOne imgdata.makernotes.phaseone +#define imRicoh imgdata.makernotes.ricoh +#define imSamsung imgdata.makernotes.samsung +#define imSony imgdata.makernotes.sony +#define imCommon imgdata.makernotes.common + + +#define ph1_bits(n) ph1_bithuff(n, 0) +#define ph1_huff(h) ph1_bithuff(*h, h + 1) +#define getbits(n) getbithuff(n, 0) +#define gethuff(h) getbithuff(*h, h + 1) + +#endif diff --git a/internal/dcraw_fileio_defs.h b/internal/dcraw_fileio_defs.h new file mode 100644 index 000000000..3d12edca5 --- /dev/null +++ b/internal/dcraw_fileio_defs.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef DCRAW_FILEIO_DEFS_H +#define DCRAW_FILEIO_DEFS_H + +#include +#define LIBRAW_LIBRARY_BUILD +#include "libraw/libraw.h" +#include "internal/defines.h" +#include "internal/var_defines.h" + +#endif diff --git a/internal/defines.h b/internal/defines.h new file mode 100644 index 000000000..674ad671b --- /dev/null +++ b/internal/defines.h @@ -0,0 +1,193 @@ +/* + Copyright 2008-2021 LibRaw LLC (info@libraw.org) + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + This file is generated from Dave Coffin's dcraw.c + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net + + Look into dcraw homepage (probably http://cybercom.net/~dcoffin/dcraw/) + for more information +*/ + +#ifndef LIBRAW_INT_DEFINES_H +#define LIBRAW_INT_DEFINES_H +#ifndef USE_JPEG +#define NO_JPEG +#endif +#ifndef USE_JASPER +#define NO_JASPER +#endif +#define DCRAW_VERSION "9.26" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __CYGWIN__ +#include +#endif +#if defined LIBRAW_WIN32_CALLS +#include +#ifndef LIBRAW_NO_WINSOCK2 +#include +#pragma comment(lib, "ws2_32.lib") +#endif +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef NODEPS +#define NO_JASPER +#define NO_JPEG +#define NO_LCMS +#endif +#ifndef NO_JASPER +#include /* Decode Red camera movies */ +#endif +#ifndef NO_JPEG +#include /* Decode compressed Kodak DC120 photos */ +#endif /* and Adobe Lossy DNGs */ +#ifndef NO_LCMS +#ifdef USE_LCMS +#include /* Support color profiles */ +#else +#include /* Support color profiles */ +#endif +#endif +#ifdef LOCALEDIR +#include +#define _(String) gettext(String) +#else +#define _(String) (String) +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof(long)) +#endif +#define FORC(cnt) for (c = 0; c < cnt; c++) +#define FORC3 FORC(3) +#define FORC4 FORC(4) +#define FORCC for (c = 0; c < colors && c < 4; c++) + +#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((int)(x), 0, 65535) +#define CLIP15(x) LIM((int)(x), 0, 32767) +#define SWAP(a, b) \ + { \ + a = a + b; \ + b = a - b; \ + a = a - b; \ + } + +#define my_swap(type, i, j) \ + { \ + type t = i; \ + i = j; \ + j = t; \ + } + +#ifdef __GNUC__ +inline +#elif defined(_MSC_VER) +__forceinline +#else +static +#endif +float fMAX(float a, float b) { return MAX(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 + */ + +// _RGBG means R, G1, B, G2 sequence +#define GRBG_2_RGBG(q) (q ^ (q >> 1) ^ 1) +#define RGGB_2_RGBG(q) (q ^ (q >> 1)) +#define BG2RG1_2_RGBG(q) (q ^ 2) +#define G2BRG1_2_RGBG(q) (q ^ (q >> 1) ^ 3) +#define GRGB_2_RGBG(q) (q ^ 1) +#define RBGG_2_RGBG(q) ((q >> 1) | ((q & 1) << 1)) + +#define RAWINDEX(row, col) ((row)*raw_width + (col)) +#define RAW(row, col) raw_image[(row)*raw_width + (col)] +#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)] +#define BAYERC(row, col, c) \ + imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][c] + +#endif diff --git a/internal/dmp_include.h b/internal/dmp_include.h new file mode 100644 index 000000000..6b6b5a6c7 --- /dev/null +++ b/internal/dmp_include.h @@ -0,0 +1,27 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef DMP_INCLUDE_H +#define DMP_INCLUDE_H + +#define LIBRAW_LIBRARY_BUILD +#define LIBRAW_IO_REDEFINED +#include "libraw/libraw.h" +#include "internal/defines.h" +#define SRC_USES_SHRINK +#define SRC_USES_BLACK +#define SRC_USES_CURVE + +#endif diff --git a/internal/libraw_cameraids.h b/internal/libraw_cameraids.h new file mode 100644 index 000000000..4d03006b6 --- /dev/null +++ b/internal/libraw_cameraids.h @@ -0,0 +1,320 @@ +/* -*- C++ -*- + * File: internal/libraw_cameraids.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Aug 17, 2020 + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef LIBRAW_CONST_H +#define LIBRAW_CONST_H + +#define CanonID_EOS_M50 0x00000412ULL +#define CanonID_EOS_M6_Mark_II 0x00000811ULL +#define CanonID_EOS_M200 0x00000812ULL +#define CanonID_EOS_D30 0x01140000ULL +#define CanonID_EOS_D60 0x01668000ULL +#define CanonID_EOS_M3 0x03740000ULL +#define CanonID_EOS_M10 0x03840000ULL +#define CanonID_EOS_M5 0x03940000ULL +#define CanonID_EOS_M100 0x03980000ULL +#define CanonID_EOS_M6 0x04070000ULL +#define CanonID_EOS_1D (0x80000000ULL + 0x001ULL) +#define CanonID_EOS_1Ds (0x80000000ULL + 0x167ULL) +#define CanonID_EOS_10D (0x80000000ULL + 0x168ULL) +#define CanonID_EOS_1D_Mark_III (0x80000000ULL + 0x169ULL) +#define CanonID_EOS_300D (0x80000000ULL + 0x170ULL) +#define CanonID_EOS_1D_Mark_II (0x80000000ULL + 0x174ULL) +#define CanonID_EOS_20D (0x80000000ULL + 0x175ULL) +#define CanonID_EOS_450D (0x80000000ULL + 0x176ULL) +#define CanonID_EOS_1Ds_Mark_II (0x80000000ULL + 0x188ULL) +#define CanonID_EOS_350D (0x80000000ULL + 0x189ULL) +#define CanonID_EOS_40D (0x80000000ULL + 0x190ULL) +#define CanonID_EOS_5D (0x80000000ULL + 0x213ULL) +#define CanonID_EOS_1Ds_Mark_III (0x80000000ULL + 0x215ULL) +#define CanonID_EOS_5D_Mark_II (0x80000000ULL + 0x218ULL) +#define CanonID_EOS_1D_Mark_II_N (0x80000000ULL + 0x232ULL) +#define CanonID_EOS_30D (0x80000000ULL + 0x234ULL) +#define CanonID_EOS_400D (0x80000000ULL + 0x236ULL) +#define CanonID_EOS_7D (0x80000000ULL + 0x250ULL) +#define CanonID_EOS_500D (0x80000000ULL + 0x252ULL) +#define CanonID_EOS_1000D (0x80000000ULL + 0x254ULL) +#define CanonID_EOS_50D (0x80000000ULL + 0x261ULL) +#define CanonID_EOS_1D_X (0x80000000ULL + 0x269ULL) +#define CanonID_EOS_550D (0x80000000ULL + 0x270ULL) +#define CanonID_EOS_1D_Mark_IV (0x80000000ULL + 0x281ULL) +#define CanonID_EOS_5D_Mark_III (0x80000000ULL + 0x285ULL) +#define CanonID_EOS_600D (0x80000000ULL + 0x286ULL) +#define CanonID_EOS_60D (0x80000000ULL + 0x287ULL) +#define CanonID_EOS_1100D (0x80000000ULL + 0x288ULL) +#define CanonID_EOS_7D_Mark_II (0x80000000ULL + 0x289ULL) +#define CanonID_EOS_650D (0x80000000ULL + 0x301ULL) +#define CanonID_EOS_6D (0x80000000ULL + 0x302ULL) +#define CanonID_EOS_1D_C (0x80000000ULL + 0x324ULL) +#define CanonID_EOS_70D (0x80000000ULL + 0x325ULL) +#define CanonID_EOS_700D (0x80000000ULL + 0x326ULL) +#define CanonID_EOS_1200D (0x80000000ULL + 0x327ULL) +#define CanonID_EOS_1D_X_Mark_II (0x80000000ULL + 0x328ULL) +#define CanonID_EOS_M (0x80000000ULL + 0x331ULL) +#define CanonID_EOS_100D (0x80000000ULL + 0x346ULL) +#define CanonID_EOS_760D (0x80000000ULL + 0x347ULL) +#define CanonID_EOS_5D_Mark_IV (0x80000000ULL + 0x349ULL) +#define CanonID_EOS_80D (0x80000000ULL + 0x350ULL) +#define CanonID_EOS_M2 (0x80000000ULL + 0x355ULL) +#define CanonID_EOS_5DS (0x80000000ULL + 0x382ULL) +#define CanonID_EOS_750D (0x80000000ULL + 0x393ULL) +#define CanonID_EOS_5DS_R (0x80000000ULL + 0x401ULL) +#define CanonID_EOS_1300D (0x80000000ULL + 0x404ULL) +#define CanonID_EOS_800D (0x80000000ULL + 0x405ULL) +#define CanonID_EOS_6D_Mark_II (0x80000000ULL + 0x406ULL) +#define CanonID_EOS_77D (0x80000000ULL + 0x408ULL) +#define CanonID_EOS_200D (0x80000000ULL + 0x417ULL) +#define CanonID_EOS_R5 (0x80000000ULL + 0x421ULL) +#define CanonID_EOS_3000D (0x80000000ULL + 0x422ULL) +#define CanonID_EOS_R (0x80000000ULL + 0x424ULL) +#define CanonID_EOS_1D_X_Mark_III (0x80000000ULL + 0x428ULL) +#define CanonID_EOS_1500D (0x80000000ULL + 0x432ULL) +#define CanonID_EOS_RP (0x80000000ULL + 0x433ULL) +#define CanonID_EOS_850D (0x80000000ULL + 0x435ULL) +#define CanonID_EOS_250D (0x80000000ULL + 0x436ULL) +#define CanonID_EOS_90D (0x80000000ULL + 0x437ULL) +#define CanonID_EOS_R3 (0x80000000ULL + 0x450ULL) +#define CanonID_EOS_R6 (0x80000000ULL + 0x453ULL) +#define CanonID_EOS_R7 (0x80000000ULL + 0x464ULL) +#define CanonID_EOS_R10 (0x80000000ULL + 0x465ULL) +#define CanonID_EOS_M50_Mark_II (0x80000000ULL + 0x468ULL) + +// CanonID_EOS_D2000C after Canon's TIFF2CR2 convertor: +#define CanonID_EOS_D2000C (0x80000000ULL + 0x520ULL) +// CanonID_EOS_D6000C id after Canon's TIFF2CR2 convertor: +#define CanonID_EOS_D6000C (0x80000000ULL + 0x560ULL) + +#define OlyID_str2hex(str) ((unsigned long long)str[0]<<32 | str[1]<<24 | str[2]<<16 | str[3]<<8 | str[4]) +#define OlyID_E_20 OlyID_str2hex("D4029") +#define OlyID_E_1 OlyID_str2hex("D4040") +#define OlyID_E_300 OlyID_str2hex("D4041") +#define OlyID_SP_550UZ OlyID_str2hex("D4321") +#define OlyID_SP_510UZ OlyID_str2hex("D4322") +#define OlyID_SP_560UZ OlyID_str2hex("D4355") +#define OlyID_SP_570UZ OlyID_str2hex("D4364") +#define OlyID_SP_565UZ OlyID_str2hex("D4374") +#define OlyID_XZ_1 OlyID_str2hex("D4401") +#define OlyID_XZ_2 OlyID_str2hex("D4531") +#define OlyID_XZ_10 OlyID_str2hex("D4546") +#define OlyID_STYLUS_1 OlyID_str2hex("D4572") +#define OlyID_SH_2 OlyID_str2hex("D4585") +#define OlyID_TG_4 OlyID_str2hex("D4586") +#define OlyID_TG_5 OlyID_str2hex("D4593") +#define OlyID_TG_6 OlyID_str2hex("D4603") +#define OlyID_E_10 OlyID_str2hex("D4842") +#define OlyID_AIR_A01 OlyID_str2hex("K0055") +#define OlyID_NORMA OlyID_str2hex("NORMA") +#define OlyID_E_330 OlyID_str2hex("S0003") +#define OlyID_E_500 OlyID_str2hex("S0004") +#define OlyID_E_400 OlyID_str2hex("S0009") +#define OlyID_E_510 OlyID_str2hex("S0010") +#define OlyID_E_3 OlyID_str2hex("S0011") +#define OlyID_E_410 OlyID_str2hex("S0013") +#define OlyID_E_420 OlyID_str2hex("S0016") +#define OlyID_E_30 OlyID_str2hex("S0017") +#define OlyID_E_520 OlyID_str2hex("S0018") +#define OlyID_E_P1 OlyID_str2hex("S0019") +#define OlyID_E_620 OlyID_str2hex("S0023") +#define OlyID_E_P2 OlyID_str2hex("S0026") +#define OlyID_E_PL1 OlyID_str2hex("S0027") +#define OlyID_E_450 OlyID_str2hex("S0029") +#define OlyID_E_600 OlyID_str2hex("S0030") +#define OlyID_E_P3 OlyID_str2hex("S0032") +#define OlyID_E_5 OlyID_str2hex("S0033") +#define OlyID_E_PL2 OlyID_str2hex("S0034") +#define OlyID_E_M5 OlyID_str2hex("S0036") +#define OlyID_E_PL3 OlyID_str2hex("S0038") +#define OlyID_E_PM1 OlyID_str2hex("S0039") +#define OlyID_E_PL1s OlyID_str2hex("S0040") +#define OlyID_E_PL5 OlyID_str2hex("S0042") +#define OlyID_E_PM2 OlyID_str2hex("S0043") +#define OlyID_E_P5 OlyID_str2hex("S0044") +#define OlyID_E_PL6 OlyID_str2hex("S0045") +#define OlyID_E_PL7 OlyID_str2hex("S0046") +#define OlyID_E_M1 OlyID_str2hex("S0047") +#define OlyID_E_M10 OlyID_str2hex("S0051") +#define OlyID_E_M5_Mark_II OlyID_str2hex("S0052") +#define OlyID_E_M10_Mark_II OlyID_str2hex("S0059") +#define OlyID_PEN_F OlyID_str2hex("S0061") +#define OlyID_E_PL8 OlyID_str2hex("S0065") +#define OlyID_E_M1_Mark_II OlyID_str2hex("S0067") +#define OlyID_E_M10_Mark_III OlyID_str2hex("S0068") +#define OlyID_E_PL9 OlyID_str2hex("S0076") +#define OlyID_E_M1X OlyID_str2hex("S0080") +#define OlyID_E_PL10 OlyID_str2hex("S0085") +#define OlyID_E_M10_Mark_IV OlyID_str2hex("S0088") +#define OlyID_E_M5_Mark_III OlyID_str2hex("S0089") +#define OlyID_E_M1_Mark_III OlyID_str2hex("S0092") +#define OlyID_E_P7 OlyID_str2hex("S0093") +#define OlyID_OM_1 OlyID_str2hex("S0095") +#define OlyID_C_3030Z OlyID_str2hex("SX351") +#define OlyID_C_5050Z OlyID_str2hex("SX558") +#define OlyID_C_350Z OlyID_str2hex("SX751") +#define OlyID_C_740UZ OlyID_str2hex("SX754") +#define OlyID_C_5060WZ OlyID_str2hex("SX756") +#define OlyID_C_8080WZ OlyID_str2hex("SX757") +#define OlyID_C_770UZ OlyID_str2hex("SX772") +#define OlyID_C_7070WZ OlyID_str2hex("SX851") +#define OlyID_C_7000Z OlyID_str2hex("SX852") +#define OlyID_SP_500UZ OlyID_str2hex("SX853") +#define OlyID_SP_310 OlyID_str2hex("SX854") +#define OlyID_SP_350 OlyID_str2hex("SX855") +#define OlyID_SP_320 OlyID_str2hex("SX873") + +#define PentaxID_Optio_S 0x1296cULL +#define PentaxID_Optio_S_V101 0x12971ULL +#define PentaxID_staristD 0x12994ULL +#define PentaxID_Optio_33WR 0x129c6ULL +#define PentaxID_Optio_S4 0x129d5ULL +#define PentaxID_Optio_750Z 0x12a66ULL +#define PentaxID_staristDS 0x12aa2ULL +#define PentaxID_staristDL 0x12b1aULL +#define PentaxID_staristDS2 0x12b60ULL +#define PentaxID_GX_1S 0x12b62ULL +#define PentaxID_staristDL2 0x12b7eULL +#define PentaxID_GX_1L 0x12b80ULL +#define PentaxID_K100D 0x12b9cULL +#define PentaxID_K110D 0x12b9dULL +#define PentaxID_K100D_Super 0x12ba2ULL +#define PentaxID_K10D 0x12c1eULL +#define PentaxID_GX10 0x12c20ULL +#define PentaxID_K20D 0x12cd2ULL +#define PentaxID_GX20 0x12cd4ULL +#define PentaxID_K200D 0x12cfaULL +#define PentaxID_K2000 0x12d72ULL +#define PentaxID_K_m 0x12d73ULL +#define PentaxID_K_7 0x12db8ULL +#define PentaxID_K_x 0x12dfeULL +#define PentaxID_645D 0x12e08ULL +#define PentaxID_K_r 0x12e6cULL +#define PentaxID_K_5 0x12e76ULL +#define PentaxID_Q 0x12ee4ULL +#define PentaxID_K_01 0x12ef8ULL +#define PentaxID_K_30 0x12f52ULL +#define PentaxID_Q10 0x12f66ULL +#define PentaxID_K_5_II 0x12f70ULL +#define PentaxID_K_5_II_s 0x12f71ULL +#define PentaxID_Q7 0x12f7aULL +#define PentaxID_MX_1 0x12f84ULL +#define PentaxID_K_50 0x12fb6ULL +#define PentaxID_K_3 0x12fc0ULL +#define PentaxID_K_500 0x12fcaULL +#define PentaxID_645Z 0x13010ULL +#define PentaxID_K_S1 0x1301aULL +#define PentaxID_K_S2 0x13024ULL +#define PentaxID_Q_S1 0x1302eULL +#define PentaxID_K_1 0x13092ULL +#define PentaxID_K_3_II 0x1309cULL +#define PentaxID_GR_III 0x1320eULL +#define PentaxID_K_70 0x13222ULL +#define PentaxID_KP 0x1322cULL +#define PentaxID_K_1_Mark_II 0x13240ULL +#define PentaxID_K_3_III 0x13254ULL +#define PentaxID_GR_IIIx 0x1329aULL + +#define SonyID_DSC_R1 0x002ULL +#define SonyID_DSLR_A100 0x100ULL +#define SonyID_DSLR_A900 0x101ULL +#define SonyID_DSLR_A700 0x102ULL +#define SonyID_DSLR_A200 0x103ULL +#define SonyID_DSLR_A350 0x104ULL +#define SonyID_DSLR_A300 0x105ULL +#define SonyID_DSLR_A900_APSC 0x106ULL +#define SonyID_DSLR_A380 0x107ULL +#define SonyID_DSLR_A330 0x108ULL +#define SonyID_DSLR_A230 0x109ULL +#define SonyID_DSLR_A290 0x10aULL +#define SonyID_DSLR_A850 0x10dULL +#define SonyID_DSLR_A850_APSC 0x10eULL +#define SonyID_DSLR_A550 0x111ULL +#define SonyID_DSLR_A500 0x112ULL +#define SonyID_DSLR_A450 0x113ULL +#define SonyID_NEX_5 0x116ULL +#define SonyID_NEX_3 0x117ULL +#define SonyID_SLT_A33 0x118ULL +#define SonyID_SLT_A55 0x119ULL +#define SonyID_DSLR_A560 0x11aULL +#define SonyID_DSLR_A580 0x11bULL +#define SonyID_NEX_C3 0x11cULL +#define SonyID_SLT_A35 0x11dULL +#define SonyID_SLT_A65 0x11eULL +#define SonyID_SLT_A77 0x11fULL +#define SonyID_NEX_5N 0x120ULL +#define SonyID_NEX_7 0x121ULL +#define SonyID_NEX_VG20 0x122ULL +#define SonyID_SLT_A37 0x123ULL +#define SonyID_SLT_A57 0x124ULL +#define SonyID_NEX_F3 0x125ULL +#define SonyID_SLT_A99 0x126ULL +#define SonyID_NEX_6 0x127ULL +#define SonyID_NEX_5R 0x128ULL +#define SonyID_DSC_RX100 0x129ULL +#define SonyID_DSC_RX1 0x12aULL +#define SonyID_NEX_VG900 0x12bULL +#define SonyID_NEX_VG30 0x12cULL +#define SonyID_ILCE_3000 0x12eULL +#define SonyID_SLT_A58 0x12fULL +#define SonyID_NEX_3N 0x131ULL +#define SonyID_ILCE_7 0x132ULL +#define SonyID_NEX_5T 0x133ULL +#define SonyID_DSC_RX100M2 0x134ULL +#define SonyID_DSC_RX10 0x135ULL +#define SonyID_DSC_RX1R 0x136ULL +#define SonyID_ILCE_7R 0x137ULL +#define SonyID_ILCE_6000 0x138ULL +#define SonyID_ILCE_5000 0x139ULL +#define SonyID_DSC_RX100M3 0x13dULL +#define SonyID_ILCE_7S 0x13eULL +#define SonyID_ILCA_77M2 0x13fULL +#define SonyID_ILCE_5100 0x153ULL +#define SonyID_ILCE_7M2 0x154ULL +#define SonyID_DSC_RX100M4 0x155ULL +#define SonyID_DSC_RX10M2 0x156ULL +#define SonyID_DSC_RX1RM2 0x158ULL +#define SonyID_ILCE_QX1 0x15aULL +#define SonyID_ILCE_7RM2 0x15bULL +#define SonyID_ILCE_7SM2 0x15eULL +#define SonyID_ILCA_68 0x161ULL +#define SonyID_ILCA_99M2 0x162ULL +#define SonyID_DSC_RX10M3 0x163ULL +#define SonyID_DSC_RX100M5 0x164ULL +#define SonyID_ILCE_6300 0x165ULL +#define SonyID_ILCE_9 0x166ULL +#define SonyID_ILCE_6500 0x168ULL +#define SonyID_ILCE_7RM3 0x16aULL +#define SonyID_ILCE_7M3 0x16bULL +#define SonyID_DSC_RX0 0x16cULL +#define SonyID_DSC_RX10M4 0x16dULL +#define SonyID_DSC_RX100M6 0x16eULL +#define SonyID_DSC_HX99 0x16fULL +#define SonyID_DSC_RX100M5A 0x171ULL +#define SonyID_ILCE_6400 0x173ULL +#define SonyID_DSC_RX0M2 0x174ULL +#define SonyID_DSC_RX100M7 0x176ULL +#define SonyID_ILCE_7RM4 0x177ULL +#define SonyID_ILCE_9M2 0x178ULL +#define SonyID_ILCE_6600 0x17aULL +#define SonyID_ILCE_6100 0x17bULL +#define SonyID_ZV_1 0x17cULL +#define SonyID_ILCE_7C 0x17dULL +#define SonyID_ZV_E10 0x17eULL +#define SonyID_ILCE_7SM3 0x17fULL +#define SonyID_ILCE_1 0x180ULL +#define SonyID_ILME_FX3 0x181ULL +#define SonyID_ILCE_7RM3A 0x182ULL +#define SonyID_ILCE_7RM4A 0x183ULL +#define SonyID_ILCE_7M4 0x184ULL +#endif diff --git a/internal/libraw_cxx_defs.h b/internal/libraw_cxx_defs.h new file mode 100644 index 000000000..164849335 --- /dev/null +++ b/internal/libraw_cxx_defs.h @@ -0,0 +1,133 @@ +/* -*- C++ -*- + * File: internal/libraw_cxx_defs.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Aug 17, 2020 + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef _LIBRAW_CXX_DEFS_H +#define _LIBRAW_CXX_DEFS_H + +#include +#include +#include +#include +#include +#include +#include +#define LIBRAW_LIBRARY_BUILD +#include "libraw/libraw.h" +#include "internal/defines.h" +#ifdef USE_ZLIB +#include +#endif + +#ifndef LIBRAW_WIN32_CALLS +#include +#else +#ifndef LIBRAW_NO_WINSOCK2 +#include +#endif +#include +#endif + +#ifdef USE_RAWSPEED +#include +#include +#include +#include +#include +#include +extern const char *_rawspeed_data_xml[]; +extern const int RAWSPEED_DATA_COUNT; +class CameraMetaDataLR : public RawSpeed::CameraMetaData +{ +public: + CameraMetaDataLR() : CameraMetaData() {} + CameraMetaDataLR(char *filename) : RawSpeed::CameraMetaData(filename) {} + CameraMetaDataLR(char *data, int sz); +}; + +CameraMetaDataLR *make_camera_metadata(); + +#endif + +#ifdef USE_DNGSDK +#include "dng_host.h" +#include "dng_negative.h" +#include "dng_simple_image.h" +#include "dng_info.h" +#endif + +#define P1 imgdata.idata +#define S imgdata.sizes +#define O imgdata.params +#define C imgdata.color +#define T imgdata.thumbnail +#define MN imgdata.makernotes +#define IO libraw_internal_data.internal_output_params +#define ID libraw_internal_data.internal_data + +#define makeIs(idx) (imgdata.idata.maker_index == idx) +#define mnCamID imgdata.lens.makernotes.CamID + +#define EXCEPTION_HANDLER(e) \ + do \ + { \ + switch (e) \ + { \ + case LIBRAW_EXCEPTION_MEMPOOL: \ + recycle(); \ + return LIBRAW_MEMPOOL_OVERFLOW; \ + case LIBRAW_EXCEPTION_ALLOC: \ + recycle(); \ + return LIBRAW_UNSUFFICIENT_MEMORY; \ + case LIBRAW_EXCEPTION_TOOBIG: \ + recycle(); \ + return LIBRAW_TOO_BIG; \ + case LIBRAW_EXCEPTION_DECODE_RAW: \ + case LIBRAW_EXCEPTION_DECODE_JPEG: \ + recycle(); \ + return LIBRAW_DATA_ERROR; \ + case LIBRAW_EXCEPTION_DECODE_JPEG2000: \ + recycle(); \ + return LIBRAW_DATA_ERROR; \ + case LIBRAW_EXCEPTION_IO_EOF: \ + case LIBRAW_EXCEPTION_IO_CORRUPT: \ + recycle(); \ + return LIBRAW_IO_ERROR; \ + case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK: \ + recycle(); \ + return LIBRAW_CANCELLED_BY_CALLBACK; \ + case LIBRAW_EXCEPTION_BAD_CROP: \ + recycle(); \ + return LIBRAW_BAD_CROP; \ + case LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT: \ + recycle(); \ + return LIBRAW_FILE_UNSUPPORTED; \ + default: \ + return LIBRAW_UNSPECIFIED_ERROR; \ + } \ + } while (0) + +// copy-n-paste from image pipe +#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)) +#ifndef CLIP +#define CLIP(x) LIM(x, 0, 65535) +#endif +#define THUMB_READ_BEYOND 16384 + +#define ZERO(a) memset(&a, 0, sizeof(a)) + +#endif diff --git a/internal/libraw_internal_funcs.h b/internal/libraw_internal_funcs.h new file mode 100644 index 000000000..6abdb6bde --- /dev/null +++ b/internal/libraw_internal_funcs.h @@ -0,0 +1,412 @@ +/* -*- C++ -*- + * File: libraw_internal_funcs.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 14, 2008 + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef _LIBRAW_INTERNAL_FUNCS_H +#define _LIBRAW_INTERNAL_FUNCS_H + +#ifndef LIBRAW_LIBRARY_BUILD +#error "This file should be used only for libraw library build" +#else + +/* inline functions */ + static int stread(char *buf, size_t len, LibRaw_abstract_datastream *fp); + static int getwords(char *line, char *words[], int maxwords, int maxlen); + static void remove_trailing_spaces(char *string, size_t len); + static void remove_caseSubstr(char *string, char *remove); + static void removeExcessiveSpaces(char *string); + static void trimSpaces(char *s); +/* static tables/variables */ + static libraw_static_table_t tagtype_dataunit_bytes; + static libraw_static_table_t Canon_wbi2std; + static libraw_static_table_t Canon_KeyIsZero_Len2048_linenums_2_StdWBi; + static libraw_static_table_t Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi; + static libraw_static_table_t Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi; + static libraw_static_table_t Canon_D30_linenums_2_StdWBi; + static libraw_static_table_t Canon_G9_linenums_2_StdWBi; + + static libraw_static_table_t Fuji_wb_list1; + static libraw_static_table_t FujiCCT_K; + static libraw_static_table_t Fuji_wb_list2; + + static libraw_static_table_t Pentax_wb_list1; + static libraw_static_table_t Pentax_wb_list2; + + static libraw_static_table_t Oly_wb_list1; + static libraw_static_table_t Oly_wb_list2; + + static libraw_static_table_t Sony_SRF_wb_list; + static libraw_static_table_t Sony_SR2_wb_list; + static libraw_static_table_t Sony_SR2_wb_list1; +/* */ + int find_ifd_by_offset(int ); + void libraw_swab(void *arr, size_t len); + ushort sget2 (uchar *s); + ushort sget2Rev(uchar *s); + libraw_area_t get_CanonArea(); + int parseCR3(INT64 oAtomList, INT64 szAtomList, short &nesting, char *AtomNameStack, short& nTrack, short &TrackType); + void selectCRXTrack(); + void parseCR3_Free(); + int parseCR3_CTMD(short trackNum); + int selectCRXFrame(short trackNum, unsigned frameIndex); + void setCanonBodyFeatures (unsigned long long id); + void processCanonCameraInfo (unsigned long long id, uchar *CameraInfo, unsigned maxlen, unsigned type, unsigned dng_writer); + static float _CanonConvertAperture(ushort in); + void Canon_CameraSettings(unsigned len); + void Canon_WBpresets (int skip1, int skip2); + void Canon_WBCTpresets (short WBCTversion); + void parseCanonMakernotes (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void processNikonLensData (uchar *LensData, unsigned len); + void Nikon_NRW_WBtag (int wb, int skip); + void parseNikonMakernote (int base, int uptag, unsigned dng_writer); + void parseEpsonMakernote (int base, int uptag, unsigned dng_writer); + void parseSigmaMakernote (int base, int uptag, unsigned dng_writer); + void setOlympusBodyFeatures (unsigned long long id); + void getOlympus_CameraType2 (); + void getOlympus_SensorTemperature (unsigned len); + void parseOlympus_Equipment (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseOlympus_CameraSettings (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseOlympus_ImageProcessing (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseOlympus_RawInfo (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseOlympusMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void setPhaseOneFeatures (unsigned long long id); + void setPentaxBodyFeatures (unsigned long long id); + void PentaxISO (ushort c); + void PentaxLensInfo (unsigned long long id, unsigned len); + void parsePentaxMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseRicohMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + void parseSamsungMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + void fixupArri(); +#endif + void setSonyBodyFeatures (unsigned long long id); + void parseSonyLensType2 (uchar a, uchar b); + void parseSonyLensFeatures (uchar a, uchar b); + void process_Sony_0x0116 (uchar * buf, ushort, unsigned long long id); + void process_Sony_0x2010 (uchar * buf, ushort); + void process_Sony_0x9050 (uchar * buf, ushort, unsigned long long id); + void process_Sony_0x9400 (uchar * buf, ushort, unsigned long long id); + void process_Sony_0x9402 (uchar * buf, ushort); + void process_Sony_0x9403 (uchar * buf, ushort); + void process_Sony_0x9406 (uchar * buf, ushort); + void process_Sony_0x940c (uchar * buf, ushort); + void process_Sony_0x940e (uchar * buf, ushort, unsigned long long id); + void parseSonyMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer, + uchar *&table_buf_0x0116, ushort &table_buf_0x0116_len, + uchar *&table_buf_0x2010, ushort &table_buf_0x2010_len, + uchar *&table_buf_0x9050, ushort &table_buf_0x9050_len, + uchar *&table_buf_0x9400, ushort &table_buf_0x9400_len, + uchar *&table_buf_0x9402, ushort &table_buf_0x9402_len, + uchar *&table_buf_0x9403, ushort &table_buf_0x9403_len, + uchar *&table_buf_0x9406, ushort &table_buf_0x9406_len, + uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len, + uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len); + void parseSonySR2 (uchar *cbuf_SR2, unsigned SR2SubIFDOffset, unsigned SR2SubIFDLength, unsigned dng_writer); + void parseSonySRF (unsigned len); + void parseFujiMakernotes (unsigned tag, unsigned type, unsigned len, unsigned dng_writer); + const char* HassyRawFormat_idx2HR(unsigned idx); + void process_Hassy_Lens (int LensMount); + void parseHassyModel (); + + void setLeicaBodyFeatures(int LeicaMakernoteSignature); + void parseLeicaLensID(); + int parseLeicaLensName(unsigned len); + int parseLeicaInternalBodySerial(unsigned len); + void parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType); + void parseAdobePanoMakernote (); + void parseAdobeRAFMakernote (); + void GetNormalizedModel (); + void SetStandardIlluminants (unsigned, const char* ); + + ushort get2(); + unsigned sget4 (uchar *s); + unsigned getint(int type); + float int_to_float (int i); + double getreal (int type); + double sgetreal(int type, uchar *s); + void read_shorts (ushort *pixel, unsigned count); + +/* Canon P&S cameras */ + 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 parse_ciff (int offset, int length, int); + void ciff_block_1030(); + + +// LJPEG decoder + unsigned getbithuff (int nbits, ushort *huff); + ushort* make_decoder_ref (const uchar **source); + ushort* make_decoder (const uchar *source); + 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); + ushort * ljpeg_row_unrolled (int jrow, struct jhead *jh); + void ljpeg_idct (struct jhead *jh); + unsigned ph1_bithuff (int nbits, ushort *huff); + +// Canon DSLRs + void crw_init_tables (unsigned table, ushort *huff[2]); + int canon_has_lowbits(); + void canon_load_raw(); + void lossless_jpeg_load_raw(); + void canon_sraw_load_raw(); +// Adobe DNG + void adobe_copy_pixel (unsigned int row, unsigned int col, ushort **rp); + void lossless_dng_load_raw(); + void deflate_dng_load_raw(); + void packed_dng_load_raw(); + void packed_tiled_dng_load_raw(); + void uncompressed_fp_dng_load_raw(); + void lossy_dng_load_raw(); +//void adobe_dng_load_raw_nc(); + +// Pentax + void pentax_load_raw(); + void pentax_4shot_load_raw(); + + void pentax_tree(); + +// Nikon (and Minolta Z2) + void nikon_load_raw(); + void nikon_he_load_raw_placeholder(); + void nikon_read_curve(); + void nikon_load_striped_packed_raw(); + void nikon_load_padded_packed_raw(); + void nikon_load_sraw(); + void nikon_yuv_load_raw(); + void nikon_coolscan_load_raw(); + int nikon_e995(); + int nikon_e2100(); + void nikon_3700(); + int minolta_z2(); +// void nikon_e2100_load_raw(); + +// Fuji +// void fuji_load_raw(); + int guess_RAFDataGeneration (uchar *RAFData_start); + void parse_fuji (int offset); + void parse_fuji_thumbnail(int offset); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +// RedCine + void parse_redcine(); + void redcine_load_raw(); +#endif + +// Rollei + void rollei_load_raw(); + void parse_rollei(); + +// Contax + void parse_kyocera (); + +// MF backs +//int bayer (unsigned row, unsigned col); + int p1raw(unsigned,unsigned); + void phase_one_flat_field (int is_float, int nc); + int p1rawc(unsigned row, unsigned col, unsigned& count); + void phase_one_fix_col_pixel_avg(unsigned row, unsigned col); + void phase_one_fix_pixel_grad(unsigned row, unsigned col); + void phase_one_load_raw(); + unsigned ph1_bits (int nbits); + void phase_one_load_raw_c(); + void phase_one_load_raw_s(); + void hasselblad_load_raw(); + void leaf_hdr_load_raw(); + void sinar_4shot_load_raw(); + void imacon_full_load_raw(); + void hasselblad_full_load_raw(); + void packed_load_raw(); + float find_green(int,int,int,int); + void unpacked_load_raw(); + void unpacked_load_raw_FujiDBP(); + void unpacked_load_raw_reversed(); + void unpacked_load_raw_fuji_f700s20(); + void parse_sinar_ia(); + void parse_phase_one (int base); + +// Misc P&S cameras + void parse_broadcom(); + void broadcom_load_raw(); + void nokia_load_raw(); + void android_loose_load_raw(); + void android_tight_load_raw(); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + void canon_rmf_load_raw(); +#endif + unsigned pana_data (int nb, unsigned *bytes); + void panasonic_load_raw(); +// void panasonic_16x10_load_raw(); + void olympus_load_raw(); +// void olympus_cseries_load_raw(); + void minolta_rd175_load_raw(); + void quicktake_100_load_raw(); + const int* make_decoder_int (const int *source, int level); + int radc_token (int tree); + void kodak_radc_load_raw(); + void kodak_jpeg_load_raw(); + void kodak_dc120_load_raw(); + void eight_bit_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 parse_riff(int maxdepth); + void parse_cine(); + void parse_smal (int offset, int fsize); + int parse_jpeg (int offset); + +// Kodak + void kodak_262_load_raw(); + int kodak_65000_decode (short *out, int bsize); + void kodak_65000_load_raw(); + void kodak_rgb_load_raw(); + void kodak_ycbcr_load_raw(); +// void kodak_yrgb_load_raw(); + void kodak_c330_load_raw(); + void kodak_c603_load_raw(); + void kodak_rgb_load_thumb(); + void kodak_ycbcr_load_thumb(); + void vc5_dng_load_raw_placeholder(); +// It's a Sony (and K&M) + void sony_decrypt (unsigned *data, int len, int start, int key); + void sony_load_raw(); + void sony_arw_load_raw(); + void sony_arw2_load_raw(); + void sony_arq_load_raw(); + void sony_ljpeg_load_raw(); + void samsung_load_raw(); + void samsung2_load_raw(); + void samsung3_load_raw(); + void parse_minolta (int base); + +#ifdef USE_X3FTOOLS +// Foveon/Sigma +// We always have x3f code compiled in! + void parse_x3f(); + void x3f_load_raw(); + void x3f_dpq_interpolate_rg(); + void x3f_dpq_interpolate_af(int xstep, int ystep, int scale); // 1x1 af pixels + void x3f_dpq_interpolate_af_sd(int xstart,int ystart, int xend, int yend, int xstep, int ystep, int scale); // sd Quattro interpolation +#else + void parse_x3f() {} + void x3f_load_raw(){} +#endif +#ifdef USE_6BY9RPI + void rpi_load_raw8(); + void rpi_load_raw12(); + void rpi_load_raw14(); + void rpi_load_raw16(); + void parse_raspberrypi(); +#endif + +// CAM/RGB + void pseudoinverse (double (*in)[3], double (*out)[3], int size); + void simple_coeff (int index); + +// Openp + char** malloc_omp_buffers(int buffer_count, size_t buffer_size); + void free_omp_buffers(char** buffers, int buffer_count); + + +// Tiff/Exif parsers + void tiff_get (unsigned base,unsigned *tag, unsigned *type, unsigned *len, unsigned *save); + short tiff_sget(unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset, + unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, + unsigned *tag_datalen, int *tag_dataunit_len); + void parse_thumb_note (int base, unsigned toff, unsigned tlen); + void parse_makernote (int base, int uptag); + void parse_makernote_0xc634(int base, int uptag, unsigned dng_writer); + void parse_exif (int base); + void parse_exif_interop(int base); + void linear_table(unsigned len); + void Kodak_DCR_WBtags(int wb, unsigned type, int wbi); + void Kodak_KDC_WBtags(int wb, int wbi); + short KodakIllumMatrix (unsigned type, float *romm_camIllum); + void parse_kodak_ifd (int base); + int parse_tiff_ifd (int base); + int parse_tiff (int base); + void apply_tiff(void); + void parse_gps (int base); + void parse_gps_libraw(int base); + void aRGB_coeff(double aRGB_cam[3][3]); + void romm_coeff(float romm_cam[3][3]); + void parse_mos (INT64 offset); + void parse_qt (int end); + void get_timestamp (int reversed); + +// The identify + short guess_byte_order (int words); + void identify_process_dng_fields(); + void identify_finetune_pentax(); + void identify_finetune_by_filesize(int); + void identify_finetune_dcr(char head[64],int,int); +// Tiff writer + void tiff_set(struct tiff_hdr *th, ushort *ntag,ushort tag, ushort type, int count, int val); + void tiff_head (struct tiff_hdr *th, int full); + +// split AHD code + void ahd_interpolate_green_h_and_v(int top, int left, ushort (*out_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]); + void ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][3]); + void ahd_interpolate_r_and_b_and_convert_to_cielab(int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], short (*out_lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]); + void ahd_interpolate_build_homogeneity_map(int top, int left, short (*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*out_homogeneity_map)[LIBRAW_AHD_TILE][2]); + void ahd_interpolate_combine_homogeneous_pixels(int top, int left, ushort (*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], char (*homogeneity_map)[LIBRAW_AHD_TILE][2]); + + void init_fuji_compr(struct fuji_compressed_params* info); + void init_fuji_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, INT64 raw_offset, unsigned dsize); + void copy_line_to_xtrans(struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width); + void copy_line_to_bayer(struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width); + void xtrans_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); + void fuji_bayer_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, int cur_line); + void fuji_compressed_load_raw(); + void fuji_14bit_load_raw(); + void parse_fuji_compressed_header(); + void crxLoadRaw(); + int crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size); + void panasonicC6_load_raw(); + void panasonicC7_load_raw(); + + void nikon_14bit_load_raw(); + +// DCB + void dcb_pp(); + void dcb_copy_to_buffer(float (*image2)[3]); + void dcb_restore_from_buffer(float (*image2)[3]); + void dcb_color(); + void dcb_color_full(); + void dcb_map(); + void dcb_correction(); + void dcb_correction2(); + void dcb_refinement(); + void rgb_to_lch(double (*image3)[3]); + void lch_to_rgb(double (*image3)[3]); + void fbdd_correction(); + void fbdd_correction2(double (*image3)[3]); + void fbdd_green(); + void dcb_ver(float (*image3)[3]); + void dcb_hor(float (*image2)[3]); + void dcb_color2(float (*image2)[3]); + void dcb_color3(float (*image3)[3]); + void dcb_decide(float (*image2)[3], float (*image3)[3]); + void dcb_nyquist(); +#endif + +#endif diff --git a/internal/var_defines.h b/internal/var_defines.h new file mode 100644 index 000000000..71db9c3bd --- /dev/null +++ b/internal/var_defines.h @@ -0,0 +1,215 @@ +/* -*- C++ -*- + * File: var_defines.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw redefinitions of dcraw internal variables + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef VAR_DEFINES_H +#define VAR_DEFINES_H + + +// imgdata.idata +#define make (imgdata.idata.make) +#define model (imgdata.idata.model) +#define software (imgdata.idata.software) +#define is_raw (imgdata.idata.raw_count) +#define dng_version (imgdata.idata.dng_version) +#define is_foveon (imgdata.idata.is_foveon) +#define colors (imgdata.idata.colors) +#define cdesc (imgdata.idata.cdesc) +#define filters (imgdata.idata.filters) +#define xtrans (imgdata.idata.xtrans) +#define xtrans_abs (imgdata.idata.xtrans_abs) +#define xmpdata (imgdata.idata.xmpdata) +#define xmplen (imgdata.idata.xmplen) +//imgdata image +#define image (imgdata.image) +#define raw_image (imgdata.rawdata.raw_image) +#define color_image (imgdata.rawdata.color_image) +#define normalized_make (imgdata.idata.normalized_make) +#define normalized_model (imgdata.idata.normalized_model) +#define maker_index (imgdata.idata.maker_index) + +// imgdata.sizes +#define raw_height (imgdata.sizes.raw_height) +#define raw_width (imgdata.sizes.raw_width) +#define raw_pitch (imgdata.sizes.raw_pitch) +#define height (imgdata.sizes.height) +#define width (imgdata.sizes.width) +#define top_margin (imgdata.sizes.top_margin) +#define left_margin (imgdata.sizes.left_margin) +#define bottom_margin (imgdata.sizes.bottom_margin) +#define right_margin (imgdata.sizes.right_margin) +#define iheight (imgdata.sizes.iheight) +#define iwidth (imgdata.sizes.iwidth) +#define pixel_aspect (imgdata.sizes.pixel_aspect) +#define flip (imgdata.sizes.flip) +#define mask (imgdata.sizes.mask) +#define raw_stride (libraw_internal_data.unpacker_data.raw_stride) + +//imgdata.color +#define white (imgdata.color.white) +#define cam_mul (imgdata.color.cam_mul) +#define pre_mul (imgdata.color.pre_mul) +#define cmatrix (imgdata.color.cmatrix) +#define rgb_cam (imgdata.color.rgb_cam) +#ifndef SRC_USES_CURVE +#define curve (imgdata.color.curve) +#endif +#ifndef SRC_USES_BLACK +#define black (imgdata.color.black) +#define cblack (imgdata.color.cblack) +#endif +#define maximum (imgdata.color.maximum) +#define channel_maximum (imgdata.color.channel_maximum) +#define profile_length (imgdata.color.profile_length) +#define color_flags (imgdata.color.color_flags) +#define ph1 (imgdata.color.phase_one_data) +#define flash_used (imgdata.color.flash_used) +#define canon_ev (imgdata.color.canon_ev) +#define model2 (imgdata.color.model2) + +//imgdata.thumbnail +#define thumb_width (imgdata.thumbnail.twidth) +#define thumb_height (imgdata.thumbnail.theight) +#define thumb_length (imgdata.thumbnail.tlength) + + +//imgdata.others +#define iso_speed (imgdata.other.iso_speed) +#define shutter (imgdata.other.shutter) +#define aperture (imgdata.other.aperture) +#define focal_len (imgdata.other.focal_len) +#define timestamp (imgdata.other.timestamp) +#define shot_order (imgdata.other.shot_order) +#define gpsdata (imgdata.other.gpsdata) +#define desc (imgdata.other.desc) +#define artist (imgdata.other.artist) + +#define FujiCropMode (imgdata.makernotes.fuji.CropMode) + +//imgdata.output +#define greybox (imgdata.params.greybox) +#define cropbox (imgdata.params.cropbox) +#define aber (imgdata.params.aber) +#define gamm (imgdata.params.gamm) +#define user_mul (imgdata.params.user_mul) +#define shot_select (imgdata.rawparams.shot_select) +#define bright (imgdata.params.bright) +#define threshold (imgdata.params.threshold) +#define half_size (imgdata.params.half_size) +#define four_color_rgb (imgdata.params.four_color_rgb) +#define highlight (imgdata.params.highlight) +#define use_auto_wb (imgdata.params.use_auto_wb) +#define use_camera_wb (imgdata.params.use_camera_wb) +#define use_camera_matrix (imgdata.params.use_camera_matrix) +#define output_color (imgdata.params.output_color) +#define output_bps (imgdata.params.output_bps) +#define gamma_16bit (imgdata.params.gamma_16bit) +#define output_tiff (imgdata.params.output_tiff) +#define med_passes (imgdata.params.med_passes) +#define no_auto_bright (imgdata.params.no_auto_bright) +#define auto_bright_thr (imgdata.params.auto_bright_thr) +#define use_fuji_rotate (imgdata.params.use_fuji_rotate) +#define filtering_mode (imgdata.params.filtering_mode) + +// DCB +#define dcb_iterations (imgdata.params.iterations) +#define dcb_enhance_fl (imgdata.params.dcb_enhance) +#define fbdd_noiserd (imgdata.params.fbdd_noiserd) + +//libraw_internal_data.internal_data +#define meta_data (libraw_internal_data.internal_data.meta_data) +#define ifp libraw_internal_data.internal_data.input +#define ifname ((char*)libraw_internal_data.internal_data.input->fname()) +#define ofp libraw_internal_data.internal_data.output +#define profile_offset (libraw_internal_data.internal_data.profile_offset) +#define thumb_offset (libraw_internal_data.internal_data.toffset) +#define pana_black (libraw_internal_data.internal_data.pana_black) + +//libraw_internal_data.internal_output_params +#define mix_green (libraw_internal_data.internal_output_params.mix_green) +#define raw_color (libraw_internal_data.internal_output_params.raw_color) +#define use_gamma (libraw_internal_data.internal_output_params.use_gamma) +#define zero_is_bad (libraw_internal_data.internal_output_params.zero_is_bad) +#ifndef SRC_USES_SHRINK +#define shrink (libraw_internal_data.internal_output_params.shrink) +#endif +#define fuji_width (libraw_internal_data.internal_output_params.fuji_width) +#define thumb_format (libraw_internal_data.unpacker_data.thumb_format) + +//libraw_internal_data.output_data +#define histogram (libraw_internal_data.output_data.histogram) +#define oprof (libraw_internal_data.output_data.oprof) + +//libraw_internal_data.identify_data +#define exif_cfa (libraw_internal_data.identify_data.olympus_exif_cfa) +#define unique_id (libraw_internal_data.identify_data.unique_id) +#define OlyID (libraw_internal_data.identify_data.OlyID) +#define tiff_nifds (libraw_internal_data.identify_data.tiff_nifds) +#define tiff_flip (libraw_internal_data.identify_data.tiff_flip) +#define metadata_blocks (libraw_internal_data.identify_data.metadata_blocks) + +//libraw_internal_data.unpacker_data +#define order (libraw_internal_data.unpacker_data.order) +#define data_error (libraw_internal_data.unpacker_data.data_error) +#define cr2_slice (libraw_internal_data.unpacker_data.cr2_slice) +#define sraw_mul (libraw_internal_data.unpacker_data.sraw_mul) +#define kodak_cbpp (libraw_internal_data.unpacker_data.kodak_cbpp) +#define strip_offset (libraw_internal_data.unpacker_data.strip_offset) +#define data_offset (libraw_internal_data.unpacker_data.data_offset) +#define data_size (libraw_internal_data.unpacker_data.data_size) +#define meta_offset (libraw_internal_data.unpacker_data.meta_offset) +#define meta_length (libraw_internal_data.unpacker_data.meta_length) +#define thumb_misc (libraw_internal_data.unpacker_data.thumb_misc) +#define fuji_layout (libraw_internal_data.unpacker_data.fuji_layout) +#define tiff_samples (libraw_internal_data.unpacker_data.tiff_samples) +#define tiff_bps (libraw_internal_data.unpacker_data.tiff_bps) +#define tiff_compress (libraw_internal_data.unpacker_data.tiff_compress) +#define tiff_sampleformat (libraw_internal_data.unpacker_data.tiff_sampleformat) +#define zero_after_ff (libraw_internal_data.unpacker_data.zero_after_ff) +#define tile_width (libraw_internal_data.unpacker_data.tile_width) +#define tile_length (libraw_internal_data.unpacker_data.tile_length) +#define load_flags (libraw_internal_data.unpacker_data.load_flags) +#define pana_encoding (libraw_internal_data.unpacker_data.pana_encoding) +#define pana_bpp (libraw_internal_data.unpacker_data.pana_bpp) +#define CM_found (libraw_internal_data.unpacker_data.CM_found) + +#define is_NikonTransfer (libraw_internal_data.unpacker_data.is_NikonTransfer) +#define is_Olympus (libraw_internal_data.unpacker_data.is_Olympus) +#define OlympusDNG_SubDirOffsetValid (libraw_internal_data.unpacker_data.OlympusDNG_SubDirOffsetValid) +#define is_Sony (libraw_internal_data.unpacker_data.is_Sony) +#define is_PentaxRicohMakernotes (libraw_internal_data.unpacker_data.is_PentaxRicohMakernotes) +#define is_pana_raw (libraw_internal_data.unpacker_data.is_pana_raw) + + +#ifdef LIBRAW_IO_REDEFINED +#define fread(ptr,size,n,stream) stream->read(ptr,size,n) +#define fseek(stream,o,w) stream->seek(o,w) +#define fseeko(stream,o,w) stream->seek(o,w) +#define ftell(stream) stream->tell() +#define ftello(stream) stream->tell() +#define feof(stream) stream->eof() +#ifdef getc +#undef getc +#endif +#define getc(stream) stream->get_char() +#define fgetc(stream) stream->get_char() +#define fgetcb(stream) stream->get_char_buf() +#define fgets(str,n,stream) stream->gets(str,n) +#define fscanf(stream,fmt,ptr) stream->scanf_one(fmt,ptr) +#endif + +#endif diff --git a/internal/x3f_tools.h b/internal/x3f_tools.h new file mode 100644 index 000000000..84bb00c00 --- /dev/null +++ b/internal/x3f_tools.h @@ -0,0 +1,539 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + */ + +/* Library for accessing X3F Files +---------------------------------------------------------------- +BSD-style License +---------------------------------------------------------------- + +* Copyright (c) 2010, Roland Karlsson (roland@proxel.se) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the organization 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 ROLAND KARLSSON ''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 ROLAND KARLSSON 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. + +*/ + +#ifndef X3F_TOOLS_H +#define X3F_TOOLS_H + +#include +#include +#include +#include +#include +#include "../libraw/libraw_datastream.h" + +/* From X3F_IO.H */ + +#define SIZE_UNIQUE_IDENTIFIER 16 +#define SIZE_WHITE_BALANCE 32 +#define SIZE_COLOR_MODE 32 +#define NUM_EXT_DATA_2_1 32 +#define NUM_EXT_DATA_3_0 64 +#define NUM_EXT_DATA NUM_EXT_DATA_3_0 + +#define X3F_VERSION(MAJ, MIN) (uint32_t)(((MAJ) << 16) + MIN) +#define X3F_VERSION_2_0 X3F_VERSION(2, 0) +#define X3F_VERSION_2_1 X3F_VERSION(2, 1) +#define X3F_VERSION_2_2 X3F_VERSION(2, 2) +#define X3F_VERSION_2_3 X3F_VERSION(2, 3) +#define X3F_VERSION_3_0 X3F_VERSION(3, 0) +#define X3F_VERSION_4_0 X3F_VERSION(4, 0) + +/* Main file identifier */ +#define X3F_FOVb (uint32_t)(0x62564f46) +/* Directory identifier */ +#define X3F_SECd (uint32_t)(0x64434553) +/* Property section identifiers */ +#define X3F_PROP (uint32_t)(0x504f5250) +#define X3F_SECp (uint32_t)(0x70434553) +/* Image section identifiers */ +#define X3F_IMAG (uint32_t)(0x46414d49) +#define X3F_IMA2 (uint32_t)(0x32414d49) +#define X3F_SECi (uint32_t)(0x69434553) +/* CAMF section identifiers */ +#define X3F_CAMF (uint32_t)(0x464d4143) +#define X3F_SECc (uint32_t)(0x63434553) +/* CAMF entry identifiers */ +#define X3F_CMbP (uint32_t)(0x50624d43) +#define X3F_CMbT (uint32_t)(0x54624d43) +#define X3F_CMbM (uint32_t)(0x4d624d43) +#define X3F_CMb (uint32_t)(0x00624d43) +/* SDQ section identifiers ? - TODO */ +#define X3F_SPPA (uint32_t)(0x41505053) +#define X3F_SECs (uint32_t)(0x73434553) + +#define X3F_IMAGE_THUMB_PLAIN (uint32_t)(0x00020003) +#define X3F_IMAGE_THUMB_HUFFMAN (uint32_t)(0x0002000b) +#define X3F_IMAGE_THUMB_JPEG (uint32_t)(0x00020012) +#define X3F_IMAGE_THUMB_SDQ (uint32_t)(0x00020019) /* SDQ ? - TODO */ + +#define X3F_IMAGE_RAW_HUFFMAN_X530 (uint32_t)(0x00030005) +#define X3F_IMAGE_RAW_HUFFMAN_10BIT (uint32_t)(0x00030006) +#define X3F_IMAGE_RAW_TRUE (uint32_t)(0x0003001e) +#define X3F_IMAGE_RAW_MERRILL (uint32_t)(0x0001001e) +#define X3F_IMAGE_RAW_QUATTRO (uint32_t)(0x00010023) +#define X3F_IMAGE_RAW_SDQ (uint32_t)(0x00010025) +#define X3F_IMAGE_RAW_SDQH (uint32_t)(0x00010027) +#define X3F_IMAGE_RAW_SDQH2 (uint32_t)(0x00010029) + +#define X3F_IMAGE_HEADER_SIZE 28 +#define X3F_CAMF_HEADER_SIZE 28 +#define X3F_PROPERTY_LIST_HEADER_SIZE 24 + +typedef uint16_t utf16_t; + +typedef int bool_t; + +typedef enum x3f_extended_types_e +{ + X3F_EXT_TYPE_NONE = 0, + X3F_EXT_TYPE_EXPOSURE_ADJUST = 1, + X3F_EXT_TYPE_CONTRAST_ADJUST = 2, + X3F_EXT_TYPE_SHADOW_ADJUST = 3, + X3F_EXT_TYPE_HIGHLIGHT_ADJUST = 4, + X3F_EXT_TYPE_SATURATION_ADJUST = 5, + X3F_EXT_TYPE_SHARPNESS_ADJUST = 6, + X3F_EXT_TYPE_RED_ADJUST = 7, + X3F_EXT_TYPE_GREEN_ADJUST = 8, + X3F_EXT_TYPE_BLUE_ADJUST = 9, + X3F_EXT_TYPE_FILL_LIGHT_ADJUST = 10 +} x3f_extended_types_t; + +typedef struct x3f_property_s +{ + /* Read from file */ + uint32_t name_offset; + uint32_t value_offset; + + /* Computed */ + utf16_t *name; /* 0x0000 terminated UTF 16 */ + utf16_t *value; /* 0x0000 terminated UTF 16 */ +} x3f_property_t; + +typedef struct x3f_property_table_s +{ + uint32_t size; + x3f_property_t *element; +} x3f_property_table_t; + +typedef struct x3f_property_list_s +{ + /* 2.0 Fields */ + uint32_t num_properties; + uint32_t character_format; + uint32_t reserved; + uint32_t total_length; + + x3f_property_table_t property_table; + + void *data; + + uint32_t data_size; + +} x3f_property_list_t; + +typedef struct x3f_table8_s +{ + uint32_t size; + uint8_t *element; +} x3f_table8_t; + +typedef struct x3f_table16_s +{ + uint32_t size; + uint16_t *element; +} x3f_table16_t; + +typedef struct x3f_table32_s +{ + uint32_t size; + uint32_t *element; +} x3f_table32_t; + +typedef struct +{ + uint8_t *data; /* Pointer to actual image data */ + void *buf; /* Pointer to allocated buffer for free() */ + uint32_t rows; + uint32_t columns; + uint32_t channels; + uint32_t row_stride; +} x3f_area8_t; + +typedef struct +{ + uint16_t *data; /* Pointer to actual image data */ + void *buf; /* Pointer to allocated buffer for free() */ + uint32_t rows; + uint32_t columns; + uint32_t channels; + uint32_t row_stride; +} x3f_area16_t; + +#define UNDEFINED_LEAF 0xffffffff + +typedef struct x3f_huffnode_s +{ + struct x3f_huffnode_s *branch[2]; + uint32_t leaf; +} x3f_huffnode_t; + +typedef struct x3f_hufftree_s +{ + uint32_t free_node_index; /* Free node index in huffman tree array */ + uint32_t total_node_index; + x3f_huffnode_t *nodes; /* Coding tree */ +} x3f_hufftree_t; + +typedef struct x3f_true_huffman_element_s +{ + uint8_t code_size; + uint8_t code; +} x3f_true_huffman_element_t; + +typedef struct x3f_true_huffman_s +{ + uint32_t size; + x3f_true_huffman_element_t *element; +} x3f_true_huffman_t; + +/* 0=bottom, 1=middle, 2=top */ +#define TRUE_PLANES 3 + +typedef struct x3f_true_s +{ + uint16_t seed[TRUE_PLANES]; /* Always 512,512,512 */ + uint16_t unknown; /* Always 0 */ + x3f_true_huffman_t table; /* Huffman table - zero + terminated. size is the number of + leaves plus 1.*/ + + x3f_table32_t plane_size; /* Size of the 3 planes */ + uint8_t *plane_address[TRUE_PLANES]; /* computed offset to the planes */ + x3f_hufftree_t tree; /* Coding tree */ + x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ +} x3f_true_t; + +typedef struct x3f_quattro_s +{ + struct + { + uint16_t columns; + uint16_t rows; + } plane[TRUE_PLANES]; + uint32_t unknown; + + bool_t quattro_layout; + x3f_area16_t top16; /* Container for the bigger top layer */ +} x3f_quattro_t; + +typedef struct x3f_huffman_s +{ + x3f_table16_t mapping; /* Value Mapping = X3F lossy compression */ + x3f_table32_t table; /* Coding Table */ + x3f_hufftree_t tree; /* Coding tree */ + x3f_table32_t row_offsets; /* Row offsets */ + x3f_area8_t rgb8; /* 3x8 bit RGB data */ + x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ +} x3f_huffman_t; + +typedef struct x3f_image_data_s +{ + /* 2.0 Fields */ + /* ------------------------------------------------------------------ */ + /* Known combinations of type and format are: + 1-6, 2-3, 2-11, 2-18, 3-6 */ + uint32_t type; /* 1 = RAW X3 (SD1) + 2 = thumbnail or maybe just RGB + 3 = RAW X3 */ + uint32_t format; /* 3 = 3x8 bit pixmap + 6 = 3x10 bit huffman with map table + 11 = 3x8 bit huffman + 18 = JPEG */ + uint32_t type_format; /* type<<16 + format */ + /* ------------------------------------------------------------------ */ + + uint32_t columns; /* width / row size in pixels */ + uint32_t rows; /* height */ + uint32_t row_stride; /* row size in bytes */ + + /* NULL if not used */ + x3f_huffman_t *huffman; /* Huffman help data */ + x3f_true_t *tru; /* TRUE help data */ + x3f_quattro_t *quattro; /* Quattro help data */ + + void *data; /* Take from file if NULL. Otherwise, + this is the actual data bytes in + the file. */ + uint32_t data_size; + +} x3f_image_data_t; + +typedef struct camf_dim_entry_s +{ + uint32_t size; + uint32_t name_offset; + uint32_t n; /* 0,1,2,3... */ + char *name; +} camf_dim_entry_t; + +typedef enum +{ + M_FLOAT, + M_INT, + M_UINT +} matrix_type_t; + +typedef struct camf_entry_s +{ + /* pointer into decoded data */ + void *entry; + + /* entry header */ + uint32_t id; + uint32_t version; + uint32_t entry_size; + uint32_t name_offset; + uint32_t value_offset; + + /* computed values */ + char *name_address; + void *value_address; + uint32_t name_size; + uint32_t value_size; + + /* extracted values for explicit CAMF entry types*/ + uint32_t text_size; + char *text; + + uint32_t property_num; + char **property_name; + uint8_t **property_value; + + uint32_t matrix_dim; + camf_dim_entry_t *matrix_dim_entry; + + /* Offset, pointer and size and type of raw data */ + uint32_t matrix_type; + uint32_t matrix_data_off; + void *matrix_data; + uint32_t matrix_element_size; + + /* Pointer and type of copied data */ + matrix_type_t matrix_decoded_type; + void *matrix_decoded; + + /* Help data to try to estimate element size */ + uint32_t matrix_elements; + uint32_t matrix_used_space; + double matrix_estimated_element_size; + +} camf_entry_t; + +typedef struct camf_entry_table_s +{ + uint32_t size; + camf_entry_t *element; +} camf_entry_table_t; + +typedef struct x3f_camf_typeN_s +{ + uint32_t val0; + uint32_t val1; + uint32_t val2; + uint32_t val3; +} x3f_camf_typeN_t; + +typedef struct x3f_camf_type2_s +{ + uint32_t reserved; + uint32_t infotype; + uint32_t infotype_version; + uint32_t crypt_key; +} x3f_camf_type2_t; + +typedef struct x3f_camf_type4_s +{ + uint32_t decoded_data_size; + uint32_t decode_bias; + uint32_t block_size; + uint32_t block_count; +} x3f_camf_type4_t; + +typedef struct x3f_camf_type5_s +{ + uint32_t decoded_data_size; + uint32_t decode_bias; + uint32_t unknown2; + uint32_t unknown3; +} x3f_camf_type5_t; + +typedef struct x3f_camf_s +{ + + /* Header info */ + uint32_t type; + union { + x3f_camf_typeN_t tN; + x3f_camf_type2_t t2; + x3f_camf_type4_t t4; + x3f_camf_type5_t t5; + }; + + /* The encrypted raw data */ + void *data; + uint32_t data_size; + + /* Help data for type 4 Huffman compression */ + x3f_true_huffman_t table; + x3f_hufftree_t tree; + uint8_t *decoding_start; + uint32_t decoding_size; + + /* The decrypted data */ + void *decoded_data; + uint32_t decoded_data_size; + + /* Pointers into the decrypted data */ + camf_entry_table_t entry_table; +} x3f_camf_t; + +typedef struct x3f_directory_entry_header_s +{ + uint32_t identifier; /* Should be ´SECp´, "SECi", ... */ + uint32_t version; /* 0x00020001 is version 2.1 */ + union { + x3f_property_list_t property_list; + x3f_image_data_t image_data; + x3f_camf_t camf; + } data_subsection; +} x3f_directory_entry_header_t; + +typedef struct x3f_directory_entry_s +{ + struct + { + uint32_t offset; + uint32_t size; + } input, output; + + uint32_t type; + + x3f_directory_entry_header_t header; +} x3f_directory_entry_t; + +typedef struct x3f_directory_section_s +{ + uint32_t identifier; /* Should be ´SECd´ */ + uint32_t version; /* 0x00020001 is version 2.1 */ + + /* 2.0 Fields */ + uint32_t num_directory_entries; + x3f_directory_entry_t *directory_entry; +} x3f_directory_section_t; + +typedef struct x3f_header_s +{ + /* 2.0 Fields */ + uint32_t identifier; /* Should be ´FOVb´ */ + uint32_t version; /* 0x00020001 means 2.1 */ + uint8_t unique_identifier[SIZE_UNIQUE_IDENTIFIER]; + uint32_t mark_bits; + uint32_t columns; /* Columns and rows ... */ + uint32_t rows; /* ... before rotation */ + uint32_t rotation; /* 0, 90, 180, 270 */ + + char white_balance[SIZE_WHITE_BALANCE]; /* Introduced in 2.1 */ + char color_mode[SIZE_COLOR_MODE]; /* Introduced in 2.3 */ + + /* Introduced in 2.1 and extended from 32 to 64 in 3.0 */ + uint8_t extended_types[NUM_EXT_DATA]; /* x3f_extended_types_t */ + float extended_data[NUM_EXT_DATA]; /* 32 bits, but do type differ? */ +} x3f_header_t; + +typedef struct x3f_info_s +{ + char *error; + struct + { + LibRaw_abstract_datastream *file; /* Use if more data is needed */ + } input, output; +} x3f_info_t; + +typedef struct x3f_s +{ + x3f_info_t info; + x3f_header_t header; + x3f_directory_section_t directory_section; +} x3f_t; + +typedef enum x3f_return_e +{ + X3F_OK = 0, + X3F_ARGUMENT_ERROR = 1, + X3F_INFILE_ERROR = 2, + X3F_OUTFILE_ERROR = 3, + X3F_INTERNAL_ERROR = 4 +} x3f_return_t; + +x3f_return_t x3f_delete(x3f_t *x3f); + +/* Hacky external flags */ +/* --------------------------------------------------------------------- */ + +extern int legacy_offset; +extern bool_t auto_legacy_offset; + +/* --------------------------------------------------------------------- */ +/* Huffman Decode Macros */ +/* --------------------------------------------------------------------- */ + +#define HUF_TREE_MAX_LENGTH 27 +#define HUF_TREE_MAX_NODES(_leaves) ((HUF_TREE_MAX_LENGTH + 1) * (_leaves)) +#define HUF_TREE_GET_LENGTH(_v) (((_v) >> 27) & 0x1f) +#define HUF_TREE_GET_CODE(_v) ((_v)&0x07ffffff) + +x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile); +x3f_return_t x3f_delete(x3f_t *x3f); +x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f); +x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f); +x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE); +x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f); +x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f); +x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f); +x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f); +/* extern */ int64_t x3f_load_data_size(x3f_t *x3f, x3f_directory_entry_t *DE); + +#endif diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 000000000..a49e51164 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,3 @@ +all: + @(cd ..; make library) + @echo Done diff --git a/libraw.pc.in b/libraw.pc.in new file mode 100644 index 000000000..c95fbc488 --- /dev/null +++ b/libraw.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libraw +Description: Raw image decoder library (non-thread-safe) +Requires: @PACKAGE_REQUIRES@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lraw -lstdc++@PC_OPENMP@ +Libs.private: @PACKAGE_LIBS_PRIVATE@ +Cflags: -I${includedir}/libraw -I${includedir} diff --git a/libraw/libraw.h b/libraw/libraw.h new file mode 100644 index 000000000..50d4276d4 --- /dev/null +++ b/libraw/libraw.h @@ -0,0 +1,534 @@ +/* -*- C++ -*- + * File: libraw.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw C++ interface + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +*/ + +#ifndef _LIBRAW_CLASS_H +#define _LIBRAW_CLASS_H + +#ifdef __linux__ +#define _FILE_OFFSET_BITS 64 +#endif + +// Enable use old cinema cameras if USE_OLD_VIDEOCAMS defined +#ifdef USE_OLD_VIDEOCAMS +#define LIBRAW_OLD_VIDEO_SUPPORT +#endif + +#ifndef LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM +#define LIBRAW_NO_IOSTREAMS_DATASTREAM +#endif + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM +/* maximum file size to use LibRaw_file_datastream (fully buffered) I/O */ +#define LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE (250 * 1024L * 1024L) +#endif + +#include +#include +#include +#include +#include + +/* better WIN32 defines */ + +/* better WIN32 defines */ + +#if defined(WIN32) || defined(_WIN32) + +/* Win32 API */ +# ifndef LIBRAW_WIN32_CALLS +# define LIBRAW_WIN32_CALLS +# endif + +/* DLLs: Microsoft or Intel compiler */ +# if defined(_MSC_VER) || defined(__INTEL_COMPILER) +# ifndef LIBRAW_WIN32_DLLDEFS +# define LIBRAW_WIN32_DLLDEFS +# endif +#endif + +/* wchar_t* API for std::filebuf */ +# if (defined(_MSC_VER) && (_MSC_VER > 1310)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 910)) +# ifndef LIBRAW_WIN32_UNICODEPATHS +# define LIBRAW_WIN32_UNICODEPATHS +# endif +# elif _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T +# ifndef LIBRAW_WIN32_UNICODEPATHS +# define LIBRAW_WIN32_UNICODEPATHS +# endif +# elif defined(_LIBCPP_HAS_OPEN_WITH_WCHAR) +# ifndef LIBRAW_WIN32_UNICODEPATHS +# define LIBRAW_WIN32_UNICODEPATHS +# endif +# endif + +#endif + +#include "libraw_datastream.h" +#include "libraw_types.h" +#include "libraw_const.h" +#include "libraw_internal.h" +#include "libraw_alloc.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + DllDef const char *libraw_strerror(int errorcode); + DllDef const char *libraw_strprogress(enum LibRaw_progress); + /* LibRaw C API */ + DllDef libraw_data_t *libraw_init(unsigned int flags); + DllDef int libraw_open_file(libraw_data_t *, const char *); +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + DllDef int libraw_open_file_ex(libraw_data_t *, const char *, + INT64 max_buff_sz); +#endif +#if defined(_WIN32) || defined(WIN32) + DllDef int libraw_open_wfile(libraw_data_t *, const wchar_t *); +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + DllDef int libraw_open_wfile_ex(libraw_data_t *, const wchar_t *, + INT64 max_buff_sz); +#endif +#endif + + DllDef int libraw_open_buffer(libraw_data_t *, const void *buffer, size_t size); + DllDef int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, + unsigned datalen, ushort _raw_width, + ushort _raw_height, ushort _left_margin, + ushort _top_margin, ushort _right_margin, + ushort _bottom_margin, unsigned char procflags, + unsigned char bayer_battern, + unsigned unused_bits, unsigned otherflags, + unsigned black_level); + DllDef int libraw_unpack(libraw_data_t *); + DllDef int libraw_unpack_thumb(libraw_data_t *); + DllDef int libraw_unpack_thumb_ex(libraw_data_t *,int); + DllDef void libraw_recycle_datastream(libraw_data_t *); + DllDef void libraw_recycle(libraw_data_t *); + DllDef void libraw_close(libraw_data_t *); + DllDef void libraw_subtract_black(libraw_data_t *); + DllDef int libraw_raw2image(libraw_data_t *); + DllDef void libraw_free_image(libraw_data_t *); + /* version helpers */ + DllDef const char *libraw_version(); + DllDef int libraw_versionNumber(); + /* Camera list */ + DllDef const char **libraw_cameraList(); + DllDef int libraw_cameraCount(); + + /* helpers */ + DllDef void libraw_set_exifparser_handler(libraw_data_t *, + exif_parser_callback cb, + void *datap); + DllDef void libraw_set_dataerror_handler(libraw_data_t *, data_callback func, + void *datap); + DllDef void libraw_set_progress_handler(libraw_data_t *, progress_callback cb, + void *datap); + DllDef const char *libraw_unpack_function_name(libraw_data_t *lr); + DllDef int libraw_get_decoder_info(libraw_data_t *lr, + libraw_decoder_info_t *d); + DllDef int libraw_COLOR(libraw_data_t *, int row, int col); + DllDef unsigned libraw_capabilities(); + + /* DCRAW compatibility */ + DllDef int libraw_adjust_sizes_info_only(libraw_data_t *); + DllDef int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, + const char *filename); + DllDef int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname); + DllDef int libraw_dcraw_process(libraw_data_t *lr); + DllDef libraw_processed_image_t * + libraw_dcraw_make_mem_image(libraw_data_t *lr, int *errc); + DllDef libraw_processed_image_t * + libraw_dcraw_make_mem_thumb(libraw_data_t *lr, int *errc); + DllDef void libraw_dcraw_clear_mem(libraw_processed_image_t *); + /* getters/setters used by 3DLut Creator */ + DllDef void libraw_set_demosaic(libraw_data_t *lr, int value); + DllDef void libraw_set_output_color(libraw_data_t *lr, int value); + DllDef void libraw_set_adjust_maximum_thr(libraw_data_t *lr, float value); + DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val); + DllDef void libraw_set_output_bps(libraw_data_t *lr, int value); + DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value); + DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value); + DllDef void libraw_set_bright(libraw_data_t *lr, float value); + DllDef void libraw_set_highlight(libraw_data_t *lr, int value); + DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value); + DllDef int libraw_get_raw_height(libraw_data_t *lr); + DllDef int libraw_get_raw_width(libraw_data_t *lr); + DllDef int libraw_get_iheight(libraw_data_t *lr); + DllDef int libraw_get_iwidth(libraw_data_t *lr); + DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index); + DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index); + DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2); + DllDef int libraw_get_color_maximum(libraw_data_t *lr); + DllDef void libraw_set_output_tif(libraw_data_t *lr, int value); + DllDef libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr); + DllDef libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr); + DllDef libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +class DllDef LibRaw +{ +public: + libraw_data_t imgdata; + + LibRaw(unsigned int flags = LIBRAW_OPTIONS_NONE); + libraw_output_params_t *output_params_ptr() { return &imgdata.params; } +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + int open_file(const char *fname, + INT64 max_buffered_sz = LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE); +#if defined(_WIN32) || defined(WIN32) + int open_file(const wchar_t *fname, + INT64 max_buffered_sz = LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE); +#endif +#else + int open_file(const char *fname); +#if defined(_WIN32) || defined(WIN32) + int open_file(const wchar_t *fname); +#endif + +#endif + int open_buffer(const void *buffer, size_t size); + virtual int open_datastream(LibRaw_abstract_datastream *); + virtual int open_bayer(const unsigned char *data, unsigned datalen, + ushort _raw_width, ushort _raw_height, + ushort _left_margin, ushort _top_margin, + ushort _right_margin, ushort _bottom_margin, + unsigned char procflags, unsigned char bayer_pattern, + unsigned unused_bits, unsigned otherflags, + unsigned black_level); + int error_count() { return libraw_internal_data.unpacker_data.data_error; } + void recycle_datastream(); + int unpack(void); + int unpack_thumb(void); + int unpack_thumb_ex(int); + int thumbOK(INT64 maxsz = -1); + int adjust_sizes_info_only(void); + int subtract_black(); + int subtract_black_internal(); + int raw2image(); + int raw2image_ex(int do_subtract_black); + void raw2image_start(); + void free_image(); + int adjust_maximum(); + int adjust_to_raw_inset_crop(unsigned mask, float maxcrop = 0.55f); + void set_exifparser_handler(exif_parser_callback cb, void *data) + { + callbacks.exifparser_data = data; + callbacks.exif_cb = cb; + } + void set_dataerror_handler(data_callback func, void *data) + { + callbacks.datacb_data = data; + callbacks.data_cb = func; + } + void set_progress_handler(progress_callback pcb, void *data) + { + callbacks.progresscb_data = data; + callbacks.progress_cb = pcb; + } + + static const char* cameramakeridx2maker(unsigned maker); + int setMakeFromIndex(unsigned index); + + void convertFloatToInt(float dmin = 4096.f, float dmax = 32767.f, + float dtarget = 16383.f); + /* helpers */ + static unsigned capabilities(); + static const char *version(); + static int versionNumber(); + static const char **cameraList(); + static int cameraCount(); + static const char *strprogress(enum LibRaw_progress); + static const char *strerror(int p); + /* dcraw emulation */ + int dcraw_ppm_tiff_writer(const char *filename); + int dcraw_thumb_writer(const char *fname); + int dcraw_process(void); + /* information calls */ + int is_fuji_rotated() + { + return libraw_internal_data.internal_output_params.fuji_width; + } + int is_sraw(); + int sraw_midpoint(); + int is_nikon_sraw(); + int is_coolscan_nef(); + int is_jpeg_thumb(); + int is_floating_point(); + int have_fpdata(); + /* memory writers */ + virtual libraw_processed_image_t *dcraw_make_mem_image(int *errcode = NULL); + virtual libraw_processed_image_t *dcraw_make_mem_thumb(int *errcode = NULL); + static void dcraw_clear_mem(libraw_processed_image_t *); + + /* Additional calls for make_mem_image */ + void get_mem_image_format(int *width, int *height, int *colors, + int *bps) const; + int copy_mem_image(void *scan0, int stride, int bgr); + + /* free all internal data structures */ + void recycle(); + virtual ~LibRaw(void); + + int COLOR(int row, int col) + { + if (!imgdata.idata.filters) + return 6; /* Special value 0+1+2+3 */ + if (imgdata.idata.filters < 1000) + return fcol(row, col); + return libraw_internal_data.internal_output_params.fuji_width + ? FCF(row, col) + : FC(row, col); + } + + int FC(int row, int col) + { + return (imgdata.idata.filters >> (((row << 1 & 14) | (col & 1)) << 1) & 3); + } + int fcol(int row, int col); + + const char *unpack_function_name(); + virtual int get_decoder_info(libraw_decoder_info_t *d_info); + libraw_internal_data_t *get_internal_data_pointer() + { + return &libraw_internal_data; + } + + static float powf_lim(float a, float b, float limup) + { + return (b > limup || b < -limup) ? 0.f : powf(a, b); + } + static float libraw_powf64l(float a, float b) { return powf_lim(a, b, 64.f); } + + static unsigned sgetn(int n, uchar *s) + { + unsigned result = 0; + while (n-- > 0) + result = (result << 8) | (*s++); + return result; + } + + /* Phase one correction/subtractBL calls */ + /* Returns libraw error code */ + + int phase_one_subtract_black(ushort *src, ushort *dest); + int phase_one_correct(); + + int set_rawspeed_camerafile(char *filename); + virtual void setCancelFlag(); + virtual void clearCancelFlag(); + virtual int adobe_coeff(unsigned, const char *, int internal_only = 0); + + void set_dng_host(void *); + +protected: + static void *memmem(char *haystack, size_t haystacklen, char *needle, + size_t needlelen); + static char *strcasestr(char *h, const char *n); + static size_t strnlen(const char *s, size_t n); + +#ifdef LIBRAW_NO_IOSTREAMS_DATASTREAM + int libraw_openfile_tail(LibRaw_abstract_datastream *stream); +#endif + + int is_curve_linear(); + void checkCancel(); + void cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]); + void phase_one_allocate_tempbuffer(); + void phase_one_free_tempbuffer(); + virtual int is_phaseone_compressed(); + virtual int is_canon_600(); + /* Hotspots */ + virtual void copy_fuji_uncropped(unsigned short cblack[4], + unsigned short *dmaxp); + virtual void copy_bayer(unsigned short cblack[4], unsigned short *dmaxp); + virtual void fuji_rotate(); + virtual void convert_to_rgb_loop(float out_cam[3][4]); + virtual void lin_interpolate_loop(int *code, int size); + virtual void scale_colors_loop(float scale_mul[4]); + + /* Fujifilm compressed decoder public interface (to make parallel decoder) */ + virtual void + fuji_decode_loop(struct fuji_compressed_params *common_info, int count, + INT64 *offsets, unsigned *sizes, uchar *q_bases); + void fuji_decode_strip(struct fuji_compressed_params *info_common, + int cur_block, INT64 raw_offset, unsigned size, uchar *q_bases); + /* CR3 decoder public interface to make parallel decoder */ + virtual void crxLoadDecodeLoop(void *, int); + int crxDecodePlane(void *, uint32_t planeNumber); + virtual void crxLoadFinalizeLoopE3(void *, int); + void crxConvertPlaneLineDf(void *, int); + + int FCF(int row, int col) + { + int rr, cc; + if (libraw_internal_data.unpacker_data.fuji_layout) + { + rr = libraw_internal_data.internal_output_params.fuji_width - 1 - col + + (row >> 1); + cc = col + ((row + 1) >> 1); + } + else + { + rr = libraw_internal_data.internal_output_params.fuji_width - 1 + row - + (col >> 1); + cc = row + ((col + 1) >> 1); + } + return FC(rr, cc); + } + + void adjust_bl(); + void *malloc(size_t t); + void *calloc(size_t n, size_t t); + void *realloc(void *p, size_t s); + void free(void *p); + void derror(); + + LibRaw_TLS *tls; + libraw_internal_data_t libraw_internal_data; + decode first_decode[2048], *second_decode, *free_decode; + tiff_ifd_t tiff_ifd[LIBRAW_IFD_MAXCOUNT]; + libraw_memmgr memmgr; + libraw_callbacks_t callbacks; + + //void (LibRaw::*write_thumb)(); + void (LibRaw::*write_fun)(); + void (LibRaw::*load_raw)(); + //void (LibRaw::*thumb_load_raw)(); + void (LibRaw::*pentax_component_load_raw)(); + + void kodak_thumb_loader(); + void write_thumb_ppm_tiff(FILE *); +#ifdef USE_X3FTOOLS + void x3f_thumb_loader(); + INT64 x3f_thumb_size(); +#endif + + int own_filtering_supported() { return 0; } + void identify(); + void initdata(); + unsigned parse_custom_cameras(unsigned limit, libraw_custom_camera_t table[], + char **list); + void write_ppm_tiff(); + void convert_to_rgb(); + void remove_zeroes(); + void crop_masked_pixels(); +#ifndef NO_LCMS + void apply_profile(const char *, const char *); +#endif + void pre_interpolate(); + void border_interpolate(int border); + void lin_interpolate(); + void vng_interpolate(); + void ppg_interpolate(); + void cielab(ushort rgb[3], short lab[3]); + void xtrans_interpolate(int); + void ahd_interpolate(); + void dht_interpolate(); + void aahd_interpolate(); + + void dcb(int iterations, int dcb_enhance); + void fbdd(int noiserd); + void exp_bef(float expos, float preser); + + void bad_pixels(const char *); + void subtract(const char *); + void hat_transform(float *temp, float *base, int st, int size, int sc); + void wavelet_denoise(); + void scale_colors(); + void median_filter(); + void blend_highlights(); + void recover_highlights(); + void green_matching(); + + void stretch(); + + void jpeg_thumb_writer(FILE *tfp, char *thumb, int thumb_length); +#if 0 + void jpeg_thumb(); + void ppm_thumb(); + void ppm16_thumb(); + void layer_thumb(); + void rollei_thumb(); +#endif + void kodak_thumb_load_raw(); + + unsigned get4(); + + int flip_index(int row, int col); + void gamma_curve(double pwr, double ts, int mode, int imax); + void cubic_spline(const int *x_, const int *y_, const int len); + + /* RawSpeed data */ + void *_rawspeed_camerameta; + void *_rawspeed_decoder; + void *_rawspeed3_handle; + void fix_after_rawspeed(int bl); + int try_rawspeed(); /* returns LIBRAW_SUCCESS on success */ + /* Fast cancel flag */ + long _exitflag; + + /* DNG SDK data */ + void *dnghost; + void *dngnegative; + void *dngimage; + int valid_for_dngsdk(); + int try_dngsdk(); + /* X3F data */ + void *_x3f_data; /* keep it even if USE_X3FTOOLS is not defined to do not change sizeof(LibRaw)*/ + + int raw_was_read() + { + return imgdata.rawdata.raw_image || imgdata.rawdata.color4_image || + imgdata.rawdata.color3_image || imgdata.rawdata.float_image || + imgdata.rawdata.float3_image || imgdata.rawdata.float4_image; + } + +#ifdef LIBRAW_LIBRARY_BUILD +#include "internal/libraw_internal_funcs.h" +#endif +}; + +#ifdef LIBRAW_LIBRARY_BUILD +ushort libraw_sget2_static(short _order, uchar *s); +unsigned libraw_sget4_static(short _order, uchar *s); +int libraw_tagtype_dataunit_bytes(int tagtype); +double libraw_sgetreal_static(short _order, int type, uchar *s); +float libraw_int_to_float (int i); +#endif + + +#ifdef LIBRAW_LIBRARY_BUILD +#define RUN_CALLBACK(stage, iter, expect) \ + if (callbacks.progress_cb) \ + { \ + int rr = (*callbacks.progress_cb)(callbacks.progresscb_data, stage, iter, \ + expect); \ + if (rr != 0) \ + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; \ + } +#endif + +#endif /* __cplusplus */ + +#endif /* _LIBRAW_CLASS_H */ diff --git a/libraw/libraw_alloc.h b/libraw/libraw_alloc.h new file mode 100644 index 000000000..c22d99586 --- /dev/null +++ b/libraw/libraw_alloc.h @@ -0,0 +1,148 @@ +/* -*- C++ -*- + * File: libraw_alloc.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 22, 2008 + * + * LibRaw C++ interface + * +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef __LIBRAW_ALLOC_H +#define __LIBRAW_ALLOC_H + +#include +#include +#include "libraw_const.h" + +#ifdef __cplusplus + +#define LIBRAW_MSIZE 512 + +class DllDef libraw_memmgr +{ +public: + libraw_memmgr(unsigned ee) : extra_bytes(ee) + { + size_t alloc_sz = LIBRAW_MSIZE * sizeof(void *); + mems = (void **)::malloc(alloc_sz); + memset(mems, 0, alloc_sz); + } + ~libraw_memmgr() + { + cleanup(); + ::free(mems); + } + void *malloc(size_t sz) + { +#ifdef LIBRAW_USE_CALLOC_INSTEAD_OF_MALLOC + void *ptr = ::calloc(sz + extra_bytes, 1); +#else + void *ptr = ::malloc(sz + extra_bytes); +#endif + mem_ptr(ptr); + return ptr; + } + void *calloc(size_t n, size_t sz) + { + void *ptr = ::calloc(n + (extra_bytes + sz - 1) / (sz ? sz : 1), sz); + mem_ptr(ptr); + return ptr; + } + void *realloc(void *ptr, size_t newsz) + { + void *ret = ::realloc(ptr, newsz + extra_bytes); + forget_ptr(ptr); + mem_ptr(ret); + return ret; + } + void free(void *ptr) + { + forget_ptr(ptr); + ::free(ptr); + } + void cleanup(void) + { + for (int i = 0; i < LIBRAW_MSIZE; i++) + if (mems[i]) + { + ::free(mems[i]); + mems[i] = NULL; + } + } + +private: + void **mems; + unsigned extra_bytes; + void mem_ptr(void *ptr) + { +#if defined(LIBRAW_USE_OPENMP) + bool ok = false; /* do not return from critical section */ +#endif + +#if defined(LIBRAW_USE_OPENMP) +#pragma omp critical + { +#endif + if (ptr) + { + for (int i = 0; i < LIBRAW_MSIZE - 1; i++) + if (!mems[i]) + { + mems[i] = ptr; +#if defined(LIBRAW_USE_OPENMP) + ok = true; + break; +#else + return; +#endif + } +#ifdef LIBRAW_MEMPOOL_CHECK +#if !defined(LIBRAW_USE_OPENMP) + /* remember ptr in last mems item to be free'ed at cleanup */ + if (!mems[LIBRAW_MSIZE - 1]) + mems[LIBRAW_MSIZE - 1] = ptr; + throw LIBRAW_EXCEPTION_MEMPOOL; +#endif +#endif + } +#if defined(LIBRAW_USE_OPENMP) + } + if(!ok) + { + if (!mems[LIBRAW_MSIZE - 1]) + mems[LIBRAW_MSIZE - 1] = ptr; + throw LIBRAW_EXCEPTION_MEMPOOL; + } +#endif + } + void forget_ptr(void *ptr) + { +#if defined(LIBRAW_USE_OPENMP) +#pragma omp critical + { +#endif + if (ptr) + for (int i = 0; i < LIBRAW_MSIZE; i++) + if (mems[i] == ptr) + { + mems[i] = NULL; + break; + } +#if defined(LIBRAW_USE_OPENMP) + } +#endif + } +}; + +#endif /* C++ */ + +#endif diff --git a/libraw/libraw_const.h b/libraw/libraw_const.h new file mode 100644 index 000000000..599306b6f --- /dev/null +++ b/libraw/libraw_const.h @@ -0,0 +1,810 @@ +/* -*- C++ -*- + * File: libraw_const.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8 , 2008 + * LibRaw error codes +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef _LIBRAW_ERRORS_H +#define _LIBRAW_ERRORS_H + +#define LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD 0.75f +#define LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD 0.01f +/* limit allocation size, default is 2Gb */ +#ifndef LIBRAW_MAX_ALLOC_MB_DEFAULT +#define LIBRAW_MAX_ALLOC_MB_DEFAULT 2048L +#endif + +#ifndef LIBRAW_MAX_NONDNG_RAW_FILE_SIZE +#define LIBRAW_MAX_NONDNG_RAW_FILE_SIZE 2147483647ULL +#endif + +#ifndef LIBRAW_MAX_DNG_RAW_FILE_SIZE +#ifdef USE_DNGSDK +#define LIBRAW_MAX_DNG_RAW_FILE_SIZE 4294967295ULL +#else +#define LIBRAW_MAX_DNG_RAW_FILE_SIZE 2147483647ULL +#endif +#endif + + +/* limit thumbnail size, default is 512Mb*/ +#ifndef LIBRAW_MAX_THUMBNAIL_MB +#define LIBRAW_MAX_THUMBNAIL_MB 512L +#endif + +/* Check if enough file space exists before tag read */ +#ifndef LIBRAW_NO_IOSPACE_CHECK +#define LIBRAW_IOSPACE_CHECK +#endif +#ifndef LIBRAW_NO_CR3_MEMPOOL +#define LIBRAW_CR3_MEMPOOL +#endif + + + +/* LibRaw uses own memory pool management, with LIBRAW_MSIZE (512) +entries. It is enough for parsing/decoding non-damaged files, but +may overflow on specially crafted files (eg. with many string values +like XMP blocks. +LIBRAW_MEMPOOL_CHECK define will result in error on pool overflow */ +#ifndef LIBRAW_NO_MEMPOOL_CHECK +#define LIBRAW_MEMPOOL_CHECK +#endif + +#define LIBRAW_MAX_METADATA_BLOCKS 1024 +#define LIBRAW_CBLACK_SIZE 4104 +#define LIBRAW_IFD_MAXCOUNT 10 +#define LIBRAW_THUMBNAIL_MAXCOUNT 8 +#define LIBRAW_CRXTRACKS_MAXCOUNT 16 +#define LIBRAW_AFDATA_MAXCOUNT 4 + +#define LIBRAW_AHD_TILE 512 + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + +enum LibRaw_open_flags +{ + LIBRAW_OPEN_BIGFILE=1, + LIBRAW_OPEN_FILE= 1<<1 +}; +#endif + +enum LibRaw_openbayer_patterns +{ + LIBRAW_OPENBAYER_RGGB = 0x94, + LIBRAW_OPENBAYER_BGGR = 0x16, + LIBRAW_OPENBAYER_GRBG = 0x61, + LIBRAW_OPENBAYER_GBRG = 0x49 +}; + +enum LibRaw_dngfields_marks +{ + LIBRAW_DNGFM_FORWARDMATRIX = 1, + LIBRAW_DNGFM_ILLUMINANT = 1 << 1, + LIBRAW_DNGFM_COLORMATRIX = 1 << 2, + LIBRAW_DNGFM_CALIBRATION = 1 << 3, + LIBRAW_DNGFM_ANALOGBALANCE = 1 << 4, + LIBRAW_DNGFM_BLACK = 1 << 5, + LIBRAW_DNGFM_WHITE = 1 << 6, + LIBRAW_DNGFM_OPCODE2 = 1 << 7, + LIBRAW_DNGFM_LINTABLE = 1 << 8, + LIBRAW_DNGFM_CROPORIGIN = 1 << 9, + LIBRAW_DNGFM_CROPSIZE = 1 << 10, + LIBRAW_DNGFM_PREVIEWCS = 1 << 11, + LIBRAW_DNGFM_ASSHOTNEUTRAL = 1 << 12, + LIBRAW_DNGFM_BASELINEEXPOSURE = 1 << 13, + LIBRAW_DNGFM_LINEARRESPONSELIMIT = 1 << 14, + LIBRAW_DNGFM_USERCROP = 1 << 15, + LIBRAW_DNGFM_OPCODE1 = 1 << 16, + LIBRAW_DNGFM_OPCODE3 = 1 << 17, +}; + +enum LibRaw_As_Shot_WB_Applied_codes +{ + LIBRAW_ASWB_APPLIED = 1, + LIBRAW_ASWB_CANON = 2, + LIBRAW_ASWB_NIKON = 4, + LIBRAW_ASWB_NIKON_SRAW = 8, + LIBRAW_ASWB_PENTAX = 16 +}; + +#define tagtypeIs(typex) (type == typex) +enum LibRaw_ExifTagTypes { + LIBRAW_EXIFTAG_TYPE_UNKNOWN = 0, + LIBRAW_EXIFTAG_TYPE_BYTE = 1, + LIBRAW_EXIFTAG_TYPE_ASCII = 2, + LIBRAW_EXIFTAG_TYPE_SHORT = 3, + LIBRAW_EXIFTAG_TYPE_LONG = 4, + LIBRAW_EXIFTAG_TYPE_RATIONAL = 5, + LIBRAW_EXIFTAG_TYPE_SBYTE = 6, + LIBRAW_EXIFTAG_TYPE_UNDEFINED = 7, + LIBRAW_EXIFTAG_TYPE_SSHORT = 8, + LIBRAW_EXIFTAG_TYPE_SLONG = 9, + LIBRAW_EXIFTAG_TYPE_SRATIONAL = 10, + LIBRAW_EXIFTAG_TYPE_FLOAT = 11, + LIBRAW_EXIFTAG_TYPE_DOUBLE = 12, + LIBRAW_EXIFTAG_TYPE_IFD = 13, + LIBRAW_EXIFTAG_TYPE_UNICODE = 14, + LIBRAW_EXIFTAG_TYPE_COMPLEX = 15, + LIBRAW_EXIFTAG_TYPE_LONG8 = 16, + LIBRAW_EXIFTAG_TYPE_SLONG8 = 17, + LIBRAW_EXIFTAG_TYPE_IFD8 = 18 +}; + +#define LIBRAW_EXIFTOOLTAGTYPE_int8u LIBRAW_EXIFTAG_TYPE_BYTE +#define LIBRAW_EXIFTOOLTAGTYPE_string LIBRAW_EXIFTAG_TYPE_ASCII +#define LIBRAW_EXIFTOOLTAGTYPE_int16u LIBRAW_EXIFTAG_TYPE_SHORT +#define LIBRAW_EXIFTOOLTAGTYPE_int32u LIBRAW_EXIFTAG_TYPE_LONG +#define LIBRAW_EXIFTOOLTAGTYPE_rational64u LIBRAW_EXIFTAG_TYPE_RATIONAL +#define LIBRAW_EXIFTOOLTAGTYPE_int8s LIBRAW_EXIFTAG_TYPE_SBYTE +#define LIBRAW_EXIFTOOLTAGTYPE_undef LIBRAW_EXIFTAG_TYPE_UNDEFINED +#define LIBRAW_EXIFTOOLTAGTYPE_binary LIBRAW_EXIFTAG_TYPE_UNDEFINED +#define LIBRAW_EXIFTOOLTAGTYPE_int16s LIBRAW_EXIFTAG_TYPE_SSHORT +#define LIBRAW_EXIFTOOLTAGTYPE_int32s LIBRAW_EXIFTAG_TYPE_SLONG +#define LIBRAW_EXIFTOOLTAGTYPE_rational64s LIBRAW_EXIFTAG_TYPE_SRATIONAL +#define LIBRAW_EXIFTOOLTAGTYPE_float LIBRAW_EXIFTAG_TYPE_FLOAT +#define LIBRAW_EXIFTOOLTAGTYPE_double LIBRAW_EXIFTAG_TYPE_DOUBLE +#define LIBRAW_EXIFTOOLTAGTYPE_ifd LIBRAW_EXIFTAG_TYPE_IFD +#define LIBRAW_EXIFTOOLTAGTYPE_unicode LIBRAW_EXIFTAG_TYPE_UNICODE +#define LIBRAW_EXIFTOOLTAGTYPE_complex LIBRAW_EXIFTAG_TYPE_COMPLEX +#define LIBRAW_EXIFTOOLTAGTYPE_int64u LIBRAW_EXIFTAG_TYPE_LONG8 +#define LIBRAW_EXIFTOOLTAGTYPE_int64s LIBRAW_EXIFTAG_TYPE_SLONG8 +#define LIBRAW_EXIFTOOLTAGTYPE_ifd64 LIBRAW_EXIFTAG_TYPE_IFD8 + +#define LIBRAW_LENS_NOT_SET 0xffffffffffffffffULL + +enum LibRaw_whitebalance_code +{ +// clang-format off + /* + EXIF light sources + 12 = FL-D; Daylight fluorescent (D 5700K – 7100K) (F1,F5) + 13 = FL-N; Day white fluorescent (N 4600K – 5400K) (F7,F8) + 14 = FL-W; Cool white fluorescent (W 3900K – 4500K) (F2,F6, office, store, warehouse) + 15 = FL-WW; White fluorescent (WW 3200K – 3700K) (F3, residential) + 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4, kitchen, bath) + */ +//clang-format on + LIBRAW_WBI_Unknown = 0, + LIBRAW_WBI_Daylight = 1, + LIBRAW_WBI_Fluorescent = 2, + LIBRAW_WBI_Tungsten = 3, + LIBRAW_WBI_Flash = 4, + LIBRAW_WBI_FineWeather = 9, + LIBRAW_WBI_Cloudy = 10, + LIBRAW_WBI_Shade = 11, + LIBRAW_WBI_FL_D = 12, + LIBRAW_WBI_FL_N = 13, + LIBRAW_WBI_FL_W = 14, + LIBRAW_WBI_FL_WW = 15, + LIBRAW_WBI_FL_L = 16, + LIBRAW_WBI_Ill_A = 17, + LIBRAW_WBI_Ill_B = 18, + LIBRAW_WBI_Ill_C = 19, + LIBRAW_WBI_D55 = 20, + LIBRAW_WBI_D65 = 21, + LIBRAW_WBI_D75 = 22, + LIBRAW_WBI_D50 = 23, + LIBRAW_WBI_StudioTungsten = 24, + LIBRAW_WBI_Sunset = 64, + LIBRAW_WBI_Underwater = 65, + LIBRAW_WBI_FluorescentHigh = 66, + LIBRAW_WBI_HT_Mercury = 67, + LIBRAW_WBI_AsShot = 81, + LIBRAW_WBI_Auto = 82, + LIBRAW_WBI_Custom = 83, + LIBRAW_WBI_Auto1 = 85, + LIBRAW_WBI_Auto2 = 86, + LIBRAW_WBI_Auto3 = 87, + LIBRAW_WBI_Auto4 = 88, + LIBRAW_WBI_Custom1 = 90, + LIBRAW_WBI_Custom2 = 91, + LIBRAW_WBI_Custom3 = 92, + LIBRAW_WBI_Custom4 = 93, + LIBRAW_WBI_Custom5 = 94, + LIBRAW_WBI_Custom6 = 95, + LIBRAW_WBI_PC_Set1 = 96, + LIBRAW_WBI_PC_Set2 = 97, + LIBRAW_WBI_PC_Set3 = 98, + LIBRAW_WBI_PC_Set4 = 99, + LIBRAW_WBI_PC_Set5 = 100, + LIBRAW_WBI_Measured = 110, + LIBRAW_WBI_BW = 120, + LIBRAW_WBI_Kelvin = 254, + LIBRAW_WBI_Other = 255, + LIBRAW_WBI_None = 0xffff +}; + +enum LibRaw_MultiExposure_related +{ + LIBRAW_ME_NONE = 0, + LIBRAW_ME_SIMPLE = 1, + LIBRAW_ME_OVERLAY = 2, + LIBRAW_ME_HDR = 3 +}; + +enum LibRaw_dng_processing +{ + LIBRAW_DNG_NONE = 0, + LIBRAW_DNG_FLOAT = 1, + LIBRAW_DNG_LINEAR = 2, + LIBRAW_DNG_DEFLATE = 4, + LIBRAW_DNG_XTRANS = 8, + LIBRAW_DNG_OTHER = 16, + LIBRAW_DNG_8BIT = 32, + /*LIBRAW_DNG_LARGERANGE=64,*/ /* more than 16 bit integer */ + LIBRAW_DNG_ALL = + LIBRAW_DNG_FLOAT | LIBRAW_DNG_LINEAR | LIBRAW_DNG_DEFLATE | LIBRAW_DNG_XTRANS | + LIBRAW_DNG_8BIT | LIBRAW_DNG_OTHER /* |LIBRAW_DNG_LARGERANGE */, + LIBRAW_DNG_DEFAULT = LIBRAW_DNG_FLOAT | LIBRAW_DNG_LINEAR | + LIBRAW_DNG_DEFLATE | LIBRAW_DNG_8BIT +}; + +enum LibRaw_output_flags +{ + LIBRAW_OUTPUT_FLAGS_NONE = 0, + LIBRAW_OUTPUT_FLAGS_PPMMETA = 1 +}; + +enum LibRaw_runtime_capabilities +{ + LIBRAW_CAPS_RAWSPEED = 1, + LIBRAW_CAPS_DNGSDK = 1<<1, + LIBRAW_CAPS_GPRSDK = 1<<2, + LIBRAW_CAPS_UNICODEPATHS = 1<<3, + LIBRAW_CAPS_X3FTOOLS = 1<<4, + LIBRAW_CAPS_RPI6BY9 = 1<<5, + LIBRAW_CAPS_ZLIB = 1<<6, + LIBRAW_CAPS_JPEG = 1<<7, + LIBRAW_CAPS_RAWSPEED3 = 1<<8, + LIBRAW_CAPS_RAWSPEED_BITS = 1<<9, +}; + +enum LibRaw_colorspace { + LIBRAW_COLORSPACE_NotFound = 0, + LIBRAW_COLORSPACE_sRGB, + LIBRAW_COLORSPACE_AdobeRGB, + LIBRAW_COLORSPACE_WideGamutRGB, + LIBRAW_COLORSPACE_ProPhotoRGB, + LIBRAW_COLORSPACE_ICC, + LIBRAW_COLORSPACE_Uncalibrated, // Tag 0x0001 InteropIndex containing "R03" + LIBRAW_COLORSPACE_Uncalibrated = Adobe RGB + LIBRAW_COLORSPACE_CameraLinearUniWB, + LIBRAW_COLORSPACE_CameraLinear, + LIBRAW_COLORSPACE_CameraGammaUniWB, + LIBRAW_COLORSPACE_CameraGamma, + LIBRAW_COLORSPACE_MonochromeLinear, + LIBRAW_COLORSPACE_MonochromeGamma, + LIBRAW_COLORSPACE_Unknown = 255 +}; + +enum LibRaw_cameramaker_index +{ + LIBRAW_CAMERAMAKER_Unknown = 0, + LIBRAW_CAMERAMAKER_Agfa, + LIBRAW_CAMERAMAKER_Alcatel, + LIBRAW_CAMERAMAKER_Apple, + LIBRAW_CAMERAMAKER_Aptina, + LIBRAW_CAMERAMAKER_AVT, + LIBRAW_CAMERAMAKER_Baumer, + LIBRAW_CAMERAMAKER_Broadcom, + LIBRAW_CAMERAMAKER_Canon, + LIBRAW_CAMERAMAKER_Casio, + LIBRAW_CAMERAMAKER_CINE, + LIBRAW_CAMERAMAKER_Clauss, + LIBRAW_CAMERAMAKER_Contax, + LIBRAW_CAMERAMAKER_Creative, + LIBRAW_CAMERAMAKER_DJI, + LIBRAW_CAMERAMAKER_DXO, + LIBRAW_CAMERAMAKER_Epson, + LIBRAW_CAMERAMAKER_Foculus, + LIBRAW_CAMERAMAKER_Fujifilm, + LIBRAW_CAMERAMAKER_Generic, + LIBRAW_CAMERAMAKER_Gione, + LIBRAW_CAMERAMAKER_GITUP, + LIBRAW_CAMERAMAKER_Google, + LIBRAW_CAMERAMAKER_GoPro, + LIBRAW_CAMERAMAKER_Hasselblad, + LIBRAW_CAMERAMAKER_HTC, + LIBRAW_CAMERAMAKER_I_Mobile, + LIBRAW_CAMERAMAKER_Imacon, + LIBRAW_CAMERAMAKER_JK_Imaging, + LIBRAW_CAMERAMAKER_Kodak, + LIBRAW_CAMERAMAKER_Konica, + LIBRAW_CAMERAMAKER_Leaf, + LIBRAW_CAMERAMAKER_Leica, + LIBRAW_CAMERAMAKER_Lenovo, + LIBRAW_CAMERAMAKER_LG, + LIBRAW_CAMERAMAKER_Logitech, + LIBRAW_CAMERAMAKER_Mamiya, + LIBRAW_CAMERAMAKER_Matrix, + LIBRAW_CAMERAMAKER_Meizu, + LIBRAW_CAMERAMAKER_Micron, + LIBRAW_CAMERAMAKER_Minolta, + LIBRAW_CAMERAMAKER_Motorola, + LIBRAW_CAMERAMAKER_NGM, + LIBRAW_CAMERAMAKER_Nikon, + LIBRAW_CAMERAMAKER_Nokia, + LIBRAW_CAMERAMAKER_Olympus, + LIBRAW_CAMERAMAKER_OmniVison, + LIBRAW_CAMERAMAKER_Panasonic, + LIBRAW_CAMERAMAKER_Parrot, + LIBRAW_CAMERAMAKER_Pentax, + LIBRAW_CAMERAMAKER_PhaseOne, + LIBRAW_CAMERAMAKER_PhotoControl, + LIBRAW_CAMERAMAKER_Photron, + LIBRAW_CAMERAMAKER_Pixelink, + LIBRAW_CAMERAMAKER_Polaroid, + LIBRAW_CAMERAMAKER_RED, + LIBRAW_CAMERAMAKER_Ricoh, + LIBRAW_CAMERAMAKER_Rollei, + LIBRAW_CAMERAMAKER_RoverShot, + LIBRAW_CAMERAMAKER_Samsung, + LIBRAW_CAMERAMAKER_Sigma, + LIBRAW_CAMERAMAKER_Sinar, + LIBRAW_CAMERAMAKER_SMaL, + LIBRAW_CAMERAMAKER_Sony, + LIBRAW_CAMERAMAKER_ST_Micro, + LIBRAW_CAMERAMAKER_THL, + LIBRAW_CAMERAMAKER_VLUU, + LIBRAW_CAMERAMAKER_Xiaomi, + LIBRAW_CAMERAMAKER_XIAOYI, + LIBRAW_CAMERAMAKER_YI, + LIBRAW_CAMERAMAKER_Yuneec, + LIBRAW_CAMERAMAKER_Zeiss, + LIBRAW_CAMERAMAKER_OnePlus, + LIBRAW_CAMERAMAKER_ISG, + LIBRAW_CAMERAMAKER_VIVO, + LIBRAW_CAMERAMAKER_HMD_Global, + LIBRAW_CAMERAMAKER_HUAWEI, + LIBRAW_CAMERAMAKER_RaspberryPi, + LIBRAW_CAMERAMAKER_OmDigital, + + // Insert additional indexes here + LIBRAW_CAMERAMAKER_TheLastOne +}; + +enum LibRaw_camera_mounts +{ + LIBRAW_MOUNT_Unknown = 0, + LIBRAW_MOUNT_Alpa, + LIBRAW_MOUNT_C, /* C-mount */ + LIBRAW_MOUNT_Canon_EF_M, + LIBRAW_MOUNT_Canon_EF_S, + LIBRAW_MOUNT_Canon_EF, + LIBRAW_MOUNT_Canon_RF, + LIBRAW_MOUNT_Contax_N, + LIBRAW_MOUNT_Contax645, + LIBRAW_MOUNT_FT, /* original 4/3 */ + LIBRAW_MOUNT_mFT, /* micro 4/3 */ + LIBRAW_MOUNT_Fuji_GF, /* Fujifilm GFX cameras, G mount */ + LIBRAW_MOUNT_Fuji_GX, /* Fujifilm GX680 */ + LIBRAW_MOUNT_Fuji_X, + LIBRAW_MOUNT_Hasselblad_H, /* Hasselblad Hn cameras, HC & HCD lenses */ + LIBRAW_MOUNT_Hasselblad_V, + LIBRAW_MOUNT_Hasselblad_XCD, /* Hasselblad Xn cameras, XCD lenses */ + LIBRAW_MOUNT_Leica_M, /* Leica rangefinder bayonet */ + LIBRAW_MOUNT_Leica_R, /* Leica SLRs, 'R' for reflex */ + LIBRAW_MOUNT_Leica_S, /* LIBRAW_FORMAT_LeicaS 'MF' */ + LIBRAW_MOUNT_Leica_SL, /* lens, mounts on 'L' throat, FF */ + LIBRAW_MOUNT_Leica_TL, /* lens, mounts on 'L' throat, APS-C */ + LIBRAW_MOUNT_LPS_L, /* Leica/Panasonic/Sigma camera mount, takes L, SL and TL lenses */ + LIBRAW_MOUNT_Mamiya67, /* Mamiya RB67, RZ67 */ + LIBRAW_MOUNT_Mamiya645, + LIBRAW_MOUNT_Minolta_A, + LIBRAW_MOUNT_Nikon_CX, /* used in 'Nikon 1' series */ + LIBRAW_MOUNT_Nikon_F, + LIBRAW_MOUNT_Nikon_Z, + LIBRAW_MOUNT_PhaseOne_iXM_MV, + LIBRAW_MOUNT_PhaseOne_iXM_RS, + LIBRAW_MOUNT_PhaseOne_iXM, + LIBRAW_MOUNT_Pentax_645, + LIBRAW_MOUNT_Pentax_K, + LIBRAW_MOUNT_Pentax_Q, + LIBRAW_MOUNT_RicohModule, + LIBRAW_MOUNT_Rollei_bayonet, /* Rollei Hy-6: Leaf AFi, Sinar Hy6- models */ + LIBRAW_MOUNT_Samsung_NX_M, + LIBRAW_MOUNT_Samsung_NX, + LIBRAW_MOUNT_Sigma_X3F, + LIBRAW_MOUNT_Sony_E, + LIBRAW_MOUNT_LF, + LIBRAW_MOUNT_DigitalBack, + LIBRAW_MOUNT_FixedLens, + LIBRAW_MOUNT_IL_UM, /* Interchangeable lens, mount unknown */ + LIBRAW_MOUNT_TheLastOne +}; + +enum LibRaw_camera_formats +{ + LIBRAW_FORMAT_Unknown = 0, + LIBRAW_FORMAT_APSC, + LIBRAW_FORMAT_FF, + LIBRAW_FORMAT_MF, + LIBRAW_FORMAT_APSH, + LIBRAW_FORMAT_1INCH, + LIBRAW_FORMAT_1div2p3INCH, /* 1/2.3" */ + LIBRAW_FORMAT_1div1p7INCH, /* 1/1.7" */ + LIBRAW_FORMAT_FT, /* sensor size in FT & mFT cameras */ + LIBRAW_FORMAT_CROP645, /* 44x33mm */ + LIBRAW_FORMAT_LeicaS, /* 'MF' Leicas */ + LIBRAW_FORMAT_645, + LIBRAW_FORMAT_66, + LIBRAW_FORMAT_69, + LIBRAW_FORMAT_LF, + LIBRAW_FORMAT_Leica_DMR, + LIBRAW_FORMAT_67, + LIBRAW_FORMAT_SigmaAPSC, /* DP1, DP2, SD15, SD14, SD10, SD9 */ + LIBRAW_FORMAT_SigmaMerrill, /* SD1, 'SD1 Merrill', 'DP1 Merrill', 'DP2 Merrill' */ + LIBRAW_FORMAT_SigmaAPSH, /* 'sd Quattro H' */ + LIBRAW_FORMAT_3648, /* DALSA FTF4052C (Mamiya ZD) */ + LIBRAW_FORMAT_68, /* Fujifilm GX680 */ + LIBRAW_FORMAT_TheLastOne +}; + +enum LibRawImageAspects +{ + LIBRAW_IMAGE_ASPECT_UNKNOWN = 0, + LIBRAW_IMAGE_ASPECT_OTHER = 1, + LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE = 99, /* 1:10*/ + LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE = 10000, /* 10: 1*/ + // Value: width / height * 1000 + LIBRAW_IMAGE_ASPECT_3to2 = (1000 * 3)/2, + LIBRAW_IMAGE_ASPECT_1to1 = 1000, + LIBRAW_IMAGE_ASPECT_4to3 = (1000 * 4)/ 3, + LIBRAW_IMAGE_ASPECT_16to9 = (1000 * 16) / 9, + //LIBRAW_IMAGE_ASPECT_6to6, // what is the difference with 1:1 ? + LIBRAW_IMAGE_ASPECT_5to4 = (1000 * 5) / 4, + LIBRAW_IMAGE_ASPECT_7to6 = (1000 * 7) / 6, + LIBRAW_IMAGE_ASPECT_6to5 = (1000 * 6) / 5, + LIBRAW_IMAGE_ASPECT_7to5 = (1000 * 7) / 5 +}; + +enum LibRaw_lens_focal_types +{ + LIBRAW_FT_UNDEFINED = 0, + LIBRAW_FT_PRIME_LENS = 1, + LIBRAW_FT_ZOOM_LENS = 2, + LIBRAW_FT_ZOOM_LENS_CONSTANT_APERTURE = 3, + LIBRAW_FT_ZOOM_LENS_VARIABLE_APERTURE = 4 +}; + +enum LibRaw_Canon_RecordModes { + LIBRAW_Canon_RecordMode_UNDEFINED = 0, + LIBRAW_Canon_RecordMode_JPEG, + LIBRAW_Canon_RecordMode_CRW_THM, + LIBRAW_Canon_RecordMode_AVI_THM, + LIBRAW_Canon_RecordMode_TIF, + LIBRAW_Canon_RecordMode_TIF_JPEG, + LIBRAW_Canon_RecordMode_CR2, + LIBRAW_Canon_RecordMode_CR2_JPEG, + LIBRAW_Canon_RecordMode_UNKNOWN, + LIBRAW_Canon_RecordMode_MOV, + LIBRAW_Canon_RecordMode_MP4, + LIBRAW_Canon_RecordMode_CRM, + LIBRAW_Canon_RecordMode_CR3, + LIBRAW_Canon_RecordMode_CR3_JPEG, + LIBRAW_Canon_RecordMode_HEIF, + LIBRAW_Canon_RecordMode_CR3_HEIF, + LIBRAW_Canon_RecordMode_TheLastOne +}; + +enum LibRaw_minolta_storagemethods +{ + LIBRAW_MINOLTA_UNPACKED = 0x52, + LIBRAW_MINOLTA_PACKED = 0x59 +}; + +enum LibRaw_minolta_bayerpatterns +{ + LIBRAW_MINOLTA_RGGB = 0x01, + LIBRAW_MINOLTA_G2BRG1 = 0x04 +}; + +enum LibRaw_sony_cameratypes +{ + LIBRAW_SONY_DSC = 1, + LIBRAW_SONY_DSLR = 2, + LIBRAW_SONY_NEX = 3, + LIBRAW_SONY_SLT = 4, + LIBRAW_SONY_ILCE = 5, + LIBRAW_SONY_ILCA = 6, + LIBRAW_SONY_CameraType_UNKNOWN = 0xffff +}; + +enum LibRaw_Sony_0x2010_Type { + LIBRAW_SONY_Tag2010None = 0, + LIBRAW_SONY_Tag2010a, + LIBRAW_SONY_Tag2010b, + LIBRAW_SONY_Tag2010c, + LIBRAW_SONY_Tag2010d, + LIBRAW_SONY_Tag2010e, + LIBRAW_SONY_Tag2010f, + LIBRAW_SONY_Tag2010g, + LIBRAW_SONY_Tag2010h, + LIBRAW_SONY_Tag2010i +}; +enum LibRaw_Sony_0x9050_Type { + LIBRAW_SONY_Tag9050None = 0, + LIBRAW_SONY_Tag9050a, + LIBRAW_SONY_Tag9050b, + LIBRAW_SONY_Tag9050c +}; + +enum LIBRAW_SONY_FOCUSMODEmodes +{ + LIBRAW_SONY_FOCUSMODE_MF = 0, + LIBRAW_SONY_FOCUSMODE_AF_S = 2, + LIBRAW_SONY_FOCUSMODE_AF_C = 3, + LIBRAW_SONY_FOCUSMODE_AF_A = 4, + LIBRAW_SONY_FOCUSMODE_DMF = 6, + LIBRAW_SONY_FOCUSMODE_AF_D = 7, + LIBRAW_SONY_FOCUSMODE_AF = 101, + LIBRAW_SONY_FOCUSMODE_PERMANENT_AF = 104, + LIBRAW_SONY_FOCUSMODE_SEMI_MF = 105, + LIBRAW_SONY_FOCUSMODE_UNKNOWN = -1 +}; + +enum LibRaw_KodakSensors +{ + LIBRAW_Kodak_UnknownSensor = 0, + LIBRAW_Kodak_M1 = 1, + LIBRAW_Kodak_M15 = 2, + LIBRAW_Kodak_M16 = 3, + LIBRAW_Kodak_M17 = 4, + LIBRAW_Kodak_M2 = 5, + LIBRAW_Kodak_M23 = 6, + LIBRAW_Kodak_M24 = 7, + LIBRAW_Kodak_M3 = 8, + LIBRAW_Kodak_M5 = 9, + LIBRAW_Kodak_M6 = 10, + LIBRAW_Kodak_C14 = 11, + LIBRAW_Kodak_X14 = 12, + LIBRAW_Kodak_M11 = 13 +}; + +enum LibRaw_HasselbladFormatCodes { + LIBRAW_HF_Unknown = 0, + LIBRAW_HF_3FR, + LIBRAW_HF_FFF, + LIBRAW_HF_Imacon, + LIBRAW_HF_HasselbladDNG, + LIBRAW_HF_AdobeDNG, + LIBRAW_HF_AdobeDNG_fromPhocusDNG +}; + +enum LibRaw_rawspecial_t +{ + LIBRAW_RAWSPECIAL_SONYARW2_NONE = 0, + LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY = 1, + LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY = 1 << 1, + LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE = 1 << 2, + LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE = 1 << 3, + LIBRAW_RAWSPECIAL_SONYARW2_ALLFLAGS = + LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY + + LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY + + LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE + + LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE, + LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG = 1<<4, + LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF = 1 << 5, + LIBRAW_RAWSPECIAL_SRAW_NO_RGB = 1 << 6, + LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE = 1 << 7 +}; + +enum LibRaw_rawspeed_bits_t +{ + LIBRAW_RAWSPEEDV1_USE = 1, + LIBRAW_RAWSPEEDV1_FAILONUNKNOWN = 1 << 1, + LIBRAW_RAWSPEEDV1_IGNOREERRORS = 1 << 2, + /* bits 3-7 are reserved*/ + LIBRAW_RAWSPEEDV3_USE = 1 << 8, + LIBRAW_RAWSPEEDV3_FAILONUNKNOWN = 1 << 9, + LIBRAW_RAWSPEEDV3_IGNOREERRORS = 1 << 10, +}; + +enum LibRaw_processing_options +{ + LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES = 1, + LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT = 1 << 1, + LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP = 1 << 2, + LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS = 1 << 3, +// LIBRAW_RAWOPTIONS_USE_DNG_DEFAULT_CROP = 1 << 4, + LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS = 1 << 5, + LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT = 1 << 6, + LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY = 1 << 7, + LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS = 1 << 8, + LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED = 1 << 9, + LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS = 1 << 10, + LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE = 1 << 11, + LIBRAW_RAWOPTIONS_DNG_STAGE2 = 1 << 12, + LIBRAW_RAWOPTIONS_DNG_STAGE3 = 1 << 13, + LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE = 1 << 14, + LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST = 1 << 15, + LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB = 1 << 16, + LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT = 1 << 17, + LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS = 1 << 18, + LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS = 1 << 19, + LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT = 1 << 20, + LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT = 1 << 21, + LIBRAW_RAWOPTIONS_DNG_ADD_MASKS = 1 << 22, + LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION = 1 << 23 +}; + +enum LibRaw_decoder_flags +{ + LIBRAW_DECODER_HASCURVE = 1 << 4, + LIBRAW_DECODER_SONYARW2 = 1 << 5, + LIBRAW_DECODER_TRYRAWSPEED = 1 << 6, + LIBRAW_DECODER_OWNALLOC = 1 << 7, + LIBRAW_DECODER_FIXEDMAXC = 1 << 8, + LIBRAW_DECODER_ADOBECOPYPIXEL = 1 << 9, + LIBRAW_DECODER_LEGACY_WITH_MARGINS = 1 << 10, + LIBRAW_DECODER_3CHANNEL = 1 << 11, + LIBRAW_DECODER_SINAR4SHOT = 1 << 11, + LIBRAW_DECODER_FLATDATA = 1 << 12, + LIBRAW_DECODER_FLAT_BG2_SWAPPED = 1<<13, + LIBRAW_DECODER_UNSUPPORTED_FORMAT = 1 << 14, + LIBRAW_DECODER_NOTSET = 1 << 15, + LIBRAW_DECODER_TRYRAWSPEED3 = 1 << 16 +}; + +#define LIBRAW_XTRANS 9 + +enum LibRaw_constructor_flags +{ + LIBRAW_OPTIONS_NONE = 0, + LIBRAW_OPTIONS_NO_DATAERR_CALLBACK = 1 << 1, + /* Compatibility w/ years old typo */ + LIBRAW_OPIONS_NO_DATAERR_CALLBACK = LIBRAW_OPTIONS_NO_DATAERR_CALLBACK +}; + +enum LibRaw_warnings +{ + LIBRAW_WARN_NONE = 0, + LIBRAW_WARN_BAD_CAMERA_WB = 1 << 2, + LIBRAW_WARN_NO_METADATA = 1 << 3, + LIBRAW_WARN_NO_JPEGLIB = 1 << 4, + LIBRAW_WARN_NO_EMBEDDED_PROFILE = 1 << 5, + LIBRAW_WARN_NO_INPUT_PROFILE = 1 << 6, + LIBRAW_WARN_BAD_OUTPUT_PROFILE = 1 << 7, + LIBRAW_WARN_NO_BADPIXELMAP = 1 << 8, + LIBRAW_WARN_BAD_DARKFRAME_FILE = 1 << 9, + LIBRAW_WARN_BAD_DARKFRAME_DIM = 1 << 10, +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + LIBRAW_WARN_NO_JASPER = 1 << 11, +#endif + LIBRAW_WARN_RAWSPEED_PROBLEM = 1 << 12, + LIBRAW_WARN_RAWSPEED_UNSUPPORTED = 1 << 13, + LIBRAW_WARN_RAWSPEED_PROCESSED = 1 << 14, + LIBRAW_WARN_FALLBACK_TO_AHD = 1 << 15, + LIBRAW_WARN_PARSEFUJI_PROCESSED = 1 << 16, + LIBRAW_WARN_DNGSDK_PROCESSED = 1 << 17, + LIBRAW_WARN_DNG_IMAGES_REORDERED = 1 << 18, + LIBRAW_WARN_DNG_STAGE2_APPLIED = 1 << 19, + LIBRAW_WARN_DNG_STAGE3_APPLIED = 1 << 20, + LIBRAW_WARN_RAWSPEED3_PROBLEM = 1 << 21, + LIBRAW_WARN_RAWSPEED3_UNSUPPORTED = 1 << 22, + LIBRAW_WARN_RAWSPEED3_PROCESSED = 1 << 23, + LIBRAW_WARN_RAWSPEED3_NOTLISTED = 1 << 24 +}; + +enum LibRaw_exceptions +{ + LIBRAW_EXCEPTION_NONE = 0, + LIBRAW_EXCEPTION_ALLOC = 1, + LIBRAW_EXCEPTION_DECODE_RAW = 2, + LIBRAW_EXCEPTION_DECODE_JPEG = 3, + LIBRAW_EXCEPTION_IO_EOF = 4, + LIBRAW_EXCEPTION_IO_CORRUPT = 5, + LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK = 6, + LIBRAW_EXCEPTION_BAD_CROP = 7, + LIBRAW_EXCEPTION_IO_BADFILE = 8, + LIBRAW_EXCEPTION_DECODE_JPEG2000 = 9, + LIBRAW_EXCEPTION_TOOBIG = 10, + LIBRAW_EXCEPTION_MEMPOOL = 11, + LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT = 12 +}; + +enum LibRaw_progress +{ + LIBRAW_PROGRESS_START = 0, + LIBRAW_PROGRESS_OPEN = 1, + LIBRAW_PROGRESS_IDENTIFY = 1 << 1, + LIBRAW_PROGRESS_SIZE_ADJUST = 1 << 2, + LIBRAW_PROGRESS_LOAD_RAW = 1 << 3, + LIBRAW_PROGRESS_RAW2_IMAGE = 1 << 4, + LIBRAW_PROGRESS_REMOVE_ZEROES = 1 << 5, + LIBRAW_PROGRESS_BAD_PIXELS = 1 << 6, + LIBRAW_PROGRESS_DARK_FRAME = 1 << 7, + LIBRAW_PROGRESS_FOVEON_INTERPOLATE = 1 << 8, + LIBRAW_PROGRESS_SCALE_COLORS = 1 << 9, + LIBRAW_PROGRESS_PRE_INTERPOLATE = 1 << 10, + LIBRAW_PROGRESS_INTERPOLATE = 1 << 11, + LIBRAW_PROGRESS_MIX_GREEN = 1 << 12, + LIBRAW_PROGRESS_MEDIAN_FILTER = 1 << 13, + LIBRAW_PROGRESS_HIGHLIGHTS = 1 << 14, + LIBRAW_PROGRESS_FUJI_ROTATE = 1 << 15, + LIBRAW_PROGRESS_FLIP = 1 << 16, + LIBRAW_PROGRESS_APPLY_PROFILE = 1 << 17, + LIBRAW_PROGRESS_CONVERT_RGB = 1 << 18, + LIBRAW_PROGRESS_STRETCH = 1 << 19, + /* reserved */ + LIBRAW_PROGRESS_STAGE20 = 1 << 20, + LIBRAW_PROGRESS_STAGE21 = 1 << 21, + LIBRAW_PROGRESS_STAGE22 = 1 << 22, + LIBRAW_PROGRESS_STAGE23 = 1 << 23, + LIBRAW_PROGRESS_STAGE24 = 1 << 24, + LIBRAW_PROGRESS_STAGE25 = 1 << 25, + LIBRAW_PROGRESS_STAGE26 = 1 << 26, + LIBRAW_PROGRESS_STAGE27 = 1 << 27, + + LIBRAW_PROGRESS_THUMB_LOAD = 1 << 28, + LIBRAW_PROGRESS_TRESERVED1 = 1 << 29, + LIBRAW_PROGRESS_TRESERVED2 = 1 << 30 +}; +#define LIBRAW_PROGRESS_THUMB_MASK 0x0fffffff + +enum LibRaw_errors +{ + LIBRAW_SUCCESS = 0, + LIBRAW_UNSPECIFIED_ERROR = -1, + LIBRAW_FILE_UNSUPPORTED = -2, + LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE = -3, + LIBRAW_OUT_OF_ORDER_CALL = -4, + LIBRAW_NO_THUMBNAIL = -5, + LIBRAW_UNSUPPORTED_THUMBNAIL = -6, + LIBRAW_INPUT_CLOSED = -7, + LIBRAW_NOT_IMPLEMENTED = -8, + LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL = -9, + LIBRAW_UNSUFFICIENT_MEMORY = -100007, + LIBRAW_DATA_ERROR = -100008, + LIBRAW_IO_ERROR = -100009, + LIBRAW_CANCELLED_BY_CALLBACK = -100010, + LIBRAW_BAD_CROP = -100011, + LIBRAW_TOO_BIG = -100012, + LIBRAW_MEMPOOL_OVERFLOW = -100013 +}; + +#define LIBRAW_FATAL_ERROR(ec) ((ec) < -100000) + +enum LibRaw_internal_thumbnail_formats +{ + LIBRAW_INTERNAL_THUMBNAIL_UNKNOWN = 0, + LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB = 1, + LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR = 2, + LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB = 3, + LIBRAW_INTERNAL_THUMBNAIL_JPEG = 4, + LIBRAW_INTERNAL_THUMBNAIL_LAYER, + LIBRAW_INTERNAL_THUMBNAIL_ROLLEI, + LIBRAW_INTERNAL_THUMBNAIL_PPM, + LIBRAW_INTERNAL_THUMBNAIL_PPM16, + LIBRAW_INTERNAL_THUMBNAIL_X3F, +}; + + +enum LibRaw_thumbnail_formats +{ + LIBRAW_THUMBNAIL_UNKNOWN = 0, + LIBRAW_THUMBNAIL_JPEG = 1, + LIBRAW_THUMBNAIL_BITMAP = 2, + LIBRAW_THUMBNAIL_BITMAP16 = 3, + LIBRAW_THUMBNAIL_LAYER = 4, + LIBRAW_THUMBNAIL_ROLLEI = 5, + LIBRAW_THUMBNAIL_H265 = 6 +}; + +enum LibRaw_image_formats +{ + LIBRAW_IMAGE_JPEG = 1, + LIBRAW_IMAGE_BITMAP = 2 +}; + +#endif diff --git a/libraw/libraw_datastream.h b/libraw/libraw_datastream.h new file mode 100644 index 000000000..0596e83a5 --- /dev/null +++ b/libraw/libraw_datastream.h @@ -0,0 +1,410 @@ +/* -*- C -*- + * File: libraw_datastream.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sun Jan 18 13:07:35 2009 + * + * LibRaw Data stream interface + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef __LIBRAW_DATASTREAM_H +#define __LIBRAW_DATASTREAM_H + +#include +#include +#include +#include + +#ifndef __cplusplus + +#else /* __cplusplus */ +#if defined _WIN32 +#ifndef LIBRAW_NO_WINSOCK2 +#include +#endif +#endif +/* No unique_ptr on Apple ?? */ +#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) || \ + (defined(_MSC_VER) && _MSVC_LANG >= 201103L) +/* OK - use unique_ptr unless LIBRAW_USE_AUTOPTR defined externally*/ +#else +/* Force to use auto_ptr */ +#ifndef LIBRAW_USE_AUTOPTR +#define LIBRAW_USE_AUTOPTR +#endif +#endif + +#include "libraw_const.h" +#include "libraw_types.h" +#include +#include +#include + +#if defined(_WIN32) && (_MSC_VER) >= 1500 +#define WIN32SECURECALLS +#endif + +#ifdef USE_DNGSDK + +#if defined LIBRAW_WIN32_CALLS +#define qWinOS 1 +#define qMacOS 0 +#elif defined(__APPLE__) +#define qWinOS 0 +#define qMacOS 1 +#else +/* define OS types for DNG here */ +#endif +#define qDNGXMPDocOps 0 +#define qDNGUseLibJPEG 1 +#define qDNGXMPFiles 0 +#define qDNGExperimental 1 +#define qDNGThreadSafe 1 +#include "dng_stream.h" +#endif /* DNGSDK */ + +#define IOERROR() \ + do \ + { \ + throw LIBRAW_EXCEPTION_IO_EOF; \ + } while (0) + +class LibRaw_buffer_datastream; +class LibRaw_bit_buffer; + +class DllDef LibRaw_abstract_datastream +{ +public: + LibRaw_abstract_datastream() { }; + virtual ~LibRaw_abstract_datastream(void) { } + virtual int valid() = 0; + virtual int read(void *, size_t, size_t) = 0; + virtual int seek(INT64, int) = 0; + virtual INT64 tell() = 0; + virtual INT64 size() = 0; + virtual int get_char() = 0; + virtual char *gets(char *, int) = 0; + virtual int scanf_one(const char *, void *) = 0; + virtual int eof() = 0; +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + virtual void *make_jas_stream() = 0; +#endif + virtual int jpeg_src(void *); + virtual void buffering_off() {} + /* reimplement in subclass to use parallel access in xtrans_load_raw() if + * OpenMP is not used */ + virtual int lock() { return 1; } /* success */ + virtual void unlock() {} + virtual const char *fname() { return NULL; }; +#ifdef LIBRAW_WIN32_UNICODEPATHS + virtual const wchar_t *wfname() { return NULL; }; +#endif +}; + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + +#ifdef LIBRAW_WIN32_DLLDEFS +#ifdef LIBRAW_USE_AUTOPTR +template class DllDef std::auto_ptr; +#else +template class DllDef std::unique_ptr; +#endif +#endif + +class DllDef LibRaw_file_datastream : public LibRaw_abstract_datastream +{ +protected: +#ifdef LIBRAW_USE_AUTOPTR + std::auto_ptr f; /* will close() automatically through dtor */ +#else + std::unique_ptr f; +#endif + std::string filename; + INT64 _fsize; +#ifdef LIBRAW_WIN32_UNICODEPATHS + std::wstring wfilename; +#endif + FILE *jas_file; + +public: + virtual ~LibRaw_file_datastream(); + LibRaw_file_datastream(const char *fname); +#ifdef LIBRAW_WIN32_UNICODEPATHS + LibRaw_file_datastream(const wchar_t *fname); +#endif +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + virtual void *make_jas_stream(); +#endif + virtual int valid(); + virtual int read(void *ptr, size_t size, size_t nmemb); + virtual int eof(); + virtual int seek(INT64 o, int whence); + virtual INT64 tell(); + virtual INT64 size() { return _fsize; } + virtual int get_char() {return f->sbumpc();} + virtual char *gets(char *str, int sz); + virtual int scanf_one(const char *fmt, void *val); + virtual const char *fname(); +#ifdef LIBRAW_WIN32_UNICODEPATHS + virtual const wchar_t *wfname(); +#endif +}; +#endif + +#if defined (LIBRAW_NO_IOSTREAMS_DATASTREAM) && defined (LIBRAW_WIN32_CALLS) + +struct DllDef LibRaw_bufio_params +{ + static int bufsize; + static void set_bufsize(int bs); +}; + +class buffer_t : public std::vector +{ +public: + INT64 _bstart, _bend; + buffer_t() : std::vector(LibRaw_bufio_params::bufsize), _bstart(0), _bend(0) {} + int charOReof(INT64 _fpos) + { + if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL) + return -1; + if ((_bend - _bstart) > (INT64)size()) + return -1; + if (_fpos >= _bstart && _fpos < _bend) + return data()[_fpos - _bstart]; + return -1; + } + bool contains(INT64 _fpos, INT64& contains) + { + if (_bstart < 0LL || _bend < 0LL || _bend < _bstart || _fpos < 0LL) + { + contains = 0; + return false; + } + if ((_bend - _bstart) > (INT64)size()) + { + contains = 0; + return false; + } + if (_fpos >= _bstart && _fpos < _bend) + { + contains = _bend - _fpos; + return true; + } + contains = 0; + return false; + } +}; + + +class DllDef LibRaw_bigfile_buffered_datastream : public LibRaw_abstract_datastream +{ +public: + LibRaw_bigfile_buffered_datastream(const char *fname); +#ifdef LIBRAW_WIN32_UNICODEPATHS + LibRaw_bigfile_buffered_datastream(const wchar_t *fname); +#endif + virtual ~LibRaw_bigfile_buffered_datastream(); + virtual int valid(); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + virtual void *make_jas_stream(); +#endif + virtual void buffering_off() { buffered = 0; } + virtual int read(void *ptr, size_t size, size_t nmemb); + virtual int eof(); + virtual int seek(INT64 o, int whence); + virtual INT64 tell(); + virtual INT64 size() { return _fsize; } + virtual char *gets(char *str, int sz); + virtual int scanf_one(const char *fmt, void *val); + virtual const char *fname(); +#ifdef LIBRAW_WIN32_UNICODEPATHS + virtual const wchar_t *wfname(); +#endif + virtual int get_char() + { + int r = iobuffers[0].charOReof(_fpos); + if (r >= 0) + { + _fpos++; + return r; + } + unsigned char c; + r = read(&c, 1, 1); + return r > 0 ? c : r; + } + +protected: + INT64 readAt(void *ptr, size_t size, INT64 off); + bool fillBufferAt(int buf, INT64 off); + int selectStringBuffer(INT64 len, INT64& contains); + HANDLE fhandle; + INT64 _fsize; + INT64 _fpos; /* current file position; current buffer start position */ +#ifdef LIBRAW_WIN32_UNICODEPATHS + std::wstring wfilename; +#endif + std::string filename; + buffer_t iobuffers[2]; + int buffered; +}; + +#endif + +class DllDef LibRaw_buffer_datastream : public LibRaw_abstract_datastream +{ +public: + LibRaw_buffer_datastream(const void *buffer, size_t bsize); + virtual ~LibRaw_buffer_datastream(); + virtual int valid(); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + virtual void *make_jas_stream(); +#endif + virtual int jpeg_src(void *jpegdata); + virtual int read(void *ptr, size_t sz, size_t nmemb); + virtual int eof(); + virtual int seek(INT64 o, int whence); + virtual INT64 tell(); + virtual INT64 size() { return streamsize; } + virtual char *gets(char *s, int sz); + virtual int scanf_one(const char *fmt, void *val); + virtual int get_char() + { + if (streampos >= streamsize) return -1; + return buf[streampos++]; + } + +private: + unsigned char *buf; + size_t streampos, streamsize; +}; + +class DllDef LibRaw_bigfile_datastream : public LibRaw_abstract_datastream +{ +public: + LibRaw_bigfile_datastream(const char *fname); +#ifdef LIBRAW_WIN32_UNICODEPATHS + LibRaw_bigfile_datastream(const wchar_t *fname); +#endif + virtual ~LibRaw_bigfile_datastream(); + virtual int valid(); +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + virtual void *make_jas_stream(); +#endif + + virtual int read(void *ptr, size_t size, size_t nmemb); + virtual int eof(); + virtual int seek(INT64 o, int whence); + virtual INT64 tell(); + virtual INT64 size() { return _fsize; } + virtual char *gets(char *str, int sz); + virtual int scanf_one(const char *fmt, void *val); + virtual const char *fname(); +#ifdef LIBRAW_WIN32_UNICODEPATHS + virtual const wchar_t *wfname(); +#endif + virtual int get_char() + { +#ifndef LIBRAW_WIN32_CALLS + return getc_unlocked(f); +#else + return fgetc(f); +#endif + } + +protected: + FILE *f; + std::string filename; + INT64 _fsize; +#ifdef LIBRAW_WIN32_UNICODEPATHS + std::wstring wfilename; +#endif +}; + +#ifdef LIBRAW_WIN32_CALLS +class DllDef LibRaw_windows_datastream : public LibRaw_buffer_datastream +{ +public: + /* ctor: high level constructor opens a file by name */ + LibRaw_windows_datastream(const TCHAR *sFile); + /* ctor: construct with a file handle - caller is responsible for closing the + * file handle */ + LibRaw_windows_datastream(HANDLE hFile); + /* dtor: unmap and close the mapping handle */ + virtual ~LibRaw_windows_datastream(); + virtual INT64 size() { return cbView_; } + +protected: + void Open(HANDLE hFile); + inline void reconstruct_base() + { + /* this subterfuge is to overcome the private-ness of + * LibRaw_buffer_datastream */ + (LibRaw_buffer_datastream &)*this = + LibRaw_buffer_datastream(pView_, (size_t)cbView_); + } + + HANDLE hMap_; /* handle of the file mapping */ + void *pView_; /* pointer to the mapped memory */ + __int64 cbView_; /* size of the mapping in bytes */ +}; + +#endif + +#ifdef USE_DNGSDK + +class libraw_dng_stream : public dng_stream +{ +public: + libraw_dng_stream(LibRaw_abstract_datastream *p) + : dng_stream((dng_abort_sniffer *)NULL, kBigBufferSize, 0), + parent_stream(p) + { + if (parent_stream) + { + parent_stream->buffering_off(); + off = parent_stream->tell(); + parent_stream->seek(0UL, SEEK_SET); /* seek to start */ + } + } + ~libraw_dng_stream() + { + if (parent_stream) + parent_stream->seek(off, SEEK_SET); + } + virtual uint64 DoGetLength() + { + if (parent_stream) + return parent_stream->size(); + return 0; + } + virtual void DoRead(void *data, uint32 count, uint64 offset) + { + if (parent_stream) + { + parent_stream->seek(offset, SEEK_SET); + parent_stream->read(data, 1, count); + } + } + +private: + libraw_dng_stream(const libraw_dng_stream &stream); + libraw_dng_stream &operator=(const libraw_dng_stream &stream); + LibRaw_abstract_datastream *parent_stream; + INT64 off; +}; + +#endif + +#endif /* cplusplus */ + +#endif diff --git a/libraw/libraw_internal.h b/libraw/libraw_internal.h new file mode 100644 index 000000000..9ed3a1790 --- /dev/null +++ b/libraw/libraw_internal.h @@ -0,0 +1,341 @@ +/* -*- C++ -*- + * File: libraw_internal.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8 , 2008 + * + * LibRaw internal data structures (not visible outside) + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef _LIBRAW_INTERNAL_TYPES_H +#define _LIBRAW_INTERNAL_TYPES_H + +#include + +#ifdef __cplusplus + +#include "libraw_datastream.h" +#include "libraw_types.h" + +class LibRaw_TLS +{ +public: + struct + { + unsigned bitbuf; + int vbits, reset; + } getbits; + struct + { + UINT64 bitbuf; + int vbits; + + } ph1_bits; + struct + { + unsigned pad[128], p; + } sony_decrypt; + struct + { + uchar buf[0x4002]; + int vpos, padding; + } pana_data; + uchar jpeg_buffer[4096]; + struct + { + float cbrt[0x10000], xyz_cam[3][4]; + } ahd_data; + void init() + { + getbits.bitbuf = 0; + getbits.vbits = getbits.reset = 0; + ph1_bits.bitbuf = 0; + ph1_bits.vbits = 0; + pana_data.vpos = 0; + ahd_data.cbrt[0] = -2.0f; + } +}; + +class LibRaw_constants +{ +public: + static const float d65_white[3]; + static const double xyz_rgb[3][3]; + static const double xyzd50_srgb[3][3]; + static const double rgb_rgb[3][3]; + static const double adobe_rgb[3][3]; + static const double wide_rgb[3][3]; + static const double prophoto_rgb[3][3]; + static const double aces_rgb[3][3]; + static const double dcip3d65_rgb[3][3]; + static const double rec2020_rgb[3][3]; +}; +#endif /* __cplusplus */ + +typedef struct +{ +#ifndef __cplusplus + struct +#endif + LibRaw_abstract_datastream *input; + FILE *output; + int input_internal; + char *meta_data; + INT64 profile_offset; + INT64 toffset; + unsigned pana_black[4]; + +} internal_data_t; + +#define LIBRAW_HISTOGRAM_SIZE 0x2000 +typedef struct +{ + int (*histogram)[LIBRAW_HISTOGRAM_SIZE]; + unsigned *oprof; +} output_data_t; + +typedef struct +{ + unsigned olympus_exif_cfa; + unsigned long long unique_id; + unsigned long long OlyID; + unsigned tiff_nifds; + int tiff_flip; + int metadata_blocks; +} identify_data_t; + +typedef struct +{ + uint32_t first; + uint32_t count; + uint32_t id; +} crx_sample_to_chunk_t; + +// contents of tag CMP1 for relevant track in CR3 file +typedef struct +{ + int32_t version; + int32_t f_width; + int32_t f_height; + int32_t tileWidth; + int32_t tileHeight; + int32_t nBits; + int32_t nPlanes; + int32_t cfaLayout; + int32_t encType; + int32_t imageLevels; + int32_t hasTileCols; + int32_t hasTileRows; + int32_t mdatHdrSize; + int32_t medianBits; + // Not from header, but from datastream + uint32_t MediaSize; + INT64 MediaOffset; + uint32_t MediaType; /* 1 -> /C/RAW, 2-> JPEG, 3-> CTMD metadata*/ + crx_sample_to_chunk_t * stsc_data; /* samples to chunk */ + uint32_t stsc_count; + uint32_t sample_count; + uint32_t sample_size; /* zero if not fixed sample size */ + int32_t *sample_sizes; + uint32_t chunk_count; + INT64 *chunk_offsets; +} crx_data_header_t; + +typedef struct +{ + short order; + ushort sraw_mul[4], cr2_slice[3]; + unsigned kodak_cbpp; + INT64 strip_offset, data_offset; + INT64 meta_offset; + INT64 exif_offset, exif_subdir_offset, ifd0_offset; + unsigned data_size; + unsigned meta_length; + unsigned cr3_exif_length, cr3_ifd0_length; + unsigned thumb_misc; + enum LibRaw_internal_thumbnail_formats thumb_format; + unsigned fuji_layout; + unsigned tiff_samples; + unsigned tiff_bps; + unsigned tiff_compress; + unsigned tiff_sampleformat; + unsigned zero_after_ff; + unsigned tile_width, tile_length, load_flags; + unsigned data_error; + int hasselblad_parser_flag; + long long posRAFData; + unsigned lenRAFData; + int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, + fuji_raw_type, fuji_lossless; + int pana_encoding, pana_bpp; + crx_data_header_t crx_header[LIBRAW_CRXTRACKS_MAXCOUNT]; + int crx_track_selected; + int crx_track_count; + short CR3_CTMDtag; + short CR3_Version; + int CM_found; + unsigned is_NikonTransfer; + unsigned is_Olympus; + int OlympusDNG_SubDirOffsetValid; + unsigned is_Sony; + unsigned is_pana_raw; + unsigned is_PentaxRicohMakernotes; /* =1 for Ricoh software by Pentax, Camera DNG */ + + unsigned dng_frames[LIBRAW_IFD_MAXCOUNT*2]; /* bits: 0-7: shot_select, 8-15: IFD#, 16-31: low 16 bit of newsubfile type */ + unsigned short raw_stride; +} unpacker_data_t; + +typedef struct +{ + internal_data_t internal_data; + libraw_internal_output_params_t internal_output_params; + output_data_t output_data; + identify_data_t identify_data; + unpacker_data_t unpacker_data; +} libraw_internal_data_t; + +struct decode +{ + struct decode *branch[2]; + int leaf; +}; + +struct tiff_ifd_t +{ + int t_width, t_height, bps, comp, phint, offset, t_flip, samples, bytes, extrasamples; + int t_tile_width, t_tile_length, sample_format, predictor; + int rows_per_strip; + int *strip_offsets, strip_offsets_count; + int *strip_byte_counts, strip_byte_counts_count; + unsigned t_filters; + int t_vwidth, t_vheight, t_lm,t_tm; + int t_fuji_width; + float t_shutter; + /* Per-IFD DNG fields */ + INT64 opcode2_offset; + INT64 lineartable_offset; + int lineartable_len; + libraw_dng_color_t dng_color[2]; + libraw_dng_levels_t dng_levels; + int newsubfiletype; +}; + +struct jhead +{ + int algo, bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort quant[64], idct[64], *huff[20], *free[20], *row; +}; + +struct libraw_tiff_tag +{ + ushort tag, type; + int count; + union { + char c[4]; + short s[2]; + int i; + } val; +}; + +struct tiff_hdr +{ + ushort t_order, magic; + int ifd; + ushort pad, ntag; + struct libraw_tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct libraw_tiff_tag exif[4]; + ushort pad3, ngps; + struct libraw_tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char t_desc[512], t_make[64], t_model[64], soft[32], date[20], t_artist[64]; +}; + +#ifdef DEBUG_STAGE_CHECKS +#define CHECK_ORDER_HIGH(expected_stage) \ + do \ + { \ + if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= \ + expected_stage) \ + { \ + fprintf(stderr, "CHECK_HIGH: check %d >= %d\n", \ + imgdata.progress_flags &LIBRAW_PROGRESS_THUMB_MASK, \ + expected_stage); \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } \ + } while (0) + +#define CHECK_ORDER_LOW(expected_stage) \ + do \ + { \ + printf("Checking LOW %d/%d : %d\n", imgdata.progress_flags, \ + expected_stage, imgdata.progress_flags < expected_stage); \ + if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < \ + expected_stage) \ + { \ + printf("failed!\n"); \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } \ + } while (0) +#define CHECK_ORDER_BIT(expected_stage) \ + do \ + { \ + if (imgdata.progress_flags & expected_stage) \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } while (0) + +#define SET_PROC_FLAG(stage) \ + do \ + { \ + imgdata.progress_flags |= stage; \ + fprintf(stderr, "SET_FLAG: %d\n", stage); \ + } while (0) + +#else + +#define CHECK_ORDER_HIGH(expected_stage) \ + do \ + { \ + if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= \ + expected_stage) \ + { \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } \ + } while (0) + +#define CHECK_ORDER_LOW(expected_stage) \ + do \ + { \ + if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < \ + expected_stage) \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } while (0) + +#define CHECK_ORDER_BIT(expected_stage) \ + do \ + { \ + if (imgdata.progress_flags & expected_stage) \ + return LIBRAW_OUT_OF_ORDER_CALL; \ + } while (0) + +#define SET_PROC_FLAG(stage) \ + do \ + { \ + imgdata.progress_flags |= stage; \ + } while (0) + +#endif + +#endif diff --git a/libraw/libraw_types.h b/libraw/libraw_types.h new file mode 100644 index 000000000..ec413b68b --- /dev/null +++ b/libraw/libraw_types.h @@ -0,0 +1,1175 @@ +/* -*- C++ -*- + * File: libraw_types.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8 , 2008 + * + * LibRaw C data structures + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef _LIBRAW_TYPES_H +#define _LIBRAW_TYPES_H + +#include +#ifndef _WIN32 +#include +#endif + +#include + +#if defined(_WIN32) +#if defined(_MSC_VER) && (_MSC_VER <= 1500) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else /* WIN32, but not old MSVC */ +#include +#endif /* _WIN32 */ +#include +#else +#include +#endif + +#if defined(_OPENMP) + +#if defined(LIBRAW_FORCE_OPENMP) +#define LIBRAW_USE_OPENMP +#else +#if defined(_WIN32) +#if defined(_MSC_VER) && \ + (_MSC_VER >= 1600 || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)) +/* VS2010+ : OpenMP works OK, VS2008: have tested by cgilles */ +#define LIBRAW_USE_OPENMP +#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 910) +/* Have not tested on 9.x and 10.x, but Intel documentation claims OpenMP 2.5 + * support in 9.1 */ +#define LIBRAW_USE_OPENMP +#else +#undef LIBRAW_USE_OPENMP +#endif +/* Not Win32 */ +#elif (defined(__APPLE__) || defined(__MACOSX__)) && defined(_REENTRANT) +/* Latest XCode works with OpenMP, need to recheck here */ +#undef LIBRAW_USE_OPENMP +#else +#define LIBRAW_USE_OPENMP +#endif +#endif +#endif + +#ifdef LIBRAW_USE_OPENMP +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if defined(USE_LCMS) +#include +#elif defined(USE_LCMS2) +#include +#else +#define NO_LCMS +#endif + +#include "libraw_const.h" +#include "libraw_version.h" + +#ifdef _WIN32 + typedef __int64 INT64; + typedef unsigned __int64 UINT64; +#else +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + + typedef unsigned char uchar; + typedef unsigned short ushort; + +#ifdef LIBRAW_WIN32_DLLDEFS +#ifdef LIBRAW_NODLL +#define DllDef +#else +#ifdef LIBRAW_BUILDLIB +#define DllDef __declspec(dllexport) +#else +#define DllDef __declspec(dllimport) +#endif +#endif +#else +#define DllDef +#endif + + typedef struct + { + const char *decoder_name; + unsigned decoder_flags; + } libraw_decoder_info_t; + + typedef struct + { + unsigned mix_green; + unsigned raw_color; + unsigned zero_is_bad; + ushort shrink; + ushort fuji_width; + } libraw_internal_output_params_t; + + typedef void (*memory_callback)(void *data, const char *file, + const char *where); + typedef void (*exif_parser_callback)(void *context, int tag, int type, + int len, unsigned int ord, void *ifp, + INT64 base); + + typedef void (*data_callback)(void *data, const char *file, const int offset); + + DllDef void default_data_callback(void *data, const char *file, + const int offset); + + typedef int (*progress_callback)(void *data, enum LibRaw_progress stage, + int iteration, int expected); + typedef int (*pre_identify_callback)(void *ctx); + typedef void (*post_identify_callback)(void *ctx); + typedef void (*process_step_callback)(void *ctx); + + typedef struct + { + data_callback data_cb; + void *datacb_data; + + progress_callback progress_cb; + void *progresscb_data; + + exif_parser_callback exif_cb; + void *exifparser_data; + pre_identify_callback pre_identify_cb; + post_identify_callback post_identify_cb; + process_step_callback pre_subtractblack_cb, pre_scalecolors_cb, + pre_preinterpolate_cb, pre_interpolate_cb, interpolate_bayer_cb, + interpolate_xtrans_cb, post_interpolate_cb, pre_converttorgb_cb, + post_converttorgb_cb; + } libraw_callbacks_t; + + typedef struct + { + enum LibRaw_image_formats type; + ushort height, width, colors, bits; + unsigned int data_size; + unsigned char data[1]; + } libraw_processed_image_t; + + typedef struct + { + char guard[4]; + char make[64]; + char model[64]; + char software[64]; + char normalized_make[64]; + char normalized_model[64]; + unsigned maker_index; + unsigned raw_count; + unsigned dng_version; + unsigned is_foveon; + int colors; + unsigned filters; + char xtrans[6][6]; + char xtrans_abs[6][6]; + char cdesc[5]; + unsigned xmplen; + char *xmpdata; + + } libraw_iparams_t; + + typedef struct + { + ushort cleft, ctop, cwidth, cheight; + } libraw_raw_inset_crop_t; + + typedef struct + { + ushort raw_height, raw_width, height, width, top_margin, left_margin; + ushort iheight, iwidth; + unsigned raw_pitch; + double pixel_aspect; + int flip; + int mask[8][4]; + ushort raw_aspect; + libraw_raw_inset_crop_t raw_inset_crops[2]; + } libraw_image_sizes_t; + + typedef struct + { + short t,l,b,r; // top, left, bottom, right pixel coordinates, (0,0) is top left pixel; + } libraw_area_t; + + struct ph1_t + { + int format, key_off, tag_21a; + int t_black, split_col, black_col, split_row, black_row; + float tag_210; + }; + + typedef struct + { + unsigned parsedfields; + ushort illuminant; + float calibration[4][4]; + float colormatrix[4][3]; + float forwardmatrix[3][4]; + } libraw_dng_color_t; + + typedef struct + { + unsigned parsedfields; + unsigned dng_cblack[LIBRAW_CBLACK_SIZE]; + unsigned dng_black; + float dng_fcblack[LIBRAW_CBLACK_SIZE]; + float dng_fblack; + unsigned dng_whitelevel[4]; + ushort default_crop[4]; /* Origin and size */ + float user_crop[4]; // top-left-bottom-right relative to default_crop + unsigned preview_colorspace; + float analogbalance[4]; + float asshotneutral[4]; + float baseline_exposure; + float LinearResponseLimit; + } libraw_dng_levels_t; + + typedef struct + { + float romm_cam[9]; + } libraw_P1_color_t; + + typedef struct + { + int ColorDataVer; + int ColorDataSubVer; + int SpecularWhiteLevel; + int NormalWhiteLevel; + int ChannelBlackLevel[4]; + int AverageBlackLevel; + /* multishot */ + unsigned int multishot[4]; + /* metering */ + short MeteringMode; + short SpotMeteringMode; + uchar FlashMeteringMode; + short FlashExposureLock; + short ExposureMode; + short AESetting; + /* stabilization */ + short ImageStabilization; + /* flash */ + short FlashMode; + short FlashActivity; + short FlashBits; + short ManualFlashOutput; + short FlashOutput; + short FlashGuideNumber; + /* drive */ + short ContinuousDrive; + /* sensor */ + short SensorWidth; + short SensorHeight; + + int AFMicroAdjMode; + float AFMicroAdjValue; + short MakernotesFlip; + short RecordMode; + short SRAWQuality; + unsigned wbi; + short RF_lensID; + int AutoLightingOptimizer; + int HighlightTonePriority; + + /* -1 = n/a 1 = Economy + 2 = Normal 3 = Fine + 4 = RAW 5 = Superfine + 7 = CRAW 130 = Normal Movie, CRM LightRaw + 131 = CRM StandardRaw */ + short Quality; + /* data compression curve + 0 = OFF 1 = CLogV1 2 = CLogV2? 3 = CLogV3 */ + int CanonLog; + + libraw_area_t DefaultCropAbsolute; + libraw_area_t RecommendedImageArea; // contains the image in proper aspect ratio? + libraw_area_t LeftOpticalBlack; // use this, when present, to estimate black levels? + libraw_area_t UpperOpticalBlack; + libraw_area_t ActiveArea; + + short ISOgain[2]; // AutoISO & BaseISO per ExifTool + } libraw_canon_makernotes_t; + + typedef struct + { + int BaseISO; + double Gain; + char Sensor[8]; + char SensorUnit[64]; // SU + char HostBody[64]; // HB + int SensorCode; + int SensorSubCode; + int CoatingCode; + int uncropped; + +/* CaptureSequenceInitiator is based on the content of the 'model' tag + - values like 'Pinhole', 'Flash Sync', '500 Mech.' etc in .3FR 'model' tag + come from MAIN MENU > SETTINGS > Camera; + - otherwise 'model' contains: + 1. if CF/CFV/CFH, SU enclosure, can be with SU type if '-' is present + 2. else if '-' is present, HB + SU type; + 3. HB; +*/ + char CaptureSequenceInitiator[32]; + +/* SensorUnitConnector, makernotes 0x0015 tag: + - in .3FR - SU side + - in .FFF - HB side +*/ + char SensorUnitConnector[64]; + + int format; // 3FR, FFF, Imacon (H3D-39 and maybe others), Hasselblad/Phocus DNG, Adobe DNG + int nIFD_CM[2]; // number of IFD containing CM + int RecommendedCrop[2]; + +/* mnColorMatrix is in makernotes tag 0x002a; + not present in .3FR files and Imacon/H3D-39 .FFF files; + when present in .FFF and Phocus .DNG files, it is a copy of CM1 from .3FR; + available samples contain all '1's in the first 3 elements +*/ + double mnColorMatrix[4][3]; + + } libraw_hasselblad_makernotes_t; + + typedef struct + { + float ExpoMidPointShift; + ushort DynamicRange; + ushort FilmMode; + ushort DynamicRangeSetting; + ushort DevelopmentDynamicRange; + ushort AutoDynamicRange; + ushort DRangePriority; + ushort DRangePriorityAuto; + ushort DRangePriorityFixed; + + /* + tag 0x9200, converted to BrightnessCompensation + F700, S3Pro, S5Pro, S20Pro, S200EXR + E550, E900, F810, S5600, S6500fd, S9000, S9500, S100FS + */ + float BrightnessCompensation; /* in EV, if =4, raw data * 2^4 */ + + ushort FocusMode; + ushort AFMode; + ushort FocusPixel[2]; + ushort PrioritySettings; + unsigned FocusSettings; + unsigned AF_C_Settings; + ushort FocusWarning; + ushort ImageStabilization[3]; + ushort FlashMode; + ushort WB_Preset; + + /* ShutterType: + 0 - mechanical + 1 = electronic + 2 = electronic, long shutter speed + 3 = electronic, front curtain + */ + ushort ShutterType; + ushort ExrMode; + ushort Macro; + unsigned Rating; + + /* CropMode: + 1 - FF on GFX, + 2 - sports finder (mechanical shutter), + 4 - 1.25x crop (electronic shutter, continuous high) + */ + ushort CropMode; + char SerialSignature[0x0c + 1]; + char SensorID[4 + 1]; + char RAFVersion[4 + 1]; + int RAFDataGeneration; // 0 (none), 1..4, 4096 + ushort RAFDataVersion; + int isTSNERDTS; + + /* DriveMode: + 0 - single frame + 1 - continuous low + 2 - continuous high + */ + short DriveMode; + + /* + tag 0x4000 BlackLevel: + S9100, S9000, S7000, S6000fd, S5200, S5100, S5000, + S5Pro, S3Pro, S2Pro, S20Pro, + S200EXR, S100FS, + F810, F700, + E900, E550, + DBP, and aliases for all of the above + */ + ushort BlackLevel[9]; + unsigned RAFData_ImageSizeTable[32]; + int AutoBracketing; + int SequenceNumber; + int SeriesLength; + float PixelShiftOffset[2]; + int ImageCount; + } libraw_fuji_info_t; + + typedef struct + { + ushort cleft, ctop, cwidth, cheight; + } libraw_sensor_highspeed_crop_t; + + typedef struct + { + double ExposureBracketValue; + ushort ActiveDLighting; + ushort ShootingMode; + /* stabilization */ + uchar ImageStabilization[7]; + uchar VibrationReduction; + uchar VRMode; + /* flash */ + char FlashSetting[13]; + char FlashType[20]; + uchar FlashExposureCompensation[4]; + uchar ExternalFlashExposureComp[4]; + uchar FlashExposureBracketValue[4]; + uchar FlashMode; + signed char FlashExposureCompensation2; + signed char FlashExposureCompensation3; + signed char FlashExposureCompensation4; + uchar FlashSource; + uchar FlashFirmware[2]; + uchar ExternalFlashFlags; + uchar FlashControlCommanderMode; + uchar FlashOutputAndCompensation; + uchar FlashFocalLength; + uchar FlashGNDistance; + uchar FlashGroupControlMode[4]; + uchar FlashGroupOutputAndCompensation[4]; + uchar FlashColorFilter; + +/* NEF compression, comments follow those for ExifTool tag 0x0093: + 1: Lossy (type 1) + 2: Uncompressed + 3: Lossless + 4: Lossy (type 2) + 5: Striped packed 12-bit + 6: Uncompressed (14-bit reduced to 12-bit) + 7: Unpacked 12-bit + 8: Small raw + 9: Packed 12-bit + 10: Packed 14-bit + 13: High Efficiency (HE) + 14: High Efficiency* (HE*) +*/ + ushort NEFCompression; + + int ExposureMode; + int ExposureProgram; + int nMEshots; + int MEgainOn; + double ME_WB[4]; + uchar AFFineTune; + uchar AFFineTuneIndex; + int8_t AFFineTuneAdj; + unsigned LensDataVersion; + unsigned FlashInfoVersion; + unsigned ColorBalanceVersion; + uchar key; + ushort NEFBitDepth[4]; + ushort HighSpeedCropFormat; /* 1 -> 1.3x; 2 -> DX; 3 -> 5:4; 4 -> 3:2; 6 -> + 16:9; 11 -> FX uncropped; 12 -> DX uncropped; + 17 -> 1:1 */ + libraw_sensor_highspeed_crop_t SensorHighSpeedCrop; + ushort SensorWidth; + ushort SensorHeight; + ushort Active_D_Lighting; + unsigned ShotInfoVersion; + short MakernotesFlip; + double RollAngle; // positive is clockwise, CW + double PitchAngle; // positive is upwords + double YawAngle; // positive is to the right + } libraw_nikon_makernotes_t; + + typedef struct + { + char CameraType2[6]; + ushort ValidBits; + int SensorCalibration[2]; + ushort DriveMode[5]; + ushort ColorSpace; + ushort FocusMode[2]; + ushort AutoFocus; + ushort AFPoint; + unsigned AFAreas[64]; + double AFPointSelected[5]; + ushort AFResult; + uchar AFFineTune; + short AFFineTuneAdj[3]; + unsigned SpecialMode[3]; + ushort ZoomStepCount; + ushort FocusStepCount; + ushort FocusStepInfinity; + ushort FocusStepNear; + double FocusDistance; + ushort AspectFrame[4]; // left, top, width, height + unsigned StackedImage[2]; + uchar isLiveND; + unsigned LiveNDfactor; + ushort Panorama_mode; + ushort Panorama_frameNum; + } libraw_olympus_makernotes_t; + + typedef struct + { + /* Compression: + 34826 (Panasonic RAW 2): LEICA DIGILUX 2; + 34828 (Panasonic RAW 3): LEICA D-LUX 3; LEICA V-LUX 1; Panasonic DMC-LX1; + Panasonic DMC-LX2; Panasonic DMC-FZ30; Panasonic DMC-FZ50; 34830 (not in + exiftool): LEICA DIGILUX 3; Panasonic DMC-L1; 34316 (Panasonic RAW 1): + others (LEICA, Panasonic, YUNEEC); + */ + ushort Compression; + ushort BlackLevelDim; + float BlackLevel[8]; + unsigned Multishot; /* 0 is Off, 65536 is Pixel Shift */ + float gamma; + int HighISOMultiplier[3]; /* 0->R, 1->G, 2->B */ + short FocusStepNear; + short FocusStepCount; + unsigned ZoomPosition; + unsigned LensManufacturer; + } libraw_panasonic_makernotes_t; + + typedef struct + { + uchar DriveMode[4]; + ushort FocusMode[2]; + ushort AFPointSelected[2]; + ushort AFPointSelected_Area; + int AFPointsInFocus_version; + unsigned AFPointsInFocus; + ushort FocusPosition; + short AFAdjustment; + uchar AFPointMode; + uchar MultiExposure; /* last bit is not "1" if ME is not used */ + ushort Quality; /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic + pixel shift */ + } libraw_pentax_makernotes_t; + + typedef struct + { + ushort AFStatus; + unsigned AFAreaXPosition[2]; + unsigned AFAreaYPosition[2]; + ushort AFAreaMode; + unsigned SensorWidth; + unsigned SensorHeight; + unsigned CroppedImageWidth; + unsigned CroppedImageHeight; + ushort WideAdapter; + ushort CropMode; + ushort NDFilter; + ushort AutoBracketing; + ushort MacroMode; + ushort FlashMode; + double FlashExposureComp; + double ManualFlashOutput; + } libraw_ricoh_makernotes_t; + + typedef struct + { + unsigned ImageSizeFull[4]; + unsigned ImageSizeCrop[4]; + int ColorSpace[2]; + unsigned key[11]; + double DigitalGain; /* PostAEGain, digital stretch */ + int DeviceType; + char LensFirmware[32]; + } libraw_samsung_makernotes_t; + + typedef struct + { + ushort BlackLevelTop; + ushort BlackLevelBottom; + short offset_left, offset_top; /* KDC files, negative values or zeros */ + ushort clipBlack, clipWhite; /* valid for P712, P850, P880 */ + float romm_camDaylight[3][3]; + float romm_camTungsten[3][3]; + float romm_camFluorescent[3][3]; + float romm_camFlash[3][3]; + float romm_camCustom[3][3]; + float romm_camAuto[3][3]; + ushort val018percent, val100percent, val170percent; + short MakerNoteKodak8a; + float ISOCalibrationGain; + float AnalogISO; + } libraw_kodak_makernotes_t; + + typedef struct { + char Software[64]; // tag 0x0203 + char SystemType[64]; // tag 0x0204 + char FirmwareString[256]; // tag 0x0301 + char SystemModel[64]; + } libraw_p1_makernotes_t; + + typedef struct + { +/* afdata: + 0x0010 CameraInfo + 0x2020 AFPointsUsed + 0x2022 FocalPlaneAFPointsUsed + 0x202a Tag202a + 0x940e AFInfo +*/ + ushort CameraType; // init in 0xffff + uchar Sony0x9400_version; /* 0 if not found/deciphered, + 0xa, 0xb, 0xc following exiftool convention */ + uchar Sony0x9400_ReleaseMode2; + unsigned Sony0x9400_SequenceImageNumber; + uchar Sony0x9400_SequenceLength1; + unsigned Sony0x9400_SequenceFileNumber; + uchar Sony0x9400_SequenceLength2; + uint8_t AFAreaModeSetting; // init in 0xff; + + uint16_t AFAreaMode; // init in 0xffff; + + ushort FlexibleSpotPosition[2]; // init in (0xffff, 0xffff) + uint8_t AFPointSelected; // init in 0xff + uint8_t AFPointSelected_0x201e; // init in 0xff + short nAFPointsUsed; + uint8_t AFPointsUsed[10]; + uint8_t AFTracking; // init in 0xff + uint8_t AFType; + ushort FocusLocation[4]; + ushort FocusPosition; // init in 0xffff + int8_t AFMicroAdjValue; // init in 0x7f + int8_t AFMicroAdjOn; // init in -1 + uchar AFMicroAdjRegisteredLenses; // init in 0xff + ushort VariableLowPassFilter; + unsigned LongExposureNoiseReduction; // init in 0xffffffff + ushort HighISONoiseReduction; // init in 0xffff + ushort HDR[2]; + ushort group2010; + ushort group9050; + ushort real_iso_offset; // init in 0xffff + ushort MeteringMode_offset; + ushort ExposureProgram_offset; + ushort ReleaseMode2_offset; + unsigned MinoltaCamID; // init in 0xffffffff + float firmware; + ushort ImageCount3_offset; // init in 0xffff + unsigned ImageCount3; + unsigned ElectronicFrontCurtainShutter; // init in 0xffffffff + ushort MeteringMode2; + char SonyDateTime[20]; + unsigned ShotNumberSincePowerUp; + ushort PixelShiftGroupPrefix; + unsigned PixelShiftGroupID; + char nShotsInPixelShiftGroup; + char numInPixelShiftGroup; /* '0' if ARQ, first shot in the group has '1' + here */ + ushort prd_ImageHeight, prd_ImageWidth; + ushort prd_Total_bps; + ushort prd_Active_bps; + ushort prd_StorageMethod; /* 82 -> Padded; 89 -> Linear */ + ushort prd_BayerPattern; /* 0 -> not valid; 1 -> RGGB; 4 -> GBRG */ + + ushort SonyRawFileType; /* init in 0xffff + valid for ARW 2.0 and up (FileFormat >= 3000) + takes precedence over RAWFileType and Quality: + 0 for uncompressed 14-bit raw + 1 for uncompressed 12-bit raw + 2 for compressed raw (lossy) + 3 for lossless compressed raw + 4 for lossless compressed raw v.2 (ILCE-1) + */ + ushort RAWFileType; /* init in 0xffff + takes precedence over Quality + 0 for compressed raw, + 1 for uncompressed; + 2 lossless compressed raw v.2 + */ + ushort RawSizeType; /* init in 0xffff + 1 - large, + 2 - small, + 3 - medium + */ + unsigned Quality; /* init in 0xffffffff + 0 or 6 for raw, 7 or 8 for compressed raw */ + ushort FileFormat; /* 1000 SR2 + 2000 ARW 1.0 + 3000 ARW 2.0 + 3100 ARW 2.1 + 3200 ARW 2.2 + 3300 ARW 2.3 + 3310 ARW 2.3.1 + 3320 ARW 2.3.2 + 3330 ARW 2.3.3 + 3350 ARW 2.3.5 + 4000 ARW 4.0 + */ + char MetaVersion [16]; + } libraw_sony_info_t; + + typedef struct + { + ushort curve[0x10000]; + unsigned cblack[LIBRAW_CBLACK_SIZE]; + unsigned black; + unsigned data_maximum; + unsigned maximum; + +// Canon (SpecularWhiteLevel) +// Kodak (14N, 14nx, SLR/c/n, DCS720X, DCS760C, DCS760M, ProBack, ProBack645, P712, P880, P850) +// Olympus, except: +// C5050Z, C5060WZ, C7070WZ, C8080WZ +// SP350, SP500UZ, SP510UZ, SP565UZ +// E-10, E-20 +// E-300, E-330, E-400, E-410, E-420, E-450, E-500, E-510, E-520 +// E-1, E-3 +// XZ-1 +// Panasonic +// Pentax +// Sony +// and aliases of the above +// DNG + long linear_max[4]; + + float fmaximum; + float fnorm; + ushort white[8][8]; + float cam_mul[4]; + float pre_mul[4]; + float cmatrix[3][4]; + float ccm[3][4]; + float rgb_cam[3][4]; + float cam_xyz[4][3]; + struct ph1_t phase_one_data; + float flash_used; + float canon_ev; + char model2[64]; + char UniqueCameraModel[64]; + char LocalizedCameraModel[64]; + char ImageUniqueID[64]; + char RawDataUniqueID[17]; + char OriginalRawFileName[64]; + void *profile; + unsigned profile_length; + unsigned black_stat[8]; + libraw_dng_color_t dng_color[2]; + libraw_dng_levels_t dng_levels; + int WB_Coeffs[256][4]; /* R, G1, B, G2 coeffs */ + float WBCT_Coeffs[64][5]; /* CCT, than R, G1, B, G2 coeffs */ + int as_shot_wb_applied; + libraw_P1_color_t P1_color[2]; + unsigned raw_bps; /* for Phase One: raw format; For other cameras: bits per pixel (copy of tiff_bps in most cases) */ + /* Phase One raw format values, makernotes tag 0x010e: + 0 Name unknown + 1 "RAW 1" + 2 "RAW 2" + 3 "IIQ L" (IIQ L14) + 4 Never seen + 5 "IIQ S" + 6 "IIQ Sv2" (S14 / S14+) + 7 Never seen + 8 "IIQ L16" (IIQ L16EX / IIQ L16) + */ + int ExifColorSpace; + } libraw_colordata_t; + + typedef struct + { + enum LibRaw_thumbnail_formats tformat; + ushort twidth, theight; + unsigned tlength; + int tcolors; + char *thumb; + } libraw_thumbnail_t; + + typedef struct + { + enum LibRaw_internal_thumbnail_formats tformat; + ushort twidth, theight, tflip; + unsigned tlength; + unsigned tmisc; + INT64 toffset; + }libraw_thumbnail_item_t; + + typedef struct + { + int thumbcount; + libraw_thumbnail_item_t thumblist[LIBRAW_THUMBNAIL_MAXCOUNT]; + } libraw_thumbnail_list_t; + + typedef struct + { + float latitude[3]; /* Deg,min,sec */ + float longitude[3]; /* Deg,min,sec */ + float gpstimestamp[3]; /* Deg,min,sec */ + float altitude; + char altref, latref, longref, gpsstatus; + char gpsparsed; + } libraw_gps_info_t; + + typedef struct + { + float iso_speed; + float shutter; + float aperture; + float focal_len; + time_t timestamp; + unsigned shot_order; + unsigned gpsdata[32]; + libraw_gps_info_t parsed_gps; + char desc[512], artist[64]; + float analogbalance[4]; + } libraw_imgother_t; + + typedef struct + { + unsigned AFInfoData_tag; + short AFInfoData_order; + unsigned AFInfoData_version; + unsigned AFInfoData_length; + uchar *AFInfoData; + } libraw_afinfo_item_t; + + typedef struct { + float FlashEC; + float FlashGN; + float CameraTemperature; + float SensorTemperature; + float SensorTemperature2; + float LensTemperature; + float AmbientTemperature; + float BatteryTemperature; + float exifAmbientTemperature; + float exifHumidity; + float exifPressure; + float exifWaterDepth; + float exifAcceleration; + float exifCameraElevationAngle; + float real_ISO; + float exifExposureIndex; + ushort ColorSpace; + char firmware[128]; + float ExposureCalibrationShift; + libraw_afinfo_item_t afdata[LIBRAW_AFDATA_MAXCOUNT]; + int afcount; + } libraw_metadata_common_t; + + typedef struct + { + unsigned greybox[4]; /* -A x1 y1 x2 y2 */ + unsigned cropbox[4]; /* -B x1 y1 x2 y2 */ + double aber[4]; /* -C */ + double gamm[6]; /* -g */ + float user_mul[4]; /* -r mul0 mul1 mul2 mul3 */ + float bright; /* -b */ + float threshold; /* -n */ + int half_size; /* -h */ + int four_color_rgb; /* -f */ + int highlight; /* -H */ + int use_auto_wb; /* -a */ + int use_camera_wb; /* -w */ + int use_camera_matrix; /* +M/-M */ + int output_color; /* -o */ + char *output_profile; /* -o */ + char *camera_profile; /* -p */ + char *bad_pixels; /* -P */ + char *dark_frame; /* -K */ + int output_bps; /* -4 */ + int output_tiff; /* -T */ + int output_flags; + int user_flip; /* -t */ + int user_qual; /* -q */ + int user_black; /* -k */ + int user_cblack[4]; + int user_sat; /* -S */ + int med_passes; /* -m */ + float auto_bright_thr; + float adjust_maximum_thr; + int no_auto_bright; /* -W */ + int use_fuji_rotate; /* -j */ + int green_matching; + /* DCB parameters */ + int dcb_iterations; + int dcb_enhance_fl; + int fbdd_noiserd; + int exp_correc; + float exp_shift; + float exp_preser; + /* Disable Auto-scale */ + int no_auto_scale; + /* Disable intepolation */ + int no_interpolation; + } libraw_output_params_t; + + typedef struct + { + /* Raw speed */ + int use_rawspeed; + /* DNG SDK */ + int use_dngsdk; + unsigned options; + unsigned shot_select; /* -s */ + unsigned specials; + unsigned max_raw_memory_mb; + int sony_arw2_posterization_thr; + /* Nikon Coolscan */ + float coolscan_nef_gamma; + char p4shot_order[5]; + /* Custom camera list */ + char **custom_camera_strings; + }libraw_raw_unpack_params_t; + + typedef struct + { + /* really allocated bitmap */ + void *raw_alloc; + /* alias to single_channel variant */ + ushort *raw_image; + /* alias to 4-channel variant */ + ushort (*color4_image)[4]; + /* alias to 3-color variand decoded by RawSpeed */ + ushort (*color3_image)[3]; + /* float bayer */ + float *float_image; + /* float 3-component */ + float (*float3_image)[3]; + /* float 4-component */ + float (*float4_image)[4]; + + /* Phase One black level data; */ + short (*ph1_cblack)[2]; + short (*ph1_rblack)[2]; + /* save color and sizes here, too.... */ + libraw_iparams_t iparams; + libraw_image_sizes_t sizes; + libraw_internal_output_params_t ioparams; + libraw_colordata_t color; + } libraw_rawdata_t; + + typedef struct + { + unsigned long long LensID; + char Lens[128]; + ushort LensFormat; /* to characterize the image circle the lens covers */ + ushort LensMount; /* 'male', lens itself */ + unsigned long long CamID; + ushort CameraFormat; /* some of the sensor formats */ + ushort CameraMount; /* 'female', body throat */ + char body[64]; + short FocalType; /* -1/0 is unknown; 1 is fixed focal; 2 is zoom */ + char LensFeatures_pre[16], LensFeatures_suf[16]; + float MinFocal, MaxFocal; + float MaxAp4MinFocal, MaxAp4MaxFocal, MinAp4MinFocal, MinAp4MaxFocal; + float MaxAp, MinAp; + float CurFocal, CurAp; + float MaxAp4CurFocal, MinAp4CurFocal; + float MinFocusDistance; + float FocusRangeIndex; + float LensFStops; + unsigned long long TeleconverterID; + char Teleconverter[128]; + unsigned long long AdapterID; + char Adapter[128]; + unsigned long long AttachmentID; + char Attachment[128]; + ushort FocalUnits; + float FocalLengthIn35mmFormat; + } libraw_makernotes_lens_t; + + typedef struct + { + float EffectiveMaxAp; + uchar LensIDNumber, LensFStops, MCUVersion, LensType; + } libraw_nikonlens_t; + + typedef struct + { + float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal; + } libraw_dnglens_t; + + typedef struct + { + float MinFocal, MaxFocal, MaxAp4MinFocal, MaxAp4MaxFocal, EXIF_MaxAp; + char LensMake[128], Lens[128], LensSerial[128], InternalLensSerial[128]; + ushort FocalLengthIn35mmFormat; + libraw_nikonlens_t nikon; + libraw_dnglens_t dng; + libraw_makernotes_lens_t makernotes; + } libraw_lensinfo_t; + + typedef struct + { + libraw_canon_makernotes_t canon; + libraw_nikon_makernotes_t nikon; + libraw_hasselblad_makernotes_t hasselblad; + libraw_fuji_info_t fuji; + libraw_olympus_makernotes_t olympus; + libraw_sony_info_t sony; + libraw_kodak_makernotes_t kodak; + libraw_panasonic_makernotes_t panasonic; + libraw_pentax_makernotes_t pentax; + libraw_p1_makernotes_t phaseone; + libraw_ricoh_makernotes_t ricoh; + libraw_samsung_makernotes_t samsung; + libraw_metadata_common_t common; + } libraw_makernotes_t; + + typedef struct + { + short DriveMode; + short FocusMode; + short MeteringMode; + short AFPoint; + short ExposureMode; + short ExposureProgram; + short ImageStabilization; + char BodySerial[64]; + char InternalBodySerial[64]; /* this may be PCB or sensor serial, depends on + make/model */ + } libraw_shootinginfo_t; + + typedef struct + { + unsigned fsize; + ushort rw, rh; + uchar lm, tm, rm, bm; + ushort lf; + uchar cf, max, flags; + char t_make[10], t_model[20]; + ushort offset; + } libraw_custom_camera_t; + + typedef struct + { + ushort (*image)[4]; + libraw_image_sizes_t sizes; + libraw_iparams_t idata; + libraw_lensinfo_t lens; + libraw_makernotes_t makernotes; + libraw_shootinginfo_t shootinginfo; + libraw_output_params_t params; + libraw_raw_unpack_params_t rawparams; + unsigned int progress_flags; + unsigned int process_warnings; + libraw_colordata_t color; + libraw_imgother_t other; + libraw_thumbnail_t thumbnail; + libraw_thumbnail_list_t thumbs_list; + libraw_rawdata_t rawdata; + void *parent_class; + } libraw_data_t; + + struct fuji_q_table + { + int8_t *q_table; /* quantization table */ + int raw_bits; + int total_values; + int max_grad; // sdp val + int q_grad_mult; // quant_gradient multiplier + int q_base; + }; + + struct fuji_compressed_params + { + struct fuji_q_table qt[4]; + void *buf; + int max_bits; + int min_value; + int max_value; // q_point[4] + ushort line_width; + }; + +#ifdef __cplusplus +} +#endif + +#if defined (LIBRAW_LIBRARY_BUILD) && defined(__cplusplus) + +class libraw_static_table_t +{ +public: + libraw_static_table_t(const int *a, const unsigned s): data(a),_size(s) {} + libraw_static_table_t(): data(0),_size(0){} + libraw_static_table_t(const libraw_static_table_t& s) : data(s.data), _size(s._size) {} + unsigned size() const { return _size; } + libraw_static_table_t& operator = (const libraw_static_table_t& s) + { + _size = s._size; + data = s.data; + return *this; + } + int operator [] (unsigned idx) const + { + if (idx < _size) return data[idx]; + if(_size>0 && data) return data[0]; + return 0; + } +private: + const int *data; + unsigned _size; +}; + +#endif + + +/* Byte order */ +#if defined(__POWERPC__) +#define LibRawBigEndian 1 + +#elif defined(__INTEL__) +#define LibRawBigEndian 0 + +#elif defined(_M_IX86) || defined(__i386__) +#define LibRawBigEndian 0 + +#elif defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) +#define LibRawBigEndian 0 + +#elif defined(__LITTLE_ENDIAN__) +#define LibRawBigEndian 0 + +#elif defined(__BIG_ENDIAN__) +#define LibRawBigEndian 1 +#elif defined(_ARM_) +#define LibRawBigEndian 0 + +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define LibRawBigEndian 0 + +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define LibRawBigEndian 1 +#else +#ifndef qXCodeRez +#error Unable to figure out byte order. +#endif +#endif + +#endif diff --git a/libraw/libraw_version.h b/libraw/libraw_version.h new file mode 100644 index 000000000..3845a5e46 --- /dev/null +++ b/libraw/libraw_version.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- + * File: libraw_version.h + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Mon Sept 8, 2008 + * + * LibRaw C++ interface + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 +(See the file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 +(See the file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#ifndef __VERSION_H +#define __VERSION_H + +#define LIBRAW_MAJOR_VERSION 0 +#define LIBRAW_MINOR_VERSION 21 +#define LIBRAW_PATCH_VERSION 1 +#define LIBRAW_VERSION_TAIL Release + +#define LIBRAW_SHLIB_CURRENT 23 +#define LIBRAW_SHLIB_REVISION 0 +#define LIBRAW_SHLIB_AGE 0 + +#define _LIBRAW_VERSION_MAKE(a, b, c, d) #a "." #b "." #c "-" #d +#define LIBRAW_VERSION_MAKE(a, b, c, d) _LIBRAW_VERSION_MAKE(a, b, c, d) + +#define LIBRAW_VERSION_STR \ + LIBRAW_VERSION_MAKE(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, \ + LIBRAW_PATCH_VERSION, LIBRAW_VERSION_TAIL) + +#define LIBRAW_MAKE_VERSION(major, minor, patch) \ + (((major) << 16) | ((minor) << 8) | (patch)) + +#define LIBRAW_VERSION \ + LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, \ + LIBRAW_PATCH_VERSION) + +#define LIBRAW_CHECK_VERSION(major, minor, patch) \ + (LibRaw::versionNumber() >= LIBRAW_MAKE_VERSION(major, minor, patch)) + +#define LIBRAW_RUNTIME_CHECK_VERSION_EXACT() \ + ((LibRaw::versionNumber() & 0xffff00) == \ + LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, 0)) + +#define LIBRAW_RUNTIME_CHECK_VERSION_NOTLESS() \ + ((LibRaw::versionNumber() & 0xffff00) >= \ + LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, 0)) + +#define LIBRAW_COMPILE_CHECK_VERSION(major, minor) \ + (LIBRAW_MAKE_VERSION(major, minor, 0) == (LIBRAW_VERSION & 0xffff00)) + +#define LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(major, minor) \ + (LIBRAW_MAKE_VERSION(major, minor, 0) <= (LIBRAW_VERSION & 0xffff00)) + +#endif diff --git a/libraw_r.pc.in b/libraw_r.pc.in new file mode 100644 index 000000000..92bbbffa1 --- /dev/null +++ b/libraw_r.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libraw +Description: Raw image decoder library (thread-safe) +Requires: @PACKAGE_REQUIRES@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lraw_r -lstdc++@PC_OPENMP@ +Libs.private: @PACKAGE_LIBS_PRIVATE@ +Cflags: -I${includedir}/libraw -I${includedir} diff --git a/m4/ax_openmp.m4 b/m4/ax_openmp.m4 new file mode 100644 index 000000000..7ea794be0 --- /dev/null +++ b/m4/ax_openmp.m4 @@ -0,0 +1,99 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_openmp.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro tries to find out how to compile programs that use OpenMP a +# standard API and set of compiler directives for parallel programming +# (see http://www-unix.mcs/) +# +# On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS +# output variable to the flag (e.g. -omp) used both to compile *and* link +# OpenMP programs in the current language. +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. +# +# If you want to compile everything with OpenMP, you should set: +# +# CFLAGS="$CFLAGS $OPENMP_CFLAGS" +# #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" +# #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" +# +# (depending on the selected language). +# +# The user can override the default choice by setting the corresponding +# environment variable (e.g. OPENMP_CFLAGS). +# +# ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is +# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is +# not found. If ACTION-IF-FOUND is not specified, the default action will +# define HAVE_OPENMP. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 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 . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 8 + +AC_DEFUN([AX_OPENMP], [ +AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX + +AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS +ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown +# Flags to try: -fopenmp (gcc), -openmp (icc), -mp (SGI & PGI), +# -xopenmp (Sun), -omp (Tru64), -qsmp=omp (AIX), none +ax_openmp_flags="-fopenmp -openmp -mp -xopenmp -omp -qsmp=omp none" +if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then + ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" +fi +for ax_openmp_flag in $ax_openmp_flags; do + case $ax_openmp_flag in + none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; + *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; + esac + AC_TRY_LINK_FUNC(omp_set_num_threads, + [ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break]) +done +[]_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS +]) +if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then + m4_default([$2],:) +else + if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then + OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp + fi + m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) +fi +])dnl AX_OPENMP diff --git a/mkdist.sh b/mkdist.sh new file mode 100755 index 000000000..247ab16af --- /dev/null +++ b/mkdist.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +if [ -d CVS ] ; then + echo 'Use mkdist script in cvs export-ed dirs' +else + if [ -f Makefile.devel ] ; then + autoreconf --install + mkdir dcraw + cd dcraw + wget https://www.dechifro.org/dcraw/dcraw.c + cd .. + rm -f clist2c.pl clist2html.pl + rm -f Makefile.devel + rm mkdist.sh export-dist.sh + else + echo 'Wrong directory or mkdist.sh already executed' + fi +fi diff --git a/object/.keep_me b/object/.keep_me new file mode 100644 index 000000000..e69de29bb diff --git a/rsxml2c.sh b/rsxml2c.sh new file mode 100755 index 000000000..0fea28ad9 --- /dev/null +++ b/rsxml2c.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "const char *_rawspeed_data_xml[]={" +cat $1 | tr -d '\015' | sed -e 's/\\/\\\\/g;s/"/\\"/g;s/ /\\t/g;s/^/"/;s/$/\\n",/' +echo "0" +echo "};" diff --git a/samples/4channels.cpp b/samples/4channels.cpp new file mode 100644 index 000000000..82d40f4e0 --- /dev/null +++ b/samples/4channels.cpp @@ -0,0 +1,174 @@ +/* -*- C++ -*- + * File: 4channels.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Mon Feb 09, 2009 + * + * LibRaw sample + * Generates 4 TIFF file from RAW data, one file per channel + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#else +#include +#endif + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#endif + +int main(int ac, char *av[]) +{ + int i, ret; + int autoscale = 0, black_subtraction = 1, use_gamma = 0; + char outfn[1024]; + + LibRaw RawProcessor; + if (ac < 2) + { + usage: + printf("4channels - LibRaw %s sample. %d cameras supported\n" + "Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n" + "\t-s N - select Nth image in file (default=0)\n" + "\t-g - use gamma correction with gamma 2.2 (not precise,use for " + "visual inspection only)\n" + "\t-A - autoscaling (by integer factor)\n" + "\t-B - no black subtraction\n", + LibRaw::version(), LibRaw::cameraCount(), av[0]); + return 0; + } + +#define P1 RawProcessor.imgdata.idata +#define S RawProcessor.imgdata.sizes +#define C RawProcessor.imgdata.color +#define T RawProcessor.imgdata.thumbnail +#define P2 RawProcessor.imgdata.other +#define OUT RawProcessor.imgdata.params +#define OUTR RawProcessor.imgdata.rawparams + + OUT.output_bps = 16; + OUT.output_tiff = 1; + OUT.user_flip = 0; + OUT.no_auto_bright = 1; + OUT.half_size = 1; + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == 's' && av[i][2] == 0) + { + i++; + OUTR.shot_select = av[i] ? atoi(av[i]) : 0; + } + else if (av[i][1] == 'g' && av[i][2] == 0) + use_gamma = 1; + else if (av[i][1] == 'A' && av[i][2] == 0) + autoscale = 1; + else if (av[i][1] == 'B' && av[i][2] == 0) + { + black_subtraction = 0; + } + else + goto usage; + continue; + } + if (!use_gamma) + OUT.gamm[0] = OUT.gamm[1] = 1; + + int c; + printf("Processing file %s\n", av[i]); + if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + if (P1.is_foveon) + { + printf("Cannot process Foveon image %s\n", av[i]); + continue; + } + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); + continue; + } + RawProcessor.raw2image(); + if (black_subtraction) + { + RawProcessor.subtract_black(); + } + + if (autoscale) + { + unsigned max = 0, scale = 1; + for (int j = 0; j < S.iheight * S.iwidth; j++) + for (int c = 0; c < 4; c++) + if (max < RawProcessor.imgdata.image[j][c]) + max = RawProcessor.imgdata.image[j][c]; + if (max > 0 && max < 1 << 15) + { + scale = (1 << 16) / max; + printf("Scaling with multiplier=%d (max=%d)\n", scale, max); + for (int j = 0; j < S.iheight * S.iwidth; j++) + for (c = 0; c < 4; c++) + RawProcessor.imgdata.image[j][c] *= scale; + } + printf("Black level (scaled)=%d\n", C.black * scale); + } + else + printf("Black level (unscaled)=%d\n", C.black); + + // hack to make dcraw tiff writer happy + int isrgb = (P1.colors == 4 ? 0 : 1); + P1.colors = 1; + S.width = S.iwidth; + S.height = S.iheight; + + for (int layer = 0; layer < 4; layer++) + { + if (layer > 0) + { + for (int rc = 0; rc < S.iheight * S.iwidth; rc++) + RawProcessor.imgdata.image[rc][0] = + RawProcessor.imgdata.image[rc][layer]; + } + char lname[8]; + if (isrgb) + { + snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]); + if (layer == 3) + strcat(lname, "2"); + } + else + snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]); + + if (OUTR.shot_select) + snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUTR.shot_select, + lname); + else + snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname); + + printf("Writing file %s\n", outfn); + if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) + fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); + } + } + return 0; +} diff --git a/samples/Makefile b/samples/Makefile new file mode 100644 index 000000000..be880e835 --- /dev/null +++ b/samples/Makefile @@ -0,0 +1,2 @@ +all: + (cd ..; make all_samples) diff --git a/samples/dcraw_emu.cpp b/samples/dcraw_emu.cpp new file mode 100644 index 000000000..1af82ff04 --- /dev/null +++ b/samples/dcraw_emu.cpp @@ -0,0 +1,670 @@ +/* -*- C++ -*- + * File: dcraw_emu.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sun Mar 23, 2008 + * + * LibRaw simple C++ API sample: almost complete dcraw emulator + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#ifdef _MSC_VER +// suppress sprintf-related warning. sprintf() is permitted in sample code +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#else +#include +#endif +#include +#include + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#include +#else +#define O_BINARY 0 +#endif + +#ifdef USE_DNGSDK +#include "dng_host.h" +#include "dng_negative.h" +#include "dng_simple_image.h" +#include "dng_info.h" +#endif + +void usage(const char *prog) +{ + printf("dcraw_emu: almost complete dcraw emulator\n"); + printf("Usage: %s [OPTION]... [FILE]...\n", prog); + printf("-c float-num Set adjust maximum threshold (default 0.75)\n" + "-v Verbose: print progress messages (repeated -v will add " + "verbosity)\n" + "-w Use camera white balance, if possible\n" + "-a Average the whole image for white balance\n" + "-A Average a grey box for white balance\n" + "-r Set custom white balance\n" + "+M/-M Use/don't use an embedded color matrix\n" + "-C Correct chromatic aberration\n" + "-P Fix the dead pixels listed in this file\n" + "-K Subtract dark frame (16-bit raw PGM)\n" + "-k Set the darkness level\n" + "-S Set the saturation level\n" + "-R Set raw processing options to num\n" + "-n Set threshold for wavelet denoising\n" + "-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)\n" + "-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)\n" + "-o [0-8] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES,\n" + " DCI-P3,Rec2020)\n" +#ifndef NO_LCMS + "-o file Output ICC profile\n" + "-p file Camera input profile (use \'embed\' for embedded profile)\n" +#endif + "-j Don't stretch or rotate raw pixels\n" + "-W Don't automatically brighten the image\n" + "-b Adjust brightness (default = 1.0)\n" + "-q N Set the interpolation quality:\n" + " 0 - linear, 1 - VNG, 2 - PPG, 3 - AHD, 4 - DCB\n" + " 11 - DHT, 12 - AAHD\n" + "-h Half-size color image (twice as fast as \"-q 0\")\n" + "-f Interpolate RGGB as four colors\n" + "-m Apply a 3x3 median filter to R-G and B-G\n" + "-s [0..N-1] Select one raw image from input file\n" + "-4 Linear 16-bit, same as \"-6 -W -g 1 1\n" + "-6 Write 16-bit output\n" + "-g pow ts Set gamma curve to gamma pow and toe slope ts (default = " + "2.222 4.5)\n" + "-T Write TIFF instead of PPM\n" + "-G Use green_matching() filter\n" + "-B use cropbox\n" + "-F Use FILE I/O instead of streambuf API\n" + "-Z Output filename generation rules\n" + " .suf => append .suf to input name, keeping existing suffix " + "too\n" + " suf => replace input filename last extension\n" + " - => output to stdout\n" + " filename.suf => output to filename.suf\n" + "-timing Detailed timing report\n" + "-fbdd N 0 - disable FBDD noise reduction (default), 1 - light " + "FBDD, 2 - full\n" + "-dcbi N Number of extra DCD iterations (default - 0)\n" + "-dcbe DCB color enhance\n" + "-aexpo exposure correction\n" + "-apentax4shot enables merge of 4-shot pentax files\n" + "-apentax4shotorder 3102 sets pentax 4-shot alignment order\n" +#ifdef USE_RAWSPEED_BITS + "-arsbits V Set use_rawspeed to V\n" +#endif + "-mmap Use memory mmaped buffer instead of plain FILE I/O\n" + "-mem Use memory buffer instead of FILE I/O\n" + "-disars Do not use RawSpeed library\n" + "-disinterp Do not run interpolation step\n" + "-dsrawrgb1 Disable YCbCr to RGB conversion for sRAW (Cb/Cr " + "interpolation enabled)\n" + "-dsrawrgb2 Disable YCbCr to RGB conversion for sRAW (Cb/Cr " + "interpolation disabled)\n" +#ifdef USE_DNGSDK + "-dngsdk Use Adobe DNG SDK for DNG decode\n" + "-dngflags N set DNG decoding options to value N\n" +#endif + "-doutputflags N set params.output_flags to N\n" + ); + exit(1); +} + +static int verbosity = 0; +int cnt = 0; +int my_progress_callback(void *d, enum LibRaw_progress p, int iteration, + int expected) +{ + char *passed = (char *)(d ? d : "default string"); // data passed to callback + // at set_callback stage + + if (verbosity > 2) // verbosity set by repeat -v switches + { + printf("CB: %s pass %d of %d (data passed=%s)\n", libraw_strprogress(p), + iteration, expected, passed); + } + else if (iteration == 0) // 1st iteration of each step + printf("Starting %s (expecting %d iterations)\n", libraw_strprogress(p), + expected); + else if (iteration == expected - 1) + printf("%s finished\n", libraw_strprogress(p)); + + /// if(++cnt>10) return 1; // emulate user termination on 10-th callback + /// call + + return 0; // always return 0 to continue processing +} + +// timer +#ifndef LIBRAW_WIN32_CALLS +static struct timeval start, end; +void timerstart(void) { gettimeofday(&start, NULL); } +void timerprint(const char *msg, const char *filename) +{ + gettimeofday(&end, NULL); + float msec = (end.tv_sec - start.tv_sec) * 1000.0f + + (end.tv_usec - start.tv_usec) / 1000.0f; + printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec); +} +#else +LARGE_INTEGER start; +void timerstart(void) { QueryPerformanceCounter(&start); } +void timerprint(const char *msg, const char *filename) +{ + LARGE_INTEGER unit, end; + QueryPerformanceCounter(&end); + QueryPerformanceFrequency(&unit); + float msec = (float)(end.QuadPart - start.QuadPart); + msec /= (float)unit.QuadPart / 1000.0f; + printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec); +} + +#endif + +struct file_mapping +{ + void *map; + INT64 fsize; +#ifdef LIBRAW_WIN32_CALLS + HANDLE fd, fd_map; + file_mapping() : map(0), fsize(0), fd(INVALID_HANDLE_VALUE), fd_map(INVALID_HANDLE_VALUE){} +#else + int fd; + file_mapping() : map(0), fsize(0), fd(-1){} +#endif +}; + +void create_mapping(struct file_mapping& data, const std::string& fn) +{ +#ifdef LIBRAW_WIN32_CALLS + std::wstring fpath(fn.begin(), fn.end()); + if ((data.fd = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) return; + LARGE_INTEGER fs; + if (!GetFileSizeEx(data.fd, &fs)) return; + data.fsize = fs.QuadPart; + if ((data.fd_map = ::CreateFileMapping(data.fd, 0, PAGE_READONLY, fs.HighPart, fs.LowPart, 0)) == INVALID_HANDLE_VALUE) return; + data.map = MapViewOfFile(data.fd_map, FILE_MAP_READ, 0, 0, data.fsize); +#else + struct stat stt; + if ((data.fd = open(fn.c_str(), O_RDONLY)) < 0) return; + if (fstat(data.fd, &stt) != 0) return; + data.fsize = stt.st_size; + data.map = mmap(0, data.fsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, data.fd, 0); + return; +#endif +} + +void close_mapping(struct file_mapping& data) +{ +#ifdef LIBRAW_WIN32_CALLS + if (data.map) UnmapViewOfFile(data.map); + if (data.fd_map != INVALID_HANDLE_VALUE) CloseHandle(data.fd_map); + if (data.fd != INVALID_HANDLE_VALUE) CloseHandle(data.fd); + data.map = 0; + data.fsize = 0; + data.fd = data.fd_map = INVALID_HANDLE_VALUE; +#else + if (data.map) + munmap(data.map, data.fsize); + if (data.fd >= 0) + close(data.fd); + data.map = 0; + data.fsize = 0; + data.fd = -1; +#endif +} + + +int main(int argc, char *argv[]) +{ + if (argc == 1) + usage(argv[0]); + + LibRaw RawProcessor; + int i, arg, c, ret; + char opm, opt, *cp, *sp; + int use_timing = 0, use_mem = 0, use_mmap = 0; + char *outext = NULL; +#ifdef USE_DNGSDK + dng_host *dnghost = NULL; +#endif + struct file_mapping mapping; + void *iobuffer = 0; +#ifdef OUT +#undef OUT +#endif +#define OUT RawProcessor.imgdata.params +#define OUTR RawProcessor.imgdata.rawparams + + argv[argc] = (char *)""; + for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';) + { + char *optstr = argv[arg]; + opt = argv[arg++][1]; + if ((cp = strchr(sp = (char *)"cnbrkStqmHABCgU", opt)) != 0) + for (i = 0; i < "111411111144221"[cp - sp] - '0'; i++) + if (!isdigit(argv[arg + i][0]) && !optstr[2]) + { + fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt); + return 1; + } + if (!strchr("ftdeam", opt) && argv[arg - 1][2]) { + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + continue; + } + switch (opt) + { + case 'v': + verbosity++; + break; + case 'G': + OUT.green_matching = 1; + break; + case 'c': + OUT.adjust_maximum_thr = (float)atof(argv[arg++]); + break; + case 'U': + OUT.auto_bright_thr = (float)atof(argv[arg++]); + break; + case 'n': + OUT.threshold = (float)atof(argv[arg++]); + break; + case 'b': + OUT.bright = (float)atof(argv[arg++]); + break; + case 'P': + OUT.bad_pixels = argv[arg++]; + break; + case 'K': + OUT.dark_frame = argv[arg++]; + break; + case 'r': + for (c = 0; c < 4; c++) + OUT.user_mul[c] = (float)atof(argv[arg++]); + break; + case 'C': + OUT.aber[0] = 1 / atof(argv[arg++]); + OUT.aber[2] = 1 / atof(argv[arg++]); + break; + case 'g': + OUT.gamm[0] = 1 / atof(argv[arg++]); + OUT.gamm[1] = atof(argv[arg++]); + break; + case 'k': + OUT.user_black = atoi(argv[arg++]); + break; + case 'S': + OUT.user_sat = atoi(argv[arg++]); + break; + case 'R': + OUTR.options = atoi(argv[arg++]); + break; + case 't': + if (!strcmp(optstr, "-timing")) + use_timing = 1; + else if (!argv[arg - 1][2]) + OUT.user_flip = atoi(argv[arg++]); + else + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + break; + case 'q': + OUT.user_qual = atoi(argv[arg++]); + break; + case 'm': + if (!strcmp(optstr, "-mmap")) + use_mmap = 1; + else + if (!strcmp(optstr, "-mem")) + use_mem = 1; + else + { + if (!argv[arg - 1][2]) + OUT.med_passes = atoi(argv[arg++]); + else + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + } + break; + case 'H': + OUT.highlight = atoi(argv[arg++]); + break; + case 's': + OUTR.shot_select = abs(atoi(argv[arg++])); + break; + case 'o': + if (isdigit(argv[arg][0]) && !isdigit(argv[arg][1])) + OUT.output_color = atoi(argv[arg++]); +#ifndef NO_LCMS + else + OUT.output_profile = argv[arg++]; + break; + case 'p': + OUT.camera_profile = argv[arg++]; +#endif + break; + case 'h': + OUT.half_size = 1; + break; + case 'f': + if (!strcmp(optstr, "-fbdd")) + OUT.fbdd_noiserd = atoi(argv[arg++]); + else + { + if (!argv[arg - 1][2]) + OUT.four_color_rgb = 1; + else + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + } + break; + case 'A': + for (c = 0; c < 4; c++) + OUT.greybox[c] = atoi(argv[arg++]); + break; + case 'B': + for (c = 0; c < 4; c++) + OUT.cropbox[c] = atoi(argv[arg++]); + break; + case 'a': + if (!strcmp(optstr, "-aexpo")) + { + OUT.exp_correc = 1; + OUT.exp_shift = (float)atof(argv[arg++]); + OUT.exp_preser = (float)atof(argv[arg++]); + } +#ifdef USE_RAWSPEED_BITS + else if (!strcmp(optstr, "-arsbits")) + { + OUTR.use_rawspeed = atoi(argv[arg++]); + } +#endif + else if (!strcmp(optstr, "-apentax4shot")) + { + OUTR.options |= LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES; + } + else if (!strcmp(optstr, "-apentax4shotorder")) + { + strncpy(OUTR.p4shot_order, argv[arg++], 5); + } + else if (!argv[arg - 1][2]) + OUT.use_auto_wb = 1; + else + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + break; + case 'w': + OUT.use_camera_wb = 1; + break; + case 'M': + OUT.use_camera_matrix = (opm == '+')?3:0; + break; + case 'j': + OUT.use_fuji_rotate = 0; + break; + case 'W': + OUT.no_auto_bright = 1; + break; + case 'T': + OUT.output_tiff = 1; + break; + case '4': + OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; /* no break here! */ + case '6': + OUT.output_bps = 16; + break; + case 'Z': + outext = strdup(argv[arg++]); + break; + case 'd': + if (!strcmp(optstr, "-dcbi")) + OUT.dcb_iterations = atoi(argv[arg++]); + else if (!strcmp(optstr, "-doutputflags")) + OUT.output_flags = atoi(argv[arg++]); + else if (!strcmp(optstr, "-disars")) + OUTR.use_rawspeed = 0; + else if (!strcmp(optstr, "-disinterp")) + OUT.no_interpolation = 1; + else if (!strcmp(optstr, "-dcbe")) + OUT.dcb_enhance_fl = 1; + else if (!strcmp(optstr, "-dsrawrgb1")) + { + OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_RGB; + OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE; + } + else if (!strcmp(optstr, "-dsrawrgb2")) + { + OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_RGB; + OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE; + } +#ifdef USE_DNGSDK + else if (!strcmp(optstr, "-dngsdk")) + { + dnghost = new dng_host; + RawProcessor.set_dng_host(dnghost); + } + else if (!strcmp(optstr, "-dngflags")) + { + OUTR.use_dngsdk = atoi(argv[arg++]); + } +#endif + else + fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]); + break; + default: + fprintf(stderr, "Unknown option \"-%c\".\n", opt); + break; + } + } +#ifndef LIBRAW_WIN32_CALLS + putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field +#else + _putenv( + (char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field +#endif +#define P1 RawProcessor.imgdata.idata +#define S RawProcessor.imgdata.sizes +#define C RawProcessor.imgdata.color +#define T RawProcessor.imgdata.thumbnail +#define P2 RawProcessor.imgdata.other + + if (outext && !strcmp(outext, "-")) + use_timing = verbosity = 0; + + if (verbosity > 1) + RawProcessor.set_progress_handler(my_progress_callback, + (void *)"Sample data passed"); +#ifdef LIBRAW_USE_OPENMP + if (verbosity) + printf("Using %d threads\n", omp_get_max_threads()); +#endif + + int done = 0; + int total = argc - arg; + for (; arg < argc; arg++) + { + char outfn[1024]; + + if (verbosity) + printf("Processing file %s\n", argv[arg]); + + timerstart(); + + if (use_mmap) + { + create_mapping(mapping, argv[arg]); + if (!mapping.map) + { + fprintf(stderr, "Cannot map %s\n", argv[arg]); + close_mapping(mapping); + continue; + } + if ((ret = RawProcessor.open_buffer(mapping.map,mapping.fsize) != + LIBRAW_SUCCESS)) + { + fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], libraw_strerror(ret)); + close_mapping(mapping); + continue; // no recycle b/c open file will recycle itself + } + } + else if (use_mem) + { + int file = open(argv[arg], O_RDONLY | O_BINARY); + struct stat st; + if (file < 0) + { + fprintf(stderr, "Cannot open %s: %s\n", argv[arg], strerror(errno)); + continue; + } + if (fstat(file, &st)) + { + fprintf(stderr, "Cannot stat %s: %s\n", argv[arg], strerror(errno)); + close(file); + continue; + } + if (!(iobuffer = malloc(st.st_size))) + { + fprintf(stderr, "Cannot allocate %d kbytes for memory buffer\n", + (int)(st.st_size / 1024)); + close(file); + continue; + } + int rd; + if (st.st_size != (rd = read(file, iobuffer, st.st_size))) + { + fprintf(stderr, + "Cannot read %d bytes instead of %d to memory buffer\n", + (int)rd, (int)st.st_size); + close(file); + free(iobuffer); + continue; + } + close(file); + if ((ret = RawProcessor.open_buffer(iobuffer, st.st_size)) != + LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], + libraw_strerror(ret)); + free(iobuffer); + continue; // no recycle b/c open file will recycle itself + } + } + else + { + ret = RawProcessor.open_file(argv[arg]); + + if (ret != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open %s: %s\n", argv[arg], + libraw_strerror(ret)); + continue; // no recycle b/c open_file will recycle itself + } + } + + if (use_timing) + timerprint("LibRaw::open_file()", argv[arg]); + + timerstart(); + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg], + libraw_strerror(ret)); + continue; + } + + if (use_timing) + timerprint("LibRaw::unpack()", argv[arg]); + + timerstart(); + if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_process())) + { + fprintf(stderr, "Cannot do postprocessing on %s: %s\n", argv[arg], + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; + } + if (use_timing) + timerprint("LibRaw::dcraw_process()", argv[arg]); + + if (!outext) + snprintf(outfn, sizeof(outfn), "%s.%s", argv[arg], + OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm")); + else if (!strcmp(outext, "-")) + snprintf(outfn, sizeof(outfn), "-"); + else + { + if (*outext == '.') // append + snprintf(outfn, sizeof(outfn), "%s%s", argv[arg], outext); + else if (strchr(outext, '.') && *outext != '.') // dot is not 1st char + strncpy(outfn, outext, sizeof(outfn)); + else + { + strncpy(outfn, argv[arg], sizeof(outfn)); + if (strlen(outfn) > 0) + { + char *lastchar = outfn + strlen(outfn); // points to term 0 + while (--lastchar > outfn) + { + if (*lastchar == '/' || *lastchar == '\\') + break; + if (*lastchar == '.') + { + *lastchar = 0; + break; + }; + } + } + strncat(outfn, ".", sizeof(outfn) - strlen(outfn) - 1); + strncat(outfn, outext, sizeof(outfn) - strlen(outfn) - 1); + } + } + + if (verbosity) + { + printf("Writing file %s\n", outfn); + } + + if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) + fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); + else + done++; + + RawProcessor.recycle(); // just for show this call + + if (use_mmap && mapping.map) + close_mapping(mapping); + else if (use_mem && iobuffer) + { + free(iobuffer); + iobuffer = 0; + } + } +#ifdef USE_DNGSDK + if (dnghost) + delete dnghost; +#endif + if (total == 0) + return 1; + if (done < total) + return 2; + return 0; +} diff --git a/samples/dcraw_half.c b/samples/dcraw_half.c new file mode 100644 index 000000000..5fe56a573 --- /dev/null +++ b/samples/dcraw_half.c @@ -0,0 +1,78 @@ +/* -*- C++ -*- + * File: dcraw_half.c + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8 , 2008 + * + * LibRaw C API sample: emulates "dcraw -h" + * +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#include + +#include "libraw/libraw.h" + +#define HANDLE_FATAL_ERROR(ret) \ + if (ret) \ + { \ + fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \ + if (LIBRAW_FATAL_ERROR(ret)) \ + exit(1); \ + } + +#define HANDLE_ALL_ERRORS(ret) \ + if (ret) \ + { \ + fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \ + continue; \ + } + +int main(int ac, char *av[]) +{ + int i; + libraw_data_t *iprc = libraw_init(0); + + if (!iprc) + { + fprintf(stderr, "Cannot create libraw handle\n"); + exit(1); + } + + iprc->params.half_size = 1; /* dcraw -h */ + + for (i = 1; i < ac; i++) + { + char outfn[1024]; + int ret = libraw_open_file(iprc, av[i]); + HANDLE_ALL_ERRORS(ret); + + printf("Processing %s (%s %s)\n", av[i], iprc->idata.make, + iprc->idata.model); + + ret = libraw_unpack(iprc); + HANDLE_ALL_ERRORS(ret); + + ret = libraw_dcraw_process(iprc); + HANDLE_ALL_ERRORS(ret); + + strcpy(outfn, av[i]); + strcat(outfn, ".ppm"); + printf("Writing to %s\n", outfn); + + ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); + HANDLE_FATAL_ERROR(ret); + } + libraw_close(iprc); + return 0; +} diff --git a/samples/half_mt.c b/samples/half_mt.c new file mode 100644 index 000000000..f46c83ea8 --- /dev/null +++ b/samples/half_mt.c @@ -0,0 +1,178 @@ +/* -*- C++ -*- + * File: halt_mt.c + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] +[-v]" + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#include +#include + +#include "libraw/libraw.h" + +#define HANDLE_ERRORS(ret) \ + do \ + { \ + if (ret) \ + { \ + fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ + if (LIBRAW_FATAL_ERROR(ret)) \ + { \ + libraw_close(iprc); \ + return NULL; \ + } \ + } \ + } while (0) + +int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; + +pthread_mutex_t qm; +char **queue = NULL; +size_t qsize = 0, qptr = 0; + +char *get_next_file() +{ + char *ret; + if (!queue) + return NULL; + if (qptr >= qsize) + return NULL; + pthread_mutex_lock(&qm); + ret = queue[qptr++]; + pthread_mutex_unlock(&qm); + return ret; +} + +void *process_files(void *q) +{ + int ret; + int count = 0; + char outfn[1024], *fn; + libraw_data_t *iprc = libraw_init(0); + + if (!iprc) + { + fprintf(stderr, "Cannot create libraw handle\n"); + return NULL; + } + + while ((fn = get_next_file())) + { + + iprc->params.half_size = 1; /* dcraw -h */ + iprc->params.use_camera_wb = use_camera_wb; + iprc->params.use_auto_wb = use_auto_wb; + iprc->params.output_tiff = tiff_mode; + + ret = libraw_open_file(iprc, fn); + if (verbose) + fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); + HANDLE_ERRORS(ret); + + ret = libraw_unpack(iprc); + HANDLE_ERRORS(ret); + + ret = libraw_dcraw_process(iprc); + HANDLE_ERRORS(ret); + + snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tiff" : "ppm"); + + if (verbose) + fprintf(stderr, "Writing file %s\n", outfn); + ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); + HANDLE_ERRORS(ret); + count++; + } + libraw_close(iprc); + return NULL; +} + +void usage(const char *p) +{ + printf("%s: Multi-threaded LibRaw sample app. Emulates dcraw -h [-w] [-a]\n", + p); + printf("Options:\n" + "-J n - set parallel job count (default 2)\n" + "-v - verbose\n" + "-w - use camera white balance\n" + "-a - average image for white balance\n"); + exit(1); +} + +int show_files(void *q) +{ + char *p; + int cnt = 0; + while ((p = get_next_file())) + { + printf("%s\n", p); + cnt++; + } + return cnt; +} + +int main(int ac, char *av[]) +{ + int i, max_threads = 2; + pthread_t *threads; + if (ac < 2) + usage(av[0]); + + queue = calloc(ac - 1, sizeof(queue[0])); + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == 'w') + use_camera_wb = 1; + if (av[i][1] == 'a') + use_auto_wb = 1; + if (av[i][1] == 'v') + verbose = 1; + if (av[i][1] == 'T') + tiff_mode = 1; + if (av[i][1] == 'J') + { + max_threads = atoi(av[++i]); + if (max_threads < 1) + { + fprintf(stderr, "Job count should be at least 1\n"); + exit(1); + } + } + } + else + queue[qsize++] = av[i]; + } + pthread_mutex_init(&qm, NULL); + threads = calloc(max_threads, sizeof(threads[0])); + for (i = 0; i < max_threads; i++) + pthread_create(&threads[i], NULL, process_files, NULL); + for (i = 0; i < max_threads; i++) + { + int *iptr; + if (threads[i]) + { + pthread_join(threads[i], (void *)&iptr); + } + } + + return 0; +} diff --git a/samples/half_mt_win32.c b/samples/half_mt_win32.c new file mode 100644 index 000000000..b8d3943d3 --- /dev/null +++ b/samples/half_mt_win32.c @@ -0,0 +1,212 @@ +/* -*- C++ -*- + * File: halt_mt_win32.c + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] +[-v]" + * Win32 version + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#include +#include +#include "libraw/libraw.h" + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#endif + +#define HANDLE_ERRORS(ret) \ + do \ + { \ + if (ret) \ + { \ + fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \ + if (LIBRAW_FATAL_ERROR(ret)) \ + { \ + libraw_close(iprc); \ + return -1; \ + } \ + } \ + } while (0) + +// global settings +int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0; + +// global file queue +HANDLE qmutex; +char **queue = NULL; +size_t qsize = 0, qptr = 0; + +char *get_next_file() +{ + char *ret; + DWORD dwWaitResult; + if (!queue) + return NULL; + if (qptr >= qsize) + return NULL; + + dwWaitResult = WaitForSingleObject(qmutex, // handle to mutex + INFINITE); // no time-out interval + switch (dwWaitResult) + { + // The thread got ownership of the mutex + case WAIT_OBJECT_0: + ret = queue[qptr++]; + ReleaseMutex(qmutex); + break; + case WAIT_ABANDONED: + return NULL; // cannot obtain the lock + }; + return ret; +} + +// thread routine +int process_files(void *q) +{ + int ret; + int count = 0; + char outfn[1024], *fn; + libraw_data_t *iprc = libraw_init(0); + + if (!iprc) + { + fprintf(stderr, "Cannot create libraw handle\n"); + return -1; + } + + while ((fn = get_next_file())) + { + + iprc->params.half_size = 1; /* dcraw -h */ + iprc->params.use_camera_wb = use_camera_wb; + iprc->params.use_auto_wb = use_auto_wb; + iprc->params.output_tiff = tiff_mode; + + ret = libraw_open_file(iprc, fn); + if (verbose) + fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model); + HANDLE_ERRORS(ret); + + ret = libraw_unpack(iprc); + HANDLE_ERRORS(ret); + + ret = libraw_dcraw_process(iprc); + HANDLE_ERRORS(ret); + + snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tif" : "ppm"); + + if (verbose) + fprintf(stderr, "Writing file %s\n", outfn); + ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn); + HANDLE_ERRORS(ret); + count++; + } + libraw_close(iprc); + printf("Processed %d files\n", count); + return 0; +} + +void usage(const char *p) +{ + printf("Options:\n" + "-J n - set parallel job count (default 2)\n" + "-v - verbose\n" + "-w - use camera white balance\n" + "-T - output TIFF instead of PPM\n" + "-a - average image for white balance\n"); + exit(1); +} + +int show_files(void *q) +{ + char *p; + int cnt = 0; + while (p = get_next_file()) + { + printf("%s\n", p); + cnt++; + } + return cnt; +} + +int main(int ac, char *av[]) +{ + int i, max_threads = 2; + HANDLE *threads; + DWORD ThreadID; + + if (ac < 2) + usage(av[0]); + + queue = calloc(ac - 1, sizeof(queue[0])); + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == 'w') + use_camera_wb = 1; + if (av[i][1] == 'a') + use_auto_wb = 1; + if (av[i][1] == 'v') + verbose = 1; + if (av[i][1] == 'T') + tiff_mode = 1; + if (av[i][1] == 'J') + { + max_threads = atoi(av[++i]); + if (max_threads < 1) + { + fprintf(stderr, "Job count should be at least 1\n"); + exit(1); + } + } + } + else + queue[qsize++] = av[i]; + } + qmutex = CreateMutex(NULL, FALSE, NULL); + threads = calloc(max_threads, sizeof(threads[0])); + for (i = 0; i < max_threads; i++) + { + + if (NULL == + (threads[i] = CreateThread(NULL, // default security attributes + 0, // default stack size + (LPTHREAD_START_ROUTINE)process_files, + NULL, // no thread function arguments + 0, // default creation flags + &ThreadID) // receive thread identifier + )) + { + printf("CreateThread error: %d\n", GetLastError()); + return 1; + } + } + + WaitForMultipleObjects(max_threads, threads, TRUE, INFINITE); + + // Close thread and mutex handles + + for (i = 0; i < max_threads; i++) + CloseHandle(threads[i]); + + CloseHandle(qmutex); + + return 0; +} diff --git a/samples/mem_image_sample.cpp b/samples/mem_image_sample.cpp new file mode 100644 index 000000000..1ce5b8c60 --- /dev/null +++ b/samples/mem_image_sample.cpp @@ -0,0 +1,282 @@ +/* -*- C++ -*- + * File: mem_image.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * + * LibRaw mem_image/mem_thumb API test. Results should be same (bitwise) to +dcraw [-4] [-6] [-e] + * Testing note: for ppm-thumbnails you should use dcraw -w -e for thumbnail +extraction + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include + +#include "libraw/libraw.h" + +#ifdef USE_JPEG +#include "jpeglib.h" +#endif + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#include +#pragma comment(lib, "ws2_32.lib") +#else +#include +#endif + +#ifdef USE_JPEG +void write_jpeg(libraw_processed_image_t *img, const char *basename, int quality) +{ + char fn[1024]; + if(img->colors != 1 && img->colors != 3) + { + printf("Only BW and 3-color images supported for JPEG output\n"); + return; + } + snprintf(fn, 1024, "%s.jpg", basename); + FILE *f = fopen(fn, "wb"); + if (!f) + return; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = img->width; /* image width and height, in pixels */ + cinfo.image_height = img->height; + cinfo.input_components = img->colors; /* # of color components per pixel */ + cinfo.in_color_space = img->colors==3?JCS_RGB:JCS_GRAYSCALE; /* colorspace of input image */ + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + row_stride = img->width * img->colors; /* JSAMPLEs per row in image_buffer */ + while (cinfo.next_scanline < cinfo.image_height) { + row_pointer[0] = &img->data[cinfo.next_scanline * row_stride]; + (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + jpeg_finish_compress(&cinfo); + fclose(f); + jpeg_destroy_compress(&cinfo); +} + +#endif + +// no error reporting, only params check +void write_ppm(libraw_processed_image_t *img, const char *basename) +{ + if (!img) + return; + // type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check + if (img->type != LIBRAW_IMAGE_BITMAP) + return; + if (img->colors != 3 && img->colors != 1) + { + printf("Only monochrome and 3-color images supported for PPM output\n"); + return; + } + + char fn[1024]; + snprintf(fn, 1024, "%s.p%cm", basename, img->colors==1?'g':'p'); + FILE *f = fopen(fn, "wb"); + if (!f) + return; + fprintf(f, "P%d\n%d %d\n%d\n", img->colors/2 + 5, img->width, img->height, (1 << img->bits) - 1); +/* + NOTE: + data in img->data is not converted to network byte order. + So, we should swap values on some architectures for dcraw compatibility + (unfortunately, xv cannot display 16-bit PPMs with network byte order data +*/ +#define SWAP(a, b) \ + { \ + a ^= b; \ + a ^= (b ^= a); \ + } + if (img->bits == 16 && htons(0x55aa) != 0x55aa) + for (unsigned i = 0; i < img->data_size-1; i += 2) + SWAP(img->data[i], img->data[i + 1]); +#undef SWAP + + fwrite(img->data, img->data_size, 1, f); + fclose(f); +} + +void write_thumb(libraw_processed_image_t *img, const char *basename) +{ + if (!img) + return; + + if (img->type == LIBRAW_IMAGE_BITMAP) + { + char fnt[1024]; + snprintf(fnt, 1024, "%s.thumb", basename); + write_ppm(img, fnt); + } + else if (img->type == LIBRAW_IMAGE_JPEG) + { + char fn[1024]; + snprintf(fn, 1024, "%s.thumb.jpg", basename); + FILE *f = fopen(fn, "wb"); + if (!f) + return; + fwrite(img->data, img->data_size, 1, f); + fclose(f); + } +} + +int main(int ac, char *av[]) +{ + int i, ret, output_thumbs = 0; +#ifdef USE_JPEG + int output_jpeg = 0, jpgqual = 90; +#endif + // don't use fixed size buffers in real apps! + + LibRaw RawProcessor; + + if (ac < 2) + { + printf("mem_image - LibRaw sample, to illustrate work for memory buffers.\n" + "Emulates dcraw [-4] [-1] [-e] [-h]\n" +#ifdef USE_JPEG + "Usage: %s [-D] [-j[nn]] [-T] [-v] [-e] raw-files....\n" +#else + "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n" +#endif + "\t-6 - output 16-bit PPM\n" + "\t-4 - linear 16-bit data\n" + "\t-e - extract thumbnails (same as dcraw -e in separate run)\n" +#ifdef USE_JPEG + "\t-j[qual] - output JPEG with qual quality (e.g. -j90)\n" +#endif + "\t-h - use half_size\n", av[0]); + return 0; + } + + putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field + +#define P1 RawProcessor.imgdata.idata +#define S RawProcessor.imgdata.sizes +#define C RawProcessor.imgdata.color +#define T RawProcessor.imgdata.thumbnail +#define P2 RawProcessor.imgdata.other +#define OUT RawProcessor.imgdata.params + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == '6' && av[i][2] == 0) + OUT.output_bps = 16; + if (av[i][1] == '4' && av[i][2] == 0) + { + OUT.output_bps = 16; + OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; + } + if (av[i][1] == 'e' && av[i][2] == 0) + output_thumbs++; + if (av[i][1] == 'h' && av[i][2] == 0) + OUT.half_size = 1; +#ifdef USE_JPEG + if (av[i][1] == 'j') + { + output_jpeg = 1; + if(av[i][2] != 0) + jpgqual = atoi(av[i]+2); + } +#endif + continue; + } +#ifdef USE_JPEG + if(output_jpeg && OUT.output_bps>8) + { + printf("JPEG is limited to 8 bit\n"); + OUT.output_bps = 8; + } +#endif + printf("Processing %s\n", av[i]); + if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); + continue; + } + + // we should call dcraw_process before thumbnail extraction because for + // some cameras (i.e. Kodak ones) white balance for thumbnail should be set + // from main image settings + + ret = RawProcessor.dcraw_process(); + + if (LIBRAW_SUCCESS != ret) + { + fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i], + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; + } + libraw_processed_image_t *image = RawProcessor.dcraw_make_mem_image(&ret); + if (image) + { +#ifdef USE_JPEG + if(output_jpeg) + write_jpeg(image, av[i], jpgqual); + else +#endif + write_ppm(image, av[i]); + LibRaw::dcraw_clear_mem(image); + } + else + fprintf(stderr, "Cannot unpack %s to memory buffer: %s\n", av[i], + libraw_strerror(ret)); + + if (output_thumbs) + { + + if ((ret = RawProcessor.unpack_thumb()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i], + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; // skip to next file + } + else + { + libraw_processed_image_t *thumb = + RawProcessor.dcraw_make_mem_thumb(&ret); + if (thumb) + { + write_thumb(thumb, av[i]); + LibRaw::dcraw_clear_mem(thumb); + } + else + fprintf(stderr, + "Cannot unpack thumbnail of %s to memory buffer: %s\n", av[i], + libraw_strerror(ret)); + } + } + + RawProcessor.recycle(); // just for show this call + } + return 0; +} diff --git a/samples/multirender_test.cpp b/samples/multirender_test.cpp new file mode 100644 index 000000000..06dcec58a --- /dev/null +++ b/samples/multirender_test.cpp @@ -0,0 +1,107 @@ +/* -*- C++ -*- + * File: multirender_test.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Jul 10, 2011 + * + * LibRaw simple C++ API: creates 8 different renderings from 1 source file. +The 1st and 4th one should be identical + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#include +#endif + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#endif + +int process_once(LibRaw &RawProcessor, int half_mode, int camera_wb, + int auto_wb, int suffix, int user_flip, char *fname) +{ + char outfn[1024]; + RawProcessor.imgdata.params.half_size = half_mode; + RawProcessor.imgdata.params.use_camera_wb = camera_wb; + RawProcessor.imgdata.params.use_auto_wb = auto_wb; + RawProcessor.imgdata.params.user_flip = user_flip; + + int ret = RawProcessor.dcraw_process(); + + if (LIBRAW_SUCCESS != ret) + { + fprintf(stderr, "Cannot do postprocessing on %s: %s\n", fname, + libraw_strerror(ret)); + return ret; + } + snprintf(outfn, sizeof(outfn), "%s.%d.%s", fname, suffix, + (RawProcessor.imgdata.idata.colors > 1 ? "ppm" : "pgm")); + + printf("Writing file %s\n", outfn); + + if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn))) + fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); + return ret; +} + +int main(int ac, char *av[]) +{ + int i, ret; + + LibRaw RawProcessor; + if (ac < 2) + { + printf("multirender_test - LibRaw %s sample. Performs 4 different " + "renderings of one file\n" + " %d cameras supported\n" + "Usage: %s raw-files....\n", + LibRaw::version(), LibRaw::cameraCount(), av[0]); + return 0; + } + + for (i = 1; i < ac; i++) + { + + printf("Processing file %s\n", av[i]); + + if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); + continue; + } + process_once(RawProcessor, 0, 0, 0, 1, -1, av[i]); // default flip + process_once(RawProcessor, 1, 0, 1, 2, -1, av[i]); + process_once(RawProcessor, 1, 1, 0, 3, -1, av[i]); // default flip + process_once(RawProcessor, 1, 1, 0, 4, 1, av[i]); // flip 1 + process_once(RawProcessor, 1, 1, 0, 5, 3, av[i]); // flip 3 + process_once(RawProcessor, 1, 1, 0, 6, 1, av[i]); // 1 again same as 4 + process_once(RawProcessor, 1, 1, 0, 7, -1, + av[i]); // default again, same as 3 + process_once(RawProcessor, 0, 0, 0, 8, -1, av[i]); // same as 1 + + RawProcessor.recycle(); // just for show this call + } + return 0; +} diff --git a/samples/openbayer_sample.cpp b/samples/openbayer_sample.cpp new file mode 100644 index 000000000..c1e46595b --- /dev/null +++ b/samples/openbayer_sample.cpp @@ -0,0 +1,65 @@ +/* -*- C++ -*- + * File: openvayer_sample.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Feb 11, 2020 + * + * LibRaw simple C++ API: opens bayer data (Kodak KAI-0340 sensor) from buffer, +dump as 8-bit tiff + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include +#include +#include + +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#include +#endif + +int main(int ac, char *av[]) +{ + if (ac != 2) + return 1; + FILE *in = fopen(av[1], "rb"); + fseek(in, 0, SEEK_END); + unsigned fsz = ftell(in); + unsigned char *buffer = (unsigned char *)malloc(fsz); + if (!buffer) + return 2; + fseek(in, 0, SEEK_SET); + unsigned readb = fread(buffer, 1, fsz, in); + if (readb != fsz) + return 3; + LibRaw rp; + rp.imgdata.params.output_tiff = 1; + int ret = rp.open_bayer(buffer, fsz, 640, 480, 0, 0, 0, 0, 0, + LIBRAW_OPENBAYER_RGGB, 0, 0, 1400); + if (ret != LIBRAW_SUCCESS) + return 4; + if ((ret = rp.unpack()) != LIBRAW_SUCCESS) + printf("Unpack error: %d\n", ret); + + if ((ret = rp.dcraw_process()) != LIBRAW_SUCCESS) + printf("Processing error: %d\n", ret); + + char outfn[256]; + sprintf(outfn, "%s.tif", av[1]); + if (LIBRAW_SUCCESS != (ret = rp.dcraw_ppm_tiff_writer(outfn))) + printf("Cannot write %s: %s\n", outfn, libraw_strerror(ret)); + else + printf("Created %s\n", outfn); +} diff --git a/samples/postprocessing_benchmark.cpp b/samples/postprocessing_benchmark.cpp new file mode 100644 index 000000000..703a7a373 --- /dev/null +++ b/samples/postprocessing_benchmark.cpp @@ -0,0 +1,223 @@ +/* -*- C++ -*- + * File: postprocessing_benchmark.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Jul 13, 2011 + * + * LibRaw simple C++ API: creates 8 different renderings from 1 source file. +The 1st and 4th one should be identical + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#include +#include +#include + +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#else +#include +#endif + +#include "libraw/libraw.h" + +void timerstart(void); +float timerend(void); + +int main(int argc, char *argv[]) +{ + int i, ret, rep = 1; + LibRaw RawProcessor; +#ifdef OUT +#undef OUT +#endif +#define OUT RawProcessor.imgdata.params +#define OUTR RawProcessor.imgdata.rawparams +#define S RawProcessor.imgdata.sizes + + if (argc < 2) + { + printf( + "postprocessing benchmark: LibRaw %s sample, %d cameras supported\n" + "Measures postprocessing speed with different options\n" + "Usage: %s [-a] [-H N] [-q N] [-h] [-m N] [-n N] [-s N] [-B x y w h] " + "[-R N]\n" + "-a average image for white balance\n" + "-H Highlight mode (0=clip, 1=unclip, 2=blend, " + "3+=rebuild)\n" + "-q Set the interpolation quality\n" + "-h Half-size color image\n" + "-m Apply a num-passes 3x3 median filter to R-G and B-G\n" + "-n Set threshold for wavelet denoising\n" + "-s Select one raw image from input file\n" + "-B Crop output image\n" + "-R Number of repetitions\n" + "-c Do not use rawspeed\n", + LibRaw::version(), LibRaw::cameraCount(), argv[0]); + return 0; + } + char opm, opt, *cp, *sp; + int arg, c; + int shrink = 0; + + argv[argc] = (char *)""; + for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';) + { + char *optstr = argv[arg]; + opt = argv[arg++][1]; + if ((cp = strchr(sp = (char *)"HqmnsBR", opt)) != 0) + for (i = 0; i < "1111141"[cp - sp] - '0'; i++) + if (!isdigit(argv[arg + i][0]) && !optstr[2]) + { + fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt); + return 1; + } + switch (opt) + { + case 'a': + OUT.use_auto_wb = 1; + break; + case 'H': + OUT.highlight = atoi(argv[arg++]); + break; + case 'q': + OUT.user_qual = atoi(argv[arg++]); + break; + case 'h': + OUT.half_size = 1; + OUT.four_color_rgb = 1; + shrink = 1; + break; + case 'm': + OUT.med_passes = atoi(argv[arg++]); + break; + case 'n': + OUT.threshold = (float)atof(argv[arg++]); + break; + case 's': + OUTR.shot_select = abs(atoi(argv[arg++])); + break; + case 'B': + for (c = 0; c < 4; c++) + OUT.cropbox[c] = atoi(argv[arg++]); + break; + case 'R': + rep = abs(atoi(argv[arg++])); + if (rep < 1) + rep = 1; + break; + case 'c': + RawProcessor.imgdata.rawparams.use_rawspeed = 0; + break; + default: + fprintf(stderr, "Unknown option \"-%c\".\n", opt); + return 1; + } + } + for (; arg < argc; arg++) + { + printf("Processing file %s\n", argv[arg]); + timerstart(); + if ((ret = RawProcessor.open_file(argv[arg])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open_file %s: %s\n", argv[arg], + libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg], + libraw_strerror(ret)); + continue; + } + float qsec = timerend(); + printf("\n%.1f msec for unpack\n", qsec); + float mpix, rmpix; + timerstart(); + for (c = 0; c < rep; c++) + { + if ((ret = RawProcessor.dcraw_process()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot postprocess %s: %s\n", argv[arg], + libraw_strerror(ret)); + break; + } + libraw_processed_image_t *p = RawProcessor.dcraw_make_mem_image(); + if (p) + RawProcessor.dcraw_clear_mem(p); + RawProcessor.free_image(); + } + float msec = timerend() / (float)rep; + + if ((ret = RawProcessor.adjust_sizes_info_only()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot adjust sizes for %s: %s\n", argv[arg], + libraw_strerror(ret)); + break; + } + rmpix = (S.iwidth * S.iheight) / 1000000.0f; + + if (c == rep) // no failure + { + unsigned int crop[4]; + for (int i = 0; i < 4; i++) + crop[i] = (OUT.cropbox[i]) >> shrink; + if (crop[0] + crop[2] > S.iwidth) + crop[2] = S.iwidth - crop[0]; + if (crop[1] + crop[3] > S.iheight) + crop[3] = S.iheight - crop[1]; + + mpix = float(crop[2] * crop[3]) / 1000000.0f; + float mpixsec = mpix * 1000.0f / msec; + + printf("Performance: %.2f Mpix/sec\n" + "File: %s, Frame: %d %.1f total Mpix, %.1f msec\n" + "Params: WB=%s Highlight=%d Qual=%d HalfSize=%s Median=%d " + "Wavelet=%.0f\n" + "Crop: %u-%u:%ux%u, active Mpix: %.2f, %.1f frames/sec\n", + mpixsec, argv[arg], OUTR.shot_select, rmpix, msec, + OUT.use_auto_wb ? "auto" : "default", OUT.highlight, OUT.user_qual, + OUT.half_size ? "YES" : "No", OUT.med_passes, OUT.threshold, + crop[0], crop[1], crop[2], crop[3], mpix, 1000.0f / msec); + } + } + + return 0; +} + +#ifndef LIBRAW_WIN32_CALLS +static struct timeval start, end; +void timerstart(void) { gettimeofday(&start, NULL); } +float timerend(void) +{ + gettimeofday(&end, NULL); + float msec = (end.tv_sec - start.tv_sec) * 1000.0f + + (end.tv_usec - start.tv_usec) / 1000.0f; + return msec; +} +#else +LARGE_INTEGER start; +void timerstart(void) { QueryPerformanceCounter(&start); } +float timerend() +{ + LARGE_INTEGER unit, end; + QueryPerformanceCounter(&end); + QueryPerformanceFrequency(&unit); + float msec = (float)(end.QuadPart - start.QuadPart); + msec /= (float)unit.QuadPart / 1000.0f; + return msec; +} + +#endif diff --git a/samples/raw-identify.cpp b/samples/raw-identify.cpp new file mode 100644 index 000000000..ced518175 --- /dev/null +++ b/samples/raw-identify.cpp @@ -0,0 +1,739 @@ +/* -*- C++ -*- + * File: identify.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw C++ demo: emulates dcraw -i [-v] + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ + +#include +#include +#include +#include +#include +#include + +#include "libraw/libraw.h" + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#include +#include +#ifndef MAX_PATH +#define MAX_PATH PATH_MAX +#endif +#endif + +#ifdef _MSC_VER +#if _MSC_VER < 1800 /* below MSVC 2013 */ +float roundf(float f) { return floorf(f + 0.5); } + +#endif +#endif + +#define P1 MyCoolRawProcessor.imgdata.idata +#define P2 MyCoolRawProcessor.imgdata.other +#define P3 MyCoolRawProcessor.imgdata.makernotes.common + +#define mnLens MyCoolRawProcessor.imgdata.lens.makernotes +#define exifLens MyCoolRawProcessor.imgdata.lens +#define ShootingInfo MyCoolRawProcessor.imgdata.shootinginfo + +#define S MyCoolRawProcessor.imgdata.sizes +#define O MyCoolRawProcessor.imgdata.params +#define C MyCoolRawProcessor.imgdata.color +#define T MyCoolRawProcessor.imgdata.thumbnail + +void print_verbose(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); +void print_wbfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); +void print_szfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); +void print_unpackfun(FILE *, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn); + +/* +table of fluorescents: +12 = FL-D; Daylight fluorescent (D 5700K – 7100K) (F1,F5) +13 = FL-N; Day white fluorescent (N 4600K – 5400K) (F7,F8) +14 = FL-W; Cool white fluorescent (W 3900K – 4500K) (F2,F6, office, +store,warehouse) 15 = FL-WW; White fluorescent (WW 3200K – 3700K) (F3, +residential) 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4, +kitchen, bath) +*/ + +static const struct +{ + const int NumId; + const char *StrId; + const char *hrStrId; // human-readable + const int aux_setting; +} WBToStr[] = { + {LIBRAW_WBI_Unknown, "WBI_Unknown", "Unknown", 0}, + {LIBRAW_WBI_Daylight, "WBI_Daylight", "Daylight", 0}, + {LIBRAW_WBI_Fluorescent, "WBI_Fluorescent", "Fluorescent", 0}, + {LIBRAW_WBI_Tungsten, "WBI_Tungsten", "Tungsten (Incandescent)", 0}, + {LIBRAW_WBI_Flash, "WBI_Flash", "Flash", 0}, + {LIBRAW_WBI_FineWeather, "WBI_FineWeather", "Fine Weather", 0}, + {LIBRAW_WBI_Cloudy, "WBI_Cloudy", "Cloudy", 0}, + {LIBRAW_WBI_Shade, "WBI_Shade", "Shade", 0}, + {LIBRAW_WBI_FL_D, "WBI_FL_D", "Daylight Fluorescent", 0}, + {LIBRAW_WBI_FL_N, "WBI_FL_N", "Day White Fluorescent", 0}, + {LIBRAW_WBI_FL_W, "WBI_FL_W", "Cool White Fluorescent", 0}, + {LIBRAW_WBI_FL_WW, "WBI_FL_WW", "White Fluorescent", 0}, + {LIBRAW_WBI_FL_L, "WBI_FL_L", "Warm White Fluorescent", 0}, + {LIBRAW_WBI_Ill_A, "WBI_Ill_A", "Illuminant A", 0}, + {LIBRAW_WBI_Ill_B, "WBI_Ill_B", "Illuminant B", 0}, + {LIBRAW_WBI_Ill_C, "WBI_Ill_C", "Illuminant C", 0}, + {LIBRAW_WBI_D55, "WBI_D55", "D55", 0}, + {LIBRAW_WBI_D65, "WBI_D65", "D65", 0}, + {LIBRAW_WBI_D75, "WBI_D75", "D75", 0}, + {LIBRAW_WBI_D50, "WBI_D50", "D50", 0}, + {LIBRAW_WBI_StudioTungsten, "WBI_StudioTungsten", "ISO Studio Tungsten", 0}, + {LIBRAW_WBI_BW, "WBI_BW", "BW", 0}, + {LIBRAW_WBI_Other, "WBI_Other", "Other", 0}, + {LIBRAW_WBI_Sunset, "WBI_Sunset", "Sunset", 1}, + {LIBRAW_WBI_Underwater, "WBI_Underwater", "Underwater", 1}, + {LIBRAW_WBI_FluorescentHigh, "WBI_FluorescentHigh", "Fluorescent High", 1}, + {LIBRAW_WBI_HT_Mercury, "WBI_HT_Mercury", "HT Mercury", 1}, + {LIBRAW_WBI_AsShot, "WBI_AsShot", "As Shot", 1}, + {LIBRAW_WBI_Measured, "WBI_Measured", "Camera Measured", 1}, + {LIBRAW_WBI_Auto, "WBI_Auto", "Camera Auto", 1}, + {LIBRAW_WBI_Auto1, "WBI_Auto1", "Camera Auto 1", 1}, + {LIBRAW_WBI_Auto2, "WBI_Auto2", "Camera Auto 2", 1}, + {LIBRAW_WBI_Auto3, "WBI_Auto3", "Camera Auto 3", 1}, + {LIBRAW_WBI_Auto4, "WBI_Auto4", "Camera Auto 4", 1}, + {LIBRAW_WBI_Custom, "WBI_Custom", "Custom", 1}, + {LIBRAW_WBI_Custom1, "WBI_Custom1", "Custom 1", 1}, + {LIBRAW_WBI_Custom2, "WBI_Custom2", "Custom 2", 1}, + {LIBRAW_WBI_Custom3, "WBI_Custom3", "Custom 3", 1}, + {LIBRAW_WBI_Custom4, "WBI_Custom4", "Custom 4", 1}, + {LIBRAW_WBI_Custom5, "WBI_Custom5", "Custom 5", 1}, + {LIBRAW_WBI_Custom6, "WBI_Custom6", "Custom 6", 1}, + {LIBRAW_WBI_PC_Set1, "WBI_PC_Set1", "PC Set 1", 1}, + {LIBRAW_WBI_PC_Set2, "WBI_PC_Set2", "PC Set 2", 1}, + {LIBRAW_WBI_PC_Set3, "WBI_PC_Set3", "PC Set 3", 1}, + {LIBRAW_WBI_PC_Set4, "WBI_PC_Set4", "PC Set 4", 1}, + {LIBRAW_WBI_PC_Set5, "WBI_PC_Set5", "PC Set 5", 1}, + {LIBRAW_WBI_Kelvin, "WBI_Kelvin", "Kelvin", 1}, +}; + +const char *WB_idx2str(unsigned WBi) +{ + for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) + if (WBToStr[i].NumId == (int)WBi) + return WBToStr[i].StrId; + return 0; +} + +const char *WB_idx2hrstr(unsigned WBi) +{ + for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) + if (WBToStr[i].NumId == (int)WBi) + return WBToStr[i].hrStrId; + return 0; +} + +double _log2(double a) +{ + if(a > 0.00000000001) return log(a)/log(2.0); + return -1000; +} + +void trimSpaces(char *s) +{ + char *p = s; + if (!strncasecmp(p, "NO=", 3)) + p = p + 3; /* fix for Nikon D70, D70s */ + int l = strlen(p); + if (!l) + return; + while (isspace(p[l - 1])) + p[--l] = 0; /* trim trailing spaces */ + while (*p && isspace(*p)) + ++p, --l; /* trim leading spaces */ + memmove(s, p, l + 1); +} + +void print_usage(const char *pname) +{ + printf("Usage: %s [options] inputfiles\n", pname); + printf("Options:\n" + "\t-v\tverbose output\n" + "\t-w\tprint white balance\n" + "\t-u\tprint unpack function\n" + "\t-f\tprint frame size (only w/ -u)\n" + "\t-s\tprint output image size\n" + "\t-h\tforce half-size mode (only for -s)\n" + "\t-M\tdisable use of raw-embedded color data\n" + "\t+M\tforce use of raw-embedded color data\n" + "\t-L filename\tread input files list from filename\n" + "\t-o filename\toutput to filename\n"); +} + +int main(int ac, char *av[]) +{ + int ret; + int verbose = 0, print_sz = 0, print_unpack = 0, print_frame = 0, print_wb = 0; + LibRaw MyCoolRawProcessor; + char *filelistfile = NULL; + char *outputfilename = NULL; + FILE *outfile = stdout; + std::vector filelist; + + filelist.reserve(ac - 1); + + for (int i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (!strcmp(av[i], "-v")) + verbose++; + if (!strcmp(av[i], "-w")) + print_wb++; + if (!strcmp(av[i], "-u")) + print_unpack++; + if (!strcmp(av[i], "-s")) + print_sz++; + if (!strcmp(av[i], "-h")) + O.half_size = 1; + if (!strcmp(av[i], "-f")) + print_frame++; + if (!strcmp(av[i], "-M")) + MyCoolRawProcessor.imgdata.params.use_camera_matrix = 0; + if (!strcmp(av[i], "-L") && i < ac - 1) + { + filelistfile = av[i + 1]; + i++; + } + if (!strcmp(av[i], "-o") && i < ac - 1) + { + outputfilename = av[i + 1]; + i++; + } + continue; + } + else if (!strcmp(av[i], "+M")) + { + MyCoolRawProcessor.imgdata.params.use_camera_matrix = 3; + continue; + } + filelist.push_back(av[i]); + } + if (filelistfile) + { + char *p; + char path[MAX_PATH + 1]; + FILE *f = fopen(filelistfile, "r"); + if (f) + { + while (fgets(path, MAX_PATH, f)) + { + if ((p = strchr(path, '\n'))) + *p = 0; + if ((p = strchr(path, '\r'))) + *p = 0; + filelist.push_back(path); + } + fclose(f); + } + } + if (filelist.size() < 1) + { + print_usage(av[0]); + return 1; + } + if (outputfilename) + outfile = fopen(outputfilename, "wt"); + + for (int i = 0; i < (int)filelist.size(); i++) + { + if ((ret = MyCoolRawProcessor.open_file(filelist[i].c_str())) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot decode %s: %s\n", filelist[i].c_str(), libraw_strerror(ret)); + continue; // no recycle, open_file will recycle + } + + if (print_sz) + print_szfun(outfile, MyCoolRawProcessor, filelist[i]); + else if (verbose) + print_verbose(outfile, MyCoolRawProcessor, filelist[i]); + else if (print_unpack) + print_unpackfun(outfile, MyCoolRawProcessor, print_frame, filelist[i]); + else if (print_wb) + print_wbfun(outfile, MyCoolRawProcessor, filelist[i]); + else + fprintf(outfile, "%s is a %s %s image.\n", filelist[i].c_str(), P1.make, P1.model); + + MyCoolRawProcessor.recycle(); + } // endfor + return 0; +} + +#define PRINTMATRIX3x4(of, mat, clrs) \ + do \ + { \ + for (int r = 0; r < 3; r++) \ + if (clrs == 4) \ + fprintf(of, "%6.4f\t%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2], mat[r][3]); \ + else \ + fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ + } while (0) + +#define PRINTMATRIX4x3(of, mat, clrs) \ + do \ + { \ + for (int r = 0; r < clrs && r < 4; r++) \ + fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ + } while (0) + +void print_verbose(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) +{ + int WBi; + float denom; + int ret; + + if ((ret = MyCoolRawProcessor.adjust_sizes_info_only())) + { + fprintf(outfile, "Cannot decode %s: %s\n", fn.c_str(), libraw_strerror(ret)); + return; // no recycle, open_file will recycle + } + + fprintf(outfile, "\nFilename: %s\n", fn.c_str()); + if (C.OriginalRawFileName[0]) + fprintf(outfile, "OriginalRawFileName: =%s=\n", C.OriginalRawFileName); + fprintf(outfile, "Timestamp: %s", ctime(&(P2.timestamp))); + fprintf(outfile, "Camera: %s %s ID: 0x%llx\n", P1.make, P1.model, mnLens.CamID); + fprintf(outfile, "Normalized Make/Model: =%s/%s= ", P1.normalized_make, P1.normalized_model); + fprintf(outfile, "CamMaker ID: %d\n", P1.maker_index); + + { + int i = 0; + char sep[] = ", "; + if (C.UniqueCameraModel[0]) + { + i++; + fprintf(outfile, "UniqueCameraModel: =%s=", C.UniqueCameraModel); + } + if (C.LocalizedCameraModel[0]) + { + if (i) + { + fprintf(outfile, "%s", sep); + i++; + } + fprintf(outfile, "LocalizedCameraModel: =%s=", C.LocalizedCameraModel); + } + if (i) + { + fprintf(outfile, "\n"); + i = 0; + } + if (C.ImageUniqueID[0]) + { + if (i) + fprintf(outfile, "%s", sep); + i++; + fprintf(outfile, "ImageUniqueID: =%s=", C.ImageUniqueID); + } + if (C.RawDataUniqueID[0]) + { + if (i) + fprintf(outfile, "%s", sep); + i++; + fprintf(outfile, "RawDataUniqueID: =%s=", C.RawDataUniqueID); + } + if (i) + fprintf(outfile, "\n"); + } + + if (ShootingInfo.BodySerial[0] && strcmp(ShootingInfo.BodySerial, "0")) + { + trimSpaces(ShootingInfo.BodySerial); + fprintf(outfile, "Body#: %s", ShootingInfo.BodySerial); + } + else if (C.model2[0] && (!strncasecmp(P1.normalized_make, "Kodak", 5))) + { + trimSpaces(C.model2); + fprintf(outfile, "Body#: %s", C.model2); + } + if (ShootingInfo.InternalBodySerial[0]) + { + trimSpaces(ShootingInfo.InternalBodySerial); + fprintf(outfile, " BodyAssy#: %s", ShootingInfo.InternalBodySerial); + } + if (exifLens.LensSerial[0]) + { + trimSpaces(exifLens.LensSerial); + fprintf(outfile, " Lens#: %s", exifLens.LensSerial); + } + if (exifLens.InternalLensSerial[0]) + { + trimSpaces(exifLens.InternalLensSerial); + fprintf(outfile, " LensAssy#: %s", exifLens.InternalLensSerial); + } + if (P2.artist[0]) + fprintf(outfile, " Owner: %s\n", P2.artist); + if (P1.dng_version) + { + fprintf(outfile, " DNG Version: "); + for (int i = 24; i >= 0; i -= 8) + fprintf(outfile, "%d%c", P1.dng_version >> i & 255, i ? '.' : '\n'); + } + fprintf(outfile, "\nEXIF:\n"); + fprintf(outfile, "\tMinFocal: %0.1f mm\n", exifLens.MinFocal); + fprintf(outfile, "\tMaxFocal: %0.1f mm\n", exifLens.MaxFocal); + fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", exifLens.MaxAp4MinFocal); + fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", exifLens.MaxAp4MaxFocal); + fprintf(outfile, "\tCurFocal: %0.1f mm\n", P2.focal_len); + fprintf(outfile, "\tMaxAperture @CurFocal: f/%0.1f\n", exifLens.EXIF_MaxAp); + fprintf(outfile, "\tFocalLengthIn35mmFormat: %d mm\n", exifLens.FocalLengthIn35mmFormat); + fprintf(outfile, "\tLensMake: %s\n", exifLens.LensMake); + fprintf(outfile, "\tLens: %s\n", exifLens.Lens); + fprintf(outfile, "\n"); + + fprintf(outfile, "\nMakernotes:\n"); + fprintf(outfile, "\tDriveMode: %d\n", ShootingInfo.DriveMode); + fprintf(outfile, "\tFocusMode: %d\n", ShootingInfo.FocusMode); + fprintf(outfile, "\tMeteringMode: %d\n", ShootingInfo.MeteringMode); + fprintf(outfile, "\tAFPoint: %d\n", ShootingInfo.AFPoint); + fprintf(outfile, "\tExposureMode: %d\n", ShootingInfo.ExposureMode); + fprintf(outfile, "\tExposureProgram: %d\n", ShootingInfo.ExposureProgram); + fprintf(outfile, "\tImageStabilization: %d\n", ShootingInfo.ImageStabilization); + + fprintf(outfile, "\tLens: %s\n", mnLens.Lens); + fprintf(outfile, "\tLensFormat: %d, ", mnLens.LensFormat); + + fprintf(outfile, "\tLensMount: %d, ", mnLens.LensMount); + fprintf(outfile, "\tFocalType: %d, ", mnLens.FocalType); + switch (mnLens.FocalType) + { + case LIBRAW_FT_UNDEFINED: + fprintf(outfile, "Undefined\n"); + break; + case LIBRAW_FT_PRIME_LENS: + fprintf(outfile, "Prime lens\n"); + break; + case LIBRAW_FT_ZOOM_LENS: + fprintf(outfile, "Zoom lens\n"); + break; + default: + fprintf(outfile, "Unknown\n"); + break; + } + fprintf(outfile, "\tLensFeatures_pre: %s\n", mnLens.LensFeatures_pre); + fprintf(outfile, "\tLensFeatures_suf: %s\n", mnLens.LensFeatures_suf); + fprintf(outfile, "\tMinFocal: %0.1f mm\n", mnLens.MinFocal); + fprintf(outfile, "\tMaxFocal: %0.1f mm\n", mnLens.MaxFocal); + fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", mnLens.MaxAp4MinFocal); + fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", mnLens.MaxAp4MaxFocal); + fprintf(outfile, "\tMinAp @MinFocal: f/%0.1f\n", mnLens.MinAp4MinFocal); + fprintf(outfile, "\tMinAp @MaxFocal: f/%0.1f\n", mnLens.MinAp4MaxFocal); + fprintf(outfile, "\tMaxAp: f/%0.1f\n", mnLens.MaxAp); + fprintf(outfile, "\tMinAp: f/%0.1f\n", mnLens.MinAp); + fprintf(outfile, "\tCurFocal: %0.1f mm\n", mnLens.CurFocal); + fprintf(outfile, "\tCurAp: f/%0.1f\n", mnLens.CurAp); + fprintf(outfile, "\tMaxAp @CurFocal: f/%0.1f\n", mnLens.MaxAp4CurFocal); + fprintf(outfile, "\tMinAp @CurFocal: f/%0.1f\n", mnLens.MinAp4CurFocal); + + if (exifLens.makernotes.FocalLengthIn35mmFormat > 1.0f) + fprintf(outfile, "\tFocalLengthIn35mmFormat: %0.1f mm\n", exifLens.makernotes.FocalLengthIn35mmFormat); + + if (exifLens.nikon.EffectiveMaxAp > 0.1f) + fprintf(outfile, "\tEffectiveMaxAp: f/%0.1f\n", exifLens.nikon.EffectiveMaxAp); + + if (exifLens.makernotes.LensFStops > 0.1f) + fprintf(outfile, "\tLensFStops @CurFocal: %0.2f\n", exifLens.makernotes.LensFStops); + + fprintf(outfile, "\tTeleconverterID: %lld\n", mnLens.TeleconverterID); + fprintf(outfile, "\tTeleconverter: %s\n", mnLens.Teleconverter); + fprintf(outfile, "\tAdapterID: %lld\n", mnLens.AdapterID); + fprintf(outfile, "\tAdapter: %s\n", mnLens.Adapter); + fprintf(outfile, "\tAttachmentID: %lld\n", mnLens.AttachmentID); + fprintf(outfile, "\tAttachment: %s\n", mnLens.Attachment); + fprintf(outfile, "\n"); + + fprintf(outfile, "ISO speed: %d\n", (int)P2.iso_speed); + if (P3.real_ISO > 0.1f) + fprintf(outfile, "real ISO speed: %d\n", (int)P3.real_ISO); + fprintf(outfile, "Shutter: "); + if (P2.shutter > 0 && P2.shutter < 1) + P2.shutter = fprintf(outfile, "1/%0.1f\n", 1.0f / P2.shutter); + else if (P2.shutter >= 1) + fprintf(outfile, "%0.1f sec\n", P2.shutter); + else /* negative*/ + fprintf(outfile, " negative value\n"); + fprintf(outfile, "Aperture: f/%0.1f\n", P2.aperture); + fprintf(outfile, "Focal length: %0.1f mm\n", P2.focal_len); + if (P3.exifAmbientTemperature > -273.15f) + fprintf(outfile, "Ambient temperature (exif data): %6.2f° C\n", P3.exifAmbientTemperature); + if (P3.CameraTemperature > -273.15f) + fprintf(outfile, "Camera temperature: %6.2f° C\n", P3.CameraTemperature); + if (P3.SensorTemperature > -273.15f) + fprintf(outfile, "Sensor temperature: %6.2f° C\n", P3.SensorTemperature); + if (P3.SensorTemperature2 > -273.15f) + fprintf(outfile, "Sensor temperature2: %6.2f° C\n", P3.SensorTemperature2); + if (P3.LensTemperature > -273.15f) + fprintf(outfile, "Lens temperature: %6.2f° C\n", P3.LensTemperature); + if (P3.AmbientTemperature > -273.15f) + fprintf(outfile, "Ambient temperature: %6.2f° C\n", P3.AmbientTemperature); + if (P3.BatteryTemperature > -273.15f) + fprintf(outfile, "Battery temperature: %6.2f° C\n", P3.BatteryTemperature); + if (P3.FlashGN > 1.0f) + fprintf(outfile, "Flash Guide Number: %6.2f\n", P3.FlashGN); + fprintf(outfile, "Flash exposure compensation: %0.2f EV\n", P3.FlashEC); + if (C.profile) + fprintf(outfile, "Embedded ICC profile: yes, %d bytes\n", C.profile_length); + else + fprintf(outfile, "Embedded ICC profile: no\n"); + + if (C.dng_levels.baseline_exposure > -999.f) + fprintf(outfile, "Baseline exposure: %04.3f\n", C.dng_levels.baseline_exposure); + + fprintf(outfile, "Number of raw images: %d\n", P1.raw_count); + + if (S.pixel_aspect != 1) + fprintf(outfile, "Pixel Aspect Ratio: %0.6f\n", S.pixel_aspect); + if (T.tlength) + fprintf(outfile, "Thumb size: %4d x %d\n", T.twidth, T.theight); + fprintf(outfile, "Full size: %4d x %d\n", S.raw_width, S.raw_height); + + if (S.raw_inset_crops[0].cwidth) + { + fprintf(outfile, "Raw inset, width x height: %4d x %d ", S.raw_inset_crops[0].cwidth, S.raw_inset_crops[0].cheight); + if (S.raw_inset_crops[0].cleft != 0xffff) + fprintf(outfile, "left: %d ", S.raw_inset_crops[0].cleft); + if (S.raw_inset_crops[0].ctop != 0xffff) + fprintf(outfile, "top: %d", S.raw_inset_crops[0].ctop); + fprintf(outfile, "\n"); + } + + fprintf(outfile, "Image size: %4d x %d\n", S.width, S.height); + fprintf(outfile, "Output size: %4d x %d\n", S.iwidth, S.iheight); + fprintf(outfile, "Image flip: %d\n", S.flip); + + fprintf(outfile, "Raw colors: %d", P1.colors); + if (P1.filters) + { + fprintf(outfile, "\nFilter pattern: "); + if (!P1.cdesc[3]) + P1.cdesc[3] = 'G'; + for (int i = 0; i < 16; i++) + putchar(P1.cdesc[MyCoolRawProcessor.fcol(i >> 1, i & 1)]); + } + + if (C.black) + { + fprintf(outfile, "\nblack: %d", C.black); + } + if (C.cblack[0] != 0) + { + fprintf(outfile, "\ncblack[0 .. 3]:"); + for (int c = 0; c < 4; c++) + fprintf(outfile, " %d", C.cblack[c]); + } + if ((C.cblack[4] * C.cblack[5]) > 0) + { + fprintf(outfile, "\nBlackLevelRepeatDim: %d x %d\n", C.cblack[4], C.cblack[5]); + int n = C.cblack[4] * C.cblack[5]; + fprintf(outfile, "cblack[6 .. %d]:", 6 + n - 1); + for (int c = 6; c < 6 + n; c++) + fprintf(outfile, " %d", C.cblack[c]); + } + + if (C.linear_max[0] != 0) + { + fprintf(outfile, "\nHighlight linearity limits:"); + for (int c = 0; c < 4; c++) + fprintf(outfile, " %ld", C.linear_max[c]); + } + + if (P1.colors > 1) + { + fprintf(outfile, "\nMakernotes WB data: coeffs EVs"); + if ((C.cam_mul[0] > 0) && (C.cam_mul[1] > 0)) + { + fprintf(outfile, "\n %-23s %g %g %g %g %5.2f %5.2f %5.2f %5.2f", "As shot", C.cam_mul[0], C.cam_mul[1], + C.cam_mul[2], C.cam_mul[3], roundf(_log2(C.cam_mul[0] / C.cam_mul[1]) * 100.0f) / 100.0f, 0.0f, + roundf(_log2(C.cam_mul[2] / C.cam_mul[1]) * 100.0f) / 100.0f, + C.cam_mul[3] ? roundf(_log2(C.cam_mul[3] / C.cam_mul[1]) * 100.0f) / 100.0f : 0.0f); + } + + for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) + { + WBi = WBToStr[cnt].NumId; + if ((C.WB_Coeffs[WBi][0] > 0) && (C.WB_Coeffs[WBi][1] > 0)) + { + denom = (float)C.WB_Coeffs[WBi][1]; + fprintf(outfile, "\n %-23s %4d %4d %4d %4d %5.2f %5.2f %5.2f %5.2f", WBToStr[cnt].hrStrId, + C.WB_Coeffs[WBi][0], C.WB_Coeffs[WBi][1], C.WB_Coeffs[WBi][2], C.WB_Coeffs[WBi][3], + roundf(_log2((float)C.WB_Coeffs[WBi][0] / denom) * 100.0f) / 100.0f, 0.0f, + roundf(_log2((float)C.WB_Coeffs[WBi][2] / denom) * 100.0f) / 100.0f, + C.WB_Coeffs[3] ? roundf(_log2((float)C.WB_Coeffs[WBi][3] / denom) * 100.0f) / 100.0f : 0.0f); + } + } + + if (C.rgb_cam[0][0] > 0.0001) + { + fprintf(outfile, "\n\nCamera2RGB matrix (mode: %d):\n", MyCoolRawProcessor.imgdata.params.use_camera_matrix); + PRINTMATRIX3x4(outfile, C.rgb_cam, P1.colors); + } + + fprintf(outfile, "\nXYZ->CamRGB matrix:\n"); + PRINTMATRIX4x3(outfile, C.cam_xyz, P1.colors); + + for (int cnt = 0; cnt < 2; cnt++) + { + if (fabsf(C.P1_color[cnt].romm_cam[0]) > 0) + { + fprintf(outfile, "\nPhaseOne Matrix %d:\n", cnt + 1); + for (int i = 0; i < 3; i++) + fprintf(outfile, "%6.4f\t%6.4f\t%6.4f\n", C.P1_color[cnt].romm_cam[i * 3], + C.P1_color[cnt].romm_cam[i * 3 + 1], C.P1_color[cnt].romm_cam[i * 3 + 2]); + } + } + + if (fabsf(C.cmatrix[0][0]) > 0) + { + fprintf(outfile, "\ncamRGB -> sRGB Matrix:\n"); + PRINTMATRIX3x4(outfile, C.cmatrix, P1.colors); + } + + if (fabsf(C.ccm[0][0]) > 0) + { + fprintf(outfile, "\nColor Correction Matrix:\n"); + PRINTMATRIX3x4(outfile, C.ccm, P1.colors); + } + + for (int cnt = 0; cnt < 2; cnt++) + { + if (C.dng_color[cnt].illuminant != LIBRAW_WBI_None) + { + if (C.dng_color[cnt].illuminant <= LIBRAW_WBI_StudioTungsten) + { + fprintf(outfile, "\nDNG Illuminant %d: %s", cnt + 1, WB_idx2hrstr(C.dng_color[cnt].illuminant)); + } + else if (C.dng_color[cnt].illuminant == LIBRAW_WBI_Other) + { + fprintf(outfile, "\nDNG Illuminant %d: Other", cnt + 1); + } + else + { + fprintf(outfile, + "\nDNG Illuminant %d is out of EXIF LightSources range " + "[0:24, 255]: %d", + cnt + 1, C.dng_color[cnt].illuminant); + } + } + } + + for (int n = 0; n < 2; n++) + { + if (fabsf(C.dng_color[n].colormatrix[0][0]) > 0) + { + fprintf(outfile, "\nDNG color matrix %d:\n", n + 1); + PRINTMATRIX4x3(outfile, C.dng_color[n].colormatrix, P1.colors); + } + } + + for (int n = 0; n < 2; n++) + { + if (fabsf(C.dng_color[n].calibration[0][0]) > 0) + { + fprintf(outfile, "\nDNG calibration matrix %d:\n", n + 1); + for (int i = 0; i < P1.colors && i < 4; i++) + { + for (int j = 0; j < P1.colors && j < 4; j++) + fprintf(outfile, "%6.4f\t", C.dng_color[n].calibration[j][i]); + fprintf(outfile, "\n"); + } + } + } + + for (int n = 0; n < 2; n++) + { + if (fabsf(C.dng_color[n].forwardmatrix[0][0]) > 0) + { + fprintf(outfile, "\nDNG forward matrix %d:\n", n + 1); + PRINTMATRIX3x4(outfile, C.dng_color[n].forwardmatrix, P1.colors); + } + } + + fprintf(outfile, "\nDerived D65 multipliers:"); + for (int c = 0; c < P1.colors; c++) + fprintf(outfile, " %f", C.pre_mul[c]); + fprintf(outfile, "\n"); + } +} + +void print_wbfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) +{ + int WBi; + float denom; + fprintf(outfile, "// %s %s\n", P1.make, P1.model); + for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) + { + WBi = WBToStr[cnt].NumId; + if (C.WB_Coeffs[WBi][0] && C.WB_Coeffs[WBi][1] && !WBToStr[cnt].aux_setting) + { + denom = (float)C.WB_Coeffs[WBi][1]; + fprintf(outfile, "{\"%s\", \"%s\", %s, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, + WBToStr[cnt].StrId, C.WB_Coeffs[WBi][0] / denom, C.WB_Coeffs[WBi][2] / denom); + if (C.WB_Coeffs[WBi][1] == C.WB_Coeffs[WBi][3]) + fprintf(outfile, "1.0f}},\n"); + else + fprintf(outfile, "%6.5ff}},\n", C.WB_Coeffs[WBi][3] / denom); + } + } + + for (int cnt = 0; cnt < 64; cnt++) + if (C.WBCT_Coeffs[cnt][0]) + { + fprintf(outfile, "{\"%s\", \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, + (int)C.WBCT_Coeffs[cnt][0], C.WBCT_Coeffs[cnt][1] / C.WBCT_Coeffs[cnt][2], + C.WBCT_Coeffs[cnt][3] / C.WBCT_Coeffs[cnt][2]); + if (C.WBCT_Coeffs[cnt][2] == C.WBCT_Coeffs[cnt][4]) + fprintf(outfile, "1.0f}},\n"); + else + fprintf(outfile, "%6.5ff}},\n", C.WBCT_Coeffs[cnt][4] / C.WBCT_Coeffs[cnt][2]); + } + else + break; + fprintf(outfile, "\n"); +} + +void print_szfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) +{ + fprintf(outfile, "%s\t%s\t%s\t%d\t%d\n", fn.c_str(), P1.make, P1.model, S.width, S.height); +} + +void print_unpackfun(FILE *outfile, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn) +{ + char frame[48] = ""; + if (print_frame) + { + ushort right_margin = S.raw_width - S.width - S.left_margin; + ushort bottom_margin = S.raw_height - S.height - S.top_margin; + snprintf(frame, 48, "F=%dx%dx%dx%d RS=%dx%d", S.left_margin, S.top_margin, right_margin, bottom_margin, S.raw_width, + S.raw_height); + } + fprintf(outfile, "%s\t%s\t%s\t%s/%s\n", fn.c_str(), MyCoolRawProcessor.unpack_function_name(), frame, P1.make, + P1.model); +} diff --git a/samples/rawtextdump.cpp b/samples/rawtextdump.cpp new file mode 100644 index 000000000..62c4c6ffe --- /dev/null +++ b/samples/rawtextdump.cpp @@ -0,0 +1,144 @@ +/* -*- C++ -*- + * File: raw2text.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sun Sept 01, 2020 + * + * LibRaw sample + * Dumps (small) selection of RAW data to text file + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include +#ifndef WIN32 +#include +#else +#include +#endif + +#include "libraw/libraw.h" + +void usage(const char *av) +{ + printf( + "Dump (small) selection of RAW file as tab-separated text file\n" + "Usage: %s inputfile COL ROW [CHANNEL] [width] [height]\n" + " COL - start column\n" + " ROW - start row\n" + " CHANNEL - raw channel to dump, default is 0 (red for rggb)\n" + " width - area width to dump, default is 16\n" + " height - area height to dump, default is 4\n" + , av); +} + +unsigned subtract_bl(unsigned int val, int bl) +{ + return val > (unsigned)bl ? val - (unsigned)bl : 0; +} + +class LibRaw_bl : public LibRaw +{ + public: + void adjust_blacklevel() { LibRaw::adjust_bl(); } +}; + +int main(int ac, char *av[]) +{ + if (ac < 4) + { + usage(av[0]); + exit(1); + } + int colstart = atoi(av[2]); + int rowstart = atoi(av[3]); + int channel = 0; + if (ac > 4) channel = atoi(av[4]); + int width = 16; + if (ac > 5) width = atoi(av[5]); + int height = 4; + if (ac > 6) height = atoi(av[6]); + if (width <1 || height<1) + { + usage(av[0]); + exit(1); + } + + LibRaw_bl lr; + + if (lr.open_file(av[1]) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Unable to open file %s\n", av[1]); + exit(1); + } + if ((lr.imgdata.idata.colors == 1 && channel>0) || (channel >3)) + { + fprintf(stderr, "Incorrect CHANNEL specified: %d\n", channel); + exit(1); + } + if (lr.unpack() != LIBRAW_SUCCESS) + { + fprintf(stderr, "Unable to unpack raw data from %s\n", av[1]); + exit(1); + } + lr.adjust_blacklevel(); + printf("%s\t%d-%d-%dx%d\tchannel: %d\n", av[1], colstart, rowstart, width, height, channel); + + printf("%6s", "R\\C"); + for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) + printf("%6u", col); + printf("\n"); + + if (lr.imgdata.rawdata.raw_image) + { + for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) + { + unsigned rcolors[48]; + if (lr.imgdata.idata.colors > 1) + for (int c = 0; c < 48; c++) + rcolors[c] = lr.COLOR(row, c); + else + memset(rcolors, 0, sizeof(rcolors)); + unsigned short *rowdata = &lr.imgdata.rawdata.raw_image[row * lr.imgdata.sizes.raw_pitch / 2]; + printf("%6u", row); + for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) + if (rcolors[col % 48] == (unsigned)channel) printf("%6u", subtract_bl(rowdata[col],lr.imgdata.color.cblack[channel])); + else printf(" -"); + printf("\n"); + } + } + else if (lr.imgdata.rawdata.color4_image && channel < 4) + { + for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) + { + unsigned short(*rowdata)[4] = &lr.imgdata.rawdata.color4_image[row * lr.imgdata.sizes.raw_pitch / 8]; + printf("%6u", row); + for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) + printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel])); + printf("\n"); + } + } + else if (lr.imgdata.rawdata.color3_image && channel < 3) + { + for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++) + { + unsigned short(*rowdata)[3] = &lr.imgdata.rawdata.color3_image[row * lr.imgdata.sizes.raw_pitch / 6]; + printf("%6u", row); + for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++) + printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel])); + printf("\n"); + } + } + else + printf("Unsupported file data (e.g. floating point format), or incorrect channel specified\n"); +} diff --git a/samples/simple_dcraw.cpp b/samples/simple_dcraw.cpp new file mode 100644 index 000000000..f96b23cff --- /dev/null +++ b/samples/simple_dcraw.cpp @@ -0,0 +1,217 @@ +/* -*- C++ -*- + * File: simple_dcraw.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8, 2008 + * + * LibRaw simple C++ API: emulates call to "dcraw [-D] [-T] [-v] [-e] [-4]" + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + + */ +#include +#include +#include + +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#include +#include +#include +#endif + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#endif + +int my_progress_callback(void *unused_data, enum LibRaw_progress state, + int iter, int expected) +{ + if (iter == 0) + printf("CB: state=%x, expected %d iterations\n", state, expected); + return 0; +} + +char *customCameras[] = { + (char *)"43704960,4080,5356, 0, 0, 0, 0,0,148,0,0, Dalsa, FTF4052C Full,0", + (char *)"42837504,4008,5344, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 3:4", + (char *)"32128128,4008,4008, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 1:1", + (char *)"24096096,4008,3006, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 4:3", + (char *)"18068064,4008,2254, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 16:9", + (char *)"67686894,5049,6703, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C Full", + (char *)"66573312,4992,6668, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 3:4", + (char *)"49840128,4992,4992, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 1:1", + (char *)"37400064,4992,3746, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 4:3", + (char *)"28035072,4992,2808, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 16:9", + NULL}; + +int main(int ac, char *av[]) +{ + int i, ret, verbose = 0, output_thumbs = 0, output_all_thumbs = 0; + + // don't use fixed size buffers in real apps! + char outfn[1024], thumbfn[1024]; + + LibRaw* RawProcessor = new LibRaw; + RawProcessor->imgdata.rawparams.custom_camera_strings = customCameras; + if (ac < 2) + { + printf("simple_dcraw - LibRaw %s sample. Emulates dcraw [-D] [-T] [-v] " + "[-e] [-E]\n" + " %d cameras supported\n" + "Usage: %s [-D] [-T] [-v] [-e] raw-files....\n" + "\t-4 - 16-bit mode\n" + "\t-L - list supported cameras and exit\n" + "\t-v - verbose output\n" + "\t-T - output TIFF files instead of .pgm/ppm\n" + "\t-e - extract thumbnails (same as dcraw -e in separate run)\n" + "\t-E - extract all thumbnails\n", + LibRaw::version(), LibRaw::cameraCount(), av[0]); + delete RawProcessor; + return 0; + } + + putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field + +#define P1 RawProcessor->imgdata.idata +#define S RawProcessor->imgdata.sizes +#define C RawProcessor->imgdata.color +#define T RawProcessor->imgdata.thumbnail +#define P2 RawProcessor->imgdata.other +#define OUT RawProcessor->imgdata.params + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == 'T' && av[i][2] == 0) + OUT.output_tiff = 1; + if (av[i][1] == 'v' && av[i][2] == 0) + verbose++; + if (av[i][1] == 'e' && av[i][2] == 0) + output_thumbs++; + if (av[i][1] == 'E' && av[i][2] == 0) + { + output_thumbs++; + output_all_thumbs++; + } + if (av[i][1] == '4' && av[i][2] == 0) + OUT.output_bps = 16; + if (av[i][1] == 'C' && av[i][2] == 0) + RawProcessor->set_progress_handler(my_progress_callback, NULL); + if (av[i][1] == 'L' && av[i][2] == 0) + { + const char **clist = LibRaw::cameraList(); + const char **cc = clist; + while (*cc) + { + printf("%s\n", *cc); + cc++; + } + delete RawProcessor; + exit(0); + } + continue; + } + + if (verbose) + printf("Processing file %s\n", av[i]); + + if ((ret = RawProcessor->open_file(av[i])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + + if (!output_thumbs) // No unpack for thumb extraction + if ((ret = RawProcessor->unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); + continue; + } + + // thumbnail unpacking and output in the middle of main + // image processing - for test purposes! + if(output_all_thumbs) + { + if (verbose) + printf("Extracting %d thumbnails\n", RawProcessor->imgdata.thumbs_list.thumbcount); + for (int t = 0; t < RawProcessor->imgdata.thumbs_list.thumbcount; t++) + { + if ((ret = RawProcessor->unpack_thumb_ex(t)) != LIBRAW_SUCCESS) + fprintf(stderr, "Cannot unpack_thumb #%d from %s: %s\n", t, av[i], libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + break; // skip to next file + snprintf(thumbfn, sizeof(thumbfn), "%s.thumb.%d.%s", av[i], t, + T.tformat == LIBRAW_THUMBNAIL_JPEG ? "jpg" : "ppm"); + if (verbose) + printf("Writing thumbnail file %s\n", thumbfn); + if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn))) + { + fprintf(stderr, "Cannot write %s: %s\n", thumbfn, libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + break; + } + } + continue; + } + else if (output_thumbs) + { + if ((ret = RawProcessor->unpack_thumb()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i], + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; // skip to next file + } + else + { + snprintf(thumbfn, sizeof(thumbfn), "%s.%s", av[i], + T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg" + : (T.tcolors == 1? "thumb.pgm" : "thumb.ppm")); + if (verbose) + printf("Writing thumbnail file %s\n", thumbfn); + if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn))) + { + fprintf(stderr, "Cannot write %s: %s\n", thumbfn, + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; + } + } + continue; + } + + ret = RawProcessor->dcraw_process(); + + if (LIBRAW_SUCCESS != ret) + { + fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i], + libraw_strerror(ret)); + if (LIBRAW_FATAL_ERROR(ret)) + continue; + } + snprintf(outfn, sizeof(outfn), "%s.%s", av[i], + OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm")); + + if (verbose) + printf("Writing file %s\n", outfn); + + if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_ppm_tiff_writer(outfn))) + fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret)); + + RawProcessor->recycle(); // just for show this call + } + + delete RawProcessor; + return 0; +} diff --git a/samples/unprocessed_raw.cpp b/samples/unprocessed_raw.cpp new file mode 100644 index 000000000..2f30ce4cb --- /dev/null +++ b/samples/unprocessed_raw.cpp @@ -0,0 +1,319 @@ +/* -*- C++ -*- + * File: unprocessed_raw.cpp + * Copyright 2009-2021 LibRaw LLC (info@libraw.org) + * Created: Fri Jan 02, 2009 + * + * LibRaw sample + * Generates unprocessed raw image: with masked pixels and without black +subtraction + * + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#include +#include +#include +#include + +#include "libraw/libraw.h" + +#ifndef LIBRAW_WIN32_CALLS +#include +#else +#include +#include +#endif + +#ifdef LIBRAW_WIN32_CALLS +#define snprintf _snprintf +#endif + +#if !(LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 14)) +#error This code is for LibRaw 0.14+ only +#endif + +void gamma_curve(unsigned short curve[]); +void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, + const char *basename); +void write_tiff(int width, int height, unsigned short *bitmap, + const char *basename); + +int main(int ac, char *av[]) +{ + int i, ret; + int verbose = 1, autoscale = 0, use_gamma = 0, out_tiff = 0; + char outfn[1024]; + + LibRaw RawProcessor; + if (ac < 2) + { + usage: + printf("unprocessed_raw - LibRaw %s sample. %d cameras supported\n" + "Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n" + "\t-q - be quiet\n" + "\t-s N - select Nth image in file (default=0)\n" + "\t-g - use gamma correction with gamma 2.2 (not precise,use for " + "visual inspection only)\n" + "\t-A - autoscaling (by integer factor)\n" + "\t-T - write tiff instead of pgm\n", + LibRaw::version(), LibRaw::cameraCount(), av[0]); + return 0; + } + +#define S RawProcessor.imgdata.sizes +#define OUT RawProcessor.imgdata.params +#define OUTR RawProcessor.imgdata.rawparams + + for (i = 1; i < ac; i++) + { + if (av[i][0] == '-') + { + if (av[i][1] == 'q' && av[i][2] == 0) + verbose = 0; + else if (av[i][1] == 'A' && av[i][2] == 0) + autoscale = 1; + else if (av[i][1] == 'g' && av[i][2] == 0) + use_gamma = 1; + else if (av[i][1] == 'T' && av[i][2] == 0) + out_tiff = 1; + else if (av[i][1] == 's' && av[i][2] == 0) + { + i++; + OUTR.shot_select = av[i] ? atoi(av[i]) : 0; + } + else + goto usage; + continue; + } + + if (verbose) + printf("Processing file %s\n", av[i]); + if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret)); + continue; // no recycle b/c open file will recycle itself + } + if (verbose) + { + printf("Image size: %dx%d\nRaw size: %dx%d\n", S.width, S.height, + S.raw_width, S.raw_height); + printf("Margins: top=%d, left=%d\n", S.top_margin, S.left_margin); + } + + if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS) + { + fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret)); + continue; + } + + if (verbose) + printf("Unpacked....\n"); + + if (!(RawProcessor.imgdata.idata.filters || + RawProcessor.imgdata.idata.colors == 1)) + { + printf("Only Bayer-pattern RAW files supported, sorry....\n"); + continue; + } + + if (autoscale) + { + unsigned max = 0, scale; + for (int j = 0; j < S.raw_height * S.raw_width; j++) + if (max < RawProcessor.imgdata.rawdata.raw_image[j]) + max = RawProcessor.imgdata.rawdata.raw_image[j]; + if (max > 0 && max < 1 << 15) + { + scale = (1 << 16) / max; + if (verbose) + printf("Scaling with multiplier=%d (max=%d)\n", scale, max); + + for (int j = 0; j < S.raw_height * S.raw_width; j++) + RawProcessor.imgdata.rawdata.raw_image[j] *= scale; + } + } + if (use_gamma) + { + unsigned short curve[0x10000]; + gamma_curve(curve); + for (int j = 0; j < S.raw_height * S.raw_width; j++) + RawProcessor.imgdata.rawdata.raw_image[j] = + curve[RawProcessor.imgdata.rawdata.raw_image[j]]; + if (verbose) + printf("Gamma-corrected....\n"); + } + + if (OUTR.shot_select) + snprintf(outfn, sizeof(outfn), "%s-%d.%s", av[i], OUTR.shot_select, + out_tiff ? "tiff" : "pgm"); + else + snprintf(outfn, sizeof(outfn), "%s.%s", av[i], out_tiff ? "tiff" : "pgm"); + + if (out_tiff) + write_tiff(S.raw_width, S.raw_height, + RawProcessor.imgdata.rawdata.raw_image, outfn); + else + write_ppm(S.raw_width, S.raw_height, + RawProcessor.imgdata.rawdata.raw_image, outfn); + + if (verbose) + printf("Stored to file %s\n", outfn); + } + return 0; +} + +void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, + const char *fname) +{ + if (!bitmap) + return; + + FILE *f = fopen(fname, "wb"); + if (!f) + return; + int bits = 16; + fprintf(f, "P5\n%d %d\n%d\n", width, height, (1 << bits) - 1); + unsigned char *data = (unsigned char *)bitmap; + unsigned data_size = width * height * 2; +#define SWAP(a, b) \ + { \ + a ^= b; \ + a ^= (b ^= a); \ + } + for (unsigned i = 0; i < data_size; i += 2) + SWAP(data[i], data[i + 1]); +#undef SWAP + fwrite(data, data_size, 1, f); + fclose(f); +} + +/* == gamma curve and tiff writer - simplified cut'n'paste from dcraw.c */ + +#define SQR(x) ((x) * (x)) + +void gamma_curve(unsigned short *curve) +{ + + double pwr = 1.0 / 2.2; + double ts = 0.0; + int imax = 0xffff; + int mode = 2; + 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; + 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 tiff_set(ushort *ntag, ushort tag, ushort type, int count, int val) +{ + struct libraw_tiff_tag *tt; + int c; + + tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++; + tt->tag = tag; + tt->type = type; + tt->count = count; + if ((type < LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 4)) + for (c = 0; c < 4; c++) + tt->val.c[c] = val >> (c << 3); + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 2)) + for (c = 0; c < 2; c++) + tt->val.s[c] = val >> (c << 4); + else + tt->val.i = val; +} +#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) + +void tiff_head(int width, int height, struct tiff_hdr *th) +{ + int c; + time_t timestamp = time(NULL); + struct tm *t; + + memset(th, 0, sizeof *th); + th->t_order = htonl(0x4d4d4949) >> 16; + th->magic = 42; + th->ifd = 10; + 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, 1, 16); + for (c = 0; c < 4; c++) + th->bps[c] = 16; + tiff_set(&th->ntag, 259, 3, 1, 1); + tiff_set(&th->ntag, 262, 3, 1, 1); + tiff_set(&th->ntag, 273, 4, 1, sizeof *th); + tiff_set(&th->ntag, 277, 3, 1, 1); + tiff_set(&th->ntag, 278, 4, 1, height); + tiff_set(&th->ntag, 279, 4, 1, height * width * 2); + 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, 306, 2, 20, TOFF(th->date)); + th->rat[0] = th->rat[2] = 300; + th->rat[1] = th->rat[3] = 1; + t = localtime(×tamp); + if (t) + 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); +} + +void write_tiff(int width, int height, unsigned short *bitmap, const char *fn) +{ + struct tiff_hdr th; + + FILE *ofp = fopen(fn, "wb"); + if (!ofp) + return; + tiff_head(width, height, &th); + fwrite(&th, sizeof th, 1, ofp); + fwrite(bitmap, 2, width * height, ofp); + fclose(ofp); +} diff --git a/shlib-version.sh b/shlib-version.sh new file mode 100755 index 000000000..89e284e05 --- /dev/null +++ b/shlib-version.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +vfile=./libraw/libraw_version.h + +major=`grep LIBRAW_SHLIB_CURRENT $vfile |head -1 | awk '{print $3}'` +minor=`grep LIBRAW_SHLIB_REVISION $vfile | head -1 | awk '{print $3}'` +patch=`grep LIBRAW_SHLIB_AGE $vfile | head -1 | awk '{print $3}'` + +echo "$major:$minor:$patch" | awk '{printf $1}' + + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 000000000..a54d1a462 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,2 @@ +all: + (cd ..; make library) diff --git a/src/decoders/canon_600.cpp b/src/decoders/canon_600.cpp new file mode 100644 index 000000000..59576f1ff --- /dev/null +++ b/src/decoders/canon_600.cpp @@ -0,0 +1,225 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::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 LibRaw::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 LibRaw::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 = int(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++) + if (total[st][i] + total[st][i + 4]) + pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]); + } +} + +void LibRaw::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] = float(table[t][i * 4 + c]) / 1024.f; +} + +void LibRaw::canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort *pix; + int irow, row; + + for (irow = row = 0; irow < height; irow++) + { + checkCancel(); + 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 LibRaw::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++) + { + checkCancel(); + 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; +} diff --git a/src/decoders/crx.cpp b/src/decoders/crx.cpp new file mode 100644 index 000000000..30a702054 --- /dev/null +++ b/src/decoders/crx.cpp @@ -0,0 +1,2781 @@ +/* -*- C++ -*- + * File: libraw_crxdec.cpp + * Copyright (C) 2018-2019 Alexey Danilchenko + * Copyright (C) 2019 Alex Tutubalin, LibRaw LLC + * + Canon CR3 file decoder + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#ifdef _abs +#undef _abs +#undef _min +#undef _constrain +#endif +#define _abs(x) (((x) ^ ((int32_t)(x) >> 31)) - ((int32_t)(x) >> 31)) +#define _min(a, b) ((a) < (b) ? (a) : (b)) +#define _constrain(x, l, u) ((x) < (l) ? (l) : ((x) > (u) ? (u) : (x))) + +#if defined(__clang__) || defined(__GNUG__) +#define libraw_inline inline __attribute__((always_inline)) +#elif defined(_MSC_VER) && _MSC_VER > 1400 +#define libraw_inline __forceinline +#else +#define libraw_inline inline +#endif + +// this should be divisible by 4 +#define CRX_BUF_SIZE 0x10000 +#if !defined(_WIN32) || (defined(__GNUC__) && !defined(__INTRINSIC_SPECIAL__BitScanReverse)) +/* __INTRINSIC_SPECIAL__BitScanReverse found in MinGW32-W64 v7.30 headers, may be there is a better solution? */ +typedef uint32_t DWORD; +libraw_inline void _BitScanReverse(DWORD *Index, unsigned long Mask) +{ + *Index = sizeof(unsigned long) * 8 - 1 - __builtin_clzl(Mask); +} +#if LibRawBigEndian +#define _byteswap_ulong(x) (x) +#else +#define _byteswap_ulong(x) __builtin_bswap32(x) +#endif +#endif + +struct CrxBitstream +{ + uint8_t mdatBuf[CRX_BUF_SIZE]; + uint64_t mdatSize; + uint64_t curBufOffset; + uint32_t curPos; + uint32_t curBufSize; + uint32_t bitData; + int32_t bitsLeft; + LibRaw_abstract_datastream *input; +}; + +struct CrxBandParam +{ + CrxBitstream bitStream; + int16_t subbandWidth; + int16_t subbandHeight; + int32_t roundedBitsMask; + int32_t roundedBits; + int16_t curLine; + int32_t *lineBuf0; + int32_t *lineBuf1; + int32_t *lineBuf2; + int32_t sParam; + int32_t kParam; + int32_t *paramData; + int32_t *nonProgrData; + bool supportsPartial; +}; + +struct CrxWaveletTransform +{ + int32_t *subband0Buf; + int32_t *subband1Buf; + int32_t *subband2Buf; + int32_t *subband3Buf; + int32_t *lineBuf[8]; + int16_t curLine; + int16_t curH; + int8_t fltTapH; + int16_t height; + int16_t width; +}; + +struct CrxSubband +{ + CrxBandParam *bandParam; + uint64_t mdatOffset; + uint8_t *bandBuf; + uint16_t width; + uint16_t height; + int32_t qParam; + int32_t kParam; + int32_t qStepBase; + uint32_t qStepMult; + bool supportsPartial; + int32_t bandSize; + uint64_t dataSize; + int64_t dataOffset; + short rowStartAddOn; + short rowEndAddOn; + short colStartAddOn; + short colEndAddOn; + short levelShift; +}; + +struct CrxPlaneComp +{ + uint8_t *compBuf; + CrxSubband *subBands; + CrxWaveletTransform *wvltTransform; + int8_t compNumber; + int64_t dataOffset; + int32_t compSize; + bool supportsPartial; + int32_t roundedBitsMask; + int8_t tileFlag; +}; + +struct CrxQStep +{ + uint32_t *qStepTbl; + int width; + int height; +}; + +struct CrxTile +{ + CrxPlaneComp *comps; + int8_t tileFlag; + int8_t tileNumber; + int64_t dataOffset; + int32_t tileSize; + uint16_t width; + uint16_t height; + bool hasQPData; + CrxQStep *qStep; + uint32_t mdatQPDataSize; + uint16_t mdatExtraSize; +}; + +struct CrxImage +{ + uint8_t nPlanes; + uint16_t planeWidth; + uint16_t planeHeight; + uint8_t samplePrecision; + uint8_t medianBits; + uint8_t subbandCount; + uint8_t levels; + uint8_t nBits; + uint8_t encType; + uint8_t tileCols; + uint8_t tileRows; + CrxTile *tiles; + uint64_t mdatOffset; + uint64_t mdatSize; + int16_t *outBufs[4]; // one per plane + int16_t *planeBuf; + LibRaw_abstract_datastream *input; +#ifdef LIBRAW_CR3_MEMPOOL + libraw_memmgr memmgr; + CrxImage() : memmgr(0) {} +#endif +}; + +enum TileFlags +{ + E_HAS_TILES_ON_THE_RIGHT = 1, + E_HAS_TILES_ON_THE_LEFT = 2, + E_HAS_TILES_ON_THE_BOTTOM = 4, + E_HAS_TILES_ON_THE_TOP = 8 +}; + +int32_t exCoefNumTbl[144] = {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, + 0, 0, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 2, + 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 2, 2, 2, 2, 1, 1, 1, + 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + +int32_t q_step_tbl[8] = {0x28, 0x2D, 0x33, 0x39, 0x40, 0x48}; + +uint32_t JS[32] = {1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, + 4, 8, 8, 8, 8, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, + 0x80, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000}; + +uint32_t J[32] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + +static inline void crxFillBuffer(CrxBitstream *bitStrm) +{ + if (bitStrm->curPos >= bitStrm->curBufSize && bitStrm->mdatSize) + { + bitStrm->curPos = 0; + bitStrm->curBufOffset += bitStrm->curBufSize; +#ifdef LIBRAW_USE_OPENMP +#pragma omp critical +#endif + { +#ifndef LIBRAW_USE_OPENMP + bitStrm->input->lock(); +#endif + bitStrm->input->seek(bitStrm->curBufOffset, SEEK_SET); + bitStrm->curBufSize = bitStrm->input->read(bitStrm->mdatBuf, 1, _min(bitStrm->mdatSize, CRX_BUF_SIZE)); +#ifndef LIBRAW_USE_OPENMP + bitStrm->input->unlock(); +#endif + } + if (bitStrm->curBufSize < 1) // nothing read + throw LIBRAW_EXCEPTION_IO_EOF; + bitStrm->mdatSize -= bitStrm->curBufSize; + } +} + +libraw_inline int crxBitstreamGetZeros(CrxBitstream *bitStrm) +{ + uint32_t nonZeroBit = 0; + uint64_t nextData = 0; + int32_t result = 0; + + if (bitStrm->bitData) + { + _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)bitStrm->bitData); + result = 31 - nonZeroBit; + bitStrm->bitData <<= 32 - nonZeroBit; + bitStrm->bitsLeft -= 32 - nonZeroBit; + } + else + { + uint32_t bitsLeft = bitStrm->bitsLeft; + while (1) + { + while (bitStrm->curPos + 4 <= bitStrm->curBufSize) + { + nextData = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos)); + bitStrm->curPos += 4; + crxFillBuffer(bitStrm); + if (nextData) + { + _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData); + result = bitsLeft + 31 - nonZeroBit; + bitStrm->bitData = nextData << (32 - nonZeroBit); + bitStrm->bitsLeft = nonZeroBit; + return result; + } + bitsLeft += 32; + } + if (bitStrm->curBufSize < bitStrm->curPos + 1) + break; // error + nextData = bitStrm->mdatBuf[bitStrm->curPos++]; + crxFillBuffer(bitStrm); + if (nextData) + break; + bitsLeft += 8; + } + _BitScanReverse((DWORD *)&nonZeroBit, (DWORD)nextData); + result = (uint32_t)(bitsLeft + 7 - nonZeroBit); + bitStrm->bitData = nextData << (32 - nonZeroBit); + bitStrm->bitsLeft = nonZeroBit; + } + return result; +} + +libraw_inline uint32_t crxBitstreamGetBits(CrxBitstream *bitStrm, int bits) +{ + int bitsLeft = bitStrm->bitsLeft; + uint32_t bitData = bitStrm->bitData; + uint32_t nextWord; + uint8_t nextByte; + uint32_t result; + + if (bitsLeft < bits) + { + // get them from stream + if (bitStrm->curPos + 4 <= bitStrm->curBufSize) + { + nextWord = _byteswap_ulong(*(uint32_t *)(bitStrm->mdatBuf + bitStrm->curPos)); + bitStrm->curPos += 4; + crxFillBuffer(bitStrm); + bitStrm->bitsLeft = 32 - (bits - bitsLeft); + result = ((nextWord >> bitsLeft) | bitData) >> (32 - bits); + bitStrm->bitData = nextWord << (bits - bitsLeft); + return result; + } + // less than a word left - read byte at a time + do + { + if (bitStrm->curPos >= bitStrm->curBufSize) + break; // error + bitsLeft += 8; + nextByte = bitStrm->mdatBuf[bitStrm->curPos++]; + crxFillBuffer(bitStrm); + bitData |= nextByte << (32 - bitsLeft); + } while (bitsLeft < bits); + } + result = bitData >> (32 - bits); // 32-bits + bitStrm->bitData = bitData << bits; + bitStrm->bitsLeft = bitsLeft - bits; + return result; +} + +libraw_inline int32_t crxPrediction(int32_t left, int32_t top, int32_t deltaH, int32_t deltaV) +{ + int32_t symb[4] = {left + deltaH, left + deltaH, left, top}; + + return symb[(((deltaV < 0) ^ (deltaH < 0)) << 1) + ((left < top) ^ (deltaH < 0))]; +} + +libraw_inline int32_t crxPredictKParameter(int32_t prevK, int32_t bitCode, int32_t maxVal = 0) +{ + int32_t newKParam = prevK - (bitCode < (1 << prevK >> 1)) + ((bitCode >> prevK) > 2) + ((bitCode >> prevK) > 5); + + return !maxVal || newKParam < maxVal ? newKParam : maxVal; +} + +libraw_inline void crxDecodeSymbolL1(CrxBandParam *param, int32_t doMedianPrediction, int32_t notEOL = 0) +{ + if (doMedianPrediction) + { + int32_t symb[4]; + + int32_t delta = param->lineBuf0[1] - param->lineBuf0[0]; + symb[2] = param->lineBuf1[0]; + symb[0] = symb[1] = delta + symb[2]; + symb[3] = param->lineBuf0[1]; + + param->lineBuf1[1] = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (delta < 0)) << 1) + + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (delta < 0))]; + } + else + param->lineBuf1[1] = param->lineBuf0[1]; + + // get next error symbol + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + + // add converted (+/-) error code to predicted value + param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + + // for not end of the line - use one symbol ahead to estimate next K + if (notEOL) + { + int32_t nextDelta = (param->lineBuf0[2] - param->lineBuf0[1]) << 1; + bitCode = (bitCode + _abs(nextDelta)) >> 1; + ++param->lineBuf0; + } + + // update K parameter + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + + ++param->lineBuf1; +} + +int crxDecodeLine(CrxBandParam *param) +{ + int length = param->subbandWidth; + + param->lineBuf1[0] = param->lineBuf0[1]; + for (; length > 1; --length) + { + if (param->lineBuf1[0] != param->lineBuf0[1] || param->lineBuf1[0] != param->lineBuf0[2]) + { + crxDecodeSymbolL1(param, 1, 1); + } + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (nSyms > length) + { + nSyms = length; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (nSyms == length) + break; + } + + if (nSyms < length) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + if (nSyms > length) + return -1; + } + + length -= nSyms; + + // copy symbol nSyms times + param->lineBuf0 += nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) + { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + } + + if (length > 0) + crxDecodeSymbolL1(param, 0, (length > 1)); + } + } + + if (length == 1) + crxDecodeSymbolL1(param, 1, 0); + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return 0; +} + +libraw_inline void crxDecodeSymbolL1Rounded(CrxBandParam *param, int32_t doSym = 1, int32_t doCode = 1) +{ + int32_t sym = param->lineBuf0[1]; + + if (doSym) + { + // calculate the next symbol gradient + int32_t symb[4]; + int32_t deltaH = param->lineBuf0[1] - param->lineBuf0[0]; + symb[2] = param->lineBuf1[0]; + symb[0] = symb[1] = deltaH + symb[2]; + symb[3] = param->lineBuf0[1]; + sym = symb[(((param->lineBuf0[0] < param->lineBuf1[0]) ^ (deltaH < 0)) << 1) + + ((param->lineBuf1[0] < param->lineBuf0[1]) ^ (deltaH < 0))]; + } + + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + int32_t code = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->lineBuf1[1] = param->roundedBitsMask * 2 * code + (code >> 31) + sym; + + if (doCode) + { + if (param->lineBuf0[2] > param->lineBuf0[1]) + code = (param->lineBuf0[2] - param->lineBuf0[1] + param->roundedBitsMask - 1) >> param->roundedBits; + else + code = -((param->lineBuf0[1] - param->lineBuf0[2] + param->roundedBitsMask) >> param->roundedBits); + + param->kParam = crxPredictKParameter(param->kParam, (bitCode + 2 * _abs(code)) >> 1, 15); + } + else + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + + ++param->lineBuf1; +} + +int crxDecodeLineRounded(CrxBandParam *param) +{ + int32_t valueReached = 0; + + param->lineBuf0[0] = param->lineBuf0[1]; + param->lineBuf1[0] = param->lineBuf0[1]; + int32_t length = param->subbandWidth; + + for (; length > 1; --length) + { + if (_abs(param->lineBuf0[2] - param->lineBuf0[1]) > param->roundedBitsMask) + { + crxDecodeSymbolL1Rounded(param); + ++param->lineBuf0; + valueReached = 1; + } + else if (valueReached || _abs(param->lineBuf0[0] - param->lineBuf1[0]) > param->roundedBitsMask) + { + crxDecodeSymbolL1Rounded(param); + ++param->lineBuf0; + valueReached = 0; + } + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (nSyms > length) + { + nSyms = length; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (nSyms == length) + break; + } + if (nSyms < length) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + } + if (nSyms > length) + return -1; + } + length -= nSyms; + + // copy symbol nSyms times + param->lineBuf0 += nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) + { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length > 1) + { + crxDecodeSymbolL1Rounded(param, 0); + ++param->lineBuf0; + valueReached = _abs(param->lineBuf0[1] - param->lineBuf0[0]) > param->roundedBitsMask; + } + else if (length == 1) + crxDecodeSymbolL1Rounded(param, 0, 0); + } + } + if (length == 1) + crxDecodeSymbolL1Rounded(param, 1, 0); + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return 0; +} + +int crxDecodeLineNoRefPrevLine(CrxBandParam *param) +{ + int32_t i = 0; + + for (; i < param->subbandWidth - 1; i++) + { + if (param->lineBuf0[i + 2] | param->lineBuf0[i + 1] | param->lineBuf1[i]) + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[i + 1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode); + if (param->lineBuf2[i + 1] - param->kParam <= 1) + { + if (param->kParam >= 15) + param->kParam = 15; + } + else + ++param->kParam; + } + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + if (i != param->subbandWidth - 1) + { + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (i + nSyms > param->subbandWidth) + { + nSyms = param->subbandWidth - i; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (i + nSyms == param->subbandWidth) + break; + } + if (i + nSyms < param->subbandWidth) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + } + if (i + nSyms > param->subbandWidth) + return -1; + } + } + else if (i > param->subbandWidth) + return -1; + + if (nSyms > 0) + { + memset(param->lineBuf1 + i + 1, 0, nSyms * sizeof(int32_t)); + memset(param->lineBuf2 + i, 0, nSyms * sizeof(int32_t)); + i += nSyms; + } + + if (i >= param->subbandWidth - 1) + { + if (i == param->subbandWidth - 1) + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[i] = param->kParam; + } + continue; + } + else + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[i + 1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode); + if (param->lineBuf2[i + 1] - param->kParam <= 1) + { + if (param->kParam >= 15) + param->kParam = 15; + } + else + ++param->kParam; + } + } + param->lineBuf2[i] = param->kParam; + } + if (i == param->subbandWidth - 1) + { + int32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[i + 1] = -(bitCode & 1) ^ (bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[i] = param->kParam; + } + + return 0; +} + +int crxDecodeTopLine(CrxBandParam *param) +{ + param->lineBuf1[0] = 0; + + int32_t length = param->subbandWidth; + + // read the line from bitstream + for (; length > 1; --length) + { + if (param->lineBuf1[0]) + param->lineBuf1[1] = param->lineBuf1[0]; + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (nSyms > length) + { + nSyms = length; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (nSyms == length) + break; + } + if (nSyms < length) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + if (nSyms > length) + return -1; + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) + { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length <= 0) + break; + } + + param->lineBuf1[1] = 0; + } + + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + if (length == 1) + { + param->lineBuf1[1] = param->lineBuf1[0]; + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[1] += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return 0; +} + +int crxDecodeTopLineRounded(CrxBandParam *param) +{ + param->lineBuf1[0] = 0; + + int32_t length = param->subbandWidth; + + // read the line from bitstream + for (; length > 1; --length) + { + if (_abs(param->lineBuf1[0]) > param->roundedBitsMask) + param->lineBuf1[1] = param->lineBuf1[0]; + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (nSyms > length) + { + nSyms = length; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (nSyms == length) + break; + } + if (nSyms < length) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + if (nSyms > length) + return -1; + } + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) + { + param->lineBuf1[1] = param->lineBuf1[0]; + ++param->lineBuf1; + } + + if (length <= 0) + break; + + param->lineBuf1[1] = 0; + } + + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + + int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + if (length == 1) + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + int32_t sVal = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->lineBuf1[1] += param->roundedBitsMask * 2 * sVal + (sVal >> 31); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + ++param->lineBuf1; + } + + param->lineBuf1[1] = param->lineBuf1[0] + 1; + + return 0; +} + +int crxDecodeTopLineNoRefPrevLine(CrxBandParam *param) +{ + param->lineBuf0[0] = 0; + param->lineBuf1[0] = 0; + int32_t length = param->subbandWidth; + for (; length > 1; --length) + { + if (param->lineBuf1[0]) + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + } + else + { + int nSyms = 0; + if (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms = 1; + while (crxBitstreamGetBits(¶m->bitStream, 1)) + { + nSyms += JS[param->sParam]; + if (nSyms > length) + { + nSyms = length; + break; + } + if (param->sParam < 31) + ++param->sParam; + if (nSyms == length) + break; + } + if (nSyms < length) + { + if (J[param->sParam]) + nSyms += crxBitstreamGetBits(¶m->bitStream, J[param->sParam]); + if (param->sParam > 0) + --param->sParam; + if (nSyms > length) + return -1; + } + } + + length -= nSyms; + + // copy symbol nSyms times + while (nSyms-- > 0) + { + param->lineBuf2[0] = 0; + param->lineBuf1[1] = 0; + ++param->lineBuf1; + ++param->lineBuf2; + } + + if (length <= 0) + break; + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[1] = -(int32_t)((bitCode + 1) & 1) ^ (int32_t)((bitCode + 1) >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + } + param->lineBuf2[0] = param->kParam; + ++param->lineBuf2; + ++param->lineBuf1; + } + + if (length == 1) + { + uint32_t bitCode = crxBitstreamGetZeros(¶m->bitStream); + if (bitCode >= 41) + bitCode = crxBitstreamGetBits(¶m->bitStream, 21); + else if (param->kParam) + bitCode = crxBitstreamGetBits(¶m->bitStream, param->kParam) | (bitCode << param->kParam); + param->lineBuf1[1] = -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); + param->kParam = crxPredictKParameter(param->kParam, bitCode, 15); + param->lineBuf2[0] = param->kParam; + ++param->lineBuf1; + } + + param->lineBuf1[1] = 0; + + return 0; +} + +int crxDecodeLine(CrxBandParam *param, uint8_t *bandBuf) +{ + if (!param || !bandBuf) + return -1; + if (param->curLine >= param->subbandHeight) + return -1; + + if (param->curLine == 0) + { + int32_t lineLength = param->subbandWidth + 2; + + param->sParam = 0; + param->kParam = 0; + if (param->supportsPartial) + { + if (param->roundedBitsMask <= 0) + { + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeTopLine(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + else + { + param->roundedBits = 1; + if (param->roundedBitsMask & ~1) + { + while (param->roundedBitsMask >> param->roundedBits) + ++param->roundedBits; + } + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeTopLineRounded(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + } + else + { + param->lineBuf2 = (int32_t *)param->nonProgrData; + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeTopLineNoRefPrevLine(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + } + else if (!param->supportsPartial) + { + int32_t lineLength = param->subbandWidth + 2; + param->lineBuf2 = (int32_t *)param->nonProgrData; + if (param->curLine & 1) + { + param->lineBuf1 = (int32_t *)param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } + else + { + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeLineNoRefPrevLine(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + else if (param->roundedBitsMask <= 0) + { + int32_t lineLength = param->subbandWidth + 2; + if (param->curLine & 1) + { + param->lineBuf1 = (int32_t *)param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } + else + { + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeLine(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + else + { + int32_t lineLength = param->subbandWidth + 2; + if (param->curLine & 1) + { + param->lineBuf1 = (int32_t *)param->paramData; + param->lineBuf0 = param->lineBuf1 + lineLength; + } + else + { + param->lineBuf0 = (int32_t *)param->paramData; + param->lineBuf1 = param->lineBuf0 + lineLength; + } + int32_t *lineBuf = param->lineBuf1 + 1; + if (crxDecodeLineRounded(param)) + return -1; + memcpy(bandBuf, lineBuf, param->subbandWidth * sizeof(int32_t)); + ++param->curLine; + } + return 0; +} + +int crxUpdateQparam(CrxSubband *subband) +{ + uint32_t bitCode = crxBitstreamGetZeros(&subband->bandParam->bitStream); + if (bitCode >= 23) + bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, 8); + else if (subband->kParam) + bitCode = crxBitstreamGetBits(&subband->bandParam->bitStream, subband->kParam) | (bitCode << subband->kParam); + + subband->qParam += -(int32_t)(bitCode & 1) ^ (int32_t)(bitCode >> 1); // converting encoded to signed integer + subband->kParam = crxPredictKParameter(subband->kParam, bitCode); + if (subband->kParam > 7) + return -1; + return 0; +} + +libraw_inline int getSubbandRow(CrxSubband *band, int row) +{ + return row < band->rowStartAddOn + ? 0 + : (row < band->height - band->rowEndAddOn ? row - band->rowEndAddOn + : band->height - band->rowEndAddOn - band->rowStartAddOn - 1); +} +int crxDecodeLineWithIQuantization(CrxSubband *band, CrxQStep *qStep) +{ + if (!band->dataSize) + { + memset(band->bandBuf, 0, band->bandSize); + return 0; + } + + if (band->supportsPartial && !qStep && crxUpdateQparam(band)) + return -1; + if (crxDecodeLine(band->bandParam, band->bandBuf)) + return -1; + + if (band->width <= 0) + return 0; + + // update band buffers + int32_t *bandBuf = (int32_t *)band->bandBuf; + if (qStep) + { + // new version + uint32_t *qStepTblPtr = &qStep->qStepTbl[qStep->width * getSubbandRow(band, band->bandParam->curLine - 1)]; + + for (int i = 0; i < band->colStartAddOn; ++i) + { + int32_t quantVal = band->qStepBase + ((qStepTblPtr[0] * band->qStepMult) >> 3); + bandBuf[i] *= _constrain(quantVal, 1, 0x168000); + } + + for (int i = band->colStartAddOn; i < band->width - band->colEndAddOn; ++i) + { + int32_t quantVal = + band->qStepBase + ((qStepTblPtr[(i - band->colStartAddOn) >> band->levelShift] * band->qStepMult) >> 3); + bandBuf[i] *= _constrain(quantVal, 1, 0x168000); + } + int lastIdx = (band->width - band->colEndAddOn - band->colStartAddOn - 1) >> band->levelShift; + for (int i = band->width - band->colEndAddOn; i < band->width; ++i) + { + int32_t quantVal = band->qStepBase + ((qStepTblPtr[lastIdx] * band->qStepMult) >> 3); + bandBuf[i] *= _constrain(quantVal, 1, 0x168000); + } + } + else + { + // prev. version + int32_t qScale = q_step_tbl[band->qParam % 6] >> (6 - band->qParam / 6); + if (band->qParam / 6 >= 6) + qScale = q_step_tbl[band->qParam % 6] * (1 << (band->qParam / 6 + 26)); + + if (qScale != 1) + for (int32_t i = 0; i < band->width; ++i) + bandBuf[i] *= qScale; + } + + return 0; +} + +void crxHorizontal53(int32_t *lineBufLA, int32_t *lineBufLB, CrxWaveletTransform *wavelet, uint32_t tileFlag) +{ + int32_t *band0Buf = wavelet->subband0Buf; + int32_t *band1Buf = wavelet->subband1Buf; + int32_t *band2Buf = wavelet->subband2Buf; + int32_t *band3Buf = wavelet->subband3Buf; + + if (wavelet->width <= 1) + { + lineBufLA[0] = band0Buf[0]; + lineBufLB[0] = band2Buf[0]; + } + else + { + if (tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band1Buf; + ++band3Buf; + } + else + { + lineBufLA[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufLB[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + ++band0Buf; + ++band2Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLA[1] = band1Buf[0] + ((delta + lineBufLA[0]) >> 1); + lineBufLA[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufLB[1] = band3Buf[0] + ((delta + lineBufLB[0]) >> 1); + lineBufLB[2] = delta; + + ++band0Buf; + ++band1Buf; + ++band2Buf; + ++band3Buf; + lineBufLA += 2; + lineBufLB += 2; + } + if (tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufLA[1] = band1Buf[0] + ((deltaA + lineBufLA[0]) >> 1); + + int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufLB[1] = band3Buf[0] + ((deltaB + lineBufLB[0]) >> 1); + + if (wavelet->width & 1) + { + lineBufLA[2] = deltaA; + lineBufLB[2] = deltaB; + } + } + else if (wavelet->width & 1) + { + lineBufLA[1] = band1Buf[0] + ((lineBufLA[0] + band0Buf[0] - ((band1Buf[0] + 1) >> 1)) >> 1); + lineBufLA[2] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + + lineBufLB[1] = band3Buf[0] + ((lineBufLB[0] + band2Buf[0] - ((band3Buf[0] + 1) >> 1)) >> 1); + lineBufLB[2] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + else + { + lineBufLA[1] = lineBufLA[0] + band1Buf[0]; + lineBufLB[1] = lineBufLB[0] + band3Buf[0]; + } + } +} + +int32_t *crxIdwt53FilterGetLine(CrxPlaneComp *comp, int32_t level) +{ + int32_t *result = comp->wvltTransform[level] + .lineBuf[(comp->wvltTransform[level].fltTapH - comp->wvltTransform[level].curH + 5) % 5 + 3]; + comp->wvltTransform[level].curH--; + return result; +} + +int crxIdwt53FilterDecode(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep) +{ + if (comp->wvltTransform[level].curH) + return 0; + + CrxSubband *sband = comp->subBands + 3 * level; + CrxQStep *qStepLevel = qStep ? qStep + level : 0; + + if (comp->wvltTransform[level].height - 3 <= comp->wvltTransform[level].curLine && + !(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) + { + if (comp->wvltTransform[level].height & 1) + { + if (level) + { + if (crxIdwt53FilterDecode(comp, level - 1, qStep)) + return -1; + } + else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) + return -1; + + if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel)) + return -1; + } + } + else + { + if (level) + { + if (crxIdwt53FilterDecode(comp, level - 1, qStep)) + return -1; + } + else if (crxDecodeLineWithIQuantization(sband, qStepLevel)) // LL band + return -1; + + if (crxDecodeLineWithIQuantization(sband + 1, qStepLevel) || // HL band + crxDecodeLineWithIQuantization(sband + 2, qStepLevel) || // LH band + crxDecodeLineWithIQuantization(sband + 3, qStepLevel)) // HH band + return -1; + } + + return 0; +} + +int crxIdwt53FilterTransform(CrxPlaneComp *comp, uint32_t level) +{ + CrxWaveletTransform *wavelet = comp->wvltTransform + level; + + if (wavelet->curH) + return 0; + + if (wavelet->curLine >= wavelet->height - 3) + { + if (!(comp->tileFlag & E_HAS_TILES_ON_THE_BOTTOM)) + { + if (wavelet->height & 1) + { + if (level) + { + if (!wavelet[-1].curH) + if (crxIdwt53FilterTransform(comp, level - 1)) + return -1; + wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); + } + int32_t *band0Buf = wavelet->subband0Buf; + int32_t *band1Buf = wavelet->subband1Buf; + int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; + + int32_t *lineBufL0 = wavelet->lineBuf[0]; + int32_t *lineBufL1 = wavelet->lineBuf[1]; + wavelet->lineBuf[1] = wavelet->lineBuf[2]; + wavelet->lineBuf[2] = lineBufL1; + + // process L bands + if (wavelet->width <= 1) + { + lineBufL0[0] = band0Buf[0]; + } + else + { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + ++band1Buf; + } + else + { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + } + ++band0Buf; + for (int i = 0; i < wavelet->width - 3; i += 2) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + lineBufL0[2] = delta; + ++band0Buf; + ++band1Buf; + lineBufL0 += 2; + } + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + if (wavelet->width & 1) + lineBufL0[2] = delta; + } + else if (wavelet->width & 1) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL0[1] = band1Buf[0] + ((lineBufL0[0] + delta) >> 1); + lineBufL0[2] = delta; + } + else + lineBufL0[1] = band1Buf[0] + lineBufL0[0]; + } + + // process H bands + lineBufL0 = wavelet->lineBuf[0]; + lineBufL1 = wavelet->lineBuf[1]; + for (int32_t i = 0; i < wavelet->width; i++) + { + int32_t delta = lineBufL0[i] - ((lineBufL1[i] + 1) >> 1); + lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); + lineBufH2[i] = delta; + } + wavelet->curH += 3; + wavelet->curLine += 3; + wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; + } + else + { + int32_t *lineBufL2 = wavelet->lineBuf[2]; + int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + wavelet->lineBuf[1] = lineBufL2; + wavelet->lineBuf[2] = wavelet->lineBuf[1]; + + for (int32_t i = 0; i < wavelet->width; i++) + lineBufH1[i] = lineBufH0[i] + lineBufL2[i]; + + wavelet->curH += 2; + wavelet->curLine += 2; + wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; + } + } + } + else + { + if (level) + { + if (!wavelet[-1].curH && crxIdwt53FilterTransform(comp, level - 1)) + return -1; + wavelet->subband0Buf = crxIdwt53FilterGetLine(comp, level - 1); + } + + int32_t *band0Buf = wavelet->subband0Buf; + int32_t *band1Buf = wavelet->subband1Buf; + int32_t *band2Buf = wavelet->subband2Buf; + int32_t *band3Buf = wavelet->subband3Buf; + + int32_t *lineBufL0 = wavelet->lineBuf[0]; + int32_t *lineBufL1 = wavelet->lineBuf[1]; + int32_t *lineBufL2 = wavelet->lineBuf[2]; + int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + int32_t *lineBufH1 = wavelet->lineBuf[(wavelet->fltTapH + 1) % 5 + 3]; + int32_t *lineBufH2 = wavelet->lineBuf[(wavelet->fltTapH + 2) % 5 + 3]; + + wavelet->lineBuf[1] = wavelet->lineBuf[2]; + wavelet->lineBuf[2] = lineBufL1; + + // process L bands + if (wavelet->width <= 1) + { + lineBufL0[0] = band0Buf[0]; + lineBufL1[0] = band2Buf[0]; + } + else + { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band1Buf; + ++band3Buf; + } + else + { + lineBufL0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL1[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + } + ++band0Buf; + ++band2Buf; + for (int i = 0; i < wavelet->width - 3; i += 2) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); + lineBufL0[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); + lineBufL1[2] = delta; + + ++band0Buf; + ++band1Buf; + ++band2Buf; + ++band3Buf; + lineBufL0 += 2; + lineBufL1 += 2; + } + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + int32_t deltaA = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufL0[1] = band1Buf[0] + ((deltaA + lineBufL0[0]) >> 1); + + int32_t deltaB = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL1[1] = band3Buf[0] + ((deltaB + lineBufL1[0]) >> 1); + + if (wavelet->width & 1) + { + lineBufL0[2] = deltaA; + lineBufL1[2] = deltaB; + } + } + else if (wavelet->width & 1) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufL0[1] = band1Buf[0] + ((delta + lineBufL0[0]) >> 1); + lineBufL0[2] = delta; + + delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + lineBufL1[1] = band3Buf[0] + ((delta + lineBufL1[0]) >> 1); + lineBufL1[2] = delta; + } + else + { + lineBufL0[1] = lineBufL0[0] + band1Buf[0]; + lineBufL1[1] = lineBufL1[0] + band3Buf[0]; + } + } + + // process H bands + lineBufL0 = wavelet->lineBuf[0]; + lineBufL1 = wavelet->lineBuf[1]; + lineBufL2 = wavelet->lineBuf[2]; + for (int32_t i = 0; i < wavelet->width; i++) + { + int32_t delta = lineBufL0[i] - ((lineBufL2[i] + lineBufL1[i] + 2) >> 2); + lineBufH1[i] = lineBufL1[i] + ((delta + lineBufH0[i]) >> 1); + lineBufH2[i] = delta; + } + if (wavelet->curLine >= wavelet->height - 3 && wavelet->height & 1) + { + wavelet->curH += 3; + wavelet->curLine += 3; + wavelet->fltTapH = (wavelet->fltTapH + 3) % 5; + } + else + { + wavelet->curH += 2; + wavelet->curLine += 2; + wavelet->fltTapH = (wavelet->fltTapH + 2) % 5; + } + } + + return 0; +} + +int crxIdwt53FilterInitialize(CrxPlaneComp *comp, int32_t level, CrxQStep *qStep) +{ + if (level == 0) + return 0; + + for (int curLevel = 0, curBand = 0; curLevel < level; curLevel++, curBand += 3) + { + CrxQStep *qStepLevel = qStep ? qStep + curLevel : 0; + CrxWaveletTransform *wavelet = comp->wvltTransform + curLevel; + if (curLevel) + wavelet[0].subband0Buf = crxIdwt53FilterGetLine(comp, curLevel - 1); + else if (crxDecodeLineWithIQuantization(comp->subBands + curBand, qStepLevel)) + return -1; + + int32_t *lineBufH0 = wavelet->lineBuf[wavelet->fltTapH + 3]; + if (wavelet->height > 1) + { + if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel) || + crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel) || + crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel)) + return -1; + + int32_t *lineBufL0 = wavelet->lineBuf[0]; + int32_t *lineBufL1 = wavelet->lineBuf[1]; + int32_t *lineBufL2 = wavelet->lineBuf[2]; + + if (comp->tileFlag & E_HAS_TILES_ON_THE_TOP) + { + crxHorizontal53(lineBufL0, wavelet->lineBuf[1], wavelet, comp->tileFlag); + if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 3, qStepLevel) || + crxDecodeLineWithIQuantization(comp->subBands + curBand + 2, qStepLevel)) + return -1; + + int32_t *band2Buf = wavelet->subband2Buf; + int32_t *band3Buf = wavelet->subband3Buf; + + // process L band + if (wavelet->width <= 1) + lineBufL2[0] = band2Buf[0]; + else + { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + ++band3Buf; + } + else + lineBufL2[0] = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + + ++band2Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) + { + int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + lineBufL2[2] = delta; + + ++band2Buf; + ++band3Buf; + lineBufL2 += 2; + } + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + int32_t delta = band2Buf[0] - ((band3Buf[0] + band3Buf[1] + 2) >> 2); + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + if (wavelet->width & 1) + lineBufL2[2] = delta; + } + else if (wavelet->width & 1) + { + int32_t delta = band2Buf[0] - ((band3Buf[0] + 1) >> 1); + + lineBufL2[1] = band3Buf[0] + ((lineBufL2[0] + delta) >> 1); + lineBufL2[2] = delta; + } + else + { + lineBufL2[1] = band3Buf[0] + lineBufL2[0]; + } + } + + // process H band + for (int32_t i = 0; i < wavelet->width; i++) + lineBufH0[i] = lineBufL0[i] - ((lineBufL1[i] + lineBufL2[i] + 2) >> 2); + } + else + { + crxHorizontal53(lineBufL0, wavelet->lineBuf[2], wavelet, comp->tileFlag); + for (int i = 0; i < wavelet->width; i++) + lineBufH0[i] = lineBufL0[i] - ((lineBufL2[i] + 1) >> 1); + } + + if (crxIdwt53FilterDecode(comp, curLevel, qStep) || crxIdwt53FilterTransform(comp, curLevel)) + return -1; + } + else + { + if (crxDecodeLineWithIQuantization(comp->subBands + curBand + 1, qStepLevel)) + return -1; + + int32_t *band0Buf = wavelet->subband0Buf; + int32_t *band1Buf = wavelet->subband1Buf; + + // process H band + if (wavelet->width <= 1) + lineBufH0[0] = band0Buf[0]; + else + { + if (comp->tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + ++band1Buf; + } + else + lineBufH0[0] = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + + ++band0Buf; + + for (int i = 0; i < wavelet->width - 3; i += 2) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + + ++band0Buf; + ++band1Buf; + lineBufH0 += 2; + } + + if (comp->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + band1Buf[1] + 2) >> 2); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + } + else if (wavelet->width & 1) + { + int32_t delta = band0Buf[0] - ((band1Buf[0] + 1) >> 1); + lineBufH0[1] = band1Buf[0] + ((lineBufH0[0] + delta) >> 1); + lineBufH0[2] = delta; + } + else + { + lineBufH0[1] = band1Buf[0] + lineBufH0[0]; + } + } + ++wavelet->curLine; + ++wavelet->curH; + wavelet->fltTapH = (wavelet->fltTapH + 1) % 5; + } + } + + return 0; +} + +void crxFreeSubbandData(CrxImage *image, CrxPlaneComp *comp) +{ + if (comp->compBuf) + { + free(comp->compBuf); + comp->compBuf = 0; + } + + if (!comp->subBands) + return; + + for (int32_t i = 0; i < image->subbandCount; i++) + { + if (comp->subBands[i].bandParam) + { + free(comp->subBands[i].bandParam); + comp->subBands[i].bandParam = 0LL; + } + + comp->subBands[i].bandBuf = 0; + comp->subBands[i].bandSize = 0; + } +} + +void crxConvertPlaneLine(CrxImage *img, int imageRow, int imageCol = 0, int plane = 0, int32_t *lineData = 0, + int lineLength = 0) +{ + if (lineData) + { + uint64_t rawOffset = 4 * img->planeWidth * imageRow + 2 * imageCol; + if (img->encType == 1) + { + int32_t maxVal = 1 << (img->nBits - 1); + int32_t minVal = -maxVal; + --maxVal; + for (int i = 0; i < lineLength; i++) + img->outBufs[plane][rawOffset + 2 * i] = _constrain(lineData[i], minVal, maxVal); + } + else if (img->encType == 3) + { + // copy to intermediate planeBuf + rawOffset = plane * img->planeWidth * img->planeHeight + img->planeWidth * imageRow + imageCol; + for (int i = 0; i < lineLength; i++) + img->planeBuf[rawOffset + i] = lineData[i]; + } + else if (img->nPlanes == 4) + { + int32_t median = 1 << (img->nBits - 1); + int32_t maxVal = (1 << img->nBits) - 1; + for (int i = 0; i < lineLength; i++) + img->outBufs[plane][rawOffset + 2 * i] = _constrain(median + lineData[i], 0, maxVal); + } + else if (img->nPlanes == 1) + { + int32_t maxVal = (1 << img->nBits) - 1; + int32_t median = 1 << (img->nBits - 1); + rawOffset = img->planeWidth * imageRow + imageCol; + for (int i = 0; i < lineLength; i++) + img->outBufs[0][rawOffset + i] = _constrain(median + lineData[i], 0, maxVal); + } + } + else if (img->encType == 3 && img->planeBuf) + { + int32_t planeSize = img->planeWidth * img->planeHeight; + int16_t *plane0 = img->planeBuf + imageRow * img->planeWidth; + int16_t *plane1 = plane0 + planeSize; + int16_t *plane2 = plane1 + planeSize; + int16_t *plane3 = plane2 + planeSize; + + int32_t median = (1 << (img->medianBits - 1)) << 10; + int32_t maxVal = (1 << img->medianBits) - 1; + uint32_t rawLineOffset = 4 * img->planeWidth * imageRow; + + // for this stage - all except imageRow is ignored + for (int i = 0; i < img->planeWidth; i++) + { + int32_t gr = median + (plane0[i] << 10) - 168 * plane1[i] - 585 * plane3[i]; + int32_t val = 0; + if (gr < 0) + gr = -(((_abs(gr) + 512) >> 9) & ~1); + else + gr = ((_abs(gr) + 512) >> 9) & ~1; + + // Essentially R = round(median + P0 + 1.474*P3) + val = (median + (plane0[i] << 10) + 1510 * plane3[i] + 512) >> 10; + img->outBufs[0][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); + // Essentially G1 = round(median + P0 + P2 - 0.164*P1 - 0.571*P3) + val = (plane2[i] + gr + 1) >> 1; + img->outBufs[1][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); + // Essentially G2 = round(median + P0 - P2 - 0.164*P1 - 0.571*P3) + val = (gr - plane2[i] + 1) >> 1; + img->outBufs[2][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); + // Essentially B = round(median + P0 + 1.881*P1) + val = (median + (plane0[i] << 10) + 1927 * plane1[i] + 512) >> 10; + img->outBufs[3][rawLineOffset + 2 * i] = _constrain(val, 0, maxVal); + } + } +} + +int crxParamInit(CrxImage *img, CrxBandParam **param, uint64_t subbandMdatOffset, uint64_t subbandDataSize, + uint32_t subbandWidth, uint32_t subbandHeight, bool supportsPartial, uint32_t roundedBitsMask) +{ + int32_t progrDataSize = supportsPartial ? 0 : sizeof(int32_t) * subbandWidth; + int32_t paramLength = 2 * subbandWidth + 4; + uint8_t *paramBuf = 0; + paramBuf = (uint8_t *) +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr. +#endif + calloc(1, sizeof(CrxBandParam) + sizeof(int32_t) * paramLength + progrDataSize); + + if (!paramBuf) + return -1; + + *param = (CrxBandParam *)paramBuf; + + paramBuf += sizeof(CrxBandParam); + + (*param)->paramData = (int32_t *)paramBuf; + (*param)->nonProgrData = progrDataSize ? (*param)->paramData + paramLength : 0; + (*param)->subbandWidth = subbandWidth; + (*param)->subbandHeight = subbandHeight; + (*param)->roundedBits = 0; + (*param)->curLine = 0; + (*param)->roundedBitsMask = roundedBitsMask; + (*param)->supportsPartial = supportsPartial; + (*param)->bitStream.bitData = 0; + (*param)->bitStream.bitsLeft = 0; + (*param)->bitStream.mdatSize = subbandDataSize; + (*param)->bitStream.curPos = 0; + (*param)->bitStream.curBufSize = 0; + (*param)->bitStream.curBufOffset = subbandMdatOffset; + (*param)->bitStream.input = img->input; + + crxFillBuffer(&(*param)->bitStream); + + return 0; +} + +int crxSetupSubbandData(CrxImage *img, CrxPlaneComp *planeComp, const CrxTile *tile, uint32_t mdatOffset) +{ + long compDataSize = 0; + long waveletDataOffset = 0; + long compCoeffDataOffset = 0; + int32_t toSubbands = 3 * img->levels + 1; + int32_t transformWidth = 0; + + CrxSubband *subbands = planeComp->subBands; + + // calculate sizes + for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) + { + subbands[subbandNum].bandSize = subbands[subbandNum].width * sizeof(int32_t); // 4bytes + compDataSize += subbands[subbandNum].bandSize; + } + + if (img->levels) + { + int32_t encLevels = img->levels ? img->levels : 1; + waveletDataOffset = (compDataSize + 7) & ~7; + compDataSize = (sizeof(CrxWaveletTransform) * encLevels + waveletDataOffset + 7) & ~7; + compCoeffDataOffset = compDataSize; + + // calc wavelet line buffer sizes (always at one level up from current) + for (int level = 0; level < img->levels; ++level) + if (level < img->levels - 1) + compDataSize += 8 * sizeof(int32_t) * planeComp->subBands[3 * (level + 1) + 2].width; + else + compDataSize += 8 * sizeof(int32_t) * tile->width; + } + // buffer allocation + planeComp->compBuf = (uint8_t *) +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr. +#endif + malloc(compDataSize); + if (!planeComp->compBuf) + return -1; + + // subbands buffer and sizes initialisation + uint64_t subbandMdatOffset = img->mdatOffset + mdatOffset; + uint8_t *subbandBuf = planeComp->compBuf; + + for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) + { + subbands[subbandNum].bandBuf = subbandBuf; + subbandBuf += subbands[subbandNum].bandSize; + subbands[subbandNum].mdatOffset = subbandMdatOffset + subbands[subbandNum].dataOffset; + } + + // wavelet data initialisation + if (img->levels) + { + CrxWaveletTransform *waveletTransforms = (CrxWaveletTransform *)(planeComp->compBuf + waveletDataOffset); + int32_t *paramData = (int32_t *)(planeComp->compBuf + compCoeffDataOffset); + + planeComp->wvltTransform = waveletTransforms; + waveletTransforms[0].subband0Buf = (int32_t *)subbands->bandBuf; + + for (int level = 0; level < img->levels; ++level) + { + int32_t band = 3 * level + 1; + + if (level >= img->levels - 1) + { + waveletTransforms[level].height = tile->height; + transformWidth = tile->width; + } + else + { + waveletTransforms[level].height = subbands[band + 3].height; + transformWidth = subbands[band + 4].width; + } + waveletTransforms[level].width = transformWidth; + waveletTransforms[level].lineBuf[0] = paramData; + waveletTransforms[level].lineBuf[1] = waveletTransforms[level].lineBuf[0] + transformWidth; + waveletTransforms[level].lineBuf[2] = waveletTransforms[level].lineBuf[1] + transformWidth; + waveletTransforms[level].lineBuf[3] = waveletTransforms[level].lineBuf[2] + transformWidth; + waveletTransforms[level].lineBuf[4] = waveletTransforms[level].lineBuf[3] + transformWidth; + waveletTransforms[level].lineBuf[5] = waveletTransforms[level].lineBuf[4] + transformWidth; + waveletTransforms[level].lineBuf[6] = waveletTransforms[level].lineBuf[5] + transformWidth; + waveletTransforms[level].lineBuf[7] = waveletTransforms[level].lineBuf[6] + transformWidth; + waveletTransforms[level].curLine = 0; + waveletTransforms[level].curH = 0; + waveletTransforms[level].fltTapH = 0; + waveletTransforms[level].subband1Buf = (int32_t *)subbands[band].bandBuf; + waveletTransforms[level].subband2Buf = (int32_t *)subbands[band + 1].bandBuf; + waveletTransforms[level].subband3Buf = (int32_t *)subbands[band + 2].bandBuf; + + paramData = waveletTransforms[level].lineBuf[7] + transformWidth; + } + } + + // decoding params and bitstream initialisation + for (int32_t subbandNum = 0; subbandNum < toSubbands; subbandNum++) + { + if (subbands[subbandNum].dataSize) + { + bool supportsPartial = false; + uint32_t roundedBitsMask = 0; + + if (planeComp->supportsPartial && subbandNum == 0) + { + roundedBitsMask = planeComp->roundedBitsMask; + supportsPartial = true; + } + if (crxParamInit(img, &subbands[subbandNum].bandParam, subbands[subbandNum].mdatOffset, + subbands[subbandNum].dataSize, subbands[subbandNum].width, subbands[subbandNum].height, + supportsPartial, roundedBitsMask)) + return -1; + } + } + + return 0; +} + +int LibRaw::crxDecodePlane(void *p, uint32_t planeNumber) +{ + CrxImage *img = (CrxImage *)p; + int imageRow = 0; + for (int tRow = 0; tRow < img->tileRows; tRow++) + { + int imageCol = 0; + for (int tCol = 0; tCol < img->tileCols; tCol++) + { + CrxTile *tile = img->tiles + tRow * img->tileCols + tCol; + CrxPlaneComp *planeComp = tile->comps + planeNumber; + uint64_t tileMdatOffset = tile->dataOffset + tile->mdatQPDataSize + tile->mdatExtraSize + planeComp->dataOffset; + + // decode single tile + if (crxSetupSubbandData(img, planeComp, tile, tileMdatOffset)) + return -1; + + if (img->levels) + { + if (crxIdwt53FilterInitialize(planeComp, img->levels, tile->qStep)) + return -1; + for (int i = 0; i < tile->height; ++i) + { + if (crxIdwt53FilterDecode(planeComp, img->levels - 1, tile->qStep) || + crxIdwt53FilterTransform(planeComp, img->levels - 1)) + return -1; + int32_t *lineData = crxIdwt53FilterGetLine(planeComp, img->levels - 1); + crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); + } + } + else + { + // we have the only subband in this case + if (!planeComp->subBands->dataSize) + { + memset(planeComp->subBands->bandBuf, 0, planeComp->subBands->bandSize); + return 0; + } + + for (int i = 0; i < tile->height; ++i) + { + if (crxDecodeLine(planeComp->subBands->bandParam, planeComp->subBands->bandBuf)) + return -1; + int32_t *lineData = (int32_t *)planeComp->subBands->bandBuf; + crxConvertPlaneLine(img, imageRow + i, imageCol, planeNumber, lineData, tile->width); + } + } + imageCol += tile->width; + } + imageRow += img->tiles[tRow * img->tileCols].height; + } + + return 0; +} + +uint32_t crxReadQP(CrxBitstream *bitStrm, int32_t kParam) +{ + uint32_t qp = crxBitstreamGetZeros(bitStrm); + if (qp >= 23) + qp = crxBitstreamGetBits(bitStrm, 8); + else if (kParam) + qp = crxBitstreamGetBits(bitStrm, kParam) | (qp << kParam); + + return qp; +} + +void crxDecodeGolombTop(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf, int32_t *kParam) +{ + lineBuf[0] = 0; + while (width-- > 0) + { + lineBuf[1] = lineBuf[0]; + uint32_t qp = crxReadQP(bitStrm, *kParam); + lineBuf[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1); + *kParam = crxPredictKParameter(*kParam, qp, 7); + ++lineBuf; + } + lineBuf[1] = lineBuf[0] + 1; +} + +void crxDecodeGolombNormal(CrxBitstream *bitStrm, int32_t width, int32_t *lineBuf0, int32_t *lineBuf1, int32_t *kParam) +{ + lineBuf1[0] = lineBuf0[1]; + int32_t deltaH = lineBuf0[1] - lineBuf0[0]; + while (width-- > 0) + { + lineBuf1[1] = crxPrediction(lineBuf1[0], lineBuf0[1], deltaH, lineBuf0[0] - lineBuf1[0]); + uint32_t qp = crxReadQP(bitStrm, *kParam); + lineBuf1[1] += -(int32_t)(qp & 1) ^ (int32_t)(qp >> 1); + if (width) + { + deltaH = lineBuf0[2] - lineBuf0[1]; + *kParam = crxPredictKParameter(*kParam, (qp + 2 * _abs(deltaH)) >> 1, 7); + ++lineBuf0; + } + else + *kParam = crxPredictKParameter(*kParam, qp, 7); + ++lineBuf1; + } + lineBuf1[1] = lineBuf1[0] + 1; +} + +int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*totalQP*/) +{ + if (img->levels > 3 || img->levels < 1) + return -1; + int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0); + int qpHeight = (tile->height >> 1) + (tile->height & 1); + int qpHeight4 = (tile->height >> 2) + ((tile->height & 3) != 0); + int qpHeight8 = (tile->height >> 3) + ((tile->height & 7) != 0); + uint32_t totalHeight = qpHeight; + if (img->levels > 1) + totalHeight += qpHeight4; + if (img->levels > 2) + totalHeight += qpHeight8; + tile->qStep = (CrxQStep *) +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr. +#endif + malloc(totalHeight * qpWidth * sizeof(uint32_t) + img->levels * sizeof(CrxQStep)); + + if (!tile->qStep) + return -1; + uint32_t *qStepTbl = (uint32_t *)(tile->qStep + img->levels); + CrxQStep *qStep = tile->qStep; + switch (img->levels) + { + case 3: + qStep->qStepTbl = qStepTbl; + qStep->width = qpWidth; + qStep->height = qpHeight8; + for (int qpRow = 0; qpRow < qpHeight8; ++qpRow) + { + int row0Idx = qpWidth * _min(4 * qpRow, qpHeight - 1); + int row1Idx = qpWidth * _min(4 * qpRow + 1, qpHeight - 1); + int row2Idx = qpWidth * _min(4 * qpRow + 2, qpHeight - 1); + int row3Idx = qpWidth * _min(4 * qpRow + 3, qpHeight - 1); + + for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl) + { + int32_t quantVal = qpTable[row0Idx++] + qpTable[row1Idx++] + qpTable[row2Idx++] + qpTable[row3Idx++]; + // not sure about this nonsense - why is it not just avg like with 2 levels? + quantVal = ((quantVal < 0) * 3 + quantVal) >> 2; + if (quantVal / 6 >= 6) + *qStepTbl = q_step_tbl[quantVal % 6] * (1 << (quantVal / 6 + 26)); + else + *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); + } + } + // continue to the next level - we always decode all levels + ++qStep; + case 2: + qStep->qStepTbl = qStepTbl; + qStep->width = qpWidth; + qStep->height = qpHeight4; + for (int qpRow = 0; qpRow < qpHeight4; ++qpRow) + { + int row0Idx = qpWidth * _min(2 * qpRow, qpHeight - 1); + int row1Idx = qpWidth * _min(2 * qpRow + 1, qpHeight - 1); + + for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl) + { + int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2; + if (quantVal / 6 >= 6) + *qStepTbl = q_step_tbl[quantVal % 6] * (1 << (quantVal / 6 + 26)); + else + *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); + } + } + // continue to the next level - we always decode all levels + ++qStep; + case 1: + qStep->qStepTbl = qStepTbl; + qStep->width = qpWidth; + qStep->height = qpHeight; + for (int qpRow = 0; qpRow < qpHeight; ++qpRow) + for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable) + if (*qpTable / 6 >= 6) + *qStepTbl = q_step_tbl[*qpTable % 6] * (1 << (*qpTable / 6 + 26)); + else + *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6); + + break; + } + return 0; +} + +libraw_inline void crxSetupSubbandIdx(crx_data_header_t *hdr, CrxImage * /*img*/, CrxSubband *band, int level, + short colStartIdx, short bandWidthExCoef, short rowStartIdx, + short bandHeightExCoef) +{ + if (hdr->version == 0x200) + { + band->rowStartAddOn = rowStartIdx; + band->rowEndAddOn = bandHeightExCoef; + band->colStartAddOn = colStartIdx; + band->colEndAddOn = bandWidthExCoef; + band->levelShift = 3 - level; + } + else + { + band->rowStartAddOn = 0; + band->rowEndAddOn = 0; + band->colStartAddOn = 0; + band->colEndAddOn = 0; + band->levelShift = 0; + } +} + +int crxProcessSubbands(crx_data_header_t *hdr, CrxImage *img, CrxTile *tile, CrxPlaneComp *comp) +{ + CrxSubband *band = comp->subBands + img->subbandCount - 1; // set to last band + uint32_t bandHeight = tile->height; + uint32_t bandWidth = tile->width; + int32_t bandWidthExCoef = 0; + int32_t bandHeightExCoef = 0; + if (img->levels) + { + // Build up subband sequences to crxDecode to a level in a header + + // Coefficient structure is a bit unclear and convoluted: + // 3 levels max - 8 groups (for tile width rounded to 8 bytes) + // of 3 band per level 4 sets of coefficients for each + int32_t *rowExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->width & 7); + int32_t *colExCoef = exCoefNumTbl + 0x30 * (img->levels - 1) + 6 * (tile->height & 7); + for (int level = 0; level < img->levels; ++level) + { + int32_t widthOddPixel = bandWidth & 1; + int32_t heightOddPixel = bandHeight & 1; + bandWidth = (widthOddPixel + bandWidth) >> 1; + bandHeight = (heightOddPixel + bandHeight) >> 1; + + int32_t bandWidthExCoef0 = 0; + int32_t bandWidthExCoef1 = 0; + int32_t bandHeightExCoef0 = 0; + int32_t bandHeightExCoef1 = 0; + int32_t colStartIdx = 0; + int32_t rowStartIdx = 0; + if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + { + bandWidthExCoef0 = rowExCoef[2 * level]; + bandWidthExCoef1 = rowExCoef[2 * level + 1]; + } + if (tile->tileFlag & E_HAS_TILES_ON_THE_LEFT) + { + ++bandWidthExCoef0; + colStartIdx = 1; + } + + if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) + { + bandHeightExCoef0 = colExCoef[2 * level]; + bandHeightExCoef1 = colExCoef[2 * level + 1]; + } + if (tile->tileFlag & E_HAS_TILES_ON_THE_TOP) + { + ++bandHeightExCoef0; + rowStartIdx = 1; + } + + band[0].width = bandWidth + bandWidthExCoef0 - widthOddPixel; + band[0].height = bandHeight + bandHeightExCoef0 - heightOddPixel; + crxSetupSubbandIdx(hdr, img, band, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, rowStartIdx, + bandHeightExCoef0 - rowStartIdx); + + band[-1].width = bandWidth + bandWidthExCoef1; + band[-1].height = bandHeight + bandHeightExCoef0 - heightOddPixel; + + crxSetupSubbandIdx(hdr, img, band - 1, level + 1, 0, bandWidthExCoef1, rowStartIdx, + bandHeightExCoef0 - rowStartIdx); + + band[-2].width = bandWidth + bandWidthExCoef0 - widthOddPixel; + band[-2].height = bandHeight + bandHeightExCoef1; + crxSetupSubbandIdx(hdr, img, band - 2, level + 1, colStartIdx, bandWidthExCoef0 - colStartIdx, 0, + bandHeightExCoef1); + + band -= 3; + } + bandWidthExCoef = bandHeightExCoef = 0; + if (tile->tileFlag & E_HAS_TILES_ON_THE_RIGHT) + bandWidthExCoef = rowExCoef[2 * img->levels - 1]; + if (tile->tileFlag & E_HAS_TILES_ON_THE_BOTTOM) + bandHeightExCoef = colExCoef[2 * img->levels - 1]; + } + band->width = bandWidthExCoef + bandWidth; + band->height = bandHeightExCoef + bandHeight; + if (img->levels) + crxSetupSubbandIdx(hdr, img, band, img->levels, 0, bandWidthExCoef, 0, bandHeightExCoef); + + return 0; +} + +int crxReadSubbandHeaders(crx_data_header_t * /*hdr*/, CrxImage *img, CrxTile * /*tile*/, CrxPlaneComp *comp, + uint8_t **subbandMdatPtr, int32_t *mdatSize) +{ + if (!img->subbandCount) + return 0; + int32_t subbandOffset = 0; + CrxSubband *band = comp->subBands; + for (int curSubband = 0; curSubband < img->subbandCount; curSubband++, band++) + { + if (*mdatSize < 4) + return -1; + + int hdrSign = LibRaw::sgetn(2, *subbandMdatPtr); + int hdrSize = LibRaw::sgetn(2, *subbandMdatPtr + 2); + if (*mdatSize < hdrSize + 4) + return -1; + if ((hdrSign != 0xFF03 || hdrSize != 8) && (hdrSign != 0xFF13 || hdrSize != 16)) + return -1; + + int32_t subbandSize = LibRaw::sgetn(4, *subbandMdatPtr + 4); + + if (curSubband != ((*subbandMdatPtr)[8] & 0xF0) >> 4) + { + band->dataSize = subbandSize; + return -1; + } + + band->dataOffset = subbandOffset; + band->kParam = 0; + band->bandParam = 0; + band->bandBuf = 0; + band->bandSize = 0; + + if (hdrSign == 0xFF03) + { + // old header + uint32_t bitData = LibRaw::sgetn(4, *subbandMdatPtr + 8); + band->dataSize = subbandSize - (bitData & 0x7FFFF); + band->supportsPartial = bitData & 0x8000000; + band->qParam = (bitData >> 19) & 0xFF; + band->qStepBase = 0; + band->qStepMult = 0; + } + else + { + // new header + if (LibRaw::sgetn(2, *subbandMdatPtr + 8) & 0xFFF) + // partial and qParam are not supported + return -1; + if (LibRaw::sgetn(2, *subbandMdatPtr + 18)) + // new header terninated by 2 zero bytes + return -1; + band->supportsPartial = false; + band->qParam = 0; + band->dataSize = subbandSize - LibRaw::sgetn(2, *subbandMdatPtr + 16); + band->qStepBase = LibRaw::sgetn(4, *subbandMdatPtr + 12); + ; + band->qStepMult = LibRaw::sgetn(2, *subbandMdatPtr + 10); + ; + } + + subbandOffset += subbandSize; + + *subbandMdatPtr += hdrSize + 4; + *mdatSize -= hdrSize + 4; + } + + return 0; +} + +int crxReadImageHeaders(crx_data_header_t *hdr, CrxImage *img, uint8_t *mdatPtr, int32_t mdatHdrSize) +{ + int nTiles = img->tileRows * img->tileCols; + + if (!nTiles) + return -1; + + if (!img->tiles) + { + img->tiles = (CrxTile *) +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr. +#endif + calloc(sizeof(CrxTile) * nTiles + sizeof(CrxPlaneComp) * nTiles * img->nPlanes + + sizeof(CrxSubband) * nTiles * img->nPlanes * img->subbandCount, + 1); + if (!img->tiles) + return -1; + + // memory areas in allocated chunk + CrxTile *tile = img->tiles; + CrxPlaneComp *comps = (CrxPlaneComp *)(tile + nTiles); + CrxSubband *bands = (CrxSubband *)(comps + img->nPlanes * nTiles); + + for (int curTile = 0; curTile < nTiles; curTile++, tile++) + { + tile->tileFlag = 0; // tile neighbouring flags + tile->tileNumber = curTile; + tile->tileSize = 0; + tile->comps = comps + curTile * img->nPlanes; + + if ((curTile + 1) % img->tileCols) + { + // not the last tile in a tile row + tile->width = hdr->tileWidth; + if (img->tileCols > 1) + { + tile->tileFlag = E_HAS_TILES_ON_THE_RIGHT; + if (curTile % img->tileCols) + // not the first tile in tile row + tile->tileFlag |= E_HAS_TILES_ON_THE_LEFT; + } + } + else + { + // last tile in a tile row + tile->width = img->planeWidth - hdr->tileWidth * (img->tileCols - 1); + if (img->tileCols > 1) + tile->tileFlag = E_HAS_TILES_ON_THE_LEFT; + } + if (curTile < nTiles - img->tileCols) + { + // in first tile row + tile->height = hdr->tileHeight; + if (img->tileRows > 1) + { + tile->tileFlag |= E_HAS_TILES_ON_THE_BOTTOM; + if (curTile >= img->tileCols) + tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; + } + } + else + { + // non first tile row + tile->height = img->planeHeight - hdr->tileHeight * (img->tileRows - 1); + if (img->tileRows > 1) + tile->tileFlag |= E_HAS_TILES_ON_THE_TOP; + } + if (img->nPlanes) + { + CrxPlaneComp *comp = tile->comps; + CrxSubband *band = bands + curTile * img->nPlanes * img->subbandCount; + + for (int curComp = 0; curComp < img->nPlanes; curComp++, comp++) + { + comp->compNumber = curComp; + comp->supportsPartial = true; + comp->tileFlag = tile->tileFlag; + comp->subBands = band; + comp->compBuf = 0; + comp->wvltTransform = 0; + if (img->subbandCount) + { + for (int curBand = 0; curBand < img->subbandCount; curBand++, band++) + { + band->supportsPartial = false; + band->qParam = 4; + band->bandParam = 0; + band->dataSize = 0; + } + } + } + } + } + } + + uint32_t tileOffset = 0; + int32_t dataSize = mdatHdrSize; + uint8_t *dataPtr = mdatPtr; + CrxTile *tile = img->tiles; + + for (int curTile = 0; curTile < nTiles; ++curTile, ++tile) + { + if (dataSize < 4) + return -1; + + int hdrSign = LibRaw::sgetn(2, dataPtr); + int hdrSize = LibRaw::sgetn(2, dataPtr + 2); + if ((hdrSign != 0xFF01 || hdrSize != 8) && (hdrSign != 0xFF11 || (hdrSize != 8 && hdrSize != 16))) + return -1; + if (dataSize < hdrSize + 4) + return -1; + int tailSign = LibRaw::sgetn(2, dataPtr + 10); + if ((hdrSize == 8 && tailSign) || (hdrSize == 16 && tailSign != 0x4000)) + return -1; + if (LibRaw::sgetn(2, dataPtr + 8) != (unsigned)curTile) + return -1; + + dataSize -= hdrSize + 4; + + tile->tileSize = LibRaw::sgetn(4, dataPtr + 4); + tile->dataOffset = tileOffset; + tile->qStep = 0; + if (hdrSize == 16) + { + // extended header data - terminated by 0 bytes + if (LibRaw::sgetn(2, dataPtr + 18) != 0) + return -1; + tile->hasQPData = true; + tile->mdatQPDataSize = LibRaw::sgetn(4, dataPtr + 12); + tile->mdatExtraSize = LibRaw::sgetn(2, dataPtr + 16); + } + else + { + tile->hasQPData = false; + tile->mdatQPDataSize = 0; + tile->mdatExtraSize = 0; + } + + dataPtr += hdrSize + 4; + tileOffset += tile->tileSize; + + uint32_t compOffset = 0; + CrxPlaneComp *comp = tile->comps; + + for (int compNum = 0; compNum < img->nPlanes; ++compNum, ++comp) + { + if (dataSize < 0xC) + return -1; + hdrSign = LibRaw::sgetn(2, dataPtr); + hdrSize = LibRaw::sgetn(2, dataPtr + 2); + if ((hdrSign != 0xFF02 && hdrSign != 0xFF12) || hdrSize != 8) + return -1; + if (compNum != dataPtr[8] >> 4) + return -1; + if (LibRaw::sgetn(3, dataPtr + 9) != 0) + return -1; + + comp->compSize = LibRaw::sgetn(4, dataPtr + 4); + + int32_t compHdrRoundedBits = (dataPtr[8] >> 1) & 3; + comp->supportsPartial = (dataPtr[8] & 8) != 0; + + comp->dataOffset = compOffset; + comp->tileFlag = tile->tileFlag; + + compOffset += comp->compSize; + dataSize -= 0xC; + dataPtr += 0xC; + + comp->roundedBitsMask = 0; + + if (compHdrRoundedBits) + { + if (img->levels || !comp->supportsPartial) + return -1; + + comp->roundedBitsMask = 1 << (compHdrRoundedBits - 1); + } + + if (crxReadSubbandHeaders(hdr, img, tile, comp, &dataPtr, &dataSize) || crxProcessSubbands(hdr, img, tile, comp)) + return -1; + } + } + + if (hdr->version != 0x200) + return 0; + + tile = img->tiles; + for (int curTile = 0; curTile < nTiles; ++curTile, ++tile) + { + if (tile->hasQPData) + { + CrxBitstream bitStrm; + bitStrm.bitData = 0; + bitStrm.bitsLeft = 0; + bitStrm.curPos = 0; + bitStrm.curBufSize = 0; + bitStrm.mdatSize = tile->mdatQPDataSize; + bitStrm.curBufOffset = img->mdatOffset + tile->dataOffset; + bitStrm.input = img->input; + + crxFillBuffer(&bitStrm); + + unsigned int qpWidth = (tile->width >> 3) + ((tile->width & 7) != 0); + unsigned int qpHeight = (tile->height >> 1) + (tile->height & 1); + unsigned long totalQP = qpHeight * qpWidth; + + try + { + std::vector qpTable(totalQP + 2 * (qpWidth + 2)); + int32_t *qpCurElem = qpTable.data(); + // 2 lines padded with extra pixels at the start and at the end + int32_t *qpLineBuf = qpTable.data() + totalQP; + int32_t kParam = 0; + for (unsigned qpRow = 0; qpRow < qpHeight; ++qpRow) + { + int32_t *qpLine0 = qpRow & 1 ? qpLineBuf + qpWidth + 2 : qpLineBuf; + int32_t *qpLine1 = qpRow & 1 ? qpLineBuf : qpLineBuf + qpWidth + 2; + + if (qpRow) + crxDecodeGolombNormal(&bitStrm, qpWidth, qpLine0, qpLine1, &kParam); + else + crxDecodeGolombTop(&bitStrm, qpWidth, qpLine1, &kParam); + + for (unsigned qpCol = 0; qpCol < qpWidth; ++qpCol) + *qpCurElem++ = qpLine1[qpCol + 1] + 4; + } + + // now we read QP data - build tile QStep + if (crxMakeQStep(img, tile, qpTable.data(), totalQP)) + return -1; + } + catch (...) + { + return -1; + } + } + } + + return 0; +} + +int crxSetupImageData(crx_data_header_t *hdr, CrxImage *img, int16_t *outBuf, uint64_t mdatOffset, uint32_t mdatSize, + uint8_t *mdatHdrPtr, int32_t mdatHdrSize) +{ + int IncrBitTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0}; + + img->planeWidth = hdr->f_width; + img->planeHeight = hdr->f_height; + + if (hdr->tileWidth < 0x16 || hdr->tileHeight < 0x16 || img->planeWidth > 0x7FFF || img->planeHeight > 0x7FFF) + return -1; + + img->tileCols = (img->planeWidth + hdr->tileWidth - 1) / hdr->tileWidth; + img->tileRows = (img->planeHeight + hdr->tileHeight - 1) / hdr->tileHeight; + + if (img->tileCols > 0xFF || img->tileRows > 0xFF || img->planeWidth - hdr->tileWidth * (img->tileCols - 1) < 0x16 || + img->planeHeight - hdr->tileHeight * (img->tileRows - 1) < 0x16) + return -1; + + img->tiles = 0; + img->levels = hdr->imageLevels; + img->subbandCount = 3 * img->levels + 1; // 3 bands per level + one last LL + img->nPlanes = hdr->nPlanes; + img->nBits = hdr->nBits; + img->encType = hdr->encType; + img->samplePrecision = hdr->nBits + IncrBitTable[4 * hdr->encType + 2] + 1; + img->mdatOffset = mdatOffset + hdr->mdatHdrSize; + img->mdatSize = mdatSize; + img->planeBuf = 0; + img->outBufs[0] = img->outBufs[1] = img->outBufs[2] = img->outBufs[3] = 0; + img->medianBits = hdr->medianBits; + + // The encoding type 3 needs all 4 planes to be decoded to generate row of + // RGGB values. It seems to be using some other colour space for raw encoding + // It is a massive buffer so ideallly it will need a different approach: + // decode planes line by line and convert single line then without + // intermediate plane buffer. At the moment though it's too many changes so + // left as is. + if (img->encType == 3 && img->nPlanes == 4 && img->nBits > 8) + { + img->planeBuf = (int16_t *) +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr. +#endif + malloc(img->planeHeight * img->planeWidth * img->nPlanes * ((img->samplePrecision + 7) >> 3)); + if (!img->planeBuf) + return -1; + } + + int32_t rowSize = 2 * img->planeWidth; + + if (img->nPlanes == 1) + img->outBufs[0] = outBuf; + else + switch (hdr->cfaLayout) + { + case 0: + // R G + // G B + img->outBufs[0] = outBuf; + img->outBufs[1] = outBuf + 1; + img->outBufs[2] = outBuf + rowSize; + img->outBufs[3] = img->outBufs[2] + 1; + break; + case 1: + // G R + // B G + img->outBufs[1] = outBuf; + img->outBufs[0] = outBuf + 1; + img->outBufs[3] = outBuf + rowSize; + img->outBufs[2] = img->outBufs[3] + 1; + break; + case 2: + // G B + // R G + img->outBufs[2] = outBuf; + img->outBufs[3] = outBuf + 1; + img->outBufs[0] = outBuf + rowSize; + img->outBufs[1] = img->outBufs[0] + 1; + break; + case 3: + // B G + // G R + img->outBufs[3] = outBuf; + img->outBufs[2] = outBuf + 1; + img->outBufs[1] = outBuf + rowSize; + img->outBufs[0] = img->outBufs[1] + 1; + break; + } + + // read header + return crxReadImageHeaders(hdr, img, mdatHdrPtr, mdatHdrSize); +} + +int crxFreeImageData(CrxImage *img) +{ +#ifdef LIBRAW_CR3_MEMPOOL + img->memmgr.cleanup(); +#else + CrxTile *tile = img->tiles; + int nTiles = img->tileRows * img->tileCols; + + if (img->tiles) + { + for (int32_t curTile = 0; curTile < nTiles; curTile++) + { + if (tile[curTile].comps) + for (int32_t curPlane = 0; curPlane < img->nPlanes; curPlane++) + crxFreeSubbandData(img, tile[curTile].comps + curPlane); + if (tile[curTile].qStep) + free(tile[curTile].qStep); + } + free(img->tiles); + img->tiles = 0; + } + + if (img->planeBuf) + { + free(img->planeBuf); + img->planeBuf = 0; + } +#endif + return 0; +} +void LibRaw::crxLoadDecodeLoop(void *img, int nPlanes) +{ +#ifdef LIBRAW_USE_OPENMP + int results[4] ={0,0,0,0}; // nPlanes is always <= 4 +#pragma omp parallel for + for (int32_t plane = 0; plane < nPlanes; ++plane) + try { + results[plane] = crxDecodePlane(img, plane); + } catch (...) { + results[plane] = 1; + } + + for (int32_t plane = 0; plane < nPlanes; ++plane) + if (results[plane]) + derror(); +#else + for (int32_t plane = 0; plane < nPlanes; ++plane) + if (crxDecodePlane(img, plane)) + derror(); +#endif +} + +void LibRaw::crxConvertPlaneLineDf(void *p, int imageRow) { crxConvertPlaneLine((CrxImage *)p, imageRow); } + +void LibRaw::crxLoadFinalizeLoopE3(void *p, int planeHeight) +{ +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for +#endif + for (int i = 0; i < planeHeight; ++i) + crxConvertPlaneLineDf(p, i); +} + +void LibRaw::crxLoadRaw() +{ + CrxImage img; + if (libraw_internal_data.unpacker_data.crx_track_selected < 0 || + libraw_internal_data.unpacker_data.crx_track_selected >= LIBRAW_CRXTRACKS_MAXCOUNT) + derror(); + + crx_data_header_t hdr = + libraw_internal_data.unpacker_data.crx_header[libraw_internal_data.unpacker_data.crx_track_selected]; + + if (libraw_internal_data.unpacker_data.data_size < (unsigned)hdr.mdatHdrSize) + derror(); + + img.input = libraw_internal_data.internal_data.input; + + // update sizes for the planes + if (hdr.nPlanes == 4) + { + hdr.f_width >>= 1; + hdr.f_height >>= 1; + hdr.tileWidth >>= 1; + hdr.tileHeight >>= 1; + } + + imgdata.color.maximum = (1 << hdr.nBits) - 1; + + std::vector hdrBuf(hdr.mdatHdrSize); + + unsigned bytes = 0; + // read image header +#ifdef LIBRAW_USE_OPENMP +#pragma omp critical +#endif + { +#ifndef LIBRAW_USE_OPENMP + libraw_internal_data.internal_data.input->lock(); +#endif + libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); + bytes = libraw_internal_data.internal_data.input->read(hdrBuf.data(), 1, hdr.mdatHdrSize); +#ifndef LIBRAW_USE_OPENMP + libraw_internal_data.internal_data.input->unlock(); +#endif + } + + if (bytes != hdr.mdatHdrSize) + throw LIBRAW_EXCEPTION_IO_EOF; + + // parse and setup the image data + if (crxSetupImageData(&hdr, &img, (int16_t *)imgdata.rawdata.raw_image, + libraw_internal_data.unpacker_data.data_offset, libraw_internal_data.unpacker_data.data_size, + hdrBuf.data(), hdr.mdatHdrSize)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + crxLoadDecodeLoop(&img, hdr.nPlanes); + + if (img.encType == 3) + crxLoadFinalizeLoopE3(&img, img.planeHeight); + + crxFreeImageData(&img); +} + +int LibRaw::crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size) +{ + if (nTrack < 0 || nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT) + return -1; + if (!cmp1TagData) + return -1; + + crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[nTrack]; + + hdr->version = sgetn(2, cmp1TagData + 4); + hdr->f_width = sgetn(4, cmp1TagData + 8); + hdr->f_height = sgetn(4, cmp1TagData + 12); + hdr->tileWidth = sgetn(4, cmp1TagData + 16); + hdr->tileHeight = sgetn(4, cmp1TagData + 20); + hdr->nBits = cmp1TagData[24]; + hdr->nPlanes = cmp1TagData[25] >> 4; + hdr->cfaLayout = cmp1TagData[25] & 0xF; + hdr->encType = cmp1TagData[26] >> 4; + hdr->imageLevels = cmp1TagData[26] & 0xF; + hdr->hasTileCols = cmp1TagData[27] >> 7; + hdr->hasTileRows = (cmp1TagData[27] >> 6) & 1; + hdr->mdatHdrSize = sgetn(4, cmp1TagData + 28); + int extHeader = cmp1TagData[32] >> 7; + int useMedianBits = 0; + hdr->medianBits = hdr->nBits; + + if (extHeader && size >= 56 && hdr->nPlanes == 4) + useMedianBits = cmp1TagData[56] >> 6 & 1; + + if (useMedianBits && size >= 84) + hdr->medianBits = cmp1TagData[84]; + + // validation + if ((hdr->version != 0x100 && hdr->version != 0x200) || !hdr->mdatHdrSize) + return -1; + if (hdr->encType == 1) + { + if (hdr->nBits > 15) + return -1; + } + else + { + if (hdr->encType && hdr->encType != 3) + return -1; + if (hdr->nBits > 14) + return -1; + } + + if (hdr->nPlanes == 1) + { + if (hdr->cfaLayout || hdr->encType || hdr->nBits != 8) + return -1; + } + else if (hdr->nPlanes != 4 || hdr->f_width & 1 || hdr->f_height & 1 || hdr->tileWidth & 1 || hdr->tileHeight & 1 || + hdr->cfaLayout > 3 || hdr->nBits == 8) + return -1; + + if (hdr->tileWidth > hdr->f_width || hdr->tileHeight > hdr->f_height) + return -1; + + if (hdr->imageLevels > 3 || hdr->hasTileCols > 1 || hdr->hasTileRows > 1) + return -1; + return 0; +} + +#undef _abs +#undef _min +#undef _constrain +#undef libraw_inline diff --git a/src/decoders/decoders_dcraw.cpp b/src/decoders/decoders_dcraw.cpp new file mode 100644 index 000000000..721d38577 --- /dev/null +++ b/src/decoders/decoders_dcraw.cpp @@ -0,0 +1,1799 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +unsigned LibRaw::getbithuff(int nbits, ushort *huff) +{ +#ifdef LIBRAW_NOTHREADS + static unsigned bitbuf = 0; + static int vbits = 0, reset = 0; +#else +#define bitbuf tls->getbits.bitbuf +#define vbits tls->getbits.vbits +#define reset tls->getbits.reset +#endif + unsigned c; + + if (nbits > 25) + return 0; + if (nbits < 0) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) + return 0; + while (!reset && vbits < nbits && (c = fgetc(ifp)) != (unsigned)EOF && + !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) + { + bitbuf = (bitbuf << 8) + (uchar)c; + vbits += 8; + } + c = vbits == 0 ? 0 : bitbuf << (32 - vbits) >> (32 - nbits); + if (huff) + { + vbits -= huff[c] >> 8; + c = (uchar)huff[c]; + } + else + vbits -= nbits; + if (vbits < 0) + derror(); + return c; +#ifndef LIBRAW_NOTHREADS +#undef bitbuf +#undef vbits +#undef reset +#endif +} + +/* + 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 *LibRaw::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); + 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 *LibRaw::make_decoder(const uchar *source) +{ + return make_decoder_ref(&source); +} + +void LibRaw::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 LibRaw::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 < int(sizeof test - 1); i++) + if (test[i] == 0xff) + { + if (test[i + 1]) + return 1; + ret = 0; + } + return ret; +} + +void LibRaw::canon_load_raw() +{ + ushort *pixel, *prow, *huff[2]; + int nblocks, lowbits, i, c, row, r, val; + INT64 save; + 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); + try + { + for (row = 0; row < raw_height; row += 8) + { + checkCancel(); + 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); + } + } + } + catch (...) + { + FORC(2) free(huff[c]); + throw; + } + FORC(2) free(huff[c]); +} + +int LibRaw::ljpeg_start(struct jhead *jh, int info_only) +{ + ushort c, tag, len; + int cnt = 0; + std::vector data_buffer(0x10000); + uchar* data = &data_buffer[0]; + const uchar *dp; + + memset(jh, 0, sizeof *jh); + jh->restart = INT_MAX; + if (fread(data, 2, 1, ifp) != 1 || data[1] != 0xd8) + return 0; + do + { + if (feof(ifp)) + return 0; + if (cnt++ > 1024) + return 0; // 1024 tags limit + if (fread(data, 2, 2, ifp) != 2) + return 0; + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) + return 0; + if (fread(data, 1, len, ifp) != len) + return 0; + switch (tag) + { + case 0xffc3: // start of frame; lossless, Huffman + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc1: + case 0xffc0: + jh->algo = tag & 0xff; + 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: // define Huffman tables + if (info_only) + break; + for (dp = data; dp < data + len && !((c = *dp++) & -20);) + jh->free[c] = jh->huff[c] = make_decoder_ref(&dp); + break; + case 0xffda: // start of scan + jh->psv = data[1 + data[0] * 2]; + jh->bits -= data[3 + data[0] * 2] & 15; + break; + case 0xffdb: + FORC(64) jh->quant[c] = data[c * 2 + 1] << 8 | data[c * 2 + 2]; + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + if (jh->bits > 16 || jh->clrs > 6 || !jh->bits || !jh->high || !jh->wide || + !jh->clrs) + return 0; + if (info_only) + return 1; + if (!jh->huff[0]) + return 0; + FORC(19) 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, 16); + return zero_after_ff = 1; +} + +void LibRaw::ljpeg_end(struct jhead *jh) +{ + int c; + FORC4 if (jh->free[c]) free(jh->free[c]); + free(jh->row); +} + +int LibRaw::ljpeg_diff(ushort *huff) +{ + int len, diff; + if (!huff) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + 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 *LibRaw::ljpeg_row(int jrow, struct jhead *jh) +{ + int col, c, diff, pred, spred = 0; + ushort mark = 0, *row[3]; + + // Use the optimized, unrolled version if possible. + if (!jh->sraw) + return ljpeg_row_unrolled(jrow, jh); + + if (jh->restart != 0 && 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) + if(!(load_flags & 512)) + derror(); + if (c <= jh->sraw) + spred = **row; + row[0]++; + row[1]++; + } + return row[2]; +} + +ushort *LibRaw::ljpeg_row_unrolled(int jrow, struct jhead *jh) +{ + int col, c, diff, pred; + ushort mark = 0, *row[3]; + + if (jh->restart != 0 && 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); + + // The first column uses one particular predictor. + FORC(jh->clrs) + { + diff = ljpeg_diff(jh->huff[c]); + pred = (jh->vpred[c] += diff) - diff; + if ((**row = pred + diff) >> jh->bits) + derror(); + row[0]++; + row[1]++; + } + + if (!jrow) + { + for (col = 1; col < jh->wide; col++) + FORC(jh->clrs) + { + diff = ljpeg_diff(jh->huff[c]); + pred = row[0][-jh->clrs]; + if ((**row = pred + diff) >> jh->bits) + derror(); + row[0]++; + row[1]++; + } + } + else if (jh->psv == 1) + { + for (col = 1; col < jh->wide; col++) + FORC(jh->clrs) + { + diff = ljpeg_diff(jh->huff[c]); + pred = row[0][-jh->clrs]; + if ((**row = pred + diff) >> jh->bits) + derror(); + row[0]++; + } + } + else + { + for (col = 1; col < jh->wide; col++) + FORC(jh->clrs) + { + diff = ljpeg_diff(jh->huff[c]); + pred = row[0][-jh->clrs]; + 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(); + row[0]++; + row[1]++; + } + } + return row[2]; +} + +void LibRaw::lossless_jpeg_load_raw() +{ + int jwide, jhigh, jrow, jcol, val, jidx, i, j, row = 0, col = 0; + struct jhead jh; + ushort *rp; + + if (!ljpeg_start(&jh, 0)) + return; + + if (jh.wide < 1 || jh.high < 1 || jh.clrs < 1 || jh.bits < 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if(cr2_slice[0] && !cr2_slice[1]) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + jwide = jh.wide * jh.clrs; + jhigh = jh.high; + if (jh.clrs == 4 && jwide >= raw_width * 2) + jhigh *= 2; + + try + { + for (jrow = 0; jrow < jh.high; jrow++) + { + checkCancel(); + rp = ljpeg_row(jrow, &jh); + if (load_flags & 1) + row = jrow & 1 ? height - 1 - jrow / 2 : jrow / 2; + for (jcol = 0; jcol < jwide; jcol++) + { + val = curve[*rp++]; + if (cr2_slice[0]) + { + jidx = jrow * jwide + jcol; + i = jidx / (cr2_slice[1] * raw_height); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1] * raw_height); + row = jidx / cr2_slice[1 + j]; + col = jidx % cr2_slice[1 + j] + i * cr2_slice[1]; + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--, raw_width); + if (row > raw_height) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if ((unsigned)row < raw_height) + RAW(row, col) = val; + if (++col >= raw_width) + col = (row++, 0); + } + } + } + catch (...) + { + ljpeg_end(&jh); + throw; + } + ljpeg_end(&jh); +} + +void LibRaw::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; + int saved_w = width, saved_h = height; + char *cp; + + if (!ljpeg_start(&jh, 0) || jh.clrs < 4) + return; + jwide = (jh.wide >>= 1) * jh.clrs; + + if (load_flags & 256) + { + width = raw_width; + height = raw_height; + } + + try + { + 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) + { + checkCancel(); + 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; + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) + { + FORC(jh.clrs - 2) + { + ip[col + (c >> 1) * width + (c & 1)][0] = rp[jcol + c]; + ip[col + (c >> 1) * width + (c & 1)][1] = + ip[col + (c >> 1) * width + (c & 1)][2] = 8192; + } + ip[col][1] = rp[jcol + jh.clrs - 2] - 8192; + ip[col][2] = rp[jcol + jh.clrs - 1] - 8192; + } + else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) + { + FORC(jh.clrs - 2) + ip[col + (c >> 1) * width + (c & 1)][0] = rp[jcol + c]; + ip[col][1] = rp[jcol + jh.clrs - 2] - 8192; + ip[col][2] = rp[jcol + jh.clrs - 1] - 8192; + } + else + { + 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; + } + } + } + } + } + catch (...) + { + ljpeg_end(&jh); + throw; + } + + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) + { + ljpeg_end(&jh); + maximum = 0x3fff; + height = saved_h; + width = saved_w; + return; + } + + try + { + 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 >= 0x80000281ULL || + (unique_id == 0x80000218ULL && ver > 1000006)) + hue = jh.sraw << 1; + ip = (short(*)[4])image; + rp = ip[0]; + for (row = 0; row < height; row++, ip += width) + { + checkCancel(); + 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; + } + if (!(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB)) + for (; rp < ip[0]; rp += 4) + { + checkCancel(); + if ((unique_id == CanonID_EOS_5D_Mark_II) || + (unique_id == CanonID_EOS_7D) || + (unique_id == CanonID_EOS_50D) || + (unique_id == CanonID_EOS_1D_Mark_IV) || + (unique_id == CanonID_EOS_60D)) + { + rp[1] = (rp[1] << 2) + hue; + rp[2] = (rp[2] << 2) + hue; + pix[0] = rp[0] + ((50 * rp[1] + 22929 * rp[2]) >> 14); + pix[1] = rp[0] + ((-5640 * rp[1] - 11751 * rp[2]) >> 14); + pix[2] = rp[0] + ((29040 * rp[1] - 101 * rp[2]) >> 14); + } + else + { + if (unique_id < CanonID_EOS_5D_Mark_II) + rp[0] -= 512; + pix[0] = rp[0] + rp[2]; + pix[2] = rp[0] + rp[1]; + pix[1] = rp[0] + ((-778 * rp[1] - (rp[2] << 11)) >> 12); + } + FORC3 rp[c] = CLIP15(pix[c] * sraw_mul[c] >> 10); + } + } + catch (...) + { + ljpeg_end(&jh); + throw; + } + height = saved_h; + width = saved_w; + ljpeg_end(&jh); + maximum = 0x3fff; +} + +void LibRaw::ljpeg_idct(struct jhead *jh) +{ + int c, i, j, len, skip, coef; + float work[3][8][8]; + static float cs[106] = {0}; + static const uchar zigzag[80] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63}; + + if (!cs[0]) + FORC(106) cs[c] = cos((c & 31) * M_PI / 16) / 2; + memset(work, 0, sizeof work); + work[0][0][0] = jh->vpred[0] += ljpeg_diff(jh->huff[0]) * jh->quant[0]; + for (i = 1; i < 64; i++) + { + len = gethuff(jh->huff[16]); + i += skip = len >> 4; + if (!(len &= 15) && skip < 15) + break; + coef = getbits(len); + if ((coef & (1 << (len - 1))) == 0) + coef -= (1 << len) - 1; + ((float *)work)[zigzag[i]] = coef * jh->quant[i]; + } + FORC(8) work[0][0][c] *= float(M_SQRT1_2); + FORC(8) work[0][c][0] *= float(M_SQRT1_2); + for (i = 0; i < 8; i++) + for (j = 0; j < 8; j++) + FORC(8) work[1][i][j] += work[0][i][c] * cs[(j * 2 + 1) * c]; + for (i = 0; i < 8; i++) + for (j = 0; j < 8; j++) + FORC(8) work[2][i][j] += work[1][c][j] * cs[(i * 2 + 1) * c]; + + FORC(64) jh->idct[c] = CLIP(((float *)work[2])[c] + 0.5); +} + +void LibRaw::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++) + { + checkCancel(); + 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 LibRaw::nikon_read_curve() +{ + ushort ver0, ver1, vpred[2][2], csize; + int i, step, max; + + fseek(ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) + fseek(ifp, 2110, SEEK_CUR); + read_shorts(vpred[0], 4); + step = max = 1 << tiff_bps & 0x7fff; + if ((csize = get2()) > 1) + step = max / (csize - 1); + if (ver0 == 0x44 && (ver1 == 0x20 || (ver1 == 0x40 && step > 3)) && step > 0) + { + if (ver1 == 0x40) + { + step /= 4; + max /= 4; + } + 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; + } + else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts(curve, max = csize); +} + +void LibRaw::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]; + int i, min, max, 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 (ver0 == 0x44 && (ver1 == 0x20 || ver1 == 0x40)) + { + if (ver1 == 0x40) + max /= 4; + fseek(ifp, meta_offset + 562, SEEK_SET); + split = get2(); + } + + while (max > 2 && (curve[max - 2] == curve[max - 1])) + max--; + huff = make_decoder(nikon_tree[tree]); + fseek(ifp, data_offset, SEEK_SET); + getbits(-1); + try + { + for (min = row = 0; row < height; row++) + { + checkCancel(); + 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 (len > 0 && (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)]; + } + } + } + catch (...) + { + free(huff); + throw; + } + free(huff); +} + +void LibRaw::nikon_yuv_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int row, col, yuv[4]={0,0,0,0}, rgb[3], b, c; + UINT64 bitbuf = 0; + float cmul[4]; + FORC4 { cmul[c] = cam_mul[c] > 0.001f ? cam_mul[c] : 1.f; } + for (row = 0; row < raw_height; row++) + { + checkCancel(); + + for (col = 0; col < raw_width; col++) + { + if (!(b = col & 1)) + { + bitbuf = 0; + FORC(6) bitbuf |= (UINT64)fgetc(ifp) << c * 8; + FORC(4) yuv[c] = (bitbuf >> c * 12 & 0xfff) - (c >> 1 << 11); + } + rgb[0] = yuv[b] + 1.370705 * yuv[3]; + rgb[1] = yuv[b] - 0.337633 * yuv[2] - 0.698001 * yuv[3]; + rgb[2] = yuv[b] + 1.732446 * yuv[2]; + FORC3 image[row * width + col][c] = + curve[LIM(rgb[c], 0, 0xfff)] / cmul[c]; + } + } +} + +void LibRaw::rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten = 0, isix, i, buffer = 0, todo[16]; + if (raw_width > 32767 || raw_height > 32767) + throw LIBRAW_EXCEPTION_IO_BADFILE; + unsigned maxpixel = raw_width * (raw_height + 7); + + isix = raw_width * raw_height * 5 / 8; + while (fread(pixel, 1, 10, ifp) == 10) + { + checkCancel(); + 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) + if (todo[i] < maxpixel) + raw_image[todo[i]] = (todo[i + 1] & 0x3ff); + else + derror(); + } + maximum = 0x3ff; +} + +void LibRaw::nokia_load_raw() +{ + uchar *dp; + int rev, dwide, row, col, c; + double sum[] = {0, 0}; + + rev = 3 * (order == 0x4949); + dwide = (raw_width * 5 + 1) / 4; +#ifdef USE_6BY9RPI + if (raw_stride) + dwide = raw_stride; +#endif + std::vector data(dwide * 2 + 4); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + if (fread(data.data() + dwide, 1, dwide, ifp) < dwide) + derror(); + FORC(dwide) data[c] = data[dwide + (c ^ rev)]; + for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4) + FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + } + maximum = 0x3ff; +#ifdef USE_6BY9RPI + if (!strcmp(make, "OmniVision") || + !strcmp(make, "Sony") || + !strcmp(make, "RaspberryPi")) return; +#else + if (strncmp(make, "OmniVision", 10)) + return; +#endif + row = raw_height / 2; + FORC(width - 1) + { + sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); + sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); + } + if (sum[1] > sum[0]) + filters = 0x4b4b4b4b; +} + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + +void LibRaw::canon_rmf_load_raw() +{ + int row, col, bits, orow, ocol, c; + + int *words = (int *)malloc(sizeof(int) * (raw_width / 3 + 1)); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + fread(words, sizeof(int), raw_width / 3, ifp); + for (col = 0; col < raw_width - 2; col += 3) + { + bits = words[col / 3]; + FORC3 + { + orow = row; + if ((ocol = col + c - 4) < 0) + { + ocol += raw_width; + if ((orow -= 2) < 0) + orow += raw_height; + } + RAW(orow, ocol) = curve[bits >> (10 * c + 2) & 0x3ff]; + } + } + } + free(words); + maximum = curve[0x3ff]; +} +#endif + +unsigned LibRaw::pana_data(int nb, unsigned *bytes) +{ +#ifndef LIBRAW_NOTHREADS +#define vpos tls->pana_data.vpos +#define buf tls->pana_data.buf +#else + static uchar buf[0x4002]; + static int vpos; +#endif + int byte; + + if (!nb && !bytes) + return vpos = 0; + + if (!vpos) + { + fread(buf + load_flags, 1, 0x4000 - load_flags, ifp); + fread(buf, 1, load_flags, ifp); + } + + if (pana_encoding == 5) + { + for (byte = 0; byte < 16; byte++) + { + bytes[byte] = buf[vpos++]; + vpos &= 0x3FFF; + } + } + else + { + vpos = (vpos - nb) & 0x1ffff; + byte = vpos >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte + 1] << 8) >> (vpos & 7) & ~((~0u) << nb); + } + return 0; +#ifndef LIBRAW_NOTHREADS +#undef vpos +#undef buf +#endif +} + +void LibRaw::panasonic_load_raw() +{ + int row, col, i, j, sh = 0, pred[2], nonz[2]; + unsigned bytes[16]; + memset(bytes,0,sizeof(bytes)); // make gcc11 happy + ushort *raw_block_data; + + pana_data(0, 0); + + int enc_blck_size = pana_bpp == 12 ? 10 : 9; + if (pana_encoding == 5) + { + for (row = 0; row < raw_height; row++) + { + raw_block_data = raw_image + row * raw_width; + checkCancel(); + for (col = 0; col < raw_width; col += enc_blck_size) + { + pana_data(0, bytes); + + if (pana_bpp == 12) + { + raw_block_data[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + raw_block_data[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + raw_block_data[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + raw_block_data[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + raw_block_data[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + raw_block_data[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + raw_block_data[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + raw_block_data[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + raw_block_data[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + raw_block_data[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + else if (pana_bpp == 14) + { + raw_block_data[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + raw_block_data[col + 1] = + (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + raw_block_data[col + 2] = + (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + raw_block_data[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + raw_block_data[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + raw_block_data[col + 5] = + (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + raw_block_data[col + 6] = + (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + raw_block_data[col + 7] = + ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + raw_block_data[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + } + } + } + else + { + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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_data(2, 0)); + if (nonz[i & 1]) + { + if ((j = pana_data(8, 0))) + { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~((~0u) << sh); + pred[i & 1] += j << sh; + } + } + else if ((nonz[i & 1] = pana_data(8, 0)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_data(4, 0); + if ((RAW(row, col) = pred[col & 1]) > 4098 && col < width && + row < height) + derror(); + } + } + } +} + +void LibRaw::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++) + { + checkCancel(); + 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 LibRaw::minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow = 0; irow < 1481; irow++) + { + checkCancel(); + 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 LibRaw::quicktake_100_load_raw() +{ + std::vector pixel_buffer(484 * 644, 0x80); + uchar* pixel = &pixel_buffer[0]; + 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 t_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; + + if (width > 640 || height > 480) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + getbits(-1); + for (row = 2; row < height + 2; row++) + { + checkCancel(); + for (col = 2 + (row & 1); col < width + 2; col += 2) + { + val = ((pixel[(row - 1) * 644 + col - 1] + 2 * pixel[(row - 1) * 644 + col + 1] + pixel[row * 644 + col - 2]) >> 2) + gstep[getbits(4)]; + pixel[row * 644 + col] = val = LIM(val, 0, 255); + if (col < 4) + pixel[row * 644 + col - 2] = pixel[(row + 1) * 644 + (~row & 1)] = val; + if (row == 2) + pixel[(row - 1) * 644 + col + 1] = pixel[(row - 1) * 644 + col + 3] = val; + } + pixel[row * 644 + col] = val; + } + for (rb = 0; rb < 2; rb++) + for (row = 2 + rb; row < height + 2; row += 2) + { + checkCancel(); + for (col = 3 - (row & 1); col < width + 2; col += 2) + { + if (row < 4 || col < 4) + sharp = 2; + else + { + val = ABS(pixel[(row - 2) * 644 + col] - pixel[row * 644 + col - 2]) + ABS(pixel[(row - 2) * 644 + col] - pixel[(row - 2) * 644 + col - 2]) + + ABS(pixel[row * 644 + col - 2] - pixel[(row - 2) * 644 + col - 2]); + sharp = val < 4 + ? 0 + : val < 8 + ? 1 + : val < 16 ? 2 : val < 32 ? 3 : val < 48 ? 4 : 5; + } + val = ((pixel[(row - 2) * 644 + col] + pixel[row * 644 + col - 2]) >> 1) + rstep[sharp][getbits(2)]; + pixel[row * 644 + col] = val = LIM(val, 0, 255); + if (row < 4) + pixel[(row - 2) * 644 + col + 2] = val; + if (col < 4) + pixel[(row + 2) * 644 + col - 2] = val; + } + } + for (row = 2; row < height + 2; row++) + { + checkCancel(); + for (col = 3 - (row & 1); col < width + 2; col += 2) + { + val = ((pixel[row * 644 + col - 1] + (pixel[row * 644 + col] << 2) + pixel[row * 644 + col + 1]) >> 1) - 0x100; + pixel[row * 644 + col] = LIM(val, 0, 255); + } + } + for (row = 0; row < height; row++) + { + checkCancel(); + for (col = 0; col < width; col++) + RAW(row, col) = t_curve[pixel[(row + 2) * 644 + col + 2]]; + } + maximum = 0x3ff; +} + +void LibRaw::sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek(ifp, 200896, SEEK_SET); + fseek(ifp, (unsigned)fgetc(ifp) * 4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + + fseek(ifp, 164600, SEEK_SET); + fread(head, 1, 40, ifp); + sony_decrypt((unsigned *)head, 10, 1, key); + for (i = 26; i-- > 22;) + key = key << 8 | head[i]; + + fseek(ifp, data_offset, SEEK_SET); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + pixel = raw_image + row * raw_width; + if (fread(pixel, 2, raw_width, ifp) < raw_width) + derror(); + sony_decrypt((unsigned *)pixel, raw_width / 2, !row, key); + for (col = 0; col < raw_width; col++) + if ((pixel[col] = ntohs(pixel[col])) >> 14) + derror(); + } + maximum = 0x3ff0; +} + +void LibRaw::sony_arw_load_raw() +{ + std::vector huff_buffer(32770); + ushort* huff = &huff_buffer[0]; + static const ushort tab[18] = {0xf11, 0xf10, 0xe0f, 0xd0e, 0xc0d, 0xb0c, + 0xa0b, 0x90a, 0x809, 0x708, 0x607, 0x506, + 0x405, 0x304, 0x303, 0x300, 0x202, 0x201}; + int i, c, n, col, row, sum = 0; + + huff[0] = 15; + for (n = i = 0; i < 18; i++) + FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (col = raw_width; col--;) + { + checkCancel(); + for (row = 0; row < raw_height + 1; row += 2) + { + if (row == raw_height) + row = 1; + if ((sum += ljpeg_diff(huff)) >> 12) + derror(); + if (row < height) + RAW(row, col) = sum; + } + } +} + +void LibRaw::sony_arw2_load_raw() +{ + uchar *data, *dp; + ushort pix[16]; + int row, col, val, max, min, imax, imin, sh, bit, i; + + data = (uchar *)malloc(raw_width + 1); + try + { + for (row = 0; row < height; row++) + { + checkCancel(); + 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++) + ; + /* flag checks if outside of loop */ + if (!(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_ALLFLAGS) // no flag set + || (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE)) + { + 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; + } + } + else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_BASEONLY) + { + for (bit = 30, i = 0; i < 16; i++) + if (i == imax) + pix[i] = max; + else if (i == imin) + pix[i] = min; + else + pix[i] = 0; + } + else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTAONLY) + { + for (bit = 30, i = 0; i < 16; i++) + if (i == imax) + pix[i] = 0; + else if (i == imin) + pix[i] = 0; + else + { + pix[i] = + ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min; + if (pix[i] > 0x7ff) + pix[i] = 0x7ff; + bit += 7; + } + } + else if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTAZEROBASE) + { + for (bit = 30, i = 0; i < 16; i++) + if (i == imax) + pix[i] = 0; + else if (i == imin) + pix[i] = 0; + else + { + pix[i] = ((sget2(dp + (bit >> 3)) >> (bit & 7) & 0x7f) << sh); + if (pix[i] > 0x7ff) + pix[i] = 0x7ff; + bit += 7; + } + } + + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE) + { + for (i = 0; i < 16; i++, col += 2) + { + unsigned slope = + pix[i] < 1001 ? 2 + : curve[pix[i] << 1] - curve[(pix[i] << 1) - 2]; + unsigned step = 1 << sh; + RAW(row, col) = + curve[pix[i] << 1] > + black + imgdata.rawparams.sony_arw2_posterization_thr + ? LIM(((slope * step * 1000) / + (curve[pix[i] << 1] - black)), + 0, 10000) + : 0; + } + } + else + for (i = 0; i < 16; i++, col += 2) + RAW(row, col) = curve[pix[i] << 1]; + col -= col & 1 ? 1 : 31; + } + } + } + catch (...) + { + free(data); + throw; + } + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SONYARW2_DELTATOVALUE) + maximum = 10000; + free(data); +} + +void LibRaw::samsung_load_raw() +{ + int row, col, c, i, dir, op[4], len[4]; + if (raw_width > 32768 || + raw_height > 32768) // definitely too much for old samsung + throw LIBRAW_EXCEPTION_IO_BADFILE; + unsigned maxpixels = raw_width * (raw_height + 7); + + order = 0x4949; + for (row = 0; row < raw_height; row++) + { + checkCancel(); + fseek(ifp, strip_offset + row * 4, SEEK_SET); + fseek(ifp, data_offset + get4(), SEEK_SET); + ph1_bits(-1); + FORC4 len[c] = row < 2 ? 7 : 4; + for (col = 0; col < raw_width; col += 16) + { + dir = ph1_bits(1); + FORC4 op[c] = ph1_bits(2); + FORC4 switch (op[c]) + { + case 3: + len[c] = ph1_bits(4); + break; + case 2: + len[c]--; + break; + case 1: + len[c]++; + } + for (c = 0; c < 16; c += 2) + { + i = len[((c & 1) << 1) | (c >> 3)]; + unsigned idest = RAWINDEX(row, col + c); + unsigned isrc = (dir ? RAWINDEX(row + (~c | -2), col + c) + : col ? RAWINDEX(row, col + (c | -2)) : 0); + if (idest < maxpixels && + isrc < + maxpixels) // less than zero is handled by unsigned conversion + RAW(row, col + c) = (i > 0 ? ((signed)ph1_bits(i) << (32 - i) >> (32 - i)) : 0) + + (dir ? RAW(row + (~c | -2), col + c) : col ? RAW(row, col + (c | -2)) : 128); + else + derror(); + if (c == 14) + c = -1; + } + } + } + for (row = 0; row < raw_height - 1; row += 2) + for (col = 0; col < raw_width - 1; col += 2) + SWAP(RAW(row, col + 1), RAW(row + 1, col)); +} + +void LibRaw::samsung2_load_raw() +{ + static const ushort tab[14] = {0x304, 0x307, 0x206, 0x205, 0x403, + 0x600, 0x709, 0x80a, 0x90b, 0xa0c, + 0xa0d, 0x501, 0x408, 0x402}; + ushort huff[1026], vpred[2][2] = {{0, 0}, {0, 0}}, hpred[2]; + int i, c, n, row, col, diff; + + huff[0] = 10; + for (n = i = 0; i < 14; i++) + FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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 LibRaw::samsung3_load_raw() +{ + int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; + ushort lent[3][2], len[4], *prow[2]; + order = 0x4949; + fseek(ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(), get2()); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + fseek(ifp, (data_offset - ftell(ifp)) & 15, SEEK_CUR); + ph1_bits(-1); + mag = 0; + pmode = 7; + FORC(6)((ushort *)lent)[c] = row < 2 ? 7 : 4; + prow[row & 1] = &RAW(row - 1, 1 - ((row & 1) << 1)); // green + prow[~row & 1] = &RAW(row - 2, 0); // red and blue + for (tab = 0; tab + 15 < raw_width; tab += 16) + { + if (~opt & 4 && !(tab & 63)) + { + i = ph1_bits(2); + mag = i < 3 ? mag - '2' + "204"[i] : ph1_bits(12); + } + if (opt & 2) + pmode = 7 - 4 * ph1_bits(1); + else if (!ph1_bits(1)) + pmode = ph1_bits(3); + if (opt & 1 || !ph1_bits(1)) + { + FORC4 len[c] = ph1_bits(2); + FORC4 + { + i = ((row & 1) << 1 | (c & 1)) % 3; + if (i < 0) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + len[c] = len[c] < 3 ? lent[i][0] - '1' + "120"[len[c]] : ph1_bits(4); + lent[i][0] = lent[i][1]; + lent[i][1] = len[c]; + } + } + FORC(16) + { + col = tab + (((c & 7) << 1) ^ (c >> 3) ^ (row & 1)); + if (col < 0) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (pmode < 0) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (pmode != 7 && row >= 2 && (col - '4' + "0224468"[pmode]) < 0) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + pred = (pmode == 7 || row < 2) + ? (tab ? RAW(row, tab - 2 + (col & 1)) : init) + : (prow[col & 1][col - '4' + "0224468"[pmode]] + + prow[col & 1][col - '4' + "0244668"[pmode]] + 1) >> + 1; + diff = ph1_bits(i = len[c >> 2]); + if (i > 0 && diff >> (i - 1)) + diff -= 1 << i; + diff = diff * (mag * 2 + 1) + mag; + RAW(row, col) = pred + diff; + } + } + } +} + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void LibRaw::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_t *)ifp->make_jas_stream(); + if (!in) + throw LIBRAW_EXCEPTION_DECODE_JPEG2000; + jas_stream_seek(in, data_offset + 20, SEEK_SET); + jimg = jas_image_decode(in, -1, 0); + if (!jimg) + { + jas_stream_close(in); + throw LIBRAW_EXCEPTION_DECODE_JPEG2000; + } + jmat = jas_matrix_create(height / 2, width / 2); + img = (ushort *)calloc((height + 2), (width + 2) * 2); + bool fastexitflag = false; + try + { + FORC4 + { + checkCancel(); + 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++) + { + checkCancel(); + 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++) + { + checkCancel(); + for (col = 0; col < width; col++) + RAW(row, col) = curve[img[(row + 1) * (width + 2) + col + 1]]; + } + } + catch (...) + { + fastexitflag = true; + } + free(img); + jas_matrix_destroy(jmat); + jas_image_destroy(jimg); + jas_stream_close(in); + if (fastexitflag) + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; +#endif +} +#endif diff --git a/src/decoders/decoders_libraw.cpp b/src/decoders/decoders_libraw.cpp new file mode 100644 index 000000000..332e2af21 --- /dev/null +++ b/src/decoders/decoders_libraw.cpp @@ -0,0 +1,861 @@ +/* -*- C++ -*- + * Copyright 2019-2022 LibRaw LLC (info@libraw.org) + * + * PhaseOne IIQ-Sv2 decoder is inspired by code provided by Daniel Vogelbacher + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#include +#include // for std::sort + +void LibRaw::sony_arq_load_raw() +{ + int row, col; + read_shorts(imgdata.rawdata.raw_image, + imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4); + libraw_internal_data.internal_data.input->seek( + -2, SEEK_CUR); // avoid wrong eof error + + if(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ARQ_SKIP_CHANNEL_SWAP) + return; + + for (row = 0; row < imgdata.sizes.raw_height; row++) + { + unsigned short(*rowp)[4] = + (unsigned short(*)[4]) & + imgdata.rawdata.raw_image[row * imgdata.sizes.raw_width * 4]; + for (col = 0; col < imgdata.sizes.raw_width; col++) + { + unsigned short g2 = rowp[col][2]; + rowp[col][2] = rowp[col][3]; + rowp[col][3] = g2; + if (((unsigned)(row - imgdata.sizes.top_margin) < imgdata.sizes.height) && + ((unsigned)(col - imgdata.sizes.left_margin) < imgdata.sizes.width) && + (MAX(MAX(rowp[col][0], rowp[col][1]), + MAX(rowp[col][2], rowp[col][3])) > imgdata.color.maximum)) + derror(); + } + } +} + +void LibRaw::pentax_4shot_load_raw() +{ + ushort *plane = (ushort *)malloc(imgdata.sizes.raw_width * + imgdata.sizes.raw_height * sizeof(ushort)); + int alloc_sz = imgdata.sizes.raw_width * (imgdata.sizes.raw_height + 16) * 4 * + sizeof(ushort); + ushort(*result)[4] = (ushort(*)[4])malloc(alloc_sz); + struct movement_t + { + int row, col; + } _move[4] = { + {1, 1}, + {0, 1}, + {0, 0}, + {1, 0}, + }; + + int tidx = 0; + for (int i = 0; i < 4; i++) + { + int move_row, move_col; + if (imgdata.rawparams.p4shot_order[i] >= '0' && + imgdata.rawparams.p4shot_order[i] <= '3') + { + move_row = ((imgdata.rawparams.p4shot_order[i] - '0') & 2) ? 1 : 0; + move_col = ((imgdata.rawparams.p4shot_order[i] - '0') & 1) ? 1 : 0; + } + else + { + move_row = _move[i].row; + move_col = _move[i].col; + } + for (; tidx < 16; tidx++) + if (tiff_ifd[tidx].t_width == imgdata.sizes.raw_width && + tiff_ifd[tidx].t_height == imgdata.sizes.raw_height && + tiff_ifd[tidx].bps > 8 && tiff_ifd[tidx].samples == 1) + break; + if (tidx >= 16) + break; + imgdata.rawdata.raw_image = plane; + ID.input->seek(tiff_ifd[tidx].offset, SEEK_SET); + imgdata.idata.filters = 0xb4b4b4b4; + libraw_internal_data.unpacker_data.data_offset = tiff_ifd[tidx].offset; + (this->*pentax_component_load_raw)(); + for (int row = 0; row < imgdata.sizes.raw_height - move_row; row++) + { + int colors[2]; + for (int c = 0; c < 2; c++) + colors[c] = COLOR(row, c); + ushort *srcrow = &plane[imgdata.sizes.raw_width * row]; + ushort(*dstrow)[4] = + &result[(imgdata.sizes.raw_width) * (row + move_row) + move_col]; + for (int col = 0; col < imgdata.sizes.raw_width - move_col; col++) + dstrow[col][colors[col % 2]] = srcrow[col]; + } + tidx++; + } + + if (imgdata.color.cblack[4] == 2 && imgdata.color.cblack[5] == 2) + for (int c = 0; c < 4; c++) + imgdata.color.cblack[FC(c / 2, c % 2)] += + imgdata.color.cblack[6 + + c / 2 % imgdata.color.cblack[4] * + imgdata.color.cblack[5] + + c % 2 % imgdata.color.cblack[5]]; + imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; + + // assign things back: + imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 8; + imgdata.idata.filters = 0; + imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image = result; + free(plane); + imgdata.rawdata.raw_image = 0; +} + +void LibRaw::hasselblad_full_load_raw() +{ + int row, col; + + for (row = 0; row < S.height; row++) + for (col = 0; col < S.width; col++) + { + read_shorts(&imgdata.image[row * S.width + col][2], 1); // B + read_shorts(&imgdata.image[row * S.width + col][1], 1); // G + read_shorts(&imgdata.image[row * S.width + col][0], 1); // R + } +} + +static inline void unpack7bytesto4x16(unsigned char *src, unsigned short *dest) +{ + dest[0] = (src[0] << 6) | (src[1] >> 2); + dest[1] = ((src[1] & 0x3) << 12) | (src[2] << 4) | (src[3] >> 4); + dest[2] = (src[3] & 0xf) << 10 | (src[4] << 2) | (src[5] >> 6); + dest[3] = ((src[5] & 0x3f) << 8) | src[6]; +} + +static inline void unpack28bytesto16x16ns(unsigned char *src, + unsigned short *dest) +{ + dest[0] = (src[3] << 6) | (src[2] >> 2); + dest[1] = ((src[2] & 0x3) << 12) | (src[1] << 4) | (src[0] >> 4); + dest[2] = (src[0] & 0xf) << 10 | (src[7] << 2) | (src[6] >> 6); + dest[3] = ((src[6] & 0x3f) << 8) | src[5]; + dest[4] = (src[4] << 6) | (src[11] >> 2); + dest[5] = ((src[11] & 0x3) << 12) | (src[10] << 4) | (src[9] >> 4); + dest[6] = (src[9] & 0xf) << 10 | (src[8] << 2) | (src[15] >> 6); + dest[7] = ((src[15] & 0x3f) << 8) | src[14]; + dest[8] = (src[13] << 6) | (src[12] >> 2); + dest[9] = ((src[12] & 0x3) << 12) | (src[19] << 4) | (src[18] >> 4); + dest[10] = (src[18] & 0xf) << 10 | (src[17] << 2) | (src[16] >> 6); + dest[11] = ((src[16] & 0x3f) << 8) | src[23]; + dest[12] = (src[22] << 6) | (src[21] >> 2); + dest[13] = ((src[21] & 0x3) << 12) | (src[20] << 4) | (src[27] >> 4); + dest[14] = (src[27] & 0xf) << 10 | (src[26] << 2) | (src[25] >> 6); + dest[15] = ((src[25] & 0x3f) << 8) | src[24]; +} + +#define swab32(x) \ + ((unsigned int)((((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ + (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ + (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ + (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24))) + +static inline void swab32arr(unsigned *arr, unsigned len) +{ + for (unsigned i = 0; i < len; i++) + arr[i] = swab32(arr[i]); +} +#undef swab32 + +static inline void unpack7bytesto4x16_nikon(unsigned char *src, + unsigned short *dest) +{ + dest[3] = (src[6] << 6) | (src[5] >> 2); + dest[2] = ((src[5] & 0x3) << 12) | (src[4] << 4) | (src[3] >> 4); + dest[1] = (src[3] & 0xf) << 10 | (src[2] << 2) | (src[1] >> 6); + dest[0] = ((src[1] & 0x3f) << 8) | src[0]; +} + +void LibRaw::nikon_14bit_load_raw() +{ + const unsigned linelen = + (unsigned)(ceilf((float)(S.raw_width * 7 / 4) / 16.0)) * + 16; // 14512; // S.raw_width * 7 / 4; + const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width; + unsigned char *buf = (unsigned char *)malloc(linelen); + for (int row = 0; row < S.raw_height; row++) + { + unsigned bytesread = + libraw_internal_data.internal_data.input->read(buf, 1, linelen); + unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; + // swab32arr((unsigned *)buf, bytesread / 4); + for (unsigned int sp = 0, dp = 0; + dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; + sp += 7, dp += 4) + unpack7bytesto4x16_nikon(buf + sp, dest + dp); + } + free(buf); +} + +void LibRaw::fuji_14bit_load_raw() +{ + const unsigned linelen = S.raw_width * 7 / 4; + const unsigned pitch = S.raw_pitch ? S.raw_pitch / 2 : S.raw_width; + unsigned char *buf = (unsigned char *)malloc(linelen); + + for (int row = 0; row < S.raw_height; row++) + { + unsigned bytesread = + libraw_internal_data.internal_data.input->read(buf, 1, linelen); + unsigned short *dest = &imgdata.rawdata.raw_image[pitch * row]; + if (bytesread % 28) + { + swab32arr((unsigned *)buf, bytesread / 4); + for (unsigned int sp = 0, dp = 0; + dp < pitch - 3 && sp < linelen - 6 && sp < bytesread - 6; + sp += 7, dp += 4) + unpack7bytesto4x16(buf + sp, dest + dp); + } + else + for (unsigned int sp = 0, dp = 0; + dp < pitch - 15 && sp < linelen - 27 && sp < bytesread - 27; + sp += 28, dp += 16) + unpack28bytesto16x16ns(buf + sp, dest + dp); + } + free(buf); +} +void LibRaw::nikon_load_padded_packed_raw() // 12 bit per pixel, padded to 16 + // bytes +{ + // libraw_internal_data.unpacker_data.load_flags -> row byte count + if (libraw_internal_data.unpacker_data.load_flags < 2000 || + libraw_internal_data.unpacker_data.load_flags > 64000) + return; + unsigned char *buf = + (unsigned char *)malloc(libraw_internal_data.unpacker_data.load_flags); + for (int row = 0; row < S.raw_height; row++) + { + checkCancel(); + libraw_internal_data.internal_data.input->read( + buf, libraw_internal_data.unpacker_data.load_flags, 1); + for (int icol = 0; icol < S.raw_width / 2; icol++) + { + imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2)] = + ((buf[icol * 3 + 1] & 0xf) << 8) | buf[icol * 3]; + imgdata.rawdata.raw_image[(row)*S.raw_width + (icol * 2 + 1)] = + buf[icol * 3 + 2] << 4 | ((buf[icol * 3 + 1] & 0xf0) >> 4); + } + } + free(buf); +} + +void LibRaw::nikon_load_striped_packed_raw() +{ + int vbits = 0, bwide, rbits, bite, row, col, i; + + UINT64 bitbuf = 0; + unsigned load_flags = 24; // libraw_internal_data.unpacker_data.load_flags; + unsigned tiff_bps = libraw_internal_data.unpacker_data.tiff_bps; + + struct tiff_ifd_t *ifd = &tiff_ifd[0]; + while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && + ifd->offset != libraw_internal_data.unpacker_data.data_offset) + ++ifd; + if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds]) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + if (!ifd->rows_per_strip || !ifd->strip_offsets_count) + return; // not unpacked + int stripcnt = 0; + + bwide = S.raw_width * tiff_bps / 8; + bwide += bwide & load_flags >> 7; + rbits = bwide * 8 - S.raw_width * tiff_bps; + if (load_flags & 1) + bwide = bwide * 16 / 15; + bite = 8 + (load_flags & 24); + for (row = 0; row < S.raw_height; row++) + { + checkCancel(); + if (!(row % ifd->rows_per_strip)) + { + if (stripcnt >= ifd->strip_offsets_count) + return; // run out of data + libraw_internal_data.internal_data.input->seek( + ifd->strip_offsets[stripcnt], SEEK_SET); + stripcnt++; + } + for (col = 0; col < S.raw_width; col++) + { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) + { + bitbuf <<= bite; + for (i = 0; i < bite; i += 8) + bitbuf |= + (unsigned)(libraw_internal_data.internal_data.input->get_char() + << i); + } + imgdata.rawdata.raw_image[(row)*S.raw_width + (col)] = + bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps); + } + vbits -= rbits; + } +} + +struct pana_cs6_page_decoder +{ + unsigned int pixelbuffer[18], lastoffset, maxoffset; + unsigned char current, *buffer; + pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) + : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) + { + } + void read_page(); // will throw IO error if not enough space in buffer + void read_page12(); // 12-bit variant + unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } + unsigned int nextpixel12() { return current < 18 ? pixelbuffer[current++] : 0; } +}; + +void pana_cs6_page_decoder::read_page() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + throw LIBRAW_EXCEPTION_IO_EOF; +#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) + pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit + pixelbuffer[1] = (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) & 0x3fff; // 14 bit + pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3; // 2 + pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4); // 10 + pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6); // 10 + pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4); // 10 + pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3; + pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8); + pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6); + pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff; + pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3; + pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12); + pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff; + pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff; +#undef wbuffer + current = 0; + lastoffset += 16; +} + +void pana_cs6_page_decoder::read_page12() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + throw LIBRAW_EXCEPTION_IO_EOF; +#define wb(i) ((unsigned short)buffer[lastoffset + 15 - i]) + pixelbuffer[0] = (wb(0) << 4) | (wb(1) >> 4); // 12 bit: 8/0 + 4 upper bits of /1 + pixelbuffer[1] = (((wb(1) & 0xf) << 8) | (wb(2))) & 0xfff; // 12 bit: 4l/1 + 8/2 + + pixelbuffer[2] = (wb(3) >> 6) & 0x3; // 2; 2u/3, 6 low bits remains in wb(3) + pixelbuffer[3] = ((wb(3) & 0x3f) << 2) | (wb(4) >> 6); // 8; 6l/3 + 2u/4; 6 low bits remains in wb(4) + pixelbuffer[4] = ((wb(4) & 0x3f) << 2) | (wb(5) >> 6); // 8: 6l/4 + 2u/5; 6 low bits remains in wb(5) + pixelbuffer[5] = ((wb(5) & 0x3f) << 2) | (wb(6) >> 6); // 8: 6l/5 + 2u/6, 6 low bits remains in wb(6) + + pixelbuffer[6] = (wb(6) >> 4) & 0x3; // 2, 4 low bits remains in wb(6) + pixelbuffer[7] = ((wb(6) & 0xf) << 4) | (wb(7) >> 4); // 8: 4 low bits from wb(6), 4 upper bits from wb(7) + pixelbuffer[8] = ((wb(7) & 0xf) << 4) | (wb(8) >> 4); // 8: 4 low bits from wb7, 4 upper bits from wb8 + pixelbuffer[9] = ((wb(8) & 0xf) << 4) | (wb(9) >> 4); // 8: 4 low bits from wb8, 4 upper bits from wb9 + + pixelbuffer[10] = (wb(9) >> 2) & 0x3; // 2: bits 2-3 from wb9, two low bits remain in wb9 + pixelbuffer[11] = ((wb(9) & 0x3) << 6) | (wb(10) >> 2); // 8: 2 bits from wb9, 6 bits from wb10 + pixelbuffer[12] = ((wb(10) & 0x3) << 6) | (wb(11) >> 2); // 8: 2 bits from wb10, 6 bits from wb11 + pixelbuffer[13] = ((wb(11) & 0x3) << 6) | (wb(12) >> 2); // 8: 2 bits from wb11, 6 bits from wb12 + + pixelbuffer[14] = wb(12) & 0x3; // 2: low bits from wb12 + pixelbuffer[15] = wb(13); + pixelbuffer[16] = wb(14); + pixelbuffer[17] = wb(15); +#undef wb + current = 0; + lastoffset += 16; +} + +void LibRaw::panasonicC6_load_raw() +{ + const int rowstep = 16; + const bool _12bit = libraw_internal_data.unpacker_data.pana_bpp == 12; + const int pixperblock = _12bit ? 14 : 11; + const int blocksperrow = imgdata.sizes.raw_width / pixperblock; + const int rowbytes = blocksperrow * 16; + const unsigned pixelbase0 = _12bit ? 0x80 : 0x200; + const unsigned pixelbase_compare = _12bit ? 0x800 : 0x2000; + const unsigned spix_compare = _12bit ? 0x3fff : 0xffff; + const unsigned pixel_mask = _12bit ? 0xfff : 0x3fff; + std::vector iobuf; + try + { + iobuf.resize(rowbytes * rowstep); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; + } + + for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; + row += rowstep) + { + int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); + if (libraw_internal_data.internal_data.input->read( + iobuf.data(), rowbytes, rowstoread) != rowstoread) + throw LIBRAW_EXCEPTION_IO_EOF; + pana_cs6_page_decoder page(iobuf.data(), rowbytes * rowstoread); + for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) + { + unsigned short *rowptr = + &imgdata.rawdata + .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; + for (int rblock = 0; rblock < blocksperrow; rblock++) + { + if (_12bit) + page.read_page12(); + else + page.read_page(); + unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; + unsigned pmul = 0, pixel_base = 0; + for (int pix = 0; pix < pixperblock; pix++) + { + if (pix % 3 == 2) + { + unsigned base = _12bit ? page.nextpixel12(): page.nextpixel(); + if (base > 3) + throw LIBRAW_EXCEPTION_IO_CORRUPT; // not possible b/c of 2-bit + // field, but.... + if (base == 3) + base = 4; + pixel_base = pixelbase0 << base; + pmul = 1 << base; + } + unsigned epixel = _12bit ? page.nextpixel12() : page.nextpixel(); + if (oddeven[pix % 2]) + { + epixel *= pmul; + if (pixel_base < pixelbase_compare && nonzero[pix % 2] > pixel_base) + epixel += nonzero[pix % 2] - pixel_base; + nonzero[pix % 2] = epixel; + } + else + { + oddeven[pix % 2] = epixel; + if (epixel) + nonzero[pix % 2] = epixel; + else + epixel = nonzero[pix % 2]; + } + unsigned spix = epixel - 0xf; + if (spix <= spix_compare) + rowptr[col++] = spix & spix_compare; + else + { + epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); + rowptr[col++] = epixel & pixel_mask; + } + } + } + } + } +} + + +void LibRaw::panasonicC7_load_raw() +{ + const int rowstep = 16; + int pixperblock = libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; + int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; + unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); + for (int row = 0; row < imgdata.sizes.raw_height - rowstep + 1; + row += rowstep) + { + int rowstoread = MIN(rowstep, imgdata.sizes.raw_height - row); + if (libraw_internal_data.internal_data.input->read( + iobuf, rowbytes, rowstoread) != rowstoread) + throw LIBRAW_EXCEPTION_IO_EOF; + unsigned char *bytes = iobuf; + for (int crow = 0; crow < rowstoread; crow++) + { + unsigned short *rowptr = + &imgdata.rawdata + .raw_image[(row + crow) * imgdata.sizes.raw_pitch / 2]; + for (int col = 0; col < imgdata.sizes.raw_width - pixperblock + 1; + col += pixperblock, bytes += 16) + { + if (libraw_internal_data.unpacker_data.pana_bpp == 14) + { + rowptr[col] = bytes[0] + ((bytes[1] & 0x3F) << 8); + rowptr[col + 1] = + (bytes[1] >> 6) + 4 * (bytes[2]) + ((bytes[3] & 0xF) << 10); + rowptr[col + 2] = + (bytes[3] >> 4) + 16 * (bytes[4]) + ((bytes[5] & 3) << 12); + rowptr[col + 3] = ((bytes[5] & 0xFC) >> 2) + (bytes[6] << 6); + rowptr[col + 4] = bytes[7] + ((bytes[8] & 0x3F) << 8); + rowptr[col + 5] = + (bytes[8] >> 6) + 4 * bytes[9] + ((bytes[10] & 0xF) << 10); + rowptr[col + 6] = + (bytes[10] >> 4) + 16 * bytes[11] + ((bytes[12] & 3) << 12); + rowptr[col + 7] = ((bytes[12] & 0xFC) >> 2) + (bytes[13] << 6); + rowptr[col + 8] = bytes[14] + ((bytes[15] & 0x3F) << 8); + } + else if (libraw_internal_data.unpacker_data.pana_bpp == + 12) // have not seen in the wild yet + { + rowptr[col] = ((bytes[1] & 0xF) << 8) + bytes[0]; + rowptr[col + 1] = 16 * bytes[2] + (bytes[1] >> 4); + rowptr[col + 2] = ((bytes[4] & 0xF) << 8) + bytes[3]; + rowptr[col + 3] = 16 * bytes[5] + (bytes[4] >> 4); + rowptr[col + 4] = ((bytes[7] & 0xF) << 8) + bytes[6]; + rowptr[col + 5] = 16 * bytes[8] + (bytes[7] >> 4); + rowptr[col + 6] = ((bytes[10] & 0xF) << 8) + bytes[9]; + rowptr[col + 7] = 16 * bytes[11] + (bytes[10] >> 4); + rowptr[col + 8] = ((bytes[13] & 0xF) << 8) + bytes[12]; + rowptr[col + 9] = 16 * bytes[14] + (bytes[13] >> 4); + } + } + } + } + free(iobuf); +} + +void LibRaw::unpacked_load_raw_fuji_f700s20() +{ + int base_offset = 0; + int row_size = imgdata.sizes.raw_width * 2; // in bytes + if (imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select) + { + libraw_internal_data.internal_data.input->seek(-row_size, SEEK_CUR); + base_offset = row_size; // in bytes + } + unsigned char *buffer = (unsigned char *)malloc(row_size * 2); + for (int row = 0; row < imgdata.sizes.raw_height; row++) + { + read_shorts((ushort *)buffer, imgdata.sizes.raw_width * 2); + memmove(&imgdata.rawdata.raw_image[row * imgdata.sizes.raw_pitch / 2], + buffer + base_offset, row_size); + } + free(buffer); +} + +void LibRaw::nikon_load_sraw() +{ + // We're already seeked to data! + unsigned char *rd = + (unsigned char *)malloc(3 * (imgdata.sizes.raw_width + 2)); + if (!rd) + throw LIBRAW_EXCEPTION_ALLOC; + try + { + int row, col; + for (row = 0; row < imgdata.sizes.raw_height; row++) + { + checkCancel(); + libraw_internal_data.internal_data.input->read(rd, 3, + imgdata.sizes.raw_width); + for (col = 0; col < imgdata.sizes.raw_width - 1; col += 2) + { + int bi = col * 3; + ushort bits1 = (rd[bi + 1] & 0xf) << 8 | rd[bi]; // 3,0,1 + ushort bits2 = rd[bi + 2] << 4 | ((rd[bi + 1] >> 4) & 0xf); // 452 + ushort bits3 = ((rd[bi + 4] & 0xf) << 8) | rd[bi + 3]; // 967 + ushort bits4 = rd[bi + 5] << 4 | ((rd[bi + 4] >> 4) & 0xf); // ab8 + imgdata.image[row * imgdata.sizes.raw_width + col][0] = bits1; + imgdata.image[row * imgdata.sizes.raw_width + col][1] = bits3; + imgdata.image[row * imgdata.sizes.raw_width + col][2] = bits4; + imgdata.image[row * imgdata.sizes.raw_width + col + 1][0] = bits2; + imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = 2048; + imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = 2048; + } + } + } + catch (...) + { + free(rd); + throw; + } + free(rd); + C.maximum = 0xfff; // 12 bit? + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) + { + return; // no CbCr interpolation + } + // Interpolate CC channels + int row, col; + for (row = 0; row < imgdata.sizes.raw_height; row++) + { + checkCancel(); // will throw out + for (col = 0; col < imgdata.sizes.raw_width; col += 2) + { + int col2 = col < imgdata.sizes.raw_width - 2 ? col + 2 : col; + imgdata.image[row * imgdata.sizes.raw_width + col + 1][1] = + (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + + col][1] + + imgdata.image[row * imgdata.sizes.raw_width + + col2][1]) / + 2); + imgdata.image[row * imgdata.sizes.raw_width + col + 1][2] = + (unsigned short)(int(imgdata.image[row * imgdata.sizes.raw_width + + col][2] + + imgdata.image[row * imgdata.sizes.raw_width + + col2][2]) / + 2); + } + } + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) + return; + + for (row = 0; row < imgdata.sizes.raw_height; row++) + { + checkCancel(); // will throw out + for (col = 0; col < imgdata.sizes.raw_width; col++) + { + float Y = + float(imgdata.image[row * imgdata.sizes.raw_width + col][0]) / 2549.f; + float Ch2 = + float(imgdata.image[row * imgdata.sizes.raw_width + col][1] - 1280) / + 1536.f; + float Ch3 = + float(imgdata.image[row * imgdata.sizes.raw_width + col][2] - 1280) / + 1536.f; + if (Y > 1.f) + Y = 1.f; + if (Y > 0.803f) + Ch2 = Ch3 = 0.5f; + float r = Y + 1.40200f * (Ch3 - 0.5f); + if (r < 0.f) + r = 0.f; + if (r > 1.f) + r = 1.f; + float g = Y - 0.34414f * (Ch2 - 0.5f) - 0.71414 * (Ch3 - 0.5f); + if (g > 1.f) + g = 1.f; + if (g < 0.f) + g = 0.f; + float b = Y + 1.77200 * (Ch2 - 0.5f); + if (b > 1.f) + b = 1.f; + if (b < 0.f) + b = 0.f; + imgdata.image[row * imgdata.sizes.raw_width + col][0] = + imgdata.color.curve[int(r * 3072.f)]; + imgdata.image[row * imgdata.sizes.raw_width + col][1] = + imgdata.color.curve[int(g * 3072.f)]; + imgdata.image[row * imgdata.sizes.raw_width + col][2] = + imgdata.color.curve[int(b * 3072.f)]; + } + } + C.maximum = 16383; +} + +/* + Each row is decoded independently. Each row starts with a 16 bit prefix. + The hi byte is zero, the lo byte (first 3 bits) indicates a bit_base. + Other bits remain unused. + + |0000 0000|0000 0XXX| => XXX is bit_base + + After the prefix the pixel data starts. Pixels are grouped into clusters + forming 8 output pixel. Each cluster starts with a variable length of + bits, indicating decompression flags. + + +*/ + +#undef MIN +#undef MAX +#undef LIM + +#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)) + +struct iiq_bitstream_t +{ + uint64_t curr; + uint32_t *input; + uint8_t used; + iiq_bitstream_t(uint32_t *img_input): curr(0),input(img_input),used(0){} + + void fill() + { + if (used <= 32) + { + uint64_t bitpump_next = *input++; + curr = (curr << 32) | bitpump_next; + used += 32; + } + } + uint64_t peek(uint8_t len) + { + if (len >= used) + fill(); + + uint64_t res = curr >> (used - len); + return res & ((1 << (uint8_t)len) - 1); + } + + void consume(uint8_t len) + { + peek(len); // fill buffer if needed + used -= len; + } + + uint64_t get(char len) + { + uint64_t val = peek(len); + consume(len); + return val; + } + +}; + +void decode_S_type(int32_t out_width, uint32_t *img_input, ushort *outbuf /*, int bit_depth*/) +{ +#if 0 + if (((bit_depth - 12) & 0xFFFFFFFD) != 0) + return 0; +#endif + iiq_bitstream_t stream(img_input); + + const int pix_corr_shift = 2; // 16 - bit_depth; + unsigned int bit_check[2] = { 0, 0 }; + + const uint8_t used_corr[8] = { + 3, 3, 3, 3, 1, 1, 1, 1, + }; + + const uint8_t extra_bits[8] = { + 1, 2, 3, 4, 0, 0, 0, 0, + }; + + const uint8_t bit_indicator[8 * 4] = { + 9, 8, 0, 7, 6, 6, 5, 5, 1, 1, 1, 1, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + }; + + const uint8_t skip_bits[8 * 4] = {5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + + int block_count = ((out_width - 8) >> 3) + 1; + int block_total_bytes = 8 * block_count; + + int32_t prev_pix_value[2] = { 0, 0 }; + + uint8_t init_bits = stream.get(16) & 7; + + if (out_width - 7 > 0) + { + uint8_t pix_sub_init = 17 - init_bits; + + for (int blk_id = 0; blk_id < block_count; ++blk_id) + { + int8_t idx_even = stream.peek(7); + stream.consume(2); + + if ((unsigned int)idx_even >= 32) + bit_check[0] = ((unsigned int)idx_even >> 5) + bit_check[0] - 2; + else + { + bit_check[0] = bit_indicator[idx_even]; + stream.consume(skip_bits[idx_even]); + } + + int8_t idx_odd = stream.peek(7); + stream.consume(2); + + if ((unsigned int)idx_odd >= 32) + bit_check[1] = ((unsigned int)idx_odd >> 5) + bit_check[1] - 2; + else + { + bit_check[1] = bit_indicator[idx_odd]; + stream.consume(skip_bits[idx_odd]); + } + + uint8_t bidx = stream.peek(3); + stream.consume(used_corr[bidx]); + + uint8_t take_bits = init_bits + extra_bits[bidx]; // 11 or less + + uint32_t bp_shift[2] = {bit_check[0] - extra_bits[bidx], bit_check[1] - extra_bits[bidx]}; + + int pix_sub[2] = {0xFFFF >> (pix_sub_init - bit_check[0]), 0xFFFF >> (pix_sub_init - bit_check[1])}; + + for (int i = 0; i < 8; i++) // MAIN LOOP for pixel decoding + { + int32_t value = 0; + if (bit_check[i & 1] == 9) + value = stream.get(14); + else + value = prev_pix_value[i & 1] + ((uint32_t)stream.get(take_bits) << bp_shift[i & 1]) - pix_sub[i & 1]; + + outbuf[i] = LIM(value << pix_corr_shift, 0, 0xffff); + prev_pix_value[i & 1] = value; + } + outbuf += 8; // always produce 8 pixels from this cluster + } + } // if width > 7 // End main if + + // Final block + // maybe fill/unpack extra bytes if width % 8 <> 0? + if (block_total_bytes < out_width) + { + do + { + stream.fill(); + uint32_t pix_value = stream.get(14); + ++block_total_bytes; + *outbuf++ = pix_value << pix_corr_shift; + } while (block_total_bytes < out_width); + } +} + +struct p1_row_info_t +{ + unsigned row; + INT64 offset; + p1_row_info_t(): row(0),offset(0){} + p1_row_info_t(const p1_row_info_t& q): row(q.row),offset(q.offset){} + bool operator < (const p1_row_info_t & rhs) const { return offset < rhs.offset; } +}; + +void LibRaw::phase_one_load_raw_s() +{ + if(!libraw_internal_data.unpacker_data.strip_offset || !imgdata.rawdata.raw_image || !libraw_internal_data.unpacker_data.data_offset) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + std::vector stripes(imgdata.sizes.raw_height+1); + libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.strip_offset, SEEK_SET); + for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) + { + stripes[row].row = row; + stripes[row].offset = INT64(get4()) + libraw_internal_data.unpacker_data.data_offset; + } + stripes[imgdata.sizes.raw_height].row = imgdata.sizes.raw_height; + stripes[imgdata.sizes.raw_height].offset = libraw_internal_data.unpacker_data.data_offset + INT64(libraw_internal_data.unpacker_data.data_size); + std::sort(stripes.begin(), stripes.end()); + INT64 maxsz = imgdata.sizes.raw_width * 3 + 2; // theor max: 17 bytes per 8 pix + row header + std::vector datavec(maxsz); + + for (unsigned row = 0; row < imgdata.sizes.raw_height; row++) + { + if (stripes[row].row >= imgdata.sizes.raw_height) continue; + ushort *datap = imgdata.rawdata.raw_image + stripes[row].row * imgdata.sizes.raw_width; + libraw_internal_data.internal_data.input->seek(stripes[row].offset, SEEK_SET); + INT64 readsz = stripes[row + 1].offset - stripes[row].offset; + if (readsz > maxsz) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if(libraw_internal_data.internal_data.input->read(datavec.data(), 1, readsz) != readsz) + derror(); // TODO: check read state + + decode_S_type(imgdata.sizes.raw_width, (uint32_t *)datavec.data(), datap /*, 14 */); + } +} diff --git a/src/decoders/decoders_libraw_dcrdefs.cpp b/src/decoders/decoders_libraw_dcrdefs.cpp new file mode 100644 index 000000000..89d82595b --- /dev/null +++ b/src/decoders/decoders_libraw_dcrdefs.cpp @@ -0,0 +1,411 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::packed_tiled_dng_load_raw() +{ + ushort *rp; + unsigned row, col; + + int ss = shot_select; + shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss, 0, (LIBRAW_IFD_MAXCOUNT * 2 - 1))] & 0xff; + std::vector pixel; + + try + { + int ntiles = 1 + (raw_width) / tile_width; + if ((unsigned)ntiles * tile_width > raw_width * 2u) throw LIBRAW_EXCEPTION_ALLOC; + pixel.resize(tile_width * ntiles * tiff_samples); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } + try + { + unsigned trow = 0, tcol = 0; + INT64 save; + while (trow < raw_height) + { + checkCancel(); + save = ftell(ifp); + if (tile_length < INT_MAX) + fseek(ifp, get4(), SEEK_SET); + + for (row = 0; row < tile_length && (row + trow) < raw_height; row++) + { + if (tiff_bps == 16) + read_shorts(pixel.data(), tile_width * tiff_samples); + else + { + getbits(-1); + for (col = 0; col < tile_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp = pixel.data(), col = 0; col < tile_width; col++) + adobe_copy_pixel(trow+row, tcol+col, &rp); + } + fseek(ifp, save + 4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + } + } + catch (...) + { + shot_select = ss; + throw; + } + shot_select = ss; +} + + + +void LibRaw::sony_ljpeg_load_raw() +{ + unsigned trow = 0, tcol = 0, jrow, jcol, row, col; + INT64 save; + struct jhead jh; + + while (trow < raw_height) + { + checkCancel(); + save = ftell(ifp); // We're at + if (tile_length < INT_MAX) + fseek(ifp, get4(), SEEK_SET); + if (!ljpeg_start(&jh, 0)) + break; + try + { + for (row = jrow = 0; jrow < (unsigned)jh.high; jrow++, row += 2) + { + checkCancel(); + ushort(*rowp)[4] = (ushort(*)[4])ljpeg_row(jrow, &jh); + for (col = jcol = 0; jcol < (unsigned)jh.wide; jcol++, col += 2) + { + RAW(trow + row, tcol + col) = rowp[jcol][0]; + RAW(trow + row, tcol + col + 1) = rowp[jcol][1]; + RAW(trow + row + 1, tcol + col) = rowp[jcol][2]; + RAW(trow + row + 1, tcol + col + 1) = rowp[jcol][3]; + } + } + } + catch (...) + { + ljpeg_end(&jh); + throw; + } + fseek(ifp, save + 4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end(&jh); + } +} + +void LibRaw::nikon_he_load_raw_placeholder() +{ + throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; +} + +void LibRaw::nikon_coolscan_load_raw() +{ + int clrs = colors == 3 ? 3 : 1; + + if (clrs == 3 && !image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if(clrs == 1 && !raw_image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + int bypp = tiff_bps <= 8 ? 1 : 2; + int bufsize = width * clrs * bypp; + unsigned char *buf = (unsigned char *)malloc(bufsize); + unsigned short *ubuf = (unsigned short *)buf; + + if (tiff_bps <= 8) + gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 255); + else + gamma_curve(1.0 / imgdata.rawparams.coolscan_nef_gamma, 0., 1, 65535); + fseek(ifp, data_offset, SEEK_SET); + for (int row = 0; row < raw_height; row++) + { + if(tiff_bps <=8) + fread(buf, 1, bufsize, ifp); + else + read_shorts(ubuf,width*clrs); + + unsigned short(*ip)[4] = (unsigned short(*)[4])image + row * width; + unsigned short *rp = raw_image + row * raw_width; + + if (is_NikonTransfer == 2) + { // it is also (tiff_bps == 8) + if (clrs == 3) + { + for (int col = 0; col < width; col++) + { + ip[col][0] = ((float)curve[buf[col * 3]]) / 255.0f; + ip[col][1] = ((float)curve[buf[col * 3 + 1]]) / 255.0f; + ip[col][2] = ((float)curve[buf[col * 3 + 2]]) / 255.0f; + ip[col][3] = 0; + } + } + else + { + for (int col = 0; col < width; col++) + rp[col] = ((float)curve[buf[col]]) / 255.0f; + } + } + else if (tiff_bps <= 8) + { + if (clrs == 3) + { + for (int col = 0; col < width; col++) + { + ip[col][0] = curve[buf[col * 3]]; + ip[col][1] = curve[buf[col * 3 + 1]]; + ip[col][2] = curve[buf[col * 3 + 2]]; + ip[col][3] = 0; + } + } + else + { + for (int col = 0; col < width; col++) + rp[col] = curve[buf[col]]; + } + } + else + { + if (clrs == 3) + { + for (int col = 0; col < width; col++) + { + ip[col][0] = curve[ubuf[col * 3]]; + ip[col][1] = curve[ubuf[col * 3 + 1]]; + ip[col][2] = curve[ubuf[col * 3 + 2]]; + ip[col][3] = 0; + } + } + else + { + for (int col = 0; col < width; col++) + rp[col] = curve[ubuf[col]]; + } + } + } + free(buf); +} + +void LibRaw::broadcom_load_raw() +{ + uchar *dp; + int rev, row, col, c; + rev = 3 * (order == 0x4949); + std::vector data(raw_stride * 2); + + for (row = 0; row < raw_height; row++) + { + if (fread(data.data() + raw_stride, 1, raw_stride, ifp) < raw_stride) + derror(); + FORC(raw_stride) data[c] = data[raw_stride + (c ^ rev)]; + for (dp = data.data(), col = 0; col < raw_width; dp += 5, col += 4) + FORC4 RAW(row, col + c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + } +} + +void LibRaw::android_tight_load_raw() +{ + uchar *data, *dp; + int bwide, row, col, c; + + bwide = -(-5 * raw_width >> 5) << 3; + data = (uchar *)malloc(bwide); + for (row = 0; row < raw_height; row++) + { + if (fread(data, 1, bwide, ifp) < bwide) + derror(); + 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); +} + +void LibRaw::android_loose_load_raw() +{ + uchar *data, *dp; + int bwide, row, col, c; + UINT64 bitbuf = 0; + + bwide = (raw_width + 5) / 6 << 3; + data = (uchar *)malloc(bwide); + for (row = 0; row < raw_height; row++) + { + if (fread(data, 1, bwide, ifp) < bwide) + derror(); + for (dp = data, col = 0; col < raw_width; dp += 8, col += 6) + { + FORC(8) bitbuf = (bitbuf << 8) | dp[c ^ 7]; + FORC(6) RAW(row, col + c) = (bitbuf >> c * 10) & 0x3ff; + } + } + free(data); +} + +void LibRaw::unpacked_load_raw_reversed() +{ + int row, col, bits = 0; + while (1 << ++bits < (int)maximum) + ; + for (row = raw_height - 1; row >= 0; row--) + { + checkCancel(); + read_shorts(&raw_image[row * raw_width], raw_width); + 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(); + } +} + +#ifdef USE_6BY9RPI + +void LibRaw::rpi_load_raw8() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[] = { 0,0 }; + rev = 3 * (order == 0x4949); + if (raw_stride == 0) + dwide = raw_width; + else + dwide = raw_stride; + data = (uchar *)malloc(dwide * 2); + 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++, col++) + RAW(row, col + c) = dp[c]; + } + free(data); + maximum = 0xff; + if (!strcmp(make, "OmniVision") || + !strcmp(make, "Sony") || + !strcmp(make, "RaspberryPi")) return; + + row = raw_height / 2; + FORC(width - 1) { + sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); + sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +void LibRaw::rpi_load_raw12() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[] = { 0,0 }; + rev = 3 * (order == 0x4949); + if (raw_stride == 0) + dwide = (raw_width * 3 + 1) / 2; + else + dwide = raw_stride; + data = (uchar *)malloc(dwide * 2); + 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 += 3, col += 2) + FORC(2) RAW(row, col + c) = (dp[c] << 4) | (dp[2] >> (c << 2) & 0xF); + } + free(data); + maximum = 0xfff; + if (!strcmp(make, "OmniVision") || + !strcmp(make, "Sony") || + !strcmp(make, "RaspberryPi")) return; + + row = raw_height / 2; + FORC(width - 1) { + sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); + sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +void LibRaw::rpi_load_raw14() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[] = { 0,0 }; + rev = 3 * (order == 0x4949); + if (raw_stride == 0) + dwide = ((raw_width * 7) + 3) >> 2; + else + dwide = raw_stride; + data = (uchar *)malloc(dwide * 2); + 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 += 7, col += 4) { + RAW(row, col + 0) = (dp[0] << 6) | (dp[4] >> 2); + RAW(row, col + 1) = (dp[1] << 6) | ((dp[4] & 0x3) << 4) | ((dp[5] & 0xf0) >> 4); + RAW(row, col + 2) = (dp[2] << 6) | ((dp[5] & 0xf) << 2) | ((dp[6] & 0xc0) >> 6); + RAW(row, col + 3) = (dp[3] << 6) | ((dp[6] & 0x3f) << 2); + } + } + free(data); + maximum = 0x3fff; + if (!strcmp(make, "OmniVision") || + !strcmp(make, "Sony") || + !strcmp(make, "RaspberryPi")) return; + + row = raw_height / 2; + FORC(width - 1) { + sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); + sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +void LibRaw::rpi_load_raw16() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[] = { 0,0 }; + rev = 3 * (order == 0x4949); + if (raw_stride == 0) + dwide = (raw_width * 2); + else + dwide = raw_stride; + data = (uchar *)malloc(dwide * 2); + 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 += 2, col++) + RAW(row, col + c) = (dp[1] << 8) | dp[0]; + } + free(data); + maximum = 0xffff; + if (!strcmp(make, "OmniVision") || + !strcmp(make, "Sony") || + !strcmp(make, "RaspberryPi")) return; + + row = raw_height / 2; + FORC(width - 1) { + sum[c & 1] += SQR(RAW(row, c) - RAW(row + 1, c + 1)); + sum[~c & 1] += SQR(RAW(row + 1, c) - RAW(row, c + 1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +#endif diff --git a/src/decoders/dng.cpp b/src/decoders/dng.cpp new file mode 100644 index 000000000..89537a540 --- /dev/null +++ b/src/decoders/dng.cpp @@ -0,0 +1,278 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::vc5_dng_load_raw_placeholder() +{ + // placeholder only, real decoding implemented in GPR SDK + throw LIBRAW_EXCEPTION_DECODE_RAW; +} + +void LibRaw::adobe_copy_pixel(unsigned row, unsigned col, ushort **rp) +{ + int c; + + if (tiff_samples == 2 && shot_select) + (*rp)++; + if (raw_image) + { + if (row < raw_height && col < raw_width) + RAW(row, col) = curve[**rp]; + *rp += tiff_samples; + } + else + { + if (row < raw_height && col < raw_width) + FORC(int(tiff_samples)) + image[row * raw_width + col][c] = curve[(*rp)[c]]; + *rp += tiff_samples; + } + if (tiff_samples == 2 && shot_select) + (*rp)--; +} +void LibRaw::lossless_dng_load_raw() +{ + unsigned trow = 0, tcol = 0, jwide, jrow, jcol, row, col, i, j; + INT64 save; + struct jhead jh; + ushort *rp; + + int ss = shot_select; + shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff; + + while (trow < raw_height) + { + checkCancel(); + 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; + + if(filters && (tiff_samples == 2)) // Fuji Super CCD + jwide /= 2; + try + { + switch (jh.algo) + { + case 0xc1: + jh.vpred[0] = 16384; + getbits(-1); + for (jrow = 0; jrow + 7 < (unsigned)jh.high; jrow += 8) + { + checkCancel(); + for (jcol = 0; jcol + 7 < (unsigned)jh.wide; jcol += 8) + { + ljpeg_idct(&jh); + rp = jh.idct; + row = trow + jcol / tile_width + jrow * 2; + col = tcol + jcol % tile_width; + for (i = 0; i < 16; i += 2) + for (j = 0; j < 8; j++) + adobe_copy_pixel(row + i, col + j, &rp); + } + } + break; + case 0xc3: + for (row = col = jrow = 0; jrow < (unsigned)jh.high; jrow++) + { + checkCancel(); + rp = ljpeg_row(jrow, &jh); + if (tiff_samples == 1 && jh.clrs > 1 && jh.clrs * jwide == raw_width) + for (jcol = 0; jcol < jwide * jh.clrs; jcol++) + { + adobe_copy_pixel(trow + row, tcol + col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + else + 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); + } + } + } + } + catch (...) + { + ljpeg_end(&jh); + shot_select = ss; + throw; + } + fseek(ifp, save + 4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end(&jh); + } + shot_select = ss; +} + +void LibRaw::packed_dng_load_raw() +{ + ushort *pixel, *rp; + unsigned row, col; + + if (tile_length < INT_MAX) + { + packed_tiled_dng_load_raw(); + return; + } + + int ss = shot_select; + shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff; + + pixel = (ushort *)calloc(raw_width, tiff_samples * sizeof *pixel); + try + { + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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); + } + } + catch (...) + { + free(pixel); + shot_select = ss; + throw; + } + free(pixel); + shot_select = ss; +} +#ifdef NO_JPEG +void LibRaw::lossy_dng_load_raw() {} +#else + +static void jpegErrorExit_d(j_common_ptr /*cinfo*/) +{ + throw LIBRAW_EXCEPTION_DECODE_JPEG; +} + +void LibRaw::lossy_dng_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + struct jpeg_decompress_struct cinfo; + JSAMPARRAY buf; + JSAMPLE(*pixel)[3]; + unsigned sorder = order, ntags, opcode, deg, i, j, c; + unsigned trow = 0, tcol = 0, row, col; + INT64 save = data_offset - 4; + ushort cur[3][256]; + double coeff[9], tot; + + if (meta_offset) + { + fseek(ifp, meta_offset, SEEK_SET); + order = 0x4d4d; + ntags = get4(); + while (ntags--) + { + opcode = get4(); + get4(); + get4(); + if (opcode != 8) + { + fseek(ifp, get4(), SEEK_CUR); + continue; + } + fseek(ifp, 20, SEEK_CUR); + if ((c = get4()) > 2) + break; + fseek(ifp, 12, SEEK_CUR); + if ((deg = get4()) > 8) + break; + for (i = 0; i <= deg && i < 9; i++) + coeff[i] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); + for (i = 0; i < 256; i++) + { + for (tot = j = 0; j <= deg; j++) + tot += coeff[j] * pow(i / 255.0, (int)j); + cur[c][i] = (ushort)(tot * 0xffff); + } + } + order = sorder; + } + else + { + gamma_curve(1 / 2.4, 12.92, 1, 255); + FORC3 memcpy(cur[c], curve, sizeof cur[0]); + } + + struct jpeg_error_mgr pub; + cinfo.err = jpeg_std_error(&pub); + pub.error_exit = jpegErrorExit_d; + + jpeg_create_decompress(&cinfo); + + while (trow < raw_height) + { + fseek(ifp, save += 4, SEEK_SET); + if (tile_length < INT_MAX) + fseek(ifp, get4(), SEEK_SET); + if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1) + { + jpeg_destroy_decompress(&cinfo); + throw LIBRAW_EXCEPTION_DECODE_JPEG; + } + 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); + try + { + while (cinfo.output_scanline < cinfo.output_height && + (row = trow + cinfo.output_scanline) < height) + { + checkCancel(); + jpeg_read_scanlines(&cinfo, buf, 1); + pixel = (JSAMPLE(*)[3])buf[0]; + for (col = 0; col < cinfo.output_width && tcol + col < width; col++) + { + FORC3 image[row * width + tcol + col][c] = cur[c][pixel[col][c]]; + } + } + } + catch (...) + { + jpeg_destroy_decompress(&cinfo); + throw; + } + jpeg_abort_decompress(&cinfo); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + } + jpeg_destroy_decompress(&cinfo); + maximum = 0xffff; +} +#endif diff --git a/src/decoders/fp_dng.cpp b/src/decoders/fp_dng.cpp new file mode 100644 index 000000000..0566ad2ca --- /dev/null +++ b/src/decoders/fp_dng.cpp @@ -0,0 +1,689 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +inline unsigned int __DNG_HalfToFloat(ushort halfValue) +{ + int sign = (halfValue >> 15) & 0x00000001; + int exponent = (halfValue >> 10) & 0x0000001f; + int mantissa = halfValue & 0x000003ff; + if (exponent == 0) + { + if (mantissa == 0) + { + return (unsigned int)(sign << 31); + } + else + { + while (!(mantissa & 0x00000400)) + { + mantissa <<= 1; + exponent -= 1; + } + exponent += 1; + mantissa &= ~0x00000400; + } + } + else if (exponent == 31) + { + if (mantissa == 0) + { + return (unsigned int)((sign << 31) | ((0x1eL + 127 - 15) << 23) | + (0x3ffL << 13)); + } + else + { + return 0; + } + } + exponent += (127 - 15); + mantissa <<= 13; + return (unsigned int)((sign << 31) | (exponent << 23) | mantissa); +} + +inline unsigned int __DNG_FP24ToFloat(const unsigned char *input) +{ + int sign = (input[0] >> 7) & 0x01; + int exponent = (input[0]) & 0x7F; + int mantissa = (((int)input[1]) << 8) | input[2]; + if (exponent == 0) + { + if (mantissa == 0) + { + return (unsigned int)(sign << 31); + } + else + { + while (!(mantissa & 0x00010000)) + { + mantissa <<= 1; + exponent -= 1; + } + exponent += 1; + mantissa &= ~0x00010000; + } + } + else if (exponent == 127) + { + if (mantissa == 0) + { + return (unsigned int)((sign << 31) | ((0x7eL + 128 - 64) << 23) | + (0xffffL << 7)); + } + else + { + // Nan -- Just set to zero. + return 0; + } + } + exponent += (128 - 64); + mantissa <<= 7; + return (uint32_t)((sign << 31) | (exponent << 23) | mantissa); +} + +inline void DecodeDeltaBytes(unsigned char *bytePtr, int cols, int channels) +{ + if (channels == 1) + { + unsigned char b0 = bytePtr[0]; + bytePtr += 1; + for (int col = 1; col < cols; ++col) + { + b0 += bytePtr[0]; + bytePtr[0] = b0; + bytePtr += 1; + } + } + else if (channels == 3) + { + unsigned char b0 = bytePtr[0]; + unsigned char b1 = bytePtr[1]; + unsigned char b2 = bytePtr[2]; + bytePtr += 3; + for (int col = 1; col < cols; ++col) + { + b0 += bytePtr[0]; + b1 += bytePtr[1]; + b2 += bytePtr[2]; + bytePtr[0] = b0; + bytePtr[1] = b1; + bytePtr[2] = b2; + bytePtr += 3; + } + } + else if (channels == 4) + { + unsigned char b0 = bytePtr[0]; + unsigned char b1 = bytePtr[1]; + unsigned char b2 = bytePtr[2]; + unsigned char b3 = bytePtr[3]; + bytePtr += 4; + for (int col = 1; col < cols; ++col) + { + b0 += bytePtr[0]; + b1 += bytePtr[1]; + b2 += bytePtr[2]; + b3 += bytePtr[3]; + bytePtr[0] = b0; + bytePtr[1] = b1; + bytePtr[2] = b2; + bytePtr[3] = b3; + bytePtr += 4; + } + } + else + { + for (int col = 1; col < cols; ++col) + { + for (int chan = 0; chan < channels; ++chan) + { + bytePtr[chan + channels] += bytePtr[chan]; + } + bytePtr += channels; + } + } +} + +#ifdef USE_ZLIB +static void DecodeFPDelta(unsigned char *input, unsigned char *output, int cols, + int channels, int bytesPerSample) +{ + DecodeDeltaBytes(input, cols * bytesPerSample, channels); + int32_t rowIncrement = cols * channels; + + if (bytesPerSample == 2) + { + +#if LibRawBigEndian + const unsigned char *input0 = input; + const unsigned char *input1 = input + rowIncrement; +#else + const unsigned char *input1 = input; + const unsigned char *input0 = input + rowIncrement; +#endif + for (int col = 0; col < rowIncrement; ++col) + { + output[0] = input0[col]; + output[1] = input1[col]; + output += 2; + } + } + else if (bytesPerSample == 3) + { + const unsigned char *input0 = input; + const unsigned char *input1 = input + rowIncrement; + const unsigned char *input2 = input + rowIncrement * 2; + for (int col = 0; col < rowIncrement; ++col) + { + output[0] = input0[col]; + output[1] = input1[col]; + output[2] = input2[col]; + output += 3; + } + } + else + { +#if LibRawBigEndian + const unsigned char *input0 = input; + const unsigned char *input1 = input + rowIncrement; + const unsigned char *input2 = input + rowIncrement * 2; + const unsigned char *input3 = input + rowIncrement * 3; +#else + const unsigned char *input3 = input; + const unsigned char *input2 = input + rowIncrement; + const unsigned char *input1 = input + rowIncrement * 2; + const unsigned char *input0 = input + rowIncrement * 3; +#endif + for (int col = 0; col < rowIncrement; ++col) + { + output[0] = input0[col]; + output[1] = input1[col]; + output[2] = input2[col]; + output[3] = input3[col]; + output += 4; + } + } +} +#endif + +static float expandFloats(unsigned char *dst, int tileWidth, int bytesps) +{ + float max = 0.f; + if (bytesps == 2) + { + uint16_t *dst16 = (ushort *)dst; + uint32_t *dst32 = (unsigned int *)dst; + float *f32 = (float *)dst; + for (int index = tileWidth - 1; index >= 0; --index) + { + dst32[index] = __DNG_HalfToFloat(dst16[index]); + max = MAX(max, f32[index]); + } + } + else if (bytesps == 3) + { + uint8_t *dst8 = ((unsigned char *)dst) + (tileWidth - 1) * 3; + uint32_t *dst32 = (unsigned int *)dst; + float *f32 = (float *)dst; + for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3) + { + dst32[index] = __DNG_FP24ToFloat(dst8); + max = MAX(max, f32[index]); + } + } + else if (bytesps == 4) + { + float *f32 = (float *)dst; + for (int index = 0; index < tileWidth; index++) + max = MAX(max, f32[index]); + } + return max; +} + +struct tile_stripe_data_t +{ + bool tiled, striped; + int tileCnt; + unsigned tileWidth, tileHeight, tilesH, tilesV; + size_t maxBytesInTile; + std::vector tOffsets, tBytes; + tile_stripe_data_t() : tiled(false), striped(false),tileCnt(0), + tileWidth(0),tileHeight(0),tilesH(0),tilesV(0), + maxBytesInTile(0){} + void init(tiff_ifd_t *ifd, const libraw_image_sizes_t&, const unpacker_data_t&, + short _order, + LibRaw_abstract_datastream *stream); +}; + +static unsigned static_get4(LibRaw_abstract_datastream *stream, short _order) +{ + uchar str[4] = { 0xff, 0xff, 0xff, 0xff }; + stream->read(str, 1, 4); + return libraw_sget4_static(_order, str); +} + + +void tile_stripe_data_t::init(tiff_ifd_t *ifd, const libraw_image_sizes_t& sizes, + const unpacker_data_t& unpacker_data, short _order, LibRaw_abstract_datastream *stream) +{ + tiled = (unpacker_data.tile_width <= sizes.raw_width) && (unpacker_data.tile_length <= sizes.raw_height); + striped = (ifd->rows_per_strip > 0 && ifd->rows_per_strip < sizes.raw_height) && ifd->strip_byte_counts_count > 0; + + tileWidth = tiled ? unpacker_data.tile_width : sizes.raw_width; + tileHeight = tiled ? unpacker_data.tile_length :(striped ? ifd->rows_per_strip : sizes.raw_height); + tilesH = tiled ? (sizes.raw_width + tileWidth - 1) / tileWidth : 1; + tilesV = tiled ? (sizes.raw_height + tileHeight - 1) / tileHeight : + (striped ? ((sizes.raw_height + ifd->rows_per_strip - 1) / ifd->rows_per_strip) : 1); + tileCnt = tilesH * tilesV; + + if (tileCnt < 1 || tileCnt > 1000000) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + tOffsets = std::vector(tileCnt); + tBytes = std::vector (tileCnt); + + if (tiled) + for (int t = 0; t < tileCnt; ++t) + tOffsets[t] = static_get4(stream, _order); + else if (striped) + for (int t = 0; t < tileCnt && t < ifd->strip_offsets_count; ++t) + tOffsets[t] = ifd->strip_offsets[t]; + else + tOffsets[0] = ifd->offset; + + maxBytesInTile = 0; + + if (tileCnt == 1 || (!tiled && !striped)) + tBytes[0] = maxBytesInTile = ifd->bytes; + else if (tiled) + { + // ifd->bytes points to tile size table if more than 1 tile exists + stream->seek(ifd->bytes, SEEK_SET); + for (int t = 0; t < tileCnt; ++t) + { + tBytes[t] = static_get4(stream, _order); ; + maxBytesInTile = MAX(maxBytesInTile, tBytes[t]); + } + } + else if (striped) + for (int t = 0; t < tileCnt && t < ifd->strip_byte_counts_count; ++t) + { + tBytes[t] = ifd->strip_byte_counts[t]; + maxBytesInTile = MAX(maxBytesInTile, tBytes[t]); + } +} + +#ifdef USE_ZLIB +void LibRaw::deflate_dng_load_raw() +{ + int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset); + if(iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds) + throw LIBRAW_EXCEPTION_DECODE_RAW; + struct tiff_ifd_t *ifd = &tiff_ifd[iifd]; + + float *float_raw_image = 0; + float max = 0.f; + + if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + if (libraw_internal_data.unpacker_data.tiff_samples != (unsigned)ifd->samples) + throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD + + if (imgdata.idata.filters && ifd->samples > 1) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + tile_stripe_data_t tiles; + tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order, + libraw_internal_data.internal_data.input); + + if (ifd->sample_format == 3) + float_raw_image = (float *)calloc(tiles.tileCnt * tiles.tileWidth * tiles.tileHeight *ifd->samples, sizeof(float)); + else + throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported + + int xFactor; + switch (ifd->predictor) + { + case 3: + default: + xFactor = 1; + break; + case 34894: + xFactor = 2; + break; + case 34895: + xFactor = 4; + break; + } + + unsigned tilePixels = tiles.tileWidth * tiles.tileHeight; + unsigned pixelSize = sizeof(float) * ifd->samples; + unsigned tileBytes = tilePixels * pixelSize; + unsigned tileRowBytes = tiles.tileWidth * pixelSize; + + if(INT64(tiles.maxBytesInTile) > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024) ) + throw LIBRAW_EXCEPTION_TOOBIG; + + std::vector cBuffer(tiles.maxBytesInTile); + std::vector uBuffer(tileBytes + tileRowBytes); // extra row for decoding + + for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight) + { + for (size_t x = 0; x < imgdata.sizes.raw_width; x += tiles.tileWidth, ++t) + { + libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET); + libraw_internal_data.internal_data.input->read(cBuffer.data(), 1, tiles.tBytes[t]); + unsigned long dstLen = tileBytes; + int err = + uncompress(uBuffer.data() + tileRowBytes, &dstLen, cBuffer.data(), (unsigned long)tiles.tBytes[t]); + if (err != Z_OK) + { + throw LIBRAW_EXCEPTION_DECODE_RAW; + return; + } + else + { + int bytesps = ifd->bps >> 3; + size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight; + size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth; + + for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed + { + unsigned char *dst = uBuffer.data() + row * tiles.tileWidth * bytesps * ifd->samples; + unsigned char *src = dst + tileRowBytes; + DecodeFPDelta(src, dst, tiles.tileWidth / xFactor, ifd->samples * xFactor, bytesps); + float lmax = expandFloats(dst, tiles.tileWidth * ifd->samples, bytesps); + max = MAX(max, lmax); + unsigned char *dst2 = (unsigned char *)&float_raw_image + [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples]; + memmove(dst2, dst, colsInTile * ifd->samples * sizeof(float)); + } + } + } + } + + imgdata.color.fmaximum = max; + + // Set fields according to data format + + imgdata.rawdata.raw_alloc = float_raw_image; + if (ifd->samples == 1) + { + imgdata.rawdata.float_image = float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 4; + } + else if (ifd->samples == 3) + { + imgdata.rawdata.float3_image = (float(*)[3])float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 12; + } + else if (ifd->samples == 4) + { + imgdata.rawdata.float4_image = (float(*)[4])float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 16; + } + + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT) + convertFloatToInt(); // with default settings +} +#else +void LibRaw::deflate_dng_load_raw() { throw LIBRAW_EXCEPTION_DECODE_RAW; } +#endif + +int LibRaw::is_floating_point() +{ + struct tiff_ifd_t *ifd = &tiff_ifd[0]; + while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] && + ifd->offset != libraw_internal_data.unpacker_data.data_offset) + ++ifd; + if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds]) + return 0; + + return ifd->sample_format == 3; +} + +int LibRaw::have_fpdata() +{ + return imgdata.rawdata.float_image || imgdata.rawdata.float3_image || + imgdata.rawdata.float4_image; +} + +void LibRaw::convertFloatToInt(float dmin /* =4096.f */, + float dmax /* =32767.f */, + float dtarget /*= 16383.f */) +{ + int samples = 0; + float *data = 0; + void *orawalloc = imgdata.rawdata.raw_alloc; + if (imgdata.rawdata.float_image) + { + samples = 1; + data = imgdata.rawdata.float_image; + } + else if (imgdata.rawdata.float3_image) + { + samples = 3; + data = (float *)imgdata.rawdata.float3_image; + } + else if (imgdata.rawdata.float4_image) + { + samples = 4; + data = (float *)imgdata.rawdata.float4_image; + } + else + return; + + ushort *raw_alloc = (ushort *)malloc( + imgdata.sizes.raw_height * imgdata.sizes.raw_width * + libraw_internal_data.unpacker_data.tiff_samples * sizeof(ushort)); + float tmax = MAX(imgdata.color.maximum, 1); + float datamax = imgdata.color.fmaximum; + + tmax = MAX(tmax, datamax); + tmax = MAX(tmax, 1.f); + + float multip = 1.f; + if (tmax < dmin || tmax > dmax) + { + imgdata.rawdata.color.fnorm = imgdata.color.fnorm = multip = dtarget / tmax; + imgdata.rawdata.color.maximum = imgdata.color.maximum = dtarget; + imgdata.rawdata.color.black = imgdata.color.black = + (float)imgdata.color.black * multip; + for (int i = 0; + i < int(sizeof(imgdata.color.cblack)/sizeof(imgdata.color.cblack[0])); + i++) + if (i != 4 && i != 5) + imgdata.rawdata.color.cblack[i] = imgdata.color.cblack[i] = + (float)imgdata.color.cblack[i] * multip; + } + else + imgdata.rawdata.color.fnorm = imgdata.color.fnorm = 0.f; + + for (size_t i = 0; i < imgdata.sizes.raw_height * imgdata.sizes.raw_width * + libraw_internal_data.unpacker_data.tiff_samples; + ++i) + { + float val = MAX(data[i], 0.f); + raw_alloc[i] = (ushort)(val * multip); + } + + if (samples == 1) + { + imgdata.rawdata.raw_alloc = imgdata.rawdata.raw_image = raw_alloc; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 2; + } + else if (samples == 3) + { + imgdata.rawdata.raw_alloc = imgdata.rawdata.color3_image = + (ushort(*)[3])raw_alloc; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 6; + } + else if (samples == 4) + { + imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image = + (ushort(*)[4])raw_alloc; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 8; + } + if(orawalloc) + free(orawalloc); // remove old allocation + imgdata.rawdata.float_image = 0; + imgdata.rawdata.float3_image = 0; + imgdata.rawdata.float4_image = 0; +} + +static +#if (defined(_MSC_VER) && !defined(__clang__)) +_forceinline +#else +inline +#endif +void swap24(uchar *data, int len) +{ + for (int i = 0; i < len - 2; i += 3) + { + uchar t = data[i]; + data[i] = data[i + 2]; + data[i + 2] = t; + } +} + +static +#if (defined(_MSC_VER) && !defined(__clang__)) +_forceinline +#else +inline +#endif +void swap32(uchar *data, int len) +{ + unsigned *d = (unsigned*)data; + for (int i = 0; i < len / 4; i++) + { + unsigned x = d[i]; + d[i] = (x << 24) + ((x << 8) & 0x00FF0000) + + ((x >> 8) & 0x0000FF00) + (x >> 24); + } +} + + +void LibRaw::uncompressed_fp_dng_load_raw() +{ + int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset); + if (iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds) + throw LIBRAW_EXCEPTION_DECODE_RAW; + struct tiff_ifd_t *ifd = &tiff_ifd[iifd]; + + float *float_raw_image = 0; + + if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + if(imgdata.idata.filters && ifd->samples > 1) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + if ((int)libraw_internal_data.unpacker_data.tiff_samples != ifd->samples) + throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD + + int bytesps = (ifd->bps + 7) >> 3; // round to upper value + + if(bytesps < 1 || bytesps > 4) + throw LIBRAW_EXCEPTION_DECODE_RAW; + + tile_stripe_data_t tiles; + tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order, + libraw_internal_data.internal_data.input); + + INT64 allocsz = INT64(tiles.tileCnt) * INT64(tiles.tileWidth) * INT64(tiles.tileHeight) * INT64(ifd->samples) * INT64(sizeof(float)); + if (allocsz > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + if (ifd->sample_format == 3) + float_raw_image = (float *)calloc(tiles.tileCnt * tiles.tileWidth * tiles.tileHeight *ifd->samples, sizeof(float)); + else + throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float supported + + bool difford = (libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234); + float max = 0.f; + + std::vector rowbuf(tiles.tileWidth *sizeof(float) * ifd->samples); // line buffer for last tile in tile row + + for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight) + { + for (unsigned x = 0; x < imgdata.sizes.raw_width && t < (unsigned)tiles.tileCnt; x += tiles.tileWidth, ++t) + { + libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET); + size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight; + size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth; + + size_t inrowbytes = colsInTile * bytesps * ifd->samples; + int fullrowbytes = tiles.tileWidth *bytesps * ifd->samples; + size_t outrowbytes = colsInTile * sizeof(float) * ifd->samples; + + for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed + { + unsigned char *dst = fullrowbytes > inrowbytes ? rowbuf.data(): // last tile in row, use buffer + (unsigned char *)&float_raw_image + [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples]; + libraw_internal_data.internal_data.input->read(dst, 1, fullrowbytes); + if (bytesps == 2 && difford) + libraw_swab(dst, fullrowbytes); + else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit + swap24(dst, fullrowbytes); + if (bytesps == 4 && difford) + swap32(dst, fullrowbytes); + + float lmax = expandFloats( + dst, + tiles.tileWidth * ifd->samples, + bytesps); + if (fullrowbytes > inrowbytes) // last tile in row: copy buffer to destination + memmove(&float_raw_image[((y + row) * imgdata.sizes.raw_width + x) * ifd->samples], dst, outrowbytes); + max = MAX(max, lmax); + } + } + } + + imgdata.color.fmaximum = max; + + // setup outpuf fields + imgdata.rawdata.raw_alloc = float_raw_image; + if (ifd->samples == 1) + { + imgdata.rawdata.float_image = float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 4; + } + else if (ifd->samples == 3) + { + imgdata.rawdata.float3_image = (float(*)[3])float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 12; + } + else if (ifd->samples == 4) + { + imgdata.rawdata.float4_image = (float(*)[4])float_raw_image; + imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch = + imgdata.sizes.raw_width * 16; + } + + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT) + convertFloatToInt(); +} diff --git a/src/decoders/fuji_compressed.cpp b/src/decoders/fuji_compressed.cpp new file mode 100644 index 000000000..9ca82f6e4 --- /dev/null +++ b/src/decoders/fuji_compressed.cpp @@ -0,0 +1,1210 @@ +/* -*- C++ -*- + * File: libraw_fuji_compressed.cpp + * Copyright (C) 2016-2019 Alexey Danilchenko + * + * Adopted to LibRaw by Alex Tutubalin, lexa@lexa.ru + * LibRaw Fujifilm/compressed decoder + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#ifdef _abs +#undef _abs +#undef _min +#undef _max +#endif +#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)) + +struct int_pair +{ + int value1; + int value2; +}; + +enum _xt_lines +{ + _R0 = 0, + _R1, + _R2, + _R3, + _R4, + _G0, + _G1, + _G2, + _G3, + _G4, + _G5, + _G6, + _G7, + _B0, + _B1, + _B2, + _B3, + _B4, + _ltotal +}; + +// tables of gradients for single sample level +struct fuji_grads +{ + int_pair grads[41]; + int_pair lossy_grads[3][5]; +}; + +struct fuji_compressed_block +{ + int cur_bit; // current bit being read (from left to right) + int cur_pos; // current position in a buffer + INT64 cur_buf_offset; // offset of this buffer in a file + unsigned max_read_size; // Amount of data to be read + int cur_buf_size; // buffer size + uchar *cur_buf; // currently read block + int fillbytes; // Counter to add extra byte for block size N*16 + LibRaw_abstract_datastream *input; + fuji_grads even[3]; // tables of even gradients + fuji_grads odd[3]; // tables of odd gradients + ushort *linealloc; + ushort *linebuf[_ltotal]; +}; + +static inline int log2ceil(int val) +{ + int result = 0; + if (val--) + do + ++result; + while (val >>= 1); + + return result; +} + +void setup_qlut(int8_t *qt, int *q_point) +{ + for (int curVal = -q_point[4]; curVal <= q_point[4]; ++qt, ++curVal) + { + if (curVal <= -q_point[3]) + *qt = -4; + else if (curVal <= -q_point[2]) + *qt = -3; + else if (curVal <= -q_point[1]) + *qt = -2; + else if (curVal < -q_point[0]) + *qt = -1; + else if (curVal <= q_point[0]) + *qt = 0; + else if (curVal < q_point[1]) + *qt = 1; + else if (curVal < q_point[2]) + *qt = 2; + else if (curVal < q_point[3]) + *qt = 3; + else + *qt = 4; + } +} + +void init_main_qtable(fuji_compressed_params *params, uchar q_base) +{ + fuji_q_table *qt = params->qt; + int qp[5]; + int maxVal = params->max_value + 1; + qp[0] = q_base; + qp[1] = 3 * q_base + 0x12; + qp[2] = 5 * q_base + 0x43; + qp[3] = 7 * q_base + 0x114; + qp[4] = params->max_value; + if (qp[1] >= maxVal || qp[1] < q_base + 1) + qp[1] = q_base + 1; + if (qp[2] < qp[1] || qp[2] >= maxVal) + qp[2] = qp[1]; + if (qp[3] < qp[2] || qp[3] >= maxVal) + qp[3] = qp[2]; + setup_qlut(qt->q_table, qp); + qt->q_base = q_base; + qt->max_grad = 0; + qt->total_values = (qp[4] + 2 * q_base) / (2 * q_base + 1) + 1; + qt->raw_bits = log2ceil(qt->total_values); + qt->q_grad_mult = 9; + params->max_bits = 4 * log2ceil(qp[4] + 1); +} + +void LibRaw::init_fuji_compr(fuji_compressed_params *params) +{ + if ((libraw_internal_data.unpacker_data.fuji_block_width % 3 && + libraw_internal_data.unpacker_data.fuji_raw_type == 16) || + (libraw_internal_data.unpacker_data.fuji_block_width & 1 && + libraw_internal_data.unpacker_data.fuji_raw_type == 0)) + derror(); + + size_t q_table_size = 2 << libraw_internal_data.unpacker_data.fuji_bits; + if (libraw_internal_data.unpacker_data.fuji_lossless) + params->buf = malloc(q_table_size); + else + params->buf = malloc(3 * q_table_size); + + if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) + params->line_width = (libraw_internal_data.unpacker_data.fuji_block_width * 2) / 3; + else + params->line_width = libraw_internal_data.unpacker_data.fuji_block_width >> 1; + + params->min_value = 0x40; + params->max_value = (1 << libraw_internal_data.unpacker_data.fuji_bits) - 1; + + // setup qtables + if (libraw_internal_data.unpacker_data.fuji_lossless) + { + // setup main qtable only, zero the rest + memset(params->qt + 1, 0, 3 * sizeof(fuji_q_table)); + params->qt[0].q_table = (int8_t *)params->buf; + params->qt[0].q_base = -1; + init_main_qtable(params, 0); + } + else + { + // setup 3 extra qtables - main one will be set for each block + memset(params->qt, 0, sizeof(fuji_q_table)); + int qp[5]; + + qp[0] = 0; + qp[4] = params->max_value; + + // table 0 + params->qt[1].q_table = (int8_t *)params->buf; + params->qt[1].q_base = 0; + params->qt[1].max_grad = 5; + params->qt[1].q_grad_mult = 3; + params->qt[1].total_values = qp[4] + 1; + params->qt[1].raw_bits = log2ceil(params->qt[1].total_values); + + qp[1] = qp[4] >= 0x12 ? 0x12 : qp[0] + 1; + qp[2] = qp[4] >= 0x43 ? 0x43 : qp[1]; + qp[3] = qp[4] >= 0x114 ? 0x114 : qp[2]; + setup_qlut(params->qt[1].q_table, qp); + + // table 1 + params->qt[2].q_table = params->qt[1].q_table + q_table_size; + params->qt[2].q_base = 1; + params->qt[2].max_grad = 6; + params->qt[2].q_grad_mult = 3; + params->qt[2].total_values = (qp[4] + 2) / 3 + 1; + params->qt[2].raw_bits = log2ceil(params->qt[2].total_values); + + qp[0] = params->qt[2].q_base; + qp[1] = qp[4] >= 0x15 ? 0x15 : qp[0] + 1; + qp[2] = qp[4] >= 0x48 ? 0x48 : qp[1]; + qp[3] = qp[4] >= 0x11B ? 0x11B : qp[2]; + setup_qlut(params->qt[2].q_table, qp); + + // table 2 + params->qt[3].q_table = params->qt[2].q_table + q_table_size; + params->qt[3].q_base = 2; + params->qt[3].max_grad = 7; + params->qt[3].q_grad_mult = 3; + params->qt[3].total_values = (qp[4] + 4) / 5 + 1; + params->qt[3].raw_bits = log2ceil(params->qt[3].total_values); + + qp[0] = params->qt[3].q_base; + qp[1] = qp[4] >= 0x18 ? 0x18 : qp[0] + 1; + qp[2] = qp[4] >= 0x4D ? 0x4D : qp[1]; + qp[3] = qp[4] >= 0x122 ? 0x122 : qp[2]; + setup_qlut(params->qt[3].q_table, qp); + } +} + +#define XTRANS_BUF_SIZE 0x10000 + +static inline void fuji_fill_buffer(fuji_compressed_block *info) +{ + if (info->cur_pos >= info->cur_buf_size) + { + info->cur_pos = 0; + info->cur_buf_offset += info->cur_buf_size; +#ifdef LIBRAW_USE_OPENMP +#pragma omp critical +#endif + { +#ifndef LIBRAW_USE_OPENMP + info->input->lock(); +#endif + info->input->seek(info->cur_buf_offset, SEEK_SET); + info->cur_buf_size = info->input->read(info->cur_buf, 1, _min(info->max_read_size, XTRANS_BUF_SIZE)); +#ifndef LIBRAW_USE_OPENMP + info->input->unlock(); +#endif + if (info->cur_buf_size < 1) // nothing read + { + if (info->fillbytes > 0) + { + int ls = _max(1, _min(info->fillbytes, XTRANS_BUF_SIZE)); + memset(info->cur_buf, 0, ls); + info->fillbytes -= ls; + } + else + throw LIBRAW_EXCEPTION_IO_EOF; + } + info->max_read_size -= info->cur_buf_size; + } + } +} + +void init_main_grads(const fuji_compressed_params *params, fuji_compressed_block *info) +{ + int max_diff = _max(2, (params->qt->total_values + 0x20) >> 6); + for (int j = 0; j < 3; j++) + for (int i = 0; i < 41; i++) + { + info->even[j].grads[i].value1 = max_diff; + info->even[j].grads[i].value2 = 1; + info->odd[j].grads[i].value1 = max_diff; + info->odd[j].grads[i].value2 = 1; + } +} + +void LibRaw::init_fuji_block(fuji_compressed_block *info, const fuji_compressed_params *params, INT64 raw_offset, + unsigned dsize) +{ + info->linealloc = (ushort *)calloc(sizeof(ushort), _ltotal * (params->line_width + 2)); + + INT64 fsize = libraw_internal_data.internal_data.input->size(); + info->max_read_size = _min(unsigned(fsize - raw_offset), dsize); // Data size may be incorrect? + info->fillbytes = 1; + + info->input = libraw_internal_data.internal_data.input; + info->linebuf[_R0] = info->linealloc; + for (int i = _R1; i <= _B4; i++) + info->linebuf[i] = info->linebuf[i - 1] + params->line_width + 2; + + // init buffer + info->cur_buf = (uchar *)malloc(XTRANS_BUF_SIZE); + info->cur_bit = 0; + info->cur_pos = 0; + info->cur_buf_offset = raw_offset; + info->cur_buf_size = 0; + fuji_fill_buffer(info); + + // init grads for lossy and lossless + if (libraw_internal_data.unpacker_data.fuji_lossless) + init_main_grads(params, info); + else + { + // init static grads for lossy only - main ones are done per line + for (int k = 0; k < 3; ++k) + { + int max_diff = _max(2, ((params->qt[k + 1].total_values + 0x20) >> 6)); + for (int j = 0; j < 3; ++j) + for (int i = 0; i < 5; ++i) + { + info->even[j].lossy_grads[k][i].value1 = max_diff; + info->even[j].lossy_grads[k][i].value2 = 1; + info->odd[j].lossy_grads[k][i].value1 = max_diff; + info->odd[j].lossy_grads[k][i].value2 = 1; + } + } + } +} + +void LibRaw::copy_line_to_xtrans(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) +{ + ushort *lineBufB[3]; + ushort *lineBufG[6]; + ushort *lineBufR[3]; + unsigned pixel_count; + ushort *line_buf; + int index; + + int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; + ushort *raw_block_data = imgdata.rawdata.raw_image + offset; + int row_count = 0; + + for (int i = 0; i < 3; i++) + { + lineBufR[i] = info->linebuf[_R2 + i] + 1; + lineBufB[i] = info->linebuf[_B2 + i] + 1; + } + for (int i = 0; i < 6; i++) + lineBufG[i] = info->linebuf[_G2 + i] + 1; + + while (row_count < 6) + { + pixel_count = 0; + while (pixel_count < (unsigned)cur_block_width) + { + switch (imgdata.idata.xtrans_abs[row_count][(pixel_count % 6)]) + { + case 0: // red + line_buf = lineBufR[row_count >> 1]; + break; + case 1: // green + default: // to make static analyzer happy + line_buf = lineBufG[row_count]; + break; + case 2: // blue + line_buf = lineBufB[row_count >> 1]; + break; + } + + index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | ((pixel_count % 3) & 1)) + ((pixel_count % 3) >> 1); + raw_block_data[pixel_count] = line_buf[index]; + + ++pixel_count; + } + ++row_count; + raw_block_data += imgdata.sizes.raw_width; + } +} + +void LibRaw::copy_line_to_bayer(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) +{ + ushort *lineBufB[3]; + ushort *lineBufG[6]; + ushort *lineBufR[3]; + unsigned pixel_count; + ushort *line_buf; + + int fuji_bayer[2][2]; + for (int r = 0; r < 2; r++) + for (int c = 0; c < 2; c++) + fuji_bayer[r][c] = FC(r, c); // We'll downgrade G2 to G below + + int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; + ushort *raw_block_data = imgdata.rawdata.raw_image + offset; + int row_count = 0; + + for (int i = 0; i < 3; i++) + { + lineBufR[i] = info->linebuf[_R2 + i] + 1; + lineBufB[i] = info->linebuf[_B2 + i] + 1; + } + for (int i = 0; i < 6; i++) + lineBufG[i] = info->linebuf[_G2 + i] + 1; + + while (row_count < 6) + { + pixel_count = 0; + while (pixel_count < (unsigned)cur_block_width) + { + switch (fuji_bayer[row_count & 1][pixel_count & 1]) + { + case 0: // red + line_buf = lineBufR[row_count >> 1]; + break; + case 1: // green + case 3: // second green + default: // to make static analyzer happy + line_buf = lineBufG[row_count]; + break; + case 2: // blue + line_buf = lineBufB[row_count >> 1]; + break; + } + + raw_block_data[pixel_count] = line_buf[pixel_count >> 1]; + ++pixel_count; + } + ++row_count; + raw_block_data += imgdata.sizes.raw_width; + } +} + +#define fuji_quant_gradient(max, q, v1, v2) (q->q_grad_mult * q->q_table[(max) + (v1)] + q->q_table[(max) + (v2)]) + +static inline void fuji_zerobits(fuji_compressed_block *info, int *count) +{ + uchar zero = 0; + *count = 0; + while (zero == 0) + { + zero = (info->cur_buf[info->cur_pos] >> (7 - info->cur_bit)) & 1; + info->cur_bit++; + info->cur_bit &= 7; + if (!info->cur_bit) + { + ++info->cur_pos; + fuji_fill_buffer(info); + } + if (zero) + break; + ++*count; + } +} + +static inline void fuji_read_code(fuji_compressed_block *info, int *data, int bits_to_read) +{ + uchar bits_left = bits_to_read; + uchar bits_left_in_byte = 8 - (info->cur_bit & 7); + *data = 0; + if (!bits_to_read) + return; + if (bits_to_read >= bits_left_in_byte) + { + do + { + *data <<= bits_left_in_byte; + bits_left -= bits_left_in_byte; + *data |= info->cur_buf[info->cur_pos] & ((1 << bits_left_in_byte) - 1); + ++info->cur_pos; + fuji_fill_buffer(info); + bits_left_in_byte = 8; + } while (bits_left >= 8); + } + if (!bits_left) + { + info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; + return; + } + *data <<= bits_left; + bits_left_in_byte -= bits_left; + *data |= ((1 << bits_left) - 1) & ((unsigned)info->cur_buf[info->cur_pos] >> bits_left_in_byte); + info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; +} + +static inline int bitDiff(int value1, int value2) +{ + int decBits = 0; + if (value2 < value1) + while (decBits <= 14 && (value2 << ++decBits) < value1) + ; + return decBits; +} + +static inline int fuji_decode_sample_even(fuji_compressed_block *info, const fuji_compressed_params *params, + ushort *line_buf, int pos, fuji_grads *grad_params) +{ + int interp_val = 0; + // ushort decBits; + int errcnt = 0; + + int sample = 0, code = 0; + ushort *line_buf_cur = line_buf + pos; + int Rb = line_buf_cur[-2 - params->line_width]; + int Rc = line_buf_cur[-3 - params->line_width]; + int Rd = line_buf_cur[-1 - params->line_width]; + int Rf = line_buf_cur[-4 - 2 * params->line_width]; + + int grad, gradient, diffRcRb, diffRfRb, diffRdRb; + + diffRcRb = _abs(Rc - Rb); + diffRfRb = _abs(Rf - Rb); + diffRdRb = _abs(Rd - Rb); + + const fuji_q_table *qt = params->qt; + int_pair *grads = grad_params->grads; + for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) + if (diffRfRb + diffRcRb <= params->qt[i].max_grad) + { + qt = params->qt + i; + grads = grad_params->lossy_grads[i - 1]; + break; + } + + grad = fuji_quant_gradient(params->max_value, qt, Rb - Rf, Rc - Rb); + gradient = _abs(grad); + + if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) + interp_val = Rf + Rd + 2 * Rb; + else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) + interp_val = Rf + Rc + 2 * Rb; + else + interp_val = Rd + Rc + 2 * Rb; + + fuji_zerobits(info, &sample); + + if (sample < params->max_bits - qt->raw_bits - 1) + { + int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); + fuji_read_code(info, &code, decBits); + code += sample << decBits; + } + else + { + fuji_read_code(info, &code, qt->raw_bits); + ++code; + } + + if (code < 0 || code >= qt->total_values) + ++errcnt; + + if (code & 1) + code = -1 - code / 2; + else + code /= 2; + + grads[gradient].value1 += _abs(code); + if (grads[gradient].value2 == params->min_value) + { + grads[gradient].value1 >>= 1; + grads[gradient].value2 >>= 1; + } + ++grads[gradient].value2; + if (grad < 0) + interp_val = (interp_val >> 2) - code * (2 * qt->q_base + 1); + else + interp_val = (interp_val >> 2) + code * (2 * qt->q_base + 1); + if (interp_val < -qt->q_base) + interp_val += qt->total_values * (2 * qt->q_base + 1); + else if (interp_val > qt->q_base + params->max_value) + interp_val -= qt->total_values * (2 * qt->q_base + 1); + + if (interp_val >= 0) + line_buf_cur[0] = _min(interp_val, params->max_value); + else + line_buf_cur[0] = 0; + return errcnt; +} + +static inline int fuji_decode_sample_odd(fuji_compressed_block *info, const fuji_compressed_params *params, + ushort *line_buf, int pos, fuji_grads *grad_params) +{ + int interp_val = 0; + int errcnt = 0; + + int sample = 0, code = 0; + ushort *line_buf_cur = line_buf + pos; + int Ra = line_buf_cur[-1]; + int Rb = line_buf_cur[-2 - params->line_width]; + int Rc = line_buf_cur[-3 - params->line_width]; + int Rd = line_buf_cur[-1 - params->line_width]; + int Rg = line_buf_cur[1]; + + int grad, gradient; + + int diffRcRa = _abs(Rc - Ra); + int diffRbRc = _abs(Rb - Rc); + + const fuji_q_table *qt = params->qt; + int_pair *grads = grad_params->grads; + for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) + if (diffRbRc + diffRcRa <= params->qt[i].max_grad) + { + qt = params->qt + i; + grads = grad_params->lossy_grads[i - 1]; + break; + } + + grad = fuji_quant_gradient(params->max_value, qt, Rb - Rc, Rc - Ra); + gradient = _abs(grad); + + if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd)) + interp_val = (Rg + Ra + 2 * Rb) >> 2; + else + interp_val = (Ra + Rg) >> 1; + + fuji_zerobits(info, &sample); + + if (sample < params->max_bits - qt->raw_bits - 1) + { + int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); + fuji_read_code(info, &code, decBits); + code += sample << decBits; + } + else + { + fuji_read_code(info, &code, qt->raw_bits); + ++code; + } + + if (code < 0 || code >= qt->total_values) + ++errcnt; + + if (code & 1) + code = -1 - code / 2; + else + code /= 2; + + grads[gradient].value1 += _abs(code); + if (grads[gradient].value2 == params->min_value) + { + grads[gradient].value1 >>= 1; + grads[gradient].value2 >>= 1; + } + ++grads[gradient].value2; + if (grad < 0) + interp_val -= code * (2 * qt->q_base + 1); + else + interp_val += code * (2 * qt->q_base + 1); + if (interp_val < -qt->q_base) + interp_val += qt->total_values * (2 * qt->q_base + 1); + else if (interp_val > qt->q_base + params->max_value) + interp_val -= qt->total_values * (2 * qt->q_base + 1); + + if (interp_val >= 0) + line_buf_cur[0] = _min(interp_val, params->max_value); + else + line_buf_cur[0] = 0; + return errcnt; +} + +static void fuji_decode_interpolation_even(int line_width, ushort *line_buf, int pos) +{ + ushort *line_buf_cur = line_buf + pos; + int Rb = line_buf_cur[-2 - line_width]; + int Rc = line_buf_cur[-3 - line_width]; + int Rd = line_buf_cur[-1 - line_width]; + int Rf = line_buf_cur[-4 - 2 * line_width]; + int diffRcRb = _abs(Rc - Rb); + int diffRfRb = _abs(Rf - Rb); + int diffRdRb = _abs(Rd - Rb); + if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) + *line_buf_cur = (Rf + Rd + 2 * Rb) >> 2; + else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) + *line_buf_cur = (Rf + Rc + 2 * Rb) >> 2; + else + *line_buf_cur = (Rd + Rc + 2 * Rb) >> 2; +} + +static void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, int end) +{ + for (int i = start; i <= end; i++) + { + linebuf[i][0] = linebuf[i - 1][1]; + linebuf[i][line_width + 1] = linebuf[i - 1][line_width]; + } +} + +static void fuji_extend_red(ushort *linebuf[_ltotal], int line_width) +{ + fuji_extend_generic(linebuf, line_width, _R2, _R4); +} + +static void fuji_extend_green(ushort *linebuf[_ltotal], int line_width) +{ + fuji_extend_generic(linebuf, line_width, _G2, _G7); +} + +static void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width) +{ + fuji_extend_generic(linebuf, line_width, _B2, _B4); +} + +void LibRaw::xtrans_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) +{ + int r_even_pos = 0, r_odd_pos = 1; + int g_even_pos = 0, g_odd_pos = 1; + int b_even_pos = 0, b_odd_pos = 1; + + int errcnt = 0; + + const int line_width = params->line_width; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + fuji_decode_interpolation_even(line_width, info->linebuf[_R2] + 1, r_even_pos); + r_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); + g_even_pos += 2; + fuji_decode_interpolation_even(line_width, info->linebuf[_B2] + 1, b_even_pos); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + r_even_pos = 0, r_odd_pos = 1; + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + if (r_even_pos & 3) + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); + else + fuji_decode_interpolation_even(line_width, info->linebuf[_R3] + 1, r_even_pos); + r_even_pos += 2; + fuji_decode_interpolation_even(line_width, info->linebuf[_G4] + 1, g_even_pos); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + b_even_pos = 0, b_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); + g_even_pos += 2; + if ((b_even_pos & 3) == 2) + fuji_decode_interpolation_even(line_width, info->linebuf[_B3] + 1, b_even_pos); + else + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + r_even_pos = 0, r_odd_pos = 1; + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + if ((r_even_pos & 3) == 2) + fuji_decode_interpolation_even(line_width, info->linebuf[_R4] + 1, r_even_pos); + else + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); + r_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + b_even_pos = 0, b_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + fuji_decode_interpolation_even(line_width, info->linebuf[_G7] + 1, g_even_pos); + g_even_pos += 2; + if (b_even_pos & 3) + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); + else + fuji_decode_interpolation_even(line_width, info->linebuf[_B4] + 1, b_even_pos); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + if (errcnt) + derror(); +} + +void LibRaw::fuji_bayer_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) +{ + int r_even_pos = 0, r_odd_pos = 1; + int g_even_pos = 0, g_odd_pos = 1; + int b_even_pos = 0, b_odd_pos = 1; + + int errcnt = 0; + + const int line_width = params->line_width; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R2] + 1, r_even_pos, &info->even[0]); + r_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); + g_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B2] + 1, b_even_pos, &info->even[1]); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + r_even_pos = 0, r_odd_pos = 1; + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); + r_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G4] + 1, g_even_pos, &info->even[2]); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + b_even_pos = 0, b_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); + g_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + r_even_pos = 0, r_odd_pos = 1; + g_even_pos = 0, g_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); + r_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); + g_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); + r_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); + g_odd_pos += 2; + } + } + + fuji_extend_red(info->linebuf, line_width); + fuji_extend_green(info->linebuf, line_width); + + g_even_pos = 0, g_odd_pos = 1; + b_even_pos = 0, b_odd_pos = 1; + + while (g_even_pos < line_width || g_odd_pos < line_width) + { + if (g_even_pos < line_width) + { + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G7] + 1, g_even_pos, &info->even[2]); + g_even_pos += 2; + errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); + b_even_pos += 2; + } + if (g_even_pos > 8) + { + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); + g_odd_pos += 2; + errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); + b_odd_pos += 2; + } + } + + fuji_extend_green(info->linebuf, line_width); + fuji_extend_blue(info->linebuf, line_width); + + if (errcnt) + derror(); +} + +void LibRaw::fuji_decode_strip(fuji_compressed_params *params, int cur_block, INT64 raw_offset, unsigned dsize, + uchar *q_bases) +{ + int cur_block_width, cur_line; + unsigned line_size; + fuji_compressed_block info; + fuji_compressed_params *info_common = params; + + if (!libraw_internal_data.unpacker_data.fuji_lossless) + { + int buf_size = sizeof(fuji_compressed_params) + (2 << libraw_internal_data.unpacker_data.fuji_bits); + + info_common = (fuji_compressed_params *)malloc(buf_size); + memcpy(info_common, params, sizeof(fuji_compressed_params)); + info_common->qt[0].q_table = (int8_t *)(info_common + 1); + info_common->qt[0].q_base = -1; + } + init_fuji_block(&info, info_common, raw_offset, dsize); + line_size = sizeof(ushort) * (info_common->line_width + 2); + + cur_block_width = libraw_internal_data.unpacker_data.fuji_block_width; + if (cur_block + 1 == libraw_internal_data.unpacker_data.fuji_total_blocks) + { + cur_block_width = imgdata.sizes.raw_width - (libraw_internal_data.unpacker_data.fuji_block_width * cur_block); + /* Old code, may get incorrect results on GFX50, but luckily large optical + black cur_block_width = imgdata.sizes.raw_width % + libraw_internal_data.unpacker_data.fuji_block_width; + */ + } + + struct i_pair + { + int a, b; + }; + const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6}, {_G1, _G7}, {_B0, _B3}, {_B1, _B4}}, + ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}}; + for (cur_line = 0; cur_line < libraw_internal_data.unpacker_data.fuji_total_lines; cur_line++) + { + // init grads and main qtable + if (!libraw_internal_data.unpacker_data.fuji_lossless) + { + int q_base = q_bases ? q_bases[cur_line] : 0; + if (!cur_line || q_base != info_common->qt[0].q_base) + { + init_main_qtable(info_common, q_bases[cur_line]); + init_main_grads(info_common, &info); + } + } + + if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) + xtrans_decode_block(&info, info_common, cur_line); + else + fuji_bayer_decode_block(&info, info_common, cur_line); + + // copy data from line buffers and advance + for (int i = 0; i < 6; i++) + memcpy(info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size); + + if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) + copy_line_to_xtrans(&info, cur_line, cur_block, cur_block_width); + else + copy_line_to_bayer(&info, cur_line, cur_block, cur_block_width); + + for (int i = 0; i < 3; i++) + { + memset(info.linebuf[ztable[i].a], 0, ztable[i].b * line_size); + info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1]; + info.linebuf[ztable[i].a][info_common->line_width + 1] = info.linebuf[ztable[i].a - 1][info_common->line_width]; + } + } + + // release data + if (!libraw_internal_data.unpacker_data.fuji_lossless) + free(info_common); + free(info.linealloc); + free(info.cur_buf); +} + +void LibRaw::fuji_compressed_load_raw() +{ + fuji_compressed_params common_info; + int cur_block; + unsigned *block_sizes; + uchar *q_bases = 0; + INT64 raw_offset, *raw_block_offsets; + + init_fuji_compr(&common_info); + + // read block sizes + block_sizes = (unsigned *)malloc(sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks); + raw_block_offsets = (INT64 *)malloc(sizeof(INT64) * libraw_internal_data.unpacker_data.fuji_total_blocks); + + libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); + int sizesToRead = sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks; + if (libraw_internal_data.internal_data.input->read(block_sizes, 1, sizesToRead) != sizesToRead) + { + free(block_sizes); + free(raw_block_offsets); + throw LIBRAW_EXCEPTION_IO_EOF; + } + + raw_offset = ((sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks) + 0xF) & ~0xF; + + // read q bases for lossy + if (!libraw_internal_data.unpacker_data.fuji_lossless) + { + int total_q_bases = libraw_internal_data.unpacker_data.fuji_total_blocks * + ((libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF); + q_bases = (uchar *)malloc(total_q_bases); + libraw_internal_data.internal_data.input->seek(raw_offset + libraw_internal_data.unpacker_data.data_offset, + SEEK_SET); + libraw_internal_data.internal_data.input->read(q_bases, 1, total_q_bases); + raw_offset += total_q_bases; + } + + raw_offset += libraw_internal_data.unpacker_data.data_offset; + + // calculating raw block offsets + raw_block_offsets[0] = raw_offset; + for (cur_block = 0; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) + { + unsigned bsize = sgetn(4, (uchar *)(block_sizes + cur_block)); + block_sizes[cur_block] = bsize; + } + + for (cur_block = 1; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) + raw_block_offsets[cur_block] = raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1]; + + fuji_decode_loop(&common_info, libraw_internal_data.unpacker_data.fuji_total_blocks, raw_block_offsets, block_sizes, + q_bases); + + free(q_bases); + free(block_sizes); + free(raw_block_offsets); + free(common_info.buf); +} + +void LibRaw::fuji_decode_loop(fuji_compressed_params *common_info, int count, INT64 *raw_block_offsets, + unsigned *block_sizes, uchar *q_bases) +{ + int cur_block; + const int lineStep = (libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF; +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for private(cur_block) +#endif + for (cur_block = 0; cur_block < count; cur_block++) + { + fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block], + q_bases ? q_bases + cur_block * lineStep : 0); + } +} + +void LibRaw::parse_fuji_compressed_header() +{ + unsigned signature, lossless, h_raw_type, h_raw_bits, h_raw_height, h_raw_rounded_width, h_raw_width, h_block_size, + h_blocks_in_row, h_total_lines; + + uchar header[16]; + + libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); + if (libraw_internal_data.internal_data.input->read(header, 1, sizeof(header)) != sizeof(header)) + return; + + // read all header + signature = sgetn(2, header); + lossless = header[2]; + h_raw_type = header[3]; + h_raw_bits = header[4]; + h_raw_height = sgetn(2, header + 5); + h_raw_rounded_width = sgetn(2, header + 7); + h_raw_width = sgetn(2, header + 9); + h_block_size = sgetn(2, header + 11); + h_blocks_in_row = header[13]; + h_total_lines = sgetn(2, header + 14); + + // general validation + if (signature != 0x4953 || lossless > 1 || h_raw_height > 0x4002 || h_raw_height < 6 || h_raw_height % 6 || + h_block_size < 1 || h_raw_width > 0x4200 || h_raw_width < 0x300 || h_raw_width % 24 || + h_raw_rounded_width > 0x4200 || h_raw_rounded_width < h_block_size || h_raw_rounded_width % h_block_size || + h_raw_rounded_width - h_raw_width >= h_block_size || h_block_size != 0x300 || h_blocks_in_row > 0x10 || + h_blocks_in_row == 0 || h_blocks_in_row != h_raw_rounded_width / h_block_size || h_total_lines > 0xAAB || + h_total_lines == 0 || h_total_lines != h_raw_height / 6 || + (h_raw_bits != 12 && h_raw_bits != 14 && h_raw_bits != 16) || (h_raw_type != 16 && h_raw_type != 0)) + return; + + // modify data + libraw_internal_data.unpacker_data.fuji_total_lines = h_total_lines; + libraw_internal_data.unpacker_data.fuji_total_blocks = h_blocks_in_row; + libraw_internal_data.unpacker_data.fuji_block_width = h_block_size; + libraw_internal_data.unpacker_data.fuji_bits = h_raw_bits; + libraw_internal_data.unpacker_data.fuji_raw_type = h_raw_type; + libraw_internal_data.unpacker_data.fuji_lossless = lossless; + imgdata.sizes.raw_width = h_raw_width; + imgdata.sizes.raw_height = h_raw_height; + libraw_internal_data.unpacker_data.data_offset += 16; + load_raw = &LibRaw::fuji_compressed_load_raw; +} + +#undef _abs +#undef _min diff --git a/src/decoders/generic.cpp b/src/decoders/generic.cpp new file mode 100644 index 000000000..6c521d849 --- /dev/null +++ b/src/decoders/generic.cpp @@ -0,0 +1,101 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::unpacked_load_raw() +{ + int row, col, bits = 0; + while (1 << ++bits < (int)maximum) + ; + read_shorts(raw_image, raw_width * raw_height); + fseek(ifp, -2, SEEK_CUR); // avoid EOF error + if (maximum < 0xffff || load_flags) + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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 LibRaw::packed_load_raw() +{ + int vbits = 0, bwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf = 0; + + bwide = raw_width * tiff_bps / 8; + bwide += bwide & load_flags >> 7; + rbits = bwide * 8 - raw_width * tiff_bps; + if (load_flags & 1) + bwide = bwide * 16 / 15; + bite = 8 + (load_flags & 24); + half = (raw_height + 1) >> 1; + for (irow = 0; irow < raw_height; irow++) + { + checkCancel(); + 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); + } + } + if (feof(ifp)) + throw LIBRAW_EXCEPTION_IO_EOF; + for (col = 0; col < raw_width; col++) + { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) + { + bitbuf <<= bite; + for (i = 0; i < bite; i += 8) + bitbuf |= (unsigned(fgetc(ifp)) << i); + } + val = bitbuf << (64 - tiff_bps - vbits) >> (64 - tiff_bps); + RAW(row, col ^ (load_flags >> 6 & 1)) = val; + if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && + row < height + top_margin && col < width + left_margin) + derror(); + } + vbits -= rbits; + } +} + +void LibRaw::eight_bit_load_raw() +{ + unsigned row, col; + + std::vector pixel(raw_width); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + if (fread(pixel.data(), 1, raw_width, ifp) < raw_width) + derror(); + for (col = 0; col < raw_width; col++) + RAW(row, col) = curve[pixel[col]]; + } + maximum = curve[0xff]; +} diff --git a/src/decoders/kodak_decoders.cpp b/src/decoders/kodak_decoders.cpp new file mode 100644 index 000000000..e4b1b3957 --- /dev/null +++ b/src/decoders/kodak_decoders.cpp @@ -0,0 +1,524 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +#define radc_token(tree) ((signed char)getbithuff(8, huff + (tree) * 256)) + +#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) + +#ifdef __GNUC__ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +#pragma GCC optimize("no-aggressive-loop-optimizations") +#endif +#endif + +void LibRaw::kodak_radc_load_raw() +{ + // All kodak radc images are 768x512 + if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + static const signed 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}; + std::vector huff_buffer(19 * 256); + ushort* huff = &huff_buffer[0]; + 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 < int(sizeof src); i += 2) + FORC(256 >> src[i]) + ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1]; + s = kodak_cbpp == 243 ? 2 : 3; + FORC(256) huff[18 * 256 + c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1); + getbits(-1); + for (i = 0; i < int(sizeof(buf) / sizeof(short)); i++) + ((short *)buf)[i] = 2048; + for (row = 0; row < height; row += 4) + { + checkCancel(); + FORC3 mul[c] = getbits(6); + if (!mul[0] || !mul[1] || !mul[2]) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + FORC3 + { + val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10 : 12; + x = ~((~0u) << (s - 1)); + val <<= 12 - s; + for (i = 0; i < int(sizeof(buf[0]) / sizeof(short)); i++) + ((short *)buf[c])[i] = MIN(0x7FFFFFFF, (((short *)buf[c])[i] * static_cast(val) + x)) >> s; + last[c] = mul[c]; + for (r = 0; r <= int(!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 (col >= 0) + { + 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; + if (col >= 0) + 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 LibRaw::kodak_jpeg_load_raw() {} +#else +static void jpegErrorExit_k(j_common_ptr /*cinfo*/) +{ + throw LIBRAW_EXCEPTION_DECODE_JPEG; +} + +// LibRaw's Kodak_jpeg_load_raw +void LibRaw::kodak_jpeg_load_raw() +{ + if (data_size < 1) + throw LIBRAW_EXCEPTION_DECODE_JPEG; + + int row, col; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr pub; + cinfo.err = jpeg_std_error(&pub); + pub.error_exit = jpegErrorExit_k; + + if (INT64(data_size) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + unsigned char *jpg_buf = (unsigned char *)malloc(data_size); + std::vector pixel_buf(width * 3); + jpeg_create_decompress(&cinfo); + + fread(jpg_buf, data_size, 1, ifp); + libraw_swab(jpg_buf, data_size); + try + { + jpeg_mem_src(&cinfo, jpg_buf, data_size); + int rc = jpeg_read_header(&cinfo, TRUE); + if (rc != 1) + throw LIBRAW_EXCEPTION_DECODE_JPEG; + + jpeg_start_decompress(&cinfo); + if ((cinfo.output_width != width) || (cinfo.output_height * 2 != height) || + (cinfo.output_components != 3)) + { + throw LIBRAW_EXCEPTION_DECODE_JPEG; + } + + unsigned char *buf[1]; + buf[0] = pixel_buf.data(); + + while (cinfo.output_scanline < cinfo.output_height) + { + checkCancel(); + row = cinfo.output_scanline * 2; + jpeg_read_scanlines(&cinfo, buf, 1); + unsigned char(*pixel)[3] = (unsigned char(*)[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]; + } + } + } + catch (...) + { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + free(jpg_buf); + throw; + } + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + free(jpg_buf); + maximum = 0xff << 1; +} +#endif + +void LibRaw::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++) + { + checkCancel(); + 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 LibRaw::kodak_c330_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int row, col, y, cb, cr, rgb[3], c; + + std::vector pixel(raw_width*2 + 4); + + for (row = 0; row < height; row++) + { + checkCancel(); + if (fread(pixel.data(), raw_width, 2, ifp) < 2) + derror(); + if (load_flags && (row & 31) == 31) + fseek(ifp, raw_width * 32, SEEK_CUR); + for (col = 0; col < width; col++) + { + y = pixel[col * 2]; + cb = pixel[(col * 2 & -4) | 1] - 128; + cr = pixel[(col * 2 & -4) | 3] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; + } + } + maximum = curve[0xff]; +} + +void LibRaw::kodak_c603_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int row, col, y, cb, cr, rgb[3], c; + + std::vector pixel(raw_width * 3); + for (row = 0; row < height; row++) + { + checkCancel(); + if (~row & 1) + if (fread(pixel.data(), raw_width, 3, ifp) < 3) + derror(); + for (col = 0; col < width; col++) + { + y = pixel[width * 2 * (row & 1) + col]; + cb = pixel[width + (col & -2)] - 128; + cr = pixel[width + (col & -2) + 1] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)]; + } + } + maximum = curve[0xff]; +} + +void LibRaw::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]; + 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; + std::vector pixel(raw_width * 32 + ns * 4); + strip = (int *)(pixel.data() + raw_width * 32); + order = 0x4d4d; + FORC(ns) strip[c] = get4(); + try + { + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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; + } + } + } + catch (...) + { + FORC(2) free(huff[c]); + throw; + } + FORC(2) free(huff[c]); +} + +int LibRaw::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 (len > 0 && (diff & (1 << (len - 1))) == 0) + diff -= (1 << len) - 1; + out[i] = diff; + } + return 0; +} + +void LibRaw::kodak_65000_load_raw() +{ + short buf[272]; /* 264 looks enough */ + int row, col, len, pred[2], ret, i; + + for (row = 0; row < height; row++) + { + checkCancel(); + 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++) + { + int idx = ret ? buf[i] : (pred[i & 1] += buf[i]); + if (idx >= 0 && idx < 0xffff) + { + if ((RAW(row, col + i) = curve[idx]) >> 12) + derror(); + } + else + derror(); + } + } + } +} + +void LibRaw::kodak_ycbcr_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; + + unsigned int bits = + (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10; + const int pixels = int(width)*int(height); + for (row = 0; row < height; row += 2) + { + checkCancel(); + 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++) >> bits) + derror(); + int indx = (row + j) * width + col + i + k; + if(indx>=0 && indx < pixels) + { + ip = image[indx]; + FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)]; + } + } + } + } + } +} + +void LibRaw::kodak_rgb_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + short buf[768], *bp; + int row, col, len, c, i, rgb[3], ret; + ushort *ip = image[0]; + + for (row = 0; row < height; row++) + { + checkCancel(); + for (col = 0; col < width; col += 256) + { + len = MIN(256, width - col); + ret = kodak_65000_decode(buf, len * 3); + memset(rgb, 0, sizeof rgb); + for (bp = buf, i = 0; i < len; i++, ip += 4) + if (load_flags == 12) + FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++); + else + FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror(); + } + } +} + +void LibRaw::kodak_thumb_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + 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; +} diff --git a/src/decoders/load_mfbacks.cpp b/src/decoders/load_mfbacks.cpp new file mode 100644 index 000000000..493c7859f --- /dev/null +++ b/src/decoders/load_mfbacks.cpp @@ -0,0 +1,915 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +inline uint32_t abs32(int32_t x) +{ + // Branchless version. + uint32_t sm = x >> 31; + return (uint32_t) ((x + sm) ^ sm); +} + +inline uint32_t min32(uint32_t x, uint32_t y) +{ + return x < y ? x : y; +} + +inline uint32_t max32(uint32_t x, uint32_t y) +{ + return x > y ? x : y; +} + +inline uint32_t constain32(uint32_t x, uint32_t l, uint32_t u) +{ + return x < l ? l : (x > u ? u : x); +} + +int unsigned_cmp(const void *a, const void *b) +{ + if (!a || !b) + return 0; + + return *(unsigned *)a > *(unsigned *)b ? 1 : (*(unsigned *)a < *(unsigned *)b ? -1 : 0); +} + +int LibRaw::p1rawc(unsigned row, unsigned col, unsigned& count) +{ + return (row < raw_height && col < raw_width) ? (++count, RAW(row, col)) : 0; +} + +int LibRaw::p1raw(unsigned row, unsigned col) +{ + return (row < raw_height && col < raw_width) ? RAW(row, col) : 0; +} + + +// DNG SDK version of fixing pixels in bad column using averages sets +// corrected not to use pixels in the same column +void LibRaw::phase_one_fix_col_pixel_avg(unsigned row, unsigned col) +{ + static const int8_t dir[3][8][2] = { + { {-2,-2}, {-2, 2}, {2,-2}, {2, 2}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} }, + { {-2,-4}, {-4,-2}, {2,-4}, {4,-2}, {-2, 4}, {-4, 2}, {2, 4}, {4, 2} }, + { {-4,-4}, {-4, 4}, {4,-4}, {4, 4}, { 0, 0}, { 0, 0}, {0, 0}, {0, 0} } }; + + for (int set=0; set < 3; ++set) + { + uint32_t total = 0; + uint32_t count = 0; + for (int i = 0; i < 8; ++i) + { + if (!dir[set][i][0] && !dir[set][i][1]) + break; + + total += p1rawc(row+dir[set][i][0], col+dir[set][i][1], count); + } + + if (count) + { + RAW(row,col) = (uint16_t)((total + (count >> 1)) / count); + break; + } + } +} + +// DNG SDK version of fixing pixels in bad column using gradient prediction +void LibRaw::phase_one_fix_pixel_grad(unsigned row, unsigned col) +{ + static const int8_t grad_sets[7][12][2] = { + { {-4,-2}, { 4, 2}, {-3,-1}, { 1, 1}, {-1,-1}, { 3, 1}, + {-4,-1}, { 0, 1}, {-2,-1}, { 2, 1}, { 0,-1}, { 4, 1} }, + { {-2,-2}, { 2, 2}, {-3,-1}, {-1, 1}, {-1,-1}, { 1, 1}, + { 1,-1}, { 3, 1}, {-2,-1}, { 0, 1}, { 0,-1}, { 2, 1} }, + { {-2,-4}, { 2, 4}, {-1,-3}, { 1, 1}, {-1,-1}, { 1, 3}, + {-2,-1}, { 0, 3}, {-1,-2}, { 1, 2}, { 0,-3}, { 2, 1} }, + { { 0,-2}, { 0, 2}, {-1,-1}, {-1, 1}, { 1,-1}, { 1, 1}, + {-1,-2}, {-1, 2}, { 0,-1}, { 0,-1}, { 1,-2}, { 1, 2} }, + { {-2, 4}, { 2,-4}, {-1, 3}, { 1,-1}, {-1, 1}, { 1,-3}, + {-2, 1}, { 0,-3}, {-1, 2}, { 1,-2}, { 0, 3}, { 2,-1} }, + { {-2, 2}, { 2,-2}, {-3, 1}, {-1,-1}, {-1, 1}, { 1,-1}, + { 1, 1}, { 3,-1}, {-2, 1}, { 0,-1}, { 0, 1}, { 2,-1} }, + { {-4, 2}, { 4,-2}, {-3, 1}, { 1,-1}, {-1, 1}, { 3,-1}, + {-4, 1}, { 0,-1}, {-2, 1}, { 2,-1}, { 0, 1}, { 4,-1} } }; + + uint32_t est[7], grad[7]; + uint32_t lower = min32(p1raw(row,col-2), p1raw(row, col+2)); + uint32_t upper = max32(p1raw(row,col-2), p1raw(row, col+2)); + uint32_t minGrad = 0xFFFFFFFF; + for (int i = 0; i<7; ++i) + { + est[i] = p1raw(row+grad_sets[i][0][0], col+grad_sets[i][0][1]) + + p1raw(row+grad_sets[i][1][0], col+grad_sets[i][1][1]); + grad[i] = 0; + for (int j=0; j<12; j+=2) + grad[i] += abs32(p1raw(row+grad_sets[i][j][0], col+grad_sets[i][j][1]) - + p1raw(row+grad_sets[i][j+1][0], col+grad_sets[i][j+1][1])); + minGrad = min32(minGrad, grad[i]); + } + + uint32_t limit = (minGrad * 3) >> 1; + uint32_t total = 0; + uint32_t count = 0; + for (int i = 0; i<7; ++i) + if (grad[i] <= limit) + { + total += est[i]; + count += 2; + } + RAW(row, col) = constain32((total + (count >> 1)) / count, lower, upper); +} + +void LibRaw::phase_one_flat_field(int is_float, int nc) +{ + ushort head[8]; + unsigned wide, high, y, x, c, rend, cend, row, col; + float *mrow, num, mult[4]; + + read_shorts(head, 8); + if (head[2] == 0 || head[3] == 0 || head[4] == 0 || head[5] == 0) + return; + wide = head[2] / head[4] + (head[2] % head[4] != 0); + high = head[3] / head[5] + (head[3] % head[5] != 0); + mrow = (float *)calloc(nc * wide, sizeof *mrow); + for (y = 0; y < high; y++) + { + checkCancel(); + for (x = 0; x < wide; x++) + for (c = 0; c < (unsigned)nc; c += 2) + { + num = is_float ? getreal(LIBRAW_EXIFTAG_TYPE_FLOAT) : 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 < unsigned(head[1] + head[3] - head[5]); + row++) + { + for (x = 1; x < wide; x++) + { + for (c = 0; c < (unsigned)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 < unsigned(head[0] + head[2] - head[4]); + col++) + { + c = nc > 2 ? FC(row - top_margin, col - left_margin) : 0; + if (!(c & 1)) + { + c = RAW(row, col) * mult[c]; + RAW(row, col) = LIM(c, 0, 65535); + } + for (c = 0; c < (unsigned)nc; c += 2) + mult[c] += mult[c + 1]; + } + } + for (x = 0; x < wide; x++) + for (c = 0; c < (unsigned)nc; c += 2) + mrow[c * wide + x] += mrow[(c + 1) * wide + x]; + } + } + free(mrow); +} + +int LibRaw::phase_one_correct() +{ + unsigned entries, tag, data, save, col, row, type; + int len, i, j, k, cip, sum; +#if 0 + int val[4], dev[4], max; +#endif + 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] = {NULL, NULL}; + ushort *xval[2]; + int qmult_applied = 0, qlin_applied = 0; + std::vector badCols; + + if (!meta_length) + return 0; + fseek(ifp, meta_offset, SEEK_SET); + order = get2(); + fseek(ifp, 6, SEEK_CUR); + fseek(ifp, meta_offset + get4(), SEEK_SET); + entries = get4(); + get4(); + + try + { + while (entries--) + { + checkCancel(); + tag = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek(ifp, meta_offset + data, SEEK_SET); +#if 1 + if (ifp->eof()) + { + // skip bad or unknown tag + fseek(ifp, save, SEEK_SET); + continue; + } +#endif + if (tag == 0x0400) + { /* Sensor defects */ + while ((len -= 8) >= 0) + { + col = get2(); + row = get2(); + type = get2(); + get2(); + if (col >= raw_width) + continue; + if (type == 131 || type == 137) /* Bad column */ +#if 0 + // Original code by Dave Coffin - it works better by + // not employing special logic for G1 channel below. + // Alternatively this column remap (including G1 channel + // logic) should be called prior to black subtraction + // unlike other corrections + 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] = p1raw(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 += p1raw(row + dir[i][0], col + dir[i][1]); + RAW(row, col) = + 0.5 + sum * 0.0732233 + + (p1raw(row, col - 2) + p1raw(row, col + 2)) * 0.3535534; + } + } +#else + // accumulae bad columns to be sorted later + badCols.push_back(col); +#endif + else if (type == 129) + { /* Bad pixel */ + if (row >= raw_height) + continue; + j = (FC(row - top_margin, col - left_margin) != 1) * 4; + unsigned count = 0; + for (sum = 0, i = j; i < j + 8; i++) + sum += p1rawc(row + dir[i][0], col + dir[i][1], count); + if (count) + RAW(row, col) = (sum + (count >> 1)) / count; + } + } + } + else if (tag == 0x0419) + { /* Polynomial curve - output calibraion */ + for (get4(), i = 0; i < 8; i++) + poly[i] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + 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 == 0x041a) + { /* Polynomial curve */ + for (i = 0; i < 4; i++) + poly[i] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + 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++) + { + checkCancel(); + for (col = (tag & 1) * ph1.split_col; col < raw_width; col++) + RAW(row, col) = curve[RAW(row, col)]; + } + } + else if (tag == 0x0401) + { /* All-color flat fields - luma calibration*/ + phase_one_flat_field(1, 2); + } + else if (tag == 0x0416 || tag == 0x0410) + { + // 0x410 - luma calibration + phase_one_flat_field(0, 2); + } + else if (tag == 0x040b) + { /* Red+blue flat field - croma calibration */ + phase_one_flat_field(0, 4); + } + else if (tag == 0x0412) + { + fseek(ifp, 36, SEEK_CUR); + diff = abs(get2() - ph1.tag_21a); + if (mindiff > diff) + { + mindiff = diff; + off_412 = ftell(ifp) - 38; + } + } + else if (tag == 0x041f && !qlin_applied) + { /* Quadrant linearization */ + ushort lc[2][2][16], ref[16]; + int qr, qc; + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + for (i = 0; i < 16; i++) + lc[qr][qc][i] = get4(); + for (i = 0; i < 16; i++) + { + int v = 0; + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + v += lc[qr][qc][i]; + ref[i] = (v + 2) >> 2; + } + for (qr = 0; qr < 2; qr++) + { + for (qc = 0; qc < 2; qc++) + { + int cx[19], cf[19]; + for (i = 0; i < 16; i++) + { + cx[1 + i] = lc[qr][qc][i]; + cf[1 + i] = ref[i]; + } + cx[0] = cf[0] = 0; + cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15]; + cf[18] = cx[18] = 65535; + cubic_spline(cx, cf, 19); + + for (row = (qr ? ph1.split_row : 0); + row < unsigned(qr ? raw_height : ph1.split_row); row++) + { + checkCancel(); + for (col = (qc ? ph1.split_col : 0); + col < unsigned(qc ? raw_width : ph1.split_col); col++) + RAW(row, col) = curve[RAW(row, col)]; + } + } + } + qlin_applied = 1; + } + else if (tag == 0x041e && !qmult_applied) + { /* Quadrant multipliers - output calibraion */ + float qmult[2][2] = {{1, 1}, {1, 1}}; + get4(); + get4(); + get4(); + get4(); + qmult[0][0] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + get4(); + get4(); + get4(); + get4(); + get4(); + qmult[0][1] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + get4(); + get4(); + get4(); + qmult[1][0] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + get4(); + get4(); + get4(); + qmult[1][1] = 1.0 + getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + for (row = 0; row < raw_height; row++) + { + checkCancel(); + for (col = 0; col < raw_width; col++) + { + i = qmult[row >= (unsigned)ph1.split_row][col >= (unsigned)ph1.split_col] * + RAW(row, col); + RAW(row, col) = LIM(i, 0, 65535); + } + } + qmult_applied = 1; + } + else if (tag == 0x0431 && !qmult_applied) + { /* Quadrant combined - four tile gain calibration */ + ushort lc[2][2][7], ref[7]; + int qr, qc; + for (i = 0; i < 7; i++) + ref[i] = get4(); + for (qr = 0; qr < 2; qr++) + for (qc = 0; qc < 2; qc++) + for (i = 0; i < 7; i++) + lc[qr][qc][i] = get4(); + for (qr = 0; qr < 2; qr++) + { + for (qc = 0; qc < 2; qc++) + { + int cx[9], cf[9]; + for (i = 0; i < 7; i++) + { + cx[1 + i] = ref[i]; + cf[1 + i] = ((unsigned)ref[i] * lc[qr][qc][i]) / 10000; + } + cx[0] = cf[0] = 0; + cx[8] = cf[8] = 65535; + cubic_spline(cx, cf, 9); + for (row = (qr ? ph1.split_row : 0); + row < unsigned(qr ? raw_height : ph1.split_row); row++) + { + checkCancel(); + for (col = (qc ? ph1.split_col : 0); + col < unsigned(qc ? raw_width : ph1.split_col); col++) + RAW(row, col) = curve[RAW(row, col)]; + } + } + } + qmult_applied = 1; + qlin_applied = 1; + } + fseek(ifp, save, SEEK_SET); + } + if (!badCols.empty()) + { + qsort(badCols.data(), badCols.size(), sizeof(unsigned), unsigned_cmp); + bool prevIsolated = true; + for (i = 0; i < (int)badCols.size(); ++i) + { + bool nextIsolated = i == ((int)(badCols.size()-1)) || badCols[i+1]>badCols[i]+4; + for (row = 0; row < raw_height; ++row) + if (prevIsolated && nextIsolated) + phase_one_fix_pixel_grad(row,badCols[i]); + else + phase_one_fix_col_pixel_avg(row,badCols[i]); + prevIsolated = nextIsolated; + } + } + 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); + 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(LIBRAW_EXIFTAG_TYPE_FLOAT); + 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++) + { + checkCancel(); + 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]); + } + } + catch (...) + { + if (yval[0]) + free(yval[0]); + return LIBRAW_CANCELLED_BY_CALLBACK; + } + return 0; +} + +void LibRaw::phase_one_load_raw() +{ + int a, b, i; + ushort akey, bkey, t_mask; + + fseek(ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + t_mask = ph1.format == 1 ? 0x5555 : 0x1354; + if (ph1.black_col || ph1.black_row) + { + imgdata.rawdata.ph1_cblack = + (short(*)[2])calloc(raw_height * 2, sizeof(ushort)); + imgdata.rawdata.ph1_rblack = + (short(*)[2])calloc(raw_width * 2, sizeof(ushort)); + if (ph1.black_col) + { + fseek(ifp, ph1.black_col, SEEK_SET); + read_shorts((ushort *)imgdata.rawdata.ph1_cblack[0], raw_height * 2); + } + if (ph1.black_row) + { + fseek(ifp, ph1.black_row, SEEK_SET); + read_shorts((ushort *)imgdata.rawdata.ph1_rblack[0], raw_width * 2); + } + } + 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 & t_mask) | (b & ~t_mask); + raw_image[i + 1] = (b & t_mask) | (a & ~t_mask); + } +} + +unsigned LibRaw::ph1_bithuff(int nbits, ushort *huff) +{ +#ifndef LIBRAW_NOTHREADS +#define bitbuf tls->ph1_bits.bitbuf +#define vbits tls->ph1_bits.vbits +#else + static UINT64 bitbuf = 0; + static int vbits = 0; +#endif + 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; +#ifndef LIBRAW_NOTHREADS +#undef bitbuf +#undef vbits +#endif +} + +void LibRaw::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(*c_black)[2], (*r_black)[2]; + if (ph1.format == 6) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + pixel = (ushort *)calloc(raw_width * 3 + raw_height * 4, 2); + offset = (int *)(pixel + raw_width); + fseek(ifp, strip_offset, SEEK_SET); + for (row = 0; row < raw_height; row++) + offset[row] = get4(); + c_black = (short(*)[2])(offset + raw_height); + fseek(ifp, ph1.black_col, SEEK_SET); + if (ph1.black_col) + read_shorts((ushort *)c_black[0], raw_height * 2); + r_black = c_black + raw_height; + fseek(ifp, ph1.black_row, SEEK_SET); + if (ph1.black_row) + read_shorts((ushort *)r_black[0], raw_width * 2); + + // Copy data to internal copy (ever if not read) + if (ph1.black_col || ph1.black_row) + { + imgdata.rawdata.ph1_cblack = + (short(*)[2])calloc(raw_height * 2, sizeof(ushort)); + memmove(imgdata.rawdata.ph1_cblack, (ushort *)c_black[0], + raw_height * 2 * sizeof(ushort)); + imgdata.rawdata.ph1_rblack = + (short(*)[2])calloc(raw_width * 2, sizeof(ushort)); + memmove(imgdata.rawdata.ph1_rblack, (ushort *)r_black[0], + raw_width * 2 * sizeof(ushort)); + } + + for (i = 0; i < 256; i++) + curve[i] = i * i / 3.969 + 0.5; + try + { + for (row = 0; row < raw_height; row++) + { + checkCancel(); + 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]]; + } + if (ph1.format == 8) + memmove(&RAW(row, 0), &pixel[0], raw_width * 2); + else + for (col = 0; col < raw_width; col++) + RAW(row, col) = pixel[col] << 2; + } + } + catch (...) + { + free(pixel); + throw; + } + free(pixel); + maximum = 0xfffc - ph1.t_black; +} + +void LibRaw::hasselblad_load_raw() +{ + struct jhead jh; + int shot, row, col, *back[5]={0,0,0,0,0}, + len[2], diff[12], pred, sh, f, c; + unsigned s; + unsigned upix, urow, ucol; + ushort *ip; + + if (!ljpeg_start(&jh, 0)) + return; + order = 0x4949; + ph1_bits(-1); + try + { + back[4] = (int *)calloc(raw_width, 3 * sizeof **back); + FORC3 back[c] = back[4] + c * raw_width; + cblack[6] >>= sh = tiff_samples > 1; + shot = LIM(shot_select, 1, tiff_samples) - 1; + for (row = 0; row < raw_height; row++) + { + checkCancel(); + FORC4 back[(c + 3) & 3] = back[c]; + for (col = 0; col < raw_width; col += 2) + { + for (s = 0; s < tiff_samples * 2; s += 2) + { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) + { + diff[s + c] = ph1_bits(len[c]); + if (len[c] > 0 && (diff[s + c] & (1 << (len[c] - 1))) == 0) + diff[s + c] -= (1 << len[c]) - 1; + if (diff[s + c] == 65535) + diff[s + c] = -32768; + } + } + for (s = col; s < unsigned(col + 2); s++) + { + pred = 0x8000 + load_flags; + if (col) + pred = back[2][s - 2]; + if (col && row > 1) + switch (jh.psv) + { + case 11: + pred += back[0][s] / 2 - back[0][s - 2] / 2; + break; + } + f = (row & 1) * 3 ^ ((col + s) & 1); + FORC(int(tiff_samples)) + { + pred += diff[(s & 1) * tiff_samples + c]; + upix = pred >> sh & 0xffff; + if (raw_image && c == shot) + RAW(row, s) = upix; + if (image) + { + urow = row - top_margin + (c & 1); + ucol = col - left_margin - ((c >> 1) & 1); + ip = &image[urow * width + ucol][f]; + if (urow < height && ucol < width) + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + back[2][s] = pred; + } + } + } + } + catch (...) + { + if(back[4]) + free(back[4]); + ljpeg_end(&jh); + throw; + } + if(back[4]) + free(back[4]); + ljpeg_end(&jh); + if (image) + mix_green = 1; +} + +void LibRaw::leaf_hdr_load_raw() +{ + ushort *pixel = 0; + unsigned tile = 0, r, c, row, col; + + if (!filters || !raw_image) + { + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + pixel = (ushort *)calloc(raw_width, sizeof *pixel); + } + try + { + FORC(tiff_samples) + for (r = 0; r < raw_height; r++) + { + checkCancel(); + 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 && raw_image) + pixel = raw_image + r * raw_width; + read_shorts(pixel, raw_width); + if (!filters && image && (row = r - top_margin) < height) + for (col = 0; col < width && col + left_margin < raw_width; col++) + image[row * width + col][c] = pixel[col + left_margin]; + } + } + catch (...) + { + if (!filters) + free(pixel); + throw; + } + if (!filters) + { + maximum = 0xffff; + raw_color = 1; + free(pixel); + } +} + +void LibRaw::unpacked_load_raw_FujiDBP() +/* +for Fuji DBP for GX680, aka DX-2000 + DBP_tile_width = 688; + DBP_tile_height = 3856; + DBP_n_tiles = 8; +*/ +{ + int scan_line, tile_n; + int nTiles; + + nTiles = 8; + tile_width = raw_width / nTiles; + + ushort *tile; + tile = (ushort *)calloc(raw_height, tile_width * 2); + + for (tile_n = 0; tile_n < nTiles; tile_n++) + { + read_shorts(tile, tile_width * raw_height); + for (scan_line = 0; scan_line < raw_height; scan_line++) + { + memcpy(&raw_image[scan_line * raw_width + tile_n * tile_width], + &tile[scan_line * tile_width], tile_width * 2); + } + } + free(tile); + fseek(ifp, -2, SEEK_CUR); // avoid EOF error +} + +void LibRaw::sinar_4shot_load_raw() +{ + ushort *pixel; + unsigned shot, row, col, r, c; + + if (raw_image) + { + shot = LIM(shot_select, 1, 4) - 1; + fseek(ifp, data_offset + shot * 4, SEEK_SET); + fseek(ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + pixel = (ushort *)calloc(raw_width, sizeof *pixel); + try + { + for (shot = 0; shot < 4; shot++) + { + checkCancel(); + fseek(ifp, data_offset + shot * 4, SEEK_SET); + fseek(ifp, get4(), SEEK_SET); + for (row = 0; row < raw_height; row++) + { + read_shorts(pixel, raw_width); + if ((r = row - top_margin - (shot >> 1 & 1)) >= height) + continue; + for (col = 0; col < raw_width; col++) + { + if ((c = col - left_margin - (shot & 1)) >= width) + continue; + image[r * width + c][(row & 1) * 3 ^ (~col & 1)] = pixel[col]; + } + } + } + } + catch (...) + { + free(pixel); + throw; + } + free(pixel); + mix_green = 1; +} + +void LibRaw::imacon_full_load_raw() +{ + if (!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int row, col; + + unsigned short *buf = + (unsigned short *)malloc(width * 3 * sizeof(unsigned short)); + + for (row = 0; row < height; row++) + { + checkCancel(); + read_shorts(buf, width * 3); + unsigned short(*rowp)[4] = &image[row * width]; + for (col = 0; col < width; col++) + { + rowp[col][0] = buf[col * 3]; + rowp[col][1] = buf[col * 3 + 1]; + rowp[col][2] = buf[col * 3 + 2]; + rowp[col][3] = 0; + } + } + free(buf); +} diff --git a/src/decoders/smal.cpp b/src/decoders/smal.cpp new file mode 100644 index 000000000..2e549906e --- /dev/null +++ b/src/decoders/smal.cpp @@ -0,0 +1,181 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +#define HOLE(row) ((holes >> (((row)-raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void LibRaw::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 s, count, bin, next, i, sym[3]; + unsigned pix; + uchar diff, pred[] = {0, 0}; + ushort data = 0, range = 0; + + fseek(ifp, seg[0][1] + 1, SEEK_SET); + getbits(-1); + if (seg[1][0] > unsigned(raw_width * raw_height)) + seg[1][0] = raw_width * raw_height; + 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)) & ((~0u) << 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; + if (pix >= unsigned(raw_width * raw_height)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + raw_image[pix] = pred[pix & 1] += diff; + if (!(pix & 1) && HOLE(pix / raw_width)) + pix += 2; + } + maximum = 0xff; +} + +void LibRaw::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 LibRaw::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 LibRaw::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 LibRaw::smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek(ifp, 67, SEEK_SET); + offset = get4(); + nseg = (uchar)fgetc(ifp); + fseek(ifp, offset, SEEK_SET); + for (i = 0; i < nseg * 2; i++) + ((unsigned *)seg)[i] = get4() + data_offset * (i & 1); + fseek(ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek(ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i = 0; i < nseg; i++) + smal_decode_segment(seg + i, holes); + if (holes) + fill_holes(holes); +} + +#undef HOLE diff --git a/src/decoders/unpack.cpp b/src/decoders/unpack.cpp new file mode 100644 index 000000000..38adba453 --- /dev/null +++ b/src/decoders/unpack.cpp @@ -0,0 +1,493 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#include "../../internal/libraw_cameraids.h" +#include "../../internal/libraw_cxx_defs.h" + +#ifdef USE_RAWSPEED3 +#include "rawspeed3_capi.h" +#include +#endif + +int LibRaw::unpack(void) +{ + CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW); + CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); + try + { + + if (!libraw_internal_data.internal_data.input) + return LIBRAW_INPUT_CLOSED; + + RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 0, 2); + if (imgdata.rawparams.shot_select >= P1.raw_count) + return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE; + + if (!load_raw) + return LIBRAW_UNSPECIFIED_ERROR; + + // already allocated ? + if (imgdata.image) + { + free(imgdata.image); + imgdata.image = 0; + } + if (imgdata.rawdata.raw_alloc) + { + free(imgdata.rawdata.raw_alloc); + imgdata.rawdata.raw_alloc = 0; + } + if (libraw_internal_data.unpacker_data.meta_length) + { + if (libraw_internal_data.unpacker_data.meta_length > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + libraw_internal_data.internal_data.meta_data = + (char *)malloc(libraw_internal_data.unpacker_data.meta_length); + } + + libraw_decoder_info_t decoder_info; + get_decoder_info(&decoder_info); + + int save_iwidth = S.iwidth, save_iheight = S.iheight, + save_shrink = IO.shrink; + + int rwidth = S.raw_width, rheight = S.raw_height; + if (!IO.fuji_width) + { + // adjust non-Fuji allocation + if (rwidth < S.width + S.left_margin) + rwidth = S.width + S.left_margin; + if (rheight < S.height + S.top_margin) + rheight = S.height + S.top_margin; + } + if (rwidth > 65535 || + rheight > 65535) // No way to make image larger than 64k pix + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + imgdata.rawdata.raw_image = 0; + imgdata.rawdata.color4_image = 0; + imgdata.rawdata.color3_image = 0; + imgdata.rawdata.float_image = 0; + imgdata.rawdata.float3_image = 0; + +#ifdef USE_DNGSDK + if (imgdata.idata.dng_version && dnghost + && libraw_internal_data.unpacker_data.tiff_samples != 2 // Fuji SuperCCD; it is better to detect is more rigid way + && valid_for_dngsdk() && load_raw != &LibRaw::pentax_4shot_load_raw) + { + // Data size check + INT64 pixcount = + INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); + INT64 planecount = + (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); + INT64 samplesize = is_floating_point() ? 4 : 2; + INT64 bytes = pixcount * planecount * samplesize; + if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length ) + > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + // find ifd to check sample + try_dngsdk(); + if (raw_was_read()) + imgdata.process_warnings |= LIBRAW_WARN_DNGSDK_PROCESSED; + } +#endif +#ifdef USE_RAWSPEED3 + if (!raw_was_read() + && (!IO.fuji_width) // Do not use for fuji rotated + && ((imgdata.idata.raw_count == 1) + // Canon dual pixel, 1st frame + || (makeIs(LIBRAW_CAMERAMAKER_Canon) && imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select==0) + ) +#ifdef USE_RAWSPEED_BITS + && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_USE) +#else + && imgdata.rawparams.use_rawspeed +#endif + && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED3) + ) + { + INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); + INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); + INT64 bytes = pixcount * planecount * 2; // sample size is always 2 for rawspeed + if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length) + > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + if (!_rawspeed3_handle) + _rawspeed3_handle = rawspeed3_initdefault(); + + if (_rawspeed3_handle && ID.input->size() > 0) // large bound is checked at identify + { + void *_rawspeed_buffer = 0; + try { + ID.input->seek(0, SEEK_SET); + INT64 _rawspeed_buffer_sz = ID.input->size() + 32; + _rawspeed_buffer = malloc(_rawspeed_buffer_sz); + if (!_rawspeed_buffer) + throw LIBRAW_EXCEPTION_ALLOC; + ID.input->read(_rawspeed_buffer, ID.input->size(), 1); + + rawspeed3_ret_t rs3ret; + rawspeed3_clearresult(&rs3ret); + int status = rawspeed3_decodefile(_rawspeed3_handle, &rs3ret, _rawspeed_buffer, ID.input->size(), +#ifdef USE_RAWSPEED_BITS + !(imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) +#else + false +#endif + ); + if (status != rawspeed3_ok) + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; + + if (status == rawspeed3_not_supported) + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_NOTLISTED; + + if (status == rawspeed3_ok +#ifdef USE_RAWSPEED_BITS + || + (status == rawspeed3_ok_warnings && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_IGNOREERRORS)) +#endif + ) + { + + if ((S.raw_width != rs3ret.width) || (S.raw_height != rs3ret.height)) + throw "Size mismatch"; + + // DECODED w/ success + if (rs3ret.filters>1) // Fuji or bayer + imgdata.rawdata.raw_image = (ushort*)rs3ret.pixeldata; + else if (rs3ret.cpp == 4) + { + imgdata.rawdata.color4_image = (ushort(*)[4])rs3ret.pixeldata; + //if (r->whitePoint > 0 && r->whitePoint < 65536) + // C.maximum = r->whitePoint; + } + else if (rs3ret.cpp == 3) + { + imgdata.rawdata.color3_image = (ushort(*)[3])rs3ret.pixeldata; + //if (r->whitePoint > 0 && r->whitePoint < 65536) + // C.maximum = r->whitePoint; + } + + if (raw_was_read()) // buffers are assigned above + { + // set sizes + S.raw_pitch = rs3ret.pitch; + S.raw_width = rs3ret.width; + S.raw_height = rs3ret.height; + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROCESSED; + // if (r->whitePoint > 0 && r->whitePoint < 65536) + // C.maximum = r->whitePoint; + } + } + free(_rawspeed_buffer); + } + catch (...) + { + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROBLEM; + if (_rawspeed_buffer) + free(_rawspeed_buffer); + } + } + } +#endif +#ifdef USE_RAWSPEED + if (!raw_was_read()) + { + int rawspeed_enabled = 1; + + if (imgdata.idata.dng_version && (libraw_internal_data.unpacker_data.tiff_samples == 2 || imgdata.idata.raw_count > 1)) + rawspeed_enabled = 0; + + if (libraw_internal_data.unpacker_data.is_NikonTransfer) + rawspeed_enabled = 0; + + if (libraw_internal_data.unpacker_data.pana_encoding == 5) + rawspeed_enabled = 0; + + if (imgdata.idata.raw_count > 1) + rawspeed_enabled = 0; + if (!strncasecmp(imgdata.idata.software, "Magic", 5)) + rawspeed_enabled = 0; + // Disable rawspeed for double-sized Oly files + if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && + ((imgdata.sizes.raw_width > 6000) || + !strncasecmp(imgdata.idata.model, "SH-", 3) || + !strncasecmp(imgdata.idata.model, "TG-", 3) )) + rawspeed_enabled = 0; + + if (makeIs(LIBRAW_CAMERAMAKER_Canon) && + (libraw_internal_data.identify_data.unique_id == CanonID_EOS_6D_Mark_II)) + rawspeed_enabled = 0; + + if (imgdata.idata.dng_version && imgdata.idata.filters == 0 && + libraw_internal_data.unpacker_data.tiff_bps == 8) // Disable for 8 bit + rawspeed_enabled = 0; + + if (load_raw == &LibRaw::packed_load_raw && + makeIs(LIBRAW_CAMERAMAKER_Nikon) && + (!strncasecmp(imgdata.idata.model, "E", 1) || + !strncasecmp(imgdata.idata.model, "COOLPIX B", 9) || + !strncasecmp(imgdata.idata.model, "COOLPIX P9", 10) || + !strncasecmp(imgdata.idata.model, "COOLPIX P1000", 13))) + rawspeed_enabled = 0; + + if (load_raw == &LibRaw::nikon_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && + !strcasecmp(imgdata.idata.model, "D6")) + rawspeed_enabled = 0; + + if (load_raw == &LibRaw::lossless_jpeg_load_raw && + MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && + /* Not normalized models here, it is intentional */ + (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || + !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) + rawspeed_enabled = 0; + + if (load_raw == &LibRaw::nikon_load_raw && + makeIs(LIBRAW_CAMERAMAKER_Nikon) && + (!strncasecmp(imgdata.idata.model, "Z", 1) || !strncasecmp(imgdata.idata.model,"D780",4))) + rawspeed_enabled = 0; + + if (load_raw == &LibRaw::panasonic_load_raw && + libraw_internal_data.unpacker_data.pana_encoding > 4) + rawspeed_enabled = 0; + + // RawSpeed Supported, + if ( +#ifdef USE_RAWSPEED_BITS + (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_USE) +#else + imgdata.rawparams.use_rawspeed +#endif + && rawspeed_enabled && + !(is_sraw() && (imgdata.rawparams.specials & + (LIBRAW_RAWSPECIAL_SRAW_NO_RGB | + LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE))) && + (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && + _rawspeed_camerameta) + { + INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * + INT64(MAX(S.height, S.raw_height)); + INT64 planecount = (imgdata.idata.filters || P1.colors == 1) + ? 1 + : LIM(P1.colors, 3, 4); + INT64 bytes = + pixcount * planecount * 2; // sample size is always 2 for rawspeed + if (bytes + +INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + /*int rr = */ try_rawspeed(); + + } + } +#endif + if (!raw_was_read()) // RawSpeed failed or not run + { + // Not allocated on RawSpeed call, try call LibRaow + int zero_rawimage = 0; + if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) + { + // x3f foveon decoder and DNG float + // Do nothing! Decoder will allocate data internally + } + if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT) + { + if (imgdata.rawparams.shot_select) // single image extract + { + if (INT64(rwidth) * INT64(rheight + 8) * + INT64(sizeof(imgdata.rawdata.raw_image[0])) + + +INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + imgdata.rawdata.raw_alloc = malloc( + rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); + imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; + if (!S.raw_pitch) + S.raw_pitch = S.raw_width * 2; // Bayer case, not set before + } + else // Full image extract + { + if (INT64(rwidth) * INT64(rheight + 8) * + INT64(sizeof(imgdata.rawdata.raw_image[0])) * 4 + +INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + S.raw_pitch = S.raw_width * 8; + imgdata.rawdata.raw_alloc = 0; + imgdata.image = (ushort(*)[4])calloc( + unsigned(MAX(S.width, S.raw_width)) * + unsigned(MAX(S.height, S.raw_height) + 8), + sizeof(*imgdata.image)); + } + } + else if (decoder_info.decoder_flags & LIBRAW_DECODER_3CHANNEL) + { + if (INT64(rwidth) * INT64(rheight + 8) * + INT64(sizeof(imgdata.rawdata.raw_image[0])) * 3 + + INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + imgdata.rawdata.raw_alloc = malloc( + rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]) * 3); + imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; + if (!S.raw_pitch) + S.raw_pitch = S.raw_width * 6; + } + else if (imgdata.idata.filters || + P1.colors == + 1) // Bayer image or single color -> decode to raw_image + { + if (INT64(rwidth) * INT64(rheight + 8) * + INT64(sizeof(imgdata.rawdata.raw_image[0])) + + INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + imgdata.rawdata.raw_alloc = malloc( + rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); + imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; + if (!S.raw_pitch) + S.raw_pitch = S.raw_width * 2; // Bayer case, not set before + } + else // NO LEGACY FLAG if (decoder_info.decoder_flags & + // LIBRAW_DECODER_LEGACY) + { + if (decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) + { + S.raw_pitch = S.raw_width * 8; + } + else + { + S.iwidth = S.width; + S.iheight = S.height; + IO.shrink = 0; + if (!S.raw_pitch) + S.raw_pitch = (decoder_info.decoder_flags & + LIBRAW_DECODER_LEGACY_WITH_MARGINS) + ? S.raw_width * 8 + : S.width * 8; + } + // sRAW and old Foveon decoders only, so extra buffer size is just 1/4 + // allocate image as temporary buffer, size + if (INT64(MAX(S.width, S.raw_width)) * + INT64(MAX(S.height, S.raw_height) + 8) * + INT64(sizeof(*imgdata.image)) + + INT64(libraw_internal_data.unpacker_data.meta_length) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + imgdata.rawdata.raw_alloc = 0; + imgdata.image = + (ushort(*)[4])calloc(unsigned(MAX(S.width, S.raw_width)) * + unsigned(MAX(S.height, S.raw_height) + 8), + sizeof(*imgdata.image)); + if (!(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL)) + { + imgdata.rawdata.raw_image = (ushort *)imgdata.image; + zero_rawimage = 1; + } + } + ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); + + unsigned m_save = C.maximum; + if (load_raw == &LibRaw::unpacked_load_raw && + (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) + ) + C.maximum = 65535; + (this->*load_raw)(); + if (zero_rawimage) + imgdata.rawdata.raw_image = 0; + if (load_raw == &LibRaw::unpacked_load_raw && + (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) + ) + C.maximum = m_save; + if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) + { + // x3f foveon decoder only: do nothing + } + else if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT && + imgdata.rawparams.shot_select == 0) + { + imgdata.rawdata.raw_alloc = imgdata.image; + imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; + imgdata.image = 0; + } + else if (!(imgdata.idata.filters || + P1.colors == 1)) // legacy decoder, ownalloc handled above + { + // successfully decoded legacy image, attach image to raw_alloc + imgdata.rawdata.raw_alloc = imgdata.image; + imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; + imgdata.image = 0; + // Restore saved values. Note: Foveon have masked frame + // Other 4-color legacy data: no borders + if (!(libraw_internal_data.unpacker_data.load_flags & 256) && + !(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) && + !(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS)) + { + S.raw_width = S.width; + S.left_margin = 0; + S.raw_height = S.height; + S.top_margin = 0; + } + } + } + + if (imgdata.rawdata.raw_image) + crop_masked_pixels(); // calculate black levels + + // recover image sizes + S.iwidth = save_iwidth; + S.iheight = save_iheight; + IO.shrink = save_shrink; + + // adjust black to possible maximum + unsigned int i = C.cblack[3]; + unsigned int c; + for (c = 0; c < 3; c++) + if (i > C.cblack[c]) + i = C.cblack[c]; + for (c = 0; c < 4; c++) + C.cblack[c] -= i; + C.black += i; + + // Save color,sizes and internal data into raw_image fields + memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); + memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); + memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); + memmove(&imgdata.rawdata.ioparams, + &libraw_internal_data.internal_output_params, + sizeof(libraw_internal_data.internal_output_params)); + + SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW); + RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 1, 2); + + return 0; + } + catch (const std::bad_alloc&) + { + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } + catch (const std::exception& ) + { + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); + } +} diff --git a/src/decoders/unpack_thumb.cpp b/src/decoders/unpack_thumb.cpp new file mode 100644 index 000000000..1f01ddc12 --- /dev/null +++ b/src/decoders/unpack_thumb.cpp @@ -0,0 +1,385 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#ifndef NO_JPEG +struct jpegErrorManager +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +static void jpegErrorExit(j_common_ptr cinfo) +{ + jpegErrorManager *myerr = (jpegErrorManager *)cinfo->err; + longjmp(myerr->setjmp_buffer, 1); +} +#endif + +int LibRaw::unpack_thumb_ex(int idx) +{ + if (idx < 0 || idx >= imgdata.thumbs_list.thumbcount || idx >= LIBRAW_THUMBNAIL_MAXCOUNT) + return LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL; + + // Set from thumb-list + libraw_internal_data.internal_data.toffset = imgdata.thumbs_list.thumblist[idx].toffset; + imgdata.thumbnail.tlength = imgdata.thumbs_list.thumblist[idx].tlength; + libraw_internal_data.unpacker_data.thumb_format = imgdata.thumbs_list.thumblist[idx].tformat; + imgdata.thumbnail.twidth = imgdata.thumbs_list.thumblist[idx].twidth; + imgdata.thumbnail.theight = imgdata.thumbs_list.thumblist[idx].theight; + libraw_internal_data.unpacker_data.thumb_misc = imgdata.thumbs_list.thumblist[idx].tmisc; + int rc = unpack_thumb(); + imgdata.progress_flags &= ~LIBRAW_PROGRESS_THUMB_LOAD; + + return rc; +} + + +int LibRaw::unpack_thumb(void) +{ + CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); + CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD); + +#define THUMB_SIZE_CHECKT(A) \ + do { \ + if (INT64(A) > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ + if (INT64(A) > 0 && INT64(A) < 64LL) return LIBRAW_NO_THUMBNAIL; \ + } while (0) + +#define THUMB_SIZE_CHECKTNZ(A) \ + do { \ + if (INT64(A) > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ + if (INT64(A) < 64LL) return LIBRAW_NO_THUMBNAIL; \ + } while (0) + + +#define THUMB_SIZE_CHECKWH(W,H) \ + do { \ + if (INT64(W)*INT64(H) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) return LIBRAW_UNSUPPORTED_THUMBNAIL; \ + if (INT64(W)*INT64(H) < 64ULL) return LIBRAW_NO_THUMBNAIL; \ + } while (0) + +#define Tformat libraw_internal_data.unpacker_data.thumb_format + + try + { + if (!libraw_internal_data.internal_data.input) + return LIBRAW_INPUT_CLOSED; + + int t_colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7; + int t_bytesps = (libraw_internal_data.unpacker_data.thumb_misc & 31) / 8; + + if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && + load_raw == &LibRaw::broadcom_load_raw) // RPi +#ifdef USE_6BY9RPI + && !(imgdata.thumbnail.tlength > 0 && libraw_internal_data.unpacker_data.load_flags & 0x4000 + && (load_raw == &LibRaw::rpi_load_raw8 || load_raw == &LibRaw::nokia_load_raw || + load_raw == &LibRaw::rpi_load_raw12 || load_raw == &LibRaw::rpi_load_raw14)) +#endif + ) + { + return LIBRAW_NO_THUMBNAIL; + } + else if ((Tformat >= LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB) + && ((Tformat <= LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB))) + { + kodak_thumb_loader(); + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + else + { +#ifdef USE_X3FTOOLS + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) + { + INT64 tsize = x3f_thumb_size(); + if (tsize < 2048 || INT64(ID.toffset) + tsize < 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND) + throw LIBRAW_EXCEPTION_IO_EOF; + THUMB_SIZE_CHECKT(tsize); + } +#else + if (0) {} +#endif + else + { + if (INT64(ID.toffset) + INT64(T.tlength) < 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (INT64(ID.toffset) + INT64(T.tlength) > + ID.input->size() + THUMB_READ_BEYOND) + throw LIBRAW_EXCEPTION_IO_EOF; + } + + ID.input->seek(ID.toffset, SEEK_SET); + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) + { + THUMB_SIZE_CHECKTNZ(T.tlength); + if (T.thumb) + free(T.thumb); + T.thumb = (char *)malloc(T.tlength); + ID.input->read(T.thumb, 1, T.tlength); + unsigned char *tthumb = (unsigned char *)T.thumb; + if (load_raw == &LibRaw::crxLoadRaw && T.tlength > 0xE0) + { + // Check if it is canon H.265 preview: CISZ at bytes 4-6, CISZ prefix is 000n + if (tthumb[0] == 0 && tthumb[1] == 0 && tthumb[2] == 0 && !memcmp(tthumb + 4, "CISZ", 4)) + { + T.tformat = LIBRAW_THUMBNAIL_H265; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + } + tthumb[0] = 0xff; + tthumb[1] = 0xd8; +#ifdef NO_JPEG + T.tcolors = 3; +#else + { + jpegErrorManager jerr; + struct jpeg_decompress_struct cinfo; + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = jpegErrorExit; + if (setjmp(jerr.setjmp_buffer)) + { + err2: + // Error in original JPEG thumb, read it again because + // original bytes 0-1 was damaged above + jpeg_destroy_decompress(&cinfo); + T.tcolors = 3; + T.tformat = LIBRAW_THUMBNAIL_UNKNOWN; + ID.input->seek(ID.toffset, SEEK_SET); + ID.input->read(T.thumb, 1, T.tlength); + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + jpeg_create_decompress(&cinfo); + jpeg_mem_src(&cinfo, (unsigned char *)T.thumb, T.tlength); + int rc = jpeg_read_header(&cinfo, TRUE); + if (rc != 1) + goto err2; + T.tcolors = (cinfo.num_components > 0 && cinfo.num_components <= 3) + ? cinfo.num_components + : 3; + jpeg_destroy_decompress(&cinfo); + } +#endif + T.tformat = LIBRAW_THUMBNAIL_JPEG; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_LAYER) + { + int colors = libraw_internal_data.unpacker_data.thumb_misc >> 5 & 7; + if (colors != 1 && colors != 3) + return LIBRAW_UNSUPPORTED_THUMBNAIL; + + THUMB_SIZE_CHECKWH(T.twidth, T.theight); + + int tlength = T.twidth * T.theight; + if (T.thumb) + free(T.thumb); + T.thumb = (char *)calloc(colors, tlength); + unsigned char *tbuf = (unsigned char *)calloc(colors, tlength); + // Avoid OOB of tbuf, should use tlength + ID.input->read(tbuf, colors, tlength); + if (libraw_internal_data.unpacker_data.thumb_misc >> 8 && + colors == 3) // GRB order + for (int i = 0; i < tlength; i++) + { + T.thumb[i * 3] = tbuf[i + tlength]; + T.thumb[i * 3 + 1] = tbuf[i]; + T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength]; + } + else if (colors == 3) // RGB or 1-channel + for (int i = 0; i < tlength; i++) + { + T.thumb[i * 3] = tbuf[i]; + T.thumb[i * 3 + 1] = tbuf[i + tlength]; + T.thumb[i * 3 + 2] = tbuf[i + 2 * tlength]; + } + else if (colors == 1) + { + free(T.thumb); + T.thumb = (char *)tbuf; + tbuf = 0; + } + if (tbuf) + free(tbuf); + T.tcolors = colors; + T.tlength = colors * tlength; + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_ROLLEI) + { + int i; + THUMB_SIZE_CHECKWH(T.twidth, T.theight); + int tlength = T.twidth * T.theight; + if (T.thumb) + free(T.thumb); + T.tcolors = 3; + T.thumb = (char *)calloc(T.tcolors, tlength); + unsigned short *tbuf = (unsigned short *)calloc(2, tlength); + read_shorts(tbuf, tlength); + for (i = 0; i < tlength; i++) + { + T.thumb[i * 3] = (tbuf[i] << 3) & 0xff; + T.thumb[i * 3 + 1] = (tbuf[i] >> 5 << 2) & 0xff; + T.thumb[i * 3 + 2] = (tbuf[i] >> 11 << 3) & 0xff; + } + free(tbuf); + T.tlength = T.tcolors * tlength; + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) + { + if (t_bytesps > 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more + // bits + THUMB_SIZE_CHECKWH(T.twidth, T.theight); + int t_length = T.twidth * T.theight * t_colors; + + if (T.tlength && + (int)T.tlength < t_length) // try to find tiff ifd with needed offset + { + int pifd = find_ifd_by_offset(libraw_internal_data.internal_data.toffset); + if (pifd >= 0 && tiff_ifd[pifd].strip_offsets_count && + tiff_ifd[pifd].strip_byte_counts_count) + { + // We found it, calculate final size + unsigned total_size = 0; + for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count; i++) + total_size += tiff_ifd[pifd].strip_byte_counts[i]; + if (total_size != (unsigned)t_length) // recalculate colors + { + if (total_size == T.twidth * T.tlength * 3) + T.tcolors = 3; + else if (total_size == T.twidth * T.tlength) + T.tcolors = 1; + } + T.tlength = total_size; + THUMB_SIZE_CHECKTNZ(T.tlength); + if (T.thumb) + free(T.thumb); + T.thumb = (char *)malloc(T.tlength); + + char *dest = T.thumb; + INT64 pos = ID.input->tell(); + + for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count && + i < tiff_ifd[pifd].strip_offsets_count; + i++) + { + int remain = T.tlength; + int sz = tiff_ifd[pifd].strip_byte_counts[i]; + int off = tiff_ifd[pifd].strip_offsets[i]; + if (off >= 0 && off + sz <= ID.input->size() && sz <= remain) + { + ID.input->seek(off, SEEK_SET); + ID.input->read(dest, sz, 1); + remain -= sz; + dest += sz; + } + } + ID.input->seek(pos, SEEK_SET); + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + } + + if (!T.tlength) + T.tlength = t_length; + if (T.thumb) + free(T.thumb); + + THUMB_SIZE_CHECKTNZ(T.tlength); + + T.thumb = (char *)malloc(T.tlength); + if (!T.tcolors) + T.tcolors = t_colors; + + ID.input->read(T.thumb, 1, T.tlength); + + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM16) + { + if (t_bytesps > 2) + throw LIBRAW_EXCEPTION_IO_CORRUPT; // 16-bit thumb, but parsed for + // more bits + int o_bps = (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1; + int o_length = T.twidth * T.theight * t_colors * o_bps; + int i_length = T.twidth * T.theight * t_colors * 2; + if (!T.tlength) + T.tlength = o_length; + THUMB_SIZE_CHECKTNZ(o_length); + THUMB_SIZE_CHECKTNZ(i_length); + THUMB_SIZE_CHECKTNZ(T.tlength); + + ushort *t_thumb = (ushort *)calloc(i_length, 1); + ID.input->read(t_thumb, 1, i_length); + if ((libraw_internal_data.unpacker_data.order == 0x4949) == + (ntohs(0x1234) == 0x1234)) + libraw_swab(t_thumb, i_length); + + if (T.thumb) + free(T.thumb); + if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS)) + { + T.thumb = (char *)t_thumb; + T.tformat = LIBRAW_THUMBNAIL_BITMAP16; + } + else + { + T.thumb = (char *)malloc(o_length); + for (int i = 0; i < o_length; i++) + T.thumb[i] = t_thumb[i] >> 8; + free(t_thumb); + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + } + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } +#ifdef USE_X3FTOOLS + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) + { + x3f_thumb_loader(); + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } +#endif + else + { + return LIBRAW_UNSUPPORTED_THUMBNAIL; + } + } + // last resort + return LIBRAW_UNSUPPORTED_THUMBNAIL; /* warned as unreachable*/ + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } +} diff --git a/src/demosaic/aahd_demosaic.cpp b/src/demosaic/aahd_demosaic.cpp new file mode 100644 index 000000000..942176566 --- /dev/null +++ b/src/demosaic/aahd_demosaic.cpp @@ -0,0 +1,781 @@ +/* -*- C++ -*- + * File: aahd_demosaic.cpp + * Copyright 2013 Anton Petrusevich + * Created: Wed May 15, 2013 + * + * This code is licensed under one of two licenses as you choose: + * + * 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + * (See file LICENSE.LGPL provided in LibRaw distribution archive for + * details). + * + * 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + * (See file LICENSE.CDDL provided in LibRaw distribution archive for + * details). + * + */ + +#include "../../internal/dmp_include.h" + +typedef ushort ushort3[3]; +typedef int int3[3]; + +#ifndef Pnw +#define Pnw (-1 - nr_width) +#define Pn (-nr_width) +#define Pne (+1 - nr_width) +#define Pe (+1) +#define Pse (+1 + nr_width) +#define Ps (+nr_width) +#define Psw (-1 + nr_width) +#define Pw (-1) +#endif + +struct AAHD +{ + int nr_height, nr_width; + static const int nr_margin = 4; + static const int Thot = 4; + static const int Tdead = 4; + static const int OverFraction = 8; + ushort3 *rgb_ahd[2]; + int3 *yuv[2]; + char *ndir, *homo[2]; + ushort channel_maximum[3], channels_max; + ushort channel_minimum[3]; + static const float yuv_coeff[3][3]; + static float gammaLUT[0x10000]; + float yuv_cam[3][3]; + LibRaw &libraw; + enum + { + HVSH = 1, + HOR = 2, + VER = 4, + HORSH = HOR | HVSH, + VERSH = VER | HVSH, + HOT = 8 + }; + + static inline float calc_dist(int c1, int c2) throw() + { + return c1 > c2 ? (float)c1 / c2 : (float)c2 / c1; + } + int inline Y(ushort3 &rgb) throw() + { + return yuv_cam[0][0] * rgb[0] + yuv_cam[0][1] * rgb[1] + + yuv_cam[0][2] * rgb[2]; + } + int inline U(ushort3 &rgb) throw() + { + return yuv_cam[1][0] * rgb[0] + yuv_cam[1][1] * rgb[1] + + yuv_cam[1][2] * rgb[2]; + } + int inline V(ushort3 &rgb) throw() + { + return yuv_cam[2][0] * rgb[0] + yuv_cam[2][1] * rgb[1] + + yuv_cam[2][2] * rgb[2]; + } + inline int nr_offset(int row, int col) throw() + { + return (row * nr_width + col); + } + ~AAHD(); + AAHD(LibRaw &_libraw); + void make_ahd_greens(); + void make_ahd_gline(int i); + void make_ahd_rb(); + void make_ahd_rb_hv(int i); + void make_ahd_rb_last(int i); + void evaluate_ahd(); + void combine_image(); + void hide_hots(); + void refine_hv_dirs(); + void refine_hv_dirs(int i, int js); + void refine_ihv_dirs(int i); + void illustrate_dirs(); + void illustrate_dline(int i); +}; + +const float AAHD::yuv_coeff[3][3] = { + // YPbPr + // { + // 0.299f, + // 0.587f, + // 0.114f }, + // { + // -0.168736, + // -0.331264f, + // 0.5f }, + // { + // 0.5f, + // -0.418688f, + // -0.081312f } + // + // Rec. 2020 + // Y'= 0,2627R' + 0,6780G' + 0,0593B' + // U = (B-Y)/1.8814 = (-0,2627R' - 0,6780G' + 0.9407B) / 1.8814 = + //-0.13963R - 0.36037G + 0.5B + // V = (R-Y)/1.4647 = (0.7373R - 0,6780G - 0,0593B) / 1.4647 = 0.5R - + //0.4629G - 0.04049B + {+0.2627f, +0.6780f, +0.0593f}, + {-0.13963f, -0.36037f, +0.5f}, + {+0.5034f, -0.4629f, -0.0405f} + +}; + +float AAHD::gammaLUT[0x10000] = {-1.f}; + +AAHD::AAHD(LibRaw &_libraw) : libraw(_libraw) +{ + nr_height = libraw.imgdata.sizes.iheight + nr_margin * 2; + nr_width = libraw.imgdata.sizes.iwidth + nr_margin * 2; + rgb_ahd[0] = (ushort3 *)calloc(nr_height * nr_width, + (sizeof(ushort3) * 2 + sizeof(int3) * 2 + 3)); + if (!rgb_ahd[0]) + throw LIBRAW_EXCEPTION_ALLOC; + + rgb_ahd[1] = rgb_ahd[0] + nr_height * nr_width; + yuv[0] = (int3 *)(rgb_ahd[1] + nr_height * nr_width); + yuv[1] = yuv[0] + nr_height * nr_width; + ndir = (char *)(yuv[1] + nr_height * nr_width); + homo[0] = ndir + nr_height * nr_width; + homo[1] = homo[0] + nr_height * nr_width; + channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0; + channel_minimum[0] = libraw.imgdata.image[0][0]; + channel_minimum[1] = libraw.imgdata.image[0][1]; + channel_minimum[2] = libraw.imgdata.image[0][2]; + int iwidth = libraw.imgdata.sizes.iwidth; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + { + yuv_cam[i][j] = 0; + for (int k = 0; k < 3; ++k) + yuv_cam[i][j] += yuv_coeff[i][k] * libraw.imgdata.color.rgb_cam[k][j]; + } + if (gammaLUT[0] < -0.1f) + { + float r; + for (int i = 0; i < 0x10000; i++) + { + r = (float)i / 0x10000; + gammaLUT[i] = + 0x10000 * (r < 0.0181 ? 4.5f * r : 1.0993f * pow(r, 0.45f) - .0993f); + } + } + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int col_cache[48]; + for (int j = 0; j < 48; ++j) + { + int c = libraw.COLOR(i, j); + if (c == 3) + c = 1; + col_cache[j] = c; + } + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < iwidth; ++j, ++moff) + { + int c = col_cache[j % 48]; + unsigned short d = libraw.imgdata.image[i * iwidth + j][c]; + if (d != 0) + { + if (channel_maximum[c] < d) + channel_maximum[c] = d; + if (channel_minimum[c] > d) + channel_minimum[c] = d; + rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = d; + } + } + } + channels_max = + MAX(MAX(channel_maximum[0], channel_maximum[1]), channel_maximum[2]); +} + +void AAHD::hide_hots() +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + int moff = nr_offset(i + nr_margin, nr_margin + js); + for (int j = js; j < iwidth; j += 2, moff += 2) + { + ushort3 *rgb = &rgb_ahd[0][moff]; + int c = rgb[0][kc]; + if ((c > rgb[2 * Pe][kc] && c > rgb[2 * Pw][kc] && c > rgb[2 * Pn][kc] && + c > rgb[2 * Ps][kc] && c > rgb[Pe][1] && c > rgb[Pw][1] && + c > rgb[Pn][1] && c > rgb[Ps][1]) || + (c < rgb[2 * Pe][kc] && c < rgb[2 * Pw][kc] && c < rgb[2 * Pn][kc] && + c < rgb[2 * Ps][kc] && c < rgb[Pe][1] && c < rgb[Pw][1] && + c < rgb[Pn][1] && c < rgb[Ps][1])) + { + int chot = c >> Thot; + int cdead = c << Tdead; + int avg = 0; + for (int k = -2; k < 3; k += 2) + for (int m = -2; m < 3; m += 2) + if (m == 0 && k == 0) + continue; + else + avg += rgb[nr_offset(k, m)][kc]; + avg /= 8; + if (chot > avg || cdead < avg) + { + ndir[moff] |= HOT; + int dh = + ABS(rgb[2 * Pw][kc] - rgb[2 * Pe][kc]) + + ABS(rgb[Pw][1] - rgb[Pe][1]) + + ABS(rgb[Pw][1] - rgb[Pe][1] + rgb[2 * Pe][kc] - rgb[2 * Pw][kc]); + int dv = + ABS(rgb[2 * Pn][kc] - rgb[2 * Ps][kc]) + + ABS(rgb[Pn][1] - rgb[Ps][1]) + + ABS(rgb[Pn][1] - rgb[Ps][1] + rgb[2 * Ps][kc] - rgb[2 * Pn][kc]); + int d; + if (dv > dh) + d = Pw; + else + d = Pn; + rgb_ahd[1][moff][kc] = rgb[0][kc] = + (rgb[+2 * d][kc] + rgb[-2 * d][kc]) / 2; + } + } + } + js ^= 1; + moff = nr_offset(i + nr_margin, nr_margin + js); + for (int j = js; j < iwidth; j += 2, moff += 2) + { + ushort3 *rgb = &rgb_ahd[0][moff]; + int c = rgb[0][1]; + if ((c > rgb[2 * Pe][1] && c > rgb[2 * Pw][1] && c > rgb[2 * Pn][1] && + c > rgb[2 * Ps][1] && c > rgb[Pe][kc] && c > rgb[Pw][kc] && + c > rgb[Pn][kc ^ 2] && c > rgb[Ps][kc ^ 2]) || + (c < rgb[2 * Pe][1] && c < rgb[2 * Pw][1] && c < rgb[2 * Pn][1] && + c < rgb[2 * Ps][1] && c < rgb[Pe][kc] && c < rgb[Pw][kc] && + c < rgb[Pn][kc ^ 2] && c < rgb[Ps][kc ^ 2])) + { + int chot = c >> Thot; + int cdead = c << Tdead; + int avg = 0; + for (int k = -2; k < 3; k += 2) + for (int m = -2; m < 3; m += 2) + if (k == 0 && m == 0) + continue; + else + avg += rgb[nr_offset(k, m)][1]; + avg /= 8; + if (chot > avg || cdead < avg) + { + ndir[moff] |= HOT; + int dh = + ABS(rgb[2 * Pw][1] - rgb[2 * Pe][1]) + + ABS(rgb[Pw][kc] - rgb[Pe][kc]) + + ABS(rgb[Pw][kc] - rgb[Pe][kc] + rgb[2 * Pe][1] - rgb[2 * Pw][1]); + int dv = ABS(rgb[2 * Pn][1] - rgb[2 * Ps][1]) + + ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2]) + + ABS(rgb[Pn][kc ^ 2] - rgb[Ps][kc ^ 2] + rgb[2 * Ps][1] - + rgb[2 * Pn][1]); + int d; + if (dv > dh) + d = Pw; + else + d = Pn; + rgb_ahd[1][moff][1] = rgb[0][1] = + (rgb[+2 * d][1] + rgb[-2 * d][1]) / 2; + } + } + } + } +} + +void AAHD::evaluate_ahd() +{ + int hvdir[4] = {Pw, Pe, Pn, Ps}; + /* + * YUV + * + */ + for (int d = 0; d < 2; ++d) + { + for (int i = 0; i < nr_width * nr_height; ++i) + { + ushort3 rgb; + for (int c = 0; c < 3; ++c) + { + rgb[c] = gammaLUT[rgb_ahd[d][i][c]]; + } + yuv[d][i][0] = Y(rgb); + yuv[d][i][1] = U(rgb); + yuv[d][i][2] = V(rgb); + } + } + /* */ + /* + * Lab + * + float r, cbrt[0x10000], xyz[3], xyz_cam[3][4]; + for (int i = 0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow((double) r, (double) (1 / 3.0)) : 7.787 * r + 16 + / 116.0; + } + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) { + xyz_cam[i][j] = 0; + for (int k = 0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * libraw.imgdata.color.rgb_cam[k][j] / + d65_white[i]; + } + for (int d = 0; d < 2; ++d) + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) { + xyz[0] = xyz[1] = xyz[2] = 0.5; + for (int c = 0; c < 3; c++) { + xyz[0] += xyz_cam[0][c] * rgb_ahd[d][moff][c]; + xyz[1] += xyz_cam[1][c] * rgb_ahd[d][moff][c]; + xyz[2] += xyz_cam[2][c] * rgb_ahd[d][moff][c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + yuv[d][moff][0] = 64 * (116 * xyz[1] - 16); + yuv[d][moff][1] = 64 * 500 * (xyz[0] - xyz[1]); + yuv[d][moff][2] = 64 * 200 * (xyz[1] - xyz[2]); + } + } + * Lab */ + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) + { + int3 *ynr; + float ydiff[2][4]; + int uvdiff[2][4]; + for (int d = 0; d < 2; ++d) + { + ynr = &yuv[d][moff]; + for (int k = 0; k < 4; k++) + { + ydiff[d][k] = ABS(ynr[0][0] - ynr[hvdir[k]][0]); + uvdiff[d][k] = SQR(ynr[0][1] - ynr[hvdir[k]][1]) + + SQR(ynr[0][2] - ynr[hvdir[k]][2]); + } + } + float yeps = + MIN(MAX(ydiff[0][0], ydiff[0][1]), MAX(ydiff[1][2], ydiff[1][3])); + int uveps = + MIN(MAX(uvdiff[0][0], uvdiff[0][1]), MAX(uvdiff[1][2], uvdiff[1][3])); + for (int d = 0; d < 2; d++) + { + ynr = &yuv[d][moff]; + for (int k = 0; k < 4; k++) + if (ydiff[d][k] <= yeps && uvdiff[d][k] <= uveps) + { + homo[d][moff + hvdir[k]]++; + if (k / 2 == d) + { + // еÑли в Ñонаправленном направлении интеполÑции Ñледующие точки + // так же гомогенны, учтём их тоже + for (int m = 2; m < 4; ++m) + { + int hvd = m * hvdir[k]; + if (ABS(ynr[0][0] - ynr[hvd][0]) < yeps && + SQR(ynr[0][1] - ynr[hvd][1]) + + SQR(ynr[0][2] - ynr[hvd][2]) < + uveps) + { + homo[d][moff + hvd]++; + } + else + break; + } + } + } + } + } + } + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff) + { + char hm[2]; + for (int d = 0; d < 2; d++) + { + hm[d] = 0; + char *hh = &homo[d][moff]; + for (int hx = -1; hx < 2; hx++) + for (int hy = -1; hy < 2; hy++) + hm[d] += hh[nr_offset(hy, hx)]; + } + char d = 0; + if (hm[0] != hm[1]) + { + if (hm[1] > hm[0]) + { + d = VERSH; + } + else + { + d = HORSH; + } + } + else + { + int3 *ynr = &yuv[1][moff]; + int gv = SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]); + gv += SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2]); + ynr = &yuv[1][moff + Pn]; + gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) + + SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / + 2; + ynr = &yuv[1][moff + Ps]; + gv += (SQR(2 * ynr[0][0] - ynr[Pn][0] - ynr[Ps][0]) + + SQR(2 * ynr[0][1] - ynr[Pn][1] - ynr[Ps][1]) + + SQR(2 * ynr[0][2] - ynr[Pn][2] - ynr[Ps][2])) / + 2; + ynr = &yuv[0][moff]; + int gh = SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]); + gh += SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2]); + ynr = &yuv[0][moff + Pw]; + gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) + + SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / + 2; + ynr = &yuv[0][moff + Pe]; + gh += (SQR(2 * ynr[0][0] - ynr[Pw][0] - ynr[Pe][0]) + + SQR(2 * ynr[0][1] - ynr[Pw][1] - ynr[Pe][1]) + + SQR(2 * ynr[0][2] - ynr[Pw][2] - ynr[Pe][2])) / + 2; + if (gv > gh) + d = HOR; + else + d = VER; + } + ndir[moff] |= d; + } + } +} + +void AAHD::combine_image() +{ + for (int i = 0, i_out = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < libraw.imgdata.sizes.iwidth; j++, ++moff, ++i_out) + { + if (ndir[moff] & HOT) + { + int c = libraw.COLOR(i, j); + rgb_ahd[1][moff][c] = rgb_ahd[0][moff][c] = + libraw.imgdata.image[i_out][c]; + } + if (ndir[moff] & VER) + { + libraw.imgdata.image[i_out][0] = rgb_ahd[1][moff][0]; + libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] = + rgb_ahd[1][moff][1]; + libraw.imgdata.image[i_out][2] = rgb_ahd[1][moff][2]; + } + else + { + libraw.imgdata.image[i_out][0] = rgb_ahd[0][moff][0]; + libraw.imgdata.image[i_out][3] = libraw.imgdata.image[i_out][1] = + rgb_ahd[0][moff][1]; + libraw.imgdata.image[i_out][2] = rgb_ahd[0][moff][2]; + } + } + } +} + +void AAHD::refine_hv_dirs() +{ + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_hv_dirs(i, i & 1); + } + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_hv_dirs(i, (i & 1) ^ 1); + } + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_ihv_dirs(i); + } +} + +void AAHD::refine_ihv_dirs(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < iwidth; j++, ++moff) + { + if (ndir[moff] & HVSH) + continue; + int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + + (ndir[moff + Pw] & VER) + (ndir[moff + Pe] & VER); + int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + + (ndir[moff + Pw] & HOR) + (ndir[moff + Pe] & HOR); + nv /= VER; + nh /= HOR; + if ((ndir[moff] & VER) && nh > 3) + { + ndir[moff] &= ~VER; + ndir[moff] |= HOR; + } + if ((ndir[moff] & HOR) && nv > 3) + { + ndir[moff] &= ~HOR; + ndir[moff] |= VER; + } + } +} + +void AAHD::refine_hv_dirs(int i, int js) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int moff = nr_offset(i + nr_margin, nr_margin + js); + for (int j = js; j < iwidth; j += 2, moff += 2) + { + int nv = (ndir[moff + Pn] & VER) + (ndir[moff + Ps] & VER) + + (ndir[moff + Pw] & VER) + (ndir[moff + Pe] & VER); + int nh = (ndir[moff + Pn] & HOR) + (ndir[moff + Ps] & HOR) + + (ndir[moff + Pw] & HOR) + (ndir[moff + Pe] & HOR); + bool codir = (ndir[moff] & VER) + ? ((ndir[moff + Pn] & VER) || (ndir[moff + Ps] & VER)) + : ((ndir[moff + Pw] & HOR) || (ndir[moff + Pe] & HOR)); + nv /= VER; + nh /= HOR; + if ((ndir[moff] & VER) && (nh > 2 && !codir)) + { + ndir[moff] &= ~VER; + ndir[moff] |= HOR; + } + if ((ndir[moff] & HOR) && (nv > 2 && !codir)) + { + ndir[moff] &= ~HOR; + ndir[moff] |= VER; + } + } +} + +/* + * вычиÑление недоÑтающих зелёных точек. + */ +void AAHD::make_ahd_greens() +{ + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_ahd_gline(i); + } +} + +void AAHD::make_ahd_gline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + int hvdir[2] = {Pe, Ps}; + for (int d = 0; d < 2; ++d) + { + int moff = nr_offset(i + nr_margin, nr_margin + js); + for (int j = js; j < iwidth; j += 2, moff += 2) + { + ushort3 *cnr; + cnr = &rgb_ahd[d][moff]; + int h1 = 2 * cnr[-hvdir[d]][1] - int(cnr[-2 * hvdir[d]][kc] + cnr[0][kc]); + int h2 = 2 * cnr[+hvdir[d]][1] - int(cnr[+2 * hvdir[d]][kc] + cnr[0][kc]); + int h0 = (h1 + h2) / 4; + int eg = cnr[0][kc] + h0; + int min = MIN(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]); + int max = MAX(cnr[-hvdir[d]][1], cnr[+hvdir[d]][1]); + min -= min / OverFraction; + max += max / OverFraction; + if (eg < min) + eg = min - sqrt(float(min - eg)); + else if (eg > max) + eg = max + sqrt(float(eg - max)); + if (eg > channel_maximum[1]) + eg = channel_maximum[1]; + else if (eg < channel_minimum[1]) + eg = channel_minimum[1]; + cnr[0][1] = eg; + } + } +} + +/* + * Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + */ + +void AAHD::illustrate_dirs() +{ + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + illustrate_dline(i); + } +} + +void AAHD::illustrate_dline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_margin; + int y = i + nr_margin; + rgb_ahd[1][nr_offset(y, x)][0] = rgb_ahd[1][nr_offset(y, x)][1] = + rgb_ahd[1][nr_offset(y, x)][2] = rgb_ahd[0][nr_offset(y, x)][0] = + rgb_ahd[0][nr_offset(y, x)][1] = rgb_ahd[0][nr_offset(y, x)][2] = 0; + int l = ndir[nr_offset(y, x)] & HVSH; + l /= HVSH; + if (ndir[nr_offset(y, x)] & VER) + rgb_ahd[1][nr_offset(y, x)][0] = + l * channel_maximum[0] / 4 + channel_maximum[0] / 4; + else + rgb_ahd[0][nr_offset(y, x)][2] = + l * channel_maximum[2] / 4 + channel_maximum[2] / 4; + } +} + +void AAHD::make_ahd_rb_hv(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + js ^= 1; // Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð° зелёного + int hvdir[2] = {Pe, Ps}; + // интерполÑÑ†Ð¸Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… вертикально и горизонтальных горизонтально + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_margin; + int y = i + nr_margin; + int moff = nr_offset(y, x); + for (int d = 0; d < 2; ++d) + { + ushort3 *cnr; + cnr = &rgb_ahd[d][moff]; + int c = kc ^ (d << 1); // цвет ÑоответÑвенного направлениÑ, Ð´Ð»Ñ + // горизонтального c = kc, Ð´Ð»Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ c=kc^2 + int h1 = cnr[-hvdir[d]][c] - cnr[-hvdir[d]][1]; + int h2 = cnr[+hvdir[d]][c] - cnr[+hvdir[d]][1]; + int h0 = (h1 + h2) / 2; + int eg = cnr[0][1] + h0; + // int min = MIN(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]); + // int max = MAX(cnr[-hvdir[d]][c], cnr[+hvdir[d]][c]); + // min -= min / OverFraction; + // max += max / OverFraction; + // if (eg < min) + // eg = min - sqrt(min - eg); + // else if (eg > max) + // eg = max + sqrt(eg - max); + if (eg > channel_maximum[c]) + eg = channel_maximum[c]; + else if (eg < channel_minimum[c]) + eg = channel_minimum[c]; + cnr[0][c] = eg; + } + } +} + +void AAHD::make_ahd_rb() +{ + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_ahd_rb_hv(i); + } + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_ahd_rb_last(i); + } +} + +void AAHD::make_ahd_rb_last(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + int dirs[2][3] = {{Pnw, Pn, Pne}, {Pnw, Pw, Psw}}; + int moff = nr_offset(i + nr_margin, nr_margin); + for (int j = 0; j < iwidth; j++) + { + for (int d = 0; d < 2; ++d) + { + ushort3 *cnr; + cnr = &rgb_ahd[d][moff + j]; + int c = kc ^ 2; + if ((j & 1) != js) + { + // точка зелёного, Ð´Ð»Ñ Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÑƒÐ¶ÐµÐ½ альтернативный + // Ñтрочному цвет + c ^= d << 1; + } + int bh = 0, bk = 0; + int bgd = 0; + for (int k = 0; k < 3; ++k) + for (int h = 0; h < 3; ++h) + { + // градиент зелёного Ð¿Ð»ÑŽÑ Ð³Ñ€Ð°Ð´Ð¸ÐµÐ½Ñ‚ {r,b} + int gd = + ABS(2 * cnr[0][1] - (cnr[+dirs[d][k]][1] + cnr[-dirs[d][h]][1])) + + ABS(cnr[+dirs[d][k]][c] - cnr[-dirs[d][h]][c]) / 4 + + ABS(cnr[+dirs[d][k]][c] - cnr[+dirs[d][k]][1] + + cnr[-dirs[d][h]][1] - cnr[-dirs[d][h]][c]) / + 4; + if (bgd == 0 || gd < bgd) + { + bgd = gd; + bh = h; + bk = k; + } + } + int h1 = cnr[+dirs[d][bk]][c] - cnr[+dirs[d][bk]][1]; + int h2 = cnr[-dirs[d][bh]][c] - cnr[-dirs[d][bh]][1]; + int eg = cnr[0][1] + (h1 + h2) / 2; + // int min = MIN(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]); + // int max = MAX(cnr[+dirs[d][bk]][c], cnr[-dirs[d][bh]][c]); + // min -= min / OverFraction; + // max += max / OverFraction; + // if (eg < min) + // eg = min - sqrt(min - eg); + // else if (eg > max) + // eg = max + sqrt(eg - max); + if (eg > channel_maximum[c]) + eg = channel_maximum[c]; + else if (eg < channel_minimum[c]) + eg = channel_minimum[c]; + cnr[0][c] = eg; + } + } +} + +AAHD::~AAHD() { free(rgb_ahd[0]); } + +void LibRaw::aahd_interpolate() +{ + AAHD aahd(*this); + aahd.hide_hots(); + aahd.make_ahd_greens(); + aahd.make_ahd_rb(); + aahd.evaluate_ahd(); + aahd.refine_hv_dirs(); + // aahd.illustrate_dirs(); + aahd.combine_image(); +} diff --git a/src/demosaic/ahd_demosaic.cpp b/src/demosaic/ahd_demosaic.cpp new file mode 100644 index 000000000..e743c96af --- /dev/null +++ b/src/demosaic/ahd_demosaic.cpp @@ -0,0 +1,355 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ + +void LibRaw::cielab(ushort rgb[3], short lab[3]) +{ + int c, i, j, k; + float r, xyz[3]; +#ifdef LIBRAW_NOTHREADS + static float cbrt[0x10000], xyz_cam[3][4]; +#else +#define cbrt tls->ahd_data.cbrt +#define xyz_cam tls->ahd_data.xyz_cam +#endif + + if (!rgb) + { +#ifndef LIBRAW_NOTHREADS + if (cbrt[0] < -1.0f) +#endif + for (i = 0; i < 0x10000; i++) + { + r = i / 65535.0; + cbrt[i] = + r > 0.008856 ? pow(r, 1.f / 3.0f) : 7.787f * r + 16.f / 116.0f; + } + 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] += LibRaw_constants::xyz_rgb[i][k] * rgb_cam[k][j] / + LibRaw_constants::d65_white[i]; + return; + } + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC + { + xyz[0] += xyz_cam[0][c] * rgb[c]; + xyz[1] += xyz_cam[1][c] * rgb[c]; + xyz[2] += xyz_cam[2][c] * rgb[c]; + } + xyz[0] = cbrt[CLIP((int)xyz[0])]; + xyz[1] = cbrt[CLIP((int)xyz[1])]; + xyz[2] = cbrt[CLIP((int)xyz[2])]; + lab[0] = 64 * (116 * xyz[1] - 16); + lab[1] = 64 * 500 * (xyz[0] - xyz[1]); + lab[2] = 64 * 200 * (xyz[1] - xyz[2]); +#ifndef LIBRAW_NOTHREADS +#undef cbrt +#undef xyz_cam +#endif +} + +void LibRaw::ahd_interpolate_green_h_and_v( + int top, int left, ushort (*out_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]) +{ + int row, col; + int c, val; + ushort(*pix)[4]; + const int rowlimit = MIN(top + LIBRAW_AHD_TILE, height - 2); + const int collimit = MIN(left + LIBRAW_AHD_TILE, width - 2); + + for (row = top; row < rowlimit; row++) + { + col = left + (FC(row, left) & 1); + for (c = FC(row, col); col < collimit; 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; + out_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; + out_rgb[1][row - top][col - left][1] = + ULIM(val, pix[-width][1], pix[width][1]); + } + } +} +void LibRaw::ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab( + int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][3], + short (*out_lab)[LIBRAW_AHD_TILE][3]) +{ + unsigned row, col; + int c, val; + ushort(*pix)[4]; + ushort(*rix)[3]; + short(*lix)[3]; + const unsigned num_pix_per_row = 4 * width; + const unsigned rowlimit = MIN(top + LIBRAW_AHD_TILE - 1, height - 3); + const unsigned collimit = MIN(left + LIBRAW_AHD_TILE - 1, width - 3); + ushort *pix_above; + ushort *pix_below; + int t1, t2; + + for (row = top + 1; row < rowlimit; row++) + { + pix = image + row * width + left; + rix = &inout_rgb[row - top][0]; + lix = &out_lab[row - top][0]; + + for (col = left + 1; col < collimit; col++) + { + pix++; + pix_above = &pix[0][0] - num_pix_per_row; + pix_below = &pix[0][0] + num_pix_per_row; + rix++; + lix++; + + c = 2 - FC(row, col); + + if (c == 1) + { + c = FC(row + 1, col); + t1 = 2 - c; + val = pix[0][1] + + ((pix[-1][t1] + pix[1][t1] - rix[-1][1] - rix[1][1]) >> 1); + rix[0][t1] = CLIP(val); + val = + pix[0][1] + ((pix_above[c] + pix_below[c] - + rix[-LIBRAW_AHD_TILE][1] - rix[LIBRAW_AHD_TILE][1]) >> + 1); + } + else + { + t1 = -4 + c; /* -4+c: pixel of color c to the left */ + t2 = 4 + c; /* 4+c: pixel of color c to the right */ + val = rix[0][1] + + ((pix_above[t1] + pix_above[t2] + pix_below[t1] + pix_below[t2] - + rix[-LIBRAW_AHD_TILE - 1][1] - rix[-LIBRAW_AHD_TILE + 1][1] - + rix[+LIBRAW_AHD_TILE - 1][1] - rix[+LIBRAW_AHD_TILE + 1][1] + + 1) >> + 2); + } + rix[0][c] = CLIP(val); + c = FC(row, col); + rix[0][c] = pix[0][c]; + cielab(rix[0], lix[0]); + } + } +} +void LibRaw::ahd_interpolate_r_and_b_and_convert_to_cielab( + int top, int left, ushort (*inout_rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], + short (*out_lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]) +{ + int direction; + for (direction = 0; direction < 2; direction++) + { + ahd_interpolate_r_and_b_in_rgb_and_convert_to_cielab( + top, left, inout_rgb[direction], out_lab[direction]); + } +} + +void LibRaw::ahd_interpolate_build_homogeneity_map( + int top, int left, short (*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], + char (*out_homogeneity_map)[LIBRAW_AHD_TILE][2]) +{ + int row, col; + int tr; + int direction; + int i; + short(*lix)[3]; + short(*lixs[2])[3]; + short *adjacent_lix; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + static const int dir[4] = {-1, 1, -LIBRAW_AHD_TILE, LIBRAW_AHD_TILE}; + const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 2, height - 4); + const int collimit = MIN(left + LIBRAW_AHD_TILE - 2, width - 4); + int homogeneity; + char(*homogeneity_map_p)[2]; + + memset(out_homogeneity_map, 0, 2 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); + + for (row = top + 2; row < rowlimit; row++) + { + tr = row - top; + homogeneity_map_p = &out_homogeneity_map[tr][1]; + for (direction = 0; direction < 2; direction++) + { + lixs[direction] = &lab[direction][tr][1]; + } + + for (col = left + 2; col < collimit; col++) + { + homogeneity_map_p++; + + for (direction = 0; direction < 2; direction++) + { + lix = ++lixs[direction]; + for (i = 0; i < 4; i++) + { + adjacent_lix = lix[dir[i]]; + ldiff[direction][i] = ABS(lix[0][0] - adjacent_lix[0]); + abdiff[direction][i] = SQR(lix[0][1] - adjacent_lix[1]) + + SQR(lix[0][2] - adjacent_lix[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 (direction = 0; direction < 2; direction++) + { + homogeneity = 0; + for (i = 0; i < 4; i++) + { + if (ldiff[direction][i] <= leps && abdiff[direction][i] <= abeps) + { + homogeneity++; + } + } + homogeneity_map_p[0][direction] = homogeneity; + } + } + } +} +void LibRaw::ahd_interpolate_combine_homogeneous_pixels( + int top, int left, ushort (*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], + char (*homogeneity_map)[LIBRAW_AHD_TILE][2]) +{ + int row, col; + int tr, tc; + int i, j; + int direction; + int hm[2]; + int c; + const int rowlimit = MIN(top + LIBRAW_AHD_TILE - 3, height - 5); + const int collimit = MIN(left + LIBRAW_AHD_TILE - 3, width - 5); + + ushort(*pix)[4]; + ushort(*rix[2])[3]; + + for (row = top + 3; row < rowlimit; row++) + { + tr = row - top; + pix = &image[row * width + left + 2]; + for (direction = 0; direction < 2; direction++) + { + rix[direction] = &rgb[direction][tr][2]; + } + + for (col = left + 3; col < collimit; col++) + { + tc = col - left; + pix++; + for (direction = 0; direction < 2; direction++) + { + rix[direction]++; + } + + for (direction = 0; direction < 2; direction++) + { + hm[direction] = 0; + for (i = tr - 1; i <= tr + 1; i++) + { + for (j = tc - 1; j <= tc + 1; j++) + { + hm[direction] += homogeneity_map[i][j][direction]; + } + } + } + if (hm[0] != hm[1]) + { + memcpy(pix[0], rix[hm[1] > hm[0]][0], 3 * sizeof(ushort)); + } + else + { + FORC3 { pix[0][c] = (rix[0][0][c] + rix[1][0][c]) >> 1; } + } + } + } +} +void LibRaw::ahd_interpolate() +{ + int terminate_flag = 0; + cielab(0, 0); + border_interpolate(5); + +#ifdef LIBRAW_USE_OPENMP + int buffer_count = omp_get_max_threads(); +#else + int buffer_count = 1; +#endif + + size_t buffer_size = 26 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE; /* 1664 kB */ + char** buffers = malloc_omp_buffers(buffer_count, buffer_size); + +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for schedule(dynamic) default(none) shared(terminate_flag) firstprivate(buffers) +#endif + for (int top = 2; top < height - 5; top += LIBRAW_AHD_TILE - 6) + { +#ifdef LIBRAW_USE_OPENMP + if (0 == omp_get_thread_num()) +#endif + if (callbacks.progress_cb) + { + int rr = (*callbacks.progress_cb)(callbacks.progresscb_data, + LIBRAW_PROGRESS_INTERPOLATE, + top - 2, height - 7); + if (rr) + terminate_flag = 1; + } + +#if defined(LIBRAW_USE_OPENMP) + char* buffer = buffers[omp_get_thread_num()]; +#else + char* buffer = buffers[0]; +#endif + + ushort(*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]; + short(*lab)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3]; + char(*homo)[LIBRAW_AHD_TILE][2]; + + rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; + lab = (short(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])( + buffer + 12 * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); + homo = (char(*)[LIBRAW_AHD_TILE][2])(buffer + 24 * LIBRAW_AHD_TILE * + LIBRAW_AHD_TILE); + + for (int left = 2; !terminate_flag && (left < width - 5); + left += LIBRAW_AHD_TILE - 6) + { + ahd_interpolate_green_h_and_v(top, left, rgb); + ahd_interpolate_r_and_b_and_convert_to_cielab(top, left, rgb, lab); + ahd_interpolate_build_homogeneity_map(top, left, lab, homo); + ahd_interpolate_combine_homogeneous_pixels(top, left, rgb, homo); + } + } + + free_omp_buffers(buffers, buffer_count); + + if (terminate_flag) + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; +} diff --git a/src/demosaic/dcb_demosaic.cpp b/src/demosaic/dcb_demosaic.cpp new file mode 100644 index 000000000..f25292b9a --- /dev/null +++ b/src/demosaic/dcb_demosaic.cpp @@ -0,0 +1,900 @@ +/* + * Copyright (C) 2010, Jacek Gozdz (cuniek@kft.umcs.lublin.pl) + * + * This code is licensed under a (3-clause) BSD license as follows : + * + * 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. + */ + +// DCB demosaicing by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) + +// FBDD denoising by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) and +// Luis Sanz Rodríguez (luis.sanz.rodriguez@gmail.com) + +// last modification: 11.07.2010 + +#include "../../internal/dcraw_defs.h" + +// interpolates green vertically and saves it to image3 +void LibRaw::dcb_ver(float (*image3)[3]) +{ + int row, col, u = width, indx; + + for (row = 2; row < height - 2; row++) + for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; + col += 2, indx += 2) + { + + image3[indx][1] = CLIP((image[indx + u][1] + image[indx - u][1]) / 2.0); + } +} + +// interpolates green horizontally and saves it to image2 +void LibRaw::dcb_hor(float (*image2)[3]) +{ + int row, col, u = width, indx; + + for (row = 2; row < height - 2; row++) + for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; + col += 2, indx += 2) + { + + image2[indx][1] = CLIP((image[indx + 1][1] + image[indx - 1][1]) / 2.0); + } +} + +// missing colors are interpolated +void LibRaw::dcb_color() +{ + int row, col, c, d, u = width, indx; + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, + c = 2 - FC(row, col); + col < u - 1; col += 2, indx += 2) + { + + image[indx][c] = CLIP((4 * 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]) / + 4.0); + } + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, + c = FC(row, col + 1), d = 2 - c; + col < width - 1; col += 2, indx += 2) + { + + image[indx][c] = + CLIP((2 * image[indx][1] - image[indx + 1][1] - image[indx - 1][1] + + image[indx + 1][c] + image[indx - 1][c]) / + 2.0); + image[indx][d] = + CLIP((2 * image[indx][1] - image[indx + u][1] - image[indx - u][1] + + image[indx + u][d] + image[indx - u][d]) / + 2.0); + } +} + +// missing R and B are interpolated horizontally and saved in image2 +void LibRaw::dcb_color2(float (*image2)[3]) +{ + int row, col, c, d, u = width, indx; + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, + c = 2 - FC(row, col); + col < u - 1; col += 2, indx += 2) + { + + image2[indx][c] = + CLIP((4 * image2[indx][1] - image2[indx + u + 1][1] - + image2[indx + u - 1][1] - image2[indx - u + 1][1] - + image2[indx - u - 1][1] + image[indx + u + 1][c] + + image[indx + u - 1][c] + image[indx - u + 1][c] + + image[indx - u - 1][c]) / + 4.0); + } + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, + c = FC(row, col + 1), d = 2 - c; + col < width - 1; col += 2, indx += 2) + { + + image2[indx][c] = CLIP((image[indx + 1][c] + image[indx - 1][c]) / 2.0); + image2[indx][d] = + CLIP((2 * image2[indx][1] - image2[indx + u][1] - + image2[indx - u][1] + image[indx + u][d] + image[indx - u][d]) / + 2.0); + } +} + +// missing R and B are interpolated vertically and saved in image3 +void LibRaw::dcb_color3(float (*image3)[3]) +{ + int row, col, c, d, u = width, indx; + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, + c = 2 - FC(row, col); + col < u - 1; col += 2, indx += 2) + { + + image3[indx][c] = + CLIP((4 * image3[indx][1] - image3[indx + u + 1][1] - + image3[indx + u - 1][1] - image3[indx - u + 1][1] - + image3[indx - u - 1][1] + image[indx + u + 1][c] + + image[indx + u - 1][c] + image[indx - u + 1][c] + + image[indx - u - 1][c]) / + 4.0); + } + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, + c = FC(row, col + 1), d = 2 - c; + col < width - 1; col += 2, indx += 2) + { + + image3[indx][c] = + CLIP((2 * image3[indx][1] - image3[indx + 1][1] - + image3[indx - 1][1] + image[indx + 1][c] + image[indx - 1][c]) / + 2.0); + image3[indx][d] = CLIP((image[indx + u][d] + image[indx - u][d]) / 2.0); + } +} + +// decides the primary green interpolation direction +void LibRaw::dcb_decide(float (*image2)[3], float (*image3)[3]) +{ + int row, col, c, d, u = width, v = 2 * u, indx; + float current, current2, current3; + + for (row = 2; row < height - 2; row++) + for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); + col < u - 2; col += 2, indx += 2) + { + + d = ABS(c - 2); + + current = MAX(image[indx + v][c], + MAX(image[indx - v][c], + MAX(image[indx - 2][c], image[indx + 2][c]))) - + MIN(image[indx + v][c], + MIN(image[indx - v][c], + MIN(image[indx - 2][c], image[indx + 2][c]))) + + MAX(image[indx + 1 + u][d], + MAX(image[indx + 1 - u][d], + MAX(image[indx - 1 + u][d], image[indx - 1 - u][d]))) - + MIN(image[indx + 1 + u][d], + MIN(image[indx + 1 - u][d], + MIN(image[indx - 1 + u][d], image[indx - 1 - u][d]))); + + current2 = + MAX(image2[indx + v][d], + MAX(image2[indx - v][d], + MAX(image2[indx - 2][d], image2[indx + 2][d]))) - + MIN(image2[indx + v][d], + MIN(image2[indx - v][d], + MIN(image2[indx - 2][d], image2[indx + 2][d]))) + + MAX(image2[indx + 1 + u][c], + MAX(image2[indx + 1 - u][c], + MAX(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) - + MIN(image2[indx + 1 + u][c], + MIN(image2[indx + 1 - u][c], + MIN(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))); + + current3 = + MAX(image3[indx + v][d], + MAX(image3[indx - v][d], + MAX(image3[indx - 2][d], image3[indx + 2][d]))) - + MIN(image3[indx + v][d], + MIN(image3[indx - v][d], + MIN(image3[indx - 2][d], image3[indx + 2][d]))) + + MAX(image3[indx + 1 + u][c], + MAX(image3[indx + 1 - u][c], + MAX(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) - + MIN(image3[indx + 1 + u][c], + MIN(image3[indx + 1 - u][c], + MIN(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))); + + if (ABS(current - current2) < ABS(current - current3)) + image[indx][1] = image2[indx][1]; + else + image[indx][1] = image3[indx][1]; + } +} + +// saves red and blue in image2 +void LibRaw::dcb_copy_to_buffer(float (*image2)[3]) +{ + int indx; + + for (indx = 0; indx < height * width; indx++) + { + image2[indx][0] = image[indx][0]; // R + image2[indx][2] = image[indx][2]; // B + } +} + +// restores red and blue from image2 +void LibRaw::dcb_restore_from_buffer(float (*image2)[3]) +{ + int indx; + + for (indx = 0; indx < height * width; indx++) + { + image[indx][0] = image2[indx][0]; // R + image[indx][2] = image2[indx][2]; // B + } +} + +// R and B smoothing using green contrast, all pixels except 2 pixel wide border +void LibRaw::dcb_pp() +{ + int g1, r1, b1, u = width, indx, row, col; + + for (row = 2; row < height - 2; row++) + for (col = 2, indx = row * u + col; col < width - 2; col++, indx++) + { + + r1 = (image[indx - 1][0] + image[indx + 1][0] + image[indx - u][0] + + image[indx + u][0] + image[indx - u - 1][0] + + image[indx + u + 1][0] + image[indx - u + 1][0] + + image[indx + u - 1][0]) / + 8.0; + g1 = (image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] + + image[indx + u][1] + image[indx - u - 1][1] + + image[indx + u + 1][1] + image[indx - u + 1][1] + + image[indx + u - 1][1]) / + 8.0; + b1 = (image[indx - 1][2] + image[indx + 1][2] + image[indx - u][2] + + image[indx + u][2] + image[indx - u - 1][2] + + image[indx + u + 1][2] + image[indx - u + 1][2] + + image[indx + u - 1][2]) / + 8.0; + + image[indx][0] = CLIP(r1 + (image[indx][1] - g1)); + image[indx][2] = CLIP(b1 + (image[indx][1] - g1)); + } +} + +// green blurring correction, helps to get the nyquist right +void LibRaw::dcb_nyquist() +{ + int row, col, c, u = width, v = 2 * u, indx; + + for (row = 2; row < height - 2; row++) + for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); + col < u - 2; col += 2, indx += 2) + { + + image[indx][1] = CLIP((image[indx + v][1] + image[indx - v][1] + + image[indx - 2][1] + image[indx + 2][1]) / + 4.0 + + image[indx][c] - + (image[indx + v][c] + image[indx - v][c] + + image[indx - 2][c] + image[indx + 2][c]) / + 4.0); + } +} + +// missing colors are interpolated using high quality algorithm by Luis Sanz +// Rodríguez +void LibRaw::dcb_color_full() +{ + int row, col, c, d, u = width, w = 3 * u, indx, g1, g2; + float f[4], g[4], (*chroma)[2]; + + chroma = (float(*)[2])calloc(width * height, sizeof *chroma); + + for (row = 1; row < height - 1; row++) + for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col), + d = c / 2; + col < u - 1; col += 2, indx += 2) + chroma[indx][d] = image[indx][c] - image[indx][1]; + + for (row = 3; row < height - 3; row++) + for (col = 3 + (FC(row, 1) & 1), indx = row * width + col, + c = 1 - FC(row, col) / 2, d = 1 - c; + col < u - 3; col += 2, indx += 2) + { + f[0] = 1.0 / + (float)(1.0 + + fabs(chroma[indx - u - 1][c] - chroma[indx + u + 1][c]) + + fabs(chroma[indx - u - 1][c] - chroma[indx - w - 3][c]) + + fabs(chroma[indx + u + 1][c] - chroma[indx - w - 3][c])); + f[1] = 1.0 / + (float)(1.0 + + fabs(chroma[indx - u + 1][c] - chroma[indx + u - 1][c]) + + fabs(chroma[indx - u + 1][c] - chroma[indx - w + 3][c]) + + fabs(chroma[indx + u - 1][c] - chroma[indx - w + 3][c])); + f[2] = 1.0 / + (float)(1.0 + + fabs(chroma[indx + u - 1][c] - chroma[indx - u + 1][c]) + + fabs(chroma[indx + u - 1][c] - chroma[indx + w + 3][c]) + + fabs(chroma[indx - u + 1][c] - chroma[indx + w - 3][c])); + f[3] = 1.0 / + (float)(1.0 + + fabs(chroma[indx + u + 1][c] - chroma[indx - u - 1][c]) + + fabs(chroma[indx + u + 1][c] - chroma[indx + w - 3][c]) + + fabs(chroma[indx - u - 1][c] - chroma[indx + w + 3][c])); + g[0] = 1.325 * chroma[indx - u - 1][c] - 0.175 * chroma[indx - w - 3][c] - + 0.075 * chroma[indx - w - 1][c] - 0.075 * chroma[indx - u - 3][c]; + g[1] = 1.325 * chroma[indx - u + 1][c] - 0.175 * chroma[indx - w + 3][c] - + 0.075 * chroma[indx - w + 1][c] - 0.075 * chroma[indx - u + 3][c]; + g[2] = 1.325 * chroma[indx + u - 1][c] - 0.175 * chroma[indx + w - 3][c] - + 0.075 * chroma[indx + w - 1][c] - 0.075 * chroma[indx + u - 3][c]; + g[3] = 1.325 * chroma[indx + u + 1][c] - 0.175 * chroma[indx + w + 3][c] - + 0.075 * chroma[indx + w + 1][c] - 0.075 * chroma[indx + u + 3][c]; + 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 (row = 3; row < height - 3; row++) + for (col = 3 + (FC(row, 2) & 1), indx = row * width + col, + c = FC(row, col + 1) / 2; + col < u - 3; col += 2, indx += 2) + for (d = 0; d <= 1; c = 1 - c, d++) + { + f[0] = 1.0 / + (float)(1.0 + fabs(chroma[indx - u][c] - chroma[indx + u][c]) + + fabs(chroma[indx - u][c] - chroma[indx - w][c]) + + fabs(chroma[indx + u][c] - chroma[indx - w][c])); + f[1] = 1.0 / + (float)(1.0 + fabs(chroma[indx + 1][c] - chroma[indx - 1][c]) + + fabs(chroma[indx + 1][c] - chroma[indx + 3][c]) + + fabs(chroma[indx - 1][c] - chroma[indx + 3][c])); + f[2] = 1.0 / + (float)(1.0 + fabs(chroma[indx - 1][c] - chroma[indx + 1][c]) + + fabs(chroma[indx - 1][c] - chroma[indx - 3][c]) + + fabs(chroma[indx + 1][c] - chroma[indx - 3][c])); + f[3] = 1.0 / + (float)(1.0 + fabs(chroma[indx + u][c] - chroma[indx - u][c]) + + fabs(chroma[indx + u][c] - chroma[indx + w][c]) + + fabs(chroma[indx - u][c] - chroma[indx + w][c])); + + g[0] = 0.875 * chroma[indx - u][c] + 0.125 * chroma[indx - w][c]; + g[1] = 0.875 * chroma[indx + 1][c] + 0.125 * chroma[indx + 3][c]; + g[2] = 0.875 * chroma[indx - 1][c] + 0.125 * chroma[indx - 3][c]; + g[3] = 0.875 * chroma[indx + u][c] + 0.125 * chroma[indx + w][c]; + + 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 (row = 6; row < height - 6; row++) + for (col = 6, indx = row * width + col; col < width - 6; col++, indx++) + { + image[indx][0] = CLIP(chroma[indx][0] + image[indx][1]); + image[indx][2] = CLIP(chroma[indx][1] + image[indx][1]); + + g1 = MIN( + image[indx + 1 + u][0], + MIN(image[indx + 1 - u][0], + MIN(image[indx - 1 + u][0], + MIN(image[indx - 1 - u][0], + MIN(image[indx - 1][0], + MIN(image[indx + 1][0], + MIN(image[indx - u][0], image[indx + u][0]))))))); + + g2 = MAX( + image[indx + 1 + u][0], + MAX(image[indx + 1 - u][0], + MAX(image[indx - 1 + u][0], + MAX(image[indx - 1 - u][0], + MAX(image[indx - 1][0], + MAX(image[indx + 1][0], + MAX(image[indx - u][0], image[indx + u][0]))))))); + + image[indx][0] = ULIM(image[indx][0], g2, g1); + + g1 = MIN( + image[indx + 1 + u][2], + MIN(image[indx + 1 - u][2], + MIN(image[indx - 1 + u][2], + MIN(image[indx - 1 - u][2], + MIN(image[indx - 1][2], + MIN(image[indx + 1][2], + MIN(image[indx - u][2], image[indx + u][2]))))))); + + g2 = MAX( + image[indx + 1 + u][2], + MAX(image[indx + 1 - u][2], + MAX(image[indx - 1 + u][2], + MAX(image[indx - 1 - u][2], + MAX(image[indx - 1][2], + MAX(image[indx + 1][2], + MAX(image[indx - u][2], image[indx + u][2]))))))); + + image[indx][2] = ULIM(image[indx][2], g2, g1); + } + + free(chroma); +} + +// green is used to create an interpolation direction map saved in image[][3] +// 1 = vertical +// 0 = horizontal +void LibRaw::dcb_map() +{ + int row, col, u = width, indx; + + for (row = 1; row < height - 1; row++) + { + for (col = 1, indx = row * width + col; col < width - 1; col++, indx++) + { + + if (image[indx][1] > (image[indx - 1][1] + image[indx + 1][1] + + image[indx - u][1] + image[indx + u][1]) / + 4.0) + image[indx][3] = ((MIN(image[indx - 1][1], image[indx + 1][1]) + + image[indx - 1][1] + image[indx + 1][1]) < + (MIN(image[indx - u][1], image[indx + u][1]) + + image[indx - u][1] + image[indx + u][1])); + else + image[indx][3] = ((MAX(image[indx - 1][1], image[indx + 1][1]) + + image[indx - 1][1] + image[indx + 1][1]) > + (MAX(image[indx - u][1], image[indx + u][1]) + + image[indx - u][1] + image[indx + u][1])); + } + } +} + +// interpolated green pixels are corrected using the map +void LibRaw::dcb_correction() +{ + int current, row, col, u = width, v = 2 * u, indx; + + for (row = 2; row < height - 2; row++) + for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; + col += 2, indx += 2) + { + + current = 4 * image[indx][3] + + 2 * (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]; + + image[indx][1] = + ((16 - current) * (image[indx - 1][1] + image[indx + 1][1]) / 2.0 + + current * (image[indx - u][1] + image[indx + u][1]) / 2.0) / + 16.0; + } +} + +// interpolated green pixels are corrected using the map +// with contrast correction +void LibRaw::dcb_correction2() +{ + int current, row, col, c, u = width, v = 2 * u, indx; + + for (row = 4; row < height - 4; row++) + for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); + col < u - 4; col += 2, indx += 2) + { + + current = 4 * image[indx][3] + + 2 * (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]; + + image[indx][1] = CLIP( + ((16 - current) * ((image[indx - 1][1] + image[indx + 1][1]) / 2.0 + + image[indx][c] - + (image[indx + 2][c] + image[indx - 2][c]) / 2.0) + + current * ((image[indx - u][1] + image[indx + u][1]) / 2.0 + + image[indx][c] - + (image[indx + v][c] + image[indx - v][c]) / 2.0)) / + 16.0); + } +} + +void LibRaw::dcb_refinement() +{ + int row, col, c, u = width, v = 2 * u, w = 3 * u, indx, current; + float f[5], g1, g2; + + for (row = 4; row < height - 4; row++) + for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); + col < u - 4; col += 2, indx += 2) + { + + current = 4 * image[indx][3] + + 2 * (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]; + + if (image[indx][c] > 1) + { + + f[0] = (float)(image[indx - u][1] + image[indx + u][1]) / + (2 * image[indx][c]); + + if (image[indx - v][c] > 0) + f[1] = 2 * (float)image[indx - u][1] / + (image[indx - v][c] + image[indx][c]); + else + f[1] = f[0]; + + if (image[indx - v][c] > 0) + f[2] = (float)(image[indx - u][1] + image[indx - w][1]) / + (2 * image[indx - v][c]); + else + f[2] = f[0]; + + if (image[indx + v][c] > 0) + f[3] = 2 * (float)image[indx + u][1] / + (image[indx + v][c] + image[indx][c]); + else + f[3] = f[0]; + + if (image[indx + v][c] > 0) + f[4] = (float)(image[indx + u][1] + image[indx + w][1]) / + (2 * image[indx + v][c]); + else + f[4] = f[0]; + + g1 = (5 * f[0] + 3 * f[1] + f[2] + 3 * f[3] + f[4]) / 13.0; + + f[0] = (float)(image[indx - 1][1] + image[indx + 1][1]) / + (2 * image[indx][c]); + + if (image[indx - 2][c] > 0) + f[1] = 2 * (float)image[indx - 1][1] / + (image[indx - 2][c] + image[indx][c]); + else + f[1] = f[0]; + + if (image[indx - 2][c] > 0) + f[2] = (float)(image[indx - 1][1] + image[indx - 3][1]) / + (2 * image[indx - 2][c]); + else + f[2] = f[0]; + + if (image[indx + 2][c] > 0) + f[3] = 2 * (float)image[indx + 1][1] / + (image[indx + 2][c] + image[indx][c]); + else + f[3] = f[0]; + + if (image[indx + 2][c] > 0) + f[4] = (float)(image[indx + 1][1] + image[indx + 3][1]) / + (2 * image[indx + 2][c]); + else + f[4] = f[0]; + + g2 = (5 * f[0] + 3 * f[1] + f[2] + 3 * f[3] + f[4]) / 13.0; + + image[indx][1] = CLIP((image[indx][c]) * + (current * g1 + (16 - current) * g2) / 16.0); + } + else + image[indx][1] = image[indx][c]; + + // get rid of overshooted pixels + + g1 = MIN( + image[indx + 1 + u][1], + MIN(image[indx + 1 - u][1], + MIN(image[indx - 1 + u][1], + MIN(image[indx - 1 - u][1], + MIN(image[indx - 1][1], + MIN(image[indx + 1][1], + MIN(image[indx - u][1], image[indx + u][1]))))))); + + g2 = MAX( + image[indx + 1 + u][1], + MAX(image[indx + 1 - u][1], + MAX(image[indx - 1 + u][1], + MAX(image[indx - 1 - u][1], + MAX(image[indx - 1][1], + MAX(image[indx + 1][1], + MAX(image[indx - u][1], image[indx + u][1]))))))); + + image[indx][1] = ULIM(image[indx][1], g2, g1); + } +} + +// converts RGB to LCH colorspace and saves it to image3 +void LibRaw::rgb_to_lch(double (*image2)[3]) +{ + int indx; + for (indx = 0; indx < height * width; indx++) + { + + image2[indx][0] = image[indx][0] + image[indx][1] + image[indx][2]; // L + image2[indx][1] = 1.732050808 * (image[indx][0] - image[indx][1]); // C + image2[indx][2] = + 2.0 * image[indx][2] - image[indx][0] - image[indx][1]; // H + } +} + +// converts LCH to RGB colorspace and saves it back to image +void LibRaw::lch_to_rgb(double (*image2)[3]) +{ + int indx; + for (indx = 0; indx < height * width; indx++) + { + + image[indx][0] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 + + image2[indx][1] / 3.464101615); + image[indx][1] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 - + image2[indx][1] / 3.464101615); + image[indx][2] = CLIP(image2[indx][0] / 3.0 + image2[indx][2] / 3.0); + } +} + +// denoising using interpolated neighbours +void LibRaw::fbdd_correction() +{ + int row, col, c, u = width, indx; + + for (row = 2; row < height - 2; row++) + { + for (col = 2, indx = row * width + col; col < width - 2; col++, indx++) + { + + c = fcol(row, col); + + image[indx][c] = + ULIM(image[indx][c], + MAX(image[indx - 1][c], + MAX(image[indx + 1][c], + MAX(image[indx - u][c], image[indx + u][c]))), + MIN(image[indx - 1][c], + MIN(image[indx + 1][c], + MIN(image[indx - u][c], image[indx + u][c])))); + } + } +} + +// corrects chroma noise +void LibRaw::fbdd_correction2(double (*image2)[3]) +{ + int indx, v = 2 * width; + int col, row; + double Co, Ho, ratio; + + for (row = 6; row < height - 6; row++) + { + for (col = 6; col < width - 6; col++) + { + indx = row * width + col; + + if (image2[indx][1] * image2[indx][2] != 0) + { + Co = (image2[indx + v][1] + image2[indx - v][1] + image2[indx - 2][1] + + image2[indx + 2][1] - + MAX(image2[indx - 2][1], + MAX(image2[indx + 2][1], + MAX(image2[indx - v][1], image2[indx + v][1]))) - + MIN(image2[indx - 2][1], + MIN(image2[indx + 2][1], + MIN(image2[indx - v][1], image2[indx + v][1])))) / + 2.0; + Ho = (image2[indx + v][2] + image2[indx - v][2] + image2[indx - 2][2] + + image2[indx + 2][2] - + MAX(image2[indx - 2][2], + MAX(image2[indx + 2][2], + MAX(image2[indx - v][2], image2[indx + v][2]))) - + MIN(image2[indx - 2][2], + MIN(image2[indx + 2][2], + MIN(image2[indx - v][2], image2[indx + v][2])))) / + 2.0; + ratio = sqrt((Co * Co + Ho * Ho) / (image2[indx][1] * image2[indx][1] + + image2[indx][2] * image2[indx][2])); + + if (ratio < 0.85) + { + image2[indx][0] = + -(image2[indx][1] + image2[indx][2] - Co - Ho) + image2[indx][0]; + image2[indx][1] = Co; + image2[indx][2] = Ho; + } + } + } + } +} + +// Cubic Spline Interpolation by Li and Randhawa, modified by Jacek Gozdz and +// Luis Sanz Rodríguez +void LibRaw::fbdd_green() +{ + int row, col, c, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, indx, + min, max; + float f[4], g[4]; + + for (row = 5; row < height - 5; row++) + for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col); + col < u - 5; col += 2, indx += 2) + { + + f[0] = 1.0 / (1.0 + abs(image[indx - u][1] - image[indx - w][1]) + + abs(image[indx - w][1] - image[indx + y][1])); + f[1] = 1.0 / (1.0 + abs(image[indx + 1][1] - image[indx + 3][1]) + + abs(image[indx + 3][1] - image[indx - 5][1])); + f[2] = 1.0 / (1.0 + abs(image[indx - 1][1] - image[indx - 3][1]) + + abs(image[indx - 3][1] - image[indx + 5][1])); + f[3] = 1.0 / (1.0 + abs(image[indx + u][1] - image[indx + w][1]) + + abs(image[indx + w][1] - image[indx - y][1])); + + g[0] = CLIP((23 * image[indx - u][1] + 23 * image[indx - w][1] + + 2 * image[indx - y][1] + + 8 * (image[indx - v][c] - image[indx - x][c]) + + 40 * (image[indx][c] - image[indx - v][c])) / + 48.0); + g[1] = CLIP((23 * image[indx + 1][1] + 23 * image[indx + 3][1] + + 2 * image[indx + 5][1] + + 8 * (image[indx + 2][c] - image[indx + 4][c]) + + 40 * (image[indx][c] - image[indx + 2][c])) / + 48.0); + g[2] = CLIP((23 * image[indx - 1][1] + 23 * image[indx - 3][1] + + 2 * image[indx - 5][1] + + 8 * (image[indx - 2][c] - image[indx - 4][c]) + + 40 * (image[indx][c] - image[indx - 2][c])) / + 48.0); + g[3] = CLIP((23 * image[indx + u][1] + 23 * image[indx + w][1] + + 2 * image[indx + y][1] + + 8 * (image[indx + v][c] - image[indx + x][c]) + + 40 * (image[indx][c] - image[indx + v][c])) / + 48.0); + + image[indx][1] = + CLIP((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / + (f[0] + f[1] + f[2] + f[3])); + + min = MIN( + image[indx + 1 + u][1], + MIN(image[indx + 1 - u][1], + MIN(image[indx - 1 + u][1], + MIN(image[indx - 1 - u][1], + MIN(image[indx - 1][1], + MIN(image[indx + 1][1], + MIN(image[indx - u][1], image[indx + u][1]))))))); + + max = MAX( + image[indx + 1 + u][1], + MAX(image[indx + 1 - u][1], + MAX(image[indx - 1 + u][1], + MAX(image[indx - 1 - u][1], + MAX(image[indx - 1][1], + MAX(image[indx + 1][1], + MAX(image[indx - u][1], image[indx + u][1]))))))); + + image[indx][1] = ULIM(image[indx][1], max, min); + } +} + +// FBDD (Fake Before Demosaicing Denoising) +void LibRaw::fbdd(int noiserd) +{ + double(*image2)[3]; + // safety net: disable for 4-color bayer or full-color images + if (colors != 3 || !filters) + return; + image2 = (double(*)[3])calloc(width * height, sizeof *image2); + + border_interpolate(4); + + if (noiserd > 1) + { + fbdd_green(); + // dcb_color_full(image2); + dcb_color_full(); + fbdd_correction(); + + dcb_color(); + rgb_to_lch(image2); + fbdd_correction2(image2); + fbdd_correction2(image2); + lch_to_rgb(image2); + } + else + { + fbdd_green(); + // dcb_color_full(image2); + dcb_color_full(); + fbdd_correction(); + } + + free(image2); +} + +// DCB demosaicing main routine +void LibRaw::dcb(int iterations, int dcb_enhance) +{ + + int i = 1; + + float(*image2)[3]; + image2 = (float(*)[3])calloc(width * height, sizeof *image2); + + float(*image3)[3]; + image3 = (float(*)[3])calloc(width * height, sizeof *image3); + + border_interpolate(6); + + dcb_hor(image2); + dcb_color2(image2); + + dcb_ver(image3); + dcb_color3(image3); + + dcb_decide(image2, image3); + + free(image3); + + dcb_copy_to_buffer(image2); + + while (i <= iterations) + { + dcb_nyquist(); + dcb_nyquist(); + dcb_nyquist(); + dcb_map(); + dcb_correction(); + i++; + } + + dcb_color(); + dcb_pp(); + + dcb_map(); + dcb_correction2(); + + dcb_map(); + dcb_correction(); + + dcb_map(); + dcb_correction(); + + dcb_map(); + dcb_correction(); + + dcb_map(); + dcb_restore_from_buffer(image2); + dcb_color(); + + if (dcb_enhance) + { + dcb_refinement(); + // dcb_color_full(image2); + dcb_color_full(); + } + + free(image2); +} diff --git a/src/demosaic/dht_demosaic.cpp b/src/demosaic/dht_demosaic.cpp new file mode 100644 index 000000000..bff8f77b0 --- /dev/null +++ b/src/demosaic/dht_demosaic.cpp @@ -0,0 +1,1033 @@ +/* -*- C++ -*- + * File: dht_demosaic.cpp + * Copyright 2013 Anton Petrusevich + * Created: Tue Apr 9, 2013 + * + * This code is licensed under one of two licenses as you choose: + * + * 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + * (See file LICENSE.LGPL provided in LibRaw distribution archive for + * details). + * + * 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + * (See file LICENSE.CDDL provided in LibRaw distribution archive for + * details). + * + */ + +/* + * Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ñ‡Ð¸ÑлÑет ÑркоÑтную диÑтанцию. + * еÑли две ÑркоÑти отличаютÑÑ Ð² два раза, например 10 и 20, то они имеют такой + * же Ð²ÐµÑ Ð¿Ñ€Ð¸ принÑтии Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¾Ð± интерполировании, как и 100 и 200 -- + * фотографичеÑÐºÐ°Ñ ÑркоÑть между ними 1 Ñтоп. диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð²Ñегда >=1 + */ + +#include "../../internal/dmp_include.h" + +static inline float calc_dist(float c1, float c2) +{ + return c1 > c2 ? c1 / c2 : c2 / c1; +} + +struct DHT +{ + int nr_height, nr_width; + static const int nr_topmargin = 4, nr_leftmargin = 4; + float (*nraw)[3]; + ushort channel_maximum[3]; + float channel_minimum[3]; + LibRaw &libraw; + enum + { + HVSH = 1, + HOR = 2, + VER = 4, + HORSH = HOR | HVSH, + VERSH = VER | HVSH, + DIASH = 8, + LURD = 16, + RULD = 32, + LURDSH = LURD | DIASH, + RULDSH = RULD | DIASH, + HOT = 64 + }; + static inline float Thot(void) throw() { return 64.0f; } + static inline float Tg(void) throw() { return 256.0f; } + static inline float T(void) throw() { return 1.4f; } + char *ndir; + inline int nr_offset(int row, int col) throw() + { + return (row * nr_width + col); + } + int get_hv_grb(int x, int y, int kc) + { + float hv1 = 2 * nraw[nr_offset(y - 1, x)][1] / + (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]); + float hv2 = 2 * nraw[nr_offset(y + 1, x)][1] / + (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]); + float kv = calc_dist(hv1, hv2) * + calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc], + (nraw[nr_offset(y - 2, x)][kc] * + nraw[nr_offset(y + 2, x)][kc])); + kv *= kv; + kv *= kv; + kv *= kv; + float dv = + kv * + calc_dist(nraw[nr_offset(y - 3, x)][1] * nraw[nr_offset(y + 3, x)][1], + nraw[nr_offset(y - 1, x)][1] * nraw[nr_offset(y + 1, x)][1]); + float hh1 = 2 * nraw[nr_offset(y, x - 1)][1] / + (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]); + float hh2 = 2 * nraw[nr_offset(y, x + 1)][1] / + (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]); + float kh = calc_dist(hh1, hh2) * + calc_dist(nraw[nr_offset(y, x)][kc] * nraw[nr_offset(y, x)][kc], + (nraw[nr_offset(y, x - 2)][kc] * + nraw[nr_offset(y, x + 2)][kc])); + kh *= kh; + kh *= kh; + kh *= kh; + float dh = + kh * + calc_dist(nraw[nr_offset(y, x - 3)][1] * nraw[nr_offset(y, x + 3)][1], + nraw[nr_offset(y, x - 1)][1] * nraw[nr_offset(y, x + 1)][1]); + float e = calc_dist(dh, dv); + char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER); + return d; + } + int get_hv_rbg(int x, int y, int hc) + { + float hv1 = 2 * nraw[nr_offset(y - 1, x)][hc ^ 2] / + (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y, x)][1]); + float hv2 = 2 * nraw[nr_offset(y + 1, x)][hc ^ 2] / + (nraw[nr_offset(y + 2, x)][1] + nraw[nr_offset(y, x)][1]); + float kv = calc_dist(hv1, hv2) * + calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1], + (nraw[nr_offset(y - 2, x)][1] * + nraw[nr_offset(y + 2, x)][1])); + kv *= kv; + kv *= kv; + kv *= kv; + float dv = kv * calc_dist(nraw[nr_offset(y - 3, x)][hc ^ 2] * + nraw[nr_offset(y + 3, x)][hc ^ 2], + nraw[nr_offset(y - 1, x)][hc ^ 2] * + nraw[nr_offset(y + 1, x)][hc ^ 2]); + float hh1 = 2 * nraw[nr_offset(y, x - 1)][hc] / + (nraw[nr_offset(y, x - 2)][1] + nraw[nr_offset(y, x)][1]); + float hh2 = 2 * nraw[nr_offset(y, x + 1)][hc] / + (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x)][1]); + float kh = calc_dist(hh1, hh2) * + calc_dist(nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1], + (nraw[nr_offset(y, x - 2)][1] * + nraw[nr_offset(y, x + 2)][1])); + kh *= kh; + kh *= kh; + kh *= kh; + float dh = + kh * calc_dist( + nraw[nr_offset(y, x - 3)][hc] * nraw[nr_offset(y, x + 3)][hc], + nraw[nr_offset(y, x - 1)][hc] * nraw[nr_offset(y, x + 1)][hc]); + float e = calc_dist(dh, dv); + char d = dh < dv ? (e > Tg() ? HORSH : HOR) : (e > Tg() ? VERSH : VER); + return d; + } + int get_diag_grb(int x, int y, int kc) + { + float hlu = + nraw[nr_offset(y - 1, x - 1)][1] / nraw[nr_offset(y - 1, x - 1)][kc]; + float hrd = + nraw[nr_offset(y + 1, x + 1)][1] / nraw[nr_offset(y + 1, x + 1)][kc]; + float dlurd = + calc_dist(hlu, hrd) * + calc_dist(nraw[nr_offset(y - 1, x - 1)][1] * + nraw[nr_offset(y + 1, x + 1)][1], + nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); + float druld = + calc_dist(hlu, hrd) * + calc_dist(nraw[nr_offset(y - 1, x + 1)][1] * + nraw[nr_offset(y + 1, x - 1)][1], + nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); + float e = calc_dist(dlurd, druld); + char d = + druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD); + return d; + } + int get_diag_rbg(int x, int y, int /* hc */) + { + float dlurd = calc_dist( + nraw[nr_offset(y - 1, x - 1)][1] * nraw[nr_offset(y + 1, x + 1)][1], + nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); + float druld = calc_dist( + nraw[nr_offset(y - 1, x + 1)][1] * nraw[nr_offset(y + 1, x - 1)][1], + nraw[nr_offset(y, x)][1] * nraw[nr_offset(y, x)][1]); + float e = calc_dist(dlurd, druld); + char d = + druld < dlurd ? (e > T() ? RULDSH : RULD) : (e > T() ? LURDSH : LURD); + return d; + } + static inline float scale_over(float ec, float base) + { + float s = base * .4; + float o = ec - base; + return base + sqrt(s * (o + s)) - s; + } + static inline float scale_under(float ec, float base) + { + float s = base * .6; + float o = base - ec; + return base - sqrt(s * (o + s)) + s; + } + ~DHT(); + DHT(LibRaw &_libraw); + void copy_to_image(); + void make_greens(); + void make_diag_dirs(); + void make_hv_dirs(); + void refine_hv_dirs(int i, int js); + void refine_diag_dirs(int i, int js); + void refine_ihv_dirs(int i); + void refine_idiag_dirs(int i); + void illustrate_dirs(); + void illustrate_dline(int i); + void make_hv_dline(int i); + void make_diag_dline(int i); + void make_gline(int i); + void make_rbdiag(int i); + void make_rbhv(int i); + void make_rb(); + void hide_hots(); + void restore_hots(); +}; + +typedef float float3[3]; + +/* + * Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ цветах копируетÑÑ Ð²Ð¾ float в общем то Ñ Ð¾Ð´Ð½Ð¾Ð¹ целью -- чтобы + * вмеÑто 0 можно было пиÑать 0.5, что больше подходит Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ ÑркоÑтной + * разницы. причина: в целых чиÑлах разница в 1 Ñтоп ÑоÑтавлÑет Ñ€Ñд 8,4,2,1,0 -- + * поÑледнее чиÑло должно быть 0.5, которое непредÑтвамио в целых чиÑлах. так же + * Ñто изменение позволÑет не думать о Ñпециальных ÑлучаÑÑ… Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð° ноль. + * + * альтернативное решение: умножить вÑе данные на 2 и в младший бит внеÑти 1. + * правда, вÑÑ‘ равно придётÑÑ Ñледить, чтобы при интерпретации зелёного цвета не + * получилÑÑ 0 при округлении, иначе проблема при интерпретации Ñиних и краÑных. + * + */ +DHT::DHT(LibRaw &_libraw) : libraw(_libraw) +{ + nr_height = libraw.imgdata.sizes.iheight + nr_topmargin * 2; + nr_width = libraw.imgdata.sizes.iwidth + nr_leftmargin * 2; + nraw = (float3 *)malloc(nr_height * nr_width * sizeof(float3)); + int iwidth = libraw.imgdata.sizes.iwidth; + ndir = (char *)calloc(nr_height * nr_width, 1); + channel_maximum[0] = channel_maximum[1] = channel_maximum[2] = 0; + channel_minimum[0] = libraw.imgdata.image[0][0]; + channel_minimum[1] = libraw.imgdata.image[0][1]; + channel_minimum[2] = libraw.imgdata.image[0][2]; + for (int i = 0; i < nr_height * nr_width; ++i) + nraw[i][0] = nraw[i][1] = nraw[i][2] = 0.5; + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int col_cache[48]; + for (int j = 0; j < 48; ++j) + { + int l = libraw.COLOR(i, j); + if (l == 3) + l = 1; + col_cache[j] = l; + } + for (int j = 0; j < iwidth; ++j) + { + int l = col_cache[j % 48]; + unsigned short c = libraw.imgdata.image[i * iwidth + j][l]; + if (c != 0) + { + if (channel_maximum[l] < c) + channel_maximum[l] = c; + if (channel_minimum[l] > c) + channel_minimum[l] = c; + nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = (float)c; + } + } + } + channel_minimum[0] += .5; + channel_minimum[1] += .5; + channel_minimum[2] += .5; +} + +void DHT::hide_hots() +{ + int iwidth = libraw.imgdata.sizes.iwidth; +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) firstprivate(iwidth) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + float c = nraw[nr_offset(y, x)][kc]; + if ((c > nraw[nr_offset(y, x + 2)][kc] && + c > nraw[nr_offset(y, x - 2)][kc] && + c > nraw[nr_offset(y - 2, x)][kc] && + c > nraw[nr_offset(y + 2, x)][kc] && + c > nraw[nr_offset(y, x + 1)][1] && + c > nraw[nr_offset(y, x - 1)][1] && + c > nraw[nr_offset(y - 1, x)][1] && + c > nraw[nr_offset(y + 1, x)][1]) || + (c < nraw[nr_offset(y, x + 2)][kc] && + c < nraw[nr_offset(y, x - 2)][kc] && + c < nraw[nr_offset(y - 2, x)][kc] && + c < nraw[nr_offset(y + 2, x)][kc] && + c < nraw[nr_offset(y, x + 1)][1] && + c < nraw[nr_offset(y, x - 1)][1] && + c < nraw[nr_offset(y - 1, x)][1] && + c < nraw[nr_offset(y + 1, x)][1])) + { + float avg = 0; + for (int k = -2; k < 3; k += 2) + for (int m = -2; m < 3; m += 2) + if (m == 0 && k == 0) + continue; + else + avg += nraw[nr_offset(y + k, x + m)][kc]; + avg /= 8; + // float dev = 0; + // for (int k = -2; k < 3; k += 2) + // for (int l = -2; l < 3; l += 2) + // if (k == 0 && l == 0) + // continue; + // else { + // float t = nraw[nr_offset(y + k, x + l)][kc] - + //avg; dev += t * t; + // } + // dev /= 8; + // dev = sqrt(dev); + if (calc_dist(c, avg) > Thot()) + { + ndir[nr_offset(y, x)] |= HOT; + float dv = calc_dist( + nraw[nr_offset(y - 2, x)][kc] * nraw[nr_offset(y - 1, x)][1], + nraw[nr_offset(y + 2, x)][kc] * nraw[nr_offset(y + 1, x)][1]); + float dh = calc_dist( + nraw[nr_offset(y, x - 2)][kc] * nraw[nr_offset(y, x - 1)][1], + nraw[nr_offset(y, x + 2)][kc] * nraw[nr_offset(y, x + 1)][1]); + if (dv > dh) + nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y, x + 2)][kc] + + nraw[nr_offset(y, x - 2)][kc]) / + 2; + else + nraw[nr_offset(y, x)][kc] = (nraw[nr_offset(y - 2, x)][kc] + + nraw[nr_offset(y + 2, x)][kc]) / + 2; + } + } + } + for (int j = js ^ 1; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + float c = nraw[nr_offset(y, x)][1]; + if ((c > nraw[nr_offset(y, x + 2)][1] && + c > nraw[nr_offset(y, x - 2)][1] && + c > nraw[nr_offset(y - 2, x)][1] && + c > nraw[nr_offset(y + 2, x)][1] && + c > nraw[nr_offset(y, x + 1)][kc] && + c > nraw[nr_offset(y, x - 1)][kc] && + c > nraw[nr_offset(y - 1, x)][kc ^ 2] && + c > nraw[nr_offset(y + 1, x)][kc ^ 2]) || + (c < nraw[nr_offset(y, x + 2)][1] && + c < nraw[nr_offset(y, x - 2)][1] && + c < nraw[nr_offset(y - 2, x)][1] && + c < nraw[nr_offset(y + 2, x)][1] && + c < nraw[nr_offset(y, x + 1)][kc] && + c < nraw[nr_offset(y, x - 1)][kc] && + c < nraw[nr_offset(y - 1, x)][kc ^ 2] && + c < nraw[nr_offset(y + 1, x)][kc ^ 2])) + { + float avg = 0; + for (int k = -2; k < 3; k += 2) + for (int m = -2; m < 3; m += 2) + if (k == 0 && m == 0) + continue; + else + avg += nraw[nr_offset(y + k, x + m)][1]; + avg /= 8; + // float dev = 0; + // for (int k = -2; k < 3; k += 2) + // for (int l = -2; l < 3; l += 2) + // if (k == 0 && l == 0) + // continue; + // else { + // float t = nraw[nr_offset(y + k, x + l)][1] - + //avg; dev += t * t; + // } + // dev /= 8; + // dev = sqrt(dev); + if (calc_dist(c, avg) > Thot()) + { + ndir[nr_offset(y, x)] |= HOT; + float dv = calc_dist( + nraw[nr_offset(y - 2, x)][1] * nraw[nr_offset(y - 1, x)][kc ^ 2], + nraw[nr_offset(y + 2, x)][1] * nraw[nr_offset(y + 1, x)][kc ^ 2]); + float dh = calc_dist( + nraw[nr_offset(y, x - 2)][1] * nraw[nr_offset(y, x - 1)][kc], + nraw[nr_offset(y, x + 2)][1] * nraw[nr_offset(y, x + 1)][kc]); + if (dv > dh) + nraw[nr_offset(y, x)][1] = + (nraw[nr_offset(y, x + 2)][1] + nraw[nr_offset(y, x - 2)][1]) / + 2; + else + nraw[nr_offset(y, x)][1] = + (nraw[nr_offset(y - 2, x)][1] + nraw[nr_offset(y + 2, x)][1]) / + 2; + } + } + } + } +} + +void DHT::restore_hots() +{ + int iwidth = libraw.imgdata.sizes.iwidth; +#if defined(LIBRAW_USE_OPENMP) +#ifdef _MSC_VER +#pragma omp parallel for firstprivate(iwidth) +#else +#pragma omp parallel for schedule(guided) firstprivate(iwidth) collapse(2) +#endif +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + for (int j = 0; j < iwidth; ++j) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + if (ndir[nr_offset(y, x)] & HOT) + { + int l = libraw.COLOR(i, j); + nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)][l] = + libraw.imgdata.image[i * iwidth + j][l]; + } + } + } +} + +void DHT::make_diag_dirs() +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_diag_dline(i); + } +//#if defined(LIBRAW_USE_OPENMP) +//#pragma omp parallel for schedule(guided) +//#endif +// for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { +// refine_diag_dirs(i, i & 1); +// } +//#if defined(LIBRAW_USE_OPENMP) +//#pragma omp parallel for schedule(guided) +//#endif +// for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) { +// refine_diag_dirs(i, (i & 1) ^ 1); +// } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_idiag_dirs(i); + } +} + +void DHT::make_hv_dirs() +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_hv_dline(i); + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_hv_dirs(i, i & 1); + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_hv_dirs(i, (i & 1) ^ 1); + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + refine_ihv_dirs(i); + } +} + +void DHT::refine_hv_dirs(int i, int js) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + if (ndir[nr_offset(y, x)] & HVSH) + continue; + int nv = + (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER) + + (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER); + int nh = + (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR) + + (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR); + bool codir = (ndir[nr_offset(y, x)] & VER) + ? ((ndir[nr_offset(y - 1, x)] & VER) || + (ndir[nr_offset(y + 1, x)] & VER)) + : ((ndir[nr_offset(y, x - 1)] & HOR) || + (ndir[nr_offset(y, x + 1)] & HOR)); + nv /= VER; + nh /= HOR; + if ((ndir[nr_offset(y, x)] & VER) && (nh > 2 && !codir)) + { + ndir[nr_offset(y, x)] &= ~VER; + ndir[nr_offset(y, x)] |= HOR; + } + if ((ndir[nr_offset(y, x)] & HOR) && (nv > 2 && !codir)) + { + ndir[nr_offset(y, x)] &= ~HOR; + ndir[nr_offset(y, x)] |= VER; + } + } +} + +void DHT::refine_ihv_dirs(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + if (ndir[nr_offset(y, x)] & HVSH) + continue; + int nv = + (ndir[nr_offset(y - 1, x)] & VER) + (ndir[nr_offset(y + 1, x)] & VER) + + (ndir[nr_offset(y, x - 1)] & VER) + (ndir[nr_offset(y, x + 1)] & VER); + int nh = + (ndir[nr_offset(y - 1, x)] & HOR) + (ndir[nr_offset(y + 1, x)] & HOR) + + (ndir[nr_offset(y, x - 1)] & HOR) + (ndir[nr_offset(y, x + 1)] & HOR); + nv /= VER; + nh /= HOR; + if ((ndir[nr_offset(y, x)] & VER) && nh > 3) + { + ndir[nr_offset(y, x)] &= ~VER; + ndir[nr_offset(y, x)] |= HOR; + } + if ((ndir[nr_offset(y, x)] & HOR) && nv > 3) + { + ndir[nr_offset(y, x)] &= ~HOR; + ndir[nr_offset(y, x)] |= VER; + } + } +} +void DHT::make_hv_dline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + char d = 0; + if ((j & 1) == js) + { + d = get_hv_grb(x, y, kc); + } + else + { + d = get_hv_rbg(x, y, kc); + } + ndir[nr_offset(y, x)] |= d; + } +} + +void DHT::make_diag_dline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + char d = 0; + if ((j & 1) == js) + { + d = get_diag_grb(x, y, kc); + } + else + { + d = get_diag_rbg(x, y, kc); + } + ndir[nr_offset(y, x)] |= d; + } +} + +void DHT::refine_diag_dirs(int i, int js) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + if (ndir[nr_offset(y, x)] & DIASH) + continue; + int nv = (ndir[nr_offset(y - 1, x)] & LURD) + + (ndir[nr_offset(y + 1, x)] & LURD) + + (ndir[nr_offset(y, x - 1)] & LURD) + + (ndir[nr_offset(y, x + 1)] & LURD) + + (ndir[nr_offset(y - 1, x - 1)] & LURD) + + (ndir[nr_offset(y - 1, x + 1)] & LURD) + + (ndir[nr_offset(y + 1, x - 1)] & LURD) + + (ndir[nr_offset(y + 1, x + 1)] & LURD); + int nh = (ndir[nr_offset(y - 1, x)] & RULD) + + (ndir[nr_offset(y + 1, x)] & RULD) + + (ndir[nr_offset(y, x - 1)] & RULD) + + (ndir[nr_offset(y, x + 1)] & RULD) + + (ndir[nr_offset(y - 1, x - 1)] & RULD) + + (ndir[nr_offset(y - 1, x + 1)] & RULD) + + (ndir[nr_offset(y + 1, x - 1)] & RULD) + + (ndir[nr_offset(y + 1, x + 1)] & RULD); + bool codir = (ndir[nr_offset(y, x)] & LURD) + ? ((ndir[nr_offset(y - 1, x - 1)] & LURD) || + (ndir[nr_offset(y + 1, x + 1)] & LURD)) + : ((ndir[nr_offset(y - 1, x + 1)] & RULD) || + (ndir[nr_offset(y + 1, x - 1)] & RULD)); + nv /= LURD; + nh /= RULD; + if ((ndir[nr_offset(y, x)] & LURD) && (nh > 4 && !codir)) + { + ndir[nr_offset(y, x)] &= ~LURD; + ndir[nr_offset(y, x)] |= RULD; + } + if ((ndir[nr_offset(y, x)] & RULD) && (nv > 4 && !codir)) + { + ndir[nr_offset(y, x)] &= ~RULD; + ndir[nr_offset(y, x)] |= LURD; + } + } +} + +void DHT::refine_idiag_dirs(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + if (ndir[nr_offset(y, x)] & DIASH) + continue; + int nv = (ndir[nr_offset(y - 1, x)] & LURD) + + (ndir[nr_offset(y + 1, x)] & LURD) + + (ndir[nr_offset(y, x - 1)] & LURD) + + (ndir[nr_offset(y, x + 1)] & LURD) + + (ndir[nr_offset(y - 1, x - 1)] & LURD) + + (ndir[nr_offset(y - 1, x + 1)] & LURD) + + (ndir[nr_offset(y + 1, x - 1)] & LURD) + + (ndir[nr_offset(y + 1, x + 1)] & LURD); + int nh = (ndir[nr_offset(y - 1, x)] & RULD) + + (ndir[nr_offset(y + 1, x)] & RULD) + + (ndir[nr_offset(y, x - 1)] & RULD) + + (ndir[nr_offset(y, x + 1)] & RULD) + + (ndir[nr_offset(y - 1, x - 1)] & RULD) + + (ndir[nr_offset(y - 1, x + 1)] & RULD) + + (ndir[nr_offset(y + 1, x - 1)] & RULD) + + (ndir[nr_offset(y + 1, x + 1)] & RULD); + nv /= LURD; + nh /= RULD; + if ((ndir[nr_offset(y, x)] & LURD) && nh > 7) + { + ndir[nr_offset(y, x)] &= ~LURD; + ndir[nr_offset(y, x)] |= RULD; + } + if ((ndir[nr_offset(y, x)] & RULD) && nv > 7) + { + ndir[nr_offset(y, x)] &= ~RULD; + ndir[nr_offset(y, x)] |= LURD; + } + } +} + +/* + * вычиÑление недоÑтающих зелёных точек. + */ +void DHT::make_greens() +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_gline(i); + } +} + +void DHT::make_gline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int kc = libraw.COLOR(i, js); + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ мимо извеÑтного зелёного + * kc -- извеÑтный цвет в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ + */ + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + int dx, dy, dx2, dy2; + float h1, h2; + if (ndir[nr_offset(y, x)] & VER) + { + dx = dx2 = 0; + dy = -1; + dy2 = 1; + h1 = 2 * nraw[nr_offset(y - 1, x)][1] / + (nraw[nr_offset(y - 2, x)][kc] + nraw[nr_offset(y, x)][kc]); + h2 = 2 * nraw[nr_offset(y + 1, x)][1] / + (nraw[nr_offset(y + 2, x)][kc] + nraw[nr_offset(y, x)][kc]); + } + else + { + dy = dy2 = 0; + dx = 1; + dx2 = -1; + h1 = 2 * nraw[nr_offset(y, x + 1)][1] / + (nraw[nr_offset(y, x + 2)][kc] + nraw[nr_offset(y, x)][kc]); + h2 = 2 * nraw[nr_offset(y, x - 1)][1] / + (nraw[nr_offset(y, x - 2)][kc] + nraw[nr_offset(y, x)][kc]); + } + float b1 = 1 / calc_dist(nraw[nr_offset(y, x)][kc], + nraw[nr_offset(y + dy * 2, x + dx * 2)][kc]); + float b2 = 1 / calc_dist(nraw[nr_offset(y, x)][kc], + nraw[nr_offset(y + dy2 * 2, x + dx2 * 2)][kc]); + b1 *= b1; + b2 *= b2; + float eg = nraw[nr_offset(y, x)][kc] * (b1 * h1 + b2 * h2) / (b1 + b2); + float min, max; + min = MIN(nraw[nr_offset(y + dy, x + dx)][1], + nraw[nr_offset(y + dy2, x + dx2)][1]); + max = MAX(nraw[nr_offset(y + dy, x + dx)][1], + nraw[nr_offset(y + dy2, x + dx2)][1]); + min /= 1.2f; + max *= 1.2f; + if (eg < min) + eg = scale_under(eg, min); + else if (eg > max) + eg = scale_over(eg, max); + if (eg > channel_maximum[1]) + eg = channel_maximum[1]; + else if (eg < channel_minimum[1]) + eg = channel_minimum[1]; + nraw[nr_offset(y, x)][1] = eg; + } +} + +/* + * Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ + */ + +void DHT::illustrate_dirs() +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + illustrate_dline(i); + } +} + +void DHT::illustrate_dline(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + for (int j = 0; j < iwidth; j++) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + nraw[nr_offset(y, x)][0] = nraw[nr_offset(y, x)][1] = + nraw[nr_offset(y, x)][2] = 0.5; + int l = ndir[nr_offset(y, x)] & 8; + // l >>= 3; // WTF? + l = 1; + if (ndir[nr_offset(y, x)] & HOT) + nraw[nr_offset(y, x)][0] = + l * channel_maximum[0] / 4 + channel_maximum[0] / 4; + else + nraw[nr_offset(y, x)][2] = + l * channel_maximum[2] / 4 + channel_maximum[2] / 4; + } +} + +/* + * интерполÑÑ†Ð¸Ñ ÐºÑ€Ð°Ñных и Ñиних. + * + * Ñначала интерполируютÑÑ Ð½ÐµÐ´Ð¾Ñтающие цвета, по диагональным направлениÑм от + * которых находÑÑ‚ÑÑ Ð¸Ð·Ð²ÐµÑтные, затем ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ ÑводитÑÑ Ðº тому как + * интерполировалиÑÑŒ зелёные. + */ + +void DHT::make_rbdiag(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = libraw.COLOR(i, 0) & 1; + int uc = libraw.COLOR(i, js); + int cl = uc ^ 2; + /* + * js -- Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ…-координата, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ‚ на уже интерполированный + * зелёный al -- извеÑтный цвет (кроме зелёного) в точке Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ cl + * -- неизвеÑтный цвет + */ + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + int dx, dy, dx2, dy2; + if (ndir[nr_offset(y, x)] & LURD) + { + dx = -1; + dx2 = 1; + dy = -1; + dy2 = 1; + } + else + { + dx = -1; + dx2 = 1; + dy = 1; + dy2 = -1; + } + float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], + nraw[nr_offset(y + dy, x + dx)][1]); + float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], + nraw[nr_offset(y + dy2, x + dx2)][1]); + g1 *= g1 * g1; + g2 *= g2 * g2; + + float eg; + eg = nraw[nr_offset(y, x)][1] * + (g1 * nraw[nr_offset(y + dy, x + dx)][cl] / + nraw[nr_offset(y + dy, x + dx)][1] + + g2 * nraw[nr_offset(y + dy2, x + dx2)][cl] / + nraw[nr_offset(y + dy2, x + dx2)][1]) / + (g1 + g2); + float min, max; + min = MIN(nraw[nr_offset(y + dy, x + dx)][cl], + nraw[nr_offset(y + dy2, x + dx2)][cl]); + max = MAX(nraw[nr_offset(y + dy, x + dx)][cl], + nraw[nr_offset(y + dy2, x + dx2)][cl]); + min /= 1.2f; + max *= 1.2f; + if (eg < min) + eg = scale_under(eg, min); + else if (eg > max) + eg = scale_over(eg, max); + if (eg > channel_maximum[cl]) + eg = channel_maximum[cl]; + else if (eg < channel_minimum[cl]) + eg = channel_minimum[cl]; + nraw[nr_offset(y, x)][cl] = eg; + } +} + +/* + * интерполÑÑ†Ð¸Ñ ÐºÑ€Ð°Ñных и Ñиних в точках где был извеÑтен только зелёный, + * Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð³Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ñ‹Ðµ или вертикальные + */ + +void DHT::make_rbhv(int i) +{ + int iwidth = libraw.imgdata.sizes.iwidth; + int js = (libraw.COLOR(i, 0) & 1) ^ 1; + for (int j = js; j < iwidth; j += 2) + { + int x = j + nr_leftmargin; + int y = i + nr_topmargin; + /* + * поÑкольку Ñверху-Ñнизу и Ñправа-Ñлева уже еÑть вÑе необходимые краÑные и + * Ñиние, то можно выбрать наилучшее направление иÑÑ…Ð¾Ð´Ñ Ð¸Ð· информации по + * обоим цветам. + */ + int dx, dy, dx2, dy2; + if (ndir[nr_offset(y, x)] & VER) + { + dx = dx2 = 0; + dy = -1; + dy2 = 1; + } + else + { + dy = dy2 = 0; + dx = 1; + dx2 = -1; + } + float g1 = 1 / calc_dist(nraw[nr_offset(y, x)][1], + nraw[nr_offset(y + dy, x + dx)][1]); + float g2 = 1 / calc_dist(nraw[nr_offset(y, x)][1], + nraw[nr_offset(y + dy2, x + dx2)][1]); + g1 *= g1; + g2 *= g2; + float eg_r, eg_b; + eg_r = nraw[nr_offset(y, x)][1] * + (g1 * nraw[nr_offset(y + dy, x + dx)][0] / + nraw[nr_offset(y + dy, x + dx)][1] + + g2 * nraw[nr_offset(y + dy2, x + dx2)][0] / + nraw[nr_offset(y + dy2, x + dx2)][1]) / + (g1 + g2); + eg_b = nraw[nr_offset(y, x)][1] * + (g1 * nraw[nr_offset(y + dy, x + dx)][2] / + nraw[nr_offset(y + dy, x + dx)][1] + + g2 * nraw[nr_offset(y + dy2, x + dx2)][2] / + nraw[nr_offset(y + dy2, x + dx2)][1]) / + (g1 + g2); + float min_r, max_r; + min_r = MIN(nraw[nr_offset(y + dy, x + dx)][0], + nraw[nr_offset(y + dy2, x + dx2)][0]); + max_r = MAX(nraw[nr_offset(y + dy, x + dx)][0], + nraw[nr_offset(y + dy2, x + dx2)][0]); + float min_b, max_b; + min_b = MIN(nraw[nr_offset(y + dy, x + dx)][2], + nraw[nr_offset(y + dy2, x + dx2)][2]); + max_b = MAX(nraw[nr_offset(y + dy, x + dx)][2], + nraw[nr_offset(y + dy2, x + dx2)][2]); + min_r /= 1.2f; + max_r *= 1.2f; + min_b /= 1.2f; + max_b *= 1.2f; + + if (eg_r < min_r) + eg_r = scale_under(eg_r, min_r); + else if (eg_r > max_r) + eg_r = scale_over(eg_r, max_r); + if (eg_b < min_b) + eg_b = scale_under(eg_b, min_b); + else if (eg_b > max_b) + eg_b = scale_over(eg_b, max_b); + + if (eg_r > channel_maximum[0]) + eg_r = channel_maximum[0]; + else if (eg_r < channel_minimum[0]) + eg_r = channel_minimum[0]; + if (eg_b > channel_maximum[2]) + eg_b = channel_maximum[2]; + else if (eg_b < channel_minimum[2]) + eg_b = channel_minimum[2]; + nraw[nr_offset(y, x)][0] = eg_r; + nraw[nr_offset(y, x)][2] = eg_b; + } +} + +void DHT::make_rb() +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp barrier +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_rbdiag(i); + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp barrier +#pragma omp parallel for schedule(guided) +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + make_rbhv(i); + } +} + +/* + * Ð¿ÐµÑ€ÐµÐ½Ð¾Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² выходной маÑÑив + */ +void DHT::copy_to_image() +{ + int iwidth = libraw.imgdata.sizes.iwidth; +#if defined(LIBRAW_USE_OPENMP) +#ifdef _MSC_VER +#pragma omp parallel for +#else +#pragma omp parallel for schedule(guided) collapse(2) +#endif +#endif + for (int i = 0; i < libraw.imgdata.sizes.iheight; ++i) + { + for (int j = 0; j < iwidth; ++j) + { + libraw.imgdata.image[i * iwidth + j][0] = + (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)] + [0]); + libraw.imgdata.image[i * iwidth + j][2] = + (unsigned short)(nraw[nr_offset(i + nr_topmargin, j + nr_leftmargin)] + [2]); + libraw.imgdata.image[i * iwidth + j][1] = + libraw.imgdata.image[i * iwidth + j][3] = + (unsigned short)(nraw[nr_offset(i + nr_topmargin, + j + nr_leftmargin)][1]); + } + } +} + +DHT::~DHT() +{ + free(nraw); + free(ndir); +} + +void LibRaw::dht_interpolate() +{ + if (imgdata.idata.filters != 0x16161616 + && imgdata.idata.filters != 0x61616161 + && imgdata.idata.filters != 0x49494949 + && imgdata.idata.filters != 0x94949494 + ) + { + ahd_interpolate(); + return; + } + DHT dht(*this); + dht.hide_hots(); + dht.make_hv_dirs(); + // dht.illustrate_dirs(); + dht.make_greens(); + dht.make_diag_dirs(); + // dht.illustrate_dirs(); + dht.make_rb(); + dht.restore_hots(); + dht.copy_to_image(); +} diff --git a/src/demosaic/misc_demosaic.cpp b/src/demosaic/misc_demosaic.cpp new file mode 100644 index 000000000..d23e494d0 --- /dev/null +++ b/src/demosaic/misc_demosaic.cpp @@ -0,0 +1,420 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::pre_interpolate() +{ + ushort(*img)[4]; + int row, col, c; + RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 0, 2); + if (shrink) + { + if (half_size) + { + height = iheight; + width = iwidth; + if (filters == 9) + { + for (row = 0; row < 3; row++) + for (col = 1; col < 4; col++) + if (!(image[row * width + col][0] | image[row * width + col][2])) + goto break2; + break2: + for (; row < height; row += 3) + for (col = (col - 1) % 3 + 1; col < width - 1; col += 3) + { + img = image + row * width + col; + for (c = 0; c < 3; c += 2) + img[0][c] = (img[-1][c] + img[1][c]) >> 1; + } + } + } + else + { + img = (ushort(*)[4])calloc(height, width * sizeof *img); + for (row = 0; row < height; row++) + for (col = 0; col < width; col++) + { + c = fcol(row, col); + img[row * width + col][c] = + image[(row >> 1) * iwidth + (col >> 1)][c]; + } + free(image); + image = img; + shrink = 0; + } + } + if (filters > 1000 && colors == 3) + { + mix_green = four_color_rgb ^ half_size; + if (four_color_rgb | half_size) + colors++; + else + { + for (row = FC(1, 0) >> 1; row < height; row += 2) + for (col = FC(row, 1) & 1; col < width; col += 2) + image[row * width + col][1] = image[row * width + col][3]; + filters &= ~((filters & 0x55555555U) << 1); + } + } + if (half_size) + filters = 0; + RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 1, 2); +} + +void LibRaw::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 == (unsigned)border && row >= (unsigned)border && row < (unsigned)(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); + FORC(unsigned(colors)) if (c != f && sum[c + 4]) image[row * width + col][c] = + sum[c] / sum[c + 4]; + } +} + +void LibRaw::lin_interpolate_loop(int *code, int size) +{ + int row; + for (row = 1; row < height - 1; row++) + { + int col, *ip; + ushort *pix; + for (col = 1; col < width - 1; col++) + { + int i; + int sum[4]; + pix = image[row * width + col]; + ip = code + ((((row % size) * 16) + (col % size)) * 32); + 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; + } + } +} + +void LibRaw::lin_interpolate() +{ + std::vector code_buffer(16 * 16 * 32); + int* code = &code_buffer[0], size = 16, *ip, sum[4]; + int f, c, x, y, row, col, shift, color; + + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); + + if (filters == 9) + size = 6; + border_interpolate(1); + for (row = 0; row < size; row++) + for (col = 0; col < size; col++) + { + ip = code + (((row * 16) + col) * 32) + 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 + 48, col + x + 48); + if (color == f) + continue; + *ip++ = (width * y + x) * 4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + code[(row * 16 + col) * 32] = (ip - (code + ((row * 16) + col) * 32)) / 3; + FORCC + if (c != f) + { + *ip++ = c; + *ip++ = sum[c] > 0 ? 256 / sum[c] : 0; + } + } + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); + lin_interpolate_loop(code, size); + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); +} + +/* + 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 LibRaw::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, -128, -1, -2, +0, -1, 0, 0x01, -1, -2, +1, + -1, 0, 0x01, -1, -2, +1, +0, 1, 0x01, -1, -1, -1, +1, 0, -120, + -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, -128, + +0, -1, +0, +1, 1, -120, +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, -128, + +1, -1, +1, +1, 0, -120, +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 (filters == 1) + prow = pcol = 16; + if (filters == 9) + prow = pcol = 6; + ip = (int *)calloc(prow * pcol, 1280); + 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 + 144, col + x1 + 144); + if (fcol(row + y2 + 144, col + x2 + 144) != 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 << g) + *ip++ = g; + *ip++ = -1; + } + *ip++ = INT_MAX; + for (cp = chood, g = 0; g < 8; g++) + { + y = *cp++; + x = *cp++; + *ip++ = (y * width + x) * 4; + color = fcol(row, col); + if (fcol(row + y + 144, col + x + 144) != color && + fcol(row + y * 2 + 144, col + x * 2 + 144) == color) + *ip++ = (y * width + x) * 8 + color; + else + *ip++ = 0; + } + } + brow[4] = (ushort(*)[4])calloc(width * 3, sizeof **brow); + for (row = 0; row < 3; row++) + brow[row] = brow[4] + row * width; + for (row = 2; row < height - 2; row++) + { /* Do VNG interpolation */ + if (!((row - 2) % 256)) + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, (row - 2) / 256 + 1, + ((height - 3) / 256) + 1); + for (col = 2; col < width - 2; col++) + { + pix = image[row * width + col]; + ip = code[row % prow][col % pcol]; + memset(gval, 0, sizeof gval); + while ((g = ip[0]) != INT_MAX) + { /* Calculate gradients */ + diff = ABS(pix[g] - pix[ip[1]]) << ip[2]; + gval[ip[3]] += diff; + ip += 5; + if ((g = ip[-1]) == -1) + continue; + gval[g] += diff; + while ((g = *ip++) != -1) + gval[g] += diff; + } + ip++; + gmin = gmax = gval[0]; /* Choose a threshold */ + for (g = 1; g < 8; g++) + { + if (gmin > gval[g]) + gmin = gval[g]; + if (gmax < gval[g]) + gmax = gval[g]; + } + 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 LibRaw::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); + + /* Fill in the green layer with gradients and pattern recognition: */ + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ + i, pix) schedule(static) +#endif + 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; i < 2; i++) + { + d = dir[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: */ + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ + i, pix) schedule(static) +#endif + 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; i < 2; c = 2 - c, i++) + { + d = dir[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: */ + RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); +#ifdef LIBRAW_USE_OPENMP +#pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ + i, pix) schedule(static) +#endif + 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; i < 2; i++) + { + d = dir[i] + dir[i+1]; + 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); + } +} diff --git a/src/demosaic/xtrans_demosaic.cpp b/src/demosaic/xtrans_demosaic.cpp new file mode 100644 index 000000000..5dbc3c3f6 --- /dev/null +++ b/src/demosaic/xtrans_demosaic.cpp @@ -0,0 +1,430 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +#define fcol(row, col) xtrans[(row + 6) % 6][(col + 6) % 6] +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + */ +void LibRaw::xtrans_interpolate(int passes) +{ + int cstat[4] = {0, 0, 0, 0}; + int ndir; + static const short orth[12] = {1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1}, + patt[2][16] = {{0, 1, 0, -1, 2, 0, -1, 0, 1, 1, 1, -1, 0, + 0, 0, 0}, + {0, 1, 0, -2, 1, 0, -2, 0, 1, 1, -2, -2, 1, + -1, -1, 1}}, + dir[4] = {1, LIBRAW_AHD_TILE, LIBRAW_AHD_TILE + 1, + LIBRAW_AHD_TILE - 1}; + short allhex[3][3][2][8]; + ushort sgrow = 0, sgcol = 0; + + if (width < LIBRAW_AHD_TILE || height < LIBRAW_AHD_TILE) + throw LIBRAW_EXCEPTION_IO_CORRUPT; // too small image + /* Check against right pattern */ + for (int row = 0; row < 6; row++) + for (int col = 0; col < 6; col++) + cstat[(unsigned)fcol(row, col)]++; + + if (cstat[0] < 6 || cstat[0] > 10 || cstat[1] < 16 || cstat[1] > 24 || + cstat[2] < 6 || cstat[2] > 10 || cstat[3]) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + // Init allhex table to unreasonable values + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + for (int l = 0; l < 8; l++) + allhex[i][j][k][l] = 32700; + + cielab(0, 0); + ndir = 4 << int(passes > 1); + + int minv = 0, maxv = 0, minh = 0, maxh = 0; + /* Map a green hexagon around each non-green pixel and vice versa: */ + for (int row = 0; row < 3; row++) + for (int col = 0; col < 3; col++) + for (int ng = 0, d = 0; d < 10; d += 2) + { + int g = fcol(row, col) == 1; + if (fcol(row + orth[d], col + orth[d + 2]) == 1) + ng = 0; + else + ng++; + if (ng == 4) + { + sgrow = row; + sgcol = col; + } + if (ng == g + 1) + { + int c; + FORC(8) + { + int v = orth[d] * patt[g][c * 2] + orth[d + 1] * patt[g][c * 2 + 1]; + int h = orth[d + 2] * patt[g][c * 2] + orth[d + 3] * patt[g][c * 2 + 1]; + minv = MIN(v, minv); + maxv = MAX(v, maxv); + minh = MIN(v, minh); + maxh = MAX(v, maxh); + allhex[row][col][0][c ^ (g * 2 & d)] = h + v * width; + allhex[row][col][1][c ^ (g * 2 & d)] = h + v * LIBRAW_AHD_TILE; + } + } + } + + // Check allhex table initialization + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + for (int l = 0; l < 8; l++) + if (allhex[i][j][k][l] > maxh + maxv * width + 1 || + allhex[i][j][k][l] < minh + minv * width - 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int retrycount = 0; + + /* Set green1 and green3 to the minimum and maximum allowed values: */ + for (int row = 2; row < height - 2; row++) + { + int col; + ushort min, max; + for (col = 2, max = 0u, min = 0xffffu; col < int(width) - 2; col++) + { + if (fcol(row, col) == 1 && (min = ~(max = 0))) + continue; + ushort(*pix)[4]; + pix = image + row * width + col; + short* hex = allhex[row % 3][col % 3][0]; + if (!max) + { + int c; + FORC(6) + { + int val = pix[hex[c]][1]; + if (min > val) + min = val; + if (max < val) + max = val; + } + } + pix[0][1] = min; + pix[0][3] = max; + switch ((row - sgrow) % 3) + { + case 1: + if (row < height - 3) + { + row++; + col--; + } + break; + case 2: + if ((min = ~(max = 0)) && (col += 2) < width - 3 && row > 2) + { + row--; + if (retrycount++ > width * height) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + } + } + + for (int row = 3; row < 9 && row < height - 3; row++) + for (int col = 3; col < 9 && col < width - 3; col++) + { + if ((fcol(row, col)) == 1) + continue; + short* hex = allhex[row % 3][col % 3][0]; + int c; + FORC(2) + { + int idx3 = 3 * hex[4 + c] + row * width + col; + int idx4 = -3 * hex[4 + c] + row * width + col; + int maxidx = width * height; + if (idx3 < 0 || idx3 >= maxidx) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (idx4 < 0 || idx4 >= maxidx) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + +#if defined(LIBRAW_USE_OPENMP) + int buffer_count = omp_get_max_threads(); +#else + int buffer_count = 1; +#endif + + size_t buffer_size = LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 11 + 6); + char** buffers = malloc_omp_buffers(buffer_count, buffer_size); + +#if defined(LIBRAW_USE_OPENMP) +# pragma omp parallel for schedule(dynamic) default(none) firstprivate(buffers, allhex, passes, sgrow, sgcol, ndir) shared(dir) +#endif + for (int top = 3; top < height - 19; top += LIBRAW_AHD_TILE - 16) + { +#if defined(LIBRAW_USE_OPENMP) + char* buffer = buffers[omp_get_thread_num()]; +#else + char* buffer = buffers[0]; +#endif + + ushort(*rgb)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3], (*rix)[3]; + short(*lab)[LIBRAW_AHD_TILE][3], (*lix)[3]; + float(*drv)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE]; + char(*homo)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE]; + + rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; + lab = (short(*)[LIBRAW_AHD_TILE][3])( + buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6)); + drv = (float(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])( + buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 6 + 6)); + homo = (char(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE])( + buffer + LIBRAW_AHD_TILE * LIBRAW_AHD_TILE * (ndir * 10 + 6)); + + for (int left = 3; left < width - 19; left += LIBRAW_AHD_TILE - 16) + { + int mrow = MIN(top + LIBRAW_AHD_TILE, height - 3); + int mcol = MIN(left + LIBRAW_AHD_TILE, width - 3); + for (int row = top; row < mrow; row++) + for (int col = left; col < mcol; col++) + memcpy(rgb[0][row - top][col - left], image[row * width + col], 6); + int c; + FORC3 memcpy(rgb[c + 1], rgb[0], sizeof * rgb); + + /* Interpolate green horizontally, vertically, and along both diagonals: + */ + int color[3][8]; + for (int row = top; row < mrow; row++) + for (int col = left; col < mcol; col++) + { + int f; + if ((f = fcol(row, col)) == 1) + continue; + ushort (*pix)[4] = image + row * width + col; + short* hex = allhex[row % 3][col % 3][0]; + color[1][0] = 174 * (pix[hex[1]][1] + pix[hex[0]][1]) - + 46 * (pix[2 * hex[1]][1] + pix[2 * hex[0]][1]); + color[1][1] = 223 * pix[hex[3]][1] + pix[hex[2]][1] * 33 + + 92 * (pix[0][f] - pix[-hex[2]][f]); + FORC(2) + color[1][2 + c] = 164 * pix[hex[4 + c]][1] + + 92 * pix[-2 * hex[4 + c]][1] + + 33 * (2 * pix[0][f] - pix[3 * hex[4 + c]][f] - + pix[-3 * hex[4 + c]][f]); + FORC4 rgb[c ^ !((row - sgrow) % 3)][row - top][col - left][1] = + LIM(color[1][c] >> 8, pix[0][1], pix[0][3]); + } + + for (int pass = 0; pass < passes; pass++) + { + if (pass == 1) + memcpy(rgb += 4, buffer, 4 * sizeof * rgb); + + /* Recalculate green from interpolated values of closer pixels: */ + if (pass) + { + for (int row = top + 2; row < mrow - 2; row++) + for (int col = left + 2; col < mcol - 2; col++) + { + int f; + if ((f = fcol(row, col)) == 1) + continue; + ushort(*pix)[4] = image + row * width + col; + short* hex = allhex[row % 3][col % 3][1]; + for (int d = 3; d < 6; d++) + { + rix = + &rgb[(d - 2) ^ !((row - sgrow) % 3)][row - top][col - left]; + int val = rix[-2 * hex[d]][1] + 2 * rix[hex[d]][1] - + rix[-2 * hex[d]][f] - 2 * rix[hex[d]][f] + 3 * rix[0][f]; + rix[0][1] = LIM(val / 3, pix[0][1], pix[0][3]); + } + } + } + + /* Interpolate red and blue values for solitary green pixels: */ + for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) + for (int col = (left - sgcol + 4) / 3 * 3 + sgcol; col < mcol - 2; col += 3) + { + rix = &rgb[0][row - top][col - left]; + int h = fcol(row, col + 1); + float diff[6]; + memset(diff, 0, sizeof diff); + for (int i = 1, d = 0; d < 6; d++, i ^= LIBRAW_AHD_TILE ^ 1, h ^= 2) + { + for (c = 0; c < 2; c++, h ^= 2) + { + int g = 2 * rix[0][1] - rix[i << c][1] - rix[-i << c][1]; + color[h][d] = g + rix[i << c][h] + rix[-i << c][h]; + if (d > 1) + diff[d] += SQR((float)rix[i << c][1] - (float)rix[-i << c][1] - + (float)rix[i << c][h] + (float)rix[-i << c][h]) + SQR((float)g); + } + if (d > 1 && (d & 1)) + if (diff[d - 1] < diff[d]) + FORC(2) color[c * 2][d] = color[c * 2][d - 1]; + if (d < 2 || (d & 1)) + { + FORC(2) rix[0][c * 2] = CLIP(color[c * 2][d] / 2); + rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE; + } + } + } + + /* Interpolate red for blue pixels and vice versa: */ + for (int row = top + 3; row < mrow - 3; row++) + for (int col = left + 3; col < mcol - 3; col++) + { + int f; + if ((f = 2 - fcol(row, col)) == 1) + continue; + rix = &rgb[0][row - top][col - left]; + c = (row - sgrow) % 3 ? LIBRAW_AHD_TILE : 1; + int h = 3 * (c ^ LIBRAW_AHD_TILE ^ 1); + for (int d = 0; d < 4; d++, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE) + { + int i = d > 1 || ((d ^ c) & 1) || + ((ABS(rix[0][1] - rix[c][1]) + + ABS(rix[0][1] - rix[-c][1])) < + 2 * (ABS(rix[0][1] - rix[h][1]) + + ABS(rix[0][1] - rix[-h][1]))) + ? c + : h; + rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + 2 * rix[0][1] - + rix[i][1] - rix[-i][1]) / + 2); + } + } + + /* Fill in red and blue for 2x2 blocks of green: */ + for (int row = top + 2; row < mrow - 2; row++) + if ((row - sgrow) % 3) + for (int col = left + 2; col < mcol - 2; col++) + if ((col - sgcol) % 3) + { + rix = &rgb[0][row - top][col - left]; + short* hex = allhex[row % 3][col % 3][1]; + for (int d = 0; d < 8; + d += 2, rix += LIBRAW_AHD_TILE * LIBRAW_AHD_TILE) + if (hex[d] + hex[d + 1]) + { + int g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; + for (c = 0; c < 4; c += 2) + rix[0][c] = CLIP( + (g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) / 3); + } + else + { + int g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; + for (c = 0; c < 4; c += 2) + rix[0][c] = + CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) / 2); + } + } + } + rgb = (ushort(*)[LIBRAW_AHD_TILE][LIBRAW_AHD_TILE][3])buffer; + mrow -= top; + mcol -= left; + + /* Convert to CIELab and differentiate in all directions: */ + // no effect + for (int d = 0; d < ndir; d++) + { + for (int row = 2; row < mrow - 2; row++) + for (int col = 2; col < mcol - 2; col++) + cielab(rgb[d][row][col], lab[row][col]); + for (int f = dir[d & 3], row = 3; row < mrow - 3; row++) + for (int col = 3; col < mcol - 3; col++) + { + lix = &lab[row][col]; + int g = 2 * lix[0][0] - lix[f][0] - lix[-f][0]; + drv[d][row][col] = + SQR(g) + + SQR((2 * lix[0][1] - lix[f][1] - lix[-f][1] + g * 500 / 232)) + + SQR((2 * lix[0][2] - lix[f][2] - lix[-f][2] - g * 500 / 580)); + } + } + + /* Build homogeneity maps from the derivatives: */ + memset(homo, 0, ndir * LIBRAW_AHD_TILE * LIBRAW_AHD_TILE); + for (int row = 4; row < mrow - 4; row++) + for (int col = 4; col < mcol - 4; col++) + { + int d; + float tr; + for (tr = FLT_MAX, d = 0; d < ndir; d++) + if (tr > drv[d][row][col]) + tr = drv[d][row][col]; + tr *= 8; + for (int dd = 0; dd < ndir; dd++) + for (int v = -1; v <= 1; v++) + for (int h = -1; h <= 1; h++) + if (drv[dd][row + v][col + h] <= tr) + homo[dd][row][col]++; + } + + /* Average the most homogeneous pixels for the final result: */ + if (height - top < LIBRAW_AHD_TILE + 4) + mrow = height - top + 2; + if (width - left < LIBRAW_AHD_TILE + 4) + mcol = width - left + 2; + for (int row = MIN(top, 8); row < mrow - 8; row++) + for (int col = MIN(left, 8); col < mcol - 8; col++) + { + int v; + int hm[8]; + for (int d = 0; d < ndir; d++) + for (v = -2, hm[d] = 0; v <= 2; v++) + for (int h = -2; h <= 2; h++) + hm[d] += homo[d][row + v][col + h]; + for (int d = 0; d < ndir - 4; d++) + if (hm[d] < hm[d + 4]) + hm[d] = 0; + else if (hm[d] > hm[d + 4]) + hm[d + 4] = 0; + ushort max; + int d; + for (d = 1, max = hm[0]; d < ndir; d++) + if (max < hm[d]) + max = hm[d]; + max -= max >> 3; + + int avg[4]; + memset(avg, 0, sizeof avg); + for (int dd = 0; dd < ndir; dd++) + if (hm[dd] >= max) + { + FORC3 avg[c] += rgb[dd][row][col][c]; + avg[3]++; + } + FORC3 image[(row + top) * width + col + left][c] = avg[c] / avg[3]; + } + } + } + +#ifdef LIBRAW_USE_OPENMP +#pragma omp barrier +#endif + + free_omp_buffers(buffers, buffer_count); + + border_interpolate(8); +} +#undef fcol diff --git a/src/integration/dngsdk_glue.cpp b/src/integration/dngsdk_glue.cpp new file mode 100644 index 000000000..494383676 --- /dev/null +++ b/src/integration/dngsdk_glue.cpp @@ -0,0 +1,414 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#if defined (USE_GPRSDK) && !defined(USE_DNGSDK) +#error GPR (GoPro) SDK should be used with Adobe DNG SDK +#endif +#ifdef USE_DNGSDK +#include "dng_read_image.h" +#endif +#ifdef USE_GPRSDK +#include "gpr_read_image.h" +#endif + +#ifdef USE_DNGSDK +static dng_ifd* search_single_ifd(const std::vector & v, uint64 offset, int& idx, dng_stream& stream) +{ + idx = -1; + for (int i = 0; i < v.size(); i++) + { + if (!v[i]) continue; + if (v[i]->fTileOffsetsOffset == offset) + { + idx = i; + return v[i]; + } + else if (v[i]->fTileOffsetsCount == 1 && v[i]->fTileOffset[0] == offset) + { + idx = i; + return v[i]; + } + else if (v[i]->fTileOffsetsCount > dng_ifd::kMaxTileInfo) + { + uint64 p = stream.Position(); + stream.SetReadPosition(v[i]->fTileOffsetsOffset); + int32 oo = stream.TagValue_uint32(v[i]->fTileOffsetsType); + stream.SetReadPosition(p); + if (oo == offset) + { + idx = i; + return v[i]; + } + } + } + return NULL; +} + +static dng_ifd* search_for_ifd(const dng_info& info, uint64 offset, ushort w, ushort h, int& ifdIndex, dng_stream& stream) +{ + dng_ifd *ret = 0; + ret = search_single_ifd(info.fIFD, offset, ifdIndex, stream); + int dummy; + if (!ret) ret = search_single_ifd(info.fChainedIFD, offset, dummy, stream); + if (!ret) + { + for (int c = 0; !ret && c < info.fChainedSubIFD.size(); c++) + ret = search_single_ifd(info.fChainedSubIFD[c], offset, dummy, stream); + } + if (ret && (ret->fImageLength == h) && ret->fImageWidth == w) + return ret; + ifdIndex = -1; + return 0; +} +#endif + +int LibRaw::valid_for_dngsdk() +{ +#ifndef USE_DNGSDK + return 0; +#else + if (!imgdata.idata.dng_version) + return 0; + + // All DNG larger than 2GB - to DNG SDK + if (libraw_internal_data.internal_data.input->size() > 2147483647ULL) + return 1; + + if (!strcasecmp(imgdata.idata.make, "Blackmagic") + && (libraw_internal_data.unpacker_data.tiff_compress == 7) + && (libraw_internal_data.unpacker_data.tiff_bps > 8) + ) + return 0; + + if (libraw_internal_data.unpacker_data.tiff_compress == 34892 + && libraw_internal_data.unpacker_data.tiff_bps == 8 + && libraw_internal_data.unpacker_data.tiff_samples == 3 + && load_raw == &LibRaw::lossy_dng_load_raw + ) + { + if (!dnghost) + return 0; + dng_host *host = static_cast(dnghost); + libraw_dng_stream stream(libraw_internal_data.internal_data.input); + AutoPtr negative; + negative.Reset(host->Make_dng_negative()); + dng_info info; + info.Parse(*host, stream); + info.PostParse(*host); + if (!info.IsValidDNG()) + return 0; + negative->Parse(*host, stream, info); + negative->PostParse(*host, stream, info); + int ifdindex = -1; + dng_ifd *rawIFD = search_for_ifd(info, libraw_internal_data.unpacker_data.data_offset, imgdata.sizes.raw_width, imgdata.sizes.raw_height, ifdindex,stream); + if (rawIFD && ifdindex >= 0 && ifdindex == info.fMainIndex) + return 1; + return 0; + } + +#ifdef USE_GPRSDK + if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) // regardless of flags or use_dngsdk value! + return 1; +#endif + if (!imgdata.rawparams.use_dngsdk) + return 0; + if (load_raw == &LibRaw::lossy_dng_load_raw) // WHY?? + return 0; + if (is_floating_point() && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_FLOAT)) + return 1; + if (!imgdata.idata.filters && (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_LINEAR)) + return 1; + if (libraw_internal_data.unpacker_data.tiff_bps == 8 && + (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_8BIT)) + return 1; + if (libraw_internal_data.unpacker_data.tiff_compress == 8 && + (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_DEFLATE)) + return 1; + if (libraw_internal_data.unpacker_data.tiff_samples == 2) + return 0; // Always deny 2-samples (old fuji superccd) + if (imgdata.idata.filters == 9 && + (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_XTRANS)) + return 1; + if (is_fuji_rotated()) + return 0; // refuse + if (imgdata.rawparams.use_dngsdk & LIBRAW_DNG_OTHER) + return 1; + return 0; +#endif +} + + + + +int LibRaw::try_dngsdk() +{ +#ifdef USE_DNGSDK + if (!dnghost) + return LIBRAW_UNSPECIFIED_ERROR; + + dng_host *host = static_cast(dnghost); + + try + { + libraw_dng_stream stream(libraw_internal_data.internal_data.input); + + AutoPtr negative; + negative.Reset(host->Make_dng_negative()); + + dng_info info; + info.Parse(*host, stream); + info.PostParse(*host); + + if (!info.IsValidDNG()) + { + return LIBRAW_DATA_ERROR; + } + negative->Parse(*host, stream, info); + negative->PostParse(*host, stream, info); + int ifdindex; + dng_ifd *rawIFD = search_for_ifd(info,libraw_internal_data.unpacker_data.data_offset,imgdata.sizes.raw_width,imgdata.sizes.raw_height,ifdindex,stream); + if(!rawIFD) + return LIBRAW_DATA_ERROR; + + AutoPtr stage2; + bool stage23used = false; + bool zerocopy = false; + + //(new dng_simple_image(rawIFD->Bounds(), rawIFD->fSamplesPerPixel, rawIFD->PixelType(), host->Allocator())); + + if (((libraw_internal_data.unpacker_data.tiff_compress == 34892 + && libraw_internal_data.unpacker_data.tiff_bps == 8 + && libraw_internal_data.unpacker_data.tiff_samples == 3 + && load_raw == &LibRaw::lossy_dng_load_raw) + || (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2| LIBRAW_RAWOPTIONS_DNG_STAGE3)) + || ((tiff_ifd[ifdindex].dng_levels.parsedfields & (LIBRAW_DNGFM_OPCODE2| LIBRAW_DNGFM_OPCODE3)) + && (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT | LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT))) + ) + && ifdindex >= 0) + { + if (info.fMainIndex != ifdindex) + info.fMainIndex = ifdindex; + + negative->ReadStage1Image(*host, stream, info); + negative->BuildStage2Image(*host); + imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE2_APPLIED; + if ( (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3) || + ((tiff_ifd[ifdindex].dng_levels.parsedfields & LIBRAW_DNGFM_OPCODE3) && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT)) + ) + { + negative->BuildStage3Image(*host); + stage2.Reset((dng_simple_image*)negative->Stage3Image()); + imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE3_APPLIED; + } + else + stage2.Reset((dng_simple_image*)negative->Stage2Image()); + stage23used = true; + } + else + { + stage2.Reset(new dng_simple_image(rawIFD->Bounds(), rawIFD->fSamplesPerPixel, rawIFD->PixelType(), host->Allocator())); +#ifdef USE_GPRSDK + if (libraw_internal_data.unpacker_data.tiff_compress == 9) + { + gpr_allocator allocator; + allocator.Alloc = ::malloc; + allocator.Free = ::free; + gpr_buffer_auto vc5_image_obj(allocator.Alloc, allocator.Free); + + gpr_read_image reader(&vc5_image_obj); + reader.Read(*host, *rawIFD, stream, *stage2.Get(), NULL, NULL); + } + else +#endif + { + dng_read_image reader; + reader.Read(*host, *rawIFD, stream, *stage2.Get(), NULL, NULL); + } + } + + if (stage2->Bounds().W() != S.raw_width || + stage2->Bounds().H() != S.raw_height) + { + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ALLOWSIZECHANGE) + { + S.raw_width = S.width = stage2->Bounds().W(); + S.left_margin = 0; + S.raw_height = S.height = stage2->Bounds().H(); + S.top_margin = 0; + } + else + { + stage2.Release(); // It holds copy to internal dngnegative + return LIBRAW_DATA_ERROR; + } + } + if (stage23used) + { + if (stage2->Planes() > 1) + { + imgdata.idata.filters = 0; + imgdata.idata.colors = stage2->Planes(); + } + // reset BL and whitepoint + imgdata.color.black = 0; + memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); + imgdata.color.maximum = 0xffff; + } + + int pplanes = stage2->Planes(); + int ptype = stage2->PixelType(); + + dng_pixel_buffer buffer; + stage2->GetPixelBuffer(buffer); + + int pixels = stage2->Bounds().H() * stage2->Bounds().W() * pplanes; + + if (ptype == ttShort && !stage23used && !is_curve_linear()) + { + imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype)); + ushort *src = (ushort *)buffer.fData; + ushort *dst = (ushort *)imgdata.rawdata.raw_alloc; + for (int i = 0; i < pixels; i++) + dst[i] = imgdata.color.curve[src[i]]; + S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype); + + } + else if (ptype == ttByte) + { + imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ttShort)); + unsigned char *src = (unsigned char *)buffer.fData; + ushort *dst = (ushort *)imgdata.rawdata.raw_alloc; + if (is_curve_linear()) + { + for (int i = 0; i < pixels; i++) + dst[i] = src[i]; + } + else + { + for (int i = 0; i < pixels; i++) + dst[i] = imgdata.color.curve[src[i]]; + } + S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ttShort); + } + else + { + // Alloc + if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY) && !stage23used) + { + zerocopy = true; + } + else + { + imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype)); + memmove(imgdata.rawdata.raw_alloc, buffer.fData, + pixels * TagTypeSize(ptype)); + } + S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype); + } + + if (stage23used) + stage2.Release(); + + if ((ptype == ttFloat) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)) + zerocopy = true; + + if (zerocopy) + { + switch (ptype) + { + case ttFloat: + if (pplanes == 1) + imgdata.rawdata.float_image = (float *)buffer.fData; + else if (pplanes == 3) + imgdata.rawdata.float3_image = (float(*)[3])buffer.fData; + else if (pplanes == 4) + imgdata.rawdata.float4_image = (float(*)[4])buffer.fData; + break; + + case ttShort: + if (pplanes == 1) + imgdata.rawdata.raw_image = (ushort *)buffer.fData; + else if (pplanes == 3) + imgdata.rawdata.color3_image = (ushort(*)[3])buffer.fData; + else if (pplanes == 4) + imgdata.rawdata.color4_image = (ushort(*)[4])buffer.fData; + break; + default: + /* do nothing */ + break; + } + } + else + { + switch (ptype) + { + case ttFloat: + if (pplanes == 1) + imgdata.rawdata.float_image = (float *)imgdata.rawdata.raw_alloc; + else if (pplanes == 3) + imgdata.rawdata.float3_image = (float(*)[3])imgdata.rawdata.raw_alloc; + else if (pplanes == 4) + imgdata.rawdata.float4_image = (float(*)[4])imgdata.rawdata.raw_alloc; + break; + + case ttByte: + case ttShort: + if (pplanes == 1) + imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; + else if (pplanes == 3) + imgdata.rawdata.color3_image = + (ushort(*)[3])imgdata.rawdata.raw_alloc; + else if (pplanes == 4) + imgdata.rawdata.color4_image = + (ushort(*)[4])imgdata.rawdata.raw_alloc; + break; + default: + /* do nothing */ + break; + } + } + + if ((ptype == ttFloat) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)) + { + convertFloatToInt(); + zerocopy = false; + } + + if (zerocopy) + { + dng_negative *stolen = negative.Release(); + dngnegative = stolen; + dng_simple_image *simage = stage2.Release(); + dngimage = simage; + } + } + catch (...) + { + return LIBRAW_UNSPECIFIED_ERROR; + } + + return (dngnegative || imgdata.rawdata.raw_alloc) ? LIBRAW_SUCCESS : LIBRAW_UNSPECIFIED_ERROR; +#else + return LIBRAW_UNSPECIFIED_ERROR; +#endif +} +void LibRaw::set_dng_host(void *p) +{ +#ifdef USE_DNGSDK + dnghost = p; +#endif +} diff --git a/src/integration/rawspeed_glue.cpp b/src/integration/rawspeed_glue.cpp new file mode 100644 index 000000000..42561e7b8 --- /dev/null +++ b/src/integration/rawspeed_glue.cpp @@ -0,0 +1,286 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#ifdef USE_RAWSPEED +using namespace RawSpeed; + +CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() +{ + ctxt = xmlNewParserCtxt(); + if (ctxt == NULL) + { + ThrowCME("CameraMetaData:Could not initialize context."); + } + + xmlResetLastError(); + doc = xmlCtxtReadMemory(ctxt, data, sz, "", NULL, XML_PARSE_DTDVALID); + + if (doc == NULL) + { + ThrowCME("CameraMetaData: XML Document could not be parsed successfully. " + "Error was: %s", + ctxt->lastError.message); + } + + if (ctxt->valid == 0) + { + if (ctxt->lastError.code == 0x5e) + { + // ignore this error code + } + else + { + ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", + ctxt->lastError.message); + } + } + + xmlNodePtr cur; + cur = xmlDocGetRootElement(doc); + if (xmlStrcmp(cur->name, (const xmlChar *)"Cameras")) + { + ThrowCME("CameraMetaData: XML document of the wrong type, root node is not " + "cameras."); + return; + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera"))) + { + Camera *camera = new Camera(doc, cur); + addCamera(camera); + + // Create cameras for aliases. + for (unsigned int i = 0; i < camera->aliases.size(); i++) + { + addCamera(new Camera(camera, i)); + } + } + cur = cur->next; + } + if (doc) + xmlFreeDoc(doc); + doc = 0; + if (ctxt) + xmlFreeParserCtxt(ctxt); + ctxt = 0; +} + +CameraMetaDataLR *make_camera_metadata() +{ + int len = 0, i; + for (i = 0; i < RAWSPEED_DATA_COUNT; i++) + if (_rawspeed_data_xml[i]) + { + len += int(strlen(_rawspeed_data_xml[i])); + } + char *rawspeed_xml = + (char *)calloc(len + 1, sizeof(_rawspeed_data_xml[0][0])); + if (!rawspeed_xml) + return NULL; + int offt = 0; + for (i = 0; i < RAWSPEED_DATA_COUNT; i++) + if (_rawspeed_data_xml[i]) + { + int ll = int(strlen(_rawspeed_data_xml[i])); + if (offt + ll > len) + break; + memmove(rawspeed_xml + offt, _rawspeed_data_xml[i], ll); + offt += ll; + } + rawspeed_xml[offt] = 0; + CameraMetaDataLR *ret = NULL; + try + { + ret = new CameraMetaDataLR(rawspeed_xml, offt); + } + catch (...) + { + // Mask all exceptions + } + free(rawspeed_xml); + return ret; +} + +#endif + +int LibRaw::set_rawspeed_camerafile(char * filename) +{ +#ifdef USE_RAWSPEED + try + { + CameraMetaDataLR *camerameta = new CameraMetaDataLR(filename); + if (_rawspeed_camerameta) + { + CameraMetaDataLR *d = + static_cast(_rawspeed_camerameta); + delete d; + } + _rawspeed_camerameta = static_cast(camerameta); + } + catch (...) + { + // just return error code + return -1; + } +#else + (void)filename; +#endif + return 0; +} +#ifdef USE_RAWSPEED +void LibRaw::fix_after_rawspeed(int /*bl*/) +{ + if (load_raw == &LibRaw::lossy_dng_load_raw) + C.maximum = 0xffff; + else if (load_raw == &LibRaw::sony_load_raw) + C.maximum = 0x3ff0; +} +#else +void LibRaw::fix_after_rawspeed(int) {} +#endif + +int LibRaw::try_rawspeed() +{ +#ifdef USE_RAWSPEED + int ret = LIBRAW_SUCCESS; + +#ifdef USE_RAWSPEED_BITS + int rawspeed_ignore_errors = (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_IGNOREERRORS); +#else + int rawspeed_ignore_errors = 0; +#endif + if (imgdata.idata.dng_version && imgdata.idata.colors == 3 && + !strcasecmp(imgdata.idata.software, + "Adobe Photoshop Lightroom 6.1.1 (Windows)")) + rawspeed_ignore_errors = 1; + + // RawSpeed Supported, + INT64 spos = ID.input->tell(); + void *_rawspeed_buffer = 0; + try + { + ID.input->seek(0, SEEK_SET); + INT64 _rawspeed_buffer_sz = ID.input->size() + 32; + _rawspeed_buffer = malloc(_rawspeed_buffer_sz); + if (!_rawspeed_buffer) + throw LIBRAW_EXCEPTION_ALLOC; + ID.input->read(_rawspeed_buffer, _rawspeed_buffer_sz, 1); + FileMap map((uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz); + RawParser t(&map); + RawDecoder *d = 0; + CameraMetaDataLR *meta = + static_cast(_rawspeed_camerameta); + d = t.getDecoder(); + if (!d) + throw "Unable to find decoder"; + +#ifdef USE_RAWSPEED_BITS + if (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_FAILONUNKNOWN) + d->failOnUnknown = TRUE; + else + d->failOnUnknown = FALSE; +#endif + d->interpolateBadPixels = FALSE; + d->applyStage1DngOpcodes = FALSE; + + try + { + d->checkSupport(meta); + } + catch (const RawDecoderException &e) + { + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; + throw e; + } + _rawspeed_decoder = static_cast(d); + d->decodeRaw(); + d->decodeMetaData(meta); + RawImage r = d->mRaw; + if (r->errors.size() > 0 && !rawspeed_ignore_errors) + { + delete d; + _rawspeed_decoder = 0; + throw 1; + } + if (r->isCFA) + { + imgdata.rawdata.raw_image = (ushort *)r->getDataUncropped(0, 0); + } + else if (r->getCpp() == 4) + { + imgdata.rawdata.color4_image = (ushort(*)[4])r->getDataUncropped(0, 0); + if (r->whitePoint > 0 && r->whitePoint < 65536) + C.maximum = r->whitePoint; + } + else if (r->getCpp() == 3) + { + imgdata.rawdata.color3_image = (ushort(*)[3])r->getDataUncropped(0, 0); + if (r->whitePoint > 0 && r->whitePoint < 65536) + C.maximum = r->whitePoint; + } + else + { + delete d; + _rawspeed_decoder = 0; + ret = LIBRAW_UNSPECIFIED_ERROR; + } + if (_rawspeed_decoder) + { + // set sizes + iPoint2D rsdim = r->getUncroppedDim(); + S.raw_pitch = r->pitch; + S.raw_width = rsdim.x; + S.raw_height = rsdim.y; + // C.maximum = r->whitePoint; + fix_after_rawspeed(r->blackLevel); + } + free(_rawspeed_buffer); + _rawspeed_buffer = 0; + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED; + } + catch (const RawDecoderException &RDE) + { + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM; + if (_rawspeed_buffer) + { + free(_rawspeed_buffer); + _rawspeed_buffer = 0; + } + if (!strncmp(RDE.what(), "Decoder canceled", strlen("Decoder canceled"))) + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; + ret = LIBRAW_UNSPECIFIED_ERROR; + } + catch (...) + { + // We may get here due to cancellation flag + imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM; + if (_rawspeed_buffer) + { + free(_rawspeed_buffer); + _rawspeed_buffer = 0; + } + ret = LIBRAW_UNSPECIFIED_ERROR; + } + ID.input->seek(spos, SEEK_SET); + + return ret; +#else + return LIBRAW_NOT_IMPLEMENTED; +#endif +} diff --git a/src/libraw_c_api.cpp b/src/libraw_c_api.cpp new file mode 100644 index 000000000..4e85ec293 --- /dev/null +++ b/src/libraw_c_api.cpp @@ -0,0 +1,457 @@ +/* -*- C++ -*- + * File: libraw_c_api.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Created: Sat Mar 8 , 2008 + * + * LibRaw C interface + + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include +#include +#include "libraw/libraw.h" + +#ifdef __cplusplus +#include +extern "C" +{ +#endif + + libraw_data_t *libraw_init(unsigned int flags) + { + LibRaw *ret; + try + { + ret = new LibRaw(flags); + } + catch (const std::bad_alloc& ) + { + return NULL; + } + return &(ret->imgdata); + } + + unsigned libraw_capabilities() { return LibRaw::capabilities(); } + const char *libraw_version() { return LibRaw::version(); } + const char *libraw_strprogress(enum LibRaw_progress p) + { + return LibRaw::strprogress(p); + } + int libraw_versionNumber() { return LibRaw::versionNumber(); } + const char **libraw_cameraList() { return LibRaw::cameraList(); } + int libraw_cameraCount() { return LibRaw::cameraCount(); } + const char *libraw_unpack_function_name(libraw_data_t *lr) + { + if (!lr) + return "NULL parameter passed"; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->unpack_function_name(); + } + + void libraw_subtract_black(libraw_data_t *lr) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->subtract_black(); + } + + int libraw_open_file(libraw_data_t *lr, const char *file) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_file(file); + } + + libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr) + { + if (!lr) + return NULL; + return &(lr->idata); + } + + libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr) + { + if (!lr) + return NULL; + return &(lr->lens); + } + + libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr) + { + if (!lr) + return NULL; + return &(lr->other); + } + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + int libraw_open_file_ex(libraw_data_t *lr, const char *file, INT64 sz) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_file(file, sz); + } +#endif + +#ifdef LIBRAW_WIN32_UNICODEPATHS + int libraw_open_wfile(libraw_data_t *lr, const wchar_t *file) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_file(file); + } + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM + int libraw_open_wfile_ex(libraw_data_t *lr, const wchar_t *file, INT64 sz) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_file(file, sz); + } +#endif +#endif + int libraw_open_buffer(libraw_data_t *lr, const void *buffer, size_t size) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_buffer(buffer, size); + } + int libraw_open_bayer(libraw_data_t *lr, unsigned char *data, + unsigned datalen, ushort _raw_width, ushort _raw_height, + ushort _left_margin, ushort _top_margin, + ushort _right_margin, ushort _bottom_margin, + unsigned char procflags, unsigned char bayer_pattern, + unsigned unused_bits, unsigned otherflags, + unsigned black_level) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->open_bayer(data, datalen, _raw_width, _raw_height, _left_margin, + _top_margin, _right_margin, _bottom_margin, procflags, + bayer_pattern, unused_bits, otherflags, black_level); + } + int libraw_unpack(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->unpack(); + } + int libraw_unpack_thumb(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->unpack_thumb(); + } + int libraw_unpack_thumb_ex(libraw_data_t *lr, int i) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->unpack_thumb_ex(i); + } + void libraw_recycle_datastream(libraw_data_t *lr) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->recycle_datastream(); + } + void libraw_recycle(libraw_data_t *lr) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->recycle(); + } + void libraw_close(libraw_data_t *lr) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + delete ip; + } + + void libraw_set_exifparser_handler(libraw_data_t *lr, exif_parser_callback cb, + void *data) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->set_exifparser_handler(cb, data); + } + + void libraw_set_dataerror_handler(libraw_data_t *lr, data_callback func, + void *data) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->set_dataerror_handler(func, data); + } + void libraw_set_progress_handler(libraw_data_t *lr, progress_callback cb, + void *data) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->set_progress_handler(cb, data); + } + + // DCRAW + int libraw_adjust_sizes_info_only(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->adjust_sizes_info_only(); + } + int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->dcraw_ppm_tiff_writer(filename); + } + int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->dcraw_thumb_writer(fname); + } + int libraw_dcraw_process(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->dcraw_process(); + } + libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t *lr, + int *errc) + { + if (!lr) + { + if (errc) + *errc = EINVAL; + return NULL; + } + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->dcraw_make_mem_image(errc); + } + libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t *lr, + int *errc) + { + if (!lr) + { + if (errc) + *errc = EINVAL; + return NULL; + } + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->dcraw_make_mem_thumb(errc); + } + + void libraw_dcraw_clear_mem(libraw_processed_image_t *p) + { + LibRaw::dcraw_clear_mem(p); + } + + int libraw_raw2image(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->raw2image(); + } + void libraw_free_image(libraw_data_t *lr) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->free_image(); + } + int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d) + { + if (!lr || !d) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->get_decoder_info(d); + } + int libraw_COLOR(libraw_data_t *lr, int row, int col) + { + if (!lr) + return EINVAL; + LibRaw *ip = (LibRaw *)lr->parent_class; + return ip->COLOR(row, col); + } + + /* getters/setters used by 3DLut Creator */ + DllDef void libraw_set_demosaic(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.user_qual = value; + } + + DllDef void libraw_set_output_color(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.output_color = value; + } + + DllDef void libraw_set_adjust_maximum_thr(libraw_data_t *lr, float value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.adjust_maximum_thr = value; + } + + DllDef void libraw_set_output_bps(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.output_bps = value; + } + + DllDef void libraw_set_output_tif(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.output_tiff = value; + } + +#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)) + + DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.user_mul[LIM(index, 0, 3)] = val; + } + + DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.gamm[LIM(index, 0, 5)] = value; + } + + DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.no_auto_bright = value; + } + + DllDef void libraw_set_bright(libraw_data_t *lr, float value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.bright = value; + } + + DllDef void libraw_set_highlight(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.highlight = value; + } + + DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value) + { + if (!lr) + return; + LibRaw *ip = (LibRaw *)lr->parent_class; + ip->imgdata.params.fbdd_noiserd = value; + } + + DllDef int libraw_get_raw_height(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + return lr->sizes.raw_height; + } + + DllDef int libraw_get_raw_width(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + return lr->sizes.raw_width; + } + + DllDef int libraw_get_iheight(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + return lr->sizes.iheight; + } + + DllDef int libraw_get_iwidth(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + return lr->sizes.iwidth; + } + + DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index) + { + if (!lr) + return EINVAL; + return lr->color.cam_mul[LIM(index, 0, 3)]; + } + + DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index) + { + if (!lr) + return EINVAL; + return lr->color.pre_mul[LIM(index, 0, 3)]; + } + + DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2) + { + if (!lr) + return EINVAL; + return lr->color.rgb_cam[LIM(index1, 0, 2)][LIM(index2, 0, 3)]; + } + + DllDef int libraw_get_color_maximum(libraw_data_t *lr) + { + if (!lr) + return EINVAL; + return lr->color.maximum; + } + +#ifdef __cplusplus +} +#endif diff --git a/src/libraw_datastream.cpp b/src/libraw_datastream.cpp new file mode 100644 index 000000000..898761de7 --- /dev/null +++ b/src/libraw_datastream.cpp @@ -0,0 +1,1046 @@ +/* -*- C++ -*- + * File: libraw_datastream.cpp + * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * + * LibRaw C++ interface (implementation) + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + +*/ + +#ifdef _WIN32 +#ifdef __MINGW32__ +#define _WIN32_WINNT 0x0500 +#include +#endif +#endif + +#define LIBRAW_LIBRARY_BUILD +#include "libraw/libraw.h" +#include "libraw/libraw_types.h" +#include "libraw/libraw_datastream.h" +#include +#ifdef USE_JASPER +#include /* Decode RED camera movies */ +#else +#define NO_JASPER +#endif +#ifdef USE_JPEG +#include +#include +#else +#define NO_JPEG +#endif + +#ifdef USE_JPEG + +typedef struct +{ + struct jpeg_source_mgr pub; /* public fields */ + LibRaw_abstract_datastream *instream; /* source stream */ + JOCTET *buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} lr_jpg_source_mgr; + +typedef lr_jpg_source_mgr *lr_jpg_src_ptr; + +#define LR_JPEG_INPUT_BUF_SIZE 16384 + +static void f_init_source(j_decompress_ptr cinfo) +{ + lr_jpg_src_ptr src = (lr_jpg_src_ptr)cinfo->src; + src->start_of_file = TRUE; +} + +#ifdef ERREXIT +#undef ERREXIT +#endif + +#define ERREXIT(cinfo, code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit)((j_common_ptr)(cinfo))) + +static boolean lr_fill_input_buffer(j_decompress_ptr cinfo) +{ + lr_jpg_src_ptr src = (lr_jpg_src_ptr)cinfo->src; + size_t nbytes; + + nbytes = src->instream->read((void*)src->buffer, 1, LR_JPEG_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; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + return TRUE; +} + +static void lr_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + struct jpeg_source_mgr *src = cinfo->src; + if (num_bytes > 0) + { + while (num_bytes > (long)src->bytes_in_buffer) + { + num_bytes -= (long)src->bytes_in_buffer; + (void)(*src->fill_input_buffer)(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->next_input_byte += (size_t)num_bytes; + src->bytes_in_buffer -= (size_t)num_bytes; + } +} + +static void lr_term_source(j_decompress_ptr /*cinfo*/) {} + +static void lr_jpeg_src(j_decompress_ptr cinfo, LibRaw_abstract_datastream *inf) +{ + lr_jpg_src_ptr src; + 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(lr_jpg_source_mgr)); + src = (lr_jpg_src_ptr)cinfo->src; + src->buffer = (JOCTET *)(*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_PERMANENT, + LR_JPEG_INPUT_BUF_SIZE * sizeof(JOCTET)); + } + else if (cinfo->src->init_source != f_init_source) + { + ERREXIT(cinfo, JERR_BUFFER_SIZE); + } + + src = (lr_jpg_src_ptr)cinfo->src; + src->pub.init_source = f_init_source; + src->pub.fill_input_buffer = lr_fill_input_buffer; + src->pub.skip_input_data = lr_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = lr_term_source; + src->instream = inf; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} +#endif + +int LibRaw_abstract_datastream::jpeg_src(void *jpegdata) +{ +#ifdef NO_JPEG + return -1; +#else + j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata; + buffering_off(); + lr_jpeg_src(cinfo, this); + return 0; // OK +#endif +} + + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM +// == LibRaw_file_datastream == + +LibRaw_file_datastream::~LibRaw_file_datastream() +{ + if (jas_file) + fclose(jas_file); +} + +LibRaw_file_datastream::LibRaw_file_datastream(const char *fname) + : filename(fname), _fsize(0) +#ifdef LIBRAW_WIN32_UNICODEPATHS + , + wfilename() +#endif + , + jas_file(NULL) +{ + if (filename.size() > 0) + { +#ifndef LIBRAW_WIN32_CALLS + struct stat st; + if (!stat(filename.c_str(), &st)) + _fsize = st.st_size; +#else + struct _stati64 st; + if (!_stati64(filename.c_str(), &st)) + _fsize = st.st_size; +#endif +#ifdef LIBRAW_USE_AUTOPTR + std::auto_ptr buf(new std::filebuf()); +#else + std::unique_ptr buf(new std::filebuf()); +#endif + buf->open(filename.c_str(), std::ios_base::in | std::ios_base::binary); + if (buf->is_open()) + { +#ifdef LIBRAW_USE_AUTOPTR + f = buf; +#else + f = std::move(buf); +#endif + } + } +} +#ifdef LIBRAW_WIN32_UNICODEPATHS +LibRaw_file_datastream::LibRaw_file_datastream(const wchar_t *fname) + : filename(), wfilename(fname), jas_file(NULL), _fsize(0) +{ + if (wfilename.size() > 0) + { + struct _stati64 st; + if (!_wstati64(wfilename.c_str(), &st)) + _fsize = st.st_size; +#ifdef LIBRAW_USE_AUTOPTR + std::auto_ptr buf(new std::filebuf()); +#else + std::unique_ptr buf(new std::filebuf()); +#endif + buf->open(wfilename.c_str(), std::ios_base::in | std::ios_base::binary); + if (buf->is_open()) + { +#ifdef LIBRAW_USE_AUTOPTR + f = buf; +#else + f = std::move(buf); +#endif + } + } +} +const wchar_t *LibRaw_file_datastream::wfname() +{ + return wfilename.size() > 0 ? wfilename.c_str() : NULL; +} +#endif + +int LibRaw_file_datastream::valid() { return f.get() ? 1 : 0; } + +#define LR_STREAM_CHK() \ + do \ + { \ + if (!f.get()) \ + throw LIBRAW_EXCEPTION_IO_EOF; \ + } while (0) + +int LibRaw_file_datastream::read(void *ptr, size_t size, size_t nmemb) +{ +/* Visual Studio 2008 marks sgetn as insecure, but VS2010 does not. */ +#if defined(WIN32SECURECALLS) && (_MSC_VER < 1600) + LR_STREAM_CHK(); + return int(f->_Sgetn_s(static_cast(ptr), nmemb * size, nmemb * size) / + (size > 0 ? size : 1)); +#else + LR_STREAM_CHK(); + return int(f->sgetn(static_cast(ptr), std::streamsize(nmemb * size)) / + (size > 0 ? size : 1)); +#endif +} + +int LibRaw_file_datastream::eof() +{ + LR_STREAM_CHK(); + return f->sgetc() == EOF; +} + +int LibRaw_file_datastream::seek(INT64 o, int whence) +{ + LR_STREAM_CHK(); + std::ios_base::seekdir dir; + switch (whence) + { + case SEEK_SET: + dir = std::ios_base::beg; + break; + case SEEK_CUR: + dir = std::ios_base::cur; + break; + case SEEK_END: + dir = std::ios_base::end; + break; + default: + dir = std::ios_base::beg; + } + return f->pubseekoff((long)o, dir) < 0; +} + +INT64 LibRaw_file_datastream::tell() +{ + LR_STREAM_CHK(); + return f->pubseekoff(0, std::ios_base::cur); +} + +char *LibRaw_file_datastream::gets(char *str, int sz) +{ + if(sz<1) return NULL; + LR_STREAM_CHK(); + std::istream is(f.get()); + is.getline(str, sz); + if (is.fail()) + return 0; + return str; +} + +int LibRaw_file_datastream::scanf_one(const char *fmt, void *val) +{ + LR_STREAM_CHK(); + + std::istream is(f.get()); + + /* HUGE ASSUMPTION: *fmt is either "%d" or "%f" */ + if (strcmp(fmt, "%d") == 0) + { + int d; + is >> d; + if (is.fail()) + return EOF; + *(static_cast(val)) = d; + } + else + { + float f; + is >> f; + if (is.fail()) + return EOF; + *(static_cast(val)) = f; + } + + return 1; +} + +const char *LibRaw_file_datastream::fname() +{ + return filename.size() > 0 ? filename.c_str() : NULL; +} + +#undef LR_STREAM_CHK + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void *LibRaw_file_datastream::make_jas_stream() +{ +#ifdef NO_JASPER + return NULL; +#else +#ifdef LIBRAW_WIN32_UNICODEPATHS + if (wfname()) + { + jas_file = _wfopen(wfname(), L"rb"); + return jas_stream_fdopen(fileno(jas_file), "rb"); + } + else +#endif + { + return jas_stream_fopen(fname(), "rb"); + } +#endif +} +#endif +#endif + +// == LibRaw_buffer_datastream +LibRaw_buffer_datastream::LibRaw_buffer_datastream(const void *buffer, size_t bsize) +{ + buf = (unsigned char *)buffer; + streampos = 0; + streamsize = bsize; +} + +LibRaw_buffer_datastream::~LibRaw_buffer_datastream() {} + +int LibRaw_buffer_datastream::read(void *ptr, size_t sz, size_t nmemb) +{ + size_t to_read = sz * nmemb; + if (to_read > streamsize - streampos) + to_read = streamsize - streampos; + if (to_read < 1) + return 0; + memmove(ptr, buf + streampos, to_read); + streampos += to_read; + return int((to_read + sz - 1) / (sz > 0 ? sz : 1)); +} + +int LibRaw_buffer_datastream::seek(INT64 o, int whence) +{ + switch (whence) + { + case SEEK_SET: + if (o < 0) + streampos = 0; + else if (size_t(o) > streamsize) + streampos = streamsize; + else + streampos = size_t(o); + return 0; + case SEEK_CUR: + if (o < 0) + { + if (size_t(-o) >= streampos) + streampos = 0; + else + streampos += (size_t)o; + } + else if (o > 0) + { + if (o + streampos > streamsize) + streampos = streamsize; + else + streampos += (size_t)o; + } + return 0; + case SEEK_END: + if (o > 0) + streampos = streamsize; + else if (size_t(-o) > streamsize) + streampos = 0; + else + streampos = streamsize + (size_t)o; + return 0; + default: + return 0; + } +} + +INT64 LibRaw_buffer_datastream::tell() +{ + return INT64(streampos); +} + +char *LibRaw_buffer_datastream::gets(char *s, int sz) +{ + if(sz<1) return NULL; + unsigned char *psrc, *pdest, *str; + str = (unsigned char *)s; + psrc = buf + streampos; + pdest = str; + if(streampos >= streamsize) return NULL; + while ((size_t(psrc - buf) < streamsize) && ((pdest - str) < (sz-1))) + { + *pdest = *psrc; + if (*psrc == '\n') + break; + psrc++; + pdest++; + } + if (size_t(psrc - buf) < streamsize) + psrc++; + if ((pdest - str) < sz-1) + *(++pdest) = 0; + else + s[sz - 1] = 0; // ensure trailing zero + + streampos = psrc - buf; + return s; +} + +int LibRaw_buffer_datastream::scanf_one(const char *fmt, void *val) +{ + int scanf_res; + if (streampos > streamsize) + return 0; +#ifndef WIN32SECURECALLS + scanf_res = sscanf((char *)(buf + streampos), fmt, val); +#else + scanf_res = sscanf_s((char *)(buf + streampos), fmt, val); +#endif + if (scanf_res > 0) + { + int xcnt = 0; + while (streampos < streamsize) + { + streampos++; + xcnt++; + if (buf[streampos] == 0 || buf[streampos] == ' ' || + buf[streampos] == '\t' || buf[streampos] == '\n' || xcnt > 24) + break; + } + } + return scanf_res; +} + +int LibRaw_buffer_datastream::eof() +{ + return streampos >= streamsize; +} +int LibRaw_buffer_datastream::valid() { return buf ? 1 : 0; } + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void *LibRaw_buffer_datastream::make_jas_stream() +{ +#ifdef NO_JASPER + return NULL; +#else + return jas_stream_memopen((char *)buf + streampos, streamsize - streampos); +#endif +} +#endif + +int LibRaw_buffer_datastream::jpeg_src(void *jpegdata) +{ +#if defined(NO_JPEG) || !defined(USE_JPEG) + return -1; +#else + j_decompress_ptr cinfo = (j_decompress_ptr)jpegdata; + jpeg_mem_src(cinfo, (unsigned char *)buf + streampos,(unsigned long)(streamsize - streampos)); + return 0; +#endif +} + +// int LibRaw_buffer_datastream + +// == LibRaw_bigfile_datastream +LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const char *fname) + : filename(fname) +#ifdef LIBRAW_WIN32_UNICODEPATHS + , + wfilename() +#endif +{ + if (filename.size() > 0) + { +#ifndef LIBRAW_WIN32_CALLS + struct stat st; + if (!stat(filename.c_str(), &st)) + _fsize = st.st_size; +#else + struct _stati64 st; + if (!_stati64(filename.c_str(), &st)) + _fsize = st.st_size; +#endif + +#ifndef WIN32SECURECALLS + f = fopen(fname, "rb"); +#else + if (fopen_s(&f, fname, "rb")) + f = 0; +#endif + } + else + { + filename = std::string(); + f = 0; + } +} + +#ifdef LIBRAW_WIN32_UNICODEPATHS +LibRaw_bigfile_datastream::LibRaw_bigfile_datastream(const wchar_t *fname) + : filename(), wfilename(fname) +{ + if (wfilename.size() > 0) + { + struct _stati64 st; + if (!_wstati64(wfilename.c_str(), &st)) + _fsize = st.st_size; +#ifndef WIN32SECURECALLS + f = _wfopen(wfilename.c_str(), L"rb"); +#else + if (_wfopen_s(&f, fname, L"rb")) + f = 0; +#endif + } + else + { + wfilename = std::wstring(); + f = 0; + } +} +const wchar_t *LibRaw_bigfile_datastream::wfname() +{ + return wfilename.size() > 0 ? wfilename.c_str() : NULL; +} +#endif + +LibRaw_bigfile_datastream::~LibRaw_bigfile_datastream() +{ + if (f) + fclose(f); +} +int LibRaw_bigfile_datastream::valid() { return f ? 1 : 0; } + +#define LR_BF_CHK() \ + do \ + { \ + if (!f) \ + throw LIBRAW_EXCEPTION_IO_EOF; \ + } while (0) + +int LibRaw_bigfile_datastream::read(void *ptr, size_t size, size_t nmemb) +{ + LR_BF_CHK(); + return int(fread(ptr, size, nmemb, f)); +} + +int LibRaw_bigfile_datastream::eof() +{ + LR_BF_CHK(); + return feof(f); +} + +int LibRaw_bigfile_datastream::seek(INT64 o, int whence) +{ + LR_BF_CHK(); +#if defined(_WIN32) +#ifdef WIN32SECURECALLS + return _fseeki64(f, o, whence); +#else + return fseek(f, (long)o, whence); +#endif +#else + return fseeko(f, o, whence); +#endif +} + +INT64 LibRaw_bigfile_datastream::tell() +{ + LR_BF_CHK(); +#if defined(_WIN32) +#ifdef WIN32SECURECALLS + return _ftelli64(f); +#else + return ftell(f); +#endif +#else + return ftello(f); +#endif +} + +char *LibRaw_bigfile_datastream::gets(char *str, int sz) +{ + if(sz<1) return NULL; + LR_BF_CHK(); + return fgets(str, sz, f); +} + +int LibRaw_bigfile_datastream::scanf_one(const char *fmt, void *val) +{ + LR_BF_CHK(); + return +#ifndef WIN32SECURECALLS + fscanf(f, fmt, val) +#else + fscanf_s(f, fmt, val) +#endif + ; +} + +const char *LibRaw_bigfile_datastream::fname() +{ + return filename.size() > 0 ? filename.c_str() : NULL; +} + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void *LibRaw_bigfile_datastream::make_jas_stream() +{ +#ifdef NO_JASPER + return NULL; +#else + return jas_stream_fdopen(fileno(f), "rb"); +#endif +} +#endif + +// == LibRaw_windows_datastream +#ifdef LIBRAW_WIN32_CALLS + +LibRaw_windows_datastream::LibRaw_windows_datastream(const TCHAR *sFile) + : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL) +{ +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) + HANDLE hFile = CreateFile2(sFile, GENERIC_READ, 0, OPEN_EXISTING, 0); +#else + HANDLE hFile = CreateFile(sFile, GENERIC_READ, 0, 0, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); +#endif + if (hFile == INVALID_HANDLE_VALUE) + throw std::runtime_error("failed to open the file"); + + try + { + Open(hFile); + } + catch (...) + { + CloseHandle(hFile); + throw; + } + + CloseHandle(hFile); // windows will defer the actual closing of this handle + // until the hMap_ is closed + reconstruct_base(); +} + +// ctor: construct with a file handle - caller is responsible for closing the +// file handle +LibRaw_windows_datastream::LibRaw_windows_datastream(HANDLE hFile) + : LibRaw_buffer_datastream(NULL, 0), hMap_(0), pView_(NULL) +{ + Open(hFile); + reconstruct_base(); +} + +// dtor: unmap and close the mapping handle +LibRaw_windows_datastream::~LibRaw_windows_datastream() +{ + if (pView_ != NULL) + ::UnmapViewOfFile(pView_); + + if (hMap_ != 0) + ::CloseHandle(hMap_); +} + +void LibRaw_windows_datastream::Open(HANDLE hFile) +{ + // create a file mapping handle on the file handle + hMap_ = ::CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0); + if (hMap_ == NULL) + throw std::runtime_error("failed to create file mapping"); + + // now map the whole file base view + if (!::GetFileSizeEx(hFile, (PLARGE_INTEGER)&cbView_)) + throw std::runtime_error("failed to get the file size"); + + pView_ = ::MapViewOfFile(hMap_, FILE_MAP_READ, 0, 0, (size_t)cbView_); + if (pView_ == NULL) + throw std::runtime_error("failed to map the file"); +} + +#endif + +#if defined (LIBRAW_NO_IOSTREAMS_DATASTREAM) && defined (LIBRAW_WIN32_CALLS) + +/* LibRaw_bigfile_buffered_datastream: copypasted from LibRaw_bigfile_datastream + extra cache on read */ + +#undef LR_BF_CHK +#define LR_BF_CHK() \ + do \ + { \ + if (fhandle ==0 || fhandle == INVALID_HANDLE_VALUE) \ + throw LIBRAW_EXCEPTION_IO_EOF; \ + } while (0) + +#define LIBRAW_BUFFER_ALIGN 4096 + +int LibRaw_bufio_params::bufsize = 16384; + +void LibRaw_bufio_params::set_bufsize(int bs) +{ + if (bs > 0) + bufsize = bs; +} + + +LibRaw_bigfile_buffered_datastream::LibRaw_bigfile_buffered_datastream(const char *fname) + : filename(fname), _fsize(0), _fpos(0) +#ifdef LIBRAW_WIN32_UNICODEPATHS + , wfilename() +#endif + , iobuffers(), buffered(1) +{ + if (filename.size() > 0) + { + std::string fn(fname); + std::wstring fpath(fn.begin(), fn.end()); +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) + if ((fhandle = CreateFile2(fpath.c_str(), GENERIC_READ, 0, OPEN_EXISTING, 0)) != INVALID_HANDLE_VALUE) +#else + if ((fhandle = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) +#endif + { + LARGE_INTEGER fs; + if (GetFileSizeEx(fhandle, &fs)) + _fsize = fs.QuadPart; + } + } + else + { + filename = std::string(); + fhandle = INVALID_HANDLE_VALUE; + } +} + +#ifdef LIBRAW_WIN32_UNICODEPATHS +LibRaw_bigfile_buffered_datastream::LibRaw_bigfile_buffered_datastream(const wchar_t *fname) + : filename(), _fsize(0), _fpos(0), + wfilename(fname), iobuffers(), buffered(1) +{ + if (wfilename.size() > 0) + { +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) + if ((fhandle = CreateFile2(wfilename.c_str(), GENERIC_READ, 0, OPEN_EXISTING, 0)) != INVALID_HANDLE_VALUE) +#else + if ((fhandle = CreateFileW(wfilename.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) +#endif + { + LARGE_INTEGER fs; + if (GetFileSizeEx(fhandle, &fs)) + _fsize = fs.QuadPart; + } + + } + else + { + wfilename = std::wstring(); + fhandle = INVALID_HANDLE_VALUE; + } +} + +const wchar_t *LibRaw_bigfile_buffered_datastream::wfname() +{ + return wfilename.size() > 0 ? wfilename.c_str() : NULL; +} +#endif + +LibRaw_bigfile_buffered_datastream::~LibRaw_bigfile_buffered_datastream() +{ + if (valid()) + CloseHandle(fhandle); +} +int LibRaw_bigfile_buffered_datastream::valid() { + return (fhandle != NULL) && (fhandle != INVALID_HANDLE_VALUE); +} + +const char *LibRaw_bigfile_buffered_datastream::fname() +{ + return filename.size() > 0 ? filename.c_str() : NULL; +} + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void *LibRaw_bigfile_buffered_datastream::make_jas_stream() +{ +#ifdef NO_JASPER + return NULL; +#else + return NULL; +#endif +} +#endif + +INT64 LibRaw_bigfile_buffered_datastream::readAt(void *ptr, size_t size, INT64 off) +{ + LR_BF_CHK(); + DWORD NumberOfBytesRead; + DWORD nNumberOfBytesToRead = (DWORD)size; + struct _OVERLAPPED olap; + memset(&olap, 0, sizeof(olap)); + olap.Offset = off & 0xffffffff; + olap.OffsetHigh = off >> 32; + if (ReadFile(fhandle, ptr, nNumberOfBytesToRead, &NumberOfBytesRead, &olap)) + return NumberOfBytesRead; + else + return 0; +} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#ifdef _MSC_VER +#pragma intrinsic(memcpy) +#endif + +int LibRaw_bigfile_buffered_datastream::read(void *data, size_t size, size_t nmemb) +{ + if (size < 1 || nmemb < 1) + return 0; + LR_BF_CHK(); + INT64 count = size * nmemb; + INT64 partbytes = 0; + if (!buffered) + { + INT64 r = readAt(data, count, _fpos); + _fpos += r; + return int(r / size); + } + + unsigned char *fBuffer = (unsigned char*)iobuffers[0].data(); + while (count) + { + INT64 inbuffer = 0; + // See if the request is totally inside buffer. + if (iobuffers[0].contains(_fpos, inbuffer)) + { + if (inbuffer >= count) + { + memcpy(data, fBuffer + (unsigned)(_fpos - iobuffers[0]._bstart), count); + _fpos += count; + return int((count + partbytes) / size); + } + memcpy(data, fBuffer + (_fpos - iobuffers[0]._bstart), inbuffer); + partbytes += inbuffer; + count -= inbuffer; + data = (void *)(((char *)data) + inbuffer); + _fpos += inbuffer; + } + if (count > (INT64) iobuffers[0].size()) + { + fallback: + if (_fpos + count > _fsize) + count = MAX(0, _fsize - _fpos); + if (count > 0) + { + INT64 r = readAt(data, count, _fpos); + _fpos += r; + return int((r + partbytes) / size); + } + else + return 0; + } + + if (!fillBufferAt(0, _fpos)) + goto fallback; + } + return 0; +} + +bool LibRaw_bigfile_buffered_datastream::fillBufferAt(int bi, INT64 off) +{ + if (off < 0LL) return false; + iobuffers[bi]._bstart = off; + if (iobuffers[bi].size() >= LIBRAW_BUFFER_ALIGN * 2)// Align to a file block. + iobuffers[bi]._bstart &= (INT64)~((INT64)(LIBRAW_BUFFER_ALIGN - 1)); + + iobuffers[bi]._bend = MIN(iobuffers[bi]._bstart + (INT64)iobuffers[bi].size(), _fsize); + if (iobuffers[bi]._bend <= off) // Buffer alignment problem, fallback + return false; + INT64 rr = readAt(iobuffers[bi].data(), (uint32_t)(iobuffers[bi]._bend - iobuffers[bi]._bstart), iobuffers[bi]._bstart); + if (rr > 0) + { + iobuffers[bi]._bend = iobuffers[bi]._bstart + rr; + return true; + } + return false; +} + + +int LibRaw_bigfile_buffered_datastream::eof() +{ + LR_BF_CHK(); + return _fpos >= _fsize; +} + +int LibRaw_bigfile_buffered_datastream::seek(INT64 o, int whence) +{ + LR_BF_CHK(); + if (whence == SEEK_SET) _fpos = o; + else if (whence == SEEK_END) _fpos = o > 0 ? _fsize : _fsize + o; + else if (whence == SEEK_CUR) _fpos += o; + return 0; +} + +INT64 LibRaw_bigfile_buffered_datastream::tell() +{ + LR_BF_CHK(); + return _fpos; +} + +char *LibRaw_bigfile_buffered_datastream::gets(char *s, int sz) +{ + if (sz < 1) + return NULL; + else if (sz < 2) + { + s[0] = 0; + return s; + } + + LR_BF_CHK(); + INT64 contains; + int bufindex = selectStringBuffer(sz, contains); + if (bufindex < 0) return NULL; + if (contains >= sz) + { + unsigned char *buf = iobuffers[bufindex].data() + (_fpos - iobuffers[bufindex]._bstart); + int streampos = 0; + int streamsize = contains; + unsigned char *str = (unsigned char *)s; + unsigned char *psrc, *pdest; + psrc = buf + streampos; + pdest = str; + + while ((size_t(psrc - buf) < streamsize) && ((pdest - str) < sz-1)) // sz-1: to append \0 + { + *pdest = *psrc; + if (*psrc == '\n') + break; + psrc++; + pdest++; + } + if (size_t(psrc - buf) < streamsize) + psrc++; + if ((pdest - str) < sz - 1) + *(++pdest) = 0; + else + s[sz - 1] = 0; // ensure trailing zero + streampos = psrc - buf; + _fpos += streampos; + return s; + } + return NULL; +} + +int LibRaw_bigfile_buffered_datastream::selectStringBuffer(INT64 len, INT64& contains) +{ + if (iobuffers[0].contains(_fpos, contains) && contains >= len) + return 0; + + if (iobuffers[1].contains(_fpos, contains) && contains >= len) + return 1; + + fillBufferAt(1, _fpos); + if (iobuffers[1].contains(_fpos, contains) && contains >= len) + return 1; + return -1; +} + +int LibRaw_bigfile_buffered_datastream::scanf_one(const char *fmt, void *val) +{ + LR_BF_CHK(); + INT64 contains = 0; + int bufindex = selectStringBuffer(24, contains); + if (bufindex < 0) return -1; + if (contains >= 24) + { + unsigned char *bstart = iobuffers[bufindex].data() + (_fpos - iobuffers[bufindex]._bstart); + int streampos = 0; + int streamsize = contains; + int +#ifndef WIN32SECURECALLS + scanf_res = sscanf((char *)(bstart), fmt, val); +#else + scanf_res = sscanf_s((char *)(bstart), fmt, val); +#endif + if (scanf_res > 0) + { + int xcnt = 0; + while (streampos < streamsize) + { + streampos++; + xcnt++; + if (bstart[streampos] == 0 || bstart[streampos] == ' ' || + bstart[streampos] == '\t' || bstart[streampos] == '\n' || xcnt > 24) + break; + } + _fpos += streampos; + return scanf_res; + } + } + return -1; +} + +#endif + diff --git a/src/metadata/adobepano.cpp b/src/metadata/adobepano.cpp new file mode 100644 index 000000000..689c24a4e --- /dev/null +++ b/src/metadata/adobepano.cpp @@ -0,0 +1,154 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parseAdobePanoMakernote() +{ + uchar *PrivateMknBuf; + unsigned posPrivateMknBuf; + unsigned PrivateMknLength; + unsigned PrivateOrder; + unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount; + unsigned PrivateTagBytes; + int truncated; + +#define CHECKSPACE(s) \ + if (posPrivateMknBuf + (s) > PrivateMknLength) \ + { \ + free(PrivateMknBuf); \ + return; \ + } + + order = 0x4d4d; + truncated = 0; + PrivateMknLength = get4(); + + if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) && + (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024))) + { // 1024b for safety + fread(PrivateMknBuf, PrivateMknLength, 1, ifp); + PrivateOrder = sget2(PrivateMknBuf); + PrivateEntries = sget2(PrivateMknBuf + 2); + if ((PrivateEntries > 1000) || + ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) + { + free(PrivateMknBuf); + return; + } + posPrivateMknBuf = 4; + while (PrivateEntries--) + { + order = 0x4d4d; + CHECKSPACE(8); + PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); + PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2); + PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4); + posPrivateMknBuf += 8; + order = PrivateOrder; + + if (truncated && !PrivateTagCount) + continue; + + PrivateTagBytes = PrivateTagCount * + tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0]; + if(PrivateTagBytes > 10240000u) + { + free(PrivateMknBuf); + return; + } + if (PrivateTagID == 0x0002) + { + posPrivateMknBuf += 2; + CHECKSPACE(2); + if (sget2(PrivateMknBuf + posPrivateMknBuf)) + { + truncated = 1; + } + else + { + posPrivateMknBuf += 2; + } + } + else if (PrivateTagID == 0x0013) + { + ushort nWB, cnt, tWB; + CHECKSPACE(2); + nWB = sget2(PrivateMknBuf + posPrivateMknBuf); + posPrivateMknBuf += 2; + if (nWB > 0x100) + break; + for (cnt = 0; cnt < nWB; cnt++) + { + CHECKSPACE(2); + tWB = sget2(PrivateMknBuf + posPrivateMknBuf); + if (tWB < 0x100) + { + CHECKSPACE(4); + icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); + icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); + icWBC[tWB][1] = icWBC[tWB][3] = 0x100; + } + posPrivateMknBuf += 6; + } + } + else if (PrivateTagID == 0x0027) + { + ushort nWB, cnt, tWB; + CHECKSPACE(2); + nWB = sget2(PrivateMknBuf + posPrivateMknBuf); + posPrivateMknBuf += 2; + if (nWB > 0x100) + break; + for (cnt = 0; cnt < nWB; cnt++) + { + CHECKSPACE(2); + tWB = sget2(PrivateMknBuf + posPrivateMknBuf); + if (tWB < 0x100) + { + CHECKSPACE(6); + icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); + icWBC[tWB][1] = icWBC[tWB][3] = + sget2(PrivateMknBuf + posPrivateMknBuf + 4); + icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6); + } + posPrivateMknBuf += 8; + } + } + else if (PrivateTagID == 0x0121) + { + CHECKSPACE(4); + imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf); + posPrivateMknBuf += 4; + } + else + { + if (PrivateTagBytes > 4) + posPrivateMknBuf += PrivateTagBytes; + else if (!truncated) + posPrivateMknBuf += 4; + else + { + if (PrivateTagBytes <= 2) + posPrivateMknBuf += 2; + else + posPrivateMknBuf += 4; + } + } + } + free(PrivateMknBuf); + } +#undef CHECKSPACE +} diff --git a/src/metadata/canon.cpp b/src/metadata/canon.cpp new file mode 100644 index 000000000..012ecb09a --- /dev/null +++ b/src/metadata/canon.cpp @@ -0,0 +1,1335 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +libraw_area_t LibRaw::get_CanonArea() { + libraw_area_t la = {}; + la.l = get2(); + la.t = get2(); + la.r = get2(); + la.b = get2(); + return la; +} + +float LibRaw::_CanonConvertAperture(ushort in) +{ + if ((in == (ushort)0xffe0) || (in == (ushort)0x7fff)) + return 0.0f; + return LibRaw::libraw_powf64l(2.f, float(in) / 64.f); +} + +static float _CanonConvertEV(short in) +{ + short EV, Sign, Frac; + float Frac_f; + EV = in; + if (EV < 0) + { + EV = -EV; + Sign = -1; + } + else + { + Sign = 1; + } + Frac = EV & 0x1f; + EV -= Frac; // remove fraction + + if (Frac == 0x0c) + { // convert 1/3 and 2/3 codes + Frac_f = 32.0f / 3.0f; + } + else if (Frac == 0x14) + { + Frac_f = 64.0f / 3.0f; + } + else + Frac_f = (float)Frac; + + return ((float)Sign * ((float)EV + Frac_f)) / 32.0f; +} + +void LibRaw::setCanonBodyFeatures(unsigned long long id) +{ + + ilm.CamID = id; + if ((id == CanonID_EOS_1D) || + (id == CanonID_EOS_1D_Mark_II) || + (id == CanonID_EOS_1D_Mark_II_N) || + (id == CanonID_EOS_1D_Mark_III) || + (id == CanonID_EOS_1D_Mark_IV)) + { + ilm.CameraFormat = LIBRAW_FORMAT_APSH; + ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; + } + else if ((id == CanonID_EOS_1Ds) || + (id == CanonID_EOS_1Ds_Mark_II) || + (id == CanonID_EOS_1Ds_Mark_III) || + (id == CanonID_EOS_1D_X) || + (id == CanonID_EOS_1D_X_Mark_II) || + (id == CanonID_EOS_1D_X_Mark_III) || + (id == CanonID_EOS_1D_C) || + (id == CanonID_EOS_5D) || + (id == CanonID_EOS_5D_Mark_II) || + (id == CanonID_EOS_5D_Mark_III) || + (id == CanonID_EOS_5D_Mark_IV) || + (id == CanonID_EOS_5DS) || + (id == CanonID_EOS_5DS_R) || + (id == CanonID_EOS_6D) || + (id == CanonID_EOS_6D_Mark_II)) + { + ilm.CameraFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; + } + else if ((id == CanonID_EOS_M) || + (id == CanonID_EOS_M2) || + (id == CanonID_EOS_M3) || + (id == CanonID_EOS_M5) || + (id == CanonID_EOS_M10) || + (id == CanonID_EOS_M50) || + (id == CanonID_EOS_M50_Mark_II) || + (id == CanonID_EOS_M6) || + (id == CanonID_EOS_M6_Mark_II) || + (id == CanonID_EOS_M100)) + { + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_Canon_EF_M; + } + else if ((id == CanonID_EOS_R) || + (id == CanonID_EOS_RP) || + (id == CanonID_EOS_R3) || + (id == CanonID_EOS_R5) || + (id == CanonID_EOS_R6)) + { + ilm.CameraFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + } + + else if ((id == CanonID_EOS_R7) || + (id == CanonID_EOS_R10)) + { + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + } + + else if ((id == CanonID_EOS_D30) || + (id == CanonID_EOS_D60) || + (id > 0x80000000ULL)) + { + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_Canon_EF; + } +} + +int CanonCameraInfo_checkFirmwareRecordLocation (uchar *offset) { +// firmware record location allows +// to determine the subversion of the CameraInfo table +// and to adjust offsets accordingly + if ( + isdigit(*offset) && + isdigit(*(offset+2)) && + isdigit(*(offset+4)) && + (*(offset+1) == '.') && + (*(offset+3) == '.') && + ((*(offset+5) == 0) || isspace(*(offset+5))) + ) return 1; + else return 0; // error +} + +void LibRaw::processCanonCameraInfo(unsigned long long id, uchar *CameraInfo, + unsigned maxlen, unsigned type, unsigned dng_writer) +{ + ushort iCanonLensID = 0, iCanonMaxFocal = 0, iCanonMinFocal = 0, + iCanonLens = 0, iCanonCurFocal = 0, iCanonFocalType = 0, + iMakernotesFlip = 0, + iHTP = 0, iALO = 0; + short SubVersion_offset = 0; + ushort SubVersion = 0, mgck = 0; + + if (maxlen < 16) + return; // too short + + mgck = sget2(CameraInfo); + CameraInfo[0] = 0; + CameraInfo[1] = 0; + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) { + if ((maxlen == 94) || (maxlen == 138) || (maxlen == 148) || + (maxlen == 156) || (maxlen == 162) || (maxlen == 167) || + (maxlen == 171) || (maxlen == 264) || (maxlen > 400)) + imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 3) << 2))); + else if (maxlen == 72) + imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 1) << 2))); + else if ((maxlen == 85) || (maxlen == 93)) + imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 2) << 2))); + else if ((maxlen == 96) || (maxlen == 104)) + imCommon.CameraTemperature = float(sget4(CameraInfo + ((maxlen - 4) << 2))); + } + + switch (id) + { + case CanonID_EOS_1D: + case CanonID_EOS_1Ds: + iCanonCurFocal = 0x0a; + iCanonLensID = 0x0d; + iCanonMinFocal = 0x0e; + iCanonMaxFocal = 0x10; + if (!ilm.CurFocal) + ilm.CurFocal = sget2(CameraInfo + iCanonCurFocal); + if (!ilm.MinFocal) + ilm.MinFocal = sget2(CameraInfo + iCanonMinFocal); + if (!ilm.MaxFocal) + ilm.MaxFocal = sget2(CameraInfo + iCanonMaxFocal); + imCommon.CameraTemperature = 0.0f; + break; + + case CanonID_EOS_1D_Mark_II: + case CanonID_EOS_1Ds_Mark_II: + iCanonCurFocal = 0x09; + iCanonLensID = 0x0c; + iCanonMinFocal = 0x11; + iCanonMaxFocal = 0x13; + iCanonFocalType = 0x2d; + break; + + case CanonID_EOS_1D_Mark_II_N: + iCanonCurFocal = 0x09; + iCanonLensID = 0x0c; + iCanonMinFocal = 0x11; + iCanonMaxFocal = 0x13; + break; + + case CanonID_EOS_1D_Mark_III: + case CanonID_EOS_1Ds_Mark_III: + iCanonCurFocal = 0x1d; + iMakernotesFlip = 0x30; + iCanonLensID = 0x111; + iCanonMinFocal = 0x113; + iCanonMaxFocal = 0x115; + break; + + case CanonID_EOS_1D_Mark_IV: + if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1e8)) + SubVersion = 1; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ed)) + SubVersion = 2; +// printf ("==>> CanonID_EOS_1D_Mark_IV, SubVersion: %d\n", SubVersion); + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x35; + + if (!SubVersion) + break; + else if (SubVersion < 2) + SubVersion_offset += -1; + + iCanonLensID = 0x14f+SubVersion_offset; + iCanonMinFocal = 0x151+SubVersion_offset; + iCanonMaxFocal = 0x153+SubVersion_offset; + break; + + case CanonID_EOS_1D_X: + if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x271)) + SubVersion = 1; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x279)) + SubVersion = 2; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x280)) + SubVersion = 3; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x285)) + SubVersion = 4; +// printf ("==>> CanonID_EOS_1D_X, SubVersion: %d\n", SubVersion); + + if (SubVersion < 3) + SubVersion_offset += -3; + + iCanonCurFocal = 0x23+SubVersion_offset; + iMakernotesFlip = 0x7d+SubVersion_offset; + + if (SubVersion < 3) + SubVersion_offset += -4; + else if (SubVersion == 4) + SubVersion_offset += 5; + + iCanonLensID = 0x1a7+SubVersion_offset; + iCanonMinFocal = 0x1a9+SubVersion_offset; + iCanonMaxFocal = 0x1ab+SubVersion_offset; + break; + + case CanonID_EOS_5D: + iMakernotesFlip = 0x27; + iCanonCurFocal = 0x28; + iCanonLensID = 0x0c; + if (!sget2Rev(CameraInfo + iCanonLensID)) + iCanonLensID = 0x97; + iCanonMinFocal = 0x93; + iCanonMaxFocal = 0x95; + break; + + case CanonID_EOS_5D_Mark_II: + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x31; + iALO = 0xbf; + iCanonLensID = 0xe6; + iCanonMinFocal = 0xe8; + iCanonMaxFocal = 0xea; + break; + + case CanonID_EOS_5D_Mark_III: + if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22c)) + SubVersion = 1; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x22d)) + SubVersion = 2; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x23c)) + SubVersion = 3; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x242)) + SubVersion = 4; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x247)) + SubVersion = 5; +// printf ("==>> CanonID_EOS_5D_Mark_III, SubVersion: %d\n", SubVersion); + + if (!SubVersion) + break; + else if (SubVersion < 3) + SubVersion_offset += -1; + + iCanonCurFocal = 0x23+SubVersion_offset; + + if (SubVersion == 1) + SubVersion_offset += -3; + else if (SubVersion == 2) + SubVersion_offset += -2; + else if (SubVersion >= 4) + SubVersion_offset += 6; + + iMakernotesFlip = 0x7d+SubVersion_offset; + + if (SubVersion < 3) + SubVersion_offset += -4; + else if (SubVersion > 4) + SubVersion_offset += 5; + + iCanonLensID = 0x153+SubVersion_offset; + iCanonMinFocal = 0x155+SubVersion_offset; + iCanonMaxFocal = 0x157+SubVersion_offset; + break; + + case CanonID_EOS_6D: + iCanonCurFocal = 0x23; + iMakernotesFlip = 0x83; + iCanonLensID = 0x161; + iCanonMinFocal = 0x163; + iCanonMaxFocal = 0x165; + break; + + case CanonID_EOS_7D: + if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1a8)) + SubVersion = 1; + else if (CanonCameraInfo_checkFirmwareRecordLocation(CameraInfo + 0x1ac)) + SubVersion = 2; +// printf ("==>> CanonID_EOS_7D, SubVersion: %d\n", SubVersion); + iHTP = 0x07; + iCanonCurFocal = 0x1e; + + if (!SubVersion) + break; + else if (SubVersion < 2) + SubVersion_offset += -4; + + iMakernotesFlip = 0x35+SubVersion_offset; + iCanonLensID = 0x112+SubVersion_offset; + iCanonMinFocal = 0x114+SubVersion_offset; + iCanonMaxFocal = 0x116+SubVersion_offset; + break; + + case CanonID_EOS_40D: + iCanonCurFocal = 0x1d; + iMakernotesFlip = 0x30; + iCanonLensID = 0xd6; + iCanonMinFocal = 0xd8; + iCanonMaxFocal = 0xda; + iCanonLens = 0x92b; + break; + + case CanonID_EOS_50D: + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x31; + iALO = 0xbf; + iCanonLensID = 0xea; + iCanonMinFocal = 0xec; + iCanonMaxFocal = 0xee; + break; + + case CanonID_EOS_60D: + case CanonID_EOS_1200D: + iCanonCurFocal = 0x1e; + if (id == CanonID_EOS_60D) + iMakernotesFlip = 0x36; + else + iMakernotesFlip = 0x3a; + iCanonLensID = 0xe8; + iCanonMinFocal = 0xea; + iCanonMaxFocal = 0xec; + break; + + case CanonID_EOS_70D: + iCanonCurFocal = 0x23; + iMakernotesFlip = 0x84; + iCanonLensID = 0x166; + iCanonMinFocal = 0x168; + iCanonMaxFocal = 0x16a; + break; + + case CanonID_EOS_80D: + iCanonCurFocal = 0x23; + iMakernotesFlip = 0x96; + iCanonLensID = 0x189; + iCanonMinFocal = 0x18b; + iCanonMaxFocal = 0x18d; + break; + + case CanonID_EOS_450D: + iCanonCurFocal = 0x1d; + iMakernotesFlip = 0x30; + iCanonLensID = 0xde; + iCanonLens = 0x933; + break; + + case CanonID_EOS_500D: + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x31; + iALO = 0xbe; + iCanonLensID = 0xf6; + iCanonMinFocal = 0xf8; + iCanonMaxFocal = 0xfa; + break; + + case CanonID_EOS_550D: + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x35; + iCanonLensID = 0xff; + iCanonMinFocal = 0x101; + iCanonMaxFocal = 0x103; + break; + + case CanonID_EOS_600D: + case CanonID_EOS_1100D: + iHTP = 0x07; + iCanonCurFocal = 0x1e; + iMakernotesFlip = 0x38; + iCanonLensID = 0xea; + iCanonMinFocal = 0xec; + iCanonMaxFocal = 0xee; + break; + + case CanonID_EOS_650D: + case CanonID_EOS_700D: + iCanonCurFocal = 0x23; + iMakernotesFlip = 0x7d; + iCanonLensID = 0x127; + iCanonMinFocal = 0x129; + iCanonMaxFocal = 0x12b; + break; + + case CanonID_EOS_750D: + case CanonID_EOS_760D: + iCanonCurFocal = 0x23; + iMakernotesFlip = 0x96; + iCanonLensID = 0x184; + iCanonMinFocal = 0x186; + iCanonMaxFocal = 0x188; + break; + + case CanonID_EOS_1000D: + iCanonCurFocal = 0x1d; + iMakernotesFlip = 0x30; + iCanonLensID = 0xe2; + iCanonMinFocal = 0xe4; + iCanonMaxFocal = 0xe6; + iCanonLens = 0x937; + break; + } + + if (iMakernotesFlip && (CameraInfo[iMakernotesFlip] < 3)) { + imCanon.MakernotesFlip = "065"[CameraInfo[iMakernotesFlip]] - '0'; +// printf ("==>> iMakernotesFlip: 0x%x, flip: %d\n", iMakernotesFlip, imCanon.MakernotesFlip); + } else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && + (mgck == 0xaaaa) && (dng_writer == nonDNG)) { // CameraOrientation + int c, i; + for (i = 2; (sget2(CameraInfo+i) != 0xbbbb) && i < (int)maxlen; i++); + i+=2; + while (i < int(maxlen - 5)) + if ((sget4(CameraInfo+i) == 257) && ((c = CameraInfo[i+8]) < 3)) { + imCanon.MakernotesFlip = "065"[c] - '0'; +// printf ("==>> MakernotesFlip offset: 0x%x, flip: %d\n", i+8, imCanon.MakernotesFlip); + break; + } else i+=4; + } + + if (iHTP) + { + imCanon.HighlightTonePriority = CameraInfo[iHTP]; + if ((imCanon.HighlightTonePriority > 5) || + (imCanon.HighlightTonePriority < 0)) + imCanon.HighlightTonePriority = 0; + if (imCanon.HighlightTonePriority) { + imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority); + } + } + if (iALO) + { + imCanon.AutoLightingOptimizer = CameraInfo[iALO]; + if ((imCanon.AutoLightingOptimizer > 3) || + (imCanon.AutoLightingOptimizer < 0)) + imCanon.AutoLightingOptimizer = 3; + } + if (iCanonFocalType) + { + if (iCanonFocalType >= maxlen) + return; // broken; + ilm.FocalType = CameraInfo[iCanonFocalType]; + if (!ilm.FocalType) // zero means 'prime' here, replacing with standard '1' + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + } + if (!ilm.CurFocal && iCanonCurFocal) + { + if (iCanonCurFocal >= maxlen) + return; // broken; + ilm.CurFocal = sget2Rev(CameraInfo + iCanonCurFocal); + } + if (!ilm.LensID && iCanonLensID) + { + if (iCanonLensID >= maxlen) + return; // broken; + ilm.LensID = sget2Rev(CameraInfo + iCanonLensID); + } + if (!ilm.MinFocal && iCanonMinFocal) + { + if (iCanonMinFocal >= maxlen) + return; // broken; + ilm.MinFocal = sget2Rev(CameraInfo + iCanonMinFocal); + } + if (!ilm.MaxFocal && iCanonMaxFocal) + { + if (iCanonMaxFocal >= maxlen) + return; // broken; + ilm.MaxFocal = sget2Rev(CameraInfo + iCanonMaxFocal); + } + if (!ilm.Lens[0] && iCanonLens) + { + if (iCanonLens + 64 >= (int)maxlen) // broken; + return; + + char *pl = (char *)CameraInfo + iCanonLens; + if (!strncmp(pl, "EF-S", 4)) + { + memcpy(ilm.Lens, pl, 4); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, pl, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + memcpy(ilm.Lens + 5, pl + 4, 60); + } + else if (!strncmp(pl, "EF-M", 4)) + { + memcpy(ilm.Lens, pl, 4); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, pl, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + memcpy(ilm.Lens + 5, pl + 4, 60); + } + else if (!strncmp(pl, "EF", 2)) + { + memcpy(ilm.Lens, pl, 2); + ilm.Lens[2] = ' '; + memcpy(ilm.LensFeatures_pre, pl, 2); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + memcpy(ilm.Lens + 3, pl + 2, 62); + } + else if (!strncmp(ilm.Lens, "CN-E", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + else if (!strncmp(pl, "TS-E", 4)) + { + memcpy(ilm.Lens, pl, 4); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, pl, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + memcpy(ilm.Lens + 5, pl + 4, 60); + } + else if (!strncmp(pl, "MP-E", 4)) + { + memcpy(ilm.Lens, pl, 4); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, pl, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + memcpy(ilm.Lens + 5, pl + 4, 60); + } + else // non-Canon lens + memcpy(ilm.Lens, pl, 64); + } + return; +} + +void LibRaw::Canon_CameraSettings(unsigned len) +{ + fseek(ifp, 6, SEEK_CUR); + imCanon.Quality = get2(); // 3 + get2(); + imgdata.shootinginfo.DriveMode = get2(); // 5 + get2(); + imgdata.shootinginfo.FocusMode = get2(); // 7 + imCanon.RecordMode = (get2(), get2()); // 9, format + fseek(ifp, 14, SEEK_CUR); + imgdata.shootinginfo.MeteringMode = get2(); // 17 + get2(); + imgdata.shootinginfo.AFPoint = get2(); // 19 + imgdata.shootinginfo.ExposureMode = get2(); // 20 + get2(); + ilm.LensID = get2(); // 22 + ilm.MaxFocal = get2(); // 23 + ilm.MinFocal = get2(); // 24 + ilm.FocalUnits = get2(); // 25 + if (ilm.FocalUnits > 1) + { + ilm.MaxFocal /= (float)ilm.FocalUnits; + ilm.MinFocal /= (float)ilm.FocalUnits; + } + ilm.MaxAp = _CanonConvertAperture(get2()); // 26 + ilm.MinAp = _CanonConvertAperture(get2()); // 27 + if (len >= 36) + { + fseek(ifp, 12, SEEK_CUR); + imgdata.shootinginfo.ImageStabilization = get2(); // 34 + } + else + return; + if (len >= 48) + { + fseek(ifp, 22, SEEK_CUR); + imCanon.SRAWQuality = get2(); // 46 + } +} + +void LibRaw::Canon_WBpresets(int skip1, int skip2) +{ + int c; + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Daylight][RGGB_2_RGBG(c)] = get2(); + + if (skip1) + fseek(ifp, skip1, SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Shade][RGGB_2_RGBG(c)] = get2(); + + if (skip1) + fseek(ifp, skip1, SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Cloudy][RGGB_2_RGBG(c)] = get2(); + + if (skip1) + fseek(ifp, skip1, SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Tungsten][RGGB_2_RGBG(c)] = get2(); + + if (skip1) + fseek(ifp, skip1, SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_FL_W][RGGB_2_RGBG(c)] = get2(); + + if (skip2) + fseek(ifp, skip2, SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Flash][RGGB_2_RGBG(c)] = get2(); + + return; +} + +void LibRaw::Canon_WBCTpresets(short WBCTversion) +{ + + int i; + float norm; + + if (WBCTversion == 0) + { // tint, as shot R, as shot B, CСT + for (i = 0; i < 15; i++) + { + icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; + fseek(ifp, 2, SEEK_CUR); + icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f); + icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f); + icWBCCTC[i][0] = get2(); + } + } + else if (WBCTversion == 1) + { // as shot R, as shot B, tint, CСT + for (i = 0; i < 15; i++) + { + icWBCCTC[i][2] = icWBCCTC[i][4] = 1.0f; + icWBCCTC[i][1] = 1024.0f / fMAX(get2(), 1.f); + icWBCCTC[i][3] = 1024.0f / fMAX(get2(), 1.f); + fseek(ifp, 2, SEEK_CUR); + icWBCCTC[i][0] = get2(); + } + } + else if (WBCTversion == 2) + { // tint, offset, as shot R, as shot B, CСT + if ((unique_id == CanonID_EOS_M3) || + (unique_id == CanonID_EOS_M10) || + (imCanon.ColorDataSubVer == 0xfffc)) + { + for (i = 0; i < 15; i++) + { + fseek(ifp, 4, SEEK_CUR); + icWBCCTC[i][2] = icWBCCTC[i][4] = + 1.0f; + icWBCCTC[i][1] = 1024.0f / fMAX(1.f, get2()); + icWBCCTC[i][3] = 1024.0f / fMAX(1.f, get2()); + icWBCCTC[i][0] = get2(); + } + } + else if (imCanon.ColorDataSubVer == 0xfffd) + { + for (i = 0; i < 15; i++) + { + fseek(ifp, 2, SEEK_CUR); + norm = (signed short)get2(); + norm = 512.0f + norm / 8.0f; + icWBCCTC[i][2] = icWBCCTC[i][4] = + 1.0f; + icWBCCTC[i][1] = (float)get2(); + if (norm > 0.001f) + icWBCCTC[i][1] /= norm; + icWBCCTC[i][3] = (float)get2(); + if (norm > 0.001f) + icWBCCTC[i][3] /= norm; + icWBCCTC[i][0] = get2(); + } + } + } + return; +} + +void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, unsigned dng_writer) +{ + +#define AsShot_Auto_MeasuredWB(offset) \ + imCanon.ColorDataSubVer = get2(); \ + fseek(ifp, save1 + (offset << 1), SEEK_SET); \ + FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); \ + get2(); \ + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); \ + get2(); \ + FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = get2(); + +#define sRAW_WB(offset) \ + fseek(ifp, save1 + (offset << 1), SEEK_SET); \ + FORC4 { \ + sraw_mul[RGGB_2_RGBG(c)] = get2(); \ + if ((float)sraw_mul[RGGB_2_RGBG(c)] > sraw_mul_max) { \ + sraw_mul_max = (float)sraw_mul[RGGB_2_RGBG(c)]; \ + } \ + } \ + sraw_mul_max /= 1024.f; \ + FORC4 sraw_mul[c] = (ushort)((float)sraw_mul[c] * sraw_mul_max); + +#define CR3_ColorData(offset) \ + fseek(ifp, save1 + ((offset+0x0041) << 1), SEEK_SET); \ + Canon_WBpresets(2, 12); \ + fseek(ifp, save1 + ((offset+0x00c3) << 1), SEEK_SET); \ + Canon_WBCTpresets(0); \ + offsetChannelBlackLevel2 = save1 + ((offset+0x0102) << 1); \ + offsetChannelBlackLevel = save1 + ((offset+0x02d1) << 1); \ + offsetWhiteLevels = save1 + ((offset+0x02d5) << 1); + + int c; + unsigned i; + + if (tag == 0x0001) { + Canon_CameraSettings(len); + + } else if (tag == 0x0002) { // focal length + ilm.FocalType = get2(); + ilm.CurFocal = get2(); + if (ilm.FocalUnits > 1) { + ilm.CurFocal /= (float)ilm.FocalUnits; + } + + } else if (tag == 0x0004) { // subdir, ShotInfo + short tempAp; + if (dng_writer == nonDNG) { + get2(); + imCanon.ISOgain[0] = get2(); + imCanon.ISOgain[1] = get2(); + if (imCanon.ISOgain[1] != 0x7fff) { + imCommon.real_ISO = floorf(100.f * libraw_powf64l(2.f, float(imCanon.ISOgain[0]+imCanon.ISOgain[1]) / 32.f - 5.f)); + if (!iso_speed || (iso_speed == 65535)) + iso_speed = imCommon.real_ISO; + } + get4(); + if (((i = get2()) != 0xffff) && !shutter) { + shutter = libraw_powf64l(2.f, float((short)i) / -32.0f); + } + imCanon.wbi = (get2(), get2()); + shot_order = (get2(), get2()); + fseek(ifp, 4, SEEK_CUR); + } else + fseek(ifp, 24, SEEK_CUR); + tempAp = get2(); + if (tempAp != 0) + imCommon.CameraTemperature = (float)(tempAp - 128); + tempAp = get2(); + if (tempAp != -1) + imCommon.FlashGN = ((float)tempAp) / 32; + get2(); + + imCommon.FlashEC = _CanonConvertEV((signed short)get2()); + fseek(ifp, 8 - 32, SEEK_CUR); + if ((tempAp = get2()) != 0x7fff) + ilm.CurAp = _CanonConvertAperture(tempAp); + if (ilm.CurAp < 0.7f) { + fseek(ifp, 32, SEEK_CUR); + ilm.CurAp = _CanonConvertAperture(get2()); + } + if (!aperture) + aperture = ilm.CurAp; + + } else if ((tag == 0x0007) && (dng_writer == nonDNG)) { + fgets(model2, 64, ifp); + + } else if ((tag == 0x0008) && (dng_writer == nonDNG)) { + shot_order = get4(); + + } else if ((tag == 0x0009) && (dng_writer == nonDNG)) { + fread(artist, 64, 1, ifp); + + } else if (tag == 0x000c) { + unsigned tS = get4(); + sprintf(imgdata.shootinginfo.BodySerial, "%d", tS); + + } else if ((tag == 0x0012) || + (tag == 0x0026) || + (tag == 0x003c)) { + if (!imCommon.afcount) { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount = 1; + } + + } else if ((tag == 0x0029) && (dng_writer == nonDNG)) { // PowerShot G9 + int Got_AsShotWB = 0; + fseek(ifp, 8, SEEK_CUR); + for (unsigned linenum = 0; linenum < Canon_G9_linenums_2_StdWBi.size(); linenum++) { + if (Canon_G9_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown ) { + FORC4 icWBC[Canon_G9_linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get4(); + if (Canon_wbi2std[imCanon.wbi] == Canon_G9_linenums_2_StdWBi[linenum]) { + FORC4 cam_mul[c] = float(icWBC[Canon_G9_linenums_2_StdWBi[linenum]][c]); + Got_AsShotWB = 1; + } + } + fseek(ifp, 16, SEEK_CUR); + } + if (!Got_AsShotWB) + FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); + + } else if ((tag == 0x0081) && (dng_writer == nonDNG)) { // -1D, -1Ds + data_offset = get4(); + fseek(ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + + } else if (tag == 0x0093) { + if (!imCanon.RF_lensID) { + fseek(ifp, 0x03d<<1, SEEK_CUR); + imCanon.RF_lensID = get2(); + } + + } else if (tag == 0x0095 && !ilm.Lens[0]) + { // lens model tag + fread(ilm.Lens, 64, 1, ifp); + if (!strncmp(ilm.Lens, "EF-S", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF_S; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + } + else if (!strncmp(ilm.Lens, "EF-M", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF_M; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + } + else if (!strncmp(ilm.Lens, "EF", 2)) + { + memmove(ilm.Lens + 3, ilm.Lens + 2, 62); + ilm.Lens[2] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 2); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + else if (!strncmp(ilm.Lens, "CN-E", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + else if (!strncmp(ilm.Lens, "TS-E", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + else if (!strncmp(ilm.Lens, "MP-E", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 60); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + + else if (!strncmp(ilm.Lens, "RF-S", 4)) + { + memmove(ilm.Lens + 5, ilm.Lens + 4, 62); + ilm.Lens[4] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 4); + ilm.LensMount = LIBRAW_MOUNT_Canon_RF; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + } + + else if (!strncmp(ilm.Lens, "RF", 2)) + { + memmove(ilm.Lens + 3, ilm.Lens + 2, 62); + ilm.Lens[2] = ' '; + memcpy(ilm.LensFeatures_pre, ilm.Lens, 2); + ilm.LensMount = LIBRAW_MOUNT_Canon_RF; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + } + else if (tag == 0x009a) + { // AspectInfo + i = get4(); + switch (i) + { + case 0: + case 12: /* APS-H crop */ + case 13: /* APS-C crop */ + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 1: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + break; + case 2: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; + break; + case 7: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; + break; + case 8: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; + break; + default: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; + break; + } + imgdata.sizes.raw_inset_crops[0].cwidth = get4(); + imgdata.sizes.raw_inset_crops[0].cheight = get4(); + imgdata.sizes.raw_inset_crops[0].cleft = get4(); + imgdata.sizes.raw_inset_crops[0].ctop = get4(); + + } else if ((tag == 0x00a4) && (dng_writer == nonDNG)) { // -1D, -1Ds + fseek(ifp, imCanon.wbi * 48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + + } else if (tag == 0x00a9) { + INT64 save1 = ftell(ifp); + fseek(ifp, (0x1 << 1), SEEK_CUR); + FORC4 imgdata.color.WB_Coeffs[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + Canon_WBpresets(0, 0); + fseek(ifp, save1, SEEK_SET); + } + else if (tag == 0x00b4) + { + switch (get2()) { + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + } + else if (tag == 0x00e0) // SensorInfo + { + imCanon.SensorWidth = (get2(), get2()); + imCanon.SensorHeight = get2(); + fseek(ifp, 4, SEEK_CUR); + imCanon.DefaultCropAbsolute = get_CanonArea(); + imCanon.LeftOpticalBlack = get_CanonArea(); + } + else if (tag == 0x4001 && len > 500) + { + float sraw_mul_max = 0.f; + int bls = 0; + INT64 offsetChannelBlackLevel = 0L; + INT64 offsetChannelBlackLevel2 = 0L; + INT64 offsetWhiteLevels = 0L; + INT64 save1 = ftell(ifp); + + switch (len) + { + + case 582: + imCanon.ColorDataVer = 1; // 20D, 350D + + fseek(ifp, save1 + (0x0019 << 1), SEEK_SET); + FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); + fseek(ifp, save1 + (0x001e << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0041 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0046 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); + + fseek(ifp, save1 + (0x0023 << 1), SEEK_SET); + Canon_WBpresets(2, 2); + fseek(ifp, save1 + (0x004b << 1), SEEK_SET); + Canon_WBCTpresets(1); // ABCT + offsetChannelBlackLevel = save1 + (0x00a6 << 1); + break; + + case 653: + imCanon.ColorDataVer = 2; // -1D Mark II, -1Ds Mark II + + fseek(ifp, save1 + (0x0018 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0022 << 1), SEEK_SET); + FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); + fseek(ifp, save1 + (0x0090 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0095 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x009a << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2(); + + fseek(ifp, save1 + (0x0027 << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x00a4 << 1), SEEK_SET); + Canon_WBCTpresets(1); // ABCT + offsetChannelBlackLevel = save1 + (0x011e << 1); + break; + + case 796: + imCanon.ColorDataVer = 3; // -1D Mark II N, 5D, 30D, 400D; ColorDataSubVer: 1 + AsShot_Auto_MeasuredWB(0x003f); + + fseek(ifp, save1 + (0x0071 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom1][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0076 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom2][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x007b << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom3][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2(); + + fseek(ifp, save1 + (0x004e << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); + Canon_WBCTpresets(0); // BCAT + offsetChannelBlackLevel = save1 + (0x00c4 << 1); + break; + + case 674: // -1D Mark III; ColorDataSubVer: 2 + case 692: // 40D; ColorDataSubVer: 3 + case 702: // -1Ds Mark III; ColorDataSubVer: 4 + case 1227: // 450D, 1000D; ColorDataSubVer: 5 + case 1250: // 5D Mark II, 50D; ColorDataSubVer: 6 + case 1251: // 500D; ColorDataSubVer: 7 + case 1337: // -1D Mark IV, 7D; ColorDataSubVer: 7 + case 1338: // 550D; ColorDataSubVer: 7 + case 1346: // 1100D, 60D; ColorDataSubVer: 9 + imCanon.ColorDataVer = 4; + AsShot_Auto_MeasuredWB(0x003f); + sRAW_WB(0x004e); + fseek(ifp, save1 + (0x0053 << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x00a8 << 1), SEEK_SET); + Canon_WBCTpresets(0); // BCAT + + if ((imCanon.ColorDataSubVer == 4) || + (imCanon.ColorDataSubVer == 5)) + { + offsetChannelBlackLevel = save1 + (0x02b4 << 1); + offsetWhiteLevels = save1 + (0x02b8 << 1); + } + else if ((imCanon.ColorDataSubVer == 6) || + (imCanon.ColorDataSubVer == 7)) + { + offsetChannelBlackLevel = save1 + (0x02cb << 1); + offsetWhiteLevels = save1 + (0x02cf << 1); + } + else if (imCanon.ColorDataSubVer == 9) + { + offsetChannelBlackLevel = save1 + (0x02cf << 1); + offsetWhiteLevels = save1 + (0x02d3 << 1); + } + else + offsetChannelBlackLevel = save1 + (0x00e7 << 1); + break; + + case 5120: // G10, G11, G12, G15, G16 + // G1 X, G1 X Mark II, G1 X Mark III + // G3 X, G5 X + // G7 X, G7 X Mark II + // G9 X, G9 X Mark II + // S90, S95, S100, S100V, S110, S120 + // SX1 IS, SX50 HS, SX60 HS + // M3, M5, M6, M10, M100 + imCanon.ColorDataVer = 5; + imCanon.ColorDataSubVer = get2(); + + fseek(ifp, save1 + (0x0047 << 1), SEEK_SET); + FORC4 cam_mul[RGGB_2_RGBG(c)] = (float)get2(); + + if (imCanon.ColorDataSubVer == 0xfffc) // ColorDataSubVer: 65532 (-4) + // G7 X Mark II, G9 X Mark II, G1 X Mark III + // M5, M100, M6 + { + fseek(ifp, save1 + (0x004f << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, 8, SEEK_CUR); + FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = + get2(); + fseek(ifp, 8, SEEK_CUR); + FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, 8, SEEK_CUR); + Canon_WBpresets(8, 24); + fseek(ifp, 168, SEEK_CUR); + FORC4 icWBC[LIBRAW_WBI_FL_WW][RGGB_2_RGBG(c)] = get2(); + fseek(ifp, 24, SEEK_CUR); + Canon_WBCTpresets(2); // BCADT + offsetChannelBlackLevel = save1 + (0x014d << 1); + offsetWhiteLevels = save1 + (0x0569 << 1); + } + else if (imCanon.ColorDataSubVer == 0xfffd) // ColorDataSubVer: 65533 (-3) + // M10, M3 + // G1 X, G1 X Mark II + // G3 X, G5 X, G7 X, G9 X + // G10, G11, G12, G15, G16 + // S90, S95, S100, S100V, S110, S120 + // SX1 IS, SX50 HS, SX60 HS + { + fseek(ifp, save1 + (0x004c << 1), SEEK_SET); + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + get2(); + FORC4 icWBC[LIBRAW_WBI_Measured][RGGB_2_RGBG(c)] = + get2(); + get2(); + FORC4 icWBC[LIBRAW_WBI_Other][RGGB_2_RGBG(c)] = get2(); + get2(); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x00ba << 1), SEEK_SET); + Canon_WBCTpresets(2); // BCADT + offsetChannelBlackLevel = save1 + (0x0108 << 1); + } + break; + + case 1273: // 600D; ColorDataSubVer: 10 + case 1275: // 1200D; ColorDataSubVer: 10 + imCanon.ColorDataVer = 6; + AsShot_Auto_MeasuredWB(0x003f); + sRAW_WB(0x0062); + fseek(ifp, save1 + (0x0067 << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x00bc << 1), SEEK_SET); + Canon_WBCTpresets(0); // BCAT + offsetChannelBlackLevel = save1 + (0x01df << 1); + offsetWhiteLevels = save1 + (0x01e3 << 1); + break; + + case 1312: // 5D Mark III, 650D, 700D, M; ColorDataSubVer: 10 + case 1313: // 100D, 6D, 70D, EOS M2; ColorDataSubVer: 10 + case 1316: // -1D C, -1D X; ColorDataSubVer: 10 + case 1506: // 750D, 760D, 7D Mark II; ColorDataSubVer: 11 + imCanon.ColorDataVer = 7; + AsShot_Auto_MeasuredWB(0x003f); + sRAW_WB(0x007b); + fseek(ifp, save1 + (0x0080 << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x00d5 << 1), SEEK_SET); + Canon_WBCTpresets(0); // BCAT + + if (imCanon.ColorDataSubVer == 10) + { + offsetChannelBlackLevel = save1 + (0x01f8 << 1); + offsetWhiteLevels = save1 + (0x01fc << 1); + } + else if (imCanon.ColorDataSubVer == 11) + { + offsetChannelBlackLevel = save1 + (0x02d8 << 1); + offsetWhiteLevels = save1 + (0x02dc << 1); + } + break; + + case 1560: // 5DS, 5DS R; ColorDataSubVer: 12 + case 1592: // 5D Mark IV, 80D, -1D X Mark II; ColorDataSubVer: 13 + case 1353: // 1300D, 1500D, 3000D; ColorDataSubVer: 14 + case 1602: // 200D, 6D Mark II, 77D, 800D; ColorDataSubVer: 15 + imCanon.ColorDataVer = 8; + AsShot_Auto_MeasuredWB(0x003f); + sRAW_WB(0x0080); + fseek(ifp, save1 + (0x0085 << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + (0x0107 << 1), SEEK_SET); + Canon_WBCTpresets(0); // BCAT + + if (imCanon.ColorDataSubVer == 14) // 1300D, 1500D, 3000D + { + offsetChannelBlackLevel = save1 + (0x022c << 1); + offsetWhiteLevels = save1 + (0x0230 << 1); + } + else + { + offsetChannelBlackLevel = save1 + (0x030a << 1); + offsetWhiteLevels = save1 + (0x030e << 1); + } + break; + + case 1820: // M50; ColorDataSubVer: 16 + case 1824: // R; ColorDataSubVer: 17 + case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18 + // M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19 + imCanon.ColorDataVer = 9; + AsShot_Auto_MeasuredWB(0x0047); + CR3_ColorData(0x0047); + break; + + case 1770: // R5 CRM + case 2024: // -1D X Mark III; ColorDataSubVer: 32 + case 3656: // R5, R6; ColorDataSubVer: 33 + imCanon.ColorDataVer = 10; + AsShot_Auto_MeasuredWB(0x0055); + CR3_ColorData(0x0055); + break; + + case 3973: // R3; ColorDataSubVer: 34 + case 3778: // R7, R10; ColorDataSubVer: 48 + imCanon.ColorDataVer = 11; + AsShot_Auto_MeasuredWB(0x0069); + + fseek(ifp, save1 + ((0x0069+0x0064) << 1), SEEK_SET); + Canon_WBpresets(2, 12); + fseek(ifp, save1 + ((0x0069+0x00c3) << 1), SEEK_SET); + Canon_WBCTpresets(0); + offsetChannelBlackLevel2 = save1 + ((0x0069+0x0102) << 1); + offsetChannelBlackLevel = save1 + ((0x0069+0x0213) << 1); + offsetWhiteLevels = save1 + ((0x0069+0x0217) << 1); + break; + + default: + imCanon.ColorDataSubVer = get2(); + break; + } + + if (offsetChannelBlackLevel) + { + fseek(ifp, offsetChannelBlackLevel, SEEK_SET); + FORC4 + bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); + imCanon.AverageBlackLevel = bls / 4; + } + if (offsetWhiteLevels) + { + if ((offsetWhiteLevels - offsetChannelBlackLevel) != 8L) + fseek(ifp, offsetWhiteLevels, SEEK_SET); + imCanon.NormalWhiteLevel = get2(); + imCanon.SpecularWhiteLevel = get2(); + FORC4 + imgdata.color.linear_max[c] = imCanon.SpecularWhiteLevel; + } + + if(!imCanon.AverageBlackLevel && offsetChannelBlackLevel2) + { + fseek(ifp, offsetChannelBlackLevel2, SEEK_SET); + FORC4 + bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); + imCanon.AverageBlackLevel = bls / 4; + } + fseek(ifp, save1, SEEK_SET); + + } else if (tag == 0x4013) { + get4(); + imCanon.AFMicroAdjMode = get4(); + float a = float(get4()); + float b = float(get4()); + if (fabsf(b) > 0.001f) + imCanon.AFMicroAdjValue = a / b; + + } else if (tag == 0x4018) { + fseek(ifp, 8, SEEK_CUR); + imCanon.AutoLightingOptimizer = get4(); + if ((imCanon.AutoLightingOptimizer > 3) || + (imCanon.AutoLightingOptimizer < 0)) + imCanon.AutoLightingOptimizer = 3; + imCanon.HighlightTonePriority = get4(); + if ((imCanon.HighlightTonePriority > 5) || + (imCanon.HighlightTonePriority < 0)) + imCanon.HighlightTonePriority = 0; + if (imCanon.HighlightTonePriority) { + imCommon.ExposureCalibrationShift -= float(imCanon.HighlightTonePriority); + } + + } else if ((tag == 0x4021) && (dng_writer == nonDNG) && + (imCanon.multishot[0] = get4()) && + (imCanon.multishot[1] = get4())) { + if (len >= 4) { + imCanon.multishot[2] = get4(); + imCanon.multishot[3] = get4(); + } + FORC4 cam_mul[c] = 1024; + } else if (tag == 0x4026) { + fseek(ifp, 44, SEEK_CUR); + imCanon.CanonLog = get4(); + } +#undef CR3_ColorData +#undef sRAW_WB +#undef AsShot_Auto_MeasuredWB +} diff --git a/src/metadata/ciff.cpp b/src/metadata/ciff.cpp new file mode 100644 index 000000000..2c59b11e7 --- /dev/null +++ b/src/metadata/ciff.cpp @@ -0,0 +1,411 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#ifdef _MSC_VER +#if _MSC_VER < 1800 /* below MSVC 2013 */ +float roundf(float f) +{ + return floorf(f + 0.5); +} + +#endif +#endif + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void LibRaw::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 >> (vbits -= bpp) & ~(-1 << bpp); + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void LibRaw::parse_ciff(int offset, int length, int depth) +{ + int nrecs, c, type, len, wbi = -1; + INT64 save, tboff; + ushort key[] = {0x410, 0x45f3}; + ushort CanonColorInfo1_key; + ushort Appendix_A = 0; + INT64 WB_table_offset = 0; + int UseWBfromTable_as_AsShot = 1; + int Got_AsShotWB = 0; + INT64 fsize = ifp->size(); + if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + fseek(ifp, offset + length - 4, SEEK_SET); + tboff = INT64(get4()) + offset; + fseek(ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs < 1) + return; + if ((nrecs | depth) > 127) + return; + + if (nrecs * 10 + offset > fsize) + return; + + while (nrecs--) + { + type = get2(); + len = get4(); + INT64 see = offset + get4(); + save = ftell(ifp); + + /* the following tags are not sub-tables + * they contain the value in the "len" field + * for such tags skip the check against filesize + */ + if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) && + (type != 0x5029) && (type != 0x5813) && (type != 0x5814) && + (type != 0x5817) && (type != 0x5834) && (type != 0x580e)) + { + + if (see >= fsize) + { // At least one byte + fseek(ifp, save, SEEK_SET); + continue; + } + fseek(ifp, see, SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + { + parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */ + } + } + + if (type == 0x3004) + { + parse_ciff(ftell(ifp), len, depth + 1); + } + else if (type == 0x0810) + { + fread(artist, 64, 1, ifp); + } + else if (type == 0x080a) + { + fread(make, 64, 1, ifp); + fseek(ifp, strbuflen(make) - 63, SEEK_CUR); + fread(model, 64, 1, ifp); + + } else if (type == 0x080b) { + stmread(imCommon.firmware, (unsigned)len, ifp); + if (!strncasecmp(imCommon.firmware, "Firmware Version", 16)) + memmove(imCommon.firmware, imCommon.firmware + 16, strlen(imCommon.firmware) - 15); + trimSpaces(imCommon.firmware); + + } else if (type == 0x1810) + { + width = get4(); + height = get4(); + pixel_aspect = int_to_float(get4()); + flip = get4(); + } + else if (type == 0x1835) + { /* Get the decoder table */ + tiff_compress = get4(); + } + else if (type == 0x2007) + { + thumb_offset = see; + thumb_length = len; + } + else if (type == 0x1818) + { + shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4()))); + ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2); + } + else if (type == 0x102a) // CanonShotInfo + { + // iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50; + get2(); // skip one + iso_speed = + libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f; + ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2())); + shutter = libraw_powf64l(2.0f, -float((short)get2()) / 32.f); + imCanon.wbi = wbi = (get2(), get2()); + if (wbi >= (int)Canon_wbi2std.size()) + wbi = 0; + fseek(ifp, 32, SEEK_CUR); + if (shutter > 1e6) + shutter = float(get2()) / 10.f; + } + else if (type == 0x102c) // CanonColorInfo2 / Appendix A: Pro90IS, G1, G2, S30, S40 + { + int CanonColorInfo2_type = get2(); // G1 1028, G2 272, Pro90 IS 769, S30 274, S40 273, EOS D30 276 + if (CanonColorInfo2_type > 512) { /* Pro90 IS, G1 */ + fseek(ifp, 118, SEEK_CUR); + FORC4 cam_mul[BG2RG1_2_RGBG(c)] = get2(); + } + else if (CanonColorInfo2_type != 276) { /* G2, S30, S40 */ + Appendix_A = 1; + WB_table_offset = -14; + fseek(ifp, 98, SEEK_CUR); + FORC4 cam_mul[GRBG_2_RGBG(c)] = get2(); + if (cam_mul[0] > 0.001f) Got_AsShotWB = 1; + } + } + else if (type == 0x10a9) // ColorBalance: Canon D60, 10D, 300D, and clones + { + int bls = 0; +/* + int table[] = { + LIBRAW_WBI_Auto, // 0 + LIBRAW_WBI_Daylight, // 1 + LIBRAW_WBI_Cloudy, // 2 + LIBRAW_WBI_Tungsten, // 3 + LIBRAW_WBI_FL_W, // 4 + LIBRAW_WBI_Flash, // 5 + LIBRAW_WBI_Custom, // 6, absent in Canon D60 + LIBRAW_WBI_Auto, // 7, use this if camera is set to b/w JPEG + LIBRAW_WBI_Shade, // 8 + LIBRAW_WBI_Kelvin // 9, absent in Canon D60 + }; +*/ + int nWB = + ((get2() - 2) / 8) - + 1; // 2 bytes this, N recs 4*2bytes each, last rec is black level + if (nWB) + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2(); + if (nWB >= 7) + Canon_WBpresets(0, 0); + else + FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); + if (nWB == 7) // mostly Canon EOS D60 + some fw#s for 300D; + // check for 0x1668000 is unreliable + { + if ((wbi >= 0) && (wbi < 9) && (wbi != 6)) + { + FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); + } + else + { + FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); + } + } + else if (nWB == 9) // Canon 10D, 300D + { + FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2(); + FORC4 icWBC[LIBRAW_WBI_Kelvin][RGGB_2_RGBG(c)] = get2(); + if ((wbi >= 0) && (wbi < 10)) + { + FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]); + } + else + { + FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]); + } + } + FORC4 + bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2()); + imCanon.AverageBlackLevel = bls / 4; + } + else if (type == 0x102d) + { + Canon_CameraSettings(len >> 1); + } + + else if (type == 0x10b4) { + switch (get2()) { + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + + } else if (type == 0x580b) + { + if (strcmp(model, "Canon EOS D30")) + sprintf(imgdata.shootinginfo.BodySerial, "%d", len); + else + sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16, + len & 0xffff); + } + else if (type == 0x0032) // CanonColorInfo1 + { + if (len == 768) { // EOS D30 + + ushort q; + fseek(ifp, 4, SEEK_CUR); + for (unsigned linenum = 0; linenum < Canon_D30_linenums_2_StdWBi.size(); linenum++) { + if (Canon_D30_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { + FORC4 { + q = get2(); + icWBC[Canon_D30_linenums_2_StdWBi[linenum]][RGGB_2_RGBG(c)] = + (int)(roundf(1024000.0f / (float)MAX(1, q))); + } +// if (Canon_wbi2std[imCanon.wbi] == *(Canon_D30_linenums_2_StdWBi + linenum)) { +// FORC4 cam_mul[c] = icWBC[*(Canon_D30_linenums_2_StdWBi + linenum)][c]; +// Got_AsShotWB = 1; +// } + } + } + fseek (ifp, 68-int(Canon_D30_linenums_2_StdWBi.size())*8, SEEK_CUR); + + FORC4 { + q = get2(); + cam_mul[RGGB_2_RGBG(c)] = 1024.f / float(MAX(1, q)); + } + if (!wbi) + cam_mul[0] = -1; // use my auto white balance + + } + else if ((cam_mul[0] <= 0.001f) || // Pro1, G3, G5, G6, S45, S50, S60, S70 + Appendix_A) // G2, S30, S40 + { + libraw_static_table_t linenums_2_StdWBi; + unsigned AsShotWB_linenum = Canon_wbi2std.size(); + + CanonColorInfo1_key = get2(); + if ((CanonColorInfo1_key == key[0]) && (len == 2048)) { // Pro1 + linenums_2_StdWBi = Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi; + WB_table_offset = 8; + + } else if ((CanonColorInfo1_key == key[0]) && (len == 3072)) { // S60, S70, G6 + linenums_2_StdWBi = Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi; + WB_table_offset = 16; + + } else if (!CanonColorInfo1_key && (len == 2048)) { // G2, S30, S40; S45, S50, G3, G5 + key[0] = key[1] = 0; + linenums_2_StdWBi = Canon_KeyIsZero_Len2048_linenums_2_StdWBi; + if (atof(imCommon.firmware) < 1.02f) + UseWBfromTable_as_AsShot = 0; + + } else goto next_tag; + + if ((Canon_wbi2std[wbi] == LIBRAW_WBI_Auto) || + (Canon_wbi2std[wbi] == LIBRAW_WBI_Unknown) || + Got_AsShotWB) + UseWBfromTable_as_AsShot = 0; + + if (UseWBfromTable_as_AsShot) { + int temp_wbi; + if (Canon_wbi2std[wbi] == LIBRAW_WBI_Custom) temp_wbi = LIBRAW_WBI_Daylight; + else temp_wbi = wbi; + for (AsShotWB_linenum = 0; AsShotWB_linenum < linenums_2_StdWBi.size(); AsShotWB_linenum++) { + if (Canon_wbi2std[temp_wbi] == linenums_2_StdWBi[AsShotWB_linenum]) { + break; + } + } + } + + fseek (ifp, 78LL+WB_table_offset, SEEK_CUR); + for (unsigned linenum = 0; linenum < linenums_2_StdWBi.size(); linenum++) { + if (linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) { + FORC4 icWBC[linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get2() ^ key[c & 1]; + if (UseWBfromTable_as_AsShot && (AsShotWB_linenum == linenum)) { + FORC4 cam_mul[c] = float(icWBC[linenums_2_StdWBi[linenum]][c]); + Got_AsShotWB = 1; + } + } else { + fseek(ifp, 8, SEEK_CUR); + } + } + if (!Got_AsShotWB) + cam_mul[0] = -1; + } + } + else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1)) + { + ciff_block_1030(); // all that don't have 0x10a9 + } + else if (type == 0x1031) + { + raw_width = imCanon.SensorWidth = (get2(), get2()); + raw_height = imCanon.SensorHeight = get2(); + fseek(ifp, 4, SEEK_CUR); + imCanon.DefaultCropAbsolute = get_CanonArea(); + imCanon.LeftOpticalBlack = get_CanonArea(); + } + else if (type == 0x501c) + { + iso_speed = float(len & 0xffff); + } + else if (type == 0x5029) + { + ilm.CurFocal = float( len >> 16); + ilm.FocalType = len & 0xffff; + if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS) + { + ilm.FocalUnits = 32; + if (ilm.FocalUnits > 1) + ilm.CurFocal /= (float)ilm.FocalUnits; + } + focal_len = ilm.CurFocal; + } + else if (type == 0x5813) + { + flash_used = int_to_float(len); + } + else if (type == 0x5814) + { + canon_ev = int_to_float(len); + } + else if (type == 0x5817) + { + shot_order = len; + } + else if (type == 0x5834) + { + unique_id = ((unsigned long long)len << 32) >> 32; + setCanonBodyFeatures(unique_id); + } + else if (type == 0x580e) + { + timestamp = len; + } + else if (type == 0x180e) + { + timestamp = get4(); + } + +next_tag:; +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime(gmtime(×tamp)); +#endif + fseek(ifp, save, SEEK_SET); + } +} diff --git a/src/metadata/cr3_parser.cpp b/src/metadata/cr3_parser.cpp new file mode 100644 index 000000000..52061e9c7 --- /dev/null +++ b/src/metadata/cr3_parser.cpp @@ -0,0 +1,896 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + + +static libraw_area_t sget_CanonArea(uchar *s) { + libraw_area_t la = {}; + la.l = s[0] << 8 | s[1]; + la.t = s[2] << 8 | s[3]; + la.r = s[4] << 8 | s[5]; + la.b = s[6] << 8 | s[7]; + return la; +} + +int LibRaw::selectCRXFrame(short trackNum, unsigned frameIndex) +{ + uint32_t sample_size; + uint32_t stsc_index = 0; + uint32_t current_sample = 0; + crx_data_header_t *hdr = &libraw_internal_data.unpacker_data.crx_header[trackNum]; + + if (frameIndex >= hdr->sample_count) + return -1; + + for (int i = 0; i < hdr->chunk_count; i++) + { + int64_t current_offset = hdr->chunk_offsets[i]; + + while((stsc_index < hdr->stsc_count) && (i+1 == hdr->stsc_data[stsc_index+1].first)) + stsc_index++; + + for (int j = 0; j < hdr->stsc_data[stsc_index].count; j++) + { + if (current_sample > hdr->sample_count) + return -1; + + sample_size = hdr->sample_size > 0 ? hdr->sample_size : hdr->sample_sizes[current_sample]; + if(current_sample == frameIndex) + { + hdr->MediaOffset = current_offset; + hdr->MediaSize = sample_size; + return 0; + } + current_offset += sample_size; + current_sample++; + } + } + return -1; +} + +void LibRaw::selectCRXTrack() +{ + short maxTrack = libraw_internal_data.unpacker_data.crx_track_count; + if (maxTrack < 0) + return; + + INT64 bitcounts[LIBRAW_CRXTRACKS_MAXCOUNT], maxbitcount = 0; + int framecounts[LIBRAW_CRXTRACKS_MAXCOUNT], maxframecount = 0; + uint32_t maxjpegbytes = 0; + int framecnt = 0; + int media_tracks = 0; + int track_select = 0; + int frame_select = 0; + int err; + memset(bitcounts, 0, sizeof(bitcounts)); + memset(framecounts, 0, sizeof(framecounts)); + + // Calc max frame bitcount for max-sized RAW track(s) selection + for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) + { + crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; + if (d->MediaType == 1) // RAW + { + bitcounts[i] = INT64(d->nBits) * INT64(d->f_width) * INT64(d->f_height); + maxbitcount = MAX(bitcounts[i], maxbitcount); + if (d->sample_count > 1) + framecounts[i] = d->sample_count; + } + } + + if (maxbitcount < 8) // no raw tracks + return; + + // Calc RAW tracks and frames + for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) + { + if (bitcounts[i] == maxbitcount) + { + media_tracks++; + if (framecounts[i] > 1) + framecnt = MAX(framecnt, framecounts[i]); + } + } + + // If the file has only 1 media track shot_select represents frames select. + // If the file has multiple media tracks shot_select represents track select. + // If the file has multiple media tracks and multiple frames it is currently unsupported. + + if (framecnt && media_tracks > 1) + return; + else if (framecnt) + frame_select = shot_select; + else + track_select = shot_select; + + int tracki = -1; + for (int i = 0, trackcnt = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) + { + if (bitcounts[i] == maxbitcount) + { + if (trackcnt <= (int)track_select) + tracki = i; + trackcnt++; + } + } + + if (tracki >= 0 && tracki < LIBRAW_CRXTRACKS_MAXCOUNT /* && frame_select > 0 */) + { + framecnt = framecounts[tracki]; // Update to selected track + frame_select = LIM(frame_select, 0, framecnt); + if(frame_select > 0) + if (selectCRXFrame(tracki, frame_select)) + return; + } + else + return; // No RAW track index + + // Frame selected: parse CTMD metadata + for (int i = 0, trackcnt = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) + { + crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; + int fsel = LIM(frame_select, 0, d->sample_count); + if (d->MediaType == 3) // CTMD metadata + { + /* ignore errors !*/ + if (fsel) + selectCRXFrame(i, fsel); + parseCR3_CTMD(i); + } + else if (d->MediaType == 2) // JPEG + { + if (fsel) + selectCRXFrame(i, fsel); + if (d->MediaSize > maxjpegbytes) + { + maxjpegbytes = d->MediaSize; + thumb_offset = d->MediaOffset; + thumb_length = d->MediaSize; + if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) + { + bool do_add = true; + for (int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) + if (imgdata.thumbs_list.thumblist[idx].toffset == thumb_offset) + { + do_add = false; + break; + } + if (do_add) + { + int idx = imgdata.thumbs_list.thumbcount; + imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; + imgdata.thumbs_list.thumblist[idx].toffset = thumb_offset; + imgdata.thumbs_list.thumblist[idx].tlength = thumb_length; + imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; + imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps + imgdata.thumbs_list.thumblist[idx].twidth = 0; + imgdata.thumbs_list.thumblist[idx].theight = 0; + imgdata.thumbs_list.thumbcount++; + } + } + } + } + } + + if (framecnt) + is_raw = framecnt; + else + is_raw = media_tracks; + + if (tracki >= 0 && tracki < LIBRAW_CRXTRACKS_MAXCOUNT) + { + crx_data_header_t *d = + &libraw_internal_data.unpacker_data.crx_header[tracki]; + data_offset = d->MediaOffset; + data_size = d->MediaSize; + raw_width = d->f_width; + raw_height = d->f_height; + load_raw = &LibRaw::crxLoadRaw; + tiff_bps = d->encType == 3? d->medianBits : d->nBits; + switch (d->cfaLayout) + { + case 0: + filters = 0x94949494; + break; + case 1: + filters = 0x61616161; + break; + case 2: + filters = 0x49494949; + break; + case 3: + filters = 0x16161616; + break; + } + + libraw_internal_data.unpacker_data.crx_track_selected = tracki; + + int tiff_idx = -1; + INT64 tpixels = 0; + for (unsigned i = 0; i < tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++) + if (INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height) > tpixels) + { + tpixels = INT64(tiff_ifd[i].t_height) * INT64(tiff_ifd[i].t_height); + tiff_idx = i; + } + if (tiff_idx >= 0) + flip = tiff_ifd[tiff_idx].t_flip; + } +} + +#define bad_hdr() \ + (((order != 0x4d4d) && (order != 0x4949)) || (get2() != 0x002a) || \ + (get4() != 0x00000008)) + +int LibRaw::parseCR3_CTMD(short trackNum) +{ + int err = 0; + short s_order = order; + order = 0x4949; + uint32_t relpos_inDir = 0; + uint32_t relpos_inBox = 0; + unsigned szItem, Tag, lTag; + ushort tItem; + +#define track libraw_internal_data.unpacker_data.crx_header[trackNum] + + if (track.MediaType != 3) + { + err = -10; + goto ctmd_fin; + } + + while (relpos_inDir + 6 < track.MediaSize) + { + if (track.MediaOffset + relpos_inDir > ifp->size() - 6) // need at least 6 bytes + { + err = -11; + goto ctmd_fin; + } + fseek(ifp, track.MediaOffset + relpos_inDir, SEEK_SET); + szItem = get4(); + tItem = get2(); + if (szItem < 1 || ( (relpos_inDir + szItem) > track.MediaSize)) + { + err = -11; + goto ctmd_fin; + } + if ((tItem == 7) || (tItem == 8) || (tItem == 9)) + { + relpos_inBox = relpos_inDir + 12L; + while (relpos_inBox + 8 < relpos_inDir + szItem) + { + if (track.MediaOffset + relpos_inBox > ifp->size() - 8) // need at least 8 bytes + { + err = -11; + goto ctmd_fin; + } + fseek(ifp, track.MediaOffset + relpos_inBox, SEEK_SET); + lTag = get4(); + Tag = get4(); + if (lTag < 8) + { + err = -12; + goto ctmd_fin; + } + else if ((relpos_inBox + lTag) > (relpos_inDir + szItem)) + { + err = -11; + goto ctmd_fin; + } + if ((Tag == 0x927c) && ((tItem == 7) || (tItem == 8))) + { + fseek(ifp, track.MediaOffset + relpos_inBox + 8L, + SEEK_SET); + short q_order = order; + order = get2(); + if (bad_hdr()) + { + err = -13; + goto ctmd_fin; + } + fseek(ifp, -8L, SEEK_CUR); + libraw_internal_data.unpacker_data.CR3_CTMDtag = 1; + parse_makernote(track.MediaOffset + relpos_inBox + 8, + 0); + libraw_internal_data.unpacker_data.CR3_CTMDtag = 0; + order = q_order; + } + relpos_inBox += lTag; + } + } + relpos_inDir += szItem; + } + +ctmd_fin: + order = s_order; + return err; +} +#undef track + +int LibRaw::parseCR3(INT64 oAtomList, + INT64 szAtomList, short &nesting, + char *AtomNameStack, short &nTrack, short &TrackType) +{ + /* + Atom starts with 4 bytes for Atom size and 4 bytes containing Atom name + Atom size includes the length of the header and the size of all "contained" + Atoms if Atom size == 1, Atom has the extended size stored in 8 bytes located + after the Atom name if Atom size == 0, it is the last top-level Atom extending + to the end of the file Atom name is often a 4 symbol mnemonic, but can be a + 4-byte integer + */ + const char UIID_Canon[17] = + "\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48"; + const unsigned char UIID_CanonPreview[17] = "\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16"; + const unsigned char UUID_XMP[17] = "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac"; + + /* + AtomType = 0 - unknown: "unk." + AtomType = 1 - container atom: "cont" + AtomType = 2 - leaf atom: "leaf" + AtomType = 3 - can be container, can be leaf: "both" + */ + short AtomType; + static const struct + { + char AtomName[5]; + short AtomType; + } AtomNamesList[] = { + {"dinf", 1}, + {"edts", 1}, + {"fiin", 1}, + {"ipro", 1}, + {"iprp", 1}, + {"mdia", 1}, + {"meco", 1}, + {"mere", 1}, + {"mfra", 1}, + {"minf", 1}, + {"moof", 1}, + {"moov", 1}, + {"mvex", 1}, + {"paen", 1}, + {"schi", 1}, + {"sinf", 1}, + {"skip", 1}, + {"stbl", 1}, + {"stsd", 1}, + {"strk", 1}, + {"tapt", 1}, + {"traf", 1}, + {"trak", 1}, + + {"cdsc", 2}, + {"colr", 2}, + {"dimg", 2}, + // {"dref", 2}, + {"free", 2}, + {"frma", 2}, + {"ftyp", 2}, + {"hdlr", 2}, + {"hvcC", 2}, + {"iinf", 2}, + {"iloc", 2}, + {"infe", 2}, + {"ipco", 2}, + {"ipma", 2}, + {"iref", 2}, + {"irot", 2}, + {"ispe", 2}, + {"meta", 2}, + {"mvhd", 2}, + {"pitm", 2}, + {"pixi", 2}, + {"schm", 2}, + {"thmb", 2}, + {"tkhd", 2}, + {"url ", 2}, + {"urn ", 2}, + + {"CCTP", 1}, + {"CRAW", 1}, + + {"JPEG", 2}, + {"CDI1", 2}, + {"CMP1", 2}, + + {"CNCV", 2}, + {"CCDT", 2}, + {"CTBO", 2}, + {"CMT1", 2}, + {"CMT2", 2}, + {"CMT3", 2}, + {"CMT4", 2}, + {"CNOP", 2}, + {"THMB", 2}, + {"co64", 2}, + {"mdat", 2}, + {"mdhd", 2}, + {"nmhd", 2}, + {"stsc", 2}, + {"stsz", 2}, + {"stts", 2}, + {"vmhd", 2}, + + {"dref", 3}, + {"uuid", 3}, + }; + + const char sHandlerType[5][5] = {"unk.", "soun", "vide", "hint", "meta"}; + + int c, err=0; + + ushort tL; // Atom length represented in 4 or 8 bytes + char nmAtom[5]; // Atom name + INT64 oAtom, szAtom; // Atom offset and Atom size + INT64 oAtomContent, + szAtomContent; // offset and size of Atom content + INT64 lHdr; + + char UIID[16]; + uchar CMP1[85]; + uchar CDI1[60]; + char HandlerType[5], MediaFormatID[5]; + uint32_t relpos_inDir, relpos_inBox; + unsigned szItem, Tag, lTag; + ushort tItem; + + nmAtom[0] = MediaFormatID[0] = nmAtom[4] = MediaFormatID[4] = '\0'; + strcpy(HandlerType, sHandlerType[0]); + oAtom = oAtomList; + nesting++; + if (nesting > 31) + return -14; // too deep nesting + short s_order = order; + + while ((oAtom + 8LL) <= (oAtomList + szAtomList)) + { + lHdr = 0ULL; + err = 0; + order = 0x4d4d; + fseek(ifp, oAtom, SEEK_SET); + szAtom = get4(); + FORC4 nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp); + AtomNameStack[(nesting + 1) * 4] = '\0'; + tL = 4; + AtomType = 0; + + for (c = 0; c < int(sizeof AtomNamesList / sizeof *AtomNamesList); c++) + if (!strcmp(nmAtom, AtomNamesList[c].AtomName)) + { + AtomType = AtomNamesList[c].AtomType; + break; + } + + if (!AtomType) + { + err = 1; + } + + if (szAtom == 0ULL) + { + if (nesting != 0) + { + err = -2; + goto fin; + } + szAtom = szAtomList - oAtom; + oAtomContent = oAtom + 8ULL; + szAtomContent = szAtom - 8ULL; + } + else if (szAtom == 1LL) + { + if ((oAtom + 16LL) > (oAtomList + szAtomList)) + { + err = -3; + goto fin; + } + tL = 8; + szAtom = (((unsigned long long)get4()) << 32) | get4(); + oAtomContent = oAtom + 16ULL; + szAtomContent = szAtom - 16ULL; + } + else + { + oAtomContent = oAtom + 8ULL; + szAtomContent = szAtom - 8ULL; + } + + if (!strcmp(AtomNameStack, "uuid")) // Top level uuid + { + INT64 tt = ftell(ifp); + lHdr = 16ULL; + fread(UIID, 1, lHdr, ifp); + if (!memcmp(UIID, UUID_XMP, 16) && szAtom > 24LL && szAtom < 1024000LL) + { + xmpdata = (char *)malloc(xmplen = unsigned(szAtom - 23)); + fread(xmpdata, szAtom - 24, 1, ifp); + xmpdata[szAtom - 24] = 0; + } + else if (!memcmp(UIID, UIID_CanonPreview, 16) && szAtom > 48LL && szAtom < 100LL * 1024000LL) + { + // read next 48 bytes, check for 'PRVW' + unsigned char xdata[32]; + fread(xdata, 32, 1, ifp); + if (!memcmp(xdata + 12, "PRVW", 4)) + { + thumb_length = unsigned(szAtom - 56); + thumb_offset = ftell(ifp); + if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) + { + bool do_add = true; + for(int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) + if (imgdata.thumbs_list.thumblist[idx].toffset == thumb_offset) + { + do_add = false; + break; + } + if (do_add) + { + int idx = imgdata.thumbs_list.thumbcount; + imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; + imgdata.thumbs_list.thumblist[idx].toffset = thumb_offset; + imgdata.thumbs_list.thumblist[idx].tlength = thumb_length; + imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; + imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps + imgdata.thumbs_list.thumblist[idx].twidth = (xdata[22] << 8) + xdata[23]; + imgdata.thumbs_list.thumblist[idx].theight = (xdata[24] << 8) + xdata[25]; + imgdata.thumbs_list.thumbcount++; + } + } + + } + } + fseek(ifp, tt, SEEK_SET); + } + + if (!strcmp(nmAtom, "trak")) + { + nTrack++; + TrackType = 0; + if (nTrack >= LIBRAW_CRXTRACKS_MAXCOUNT) + break; + } + if (!strcmp(AtomNameStack, "moovuuid")) + { + lHdr = 16ULL; + fread(UIID, 1, lHdr, ifp); + if (!strncmp(UIID, UIID_Canon, lHdr)) + { + AtomType = 1; + } + else + fseek(ifp, -lHdr, SEEK_CUR); + } + else if (!strcmp(AtomNameStack, "moovuuidCCTP")) + { + lHdr = 12ULL; + } + else if (!strcmp(AtomNameStack, "moovuuidCMT1")) + { + short q_order = order; + order = get2(); + if ((tL != 4) || bad_hdr()) + { + err = -4; + goto fin; + } + if (!libraw_internal_data.unpacker_data.cr3_ifd0_length) + libraw_internal_data.unpacker_data.cr3_ifd0_length = unsigned(szAtomContent); + parse_tiff_ifd(oAtomContent); + order = q_order; + } + else if (!strcmp(AtomNameStack, "moovuuidTHMB") && szAtom > 24) + { + unsigned char xdata[16]; + fread(xdata, 16, 1, ifp); + INT64 xoffset = ftell(ifp); + if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) + { + bool do_add = true; + for (int idx = 0; idx < imgdata.thumbs_list.thumbcount; idx++) + if (imgdata.thumbs_list.thumblist[idx].toffset == xoffset) + { + do_add = false; + break; + } + if (do_add) + { + int idx = imgdata.thumbs_list.thumbcount; + imgdata.thumbs_list.thumblist[idx].tformat = LIBRAW_INTERNAL_THUMBNAIL_JPEG; + imgdata.thumbs_list.thumblist[idx].toffset = xoffset; + imgdata.thumbs_list.thumblist[idx].tlength = szAtom-24; + imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; + imgdata.thumbs_list.thumblist[idx].tmisc = (3 << 5) | 8; // 3 samples/8 bps + imgdata.thumbs_list.thumblist[idx].twidth = (xdata[4] << 8) + xdata[5]; + imgdata.thumbs_list.thumblist[idx].theight = (xdata[6] << 8) + xdata[7]; + imgdata.thumbs_list.thumbcount++; + } + } + } + else if (!strcmp(AtomNameStack, "moovuuidCMT2")) + { + short q_order = order; + order = get2(); + if ((tL != 4) || bad_hdr()) + { + err = -5; + goto fin; + } + if (!libraw_internal_data.unpacker_data.cr3_exif_length) + libraw_internal_data.unpacker_data.cr3_exif_length = unsigned(szAtomContent); + parse_exif(oAtomContent); + order = q_order; + } + else if (!strcmp(AtomNameStack, "moovuuidCMT3")) + { + short q_order = order; + order = get2(); + if ((tL != 4) || bad_hdr()) + { + err = -6; + goto fin; + } + fseek(ifp, -12L, SEEK_CUR); + parse_makernote(oAtomContent, 0); + order = q_order; + } + else if (!strcmp(AtomNameStack, "moovuuidCMT4")) + { + short q_order = order; + order = get2(); + if ((tL != 4) || bad_hdr()) + { + err = -6; + goto fin; + } + INT64 off = ftell(ifp); + parse_gps(oAtomContent); + fseek(ifp, off, SEEK_SET); + parse_gps_libraw(oAtomContent); + order = q_order; + } + else if (!strcmp(AtomNameStack, "moovtrakmdiahdlr")) + { + fseek(ifp, 8L, SEEK_CUR); + FORC4 HandlerType[c] = fgetc(ifp); + for (c = 1; c < int(sizeof sHandlerType / sizeof *sHandlerType); c++) + if (!strcmp(HandlerType, sHandlerType[c])) + { + TrackType = c; + break; + } + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsd")) + { + if (szAtomContent >= 16) + { + fseek(ifp, 12L, SEEK_CUR); + lHdr = 8; + } + else + { + err = -7; + goto fin; + } + FORC4 MediaFormatID[c] = fgetc(ifp); + if ((TrackType == 2) && (!strcmp(MediaFormatID, "CRAW"))) + { + if (szAtomContent >= 44) + fseek(ifp, 24L, SEEK_CUR); + else + { + err = -8; + goto fin; + } + } + else + { + AtomType = 2; // only continue for CRAW + lHdr = 0; + } +#define current_track libraw_internal_data.unpacker_data.crx_header[nTrack] + + /*ImageWidth =*/ get2(); + /*ImageHeight =*/ get2(); + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAW")) + { + lHdr = 82; + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCMP1")) + { + int read_size = szAtomContent > 85 ? 85 : szAtomContent; + if (szAtomContent >= 40) + fread(CMP1, 1, read_size, ifp); + else + { + err = -7; + goto fin; + } + if (!crxParseImageHeader(CMP1, nTrack, read_size)) + current_track.MediaType = 1; + } + + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWCDI1")) { + if (szAtomContent >= 60) { + fread(CDI1, 1, 60, ifp); + if (!strncmp((char *)CDI1+8, "IAD1", 4) && (sgetn(8, CDI1) == 0x38)) { + // sensor area at CDI1+12, 4 16-bit values + // Bayer pattern? - next 4 16-bit values + imCanon.RecommendedImageArea = sget_CanonArea(CDI1+12 + 2*4*2); + imCanon.LeftOpticalBlack = sget_CanonArea(CDI1+12 + 3*4*2); + imCanon.UpperOpticalBlack = sget_CanonArea(CDI1+12 + 4*4*2); + imCanon.ActiveArea = sget_CanonArea(CDI1+12 + 5*4*2); + } + } + } + + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsdCRAWJPEG")) + { + current_track.MediaType = 2; + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsc")) + { + if (szAtomContent >= 12) { + fseek(ifp, 4L, SEEK_CUR); + int entries = get4(); + if (entries < 1 || entries > 1000000) + { + err = -9; + goto fin; + } + + current_track.stsc_data = (crx_sample_to_chunk_t*) malloc(entries * sizeof(crx_sample_to_chunk_t)); + if(!current_track.stsc_data) + { + err = -9; + goto fin; + } + current_track.stsc_count = entries; + for(int i = 0; i < entries; i++) + { + current_track.stsc_data[i].first = get4(); + current_track.stsc_data[i].count = get4(); + current_track.stsc_data[i].id = get4(); + } + } + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblstsz")) + { + if (szAtomContent >= 12) + { + fseek(ifp, 4L, SEEK_CUR); + int sample_size = get4(); + int entries = get4(); + current_track.sample_count = entries; + + // if sample size is zero sample size is fixed + if (sample_size) + { + current_track.MediaSize = sample_size; + current_track.sample_size = sample_size; + } + else + { + current_track.sample_size = 0; + if (entries < 1 || entries > 1000000) { + err = -10; + goto fin; + } + current_track.sample_sizes = (int32_t*)malloc(entries * sizeof(int32_t)); + if (!current_track.sample_sizes) + { + err = -10; + goto fin; + } + for (int i = 0; i < entries; i++) + current_track.sample_sizes[i] = get4(); + + current_track.MediaSize = current_track.sample_sizes[0]; + } + } + } + else if (!strcmp(AtomNameStack, "moovtrakmdiaminfstblco64")) + { + if (szAtomContent >= 16) { + fseek(ifp, 4L, SEEK_CUR); + uint32_t entries = get4(); + int i; + if (entries < 1 || entries > 1000000) + { + err = -11; + goto fin; + } + current_track.chunk_offsets = (INT64*)malloc(entries * sizeof(int64_t)); + if(!current_track.chunk_offsets) + { + err = -11; + goto fin; + } + + current_track.chunk_count = entries; + for (i = 0; i < entries; i++) + current_track.chunk_offsets[i] = (((int64_t)get4()) << 32) | get4(); + + current_track.chunk_count = i; + current_track.MediaOffset = current_track.chunk_offsets[0]; + } + } + + if (nTrack >= 0 && nTrack < LIBRAW_CRXTRACKS_MAXCOUNT && + current_track.MediaSize && current_track.MediaOffset && + ((oAtom + szAtom) >= (oAtomList + szAtomList)) && + !strncmp(AtomNameStack, "moovtrakmdiaminfstbl", 20)) + { + if ((TrackType == 4) && (!strcmp(MediaFormatID, "CTMD"))) + { + current_track.MediaType = 3; + } + } +#undef current_track + if (AtomType == 1) + { + err = parseCR3(oAtomContent + lHdr, szAtomContent - lHdr, nesting, + AtomNameStack, nTrack, TrackType); + if (err) + goto fin; + } + oAtom += szAtom; + } + +fin: + nesting--; + if (nesting >= 0) + AtomNameStack[nesting * 4] = '\0'; + order = s_order; + return err; +} +#undef bad_hdr + +void LibRaw::parseCR3_Free() +{ + short maxTrack = libraw_internal_data.unpacker_data.crx_track_count; + if (maxTrack < 0) + return; + + for (int i = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) + { + crx_data_header_t *d = &libraw_internal_data.unpacker_data.crx_header[i]; + if (d->stsc_data) + { + free(d->stsc_data); + d->stsc_data = NULL; + } + if (d->chunk_offsets) + { + free(d->chunk_offsets); + d->chunk_offsets = NULL; + } + + if (d->sample_sizes) + { + free(d->sample_sizes); + d->sample_sizes = NULL; + } + d->stsc_count = 0; + d->sample_count = 0; + d->sample_size = 0; + d->chunk_count = 0; + } + libraw_internal_data.unpacker_data.crx_track_count = -1; +} diff --git a/src/metadata/epson.cpp b/src/metadata/epson.cpp new file mode 100644 index 000000000..427d98e9c --- /dev/null +++ b/src/metadata/epson.cpp @@ -0,0 +1,96 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parseEpsonMakernote(int base, int uptag, unsigned dng_writer) +{ + +#define isRIC imgdata.sizes.raw_inset_crops[0] + + unsigned entries, tag, type, len, save; + short morder, sorder = order; + ushort c; + INT64 fsize = ifp->size(); + + fseek(ifp, -2, SEEK_CUR); + + entries = get2(); + if (entries > 1000) + return; + morder = order; + + while (entries--) + { + order = morder; + tiff_get(base, &tag, &type, &len, &save); + INT64 pos = ifp->tell(); + if (len > 8 && pos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + + tag |= uptag << 16; + if (len > 100 * 1024 * 1024) + goto next; // 100Mb tag? No! + + if (tag == 0x020b) + { + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + isRIC.cwidth = get4(); + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + isRIC.cwidth = get2(); + } + else if (tag == 0x020c) + { + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + isRIC.cheight = get4(); + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + isRIC.cheight = get2(); + } + else if (tag == 0x0400) + { // sensor area + ushort sdims[4] = {0, 0, 0, 0}; // left margin, top margin, width, height + FORC4 sdims[c] = get2(); + isRIC.cleft = (sdims[2] - sdims[0] - isRIC.cwidth) / 2; + isRIC.ctop = (sdims[3] - sdims[1] - isRIC.cheight) / 2; + } + + if (dng_writer == nonDNG) + { + + if (tag == 0x0280) + { + thumb_offset = ftell(ifp); + thumb_length = len; + } + else if (tag == 0x0401) + { + FORC4 cblack[RGGB_2_RGBG(c)] = get4(); + } + else if (tag == 0x0e80) + { + fseek(ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 567.0 / 0x10000; + cam_mul[2] = get2() * 431.0 / 0x10000; + } + } + + next: + fseek(ifp, save, SEEK_SET); + } + order = sorder; +#undef isRIC +} diff --git a/src/metadata/exif_gps.cpp b/src/metadata/exif_gps.cpp new file mode 100644 index 000000000..7fb3b53ff --- /dev/null +++ b/src/metadata/exif_gps.cpp @@ -0,0 +1,430 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +void LibRaw::parse_exif_interop(int base) +{ + unsigned entries, tag, type, len, save; + char value[4] = { 0,0,0,0 }; + entries = get2(); + INT64 fsize = ifp->size(); + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + + INT64 savepos = ftell(ifp); + if (len > 8 && savepos + len > fsize * 2) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + if (callbacks.exif_cb) + { + callbacks.exif_cb(callbacks.exifparser_data, tag | 0x40000, type, len, order, ifp, base); + fseek(ifp, savepos, SEEK_SET); + } + + switch (tag) + { + case 0x0001: // InteropIndex + fread(value, 1, MIN(4, len), ifp); + if (strncmp(value, "R98", 3) == 0 && + // Canon bug, when [Canon].ColorSpace = AdobeRGB, + // but [ExifIFD].ColorSpace = Uncalibrated and + // [InteropIFD].InteropIndex = "R98" + imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown) + imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB; + else if (strncmp(value, "R03", 3) == 0) + imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + } + fseek(ifp, save, SEEK_SET); + } +} + +void LibRaw::parse_exif(int base) +{ + unsigned entries, tag, type, len, save, c; + double expo, ape; + + unsigned kodak = !strncmp(make, "EASTMAN", 7) && tiff_nifds < 3; + + if (!libraw_internal_data.unpacker_data.exif_subdir_offset) + { + libraw_internal_data.unpacker_data.exif_offset = base; + libraw_internal_data.unpacker_data.exif_subdir_offset = ftell(ifp); + } + + entries = get2(); + if (!strncmp(make, "Hasselblad", 10) && (tiff_nifds > 3) && (entries > 512)) + return; + INT64 fsize = ifp->size(); + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + + INT64 savepos = ftell(ifp); + if (len > 8 && savepos + len > fsize * 2) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + if (callbacks.exif_cb) + { + callbacks.exif_cb(callbacks.exifparser_data, tag, type, len, order, ifp, + base); + fseek(ifp, savepos, SEEK_SET); + } + + switch (tag) + { + case 0xA005: // Interoperability IFD + fseek(ifp, get4() + base, SEEK_SET); + parse_exif_interop(base); + break; + case 0xA001: // ExifIFD.ColorSpace + c = get2(); + if (c == 1 && imgdata.color.ExifColorSpace == LIBRAW_COLORSPACE_Unknown) + imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_sRGB; + else if (c == 2) + imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + case 0x9400: + imCommon.exifAmbientTemperature = getreal(type); + if ((imCommon.CameraTemperature > -273.15f) && + ((OlyID == OlyID_TG_5) || + (OlyID == OlyID_TG_6)) + ) + imCommon.CameraTemperature += imCommon.exifAmbientTemperature; + break; + case 0x9401: + imCommon.exifHumidity = getreal(type); + break; + case 0x9402: + imCommon.exifPressure = getreal(type); + break; + case 0x9403: + imCommon.exifWaterDepth = getreal(type); + break; + case 0x9404: + imCommon.exifAcceleration = getreal(type); + break; + case 0x9405: + imCommon.exifCameraElevationAngle = getreal(type); + break; + + case 0xa405: // FocalLengthIn35mmFormat + imgdata.lens.FocalLengthIn35mmFormat = get2(); + break; + case 0xa431: // BodySerialNumber + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + break; + case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard + imgdata.lens.MinFocal = getreal(type); + imgdata.lens.MaxFocal = getreal(type); + imgdata.lens.MaxAp4MinFocal = getreal(type); + imgdata.lens.MaxAp4MaxFocal = getreal(type); + break; + case 0xa435: // LensSerialNumber + stmread(imgdata.lens.LensSerial, len, ifp); + if (!strncmp(imgdata.lens.LensSerial, "----", 4)) + imgdata.lens.LensSerial[0] = '\0'; + break; + case 0xa420: /* 42016, ImageUniqueID */ + stmread(imgdata.color.ImageUniqueID, len, ifp); + break; + case 0xc65d: /* 50781, RawDataUniqueID */ + imgdata.color.RawDataUniqueID[16] = 0; + fread(imgdata.color.RawDataUniqueID, 1, 16, ifp); + break; + case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard + imgdata.lens.dng.MinFocal = getreal(type); + imgdata.lens.dng.MaxFocal = getreal(type); + imgdata.lens.dng.MaxAp4MinFocal = getreal(type); + imgdata.lens.dng.MaxAp4MaxFocal = getreal(type); + break; + case 0xc68b: /* 50827, OriginalRawFileName */ + stmread(imgdata.color.OriginalRawFileName, len, ifp); + break; + case 0xa433: // LensMake + stmread(imgdata.lens.LensMake, len, ifp); + break; + case 0xa434: // LensModel + stmread(imgdata.lens.Lens, len, ifp); + if (!strncmp(imgdata.lens.Lens, "----", 4)) + imgdata.lens.Lens[0] = '\0'; + break; + case 0x9205: + imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f)); + break; + case 0x829a: // 33434 + shutter = getreal(type); + if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT) + tiff_ifd[tiff_nifds - 1].t_shutter = shutter; + break; + case 0x829d: // 33437, FNumber + aperture = getreal(type); + break; + case 0x8827: // 34855 + iso_speed = get2(); + break; + case 0x8831: // 34865 + if (iso_speed == 0xffff && !strncasecmp(make, "FUJI", 4)) + iso_speed = getreal(type); + break; + case 0x8832: // 34866 + if (iso_speed == 0xffff && + (!strncasecmp(make, "SONY", 4) || !strncasecmp(make, "CANON", 5))) + iso_speed = getreal(type); + break; + case 0x9003: // 36867 + case 0x9004: // 36868 + get_timestamp(0); + break; + case 0x9201: // 37377 + if ((expo = -getreal(type)) < 128 && shutter == 0.) + { + shutter = libraw_powf64l(2.0, expo); + if (tiff_nifds > 0 && tiff_nifds <= LIBRAW_IFD_MAXCOUNT) + tiff_ifd[tiff_nifds - 1].t_shutter = shutter; + } + break; + case 0x9202: // 37378 ApertureValue + if ((fabs(ape = getreal(type)) < 256.0) && (!aperture)) + aperture = libraw_powf64l(2.0, ape / 2); + break; + case 0x9209: // 37385 + flash_used = getreal(type); + break; + case 0x920a: // 37386 + focal_len = getreal(type); + break; + case 0x927c: // 37500 +#ifndef USE_6BY9RPI + if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) || + (!strncmp(make, "RaspberryPi", 11) && + (!strncmp(model, "RP_OV5647", 9) || + !strncmp(model, "RP_imx219", 9)))) +#else + if (((make[0] == '\0') && !strncmp(model, "ov5647", 6)) || + (!strncmp(make, "RaspberryPi", 11) && + (!strncmp(model, "RP_", 3) || !strncmp(model,"imx477",6)))) +#endif + { + char mn_text[512]; + char *pos; + char ccms[512]; + ushort l; + float num; + + fgets(mn_text, MIN(len, 511), ifp); + mn_text[511] = 0; + + pos = strstr(mn_text, "ev="); + if (pos) + imCommon.ExposureCalibrationShift = atof(pos + 3); + + pos = strstr(mn_text, "gain_r="); + if (pos) + cam_mul[0] = atof(pos + 7); + pos = strstr(mn_text, "gain_b="); + if (pos) + cam_mul[2] = atof(pos + 7); + if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f)) + cam_mul[1] = cam_mul[3] = 1.0f; + else + cam_mul[0] = cam_mul[2] = 0.0f; + + pos = strstr(mn_text, "ccm="); + if (pos) + { + pos += 4; + char *pos2 = strstr(pos, " "); + if (pos2) + { + l = pos2 - pos; + memcpy(ccms, pos, l); + ccms[l] = '\0'; +#ifdef LIBRAW_WIN32_CALLS + // Win32 strtok is already thread-safe + pos = strtok(ccms, ","); +#else + char *last = 0; + pos = strtok_r(ccms, ",", &last); +#endif + if (pos) + { + for (l = 0; l < 3; l++) // skip last row + { + num = 0.0; + for (c = 0; c < 3; c++) + { + cmatrix[l][c] = (float)atoi(pos); + num += cmatrix[c][l]; +#ifdef LIBRAW_WIN32_CALLS + pos = strtok(NULL, ","); +#else + pos = strtok_r(NULL, ",", &last); +#endif + if (!pos) + goto end; // broken + } + if (num > 0.01) + FORC3 cmatrix[l][c] = cmatrix[l][c] / num; + } + } + } + } + end:; + } + else if (!strncmp(make, "SONY", 4) && + (!strncmp(model, "DSC-V3", 6) || !strncmp(model, "DSC-F828", 8))) + { + parseSonySRF(len); + break; + } + else if ((len == 1) && !strncmp(make, "NIKON", 5)) + { + c = get4(); + if (c) + fseek(ifp, c, SEEK_SET); + is_NikonTransfer = 1; + } + parse_makernote(base, 0); + break; + case 0xa002: // 40962 + if (kodak) + raw_width = get4(); + break; + case 0xa003: // 40963 + if (kodak) + raw_height = get4(); + break; + case 0xa302: // 41730 + if (get4() == 0x20002) + for (exif_cfa = c = 0; c < 8; c += 2) + exif_cfa |= fgetc(ifp) * 0x01010101U << c; + } + fseek(ifp, save, SEEK_SET); + } +} + +void LibRaw::parse_gps_libraw(int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + if (entries > 40) + return; + if (entries > 0) + imgdata.other.parsed_gps.gpsparsed = 1; + INT64 fsize = ifp->size(); + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + if (len > 1024) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; // no GPS tags are 1k or larger + } + INT64 savepos = ftell(ifp); + if (len > 8 && savepos + len > fsize * 2) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + + if (callbacks.exif_cb) + { + callbacks.exif_cb(callbacks.exifparser_data, tag | 0x50000, type, len, order, ifp, base); + fseek(ifp, savepos, SEEK_SET); + } + + switch (tag) + { + case 0x0001: + imgdata.other.parsed_gps.latref = getc(ifp); + break; + case 0x0003: + imgdata.other.parsed_gps.longref = getc(ifp); + break; + case 0x0005: + imgdata.other.parsed_gps.altref = getc(ifp); + break; + case 0x0002: + if (len == 3) + FORC(3) imgdata.other.parsed_gps.latitude[c] = getreal(type); + break; + case 0x0004: + if (len == 3) + FORC(3) imgdata.other.parsed_gps.longitude[c] = getreal(type); + break; + case 0x0007: + if (len == 3) + FORC(3) imgdata.other.parsed_gps.gpstimestamp[c] = getreal(type); + break; + case 0x0006: + imgdata.other.parsed_gps.altitude = getreal(type); + break; + case 0x0009: + imgdata.other.parsed_gps.gpsstatus = getc(ifp); + break; + } + fseek(ifp, save, SEEK_SET); + } +} + +void LibRaw::parse_gps(int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + if (entries > 40) + return; + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + if (len > 1024) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; // no GPS tags are 1k or larger + } + switch (tag) + { + case 0x0001: + case 0x0003: + case 0x0005: + gpsdata[29 + tag / 2] = getc(ifp); + break; + case 0x0002: + case 0x0004: + case 0x0007: + FORC(6) gpsdata[tag / 3 * 6 + c] = get4(); + break; + case 0x0006: + FORC(2) gpsdata[18 + c] = get4(); + break; + case 0x0012: // 18 + case 0x001d: // 29 + fgets((char *)(gpsdata + 14 + tag / 3), MIN(len, 12), ifp); + } + fseek(ifp, save, SEEK_SET); + } +} diff --git a/src/metadata/fuji.cpp b/src/metadata/fuji.cpp new file mode 100644 index 000000000..4c9fe5025 --- /dev/null +++ b/src/metadata/fuji.cpp @@ -0,0 +1,1427 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to first valid width/height pair +{ + +/* RAFDataGeneration codes, values are 4 bytes, little endian + + RAFData gen. 0: no RAFData + DBP for GX680 / DX-2000 + E550, E900, (F500 / F505?) F550, F600 / F605, F700, F770 / F775, F800, F810, F900 + HS10 HS11, HS20 / HS22, HS30 / HS33 / HS35, HS50 + S1, SL1000, S100, S200 / S205, S20Pro, S2Pro, S3Pro, S5Pro + S5000, S5100 / S5500, S5200 / S5600, S6000 / S6500, S7000, S9000 / S9500, S9100 / S9600 + + RAFData gen. 1, offset to WH pair (offsetWH_inRAFData) = 0: + - number in bytes 0..1 is less than 10000 + - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values (for crops, scales?) + X100, X-Pro1, X-S1, X10, XF1 + + RAFData gen. 2, offset to WH pair = 4: + - bytes 0..1 contain a number greater than 10000; bytes 2..3 contain zero; + version is in bytes 0..1, possibly big endian + - contains WH pair, recommended image size WH pair, 16 bytes unknown, 2*13 values + X-E1 + + RAFData gen. 3, offset to WH pair = 4: + - bytes 0..1 contain zero; bytes 2..3 contain version; + - contains a table of 3+2*13 values; first 3 values look like WHW + X-A1, X-A2, X-E2, X-M1 + X-T1, X-T10 + X100S, X100T + X20, X30, X70, XQ1, XQ2 + + RAFData gen. 4, offset to WH pair = 8: + - same conditions as for RAFData gen. 3, but also adds WRTS in bytes 4..7 + - contains a table of 3+2*13 values; first 3 values look like WHW + - H in WHW group has a different meaning if the shot is taken in crop 2 mode + GFX 100, GFX 100S, GFX 50R, GFX 50S, GFX 50S II + X-E2S, X-E3, X-H1, X-S10 + X-T2, X-T3, X-T4, X-T20, X-T30 + X-Pro2, X-Pro3 + X100F, X100V + + RAFData gen. set to 4096: + - RAFData length is exactly 4096 + X-A3, X-A5, X-A7, X-A10, X-A20 + X-T100, X-T200, + XF10 +*/ + + int offsetWH_inRAFData=0; /* clang warns about not initialized value */ + ushort b01 = sget2(RAFData_start); // bytes 0..1 + ushort b23 = sget2(RAFData_start+2); // bytes 2..3 + int is_WRTS = (sget4(RAFData_start + 4) == 0x53545257); // STRW + if (b01 && !b23 && (b01<10000)) + { + imFuji.RAFDataGeneration = 1; + offsetWH_inRAFData = 0; + } + else if ((b01>10000) && !b23) + { + imFuji.RAFDataGeneration = 2; + imFuji.RAFDataVersion = b01; + offsetWH_inRAFData = 4; + } + else if (!b01) + { + if (!is_WRTS) + { + imFuji.RAFDataGeneration = 3; + offsetWH_inRAFData = 4; + } + else + { + imFuji.RAFDataGeneration = 4; + offsetWH_inRAFData = 8; + } + imFuji.RAFDataVersion = b23; + } + +// printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", +// imFuji.RAFDataVersion, imFuji.RAFDataGeneration); + + return offsetWH_inRAFData; +} + +void LibRaw::parseAdobeRAFMakernote() +{ + + uchar *PrivateMknBuf; + unsigned posPrivateMknBuf=0; /* clang warns about not inited value */ + unsigned PrivateMknLength; + unsigned PrivateOrder; + unsigned ifd_start, ifd_len; + unsigned PrivateEntries, PrivateTagID; + unsigned PrivateTagBytes; + int FujiShotSelect; + unsigned wb_section_offset = 0; + int posWB; + int c; + +#define CHECKSPACE_ABS3(s1, s2, s3) \ + if (INT64(s1) + INT64(s2) + INT64(s3) > INT64(PrivateMknLength)) \ + { \ + free(PrivateMknBuf); \ + return; \ + } + +#define CHECKSPACE_ABS2(s1,s2) \ + if (INT64(s1) + INT64(s2) > INT64(PrivateMknLength)) \ + { \ + free(PrivateMknBuf); \ + return; \ + } + +#define CHECKSPACE(s) \ + if (posPrivateMknBuf + (s) > PrivateMknLength) \ + { \ + free(PrivateMknBuf); \ + return; \ + } + +#define isWB(posWB) \ + sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 && \ + sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 && \ + sget2(posWB + 10) != 0 && sget2(posWB) != 0xff && \ + sget2(posWB + 2) != 0xff && sget2(posWB + 4) != 0xff && \ + sget2(posWB + 6) != 0xff && sget2(posWB + 8) != 0xff && \ + sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) && \ + sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) && \ + sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10) + +#define get_average_WB(wb_index) \ + CHECKSPACE(8); \ + FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ + sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); \ + if ((PrivateTagBytes == 16) && average_WBData) { \ + CHECKSPACE(16); \ + FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ + (icWBC[wb_index][GRGB_2_RGBG(c)] + \ + sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)+8)) /2; \ + } \ + if (use_WBcorr_coeffs) { \ + icWBC[wb_index][0] *= wbR_corr; \ + icWBC[wb_index][2] *= wbB_corr; \ + } + + ushort use_WBcorr_coeffs = 0; + double wbR_corr = 1.0; + double wbB_corr = 1.0; + + if (strstr(model, "S2Pro") + || strstr(model, "S20Pro") + || strstr(model, "F700") + || strstr(model, "S5000") + || strstr(model, "S7000") + ) { + use_WBcorr_coeffs = 1; + wbR_corr = 10.0 / 17.0 / 0.652941; + wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); + } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { + use_WBcorr_coeffs = 1; + wbR_corr = 0.7632653061; + wbB_corr = 0.8591549296; + } + + FujiShotSelect = LIM(shot_select, 0, 1); + int average_WBData = 1; + + order = 0x4d4d; + PrivateMknLength = get4(); + + // At least 0x36 bytes because of memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); + if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000) && + (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024))) // 1024b for safety + { + fread(PrivateMknBuf, PrivateMknLength, 1, ifp); + memcpy(imFuji.SerialSignature, PrivateMknBuf + 6, 0x0c); + imFuji.SerialSignature[0x0c] = 0; + memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); + imFuji.SensorID[0x04] = 0; + c = 11; + while (isdigit(imFuji.SerialSignature[c]) && (c>0)) + c--; + ilm.CamID = unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); + memcpy(model, PrivateMknBuf + 0x12, 0x20); + model[0x20] = 0; + memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); + imFuji.RAFVersion[4] = 0; + + PrivateOrder = sget2(PrivateMknBuf); + unsigned s, l; + s = ifd_start = sget4(PrivateMknBuf +2)+6; + CHECKSPACE(ifd_start+4); + l = ifd_len = sget4(PrivateMknBuf +ifd_start); + CHECKSPACE_ABS3(ifd_start, ifd_len, 4); + + if (!sget4(PrivateMknBuf+ifd_start+ifd_len+4)) + FujiShotSelect = 0; + + if ((FujiShotSelect == 1) && (PrivateMknLength > ifd_len*2)) { + ifd_start += (ifd_len+4); + CHECKSPACE_ABS2(ifd_start, 4); + ifd_len = sget4(PrivateMknBuf +ifd_start); + if ((ifd_start+ifd_len) > PrivateMknLength) { + ifd_start = s; + ifd_len = l; + FujiShotSelect = 0; + } + } else FujiShotSelect = 0; + + CHECKSPACE_ABS3(ifd_start, 4, 4); + PrivateEntries = sget4(PrivateMknBuf + ifd_start + 4); + if ((PrivateEntries > 1000) || + ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) + { + free(PrivateMknBuf); + return; + } + posPrivateMknBuf = (ifd_start+8); + + /* + * because Adobe DNG converter strips or misplaces 0xfnnn tags, + * for now, Auto WB is missing for the following cameras: + * - F550EXR / F600EXR / F770EXR / F800EXR / F900EXR + * - HS10 / HS11 / HS20EXR / HS30EXR / HS33EXR / HS35EXR / HS50EXR + * - S1 / SL1000 + **/ + while (PrivateEntries--) + { + order = 0x4d4d; + CHECKSPACE(4); + PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); + PrivateTagBytes = sget2(PrivateMknBuf + posPrivateMknBuf + 2); + posPrivateMknBuf += 4; + order = PrivateOrder; + + if (PrivateTagID == 0x2000) + { + get_average_WB(LIBRAW_WBI_Auto); + } + else if (PrivateTagID == 0x2100) + { + get_average_WB(LIBRAW_WBI_FineWeather); + } + else if (PrivateTagID == 0x2200) + { + get_average_WB(LIBRAW_WBI_Shade); + } + else if (PrivateTagID == 0x2300) + { + get_average_WB(LIBRAW_WBI_FL_D); + } + else if (PrivateTagID == 0x2301) + { + get_average_WB(LIBRAW_WBI_FL_N); + } + else if (PrivateTagID == 0x2302) + { + get_average_WB(LIBRAW_WBI_FL_W); + } + else if (PrivateTagID == 0x2310) + { + get_average_WB(LIBRAW_WBI_FL_WW); + } + else if (PrivateTagID == 0x2311) + { + get_average_WB(LIBRAW_WBI_FL_L); + } + else if (PrivateTagID == 0x2400) + { + get_average_WB(LIBRAW_WBI_Tungsten); + } + else if (PrivateTagID == 0x2410) + { + get_average_WB(LIBRAW_WBI_Flash); + } + else if (PrivateTagID == 0x2f00) + { + CHECKSPACE(4); + int nWBs = MIN(sget4(PrivateMknBuf + posPrivateMknBuf), 6); + posWB = posPrivateMknBuf + 4; + for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { + CHECKSPACE_ABS2(posWB, 8); + FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = + sget2(PrivateMknBuf + posWB + (c << 1)); + if ((PrivateTagBytes >= unsigned(4+16*nWBs)) && average_WBData) { + posWB += 8; + CHECKSPACE_ABS2(posWB, 8); + FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = + (icWBC[wb_ind][GRGB_2_RGBG(c)] + + sget2(PrivateMknBuf + posWB + (c << 1))) /2; + } + if (use_WBcorr_coeffs) { + icWBC[wb_ind][0] *= wbR_corr; + icWBC[wb_ind][2] *= wbB_corr; + } + posWB += 8; + } + } + else if (PrivateTagID == 0x2ff0) + { + get_average_WB(LIBRAW_WBI_AsShot); + FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_AsShot][c]; + } + else if ((PrivateTagID == 0x4000) && + ((PrivateTagBytes == 8) || (PrivateTagBytes == 16))) + { + imFuji.BlackLevel[0] = PrivateTagBytes / 2; + CHECKSPACE(10); + FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = + sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); + if (imFuji.BlackLevel[0] == 8) { + CHECKSPACE(18); + FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c) + 5] = + sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1) + 8); + } + } + else if (PrivateTagID == 0x9650) + { + CHECKSPACE(4); + short a = (short)sget2(PrivateMknBuf + posPrivateMknBuf); + float b = fMAX(1.0f, sget2(PrivateMknBuf + posPrivateMknBuf + 2)); + imFuji.ExpoMidPointShift = a / b; + imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; + } + else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) && + (PrivateTagBytes < 10240000)) + { + order = 0x4949; + if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 + { + int is34 = 0; + CHECKSPACE(8); + guess_RAFDataGeneration (PrivateMknBuf + posPrivateMknBuf); +// printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", +// imFuji.RAFDataVersion, imFuji.RAFDataGeneration); + + for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++) + { + CHECKSPACE_ABS2(posWB, 12); + if ((!memcmp(PrivateMknBuf + posWB, "TSNERDTS", 8) && + (sget2(PrivateMknBuf + posWB + 10) > 125))) + { + posWB += 10; + icWBC[LIBRAW_WBI_Auto][1] = + icWBC[LIBRAW_WBI_Auto][3] = + sget2(PrivateMknBuf + posWB); + icWBC[LIBRAW_WBI_Auto][0] = + sget2(PrivateMknBuf + posWB + 2); + icWBC[LIBRAW_WBI_Auto][2] = + sget2(PrivateMknBuf + posWB + 4); + break; + } + } + + if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S + (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II + (imFuji.RAFDataVersion == 0x0262) || // X-T4 + (imFuji.RAFDataVersion == 0x0264) || // X-S10 + (imFuji.RAFDataVersion == 0x0265) || // X-E4 + (imFuji.RAFDataVersion == 0x0266) || // X-T30 II + !strcmp(model, "X-Pro3") || + !strcmp(model, "GFX 100S") || + !strcmp(model, "GFX100S") || + !strcmp(model, "GFX 50S II") || + !strcmp(model, "GFX50S II") || + !strcmp(model, "X100V") || + !strcmp(model, "X-T4") || + !strcmp(model, "X-E4") || + !strcmp(model, "X-T30 II") || + !strcmp(model, "X-S10")) + is34 = 1; + + if (imFuji.RAFDataVersion == 0x4500) // X-E1, RAFData gen. 3 + { + wb_section_offset = 0x13ac; + } + else if (imFuji.RAFDataVersion == 0x0146 || // X20 + imFuji.RAFDataVersion == 0x0149 || // X100S + imFuji.RAFDataVersion == 0x0249) // X100S + { + wb_section_offset = 0x1410; + } + else if (imFuji.RAFDataVersion == 0x014d || // X-M1 + imFuji.RAFDataVersion == 0x014e) // X-A1, X-A2 + { + wb_section_offset = 0x1474; + } + else if (imFuji.RAFDataVersion == 0x014f || // X-E2 + imFuji.RAFDataVersion == 0x024f || // X-E2 + imFuji.RAFDataVersion == 0x025d || // X-H1 + imFuji.RAFDataVersion == 0x035d) // X-H1 + { + wb_section_offset = 0x1480; + } + else if (imFuji.RAFDataVersion == 0x0150) // XQ1, XQ2 + { + wb_section_offset = 0x1414; + } + else if (imFuji.RAFDataVersion == 0x0151 || // X-T1 w/diff. fws + imFuji.RAFDataVersion == 0x0251 || imFuji.RAFDataVersion == 0x0351 || + imFuji.RAFDataVersion == 0x0451 || imFuji.RAFDataVersion == 0x0551) + { + wb_section_offset = 0x14b0; + } + else if (imFuji.RAFDataVersion == 0x0152 || // X30 + imFuji.RAFDataVersion == 0x0153) // X100T + { + wb_section_offset = 0x1444; + } + else if (imFuji.RAFDataVersion == 0x0154) // X-T10 + { + wb_section_offset = 0x1824; + } + else if (imFuji.RAFDataVersion == 0x0155) // X70 + { + wb_section_offset = 0x17b4; + } + else if (imFuji.RAFDataVersion == 0x0255 || // X-Pro2 + imFuji.RAFDataVersion == 0x0455) + { + wb_section_offset = 0x135c; + } + else if (imFuji.RAFDataVersion == 0x0258 || // X-T2 + imFuji.RAFDataVersion == 0x025b) // X-T20 + { + wb_section_offset = 0x13dc; + } + else if (imFuji.RAFDataVersion == 0x0259) // X100F + { + wb_section_offset = 0x1370; + } + else if (imFuji.RAFDataVersion == 0x025a || // GFX 50S + imFuji.RAFDataVersion == 0x045a) + { + wb_section_offset = 0x1424; + } + else if (imFuji.RAFDataVersion == 0x025c) // X-E3 + { + wb_section_offset = 0x141c; + } + else if (imFuji.RAFDataVersion == 0x025e) // X-T3 + { + wb_section_offset = 0x2014; + } + else if (imFuji.RAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100 (? RAFDataVersion 0x045f) + { + if (!strcmp(model, "X-T30")) { + CHECKSPACE(0x20b8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) + wb_section_offset = 0x20b8; + else + { + CHECKSPACE(0x20c8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) + wb_section_offset = 0x20c8; + } + } + else if (!strcmp(model, "GFX 50R")) + wb_section_offset = 0x1424; + else if (!strcmp(model, "GFX 100")) + wb_section_offset = 0x20e4; + } + else if (imFuji.RAFDataVersion == 0x0260) // X-Pro3, GFX 100S + { + if (!strcmp(model, "X-Pro3")) + wb_section_offset = 0x20e8; + else if (!strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S")) + wb_section_offset = 0x2108; + } + else if (imFuji.RAFDataVersion == 0x0261) // X100V, GFX 50S II + { + if (!strcmp(model, "X100V")) + wb_section_offset = 0x2078; + else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) + wb_section_offset = 0x214c; + } + else if (imFuji.RAFDataVersion == 0x0262) // X-T4 + { + wb_section_offset = 0x21c8; + } + else if (imFuji.RAFDataVersion == 0x0264) // X-S10 + { + wb_section_offset = 0x21de; + } + else if ((imFuji.RAFDataVersion == 0x0265) || // X-E4 + (imFuji.RAFDataVersion == 0x0266)) // X-T30 II + { + wb_section_offset = 0x21cc; + } + else if (imFuji.RAFDataVersion == 0x0355) // X-E2S + { + wb_section_offset = 0x1840; + } + +/* try for unknown RAF Data versions */ + else if (!strcmp(model, "X-Pro2")) + { + CHECKSPACE(0x135c + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x135c)) + wb_section_offset = 0x135c; + } + else if (!strcmp(model, "X100F")) + { + CHECKSPACE(0x1370 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1370)) + wb_section_offset = 0x1370; + } + else if (!strcmp(model, "X-E1")) + { + CHECKSPACE(0x13ac + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13ac)) + wb_section_offset = 0x13ac; + } + else if (!strcmp(model, "X-T2") || + !strcmp(model, "X-T20")) + { + CHECKSPACE(0x13dc + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc)) + wb_section_offset = 0x13dc; + } + else if (!strcmp(model, "X20") || + !strcmp(model, "X100S")) + { + CHECKSPACE(0x1410 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410)) + wb_section_offset = 0x1410; + } + else if (!strcmp(model, "XQ1") || + !strcmp(model, "XQ2")) + { + CHECKSPACE(0x1414+ 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414)) + wb_section_offset = 0x1414; + } + else if (!strcmp(model, "X-E3")) + { + CHECKSPACE(0x141c + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x141c)) + wb_section_offset = 0x141c; + } + else if (!strcmp(model, "GFX 50S") || + !strcmp(model, "GFX 50R")) + { + CHECKSPACE(0x1424 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424)) + wb_section_offset = 0x1424; + } + else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) { + CHECKSPACE(0x214c + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x214c)) + wb_section_offset = 0x214c; + } + else if (!strcmp(model, "X30") || + !strcmp(model, "X100T")) + { + CHECKSPACE(0x1444 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444)) + wb_section_offset = 0x1444; + } + else if (!strcmp(model, "X-M1") || + !strcmp(model, "X-A1") || + !strcmp(model, "X-A2")) + { + CHECKSPACE(0x1474 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474)) + wb_section_offset = 0x1474; + } + else if (!strcmp(model, "X-E2") || + !strcmp(model, "X-H1")) + { + CHECKSPACE(0x1480 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480)) + wb_section_offset = 0x1480; + } + else if (!strcmp(model, "X-T1")) + { + CHECKSPACE(0x14b0 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x14b0)) + wb_section_offset = 0x14b0; + } + else if (!strcmp(model, "X70")) + { + CHECKSPACE(0x17b4 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x17b4)) + wb_section_offset = 0x17b4; + } + else if (!strcmp(model, "X-T10")) + { + CHECKSPACE(0x1824 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1824)) + wb_section_offset = 0x1824; + } + else if (!strcmp(model, "X-E2S")) + { + CHECKSPACE(0x1840 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1840)) + wb_section_offset = 0x1840; + } + else if (!strcmp(model, "X-T3")) + { + CHECKSPACE(0x2014 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2014)) + wb_section_offset = 0x2014; + } + else if (!strcmp(model, "X100V")) + { + CHECKSPACE(0x2078 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2078)) + wb_section_offset = 0x2078; + } + else if (!strcmp(model, "X-T30")) + { + CHECKSPACE(0x20b8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) + wb_section_offset = 0x20b8; + else + { + CHECKSPACE(0x20c8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) + wb_section_offset = 0x20c8; + } + } + else if (!strcmp(model, "GFX 100")) + { + CHECKSPACE(0x20e4 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e4)) + wb_section_offset = 0x20e4; + } + else if (!strcmp(model, "X-Pro3")) + { + CHECKSPACE(0x20e8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e8)) + wb_section_offset = 0x20e8; + } + else if (!strcmp(model, "GFX100S") || !strcmp(model, "GFX 100S")) + { + CHECKSPACE(0x2108 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2108)) + wb_section_offset = 0x2108; + } + else if (!strcmp(model, "X-T4")) + { + CHECKSPACE(0x21c8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21c8)) + wb_section_offset = 0x21c8; + } + else if ((!strcmp(model, "X-E4")) || + (!strcmp(model, "X-T30 II"))) + { + CHECKSPACE(0x21cc + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21cc)) + wb_section_offset = 0x21cc; + } + else if (!strcmp(model, "X-S10")) + { + CHECKSPACE(0x21de + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21de)) + wb_section_offset = 0x21de; + } +/* no RAF Data version for the models below */ + else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8 + { + if (!strcmp(imFuji.RAFVersion, "0069")) + wb_section_offset = 0x19e8; + else if (!strcmp(imFuji.RAFVersion, "0100") || + !strcmp(imFuji.RAFVersion, "0110")) + wb_section_offset = 0x19f0; + else + { + CHECKSPACE(0x19e8 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19e8)) + wb_section_offset = 0x19e8; + else + { + CHECKSPACE(0x19f0 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19f0)) + wb_section_offset = 0x19f0; + } + } + } + else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4 + { + if (!strcmp(imFuji.RAFVersion, "0100") || + !strcmp(imFuji.RAFVersion, "0101") || + !strcmp(imFuji.RAFVersion, "0204")) + wb_section_offset = 0x13a4; + else + { + CHECKSPACE(0x13a4 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13a4)) + wb_section_offset = 0x13a4; + } + } + else if (!strcmp(model, "XF1")) // XF1 0 0x138c + { + if (!strcmp(imFuji.RAFVersion, "0100")) + wb_section_offset = 0x138c; + else + { + CHECKSPACE(0x138c + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) + wb_section_offset = 0x138c; + } + } + else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284 + { + if (!strcmp(imFuji.RAFVersion, "0100")) + wb_section_offset = 0x1284; + else + { + CHECKSPACE(0x1284 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1284)) + wb_section_offset = 0x1284; + } + } + else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4 + { + if (!strcmp(imFuji.RAFVersion, "0100") || + !strcmp(imFuji.RAFVersion, "0102")) + wb_section_offset = 0x1280; + else if (!strcmp(imFuji.RAFVersion, "0103")) + wb_section_offset = 0x12d4; + else + { + CHECKSPACE(0x1280 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1280)) + wb_section_offset = 0x1280; + else + { + CHECKSPACE(0x12d4 + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x12d4)) + wb_section_offset = 0x12d4; + } + } + } + else if (!strcmp(model, "XF1")) // XF1 0 0x138c + { + if (!strcmp(imFuji.RAFVersion, "0100")) + wb_section_offset = 0x138c; + else + { + CHECKSPACE(0x138c + 12); + if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) + wb_section_offset = 0x138c; + } + } + + if (wb_section_offset) + { + CHECKSPACE(wb_section_offset + 12); + } + + if (wb_section_offset && + isWB(PrivateMknBuf + posPrivateMknBuf + wb_section_offset)) + { + + if (!imFuji.RAFDataVersion) + { + posWB = posPrivateMknBuf + wb_section_offset - 6; + CHECKSPACE_ABS2(posWB, 6); + icWBC[LIBRAW_WBI_Auto][1] = + icWBC[LIBRAW_WBI_Auto][3] = + sget2(PrivateMknBuf + posWB); + icWBC[LIBRAW_WBI_Auto][0] = + sget2(PrivateMknBuf + posWB + 2); + icWBC[LIBRAW_WBI_Auto][2] = + sget2(PrivateMknBuf + posWB + 4); + } + + posWB = posPrivateMknBuf + wb_section_offset; + for (int wb_ind = 0; wb_ind < (int)Fuji_wb_list1.size(); posWB += 6, wb_ind++) + { + CHECKSPACE_ABS2(posWB, 6); + icWBC[Fuji_wb_list1[wb_ind]][1] = + icWBC[Fuji_wb_list1[wb_ind]][3] = + sget2(PrivateMknBuf + posWB); + icWBC[Fuji_wb_list1[wb_ind]][0] = + sget2(PrivateMknBuf + posWB + 2); + icWBC[Fuji_wb_list1[wb_ind]][2] = + sget2(PrivateMknBuf + posWB + 4); + } + int found = 0; + if (is34) + posWB += 0x30; + posWB += 0xc0; + CHECKSPACE_ABS2(posWB, 2); + ushort Gval = sget2(PrivateMknBuf + posWB); + for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30); + posEndCCTsection += 6) + { + CHECKSPACE_ABS2(posEndCCTsection, 2); + if (sget2(PrivateMknBuf + posEndCCTsection) != Gval) + { + if (is34) + wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record + else + wb_section_offset = posEndCCTsection - 31*3*2; // 31 records, 3 2-byte values in a record + found = 1; + break; + } + } + + if (found) + { + for (int iCCT = 0; iCCT < 31; iCCT++) + { + CHECKSPACE_ABS2(wb_section_offset, iCCT*6+6); + icWBCCTC[iCCT][0] = FujiCCT_K[iCCT]; + icWBCCTC[iCCT][1] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 2); + icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6); + icWBCCTC[iCCT][3] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 4); + } + } + } + } + else // process 4K raf data + { + int wb[4]; + int nWB, tWB, pWB; + int iCCT = 0; + imFuji.RAFDataGeneration = 4096; // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 + posWB = posPrivateMknBuf + 0x200; + for (int wb_ind = 0; wb_ind < 42; wb_ind++) + { + CHECKSPACE_ABS2(posWB, 24); + nWB = sget4(PrivateMknBuf + posWB); + posWB += 4; + tWB = sget4(PrivateMknBuf + posWB); + posWB += 4; + wb[0] = sget4(PrivateMknBuf + posWB) << 1; + posWB += 4; + wb[1] = sget4(PrivateMknBuf + posWB); + posWB += 4; + wb[3] = sget4(PrivateMknBuf + posWB); + posWB += 4; + wb[2] = sget4(PrivateMknBuf + posWB) << 1; + posWB += 4; + + if (tWB && (iCCT < 255)) + { + icWBCCTC[iCCT][0] = tWB; + FORC4 icWBCCTC[iCCT][c + 1] = wb[c]; + iCCT++; + } + if (nWB != 0x46) + { + for (pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) + { + if (Fuji_wb_list2[pWB] == nWB) + { + FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; + break; + } + } + } + } + } + } + posPrivateMknBuf += PrivateTagBytes; + } + free(PrivateMknBuf); + } +#undef get_average_WB +#undef CHECKSPACE +#undef CHECKSPACE_ABS2 +#undef CHECKSPACE_ABS3 +} + +void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, + unsigned /*dng_writer*/) +{ + if (tag == 0x0010) + { + char FujiSerial[sizeof(imgdata.shootinginfo.InternalBodySerial)]; + char *words[4] = { 0,0,0,0 }; + char yy[2], mm[3], dd[3], ystr[16], ynum[16]; + int year, nwords, ynum_len; + unsigned c; + memset(FujiSerial, 0, sizeof(imgdata.shootinginfo.InternalBodySerial)); + ifp->read(FujiSerial, MIN(len,sizeof(FujiSerial)), 1); + nwords = getwords(FujiSerial, words, 4, + sizeof(imgdata.shootinginfo.InternalBodySerial)); + for (int i = 0; i < nwords; i++) + { + if (!words[i]) break; // probably damaged input + mm[2] = dd[2] = 0; + if (strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) < 18) + { + if (i == 0) + { + strncpy(imgdata.shootinginfo.InternalBodySerial, words[0], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); + } + else + { + char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; + snprintf(tbuf, sizeof(tbuf)-1, "%s %s", + imgdata.shootinginfo.InternalBodySerial, words[i]); + strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); + } + } + else + { + strncpy( + dd, + words[i] + + strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - + 14, + 2); + strncpy( + mm, + words[i] + + strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - + 16, + 2); + strncpy( + yy, + words[i] + + strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - + 18, + 2); + year = (yy[0] - '0') * 10 + (yy[1] - '0'); + if (year < 70) + year += 2000; + else + year += 1900; + + ynum_len = MIN( + int(sizeof(ynum) - 1), + (int)strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - + 18); + strncpy(ynum, words[i], ynum_len); + ynum[ynum_len] = 0; + for (int j = 0; ynum[j] && ynum[j + 1] && sscanf(ynum + j, "%2x", &c); + j += 2) + ystr[j / 2] = c; + ynum_len /= 2; + ystr[ynum_len + 1] = 0; + strcpy(model2, ystr); + + if (i == 0) + { + char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; + + if (nwords == 1) + { + snprintf( + tbuf, sizeof(tbuf), "%s %d:%s:%s %s", + ystr, year, mm, dd, + words[0] + + strnlen(words[0], sizeof(imgdata.shootinginfo.InternalBodySerial)-1)-12); + } + else + { + snprintf( + tbuf, sizeof(tbuf), "%s %d:%s:%s %s", ystr, year, mm, dd, + words[0] + + strnlen(words[0], + sizeof(imgdata.shootinginfo.InternalBodySerial) - + 1) - + 12); + } + strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); + } + else + { + char tbuf[sizeof(imgdata.shootinginfo.InternalBodySerial)]; + snprintf( + tbuf, sizeof(tbuf), "%s %s %d:%s:%s %s", + imgdata.shootinginfo.InternalBodySerial, ystr, year, mm, dd, + words[i] + + strnlen(words[i], + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1) - + 12); + strncpy(imgdata.shootinginfo.InternalBodySerial, tbuf, + sizeof(imgdata.shootinginfo.InternalBodySerial) - 1); + } + } + } + } + else + switch (tag) + { + case 0x1002: + imFuji.WB_Preset = get2(); + break; + case 0x1011: + imCommon.FlashEC = getreal(type); + break; + case 0x1020: + imFuji.Macro = get2(); + break; + case 0x1021: + imFuji.FocusMode = imgdata.shootinginfo.FocusMode = get2(); + break; + case 0x1022: + imFuji.AFMode = get2(); + break; + case 0x1023: + imFuji.FocusPixel[0] = get2(); + imFuji.FocusPixel[1] = get2(); + break; + case 0x102b: + imFuji.PrioritySettings = get2(); + break; + case 0x102d: + imFuji.FocusSettings = get4(); + break; + case 0x102e: + imFuji.AF_C_Settings = get4(); + break; + case 0x1034: + imFuji.ExrMode = get2(); + break; + case 0x104d: + FujiCropMode = get2(); // odd: one of raw dimensions here can be lost + break; + case 0x1050: + imFuji.ShutterType = get2(); + break; + case 0x1100: + imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode + break; + case 0x1101: + imFuji.SequenceNumber = get2(); + break; + case 0x1103: + imgdata.shootinginfo.DriveMode = get2(); + imFuji.DriveMode = imgdata.shootinginfo.DriveMode & 0xff; + break; + case 0x1105: + imFuji.SeriesLength = get2(); + break; + case 0x1106: + imFuji.PixelShiftOffset[0] = getreal(type); + imFuji.PixelShiftOffset[1] = getreal(type); + break; + case 0x1301: + imFuji.FocusWarning = get2(); + break; + case 0x1400: + imFuji.DynamicRange = get2(); + break; + case 0x1401: + imFuji.FilmMode = get2(); + break; + case 0x1402: + imFuji.DynamicRangeSetting = get2(); + break; + case 0x1403: + imFuji.DevelopmentDynamicRange = get2(); + break; + case 0x1404: + ilm.MinFocal = getreal(type); + break; + case 0x1405: + ilm.MaxFocal = getreal(type); + break; + case 0x1406: + ilm.MaxAp4MinFocal = getreal(type); + break; + case 0x1407: + ilm.MaxAp4MaxFocal = getreal(type); + break; + case 0x140b: + imFuji.AutoDynamicRange = get2(); + break; + case 0x1422: + imFuji.ImageStabilization[0] = get2(); + imFuji.ImageStabilization[1] = get2(); + imFuji.ImageStabilization[2] = get2(); + imgdata.shootinginfo.ImageStabilization = + (imFuji.ImageStabilization[0] << 9) + imFuji.ImageStabilization[1]; + break; + case 0x1438: + imFuji.ImageCount = get2(); + break; + case 0x1431: + imFuji.Rating = get4(); + break; + case 0x1443: + imFuji.DRangePriority = get2(); + break; + case 0x1444: + imFuji.DRangePriorityAuto = get2(); + break; + case 0x1445: + imFuji.DRangePriorityFixed = get2(); + break; + } + return; +} + +void LibRaw::parse_fuji_thumbnail(int offset) +{ + uchar xmpmarker[] = "http://ns.adobe.com/xap/1.0/"; + uchar buf[sizeof(xmpmarker)+1]; + int xmpsz = sizeof(xmpmarker); // we do not + + INT64 pos = ftell(ifp); + fseek(ifp, offset, SEEK_SET); + ushort s_order = order; + order = 0x4a4a; // JPEG is always in MM order + + if (get2() == 0xFFD8) + { + while (1) + { + ushort tag = get2(); + if (tag != 0xFFE1 && tag != 0xFFE2) // allow APP1/APP2 only + break; + INT64 tpos = ftell(ifp); + int len = get2(); + if (len > xmpsz + 2) + { + if ((fread(buf, 1, xmpsz, ifp) == xmpsz) && !memcmp(buf, xmpmarker, xmpsz)) // got it + { + xmplen = len - xmpsz - 2; + xmpdata = (char*) malloc(xmplen+1); + fread(xmpdata, 1, xmplen, ifp); + xmpdata[xmplen] = 0; + break; + } + } + fseek(ifp, tpos + len, SEEK_SET); + } + } + + order = s_order; + fseek(ifp, pos, SEEK_SET); +} + +void LibRaw::parse_fuji(int offset) +{ + unsigned entries, tag, len, save, c; + +#define get_average_WB(wb_index) \ + FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = get2(); \ + if ((len == 16) && average_WBData) { \ + FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ + (icWBC[wb_index][GRGB_2_RGBG(c)] + get2())/2; \ + } \ + if (use_WBcorr_coeffs) { \ + icWBC[wb_index][0] *= wbR_corr; \ + icWBC[wb_index][2] *= wbB_corr; \ + } + + ushort raw_inset_present = 0; + ushort use_WBcorr_coeffs = 0; + double wbR_corr = 1.0; + double wbB_corr = 1.0; + ilm.CamID = unique_id; + int average_WBData = 1; + + fseek(ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) + return; + imgdata.process_warnings |= LIBRAW_WARN_PARSEFUJI_PROCESSED; + + if (strstr(model, "S2Pro") + || strstr(model, "S20Pro") + || strstr(model, "F700") + || strstr(model, "S5000") + || strstr(model, "S7000") + ) { + use_WBcorr_coeffs = 1; + wbR_corr = 10.0 / 17.0 / 0.652941; + wbB_corr = 2.0 /3.0 / (3.0 / 4.0 + 1.0 / 300.0); + } else if (strstr(model, "DBP") || strstr(model, "DX-2000")) { + use_WBcorr_coeffs = 1; + wbR_corr = 0.7632653061; + wbB_corr = 0.8591549296; + } + + while (entries--) + { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x0100) // RawImageFullSize + { + raw_height = get2(); + raw_width = get2(); + raw_inset_present = 1; + } + else if ((tag == 0x0110) && raw_inset_present) // RawImageCropTopLeft + { + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + } + else if ((tag == 0x0111) && raw_inset_present) // RawImageCroppedSize + { + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + } + else if ((tag == 0x0115) && raw_inset_present) // RawImageAspectRatio + { + int a = get2(); + int b = get2(); + if (a * b == 6) + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + else if (a * b == 12) + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; + else if (a * b == 144) + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; + else if (a * b == 1) + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + } + else if (tag == 0x0121) // RawImageSize + { + height = get2(); + if ((width = get2()) == 4284) + width += 3; + } + else if (tag == 0x0130) // FujiLayout, + { + fuji_layout = fgetc(ifp) >> 7; + fuji_width = !(fgetc(ifp) & 8); + } + else if (tag == 0x0131) // XTransLayout + { + filters = 9; + char *xtrans_abs_alias = &xtrans_abs[0][0]; + FORC(36) + { + int q = fgetc(ifp); + xtrans_abs_alias[35 - c] = MAX(0, MIN(q, 2)); /* & 3;*/ + } + } + else if (tag == 0x2ff0) // WB_GRGBLevels + { + get_average_WB(LIBRAW_WBI_AsShot); + FORC4 cam_mul[c] = icWBC[LIBRAW_WBI_AsShot][c]; + } + else if ((tag == 0x4000) && + ((len == 8) || (len == 16))) + { + imFuji.BlackLevel[0] = len / 2; + FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = get2(); + if (imFuji.BlackLevel[0] == 8) + FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+5] = get2(); + if (imFuji.BlackLevel[0] == 4) + FORC4 cblack[c] = imFuji.BlackLevel[c+1]; + else if (imFuji.BlackLevel[0] == 8) + FORC4 cblack[c] = (imFuji.BlackLevel[c+1]+imFuji.BlackLevel[c+5]) /2; + } + else if (tag == 0x9200) // RelativeExposure + { + int s1 = get2(); + int s2 = get2(); + if ((s1 == s2) || !s1) + imFuji.BrightnessCompensation = 0.0f; + else if ((s1*4) == s2) + imFuji.BrightnessCompensation = 2.0f; + else if ((s1*16) == s2) + imFuji.BrightnessCompensation = 4.0f; + else + imFuji.BrightnessCompensation = log(double(s2)/double(s1))/log(2.0); + } + else if (tag == 0x9650) // RawExposureBias + { + short a = (short)get2(); + float b = fMAX(1.0f, get2()); + imFuji.ExpoMidPointShift = a / b; + imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; + } + else if (tag == 0x2000) // WB_GRGBLevelsAuto + { + get_average_WB(LIBRAW_WBI_Auto); + } + else if (tag == 0x2100) // WB_GRGBLevelsDaylight + { + get_average_WB(LIBRAW_WBI_FineWeather); + } + else if (tag == 0x2200) // WB_GRGBLevelsCloudy + { + get_average_WB(LIBRAW_WBI_Shade); + } + else if (tag == 0x2300) // WB_GRGBLevelsDaylightFluor + { + get_average_WB(LIBRAW_WBI_FL_D); + } + else if (tag == 0x2301) // WB_GRGBLevelsDayWhiteFluor + { + get_average_WB(LIBRAW_WBI_FL_N); + } + else if (tag == 0x2302) // WB_GRGBLevelsWhiteFluorescent + { + get_average_WB(LIBRAW_WBI_FL_W); + } + else if (tag == 0x2310) // WB_GRGBLevelsWarmWhiteFluor + { + get_average_WB(LIBRAW_WBI_FL_WW); + } + else if (tag == 0x2311) // WB_GRGBLevelsLivingRoomWarmWhiteFluor + { + get_average_WB(LIBRAW_WBI_FL_L); + } + else if (tag == 0x2400) // WB_GRGBLevelsTungsten + { + get_average_WB(LIBRAW_WBI_Tungsten); + } + else if (tag == 0x2410) + { + get_average_WB(LIBRAW_WBI_Flash); + } + else if (tag == 0x2f00) // WB_GRGBLevels + { + int nWBs = get4(); + nWBs = MIN(nWBs, 6); + for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { + FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = get2(); + if ((len >= unsigned(4+16*nWBs)) && average_WBData) { + FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = + (icWBC[wb_ind][GRGB_2_RGBG(c)] +get2()) /2; + } + if (use_WBcorr_coeffs) { + icWBC[LIBRAW_WBI_Custom1 + wb_ind][0] *= wbR_corr; + icWBC[LIBRAW_WBI_Custom1 + wb_ind][2] *= wbB_corr; + } + } + } + + else if (tag == 0xc000) // RAFData + { + int offsetWH_inRAFData; + unsigned save_order = order; + order = 0x4949; + if (len > 20000) + { + uchar RAFDataHeader[16]; + libraw_internal_data.unpacker_data.posRAFData = save; + libraw_internal_data.unpacker_data.lenRAFData = (len >> 1); + fread(RAFDataHeader, sizeof RAFDataHeader, 1, ifp); + offsetWH_inRAFData = guess_RAFDataGeneration(RAFDataHeader); + fseek(ifp, offsetWH_inRAFData-int(sizeof RAFDataHeader), SEEK_CUR); + for (int i=0; + i< (int)((sizeof imFuji.RAFData_ImageSizeTable) / (sizeof imFuji.RAFData_ImageSizeTable[0])); + i++) { + imFuji.RAFData_ImageSizeTable[i] = get4(); + } + +// if ((width > raw_width) +// || (raw_inset_present && (width < imgdata.sizes.raw_inset_crops[0].cwidth)) +// ) +// width = raw_width; +// if ((height > raw_height) +// || (raw_inset_present && (height < imgdata.sizes.raw_inset_crops[0].cheight)) +// ) +// height = raw_height; +// + + } + else if (len == 4096) // X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 + { // Ill.A aligned to CCT 2850 + int wb[4]; + int nWB, tWB; + int iCCT = 0; + imFuji.RAFDataGeneration = 4096; + fseek(ifp, save + 0x200, SEEK_SET); + for (int wb_ind = 0; wb_ind < 42; wb_ind++) + { + nWB = get4(); + tWB = get4(); + wb[0] = get4() << 1; + wb[1] = get4(); + wb[3] = get4(); + wb[2] = get4() << 1; + if (tWB && (iCCT < 255)) + { + icWBCCTC[iCCT][0] = tWB; + FORC4 icWBCCTC[iCCT][c + 1] = wb[c]; + iCCT++; + } + if (nWB != 70) + { + for (int pWB = 1; pWB < (int)Fuji_wb_list2.size(); pWB += 2) + { + if (Fuji_wb_list2[pWB] == nWB) + { + FORC4 icWBC[Fuji_wb_list2[pWB - 1]][c] = wb[c]; + break; + } + } + } + } + } + order = save_order; + } + fseek(ifp, save + len, SEEK_SET); + } + + if (!imFuji.RAFDataGeneration) { + height <<= fuji_layout; + width >>= fuji_layout; + } +#undef get_average_WB +} + diff --git a/src/metadata/hasselblad_model.cpp b/src/metadata/hasselblad_model.cpp new file mode 100644 index 000000000..b20da5efa --- /dev/null +++ b/src/metadata/hasselblad_model.cpp @@ -0,0 +1,538 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + + static const struct { + const int idx; + const char *FormatName; + } HassyRawFormat[] = { + { LIBRAW_HF_Unknown, "Unknown"}, + { LIBRAW_HF_3FR, "-3FR"}, + { LIBRAW_HF_FFF, "-FFF"}, + { LIBRAW_HF_Imacon, "Imacon"}, + { LIBRAW_HF_HasselbladDNG, "hDNG"}, + { LIBRAW_HF_AdobeDNG, "aDNG"}, + { LIBRAW_HF_AdobeDNG_fromPhocusDNG, "a(hDNG)"}, + }; + +const char* LibRaw::HassyRawFormat_idx2HR(unsigned idx) // HR means "human-readable" +{ + for (int i = 0; i < int(sizeof HassyRawFormat / sizeof *HassyRawFormat); i++) + if((unsigned)HassyRawFormat[i].idx == idx) + return HassyRawFormat[i].FormatName; + return 0; +} + +void LibRaw::process_Hassy_Lens (int LensMount) { +// long long unsigned id = +// mount*100000000ULL + series*10000000ULL + +// focal1*10000ULL + focal2*10 + version; + char *ps; + int c; + char *q = strchr(imgdata.lens.Lens, ' '); + if(!q) return ; + c = atoi(q+1); + if (!c) + return; + + if (LensMount == LIBRAW_MOUNT_Hasselblad_H) { + if (imgdata.lens.Lens[2] == ' ') // HC lens + ilm.LensID = LensMount*100000000ULL + 10000000ULL; + else // HCD lens + ilm.LensID = LensMount*100000000ULL + 20000000ULL; + ilm.LensFormat = LIBRAW_FORMAT_645; + } else if (LensMount == LIBRAW_MOUNT_Hasselblad_XCD) { + ilm.LensFormat = LIBRAW_FORMAT_CROP645; + ilm.LensID = LensMount*100000000ULL; + } else + return; + + ilm.LensMount = LensMount; + ilm.LensID += c*10000ULL; + if ((ps=strchr(imgdata.lens.Lens, '-'))) { + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + ilm.LensID += atoi(ps+1)*10ULL; + } else { + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + ilm.LensID += c*10ULL; + } + if (strstr(imgdata.lens.Lens, "III")) + ilm.LensID += 3ULL; + else if (strstr(imgdata.lens.Lens, "II")) + ilm.LensID += 2ULL; +} + +void LibRaw::parseHassyModel() { + +static const char *Hasselblad_Ctrl[] = { // manually selectable options only + "ELD", "ELX", "Winder CW", "CW", "Pinhole", "Flash Sync", + "SWC", "200 (Mod)", "200", "500 Mech.", "500", "H Series", + "H-Series", "H1", "H2", "Black Box", "LENSCONTROL S", "LENSCTRL S", "Generic", +}; + +static const char *Hasselblad_SensorEnclosures[] = { + "CFH", "CFV", "CFV", "CFII", "CF", "Ixpress", +}; + + char tmp_model[64]; + const char *ps; + char *eos; + int c; + int nPix = raw_width*raw_height; + int add_MP_toName = 1; + int norm_model_isSet = 0; + + if (model[0] == ' ') + memmove(model, model+1, MIN(sizeof(model)-1,strlen(model))); + + imHassy.HostBody[0] = 0; + if ((ps = strrchr(model, '/'))) + strcpy(imHassy.HostBody, ps+1); + else if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '/'))) + strcpy(imHassy.HostBody, ps+1); + else if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/'))) + strcpy(imHassy.HostBody, ps+1); + else if ((ps = strrchr(imHassy.SensorUnitConnector, '/'))) + strcpy(imHassy.HostBody, ps+1); + if (imHassy.HostBody[0]) { + if ((eos = strrchr(imHassy.HostBody, '-'))) + *eos = 0; + } + + if (!imHassy.format) { + if (dng_version) { + if (!strncmp(software, "Adobe", 5)) { + if (!imgdata.color.OriginalRawFileName[0] || + !imgdata.color.LocalizedCameraModel[0] || + !strcasestr(imgdata.color.UniqueCameraModel, "coated")) + imHassy.format = LIBRAW_HF_AdobeDNG_fromPhocusDNG; + else + imHassy.format = LIBRAW_HF_AdobeDNG; + } else imHassy.format = LIBRAW_HF_HasselbladDNG; + } else if ((imHassy.nIFD_CM[0] != -1) && + (imHassy.nIFD_CM[1] == -1) && + !imHassy.mnColorMatrix[0][0]) { + imHassy.format = LIBRAW_HF_3FR; + } else imHassy.format = LIBRAW_HF_FFF; + } + + if (imHassy.SensorUnitConnector[0]) { + char buf[64]; + if (!strncmp(imHassy.SensorUnitConnector, "Hasselblad ", 11)) + memmove(imHassy.SensorUnitConnector, imHassy.SensorUnitConnector+11, 64-11); + strcpy(buf, imHassy.SensorUnitConnector); + if ((eos = strrchr(buf, '/'))) { + *eos = 0; + if ((eos = strrchr(buf, ' '))) { + *eos = 0; + strcpy (imHassy.SensorUnitConnector, buf); + } + } + } + + if (imHassy.format == LIBRAW_HF_AdobeDNG) { // Adobe DNG, use LocalizedCameraModel + imgdata.color.LocalizedCameraModel[63] = 0; // make sure it's 0-terminated + if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '-'))) + c = ps-imgdata.color.LocalizedCameraModel; + else c = int(strlen(imgdata.color.LocalizedCameraModel)); + int cc = MIN(c, (int)sizeof(tmp_model)-1); + memcpy(tmp_model, imgdata.color.LocalizedCameraModel,cc); + tmp_model[cc] = 0; + if (strcasestr(imgdata.color.UniqueCameraModel, "coated")) { + strncpy(normalized_model, imgdata.color.UniqueCameraModel,sizeof(imgdata.color.UniqueCameraModel)-1); + normalized_model[sizeof(imgdata.color.UniqueCameraModel) - 1] = 0; + norm_model_isSet = 1; + } + if (!strncmp(normalized_model, "Hasselblad ", 11)) + memmove(normalized_model, normalized_model+11, 64-11); + } else { + if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/'))) { + c = ps-imgdata.color.UniqueCameraModel; + } + else c = int(strlen(imgdata.color.UniqueCameraModel)); + int cc = MIN(c, (int)sizeof(tmp_model)-1); + memcpy(tmp_model, imgdata.color.UniqueCameraModel,cc); + tmp_model[cc] = 0; + } + if (!strncasecmp(tmp_model, "Hasselblad ", 11)) + memmove(tmp_model, tmp_model+11, 64-11); + + strncpy(imHassy.CaptureSequenceInitiator, model,31); + imHassy.CaptureSequenceInitiator[31] = 0; + if ((eos = strrchr(imHassy.CaptureSequenceInitiator, '/'))) { + *eos = 0; + } +// check if model tag contains manual CaptureSequenceInitiator info: + FORC(int(sizeof Hasselblad_Ctrl / sizeof *Hasselblad_Ctrl)) { + if (strcasestr(model, Hasselblad_Ctrl[c])) { +// yes, fill 'model' with sensor unit data + strncpy(model, tmp_model,63); + model[63] = 0; + break; + } + } + + if (!imHassy.HostBody[0]) { + ps = strchr(model, '-'); + if (ps) { // check if model contains both host body and sensor version, resolution, MS info + strncpy(imHassy.SensorUnit, model,63); + memcpy(imHassy.HostBody, model, ps-model); + imHassy.HostBody[ps-model] = 0; + if (!strncmp(ps-2, "II-", 3)) + ps -=2; + strncpy(imHassy.Sensor, ps,7); + imHassy.Sensor[7] = 0; + add_MP_toName = 0; + } else { // model contains host body only + strncpy(imHassy.HostBody, model,63); + imHassy.HostBody[63] = 0; + // fill 'model' with sensor unit data + strncpy(model, tmp_model,63); + model[63] = 0; + } + } + + if (strstr(model, "503CWD")) { + strncpy(imHassy.HostBody, model,63); + imHassy.HostBody[63] = 0; + ilm.CameraFormat = LIBRAW_FORMAT_66; + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V; + if (model[6] == 'I' && model[7] == 'I') + strcpy(model, "CFVII"); + else strcpy(model, "CFV"); + } else if (strstr(model, "Hasselblad") && + (model[10] != ' ')) { + strcpy(model, "CFV"); + ilm.CameraMount = LIBRAW_MOUNT_DigitalBack; + } else { + FORC(int(sizeof Hasselblad_SensorEnclosures / sizeof *Hasselblad_SensorEnclosures)) { + if (strcasestr(model, Hasselblad_SensorEnclosures[c])) { + if (add_MP_toName) strcpy(model, Hasselblad_SensorEnclosures[c]); + ilm.CameraMount = LIBRAW_MOUNT_DigitalBack; + break; + } + } + } + +#define cpynorm(str) \ + if (!norm_model_isSet) { \ + strcpy(normalized_model, str); \ + norm_model_isSet = 1; \ + } + + if ((imHassy.SensorCode == 4) && + (imHassy.CoatingCode < 2)) { + strcpy(imHassy.Sensor, "-16"); + cpynorm("16-Uncoated"); + + } else if ((imHassy.SensorCode == 6) && + (imHassy.CoatingCode < 2)) { + strcpy(imHassy.Sensor, "-22"); + cpynorm("22-Uncoated"); + + } else if ((imHassy.SensorCode == 8) && + (imHassy.CoatingCode == 1)) { + strcpy(imHassy.Sensor, "-31"); + cpynorm("31-Uncoated"); + + } else if ((imHassy.SensorCode == 9) && + (imHassy.CoatingCode < 2)) { + strcpy(imHassy.Sensor, "-39"); + cpynorm("39-Uncoated"); + + } else if ((imHassy.SensorCode == 9) && + (imHassy.CoatingCode == 4)) { + strcpy(imHassy.Sensor, "-39"); + strcpy(model, "H3DII"); + add_MP_toName = 1; + cpynorm("39-Coated"); + + } else if ((imHassy.SensorCode == 13) && + (imHassy.CoatingCode == 4)) { + strcpy(imHassy.Sensor, "-40"); + cpynorm("40-Coated"); + + } else if ((imHassy.SensorCode == 13) && + (imHassy.CoatingCode == 5)) { + strcpy(imHassy.Sensor, "-40"); + cpynorm("40-Coated5"); + + } else if ((imHassy.SensorCode == 11) && + (imHassy.CoatingCode == 4)) { + if (!strncmp(model, "H3D", 3)) + strcpy(model, "H3DII-50"); + else strcpy(imHassy.Sensor, "-50"); + cpynorm("50-Coated"); + + } else if ((imHassy.SensorCode == 11) && + (imHassy.CoatingCode == 5)) { + strcpy(imHassy.Sensor, "-50"); + cpynorm("50-Coated5"); + + } else if ((imHassy.SensorCode == 15) && + (imHassy.CoatingCode == 5)) { + strcpy(imHassy.Sensor, "-50c"); + cpynorm("50-15-Coated5"); + if (!strncmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) { + imHassy.SensorSubCode = 2; + add_MP_toName = 0; + strcat(imHassy.Sensor, " II"); + strcpy(model, "CFV II 50C"); + strcat(normalized_model, "-II"); + } else if (!strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3)) { + imHassy.SensorSubCode = 2; + add_MP_toName = 0; + strcat(imHassy.Sensor, " II"); + if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) { + strcpy(model, "X1D II 50C"); + strcat(normalized_model, "-II"); + } else { + strcpy(model, "X1D-50c"); + } + } + + } else if ((imHassy.SensorCode == 12) && + (imHassy.CoatingCode == 4)) { + strcpy(imHassy.Sensor, "-60"); + cpynorm("60-Coated"); + + } else if ((imHassy.SensorCode == 17) && + (imHassy.CoatingCode == 5)) { + strcpy(imHassy.Sensor, "-100c"); + cpynorm("100-17-Coated5"); + + } else if ((raw_width == 4090) || // V96C + ((raw_width == 4096) && (raw_height == 4096)) || + ((raw_width == 4088) && (raw_height == 4088)) || // Adobe crop + ((raw_width == 4080) && (raw_height == 4080))) { // Phocus crop + strcpy(imHassy.Sensor, "-16"); + cpynorm("16-Uncoated"); + if (!imHassy.SensorCode) imHassy.SensorCode = 4; + + } else if ((raw_width == 5568) && (raw_height == 3648)) { + strcpy(imHassy.Sensor, "-20c"); + + } else if (((raw_width == 4096) && (raw_height == 5456)) || + ((raw_width == 4088) && (raw_height == 5448)) || // Adobe crop + ((raw_width == 4080) && (raw_height == 5440))) { // Phocus crop + strcpy(imHassy.Sensor, "-22"); + cpynorm("22-Uncoated"); + if (!imHassy.SensorCode) imHassy.SensorCode = 6; + + } else if (((raw_width == 6542) && (raw_height == 4916)) || + ((raw_width == 6504) && (raw_height == 4880)) || // Adobe crop + ((raw_width == 6496) && (raw_height == 4872))) { // Phocus crop + strcpy(imHassy.Sensor, "-31"); + cpynorm("31-Uncoated"); + if (!imHassy.SensorCode) imHassy.SensorCode = 8; + + } else if (((raw_width == 7262) && (raw_height == 5456)) || // + ((raw_width == 7224) && (raw_height == 5420)) || // Adobe crop + ((raw_width == 7216) && (raw_height == 5412)) || // Phocus crop + ((raw_width == 7212) && (raw_height == 5412)) || // CF-39, CFV-39, possibly v.II; Phocus crop +// uncropped, when the exact size is unknown, should be: +// - greater or equal to the smallest Phocus crop for the current size +// - smaller than the smallest Phocus crop for the next size + ((nPix >= 7212*5412) && (nPix < 7304*5478))) { + strcpy(imHassy.Sensor, "-39"); + if (!imHassy.SensorCode) imHassy.SensorCode = 9; + if (!strncmp(model, "H3D", 3)) { + if (((imHassy.format == LIBRAW_HF_Imacon) || + strstr(imgdata.color.UniqueCameraModel, "H3D-39") || + strstr(imgdata.color.LocalizedCameraModel, "H3D-39") || + strstr(model, "H3D-39")) && + !strstr(imgdata.color.UniqueCameraModel, "II") && + !strstr(imgdata.color.LocalizedCameraModel, "II") && + !strstr(model, "II")) { + strcpy(model, "H3D-39"); + add_MP_toName = 0; + cpynorm("39-Uncoated"); + + } else { + strcpy(model, "H3DII-39"); + add_MP_toName = 0; + cpynorm("39-Coated"); + if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; + } + + } else + cpynorm("39-Uncoated"); + + } else if (((raw_width == 7410) && (raw_height == 5586)) || // (H4D-40, H5D-40) + ((raw_width == 7312) && (raw_height == 5486)) || // Adobe crop + ((raw_width == 7304) && (raw_height == 5478))) { // Phocus crop + strcpy(imHassy.Sensor, "-40"); + if (!strncmp(model, "H4D", 3)) { + cpynorm("40-Coated"); + if (!imHassy.SensorCode) imHassy.SensorCode = 13; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; + } else { + cpynorm("40-Coated5"); + if (!imHassy.SensorCode) imHassy.SensorCode = 13; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; + } + + } else if (((raw_width == 8282) && (raw_height == 6240)) || // (CFV-50, H3DII-50, H5D-50) + ((raw_width == 8184) && (raw_height == 6140)) || // Adobe crop + ((raw_width == 8176) && (raw_height == 6132))) { // Phocus crop + strcpy(imHassy.Sensor, "-50"); + if (!strncmp(model, "H5D", 3)) { + cpynorm("50-Coated5"); + if (!imHassy.SensorCode) imHassy.SensorCode = 11; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; + } else { + cpynorm("50-Coated"); // CFV-50, H3DII-50, + if (!strncmp(model, "H3D", 3)) { + strcpy(model, "H3DII-50"); + if (!imHassy.SensorCode) imHassy.SensorCode = 11; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; + add_MP_toName = 0; + } + } + + } else if (((raw_width == 8374) && (raw_height == 6304)) || // (H5D-50c) + ((raw_width == 8384) && (raw_height == 6304)) || // (X1D-50c, "X1D II 50C", "CFV II 50C") + ((raw_width == 8280) && (raw_height == 6208)) || // Adobe crop + ((raw_width == 8272) && (raw_height == 6200))) { // Phocus crop + cpynorm("50-15-Coated5"); + if (!imHassy.SensorCode) imHassy.SensorCode = 15; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; + strcpy(imHassy.Sensor, "-50c"); + if ((raw_width == 8384) || + !strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3) || + !strncmp(imHassy.CaptureSequenceInitiator, "CFV II", 6)) { + imHassy.SensorSubCode = 2; + add_MP_toName = 0; + strcat(imHassy.Sensor, " II"); + if (strstr(imHassy.CaptureSequenceInitiator, " II ")) { + strcat(normalized_model, "-II"); + if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) { + strcpy(model, "X1D II 50C"); + } else if (!strncasecmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) { + strcpy(model, "CFV II 50C"); + } + } else { + strcpy(model, "X1D-50c"); + } + } + + } else if (((raw_width == 9044) && (raw_height == 6732)) || + ((raw_width == 8964) && (raw_height == 6716)) || // Adobe crop + ((raw_width == 8956) && (raw_height == 6708))) { // Phocus crop + strcpy(imHassy.Sensor, "-60"); + cpynorm("60-Coated"); + if (!imHassy.SensorCode) imHassy.SensorCode = 12; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 4; + + + } else if (((raw_width == 10320) && (raw_height == 7752)) || // Phocus crop, A5D-80 + ((nPix >= 10320*7752) && (nPix < 10520*8000))) { + strcpy(imHassy.Sensor, "-80"); + cpynorm("80-Coated"); + + } else if (((raw_width == 12000) && (raw_height == 8816)) || + ((raw_width == 11608) && (raw_height == 8708)) || // Adobe crop + ((raw_width == 11600) && (raw_height == 8700))) { // Phocus crop + strcpy(imHassy.Sensor, "-100c"); + cpynorm("100-17-Coated5"); + if (!imHassy.SensorCode) imHassy.SensorCode = 17; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; + + } + + if (raw_width == 4090) + strcpy(model, "V96C"); + + if ( + (raw_width == 4090) || + ((raw_width == 4096) && (raw_height == 4096)) || + ((raw_width == 5568) && (raw_height == 3648)) || + ((raw_width == 4096) && (raw_height == 5456)) || + ((raw_width == 6542) && (raw_height == 4916)) || + ((raw_width == 7262) && (raw_height == 5456)) || + ((raw_width == 7410) && (raw_height == 5586)) || + ((raw_width == 8282) && (raw_height == 6240)) || + ((raw_width == 8374) && (raw_height == 6304)) || + ((raw_width == 8384) && (raw_height == 6304)) || + ((raw_width == 9044) && (raw_height == 6732)) || + ((raw_width == 10320) && (raw_height == 7752)) || + ((raw_width == 12000) && (raw_height == 8816)) + ) + imHassy.uncropped = 1; + + + if (model[0] && add_MP_toName) + strcat(model, imHassy.Sensor); + if (imHassy.Sensor[0] == '-') + memmove(imHassy.Sensor, imHassy.Sensor+1, strlen(imHassy.Sensor)); + + if (dng_version && + (imHassy.SensorCode == 13) && + (imHassy.CoatingCode == 4)) { + c = LIBRAW_HF_AdobeDNG; + } else if ((imHassy.format == LIBRAW_HF_HasselbladDNG) || + (imHassy.format == LIBRAW_HF_AdobeDNG_fromPhocusDNG)) { + c = LIBRAW_HF_FFF; + } else if (imHassy.format == LIBRAW_HF_Imacon) { + c = LIBRAW_HF_3FR; + } else { + c = imHassy.format; + } + ps = HassyRawFormat_idx2HR(c); + if ((c == LIBRAW_HF_3FR) || + (c == LIBRAW_HF_FFF)) + strcat(normalized_model, ps); + + if (((imHassy.CaptureSequenceInitiator[0] == 'H') && + (imHassy.CaptureSequenceInitiator[1] != 'a')) || + ((imHassy.CaptureSequenceInitiator[0] == 'A') && + isdigit(imHassy.CaptureSequenceInitiator[1]))) { + ilm.CameraFormat = LIBRAW_FORMAT_645; + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; + if (imgdata.lens.Lens[0] == 'H') + process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H); + } else if (((imHassy.CaptureSequenceInitiator[0] == 'X') && + isdigit(imHassy.CaptureSequenceInitiator[1])) || + !strncmp(imHassy.HostBody, "907", 3)) { + ilm.CameraFormat = LIBRAW_FORMAT_CROP645; + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_XCD; + if (imgdata.lens.Lens[0] == 'H') { + process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H); + strcpy(ilm.Adapter, "XH"); + } else { + if (imgdata.lens.Lens[0] == 'X') { + process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_XCD); + } else if (!imgdata.lens.Lens[0] && + (aperture > 1.0f) && + (focal_len > 10.0f)) { + ilm.LensID = focal_len; + if (ilm.LensID == 35) { + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL + + 35*10000ULL + 75*10; + } + else { + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL + + ilm.LensID*10000ULL + ilm.LensID*10; + } + } + } + } + if (normalized_model[0] && !CM_found) + CM_found = adobe_coeff(maker_index, normalized_model); +} diff --git a/src/metadata/identify.cpp b/src/metadata/identify.cpp new file mode 100644 index 000000000..aabbf85c1 --- /dev/null +++ b/src/metadata/identify.cpp @@ -0,0 +1,3167 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +// clang-format on +static const struct +{ + const int CorpId; + const char *CorpName; +} CorpTable[] = { + {LIBRAW_CAMERAMAKER_Agfa, "AgfaPhoto"}, + {LIBRAW_CAMERAMAKER_Apple, "Apple"}, + {LIBRAW_CAMERAMAKER_Broadcom, "Broadcom"}, + {LIBRAW_CAMERAMAKER_Canon, "Canon"}, + {LIBRAW_CAMERAMAKER_Casio, "Casio"}, + {LIBRAW_CAMERAMAKER_CINE, "CINE"}, + {LIBRAW_CAMERAMAKER_Epson, "Epson"}, + {LIBRAW_CAMERAMAKER_Fujifilm, "Fujifilm"}, + {LIBRAW_CAMERAMAKER_Mamiya, "Mamiya"}, + {LIBRAW_CAMERAMAKER_Motorola, "Motorola"}, + {LIBRAW_CAMERAMAKER_Kodak, "Kodak"}, + {LIBRAW_CAMERAMAKER_Konica, "Konica"}, + {LIBRAW_CAMERAMAKER_Minolta, "Minolta"}, + {LIBRAW_CAMERAMAKER_Leica, "Leica"}, + {LIBRAW_CAMERAMAKER_Nikon, "Nikon"}, + {LIBRAW_CAMERAMAKER_Nokia, "Nokia"}, + {LIBRAW_CAMERAMAKER_Olympus, "Olympus"}, + {LIBRAW_CAMERAMAKER_OmDigital, "OM Digital"}, + {LIBRAW_CAMERAMAKER_Ricoh, "Ricoh"}, + {LIBRAW_CAMERAMAKER_Pentax, "Pentax"}, + {LIBRAW_CAMERAMAKER_PhaseOne, "Phase One"}, + {LIBRAW_CAMERAMAKER_PhaseOne, "PhaseOne"}, + {LIBRAW_CAMERAMAKER_Samsung, "Samsung"}, + {LIBRAW_CAMERAMAKER_Sigma, "Sigma"}, + {LIBRAW_CAMERAMAKER_Sinar, "Sinar"}, + {LIBRAW_CAMERAMAKER_Sony, "Sony"}, + {LIBRAW_CAMERAMAKER_YI, "YI"}, + // add corp. names below + {LIBRAW_CAMERAMAKER_Alcatel, "Alcatel"}, + {LIBRAW_CAMERAMAKER_Aptina, "Aptina"}, + {LIBRAW_CAMERAMAKER_AVT, "AVT"}, + {LIBRAW_CAMERAMAKER_Baumer, "Baumer"}, + {LIBRAW_CAMERAMAKER_Clauss, "Clauss"}, + {LIBRAW_CAMERAMAKER_Contax, "Contax"}, + {LIBRAW_CAMERAMAKER_Creative, "Creative"}, + {LIBRAW_CAMERAMAKER_DJI, "DJI"}, + {LIBRAW_CAMERAMAKER_Foculus, "Foculus"}, + {LIBRAW_CAMERAMAKER_Generic, "Generic"}, + {LIBRAW_CAMERAMAKER_Gione, "Gione"}, + {LIBRAW_CAMERAMAKER_GITUP, "GITUP"}, + {LIBRAW_CAMERAMAKER_Hasselblad, "Hasselblad"}, + {LIBRAW_CAMERAMAKER_HTC, "HTC"}, + {LIBRAW_CAMERAMAKER_I_Mobile, "I_Mobile"}, + {LIBRAW_CAMERAMAKER_Imacon, "Imacon"}, + {LIBRAW_CAMERAMAKER_ISG, "ISG"}, + {LIBRAW_CAMERAMAKER_JK_Imaging, "JK Imaging"}, // Kodak + {LIBRAW_CAMERAMAKER_Leaf, "Leaf"}, + {LIBRAW_CAMERAMAKER_Lenovo, "Lenovo"}, + {LIBRAW_CAMERAMAKER_LG, "LG"}, + {LIBRAW_CAMERAMAKER_Logitech, "Logitech"}, + {LIBRAW_CAMERAMAKER_Matrix, "Matrix"}, + {LIBRAW_CAMERAMAKER_Meizu, "Meizu"}, + {LIBRAW_CAMERAMAKER_Micron, "Micron"}, + {LIBRAW_CAMERAMAKER_NGM, "NGM"}, + {LIBRAW_CAMERAMAKER_OmniVison, "OmniVison"}, + {LIBRAW_CAMERAMAKER_Panasonic, "Panasonic"}, + {LIBRAW_CAMERAMAKER_Photron, "Photron"}, + {LIBRAW_CAMERAMAKER_Pixelink, "Pixelink"}, + {LIBRAW_CAMERAMAKER_Polaroid, "Polaroid"}, + {LIBRAW_CAMERAMAKER_Rollei, "Rollei"}, + {LIBRAW_CAMERAMAKER_RoverShot, "RoverShot"}, + {LIBRAW_CAMERAMAKER_SMaL, "SMaL"}, + {LIBRAW_CAMERAMAKER_ST_Micro, "ST Micro"}, + {LIBRAW_CAMERAMAKER_THL, "THL"}, + {LIBRAW_CAMERAMAKER_Xiaomi, "Xiaomi"}, + {LIBRAW_CAMERAMAKER_XIAOYI, "Xiayi"}, + {LIBRAW_CAMERAMAKER_Yuneec, "Yuneec"}, + {LIBRAW_CAMERAMAKER_DXO, "DxO"}, + {LIBRAW_CAMERAMAKER_RED, "Red"}, + {LIBRAW_CAMERAMAKER_PhotoControl, "Photo Control"}, + {LIBRAW_CAMERAMAKER_Google, "Google"}, + {LIBRAW_CAMERAMAKER_GoPro, "GoPro"}, + {LIBRAW_CAMERAMAKER_Parrot, "Parrot"}, + {LIBRAW_CAMERAMAKER_Zeiss, "Zeiss"}, + {LIBRAW_CAMERAMAKER_OnePlus, "OnePlus"}, + {LIBRAW_CAMERAMAKER_VIVO, "Vivo"}, + {LIBRAW_CAMERAMAKER_HMD_Global, "HMD Global"}, + {LIBRAW_CAMERAMAKER_HUAWEI, "Huawei"}, + {LIBRAW_CAMERAMAKER_RaspberryPi, "RaspberryPi"}, +}; +// clang-format on + +int LibRaw::setMakeFromIndex(unsigned makei) +{ + if (makei <= LIBRAW_CAMERAMAKER_Unknown || makei >= LIBRAW_CAMERAMAKER_TheLastOne) return 0; + + for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) + if ((unsigned)CorpTable[i].CorpId == makei) + { + strcpy(normalized_make, CorpTable[i].CorpName); + maker_index = makei; + return 1; + } + return 0; +} + +const char *LibRaw::cameramakeridx2maker(unsigned maker) +{ + for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) + if((unsigned)CorpTable[i].CorpId == maker) + return CorpTable[i].CorpName; + return 0; +} + + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void LibRaw::fixupArri() +{ + struct alist_t + { + const char *a_model; + const char *a_software; + ushort a_width,a_height; + int a_black; + unsigned a_filters; + float a_aspect; + } + alist[] = + { + {"ALEXA65", "Alexa65 XT", 6560 ,3100, 256,0x49494949,1.f}, + + {"ALEXALF", "Alexa LF Plus W", 3840 ,2160, 256,0x49494949,1.0f }, + {"ALEXALF", "Alexa LF Plus W", 4448 ,1856, 256,0x49494949,0.75f }, + {"ALEXALF", "Alexa LF Plus W", 4448 ,3096, 256,0x49494949,1.f }, + + {"ALEXA", "Alexa Plus 4:3 SXT", 2880 ,1620, 256,0x61616161,.75f}, + {"ALEXA", "Alexa Plus 4:3 SXT", 3168 ,1782, 256,0x61616161,0.75f}, + {"ALEXA", "Alexa Plus 4:3 SXT", 3424 ,2202, 256,0x61616161,1.f}, + {"ALEXA", "Alexa Plus 4:3 SXT", 2592 ,2160, 256,0x61616161,1.12f}, + + {"ALEXA", "Alexa Plus 4:3 XT", 2592 ,2160, 256,0x61616161,1.12f}, + {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,2160, 256,0x61616161,1.f}, + {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,1620, 256,0x61616161,0.75f}, + {"ALEXA", "Alexa Plus 4:3 XT", 3424 ,2202, 256,0x61616161,1.f}, + }; + for(int i = 0; i < int(sizeof(alist)/sizeof(alist[0])); i++) + if(!strncasecmp(model,alist[i].a_model,strlen(alist[i].a_model)) && software + && !strncasecmp(software,alist[i].a_software,strlen(alist[i].a_software)) + && width == alist[i].a_width && height == alist[i].a_height) + { + filters = alist[i].a_filters; + black = alist[i].a_black; + pixel_aspect = alist[i].a_aspect; + strcpy(model,software); + software[0]=0; + return; + } +} +#endif +/* + Identify which camera created this file, and set global variables + accordingly. + */ +void LibRaw::identify() +{ + // clang-format off + static const ushort canon[][11] = { + // raw_width, raw_height, left_margin, top_margin, + // width_decrement, height_decrement, + // mask01, mask03, mask11, mask13, + // CFA_filters. + { 1944, 1416, 0, 0, 48, 0 }, // 00 "PowerShot Pro90 IS" + { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, // 01 "PowerShot S30", "PowerShot G1" + { 2224, 1456, 48, 6, 0, 2 }, // 02 "EOS D30" + { 2376, 1728, 12, 6, 52, 2 }, // 03 "PowerShot G2", "PowerShot S40", "PowerShot G3", "PowerShot S45" + { 2672, 1968, 12, 6, 44, 2 }, // 04 "PowerShot G5", "PowerShot S50", "PowerShot S60" + { 3152, 2068, 64, 12, 0, 0, 16 }, // 05 "EOS D60", "EOS 10D", "EOS 300D" + { 3160, 2344, 44, 12, 4, 4 }, // 06 "PowerShot G6", "PowerShot S70" + { 3344, 2484, 4, 6, 52, 6 }, // 07 "PowerShot Pro1" + { 3516, 2328, 42, 14, 0, 0 }, // 08 "EOS 350D" + { 3596, 2360, 74, 12, 0, 0 }, // 09 "EOS-1D Mark II", "EOS 20D", "EOS-1D Mark II N", "EOS 30D" + { 3744, 2784, 52, 12, 8, 12 }, // 10 "PowerShot G11", "PowerShot S90", "PowerShot G12", "PowerShot S95" + { 3944, 2622, 30, 18, 6, 2 }, // 11 "EOS 40D" + { 3948, 2622, 42, 18, 0, 2 }, // 12 "EOS 400D", "EOS 1000D" + { 3984, 2622, 76, 20, 0, 2, 14 }, // 13 "EOS-1D Mark III" + { 4032, 2656, 112, 44, 10, 0 }, // 14 APS-C crop mode: "EOS 6D Mark II"??, "EOS RP" + { 4104, 3048, 48, 12, 24, 12 }, // 15 "PowerShot G9" + { 4116, 2178, 4, 2, 0, 0 }, // 16 ?? + { 4152, 2772, 192, 12, 0, 0 }, // 17 "PowerShot SX1 IS" + { 4160, 3124, 104, 11, 8, 65 }, // 18 "PowerShot S100 (new)", "PowerShot S100V", "PowerShot G15", "PowerShot S110 (new)" + { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, // 19 "PowerShot SX50 HS" + { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, // 20 "PowerShot G16", "PowerShot S120" + { 4312, 2876, 22, 18, 0, 2 }, // 21 "EOS 450D" + { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R" + { 4352, 2874, 62, 18, 0, 0 }, // 23 "EOS 1100D" + { 4476, 2954, 90, 34, 0, 0 }, // 24 "EOS 5D" + { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, // 25 "PowerShot G10" + { 4480, 3366, 80, 50, 0, 0 }, // 26 "PowerShot G1 X Mark II" + { 4496, 3366, 80, 50, 12, 0 }, // 27 "PowerShot G1 X" + { 4768, 3516, 96, 16, 0, 0, 0, 16 }, // 28 "PowerShot SX60 HS" + { 4832, 3204, 62, 26, 0, 0 }, // 29 "EOS 500D" + { 4832, 3228, 62, 51, 0, 0 }, // 30 "EOS 50D" + { 5108, 3349, 98, 13, 0, 0 }, // 31 "EOS-1Ds Mark II" + { 5120, 3318, 142, 45, 62, 0 }, // 32 "EOS-1D Mark IV" + { 5280, 3528, 72, 52, 0, 0 }, // 33 "EOS M10", "EOS 650D", "EOS 700D", "EOS M", "EOS 100D", "EOS M2" + { 5344, 3516, 142, 51, 0, 0 }, // 34 "EOS 550D", "EOS 600D", "EOS 60D", "EOS 1200D", "EOS 1300D", "EOS 3000D" + { 5344, 3584, 126, 100, 0, 2 }, // 35 "EOS-1D X", "EOS-1D C" + { 5344, 3950, 98, 18, 0, 0, 0, 24, 0, 0 }, // 36 "PowerShot SX70 HS" + { 5360, 3516, 158, 51, 0, 0 }, // 37 "EOS 7D" + { 5568, 3708, 72, 38, 0, 0 }, // 38; "EOS 7D Mark II", "EOS 6D", "EOS 70D", "EOS-1D X MARK II" + { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, // 39 "PowerShot G7 X", "PowerShot G3 X", "PowerShot G9 X", "PowerShot G5 X", "PowerShot G7 X Mark II", "PowerShot G9 X Mark II" + { 5712, 3774, 62, 20, 10, 2 }, // 40 "EOS-1Ds Mark III" + { 5792, 3804, 158, 51, 0, 0 }, // 41 "EOS 5D Mark II" + { 5920, 3950, 122, 80, 2, 0 }, // 42 "EOS 5D Mark III" + { 6096, 4051, 76, 35, 0, 0 }, // 43 "EOS 1500D" + { 6096, 4056, 72, 34, 0, 0 }, // 44 "EOS M3", "EOS 760D", "EOS 750D" + { 6288, 4056, 264, 36, 0, 0 }, // 45 "EOS M5", "EOS M100", "EOS M6", "PowerShot G1 X Mark III", "EOS 80D", "EOS 800D", "EOS 77D", "EOS 200D", "EOS 250D", "EOS M50" + { 6384, 4224, 120, 44, 0, 0 }, // 46 "EOS 6D Mark II", "EOS RP" + { 6880, 4544, 136, 42, 0, 0 }, // 47 "EOS 5D Mark IV" + { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R" + { 7128, 4732, 144, 72, 0, 0 }, // 49 "EOS M6 II", "EOS 90D" + { 8896, 5920, 160, 64, 0, 0 }, // 50 "EOS 5DS", "EOS 5DS R" + { 6192, 4152, 160, 120, 0, 0}, // EOS R3 + { 6192, 4060, 168, 52, 24, 8, 16,48,32,0,} // EOS R10 + }; + + static const libraw_custom_camera_t const_table[] = { + { 786432, 1024, 768, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-080C" }, + { 1447680, 1392, 1040, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-145C" }, + { 1920000, 1600, 1200, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-201C" }, + { 5067304, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C" }, + { 5067316, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C", 12 }, + { 10134608, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C" }, + { 10134620, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C", 12 }, + { 16157136, 3272, 2469, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-810C" }, + { 3995136, 1632, 1224, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, + { 15980544, 3264, 2448, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, + { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" }, + { 31850496, 4608, 3456, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 4:3" }, + { 23887872, 4608, 2592, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 16:9" }, + { 32257024, 4624, 3488, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" }, + { 24192768, 4624, 2616, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" }, + { 18016000, 4000, 2252, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" }, + // {24000000, 4000, 3000, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", + // "G3DUO 4:3"}, // Conflict w/ Samsung WB550 + + // Android Raw dumps id start + // File Size in bytes Horizontal Res Vertical Flag then bayer order eg + // 0x16 bbgr 0x94 rggb + { 1540857, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "Samsung", "S3" }, + { 2658304, 1212, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontMipi" }, + { 2842624, 1296, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontQCOM" }, + { 2969600, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" }, + { 3170304, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" }, + { 3763584, 1584, 1184, 0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" }, + { 5107712, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" }, + { 5382640, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" }, + { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 5364240, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 6299648, 2592, 1944, 0, 0, 0, 0, 1, 0x16, 0, 0, "OmniVisi", "OV5648" }, + { 6721536, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "OmniVisi", "OV56482" }, + { 6746112, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "OneSV" }, + { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" }, + { 9830400, 2560, 1920, 0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" }, + { 10186752, 3264, 2448, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" }, + { 10223360, 2608, 1944, 0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" }, + { 10782464, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" }, + { 10788864, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "Xperia", "L" }, + { 15967488, 3264, 2446, 0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" }, + { 16224256, 4208, 3082, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3MipiL" }, + { 16424960, 4208, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "IMX135", "MipiL" }, + { 17326080, 4164, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3LQCom" }, + { 17522688, 4212, 3120, 0, 0, 0, 0, 0, 0x16, 0, 0, "Sony", "IMX135-QCOM" }, + { 19906560, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7mipi" }, + { 19976192, 5312, 2988, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G4" }, + { 20389888, 4632, 3480, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" }, + { 20500480, 4656, 3496, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" }, + { 21233664, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7qcom" }, + { 26023936, 4192, 3104, 0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" }, + { 26257920, 4208, 3120, 0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" }, + { 26357760, 4224, 3120, 0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" }, + { 41312256, 5248, 3936, 0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" }, + { 42923008, 5344, 4016, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" }, + // Android Raw dumps id end + { 20137344, 3664, 2748, 0, 0, 0, 0, 0x40, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff }, + { 2868726, 1384, 1036, 0, 0, 0, 0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 }, + { 6553440, 2664, 1968, 4, 4, 44, 4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack + { 9243240, 3152, 2346, 12, 7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack + { 6653280, 2672, 1992, 10, 6, 42, 2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack + { 6573120, 2672, 1968, 12, 8, 44, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack + { 9219600, 3152, 2340, 36, 12, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack + { 10383120, 3344, 2484, 12, 6, 44, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack + { 12945240, 3736, 2772, 12, 6, 52, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack + { 15636240, 4104, 3048, 48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack + { 10341600, 3336, 2480, 6, 5, 32, 3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack + { 24724224, 4704, 3504, 8, 16, 56, 8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack + { 18763488, 4104, 3048, 10, 22, 82, 22, 8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ? + { 19493760, 4160, 3124, 104, 12, 8, 66, 40, 0x49, 0, 2, "Canon", "PowerShot S100" }, // chdk hack CRW + { 7710960, 2888, 2136, 44, 8, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack + { 5298000, 2400, 1766, 12, 12, 44, 2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack + { 18653760, 4080, 3048, 24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack + { 21936096, 4464, 3276, 25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack + { 19167840, 4176, 3060, 96, 16, 8, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2 + { 15467760, 3720, 2772, 6, 12, 30, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack + { 15534576, 3728, 2778, 12, 9, 44, 9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack + { 19131120, 4168, 3060, 92, 16, 4, 1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack + { 31663200, 5344, 3950, 96, 18, 0, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack + { 30858240, 5248, 3920, 8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack + { 1976352, 1632, 1211, 0, 2, 0, 1, 0, 0x94, 0, 1, "Casio", "QV-2000UX" }, + { 3217760, 2080, 1547, 0, 0, 10, 1, 0, 0x94, 0, 1, "Casio", "QV-3*00EX" }, + { 6218368, 2585, 1924, 0, 0, 9, 0, 0, 0x94, 0, 1, "Casio", "QV-5700" }, + { 7816704, 2867, 2181, 0, 0, 34, 36, 0, 0x16, 0, 1, "Casio", "EX-Z60" }, + { 2937856, 1621, 1208, 0, 0, 1, 0, 0, 0x94, 7, 13, "Casio", "EX-S20" }, + { 4948608, 2090, 1578, 0, 0, 32, 34, 0, 0x94, 7, 1, "Casio", "EX-S100" }, + { 6054400, 2346, 1720, 2, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "QV-R41" }, + { 7426656, 2568, 1928, 0, 0, 0, 0, 0, 0x94, 0, 1, "Casio", "EX-P505" }, + { 7530816, 2602, 1929, 0, 0, 22, 0, 0, 0x94, 7, 1, "Casio", "QV-R51" }, + { 7542528, 2602, 1932, 0, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "EX-Z50" }, + { 7562048, 2602, 1937, 0, 0, 25, 0, 0, 0x16, 7, 1, "Casio", "EX-Z500" }, + { 7753344, 2602, 1986, 0, 0, 32, 26, 0, 0x94, 7, 1, "Casio", "EX-Z55" }, + { 9313536, 2858, 2172, 0, 0, 14, 30, 0, 0x94, 7, 1, "Casio", "EX-P600" }, + { 10834368, 3114, 2319, 0, 0, 27, 0, 0, 0x94, 0, 1, "Casio", "EX-Z750" }, + { 10843712, 3114, 2321, 0, 0, 25, 0, 0, 0x94, 0, 1, "Casio", "EX-Z75" }, + { 10979200, 3114, 2350, 0, 0, 32, 32, 0, 0x94, 7, 1, "Casio", "EX-P700" }, + { 12310144, 3285, 2498, 0, 0, 6, 30, 0, 0x94, 0, 1, "Casio", "EX-Z850" }, + { 12489984, 3328, 2502, 0, 0, 47, 35, 0, 0x94, 0, 1, "Casio", "EX-Z8" }, + { 15499264, 3754, 2752, 0, 0, 82, 0, 0, 0x94, 0, 1, "Casio", "EX-Z1050" }, + { 18702336, 4096, 3044, 0, 0, 24, 0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" }, + { 7684000, 2260, 1700, 0, 0, 0, 0, 13, 0x94, 0, 1, "Casio", "QV-4000" }, + { 787456, 1024, 769, 0, 1, 0, 0, 0, 0x49, 0, 0, "Creative", "PC-CAM 600" }, + { 28829184, 4384, 3288, 0, 0, 0, 0, 36, 0x61, 0, 0, "DJI" }, + { 15151104, 4608, 3288, 0, 0, 0, 0, 0, 0x94, 0, 0, "Matrix" }, + { 3840000, 1600, 1200, 0, 0, 0, 0, 65, 0x49, 0, 0, "Foculus", "531C" }, + { 307200, 640, 480, 0, 0, 0, 0, 0, 0x94, 0, 0, "Generic" }, + { 62464, 256, 244, 1, 1, 6, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, + { 124928, 512, 244, 1, 1, 10, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, + { 1652736, 1536, 1076, 0, 52, 0, 0, 0, 0x61, 0, 0, "Kodak", "DCS200" }, + { 4159302, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330" }, + { 4162462, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330", 3160 }, + { 2247168, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, + { 3370752, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, + { 6163328, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603" }, + { 6166488, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603", 3160 }, + { 460800, 640, 480, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, + { 9116448, 2848, 2134, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, + { 12241200, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP" }, + { 12272756, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP", 31556 }, + { 18000000, 4000, 3000, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "12MP" }, + { 614400, 640, 480, 0, 3, 0, 0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" }, + { 15360000, 3200, 2400, 0, 0, 0, 0, 96, 0x16, 0, 0, "Lenovo", "A820" }, + { 3884928, 1608, 1207, 0, 0, 0, 0, 96, 0x16, 0, 0, "Micron", "2010", 3212 }, + { 1138688, 1534, 986, 0, 0, 0, 0, 0, 0x61, 0, 0, "Minolta", "RD175", 513 }, + { 1581060, 1305, 969, 0, 0, 18, 6, 6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack + { 2465792, 1638, 1204, 0, 0, 22, 1, 6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775; + // Olympus C-2020Z + { 2940928, 1616, 1213, 0, 0, 0, 7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500 + { 4771840, 2064, 1541, 0, 0, 0, 1, 6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995; + // Olympus C-3030Z + { 4775936, 2064, 1542, 0, 0, 0, 0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500; + // Pentax "Optio 33WR"; possibly also Olympus C-740UZ + { 5865472, 2288, 1709, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z + { 5869568, 2288, 1710, 0, 0, 0, 0, 6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2" + { 7438336, 2576, 1925, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700 + { 8998912, 2832, 2118, 0, 0, 0, 0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack + { 5939200, 2304, 1718, 0, 0, 0, 0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ + { 3178560, 2064, 1540, 0, 0, 0, 0, 0, 0x94, 0, 1, "Pentax", "Optio S V1.01" }, + { 4841984, 2090, 1544, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S" }, + { 6114240, 2346, 1737, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S4" }, + { 10702848, 3072, 2322, 0, 0, 0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" }, + { 4147200, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD" }, + { 4151666, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD", 8 }, + { 13248000, 2208, 3000, 0, 0, 0, 0, 13, 0x61, 0, 0, "Pixelink", "A782" }, + { 6291456, 2048, 1536, 0, 0, 0, 0, 96, 0x61, 0, 0, "RoverShot", "3320AF" }, + { 311696, 644, 484, 0, 0, 0, 0, 0, 0x16, 0, 8, "ST Micro", "STV680 VGA" }, + { 16098048, 3288, 2448, 0, 0, 24, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack + { 16215552, 3312, 2448, 0, 0, 48, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack + { 20487168, 3648, 2808, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, + { 24000000, 4000, 3000, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, + { 12582980, 3072, 2048, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare + { 33292868, 4080, 4080, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44 + { 44390468, 4080, 5440, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54 + { 1409024, 1376, 1024, 0, 0, 1, 0, 0, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, + { 2818048, 1376, 1024, 0, 0, 1, 0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, + }; + + libraw_custom_camera_t + table[64 + sizeof(const_table) / sizeof(const_table[0])]; + + + // clang-format on + + char head[64] = {0}, *cp; + int hlen, fsize, flen, zero_fsize = 1, i, c; + INT64 fsize64; + struct jhead jh; + + unsigned camera_count = + parse_custom_cameras(64, table, imgdata.rawparams.custom_camera_strings); + for (int q = 0; q < int(sizeof(const_table) / sizeof(const_table[0])); q++) + memmove(&table[q + camera_count], &const_table[q], sizeof(const_table[0])); + camera_count += sizeof(const_table) / sizeof(const_table[0]); + + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + iso_speed = shutter = aperture = focal_len = 0; + unique_id = 0ULL; + tiff_nifds = 0; + is_NikonTransfer = 0; + is_Olympus = 0; + OlympusDNG_SubDirOffsetValid = 0; + is_Sony = 0; + is_pana_raw = 0; + maker_index = LIBRAW_CAMERAMAKER_Unknown; + FujiCropMode = 0; + is_PentaxRicohMakernotes = 0; + normalized_model[0] = 0; + normalized_make[0] = 0; + CM_found = 0; + memset(tiff_ifd, 0, sizeof tiff_ifd); + libraw_internal_data.unpacker_data.crx_track_selected = -1; + libraw_internal_data.unpacker_data.crx_track_count = -1; + libraw_internal_data.unpacker_data.CR3_CTMDtag = 0; + imHassy.nIFD_CM[0] = imHassy.nIFD_CM[1] = -1; + imKodak.ISOCalibrationGain = 1.0f; + imCommon.CameraTemperature = imCommon.SensorTemperature = + imCommon.SensorTemperature2 = imCommon.LensTemperature = + imCommon.AmbientTemperature = imCommon.BatteryTemperature = + imCommon.exifAmbientTemperature = -1000.0f; + + libraw_internal_data.unpacker_data.ifd0_offset = -1LL; + + imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_Unknown; + for (i = 0; i < LIBRAW_IFD_MAXCOUNT; i++) + { + tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = + 0xffff; + for (int q = 0; q < 4; q++) + tiff_ifd[i].dng_levels.analogbalance[q] = 1.0f; + } + + 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 = 0; + thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG + data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = 0; + metadata_blocks = 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); + + if (fread(head, 1, 64, ifp) < 64) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + libraw_internal_data.unpacker_data.lenRAFData = + libraw_internal_data.unpacker_data.posRAFData = 0; + + fseek(ifp, 0, SEEK_END); + fsize64 = ftell(ifp); + if(fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE && fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE) + throw LIBRAW_EXCEPTION_TOOBIG; + + flen = fsize = ftell(ifp); + 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; + parse_ciff(hlen, flen - hlen, 0); + load_raw = &LibRaw::canon_load_raw; + } + else if (parse_tiff(0)) + apply_tiff(); + } + else if (!memcmp(head, "\xff\xd8\xff\xe1", 4) && !memcmp(head + 6, "Exif", 4)) + { + fseek(ifp, 4, SEEK_SET); + data_offset = 4 + get2(); + fseek(ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } + else if (!memcmp(head + 25, "ARECOYK", 7)) // 'KYOCERA' right-to-left + { + strcpy(make, "Contax"); + strcpy(model, "N Digital"); + parse_kyocera(); + } + 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 = &LibRaw::quicktake_100_load_raw; + } + else if (!strcmp(head, "qktn")) + { + strcpy(make, "Apple"); + strcpy(model, "QuickTake 150"); + load_raw = &LibRaw::kodak_radc_load_raw; + } + else if (!memcmp(head, "FUJIFILM", 8)) + { + memcpy(imFuji.SerialSignature, head + 0x10, 0x0c); + imFuji.SerialSignature[0x0c] = 0; + memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); + imFuji.SensorID[0x04] = 0; + strncpy(model, head + 0x1c, 0x20); + model[0x20] = 0; + c = 11; + while (imFuji.SerialSignature[c] > 0 && isdigit(imFuji.SerialSignature[c]) && (c>0)) + c--; + if(c < 11) + unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); + memcpy(imFuji.RAFVersion, head + 0x3c, 4); + imFuji.RAFVersion[4] = 0; + 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 : 0; + if (is_raw == 2 && shot_select) + parse_fuji(i); + } + load_raw = &LibRaw::unpacked_load_raw; + fseek(ifp, 100 + 28 * (shot_select > 0), SEEK_SET); + parse_tiff(data_offset = get4()); + parse_tiff(thumb_offset + 12); + parse_fuji_thumbnail(thumb_offset); + apply_tiff(); + } + else if (!memcmp(head, "RIFF", 4)) + { + fseek(ifp, 0, SEEK_SET); + parse_riff(100); + } + else if (!memcmp(head + 4, "ftypqt ", 9)) + { + fseek(ifp, 0, SEEK_SET); + parse_qt(fsize); + is_raw = 0; + } + else if (!memcmp(head, "\0\001\0\001\0@", 6)) + { + fseek(ifp, 6, SEEK_SET); + fread(make, 1, 8, ifp); + fread(model, 1, 8, ifp); + fread(model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); + raw_height = get2(); + load_raw = &LibRaw::nokia_load_raw; + filters = 0x61616161; + } + else if (!memcmp(head, "NOKIARAW", 8)) + { + strcpy(make, "NOKIA"); + order = 0x4949; + fseek(ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); // bytes count + width = get2(); + height = get2(); + + // Data integrity check + if (width < 1 || width > 16000 || height < 1 || height > 16000 || + i < (width * height) || i > (2 * width * height)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + switch (tiff_bps = i * 8 / (width * height)) + { + case 8: + load_raw = &LibRaw::eight_bit_load_raw; + break; + case 10: + load_raw = &LibRaw::nokia_load_raw; + break; + case 0: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + break; + } + raw_height = height + (top_margin = i / (width * tiff_bps / 8) - height); + mask[0][3] = 1; + filters = 0x61616161; + } +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + 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); + model[63] = 0; + fseek(ifp, 760, SEEK_SET); + fread(software, 1, 64, ifp); + if((unsigned char)software[0] == 0xff) software[0] = 0; + software[63] = 0; + data_offset = 4096; + load_raw = &LibRaw::packed_load_raw; + load_flags = 88; + filters = 0x61616161; + fixupArri(); + } + else if (!memcmp(head, "XPDS", 4)) + { + order = 0x4949; + fseek(ifp, 0x800, SEEK_SET); + fread(make, 1, 41, ifp); + raw_height = get2(); + raw_width = get2(); + fseek(ifp, 56, SEEK_CUR); + fread(model, 1, 30, ifp); + data_offset = 0x10000; + load_raw = &LibRaw::canon_rmf_load_raw; + gamma_curve(0, 12.25, 1, 1023); + } + else if (!memcmp(head + 4, "RED1", 4)) + { + strcpy(make, "Red"); + strcpy(model, "One"); + parse_redcine(); + load_raw = &LibRaw::redcine_load_raw; + gamma_curve(1 / 2.4, 12.92, 1, 4095); + filters = 0x49494949; + } +#endif + 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_x3f(); /* Does nothing if USE_X3FTOOLS is not defined */ + } + else if (!memcmp(head, "CI", 2)) + parse_cine(); +#ifdef USE_6BY9RPI + else if (!memcmp(head, "BRCM", 4)) { + fseek(ifp, 0, SEEK_SET); + strcpy(make, "RaspberryPi"); + strcpy(model, "Pi"); + parse_raspberrypi(); + } +#endif + else if (!memcmp(head + 4, "ftypcrx ", 8)) + { + int err; + unsigned long long szAtomList; + short nesting = -1; + short nTrack = -1; + short TrackType; + char AtomNameStack[129]; + strcpy(make, "Canon"); + + szAtomList = ifp->size(); + err = parseCR3(0ULL, szAtomList, nesting, AtomNameStack, nTrack, TrackType); + libraw_internal_data.unpacker_data.crx_track_count = nTrack; + if ((err == 0 || err == -14) && + nTrack >= 0) // no error, or too deep nesting + selectCRXTrack(); + } + + if (dng_version) + { + if (fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE) + throw LIBRAW_EXCEPTION_TOOBIG; + } + else + { + if (fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) + throw LIBRAW_EXCEPTION_TOOBIG; + } + + if (make[0] == 0) + for (zero_fsize = i = 0; i < (int)camera_count; i++) + if (fsize == (int)table[i].fsize) + { + strcpy(make, table[i].t_make); + strcpy(model, table[i].t_model); + flip = table[i].flags >> 2; + zero_is_bad = table[i].flags & 2; + data_offset = table[i].offset == 0xffff ? 0 : table[i].offset; + raw_width = table[i].rw; + raw_height = table[i].rh; + left_margin = table[i].lm; + top_margin = table[i].tm; + width = raw_width - left_margin - table[i].rm; + height = raw_height - top_margin - table[i].bm; + filters = 0x1010101U * table[i].cf; + colors = 4 - !((filters & filters >> 1) & 0x5555); + load_flags = table[i].lf & 0xff; + if (table[i].lf & 0x100) /* Monochrome sensor dump */ + { + colors = 1; + filters = 0; + } + switch (tiff_bps = (fsize - data_offset) * 8 / (raw_width * raw_height)) + { + case 6: + load_raw = &LibRaw::minolta_rd175_load_raw; + ilm.CameraMount = LIBRAW_MOUNT_Minolta_A; + break; + case 8: + load_raw = &LibRaw::eight_bit_load_raw; + break; + case 10: + if ((fsize - data_offset) / raw_height * 3 >= raw_width * 4) + { + load_raw = &LibRaw::android_loose_load_raw; + break; + } + else if (load_flags & 1) + { + load_raw = &LibRaw::android_tight_load_raw; + break; + } + case 12: + load_flags |= 128; + load_raw = &LibRaw::packed_load_raw; + break; + case 16: + order = 0x4949 | 0x404 * (load_flags & 1); + tiff_bps -= load_flags >> 4; + tiff_bps -= load_flags = load_flags >> 1 & 7; + load_raw = table[i].offset == 0xffff + ? &LibRaw::unpacked_load_raw_reversed + : &LibRaw::unpacked_load_raw; + } + maximum = (1 << tiff_bps) - (1 << table[i].max); + break; + } + if (zero_fsize) + fsize = 0; + if (make[0] == 0 && fsize64 < 25000000LL) + parse_smal(0, flen); + if (make[0] == 0) + { + parse_jpeg(0); +#ifdef USE_6BY9RPI + if (!(strncmp(model, "ov", 2) && strncmp(model, "RP_", 3) && strncmp(model, "imx477", 6))) { + //Assume that this isn't a raw unless the header can be found + is_raw = 0; + + if (!strncasecmp(model, "RP_testc",8) + || !strncasecmp(model, "imx477", 6) // from PyDNG + || !strncasecmp(model, "RP_imx477",9)) { + const long offsets[] = { + //IMX477 offsets + 3375104, //2028x1080 12bit + 4751360, //2028x1520 12bit + 18711040, //4056x3040 12bit + 1015808, //1012x760 10bit + -1 //Marker for end of table + }; + int offset_idx; + for (offset_idx=0; offsets[offset_idx]!=-1; offset_idx++) { + if(!fseek (ifp, -offsets[offset_idx], SEEK_END) && + fread (head, 1, 32, ifp) && !strncmp(head,"BRCM", 4)) { + fseek(ifp, -32, SEEK_CUR); + strcpy (make, "RaspberryPi"); + strcpy(model, "RP_imx477"); // Force single model + black = (offset_idx == 3) ? 64 : 256; + parse_raspberrypi(); + break; + } + } + } + else if (!strncasecmp(model, "RP_imx", 6)) { + const long offsets[] = { + //IMX219 offsets + 10270208, //8MPix 3280x2464 + 2678784, //1920x1080 + 2628608, //1640x1232 + 1963008, //1640x922 + 1233920, //1280x720 + 445440, //640x480 + -1 //Marker for end of table + }; + int offset_idx; + for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) { + if (!fseek(ifp, -offsets[offset_idx], SEEK_END) && + fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) { + + fseek(ifp, -32, SEEK_CUR); + strcpy(make, "RaspberryPi"); + black = 66; + parse_raspberrypi(); + break; + } + } + } + else if (!strncasecmp(model, "RP_OV", 5) || !strncasecmp(model, "ov5647", 6)) { + const long offsets[] = { + 6404096, //5MPix 2592x1944 + 2717696, //1920x1080 + 1625600, //1296x972 + 1233920, //1296x730 + 445440, //640x480 + -1 //Marker for end of table + }; + int offset_idx; + for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) { + if (!fseek(ifp, -offsets[offset_idx], SEEK_END) && + fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) { + fseek(ifp, -32, SEEK_CUR); + strcpy(make, "RaspberryPi"); + strcpy(model, "ov5647"); // Force single model + width = raw_width; + //Defaults + raw_width = 2611; + filters = 0x16161616; + black = 16; + parse_raspberrypi(); + break; + } + } + } + }// else is_raw = 0; +#else + fseek(ifp, 0, SEEK_END); + int sz = ftell(ifp); + if (!strncmp(model, "RP_imx219", 9) && sz >= 0x9cb600 && + !fseek(ifp, -0x9cb600, SEEK_END) && fread(head, 1, 0x20, ifp) && + !strncmp(head, "BRCM", 4)) + { + strcpy(make, "Broadcom"); + strcpy(model, "RPi IMX219"); + if (raw_height > raw_width) + flip = 5; + data_offset = ftell(ifp) + 0x8000 - 0x20; + parse_broadcom(); + black = 66; + maximum = 0x3ff; + load_raw = &LibRaw::broadcom_load_raw; + thumb_offset = 0; + thumb_length = sz - 0x9cb600 - 1; + } + else if (!(strncmp(model, "ov5647", 6) && strncmp(model, "RP_OV5647", 9)) && + sz >= 0x61b800 && !fseek(ifp, -0x61b800, SEEK_END) && + fread(head, 1, 0x20, ifp) && !strncmp(head, "BRCM", 4)) + { + strcpy(make, "Broadcom"); + if (!strncmp(model, "ov5647", 6)) + strcpy(model, "RPi OV5647 v.1"); + else + strcpy(model, "RPi OV5647 v.2"); + if (raw_height > raw_width) + flip = 5; + data_offset = ftell(ifp) + 0x8000 - 0x20; + parse_broadcom(); + black = 16; + maximum = 0x3ff; + load_raw = &LibRaw::broadcom_load_raw; + thumb_offset = 0; + thumb_length = sz - 0x61b800 - 1; + } + else + is_raw = 0; +#endif + } + + // make sure strings are terminated + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; + + for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) + { + if (strcasestr(make, CorpTable[i].CorpName)) + { /* Simplify company names */ + maker_index = CorpTable[i].CorpId; + break; + } + } + + if (makeIs(LIBRAW_CAMERAMAKER_HMD_Global) && !strncasecmp(model, "Nokia", 5)) { + maker_index = LIBRAW_CAMERAMAKER_Nokia; + } else if (makeIs(LIBRAW_CAMERAMAKER_JK_Imaging) && !strncasecmp(model, "Kodak", 5)) { + maker_index = LIBRAW_CAMERAMAKER_Kodak; + } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && !strncasecmp(model, "PENTAX", 6)) { + maker_index = LIBRAW_CAMERAMAKER_Pentax; + } + + for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) { + if (maker_index == (unsigned)CorpTable[i].CorpId) { + strcpy(make, CorpTable[i].CorpName); + break; + } + } + + if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Leica)) && + ((cp = strcasestr(model, " DIGITAL CAMERA")) || + (cp = strstr(model, "FILE VERSION")))) { + *cp = 0; + } + + remove_trailing_spaces(make, sizeof(make)); + remove_trailing_spaces(model, sizeof(model)); + + i = int(strbuflen(make)); /* Remove make from model */ + if (!strncasecmp(model, make, i) && model[i++] == ' ') + memmove(model, model + i, 64 - i); + + if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && !strncmp(model, "FinePix", 7)) { + memmove(model, model + 7, strlen(model) - 6); + if (model[0] == ' ') { + memmove(model, model + 1, strlen(model)); + } + } else if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Konica)) && + !strncmp(model, "Digital Camera ", 15)) { + memmove(model, model + 15, strlen(model) - 14); + } + + 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; + + identify_finetune_pentax(); + + + if (dng_version) + { + if (filters == UINT_MAX) + filters = 0; + if (!filters) + colors = tiff_samples; + switch (tiff_compress) + { + case 0: // Compression not set, assuming uncompressed + case 1: + // Uncompressed float: decoder set in apply_tiff for valid files; not set for non-valid with sampleformat==3 + if ((load_raw != &LibRaw::uncompressed_fp_dng_load_raw) && (tiff_sampleformat != 3)) + load_raw = &LibRaw::packed_dng_load_raw; + break; + case 7: + load_raw = &LibRaw::lossless_dng_load_raw; + break; + case 8: + if (tiff_sampleformat == 3 && tiff_bps > 8 && (tiff_bps % 8 == 0) && tiff_bps <= 32) + load_raw = &LibRaw::deflate_dng_load_raw; + else if((tiff_sampleformat == 0 || tiff_sampleformat == 1) && tiff_bps>=8 && tiff_bps <=16) + load_raw = &LibRaw::deflate_dng_load_raw; + break; +#ifdef USE_GPRSDK + case 9: + load_raw = &LibRaw::vc5_dng_load_raw_placeholder; + break; +#endif + case 34892: + load_raw = &LibRaw::lossy_dng_load_raw; + break; + default: + load_raw = 0; + } + GetNormalizedModel(); + if (makeIs(LIBRAW_CAMERAMAKER_Leica)) { + if (!strcmp(model, "SL2")) + height -= 3; + if (!strncasecmp(model, "Q2 MONO",7)) + height -= 18; + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && + (OlyID == OlyID_STYLUS_1) && // don't use normalized_model below, it is 'Stylus 1' + (strchr(model+6, 's') || + strchr(model+6, 'S'))) + { + width -= 16; + } + goto dng_skip; + } + + if (makeIs(LIBRAW_CAMERAMAKER_Canon) && !fsize && tiff_bps != 15) + { + bool fromtable = false; + if (!load_raw) + load_raw = &LibRaw::lossless_jpeg_load_raw; + for (i = 0; i < int(sizeof canon / sizeof *canon); i++) + if (raw_width == canon[i][0] && raw_height == canon[i][1]) + { + width = raw_width - (left_margin = canon[i][2]); + height = raw_height - (top_margin = canon[i][3]); + width -= canon[i][4]; + height -= canon[i][5]; + mask[0][1] = canon[i][6]; + mask[0][3] = -canon[i][7]; + mask[1][1] = canon[i][8]; + mask[1][3] = -canon[i][9]; + if (canon[i][10]) + filters = canon[i][10] * 0x01010101U; + fromtable = true; + } + if ((unique_id | 0x20000ULL) == + 0x2720000ULL) // "PowerShot G11", "PowerShot S90": 0x2700000, 0x2720000 + // possibly "PowerShot SX120 IS" (if not chdk hack?): 0x2710000 + { + left_margin = 8; + top_margin = 16; + } + if(!fromtable && imCanon.AverageBlackLevel) // not known, but metadata known + { + FORC4 cblack[c] = imCanon.ChannelBlackLevel[c]; + black = cblack[4] = cblack[5] = 0; + // Prevent automatic BL calculation + mask[0][3] = 1; + mask[0][1] = 2; + + if ((imCanon.SensorWidth == raw_width) && + (imCanon.SensorHeight == raw_height)) + { + left_margin = (imCanon.DefaultCropAbsolute.l+1) & 0xfffe; // round to 2 + width = imCanon.DefaultCropAbsolute.r - left_margin; + top_margin = (imCanon.DefaultCropAbsolute.t +1) & 0xfffe; + height = imCanon.DefaultCropAbsolute.b - top_margin; + } + } + } + + identify_finetune_by_filesize(fsize); + + if (!strcmp(model, "KAI-0340") && find_green(16, 16, 3840, 5120) < 25) + { + height = 480; + top_margin = filters = 0; + strcpy(model, "C603"); + } + + GetNormalizedModel(); + + identify_finetune_dcr(head, fsize, flen); + + /* Early reject for damaged images */ + if (!load_raw || height < 22 || width < 22 || + (tiff_bps > 16 && + (load_raw != &LibRaw::deflate_dng_load_raw && + load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) || + tiff_samples > 4 || colors > 4 || + colors < 1 + /* alloc in unpack() may be fooled by size adjust */ + || ((int)width + (int)left_margin > 65535) || + ((int)height + (int)top_margin > 65535)) + { + is_raw = 0; + RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); + return; + } + if (!model[0]) + { + sprintf(model, "%dx%d", width, height); + strcpy(normalized_model, model); + } + + if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS) && + (filters == UINT_MAX)) // Default dcraw behaviour + filters = 0x94949494; + else if (filters == UINT_MAX) + { + if (tiff_nifds > 0 && tiff_samples == 1) + { + colors = 1; + filters = 0; + } + else + filters = 0x94949494; + } + + if (thumb_offset && !thumb_height) + { + fseek(ifp, thumb_offset, SEEK_SET); + if (ljpeg_start(&jh, 1)) + { + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + +dng_skip: + if (dng_version) + identify_process_dng_fields(); + + /* Early reject for damaged images again (after dng fields processing) */ + if (!load_raw || height < 22 || width < 22 || + (tiff_bps > 16 && + (load_raw != &LibRaw::deflate_dng_load_raw && + load_raw != &LibRaw::uncompressed_fp_dng_load_raw )) || + ((load_raw == &LibRaw::deflate_dng_load_raw || load_raw == &LibRaw::uncompressed_fp_dng_load_raw) + && (tiff_bps < 16 || tiff_bps > 32 || (tiff_bps % 8)) ) + ||tiff_samples > 4 || colors > 4 || colors < 1) + { + is_raw = 0; + RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); + return; + } + { + // Check cam_mul range + int cmul_ok = 1; + FORCC if (cam_mul[c] <= 0.001f) cmul_ok = 0; + ; + + if (cmul_ok) + { + double cmin = cam_mul[0], cmax; + double cnorm[4]; + FORCC cmin = MIN(cmin, cam_mul[c]); + FORCC cnorm[c] = cam_mul[c] / cmin; + cmax = cmin = cnorm[0]; + FORCC + { + cmin = MIN(cmin, cnorm[c]); + cmax = MIN(cmax, cnorm[c]); + } + if (cmin <= 0.01f || cmax > 100.f) + cmul_ok = false; + } + if (!cmul_ok) + { + if (cam_mul[0] > 0) + cam_mul[0] = 0; + cam_mul[3] = 0; + } + } + if ((use_camera_matrix & (((use_camera_wb || dng_version)?1:0) | 0x2)) && + cmatrix[0][0] > 0.125) + { + memcpy(rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + if (raw_color && !CM_found) + CM_found = adobe_coeff(maker_index, normalized_model); + else if ((imgdata.color.cam_xyz[0][0] < 0.01) && !CM_found) + CM_found = adobe_coeff(maker_index, normalized_model, 1); + + if (load_raw == &LibRaw::kodak_radc_load_raw) + if ((raw_color) && !CM_found) + CM_found = adobe_coeff(LIBRAW_CAMERAMAKER_Apple, "Quicktake"); + + if ((maker_index != LIBRAW_CAMERAMAKER_Unknown) && normalized_model[0]) + SetStandardIlluminants (maker_index, normalized_model); + + // Clear erroneous fuji_width if not set through parse_fuji or for DNG + if (fuji_width && !dng_version && + !(imgdata.process_warnings & LIBRAW_WARN_PARSEFUJI_PROCESSED)) + fuji_width = 0; + + if (fuji_width) + { + fuji_width = width >> int(!fuji_layout); + filters = fuji_width & 1 ? 0x94949494 : 0x49494949; + width = (height >> fuji_layout) + fuji_width; + height = width - 1; + pixel_aspect = 1; + // Prevent incorrect-sized fuji-rotated files + if (INT64(width)*INT64(height) > INT64(raw_width) * INT64(raw_height) * 8LL) + is_raw = 0; + } + 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 (maximum < 0x10000 && curve[maximum] > 0 && + load_raw == &LibRaw::sony_arw2_load_raw) + maximum = curve[maximum]; + } + if (maximum > 0xffff) + maximum = 0xffff; + if (!load_raw || height < 22 || width < 22 || + (tiff_bps > 16 && + (load_raw != &LibRaw::deflate_dng_load_raw && + load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) || + tiff_samples > 6 || colors > 4) + is_raw = 0; + + if (raw_width < 22 || raw_width > 64000 || raw_height < 22 || + pixel_aspect < 0.1 || pixel_aspect > 10. || + raw_height > 64000) + is_raw = 0; + if(raw_width <= left_margin || raw_height <= top_margin) + is_raw = 0; + if (dng_version && (tiff_samples < 1 || tiff_samples > 4)) + is_raw = 0; // we do not handle DNGs with more than 4 values per pixel + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +#ifdef NO_JASPER + if (load_raw == &LibRaw::redcine_load_raw) + { + is_raw = 0; + imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER; + } +#endif +#endif +#ifdef NO_JPEG + if (load_raw == &LibRaw::kodak_jpeg_load_raw || + load_raw == &LibRaw::lossy_dng_load_raw) + { + is_raw = 0; + imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB; + } +#endif + if (!cdesc[0]) + strcpy(cdesc, colors == 3 ? "RGBG" : "GMCY"); + if (!raw_height) + raw_height = height; + if (!raw_width) + raw_width = width; + if (filters > 999 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) & + filters << 1; +notraw: + if (flip == (int)UINT_MAX) + flip = tiff_flip; + if (flip == (int)UINT_MAX) + flip = 0; + + // Convert from degrees to bit-field if needed + if (flip > 89 || flip < -89) + { + switch ((flip + 3600) % 360) + { + case 270: + flip = 5; + break; + case 180: + flip = 3; + break; + case 90: + flip = 6; + break; + } + } + + if (pana_bpp) + imgdata.color.raw_bps = pana_bpp; + else if ((load_raw == &LibRaw::phase_one_load_raw) || + (load_raw == &LibRaw::phase_one_load_raw_s) || + (load_raw == &LibRaw::phase_one_load_raw_c)) + imgdata.color.raw_bps = ph1.format; + else + imgdata.color.raw_bps = tiff_bps; + + RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2); +} + +void LibRaw::identify_process_dng_fields() +{ + if (!dng_version) return; + + // Cleanup inset_crops if set by makernotes parser + imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[0].ctop = + imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff; + imgdata.sizes.raw_inset_crops[0].cwidth = imgdata.sizes.raw_inset_crops[0].cheight = + imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[1].cheight = 0; + + + int c; + { + /* copy DNG data from per-IFD field to color.dng */ + int iifd = find_ifd_by_offset(data_offset); + int pifd = find_ifd_by_offset(thumb_offset); + + +#define IFDCOLORINDEX(ifd, subset, bit) \ + (tiff_ifd[ifd].dng_color[subset].parsedfields & bit) \ + ? ifd \ + : ((tiff_ifd[0].dng_color[subset].parsedfields & bit) ? 0 : -1) + +#define IFDLEVELINDEX(ifd, bit) \ + (tiff_ifd[ifd].dng_levels.parsedfields & bit) \ + ? ifd \ + : ((tiff_ifd[0].dng_levels.parsedfields & bit) ? 0 : -1) + +#define COPYARR(to, from) memmove(&to, &from, sizeof(from)) + + if (iifd < (int)tiff_nifds && iifd >= 0) + { + int sidx; + // Per field, not per structure + if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT)) + { + int illidx[2], cmidx[2], calidx[2], abidx; + for (int i = 0; i < 2; i++) + { + illidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_ILLUMINANT); + cmidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_COLORMATRIX); + calidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_CALIBRATION); + } + abidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE); + // Data found, all in same ifd, illuminants are inited + if (illidx[0] >= 0 && illidx[0] < (int)tiff_nifds && + illidx[0] == illidx[1] && illidx[0] == cmidx[0] && + illidx[0] == cmidx[1] && + tiff_ifd[illidx[0]].dng_color[0].illuminant > 0 && + tiff_ifd[illidx[0]].dng_color[1].illuminant > 0) + { + sidx = illidx[0]; // => selected IFD + double cc[4][4], cm[4][3], cam_xyz[4][3]; + // CM -> Color Matrix + // CC -> Camera calibration + for (int j = 0; j < 4; j++) + for (int i = 0; i < 4; i++) + cc[j][i] = i == j; + int colidx = -1; + + // IS D65 here? + for (int i = 0; i < 2; i++) + { + if (tiff_ifd[sidx].dng_color[i].illuminant == LIBRAW_WBI_D65) + { + colidx = i; + break; + } + } + + // Other daylight-type ill + if (colidx < 0) + for (int i = 0; i < 2; i++) + { + int ill = tiff_ifd[sidx].dng_color[i].illuminant; + if (ill == LIBRAW_WBI_Daylight || ill == LIBRAW_WBI_D55 || + ill == LIBRAW_WBI_D75 || ill == LIBRAW_WBI_D50 || + ill == LIBRAW_WBI_Flash) + { + colidx = i; + break; + } + } + if (colidx >= 0) // Selected + { + // Init camera matrix from DNG + FORCC for (int j = 0; j < 3; j++) cm[c][j] = + tiff_ifd[sidx].dng_color[colidx].colormatrix[c][j]; + + if (calidx[colidx] == sidx) + { + for (int i = 0; i < colors && i < 4; i++) + FORCC + cc[i][c] = tiff_ifd[sidx].dng_color[colidx].calibration[i][c]; + } + + if (abidx == sidx) + for (int i = 0; i < colors && i < 4; i++) + FORCC cc[i][c] *= tiff_ifd[sidx].dng_levels.analogbalance[i]; + int j; + FORCC for (int i = 0; i < 3; i++) + for (cam_xyz[c][i] = j = 0; j < colors && j < 4; j++) + cam_xyz[c][i] += + cc[c][j] * cm[j][i]; // add AsShotXY later * xyz[i]; + cam_xyz_coeff(cmatrix, cam_xyz); + } + } + } + + bool noFujiDNGCrop = makeIs(LIBRAW_CAMERAMAKER_Fujifilm) + && (!strcmp(normalized_model, "S3Pro") + || !strcmp(normalized_model, "S5Pro") + || !strcmp(normalized_model, "S2Pro")); + + if (!noFujiDNGCrop) // Promote DNG Crops to raw_inset_crops + { + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPORIGIN); + int sidx2 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPSIZE); + if (sidx >= 0 && sidx == sidx2 && + tiff_ifd[sidx].dng_levels.default_crop[2] > 0 && + tiff_ifd[sidx].dng_levels.default_crop[3] > 0) + { + int lm = tiff_ifd[sidx].dng_levels.default_crop[0]; + int tm = tiff_ifd[sidx].dng_levels.default_crop[1]; + int ww = tiff_ifd[sidx].dng_levels.default_crop[2]; + int hh = tiff_ifd[sidx].dng_levels.default_crop[3]; + if ((lm + ww < int(raw_width) + int(left_margin)) + && (tm + hh < int(raw_height) + int(top_margin))) // Crop data is correct + { + imgdata.sizes.raw_inset_crops[0].cleft = left_margin + lm; + imgdata.sizes.raw_inset_crops[0].cwidth = ww; + imgdata.sizes.raw_inset_crops[0].ctop = top_margin + tm; + imgdata.sizes.raw_inset_crops[0].cheight = hh; + + int sidx3 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_USERCROP); + if (sidx3 >= 0 && sidx3 == sidx) // No need to check values range, it is checked at parse + { + int dt = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[0]); + int dl = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[1]); + int db = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[2]); + int dr = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[3]); + + int dh = db - dt; + int dw = dr - dl; + + if (dh > 0 && dw > 0 + && dh < imgdata.sizes.raw_inset_crops[0].cheight // No need to repeat crop for 0,0,1,1 + && dw < imgdata.sizes.raw_inset_crops[0].cwidth) + { + imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dl; + imgdata.sizes.raw_inset_crops[1].cwidth = dw; + imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dt; + imgdata.sizes.raw_inset_crops[1].cheight = dh; + } + } + + } + } + } + if (!(imgdata.color.dng_color[0].parsedfields & + LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes) + { + sidx = IFDCOLORINDEX(iifd, 0, LIBRAW_DNGFM_FORWARDMATRIX); + if (sidx >= 0) + COPYARR(imgdata.color.dng_color[0].forwardmatrix, + tiff_ifd[sidx].dng_color[0].forwardmatrix); + } + if (!(imgdata.color.dng_color[1].parsedfields & + LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes) + { + sidx = IFDCOLORINDEX(iifd, 1, LIBRAW_DNGFM_FORWARDMATRIX); + if (sidx >= 0) + COPYARR(imgdata.color.dng_color[1].forwardmatrix, + tiff_ifd[sidx].dng_color[1].forwardmatrix); + } + for (int ss = 0; ss < 2; ss++) + { + sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_COLORMATRIX); + if (sidx >= 0) + COPYARR(imgdata.color.dng_color[ss].colormatrix, + tiff_ifd[sidx].dng_color[ss].colormatrix); + + sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_CALIBRATION); + if (sidx >= 0) + COPYARR(imgdata.color.dng_color[ss].calibration, + tiff_ifd[sidx].dng_color[ss].calibration); + + sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_ILLUMINANT); + if (sidx >= 0) + imgdata.color.dng_color[ss].illuminant = + tiff_ifd[sidx].dng_color[ss].illuminant; + } + // Levels + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE); + if (sidx >= 0) + COPYARR(imgdata.color.dng_levels.analogbalance, + tiff_ifd[sidx].dng_levels.analogbalance); + + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BASELINEEXPOSURE); + if (sidx >= 0) + imgdata.color.dng_levels.baseline_exposure = + tiff_ifd[sidx].dng_levels.baseline_exposure; + + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_WHITE); + if (sidx >= 0 && tiff_ifd[sidx].dng_levels.dng_whitelevel[0]) + COPYARR(imgdata.color.dng_levels.dng_whitelevel, + tiff_ifd[sidx].dng_levels.dng_whitelevel); + else if (tiff_ifd[iifd].sample_format <= 2 && tiff_ifd[iifd].bps > 0 && tiff_ifd[iifd].bps < 32) + FORC4 + imgdata.color.dng_levels.dng_whitelevel[c] = (1 << tiff_ifd[iifd].bps) - 1; + + + + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ASSHOTNEUTRAL); + if (sidx >= 0) + { + COPYARR(imgdata.color.dng_levels.asshotneutral, + tiff_ifd[sidx].dng_levels.asshotneutral); + if (imgdata.color.dng_levels.asshotneutral[0]) + { + cam_mul[3] = 0; + FORCC + if (fabs(imgdata.color.dng_levels.asshotneutral[c]) > 0.0001) + cam_mul[c] = 1 / imgdata.color.dng_levels.asshotneutral[c]; + } + } + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BLACK); + if (sidx >= 0) + { + imgdata.color.dng_levels.dng_fblack = + tiff_ifd[sidx].dng_levels.dng_fblack; + imgdata.color.dng_levels.dng_black = + tiff_ifd[sidx].dng_levels.dng_black; + COPYARR(imgdata.color.dng_levels.dng_cblack, + tiff_ifd[sidx].dng_levels.dng_cblack); + COPYARR(imgdata.color.dng_levels.dng_fcblack, + tiff_ifd[sidx].dng_levels.dng_fcblack); + } + + + if (pifd >= 0) + { + sidx = IFDLEVELINDEX(pifd, LIBRAW_DNGFM_PREVIEWCS); + if (sidx >= 0) + imgdata.color.dng_levels.preview_colorspace = + tiff_ifd[sidx].dng_levels.preview_colorspace; + } + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_OPCODE2); + if (sidx >= 0) + meta_offset = tiff_ifd[sidx].opcode2_offset; + + sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINTABLE); + INT64 linoff = -1; + int linlen = 0; + if (sidx >= 0) + { + linoff = tiff_ifd[sidx].lineartable_offset; + linlen = tiff_ifd[sidx].lineartable_len; + } + + if (linoff >= 0 && linlen > 0) + { + INT64 pos = ftell(ifp); + fseek(ifp, linoff, SEEK_SET); + linear_table(linlen); + fseek(ifp, pos, SEEK_SET); + } + // Need to add curve too + } + /* Copy DNG black level to LibRaw's */ + if (load_raw == &LibRaw::lossy_dng_load_raw) + { + maximum = 0xffff; + FORC4 imgdata.color.linear_max[c] = imgdata.color.dng_levels.dng_whitelevel[c] = 0xffff; + } + else + { + maximum = imgdata.color.dng_levels.dng_whitelevel[0]; + } + black = imgdata.color.dng_levels.dng_black; + if (tiff_samples == 2 && + !imgdata.color.dng_levels.dng_cblack[2] && + !imgdata.color.dng_levels.dng_cblack[3] && + (imgdata.color.dng_levels.dng_cblack[4] == 1) && + (imgdata.color.dng_levels.dng_cblack[5] == 1) + && (imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] == tiff_samples) + ) { + black = imgdata.color.dng_levels.dng_cblack[shot_select]; + imgdata.color.dng_levels.dng_cblack[0] = imgdata.color.dng_levels.dng_cblack[1] = 0; + imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; + imgdata.color.dng_levels.dng_fcblack[0] = imgdata.color.dng_levels.dng_fcblack[1] = 0.0f; + imgdata.color.dng_levels.dng_fcblack[4] = imgdata.color.dng_levels.dng_fcblack[5] = 0.0f; + } + else if (tiff_samples == 2 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples + == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1]) + { + unsigned ff = filters; + if (filters > 999 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) & + filters << 1; + + /* Special case, Fuji SuperCCD dng */ + int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 }; + int i = 6 + shot_select; + for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++) + for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++) + { + csum[FC(row, col)] += imgdata.color.dng_levels.dng_cblack[i]; + ccount[FC(row, col)]++; + i += tiff_samples; + } + for (int q = 0; q < 4; q++) + if (ccount[q]) + imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q]; + imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; + filters = ff; + } + else if (tiff_samples > 2 && tiff_samples <= 4 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples + == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1]) + { + /* Special case, per_channel blacks in RepeatDim, average for per-channel */ + int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 }; + int i = 6; + for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++) + for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++) + for (unsigned q = 0; q < tiff_samples && q < 4; q++) + { + csum[q] += imgdata.color.dng_levels.dng_cblack[i]; + ccount[q]++; + i++; + } + for (int q = 0; q < 4; q++) + if (ccount[q]) + imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q]; + imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0; + } + + memmove(cblack, imgdata.color.dng_levels.dng_cblack, sizeof(cblack)); + + if (iifd < (int)tiff_nifds && iifd >= 0) + { + int sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINEARRESPONSELIMIT); + if (sidx >= 0) + { + imgdata.color.dng_levels.LinearResponseLimit = + tiff_ifd[sidx].dng_levels.LinearResponseLimit; + if (imgdata.color.dng_levels.LinearResponseLimit > 0.1 && + imgdata.color.dng_levels.LinearResponseLimit <= 1.0) + { + // And approx promote it to linear_max: + int bl4 = 0, bl64 = 0; + for (int chan = 0; chan < colors && chan < 4; chan++) + bl4 += cblack[chan]; + bl4 /= LIM(colors, 1, 4); + + if (cblack[4] * cblack[5] > 0) + { + unsigned cnt = 0; + for (unsigned q = 0; q < 4096 && q < cblack[4] * cblack[5]; q++) + { + bl64 += cblack[q + 6]; + cnt++; + } + bl64 /= LIM(cnt, 1, 4096); + } + int rblack = black + bl4 + bl64; + for (int chan = 0; chan < colors && chan < 4; chan++) + imgdata.color.linear_max[chan] = + (maximum - rblack) * + imgdata.color.dng_levels.LinearResponseLimit + + rblack; + if (imgdata.color.linear_max[1] && !imgdata.color.linear_max[3]) + imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; + } + } + } + } +} + +void LibRaw::identify_finetune_pentax() +{ + if (dng_version && data_offset) + { + for(int i = 0; i < (int)tiff_nifds; i++) + if (tiff_ifd[i].offset == data_offset) + { + if (tiff_ifd[i].phint == 34892) return; // Linear DNG made from Pentax source + break; + } + } + + if (makeIs(LIBRAW_CAMERAMAKER_Pentax) || + makeIs(LIBRAW_CAMERAMAKER_Samsung)) { + if (height == 2624 && + width == 3936) // Pentax K10D, Samsung GX10; + { + height = 2616; + width = 3896; + } + if (height == 3136 && + width == 4864) // Pentax K20D, Samsung GX20; + { + height = 3124; + width = 4688; + filters = 0x16161616; + } + } + + if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) { + if ((width == 4352) && + ((unique_id == PentaxID_K_r) || + (unique_id == PentaxID_K_x))) + { + width = 4309; + filters = 0x16161616; + } + if ((width >= 4960) && + ((unique_id == PentaxID_K_5) || + (unique_id == PentaxID_K_5_II) || + (unique_id == PentaxID_K_5_II_s))) + { + left_margin = 10; + width = 4950; + filters = 0x16161616; + } + if ((width == 6080) && (unique_id == PentaxID_K_70)) + { + height = 4016; + top_margin = 32; + width = 6020; + left_margin = 60; + } + if ((width == 4736) && (unique_id == PentaxID_K_7)) + { + height = 3122; + width = 4684; + filters = 0x16161616; + top_margin = 2; + } + if ((width == 6080) && (unique_id == PentaxID_K_3_II)) + { + left_margin = 4; + width = 6040; + } + if ((width == 6304) && (unique_id == PentaxID_K_3_III)) // From DNG ActiveArea + { + left_margin = 26; + width = 6224; + top_margin = 34; + height = 4160; + } + if ((width == 6112) && (unique_id == PentaxID_KP)) + { + // From DNG, maybe too strict + left_margin = 54; + top_margin = 28; + width = 6028; + height = raw_height - top_margin; + } + if ((width == 6080) && (unique_id == PentaxID_K_3)) + { + left_margin = 4; + width = 6040; + } + if ((width == 7424) && (unique_id == PentaxID_645D)) + { + height = 5502; + width = 7328; + filters = 0x61616161; + top_margin = 29; + left_margin = 48; + } + } + else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && + (height == 3014) && (width == 4096)) // Ricoh GX200 + width = 4014; +} + +void LibRaw::identify_finetune_by_filesize(int fsize) +{ + + if (fsize == 4771840) + { // hack Nikon 3mpix: E880, E885, E990, E995; + // Olympus C-3030Z + if (!timestamp && nikon_e995()) + strcpy(model, "E995"); + } + else if (fsize == 2940928) + { // hack Nikon 2mpix: E2100, E2500 + if (!timestamp && !nikon_e2100()) + strcpy(model, "E2500"); + } + else if (fsize == 4775936) + { // hack Nikon 3mpix: E3100, E3200, E3500, E3700; + // Pentax "Optio 33WR"; + // Olympus C-740UZ + if (!timestamp) + nikon_3700(); + } + else if (fsize == 5869568) + { // hack Nikon 4mpix: E4300; + // hack Minolta "DiMAGE Z2" + if (!timestamp && minolta_z2()) + { + maker_index = LIBRAW_CAMERAMAKER_Minolta; + strcpy(make, "Minolta"); + strcpy(model, "DiMAGE Z2"); + } + } +} + +void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) +{ + static const short pana[][6] = { + // raw_width, raw_height, left_margin, top_margin, width_increment, + // height_increment + {3130, 1743, 4, 0, -6, 0}, /* 00 */ + {3130, 2055, 4, 0, -6, 0}, /* 01 */ + {3130, 2319, 4, 0, -6, 0}, /* 02 DMC-FZ8 */ + {3170, 2103, 18, 0, -42, 20}, /* 03 */ + {3170, 2367, 18, 13, -42, -21}, /* 04 */ + {3177, 2367, 0, 0, -1, 0}, /* 05 DMC-L1 */ + {3304, 2458, 0, 0, -1, 0}, /* 06 DMC-FZ30 */ + {3330, 2463, 9, 0, -5, 0}, /* 07 DMC-FZ18 */ + {3330, 2479, 9, 0, -17, 4}, /* 08 */ + {3370, 1899, 15, 0, -44, 20}, /* 09 */ + {3370, 2235, 15, 0, -44, 20}, /* 10 */ + {3370, 2511, 15, 10, -44, -21}, /* 11 */ + {3690, 2751, 3, 0, -8, -3}, /* 12 DMC-FZ50 */ + {3710, 2751, 0, 0, -3, 0}, /* 13 DMC-L10 */ + {3724, 2450, 0, 0, 0, -2}, /* 14 */ + {3770, 2487, 17, 0, -44, 19}, /* 15 */ + {3770, 2799, 17, 15, -44, -19}, /* 16 */ + {3880, 2170, 6, 0, -6, 0}, /* 17 DMC-LX1 */ + {4060, 3018, 0, 0, 0, -2}, /* 18 DMC-FZ35, DMC-FZ38 */ + {4290, 2391, 3, 0, -8, -1}, /* 19 DMC-LX2 */ + {4330, 2439, 17, 15, -44, -19}, /* 20 "D-LUX 3" */ + {4508, 2962, 0, 0, -3, -4}, /* 21 */ + {4508, 3330, 0, 0, -3, -6}, /* 22 */ + {10480, 7794, 0, 0, -2, 0}, /* 23: G9 in high-res */ + }; + int i,c; + struct jhead jh; + + if (makeIs(LIBRAW_CAMERAMAKER_Canon) + && ( !tiff_flip || unique_id == CanonID_EOS_40D) + && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION) + && imCanon.MakernotesFlip) + { + tiff_flip = imCanon.MakernotesFlip; + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) + { + if (!load_raw) + load_raw = &LibRaw::packed_load_raw; + if (model[0] == 'E') // Nikon E8800, E8700, E8400, E5700, E5400, E5000, + // others are diag hacks? + load_flags |= !data_offset << 2 | 2; + } + /* Set parameters based on camera name (for non-DNG files). */ + + /* Always 512 for arw2_load_raw */ + else if (makeIs(LIBRAW_CAMERAMAKER_Sony) && + (raw_width > 3888) && !black && !cblack[0]) + { + black = (load_raw == &LibRaw::sony_arw2_load_raw) + ? 512 + : (128 << (tiff_bps - 12)); + } + + if (is_foveon) { + if (height * 2 < width) + pixel_aspect = 0.5; + if (height > width) + pixel_aspect = 2; + filters = 0; + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) { + if ((unique_id == PentaxID_K_1) || + (unique_id == PentaxID_K_1_Mark_II)) { + top_margin = 18; + height = raw_height - top_margin; + if (raw_width == 7392) { + left_margin = 6; + width = 7376; + } + + } + else if (unique_id == PentaxID_Optio_S_V101) { // (fsize == 3178560) + cam_mul[0] *= 4; + cam_mul[2] *= 4; + + } + else if (unique_id == PentaxID_Optio_33WR) { // (fsize == 4775936) + flip = 1; + filters = 0x16161616; + + } + else if (unique_id == PentaxID_staristD) { + load_raw = &LibRaw::unpacked_load_raw; + /* data_error = -1; */ /* No way to know why data_error was raised in dcraw.c, looks not needed esp. for unpacked_load_raw */ + } + else if (unique_id == PentaxID_staristDS) { + height -= 2; + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Canon)) { + if (tiff_bps == 15) { // Canon sRAW + if (width == 3344) + width = 3272; + else if (width == 3872) + width = 3866; + + if (height > width) { + SWAP(height, width); + SWAP(raw_height, raw_width); + } + if (width == 7200 && + height == 3888) { // Canon EOS 5DS (R); + raw_width = width = 6480; + raw_height = height = 4320; + } + filters = 0; + tiff_samples = colors = 3; + load_raw = &LibRaw::canon_sraw_load_raw; + } + + if (!strcmp(normalized_model, "PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = &LibRaw::canon_600_load_raw; + + } + else if (!strcmp(normalized_model, "PowerShot A5") || + !strcmp(normalized_model, "PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + pixel_aspect = 256 / 235.0; + filters = 0x1e4e1e4e; + goto canon_a5; + + } + else if (!strcmp(normalized_model, "PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + filters = 0x1b4e4b1e; + goto canon_a5; + + } + else if (!strcmp(normalized_model, "PowerShot Pro70")) { + height = 1024; + width = 1552; + filters = 0x1e4b4e1b; + canon_a5: + colors = 4; + tiff_bps = 10; + load_raw = &LibRaw::packed_load_raw; + load_flags = 40; + + } + else if (!strcmp(normalized_model, "PowerShot Pro90 IS") || + !strcmp(normalized_model, "PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + + } + else if (!strcmp(normalized_model, "PowerShot A610")) { // chdk hack + if (canon_s2is()) { + strcpy(model + 10, "S2 IS"); + strcpy(normalized_model + 10, "S2 IS"); + } + + } + else if (!strcmp(normalized_model, "PowerShot SX220 HS")) { // chdk hack + mask[1][3] = -4; + top_margin = 16; + left_margin = 92; + + } + else if (!strcmp(normalized_model, "PowerShot S120")) { // chdk hack + raw_width = 4192; + raw_height = 3062; + width = 4022; + height = 3016; + mask[0][0] = top_margin = 31; + mask[0][2] = top_margin + height; + left_margin = 120; + mask[0][1] = 23; + mask[0][3] = 72; + + } + else if (!strcmp(normalized_model, "PowerShot G16")) { + mask[0][0] = 0; + mask[0][2] = 80; + mask[0][1] = 0; + mask[0][3] = 16; + top_margin = 29; + left_margin = 120; + width = raw_width - left_margin - 48; + height = raw_height - top_margin - 14; + + } + else if (!strcmp(normalized_model, "PowerShot SX50 HS")) { + top_margin = 17; + } + + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) { + if (!strcmp(model, "D1")) + { + imgdata.other.analogbalance[0] = cam_mul[0]; + imgdata.other.analogbalance[2] = cam_mul[2]; + imgdata.other.analogbalance[1] = imgdata.other.analogbalance[3] = + cam_mul[1]; + cam_mul[0] = cam_mul[1] = cam_mul[2] = 1.0f; + } + + else if (!strcmp(model, "D1X")) + { + width -= 4; + pixel_aspect = 0.5; + } + else if (!strcmp(model, "D40X") || + !strcmp(model, "D60") || + !strcmp(model, "D80") || + !strcmp(model, "D3000")) + { + height -= 3; + width -= 4; + } + else if (!strcmp(model, "D3") || + !strcmp(model, "D3S") || + !strcmp(model, "D700")) + { + width -= 4; + left_margin = 2; + } + else if (!strcmp(model, "D3100")) + { + width -= 28; + left_margin = 6; + } + else if (!strcmp(model, "D5000") || + !strcmp(model, "D90")) + { + width -= 42; + } + else if (!strcmp(model, "D5100") || + !strcmp(model, "D7000") || + !strcmp(model, "COOLPIX A")) + { + width -= 44; + } + else if (!strcmp(model, "D3200") || + !strcmp(model, "D600") || + !strcmp(model, "D610") || + !strncmp(model, "D800", 4)) // Nikons: D800, D800E + { + width -= 46; + } + else if (!strcmp(model, "D4") || + !strcmp(model, "Df")) + { + width -= 52; + left_margin = 2; + } + else if (!strcmp(model, "D500")) + { + // Empty - to avoid width-1 below + } + else if (!strncmp(model, "D40", 3) || + !strncmp(model, "D50", 3) || + !strncmp(model, "D70", 3)) + { + width--; + } + else if (!strcmp(model, "D100")) + { + if (load_flags) // compressed NEF + raw_width = (width += 3) + 3; + } + else if (!strcmp(model, "D200")) + { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } + else if (!strncmp(model, "D2H", 3)) // Nikons: D2H, D2Hs + { + left_margin = 6; + width -= 14; + } + else if (!strncmp(model, "D2X", 3)) // Nikons: D2X, D2Xs + { + if (width == 3264) // in-camera Hi-speed crop: On + width -= 32; + else + width -= 8; + } + else if (!strncmp(model, "D300", 4)) // Nikons: D300, D300s + { + width -= 32; + } + else if (raw_width == 4032) // Nikon "COOLPIX P7700", "COOLPIX P7800", + // "COOLPIX P330", "COOLPIX P340" + { + if (!strcmp(normalized_model, "COOLPIX P7700")) + { + maximum = 65504; + load_flags = 0; + } + else if (!strcmp(normalized_model, "COOLPIX P7800")) + { + maximum = 65504; + load_flags = 0; + } + else if (!strcmp(model, "COOLPIX P340")) + { + load_flags = 0; + } + } + else if (!strncmp(model, "COOLPIX P", 9) && + raw_width != 4032) // Nikon "COOLPIX P1000", "COOLPIX P6000", + // "COOLPIX P7000", "COOLPIX P7100" + { + load_flags = 24; + filters = 0x94949494; + /* the following 'if' is most probably obsolete, because we now read black + * level from metadata */ + if ((model[9] == '7') && /* P7000, P7100 */ + ((iso_speed >= 400) || (iso_speed == 0)) && + !strstr(software, "V1.2")) /* v. 1.2 seen for P7000 only */ + black = 255; + } + else if (!strncmp(model, "COOLPIX B700", 12)) + { + load_flags = 24; + } + else if (!strncmp(model, "1 ", + 2)) // Nikons: "1 AW1", "1 J1", "1 J2", "1 J3", "1 J4", + // "1 J5", "1 S1", "1 S2", "1 V1", "1 V2", "1 V3" + { + height -= 2; + } + else if (fsize == 1581060) // hack Nikon 1mpix: E900 + { + simple_coeff(3); + pre_mul[0] = 1.2085f; + pre_mul[1] = 1.0943f; + pre_mul[3] = 1.1103f; + } + else if ((fsize == 4771840) && // hack Nikon 3mpix: E880, E885, E990 + strcmp(model, "E995")) // but not E995 + { + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196f; + pre_mul[1] = 1.246f; + pre_mul[2] = 1.018f; + } + else if ((fsize == 4775936) && // hack Nikon 3mpix: E3100, E3200, E3500 + (atoi(model + 1) < 3700)) // but not E3700; + { + filters = 0x49494949; + } + else if (fsize == 5869568) // hack Nikon 4mpix: E4300; + { + load_flags = 6; + } + else if (!strcmp(model, "E2500")) + { + height -= 2; + load_flags = 6; + colors = 4; + filters = 0x4b4b4b4b; + } + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Olympus)) { + if (OlyID == OlyID_C_740UZ) { // (fsize == 4775936) + 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 (OlyID == OlyID_C_770UZ) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = &LibRaw::packed_load_raw; + load_flags = 30; + } + else { + height += height & 1; + if (exif_cfa) + filters = exif_cfa; + + if (width == 4100) // Olympus E-PL2, E-PL1, E-P2, E-P1, E-620, E-600, E-5, E-30; + width -= 4; + + if (width == 4080) // Olympus E-PM1, E-PL3, E-P3; + width -= 24; + + if (width == 10400) // Olympus PEN-F, E-M1-II, E-M1-III, E-M1X, OM-1 + width -= 12; + + if (width == 8200) // E-M1-III in 50Mp mode, E-M1X + width -= 30; + + if (width == 8180) // OM-1 in 50Mp + width -= 10; + + if (width == 9280) { // Olympus E-M5 Mark II; + width -= 6; + height -= 6; + } + + if (load_raw == &LibRaw::unpacked_load_raw) { + load_flags = 4; + if (imOly.ValidBits == 10) load_flags += 2; + } + tiff_bps = imOly.ValidBits; + + if ((OlyID == OlyID_E_300) || + (OlyID == OlyID_E_500)) { + width -= 20; + if (load_raw == &LibRaw::unpacked_load_raw) { + maximum = 0xfc3; + memset(cblack, 0, sizeof cblack); + } + } + else if (OlyID == OlyID_STYLUS_1) { + width -= 16; + maximum = 0xfff; + + } + else if (OlyID == OlyID_E_330) { + width -= 30; + if (load_raw == &LibRaw::unpacked_load_raw) + maximum = 0xf79; + + } + else if (OlyID == OlyID_SP_550UZ) { + thumb_length = flen - (thumb_offset = 0xa39800); + thumb_height = 480; + thumb_width = 640; + + } + else if (OlyID == OlyID_TG_4) { + width -= 16; + + } + else if ((OlyID == OlyID_TG_5) || + (OlyID == OlyID_TG_6)) { + width -= 26; + } + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_RoverShot) && + (fsize == 6291456)) { // RoverShot 3320AF + 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"); + maker_index = LIBRAW_CAMERAMAKER_ISG; + model[0] = 0; + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) { + if (!imFuji.RAFDataGeneration && (raw_width == 2944)) // S2Pro + { + height = 2144; + width = 2880; + flip = 6; + } + else if (load_raw != &LibRaw::packed_load_raw && + strncmp(model, "X-", 2) && + filters >= 1000) // Bayer and not an X-model + maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00; + + if (!FujiCropMode && imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) + { + width = imFuji.RAFData_ImageSizeTable[0]; + height = imFuji.RAFData_ImageSizeTable[1]; + } + else if (FujiCropMode == 1) // FF crop on GFX + { + width = raw_width; + height = raw_height; + } + // Do we need set height = raw_height for CropMode == 2 for all cameras?? + else if (FujiCropMode == 4) // electronic shutter, high speed mode (1.25x crop) + { + height = raw_height; + } + + top_margin = (raw_height >= height) ? (raw_height - height) >> 2 << 1 : 0; + left_margin = (raw_width >= width) ? (raw_width - width) >> 2 << 1 : 0; + + if (imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) { + switch (raw_width) { + case 2944: // X-S1, X10, XF1 + filters = 0x16161616; + break; + case 4096: // X20, X30, XQ1, XQ2 + case 5120: // X-Pro1, X-E1, X-A1, X-A2, X-M1 + case 6048: // lossless compressed X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3 + case 6160: // uncompressed (unpacked) X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3 + left_margin = 0; + break; + case 4992: // X-E2S, X-E2, X-T10, X-T1, X100S, X100T, X70 + left_margin = 4; + break; + case 6336: // X-H2S + top_margin = 6; + left_margin = 0; + width = 6264; + height = 4176; + break; + case 6384: // X-T3, X-T4, X100V, X-S10, X-T30, X-Pro3 + top_margin = 0; + switch (FujiCropMode) { + case 0: // no crop + left_margin = 0; + top_margin = 6; + width = 6246; + height = 4170; + break; + case 2: // sports finder mode + left_margin = 624; + width = 5004; + height = raw_height; + break; + case 4: // electronic shutter, high speed mode (1.25x crop) + left_margin = 624; + width = 5004; + break; + } + break; + case 6912: // GFX 50S, GFX 50R; FF crop + case 9216: // GFX 50S, GFX 50R; no crop + left_margin = 0; + top_margin = 0; + break; + case 8472: // GFX 50S II + left_margin = 0; + top_margin = 0; + width = raw_width - 192; + break; + case 9696: // GFX 100; FF crop + case 11808: // GFX 100; no crop + left_margin = 0; + width = raw_width - 146; + height = raw_height - (top_margin = 2); + if (tiff_bps == 16) + maximum = 0xffff; + default: + /* insert model name-based width/height/margins/etc. assignments */ + break; + } + + } else if (!imFuji.RAFDataGeneration) { + switch (raw_width) { + case 2304: // S5100 + height -= (top_margin = 6); + break; + case 3328: // F550EXR, F600EXR, F770EXR, F800EXR, F900EXR, + // HS20EXR, HS30EXR, HS33EXR, HS50EXR + if ((width = raw_width - 66)) + left_margin = 34; + if (imgdata.sizes.raw_inset_crops[0].cleft == 8) // HS50EXR, F900EXR + { + left_margin = 0; + width += 2; + filters = 0x16161616; + } + break; + case 3664: // "HS10 HS11" + filters = 0x16161616; + break; + case 5504: // DBP for GX680 aka DX-2000 + +// 7712 2752 -> 5504 3856 +// width = 688; +// height = 30848; +// raw_width = 688; +// raw_height = 30848; + + left_margin = 32; // imgdata.sizes.raw_inset_crops[0].cleft + top_margin = 8; + width = raw_width - 2*left_margin; + height = raw_height - 2*top_margin; + + load_raw = &LibRaw::unpacked_load_raw_FujiDBP; + // maximum = 0x0fff; + filters = 0x16161616; + load_flags = 0; + flip = 6; + break; + default: + /* insert model name-based width/height/margins/etc. assignments */ + break; + } + } + if (fuji_layout) + raw_width *= is_raw; + if (filters == 9) + FORC(36) + ((char *)xtrans)[c] = + xtrans_abs[(c / 6 + top_margin) % 6][(c + left_margin) % 6]; + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Konica)) { + if (!strcmp(model, "KD-400Z")) { + height = 1711; // 1712 + width = 2312; + raw_width = 2336; + goto konica_400z; + } + else if (!strcmp(model, "KD-510Z")) { + goto konica_510z; + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Minolta)) { + if (fsize == 5869568) { // hack "DiMAGE Z2" + load_flags = 30; + } + + if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_UNPACKED) { + load_raw = &LibRaw::unpacked_load_raw; + } else if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_PACKED) { + load_raw = &LibRaw::packed_load_raw; + } else if (!load_raw && (maximum = 0xfff)) { + load_raw = &LibRaw::unpacked_load_raw; + } + + if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) { + filters = 0x49494949; + } else if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_RGGB) { + filters = 0x94949494; + } + + if (imSony.prd_Active_bps && imSony.prd_Total_bps) { + tiff_bps = imSony.prd_Active_bps; + } + + if (!strncmp(model, "DiMAGE G", 8)) // hack "DiMAGE G400", "DiMAGE G500", + // "DiMAGE G530", "DiMAGE G600" + { + if (model[8] == '4') // DiMAGE G400 + { + height = 1716; + width = 2304; + } + else if (model[8] == '5') // DiMAGE G500 / G530 + { + konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } + else if (model[8] == '6') // DiMAGE G600 + { + height = 2136; + width = 2848; + } + data_offset += 14; + filters = 0x61616161; + konica_400z: + load_raw = &LibRaw::unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) { + if (raw_width == 4704) // Samsung NX100, NX10, NX11, + { + height -= top_margin = 8; + width -= 2 * (left_margin = 8); + load_flags = 32; + } + else if (!strcmp(model, "NX3000")) // Samsung NX3000; raw_width: 5600 + { + top_margin = 38; + left_margin = 92; + width = 5456; + height = 3634; + filters = 0x61616161; + colors = 3; + } + else if (raw_height == 3714) // Samsung NX2000, NX300M, NX300, NX30, + // "NX U" (aka: + // "EK-GN100", "EK-GN110", "EK-GN120", + // "EK-KN120", "Galaxy NX") + { + height -= top_margin = 18; + left_margin = raw_width - (width = 5536); + if (raw_width != 5600) + left_margin = top_margin = 0; + filters = 0x61616161; + colors = 3; + } + else if (raw_width == 5632) // Samsung NX1000, NX200, NX20, NX210 + { + order = 0x4949; + height = 3694; + top_margin = 2; + width = 5574 - (left_margin = 32 + tiff_bps); + if (tiff_bps == 12) + load_flags = 80; + } + else if (raw_width == 5664) // Samsung "NX mini" + { + height -= top_margin = 17; + left_margin = 96; + width = 5544; + filters = 0x49494949; + } + else if (raw_width == 6496) // Samsung NX1, NX500 + { + filters = 0x61616161; + if (!black && !cblack[0] && !cblack[1] && !cblack[2] && !cblack[3]) + black = 1 << (tiff_bps - 7); + } + else if (!strcmp(normalized_model, "EX1")) // Samsung EX1; raw_width: 3688 + { + order = 0x4949; + height -= 20; + top_margin = 2; + if ((width -= 6) > 3682) + { + height -= 10; + width -= 46; + top_margin = 8; + } + } + else if (!strcmp(normalized_model, "WB2000")) // Samsung WB2000; raw_width: 3728 + { + order = 0x4949; + height -= 3; + top_margin = 2; + if ((width -= 10) > 3718) + { + height -= 28; + width -= 56; + top_margin = 8; + } + } + else if (!strcmp(model, "WB550")) // Samsung WB550; raw_width: 4000 + { + order = 0x4949; + } + else if (!strcmp(model, "EX2F")) // Samsung EX2F; raw_width: 4176 + { + height = 3030; + width = 4040; + top_margin = 15; + left_margin = 24; + order = 0x4949; + filters = 0x49494949; + load_raw = &LibRaw::unpacked_load_raw; + } + } + + else if (makeIs(LIBRAW_CAMERAMAKER_ST_Micro) && !strcmp(model, "STV680 VGA")) + { + black = 16; + } + else if (!strcmp(model, "N95")) + { + height = raw_height - (top_margin = 2); + } + else if (!strcmp(model, "640x480")) + { + gamma_curve(0.45, 4.5, 1, 255); + } + else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad)) + { + if (load_raw == &LibRaw::lossless_jpeg_load_raw) + load_raw = &LibRaw::hasselblad_load_raw; + + if ((imHassy.SensorCode == 4) && !strncmp(model, "V96C", 4)) { // Hasselblad V96C + strcpy(model, "V96C"); + strcpy(normalized_model, model); + height -= (top_margin = 6); + width -= (left_margin = 3) + 7; + filters = 0x61616161; + + } + else if ((imHassy.SensorCode == 9) && imHassy.uncropped) { // various Hasselblad '-39' + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; + + } + else if ((imHassy.SensorCode == 13) && imHassy.uncropped) { // Hasselblad H4D-40, H5D-40 + height -= 84; + width -= 82; + top_margin = 4; + left_margin = 41; + filters = 0x61616161; + + } + else if ((imHassy.SensorCode == 11) && imHassy.uncropped) { // Hasselblad H5D-50 + height -= 84; + width -= 82; + top_margin = 4; + left_margin = 41; + filters = 0x61616161; + + } + else if ((imHassy.SensorCode == 15) && + !imHassy.SensorSubCode && // Hasselblad H5D-50c + imHassy.uncropped) { + left_margin = 52; + top_margin = 100; + width = 8272; + height = 6200; + black = 256; + + } + else if ((imHassy.SensorCode == 15) && + (imHassy.SensorSubCode == 2) && // various Hasselblad X1D cameras + imHassy.uncropped) { + top_margin = 96; + height -= 96; + left_margin = 48; + width -= 106; + maximum = 0xffff; + tiff_bps = 16; + + } + else if ((imHassy.SensorCode == 12) && imHassy.uncropped) { // Hasselblad H4D-60 + if (black > 500) { // (imHassy.format == LIBRAW_HF_FFF) + top_margin = 12; + left_margin = 44; + width = 8956; + height = 6708; + memset(cblack, 0, sizeof(cblack)); + black = 512; + } + else { // (imHassy.format == LIBRAW_HF_3FR) + top_margin = 8; + left_margin = 40; + width = 8964; + height = 6716; + black += load_flags = 256; + maximum = 0x8101; + } + + } + else if ((imHassy.SensorCode == 17) && imHassy.uncropped) { // Hasselblad H6D-100c, A6D-100c + left_margin = 64; + width = 11608; + top_margin = 108; + height = raw_height - top_margin; + } + + if (tiff_samples > 1) + { + is_raw = tiff_samples + 1; + if (!shot_select && !half_size) + filters = 0; + } + } + else if (makeIs(LIBRAW_CAMERAMAKER_Sinar)) + { + if (!load_raw) + load_raw = &LibRaw::unpacked_load_raw; + if (is_raw > 1 && !shot_select) + filters = 0; + maximum = 0x3fff; + } + + if (load_raw == &LibRaw::sinar_4shot_load_raw) + { + if (is_raw > 1 && !shot_select) + filters = 0; + } + else if (makeIs(LIBRAW_CAMERAMAKER_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 = &LibRaw::leaf_hdr_load_raw; + raw_width = tile_width; + } + if ((width | height) == 2048) + { + if (tiff_samples == 1) + { + filters = 1; + strcpy(cdesc, "RBTG"); + strcpy(model, "CatchLight"); + strcpy(normalized_model, model); + top_margin = 8; + left_margin = 18; + height = 2032; + width = 2016; + } + else + { + strcpy(model, "DCB2"); + strcpy(normalized_model, model); + top_margin = 10; + left_margin = 16; + height = 2028; + width = 2022; + } + } + else if (width + height == 3144 + 2060) + { + if (!model[0]) + { + strcpy(model, "Cantare"); + strcpy(normalized_model, model); + } + 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) // Leaf "Valeo 6" + { + strcpy(model, "Valeo 6"); + strcpy(normalized_model, model); + height -= 2 * (top_margin = 30); + width -= 2 * (left_margin = 55); + filters = 0x49494949; + } + else if (width == 3171) // Leaf "Valeo 6" + { + strcpy(model, "Valeo 6"); + strcpy(normalized_model, model); + height -= 2 * (top_margin = 24); + width -= 2 * (left_margin = 24); + filters = 0x16161616; + } + } + else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic)) + { + if (raw_width > 0 && + ((flen - data_offset) / (raw_width * 8 / 7) == raw_height)) + load_raw = &LibRaw::panasonic_load_raw; + if (!load_raw) + { + load_raw = &LibRaw::unpacked_load_raw; + load_flags = 4; + } + zero_is_bad = 1; + if ((height += 12) > raw_height) + height = raw_height; + for (i = 0; i < int(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]; + } + if (!tiff_bps && pana_bpp >= 12 && pana_bpp <= 14) + tiff_bps = pana_bpp; + + if (!strcmp(model, "DC-LX100M2") && raw_height == 3568 && raw_width == 4816 && filters == 3) + filters = 4; + + filters = 0x01010101U * + (uchar) "\x94\x61\x49\x16"[((filters - 1) ^ (left_margin & 1) ^ + (top_margin << 1)) & + 3]; + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Contax) && + !strcmp(model, "N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = &LibRaw::packed_load_raw; + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Sony)) { + if (!strcmp(model, "DSC-F828")) { // Sony DSC-F828 + width = 3288; + left_margin = 5; + mask[1][3] = -17; + data_offset = 862144; + load_raw = &LibRaw::sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + strcpy(cdesc, "RGBE"); + + } + else if (!strcmp(model, "DSC-V3")) { // Sony DSC-V3 + width = 3109; + left_margin = 59; + mask[0][1] = 9; + data_offset = 787392; + load_raw = &LibRaw::sony_load_raw; + + } + else if (raw_width == 3984) { // Sony DSC-R1; + width = 3925; + order = 0x4d4d; + + } + else if (raw_width == 4288) { // Sony ILCE-7S, ILCE-7SM2, ILCE-7SM3, DSLR-A700, DSLR-A500; + width -= 32; + } + else if (raw_width == 4600) { // Sony DSLR-A290, DSLR-A350, DSLR-A380; + if (!strcmp(model, "DSLR-A350")) + height -= 4; + black = 0; + + } + else if (raw_width == 4928) { + // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, SLT-A55, + // NEX-5N, SLT-A37, SLT-A57, NEX-F3, NEX-6, NEX-5R, NEX-3N, NEX-5T; + if (height < 3280) + width -= 8; + + } + else if (raw_width == 5504) { + // Sony ILCE-3000, SLT-A58, DSC-RX100M3, ILCE-QX1, + // DSC-RX10M4, DSC-RX100M6, DSC-RX100, DSC-RX100M2, DSC-RX10, + // ILCE-5000, DSC-RX100M4, DSC-RX10M2, DSC-RX10M3, + // DSC-RX100M5, DSC-RX100M5A; + width -= height > 3664 ? 8 : 32; + + } + else if (raw_width == 6048) { + // Sony SLT-A65, DSC-RX1, SLT-A77, DSC-RX1, ILCA-77M2, + // ILCE-7M3, NEX-7, SLT-A99, ILCE-7, DSC-RX1R, ILCE-6000, + // ILCE-5100, ILCE-7M2, ILCA-68, ILCE-6300, ILCE-9, + // ILCE-6500, ILCE-6400; + width -= 24; + if (strstr(normalized_model, "RX1") || + strstr(normalized_model, "A99")) + width -= 6; + + } + else if (raw_width == 7392) { // Sony ILCE-7R; + width -= 30; + + } + else if (raw_width == 8000) { + // Sony ILCE-7RM2, ILCE-7RM2, ILCE-7RM3, DSC-RX1RM2, ILCA-99M2; + width -= 32; + + } + else if (raw_width == 9600) { // Sony ILCE-7RM4 + width -= 32; + + } + else if(unique_id == SonyID_ILCE_1) + { + if (raw_width == 8704 && raw_height == 6144) // ILCE-1 FF@Compressed + { + width = 8660; + height = 5784; + } + else if (raw_width == 8672) // FF uncompressed/lossy + { + width -= 12; + } + else if (raw_width == 6144 && raw_height == 4096) // APSC/Lossless + { + width = 5636; + height = 3768; + } + else if (raw_width == 5664) // APS-C/Uncompressed or lossy + { + width -= 28; + } + } + else if (unique_id == SonyID_ILCE_7M4) + { + if (raw_width == 7168 && raw_height == 5120) // ILCE-1 FF@Compressed + { + width = 7028; + height = 4688; + } + else if (raw_width == 7040) // FF uncompressed/lossy + { + width -= 12; + } + /* FIXME: need APS-C samples, both losslesscompressed and uncompressed or lossy */ + } + + else if (!strcmp(model, "DSLR-A100")) { + if (width == 3880) { + height--; + width = ++raw_width; + } + else { + height -= 4; + width -= 4; + order = 0x4d4d; + load_flags = 2; + } + filters = 0x61616161; + } + } + + else if (!strcmp(model, "PIXL")) { + height -= top_margin = 4; + width -= left_margin = 32; + gamma_curve(0, 7, 1, 255); + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) { + + if (!strncasecmp(model, "EasyShare", 9)) { + data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; + load_raw = &LibRaw::packed_load_raw; + + } + else if (!strcmp(model, "C603") || + !strcmp(model, "C330") || + !strcmp(model, "12MP")) { + order = 0x4949; + if (filters && data_offset) { + fseek(ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); + read_shorts(curve, 256); + } + else + gamma_curve(0, 3.875, 1, 255); + + load_raw = filters ? &LibRaw::eight_bit_load_raw + : strcmp(model, "C330") ? &LibRaw::kodak_c603_load_raw + : &LibRaw::kodak_c330_load_raw; + load_flags = tiff_bps > 16; + tiff_bps = 8; + + } + else { + if (!strncmp(model, "NC2000", 6) || + !strncmp(model, "EOSDCS", 6) || + !strncmp(model, "DCS4", 4)) { + width -= 4; + left_margin = 2; + + } + else if (!strcmp(model, "DCS660M")) { + black = 214; + + } + else if (!strcmp(model, "EOS D2000C")) { + filters = 0x61616161; + if (!black) black = curve[200]; + } + + if (filters == UINT_MAX) filters = 0x61616161; + + if (!strcmp(model + 4, "20X")) + strcpy(cdesc, "MYCY"); + if (!strcmp(model, "DC25")) { + data_offset = 15424; + } + + if (!strncmp(model, "DC2", 3)) { + raw_height = 2 + (height = 242); + if (!strncmp(model, "DC290", 5)) + iso_speed = 100; + if (!strncmp(model, "DC280", 5)) + iso_speed = 70; + if (flen < 100000) { + raw_width = 256; + width = 249; + pixel_aspect = (4.0 * height) / (3.0 * width); + } + else { + raw_width = 512; + width = 501; + pixel_aspect = (493.0 * height) / (373.0 * width); + } + top_margin = left_margin = 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179f; + pre_mul[2] = 1.209f; + pre_mul[3] = 1.036f; + load_raw = &LibRaw::eight_bit_load_raw; + } + else if (!strcmp(model, "DC40")) { + height = 512; + width = 768; + data_offset = 1152; + load_raw = &LibRaw::kodak_radc_load_raw; + tiff_bps = 12; + FORC4 cam_mul[c] = 1.0f; + + } + else if (!strcmp(model, "DC50")) { + height = 512; + width = 768; + iso_speed = 84; + data_offset = 19712; + load_raw = &LibRaw::kodak_radc_load_raw; + FORC4 cam_mul[c] = 1.0f; + + } + else if (!strcmp(model, "DC120")) { + raw_height = height = 976; + raw_width = width = 848; + iso_speed = 160; + pixel_aspect = height / 0.75 / width; + load_raw = tiff_compress == 7 ? &LibRaw::kodak_jpeg_load_raw + : &LibRaw::kodak_dc120_load_raw; + + } + else if (!strcmp(model, "DCS200")) { + thumb_height = 128; + thumb_width = 192; + thumb_offset = 6144; + thumb_misc = 360; + iso_speed = 140; + thumb_format = LIBRAW_INTERNAL_THUMBNAIL_LAYER; + black = 17; + } + } + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Logitech) && + !strcmp(model, "Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = &LibRaw::kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + + } + else if (makeIs(LIBRAW_CAMERAMAKER_Apple) && + !strncmp(model, "QuickTake", 9)) { + if (head[5]) { + strcpy(model + 10, "200"); + strcpy(normalized_model, model); + } + 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 (makeIs(LIBRAW_CAMERAMAKER_Rollei) && + !load_raw) { + switch (raw_width) { + case 1316: // Rollei d530flex + 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 = &LibRaw::rollei_load_raw; + + } + else if (!strcmp(model, "GRAS-50S5C")) { + height = 2048; + width = 2440; + load_raw = &LibRaw::unpacked_load_raw; + data_offset = 0; + filters = 0x49494949; + order = 0x4949; + maximum = 0xfffC; + + } + else if (!strcmp(model, "BB-500CL")) { + height = 2058; + width = 2448; + load_raw = &LibRaw::unpacked_load_raw; + data_offset = 0; + filters = 0x94949494; + order = 0x4949; + maximum = 0x3fff; + + } + else if (!strcmp(model, "BB-500GE")) { + height = 2058; + width = 2456; + load_raw = &LibRaw::unpacked_load_raw; + data_offset = 0; + filters = 0x94949494; + order = 0x4949; + maximum = 0x3fff; + + } + else if (!strcmp(model, "SVS625CL")) { + height = 2050; + width = 2448; + load_raw = &LibRaw::unpacked_load_raw; + data_offset = 0; + filters = 0x94949494; + order = 0x4949; + maximum = 0x0fff; + } +} diff --git a/src/metadata/identify_tools.cpp b/src/metadata/identify_tools.cpp new file mode 100644 index 000000000..28a1d69c8 --- /dev/null +++ b/src/metadata/identify_tools.cpp @@ -0,0 +1,140 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +short LibRaw::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 LibRaw::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}; + if (width > 2064) + return 0.f; // too wide + + 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]); + } + if (sum[0] >= 1.0 && sum[1] >= 1.0) + return 100 * log(sum[0] / sum[1]); + else + return 0.f; +} + +void LibRaw::trimSpaces(char *s) +{ + char *p = s; + int l = int(strlen(p)); + if (!l) + return; + while (isspace(p[l - 1])) + p[--l] = 0; /* trim trailing spaces */ + while (*p && isspace(*p)) + ++p, --l; /* trim leading spaces */ + memmove(s, p, l + 1); +} + +void LibRaw::remove_trailing_spaces(char *string, size_t len) +{ + if (len < 1) + return; // not needed, b/c sizeof of make/model is 64 + string[len - 1] = 0; + if (len < 3) + return; // also not needed + len = strnlen(string, len - 1); + for (size_t i = len - 1; i >= 0; i--) + { + if (isspace((unsigned char)string[i])) + string[i] = 0; + else + break; + } +} + +void LibRaw::remove_caseSubstr(char *string, char *subStr) // replace a substring with an equal length of spaces +{ + char *found; + while ((found = strcasestr(string,subStr))) { + if (!found) return; + int fill_len = int(strlen(subStr)); + int p = found - string; + for (int i=p; i 0x1fff) && (romm_camScale[1] > 0x1fff) && + (romm_camScale[2] > 0x1fff)) + { + FORC3 for (j = 0; j < 3; j++)((float *)romm_camIllum)[c * 3 + j] = + ((float)romm_camTemp[c * 3 + j]) / ((float)romm_camScale[c]); + return 1; + } + } + return 0; +} + +/* Thanks to Alexey Danilchenko for wb as-shot parsing code */ +void LibRaw::parse_kodak_ifd(int base) +{ + unsigned entries, tag, type, len, save; + int c, wbi = -1; + + static const int wbtag_kdc[] = { + LIBRAW_WBI_Auto, // 64037 / 0xfa25 + LIBRAW_WBI_Fluorescent, // 64040 / 0xfa28 + LIBRAW_WBI_Tungsten, // 64039 / 0xfa27 + LIBRAW_WBI_Daylight, // 64041 / 0xfa29 + -1, + -1, + LIBRAW_WBI_Shade // 64042 / 0xfa2a + }; + + static const int wbtag_dcr[] = { + LIBRAW_WBI_Daylight, // 2120 / 0x0848 + LIBRAW_WBI_Tungsten, // 2121 / 0x0849 + LIBRAW_WBI_Fluorescent, // 2122 / 0x084a + LIBRAW_WBI_Flash, // 2123 / 0x084b + LIBRAW_WBI_Custom, // 2124 / 0x084c + LIBRAW_WBI_Auto // 2125 / 0x084d + }; + + // int a_blck = 0; + + entries = get2(); + if (entries > 1024) + return; + INT64 fsize = ifp->size(); + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + INT64 savepos = ftell(ifp); + if (len > 8 && len + savepos > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + if (callbacks.exif_cb) + { + callbacks.exif_cb(callbacks.exifparser_data, tag | 0x20000, type, len, + order, ifp, base); + fseek(ifp, savepos, SEEK_SET); + } + if (tag == 0x03eb) // 1003 + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + else if (tag == 0x03ec) // 1004 + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + else if (tag == 0x03ed) // 1005 + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + else if (tag == 0x03ee) // 1006 + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + else if (tag == 0x03ef) // 1007 + { + if (!strcmp(model, "EOS D2000C")) + black = get2(); + else + imKodak.BlackLevelTop = get2(); + } + else if (tag == 0x03f0) // 1008 + { + if (!strcmp(model, "EOS D2000C")) + { + if (black) // already set by tag 1007 (0x03ef) + black = (black + get2()) / 2; + else + black = get2(); + } + else + imKodak.BlackLevelBottom = get2(); + } + + else if (tag == 0x03f1) + { // 1009 Kodak TextualInfo + if (len > 0) + { + char kti[1024]; + char *pkti; + int nsym = MIN(len, 1023); + fread(kti, 1, nsym, ifp); + kti[nsym] = 0; +#ifdef LIBRAW_WIN32_CALLS + pkti = strtok(kti, "\x0a"); +#else + char *last = 0; + pkti = strtok_r(kti, "\x0a", &last); +#endif + while (pkti != NULL) + { + c = 12; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Camera body:", c))) + { + while ((pkti[c] == ' ') && (c < (int)strlen(pkti))) + { + c++; + } + strcpy(ilm.body, pkti + c); + } + c = 5; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Lens:", c))) + { + ilm.CurFocal = atoi(pkti + c); + } + c = 9; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Aperture:", c))) + { + while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) + { + c++; + } + ilm.CurAp = atof(pkti + c); + } + c = 10; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "ISO Speed:", c))) + { + iso_speed = atoi(pkti + c); + } + c = 13; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Focal Length:", c))) + { + ilm.CurFocal = atoi(pkti + c); + } + c = 13; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Max Aperture:", c))) + { + while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) + { + c++; + } + ilm.MaxAp4CurFocal = atof(pkti + c); + } + c = 13; + if (((int)strlen(pkti) > c) && (!strncasecmp(pkti, "Min Aperture:", c))) + { + while (((pkti[c] == ' ') || (pkti[c] == 'f')) && (c < (int)strlen(pkti))) + { + c++; + } + ilm.MinAp4CurFocal = atof(pkti + c); + } +#ifdef LIBRAW_WIN32_CALLS + pkti = strtok(NULL, "\x0a"); +#else + pkti = strtok_r(NULL, "\x0a", &last); +#endif + } + } + } + + else if (tag == 0x03f3) // 1011 + imCommon.FlashEC = getreal(type); + + else if (tag == 0x03fc) // 1020 + { + wbi = getint(type); + if ((wbi >= 0) && (wbi < 6) && (wbi != -2)) + wbi = wbtag_dcr[wbi]; + } + else if (tag == 0x03fd && len == 72) // 1021 + { /* WB set in software */ + fseek(ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / fMAX(1.0f, get2()); + wbi = -2; + } + + else if ((tag == 0x0406) && (len == 1)) // 1030 + imCommon.CameraTemperature = getreal(type); + else if ((tag == 0x0413) && (len == 1)) // 1043 + imCommon.SensorTemperature = getreal(type); + else if (tag == 0x0848) // 2120 + Kodak_DCR_WBtags(LIBRAW_WBI_Daylight, type, wbi); + else if (tag == 0x0849) // 2121 + Kodak_DCR_WBtags(LIBRAW_WBI_Tungsten, type, wbi); + else if (tag == 0x084a) // 2122 + Kodak_DCR_WBtags(LIBRAW_WBI_Fluorescent, type, wbi); + else if (tag == 0x084b) // 2123 + Kodak_DCR_WBtags(LIBRAW_WBI_Flash, type, wbi); + else if (tag == 0x084c) // 2124 + Kodak_DCR_WBtags(LIBRAW_WBI_Custom, type, wbi); + else if (tag == 0x084d) // 2125 + { + if (wbi == -1) + wbi = LIBRAW_WBI_Auto; + Kodak_DCR_WBtags(LIBRAW_WBI_Auto, type, wbi); + } + else if (tag == 0x089f) // 2207 + imKodak.ISOCalibrationGain = getreal(type); + else if (tag == 0x0903) // 2307 + imKodak.AnalogISO = iso_speed = getreal(type); + else if (tag == 0x090d) // 2317 + linear_table(len); + else if (tag == 0x09ce) // 2510 + stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp); + else if (tag == 0x0e92) // 3730 + { + imKodak.val018percent = get2(); + imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = + imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = + (int)(((float)imKodak.val018percent) / 18.0f * 170.0f); + } + else if (tag == 0x0e93) // 3731 + imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = + imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = + imKodak.val170percent = get2(); + else if (tag == 0x0e94) // 3732 + imKodak.val100percent = get2(); + /* + else if (tag == 0x1784) // 6020 + iso_speed = getint(type); + */ + else if (tag == 0xfa00) // 64000 + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + else if (tag == 0xfa0d) // 64013 + { + wbi = fgetc(ifp); + if ((wbi >= 0) && (wbi < 7)) + wbi = wbtag_kdc[wbi]; + } + else if (tag == 0xfa13) // 64019 + width = getint(type); + else if (tag == 0xfa14) // 64020 + height = (getint(type) + 1) & -2; + /* + height = getint(type); + + else if (tag == 0xfa16) // 64022 + raw_width = get2(); + else if (tag == 0xfa17) // 64023 + raw_height = get2(); + */ + else if (tag == 0xfa18) // 64024 + { + imKodak.offset_left = getint(LIBRAW_EXIFTAG_TYPE_SSHORT); + if (type != LIBRAW_EXIFTAG_TYPE_SSHORT) + imKodak.offset_left += 1; + } + else if (tag == 0xfa19) // 64025 + { + imKodak.offset_top = getint(LIBRAW_EXIFTAG_TYPE_SSHORT); + if (type != LIBRAW_EXIFTAG_TYPE_SSHORT) + imKodak.offset_top += 1; + } + + else if (tag == 0xfa25) // 64037 + Kodak_KDC_WBtags(LIBRAW_WBI_Auto, wbi); + else if (tag == 0xfa27) // 64039 + Kodak_KDC_WBtags(LIBRAW_WBI_Tungsten, wbi); + else if (tag == 0xfa28) // 64040 + Kodak_KDC_WBtags(LIBRAW_WBI_Fluorescent, wbi); + else if (tag == 0xfa29) // 64041 + Kodak_KDC_WBtags(LIBRAW_WBI_Daylight, wbi); + else if (tag == 0xfa2a) // 64042 + Kodak_KDC_WBtags(LIBRAW_WBI_Shade, wbi); + + else if (tag == 0xfa31) // 64049 + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + else if (tag == 0xfa32) // 64050 + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + else if (tag == 0xfa3e) // 64062 + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + else if (tag == 0xfa3f) // 64063 + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + + else if (((tag == 0x07e4) || (tag == 0xfb01)) && + (len == 9)) // 2020 or 64257 + { + if (KodakIllumMatrix(type, (float *)imKodak.romm_camDaylight)) + { + romm_coeff(imKodak.romm_camDaylight); + } + } + else if (((tag == 0x07e5) || (tag == 0xfb02)) && + (len == 9)) // 2021 or 64258 + KodakIllumMatrix(type, (float *)imKodak.romm_camTungsten); + else if (((tag == 0x07e6) || (tag == 0xfb03)) && + (len == 9)) // 2022 or 64259 + KodakIllumMatrix(type, (float *)imKodak.romm_camFluorescent); + else if (((tag == 0x07e7) || (tag == 0xfb04)) && + (len == 9)) // 2023 or 64260 + KodakIllumMatrix(type, (float *)imKodak.romm_camFlash); + else if (((tag == 0x07e8) || (tag == 0xfb05)) && + (len == 9)) // 2024 or 64261 + KodakIllumMatrix(type, (float *)imKodak.romm_camCustom); + else if (((tag == 0x07e9) || (tag == 0xfb06)) && + (len == 9)) // 2025 or 64262 + KodakIllumMatrix(type, (float *)imKodak.romm_camAuto); + + fseek(ifp, save, SEEK_SET); + } +} diff --git a/src/metadata/leica.cpp b/src/metadata/leica.cpp new file mode 100644 index 000000000..cda4b0c63 --- /dev/null +++ b/src/metadata/leica.cpp @@ -0,0 +1,375 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::setLeicaBodyFeatures(int LeicaMakernoteSignature) +{ + if (LeicaMakernoteSignature == -3) // M8 + { + ilm.CameraFormat = LIBRAW_FORMAT_APSH; + ilm.CameraMount = LIBRAW_MOUNT_Leica_M; + } + else if (LeicaMakernoteSignature == -2) // DMR + { + ilm.CameraFormat = LIBRAW_FORMAT_Leica_DMR; + if ((model[0] == 'R') || (model[6] == 'R')) + ilm.CameraMount = LIBRAW_MOUNT_Leica_R; + } + else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" + { + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + } + else if ((LeicaMakernoteSignature == 0x0100) || // X1 + (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" + (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" + (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" + { + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + } + else if (LeicaMakernoteSignature == 0x0400) // "X VARIO (Typ 107)" + { + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + } + else if ((LeicaMakernoteSignature == + 0x0200) || // M10, M10-D, M10-R, "S (Typ 007)", M11 + (LeicaMakernoteSignature == + 0x02ff) || // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)", + // "M Monochrom (Typ 246)", "S (Typ 006)", "S-E (Typ 006)", S2, S3 + (LeicaMakernoteSignature == + 0x0300)) // M9, "M9 Monochrom", "M Monochrom", M-E + { + if ((model[0] == 'M') || (model[6] == 'M')) + { + ilm.CameraFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = LIBRAW_MOUNT_Leica_M; + } + else if ((model[0] == 'S') || (model[6] == 'S')) + { + ilm.CameraFormat = LIBRAW_FORMAT_LeicaS; + ilm.CameraMount = LIBRAW_MOUNT_Leica_S; + } + } + else if ((LeicaMakernoteSignature == 0x0600) || // "T (Typ 701)", TL + (LeicaMakernoteSignature == 0x0900) || // SL2, "SL2-S", "SL (Typ 601)", CL, Q2, "Q2 MONO" + (LeicaMakernoteSignature == 0x1a00)) // TL2 + { + if ((model[0] == 'S') || (model[6] == 'S')) + { + ilm.CameraFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = LIBRAW_MOUNT_LPS_L; + } + else if ((model[0] == 'T') || (model[6] == 'T') || + (model[0] == 'C') || (model[6] == 'C')) + { + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_LPS_L; + } + else if (((model[0] == 'Q') || (model[6] == 'Q')) && + ((model[1] == '2') || (model[7] == '2'))) + { + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + } + } + else if (LeicaMakernoteSignature == 0x0800) // "Q (Typ 116)" + { + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + } +} + +void LibRaw::parseLeicaLensID() +{ + ilm.LensID = get4(); + if (ilm.LensID) + { + ilm.LensID = ((ilm.LensID >> 2) << 8) | (ilm.LensID & 0x3); + if ((ilm.LensID > 0x00ff) && (ilm.LensID < 0x3b00)) + { + ilm.LensMount = ilm.CameraMount; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + } +} + +int LibRaw::parseLeicaLensName(unsigned len) +{ +#define plln ilm.Lens + if (!len) + { + strcpy(plln, "N/A"); + return 0; + } + stmread(plln, len, ifp); + if ((plln[0] == ' ') || !strncasecmp(plln, "not ", 4) || + !strncmp(plln, "---", 3) || !strncmp(plln, "***", 3)) + { + strcpy(plln, "N/A"); + return 0; + } + else + return 1; +#undef plln +} + +int LibRaw::parseLeicaInternalBodySerial(unsigned len) +{ +#define plibs imgdata.shootinginfo.InternalBodySerial + if (!len) + { + strcpy(plibs, "N/A"); + return 0; + } + stmread(plibs, len, ifp); + if (!strncmp(plibs, "000000000000", 12)) + { + plibs[0] = '0'; + plibs[1] = '\0'; + return 1; + } + + if (strnlen(plibs, len) == 13) + { + for (int i = 3; i < 13; i++) + { + if (!isdigit(plibs[i])) + goto non_std; + } + memcpy(plibs + 15, plibs + 9, 4); + memcpy(plibs + 12, plibs + 7, 2); + memcpy(plibs + 9, plibs + 5, 2); + memcpy(plibs + 6, plibs + 3, 2); + plibs[3] = plibs[14] = ' '; + plibs[8] = plibs[11] = '/'; + if (((short)(plibs[3] - '0') * 10 + (short)(plibs[4] - '0')) < 70) + { + memcpy(plibs + 4, "20", 2); + } + else + { + memcpy(plibs + 4, "19", 2); + } + return 2; + } +non_std: +#undef plibs + return 1; +} + +void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) +{ + int c; + uchar ci, cj; + unsigned entries, tag, type, len, save; + short morder, sorder = order; + char buf[10]; + int LeicaMakernoteSignature = -1; + INT64 fsize = ifp->size(); + + fread(buf, 1, 10, ifp); + if (strncmp(buf, "LEICA", 5)) + { + fseek(ifp, -10, SEEK_CUR); + if (uptag == 0x3400) + LeicaMakernoteSignature = 0x3400; + else + LeicaMakernoteSignature = -2; // DMR + } + else + { + fseek(ifp, -2, SEEK_CUR); + LeicaMakernoteSignature = ((uchar)buf[6] << 8) | (uchar)buf[7]; + // printf ("LeicaMakernoteSignature 0x%04x\n", LeicaMakernoteSignature); + if (!LeicaMakernoteSignature && + (!strncmp(model, "M8", 2) || !strncmp(model + 6, "M8", 2))) + LeicaMakernoteSignature = -3; + if ((LeicaMakernoteSignature != 0x0000) && + (LeicaMakernoteSignature != 0x0200) && + (LeicaMakernoteSignature != 0x0800) && + (LeicaMakernoteSignature != 0x0900) && + (LeicaMakernoteSignature != 0x02ff)) + base = ftell(ifp) - 8; + } + setLeicaBodyFeatures(LeicaMakernoteSignature); + + entries = get2(); + if (entries > 1000) + return; + morder = order; + + while (entries--) + { + order = morder; + tiff_get(base, &tag, &type, &len, &save); + + INT64 pos = ifp->tell(); + if (len > 8 && pos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + tag |= uptag << 16; + if (len > 100 * 1024 * 1024) + goto next; // 100Mb tag? No! + + if (LeicaMakernoteSignature == -3) // M8 + { + if (tag == 0x0310) + { + parseLeicaLensID(); + } + else if ((tag == 0x0313) && (fabs(ilm.CurAp) < 0.17f)) + { + ilm.CurAp = getreal(type); + if (ilm.CurAp > 126.3) + { + ilm.CurAp = 0.0f; + } else if (fabs(aperture) < 0.17f) + aperture = ilm.CurAp; + } + else if (tag == 0x0320) + { + imCommon.CameraTemperature = getreal(type); + } + } + else if (LeicaMakernoteSignature == -2) // DMR + { + if (tag == 0x000d) + { + FORC3 cam_mul[c] = get2(); + cam_mul[3] = cam_mul[1]; + } + } + else if (LeicaMakernoteSignature == 0) // "DIGILUX 2" + { + if (tag == 0x0007) + { + imgdata.shootinginfo.FocusMode = get2(); + } + else if (tag == 0x001a) + { + imgdata.shootinginfo.ImageStabilization = get2(); + } + } + else if ((LeicaMakernoteSignature == 0x0100) || // X1 + (LeicaMakernoteSignature == 0x0400) || // "X VARIO" + (LeicaMakernoteSignature == 0x0500) || // X2, "X-E (Typ 102)" + (LeicaMakernoteSignature == 0x0700) || // "X (Typ 113)" + (LeicaMakernoteSignature == 0x1000)) // "X-U (Typ 113)" + { + if (tag == 0x040d) + { + ci = fgetc(ifp); + cj = fgetc(ifp); + imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; + } + } + else if ((LeicaMakernoteSignature == 0x0600) || // TL, "T (Typ 701)" + (LeicaMakernoteSignature == 0x1a00)) // TL2 + { + if (tag == 0x040d) + { + ci = fgetc(ifp); + cj = fgetc(ifp); + imgdata.shootinginfo.ExposureMode = ((ushort)ci << 8) | cj; + } + else if (tag == 0x0303) + { + parseLeicaLensName(len); + } + } + else if (LeicaMakernoteSignature == 0x0200) // M10, M10-D, M10-R, "S (Typ 007)", M11 + { + if ((tag == 0x035a) && (fabs(ilm.CurAp) < 0.17f)) + { + ilm.CurAp = get4() / 1000.0f; + if (ilm.CurAp > 126.3) + { + ilm.CurAp = 0.0f; + } else if (fabs(aperture) < 0.17f) + aperture = ilm.CurAp; + } + } + else if (LeicaMakernoteSignature == 0x02ff) + // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)" + // "M Monochrom (Typ 246)" + // "S (Typ 006)", "S-E (Typ 006)", S2, S3 + { + if (tag == 0x0303) + { + if (parseLeicaLensName(len)) + { + ilm.LensMount = ilm.CameraMount; + ilm.LensFormat = ilm.CameraFormat; + } + } + } + else if (LeicaMakernoteSignature == 0x0300) // M9, "M9 Monochrom", "M Monochrom", M-E + { + if (tag == 0x3400) + { + parseLeicaMakernote(base, 0x3400, MakernoteTagType); + } + } + else if ((LeicaMakernoteSignature == 0x0800) || // "Q (Typ 116)" + (LeicaMakernoteSignature == 0x0900)) // SL2, "SL2-S", "SL (Typ 601)", + // CL, Q2, "Q2 MONO" + { + if ((tag == 0x0304) && (len == 1) && ((c = fgetc(ifp)) != 0) && + (ilm.CameraMount == LIBRAW_MOUNT_LPS_L)) + { + strcpy(ilm.Adapter, "M-Adapter L"); + ilm.LensMount = LIBRAW_MOUNT_Leica_M; + ilm.LensFormat = LIBRAW_FORMAT_FF; + if (c != 0xff) ilm.LensID = c * 256; + } + else if (tag == 0x0500) + { + parseLeicaInternalBodySerial(len); + } + } + else if (LeicaMakernoteSignature == 0x3400) // tag 0x3400 in M9, "M9 Monochrom", "M Monochrom" + { + if (tag == 0x34003402) + { + imCommon.CameraTemperature = getreal(type); + } + else if (tag == 0x34003405) + { + parseLeicaLensID(); + } + else if ((tag == 0x34003406) && (fabs(ilm.CurAp) < 0.17f)) + { + ilm.CurAp = getreal(type); + if (ilm.CurAp > 126.3) + { + ilm.CurAp = 0.0f; + } else if (fabs(aperture) < 0.17f) + aperture = ilm.CurAp; + } + } + + next: + fseek(ifp, save, SEEK_SET); + } + order = sorder; +} diff --git a/src/metadata/makernotes.cpp b/src/metadata/makernotes.cpp new file mode 100644 index 000000000..b8ed4d3c7 --- /dev/null +++ b/src/metadata/makernotes.cpp @@ -0,0 +1,786 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parseSigmaMakernote (int base, int /*uptag*/, unsigned /*dng_writer*/) { +unsigned wb_table1 [] = { + LIBRAW_WBI_Auto, LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, LIBRAW_WBI_Fluorescent, LIBRAW_WBI_Flash, + LIBRAW_WBI_Custom, LIBRAW_WBI_Custom1, LIBRAW_WBI_Custom2 +}; + + unsigned entries, tag, type, len, save; + unsigned i; + + entries = get2(); + if (entries > 1000) + return; + while (entries--) { + tiff_get(base, &tag, &type, &len, &save); + if (tag == 0x0027) { + ilm.LensID = get2(); + } else if (tag == 0x002a) { + ilm.MinFocal = getreal(type); + ilm.MaxFocal = getreal(type); + } else if (tag == 0x002b) { + ilm.MaxAp4MinFocal = getreal(type); + ilm.MaxAp4MaxFocal = getreal(type); + } else if (tag == 0x0120) { + const unsigned tblsz = (sizeof wb_table1 / sizeof wb_table1[0]); + if ((len >= tblsz) && (len%3 == 0) && len/3 <= tblsz) { + for (i=0; i<(len/3); i++) { + icWBC[wb_table1[i]][0] = (int)(getreal(type)*10000.0); + icWBC[wb_table1[i]][1] = icWBC[wb_table1[i]][3] = (int)(getreal(type)*10000.0); + icWBC[wb_table1[i]][2] = (int)(getreal(type)*10000.0); + } + } + } + fseek(ifp, save, SEEK_SET); + } + + return; +} + +void LibRaw::parse_makernote_0xc634(int base, int uptag, unsigned dng_writer) +{ + + if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (!strncmp(make, "NIKON", 5)) + { + parseNikonMakernote(base, uptag, AdobeDNG); + return; + } + else if (!strncasecmp(make, "LEICA", 5)) + { + parseLeicaMakernote(base, uptag, is_0xc634); + return; + } + + short morder, sorder = order; + char buf[10]; + INT64 fsize = ifp->size(); + + fread(buf, 1, 10, ifp); + + if (!strcmp(buf, "EPSON")) + { + parseEpsonMakernote(base, uptag, AdobeDNG); + return; + } + else if (!strcmp(buf, "SIGMA")) + { + parseSigmaMakernote(base, uptag, AdobeDNG); + return; + } + + unsigned entries, tag, type, len, save, c; + + uchar *CanonCameraInfo = NULL; + unsigned lenCanonCameraInfo = 0; + unsigned typeCanonCameraInfo = 0; + + uchar *table_buf_0x0116; + ushort table_buf_0x0116_len = 0; + uchar *table_buf_0x2010; + ushort table_buf_0x2010_len = 0; + uchar *table_buf_0x9050; + ushort table_buf_0x9050_len = 0; + uchar *table_buf_0x9400; + ushort table_buf_0x9400_len = 0; + uchar *table_buf_0x9402; + ushort table_buf_0x9402_len = 0; + uchar *table_buf_0x9403; + ushort table_buf_0x9403_len = 0; + uchar *table_buf_0x9406; + ushort table_buf_0x9406_len = 0; + uchar *table_buf_0x940c; + ushort table_buf_0x940c_len = 0; + uchar *table_buf_0x940e; + ushort table_buf_0x940e_len = 0; + + if (!strcmp(buf, "OLYMPUS") || !strcmp(buf, "PENTAX ") || !strncmp(buf,"OM SYS",6)|| + (!strncmp(make, "SAMSUNG", 7) && (dng_writer == CameraDNG))) + { + base = ftell(ifp) - 10; + fseek(ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') + get2(); + else if (buf[0] == 'P') + is_PentaxRicohMakernotes = 1; + } + else if (is_PentaxRicohMakernotes && (dng_writer == CameraDNG)) + { + base = ftell(ifp) - 10; + fseek(ifp, -4, SEEK_CUR); + order = get2(); + } + else if (!strncmp(buf, "SONY", 4) || + !strcmp(buf, "Panasonic")) + { + order = 0x4949; + fseek(ifp, 2, SEEK_CUR); + } + else if (!strncmp(buf, "FUJIFILM", 8)) + { + base = ftell(ifp) - 10; + order = 0x4949; + fseek(ifp, 2, SEEK_CUR); + } + else if (!strcmp(buf, "OLYMP") || + !strcmp(buf, "Ricoh")) + { + 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) && (dng_writer == AdobeDNG))) + base = ftell(ifp); + } + + entries = get2(); + if (entries > 1000) + return; + + if (!strncasecmp(make, "SONY", 4) || + !strncasecmp(make, "Konica", 6) || + !strncasecmp(make, "Minolta", 7) || + (!strncasecmp(make, "Hasselblad", 10) && + (!strncasecmp(model, "Stellar", 7) || + !strncasecmp(model, "Lunar", 5) || + !strncasecmp(model, "Lusso", 5) || + !strncasecmp(model, "HV", 2)))) + is_Sony = 1; + + if (!is_Olympus && + (!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || + (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) { + is_Olympus = 1; + OlympusDNG_SubDirOffsetValid = + strncmp(model, "E-300", 5) && strncmp(model, "E-330", 5) && + strncmp(model, "E-400", 5) && strncmp(model, "E-500", 5) && + strncmp(model, "E-1", 3); + } + + morder = order; + while (entries--) + { + order = morder; + + tiff_get(base, &tag, &type, &len, &save); + + INT64 pos = ifp->tell(); + if (len > 8 && pos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + tag |= uptag << 16; + if (len > 100 * 1024 * 1024) + goto next; // 100Mb tag? No! + + if (!strncmp(make, "Canon", 5)) + { + if (tag == 0x000d && len < 256000) + { // camera info + if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + CanonCameraInfo = (uchar *)malloc(MAX(16, len)); + fread(CanonCameraInfo, len, 1, ifp); + } + else + { + CanonCameraInfo = (uchar *)malloc(MAX(16, len * 4)); + fread(CanonCameraInfo, len, 4, ifp); + } + lenCanonCameraInfo = len; + typeCanonCameraInfo = type; + } + + else if (tag == 0x0010) // Canon ModelID + { + unique_id = get4(); + setCanonBodyFeatures(unique_id); + if (lenCanonCameraInfo) + { + processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo, + typeCanonCameraInfo, AdobeDNG); + free(CanonCameraInfo); + CanonCameraInfo = 0; + lenCanonCameraInfo = 0; + } + } + + else + parseCanonMakernotes(tag, type, len, AdobeDNG); + } + + else if (!strncmp(make, "FUJI", 4)) { + parseFujiMakernotes(tag, type, len, AdobeDNG); + + } else if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) { + if (tag == 0x0011) { + imHassy.SensorCode = getint(type); + } else if ((tag == 0x0015) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) { + stmread (imHassy.SensorUnitConnector, len, ifp); + for (int i=0; i<(int)len; i++) { + if(!isalnum(imHassy.SensorUnitConnector[i]) && + (imHassy.SensorUnitConnector[i]!=' ') && + (imHassy.SensorUnitConnector[i]!='/') && + (imHassy.SensorUnitConnector[i]!='-')) { + imHassy.SensorUnitConnector[0] = 0; + break; + } + } + } else if (tag == 0x0016) { + imHassy.CoatingCode = getint(type); + } else if ((tag == 0x002a) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) && + (len == 12) && + imHassy.SensorUnitConnector[0]) { + FORC4 for (int i = 0; i < 3; i++) + imHassy.mnColorMatrix[c][i] = getreal(type); + + } else if ((tag == 0x0031) && + imHassy.SensorUnitConnector[0]) { + imHassy.RecommendedCrop[0] = getint(type); + imHassy.RecommendedCrop[1] = getint(type); + } + + } else if (is_Olympus) { + + if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) || + (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) || + (tag == 0x3000)) + { + fseek(ifp, save - 4, SEEK_SET); + fseek(ifp, base + get4(), SEEK_SET); + parse_makernote_0xc634(base, tag, dng_writer); + } + + if (!OlympusDNG_SubDirOffsetValid && + ((len > 4) || + ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) || + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SSHORT)) && (len > 2)) || + ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) || + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) && (len > 1)) || + tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL) || + (type > LIBRAW_EXIFTAG_TYPE_SLONG))) { + goto skip_Oly_broken_tags; + } + else { + parseOlympusMakernotes(base, tag, type, len, AdobeDNG); + } + skip_Oly_broken_tags:; + } + + else if (!strncmp(make, "PENTAX", 6) || + !strncmp(model, "PENTAX", 6) || + is_PentaxRicohMakernotes) + { + parsePentaxMakernotes(base, tag, type, len, dng_writer); + } + else if (!strncmp(make, "SAMSUNG", 7)) + { + if (dng_writer == AdobeDNG) + parseSamsungMakernotes(base, tag, type, len, dng_writer); + else + parsePentaxMakernotes(base, tag, type, len, dng_writer); + } + else if (is_Sony) + { + parseSonyMakernotes( + base, tag, type, len, AdobeDNG, + table_buf_0x0116, table_buf_0x0116_len, + table_buf_0x2010, table_buf_0x2010_len, + table_buf_0x9050, table_buf_0x9050_len, + table_buf_0x9400, table_buf_0x9400_len, + table_buf_0x9402, table_buf_0x9402_len, + table_buf_0x9403, table_buf_0x9403_len, + table_buf_0x9406, table_buf_0x9406_len, + table_buf_0x940c, table_buf_0x940c_len, + table_buf_0x940e, table_buf_0x940e_len); + } + next: + fseek(ifp, save, SEEK_SET); + } + + order = sorder; +} + +void LibRaw::parse_makernote(int base, int uptag) +{ + + if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (!strncmp(make, "NIKON", 5)) + { + parseNikonMakernote(base, uptag, nonDNG); + return; + } + else if (!strncasecmp(make, "LEICA", 5)) + { + parseLeicaMakernote(base, uptag, is_0x927c); + return; + } + + if (!strncmp(make, "Nokia", 5)) + return; + + char buf[10]; + char another_buf[128]; + + fseek(ifp, -12, SEEK_CUR); + fread (another_buf, 1, 12, ifp); + if (!strncmp(another_buf, "SONY", 4) || + !strncmp(another_buf, "VHAB", 4)) { // Sony branded as Hasselblad + is_Sony = 1; + } + + 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 (!strcmp(buf, "EPSON")) + { + parseEpsonMakernote(base, uptag, nonDNG); + return; + } + else if (!strcmp(buf, "SIGMA")) + { + parseSigmaMakernote(base, uptag, CameraDNG); + return; + } + + + unsigned entries, tag, type, len, save, c; + unsigned i, wb[4] = {0, 0, 0, 0}; + short morder, sorder = order; + + uchar *CanonCameraInfo = 0;; + unsigned lenCanonCameraInfo = 0; + unsigned typeCanonCameraInfo = 0; + imCanon.wbi = 0; + + uchar *table_buf_0x0116; + ushort table_buf_0x0116_len = 0; + uchar *table_buf_0x2010; + ushort table_buf_0x2010_len = 0; + uchar *table_buf_0x9050; + ushort table_buf_0x9050_len = 0; + uchar *table_buf_0x9400; + ushort table_buf_0x9400_len = 0; + uchar *table_buf_0x9402; + ushort table_buf_0x9402_len = 0; + uchar *table_buf_0x9403; + ushort table_buf_0x9403_len = 0; + uchar *table_buf_0x9406; + ushort table_buf_0x9406_len = 0; + uchar *table_buf_0x940c; + ushort table_buf_0x940c_len = 0; + uchar *table_buf_0x940e; + ushort table_buf_0x940e_len = 0; + + INT64 fsize = ifp->size(); + + /* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + + 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]; + if (feof(ifp)) + break; + 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, "OLYMPUS") || !strncmp(buf, "OM SYS",6) || + !strcmp(buf, "PENTAX ")) + { + base = ftell(ifp) - 10; + fseek(ifp, -2, SEEK_CUR); + if (buf[1] == 'M') + get4(); + order = get2(); + if (buf[0] == 'O') + get2(); + } + else if (!strncmp(buf, "SONY", 4) || // DSLR-A100 + !strcmp(buf, "Panasonic")) { + if (buf[0] == 'S') + is_Sony = 1; + 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") || + !strncmp(buf, "LEICA", 5) || + !strcmp (buf, "Ricoh")) + { + fseek(ifp, -2, SEEK_CUR); + } + else if (!strcmp(buf, "AOC") || // Pentax, tribute to Asahi Optical Co. + !strcmp(buf, "QVC")) // Casio, from "QV-Camera" + { + fseek(ifp, -4, SEEK_CUR); + } + else if (!strncmp(buf, "CMT3", 4)) + { + order = sget2((uchar *)(buf + 4)); + fseek(ifp, 2L, SEEK_CUR); + } + else if (libraw_internal_data.unpacker_data.CR3_CTMDtag) + { + order = sget2((uchar *)buf); + fseek(ifp, -2L, SEEK_CUR); + } + else + { + fseek(ifp, -10, SEEK_CUR); + if (!strncmp(make, "SAMSUNG", 7)) + base = ftell(ifp); + } + + if (!is_Olympus && + (!strncasecmp(make, "Olympus", 7) || !strncmp(make, "OM Digi", 7) || + (!strncasecmp(make, "CLAUSS", 6) && !strncasecmp(model, "piX 5oo", 7)))) { + is_Olympus = 1; + } + + if (!is_Sony && + (!strncasecmp(make, "SONY", 4) || + !strncasecmp(make, "Konica", 6) || + !strncasecmp(make, "Minolta", 7) || + (!strncasecmp(make, "Hasselblad", 10) && + (!strncasecmp(model, "Stellar", 7) || + !strncasecmp(model, "Lunar", 5) || + !strncasecmp(model, "Lusso", 5) || + !strncasecmp(model, "HV", 2))))) { + is_Sony = 1; + } + + if (strcasestr(make, "Kodak") && + (sget2((uchar *)buf) > 1) && // check number of entries + (sget2((uchar *)buf) < 128) && + (sget2((uchar *)(buf + 4)) > 0) && // check type + (sget2((uchar *)(buf + 4)) < 13) && + (sget4((uchar *)(buf + 6)) < 256) // check count + ) + imKodak.MakerNoteKodak8a = 1; // Kodak P712 / P850 / P880 + + entries = get2(); + if (entries > 1000) + return; + + morder = order; + while (entries--) + { + order = morder; + tiff_get(base, &tag, &type, &len, &save); + tag |= uptag << 16; + + INT64 _pos = ftell(ifp); + if (len > 100 * 1024 * 1024) + goto next; // 100Mb tag? No! + if (len > 8 && _pos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + if (imKodak.MakerNoteKodak8a) + { + if ((tag == 0xff00) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && (len == 1)) + { + INT64 _pos1 = get4(); + if ((_pos1 < fsize) && (_pos1 > 0)) + { + fseek(ifp, _pos1, SEEK_SET); + parse_makernote(base, tag); + } + } + else if (tag == 0xff00f90b) + { + imKodak.clipBlack = get2(); + } + else if (tag == 0xff00f90c) + { + imKodak.clipWhite = imgdata.color.linear_max[0] = + imgdata.color.linear_max[1] = imgdata.color.linear_max[2] = + imgdata.color.linear_max[3] = get2(); + } + } + else if (!strncmp(make, "Canon", 5)) + { + if (tag == 0x000d && len < 256000) // camera info + { + if (!tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + CanonCameraInfo = (uchar *)malloc(MAX(16, len)); + fread(CanonCameraInfo, len, 1, ifp); + } + else + { + CanonCameraInfo = (uchar *)malloc(MAX(16, len * 4)); + fread(CanonCameraInfo, len, 4, ifp); + } + lenCanonCameraInfo = len; + typeCanonCameraInfo = type; + } + + else if (tag == 0x0010) // Canon ModelID + { + unique_id = get4(); + setCanonBodyFeatures(unique_id); + if (lenCanonCameraInfo) + { + processCanonCameraInfo(unique_id, CanonCameraInfo, lenCanonCameraInfo, + typeCanonCameraInfo, nonDNG); + if(CanonCameraInfo) + free(CanonCameraInfo); + CanonCameraInfo = 0; + lenCanonCameraInfo = 0; + } + } + + else + parseCanonMakernotes(tag, type, len, nonDNG); + } + + else if (!strncmp(make, "FUJI", 4)) + parseFujiMakernotes(tag, type, len, nonDNG); + + else if (!strncasecmp(model, "Hasselblad X1D", 14) || + !strncasecmp(model, "Hasselblad H6D", 14) || + !strncasecmp(model, "Hasselblad A6D", 14)) + { + if (tag == 0x0045) + { + imHassy.BaseISO = get4(); + } + else if (tag == 0x0046) + { + imHassy.Gain = getreal(type); + } + } + + else if (!strncmp(make, "PENTAX", 6) || + !strncmp(make, "RICOH", 5) || + !strncmp(model, "PENTAX", 6)) + { + if (!strncmp(model, "GR", 2) || + !strncmp(model, "GXR", 3)) + { + parseRicohMakernotes(base, tag, type, len, CameraDNG); + } + else + { + parsePentaxMakernotes(base, tag, type, len, nonDNG); + } + } + + else if (!strncmp(make, "SAMSUNG", 7)) + { + if (!dng_version) + parseSamsungMakernotes(base, tag, type, len, nonDNG); + else + parsePentaxMakernotes(base, tag, type, len, CameraDNG); + } + + else if (is_Sony) + { + if ((tag == 0xb028) && (len == 1) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) // DSLR-A100 + { + if ((c = get4())) + { + fseek(ifp, c, SEEK_SET); + parse_makernote(base, tag); + } + } + else + { + parseSonyMakernotes( + base, tag, type, len, nonDNG, + table_buf_0x0116, table_buf_0x0116_len, + table_buf_0x2010, table_buf_0x2010_len, + table_buf_0x9050, table_buf_0x9050_len, + table_buf_0x9400, table_buf_0x9400_len, + table_buf_0x9402, table_buf_0x9402_len, + table_buf_0x9403, table_buf_0x9403_len, + table_buf_0x9406, table_buf_0x9406_len, + table_buf_0x940c, table_buf_0x940c_len, + table_buf_0x940e, table_buf_0x940e_len); + } + } + fseek(ifp, _pos, SEEK_SET); + + if (!strncasecmp(make, "Hasselblad", 10) && !is_Sony) { + if (tag == 0x0011) + imHassy.SensorCode = getint(type); + else if (tag == 0x0016) + imHassy.CoatingCode = getint(type); + else if ((tag == 0x002a) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) && + (len == 12)) { + FORC4 for (int ii = 0; ii < 3; ii++) + imHassy.mnColorMatrix[c][ii] = getreal(type); + + } else if (tag == 0x0031) { + imHassy.RecommendedCrop[0] = getint(type); + imHassy.RecommendedCrop[1] = getint(type); + } + } + + if ((tag == 0x0004 || tag == 0x0114) && !strncmp(make, "KONICA", 6)) + { + fseek(ifp, tag == 0x0004 ? 140 : 160, SEEK_CUR); + switch (get2()) + { + case 72: + flip = 0; + break; + case 76: + flip = 6; + break; + case 82: + flip = 5; + break; + } + } + + if (is_Olympus) { + INT64 _pos2 = ftell(ifp); + if ((tag == 0x2010) || (tag == 0x2020) || (tag == 0x2030) || + (tag == 0x2031) || (tag == 0x2040) || (tag == 0x2050) || + (tag == 0x3000)) + { + if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) { + parse_makernote(base, tag); + + } else if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_ifd) || + tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_int32u)) { + fseek(ifp, base + get4(), SEEK_SET); + parse_makernote(base, tag); + } + + } else { + parseOlympusMakernotes(base, tag, type, len, nonDNG); + } + fseek(ifp, _pos2, SEEK_SET); + } + + if ((tag == 0x0015) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) && + is_raw) + { // Hasselblad + stmread (imHassy.SensorUnitConnector, len, ifp); + } + + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && + ((tag == 0x0081) || // Minolta + (tag == 0x0100))) // Olympus + { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if ((tag == 0x0088) && // Minolta, possibly Olympus too + tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG) && + (thumb_offset = get4())) + thumb_offset += base; + + if ((tag == 0x0089) && // Minolta, possibly Olympus too + tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + thumb_length = get4(); + + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && // Nikon + ((tag == 0x008c) || + (tag == 0x0096))) { + meta_offset = ftell(ifp); + } + + if ((tag == 0x00a1) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && + strncasecmp(make, "Samsung", 7)) + { + order = 0x4949; + fseek(ifp, 140, SEEK_CUR); + FORC3 cam_mul[c] = get4(); + } + + if (tag == 0xb001 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) // Sony ModelID + { + unique_id = get2(); + } + if (tag == 0x0200 && len == 3) // Olympus + shot_order = (get4(), get4()); + + if (tag == 0x0f00 && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) + { + if (len == 614) + fseek(ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) // Kodak, Minolta, Olympus + fseek(ifp, 148, SEEK_CUR); + else + goto next; + goto get2_256; + } + + if (tag == 0x2011 && len == 2) // Casio + { + get2_256: + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + + next: + fseek(ifp, save, SEEK_SET); + } +quit: + order = sorder; +} diff --git a/src/metadata/mediumformat.cpp b/src/metadata/mediumformat.cpp new file mode 100644 index 000000000..6bb8705d9 --- /dev/null +++ b/src/metadata/mediumformat.cpp @@ -0,0 +1,521 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parse_phase_one(int base) +{ + unsigned entries, tag, type, len, data, i, c; + INT64 save; + 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" */ + unsigned offset = get4(); + if (offset == 0xbad0bad) + return; + fseek(ifp, offset + base, SEEK_SET); + entries = get4(); + if (entries > 8192) + return; // too much?? + get4(); + while (entries--) + { + tag = get4(); + type = get4(); + len = get4(); + if (feof(ifp)) + break; + data = get4(); + save = ftell(ifp); + bool do_seek = (tag < 0x0108 || tag > 0x0110); // to make it single rule, not copy-paste + if(do_seek) + fseek(ifp, base + data, SEEK_SET); + switch (tag) + { + + case 0x0100: + flip = "0653"[data & 3] - '0'; + break; + case 0x0102: + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && (imgdata.shootinginfo.BodySerial[1] == 0x49)) + { + unique_id = + (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - 0x41; + } + else + { + unique_id = + (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - 0x41; + } + setPhaseOneFeatures(unique_id); + break; + case 0x0106: + for (i = 0; i < 9; i++) + imgdata.color.P1_color[0].romm_cam[i] = ((float *)romm_cam)[i] = + (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + romm_coeff(romm_cam); + break; + case 0x0107: + FORC3 cam_mul[c] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + break; + case 0x0108: + raw_width = data; + break; + case 0x0109: + raw_height = data; + break; + case 0x010a: + left_margin = data; + break; + case 0x010b: + top_margin = data; + break; + case 0x010c: + width = data; + break; + case 0x010d: + height = data; + break; + case 0x010e: + ph1.format = data; + break; + case 0x010f: + data_offset = data + base; + data_size = len; + break; + case 0x0110: + meta_offset = data + base; + meta_length = len; + break; + case 0x0112: + ph1.key_off = int(save - 4); + break; + case 0x0203: + stmread(imPhaseOne.Software, len, ifp); + case 0x0204: + stmread(imPhaseOne.SystemType, len, ifp); + case 0x0210: + ph1.tag_210 = int_to_float(data); + imCommon.SensorTemperature = ph1.tag_210; + break; + case 0x0211: + imCommon.SensorTemperature2 = int_to_float(data); + break; + case 0x021a: + ph1.tag_21a = data; + break; + case 0x021c: + strip_offset = data + base; + break; + case 0x021d: + ph1.t_black = data; + break; + case 0x0222: + ph1.split_col = data; + break; + case 0x0223: + ph1.black_col = data + base; + break; + case 0x0224: + ph1.split_row = data; + break; + case 0x0225: + ph1.black_row = data + base; + break; + case 0x0226: + for (i = 0; i < 9; i++) + imgdata.color.P1_color[1].romm_cam[i] = (float)getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + break; + case 0x0301: + model[63] = 0; + fread(imPhaseOne.FirmwareString, 1, 255, ifp); + imPhaseOne.FirmwareString[255] = 0; + memcpy(model, imPhaseOne.FirmwareString, 63); + model[63] = 0; + if ((cp = strstr(model, " camera"))) + *cp = 0; + else if ((cp = strchr(model, ','))) + *cp = 0; + /* minus and the letter after it are not always present + if present, last letter means: + C : Contax 645AF + H : Hasselblad H1 / H2 + M : Mamiya + V : Hasselblad 555ELD / 553ELX / 503CW / 501CM; not included below + because of adapter conflicts (Mamiya RZ body) if not present, Phase One + 645 AF, Mamiya 645AFD Series, or anything + */ + strcpy(imPhaseOne.SystemModel, model); + if ((cp = strchr(model, '-'))) + { + if (cp[1] == 'C') + { + strcpy(ilm.body, "Contax 645AF"); + ilm.CameraMount = LIBRAW_MOUNT_Contax645; + ilm.CameraFormat = LIBRAW_FORMAT_645; + } + else if (cp[1] == 'M') + { + strcpy(ilm.body, "Mamiya 645"); + ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; + ilm.CameraFormat = LIBRAW_FORMAT_645; + } + else if (cp[1] == 'H') + { + strcpy(ilm.body, "Hasselblad H1/H2"); + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; + ilm.CameraFormat = LIBRAW_FORMAT_645; + } + *cp = 0; + } + case 0x0401: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + ilm.CurAp = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); + else + ilm.CurAp = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); + break; + case 0x0403: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + ilm.CurFocal = int_to_float(data); + else + ilm.CurFocal = (float)getreal(type); + break; + case 0x0410: + stmread(ilm.body, len, ifp); + if (((unsigned char)ilm.body[0]) == 0xff) + ilm.body[0] = 0; + break; + case 0x0412: + stmread(ilm.Lens, len, ifp); + if (((unsigned char)ilm.Lens[0]) == 0xff) + ilm.Lens[0] = 0; + break; + case 0x0414: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); + } + else + { + ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); + } + break; + case 0x0415: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + ilm.MinAp4CurFocal = libraw_powf64l(2.0f, (int_to_float(data) / 2.0f)); + } + else + { + ilm.MinAp4CurFocal = libraw_powf64l(2.0f, float(getreal(type) / 2.0f)); + } + break; + case 0x0416: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + ilm.MinFocal = int_to_float(data); + } + else + { + ilm.MinFocal = (float)getreal(type); + } + if (ilm.MinFocal > 1000.0f) + { + ilm.MinFocal = 0.0f; + } + break; + case 0x0417: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + ilm.MaxFocal = int_to_float(data); + } + else + { + ilm.MaxFocal = (float)getreal(type); + } + break; + } + if (do_seek) + fseek(ifp, save, SEEK_SET); + } + + if (!ilm.body[0] && !imgdata.shootinginfo.BodySerial[0]) + { + fseek(ifp, meta_offset, SEEK_SET); + order = get2(); + fseek(ifp, 6, SEEK_CUR); + fseek(ifp, meta_offset + get4(), SEEK_SET); + entries = get4(); + if (entries > 8192) + return; // too much?? + get4(); + while (entries--) + { + tag = get4(); + len = get4(); + if (feof(ifp)) + break; + data = get4(); + save = ftell(ifp); + fseek(ifp, meta_offset + data, SEEK_SET); + if (tag == 0x0407) + { + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + if ((imgdata.shootinginfo.BodySerial[0] == 0x4c) && + (imgdata.shootinginfo.BodySerial[1] == 0x49)) + { + unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | + (imgdata.shootinginfo.BodySerial[2] & 0x3f)) - + 0x41; + } + else + { + unique_id = (((imgdata.shootinginfo.BodySerial[0] & 0x3f) << 5) | + (imgdata.shootinginfo.BodySerial[1] & 0x3f)) - + 0x41; + } + setPhaseOneFeatures(unique_id); + } + fseek(ifp, save, SEEK_SET); + } + } + + if ((ilm.MaxAp4CurFocal > 0.7f) && + (ilm.MinAp4CurFocal > 0.7f)) { + float MinAp4CurFocal = MAX(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); + ilm.MaxAp4CurFocal = MIN(ilm.MaxAp4CurFocal,ilm.MinAp4CurFocal); + ilm.MinAp4CurFocal = MinAp4CurFocal; + } + + if (ph1.format == 6) + load_raw = &LibRaw::phase_one_load_raw_s; + else + load_raw = ph1.format < 3 ? &LibRaw::phase_one_load_raw : &LibRaw::phase_one_load_raw_c; + maximum = 0xffff; // Always scaled to 16bit? + 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 LibRaw::parse_mos(INT64 offset) +{ + char data[40]; + int i, c, neut[4], planes = 0, frot = 0; + INT64 from; + unsigned skip; + static const char *mod[] = { + /* DM22, DM28, DM40, DM56 are somewhere here too */ + "", // 0 + "DCB2", // 1 + "Volare", // 2 + "Cantare", // 3 + "CMost", // 4 + "Valeo 6", // 5 + "Valeo 11", // 6 + "Valeo 22", // 7 + "Valeo 11p", // 8 + "Valeo 17", // 9 + "", // 10 + "Aptus 17", // 11 + "Aptus 22", // 12 + "Aptus 75", // 13 + "Aptus 65", // 14 + "Aptus 54S", // 15 + "Aptus 65S", // 16 + "Aptus 75S", // 17 + "AFi 5", // 18 + "AFi 6", // 19 + "AFi 7", // 20 + "AFi-II 7", // 21 + "Aptus-II 7", // 22 (same CMs as Mamiya DM33) + "", // 23 + "Aptus-II 6", // 24 (same CMs as Mamiya DM28) + "AFi-II 10", // 25 + "", // 26 + "Aptus-II 10", // 27 (same CMs as Mamiya DM56) + "Aptus-II 5", // 28 (same CMs as Mamiya DM22) + "", // 29 + "DM33", // 30, make is Mamiya + "", // 31 + "", // 32 + "Aptus-II 10R", // 33 + "Aptus-II 8", // 34 (same CMs as Mamiya DM40) + "", // 35 + "Aptus-II 12", // 36 + "", // 37 + "AFi-II 12" // 38 + }; + float romm_cam[3][3]; + + fseek(ifp, offset, SEEK_SET); + while (!feof(ifp)) + { + if (get4() != 0x504b5453) + break; + get4(); + fread(data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + + if (!strcmp(data, "CameraObj_camera_type")) + { + stmread(ilm.body, (unsigned)skip, ifp); + if (ilm.body[0]) + { + if (!strncmp(ilm.body, "Mamiya R", 8)) + { + ilm.CameraMount = LIBRAW_MOUNT_Mamiya67; + ilm.CameraFormat = LIBRAW_FORMAT_67; + } + else if (!strncmp(ilm.body, "Hasselblad 5", 12)) + { + ilm.CameraFormat = LIBRAW_FORMAT_66; + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V; + } + else if (!strncmp(ilm.body, "Hasselblad H", 12)) + { + ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H; + ilm.CameraFormat = LIBRAW_FORMAT_645; + } + else if (!strncmp(ilm.body, "Mamiya 6", 8) || + !strncmp(ilm.body, "Phase One 6", 11)) + { + ilm.CameraMount = LIBRAW_MOUNT_Mamiya645; + ilm.CameraFormat = LIBRAW_FORMAT_645; + } + else if (!strncmp(ilm.body, "Large F", 7)) + { + ilm.CameraMount = LIBRAW_MOUNT_LF; + ilm.CameraFormat = LIBRAW_FORMAT_LF; + } + else if (!strncmp(model, "Leaf AFi", 8)) + { + ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; + ilm.CameraFormat = LIBRAW_FORMAT_66; + } + } + } + if (!strcmp(data, "back_serial_number")) + { + char buffer[sizeof(imgdata.shootinginfo.BodySerial)]; + char *words[4] = {0, 0, 0, 0}; + stmread(buffer, (unsigned)skip, ifp); + /*nwords = */ + getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.BodySerial)); + if(words[0]) + strcpy(imgdata.shootinginfo.BodySerial, words[0]); + } + if (!strcmp(data, "CaptProf_serial_number")) + { + char buffer[sizeof(imgdata.shootinginfo.InternalBodySerial)]; + char *words[4] = {0, 0, 0, 0}; + stmread(buffer, (unsigned)skip, ifp); + getwords(buffer, words, 4, sizeof(imgdata.shootinginfo.InternalBodySerial)); + if(words[0]) + strcpy(imgdata.shootinginfo.InternalBodySerial, words[0]); + } + + 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 (!strncmp(model, "AFi", 3)) + { + ilm.CameraMount = LIBRAW_MOUNT_Rollei_bayonet; + ilm.CameraFormat = LIBRAW_FORMAT_66; + } + ilm.CamID = i; + } + } + if (!strcmp(data, "icc_camera_to_tone_matrix")) + { + for (i = 0; i < 9; i++) + ((float *)romm_cam)[i] = int_to_float(get4()); + romm_coeff(romm_cam); + } + if (!strcmp(data, "CaptProf_color_matrix")) + { + for (i = 0; i < 9; i++) + fscanf(ifp, "%f", (float *)romm_cam + i); + romm_coeff(romm_cam); + } + if (!strcmp(data, "CaptProf_number_of_planes")) + fscanf(ifp, "%d", &planes); + if (!strcmp(data, "CaptProf_raw_data_rotation")) + fscanf(ifp, "%d", &flip); + if (!strcmp(data, "CaptProf_mosaic_pattern")) + FORC4 + { + fscanf(ifp, "%d", &i); + if (i == 1) + frot = c ^ (c >> 1); // 0123 -> 0132 + } + 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 + if (neut[c + 1]) + 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) * 0x01010101U * + (uchar) "\x94\x61\x16\x49"[(flip / 90 + frot) & 3]; +} diff --git a/src/metadata/minolta.cpp b/src/metadata/minolta.cpp new file mode 100644 index 000000000..c8224332c --- /dev/null +++ b/src/metadata/minolta.cpp @@ -0,0 +1,110 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parse_minolta(int base) +{ + int tag, len, offset, high = 0, wide = 0, i, c; + short sorder = order; + INT64 save; + + fseek(ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp) - 'M' || fgetc(ifp) - 'R') + return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + INT64 fsize = ifp->size(); + if (offset > fsize - 8) // At least 8 bytes for tag/len + offset = fsize - 8; + + while ((save = ftell(ifp)) < offset) + { + for (tag = i = 0; i < 4; i++) + tag = tag << 8 | fgetc(ifp); + len = get4(); + if (len < 0) + return; // just ignore wrong len?? or raise bad file exception? + if ((INT64)len + save + 8LL > fsize) + return; // just ignore out of file metadata, stop parse + switch (tag) + { + case 0x505244: /* PRD */ + fseek(ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + imSony.prd_ImageHeight = get2(); + imSony.prd_ImageWidth = get2(); + imSony.prd_Total_bps = (ushort)fgetc(ifp); + imSony.prd_Active_bps = (ushort)fgetc(ifp); + imSony.prd_StorageMethod = (ushort)fgetc(ifp); + fseek(ifp, 4L, SEEK_CUR); + imSony.prd_BayerPattern = (ushort)fgetc(ifp); + break; + case 0x524946: /* RIF */ + fseek(ifp, 8, SEEK_CUR); + icWBC[LIBRAW_WBI_Tungsten][0] = get2(); + icWBC[LIBRAW_WBI_Tungsten][2] = get2(); + icWBC[LIBRAW_WBI_Daylight][0] = get2(); + icWBC[LIBRAW_WBI_Daylight][2] = get2(); + icWBC[LIBRAW_WBI_Cloudy][0] = get2(); + icWBC[LIBRAW_WBI_Cloudy][2] = get2(); + icWBC[LIBRAW_WBI_FL_W][0] = get2(); + icWBC[LIBRAW_WBI_FL_W][2] = get2(); + icWBC[LIBRAW_WBI_Flash][0] = get2(); + icWBC[LIBRAW_WBI_Flash][2] = get2(); + icWBC[LIBRAW_WBI_Custom][0] = get2(); + icWBC[LIBRAW_WBI_Custom][2] = get2(); + icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = + icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = + icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = + icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = + icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = + icWBC[LIBRAW_WBI_Custom][1] = icWBC[LIBRAW_WBI_Custom][3] = 0x100; + if (!strncasecmp(model, "DSLR-A100", 9)) { + icWBC[LIBRAW_WBI_Shade][0] = get2(); + icWBC[LIBRAW_WBI_Shade][2] = get2(); + icWBC[LIBRAW_WBI_FL_D][0] = get2(); + icWBC[LIBRAW_WBI_FL_D][2] = get2(); + icWBC[LIBRAW_WBI_FL_N][0] = get2(); + icWBC[LIBRAW_WBI_FL_N][2] = get2(); + icWBC[LIBRAW_WBI_FL_WW][0] = get2(); + icWBC[LIBRAW_WBI_FL_WW][2] = get2(); + icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = + icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = + icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = + icWBC[LIBRAW_WBI_FL_WW][1] = icWBC[LIBRAW_WBI_FL_WW][3] = 0x0100; + } + break; + case 0x574247: /* WBG */ + get4(); + if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) + FORC4 cam_mul[G2BRG1_2_RGBG(c)] = get2(); + else + FORC4 cam_mul[RGGB_2_RGBG(c)] = 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; +} diff --git a/src/metadata/misc_parsers.cpp b/src/metadata/misc_parsers.cpp new file mode 100644 index 000000000..7d6e2f447 --- /dev/null +++ b/src/metadata/misc_parsers.cpp @@ -0,0 +1,694 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int LibRaw::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 LibRaw::nikon_3700() +{ + int bits, i; + uchar dp[24]; + static const struct + { + int bits; + char t_make[12], t_model[15]; + int t_maker_idx; + } table[] = {{0x00, "Pentax", "Optio 33WR", LIBRAW_CAMERAMAKER_Pentax}, + {0x03, "Nikon", "E3200", LIBRAW_CAMERAMAKER_Nikon}, + {0x32, "Nikon", "E3700", LIBRAW_CAMERAMAKER_Nikon}, + {0x33, "Olympus", "C-740UZ", LIBRAW_CAMERAMAKER_Olympus}}; + + fseek(ifp, 3072, SEEK_SET); + fread(dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i = 0; i < int(sizeof table / sizeof *table); i++) + if (bits == table[i].bits) + { + strcpy(make, table[i].t_make); + maker_index = table[i].t_maker_idx; + strcpy(model, table[i].t_model); + } +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int LibRaw::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 < int(sizeof tail); i++) + if (tail[i]) + nz++; + return nz > 20; +} + +int LibRaw::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; +} + +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +void LibRaw::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) + { + fseek(ifp, 0, SEEK_SET); + while ((len = get4()) != (unsigned)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(); + } +} +#endif + +void LibRaw::parse_cine() +{ + unsigned off_head, off_setup, off_image, i, temp; + + 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 = &LibRaw::eight_bit_load_raw; + break; + case 16: + load_raw = &LibRaw::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(LIBRAW_EXIFTAG_TYPE_FLOAT); + cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + temp = get4(); + maximum = ~((~0u) << LIM(temp, 1, 31)); + 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 LibRaw::parse_qt(int end) +{ + unsigned save, size; + char tag[4]; + + order = 0x4d4d; + while (ftell(ifp) + 7 < end) + { + save = ftell(ifp); + if ((size = get4()) < 8) + return; + if ((int)size < 0) + return; // 2+GB is too much + if (save + size < save) + return; // 32bit overflow + fread(tag, 4, 1, ifp); + if (!memcmp(tag, "moov", 4) || !memcmp(tag, "udta", 4) || + !memcmp(tag, "CNTH", 4)) + parse_qt(save + size); + if (!memcmp(tag, "CNDA", 4)) + parse_jpeg(ftell(ifp)); + fseek(ifp, save + size, SEEK_SET); + } +} + +void LibRaw::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() != (unsigned)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 = &LibRaw::smal_v6_load_raw; + if (ver == 9) + load_raw = &LibRaw::smal_v9_load_raw; +} + +void LibRaw::parse_riff(int maxdepth) +{ + 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; + if (maxdepth < 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + order = 0x4949; + fread(tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag, "RIFF", 4) || !memcmp(tag, "LIST", 4)) + { + int maxloop = 1000; + get4(); + while (ftell(ifp) + 7 < end && !feof(ifp) && maxloop--) + parse_riff(maxdepth-1); + } + else if (!memcmp(tag, "nctg", 4)) + { + while (ftell(ifp) + 7 < end) + { + if (feof(ifp)) + break; + 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 LibRaw::parse_rollei() +{ + char line[128], *val; + struct tm t; + + fseek(ifp, 0, SEEK_SET); + memset(&t, 0, sizeof t); + do + { + line[0] = 0; + if (!fgets(line, 128, ifp)) + break; + line[127] = 0; + if(!line[0]) break; // zero-length + if ((val = strchr(line, '='))) + *val++ = 0; + else + val = line + strbuflen(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); + if (!strcmp(line, "APT")) + aperture = atof(val); + if (!strcmp(line, "SPE")) + shutter = atof(val); + if (!strcmp(line, "FOCLEN")) + focal_len = atof(val); + if (!strcmp(line, "BLKOFS")) + black = atoi(val) +1; + if (!strcmp(line, "ORI")) + switch (atoi(val)) { + case 1: + flip = 6; + break; + case 2: + flip = 3; + break; + case 3: + flip = 5; + break; + } + if (!strcmp(line, "CUTRECT")) { + sscanf(val, "%hu %hu %hu %hu", + &imgdata.sizes.raw_inset_crops[0].cleft, + &imgdata.sizes.raw_inset_crops[0].ctop, + &imgdata.sizes.raw_inset_crops[0].cwidth, + &imgdata.sizes.raw_inset_crops[0].cheight); + } + } 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"); + thumb_format = LIBRAW_INTERNAL_THUMBNAIL_ROLLEI; +} + +void LibRaw::parse_sinar_ia() +{ + int entries, off; + char str[8], *cp; + + order = 0x4949; + fseek(ifp, 4, SEEK_SET); + entries = get4(); + if (entries < 1 || entries > 8192) + return; + fseek(ifp, get4(), SEEK_SET); + while (entries--) + { + off = get4(); + get4(); + fread(str, 8, 1, ifp); + str[7] = 0; // Ensure end of string + 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 = &LibRaw::unpacked_load_raw; + thumb_width = (get4(), get2()); + thumb_height = get2(); + thumb_format = LIBRAW_INTERNAL_THUMBNAIL_PPM; + maximum = 0x3fff; +} + +void LibRaw::parse_kyocera() +{ + + int c; + static const ushort table[13] = {25, 32, 40, 50, 64, 80, 100, + 125, 160, 200, 250, 320, 400}; + + fseek(ifp, 33, SEEK_SET); + get_timestamp(1); + fseek(ifp, 52, SEEK_SET); + c = get4(); + if ((c > 6) && (c < 20)) + iso_speed = table[c - 7]; + shutter = libraw_powf64l(2.0f, (((float)get4()) / 8.0f)) / 16000.0f; + FORC4 cam_mul[RGGB_2_RGBG(c)] = get4(); + fseek(ifp, 88, SEEK_SET); + aperture = libraw_powf64l(2.0f, ((float)get4()) / 16.0f); + fseek(ifp, 112, SEEK_SET); + focal_len = get4(); + + fseek(ifp, 104, SEEK_SET); + ilm.MaxAp4CurFocal = libraw_powf64l(2.0f, ((float)get4()) / 16.0f); + fseek(ifp, 124, SEEK_SET); + stmread(ilm.Lens, 32, ifp); + ilm.CameraMount = LIBRAW_MOUNT_Contax_N; + ilm.CameraFormat = LIBRAW_FORMAT_FF; + if (ilm.Lens[0]) + { + ilm.LensMount = LIBRAW_MOUNT_Contax_N; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } +} + +int LibRaw::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 || mark == 0xc9) + { + fgetc(ifp); + raw_height = get2(); + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150 && (save + hlen) >= 0 && + (save + hlen) <= ifp->size()) /* "HEAP" */ + { + parse_ciff(save + hlen, len - hlen, 0); + } + if (parse_tiff(save + 6)) + apply_tiff(); + fseek(ifp, save + len, SEEK_SET); + } + return 1; +} + +void LibRaw::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); + } +} + +void LibRaw::parse_broadcom() +{ + + /* This structure is at offset 0xb0 from the 'BRCM' ident. */ + struct + { + uint8_t umode[32]; + uint16_t uwidth; + uint16_t uheight; + uint16_t padding_right; + uint16_t padding_down; + uint32_t unknown_block[6]; + uint16_t transform; + uint16_t format; + uint8_t bayer_order; + uint8_t bayer_format; + } header; + + header.bayer_order = 0; + fseek(ifp, 0xb0 - 0x20, SEEK_CUR); + fread(&header, 1, sizeof(header), ifp); + raw_stride = + ((((((header.uwidth + header.padding_right) * 5) + 3) >> 2) + 0x1f) & + (~0x1f)); + raw_width = width = header.uwidth; + raw_height = height = header.uheight; + filters = 0x16161616; /* default Bayer order is 2, BGGR */ + + switch (header.bayer_order) + { + case 0: /* RGGB */ + filters = 0x94949494; + break; + case 1: /* GBRG */ + filters = 0x49494949; + break; + case 3: /* GRBG */ + filters = 0x61616161; + break; + } +} + +/* + Returns 1 for a Coolpix 995, 0 for anything else. + */ +int LibRaw::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; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void LibRaw::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); +} + +#ifdef USE_6BY9RPI +void LibRaw::parse_raspberrypi() +{ + //This structure is at offset 0xB0 from the 'BRCM' ident. + struct brcm_raw_header { + uint8_t name[32]; + uint16_t h_width; + uint16_t h_height; + uint16_t padding_right; + uint16_t padding_down; + uint32_t dummy[6]; + uint16_t transform; + uint16_t format; + uint8_t bayer_order; + uint8_t bayer_format; + }; + //Values taken from https://github.com/raspberrypi/userland/blob/master/interface/vctypes/vc_image_types.h +#define BRCM_FORMAT_BAYER 33 +#define BRCM_BAYER_RAW8 2 +#define BRCM_BAYER_RAW10 3 +#define BRCM_BAYER_RAW12 4 +#define BRCM_BAYER_RAW14 5 +#define BRCM_BAYER_RAW16 6 + + struct brcm_raw_header header; + uint8_t brcm_tag[4]; + + if (ftell(ifp) > 22LL) // 22 bytes is minimum jpeg size + { + thumb_length = ftell(ifp); + thumb_offset = 0; + thumb_width = thumb_height = 0; + load_flags |= 0x4000; // flag: we have JPEG from beginning to meta_offset + } + + // Sanity check that the caller has found a BRCM header + if (!fread(brcm_tag, 1, sizeof(brcm_tag), ifp) || + memcmp(brcm_tag, "BRCM", sizeof(brcm_tag))) + return; + + width = raw_width; + data_offset = ftell(ifp) + 0x8000 - sizeof(brcm_tag); + + if (!fseek(ifp, 0xB0 - int(sizeof(brcm_tag)), SEEK_CUR) && + fread(&header, 1, sizeof(header), ifp)) { + switch (header.bayer_order) { + case 0: //RGGB + filters = 0x94949494; + break; + case 1: //GBRG + filters = 0x49494949; + break; + default: + case 2: //BGGR + filters = 0x16161616; + break; + case 3: //GRBG + filters = 0x61616161; + break; + } + + if (header.format == BRCM_FORMAT_BAYER) { + switch (header.bayer_format) { + case BRCM_BAYER_RAW8: + load_raw = &LibRaw::rpi_load_raw8; + //1 pixel per byte + raw_stride = ((header.h_width + header.padding_right) + 31)&(~31); + width = header.h_width; + raw_height = height = header.h_height; + is_raw = 1; + order = 0x4d4d; + break; + case BRCM_BAYER_RAW10: + load_raw = &LibRaw::nokia_load_raw; + //4 pixels per 5 bytes + raw_stride = (((((header.h_width + header.padding_right) * 5) + 3) >> 2) + 31)&(~31); + width = header.h_width; + raw_height = height = header.h_height; + is_raw = 1; + order = 0x4d4d; + break; + case BRCM_BAYER_RAW12: + load_raw = &LibRaw::rpi_load_raw12; + //2 pixels per 3 bytes + raw_stride = (((((header.h_width + header.padding_right) * 3) + 1) >> 1) + 31)&(~31); + width = header.h_width; + raw_height = height = header.h_height; + is_raw = 1; + order = 0x4d4d; + break; + case BRCM_BAYER_RAW14: + load_raw = &LibRaw::rpi_load_raw14; + //4 pixels per 7 bytes + raw_stride = (((((header.h_width + header.padding_right) * 7) + 3) >> 2) + 31)&(~31); + width = header.h_width; + raw_height = height = header.h_height; + is_raw = 1; + order = 0x4d4d; + break; + case BRCM_BAYER_RAW16: + load_raw = &LibRaw::rpi_load_raw16; + //1 pixel per 2 bytes + raw_stride = (((header.h_width + header.padding_right) << 1) + 31)&(~31); + width = header.h_width; + raw_height = height = header.h_height; + is_raw = 1; + order = 0x4d4d; + break; + default: + break; + } + } + } +} +#endif diff --git a/src/metadata/nikon.cpp b/src/metadata/nikon.cpp new file mode 100644 index 000000000..c0c90f81c --- /dev/null +++ b/src/metadata/nikon.cpp @@ -0,0 +1,1051 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +// void hexDump(char *title, void *addr, int len); + +unsigned sget4_order (short _order, uchar *s); +double sget_fixed32u (short _order, uchar *s); +double AngleConversion_a (short _order, uchar *s); +double AngleConversion (short _order, uchar *s); + +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} }; + +void LibRaw::processNikonLensData(uchar *LensData, unsigned len) +{ + + ushort i=0; + if (imgdata.lens.nikon.LensType & 0x80) { + strcpy (ilm.LensFeatures_pre, "AF-P"); + } else if (!(imgdata.lens.nikon.LensType & 0x01)) { + ilm.LensFeatures_pre[0] = 'A'; + ilm.LensFeatures_pre[1] = 'F'; + } else { + ilm.LensFeatures_pre[0] = 'M'; + ilm.LensFeatures_pre[1] = 'F'; + } + + if (imgdata.lens.nikon.LensType & 0x40) { + ilm.LensFeatures_suf[0] = 'E'; + } else if (imgdata.lens.nikon.LensType & 0x04) { + ilm.LensFeatures_suf[0] = 'G'; + } else if (imgdata.lens.nikon.LensType & 0x02) { + ilm.LensFeatures_suf[0] = 'D'; + } + + if (imgdata.lens.nikon.LensType & 0x08) + { + ilm.LensFeatures_suf[1] = ' '; + ilm.LensFeatures_suf[2] = 'V'; + ilm.LensFeatures_suf[3] = 'R'; + } + + if (imgdata.lens.nikon.LensType & 0x10) + { + ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1INCH; + } + else + ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Nikon_F; + + if (imgdata.lens.nikon.LensType & 0x20) + { + strcpy(ilm.Adapter, "FT-1"); + ilm.LensMount = LIBRAW_MOUNT_Nikon_F; + ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; + ilm.CameraFormat = LIBRAW_FORMAT_1INCH; + } + + imgdata.lens.nikon.LensType = imgdata.lens.nikon.LensType & 0xdf; + + if ((len < 20) || (len == 58) || (len == 108)) + { + switch (len) + { + case 9: + i = 2; + break; + case 15: + i = 7; + break; + case 16: + i = 8; + break; + case 58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc" + case 108: // "Z 9" + if (model[6] == 'Z') + ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z; + if (imNikon.HighSpeedCropFormat != 12) + ilm.CameraFormat = LIBRAW_FORMAT_FF; + i = 1; + while ((LensData[i] == LensData[0]) && (i < 17)) + i++; + if (i == 17) + { + ilm.LensMount = LIBRAW_MOUNT_Nikon_Z; + ilm.LensID = sget2(LensData + 0x2c); + if ( + (ilm.LensID == 11) + || (ilm.LensID == 12) + || (ilm.LensID == 26) + ) ilm.LensFormat = LIBRAW_FORMAT_APSC; + else ilm.LensFormat = LIBRAW_FORMAT_FF; + if (ilm.MaxAp4CurFocal < 0.7f) + ilm.MaxAp4CurFocal = libraw_powf64l( + 2.0f, (float)sget2(LensData + 0x32) / 384.0f - 1.0f); + if (ilm.CurAp < 0.7f) + ilm.CurAp = libraw_powf64l( + 2.0f, (float)sget2(LensData + 0x34) / 384.0f - 1.0f); + if (fabsf(ilm.CurFocal) < 1.1f) + ilm.CurFocal = sget2(LensData + 0x38); + return; + } + i = 9; + ilm.LensMount = LIBRAW_MOUNT_Nikon_F; + if (ilm.CameraMount == LIBRAW_MOUNT_Nikon_Z) + strcpy(ilm.Adapter, "FTZ"); + break; + } + imgdata.lens.nikon.LensIDNumber = LensData[i]; + imgdata.lens.nikon.LensFStops = LensData[i + 1]; + ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; + if (fabsf(ilm.MinFocal) < 1.1f) + { + if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 2]) + ilm.MinFocal = + 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 2] / 24.0f); + if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 3]) + ilm.MaxFocal = + 5.0f * libraw_powf64l(2.0f, (float)LensData[i + 3] / 24.0f); + if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 4]) + ilm.MaxAp4MinFocal = + libraw_powf64l(2.0f, (float)LensData[i + 4] / 24.0f); + if ((imgdata.lens.nikon.LensType ^ (uchar)0x01) || LensData[i + 5]) + ilm.MaxAp4MaxFocal = + libraw_powf64l(2.0f, (float)LensData[i + 5] / 24.0f); + } + imgdata.lens.nikon.MCUVersion = LensData[i + 6]; + if (i != 2) + { + if ((LensData[i - 1]) && (fabsf(ilm.CurFocal) < 1.1f)) + ilm.CurFocal = + 5.0f * libraw_powf64l(2.0f, (float)LensData[i - 1] / 24.0f); + if (LensData[i + 7]) + imgdata.lens.nikon.EffectiveMaxAp = + libraw_powf64l(2.0f, (float)LensData[i + 7] / 24.0f); + } + ilm.LensID = (unsigned long long)LensData[i] << 56 | + (unsigned long long)LensData[i + 1] << 48 | + (unsigned long long)LensData[i + 2] << 40 | + (unsigned long long)LensData[i + 3] << 32 | + (unsigned long long)LensData[i + 4] << 24 | + (unsigned long long)LensData[i + 5] << 16 | + (unsigned long long)LensData[i + 6] << 8 | + (unsigned long long)imgdata.lens.nikon.LensType; + } + else if ((len == 459) || (len == 590)) + { + memcpy(ilm.Lens, LensData + 390, 64); + } + else if (len == 509) + { + memcpy(ilm.Lens, LensData + 391, 64); + } + else if (len == 879) + { + memcpy(ilm.Lens, LensData + 680, 64); + } + + return; +} + +void LibRaw::Nikon_NRW_WBtag(int wb, int skip) +{ + + int r, g0, g1, b; + if (skip) + get4(); // skip wb "CCT", it is not unique + r = get4(); + g0 = get4(); + g1 = get4(); + b = get4(); + if (r && g0 && g1 && b) + { + icWBC[wb][0] = r << 1; + icWBC[wb][1] = g0; + icWBC[wb][2] = b << 1; + icWBC[wb][3] = g1; + } + return; +} + +void LibRaw::parseNikonMakernote(int base, int uptag, unsigned /*dng_writer */) +{ + + unsigned offset = 0, entries, tag, type, len, save; + + unsigned c, i; + unsigned LensData_len = 0; + uchar *LensData_buf=0; + uchar ColorBalanceData_buf[324]; + int ColorBalanceData_ready = 0; + uchar ci, cj, ck; + unsigned serial = 0; + unsigned custom_serial = 0; + + unsigned ShotInfo_len = 0; + uchar *ShotInfo_buf=0; + +/* for dump: +uchar *cj_block, *ck_block; +*/ + + short morder, sorder = order; + char buf[10]; + INT64 fsize = ifp->size(); + + fread(buf, 1, 10, ifp); + + if (!strcmp(buf, "Nikon")) + { + if (buf[6] != '\2') + return; + base = ftell(ifp); + order = get2(); + if (get2() != 42) + goto quit; + offset = get4(); + fseek(ifp, INT64(offset) - 8LL, SEEK_CUR); + } + else + { + fseek(ifp, -10, SEEK_CUR); + } + + entries = get2(); + if (entries > 1000) + return; + morder = order; + + while (entries--) + { + order = morder; + tiff_get(base, &tag, &type, &len, &save); + + INT64 pos = ifp->tell(); + if (len > 8 && pos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + tag |= uptag << 16; + if (len > 100 * 1024 * 1024) + goto next; // 100Mb tag? No! + + if (tag == 0x0002) + { + if (!iso_speed) + iso_speed = (get2(), get2()); + } + else if (tag == 0x000a) + { + ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + } + else if ((tag == 0x000c) && (len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_RATIONAL)) + { + cam_mul[0] = getreal(type); + cam_mul[2] = getreal(type); + cam_mul[1] = getreal(type); + cam_mul[3] = getreal(type); + } + else if (tag == 0x0011) + { + if (is_raw) + { + fseek(ifp, get4() + base, SEEK_SET); + parse_tiff_ifd(base); + } + } + else if (tag == 0x0012) + { + uchar uc1 = fgetc(ifp); + uchar uc2 = fgetc(ifp); + uchar uc3 = fgetc(ifp); + if (uc3) + imCommon.FlashEC = (float)(uc1 * uc2) / (float)uc3; + } + else if (tag == 0x0014) + { + if (tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) + { + if (len == 2560) + { // E5400, E8400, E8700, E8800 + fseek(ifp, 0x4e0L, SEEK_CUR); + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + cam_mul[1] = cam_mul[3] = 1.0; + icWBC[LIBRAW_WBI_Auto][0] = get2(); + icWBC[LIBRAW_WBI_Auto][2] = get2(); + icWBC[LIBRAW_WBI_Daylight][0] = get2(); + icWBC[LIBRAW_WBI_Daylight][2] = get2(); + fseek(ifp, 0x18L, SEEK_CUR); + icWBC[LIBRAW_WBI_Tungsten][0] = get2(); + icWBC[LIBRAW_WBI_Tungsten][2] = get2(); + fseek(ifp, 0x18L, SEEK_CUR); + icWBC[LIBRAW_WBI_FL_W][0] = get2(); + icWBC[LIBRAW_WBI_FL_W][2] = get2(); + icWBC[LIBRAW_WBI_FL_N][0] = get2(); + icWBC[LIBRAW_WBI_FL_N][2] = get2(); + icWBC[LIBRAW_WBI_FL_D][0] = get2(); + icWBC[LIBRAW_WBI_FL_D][2] = get2(); + icWBC[LIBRAW_WBI_Cloudy][0] = get2(); + icWBC[LIBRAW_WBI_Cloudy][2] = get2(); + fseek(ifp, 0x18L, SEEK_CUR); + icWBC[LIBRAW_WBI_Flash][0] = get2(); + icWBC[LIBRAW_WBI_Flash][2] = get2(); + + icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = + icWBC[LIBRAW_WBI_Daylight][1] = icWBC[LIBRAW_WBI_Daylight][3] = + icWBC[LIBRAW_WBI_Tungsten][1] = icWBC[LIBRAW_WBI_Tungsten][3] = + icWBC[LIBRAW_WBI_FL_W][1] = icWBC[LIBRAW_WBI_FL_W][3] = + icWBC[LIBRAW_WBI_FL_N][1] = icWBC[LIBRAW_WBI_FL_N][3] = + icWBC[LIBRAW_WBI_FL_D][1] = icWBC[LIBRAW_WBI_FL_D][3] = + icWBC[LIBRAW_WBI_Cloudy][1] = icWBC[LIBRAW_WBI_Cloudy][3] = + icWBC[LIBRAW_WBI_Flash][1] = icWBC[LIBRAW_WBI_Flash][3] = 256; + + if (strncmp(model, "E8700", 5)) + { + fseek(ifp, 0x18L, SEEK_CUR); + icWBC[LIBRAW_WBI_Shade][0] = get2(); + icWBC[LIBRAW_WBI_Shade][2] = get2(); + icWBC[LIBRAW_WBI_Shade][1] = icWBC[LIBRAW_WBI_Shade][3] = 256; + } + } + else if (len == 1280) + { // E5000, E5700 + cam_mul[0] = cam_mul[1] = cam_mul[2] = cam_mul[3] = 1.0; + } + else + { + fread(buf, 1, 10, ifp); + if (!strncmp(buf, "NRW ", 4)) + { // P6000, P7000, P7100, B700, P1000 + if (!strcmp(buf + 4, "0100")) + { // P6000 + fseek(ifp, 0x13deL, SEEK_CUR); + cam_mul[0] = get4() << 1; + cam_mul[1] = get4(); + cam_mul[3] = get4(); + cam_mul[2] = get4() << 1; + Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 0); + Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 0); + fseek(ifp, 0x10L, SEEK_CUR); + Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 0); + Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 0); + Nikon_NRW_WBtag(LIBRAW_WBI_Flash, 0); + fseek(ifp, 0x10L, SEEK_CUR); + Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 0); + Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 0); + } + else + { // P7000, P7100, B700, P1000 + fseek(ifp, 0x16L, SEEK_CUR); + black = get2(); + if (cam_mul[0] < 0.1f) + { + fseek(ifp, 0x16L, SEEK_CUR); + cam_mul[0] = get4() << 1; + cam_mul[1] = get4(); + cam_mul[3] = get4(); + cam_mul[2] = get4() << 1; + } + else + { + fseek(ifp, 0x26L, SEEK_CUR); + } + if (len != 332) + { // not A1000 + Nikon_NRW_WBtag(LIBRAW_WBI_Daylight, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_Cloudy, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_Shade, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_Tungsten, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_FL_W, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_FL_N, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_FL_D, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_HT_Mercury, 1); + fseek(ifp, 0x14L, SEEK_CUR); + Nikon_NRW_WBtag(LIBRAW_WBI_Custom, 1); + Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); + } + else + { + fseek(ifp, 0xc8L, SEEK_CUR); + Nikon_NRW_WBtag(LIBRAW_WBI_Auto, 1); + } + } + } + } + } + } + else if (tag == 0x001b) + { + imNikon.HighSpeedCropFormat = get2(); + imNikon.SensorHighSpeedCrop.cwidth = get2(); + imNikon.SensorHighSpeedCrop.cheight = get2(); + imNikon.SensorWidth = get2(); + imNikon.SensorHeight = get2(); + imNikon.SensorHighSpeedCrop.cleft = get2(); + imNikon.SensorHighSpeedCrop.ctop = get2(); + switch (imNikon.HighSpeedCropFormat) + { + case 0: + case 1: + case 2: + case 4: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 11: + ilm.CameraFormat = LIBRAW_FORMAT_FF; + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 12: + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 3: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; + break; + case 6: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; + break; + case 17: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + break; + default: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; + break; + } + } + else if (tag == 0x001d) + { // serial number + if (len > 0) + { + int model_len = (int)strbuflen(model); + while ((c = fgetc(ifp)) && (len-- > 0) && (c != (unsigned)EOF)) + { + if ((!custom_serial) && (!isdigit(c))) + { + if (((model_len == 3) && !strcmp(model, "D50")) || + ((model_len >= 4) && !isalnum(model[model_len - 4]) && + !strncmp(&model[model_len - 3], "D50", 3))) + { + custom_serial = 34; + } + else + { + custom_serial = 96; + } + break; + } + serial = serial * 10 + (isdigit(c) ? c - '0' : c % 10); + } + if (!imgdata.shootinginfo.BodySerial[0]) + sprintf(imgdata.shootinginfo.BodySerial, "%d", serial); + } + } + else if (tag == 0x001e) { + switch (get2()) { + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + } else if (tag == 0x0025) + { + imCommon.real_ISO = int(100.0 * libraw_powf64l(2.0, double((uchar)fgetc(ifp)) / 12.0 - 5.0)); + if (!iso_speed || (iso_speed == 65535)) + { + iso_speed = imCommon.real_ISO; + } + } + else if (tag == 0x0022) + { + imNikon.Active_D_Lighting = get2(); + } + else if (tag == 0x003b) + { // WB for multi-exposure (ME); all 1s for regular exposures + imNikon.ME_WB[0] = getreal(type); + imNikon.ME_WB[2] = getreal(type); + imNikon.ME_WB[1] = getreal(type); + imNikon.ME_WB[3] = getreal(type); + } + else if (tag == 0x003d) + { // not corrected for file bitcount, to be patched in open_datastream + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + i = cblack[3]; + FORC3 if (i > cblack[c]) i = cblack[c]; + FORC4 cblack[c] -= i; + black += i; + } + else if (tag == 0x0045) + { /* upper left pixel (x,y), size (width,height) */ + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + } + else if (tag == 0x0051) + { + fseek(ifp, 10LL, SEEK_CUR); + imNikon.NEFCompression = get2(); + } + else if (tag == 0x0082) + { // lens attachment + stmread(ilm.Attachment, len, ifp); + } + else if (tag == 0x0083) + { // lens type + imgdata.lens.nikon.LensType = fgetc(ifp); + } + else if (tag == 0x0084) + { // lens + ilm.MinFocal = getreal(type); + ilm.MaxFocal = getreal(type); + ilm.MaxAp4MinFocal = getreal(type); + ilm.MaxAp4MaxFocal = getreal(type); + } + else if (tag == 0x0088) // AFInfo + { + if (!imCommon.afcount) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount = 1; + } + } + else if (tag == 0x008b) // lens f-stops + { + uchar uc1 = fgetc(ifp); + uchar uc2 = fgetc(ifp); + uchar uc3 = fgetc(ifp); + if (uc3) + { + imgdata.lens.nikon.LensFStops = uc1 * uc2 * (12 / uc3); + ilm.LensFStops = (float)imgdata.lens.nikon.LensFStops / 12.0f; + } + } + else if ((tag == 0x008c) || (tag == 0x0096)) + { + meta_offset = ftell(ifp); + } + else if ((tag == 0x0091) && (len > 4)) + { + ShotInfo_len = len; + ShotInfo_buf = (uchar *)malloc(ShotInfo_len); + +/* for dump: +cj_block = (uchar *)malloc(ShotInfo_len); +ck_block = (uchar *)malloc(ShotInfo_len); +*/ + + fread(ShotInfo_buf, ShotInfo_len, 1, ifp); + FORC4 imNikon.ShotInfoVersion = + imNikon.ShotInfoVersion * 10 + ShotInfo_buf[c] - '0'; + } + else if (tag == 0x0093) + { + imNikon.NEFCompression = i = get2(); + if ((i == 7) || (i == 9)) + { + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + } + } + else if (tag == 0x0097) + { // ver97 + FORC4 imNikon.ColorBalanceVersion = + imNikon.ColorBalanceVersion * 10 + fgetc(ifp) - '0'; + switch (imNikon.ColorBalanceVersion) + { + case 100: // NIKON D100 + fseek(ifp, 0x44L, SEEK_CUR); + FORC4 cam_mul[RBGG_2_RGBG(c)] = get2(); + break; + case 102: // NIKON D2H + fseek(ifp, 0x6L, SEEK_CUR); + FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); + break; + case 103: // NIKON D70, D70s + fseek(ifp, 0x10L, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (imNikon.ColorBalanceVersion >= 200) + { + /* + 204: NIKON D2X, D2Xs + 205: NIKON D50 + 206: NIKON D2Hs + 207: NIKON D200 + 208: NIKON D40, D40X, D80 + 209: NIKON D3, D3X, D300, D700 + 210: NIKON D60 + 211: NIKON D90, D5000 + 212: NIKON D300S + 213: NIKON D3000 + 214: NIKON D3S + 215: NIKON D3100 + 216: NIKON D5100, D7000 + 217: NIKON D4, D600, D800, D800E, D3200 + -= unknown =- + 218: NIKON D5200, D7100 + 219: NIKON D5300 + 220: NIKON D610, Df + 221: NIKON D3300 + 222: NIKON D4S + 223: NIKON D750, D810 + 224: NIKON D3400, D3500, D5500, D5600, D7200 + 225: NIKON D5, D500 + 226: NIKON D7500 + 227: NIKON D850 + */ + if (imNikon.ColorBalanceVersion != 205) + { + fseek(ifp, 0x118L, SEEK_CUR); + } + ColorBalanceData_ready = + (fread(ColorBalanceData_buf, 324, 1, ifp) == 1); + } + if ((imNikon.ColorBalanceVersion >= 400) && + (imNikon.ColorBalanceVersion <= 405)) + { // 1 J1, 1 V1, 1 J2, 1 V2, 1 J3, 1 S1, 1 AW1, 1 S2, 1 J4, 1 V3, 1 J5 + ilm.CameraFormat = LIBRAW_FORMAT_1INCH; + ilm.CameraMount = LIBRAW_MOUNT_Nikon_CX; + } + else if ((imNikon.ColorBalanceVersion >= 500) && + (imNikon.ColorBalanceVersion <= 502)) + { // P7700, P7800, P330, P340 + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + } + else if (imNikon.ColorBalanceVersion == 601) + { // Coolpix A + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + } + } + else if (tag == 0x0098) // contains lens data + { + FORC4 imNikon.LensDataVersion = + imNikon.LensDataVersion * 10 + fgetc(ifp) - '0'; + switch (imNikon.LensDataVersion) + { + case 100: + LensData_len = 9; + break; + case 101: + case 201: // encrypted, starting from v.201 + case 202: + case 203: + LensData_len = 15; + break; + case 204: + LensData_len = 16; + break; + case 400: + LensData_len = 459; + break; + case 401: + LensData_len = 590; + break; + case 402: + LensData_len = 509; + break; + case 403: + LensData_len = 879; + break; + case 800: + case 801: + LensData_len = 58; + break; + case 802: + LensData_len = 108; + break; + } + if (LensData_len) + { + LensData_buf = (uchar *)malloc(LensData_len); + fread(LensData_buf, LensData_len, 1, ifp); + } + } + else if (tag == 0x00a0) + { + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + } + else if (tag == 0x00a7) // shutter count + { + imNikon.key = fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp) ^ fgetc(ifp); + if (custom_serial) + { + ci = xlat[0][custom_serial]; + } + else + { + ci = xlat[0][serial & 0xff]; + } + cj = xlat[1][imNikon.key]; + ck = 0x60; + if (((unsigned)(imNikon.ColorBalanceVersion - 200) < 18) && + ColorBalanceData_ready) + { + for (i = 0; i < 324; i++) + ColorBalanceData_buf[i] ^= (cj += ci * ck++); + i = "66666>666;6A;:;555"[imNikon.ColorBalanceVersion - 200] - '0'; + FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = + sget2(ColorBalanceData_buf + (i & -2) + c * 2); + } + + if (LensData_len) + { + if (imNikon.LensDataVersion > 200) + { + cj = xlat[1][imNikon.key]; + ck = 0x60; + for (i = 0; i < LensData_len; i++) + { + LensData_buf[i] ^= (cj += ci * ck++); + } + } + processNikonLensData(LensData_buf, LensData_len); + LensData_len = 0; + free(LensData_buf); + } + if (ShotInfo_len && (imNikon.ShotInfoVersion >= 208)) { + unsigned RotationOffset = 0, + OrientationOffset = 0; + + cj = xlat[1][imNikon.key]; + ck = 0x60; + for (i = 4; i < ShotInfo_len; i++) { + ShotInfo_buf[i] ^= (cj += ci * ck++); + +/* for dump: +cj_block[i-4] = cj; +ck_block[i-4] = ck-1; +*/ + } +/* for dump: +printf ("==>> ci: 0x%02x, cj at start: 0x%02x\n", +ci, xlat[1][imNikon.key]); +hexDump("ck array:", ck_block, ShotInfo_len-4); +hexDump("cj array:", cj_block, ShotInfo_len-4); +free(cj_block); +free(ck_block); +*/ + + switch (imNikon.ShotInfoVersion) { + case 208: // ShotInfoD80, Rotation + RotationOffset = 590; + if (RotationOffset>4) & 0x03; + } + break; + + case 233: // ShotInfoD810, Roll/Pitch/Yaw + OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); + break; + + case 238: // D5, ShotInfoD500, Rotation, Roll/Pitch/Yaw + case 239: // D500, ShotInfoD500, Rotation, Roll/Pitch/Yaw + RotationOffset = sget4_order(morder, ShotInfo_buf+0x10) + 0xca; + if (RotationOffset > 0xca) { + RotationOffset -= 0xb0; + } + if (RotationOffset= 0)) + imNikon.MakernotesFlip = "0863"[imNikon.MakernotesFlip] - '0'; + ShotInfo_len = 0; + free(ShotInfo_buf); + } + } + else if (tag == 0x00a8) + { // contains flash data + FORC4 imNikon.FlashInfoVersion = + imNikon.FlashInfoVersion * 10 + fgetc(ifp) - '0'; + } + else if (tag == 0x00b0) + { + get4(); // ME (multi-exposure) tag version, 4 symbols + imNikon.ExposureMode = get4(); + imNikon.nMEshots = get4(); + imNikon.MEgainOn = get4(); + } + else if (tag == 0x00b7) // AFInfo2 + { + if (!imCommon.afcount && len > 4) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + int ver = 0; + FORC4 ver = ver * 10 + (fgetc(ifp) - '0'); + imCommon.afdata[imCommon.afcount].AFInfoData_version = ver; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len-4; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount = 1; + } + } + else if (tag == 0x00b9) + { + imNikon.AFFineTune = fgetc(ifp); + imNikon.AFFineTuneIndex = fgetc(ifp); + imNikon.AFFineTuneAdj = (int8_t)fgetc(ifp); + } + else if ((tag == 0x0100) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) + { + thumb_offset = ftell(ifp); + thumb_length = len; + } + else if (tag == 0x0e01) + { /* Nikon Software / in-camera edit Note */ + int loopc = 0; + int WhiteBalanceAdj_active = 0; + order = 0x4949; + fseek(ifp, 22, SEEK_CUR); + for (offset = 22; offset + 22 < len; offset += 22 + i) + { + if (loopc++ > 1024) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + tag = get4(); + fseek(ifp, 14, SEEK_CUR); + i = get4() - 4; + + if (tag == 0x76a43204) + { + WhiteBalanceAdj_active = fgetc(ifp); + } + else if (tag == 0xbf3c6c20) + { + if (WhiteBalanceAdj_active) + { + union { + double dbl; + unsigned long long lng; + } un; + un.dbl = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); + if ((un.lng != 0x3FF0000000000000ULL) && + (un.lng != 0x000000000000F03FULL)) + { + cam_mul[0] = un.dbl; + cam_mul[2] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE); + cam_mul[1] = cam_mul[3] = 1.0; + i -= 16; + } + else + i -= 8; + } + fseek(ifp, i, SEEK_CUR); + } + else if (tag == 0x76a43207) + { + flip = get2(); + } + else + { + fseek(ifp, i, SEEK_CUR); + } + } + } + else if (tag == 0x0e22) + { + FORC4 imNikon.NEFBitDepth[c] = get2(); + } + next: + fseek(ifp, save, SEEK_SET); + } +quit: + order = sorder; +} + +unsigned sget4_order (short _order, uchar *s) { + unsigned v; + if (_order == 0x4949) + v= s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + v= s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; + return v; +} + +double sget_fixed32u (short _order, uchar *s) { + unsigned v = sget4_order (_order, s); + return ((double)v / 6.5536 + 0.5) / 10000.0; +} + +double AngleConversion_a (short _order, uchar *s) { + double v = sget_fixed32u(_order, s); + if (v < 180.0) return -v; + return 360.0-v; +} + +double AngleConversion (short _order, uchar *s) { + double v = sget_fixed32u(_order, s); + if (v <= 180.0) return v; + return v-360.0; +} + +/* ========= */ +/* +void hexDump(char *title, void *addr, int len) +{ + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + + // Output description if given. + if (title != NULL) + printf ("%s:\n", title); + + // Process every byte in the data. + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + printf(" %s\n", buff); + + // Output the offset. + printf(" %04x ", i); + } + + // Now the hex code for the specific character. + printf(" %02x", pc[i]); + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { + buff[i % 16] = '.'; + } else { + buff[i % 16] = pc[i]; + } + + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + printf(" "); + i++; + } + + // And print the final ASCII bit. + printf(" %s\n", buff); +} +*/ diff --git a/src/metadata/normalize_model.cpp b/src/metadata/normalize_model.cpp new file mode 100644 index 000000000..064c4a565 --- /dev/null +++ b/src/metadata/normalize_model.cpp @@ -0,0 +1,1451 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +void LibRaw::GetNormalizedModel() +{ + + int i, j; + char *ps; + int try_xml = 0; + + static const struct + { + unsigned long long id; + char t_model[20]; + } unique[] = +// clang-format off + { + { CanonID_EOS_M50, "EOS M50"}, // Kiss M + { CanonID_EOS_M6_Mark_II, "EOS M6 Mark II"}, + { CanonID_EOS_M200, "EOS M200"}, + { CanonID_EOS_D30, "EOS D30"}, + { CanonID_EOS_D60, "EOS D60"}, + { CanonID_EOS_M3, "EOS M3"}, + { CanonID_EOS_M10, "EOS M10"}, + { CanonID_EOS_M5, "EOS M5"}, + { CanonID_EOS_M100, "EOS M100"}, + { CanonID_EOS_M6, "EOS M6"}, + { CanonID_EOS_1D, "EOS-1D"}, + { CanonID_EOS_1Ds, "EOS-1Ds"}, + { CanonID_EOS_10D, "EOS 10D"}, + { CanonID_EOS_1D_Mark_III, "EOS-1D Mark III"}, + { CanonID_EOS_300D, "EOS 300D"}, // Digital Rebel / Kiss Digital + { CanonID_EOS_1D_Mark_II, "EOS-1D Mark II"}, + { CanonID_EOS_20D, "EOS 20D"}, + { CanonID_EOS_450D, "EOS 450D"}, // Digital Rebel XSi / Kiss X2 + { CanonID_EOS_1Ds_Mark_II, "EOS-1Ds Mark II"}, + { CanonID_EOS_350D, "EOS 350D"}, // Digital Rebel XT / Kiss Digital N + { CanonID_EOS_40D, "EOS 40D"}, + { CanonID_EOS_5D, "EOS 5D"}, + { CanonID_EOS_1Ds_Mark_III, "EOS-1Ds Mark III"}, + { CanonID_EOS_5D_Mark_II, "EOS 5D Mark II"}, + { CanonID_EOS_1D_Mark_II_N, "EOS-1D Mark II N"}, + { CanonID_EOS_30D, "EOS 30D"}, + { CanonID_EOS_400D, "EOS 400D"}, // Digital Rebel XTi / Kiss Digital X + { CanonID_EOS_7D, "EOS 7D"}, + { CanonID_EOS_500D, "EOS 500D"}, // Rebel T1i / Kiss X3 + { CanonID_EOS_1000D, "EOS 1000D"}, // Digital Rebel XS / Kiss F + { CanonID_EOS_50D, "EOS 50D"}, + { CanonID_EOS_1D_X, "EOS-1D X"}, + { CanonID_EOS_550D, "EOS 550D"}, // Rebel T2i / Kiss X4 + { CanonID_EOS_1D_Mark_IV, "EOS-1D Mark IV"}, + { CanonID_EOS_5D_Mark_III, "EOS 5D Mark III"}, + { CanonID_EOS_600D, "EOS 600D"}, // Rebel T3i / Kiss X5 + { CanonID_EOS_60D, "EOS 60D"}, + { CanonID_EOS_1100D, "EOS 1100D"}, // Rebel T3 / Kiss X50 + { CanonID_EOS_7D_Mark_II, "EOS 7D Mark II"}, + { CanonID_EOS_650D, "EOS 650D"}, // Rebel T4i / Kiss X6i + { CanonID_EOS_6D, "EOS 6D"}, + { CanonID_EOS_1D_C, "EOS-1D C"}, + { CanonID_EOS_70D, "EOS 70D"}, + { CanonID_EOS_700D, "EOS 700D"}, // Rebel T5i / Kiss X7i + { CanonID_EOS_1200D, "EOS 1200D"}, // Rebel T5 / Kiss X70 / Hi + { CanonID_EOS_1D_X_Mark_II, "EOS-1D X Mark II"}, + { CanonID_EOS_M, "EOS M"}, + { CanonID_EOS_100D, "EOS 100D"}, // Rebel SL1 / Kiss X7 + { CanonID_EOS_760D, "EOS 760D"}, // Rebel T6s / 8000D + { CanonID_EOS_5D_Mark_IV, "EOS 5D Mark IV"}, + { CanonID_EOS_80D, "EOS 80D"}, + { CanonID_EOS_M2, "EOS M2"}, + { CanonID_EOS_5DS, "EOS 5DS"}, + { CanonID_EOS_750D, "EOS 750D"}, // Rebel T6i / Kiss X8i + { CanonID_EOS_5DS_R, "EOS 5DS R"}, + { CanonID_EOS_1300D, "EOS 1300D"}, // Rebel T6 / Kiss X80 + { CanonID_EOS_800D, "EOS 800D"}, // Rebel T7i / Kiss X9i + { CanonID_EOS_6D_Mark_II, "EOS 6D Mark II"}, + { CanonID_EOS_77D, "EOS 77D"}, // 9000D + { CanonID_EOS_200D, "EOS 200D"}, // Rebel SL2 / Kiss X9 + { CanonID_EOS_R5, "EOS R5"}, + { CanonID_EOS_3000D, "EOS 3000D"}, // Rebel T100 / 4000D + { CanonID_EOS_R, "EOS R"}, + { CanonID_EOS_1D_X_Mark_III, "EOS-1D X Mark III"}, + { CanonID_EOS_1500D, "EOS 1500D"}, // Rebel T7 / 2000D / Kiss X90 + { CanonID_EOS_RP, "EOS RP"}, + { CanonID_EOS_850D, "EOS 850D"}, // EOS Rebel T8i / X10i + { CanonID_EOS_250D, "EOS 250D"}, // Rebel SL3 / 200D II / Kiss X10 + { CanonID_EOS_90D, "EOS 90D"}, + { CanonID_EOS_R3, "EOS R3"}, + { CanonID_EOS_R6, "EOS R6"}, + { CanonID_EOS_R7, "EOS R7"}, + { CanonID_EOS_R10, "EOS R10"}, + { CanonID_EOS_M50_Mark_II, "EOS M50 Mark II"}, // M50m2, Kiss M2 + }, +#if 0 + olyque[] = { + { OlyID_E_20, "E-20"}, + { OlyID_E_20, "E-20,E-20N,E-20P"}, + { OlyID_E_1, "E-1"}, + { OlyID_E_300, "E-300"}, + { OlyID_SP_550UZ, "SP-550UZ"}, + { OlyID_SP_550UZ, "SP550UZ"}, + { OlyID_SP_510UZ, "SP-510UZ"}, + { OlyID_SP_510UZ, "SP510UZ"}, + { OlyID_SP_560UZ, "SP-560UZ"}, + { OlyID_SP_560UZ, "SP560UZ"}, + { OlyID_SP_570UZ, "SP-570UZ"}, + { OlyID_SP_570UZ, "SP570UZ"}, + { OlyID_SP_565UZ, "SP-565UZ"}, + { OlyID_SP_565UZ, "SP565UZ"}, + { OlyID_XZ_1, "XZ-1"}, + { OlyID_XZ_2, "XZ-2"}, + { OlyID_XZ_10, "XZ-10"}, + { OlyID_STYLUS_1, "Stylus 1"}, + { OlyID_STYLUS_1, "STYLUS1"}, + { OlyID_STYLUS_1, "STYLUS1,1s"}, + { OlyID_SH_2, "SH-2"}, + { OlyID_TG_4, "TG-4"}, + { OlyID_TG_5, "TG-5"}, + { OlyID_TG_6, "TG-6"}, + { OlyID_E_10, "E-10"}, + { OlyID_AIR_A01, "AIR A01"}, + { OlyID_AIR_A01, "AIR-A01"}, + { OlyID_E_330, "E-330"}, + { OlyID_E_500, "E-500"}, + { OlyID_E_400, "E-400"}, + { OlyID_E_510, "E-510"}, + { OlyID_E_3, "E-3"}, + { OlyID_E_410, "E-410"}, + { OlyID_E_420, "E-420"}, + { OlyID_E_30, "E-30"}, + { OlyID_E_520, "E-520"}, + { OlyID_E_P1, "E-P1"}, + { OlyID_E_620, "E-620"}, + { OlyID_E_P2, "E-P2"}, + { OlyID_E_PL1, "E-PL1"}, + { OlyID_E_450, "E-450"}, + { OlyID_E_600, "E-600"}, + { OlyID_E_P3, "E-P3"}, + { OlyID_E_5, "E-5"}, + { OlyID_E_PL2, "E-PL2"}, + { OlyID_E_M5, "E-M5"}, + { OlyID_E_PL3, "E-PL3"}, + { OlyID_E_PM1, "E-PM1"}, + { OlyID_E_PL1s, "E-PL1s"}, + { OlyID_E_PL5, "E-PL5"}, + { OlyID_E_PM2, "E-PM2"}, + { OlyID_E_P5, "E-P5"}, + { OlyID_E_PL6, "E-PL6"}, + { OlyID_E_PL7, "E-PL7"}, + { OlyID_E_M1, "E-M1"}, + { OlyID_E_M10, "E-M10"}, + { OlyID_E_M5_Mark_II, "E-M5 Mark II"}, + { OlyID_E_M5_Mark_II, "E-M5MarkII"}, + { OlyID_E_M5_Mark_II, "E-M5_M2"}, + { OlyID_E_M10_Mark_II, "E-M10 Mark II"}, // Clauss piX 5oo + { OlyID_E_M10_Mark_II, "E-M10MarkII"}, + { OlyID_E_M10_Mark_II, "E-M10_M2"}, + { OlyID_PEN_F, "PEN-F"}, + { OlyID_E_PL8, "E-PL8"}, + { OlyID_E_M1_Mark_II, "E-M1 Mark II"}, + { OlyID_E_M1_Mark_II, "E-M1MarkII"}, + { OlyID_E_M1_Mark_II, "E-M1_M2"}, + { OlyID_E_M10_Mark_III, "E-M10 Mark III"}, + { OlyID_E_M10_Mark_III, "E-M10_M3"}, + { OlyID_E_PL9, "E-PL9"}, + { OlyID_E_M1X, "E-M1X"}, + { OlyID_E_PL10, "E-PL10"}, + { OlyID_E_M10_Mark_IV, "E-M10 Mark IV"}, + { OlyID_E_M10_Mark_IV, "E-M10MarkIV"}, + { OlyID_E_M10_Mark_IV, "E-M10_M4"}, + { OlyID_E_M5_Mark_III, "E-M5 Mark III"}, + { OlyID_E_M5_Mark_III, "E-M5MarkIII"}, + { OlyID_E_M5_Mark_III, "E-M5_M3"}, + { OlyID_E_M1_Mark_III, "E-M1 Mark III"}, + { OlyID_E_M1_Mark_III, "E-M1MarkIII"}, + { OlyID_E_M1_Mark_III, "E-M1_M3"}, + { OlyID_E_P7 "E-P7"}, + { OlyID_C_3030Z, "C-3030Z"}, + { OlyID_C_3030Z, "C3030Z"}, + { OlyID_C_5050Z, "C-5050Z"}, + { OlyID_C_5050Z, "C5050Z"}, + { OlyID_C_350Z, "C-350Z"}, + { OlyID_C_350Z, "X200,D560Z,C350Z"}, + { OlyID_C_740UZ, "C-740UZ"}, + { OlyID_C_740UZ, "C740UZ"}, + { OlyID_C_5060WZ, "C-5060WZ"}, + { OlyID_C_5060WZ, "C5060WZ"}, + { OlyID_C_8080WZ, "C-8080WZ"}, + { OlyID_C_8080WZ, "C8080WZ"}, + { OlyID_C_770UZ, "C-770UZ"}, + { OlyID_C_770UZ, "C770UZ"}, + { OlyID_C_7070WZ, "C-7070WZ"}, + { OlyID_C_7070WZ, "C7070WZ"}, + { OlyID_C_7000Z, "C-7000Z"}, + { OlyID_C_7000Z, "C70Z,C7000Z"}, + { OlyID_SP_500UZ, "SP-500UZ"}, + { OlyID_SP_500UZ, "SP500UZ"}, + { OlyID_SP_310, "SP-310"}, + { OlyID_SP_310, "SP310"}, + { OlyID_SP_350, "SP-350"}, + { OlyID_SP_350, "SP350"}, + { OlyID_SP_320, "SP-320"}, + { OlyID_SP_320, "SP320"}, + }, + + penique[] = { + { PentaxID_Optio_S, "Optio S"}, + { PentaxID_Optio_S_V101, "Optio S V1.01"}, + { PentaxID_staristD, "*istD"}, + { PentaxID_staristD, "*ist D"}, + { PentaxID_Optio_33WR, "Optio 33WR"}, + { PentaxID_Optio_S4, "Optio S4"}, + { PentaxID_Optio_750Z, "Optio 750Z"}, + { PentaxID_staristDS, "*istDS"}, + { PentaxID_staristDS, "*ist DS"}, + { PentaxID_staristDL, "*istDL"}, + { PentaxID_staristDL, "*ist DL"}, + { PentaxID_staristDS2, "*istDS2"}, + { PentaxID_staristDS2, "*ist DS2"}, + { PentaxID_GX_1S, "GX-1S"}, // Samsung + { PentaxID_staristDL2, "*istDL2"}, + { PentaxID_staristDL2, "*ist DL2"}, + { PentaxID_GX_1L, "GX-1L"}, // Samsung + { PentaxID_K100D, "K100D"}, + { PentaxID_K110D, "K110D"}, + { PentaxID_K100D_Super, "K100D Super"}, + { PentaxID_K10D, "K10D"}, + { PentaxID_GX10, "GX10"}, // Samsung + { PentaxID_GX10, "GX-10"}, // Samsung + { PentaxID_K20D, "K20D"}, + { PentaxID_GX20, "GX20"}, // Samsung + { PentaxID_GX20, "GX-20"}, // Samsung + { PentaxID_K200D, "K200D"}, + { PentaxID_K2000, "K2000"}, + { PentaxID_K_m, "K-m"}, + { PentaxID_K_7, "K-7"}, + { PentaxID_K_x, "K-x"}, + { PentaxID_645D, "645D"}, + { PentaxID_K_r, "K-r"}, + { PentaxID_K_5, "K-5"}, + { PentaxID_Q, "Q"}, + { PentaxID_K_01, "K-01"}, + { PentaxID_K_30, "K-30"}, + { PentaxID_Q10, "Q10"}, + { PentaxID_K_5_II, "K-5 II"}, + { PentaxID_K_5_II_s, "K-5 II s"}, + { PentaxID_Q7, "Q7"}, + { PentaxID_MX_1, "MX-1"}, + { PentaxID_K_50, "K-50"}, + { PentaxID_K_3, "K-3"}, + { PentaxID_K_500, "K-500"}, + { PentaxID_645Z, "645Z"}, + { PentaxID_K_S1, "K-S1"}, + { PentaxID_K_S2, "K-S2"}, // Ricoh + { PentaxID_Q_S1, "Q-S1"}, + { PentaxID_K_1, "K-1"}, // Ricoh + { PentaxID_K_3_II, "K-3 II"}, // Ricoh + { PentaxID_GR_III, "GR III"}, // Ricoh + { PentaxID_K_70, "K-70"}, // Ricoh + { PentaxID_KP, "KP"}, // Ricoh + { PentaxID_K_1_Mark_II, "K-1 Mark II"}, // Ricoh + { PentaxID_K_3_III, "K-3 Mark III"}, // Ricoh + { PentaxID_GR_IIIx, "GR IIIx"}, + }, +#endif + sonique[] = { + { SonyID_DSC_R1, "DSC-R1"}, + { SonyID_DSLR_A100, "DSLR-A100"}, + { SonyID_DSLR_A900, "DSLR-A900"}, + { SonyID_DSLR_A700, "DSLR-A700"}, + { SonyID_DSLR_A200, "DSLR-A200"}, + { SonyID_DSLR_A350, "DSLR-A350"}, + { SonyID_DSLR_A300, "DSLR-A300"}, + { SonyID_DSLR_A900_APSC, "DSLR-A900"}, + { SonyID_DSLR_A380, "DSLR-A380"}, // DSLR-A390 + { SonyID_DSLR_A330, "DSLR-A330"}, + { SonyID_DSLR_A230, "DSLR-A230"}, + { SonyID_DSLR_A290, "DSLR-A290"}, + { SonyID_DSLR_A850, "DSLR-A850"}, + { SonyID_DSLR_A850_APSC, "DSLR-A850"}, + { SonyID_DSLR_A550, "DSLR-A550"}, + { SonyID_DSLR_A500, "DSLR-A500"}, + { SonyID_DSLR_A450, "DSLR-A450"}, + { SonyID_NEX_5, "NEX-5"}, + { SonyID_NEX_3, "NEX-3"}, + { SonyID_SLT_A33, "SLT-A33"}, + { SonyID_SLT_A55, "SLT-A55"}, // SLT-A55V + { SonyID_DSLR_A560, "DSLR-A560"}, + { SonyID_DSLR_A580, "DSLR-A580"}, + { SonyID_NEX_C3, "NEX-C3"}, + { SonyID_SLT_A35, "SLT-A35"}, + { SonyID_SLT_A65, "SLT-A65"}, // SLT-A65V + { SonyID_SLT_A77, "SLT-A77"}, // SLT-A77V + { SonyID_NEX_5N, "NEX-5N"}, + { SonyID_NEX_7, "NEX-7"}, // Hasselblad Lunar + { SonyID_NEX_VG20, "NEX-VG20"}, + { SonyID_SLT_A37, "SLT-A37"}, + { SonyID_SLT_A57, "SLT-A57"}, + { SonyID_NEX_F3, "NEX-F3"}, + { SonyID_SLT_A99, "SLT-A99"}, // SLT-A99V / Hasselblad HV + { SonyID_NEX_6, "NEX-6"}, + { SonyID_NEX_5R, "NEX-5R"}, + { SonyID_DSC_RX100, "DSC-RX100"}, // Hasselblad Stellar + { SonyID_DSC_RX1, "DSC-RX1"}, + { SonyID_NEX_VG900, "NEX-VG900"}, + { SonyID_NEX_VG30, "NEX-VG30"}, + { SonyID_ILCE_3000, "ILCE-3000"}, // ILCE-3500 + { SonyID_SLT_A58, "SLT-A58"}, + { SonyID_NEX_3N, "NEX-3N"}, + { SonyID_ILCE_7, "ILCE-7"}, + { SonyID_NEX_5T, "NEX-5T"}, + { SonyID_DSC_RX100M2, "DSC-RX100M2"}, // Hasselblad Stellar II + { SonyID_DSC_RX10, "DSC-RX10"}, + { SonyID_DSC_RX1R, "DSC-RX1R"}, + { SonyID_ILCE_7R, "ILCE-7R"}, // Hasselblad Lusso + { SonyID_ILCE_6000, "ILCE-6000"}, + { SonyID_ILCE_5000, "ILCE-5000"}, + { SonyID_DSC_RX100M3, "DSC-RX100M3"}, + { SonyID_ILCE_7S, "ILCE-7S"}, + { SonyID_ILCA_77M2, "ILCA-77M2"}, + { SonyID_ILCE_5100, "ILCE-5100"}, + { SonyID_ILCE_7M2, "ILCE-7M2"}, + { SonyID_DSC_RX100M4, "DSC-RX100M4"}, + { SonyID_DSC_RX10M2, "DSC-RX10M2"}, + { SonyID_DSC_RX1RM2, "DSC-RX1RM2"}, + { SonyID_ILCE_QX1, "ILCE-QX1"}, + { SonyID_ILCE_7RM2, "ILCE-7RM2"}, + { SonyID_ILCE_7SM2, "ILCE-7SM2"}, + { SonyID_ILCA_68, "ILCA-68"}, + { SonyID_ILCA_99M2, "ILCA-99M2"}, + { SonyID_DSC_RX10M3, "DSC-RX10M3"}, + { SonyID_DSC_RX100M5, "DSC-RX100M5"}, + { SonyID_ILCE_6300, "ILCE-6300"}, + { SonyID_ILCE_9, "ILCE-9"}, + { SonyID_ILCE_6500, "ILCE-6500"}, + { SonyID_ILCE_7RM3, "ILCE-7RM3"}, + { SonyID_ILCE_7M3, "ILCE-7M3"}, + { SonyID_DSC_RX0, "DSC-RX0"}, + { SonyID_DSC_RX10M4, "DSC-RX10M4"}, + { SonyID_DSC_RX100M6, "DSC-RX100M6"}, + { SonyID_DSC_HX99, "DSC-HX99"}, + { SonyID_DSC_RX100M5A, "DSC-RX100M5A"}, + { SonyID_ILCE_6400, "ILCE-6400"}, + { SonyID_DSC_RX0M2, "DSC-RX0M2"}, + { SonyID_DSC_RX100M7, "DSC-RX100M7"}, + { SonyID_ILCE_7RM4, "ILCE-7RM4"}, + { SonyID_ILCE_9M2, "ILCE-9M2"}, + { SonyID_ILCE_6600, "ILCE-6600"}, + { SonyID_ILCE_6100, "ILCE-6100"}, + { SonyID_ZV_1, "ZV-1"}, + { SonyID_ILCE_7C, "ILCE-7C"}, + { SonyID_ZV_E10, "ZV-E10"}, + { SonyID_ILCE_7SM3, "ILCE-7SM3"}, + { SonyID_ILCE_1, "ILCE-1"}, + { SonyID_ILME_FX3, "ILME-FX3"}, + { SonyID_ILCE_7RM3A, "ILCE-7RM3A"}, + { SonyID_ILCE_7RM4A, "ILCE-7RM4A"}, + { SonyID_ILCE_7M4, "ILCE-7M4"}, + }; + + static const char *orig; + + static const char fujialias[][16] = { + "@DBP for GX680", "DX-2000", + "@F500EXR", "F505EXR", + "@F600EXR", "F605EXR", + "@F770EXR", "F775EXR", + "@HS10", "HS10 HS11", + "@HS20EXR", "HS22EXR", + "@HS30EXR", "HS33EXR", "HS35EXR", + "@S5100", "S5500", + "@S5200", "S5600", + "@S6000fd", "S6500fd", + "@S9000", "S9500", + "@S9100", "S9600", + "@S200EXR", "S205EXR", + "@X-T1 IR", "X-T1IR", + "@GFX 100S", "GFX100S", + "@GFX 50S II", "GFX50S II" + }; + + static const char kodakalias[][16] = { + "@DCS Pro 14N", "Camerz ZDS 14", // Camerz rebadge make: "Photo Control" + "@DCS720X", "SCS2000", + "@DCS520C", "EOS D2000C", "EOS D2000", // EOS rebadge make: Canon + "@DCS560C", "EOS D6000C", "EOS D6000", // EOS rebadge make: Canon + "@DCS460M", "DCS460A", // 'A' was supposed to stand for 'achromatic', marketing changed it to 'M' + "@DCS460", "DCS460C", "DCS460D", + "@DCS465", "DCS465C", "DCS465D", + "@EOSDCS1", "EOSDCS1B", "EOSDCS1C", + "@EOSDCS3", "EOSDCS3B", "EOSDCS3C", + }; + + static const struct + { + const char *Kmodel; + ushort mount; + } Kodak_mounts[] = { + {"DCS465", LIBRAW_MOUNT_DigitalBack}, + {"DCS5", LIBRAW_MOUNT_Canon_EF}, + {"DCS Pro SLR/c", LIBRAW_MOUNT_Canon_EF}, + {"DCS", LIBRAW_MOUNT_Nikon_F}, + {"EOS", LIBRAW_MOUNT_Canon_EF}, + {"NC2000", LIBRAW_MOUNT_Nikon_F}, // AP "News Camera" + {"Pixpro S-1", LIBRAW_MOUNT_mFT}, + {"ProBack", LIBRAW_MOUNT_DigitalBack}, + {"SCS1000", LIBRAW_MOUNT_Canon_EF}, + }; + + static const char *KodakMonochrome[] = { + "DCS420M", "DCS420A", "DCS420I", + "DCS460M", "DCS460A", "DCS460I", + "DCS465M", "DCS465A", "DCS465I", + "DCS560M", "DCS660M", "DCS760M", "EOS D2000M", "EOS D6000M", + "EOSDCS1M", "EOSDCS1I", + "EOSDCS3M", "EOSDCS3I", + "EOSDCS5M", "EOSDCS5I", + "NC2000M", "NC2000A", "NC2000I", + }; + + static const char leafalias[][16] = { + // Leaf re-badged to Mamiya + "@Aptus-II 5", "DM22", + "@Aptus-II 6", "DM28", + "@Aptus-II 7", "DM33", + "@Aptus-II 8", "DM40", + "@Aptus-II 10", "DM56", + }; + + static const char KonicaMinolta_aliases[][24] = { + "@DG-5D", "DYNAX 5D", "MAXXUM 5D", "ALPHA-5 DIGITAL", "ALPHA SWEET DIGITAL", + "@DG-7D", "DYNAX 7D", "MAXXUM 7D", "ALPHA-7 DIGITAL", + }; + + static const char nikonalias[][16] = { + "@COOLPIX 2100", "E2100", "@COOLPIX 2500", "E2500", + "@COOLPIX 3200", "E3200", "@COOLPIX 3700", "E3700", + "@COOLPIX 4300", "E4300", "@COOLPIX 4500", "E4500", + "@COOLPIX 5000", "E5000", "@COOLPIX 5400", "E5400", + "@COOLPIX 5700", "E5700", "@COOLPIX 8400", "E8400", + "@COOLPIX 8700", "E8700", "@COOLPIX 8800", "E8800", + "@COOLPIX 700", "E700", "@COOLPIX 800", "E800", + "@COOLPIX 880", "E880", "@COOLPIX 900", "E900", + "@COOLPIX 950", "E950", "@COOLPIX 990", "E990", + "@COOLPIX 995", "E995", "@COOLPIX P7700", "COOLPIX Deneb", + "@COOLPIX P7800", "COOLPIX Kalon", + }; + + static const char olyalias[][32] = { // Olympus + "@AIR A01", "AIR-A01", + "@C-3030Z", "C3030Z", + "@C-5050Z", "C5050Z", + "@C-5060WZ", "C5060WZ", + "@C-7000Z", "C7000Z", "C70Z,C7000Z", "C70Z", + "@C-7070WZ", "C7070WZ", + "@C-8080WZ", "C8080WZ", + "@C-350Z", "C350Z", "X200,D560Z,C350Z", "X200", "D560Z", + "@C-740UZ", "C740UZ", + "@C-770UZ", "C770UZ", + "@E-20", "E-20,E-20N,E-20P", "E-20N", "E-20P", + "@E-M10 Mark II", "E-M10MarkII", "E-M10_M2", "piX 5oo", + "@E-M10 Mark III", "E-M10MarkIII", "E-M10_M3", + "@E-M10 Mark IV", "E-M10MarkIV", "E-M10_M4", + "@E-M1 Mark II", "E-M1MarkII", "E-M1_M2", + "@E-M1 Mark III", "E-M1MarkIII", "E-M1_M3", + "@E-M5 Mark II", "E-M5MarkII", "E-M5_M2", + "@E-M5 Mark III", "E-M5MarkIII", "E-M5_M3", + "@SH-2", "SH-3", + "@SP-310", "SP310", + "@SP-320", "SP320", + "@SP-350", "SP350", + "@SP-500UZ", "SP500UZ", + "@SP-510UZ", "SP510UZ", + "@SP-550UZ", "SP550UZ", + "@SP-560UZ", "SP560UZ", + "@SP-565UZ", "SP565UZ", + "@SP-570UZ", "SP570UZ", + "@Stylus 1", "STYLUS1", "STYLUS1s", "STYLUS1,1s", + }; + + static const char panalias[][16] = { // Panasonic, PanaLeica +// fixed lens + "@DMC-FX150", "DMC-FX180", + "@DC-FZ1000M2", "DC-FZ10002", "V-Lux 5", + "@DMC-FZ1000", "V-LUX (Typ 114)", + "@DMC-FZ2500", "DMC-FZ2000", "DMC-FZH1", + "@DMC-FZ100", "V-LUX 2", + "@DMC-FZ150", "V-LUX 3", + "@DMC-FZ200", "V-LUX 4", + "@DMC-FZ300", "DMC-FZ330", + "@DMC-FZ35", "DMC-FZ38", + "@DMC-FZ40", "DMC-FZ42", "DMC-FZ45", "DC-FZ40", "DC-FZ42", "DC-FZ45", + "@DMC-FZ50", "V-LUX 1", "V-LUX1", + "@DMC-FZ70", "DMC-FZ72", + "@DC-FZ80", "DC-FZ81", "DC-FZ82", "DC-FZ83", "DC-FZ85", + "@DMC-LC1", "DIGILUX 2", "Digilux 2", "DIGILUX2", + "@DMC-LF1", "C (Typ 112)", + "@DC-LX100M2", "D-Lux 7", + "@DMC-LX100", "D-LUX (Typ 109)", "D-Lux (Typ 109)", + "@DMC-LX1", "D-Lux2", "D-LUX2", "D-LUX 2", + "@DMC-LX2", "D-LUX 3", "D-LUX3", + "@DMC-LX3", "D-LUX 4", + "@DMC-LX5", "D-LUX 5", + "@DMC-LX7", "D-LUX 6", + "@DMC-LX9", "DMC-LX10", "DMC-LX15", + "@DMC-ZS100", "DMC-ZS110", "DMC-TZ100", "DMC-TZ101", "DMC-TZ110", "DMC-TX1", + "@DC-ZS200", "DC-ZS220", "DC-TZ200", "DC-TZ202", "DC-TZ220", "DC-TX2", "C-Lux", "CAM-DC25", + "@DMC-ZS40", "DMC-TZ60", "DMC-TZ61", + "@DMC-ZS50", "DMC-TZ70", "DMC-TZ71", + "@DMC-ZS60", "DMC-TZ80", "DMC-TZ81", "DMC-TZ82", "DMC-TZ85", + "@DC-ZS70", "DC-TZ90", "DC-TZ91", "DC-TZ92", "DC-TZ93", + "@DC-ZS80", "DC-TZ95", "DC-TZ96", "DC-TZ97", + +// interchangeable lens + "@DC-G100", "DC-G110", + "@DC-G99", "DC-G90", "DC-G91", "DC-G95", + "@DMC-G7", "DMC-G70", + "@DMC-G8", "DMC-G80", "DMC-G81", "DMC-G85", + "@DMC-GH4", "AG-GH4", "CGO4", + "@DC-GF10", "DC-GF90", "DC-GX880", + "@DC-GF9", "DC-GX850", "DC-GX800", + "@DMC-GM1", "DMC-GM1S", + "@DMC-GX85", "DMC-GX80", "DMC-GX7MK2", + "@DC-GX9", "DC-GX7MK3", + "@DMC-L1", "DIGILUX 3", "DIGILUX3", // full 4/3 mount, not m43 + }; + + static const char phase1alias[][16] = { + "@H20", "H 20", + "@H25", "H 25", + "@P20+", "P 20+", + "@P20", "P 20", + "@P21+", "P 21+", "M18", // "Mamiya M18" + "@P21", "P 21", + "@P25+", "P 25+", "M22", // "Mamiya M22" + "@P25", "P 25", + "@P30+", "P 30+", "M31", // "Mamiya M31" + "@P30", "P 30", + "@P40+", "P 40+", + "@P40", "P 40", + "@P45+", "P 45+", + "@P45", "P 45", + "@P65+", "P 65+", + "@P65", "P 65", + }; + + static const char SamsungPentax_aliases[][16] = { + "@*istDL2", "*ist DL2", "GX-1L", + "@*istDS2", "*ist DS2", "GX-1S", + "@*istDL", "*ist DL", + "@*istDS", "*ist DS", + "@*istD", "*ist D", + "@K10D", "GX10", "GX-10", + "@K20D", "GX20", "GX-20", + "@K-m", "K2000", + }; + + static const char samsungalias[][64] = { + "@EX1", "TL500", + "@NX U", "EK-GN100", "EK-GN110", "EK-GN120", "EK-KN120", "Galaxy NX", + "@NX mini", "NXF1", + "@WB2000", "TL350", + // "@WB5000", "WB5000/HZ25W", // no spaces around the slash separating names + // "@WB5500", "WB5500 / VLUU WB5500 / SAMSUNG HZ50W", + // "@WB500", "WB510 / VLUU WB500 / SAMSUNG HZ10W", + // "@WB550", "WB560 / VLUU WB550 / SAMSUNG HZ15W", + // "@WB650", "SAMSUNG WB650 / VLUU WB650 / SAMSUNG WB660" aka HZ35W + }; + +//clang-format on + if (makeIs(LIBRAW_CAMERAMAKER_VLUU)) { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Samsung); + } + + if (makeIs(LIBRAW_CAMERAMAKER_Samsung) && + (ilm.CameraMount == LIBRAW_MOUNT_Pentax_K)) { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Pentax); + + } else if (makeIs(LIBRAW_CAMERAMAKER_Unknown)) { + if (strcasestr(model, "Google")) { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Google); + } +#ifdef USE_6BY9RPI + else if(strcasestr(make,"RaspberryPi")) + setMakeFromIndex(LIBRAW_CAMERAMAKER_RaspberryPi); +#endif + } + else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad) && is_Sony) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Sony); + } + else if (makeIs(LIBRAW_CAMERAMAKER_OmDigital)) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Olympus); + } + else if (makeIs(LIBRAW_CAMERAMAKER_Clauss) && (OlyID == OlyID_E_M10_Mark_II)) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Olympus); + } else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && + (!strncmp(model, "EOS D2000", 9) || // don't use unique_id here + !strncmp(model, "EOS D6000", 9) || // because ids for Monochrome models are unknown + !strncmp(model, "EOSDCS", 6))) { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak); +// if (unique_id == CanonID_EOS_D2000C) { +// +// } else if (unique_id == CanonID_EOS_D6000C) { +/// +// } + + } else if (makeIs(LIBRAW_CAMERAMAKER_PhotoControl) && + !strncasecmp(model, "Camerz ZDS 14", 13)) { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Kodak); + + } else { + strcpy(normalized_make, make); + } + + if (makeIs(LIBRAW_CAMERAMAKER_Apple)) { + if ((imgdata.color.UniqueCameraModel[0]) && + (!strncmp(model, "iPad", 4) || !strncmp(model, "iPhone", 6))) + strcpy(model, imgdata.color.UniqueCameraModel); + + } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) { + if ((model[6] == ' ') && + (!strncmp(model, "DCS4", 4) || + !strncmp(model, "NC2000", 6))) + { + model[6] = 0; + } + if ((model[6] != 'A') && + (model[6] != 'I') && + (model[6] != 'M') && + !strncmp(model, "NC2000", 6)) + { + model[6] = 0; + } + } + + else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && + !strncmp(model, "GXR", 3)) { + strcpy(ilm.body, "Ricoh GXR"); + if (!imgdata.lens.Lens[0] && imgdata.color.UniqueCameraModel[0]) { + strcpy (imgdata.lens.Lens, imgdata.color.UniqueCameraModel); + remove_caseSubstr (imgdata.lens.Lens, (char *)"Ricoh"); + remove_caseSubstr (imgdata.lens.Lens, (char *)"Lens"); + removeExcessiveSpaces (imgdata.lens.Lens); + } + if (ilm.LensID == LIBRAW_LENS_NOT_SET) { + if (strstr(imgdata.lens.Lens, "50mm")) + ilm.LensID = 1; + else if (strstr(imgdata.lens.Lens, "S10")) + ilm.LensID = 2; + else if (strstr(imgdata.lens.Lens, "P10")) + ilm.LensID = 3; + else if (strstr(imgdata.lens.Lens, "28mm")) + ilm.LensID = 5; + else if (strstr(imgdata.lens.Lens, "A16")) + ilm.LensID = 6; + } + switch (ilm.LensID) { + case 1: // GR Lens A12 50mm F2.5 Macro + strcpy(model, "GXR A12 50mm"); + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_RicohModule; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + break; + case 2: + strcpy(model, "GXR S10"); + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div1p7INCH; + ilm.CameraMount = LIBRAW_MOUNT_RicohModule; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + break; + case 3: // Ricoh Lens P10 28-300mm F3.5-5.6 VC + strcpy(model, "GXR P10"); + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_1div2p3INCH; + ilm.CameraMount = LIBRAW_MOUNT_RicohModule; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + break; + case 5: // GR Lens A12 28mm F2.5 + strcpy(model, "GXR A12 28mm"); + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_RicohModule; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + break; + case 6: // Ricoh Lens A16 24-85mm F3.5-5.5 + strcpy(model, "GXR A16"); + ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_RicohModule; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + break; + case 8: // Ricoh Mount A12 (Leica M lenses) + strcpy(model, "GXR Mount A12"); + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.CameraMount = LIBRAW_MOUNT_Leica_M; + ilm.LensID = LIBRAW_LENS_NOT_SET; + break; + } + } + + strcpy(normalized_model, model); + + if (makeIs(LIBRAW_CAMERAMAKER_Canon)) + { + if (unique_id) + { + if ((unique_id != CanonID_EOS_D2000C) && + (unique_id != CanonID_EOS_D6000C)) + { + for (i = 0; i < int(sizeof unique / sizeof *unique); i++) + { + if (unique_id == unique[i].id) + { + strcpy(model, unique[i].t_model); + strcpy(normalized_model, unique[i].t_model); + break; + } + } + } + } + else + { + if ((dng_version) && + (strlen(imgdata.color.UniqueCameraModel) > 6) && + strncmp(imgdata.color.UniqueCameraModel+6, "PowerShot", 9)) + { + for (i = 0; i < int(sizeof unique / sizeof *unique); i++) + { + if (!strcmp(unique[i].t_model, imgdata.color.UniqueCameraModel+6)) + { + ilm.CamID = unique_id = unique[i].id; + strcpy(normalized_model, unique[i].t_model); + try_xml = 1; + break; + } + } + } + } + } + else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) + { + for (i = 0; i < int(sizeof fujialias / sizeof *fujialias); i++) + { + if (fujialias[i][0] == '@') + { + orig = fujialias[i] + 1; + if (!strcmp(model, orig)) break; + } + else if (!strcmp(model, fujialias[i])) + { + strcpy(normalized_model, orig); + break; + } + } + + } else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad)) { + parseHassyModel(); + } + else if (makeIs(LIBRAW_CAMERAMAKER_Mamiya)) + { + for (i = 0; i < int(sizeof phase1alias / sizeof *phase1alias); i++) + { // re-badged Phase One backs + if (phase1alias[i][0] == '@') orig = phase1alias[i] + 1; + else if (!strcmp(model, phase1alias[i])) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_PhaseOne); + strcpy(normalized_model, orig); + break; + } + } + for (i = 0; i < int(sizeof leafalias / sizeof *leafalias); i++) + { // re-badged Leaf backs + if (leafalias[i][0] == '@') orig = leafalias[i] + 1; + else if (!strcmp(model, leafalias[i])) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Leaf); + strcpy(normalized_model, orig); + break; + } + } + + /* repeating, because make for some Mamiya re-badged Leaf backs is set to + * Leaf */ + } + else if (makeIs(LIBRAW_CAMERAMAKER_Leaf)) + { + for (i = 0; i < int(sizeof leafalias / sizeof *leafalias); i++) + { // re-badged Leaf backs + if (leafalias[i][0] == '@') + { + orig = leafalias[i] + 1; + if (!strcmp(model, orig)) break; + } + else if (!strcmp(model, leafalias[i])) + { // maybe to change regular "make" to "Mamiya" too + strcpy(normalized_model, orig); + break; + } + } + if ((ps = strchr(normalized_model, '('))) + *ps = 0; + } + else if (makeIs(LIBRAW_CAMERAMAKER_Minolta) || + makeIs(LIBRAW_CAMERAMAKER_Konica)) + { + if (makeIs(LIBRAW_CAMERAMAKER_Konica) && !strncasecmp(model, "DiMAGE", 6)) + { + setMakeFromIndex(LIBRAW_CAMERAMAKER_Minolta); + strcpy(make, "Minolta"); + } + else + { + for (i = 0; + i 9)) + { + if (makeIs(LIBRAW_CAMERAMAKER_Canon) && + try_xml && + (ps = strstr(xmpdata, "LensID=\""))) + { + ilm.LensID = atoi(ps + 8); + if (ilm.LensID == 61182) + { + ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; + } + } + else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) + { + if ((ilm.LensMount == LIBRAW_MOUNT_Samsung_NX) && + (ps = strstr(xmpdata, "LensID=\"("))) + { + ilm.LensID = atoi(ps + 9); + } + } + } + + if (ilm.CameraMount == LIBRAW_MOUNT_FixedLens) + { + if (ilm.CameraFormat) + ilm.LensFormat = ilm.CameraFormat; + if (ilm.LensMount == LIBRAW_MOUNT_Unknown) + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + } + + if ((ilm.CameraMount != LIBRAW_MOUNT_Unknown) && + (ilm.CameraMount != LIBRAW_MOUNT_FixedLens) && + (ilm.LensMount == LIBRAW_MOUNT_Unknown)) { + if (ilm.LensID == LIBRAW_LENS_NOT_SET) ilm.LensMount = LIBRAW_MOUNT_IL_UM; + else ilm.LensMount = ilm.CameraMount; + } +} + +void LibRaw::SetStandardIlluminants (unsigned makerIdx, const char* /*normModel*/) { + int i = -1; + int c; + if (!icWBC[LIBRAW_WBI_Ill_A][0] && + !icWBC[LIBRAW_WBI_D65][0]) { + if (makerIdx == LIBRAW_CAMERAMAKER_Olympus ) { + while (++i, icWBCCTC[i][0]) { + if (icWBCCTC[i][0] == 3000) + FORC4 icWBC[LIBRAW_WBI_Ill_A][c] = icWBCCTC[i][c+1]; + else if (icWBCCTC[i][0] == 6600) + FORC4 icWBC[LIBRAW_WBI_D65][c] = icWBCCTC[i][c+1]; + } + } + } + + if (!icWBC[LIBRAW_WBI_Ill_A][0] && icWBC[LIBRAW_WBI_Tungsten][0]) + FORC4 icWBC[LIBRAW_WBI_Ill_A][c] = icWBC[LIBRAW_WBI_Tungsten][c]; + + if (!icWBC[LIBRAW_WBI_D65][0] && icWBC[LIBRAW_WBI_FL_N][0]) + FORC4 icWBC[LIBRAW_WBI_D65][c] = icWBC[LIBRAW_WBI_FL_N][c]; + + return; +} diff --git a/src/metadata/olympus.cpp b/src/metadata/olympus.cpp new file mode 100644 index 000000000..6c427137b --- /dev/null +++ b/src/metadata/olympus.cpp @@ -0,0 +1,685 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +void LibRaw::setOlympusBodyFeatures(unsigned long long id) +{ + ilm.CamID = id; + + if ((id == OlyID_E_1) || + (id == OlyID_E_300) || + ((id & 0x00ffff0000ULL) == 0x0030300000ULL)) + { + ilm.CameraFormat = LIBRAW_FORMAT_FT; + + if ((id == OlyID_E_1) || + (id == OlyID_E_300) || + ((id >= OlyID_E_330) && (id <= OlyID_E_520)) || + (id == OlyID_E_620) || + (id == OlyID_E_450) || + (id == OlyID_E_600) || + (id == OlyID_E_5)) + { + ilm.CameraMount = LIBRAW_MOUNT_FT; + } + else + { + ilm.CameraMount = LIBRAW_MOUNT_mFT; + } + } + else + { + ilm.LensMount = ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + } + return; +} + +void LibRaw::getOlympus_CameraType2() +{ + + if (OlyID != 0x0ULL) + return; + + int i = 0; + fread(imOly.CameraType2, 6, 1, ifp); + imOly.CameraType2[5] = 0; + while ((i < 6) && imOly.CameraType2[i]) + { + OlyID = OlyID << 8 | imOly.CameraType2[i]; + if (i < 5 && isspace(imOly.CameraType2[i + 1])) { + imOly.CameraType2[i + 1] = '\0'; + break; + } + i++; + } + if (OlyID == OlyID_NORMA) { + if (strcmp(model, "SP510UZ")) OlyID = OlyID_SP_510UZ; + else OlyID = 0x0ULL; + } + unique_id = OlyID; + setOlympusBodyFeatures(OlyID); + return; +} + +void LibRaw::getOlympus_SensorTemperature(unsigned len) +{ + if (OlyID != 0x0ULL) + { + short temp = get2(); + if ((OlyID == OlyID_E_1) || + (OlyID == OlyID_E_M5) || + (len != 1)) + imCommon.SensorTemperature = (float)temp; + else if ((temp != -32768) && (temp != 0)) + { + if (temp > 199) + imCommon.SensorTemperature = 86.474958f - 0.120228f * (float)temp; + else + imCommon.SensorTemperature = (float)temp; + } + } + return; +} + +void LibRaw::parseOlympus_Equipment(unsigned tag, unsigned /*type */, unsigned len, + unsigned dng_writer) +{ + // uptag 2010 + + switch (tag) + { + case 0x0100: + getOlympus_CameraType2(); + break; + case 0x0101: + if ((!imgdata.shootinginfo.BodySerial[0]) && (dng_writer == nonDNG)) + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + break; + case 0x0102: + stmread(imgdata.shootinginfo.InternalBodySerial, len, ifp); + break; + case 0x0201: + { + unsigned char bits[4]; + fread(bits, 1, 4, ifp); + ilm.LensID = (unsigned long long)bits[0] << 16 | + (unsigned long long)bits[2] << 8 | (unsigned long long)bits[3]; + ilm.LensMount = LIBRAW_MOUNT_FT; + ilm.LensFormat = LIBRAW_FORMAT_FT; + if (((ilm.LensID < 0x20000) || (ilm.LensID > 0x4ffff)) && + (ilm.LensID & 0x10)) + ilm.LensMount = LIBRAW_MOUNT_mFT; + } + break; + case 0x0202: + if ((!imgdata.lens.LensSerial[0])) + stmread(imgdata.lens.LensSerial, len, ifp); + break; + case 0x0203: + stmread(ilm.Lens, len, ifp); + break; + case 0x0205: + ilm.MaxAp4MinFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); + break; + case 0x0206: + ilm.MaxAp4MaxFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); + break; + case 0x0207: + ilm.MinFocal = (float)get2(); + break; + case 0x0208: + ilm.MaxFocal = (float)get2(); + if (ilm.MaxFocal > 1000.0f) + ilm.MaxFocal = ilm.MinFocal; + break; + case 0x020a: + ilm.MaxAp4CurFocal = libraw_powf64l(sqrt(2.0f), get2() / 256.0f); + break; + case 0x0301: + ilm.TeleconverterID = fgetc(ifp) << 8; + fgetc(ifp); + ilm.TeleconverterID = ilm.TeleconverterID | fgetc(ifp); + break; + case 0x0303: + stmread(ilm.Teleconverter, len, ifp); + if (!strlen(ilm.Teleconverter) && strchr(ilm.Lens, '+')) { + if (strstr(ilm.Lens, "MC-20")) + strcpy(ilm.Teleconverter, "MC-20"); + else if (strstr(ilm.Lens, "MC-14")) + strcpy(ilm.Teleconverter, "MC-14"); + else if (strstr(ilm.Lens, "EC-20")) + strcpy(ilm.Teleconverter, "EC-20"); + else if (strstr(ilm.Lens, "EC-14")) + strcpy(ilm.Teleconverter, "EC-14"); } + break; + case 0x0403: + stmread(ilm.Attachment, len, ifp); + break; + } + + return; +} +void LibRaw::parseOlympus_CameraSettings(int base, unsigned tag, unsigned type, + unsigned len, unsigned dng_writer) +{ + // uptag 0x2020 + + int c; + switch (tag) + { + case 0x0101: + if (dng_writer == nonDNG) + { + thumb_offset = get4() + base; + } + break; + case 0x0102: + if (dng_writer == nonDNG) + { + thumb_length = get4(); + } + break; + case 0x0200: + imgdata.shootinginfo.ExposureMode = get2(); + break; + case 0x0202: + imgdata.shootinginfo.MeteringMode = get2(); + break; + case 0x0301: + imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = get2(); + if (len == 2) + { + imOly.FocusMode[1] = get2(); + } + break; + case 0x0304: + for (c = 0; c < 64; c++) + { + imOly.AFAreas[c] = get4(); + } + break; + case 0x0305: + for (c = 0; c < 5; c++) + { + imOly.AFPointSelected[c] = getreal(type); + } + break; + case 0x0306: + imOly.AFFineTune = fgetc(ifp); + break; + case 0x0307: + FORC3 imOly.AFFineTuneAdj[c] = get2(); + break; + case 0x0401: + imCommon.FlashEC = getreal(type); + break; + case 0x0507: + imOly.ColorSpace = get2(); + switch (imOly.ColorSpace) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_ProPhotoRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + break; + case 0x0600: + imgdata.shootinginfo.DriveMode = imOly.DriveMode[0] = get2(); + for (c = 1; c < (int)len && c < 5; c++) + { + imOly.DriveMode[c] = get2(); + } + break; + case 0x0601: + imOly.Panorama_mode = get2(); + imOly.Panorama_frameNum = get2(); + break; + case 0x0604: + imgdata.shootinginfo.ImageStabilization = get4(); + break; + case 0x0804: + imOly.StackedImage[0] = get4(); + imOly.StackedImage[1] = get4(); + if (imOly.StackedImage[0] == 3) { + imOly.isLiveND = 1; + imOly.LiveNDfactor = imOly.StackedImage[1]; + } else { + imOly.isLiveND = 0; + } + break; + } + + return; +} + +void LibRaw::parseOlympus_ImageProcessing(unsigned tag, unsigned type, + unsigned len, unsigned dng_writer) +{ + // uptag 0x2040 + + int i, c, wb[4], nWB, tWB, wbG; + ushort CT; + short sorder; + + if ((tag == 0x0100) && (dng_writer == nonDNG)) + { + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + else if ((tag == 0x0101) && (len == 2) && + ((OlyID == OlyID_E_410) || (OlyID == OlyID_E_510))) + { + for (i = 0; i < 64; i++) + { + icWBCCTC[i][2] = icWBCCTC[i][4] = icWBC[i][1] = icWBC[i][3] = 0x100; + } + for (i = 64; i < 256; i++) + { + icWBC[i][1] = icWBC[i][3] = 0x100; + } + } + else if ((tag > 0x0101) && (tag <= 0x0111)) + { + nWB = tag - 0x0101; + tWB = Oly_wb_list2[nWB << 1]; + CT = Oly_wb_list2[(nWB << 1) | 1]; + wb[0] = get2(); + wb[2] = get2(); + if (tWB != 0x100) + { + icWBC[tWB][0] = wb[0]; + icWBC[tWB][2] = wb[2]; + } + if (CT) + { + icWBCCTC[nWB - 1][0] = CT; + icWBCCTC[nWB - 1][1] = wb[0]; + icWBCCTC[nWB - 1][3] = wb[2]; + } + if (len == 4) + { + wb[1] = get2(); + wb[3] = get2(); + if (tWB != 0x100) + { + icWBC[tWB][1] = wb[1]; + icWBC[tWB][3] = wb[3]; + } + if (CT) + { + icWBCCTC[nWB - 1][2] = wb[1]; + icWBCCTC[nWB - 1][4] = wb[3]; + } + } + } + else if ((tag >= 0x0112) && (tag <= 0x011e)) + { + nWB = tag - 0x0112; + wbG = get2(); + tWB = Oly_wb_list2[nWB << 1]; + if (nWB) + icWBCCTC[nWB - 1][2] = icWBCCTC[nWB - 1][4] = wbG; + if (tWB != 0x100) + icWBC[tWB][1] = icWBC[tWB][3] = wbG; + } + else if (tag == 0x011f) + { + wbG = get2(); + if (icWBC[LIBRAW_WBI_Flash][0]) + icWBC[LIBRAW_WBI_Flash][1] = + icWBC[LIBRAW_WBI_Flash][3] = wbG; + FORC4 if (icWBC[LIBRAW_WBI_Custom1 + c][0]) + icWBC[LIBRAW_WBI_Custom1 + c][1] = + icWBC[LIBRAW_WBI_Custom1 + c][3] = wbG; + } + else if (tag == 0x0121) + { + icWBC[LIBRAW_WBI_Flash][0] = get2(); + icWBC[LIBRAW_WBI_Flash][2] = get2(); + if (len == 4) + { + icWBC[LIBRAW_WBI_Flash][1] = get2(); + icWBC[LIBRAW_WBI_Flash][3] = get2(); + } + } + else if ((tag == 0x0200) && (dng_writer == nonDNG) && + strcmp(software, "v757-71")) + { + for (i = 0; i < 3; i++) + { + if (!imOly.ColorSpace) + { + FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; + } + else + { + FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; + } + } + } + else if ((tag == 0x0600) && (dng_writer == nonDNG)) + { + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + } + else if ((tag == 0x0611) && (dng_writer == nonDNG)) + { + imOly.ValidBits = get2(); + } + else if ((tag == 0x0612) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + } + else if ((tag == 0x0613) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + } + else if ((tag == 0x0614) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + } + else if ((tag == 0x0615) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + } + else if ((tag == 0x0805) && (len == 2)) + { + imOly.SensorCalibration[0] = getreal(type); + imOly.SensorCalibration[1] = getreal(type); + if ((dng_writer == nonDNG) && (OlyID != OlyID_XZ_1)) + FORC4 imgdata.color.linear_max[c] = imOly.SensorCalibration[0]; + } + else if (tag == 0x1112) + { + sorder = order; + order = 0x4d4d; + c = get2(); + order = sorder; + switch (c) { + case 0x0101: + case 0x0901: + case 0x0909: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; + break; + case 0x0104: + case 0x0401: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + break; + case 0x0201: + case 0x0202: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 0x0301: + case 0x0303: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; + break; + case 0x0404: +// imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_6to6; + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + break; + case 0x0505: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_5to4; + break; + case 0x0606: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_7to6; + break; + case 0x0707: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_6to5; + break; + case 0x0808: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_7to5; + break; + default: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_OTHER; + break; + } + } + else if (tag == 0x1113) + { + imOly.AspectFrame[0] = get2(); + imOly.AspectFrame[1] = get2(); + imOly.AspectFrame[2] = get2(); + imOly.AspectFrame[3] = get2(); + } + else if (tag == 0x1306) + { + c = get2(); + if ((c != 0) && (c != 100)) + { + if (c < 61) + imCommon.CameraTemperature = (float)c; + else + imCommon.CameraTemperature = (float)(c - 32) / 1.8f; + if ((imCommon.exifAmbientTemperature > -273.15f) && + ((OlyID == OlyID_TG_5) || + (OlyID == OlyID_TG_6)) + ) + imCommon.CameraTemperature += imCommon.exifAmbientTemperature; + } + } + + return; +} + +void LibRaw::parseOlympus_RawInfo(unsigned tag, unsigned /*type */, unsigned len, + unsigned dng_writer) +{ + // uptag 0x3000 + + int wb_ind, c, i; + + if ((tag == 0x0110) && strcmp(software, "v757-71")) + { + icWBC[LIBRAW_WBI_Auto][0] = get2(); + icWBC[LIBRAW_WBI_Auto][2] = get2(); + if (len == 2) + { + for (i = 0; i < 256; i++) + icWBC[i][1] = icWBC[i][3] = 0x100; + } + } + else if ((((tag >= 0x0120) && (tag <= 0x0124)) || + ((tag >= 0x0130) && (tag <= 0x0133))) && + strcmp(software, "v757-71")) + { + if (tag <= 0x0124) + wb_ind = tag - 0x0120; + else + wb_ind = tag - 0x0130 + 5; + + icWBC[Oly_wb_list1[wb_ind]][0] = get2(); + icWBC[Oly_wb_list1[wb_ind]][2] = get2(); + } + else if ((tag == 0x0200) && (dng_writer == nonDNG)) + { + for (i = 0; i < 3; i++) + { + if (!imOly.ColorSpace) + { + FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; + } + else + { + FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; + } + } + } + else if ((tag == 0x0600) && (dng_writer == nonDNG)) + { + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + } + else if ((tag == 0x0612) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + } + else if ((tag == 0x0613) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + } + else if ((tag == 0x0614) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + } + else if ((tag == 0x0615) && (dng_writer == nonDNG)) + { + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + } + return; +} + + +void LibRaw::parseOlympusMakernotes (int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer) { + + int c; + unsigned a; + if ((tag >= 0x20100000) && (tag <= 0x2010ffff)) { + parseOlympus_Equipment((tag & 0x0000ffff), type, len, dng_writer); + + } else if ((tag >= 0x20200000) && (tag <= 0x2020ffff)) { + parseOlympus_CameraSettings(base, (tag & 0x0000ffff), type, len, dng_writer); + + } else if ((tag >= 0x20400000) && (tag <= 0x2040ffff)) { + parseOlympus_ImageProcessing((tag & 0x0000ffff), type, len, dng_writer); + + } else if ((tag >= 0x30000000) && (tag <= 0x3000ffff)) { + parseOlympus_RawInfo((tag & 0x0000ffff), type, len, dng_writer); + + } else { + switch (tag) { + case 0x0200: + FORC3 if ((imOly.SpecialMode[c] = get4()) >= 0xff) imOly.SpecialMode[c] = 0xffffffff; + break; + case 0x0207: + getOlympus_CameraType2(); + break; + case 0x0404: + case 0x101a: + if (!imgdata.shootinginfo.BodySerial[0] && (dng_writer == nonDNG)) + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + break; + case 0x1002: + ilm.CurAp = libraw_powf64l(2.0f, getreal(type) / 2); + break; + case 0x1007: + imCommon.SensorTemperature = (float)get2(); + break; + case 0x1008: + imCommon.LensTemperature = (float)get2(); + break; + case 0x100b: + if (imOly.FocusMode[0] == 0xffff) { + imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = get2(); + if (imgdata.shootinginfo.FocusMode == 1) + imgdata.shootinginfo.FocusMode = imOly.FocusMode[0] = 10; + } + break; + case 0x100d: + if (imOly.ZoomStepCount == 0xffff) imOly.ZoomStepCount = get2(); + break; + case 0x100e: + if (imOly.FocusStepCount == 0xffff) imOly.FocusStepCount = get2(); + break; + case 0x1011: + if (strcmp(software, "v757-71") && (dng_writer == nonDNG)) { + for (int i = 0; i < 3; i++) { + if (!imOly.ColorSpace) { + FORC3 cmatrix[i][c] = ((short)get2()) / 256.0; + } else { + FORC3 imgdata.color.ccm[i][c] = ((short)get2()) / 256.0; + } + } + } + break; + case 0x1012: + if (dng_writer == nonDNG) + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + break; + case 0x1017: + if (dng_writer == nonDNG) + cam_mul[0] = get2() / 256.0; + break; + case 0x1018: + if (dng_writer == nonDNG) + cam_mul[2] = get2() / 256.0; + break; + case 0x102c: + if (dng_writer == nonDNG) + imOly.ValidBits = get2(); + break; + case 0x1038: + imOly.AFResult = get2(); + break; + case 0x103b: + if (imOly.FocusStepInfinity == 0xffff) imOly.FocusStepInfinity = get2(); + break; + case 0x103c: + if (imOly.FocusStepNear == 0xffff) imOly.FocusStepNear = get2(); + break; + case 0x20300108: + case 0x20310109: + if (dng_writer == nonDNG) { + imOly.ColorSpace = get2(); + switch (imOly.ColorSpace) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_ProPhotoRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + } + case 0x20500209: + imOly.AutoFocus = get2(); + break; + case 0x20500300: + imOly.ZoomStepCount = get2(); + break; + case 0x20500301: + imOly.FocusStepCount = get2(); + break; + case 0x20500303: + imOly.FocusStepInfinity = get2(); + break; + case 0x20500304: + imOly.FocusStepNear = get2(); + break; + case 0x20500305: + a = get4(); + /*b = */ get4(); // b is not used, so removed + if (a >= 0x7f000000) imOly.FocusDistance = -1.0; // infinity + else imOly.FocusDistance = (double) a / 1000.0; // convert to meters + break; + case 0x20500308: + imOly.AFPoint = get2(); + break; + case 0x20501500: + getOlympus_SensorTemperature(len); + break; + } + } +} diff --git a/src/metadata/p1.cpp b/src/metadata/p1.cpp new file mode 100644 index 000000000..a3867b8c9 --- /dev/null +++ b/src/metadata/p1.cpp @@ -0,0 +1,192 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::setPhaseOneFeatures(unsigned long long id) +{ + + ushort i; + static const struct + { + unsigned long long id; + char t_model[32]; + int CamMnt; + int CamFmt; + } p1_unique[] = { + // Phase One section: + {0x001ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x00aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x00cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x010ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x011ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x012ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x013ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x014ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x015ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x016ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x017ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x018ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x019ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x020ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x022ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x023ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x024ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x025ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x026ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x027ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x028ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x029ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x02aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x02cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x02dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x02eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x02fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x030ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x031ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x032ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x033ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x034ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x035ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x036ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x037ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x043ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x044ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x045ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x046ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x047ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x048ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x049ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x04aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x04cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x04dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x04eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x04fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x050ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x051ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x052ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x053ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x054ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x055ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x056ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x057ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x063ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x064ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x065ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x066ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x067ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x068ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x069ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x06aULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x070ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x071ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x072ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x073ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x083ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x084ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x085ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x086ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x087ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x088ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x089ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x08aULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x08cULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x08dULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x08eULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x08fULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x094ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x095ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x096ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x097ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x0a0ULL, "A-250", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, + {0x0a1ULL, "A-260", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, + {0x0a2ULL, "A-280", LIBRAW_MOUNT_Alpa, LIBRAW_FORMAT_69}, + {0x0a7ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x0a8ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x0a9ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x0aaULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x0acULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x0adULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x0aeULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x0afULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x0b0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x0b1ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x0b2ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x0b3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x0b4ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x0b5ULL, "Hasselblad H", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x0b6ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x0b7ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x0d0ULL, "Hasselblad V", LIBRAW_MOUNT_Hasselblad_V, LIBRAW_FORMAT_66}, + {0x0d3ULL, "PhaseOne/Mamiya", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x1c0ULL, "Phase One 645AF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x1c9ULL, "Phase One 645DF", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x1d7ULL, "Phase One 645DF+", LIBRAW_MOUNT_Mamiya645, LIBRAW_FORMAT_645}, + {0x2c0ULL, "Phase One iXA", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x2c1ULL, "Phase One iXA - R", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x2c2ULL, "Phase One iXU 150", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x2c3ULL, "Phase One iXU 150 - NIR", LIBRAW_MOUNT_Unknown,LIBRAW_FORMAT_Unknown}, + {0x2c4ULL, "Phase One iXU 180", LIBRAW_MOUNT_Unknown,LIBRAW_FORMAT_Unknown}, + {0x2d1ULL, "Phase One iXR", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + // Leaf section: + {0x140ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x141ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x142ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x143ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x144ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x145ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x146ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x147ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x149ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x14aULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x14cULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x14dULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x14eULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, + {0x14fULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, + {0x150ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, + {0x151ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x152ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x153ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x154ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + + {0x16cULL, "Phase One iXM-RS150F", LIBRAW_MOUNT_PhaseOne_iXM_RS, LIBRAW_FORMAT_645}, + + {0x171ULL, "Universal", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x172ULL, "Mamiya", LIBRAW_MOUNT_Unknown, LIBRAW_FORMAT_Unknown}, + {0x173ULL, "Hasselblad H1/H2", LIBRAW_MOUNT_Hasselblad_H, LIBRAW_FORMAT_645}, + {0x174ULL, "Contax 645", LIBRAW_MOUNT_Contax645, LIBRAW_FORMAT_645}, + {0x175ULL, "AFi", LIBRAW_MOUNT_Rollei_bayonet, LIBRAW_FORMAT_66}, + }; + ilm.CamID = id; + if (id && !ilm.body[0]) + { + for (i = 0; i < sizeof p1_unique / sizeof *p1_unique; i++) + if (id == p1_unique[i].id) + { + strcpy(ilm.body, p1_unique[i].t_model); + ilm.CameraFormat = p1_unique[i].CamFmt; + ilm.CameraMount = p1_unique[i].CamMnt; + if ((ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM_RS) || + (ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM)) { + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + ilm.LensMount = ilm.CameraMount; + } else if (ilm.CameraMount == LIBRAW_MOUNT_PhaseOne_iXM_MV) { + ilm.LensMount = ilm.CameraMount; + } + break; + } + } + return; +} diff --git a/src/metadata/pentax.cpp b/src/metadata/pentax.cpp new file mode 100644 index 000000000..705fd84c9 --- /dev/null +++ b/src/metadata/pentax.cpp @@ -0,0 +1,675 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +void LibRaw::setPentaxBodyFeatures(unsigned long long id) +{ + + ilm.CamID = id; + + switch (id) { + case PentaxID_staristD: + case PentaxID_staristDS: + case PentaxID_staristDL: + case PentaxID_staristDS2: + case PentaxID_GX_1S: + case PentaxID_staristDL2: + case PentaxID_GX_1L: + case PentaxID_K100D: + case PentaxID_K110D: + case PentaxID_K100D_Super: + case PentaxID_K10D: + case PentaxID_GX10: + case PentaxID_K20D: + case PentaxID_GX20: + case PentaxID_K200D: + case PentaxID_K2000: + case PentaxID_K_m: + case PentaxID_K_7: + case PentaxID_K_x: + case PentaxID_K_r: + case PentaxID_K_5: + case PentaxID_K_01: + case PentaxID_K_30: + case PentaxID_K_5_II: + case PentaxID_K_5_II_s: + case PentaxID_K_50: + case PentaxID_K_3: + case PentaxID_K_500: + case PentaxID_K_S1: + case PentaxID_K_S2: + case PentaxID_K_3_II: + case PentaxID_K_3_III: + case PentaxID_K_70: + case PentaxID_KP: + ilm.CameraMount = LIBRAW_MOUNT_Pentax_K; + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + break; + case PentaxID_K_1: + case PentaxID_K_1_Mark_II: + ilm.CameraMount = LIBRAW_MOUNT_Pentax_K; + ilm.CameraFormat = LIBRAW_FORMAT_FF; + break; + case PentaxID_645D: + case PentaxID_645Z: + ilm.CameraMount = LIBRAW_MOUNT_Pentax_645; + ilm.CameraFormat = LIBRAW_FORMAT_CROP645; + break; + case PentaxID_Q: + case PentaxID_Q10: + ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q; + ilm.CameraFormat = LIBRAW_FORMAT_1div2p3INCH; + break; + case PentaxID_Q7: + case PentaxID_Q_S1: + ilm.CameraMount = LIBRAW_MOUNT_Pentax_Q; + ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH; + break; + case PentaxID_MX_1: + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraFormat = LIBRAW_FORMAT_1div1p7INCH; + ilm.FocalType = LIBRAW_FT_ZOOM_LENS; + break; + case PentaxID_GR_III: + case PentaxID_GR_IIIx: + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + break; + default: + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + } + return; +} + +void LibRaw::PentaxISO(ushort c) +{ + int code[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 50, 100, 200, 400, 800, + 1600, 3200, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278}; + double value[] = { + 50, 64, 80, 100, 125, 160, 200, 250, 320, + 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, + 3200, 4000, 5000, 6400, 8000, 10000, 12800, 16000, 20000, + 25600, 32000, 40000, 51200, 64000, 80000, 102400, 128000, 160000, + 204800, 258000, 325000, 409600, 516000, 650000, 819200, 50, 100, + 200, 400, 800, 1600, 3200, 50, 70, 100, 140, + 200, 280, 400, 560, 800, 1100, 1600, 2200, 3200, + 4500, 6400, 9000, 12800, 18000, 25600, 36000, 51200}; +#define numel (sizeof(code) / sizeof(code[0])) + int i; + for (i = 0; i < (int)numel; i++) + { + if (code[i] == c) + { + iso_speed = value[i]; + return; + } + } + if (i == numel) + iso_speed = 65535.0f; +} +#undef numel + +void LibRaw::PentaxLensInfo(unsigned long long id, unsigned len) // tag 0x0207 +{ + ushort iLensData = 0; + uchar *table_buf; + table_buf = (uchar *)malloc(MAX(len, 128)); + fread(table_buf, len, 1, ifp); + if ((id < PentaxID_K100D) || + (((id == PentaxID_K100D) || + (id == PentaxID_K110D) || + (id == PentaxID_K100D_Super)) && + ((!table_buf[20] || + (table_buf[20] == 0xff))))) + { + iLensData = 3; + if (ilm.LensID == LIBRAW_LENS_NOT_SET) + ilm.LensID = (((unsigned)table_buf[0]) << 8) + table_buf[1]; + } + else + switch (len) + { + case 90: // LensInfo3 + iLensData = 13; + if (ilm.LensID == LIBRAW_LENS_NOT_SET) + ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + + table_buf[4]; + break; + case 91: // LensInfo4 + iLensData = 12; + if (ilm.LensID == LIBRAW_LENS_NOT_SET) + ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[3]) << 8) + + table_buf[4]; + break; + case 80: // LensInfo5 + case 128: + iLensData = 15; + if (ilm.LensID == LIBRAW_LENS_NOT_SET) + ilm.LensID = ((unsigned)((table_buf[1] & 0x0f) + table_buf[4]) << 8) + + table_buf[5]; + break; + case 168: // Ricoh GR III, id 0x1320e + break; + default: + if (id >= 0x12b9cULL) // LensInfo2 + { + iLensData = 4; + if (ilm.LensID == LIBRAW_LENS_NOT_SET) + ilm.LensID = ((unsigned)((table_buf[0] & 0x0f) + table_buf[2]) << 8) + + table_buf[3]; + } + } + if (iLensData) + { + if (table_buf[iLensData + 9] && (fabs(ilm.CurFocal) < 0.1f)) + ilm.CurFocal = 10 * (table_buf[iLensData + 9] >> 2) * + libraw_powf64l(4, (table_buf[iLensData + 9] & 0x03) - 2); + if (table_buf[iLensData + 10] & 0xf0) + ilm.MaxAp4CurFocal = libraw_powf64l( + 2.0f, (float)((table_buf[iLensData + 10] & 0xf0) >> 4) / 4.0f); + if (table_buf[iLensData + 10] & 0x0f) + ilm.MinAp4CurFocal = libraw_powf64l( + 2.0f, (float)((table_buf[iLensData + 10] & 0x0f) + 10) / 4.0f); + + if (iLensData != 12) + { + switch (table_buf[iLensData] & 0x06) + { + case 0: + ilm.MinAp4MinFocal = 22.0f; + break; + case 2: + ilm.MinAp4MinFocal = 32.0f; + break; + case 4: + ilm.MinAp4MinFocal = 45.0f; + break; + case 6: + ilm.MinAp4MinFocal = 16.0f; + break; + } + if (table_buf[iLensData] & 0x70) + ilm.LensFStops = + ((float)(((table_buf[iLensData] & 0x70) >> 4) ^ 0x07)) / 2.0f + + 5.0f; + + ilm.MinFocusDistance = (float)(table_buf[iLensData + 3] & 0xf8); + ilm.FocusRangeIndex = (float)(table_buf[iLensData + 3] & 0x07); + + if ((table_buf[iLensData + 14] > 1) && (fabs(ilm.MaxAp4CurFocal) < 0.7f)) + ilm.MaxAp4CurFocal = libraw_powf64l( + 2.0f, (float)((table_buf[iLensData + 14] & 0x7f) - 1) / 32.0f); + } + else if ((id != 0x12e76ULL) && // K-5 + (table_buf[iLensData + 15] > 1) && + (fabs(ilm.MaxAp4CurFocal) < 0.7f)) + { + ilm.MaxAp4CurFocal = libraw_powf64l( + 2.0f, (float)((table_buf[iLensData + 15] & 0x7f) - 1) / 32.0f); + } + } + free(table_buf); + return; +} + +void LibRaw::parsePentaxMakernotes(int /*base*/, unsigned tag, unsigned type, + unsigned len, unsigned dng_writer) +{ + + int c; +// printf ("==>> =%s= tag:0x%x, type: %d, len:%d\n", model, tag, type, len); + + if (tag == 0x0005) + { + unique_id = get4(); + setPentaxBodyFeatures(unique_id); + } + else if (tag == 0x0008) + { /* 4 is raw, 7 is raw w/ pixel shift, 8 is raw w/ dynamic pixel shift */ + imPentax.Quality = get2(); + } + else if (tag == 0x000d) + { + imgdata.shootinginfo.FocusMode = imPentax.FocusMode[0] = get2(); + } + else if (tag == 0x000e) + { + imgdata.shootinginfo.AFPoint = imPentax.AFPointSelected[0] = get2(); + if (len == 2) + imPentax.AFPointSelected_Area = get2(); + } + else if (tag == 0x000f) + { + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_LONG)) + { + imPentax.AFPointsInFocus = get4(); + if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff; + else imPentax.AFPointsInFocus_version = 3; + } + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + imPentax.AFPointsInFocus = (unsigned) get2(); + if (imPentax.AFPointsInFocus == 0x0000ffff) + imPentax.AFPointsInFocus = 0xffffffff; + else imPentax.AFPointsInFocus_version = 2; + } + } + else if (tag == 0x0010) + { + imPentax.FocusPosition = get2(); + } + else if (tag == 0x0013) + { + ilm.CurAp = (float)get2() / 10.0f; + } + else if (tag == 0x0014) + { + PentaxISO(get2()); + } + else if (tag == 0x0017) + { + imgdata.shootinginfo.MeteringMode = get2(); + } + else if (tag == 0x001b) { + cam_mul[2] = get2() / 256.0; + } + else if (tag == 0x001c) { + cam_mul[0] = get2() / 256.0; + } + else if (tag == 0x001d) + { + ilm.CurFocal = (float)get4() / 100.0f; + } + else if (tag == 0x0034) + { + uchar uc; + FORC4 + { + fread(&uc, 1, 1, ifp); + imPentax.DriveMode[c] = uc; + } + imgdata.shootinginfo.DriveMode = imPentax.DriveMode[0]; + } + else if (tag == 0x0037) { + switch (get2()) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + } + else if (tag == 0x0038) + { + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + } + else if (tag == 0x0039) + { + imgdata.sizes.raw_inset_crops[0].cwidth = get2(); + imgdata.sizes.raw_inset_crops[0].cheight = get2(); + } + else if (tag == 0x003c) + { + if ((len == 4) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED)) { + imPentax.AFPointsInFocus = get4() & 0x7ff; + if (!imPentax.AFPointsInFocus) { + imPentax.AFPointsInFocus = 0xffffffff; + } + else { + imPentax.AFPointsInFocus_version = 1; + } + } + } + else if (tag == 0x003f) + { + unsigned a = unsigned(fgetc(ifp)) << 8; + ilm.LensID = a | fgetc(ifp); + } + else if (tag == 0x0047) + { + imCommon.CameraTemperature = (float)fgetc(ifp); + } + else if (tag == 0x004d) + { + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SLONG)) + imCommon.FlashEC = getreal(type) / 256.0f; + else + imCommon.FlashEC = (float)((signed short)fgetc(ifp)) / 6.0f; + } + else if (tag == 0x005c) + { + fgetc(ifp); + imgdata.shootinginfo.ImageStabilization = (short)fgetc(ifp); + } + else if (tag == 0x0072) + { + imPentax.AFAdjustment = get2(); + } + else if ((tag == 0x007e) && (dng_writer == nonDNG)) + { + imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = + imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = + get4(); + } + else if (tag == 0x0080) + { + short a = (short)fgetc(ifp); + switch (a) + { + case 0: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; + break; + case 1: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 2: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_16to9; + break; + case 3: + imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; + break; + } + } + + else if ((tag == 0x0200) && (dng_writer == nonDNG)) { // Pentax black level + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + } + + else if ((tag == 0x0201) && (dng_writer == nonDNG)) { // Pentax As Shot WB + FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); + } + + else if ((tag == 0x0203) && (dng_writer == nonDNG)) + { + for (int i = 0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0; + } + else if (tag == 0x0205) + { + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + if ((len < 25) && (len >= 11)) + { + imPentax.AFPointMode = (imCommon.afdata[imCommon.afcount].AFInfoData[3] >>4) & 0x0f; + imPentax.FocusMode[1] = imCommon.afdata[imCommon.afcount].AFInfoData[3] & 0x0f; + imPentax.AFPointSelected[1] = sget2(imCommon.afdata[imCommon.afcount].AFInfoData+4); +// Pentax K-m has multiexposure set to 8 when no multi-exposure is in effect + imPentax.MultiExposure = imCommon.afdata[imCommon.afcount].AFInfoData[10] & 0x0f; + } + imCommon.afcount++; + } + } + else if (tag == 0x0207) + { + if (len < 65535) // Safety belt + PentaxLensInfo(ilm.CamID, len); + } + else if ((tag >= 0x020d) && (tag <= 0x0214)) + { + FORC4 icWBC[Pentax_wb_list1[tag - 0x020d]][RGGB_2_RGBG(c)] = get2(); + } + else if ((tag == 0x021d) && (len == 18) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_UNDEFINED) && (dng_writer == nonDNG)) + { + for (int i = 0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short)get2()) / 8192.0; + } + else if (tag == 0x021f) + { + if ((unique_id != PentaxID_K_1) && + (unique_id != PentaxID_K_3) && + (unique_id != PentaxID_K_3_II) && + (unique_id != PentaxID_K_1_Mark_II)) + { + fseek (ifp, 0x0b, SEEK_CUR); + imPentax.AFPointsInFocus = (unsigned) fgetc(ifp); + if (!imPentax.AFPointsInFocus) imPentax.AFPointsInFocus = 0xffffffff; + else imPentax.AFPointsInFocus_version = 4; + } + } + else if ((tag == 0x0220) && (dng_writer == nonDNG)) { + meta_offset = ftell(ifp); + } + else if (tag == 0x0221) + { + int nWB = get2(); + if (nWB <= int(sizeof(icWBCCTC) / sizeof(icWBCCTC[0]))) + FORC(nWB) + { + icWBCCTC[c][0] = (unsigned)0xcfc6 - get2(); + fseek(ifp, 2, SEEK_CUR); + icWBCCTC[c][1] = get2(); + icWBCCTC[c][2] = icWBCCTC[c][4] = 0x2000; + icWBCCTC[c][3] = get2(); + } + } + else if (tag == 0x0215) + { + fseek(ifp, 16, SEEK_CUR); + sprintf(imgdata.shootinginfo.InternalBodySerial, "%d", get4()); + } + else if (tag == 0x0229) + { + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + } + else if (tag == 0x022d) + { + int wb_ind; + getc(ifp); + for (int wb_cnt = 0; wb_cnt < (int)Pentax_wb_list2.size(); wb_cnt++) + { + wb_ind = getc(ifp); + if (wb_ind >= 0 && wb_ind < (int)Pentax_wb_list2.size() ) + FORC4 icWBC[Pentax_wb_list2[wb_ind]][RGGB_2_RGBG(c)] = get2(); + } + } + else if (tag == 0x0239) // Q-series lens info (LensInfoQ) + { + char LensInfo[20]; + fseek(ifp, 12, SEEK_CUR); + stread(ilm.Lens, 30, ifp); + strcat(ilm.Lens, " "); + stread(LensInfo, 20, ifp); + strcat(ilm.Lens, LensInfo); + } + else if (tag == 0x0245) + { + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount++; + } + } +} + +void LibRaw::parseRicohMakernotes(int /*base*/, unsigned tag, unsigned type, + unsigned /*len*/, unsigned /*dng_writer */) +{ + char buffer[17]; + if (tag == 0x0005) + { + int c; + int count = 0; + fread(buffer, 16, 1, ifp); + buffer[16] = 0; + FORC(16) + { + if ((isspace(buffer[c])) || (buffer[c] == 0x2D) || (isalnum(buffer[c]))) + count++; + else + break; + } + if (count == 16) + { + if (strncmp(model, "GXR", 3)) + { + sprintf(imgdata.shootinginfo.BodySerial, "%8s", buffer + 8); + } + buffer[8] = 0; + sprintf(imgdata.shootinginfo.InternalBodySerial, "%8s", buffer); + } + else + { + sprintf(imgdata.shootinginfo.BodySerial, "%02x%02x%02x%02x", buffer[4], + buffer[5], buffer[6], buffer[7]); + sprintf(imgdata.shootinginfo.InternalBodySerial, "%02x%02x%02x%02x", + buffer[8], buffer[9], buffer[10], buffer[11]); + } + } + else if ((tag == 0x1001) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + ilm.LensID = LIBRAW_LENS_NOT_SET; + ilm.FocalType = LIBRAW_FT_PRIME_LENS; + imgdata.shootinginfo.ExposureProgram = get2(); + } + else if ((tag == 0x1002) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + imgdata.shootinginfo.DriveMode = get2(); + } + else if (tag == 0x1006) + { + imgdata.shootinginfo.FocusMode = get2(); + } + else if (tag == 0x1007) + { + imRicoh.AutoBracketing = get2(); + } + else if (tag == 0x1009) + { + imRicoh.MacroMode = get2(); + } + else if (tag == 0x100a) + { + imRicoh.FlashMode = get2(); + } + else if (tag == 0x100b) + { + imRicoh.FlashExposureComp = getreal(type); + } + else if (tag == 0x100c) + { + imRicoh.ManualFlashOutput = getreal(type); + } + else if ((tag == 0x100b) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL)) + { + imCommon.FlashEC = getreal(type); + } + else if ((tag == 0x1017) && ((imRicoh.WideAdapter = get2()) == 2)) + { + strcpy(ilm.Attachment, "Wide-Angle Adapter"); + } + else if (tag == 0x1018) + { + imRicoh.CropMode = get2(); + } + else if (tag == 0x1019) + { + imRicoh.NDFilter = get2(); + } + else if (tag == 0x1200) + { + imRicoh.AFStatus = get2(); + } + else if (tag == 0x1201) + { + imRicoh.AFAreaXPosition[1] = get4(); + } + else if (tag == 0x1202) + { + imRicoh.AFAreaYPosition[1] = get4(); + } + else if (tag == 0x1203) + { + imRicoh.AFAreaXPosition[0] = get4(); + } + else if (tag == 0x1204) + { + imRicoh.AFAreaYPosition[0] = get4(); + } + else if (tag == 0x1205) + { + imRicoh.AFAreaMode = get2(); + } + else if (tag == 0x1500) + { + ilm.CurFocal = getreal(type); + } + else if (tag == 0x1601) + { + imRicoh.SensorWidth = get4(); + } + else if (tag == 0x1602) + { + imRicoh.SensorHeight = get4(); + } + else if (tag == 0x1603) + { + imRicoh.CroppedImageWidth = get4(); + } + else if (tag == 0x1604) + { + imRicoh.CroppedImageHeight= get4(); + } + else if ((tag == 0x2001) && !strncmp(model, "GXR", 3)) + { + short cur_tag; + fseek(ifp, 20, SEEK_CUR); + /*ntags =*/ get2(); + cur_tag = get2(); + while (cur_tag != 0x002c) + { + fseek(ifp, 10, SEEK_CUR); + cur_tag = get2(); + } + fseek(ifp, 6, SEEK_CUR); + fseek(ifp, get4(), SEEK_SET); + for (int i=0; i<4; i++) { + stread(buffer, 16, ifp); + if ((buffer[0] == 'S') && (buffer[1] == 'I') && (buffer[2] == 'D')) + memcpy(imgdata.shootinginfo.BodySerial, buffer+4, 12); + else if ((buffer[0] == 'R') && (buffer[1] == 'L')) + ilm.LensID = buffer[2] - '0'; + else if ((buffer[0] == 'L') && (buffer[1] == 'I') && (buffer[2] == 'D')) + memcpy(imgdata.lens.LensSerial, buffer+4, 12); + } + } +} diff --git a/src/metadata/samsung.cpp b/src/metadata/samsung.cpp new file mode 100644 index 000000000..5c595e8ba --- /dev/null +++ b/src/metadata/samsung.cpp @@ -0,0 +1,182 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::parseSamsungMakernotes(int /*base*/, unsigned tag, unsigned type, + unsigned len, unsigned dng_writer) +{ + int i, c; + if (tag == 0x0002) + { + imSamsung.DeviceType = get4(); + if (imSamsung.DeviceType == 0x2000) + { + ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX; + ilm.CameraFormat = LIBRAW_FORMAT_APSC; + } + else if (!strncmp(model, "NX mini", 7)) + { // device type 0x1000: 'NX mini', EX2F, EX1, WB2000 + ilm.CameraMount = LIBRAW_MOUNT_Samsung_NX_M; + ilm.CameraFormat = LIBRAW_FORMAT_1INCH; + } + else + { + ilm.CameraMount = LIBRAW_MOUNT_FixedLens; + ilm.LensMount = LIBRAW_MOUNT_FixedLens; + } + } + else if (tag == 0x0003) + { + ilm.CamID = unique_id = get4(); + } + else if (tag == 0x0043) + { + if ((i = get4())) + { + imCommon.CameraTemperature = (float)i; + if (get4() == 10) + imCommon.CameraTemperature /= 10.0f; + } + } + else if ((tag == 0xa002) && (dng_writer != AdobeDNG)) + { + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + } + else if (tag == 0xa003) + { + ilm.LensID = get2(); + if (ilm.LensID) + ilm.LensMount = LIBRAW_MOUNT_Samsung_NX; + } + else if (tag == 0xa004) + { // LensFirmware + stmread(imSamsung.LensFirmware, len, ifp); + } + else if (tag == 0xa005) + { + stmread(imgdata.lens.InternalLensSerial, len, ifp); + } + else if (tag == 0xa010) + { + FORC4 imSamsung.ImageSizeFull[c] = get4(); + FORC4 imSamsung.ImageSizeCrop[c] = get4(); + } + else if ((tag == 0xa011) && ((len == 1) || (len == 2)) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + imSamsung.ColorSpace[0] = (int)get2(); + switch (imSamsung.ColorSpace[0]) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + if (len == 2) + imSamsung.ColorSpace[1] = (int)get2(); + } + else if (tag == 0xa019) + { + ilm.CurAp = getreal(type); + } + else if ((tag == 0xa01a) && (unique_id != 0x5000000) && + (!imgdata.lens.FocalLengthIn35mmFormat)) + { + ilm.FocalLengthIn35mmFormat = get4(); + if (ilm.FocalLengthIn35mmFormat >= 160) + ilm.FocalLengthIn35mmFormat /= 10.0f; + if ((ilm.CameraMount == LIBRAW_MOUNT_Samsung_NX_M) && + (imSamsung.LensFirmware[10] < '6')) + ilm.FocalLengthIn35mmFormat *= 1.6f; + } + else if (tag == 0xa020) + { + FORC(11) imSamsung.key[c] = get4(); + } + else if ((tag == 0xa021) && (dng_writer == nonDNG)) + { + FORC4 cam_mul[RGGB_2_RGBG(c)] = get4() - imSamsung.key[c]; + } + else if (tag == 0xa022) + { + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = + get4() - imSamsung.key[c + 4]; + if (icWBC[LIBRAW_WBI_Auto][0] < + (icWBC[LIBRAW_WBI_Auto][1] >> 1)) + { + icWBC[LIBRAW_WBI_Auto][1] = + icWBC[LIBRAW_WBI_Auto][1] >> 4; + icWBC[LIBRAW_WBI_Auto][3] = + icWBC[LIBRAW_WBI_Auto][3] >> 4; + } + } + else if (tag == 0xa023) + { + ushort ki[4] = {8, 9, 10, 0}; + FORC4 icWBC[LIBRAW_WBI_Ill_A][RGGB_2_RGBG(c)] = + get4() - imSamsung.key[ki[c]]; + if (icWBC[LIBRAW_WBI_Ill_A][0] < + (icWBC[LIBRAW_WBI_Ill_A][1] >> 1)) + { + icWBC[LIBRAW_WBI_Ill_A][1] = + icWBC[LIBRAW_WBI_Ill_A][1] >> 4; + icWBC[LIBRAW_WBI_Ill_A][3] = + icWBC[LIBRAW_WBI_Ill_A][3] >> 4; + } + } + else if (tag == 0xa024) + { + FORC4 icWBC[LIBRAW_WBI_D65][RGGB_2_RGBG(c)] = + get4() - imSamsung.key[c + 1]; + if (icWBC[LIBRAW_WBI_D65][0] < + (icWBC[LIBRAW_WBI_D65][1] >> 1)) + { + icWBC[LIBRAW_WBI_D65][1] = + icWBC[LIBRAW_WBI_D65][1] >> 4; + icWBC[LIBRAW_WBI_D65][3] = + icWBC[LIBRAW_WBI_D65][3] >> 4; + } + } + else if (tag == 0xa025) + { + unsigned t = get4() + imSamsung.key[0]; + if (t == 4096) + imSamsung.DigitalGain = 1.0; + else + imSamsung.DigitalGain = ((double)t) / 4096.0; + } + else if ((tag == 0xa028) && (dng_writer == nonDNG)) + { + FORC4 cblack[RGGB_2_RGBG(c)] = get4() - imSamsung.key[c]; + } + else if ((tag == 0xa030) && (len == 9)) + { + for (i = 0; i < 3; i++) + FORC3 imgdata.color.ccm[i][c] = + (float)((short)((get4() + imSamsung.key[i * 3 + c]))) / 256.0; + } + else if ((tag == 0xa032) && (len == 9) && (dng_writer == nonDNG)) + { + double aRGB_cam[3][3]; + FORC(9) + ((double *)aRGB_cam)[c] = + ((double)((short)((get4() + imSamsung.key[c])))) / 256.0; + aRGB_coeff(aRGB_cam); + } +} diff --git a/src/metadata/sony.cpp b/src/metadata/sony.cpp new file mode 100644 index 000000000..ea568b5ff --- /dev/null +++ b/src/metadata/sony.cpp @@ -0,0 +1,2316 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e, + uchar f) +{ + if ((a >> 4) > 9) + return 0; + else if ((a & 0x0f) > 9) + return 0; + else if ((b >> 4) > 9) + return 0; + else if ((b & 0x0f) > 9) + return 0; + else if ((c >> 4) > 9) + return 0; + else if ((c & 0x0f) > 9) + return 0; + else if ((d >> 4) > 9) + return 0; + else if ((d & 0x0f) > 9) + return 0; + else if ((e >> 4) > 9) + return 0; + else if ((e & 0x0f) > 9) + return 0; + else if ((f >> 4) > 9) + return 0; + else if ((f & 0x0f) > 9) + return 0; + return 1; +} +static float my_roundf(float x) +{ + float t; + if (x >= 0.0) + { + t = ceilf(x); + if (t - x > 0.5) + t -= 1.0; + return t; + } + else + { + t = ceilf(-x); + if (t + x > 0.5) + t -= 1.0; + return -t; + } +} + +static ushort bcd2dec(uchar data) +{ + if ((data >> 4) > 9) + return 0; + else if ((data & 0x0f) > 9) + return 0; + else + return (data >> 4) * 10 + (data & 0x0f); +} + +static uchar SonySubstitution[257] = + "\x00\x01\x32\xb1\x0a\x0e\x87\x28\x02\xcc\xca\xad\x1b\xdc\x08\xed\x64\x86" + "\xf0\x4f\x8c\x6c\xb8\xcb\x69\xc4\x2c\x03" + "\x97\xb6\x93\x7c\x14\xf3\xe2\x3e\x30\x8e\xd7\x60\x1c\xa1\xab\x37\xec\x75" + "\xbe\x23\x15\x6a\x59\x3f\xd0\xb9\x96\xb5" + "\x50\x27\x88\xe3\x81\x94\xe0\xc0\x04\x5c\xc6\xe8\x5f\x4b\x70\x38\x9f\x82" + "\x80\x51\x2b\xc5\x45\x49\x9b\x21\x52\x53" + "\x54\x85\x0b\x5d\x61\xda\x7b\x55\x26\x24\x07\x6e\x36\x5b\x47\xb7\xd9\x4a" + "\xa2\xdf\xbf\x12\x25\xbc\x1e\x7f\x56\xea" + "\x10\xe6\xcf\x67\x4d\x3c\x91\x83\xe1\x31\xb3\x6f\xf4\x05\x8a\x46\xc8\x18" + "\x76\x68\xbd\xac\x92\x2a\x13\xe9\x0f\xa3" + "\x7a\xdb\x3d\xd4\xe7\x3a\x1a\x57\xaf\x20\x42\xb2\x9e\xc3\x8b\xf2\xd5\xd3" + "\xa4\x7e\x1f\x98\x9c\xee\x74\xa5\xa6\xa7" + "\xd8\x5e\xb0\xb4\x34\xce\xa8\x79\x77\x5a\xc1\x89\xae\x9a\x11\x33\x9d\xf5" + "\x39\x19\x65\x78\x16\x71\xd2\xa9\x44\x63" + "\x40\x29\xba\xa0\x8f\xe4\xd6\x3b\x84\x0d\xc2\x4e\x58\xdd\x99\x22\x6b\xc9" + "\xbb\x17\x06\xe5\x7d\x66\x43\x62\xf6\xcd" + "\x35\x90\x2e\x41\x8d\x6d\xaa\x09\x73\x95\x0c\xf1\x1d\xde\x4c\x2f\x2d\xf7" + "\xd1\x72\xeb\xef\x48\xc7\xf8\xf9\xfa\xfb" + "\xfc\xfd\xfe\xff"; + +void LibRaw::sony_decrypt(unsigned *data, int len, int start, int key) +{ +#ifndef LIBRAW_NOTHREADS +#define pad tls->sony_decrypt.pad +#define p tls->sony_decrypt.p +#else + static unsigned pad[128], p; +#endif + if (start) + { + for (p = 0; p < 4; p++) + pad[p] = key = key * 48828125ULL + 1; + pad[3] = pad[3] << 1 | (pad[0] ^ pad[2]) >> 31; + for (p = 4; p < 127; p++) + pad[p] = (pad[p - 4] ^ pad[p - 2]) << 1 | (pad[p - 3] ^ pad[p - 1]) >> 31; + for (p = 0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len--) + { + *data++ ^= pad[p & 127] = pad[(p + 1) & 127] ^ pad[(p + 65) & 127]; + p++; + } +#ifndef LIBRAW_NOTHREADS +#undef pad +#undef p +#endif +} +void LibRaw::setSonyBodyFeatures(unsigned long long id) +{ + static const struct + { + ushort scf[11]; + /* + scf[0] camera id + scf[1] camera format + scf[2] camera mount: Minolta A, Sony E, fixed, + scf[3] camera type: DSLR, NEX, SLT, ILCE, ILCA, DSC + scf[4] lens mount, LIBRAW_MOUNT_FixedLens or LIBRAW_MOUNT_Unknown + scf[5] tag 0x2010 group (0 if not used) + scf[6] offset of Sony ISO in 0x2010 table, 0xffff if not valid + scf[7] offset of ShutterCount3 in 0x9050 table, 0xffff if not valid + scf[8] offset of MeteringMode in 0x2010 table, 0xffff if not valid + scf[9] offset of ExposureProgram in 0x2010 table, 0xffff if not valid + scf[10] offset of ReleaseMode2 in 0x2010 table, 0xffff if not valid + */ + } SonyCamFeatures[] = { + {SonyID_DSLR_A100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A900, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A700, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A200, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A350, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A300, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A900, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A380, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A330, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A230, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A290, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A850, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A850, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A550, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A500, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A450, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_NEX_5, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_NEX_3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_SLT_A33, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_SLT_A55, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A560, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_DSLR_A580, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_DSLR, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_NEX_C3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_SLT_A35, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_SLT_A65, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, + {SonyID_SLT_A77, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, + {SonyID_NEX_5N, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010a, 0x113e, 0x01bd, 0x1174, 0x1175, 0x112c}, + {SonyID_NEX_7, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, + {SonyID_NEX_VG20, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010b, 0x1218, 0x01bd, 0x1178, 0x1179, 0x112c}, + {SonyID_SLT_A37, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, + {SonyID_SLT_A57, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, + {SonyID_NEX_F3, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010c, 0x11f4, 0x01bd, 0x1154, 0x1155, 0x1108}, + {SonyID_SLT_A99, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_NEX_6, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_NEX_5R, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_DSC_RX100, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010e, 0x1254, 0xffff, 0x11ac, 0x11ad, 0x1160}, + {SonyID_DSC_RX1, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160}, + {SonyID_NEX_VG900, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_NEX_VG30, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_ILCE_3000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_SLT_A58, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_SLT, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_NEX_3N, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1280, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_ILCE_7, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_NEX_5T, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_NEX, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010e, 0x1254, 0x01aa, 0x11ac, 0x11ad, 0x1160}, + {SonyID_DSC_RX100M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010f, 0x113c, 0xffff, 0x1064, 0x1065, 0x1018}, + {SonyID_DSC_RX10, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX1R, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010e, 0x1258, 0xffff, 0x11ac, 0x11ad, 0x1160}, + {SonyID_ILCE_7R, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_6000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_5000, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0x01aa, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX100M3, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_7S, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCA_77M2, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_5100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_7M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX100M4, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX10M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX1RM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_QX1, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_7RM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_7SM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010h, 0x0346, 0x01cb, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCA_68, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010g, 0x0344, 0x01a0, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCA_99M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Minolta_A, LIBRAW_SONY_ILCA, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX10M3, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX100M5, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_6300, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_9, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_6500, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010h, 0x0346, 0x01cd, 0x025c, 0x025d, 0x0210}, + {SonyID_ILCE_7RM3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_7M3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_RX0, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010h, 0x0346, 0xffff, 0x025c, 0x025d, 0x0210}, + {SonyID_DSC_RX10M4, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_RX100M6, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_HX99, LIBRAW_FORMAT_1div2p3INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_RX100M5A, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_6400, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_RX0M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_RX100M7, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_7RM4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_9M2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_6600, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_6100, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ZV_1, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_7C, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + +// a la SonyID_ILCE_6100 + {SonyID_ZV_E10, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + + {SonyID_ILCE_7SM3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILCE_1, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILME_FX3, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILCE_7RM3A, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_7RM4A, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, + {SonyID_ILCE_7M4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + }; + ilm.CamID = id; + + if (id == SonyID_DSC_R1) + { + ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; + imSony.CameraType = LIBRAW_SONY_DSC; + imSony.group2010 = LIBRAW_SONY_Tag2010None; + imSony.group9050 = LIBRAW_SONY_Tag9050None; + return; + } + + for (unsigned i = 0; i < (sizeof SonyCamFeatures / sizeof *SonyCamFeatures); i++) { + if (SonyCamFeatures[i].scf[0] == id) { + ilm.CameraFormat = SonyCamFeatures[i].scf[1]; + ilm.CameraMount = SonyCamFeatures[i].scf[2]; + imSony.CameraType = SonyCamFeatures[i].scf[3]; + if (SonyCamFeatures[i].scf[4]) + ilm.LensMount = SonyCamFeatures[i].scf[4]; + imSony.group2010 = SonyCamFeatures[i].scf[5]; + imSony.real_iso_offset = SonyCamFeatures[i].scf[6]; + imSony.ImageCount3_offset = SonyCamFeatures[i].scf[7]; + imSony.MeteringMode_offset = SonyCamFeatures[i].scf[8]; + imSony.ExposureProgram_offset = SonyCamFeatures[i].scf[9]; + imSony.ReleaseMode2_offset = SonyCamFeatures[i].scf[10]; + break; + } + } + + switch (id) { + case SonyID_ILCE_6100: + case SonyID_ILCE_6300: + case SonyID_ILCE_6400: + case SonyID_ILCE_6500: + case SonyID_ILCE_6600: + case SonyID_ILCE_7C: + case SonyID_ILCE_7M3: + case SonyID_ILCE_7RM2: + case SonyID_ILCE_7RM3A: + case SonyID_ILCE_7RM3: + case SonyID_ILCE_7RM4: + case SonyID_ILCE_7RM4A: + case SonyID_ILCE_7SM2: + case SonyID_ILCE_9: + case SonyID_ILCE_9M2: + case SonyID_ILCA_99M2: + case SonyID_ZV_E10: + imSony.group9050 = LIBRAW_SONY_Tag9050b; + break; + case SonyID_ILCE_7SM3: + case SonyID_ILCE_1: + case SonyID_ILME_FX3: + case SonyID_ILCE_7M4: + imSony.group9050 = LIBRAW_SONY_Tag9050c; + break; + default: + if ((imSony.CameraType != LIBRAW_SONY_DSC) && + (imSony.CameraType != LIBRAW_SONY_DSLR)) + imSony.group9050 = LIBRAW_SONY_Tag9050a; + else + imSony.group9050 = LIBRAW_SONY_Tag9050None; + break; + } + + char *sbstr = strstr(software, " v"); + if (sbstr != NULL) + { + sbstr += 2; + strcpy(imCommon.firmware, sbstr); + imSony.firmware = atof(sbstr); + + if ((id == SonyID_ILCE_7) || + (id == SonyID_ILCE_7R)) + { + if (imSony.firmware < 1.2f) + imSony.ImageCount3_offset = 0x01aa; + else + imSony.ImageCount3_offset = 0x01c0; + } + else if (id == SonyID_ILCE_6000) + { + if (imSony.firmware < 2.0f) + imSony.ImageCount3_offset = 0x01aa; + else + imSony.ImageCount3_offset = 0x01c0; + } + else if ((id == SonyID_ILCE_7S) || + (id == SonyID_ILCE_7M2)) + { + if (imSony.firmware < 1.2f) + imSony.ImageCount3_offset = 0x01a0; + else + imSony.ImageCount3_offset = 0x01b6; + } + } + + if ((id == SonyID_ILCE_7SM3) && + !strcmp(model, "MODEL-NAME")) { + imSony.group9050 = LIBRAW_SONY_Tag9050a; + } + +} + +void LibRaw::parseSonyLensType2(uchar a, uchar b) +{ + ushort lid2; + lid2 = (((ushort)a) << 8) | ((ushort)b); + if (!lid2) + return; + if (lid2 < 0x100) + { + if ((ilm.AdapterID != 0x4900) && (ilm.AdapterID != 0xef00)) + { + ilm.AdapterID = lid2; + switch (lid2) + { + case 1: // Sony LA-EA1 or Sigma MC-11 Adapter + case 2: // Sony LA-EA2 + case 3: // Sony LA-EA3 + case 6: // Sony LA-EA4 + case 7: // Sony LA-EA5 + case 24593: // LA-EA4r MonsterAdapter, id = 0x6011 + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + break; + case 44: // Metabones Canon EF Smart Adapter + case 78: // Metabones Canon EF Smart Adapter Mark III or Other Adapter + case 184: // Metabones Canon EF Speed Booster Ultra + case 234: // Metabones Canon EF Smart Adapter Mark IV + case 239: // Metabones Canon EF Speed Booster + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + break; + } + } + } + else + ilm.LensID = lid2; + + if ((lid2 >= 50481) && + (lid2 < 50500)) { + strcpy(ilm.Adapter, "MC-11"); + ilm.AdapterID = 0x4900; + } else if ((lid2 > 0xef00) && + (lid2 < 0xffff) && + (lid2 != 0xff00)) { + ilm.AdapterID = 0xef00; + ilm.LensID -= ilm.AdapterID; + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + } + + return; +} + +void LibRaw::parseSonyLensFeatures(uchar a, uchar b) +{ + + ushort features; + features = (((ushort)a) << 8) | ((ushort)b); + + if ((ilm.LensMount == LIBRAW_MOUNT_Canon_EF) || + (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F) || !features) + return; + + ilm.LensFeatures_pre[0] = 0; + ilm.LensFeatures_suf[0] = 0; + if ((features & 0x0200) && (features & 0x0100)) + strcpy(ilm.LensFeatures_pre, "E"); + else if (features & 0x0200) + strcpy(ilm.LensFeatures_pre, "FE"); + else if (features & 0x0100) + strcpy(ilm.LensFeatures_pre, "DT"); + + if (!ilm.LensFormat && !ilm.LensMount) + { + ilm.LensFormat = LIBRAW_FORMAT_FF; + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + + if ((features & 0x0200) && (features & 0x0100)) + { + ilm.LensFormat = LIBRAW_FORMAT_APSC; + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + } + else if (features & 0x0200) + { + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + } + else if (features & 0x0100) + { + ilm.LensFormat = LIBRAW_FORMAT_APSC; + } + } + + if (features & 0x4000) + strnXcat(ilm.LensFeatures_pre, " PZ"); + + if (features & 0x0008) + strnXcat(ilm.LensFeatures_suf, " G"); + else if (features & 0x0004) + strnXcat(ilm.LensFeatures_suf, " ZA"); + + if ((features & 0x0020) && (features & 0x0040)) + strnXcat(ilm.LensFeatures_suf, " Macro"); + else if (features & 0x0020) + strnXcat(ilm.LensFeatures_suf, " STF"); + else if (features & 0x0040) + strnXcat(ilm.LensFeatures_suf, " Reflex"); + else if (features & 0x0080) + strnXcat(ilm.LensFeatures_suf, " Fisheye"); + + if (features & 0x0001) + strnXcat(ilm.LensFeatures_suf, " SSM"); + else if (features & 0x0002) + strnXcat(ilm.LensFeatures_suf, " SAM"); + + if (features & 0x8000) + strnXcat(ilm.LensFeatures_suf, " OSS"); + + if (features & 0x2000) + strnXcat(ilm.LensFeatures_suf, " LE"); + + if (features & 0x0800) + strnXcat(ilm.LensFeatures_suf, " II"); + + if (ilm.LensFeatures_suf[0] == ' ') + memmove(ilm.LensFeatures_suf, ilm.LensFeatures_suf + 1, + strbuflen(ilm.LensFeatures_suf) - 1); + + return; +} + +void LibRaw::process_Sony_0x0116(uchar *buf, ushort len, unsigned long long id) +{ + int i = 0; + + if (((id == SonyID_DSLR_A900) || + (id == SonyID_DSLR_A900_APSC) || + (id == SonyID_DSLR_A850) || + (id == SonyID_DSLR_A850_APSC)) && + (len >= 2)) + i = 1; + else if ((id >= SonyID_DSLR_A550) && (len >= 3)) + i = 2; + else + return; + + imCommon.BatteryTemperature = (float)(buf[i] - 32) / 1.8f; +} + +void LibRaw::process_Sony_0x2010(uchar *buf, ushort len) +{ + + if (imSony.group2010 == LIBRAW_SONY_Tag2010None) return; + + if ((imSony.real_iso_offset != 0xffff) && + (len >= (imSony.real_iso_offset + 2)) && (imCommon.real_ISO < 0.1f)) + { + uchar s[2]; + s[0] = SonySubstitution[buf[imSony.real_iso_offset]]; + s[1] = SonySubstitution[buf[imSony.real_iso_offset + 1]]; + imCommon.real_ISO = + 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); + } + + if ((imSony.MeteringMode_offset != 0xffff) && + (imSony.ExposureProgram_offset != 0xffff) && + (len >= (imSony.MeteringMode_offset + 2))) + { + imgdata.shootinginfo.MeteringMode = + SonySubstitution[buf[imSony.MeteringMode_offset]]; + imgdata.shootinginfo.ExposureProgram = + SonySubstitution[buf[imSony.ExposureProgram_offset]]; + } + + if ((imSony.ReleaseMode2_offset != 0xffff) && + (len >= (imSony.ReleaseMode2_offset + 2))) + { + imgdata.shootinginfo.DriveMode = + SonySubstitution[buf[imSony.ReleaseMode2_offset]]; + } +} + +void LibRaw::process_Sony_0x9050(uchar *buf, ushort len, unsigned long long id) +{ + ushort lid; + uchar s[4]; + int c; + + if ((imSony.group9050 == LIBRAW_SONY_Tag9050None) && + (imSony.CameraType != LIBRAW_SONY_DSC) && + (imSony.CameraType != LIBRAW_SONY_DSLR)) + imSony.group9050 = LIBRAW_SONY_Tag9050a; + + if (imSony.group9050 == LIBRAW_SONY_Tag9050None) return; + + if ((ilm.CameraMount != LIBRAW_MOUNT_Sony_E) && + (imSony.CameraType != LIBRAW_SONY_DSC)) + { + if (len < 2) + return; + if (buf[0]) + ilm.MaxAp4CurFocal = + my_roundf( + libraw_powf64l(2.0f, ((float)SonySubstitution[buf[0]] / 8.0 - 1.06f) / 2.0f) * + 10.0f) / 10.0f; + + if (buf[1]) + ilm.MinAp4CurFocal = + my_roundf( + libraw_powf64l(2.0f, ((float)SonySubstitution[buf[1]] / 8.0 - 1.06f) / 2.0f) * + 10.0f) / 10.0f; + } + + if ((imSony.group9050 == LIBRAW_SONY_Tag9050b) || + (imSony.group9050 == LIBRAW_SONY_Tag9050c)) { + if (len <= 0x8d) return; + unsigned long long b88 = SonySubstitution[buf[0x88]]; + unsigned long long b89 = SonySubstitution[buf[0x89]]; + unsigned long long b8a = SonySubstitution[buf[0x8a]]; + unsigned long long b8b = SonySubstitution[buf[0x8b]]; + unsigned long long b8c = SonySubstitution[buf[0x8c]]; + unsigned long long b8d = SonySubstitution[buf[0x8d]]; + sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx", + (b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) + b8d); + + } else if (imSony.group9050 == LIBRAW_SONY_Tag9050a) { + if ((ilm.CameraMount == LIBRAW_MOUNT_Sony_E) && + (id != SonyID_NEX_5N) && + (id != SonyID_NEX_7) && + (id != SonyID_NEX_VG20)) { + if (len <= 0x7f) return; + unsigned b7c = SonySubstitution[buf[0x7c]]; + unsigned b7d = SonySubstitution[buf[0x7d]]; + unsigned b7e = SonySubstitution[buf[0x7e]]; + unsigned b7f = SonySubstitution[buf[0x7f]]; + sprintf(imgdata.shootinginfo.InternalBodySerial, "%04x", + (b7c << 24) + (b7d << 16) + (b7e << 8) + b7f); + + } else if (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A) { + if (len <= 0xf4) return; + unsigned long long bf0 = SonySubstitution[buf[0xf0]]; + unsigned long long bf1 = SonySubstitution[buf[0xf1]]; + unsigned long long bf2 = SonySubstitution[buf[0xf2]]; + unsigned long long bf3 = SonySubstitution[buf[0xf3]]; + unsigned long long bf4 = SonySubstitution[buf[0xf4]]; + sprintf(imgdata.shootinginfo.InternalBodySerial, "%05llx", + (bf0 << 32) + (bf1 << 24) + (bf2 << 16) + (bf3 << 8) + bf4); + } + } + + if (imSony.CameraType != LIBRAW_SONY_DSC) + { + if (len <= 0x106) + return; + if (buf[0x3d] | buf[0x3c]) + { + lid = SonySubstitution[buf[0x3d]] << 8 | SonySubstitution[buf[0x3c]]; + ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 256.0f - 16.0f) / 2.0f); + } + if (buf[0x105] && + (ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && + (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) { + switch (SonySubstitution[buf[0x105]]) { + case 1: + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + break; + case 2: + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + break; + } + } + if (buf[0x106]) { + switch (SonySubstitution[buf[0x106]]) { + case 1: + ilm.LensFormat = LIBRAW_FORMAT_APSC; + break; + case 2: + ilm.LensFormat = LIBRAW_FORMAT_FF; + break; + } + } + } + + if (ilm.CameraMount == LIBRAW_MOUNT_Sony_E) + { + if (len <= 0x108) + return; + parseSonyLensType2( + SonySubstitution[buf[0x0108]], // LensType2 - Sony lens ids + SonySubstitution[buf[0x0107]]); + } + + if (len <= 0x10a) + return; + if ((ilm.LensID == LIBRAW_LENS_NOT_SET) && + (ilm.CameraMount == LIBRAW_MOUNT_Minolta_A) && + (buf[0x010a] | buf[0x0109])) + { + ilm.LensID = // LensType - Minolta/Sony lens ids + SonySubstitution[buf[0x010a]] << 8 | SonySubstitution[buf[0x0109]]; + + if ((ilm.LensID > 0x4900) && (ilm.LensID <= 0x5900)) + { + ilm.AdapterID = 0x4900; + ilm.LensID -= ilm.AdapterID; + ilm.LensMount = LIBRAW_MOUNT_Sigma_X3F; + strcpy(ilm.Adapter, "MC-11"); + } + + else if ((ilm.LensID > 0xef00) && (ilm.LensID < 0xffff) && + (ilm.LensID != 0xff00)) + { + ilm.AdapterID = 0xef00; + ilm.LensID -= ilm.AdapterID; + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + } + } + + if ((id >= SonyID_SLT_A65) && (id <= SonyID_NEX_F3)) + { + if (len <= 0x116) + return; + // "SLT-A65", "SLT-A77", "NEX-7", "NEX-VG20", + // "SLT-A37", "SLT-A57", "NEX-F3", "Lunar" + parseSonyLensFeatures(SonySubstitution[buf[0x115]], + SonySubstitution[buf[0x116]]); + } + else if (ilm.CameraMount != LIBRAW_MOUNT_FixedLens) + { + if (len <= 0x117) + return; + parseSonyLensFeatures(SonySubstitution[buf[0x116]], + SonySubstitution[buf[0x117]]); + } + + if ((imSony.ImageCount3_offset != 0xffff) && + (len >= (imSony.ImageCount3_offset + 4))) + { + FORC4 s[c] = SonySubstitution[buf[imSony.ImageCount3_offset + c]]; + imSony.ImageCount3 = sget4(s); + } + + return; +} + +void LibRaw::process_Sony_0x9400(uchar *buf, ushort len, unsigned long long /*id*/) +{ + + uchar s[4]; + int c; + uchar bufx = buf[0]; + + if (((bufx == 0x23) || + (bufx == 0x24) || + (bufx == 0x26) || + (bufx == 0x28) || + (bufx == 0x31)) && + (len >= 0x1f)) // 0x9400 'c' version + { + imSony.Sony0x9400_version = 0xc; + imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x09]]; + + if ((imSony.group2010 == LIBRAW_SONY_Tag2010g) || + (imSony.group2010 == LIBRAW_SONY_Tag2010h)) { + FORC4 s[c] = SonySubstitution[buf[0x0a + c]]; + imSony.ShotNumberSincePowerUp = sget4(s); + } else { + imSony.ShotNumberSincePowerUp = SonySubstitution[buf[0x0a]]; + } + + FORC4 s[c] = SonySubstitution[buf[0x12 + c]]; + imSony.Sony0x9400_SequenceImageNumber = sget4(s); + + imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x16]]; // shots + + FORC4 s[c] = SonySubstitution[buf[0x1a + c]]; + imSony.Sony0x9400_SequenceFileNumber = sget4(s); + + imSony.Sony0x9400_SequenceLength2 = SonySubstitution[buf[0x1e]]; // files + } + + else if ((bufx == 0x0c) && (len >= 0x1f)) // 0x9400 'b' version + { + imSony.Sony0x9400_version = 0xb; + + FORC4 s[c] = SonySubstitution[buf[0x08 + c]]; + imSony.Sony0x9400_SequenceImageNumber = sget4(s); + + FORC4 s[c] = SonySubstitution[buf[0x0c + c]]; + imSony.Sony0x9400_SequenceFileNumber = sget4(s); + + imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]]; + + imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x1e]]; + } + + else if ((bufx == 0x0a) && (len >= 0x23)) // 0x9400 'a' version + { + imSony.Sony0x9400_version = 0xa; + + FORC4 s[c] = SonySubstitution[buf[0x08 + c]]; + imSony.Sony0x9400_SequenceImageNumber = sget4(s); + + FORC4 s[c] = SonySubstitution[buf[0x0c + c]]; + imSony.Sony0x9400_SequenceFileNumber = sget4(s); + + imSony.Sony0x9400_ReleaseMode2 = SonySubstitution[buf[0x10]]; + + imSony.Sony0x9400_SequenceLength1 = SonySubstitution[buf[0x22]]; + } + + else + return; +} + +void LibRaw::process_Sony_0x9402(uchar *buf, ushort len) +{ + + if (len < 0x17) + return; + + if ((imSony.CameraType == LIBRAW_SONY_SLT) || + (imSony.CameraType == LIBRAW_SONY_ILCA) || + (buf[0x00] == 0x05) || + (buf[0x00] == 0xff)) + return; + + if (buf[0x02] == 0xff) + { + imCommon.AmbientTemperature = + (float)((short)SonySubstitution[buf[0x04]]); + } + + if (imgdata.shootinginfo.FocusMode == LIBRAW_SONY_FOCUSMODE_UNKNOWN) + { + imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x16]]&0x7f; + } + if (len >= 0x18) + imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x17]]; + + if ((len >= 0x2e) && + (imSony.CameraType != LIBRAW_SONY_DSC)) + { + imSony.FocusPosition = (ushort)SonySubstitution[buf[0x2d]]; // FocusPosition2 + } + return; +} + +void LibRaw::process_Sony_0x9403(uchar *buf, ushort len) +{ + if ((len < 6) || (unique_id == SonyID_ILCE_7C)) + return; + uchar bufx = SonySubstitution[buf[4]]; + if ((bufx == 0x00) || (bufx == 0x94)) + return; + + imCommon.SensorTemperature = (float)((short)SonySubstitution[buf[5]]); + + return; +} + +void LibRaw::process_Sony_0x9406(uchar *buf, ushort len) +{ + if (len < 6) + return; + uchar bufx = buf[0]; + if ((bufx != 0x01) && (bufx != 0x08) && (bufx != 0x1b)) + return; + bufx = buf[2]; + if ((bufx != 0x08) && (bufx != 0x1b)) + return; + + imCommon.BatteryTemperature = + (float)(SonySubstitution[buf[5]] - 32) / 1.8f; + + return; +} + +void LibRaw::process_Sony_0x940c(uchar *buf, ushort len) +{ + if ((imSony.CameraType != LIBRAW_SONY_ILCE) && + (imSony.CameraType != LIBRAW_SONY_NEX)) + return; + if (len <= 0x000a) + return; + ushort lid2; + if ((ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && + (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) + { + switch (SonySubstitution[buf[0x0008]]) + { + case 1: + case 5: + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + break; + case 4: + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + break; + } + } + if (ilm.LensMount != LIBRAW_MOUNT_Unknown) { + lid2 = (((ushort)SonySubstitution[buf[0x000a]]) << 8) | + ((ushort)SonySubstitution[buf[0x0009]]); + if ((lid2 > 0) && + ((lid2 < 32784) || (ilm.LensID == 0x1999) || (ilm.LensID == 0xffff))) + parseSonyLensType2( + SonySubstitution[buf[0x000a]], // LensType2 - Sony lens ids + SonySubstitution[buf[0x0009]]); + if ((lid2 == 44) || (lid2 == 78) || (lid2 == 184) || (lid2 == 234) || + (lid2 == 239)) + ilm.AdapterID = lid2; + } + return; +} + +void LibRaw::process_Sony_0x940e(uchar *buf, ushort len, unsigned long long id) +{ + if (len < 3) + return; + + if (((imSony.CameraType != LIBRAW_SONY_SLT) && + (imSony.CameraType != LIBRAW_SONY_ILCA)) || + (id == SonyID_SLT_A33) || + (id == SonyID_SLT_A35) || + (id == SonyID_SLT_A55)) + return; + + int c; + imSony.AFType = SonySubstitution[buf[0x02]]; + + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + unsigned tag = 0x940e; + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + FORC((int)imCommon.afdata[imCommon.afcount].AFInfoData_length) + imCommon.afdata[imCommon.afcount].AFInfoData[c] = SonySubstitution[buf[c]]; + imCommon.afcount++; + } + + if (imSony.CameraType == LIBRAW_SONY_ILCA) + { + if (len >= 0x0051) + { + imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x05]]; + imSony.nAFPointsUsed = + MIN(10, sizeof imSony.AFPointsUsed); + FORC(imSony.nAFPointsUsed) imSony.AFPointsUsed[c] = SonySubstitution[buf[0x10 +c]]; + imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x3a]]; + imSony.AFMicroAdjValue = SonySubstitution[buf[0x0050]]; + if (!imSony.AFMicroAdjValue) imSony.AFMicroAdjValue = 0x7f; + else imSony.AFMicroAdjOn = 1; + } + } + else + { + if (len >= 0x017e) + { + imSony.AFAreaMode = (uint16_t)SonySubstitution[buf[0x0a]]; + imgdata.shootinginfo.FocusMode = SonySubstitution[buf[0x0b]]; + imSony.nAFPointsUsed = + MIN(4, sizeof imSony.AFPointsUsed); + FORC(imSony.nAFPointsUsed) imSony.AFPointsUsed[c] = SonySubstitution[buf[0x016e +c]]; + imSony.AFMicroAdjValue = SonySubstitution[buf[0x017d]]; + if (!imSony.AFMicroAdjValue) imSony.AFMicroAdjValue = 0x7f; + else imSony.AFMicroAdjOn = 1; + } + } + +} + +void LibRaw::parseSonyMakernotes( + int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer, + uchar *&table_buf_0x0116, ushort &table_buf_0x0116_len, + uchar *&table_buf_0x2010, ushort &table_buf_0x2010_len, + uchar *&table_buf_0x9050, ushort &table_buf_0x9050_len, + uchar *&table_buf_0x9400, ushort &table_buf_0x9400_len, + uchar *&table_buf_0x9402, ushort &table_buf_0x9402_len, + uchar *&table_buf_0x9403, ushort &table_buf_0x9403_len, + uchar *&table_buf_0x9406, ushort &table_buf_0x9406_len, + uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len, + uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len) +{ + + ushort lid, a, c, d; + uchar *table_buf; + uchar uc; + uchar s[2]; + int LensDataValid = 0; + unsigned uitemp; + +// printf ("==>> tag 0x%x, len %d, type %d, model =%s=, cam.id 0x%llx, cam.type %d, =%s=\n", +// tag, len, type, model, ilm.CamID, imSony.CameraType, imSony.MetaVersion); + + if (tag == 0xb001) // Sony ModelID + { + unique_id = get2(); + setSonyBodyFeatures(unique_id); + + if (table_buf_0x0116_len) + { + process_Sony_0x0116(table_buf_0x0116, table_buf_0x0116_len, unique_id); + free(table_buf_0x0116); + table_buf_0x0116_len = 0; + } + + if (table_buf_0x2010_len) + { + process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len); + free(table_buf_0x2010); + table_buf_0x2010_len = 0; + } + + if (table_buf_0x9050_len) + { + process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, unique_id); + free(table_buf_0x9050); + table_buf_0x9050_len = 0; + } + + if (table_buf_0x9400_len) + { + process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id); + free(table_buf_0x9400); + table_buf_0x9400_len = 0; + } + + if (table_buf_0x9402_len) + { + process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len); + free(table_buf_0x9402); + table_buf_0x9402_len = 0; + } + + if (table_buf_0x9403_len) + { + process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len); + free(table_buf_0x9403); + table_buf_0x9403_len = 0; + } + + if (table_buf_0x9406_len) + { + process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len); + free(table_buf_0x9406); + table_buf_0x9406_len = 0; + } + + if (table_buf_0x940c_len) + { + process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len); + free(table_buf_0x940c); + table_buf_0x940c_len = 0; + } + + if (table_buf_0x940e_len) + { + process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, unique_id); + free(table_buf_0x940e); + table_buf_0x940e_len = 0; + } + } + else if (tag == 0xb000) + { + FORC4 imSony.FileFormat = imSony.FileFormat * 10 + fgetc(ifp); + } + else if (tag == 0xb026) + { + uitemp = get4(); + if (uitemp != 0xffffffff) + imgdata.shootinginfo.ImageStabilization = uitemp; + } + else if (((tag == 0x0001) || // Minolta CameraSettings, big endian + (tag == 0x0003)) && + (len >= 196)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + + lid = 0x01 << 2; + imgdata.shootinginfo.ExposureMode = + (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | + (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; + + lid = 0x06 << 2; + imgdata.shootinginfo.DriveMode = + (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | + (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; + + lid = 0x07 << 2; + imgdata.shootinginfo.MeteringMode = + (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | + (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; + + lid = 0x25 << 2; + imSony.MinoltaCamID = + (unsigned)table_buf[lid] << 24 | (unsigned)table_buf[lid + 1] << 16 | + (unsigned)table_buf[lid + 2] << 8 | (unsigned)table_buf[lid + 3]; + if (imSony.MinoltaCamID != 0xffffffff) + ilm.CamID = imSony.MinoltaCamID; + + lid = 0x30 << 2; + imgdata.shootinginfo.FocusMode = + table_buf[lid + 3]?LIBRAW_SONY_FOCUSMODE_MF:LIBRAW_SONY_FOCUSMODE_AF; + free(table_buf); + } + else if ((tag == 0x0004) && // Minolta CameraSettings7D, big endian + (len >= 227)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + + lid = 0x0; + imgdata.shootinginfo.ExposureMode = + (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; + + lid = 0x0e << 1; + imgdata.shootinginfo.FocusMode = (short)table_buf[lid + 1]; + switch (imgdata.shootinginfo.FocusMode) { + case 0: case 1: imgdata.shootinginfo.FocusMode += 2; break; + case 3: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; + } + lid = 0x10 << 1; + imgdata.shootinginfo.AFPoint = + (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; + + lid = 0x25 << 1; + switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { + case 0: + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 4: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + + lid = 0x71 << 1; + imgdata.shootinginfo.ImageStabilization = + (ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]; + + free(table_buf); + } + else if ((tag == 0x0010) && // CameraInfo + strncasecmp(model, "DSLR-A100", 9) && + !strncasecmp(make, "SONY", 4) && + ((len == 368) || // a700 : CameraInfo + (len == 5478) || // a850, a900 : CameraInfo + (len == 5506) || // a200, a300, a350 : CameraInfo2 + (len == 6118) || // a230, a290, a330, a380, a390 : CameraInfo2 + (len == 15360)) // a450, a500, a550, a560, a580 : CameraInfo3 + // a33, a35, a55 + // NEX-3, NEX-5, NEX-5C, NEX-C3, NEX-VG10E + + ) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + memcpy(imCommon.afdata[imCommon.afcount].AFInfoData, table_buf, imCommon.afdata[imCommon.afcount].AFInfoData_length); + imCommon.afcount++; + } + if (memcmp(table_buf, "\xff\xff\xff\xff\xff\xff\xff\xff", 8) && + memcmp(table_buf, "\x00\x00\x00\x00\x00\x00\x00\x00", 8)) + { + LensDataValid = 1; + } + switch (len) + { + case 368: // a700: CameraInfo + case 5478: // a850, a900: CameraInfo + if ((!dng_writer) || + (saneSonyCameraInfo(table_buf[0], table_buf[3], table_buf[2], + table_buf[5], table_buf[4], table_buf[7]))) + { + if (LensDataValid) + { + if (table_buf[0] | table_buf[3]) + ilm.MinFocal = bcd2dec(table_buf[0]) * 100 + bcd2dec(table_buf[3]); + if (table_buf[2] | table_buf[5]) + ilm.MaxFocal = bcd2dec(table_buf[2]) * 100 + bcd2dec(table_buf[5]); + if (table_buf[4]) + ilm.MaxAp4MinFocal = bcd2dec(table_buf[4]) / 10.0f; + if (table_buf[4]) + ilm.MaxAp4MaxFocal = bcd2dec(table_buf[7]) / 10.0f; + parseSonyLensFeatures(table_buf[1], table_buf[6]); + } + + imSony.AFPointSelected = table_buf[21]; + imgdata.shootinginfo.AFPoint = (ushort)table_buf[25]; + + if (len == 5478) + { + imSony.AFMicroAdjValue = table_buf[0x130] - 20; + imSony.AFMicroAdjOn = (((table_buf[0x131] & 0x80) == 0x80) ? 1 : 0); + imSony.AFMicroAdjRegisteredLenses = table_buf[0x131] & 0x7f; + } + } + break; + default: + // CameraInfo2 & 3 + if ((!dng_writer) || + (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], + table_buf[4], table_buf[5], table_buf[6]))) + { + if ((LensDataValid) && strncasecmp(model, "NEX-5C", 6)) + { + if (table_buf[1] | table_buf[2]) + ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]); + if (table_buf[3] | table_buf[4]) + ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]); + if (table_buf[5]) + ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f; + if (table_buf[6]) + ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f; + parseSonyLensFeatures(table_buf[0], table_buf[7]); + } + + if ( // CameraInfo2 + (len == 5506) || // a200, a300, a350 + (len == 6118)) // a230, a290, a330, a380, a390 + { + imSony.AFPointSelected = table_buf[0x14]; + } + else if (!strncasecmp(model, "DSLR-A450", 9) || + !strncasecmp(model, "DSLR-A500", 9) || + !strncasecmp(model, "DSLR-A550", 9)) + { + imSony.AFPointSelected = table_buf[0x14]; + if (table_buf[0x15]) /* focus mode values translated to values in tag 0x201b */ + imgdata.shootinginfo.FocusMode = table_buf[0x15]+1; + else imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; + imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x18]; + } + else if (!strncasecmp(model, "SLT-", 4) || + !strncasecmp(model, "DSLR-A560", 9) || + !strncasecmp(model, "DSLR-A580", 9)) + { + imSony.AFPointSelected = table_buf[0x1c]; + if (table_buf[0x1d]) + imgdata.shootinginfo.FocusMode = table_buf[0x1d]+1; + else imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; + imgdata.shootinginfo.AFPoint = (ushort)table_buf[0x20]; + } + } + } + free(table_buf); + } + else if ((!dng_writer) && + ((tag == 0x0020) || (tag == 0xb0280020))) + { + if (!strncasecmp(model, "DSLR-A100", 9)) // WBInfoA100 + { + fseek(ifp, 0x49dc, SEEK_CUR); + stmread(imgdata.shootinginfo.InternalBodySerial, 13, ifp); + } + else if ((len == 19154) || // a200 a230 a290 a300 a330 a350 a380 a390 : FocusInfo + (len == 19148)) // a700 a850 a900 : FocusInfo + { + table_buf = (uchar *)malloc(0x0080); + fread(table_buf, 0x0080, 1, ifp); + imgdata.shootinginfo.DriveMode = table_buf[14]; + imgdata.shootinginfo.ExposureProgram = table_buf[63]; + free(table_buf); + fseek (ifp, 0x09bb - 0x0080, SEEK_CUR); // offset 2491 from the start of tag 0x0020 + imSony.FocusPosition = (ushort)fgetc(ifp); + } + else if (len == 20480) // a450 a500 a550 a560 a580 a33 a35 a55 : MoreInfo + // NEX-3 NEX-5 NEX-C3 NEX-VG10E : MoreInfo + { + a = get2(); + /*b =*/ get2(); + c = get2(); + d = get2(); + if ((a) && (c == 1)) + { + fseek(ifp, INT64(d) - 8LL, SEEK_CUR); + table_buf = (uchar *)malloc(256); + fread(table_buf, 256, 1, ifp); + imgdata.shootinginfo.DriveMode = table_buf[1]; + imgdata.shootinginfo.ExposureProgram = table_buf[2]; + imgdata.shootinginfo.MeteringMode = table_buf[3]; + switch (table_buf[6]) { + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + if (strncasecmp(model, "DSLR-A450", 9) && + strncasecmp(model, "DSLR-A500", 9) && + strncasecmp(model, "DSLR-A550", 9)) + { // NEX-3, NEX-5, NEX-5C??, NEX-C3, NEX-VG10(E), a560, a580, a33, a35, a55 + imgdata.shootinginfo.FocusMode = table_buf[0x13]; + switch (table_buf[0x13]) { + case 17: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_S; break; + case 18: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_C; break; + case 19: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_A; break; + case 32: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; + case 48: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_DMF; break; + default: imgdata.shootinginfo.FocusMode = table_buf[0x13]; break; + } + if (!strncasecmp(model, "DSLR-A560", 9) || + !strncasecmp(model, "DSLR-A580", 9) || + !strncasecmp(model, "SLT-A33", 7) || + !strncasecmp(model, "SLT-A35", 7) || + !strncasecmp(model, "SLT-A55", 7) || + !strncasecmp(model, "NEX-VG10", 8) || + !strncasecmp(model, "NEX-C3", 6)) + imSony.FocusPosition = (ushort)table_buf[0x2f]; // FocusPosition2 + else // NEX-3, NEX-5, NEX-5C + imSony.FocusPosition = (ushort)table_buf[0x2b]; // FocusPosition2 + } + else // a450 a500 a550 + { + imSony.FocusPosition = (ushort)table_buf[0x29]; // FocusPosition2 + } + free(table_buf); + } + } + } + else if (tag == 0x0102) + { + imSony.Quality = get4(); + } + else if (tag == 0x0104) + { + imCommon.FlashEC = getreal(type); + } + else if (tag == 0x0105) // Teleconverter + { + ilm.TeleconverterID = get4(); + } + else if (tag == 0x0107) + { + uitemp = get4(); + if (uitemp == 1) + imgdata.shootinginfo.ImageStabilization = 0; + else if (uitemp == 5) + imgdata.shootinginfo.ImageStabilization = 1; + else + imgdata.shootinginfo.ImageStabilization = uitemp; + } + else if ((tag == 0xb0280088) && (dng_writer == nonDNG)) + { + thumb_offset = get4() + base; + } + else if ((tag == 0xb0280089) && (dng_writer == nonDNG)) + { + thumb_length = get4(); + } + else if (((tag == 0x0114) || // CameraSettings + (tag == 0xb0280114)) && + (len < 256000)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + switch (len) + { + case 260: // Sony a100, big endian + imgdata.shootinginfo.ExposureMode = + ((ushort)table_buf[0]) << 8 | ((ushort)table_buf[1]); + lid = 0x0a << 1; + imgdata.shootinginfo.DriveMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + lid = 0x0c << 1; + imgdata.shootinginfo.FocusMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + switch (imgdata.shootinginfo.FocusMode) { + case 0: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_S; break; + case 1: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_AF_C; break; + case 5: imgdata.shootinginfo.FocusMode = LIBRAW_SONY_FOCUSMODE_MF; break; + } + lid = 0x0d << 1; + imSony.AFPointSelected = table_buf[lid + 1]; + lid = 0x0e << 1; + imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; + lid = 0x12 << 1; + imgdata.shootinginfo.MeteringMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + + lid = 0x17 << 1; + switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_MonochromeGamma; + break; + case 5: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + + break; + case 448: // Minolta "DYNAX 5D" and its aliases, big endian + lid = 0x0a << 1; + imgdata.shootinginfo.ExposureMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + lid = 0x25 << 1; + imgdata.shootinginfo.MeteringMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + + lid = 0x2f << 1; + switch ((ushort)table_buf[lid] << 8 | (ushort)table_buf[lid + 1]) { + case 0: + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_MonochromeGamma; + break; + case 4: + case 5: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + + lid = 0xbd << 1; + imgdata.shootinginfo.ImageStabilization = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + break; + case 280: // a200 a300 a350 a700 + case 364: // a850 a900 + // CameraSettings and CameraSettings2 are big endian + if (table_buf[2] | table_buf[3]) + { + lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]); + ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f); + } + lid = 0x04 << 1; + imgdata.shootinginfo.DriveMode = table_buf[lid + 1]; + lid = 0x11 << 1; + imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; + lid = 0x1b << 1; + switch (((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1])) { + case 0: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 1: + case 5: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + lid = 0x4d << 1; + imgdata.shootinginfo.FocusMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + switch (imgdata.shootinginfo.FocusMode) { + case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; + case 4: imgdata.shootinginfo.FocusMode +=2; break; + } + if (!imCommon.ColorSpace || + (imCommon.ColorSpace == LIBRAW_COLORSPACE_Unknown)) { + lid = 0x83 << 1; + switch (((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1])) { + case 6: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 5: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + } + break; + case 332: // a230 a290 a330 a380 a390 + // CameraSettings and CameraSettings2 are big endian + if (table_buf[2] | table_buf[3]) + { + lid = (((ushort)table_buf[2]) << 8) | ((ushort)table_buf[3]); + ilm.CurAp = libraw_powf64l(2.0f, ((float)lid / 8.0f - 1.0f) / 2.0f); + } + lid = 0x10 << 1; + imSony.AFAreaMode = (uint16_t)table_buf[lid + 1]; + lid = 0x4d << 1; + imgdata.shootinginfo.FocusMode = + ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + switch (imgdata.shootinginfo.FocusMode) { + case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; + case 4: imgdata.shootinginfo.FocusMode +=2; break; + } + lid = 0x7e << 1; + imgdata.shootinginfo.DriveMode = table_buf[lid + 1]; + break; + case 1536: // a560 a580 a33 a35 a55 NEX-3 NEX-5 NEX-5C NEX-C3 NEX-VG10E + case 2048: // a450 a500 a550 + // CameraSettings3 are little endian + switch (table_buf[0x0e]) { + case 1: + imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; + break; + case 2: + imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; + break; + default: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; + break; + } + imSony.AFAreaMode = (uint16_t)table_buf[0x24]; + imgdata.shootinginfo.DriveMode = table_buf[0x34]; + parseSonyLensType2(table_buf[1016], table_buf[1015]); + if (ilm.LensMount != LIBRAW_MOUNT_Canon_EF) + { + switch (table_buf[153]) + { + case 16: + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + break; + case 17: + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + break; + } + } + break; + } + free(table_buf); + } + else if ((tag == 0x3000) && (len < 256000)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + if (len >= 0x19) + { + for (int i = 0; i < 20; i++) + imSony.SonyDateTime[i] = table_buf[6 + i]; + } + if (len >= 0x43) // MetaVersion: (unique_id >= 286) + { + memcpy (imSony.MetaVersion, table_buf+0x34, 15); + imSony.MetaVersion[15] = 0; + } + free(table_buf); + } + else if (tag == 0x0116 && len < 256000) + { + table_buf_0x0116 = (uchar *)malloc(len); + table_buf_0x0116_len = len; + fread(table_buf_0x0116, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x0116(table_buf_0x0116, table_buf_0x0116_len, ilm.CamID); + free(table_buf_0x0116); + table_buf_0x0116_len = 0; + } + } + else if (tag == 0x2008) + { + imSony.LongExposureNoiseReduction = get4(); + } + else if (tag == 0x2009) + { + imSony.HighISONoiseReduction = get2(); + } + else if (tag == 0x200a) + { + imSony.HDR[0] = get2(); + imSony.HDR[1] = get2(); + } + else if (tag == 0x2010 && len < 256000) + { + table_buf_0x2010 = (uchar *)malloc(len); + table_buf_0x2010_len = len; + fread(table_buf_0x2010, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x2010(table_buf_0x2010, table_buf_0x2010_len); + free(table_buf_0x2010); + table_buf_0x2010_len = 0; + } + } + else if (tag == 0x201a) + { + imSony.ElectronicFrontCurtainShutter = get4(); + } + else if (tag == 0x201b) + { + if ((imSony.CameraType != LIBRAW_SONY_DSC) || + (imSony.group2010 == LIBRAW_SONY_Tag2010i)) + { + short t = (short)fgetc(ifp); + if (imgdata.shootinginfo.FocusMode != t) + { + imgdata.shootinginfo.FocusMode = t; + } + } + } + else if ((tag == 0x201c) && + (len == 1) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE)) + { + imSony.AFAreaModeSetting = (uint8_t)fgetc(ifp); + } + else if ((tag == 0x201d) && + (len == 2) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + imSony.FlexibleSpotPosition[0] = get2(); + imSony.FlexibleSpotPosition[1] = get2(); + } + else if (tag == 0x201e) + { + if (imSony.CameraType != LIBRAW_SONY_DSC) + { + imSony.AFPointSelected = imSony.AFPointSelected_0x201e = fgetc(ifp); + } + } + else if (tag == 0x2020) // AFPointsUsed + { + if (imSony.CameraType != LIBRAW_SONY_DSC) + { + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imSony.nAFPointsUsed = + short(MIN(imCommon.afdata[imCommon.afcount].AFInfoData_length, sizeof imSony.AFPointsUsed)); + memcpy(imSony.AFPointsUsed, imCommon.afdata[imCommon.afcount].AFInfoData, imSony.nAFPointsUsed); + imCommon.afcount++; + } + } + } + else if (tag == 0x2021) // AFTracking + { + if ((imSony.CameraType != LIBRAW_SONY_DSC) || + (imSony.group2010 == LIBRAW_SONY_Tag2010i)) + { + imSony.AFTracking = fgetc(ifp); + } + } + else if (tag == 0x2022) // FocalPlaneAFPointsUsed + { + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount++; + } + } + else if (tag == 0x2027) + { + FORC4 imSony.FocusLocation[c] = get2(); + } + else if (tag == 0x2028) + { + if (get2()) + { + imSony.VariableLowPassFilter = get2(); + } + } + else if (tag == 0x2029) + { + imSony.RAWFileType = get2(); + } + else if (tag == 0x202c) + { + imSony.MeteringMode2 = get2(); + } + + else if (tag == 0x202a) // FocalPlaneAFPointsUsed, newer?? + { + if (imCommon.afcount < LIBRAW_AFDATA_MAXCOUNT) + { + imCommon.afdata[imCommon.afcount].AFInfoData_tag = tag; + imCommon.afdata[imCommon.afcount].AFInfoData_order = order; + imCommon.afdata[imCommon.afcount].AFInfoData_length = len; + imCommon.afdata[imCommon.afcount].AFInfoData = (uchar *)malloc(imCommon.afdata[imCommon.afcount].AFInfoData_length); + fread(imCommon.afdata[imCommon.afcount].AFInfoData, imCommon.afdata[imCommon.afcount].AFInfoData_length, 1, ifp); + imCommon.afcount++; + } + } + else if (tag == 0x202e) + { + imSony.RawSizeType = get2(); + } + else if (tag == 0x202f) + { + imSony.PixelShiftGroupID = get4(); + imSony.PixelShiftGroupPrefix = imSony.PixelShiftGroupID >> 22; + imSony.PixelShiftGroupID = + ((imSony.PixelShiftGroupID >> 17) & (unsigned)0x1f) * + (unsigned)1000000 + + ((imSony.PixelShiftGroupID >> 12) & (unsigned)0x1f) * (unsigned)10000 + + ((imSony.PixelShiftGroupID >> 6) & (unsigned)0x3f) * (unsigned)100 + + (imSony.PixelShiftGroupID & (unsigned)0x3f); + + imSony.numInPixelShiftGroup = fgetc(ifp); + imSony.nShotsInPixelShiftGroup = fgetc(ifp); + } + else if (tag == 0x9050 && len < 256000) // little endian + { + table_buf_0x9050 = (uchar *)malloc(len); + table_buf_0x9050_len = len; + fread(table_buf_0x9050, len, 1, ifp); + + if (ilm.CamID) + { + process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, ilm.CamID); + free(table_buf_0x9050); + table_buf_0x9050_len = 0; + } + } + else if (tag == 0x9400 && len < 256000) + { + table_buf_0x9400 = (uchar *)malloc(len); + table_buf_0x9400_len = len; + fread(table_buf_0x9400, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x9400(table_buf_0x9400, table_buf_0x9400_len, unique_id); + free(table_buf_0x9400); + table_buf_0x9400_len = 0; + } + } + else if (tag == 0x9402 && len < 256000) + { + table_buf_0x9402 = (uchar *)malloc(len); + table_buf_0x9402_len = len; + fread(table_buf_0x9402, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x9402(table_buf_0x9402, table_buf_0x9402_len); + free(table_buf_0x9402); + table_buf_0x9402_len = 0; + } + } + else if (tag == 0x9403 && len < 256000) + { + table_buf_0x9403 = (uchar *)malloc(len); + table_buf_0x9403_len = len; + fread(table_buf_0x9403, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x9403(table_buf_0x9403, table_buf_0x9403_len); + free(table_buf_0x9403); + table_buf_0x9403_len = 0; + } + } + else if ((tag == 0x9405) && (len < 256000) && (len > 0x64)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + uc = table_buf[0x0]; + if (imCommon.real_ISO < 0.1f) + { + if ((uc == 0x25) || (uc == 0x3a) || (uc == 0x76) || (uc == 0x7e) || + (uc == 0x8b) || (uc == 0x9a) || (uc == 0xb3) || (uc == 0xe1)) + { + s[0] = SonySubstitution[table_buf[0x04]]; + s[1] = SonySubstitution[table_buf[0x05]]; + imCommon.real_ISO = + 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); + } + } + free(table_buf); + } + else if ((tag == 0x9404) && (len < 256000) && (len > 0x21)) + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + uc = table_buf[0x00]; + if (((uc == 0x70) || + (uc == 0x8a) || + (uc == 0xcd) || + (uc == 0xe7) || + (uc == 0xea)) && + (table_buf[0x03] == 0x08)) + { + if ((imSony.CameraType == LIBRAW_SONY_ILCA) || + (imSony.CameraType == LIBRAW_SONY_SLT)) + { + imSony.FocusPosition = (ushort)SonySubstitution[table_buf[0x20]]; // FocusPosition2 + } + } + free(table_buf); + } + else if (tag == 0x9406 && len < 256000) + { + table_buf_0x9406 = (uchar *)malloc(len); + table_buf_0x9406_len = len; + fread(table_buf_0x9406, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x9406(table_buf_0x9406, table_buf_0x9406_len); + free(table_buf_0x9406); + table_buf_0x9406_len = 0; + } + } + else if (tag == 0x940c && len < 256000) + { + table_buf_0x940c = (uchar *)malloc(len); + table_buf_0x940c_len = len; + fread(table_buf_0x940c, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x940c(table_buf_0x940c, table_buf_0x940c_len); + free(table_buf_0x940c); + table_buf_0x940c_len = 0; + } + } + else if (tag == 0x940e && len < 256000) + { + table_buf_0x940e = (uchar *)malloc(len); + table_buf_0x940e_len = len; + fread(table_buf_0x940e, len, 1, ifp); + if (ilm.CamID) + { + process_Sony_0x940e(table_buf_0x940e, table_buf_0x940e_len, ilm.CamID); + free(table_buf_0x940e); + table_buf_0x940e_len = 0; + } + } + else if ((tag == 0x9416) && (len < 256000) && (len > 0x0076)) { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + if (imCommon.real_ISO < 0.1f) { + s[0] = SonySubstitution[table_buf[0x04]]; + s[1] = SonySubstitution[table_buf[0x05]]; + imCommon.real_ISO = + 100.0f * libraw_powf64l(2.0f, (16 - ((float)sget2(s)) / 256.0f)); + } + imgdata.shootinginfo.ExposureProgram = SonySubstitution[table_buf[0x35]]; + if ((ilm.LensMount != LIBRAW_MOUNT_Canon_EF) && + (ilm.LensMount != LIBRAW_MOUNT_Sigma_X3F)) { + switch (SonySubstitution[table_buf[0x0048]]) { + case 1: + case 3: + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + break; + case 2: + ilm.LensMount = LIBRAW_MOUNT_Sony_E; + break; + } + } + switch (SonySubstitution[table_buf[0x0049]]) { + case 1: + ilm.LensFormat = LIBRAW_FORMAT_APSC; + break; + case 2: + ilm.LensFormat = LIBRAW_FORMAT_FF; + break; + } + if (ilm.LensMount == LIBRAW_MOUNT_Sony_E) + parseSonyLensType2(SonySubstitution[table_buf[0x4c]], SonySubstitution[table_buf[0x4b]]); + free(table_buf); + } + else if (((tag == 0xb027) || + (tag == 0x010c)) && + (ilm.LensID == LIBRAW_LENS_NOT_SET)) + { + ilm.LensID = get4(); + if ((ilm.LensID > 0x4900) && (ilm.LensID <= 0x5900)) + { + ilm.AdapterID = 0x4900; + ilm.LensID -= ilm.AdapterID; + ilm.LensMount = LIBRAW_MOUNT_Sigma_X3F; + strcpy(ilm.Adapter, "MC-11"); + } + + else if ((ilm.LensID > 0xef00) && + (ilm.LensID < 0xffff) && + (ilm.LensID != 0xff00)) + { + ilm.AdapterID = 0xef00; + ilm.LensID -= ilm.AdapterID; + ilm.LensMount = LIBRAW_MOUNT_Canon_EF; + } + + else if (((ilm.LensID != LIBRAW_LENS_NOT_SET) && (ilm.LensID < 0xef00)) || + (ilm.LensID == 0xff00)) + ilm.LensMount = LIBRAW_MOUNT_Minolta_A; + /* + if (tag == 0x010c) + ilm.CameraMount = LIBRAW_MOUNT_Minolta_A; + */ + } + else if (tag == 0xb02a && len < 256000) // Sony LensSpec + { + table_buf = (uchar *)malloc(len); + fread(table_buf, len, 1, ifp); + if ((!dng_writer) || + (saneSonyCameraInfo(table_buf[1], table_buf[2], table_buf[3], + table_buf[4], table_buf[5], table_buf[6]))) + { + if (table_buf[1] | table_buf[2]) + ilm.MinFocal = bcd2dec(table_buf[1]) * 100 + bcd2dec(table_buf[2]); + if (table_buf[3] | table_buf[4]) + ilm.MaxFocal = bcd2dec(table_buf[3]) * 100 + bcd2dec(table_buf[4]); + if (table_buf[5]) + ilm.MaxAp4MinFocal = bcd2dec(table_buf[5]) / 10.0f; + if (table_buf[6]) + ilm.MaxAp4MaxFocal = bcd2dec(table_buf[6]) / 10.0f; + parseSonyLensFeatures(table_buf[0], table_buf[7]); + } + free(table_buf); + } + else if ((tag == 0xb02b) && !imgdata.sizes.raw_inset_crops[0].cwidth && + (len == 2)) + { + imgdata.sizes.raw_inset_crops[0].cheight = get4(); + imgdata.sizes.raw_inset_crops[0].cwidth = get4(); + } + else if (tag == 0xb041) + { + imgdata.shootinginfo.ExposureMode = get2(); + } + else if ((tag == 0xb043) && + (len == 1) && + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + { + imSony.AFAreaMode = get2(); + } +} + +class checked_buffer_t +{ +public: + // create with internal storage + checked_buffer_t(short ord, int size) : _order(ord), storage(size+64) { + _data = storage.data(); + _len = size; + } + checked_buffer_t(short ord, unsigned char *dd, int ss): _order(ord), _data(dd),_len(ss){} + + ushort sget2(int offset) + { + checkoffset(offset + 2); + return libraw_sget2_static(_order, _data + offset); + } + void checkoffset(int off) + { + if (off >= _len) throw LIBRAW_EXCEPTION_IO_EOF; + } + unsigned char operator [] (int idx) + { + checkoffset(idx); + return _data[idx]; + } + unsigned sget4(int offset) + { + checkoffset(offset+4); + return libraw_sget4_static(_order, _data + offset); + } + double sgetreal(int type, int offset) + { + int sz = libraw_tagtype_dataunit_bytes(type); + checkoffset(offset + sz); + return libraw_sgetreal_static(_order, type, _data + offset); + } + + unsigned char *data() { return _data; } + + int tiff_sget(unsigned save, INT64 *tag_offset, + unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, + unsigned *tag_datalen, int *tag_dataunitlen) + { + if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun + return -1; + } + int pos = *tag_offset; + *tag_id = sget2(pos); pos += 2; + *tag_type = sget2(pos); pos += 2; + *tag_datalen = sget4(pos); pos += 4; + *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type); + if ((*tag_datalen * (*tag_dataunitlen)) > 4) { + *tag_dataoffset = sget4(pos) - save; + if ((*tag_dataoffset + *tag_datalen) > _len) { // abnormal, tag data buffer overrun + return -2; + } + } + else *tag_dataoffset = *tag_offset + 8; + *tag_offset += 12; + return 0; + } + +private: + short _order; + unsigned char *_data; + int _len; + std::vector storage; +}; + +void LibRaw::parseSonySR2(uchar *_cbuf_SR2, unsigned SR2SubIFDOffset, + unsigned SR2SubIFDLength, unsigned dng_writer) +{ + unsigned c; + unsigned entries, tag_id, tag_type, tag_datalen; + INT64 tag_offset, tag_dataoffset; + int TagProcessed; + int tag_dataunitlen; + float num; + int i; + int WBCTC_count; + try + { + checked_buffer_t cbuf_SR2(order, _cbuf_SR2, SR2SubIFDLength); + entries = cbuf_SR2.sget2(0); + if (entries > 1000) + return; + tag_offset = 2; + WBCTC_count = 0; + while (entries--) { + if (cbuf_SR2.tiff_sget(SR2SubIFDOffset, + &tag_offset, &tag_id, &tag_type, &tag_dataoffset, + &tag_datalen, &tag_dataunitlen) == 0) { + TagProcessed = 0; + if (dng_writer == nonDNG) { + switch (tag_id) { + case 0x7300: + FORC4 cblack[c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + TagProcessed = 1; + break; + case 0x7303: + FORC4 cam_mul[GRBG_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + TagProcessed = 1; + break; + case 0x7310: + FORC4 cblack[RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + i = cblack[3]; + FORC3 if (i > (int)cblack[c]) i = cblack[c]; + FORC4 cblack[c] -= i; + black = i; + TagProcessed = 1; + break; + case 0x7313: + FORC4 cam_mul[RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + TagProcessed = 1; + break; + case 0x74a0: + ilm.MaxAp4MaxFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); + TagProcessed = 1; + break; + case 0x74a1: + ilm.MaxAp4MinFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); + TagProcessed = 1; + break; + case 0x74a2: + ilm.MaxFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); + TagProcessed = 1; + break; + case 0x74a3: + ilm.MinFocal = cbuf_SR2.sgetreal(tag_type, tag_dataoffset); + TagProcessed = 1; + break; + case 0x7800: + for (i = 0; i < 3; i++) + { + num = 0.0; + for (c = 0; c < 3; c++) + { + imgdata.color.ccm[i][c] = + (float)((short)cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * (i * 3 + c))); + num += imgdata.color.ccm[i][c]; + } + if (num > 0.01) + FORC3 imgdata.color.ccm[i][c] = imgdata.color.ccm[i][c] / num; + } + TagProcessed = 1; + break; + case 0x787f: + if (tag_datalen == 3) + { + FORC3 imgdata.color.linear_max[c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; + } + else if (tag_datalen == 1) + { + imgdata.color.linear_max[0] = imgdata.color.linear_max[1] = + imgdata.color.linear_max[2] = imgdata.color.linear_max[3] = + cbuf_SR2.sget2(tag_dataoffset); + } + TagProcessed = 1; + break; + } + } + + if (!TagProcessed) { + if ((tag_id >= 0x7480) && (tag_id <= 0x7486)) { + i = tag_id - 0x7480; + if (Sony_SR2_wb_list[i] > 255) { + icWBCCTC[WBCTC_count][0] = Sony_SR2_wb_list[i]; + FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + icWBCCTC[WBCTC_count][4] = icWBCCTC[WBCTC_count][2]; + WBCTC_count++; + } + else { + FORC3 icWBC[Sony_SR2_wb_list[i]][c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + icWBC[Sony_SR2_wb_list[i]][3] = icWBC[Sony_SR2_wb_list[i]][1]; + } + } + else if ((tag_id >= 0x7820) && (tag_id <= 0x782d)) { + i = tag_id - 0x7820; + if (Sony_SR2_wb_list1[i] > 255) { + icWBCCTC[WBCTC_count][0] = Sony_SR2_wb_list1[i]; + FORC3 icWBCCTC[WBCTC_count][c + 1] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + icWBCCTC[WBCTC_count][4] = icWBCCTC[WBCTC_count][2]; + if (Sony_SR2_wb_list1[i] == 3200) { + FORC3 icWBC[LIBRAW_WBI_StudioTungsten][c] = icWBCCTC[WBCTC_count][c + 1]; + icWBC[LIBRAW_WBI_StudioTungsten][3] = icWBC[LIBRAW_WBI_StudioTungsten][1]; + } + WBCTC_count++; + } + else { + FORC3 icWBC[Sony_SR2_wb_list1[i]][c] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + icWBC[Sony_SR2_wb_list1[i]][3] = icWBC[Sony_SR2_wb_list1[i]][1]; + } + } + else if (tag_id == 0x7302) { + FORC4 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + } + else if (tag_id == 0x7312) { + FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = cbuf_SR2.sget2(tag_dataoffset + tag_dataunitlen * c); + } + } + } + } + } + catch (...) + { + return; + } +} + +void LibRaw::parseSonySRF(unsigned len) +{ + + if ((len > 0xfffff) || (len == 0)) + return; + + INT64 save = ftell(ifp); + INT64 offset = 0x0310c0 - save; /* for non-DNG this value normally is 0x8ddc */ + if (len < offset || offset < 0) + return; + try { + + INT64 decrypt_len = offset >> 2; /* master key offset value is the next + un-encrypted metadata field after SRF0 */ + + unsigned i, nWB; + unsigned MasterKey, SRF2Key=0; + INT64 srf_offset, tag_offset, tag_dataoffset; + int tag_dataunitlen; + //uchar *srf_buf; + ushort entries; + unsigned tag_id, tag_type, tag_datalen; + + //srf_buf = (uchar *)malloc(len+64); + checked_buffer_t srf_buf(order, len); + fread(srf_buf.data(), len, 1, ifp); + + offset += srf_buf[offset] << 2; + + /* master key is stored in big endian */ + MasterKey = ((unsigned)srf_buf[offset] << 24) | + ((unsigned)srf_buf[offset + 1] << 16) | + ((unsigned)srf_buf[offset + 2] << 8) | + (unsigned)srf_buf[offset + 3]; + + /* skip SRF0 */ + srf_offset = 0; + entries = srf_buf.sget2(srf_offset); + if (entries > 1000) + goto restore_after_parseSonySRF; + offset = srf_offset + 2; + srf_offset = srf_buf.sget4(offset + 12 * entries) - save; /* SRF0 ends with SRF1 abs. position */ + + /* get SRF1, it has fixed 40 bytes length and contains keys to decode metadata + * and raw data */ + if (srf_offset < 0 || decrypt_len < srf_offset / 4) + goto restore_after_parseSonySRF; + sony_decrypt((unsigned *)(srf_buf.data() + srf_offset), decrypt_len - srf_offset / 4, + 1, MasterKey); + entries = srf_buf.sget2(srf_offset); + if (entries > 1000) + goto restore_after_parseSonySRF; + offset = srf_offset + 2; + tag_offset = offset; + + while (entries--) { + if (tiff_sget(save, srf_buf.data(), len, + &tag_offset, &tag_id, &tag_type, &tag_dataoffset, + &tag_datalen, &tag_dataunitlen) == 0) { + if (tag_id == 0x0000) { + SRF2Key = srf_buf.sget4(tag_dataoffset); + } + else if (tag_id == 0x0001) { + /*RawDataKey =*/ srf_buf.sget4(tag_dataoffset); + } + } + else goto restore_after_parseSonySRF; + } + offset = tag_offset; + + /* get SRF2 */ + srf_offset = srf_buf.sget4(offset) - save; /* SRFn ends with SRFn+1 position */ + if (srf_offset < 0 || decrypt_len < srf_offset / 4) + goto restore_after_parseSonySRF; + sony_decrypt((unsigned *)(srf_buf.data() + srf_offset), decrypt_len - srf_offset / 4, + 1, SRF2Key); + + entries = srf_buf.sget2(srf_offset); + if (entries > 1000) + goto restore_after_parseSonySRF; + offset = srf_offset + 2; + tag_offset = offset; + + while (entries--) { + if (srf_buf.tiff_sget(save, + &tag_offset, &tag_id, &tag_type, &tag_dataoffset, + &tag_datalen, &tag_dataunitlen) == 0) { + if ((tag_id >= 0x00c0) && (tag_id <= 0x00ce)) { + i = (tag_id - 0x00c0) % 3; + nWB = (tag_id - 0x00c0) / 3; + icWBC[Sony_SRF_wb_list[nWB]][i] = srf_buf.sget4(tag_dataoffset); + if (i == 1) { + icWBC[Sony_SRF_wb_list[nWB]][3] = + icWBC[Sony_SRF_wb_list[nWB]][i]; + } + } + else if ((tag_id >= 0x00d0) && (tag_id <= 0x00d2)) { + i = (tag_id - 0x00d0) % 3; + cam_mul[i] = srf_buf.sget4(tag_dataoffset); + if (i == 1) { + cam_mul[3] = cam_mul[i]; + } + } + else switch (tag_id) { + /* + 0x0002 SRF6Offset + 0x0003 SRFDataOffset (?) + 0x0004 RawDataOffset + 0x0005 RawDataLength + */ + case 0x0043: + ilm.MaxAp4MaxFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); + break; + case 0x0044: + ilm.MaxAp4MinFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); + break; + case 0x0045: + ilm.MinFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); + break; + case 0x0046: + ilm.MaxFocal = srf_buf.sgetreal(tag_type, tag_dataoffset); + break; + } + } + else goto restore_after_parseSonySRF; + } + offset = tag_offset; + + restore_after_parseSonySRF:; + } + catch (...) // srf_buf can raise IO_EOF exception, catch it and return usual way + { + fseek(ifp, save, SEEK_SET); + return; + } + fseek(ifp, save, SEEK_SET); +} diff --git a/src/metadata/tiff.cpp b/src/metadata/tiff.cpp new file mode 100644 index 000000000..c34b86470 --- /dev/null +++ b/src/metadata/tiff.cpp @@ -0,0 +1,2188 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_cameraids.h" + +int LibRaw::parse_tiff_ifd(int base) +{ + unsigned entries, tag, type, len, plen = 16, save, utmp; + int ifd, use_cm = 0, cfa, i, j, c, ima_len = 0; + char *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = {0, 1, 2, 3}, tab[256]; + double fm[3][4], 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; + + ushort *rafdata; + + 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; + + if (libraw_internal_data.unpacker_data.ifd0_offset == -1LL) + libraw_internal_data.unpacker_data.ifd0_offset = base; + + entries = get2(); + if (entries > 512) + return 1; + + INT64 fsize = ifp->size(); + + while (entries--) + { + tiff_get(base, &tag, &type, &len, &save); + INT64 savepos = ftell(ifp); + if (len > 8 && savepos + len > 2 * fsize) + { + fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! + continue; + } + if (callbacks.exif_cb) + { + callbacks.exif_cb(callbacks.exifparser_data, + tag | (is_pana_raw ? 0x30000 : ((ifd + 1) << 20)), type, + len, order, ifp, base); + fseek(ifp, savepos, SEEK_SET); + } + + if (!is_pana_raw) + { /* processing of EXIF tags that collide w/ PanasonicRaw tags */ + switch (tag) + { + case 0x0001: + if (len == 4) + is_pana_raw = get4(); + break; + case 0x000b: /* 11, Std. EXIF Software tag */ + fgets(software, 64, ifp); + if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) || + !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) || + !strcmp(software, "Digital Photo Professional")) + is_raw = 0; + break; + case 0x001c: /* 28, safeguard, probably not needed */ + case 0x001d: /* 29, safeguard, probably not needed */ + case 0x001e: /* 30, safeguard, probably not needed */ + cblack[tag - 0x001c] = get2(); + cblack[3] = cblack[1]; + break; + + case 0x0111: /* 273, StripOffset */ + if (len > 1 && len < 16384) + { + off_t sav = ftell(ifp); + tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int)); + tiff_ifd[ifd].strip_offsets_count = len; + for (int ii = 0; ii < (int)len; ii++) + tiff_ifd[ifd].strip_offsets[ii] = get4() + base; + fseek(ifp, sav, SEEK_SET); // restore position + } + /* fallback */ + case 0x0201: /* 513, JpegIFOffset */ + case 0xf007: // 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)) + { + if (!dng_version && !strcasecmp(make, "SONY") && tiff_ifd[ifd].phint == 32803 && + tiff_ifd[ifd].comp == 7) // Sony/lossless compressed IFD + { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = 1; + } + else + { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].t_width = jh.wide; + tiff_ifd[ifd].t_height = jh.high; + tiff_ifd[ifd].samples = jh.clrs; + if (!(jh.sraw || (jh.clrs & 1))) + tiff_ifd[ifd].t_width *= jh.clrs; + if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs) + { + tiff_ifd[ifd].t_width /= 2; + tiff_ifd[ifd].t_height *= 2; + } + i = order; + parse_tiff(tiff_ifd[ifd].offset + 12); + order = i; + } + } + } + break; + } + } + else + { /* processing Panasonic-specific "PanasonicRaw" tags */ + switch (tag) + { + case 0x0004: /* 4, SensorTopBorder */ + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + break; + case 0x000a: /* 10, BitsPerSample */ + pana_bpp = get2(); + pana_bpp = LIM(pana_bpp, 8, 16); + break; + case 0x000b: /* 11, Compression */ + imPana.Compression = get2(); + break; + case 0x000e: /* 14, LinearityLimitRed */ + case 0x000f: /* 15, LinearityLimitGreen */ + case 0x0010: /* 16, LinearityLimitBlue */ + imgdata.color.linear_max[tag - 14] = get2(); + if (imgdata.color.linear_max[tag - 14] == 16383) + imgdata.color.linear_max[tag - 14] -= 64; + if (imgdata.color.linear_max[tag - 14] == 4095) + imgdata.color.linear_max[tag - 14] -= 16; + if (tag == 0x000f) // 15, LinearityLimitGreen + imgdata.color.linear_max[3] = imgdata.color.linear_max[1]; + break; + case 0x0013: /* 19, WBInfo */ + if ((i = get2()) > 0x100) + break; + for (c = 0; c < i; c++) + { + if ((j = get2()) < 0x100) + { + icWBC[j][0] = get2(); + icWBC[j][2] = get2(); + icWBC[j][1] = icWBC[j][3] = + 0x100; + } + else // light source out of EXIF numbers range + get4(); + } + break; + case 0x0018: /* 24, HighISOMultiplierRed */ + case 0x0019: /* 25, HighISOMultiplierGreen */ + case 0x001a: /* 26, HighISOMultiplierBlue */ + imPana.HighISOMultiplier[tag - 0x0018] = get2(); + break; + case 0x001c: /* 28, BlackLevelRed */ + case 0x001d: /* 29, BlackLevelGreen */ + case 0x001e: /* 30, BlackLevelBlue */ + pana_black[tag - 0x001c] = get2(); + break; + case 0x002d: /* 45, RawFormat */ + /* pana_encoding: tag 0x002d (45dec) + not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 + 2 - RAW DMC-FZ8/FZ18 + 3 - RAW DMC-L10 + 4 - RW2 for most other models, including G9 in "pixel shift off" + mode and YUNEEC CGO4 (must add 15 to black levels for + RawFormat == 4) 5 - RW2 DC-GH5s; G9 in "pixel shift on" + mode 6 - RW2 DC-S1, DC-S1R in "pixel shift off" + mode 7 - RW2 DC-S1R (probably DC-S1 too) in + "pixel shift on" mode + */ + pana_encoding = get2(); + break; + case 0x002f: /* 47, CropTop */ + imgdata.sizes.raw_inset_crops[0].ctop = get2(); + break; + case 0x0030: /* 48, CropLeft */ + imgdata.sizes.raw_inset_crops[0].cleft = get2(); + break; + case 0x0031: /* 49, CropBottom */ + imgdata.sizes.raw_inset_crops[0].cheight = + get2() - imgdata.sizes.raw_inset_crops[0].ctop; + break; + case 0x0032: /* 50, CropRight */ + imgdata.sizes.raw_inset_crops[0].cwidth = + get2() - imgdata.sizes.raw_inset_crops[0].cleft; + break; + case 0x0037: /* 55, ISO if ISO in 0x8827 & ISO in 0x0017 == 65535 */ + if (iso_speed == 65535) + iso_speed = get4(); + break; + case 0x011c: /* 284, Gamma */ + { + int n = get2(); + if (n >= 1024) + imPana.gamma = (float)n / 1024.0f; + else if (n >= 256) + imPana.gamma = (float)n / 256.0f; + else + imPana.gamma = (float)n / 100.0f; + } + break; + case 0x0120: /* 288, CameraIFD, contains tags 0x1xxx, 0x2xxx, 0x3xxx */ + { + unsigned sorder = order; + unsigned long sbase = base; + base = ftell(ifp); + order = get2(); + fseek(ifp, 2, SEEK_CUR); + fseek(ifp, INT64(get4()) - 8LL, SEEK_CUR); + parse_tiff_ifd(base); + base = sbase; + order = sorder; + } + break; + case 0x0121: /* 289, Multishot, 0 is Off, 65536 is Pixel Shift */ + imPana.Multishot = get4(); + break; + case 0x1001: + if (imPana.Multishot == 0) { + imPana.Multishot = get4(); + if (imPana.Multishot) + imPana.Multishot += 65535; + } + break; + case 0x1100: + imPana.FocusStepNear = get2(); + break; + case 0x1101: + imPana.FocusStepCount = get2(); + break; + case 0x1105: + imPana.ZoomPosition = get4(); + break; + case 0x1201: + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) { + imPana.LensManufacturer = fgetc(ifp); + } else if (type == 258) { + imPana.LensManufacturer = get4(); + if (imPana.LensManufacturer >= 257) { + ilm.LensMount = LIBRAW_MOUNT_LPS_L; + ilm.LensFormat = LIBRAW_FORMAT_FF; + } + } + break; + case 0x1202: + if (ilm.LensMount == LIBRAW_MOUNT_LPS_L) { + if ((utmp = get2())) ilm.LensID = utmp; + } else if ((imPana.LensManufacturer != 0xff) && + (imPana.LensManufacturer != 0xffffffff)) { + if ((utmp = (fgetc(ifp) << 8) | fgetc(ifp))) + ilm.LensID = (imPana.LensManufacturer << 16) + utmp; + } + break; + case 0x1203: /* 4611, FocalLengthIn35mmFormat, contained in 0x0120 + CameraIFD */ + if (imgdata.lens.FocalLengthIn35mmFormat < 0.65f) + imgdata.lens.FocalLengthIn35mmFormat = get2(); + break; + case 0x2009: /* 8201, contained in 0x0120 CameraIFD */ + if ((pana_encoding == 4) || (pana_encoding == 5)) + { + i = MIN(8, len); + int permut[8] = {3, 2, 1, 0, 3 + 4, 2 + 4, 1 + 4, 0 + 4}; + imPana.BlackLevelDim = len; + for (j = 0; j < i; j++) + { + imPana.BlackLevel[permut[j]] = + (float)(get2()) / (float)(powf(2.f, 14.f - pana_bpp)); + } + } + break; + case 0x3420: /* 13344, WB_RedLevelAuto, contained in 0x0120 CameraIFD */ + icWBC[LIBRAW_WBI_Auto][0] = get2(); + icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = 1024.0f; + break; + case 0x3421: /* 13345, WB_BlueLevelAuto, contained in 0x0120 CameraIFD */ + icWBC[LIBRAW_WBI_Auto][2] = get2(); + break; + case 0x0002: /* 2, ImageWidth */ + tiff_ifd[ifd].t_width = getint(type); + break; + case 0x0003: /* 3, ImageHeight */ + tiff_ifd[ifd].t_height = getint(type); + break; + case 0x0005: /* 5, SensorLeftBorder */ + width = get2(); + imgdata.sizes.raw_inset_crops[0].cleft = width; + break; + case 0x0006: /* 6, SensorBottomBorder */ + height = get2(); + imgdata.sizes.raw_inset_crops[0].cheight = + height - imgdata.sizes.raw_inset_crops[0].ctop; + break; + case 0x0007: /* 7, SensorRightBorder */ + i = get2(); + width += i; + imgdata.sizes.raw_inset_crops[0].cwidth = + i - imgdata.sizes.raw_inset_crops[0].cleft; + break; + case 0x0009: /* 9, CFAPattern */ + if ((i = get2())) + filters = i; + break; + case 0x0011: /* 17, RedBalance */ + case 0x0012: /* 18, BlueBalance */ + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && len == 1) + cam_mul[(tag - 0x0011) * 2] = get2() / 256.0; + break; + case 0x0017: /* 23, ISO */ + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT)) + iso_speed = get2(); + break; + case 0x0024: /* 36, WBRedLevel */ + case 0x0025: /* 37, WBGreenLevel */ + case 0x0026: /* 38, WBBlueLevel */ + cam_mul[tag - 0x0024] = get2(); + break; + case 0x0027: /* 39, WBInfo2 */ + if ((i = get2()) > 0x100) + break; + for (c = 0; c < i; c++) + { + if ((j = get2()) < 0x100) + { + icWBC[j][0] = get2(); + icWBC[j][1] = icWBC[j][3] = get2(); + icWBC[j][2] = get2(); + if (c == 1 && i > 6 && cam_mul[0] <= 0.001f) + for (int q = 0; q < 4; q++) + cam_mul[q] = icWBC[j][q]; + } + else + fseek(ifp, 6, SEEK_CUR); + } + break; + case 0x002e: /* 46, JpgFromRaw */ + if ((type != LIBRAW_EXIFTAG_TYPE_UNDEFINED) || (fgetc(ifp) != 0xff) || (fgetc(ifp) != 0xd8)) + break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + + case 0x0118: /* 280, Panasonic RW2 offset */ + if (type != LIBRAW_EXIFTAG_TYPE_LONG) + break; + load_raw = &LibRaw::panasonic_load_raw; + load_flags = 0x2008; + case 0x0111: /* 273, StripOffset */ + if (len > 1 && len < 16384) + { + off_t sav = ftell(ifp); + tiff_ifd[ifd].strip_offsets = (int *)calloc(len, sizeof(int)); + tiff_ifd[ifd].strip_offsets_count = len; + for (int ii = 0; ii < (int)len; ii++) + tiff_ifd[ifd].strip_offsets[ii] = get4() + base; + fseek(ifp, sav, SEEK_SET); // restore position + } + /* fallthrough */ + 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].t_width = jh.wide; + tiff_ifd[ifd].t_height = jh.high; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = jh.clrs; + if (!(jh.sraw || (jh.clrs & 1))) + tiff_ifd[ifd].t_width *= jh.clrs; + if ((tiff_ifd[ifd].t_width > 4 * tiff_ifd[ifd].t_height) & ~jh.clrs) + { + tiff_ifd[ifd].t_width /= 2; + tiff_ifd[ifd].t_height *= 2; + } + i = order; + parse_tiff(tiff_ifd[ifd].offset + 12); + order = i; + } + } + break; + } + + } /* processing of Panasonic-specific tags finished */ + + switch (tag) + { /* processing of general EXIF tags */ + case 0xf000: /* 61440, Fuji HS10 table */ + fseek(ifp, get4() + base, SEEK_SET); + parse_tiff_ifd(base); + break; + case 0x00fe: /* NewSubfileType */ + tiff_ifd[ifd].newsubfiletype = getreal(type); + break; + case 0x0100: /* 256, ImageWidth */ + case 0xf001: /* 61441, Fuji RAF RawImageFullWidth */ + tiff_ifd[ifd].t_width = getint(type); + break; + case 0x0101: /* 257, ImageHeight */ + case 0xf002: /* 61442, Fuji RAF RawImageFullHeight */ + tiff_ifd[ifd].t_height = getint(type); + break; + case 0x0102: /* 258, BitsPerSample */ + case 0xf003: /* 61443, Fuji RAF 0xf003 */ + if(!tiff_ifd[ifd].samples || tag != 0x0102) // ??? already set by tag 0x115 + tiff_ifd[ifd].samples = len & 7; + tiff_ifd[ifd].bps = getint(type); + if (tiff_bps < (unsigned)tiff_ifd[ifd].bps) + tiff_bps = tiff_ifd[ifd].bps; + break; + case 0xf006: /* 61446, Fuji RAF 0xf006 */ + raw_height = 0; + if (tiff_ifd[ifd].bps > 12) + break; + load_raw = &LibRaw::packed_load_raw; + load_flags = get4() ? 24 : 80; + break; + case 0x0103: /* 259, Compression */ + /* + 262 = Kodak 262 + 32767 = Sony ARW Compressed + 32769 = Packed RAW + 32770 = Samsung SRW Compressed + 32772 = Samsung SRW Compressed 2 + 32867 = Kodak KDC Compressed + 34713 = Nikon NEF Compressed + 65000 = Kodak DCR Compressed + 65535 = Pentax PEF Compressed + */ + tiff_ifd[ifd].comp = getint(type); + break; + case 0x0106: /* 262, PhotometricInterpretation */ + tiff_ifd[ifd].phint = get2(); + break; + case 0x010e: /* 270, ImageDescription */ + fread(desc, 512, 1, ifp); + break; + case 0x010f: /* 271, Make */ + fgets(make, 64, ifp); + break; + case 0x0110: /* 272, Model */ + if (!strncmp(make, "Hasselblad", 10) && model[0] && + (imHassy.format != LIBRAW_HF_Imacon)) + break; + fgets(model, 64, ifp); + break; + case 0x0116: // 278 + tiff_ifd[ifd].rows_per_strip = getint(type); + break; + case 0x0112: /* 274, Orientation */ + tiff_ifd[ifd].t_flip = "50132467"[get2() & 7] - '0'; + break; + case 0x0115: /* 277, SamplesPerPixel */ + tiff_ifd[ifd].samples = getint(type) & 7; + break; + case 0x0152: /* Extrasamples */ + tiff_ifd[ifd].extrasamples = (getint(type) & 0xff) + 1024; + break; + case 0x0117: /* 279, StripByteCounts */ + if (len > 1 && len < 16384) + { + off_t sav = ftell(ifp); + tiff_ifd[ifd].strip_byte_counts = (int *)calloc(len, sizeof(int)); + tiff_ifd[ifd].strip_byte_counts_count = len; + for (int ii = 0; ii < (int)len; ii++) + tiff_ifd[ifd].strip_byte_counts[ii] = get4(); + fseek(ifp, sav, SEEK_SET); // restore position + } + /* fallback */ + case 0x0202: // 514 + case 0xf008: // 61448 + tiff_ifd[ifd].bytes = get4(); + break; + case 0xf00e: // 61454, FujiFilm "As Shot" + FORC3 cam_mul[GRBG_2_RGBG(c)] = getint(type); + break; + case 0x0131: /* 305, Software */ + fgets(software, 64, ifp); + if (!strncmp(software, "Adobe", 5) || !strncmp(software, "dcraw", 5) || + !strncmp(software, "UFRaw", 5) || !strncmp(software, "Bibble", 6) || + !strcmp(software, "Digital Photo Professional")) + is_raw = 0; + break; + case 0x0132: /* 306, DateTime */ + get_timestamp(0); + break; + case 0x013b: /* 315, Artist */ + fread(artist, 64, 1, ifp); + break; + case 0x013d: // 317 + tiff_ifd[ifd].predictor = getint(type); + break; + case 0x0142: /* 322, TileWidth */ + tiff_ifd[ifd].t_tile_width = getint(type); + break; + case 0x0143: /* 323, TileLength */ + tiff_ifd[ifd].t_tile_length = getint(type); + break; + case 0x0144: /* 324, TileOffsets */ + tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); + if (len == 1) + tiff_ifd[ifd].t_tile_width = tiff_ifd[ifd].t_tile_length = 0; + if (len == 4) + { + load_raw = &LibRaw::sinar_4shot_load_raw; + is_raw = 5; + } + break; + case 0x0145: // 325 + tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4(); + break; + case 0x014a: /* 330, SubIFDs */ + if (!strcmp(model, "DSLR-A100") && tiff_ifd[ifd].t_width == 3872) + { + load_raw = &LibRaw::sony_arw_load_raw; + data_offset = get4() + base; + ifd++; + if (ifd >= int(sizeof tiff_ifd / sizeof tiff_ifd[0])) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + break; + } + if (!strncmp(make, "Hasselblad", 10) && + libraw_internal_data.unpacker_data.hasselblad_parser_flag) + { + fseek(ifp, ftell(ifp) + 4, SEEK_SET); + fseek(ifp, get4() + base, SEEK_SET); + parse_tiff_ifd(base); + break; + } + if (len > 1000) + len = 1000; /* 1000 SubIFDs is enough */ + 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 0x0153: // 339 + tiff_ifd[ifd].sample_format = getint(type); + break; + case 0x0190: // 400 + strcpy(make, "Sarnoff"); + maximum = 0xfff; + break; + case 0x02bc: // 700 + if ((tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) || + tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII) || + tagtypeIs(LIBRAW_EXIFTAG_TYPE_SBYTE) || + tagtypeIs(LIBRAW_EXIFTOOLTAGTYPE_binary)) && + (len > 1) && (len < 5100000)) + { + xmpdata = (char *)malloc(xmplen = len + 1); + fread(xmpdata, len, 1, ifp); + xmpdata[len] = 0; + } + break; + case 0x7000: + imSony.SonyRawFileType = get2(); + break; + case 0x7010: // 28688 + FORC4 sony_curve[c + 1] = get2() >> 2 & 0xfff; + for (i = 0; i < 5; i++) + for (j = sony_curve[i] + 1; j <= (int)sony_curve[i + 1]; j++) + curve[j] = curve[j - 1] + (1 << i); + break; + case 0x7200: // 29184, Sony SR2Private + sony_offset = get4(); + break; + case 0x7201: // 29185, Sony SR2Private + sony_length = get4(); + break; + case 0x7221: // 29217, Sony SR2Private + sony_key = get4(); + break; + case 0x7250: // 29264, Sony SR2Private + parse_minolta(ftell(ifp)); + raw_width = 0; + break; + case 0x7303: // 29443, Sony SR2SubIFD + FORC4 cam_mul[GRBG_2_RGBG(c)] = get2(); + break; + case 0x7313: // 29459, Sony SR2SubIFD + FORC4 cam_mul[RGGB_2_RGBG(c)] = get2(); + break; + case 0x7310: // 29456, Sony SR2SubIFD + FORC4 cblack[RGGB_2_RGBG(c)] = get2(); + i = cblack[3]; + FORC3 if (i > (int)cblack[c]) i = cblack[c]; + FORC4 cblack[c] -= i; + black = i; + break; + case 0x827d: /* 33405, Model2 */ + /* + for Kodak ProBack 645 PB645x-yyyy 'x' is: + 'M' for Mamiya 645 + 'C' for Contax 645 + 'H' for Hasselblad H-series + */ + fgets(model2, 64, ifp); + break; + case 0x828d: /* 33421, CFARepeatPatternDim */ + if (get2() == 6 && get2() == 6) + tiff_ifd[ifd].t_filters = filters = 9; + break; + case 0x828e: /* 33422, CFAPattern */ + if (filters == 9) + { + FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3; + break; + } + case 0xfd09: /* 64777, Kodak P-series */ + if (len == 36) + { + tiff_ifd[ifd].t_filters = filters = 9; + colors = 3; + FORC(36)((char *)xtrans)[c] = fgetc(ifp) & 3; + } + else if (len > 0) + { + if ((plen = len) > 16) + plen = 16; + fread(cfa_pat, 1, plen, ifp); + for (colors = cfa = i = 0; i < (int)plen && colors < 4; i++) + { + if (cfa_pat[i] > 31) + continue; // Skip wrong data + 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; + } + break; + case 0x8290: // 33424 + case 0xfe00: // 65024 + fseek(ifp, get4() + base, SEEK_SET); + parse_kodak_ifd(base); + break; + case 0x829a: /* 33434, ExposureTime */ + tiff_ifd[ifd].t_shutter = shutter = getreal(type); + break; + case 0x829d: /* 33437, FNumber */ + aperture = getreal(type); + break; + case 0x9400: + imCommon.exifAmbientTemperature = getreal(type); + if ((imCommon.CameraTemperature > -273.15f) && + ((OlyID == OlyID_TG_5) || (OlyID == OlyID_TG_6))) + imCommon.CameraTemperature += + imCommon.exifAmbientTemperature; + break; + case 0x9401: + imCommon.exifHumidity = getreal(type); + break; + case 0x9402: + imCommon.exifPressure = getreal(type); + break; + case 0x9403: + imCommon.exifWaterDepth = getreal(type); + break; + case 0x9404: + imCommon.exifAcceleration = getreal(type); + break; + case 0x9405: + imCommon.exifCameraElevationAngle = getreal(type); + break; + case 0xa405: // FocalLengthIn35mmFormat + imgdata.lens.FocalLengthIn35mmFormat = get2(); + break; + case 0xa431: // BodySerialNumber + case 0xc62f: + stmread(imgdata.shootinginfo.BodySerial, len, ifp); + break; + case 0xa432: // LensInfo, 42034dec, Lens Specification per EXIF standard + imgdata.lens.MinFocal = getreal(type); + imgdata.lens.MaxFocal = getreal(type); + imgdata.lens.MaxAp4MinFocal = getreal(type); + imgdata.lens.MaxAp4MaxFocal = getreal(type); + break; + case 0xa435: // LensSerialNumber + stmread(imgdata.lens.LensSerial, len, ifp); + break; + case 0xc630: // DNG LensInfo, Lens Specification per EXIF standard + imgdata.lens.MinFocal = getreal(type); + imgdata.lens.MaxFocal = getreal(type); + imgdata.lens.MaxAp4MinFocal = getreal(type); + imgdata.lens.MaxAp4MaxFocal = getreal(type); + break; + case 0xa420: /* 42016, ImageUniqueID */ + stmread(imgdata.color.ImageUniqueID, len, ifp); + break; + case 0xc65d: /* 50781, RawDataUniqueID */ + imgdata.color.RawDataUniqueID[16] = 0; + fread(imgdata.color.RawDataUniqueID, 1, 16, ifp); + break; + case 0xa433: // LensMake + stmread(imgdata.lens.LensMake, len, ifp); + break; + case 0xa434: // LensModel + stmread(imgdata.lens.Lens, len, ifp); + if (!strncmp(imgdata.lens.Lens, "----", 4)) + imgdata.lens.Lens[0] = 0; + break; + case 0x9205: + imgdata.lens.EXIF_MaxAp = libraw_powf64l(2.0f, (getreal(type) / 2.0f)); + break; + case 0x8602: /* 34306, Leaf white balance */ + FORC4 + { + int q = get2(); + if (q) + cam_mul[GRGB_2_RGBG(c)] = 4096.0 / q; + } + break; + case 0x8603: /* 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][GRGB_2_RGBG(c)]); + if (!use_camera_wb) + continue; + num = 0; + FORC4 num += rgb_cam[i][c]; + FORC4 rgb_cam[i][c] /= MAX(1, num); + } + break; + case 0x8606: /* 34310, Leaf metadata */ + parse_mos(ftell(ifp)); + case 0x85ff: // 34303 + strcpy(make, "Leaf"); + break; + case 0x8769: /* 34665, EXIF tag */ + fseek(ifp, get4() + base, SEEK_SET); + parse_exif(base); + break; + case 0x8825: /* 34853, GPSInfo tag */ + { + unsigned pos; + fseek(ifp, pos = (get4() + base), SEEK_SET); + parse_gps(base); + fseek(ifp, pos, SEEK_SET); + parse_gps_libraw(base); + } + break; + case 0x8773: /* 34675, InterColorProfile */ + case 0xc68f: /* 50831, AsShotICCProfile */ + profile_offset = ftell(ifp); + profile_length = len; + break; + case 0x9102: /* 37122, CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 0x920a: /* 37386, FocalLength */ + focal_len = getreal(type); + break; + case 0x9211: /* 37393, ImageNumber */ + shot_order = getint(type); + break; + case 0x9215: /* 37397, ExposureIndex */ + imCommon.exifExposureIndex = getreal(type); + break; + case 0x9218: /* 37400, old Kodak KDC tag */ + for (raw_color = i = 0; i < 3; i++) + { + getreal(type); + FORC3 rgb_cam[i][c] = getreal(type); + } + break; + case 0xa010: // 40976 + strip_offset = get4(); + switch (tiff_ifd[ifd].comp) + { + case 0x8002: // 32770 + load_raw = &LibRaw::samsung_load_raw; + break; + case 0x8004: // 32772 + load_raw = &LibRaw::samsung2_load_raw; + break; + case 0x8005: // 32773 + load_raw = &LibRaw::samsung3_load_raw; + break; + } + break; + case 0xb4c3: /* 46275, Imacon tags */ + imHassy.format = LIBRAW_HF_Imacon; + strcpy(make, "Imacon"); + data_offset = ftell(ifp); + ima_len = len; + break; + case 0xb4c7: // 46279 + if (!ima_len) + break; + fseek(ifp, 38, SEEK_CUR); + case 0xb4c2: // 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 && ima_len == 234317952) + { + height = 5412; + width = 7216; + left_margin = 7; + filters = 0; + } + else if (raw_width == 7262) + { + height = 5444; + width = 7244; + left_margin = 7; + } + fseek(ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(LIBRAW_EXIFTAG_TYPE_FLOAT); + fseek(ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * (height * 6l) == ima_len) + { + if (flip % 180 == 90) + SWAP(width, height); + raw_width = width; + raw_height = height; + left_margin = top_margin = filters = flip = 0; + } + c = unsigned(height) * unsigned(width) / 1000000; + if (c == 32) + c--; + sprintf(model, "Ixpress %d-Mp", c); + load_raw = &LibRaw::imacon_full_load_raw; + if (filters) + { + if (left_margin & 1) + filters = 0x61616161; + load_raw = &LibRaw::unpacked_load_raw; + } + maximum = 0xffff; + break; + case 0xc516: /* 50454, Sinar tag */ + case 0xc517: // 50455 + if (len < 1 || len > 2560000 || !(cbuf = (char *)malloc(len))) + break; + if (fread(cbuf, 1, len, ifp) != (int)len) + throw LIBRAW_EXCEPTION_IO_CORRUPT; // cbuf to be free'ed in recycle + cbuf[len - 1] = 0; + 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 0xc51a: // 50458 + if (!make[0]) + strcpy(make, "Hasselblad"); + break; + case 0xc51b: /* 50459, Hasselblad tag */ + if (!libraw_internal_data.unpacker_data.hasselblad_parser_flag) + { + libraw_internal_data.unpacker_data.hasselblad_parser_flag = 1; + 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 0xc612: /* 50706, DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + if (!make[0]) + strcpy(make, "DNG"); + is_raw = 1; + break; + case 0xc614: /* 50708, UniqueCameraModel */ + stmread(imgdata.color.UniqueCameraModel, len, ifp); + if (model[0]) + break; + strncpy(make, imgdata.color.UniqueCameraModel, + MIN(len, sizeof(imgdata.color.UniqueCameraModel))); + if ((cp = strchr(make, ' '))) + { + strcpy(model, cp + 1); + *cp = 0; + } + break; + case 0xc616: /* 50710, CFAPlaneColor */ + if (filters == 9) + break; + if (len > 4) + len = 4; + colors = len; + fread(cfa_pc, 1, colors, ifp); + guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; + for (i = 16; i--;) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + filters -= !filters; + tiff_ifd[ifd].t_filters = filters; + break; + case 0xc617: /* 50711, CFALayout */ + if (get2() == 2) + tiff_ifd[ifd].t_fuji_width = fuji_width = 1; + break; + case 0x0123: // 291 + case 0xc618: /* 50712, LinearizationTable */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINTABLE; + tiff_ifd[ifd].lineartable_offset = ftell(ifp); + tiff_ifd[ifd].lineartable_len = len; + linear_table(len); + break; + case 0xc619: /* 50713, BlackLevelRepeatDim */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + tiff_ifd[ifd].dng_levels.dng_fcblack[4] = + tiff_ifd[ifd].dng_levels.dng_cblack[4] = cblack[4] = get2(); + tiff_ifd[ifd].dng_levels.dng_fcblack[5] = + tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[5] = get2(); + if (cblack[4] * cblack[5] > + (LIBRAW_CBLACK_SIZE - + 7)) // Use last cblack item as DNG black level count + tiff_ifd[ifd].dng_levels.dng_fcblack[4] = + tiff_ifd[ifd].dng_levels.dng_fcblack[5] = + tiff_ifd[ifd].dng_levels.dng_cblack[4] = + tiff_ifd[ifd].dng_levels.dng_cblack[5] = cblack[4] = + cblack[5] = 1; + break; + + case 0xf00c: + if (imFuji.RAFDataGeneration != 4096) + { + unsigned fwb[4]; + FORC4 fwb[c] = get4(); + if (fwb[3] < 0x100) + { + FORC3 icWBC[fwb[3]][GRBG_2_RGBG(c)] = fwb[c]; + icWBC[fwb[3]][3] = icWBC[fwb[3]][1]; + if ((fwb[3] == 17) && // Tungsten WB + (libraw_internal_data.unpacker_data.lenRAFData > 3) && + (libraw_internal_data.unpacker_data.lenRAFData < 10240000)) + { + INT64 f_save = ftell(ifp); + rafdata = (ushort *)malloc( + sizeof(ushort) * libraw_internal_data.unpacker_data.lenRAFData); + fseek(ifp, libraw_internal_data.unpacker_data.posRAFData, SEEK_SET); + fread(rafdata, sizeof(ushort), + libraw_internal_data.unpacker_data.lenRAFData, ifp); + fseek(ifp, f_save, SEEK_SET); + + uchar *PrivateMknBuf = (uchar *)rafdata; + int PrivateMknLength = libraw_internal_data.unpacker_data.lenRAFData + << 1; + for (int pos = 0; pos < PrivateMknLength - 16; pos++) + { + if (!memcmp(PrivateMknBuf + pos, "TSNERDTS", 8)) // STDRENST + { + imFuji.isTSNERDTS = 1; + break; + } + } + int fj; // 31? (fj<<1)-0x3c : 34? (fj<<1)-0x4e : undef + int is34 = 0; + if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S + (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II + (imFuji.RAFDataVersion == 0x0262) || // X-T4 + (imFuji.RAFDataVersion == 0x0263) || // X-H2S + (imFuji.RAFDataVersion == 0x0264) || // X-S10 + (imFuji.RAFDataVersion == 0x0265) || // X-E4 + (imFuji.RAFDataVersion == 0x0266) || // X-T30 II + !strcmp(model, "X-Pro3") || + !strcmp(model, "GFX 100S") || + !strcmp(model, "GFX100S") || + !strcmp(model, "GFX 50S II") || + !strcmp(model, "GFX50S II") || + !strcmp(model, "X100V") || + !strcmp(model, "X-T4") || + !strcmp(model, "X-H2S") || + !strcmp(model, "X-E4") || + !strcmp(model, "X-T30 II") || + !strcmp(model, "X-S10")) +// is34 cameras have 34 CCT values instead of 31, manual still claims 2500 to 10000 K +// aligned 3000 K to Incandescent, as it is usual w/ other Fujifilm cameras + is34 = 1; + + for (int fi = 0; + fi < int(libraw_internal_data.unpacker_data.lenRAFData - 3); fi++) // looking for Tungsten WB + { + if ((fwb[0] == rafdata[fi]) && (fwb[1] == rafdata[fi + 1]) && + (fwb[2] == rafdata[fi + 2])) // found Tungsten WB + { + if (rafdata[fi - 15] != + fwb[0]) // 15 is offset of Tungsten WB from the first + // preset, Fine Weather WB + continue; + for (int wb_ind = 0, ofst = fi - 15; wb_ind < (int)Fuji_wb_list1.size(); + wb_ind++, ofst += 3) + { + icWBC[Fuji_wb_list1[wb_ind]][1] = + icWBC[Fuji_wb_list1[wb_ind]][3] = rafdata[ofst]; + icWBC[Fuji_wb_list1[wb_ind]][0] = rafdata[ofst + 1]; + icWBC[Fuji_wb_list1[wb_ind]][2] = rafdata[ofst + 2]; + } + + if (is34) + fi += 24; + fi += 96; + for (fj = fi; fj < (fi + 15); fj += 3) // looking for the end of the WB table + { + if (rafdata[fj] != rafdata[fi]) + { + fj -= 93; + if (is34) + fj -= 9; +// printf ("wb start in DNG: 0x%04x\n", fj*2-0x4e); + for (int iCCT = 0, ofst = fj; iCCT < 31; + iCCT++, ofst += 3) + { + icWBCCTC[iCCT][0] = FujiCCT_K[iCCT]; + icWBCCTC[iCCT][1] = rafdata[ofst + 1]; + icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = rafdata[ofst]; + icWBCCTC[iCCT][3] = rafdata[ofst + 2]; + } + break; + } + } + free(rafdata); + break; + } + } + } + } + FORC4 fwb[c] = get4(); + if (fwb[3] < 0x100) { + FORC3 icWBC[fwb[3]][GRBG_2_RGBG(c)] = fwb[c]; + icWBC[fwb[3]][3] = icWBC[fwb[3]][1]; + } + } + break; + case 0xf00d: + if (imFuji.RAFDataGeneration != 4096) + { + FORC3 icWBC[LIBRAW_WBI_Auto][GRBG_2_RGBG(c)] = getint(type); + icWBC[LIBRAW_WBI_Auto][3] = icWBC[LIBRAW_WBI_Auto][1]; + } + break; + case 0xc615: /* 50709, LocalizedCameraModel */ + stmread(imgdata.color.LocalizedCameraModel, len, ifp); + break; + case 0xf00a: // 61450 + cblack[4] = cblack[5] = MIN(sqrt((double)len), 64); + case 0xc61a: /* 50714, BlackLevel */ + if (tiff_ifd[ifd].samples > 1 && + tiff_ifd[ifd].samples == (int)len) // LinearDNG, per-channel black + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + for (i = 0; i < 4 && i < (int)len; i++) + { + tiff_ifd[ifd].dng_levels.dng_fcblack[i] = getreal(type); + tiff_ifd[ifd].dng_levels.dng_cblack[i] = cblack[i] = + tiff_ifd[ifd].dng_levels.dng_fcblack[i] + 0.5; + } + // Record len in last cblack field + tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] = len; + + tiff_ifd[ifd].dng_levels.dng_fblack = + tiff_ifd[ifd].dng_levels.dng_black = black = 0; + } + else if (tiff_ifd[ifd].samples > 1 // Linear DNG w repeat dim + && (tiff_ifd[ifd].samples * cblack[4] * cblack[5] == len)) + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + tiff_ifd[ifd].dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] = + cblack[LIBRAW_CBLACK_SIZE - 1] = len; + for (i = 0; i < (int)len && i < LIBRAW_CBLACK_SIZE - 7; i++) + { + tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] = getreal(type); + tiff_ifd[ifd].dng_levels.dng_cblack[i + 6] = cblack[i + 6] = + tiff_ifd[ifd].dng_levels.dng_fcblack[i + 6] + 0.5; + } + } + else if ((cblack[4] * cblack[5] < 2) && len == 1) + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + tiff_ifd[ifd].dng_levels.dng_fblack = getreal(type); + black = tiff_ifd[ifd].dng_levels.dng_black = + tiff_ifd[ifd].dng_levels.dng_fblack; + } + else if (cblack[4] * cblack[5] <= len) + { + FORC(int(cblack[4] * cblack[5])) + { + tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c] = getreal(type); + cblack[6 + c] = tiff_ifd[ifd].dng_levels.dng_fcblack[6 + c]; + } + black = 0; + FORC4 + cblack[c] = 0; + + if (tag == 0xc61a) + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + FORC(int(cblack[4] * cblack[5])) + tiff_ifd[ifd].dng_levels.dng_cblack[6 + c] = cblack[6 + c]; + tiff_ifd[ifd].dng_levels.dng_fblack = 0; + tiff_ifd[ifd].dng_levels.dng_black = 0; + FORC4 + tiff_ifd[ifd].dng_levels.dng_fcblack[c] = + tiff_ifd[ifd].dng_levels.dng_cblack[c] = 0; + } + } + break; + case 0xc61b: /* 50715, BlackLevelDeltaH */ + case 0xc61c: /* 50716, BlackLevelDeltaV */ + for (num = i = 0; i < (int)len && i < 65536; i++) + num += getreal(type); + if (len > 0) + { + black += num / len + 0.5; + tiff_ifd[ifd].dng_levels.dng_fblack += num / float(len); + tiff_ifd[ifd].dng_levels.dng_black += num / len + 0.5; + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BLACK; + } + break; + case 0xc61d: /* 50717, WhiteLevel */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_WHITE; + tiff_ifd[ifd].dng_levels.dng_whitelevel[0] = maximum = getint(type); + if (tiff_ifd[ifd].samples > 1) // Linear DNG case + for (i = 1; i < 4 && i < (int)len; i++) + tiff_ifd[ifd].dng_levels.dng_whitelevel[i] = getint(type); + break; + case 0xc61e: /* DefaultScale */ + { + float q1 = getreal(type); + float q2 = getreal(type); + if (q1 > 0.00001f && q2 > 0.00001f) + { + pixel_aspect = q1 / q2; + if (pixel_aspect > 0.995 && pixel_aspect < 1.005) + pixel_aspect = 1.0; + } + } + break; + case 0xc61f: /* 50719, DefaultCropOrigin */ + if (len == 2) + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPORIGIN; + tiff_ifd[ifd].dng_levels.default_crop[0] = getreal(type); + tiff_ifd[ifd].dng_levels.default_crop[1] = getreal(type); + if (!strncasecmp(make, "SONY", 4)) + { + imgdata.sizes.raw_inset_crops[0].cleft = + tiff_ifd[ifd].dng_levels.default_crop[0]; + imgdata.sizes.raw_inset_crops[0].ctop = + tiff_ifd[ifd].dng_levels.default_crop[1]; + } + } + break; + + case 0xc620: /* 50720, DefaultCropSize */ + if (len == 2) + { + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_CROPSIZE; + tiff_ifd[ifd].dng_levels.default_crop[2] = getreal(type); + tiff_ifd[ifd].dng_levels.default_crop[3] = getreal(type); + if (!strncasecmp(make, "SONY", 4)) + { + imgdata.sizes.raw_inset_crops[0].cwidth = + tiff_ifd[ifd].dng_levels.default_crop[2]; + imgdata.sizes.raw_inset_crops[0].cheight = + tiff_ifd[ifd].dng_levels.default_crop[3]; + } + } + break; + + case 0xc7b5: /* 51125 DefaultUserCrop */ + if (len == 4) + { + int cnt = 0; + FORC4 + { + float v = getreal(type); + if (v >= 0.f && v <= 1.f) + { + tiff_ifd[ifd].dng_levels.user_crop[c] = v; + cnt++; + } + } + if(cnt == 4 // valid values + && tiff_ifd[ifd].dng_levels.user_crop[0] < tiff_ifd[ifd].dng_levels.user_crop[2] // top < bottom + && tiff_ifd[ifd].dng_levels.user_crop[1] < tiff_ifd[ifd].dng_levels.user_crop[3] // left < right + ) + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_USERCROP; + } + break; + case 0x74c7: + if ((len == 2) && !strncasecmp(make, "SONY", 4)) + { + imgdata.sizes.raw_inset_crops[0].cleft = get4(); + imgdata.sizes.raw_inset_crops[0].ctop = get4(); + } + break; + + case 0x74c8: + if ((len == 2) && !strncasecmp(make, "SONY", 4)) + { + imgdata.sizes.raw_inset_crops[0].cwidth = get4(); + imgdata.sizes.raw_inset_crops[0].cheight = get4(); + } + break; + + case 0xc65a: // 50778 + tiff_ifd[ifd].dng_color[0].illuminant = get2(); + tiff_ifd[ifd].dng_color[0].parsedfields |= LIBRAW_DNGFM_ILLUMINANT; + break; + case 0xc65b: // 50779 + tiff_ifd[ifd].dng_color[1].illuminant = get2(); + tiff_ifd[ifd].dng_color[1].parsedfields |= LIBRAW_DNGFM_ILLUMINANT; + break; + + case 0xc621: /* 50721, ColorMatrix1 */ + case 0xc622: /* 50722, ColorMatrix2 */ + { + int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0); + i = tag == 0xc621 ? 0 : 1; + if (chan) + { + tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_COLORMATRIX; + imHassy.nIFD_CM[i] = ifd; + } + FORC(chan) for (j = 0; j < 3; j++) + { + tiff_ifd[ifd].dng_color[i].colormatrix[c][j] = cm[c][j] = getreal(type); + } + use_cm = 1; + } + break; + + case 0xc714: /* ForwardMatrix1 */ + case 0xc715: /* ForwardMatrix2 */ + { + int chan = (len == 9) ? 3 : (len == 12 ? 4 : 0); + i = tag == 0xc714 ? 0 : 1; + if (chan) + tiff_ifd[ifd].dng_color[i].parsedfields |= LIBRAW_DNGFM_FORWARDMATRIX; + for (j = 0; j < 3; j++) + FORC(chan) + { + tiff_ifd[ifd].dng_color[i].forwardmatrix[j][c] = fm[j][c] = + getreal(type); + } + } + break; + + case 0xc623: /* 50723, CameraCalibration1 */ + case 0xc624: /* 50724, CameraCalibration2 */ + { + int chan = (len == 9) ? 3 : (len == 16 ? 4 : 0); + j = tag == 0xc623 ? 0 : 1; + if (chan) + tiff_ifd[ifd].dng_color[j].parsedfields |= LIBRAW_DNGFM_CALIBRATION; + for (i = 0; i < chan; i++) + FORC(chan) + { + tiff_ifd[ifd].dng_color[j].calibration[i][c] = cc[i][c] = + getreal(type); + } + } + break; + case 0xc627: /* 50727, AnalogBalance */ + if (len >= 3) + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ANALOGBALANCE; + for (c = 0; c < (int)len && c < 4; c++) + { + tiff_ifd[ifd].dng_levels.analogbalance[c] = ab[c] = getreal(type); + } + break; + case 0xc628: /* 50728, AsShotNeutral */ + if (len >= 3) + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_ASSHOTNEUTRAL; + for (c = 0; c < (int)len && c < 4; c++) + tiff_ifd[ifd].dng_levels.asshotneutral[c] = asn[c] = getreal(type); + break; + case 0xc629: /* 50729, AsShotWhiteXY */ + xyz[0] = getreal(type); + xyz[1] = getreal(type); + xyz[2] = 1 - xyz[0] - xyz[1]; + FORC3 xyz[c] /= LibRaw_constants::d65_white[c]; + break; + case 0xc62a: /* DNG: 50730 BaselineExposure */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_BASELINEEXPOSURE; + tiff_ifd[ifd].dng_levels.baseline_exposure = getreal(type); + break; + case 0xc62e: /* DNG: 50734 LinearResponseLimit */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_LINEARRESPONSELIMIT; + tiff_ifd[ifd].dng_levels.LinearResponseLimit = getreal(type); + break; + + case 0xc634: /* 50740 : DNG Adobe, DNG Pentax, Sony SR2, DNG Private */ + { + char mbuf[64]; + INT64 curr_pos, start_pos = ftell(ifp); + unsigned MakN_order, m_sorder = order; + unsigned MakN_length; + unsigned pos_in_original_raw; + fread(mbuf, 1, 6, ifp); + + if (!strcmp(mbuf, "Adobe")) + { + order = 0x4d4d; // Adobe header is always in "MM" / big endian + curr_pos = start_pos + 6; + while (curr_pos + 8 - start_pos <= len) + { + fread(mbuf, 1, 4, ifp); + curr_pos += 8; + + if (!strncmp(mbuf, "Pano", 4)) + { // PanasonicRaw, yes, they use "Pano" as signature + parseAdobePanoMakernote(); + } + + if (!strncmp(mbuf, "MakN", 4)) + { + MakN_length = get4(); + MakN_order = get2(); + pos_in_original_raw = get4(); + order = MakN_order; + + INT64 save_pos = ifp->tell(); + parse_makernote_0xc634(curr_pos + 6 - pos_in_original_raw, 0, + AdobeDNG); + + curr_pos = save_pos + MakN_length - 6; + fseek(ifp, curr_pos, SEEK_SET); + + fread(mbuf, 1, 4, ifp); + curr_pos += 8; + + if (!strncmp(mbuf, "Pano ", 4)) + { + parseAdobePanoMakernote(); + } + + if (!strncmp(mbuf, "RAF ", 4)) + { // Fujifilm Raw, AdobeRAF + parseAdobeRAFMakernote(); + } + + if (!strncmp(mbuf, "SR2 ", 4)) + { + order = 0x4d4d; + MakN_length = get4(); + MakN_order = get2(); + pos_in_original_raw = get4(); + order = MakN_order; + + unsigned *buf_SR2; + unsigned SR2SubIFDOffset = 0; + unsigned SR2SubIFDLength = 0; + unsigned SR2SubIFDKey = 0; + { + int _base = curr_pos + 6 - pos_in_original_raw; + unsigned _entries, _tag, _type, _len, _save; + _entries = get2(); + while (_entries--) + { + tiff_get(_base, &_tag, &_type, &_len, &_save); + + if (_tag == 0x7200) + { + SR2SubIFDOffset = get4(); + } + else if (_tag == 0x7201) + { + SR2SubIFDLength = get4(); + } + else if (_tag == 0x7221) + { + SR2SubIFDKey = get4(); + } + fseek(ifp, _save, SEEK_SET); + } + } + + if (SR2SubIFDLength && (SR2SubIFDLength < 10240000) && + (buf_SR2 = (unsigned *)malloc(SR2SubIFDLength + 1024))) + { // 1024b for safety + fseek(ifp, SR2SubIFDOffset + base, SEEK_SET); + fread(buf_SR2, SR2SubIFDLength, 1, ifp); + sony_decrypt(buf_SR2, SR2SubIFDLength / 4, 1, SR2SubIFDKey); + parseSonySR2((uchar *)buf_SR2, SR2SubIFDOffset, + SR2SubIFDLength, AdobeDNG); + + free(buf_SR2); + } + + } /* SR2 processed */ + break; + } + } + } + else + { + fread(mbuf + 6, 1, 2, ifp); + if (!strcmp(mbuf, "RICOH") && ((sget2((uchar *)mbuf + 6) == 0x4949) || + (sget2((uchar *)mbuf + 6) == 0x4d4d))) + { + is_PentaxRicohMakernotes = 1; + } + if (!strcmp(mbuf, "PENTAX ") || !strcmp(mbuf, "SAMSUNG") || + is_PentaxRicohMakernotes) + { + fseek(ifp, start_pos, SEEK_SET); + parse_makernote_0xc634(base, 0, CameraDNG); + } + } + fseek(ifp, start_pos, SEEK_SET); + order = m_sorder; + } + if (dng_version) + { + break; + } + parse_minolta(j = get4() + base); + fseek(ifp, j, SEEK_SET); + parse_tiff_ifd(base); + break; + case 0xc640: // 50752 + read_shorts(cr2_slice, 3); + break; + case 0xc68b: /* 50827, OriginalRawFileName */ + stmread(imgdata.color.OriginalRawFileName, len, ifp); + break; + case 0xc68d: /* 50829 ActiveArea */ + tiff_ifd[ifd].t_tm = top_margin = getint(type); + tiff_ifd[ifd].t_lm = left_margin = getint(type); + tiff_ifd[ifd].t_vheight = height = getint(type) - top_margin; + tiff_ifd[ifd].t_vwidth = width = getint(type) - left_margin; + break; + case 0xc68e: /* 50830 MaskedAreas */ + for (i = 0; i < (int)len && i < 32; i++) + ((int *)mask)[i] = getint(type); + black = 0; + break; + case 0xc71a: /* 50970, PreviewColorSpace */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_PREVIEWCS; + tiff_ifd[ifd].dng_levels.preview_colorspace = getint(type); + break; + case 0xc740: /* 51008, OpcodeList1 */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE1; + break; + case 0xc741: /* 51009, OpcodeList2 */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE2; + tiff_ifd[ifd].opcode2_offset = meta_offset = ftell(ifp); + break; + case 0xc74e: /* 51022, OpcodeList3 */ + tiff_ifd[ifd].dng_levels.parsedfields |= LIBRAW_DNGFM_OPCODE3; + break; + case 0xfd04: /* 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 = &LibRaw::packed_load_raw; + break; + case 0xfe02: // 65026 + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) + fgets(model2, 64, ifp); + } + fseek(ifp, save, SEEK_SET); + } + if (sony_length && sony_length < 10240000 && + (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); + parseSonySR2((uchar *)buf, sony_offset, sony_length, nonDNG); + free(buf); + } + for (i = 0; i < colors && i < 4; i++) + FORCC cc[i][c] *= ab[i]; + if (use_cm) + { + FORCC for (i = 0; i < 3; i++) for (cam_xyz[c][i] = j = 0; j < colors; j++) + cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; + cam_xyz_coeff(cmatrix, cam_xyz); + } + if (asn[0]) + { + cam_mul[3] = 0; + FORCC + if (fabs(asn[c]) > 0.0001) + cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) + FORCC if (fabs(cc[c][c]) > 0.0001) pre_mul[c] /= cc[c][c]; + return 0; +} + +int LibRaw::parse_tiff(int _base) +{ + INT64 base = _base; + int doff; + fseek(ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) + return 0; + get2(); + while ((doff = get4())) + { + INT64 doff64 = doff; + if (doff64 + base > ifp->size()) break; + fseek(ifp, doff64 + base, SEEK_SET); + if (parse_tiff_ifd(_base)) + break; + } + return 1; +} + +struct ifd_size_t +{ + int ifdi; + INT64 databits; +}; + +int ifd_size_t_cmp(const void *a, const void *b) +{ + if (!a || !b) + return 0; + const ifd_size_t *ai = (ifd_size_t *)a; + const ifd_size_t *bi = (ifd_size_t *)b; + return bi->databits > ai->databits ? 1 + : (bi->databits < ai->databits ? -1 : 0); +} + +static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make); + +void LibRaw::apply_tiff() +{ + int max_samp = 0, ties = 0, raw = -1, thm = -1, i; + unsigned long long ns, os; + struct jhead jh; + + thumb_misc = 16; + if (thumb_offset) + { + fseek(ifp, thumb_offset, SEEK_SET); + if (ljpeg_start(&jh, 1)) + { + if ((unsigned)jh.bits < 17 && (unsigned)jh.wide < 0x10000 && + (unsigned)jh.high < 0x10000) + { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + } + for (i = tiff_nifds; i--;) + { + if (tiff_ifd[i].t_shutter) + shutter = tiff_ifd[i].t_shutter; + tiff_ifd[i].t_shutter = shutter; + } + + if (dng_version) + { + int ifdc = 0; + for (i = 0; i < (int)tiff_nifds; i++) + { + if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 || + tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535) + continue; /* wrong image dimensions */ + + int samp = tiff_ifd[i].samples; + if (samp == 2) + samp = 1; // Fuji 2-frame + max_samp = LIM(MAX(max_samp, samp), 1, + 3); // max_samp is needed for thumbnail selection below + + if ( // Check phint only for RAW subfiletype + (tiff_ifd[i].newsubfiletype == 16 + || tiff_ifd[i].newsubfiletype == 0 + || (tiff_ifd[i].newsubfiletype & 0xffff) == 1) + && + (tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892) + ) + continue; + + if ((tiff_ifd[i].newsubfiletype == 0) // main image + // Enhanced demosaiced: + || (tiff_ifd[i].newsubfiletype == 16 && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_ENHANCED)) + // Preview: 0x1 or 0x10001 + || ((tiff_ifd[i].newsubfiletype & 0xffff) == 1 && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS)) + // Transparency mask: 0x4 + || ((tiff_ifd[i].newsubfiletype & 0xffff) == 4 && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_MASKS))) + { + // Add this IFD to dng_frames + libraw_internal_data.unpacker_data.dng_frames[ifdc] = + ((tiff_ifd[i].newsubfiletype & 0xffff) << 16) | ((i << 8) & 0xff00); + ifdc++; + // Fuji SuperCCD: second frame: + if ((tiff_ifd[i].newsubfiletype == 0) && tiff_ifd[i].samples == 2) + { + libraw_internal_data.unpacker_data.dng_frames[ifdc] = + ((tiff_ifd[i].newsubfiletype & 0xffff) << 16) | + ((i << 8) & 0xff00) | 1; + ifdc++; + } + } + } + if (ifdc) + { + if (ifdc > 1 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_PREFER_LARGEST_IMAGE)) + { + ifd_size_t arr[LIBRAW_IFD_MAXCOUNT * 2]; + memset(arr, 0, sizeof(arr)); + for (int q = 0; q < ifdc && q < LIBRAW_IFD_MAXCOUNT * 2; q++) + { + int ifdidx = + (libraw_internal_data.unpacker_data.dng_frames[q] >> 8) & 0xff; + arr[q].ifdi = libraw_internal_data.unpacker_data.dng_frames[q]; + arr[q].databits = + tiff_ifd[ifdidx].t_width * tiff_ifd[ifdidx].t_height * + tiff_ifd[ifdidx].samples * tiff_ifd[ifdidx].bps + + (0x100 - + (arr[q].ifdi & 0xff)); // add inverted frame # to ensure same + // sort order for similar sized frames. + if (tiff_ifd[ifdidx].phint == 4) + arr[q].databits /= 4; // Force lower bit count for Transp. mask images + } + qsort(arr, MIN(ifdc, LIBRAW_IFD_MAXCOUNT * 2), sizeof(arr[0]), + ifd_size_t_cmp); + for (int q = 0; q < ifdc && q < LIBRAW_IFD_MAXCOUNT * 2; q++) + libraw_internal_data.unpacker_data.dng_frames[q] = arr[q].ifdi; + } + + int idx = LIM((int)shot_select, 0, ifdc - 1); + i = (libraw_internal_data.unpacker_data.dng_frames[idx] >> 8) & + 0xff; // extract frame# back + + raw_width = tiff_ifd[i].t_width; + raw_height = tiff_ifd[i].t_height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + tiff_sampleformat = tiff_ifd[i].sample_format; + data_offset = tiff_ifd[i].offset; + data_size = tiff_ifd[i].bytes; + tiff_flip = tiff_ifd[i].t_flip; + tiff_samples = tiff_ifd[i].samples; + tile_width = tiff_ifd[i].t_tile_width; + tile_length = tiff_ifd[i].t_tile_length; + fuji_width = tiff_ifd[i].t_fuji_width; + if (tiff_samples != 2) /* special case: Fuji SuperCCD */ + { + if (tiff_ifd[i].phint == 34892) + filters = 0; + else if (i > 0 && tiff_ifd[i].phint == 32803 && + tiff_ifd[0].phint == 32803 && !tiff_ifd[i].t_filters && + tiff_ifd[0].t_filters) + filters = tiff_ifd[0].t_filters; + else + filters = tiff_ifd[i].t_filters; + width = tiff_ifd[i].t_vwidth; + height = tiff_ifd[i].t_vheight; + top_margin = tiff_ifd[i].t_tm; + left_margin = tiff_ifd[i].t_lm; + shutter = tiff_ifd[i].t_shutter; + if (tiff_ifd[i].dng_levels.dng_whitelevel[0]) + maximum = tiff_ifd[i].dng_levels.dng_whitelevel[0]; + else if (tiff_ifd[i].sample_format <= 2 && tiff_bps > 0 && + tiff_bps < 32) // SampleFormat: 0-default(1), 1 - Uint, 2 - Int + maximum = (1 << tiff_bps) - 1; + else if (tiff_ifd[i].sample_format == 3) + maximum = 1; // Defaults for FP + } + raw = i; + is_raw = ifdc; + } + else + is_raw = 0; + } + else + { + // Fix for broken Sony bps tag + if (!strncasecmp(make, "Sony", 4)) + { + for (i = 0; i < (int)tiff_nifds; i++) + { + if (tiff_ifd[i].bps > 33 && tiff_ifd[i].samples == 1) + { + int bps = 14; // default + if (tiff_ifd[i].dng_levels.dng_whitelevel[0] > 0) + { + for(int c = 0,j=1; c < 16; c++, j<<=1) + if (j > (int)tiff_ifd[i].dng_levels.dng_whitelevel[0]) + { + bps = c; break; + } + } + tiff_ifd[i].bps = bps; + } + } + } + + for (i = 0; i < (int)tiff_nifds; i++) + { + if (tiff_ifd[i].t_width < 1 || tiff_ifd[i].t_width > 65535 || + tiff_ifd[i].t_height < 1 || tiff_ifd[i].t_height > 65535) + continue; /* wrong image dimensions */ + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; + if (max_samp > 3) + max_samp = 3; + + os = unsigned(raw_width) * unsigned(raw_height); + ns = unsigned(tiff_ifd[i].t_width) * unsigned(tiff_ifd[i].t_height); + if (tiff_bps) + { + os *= tiff_bps; + ns *= tiff_ifd[i].bps; + } + /* too complex if below, so separate if to skip RGB+Alpha TIFFs*/ + if (tiff_ifd[i].phint == 2 && tiff_ifd[i].extrasamples > 0 && tiff_ifd[i].samples > 3) + continue; // SKIP RGB+Alpha IFDs + + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && + (unsigned)tiff_ifd[i].bps < 33 && + (unsigned)tiff_ifd[i].samples < 13 && ns && + ((ns > os && (ties = 1)) || (ns == os && (int)shot_select == ties++))) + { + raw_width = tiff_ifd[i].t_width; + raw_height = tiff_ifd[i].t_height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + tiff_sampleformat = tiff_ifd[i].sample_format; + data_offset = tiff_ifd[i].offset; + data_size = tiff_ifd[i].bytes; + tiff_flip = tiff_ifd[i].t_flip; + tiff_samples = tiff_ifd[i].samples; + tile_width = tiff_ifd[i].t_tile_width; + tile_length = tiff_ifd[i].t_tile_length; + shutter = tiff_ifd[i].t_shutter; + raw = i; + } + } + if (is_raw == 1 && ties) + is_raw = ties; + } + if (is_NikonTransfer && raw >= 0) + { + if (tiff_ifd[raw].bps == 16) + { + if (tiff_compress == 1) + { + if ((raw_width * raw_height * 3) == (tiff_ifd[raw].bytes << 1)) + { + tiff_bps = tiff_ifd[raw].bps = 12; + } + else + { + tiff_bps = tiff_ifd[raw].bps = 14; + } + } + } + else if (tiff_ifd[raw].bps == 8) + { + if (tiff_compress == 1) + { + is_NikonTransfer = 2; // 8-bit debayered TIFF, like CoolScan NEFs + imgdata.rawparams.coolscan_nef_gamma = 2.2f; + } + } + } + + if (!tile_width) + tile_width = INT_MAX; + if (!tile_length) + tile_length = INT_MAX; + for (i = tiff_nifds; i--;) + if (tiff_ifd[i].t_flip) + tiff_flip = tiff_ifd[i].t_flip; + +#if 0 + if (raw < 0 && is_raw) + is_raw = 0; +#endif + + if (raw >= 0 && !load_raw) + switch (tiff_compress) + { + case 32767: + if (!dng_version && + INT64(tiff_ifd[raw].bytes) == INT64(raw_width) * INT64(raw_height)) + { + tiff_bps = 14; + load_raw = &LibRaw::sony_arw2_load_raw; + break; + } + if (!dng_version && !strncasecmp(make, "Sony", 4) && + INT64(tiff_ifd[raw].bytes) == + INT64(raw_width) * INT64(raw_height) * 2LL) + { + tiff_bps = 14; + load_raw = &LibRaw::unpacked_load_raw; + break; + } + if (INT64(tiff_ifd[raw].bytes) * 8LL != + INT64(raw_width) * INT64(raw_height) * INT64(tiff_bps)) + { + raw_height += 8; + load_raw = &LibRaw::sony_arw_load_raw; + break; + } + load_flags = 79; + case 32769: + load_flags++; + case 32770: + case 32773: + goto slr; + case 0: + case 1: + if (dng_version && tiff_sampleformat == 3 && + (tiff_bps > 8 && (tiff_bps % 8 == 0) && (tiff_bps <= 32))) // only 16,24, and 32 are allowed + { + load_raw = &LibRaw::uncompressed_fp_dng_load_raw; + break; + } + // Sony 14-bit uncompressed + if (!dng_version && !strncasecmp(make, "Sony", 4) && + INT64(tiff_ifd[raw].bytes) == + INT64(raw_width) * INT64(raw_height) * 2LL) + { + tiff_bps = 14; + load_raw = &LibRaw::unpacked_load_raw; + break; + } + if (!dng_version && !strncasecmp(make, "Sony", 4) && + tiff_ifd[raw].samples == 4 && + INT64(tiff_ifd[raw].bytes) == + INT64(raw_width) * INT64(raw_height) * 8LL) // Sony ARQ + { + // maybe to detect ARQ with the following: + // if (tiff_ifd[raw].phint == 32892) + tiff_bps = 14; + tiff_samples = 4; + load_raw = &LibRaw::sony_arq_load_raw; + filters = 0; + strcpy(cdesc, "RGBG"); + break; + } + if (!strncasecmp(make, "Nikon", 5) && + (!strncmp(software, "Nikon Scan", 10) || (is_NikonTransfer == 2) || + strcasestr(model, "COOLSCAN"))) + { + load_raw = &LibRaw::nikon_coolscan_load_raw; + raw_color = 1; + colors = (tiff_samples == 3) ? 3 : 1; + filters = 0; + break; + } + if ((!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || + (!strncasecmp(make, "CLAUSS", 6) && + !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here + (INT64(tiff_ifd[raw].bytes) * 2ULL == + INT64(raw_width) * INT64(raw_height) * 3ULL)) + load_flags = 24; + if (!dng_version && INT64(tiff_ifd[raw].bytes) * 5ULL == + INT64(raw_width) * INT64(raw_height) * 8ULL) + { + load_flags = 81; + tiff_bps = 12; + } + slr: + switch (tiff_bps) + { + case 8: + load_raw = &LibRaw::eight_bit_load_raw; + break; + case 12: + if (tiff_ifd[raw].phint == 2) + load_flags = 6; + if (!strncasecmp(make, "NIKON", 5) && + !strncasecmp(model, "COOLPIX A1000", 13) && + data_size == raw_width * raw_height * 2u) + load_raw = &LibRaw::unpacked_load_raw; + else + load_raw = &LibRaw::packed_load_raw; + break; + case 14: + load_flags = 0; + case 16: + load_raw = &LibRaw::unpacked_load_raw; + if ((!strncmp(make, "OLYMPUS", 7) || !strncmp(make, "OM Digi", 7) || + (!strncasecmp(make, "CLAUSS", 6) && + !strncasecmp(model, "piX 5oo", 7))) && // 0x5330303539 works here + (INT64(tiff_ifd[raw].bytes) * 7LL > + INT64(raw_width) * INT64(raw_height))) + load_raw = &LibRaw::olympus_load_raw; + } + break; + case 6: + case 7: + case 99: + if (!dng_version && tiff_compress == 6 && !strcasecmp(make, "SONY")) + load_raw = &LibRaw::sony_ljpeg_load_raw; + else + load_raw = &LibRaw::lossless_jpeg_load_raw; + break; + case 262: + load_raw = &LibRaw::kodak_262_load_raw; + break; + case 34713: + if ((INT64(raw_width) + 9LL) / 10LL * 16LL * INT64(raw_height) == + INT64(tiff_ifd[raw].bytes)) + { + load_raw = &LibRaw::packed_load_raw; + load_flags = 1; + } + else if (INT64(raw_width) * INT64(raw_height) * 3LL == + INT64(tiff_ifd[raw].bytes) * 2LL) + { + load_raw = &LibRaw::packed_load_raw; + if (model[0] == 'N') + load_flags = 80; + } + else if (INT64(raw_width) * INT64(raw_height) * 3LL == + INT64(tiff_ifd[raw].bytes)) + { + load_raw = &LibRaw::nikon_yuv_load_raw; + gamma_curve(1 / 2.4, 12.92, 1, 4095); + memset(cblack, 0, sizeof cblack); + filters = 0; + } + else if (INT64(raw_width) * INT64(raw_height) * 2LL == + INT64(tiff_ifd[raw].bytes)) + { + load_raw = &LibRaw::unpacked_load_raw; + load_flags = 4; + order = 0x4d4d; + } +#if 0 /* Never used because of same condition above, but need to recheck */ + else if (INT64(raw_width) * INT64(raw_height) * 3LL == + INT64(tiff_ifd[raw].bytes) * 2LL) + { + load_raw = &LibRaw::packed_load_raw; + load_flags = 80; + } +#endif + else if (tiff_ifd[raw].rows_per_strip && + tiff_ifd[raw].strip_offsets_count && + tiff_ifd[raw].strip_offsets_count == + tiff_ifd[raw].strip_byte_counts_count) + { + int fit = 1; + for (int q = 0; q < tiff_ifd[raw].strip_byte_counts_count - 1; + q++) // all but last + if (INT64(tiff_ifd[raw].strip_byte_counts[q]) * 2LL != + INT64(tiff_ifd[raw].rows_per_strip) * INT64(raw_width) * 3LL) + { + fit = 0; + break; + } + if (fit) + load_raw = &LibRaw::nikon_load_striped_packed_raw; + else + load_raw = &LibRaw::nikon_load_raw; // fallback + } + else if ((((INT64(raw_width) * 3LL / 2LL) + 15LL) / 16LL) * 16LL * + INT64(raw_height) == + INT64(tiff_ifd[raw].bytes)) + { + load_raw = &LibRaw::nikon_load_padded_packed_raw; + load_flags = (((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) * + 16ULL; // bytes per row + } + else if (!strncmp(model, "NIKON Z 9", 9) && tiff_ifd[raw].offset) + { + INT64 pos = ftell(ifp); + unsigned char cmp[] = "CONTACT_INTOPIX"; // 15 + unsigned char buf[16]; + fseek(ifp, INT64(tiff_ifd[raw].offset) + 6LL, SEEK_SET); + fread(buf, 1, 16, ifp); + fseek(ifp, pos, SEEK_SET); + if(!memcmp(buf,cmp,15)) + load_raw = &LibRaw::nikon_he_load_raw_placeholder; + else + load_raw = &LibRaw::nikon_load_raw; + } + else + load_raw = &LibRaw::nikon_load_raw; + break; + case 65535: + load_raw = &LibRaw::pentax_load_raw; + break; + case 65000: + switch (tiff_ifd[raw].phint) + { + case 2: + load_raw = &LibRaw::kodak_rgb_load_raw; + filters = 0; + break; + case 6: + load_raw = &LibRaw::kodak_ycbcr_load_raw; + filters = 0; + break; + case 32803: + load_raw = &LibRaw::kodak_65000_load_raw; + } + case 32867: + case 34892: + break; + case 8: + break; +#ifdef USE_GPRSDK + case 9: + if (dng_version) + break; /* Compression=9 supported for dng if we compiled with GPR SDK */ + /* Else: fallthrough */ +#endif + default: + is_raw = 0; + } + if (!dng_version) + { + if (((tiff_samples == 3 && tiff_ifd[raw].bytes && + !(tiff_bps == 16 && + !strncmp(make, "Leaf", 4)) && // Allow Leaf/16bit/3color files + tiff_bps != 14 && + (tiff_compress & -16) != 32768) || + (tiff_bps == 8 && strncmp(make, "Phase", 5) && + strncmp(make, "Leaf", 4) && !strcasestr(make, "Kodak") && + !strstr(model2, "DEBUG RAW"))) && + !strcasestr(model, "COOLSCAN") && strncmp(software, "Nikon Scan", 10) && + is_NikonTransfer != 2) + is_raw = 0; + + if (is_raw && raw >= 0 && tiff_ifd[raw].phint == 2 && tiff_ifd[raw].extrasamples > 0 && tiff_ifd[raw].samples > 3) + is_raw = 0; // SKIP RGB+Alpha IFDs + } + + INT64 fsizecheck = 0ULL; + + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS) + fsizecheck = ifp->size(); + else if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS) + && !strncasecmp(make,"Ricoh",5)) + fsizecheck = ifp->size(); + + for (i = 0; i < (int)tiff_nifds; i++) + if (i != raw && + (tiff_ifd[i].samples == max_samp || + (tiff_ifd[i].comp == 7 && + tiff_ifd[i].samples == 1)) /* Allow 1-bps JPEGs */ + && tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 && + tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892 && + unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && + tiff_ifd[i].comp != 34892) + { + if (fsizecheck > 0LL) + { + bool ok = true; + if (tiff_ifd[i].strip_byte_counts_count && tiff_ifd[i].strip_offsets_count) + for (int s = 0; s < MIN(tiff_ifd[i].strip_byte_counts_count, tiff_ifd[i].strip_offsets_count); s++) + { + if (tiff_ifd[i].strip_offsets[s] + tiff_ifd[i].strip_byte_counts[s] > fsizecheck) + { + ok = false; + break; + } + } + else if (tiff_ifd[i].bytes > 0) + if (tiff_ifd[i].offset + tiff_ifd[i].bytes > fsizecheck) + ok = false; + + if(!ok) + continue; + } + if ( (INT64(tiff_ifd[i].t_width) * INT64(tiff_ifd[i].t_height) / INT64(SQR(tiff_ifd[i].bps) + 1)) > + (INT64(thumb_width) * INT64(thumb_height) / INT64(SQR(thumb_misc) + 1)) ) + { + + thumb_width = tiff_ifd[i].t_width; + thumb_height = tiff_ifd[i].t_height; + thumb_offset = tiff_ifd[i].offset; + thumb_length = tiff_ifd[i].bytes; + thumb_misc = tiff_ifd[i].bps; + thm = i; + } + if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT && tiff_ifd[i].bytes > 0) + { + bool already = false; + for(int idx = 0; idx < imgdata.thumbs_list.thumbcount ; idx++) + if (imgdata.thumbs_list.thumblist[idx].toffset == tiff_ifd[i].offset) + { + already = true; + break; + } + if (!already) + { + int idx = imgdata.thumbs_list.thumbcount; + imgdata.thumbs_list.thumblist[idx].tformat = tiff2thumbformat(tiff_ifd[i].comp, tiff_ifd[i].phint, + tiff_ifd[i].bps, make); + imgdata.thumbs_list.thumblist[idx].twidth = tiff_ifd[i].t_width; + imgdata.thumbs_list.thumblist[idx].theight = tiff_ifd[i].t_height; + imgdata.thumbs_list.thumblist[idx].tflip = tiff_ifd[i].t_flip; + imgdata.thumbs_list.thumblist[idx].tlength = tiff_ifd[i].bytes; + imgdata.thumbs_list.thumblist[idx].tmisc = tiff_ifd[i].bps | (tiff_ifd[i].samples << 5); + imgdata.thumbs_list.thumblist[idx].toffset = tiff_ifd[i].offset; + imgdata.thumbs_list.thumbcount++; + } + } + } + if (thm >= 0) + { + thumb_misc |= tiff_ifd[thm].samples << 5; + thumb_format = tiff2thumbformat(tiff_ifd[thm].comp, tiff_ifd[thm].phint, tiff_ifd[thm].bps, make); + } +} + +static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make) +{ + switch (_comp) + { + case 0: + return LIBRAW_INTERNAL_THUMBNAIL_LAYER; + case 1: + if (_bps <= 8) + return LIBRAW_INTERNAL_THUMBNAIL_PPM; + else if (!strncmp(_make, "Imacon", 6)) + return LIBRAW_INTERNAL_THUMBNAIL_PPM16; + else + return LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB; + case 65000: + return _phint == 6 ? LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR : LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB; + } + return LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default +} diff --git a/src/postprocessing/aspect_ratio.cpp b/src/postprocessing/aspect_ratio.cpp new file mode 100644 index 000000000..7e0dfd098 --- /dev/null +++ b/src/postprocessing/aspect_ratio.cpp @@ -0,0 +1,113 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::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; + fuji_width = (fuji_width - 1 + shrink) >> shrink; + step = sqrt(0.5); + wide = fuji_width / step; + high = (height - fuji_width) / step; + + // All real fuji/rotated images are small, so check against max_raw_memory_mb here is safe + if (INT64(wide) * INT64(high) * INT64(sizeof(*img)) > + INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) + throw LIBRAW_EXCEPTION_TOOBIG; + + img = (ushort(*)[4])calloc(high, wide * sizeof *img); + + RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2); + + 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 > (unsigned)height - 2 || uc > (unsigned)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; + RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2); +} + +void LibRaw::stretch() +{ + ushort newdim, (*img)[4], *pix0, *pix1; + int row, col, c; + double rc, frac; + + if (pixel_aspect == 1) + return; + RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 0, 2); + if (pixel_aspect < 1) + { + newdim = height / pixel_aspect + 0.5; + img = (ushort(*)[4])calloc(width, newdim * sizeof *img); + 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); + 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; + RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 1, 2); +} diff --git a/src/postprocessing/dcraw_process.cpp b/src/postprocessing/dcraw_process.cpp new file mode 100644 index 000000000..e8eff1317 --- /dev/null +++ b/src/postprocessing/dcraw_process.cpp @@ -0,0 +1,259 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +int LibRaw::dcraw_process(void) +{ + int quality, i; + + int iterations = -1, dcb_enhance = 1, noiserd = 0; + float preser = 0; + float expos = 1.0; + + CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); + // CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE); + + try + { + + int no_crop = 1; + + if (~O.cropbox[2] && ~O.cropbox[3]) + no_crop = 0; + + libraw_decoder_info_t di; + get_decoder_info(&di); + + bool is_bayer = (imgdata.idata.filters || P1.colors == 1); + int subtract_inline = + !O.bad_pixels && !O.dark_frame && is_bayer && !IO.zero_is_bad; + + int rc = raw2image_ex(subtract_inline); // allocate imgdata.image and copy data! + if (rc != LIBRAW_SUCCESS) + return rc; + + // Adjust sizes + + int save_4color = O.four_color_rgb; + + if (IO.zero_is_bad) + { + remove_zeroes(); + SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES); + } + + if (O.bad_pixels && no_crop) + { + bad_pixels(O.bad_pixels); + SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS); + } + + if (O.dark_frame && no_crop) + { + subtract(O.dark_frame); + SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME); + } + /* pre subtract black callback: check for it above to disable subtract + * inline */ + + if (callbacks.pre_subtractblack_cb) + (callbacks.pre_subtractblack_cb)(this); + + quality = 2 + !IO.fuji_width; + + if (O.user_qual >= 0) + quality = O.user_qual; + + if (!subtract_inline || !C.data_maximum) + { + adjust_bl(); + subtract_black_internal(); + } + + if (!(di.decoder_flags & LIBRAW_DECODER_FIXEDMAXC)) + adjust_maximum(); + + if (O.user_sat > 0) + C.maximum = O.user_sat; + + if (P1.is_foveon) + { + if (load_raw == &LibRaw::x3f_load_raw) + { + // Filter out zeroes + for (int q = 0; q < S.height * S.width; q++) + { + for (int c = 0; c < 4; c++) + if ((short)imgdata.image[q][c] < 0) + imgdata.image[q][c] = 0; + } + } + SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE); + } + + if (O.green_matching && !O.half_size) + { + green_matching(); + } + + if (callbacks.pre_scalecolors_cb) + (callbacks.pre_scalecolors_cb)(this); + + if (!O.no_auto_scale) + { + scale_colors(); + SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS); + } + + if (callbacks.pre_preinterpolate_cb) + (callbacks.pre_preinterpolate_cb)(this); + + pre_interpolate(); + + SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE); + + if (O.dcb_iterations >= 0) + iterations = O.dcb_iterations; + if (O.dcb_enhance_fl >= 0) + dcb_enhance = O.dcb_enhance_fl; + if (O.fbdd_noiserd >= 0) + noiserd = O.fbdd_noiserd; + + /* pre-exposure correction callback */ + + if (O.exp_correc > 0) + { + expos = O.exp_shift; + preser = O.exp_preser; + exp_bef(expos, preser); + } + + if (callbacks.pre_interpolate_cb) + (callbacks.pre_interpolate_cb)(this); + + /* post-exposure correction fallback */ + if (P1.filters && !O.no_interpolation) + { + if (noiserd > 0 && P1.colors == 3 && P1.filters > 1000) + fbdd(noiserd); + + if (P1.filters > 1000 && callbacks.interpolate_bayer_cb) + (callbacks.interpolate_bayer_cb)(this); + else if (P1.filters == 9 && callbacks.interpolate_xtrans_cb) + (callbacks.interpolate_xtrans_cb)(this); + else if (quality == 0) + lin_interpolate(); + else if (quality == 1 || P1.colors > 3) + vng_interpolate(); + else if (quality == 2 && P1.filters > 1000) + ppg_interpolate(); + else if (P1.filters == LIBRAW_XTRANS) + { + // Fuji X-Trans + xtrans_interpolate(quality > 2 ? 3 : 1); + } + else if (quality == 3) + ahd_interpolate(); // really don't need it here due to fallback op + else if (quality == 4) + dcb(iterations, dcb_enhance); + + else if (quality == 11) + dht_interpolate(); + else if (quality == 12) + aahd_interpolate(); + // fallback to AHD + else + { + ahd_interpolate(); + imgdata.process_warnings |= LIBRAW_WARN_FALLBACK_TO_AHD; + } + + SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE); + } + if (IO.mix_green) + { + for (P1.colors = 3, i = 0; i < S.height * S.width; i++) + imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1; + SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN); + } + + if (callbacks.post_interpolate_cb) + (callbacks.post_interpolate_cb)(this); + else if (!P1.is_foveon && P1.colors == 3 && O.med_passes > 0) + { + median_filter(); + SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER); + } + + if (O.highlight == 2) + { + blend_highlights(); + SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); + } + + if (O.highlight > 2) + { + recover_highlights(); + SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS); + } + + if (O.use_fuji_rotate) + { + fuji_rotate(); + SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); + } + + if (!libraw_internal_data.output_data.histogram) + { + libraw_internal_data.output_data.histogram = + (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc( + sizeof(*libraw_internal_data.output_data.histogram) * 4); + } +#ifndef NO_LCMS + if (O.camera_profile) + { + apply_profile(O.camera_profile, O.output_profile); + SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE); + } +#endif + + if (callbacks.pre_converttorgb_cb) + (callbacks.pre_converttorgb_cb)(this); + + convert_to_rgb(); + SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB); + + if (callbacks.post_converttorgb_cb) + (callbacks.post_converttorgb_cb)(this); + + if (O.use_fuji_rotate) + { + stretch(); + SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH); + } + O.four_color_rgb = save_4color; // also, restore + + return 0; + } + catch (const std::bad_alloc&) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } +} diff --git a/src/postprocessing/mem_image.cpp b/src/postprocessing/mem_image.cpp new file mode 100644 index 000000000..9f70d671b --- /dev/null +++ b/src/postprocessing/mem_image.cpp @@ -0,0 +1,292 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *errcode) +{ + if (!T.thumb) + { + if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && + load_raw == &LibRaw::broadcom_load_raw) // RPi + ) + { + if (errcode) + *errcode = LIBRAW_NO_THUMBNAIL; + } + else + { + if (errcode) + *errcode = LIBRAW_OUT_OF_ORDER_CALL; + } + return NULL; + } + + if (T.tlength < 64u) + { + if (errcode) + *errcode = EINVAL; + return NULL; + } + + if (INT64(T.tlength) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) + { + if (errcode) + *errcode = LIBRAW_TOO_BIG; + return NULL; + } + + if (T.tformat == LIBRAW_THUMBNAIL_BITMAP) + { + libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( + sizeof(libraw_processed_image_t) + T.tlength); + + if (!ret) + { + if (errcode) + *errcode = ENOMEM; + return NULL; + } + + memset(ret, 0, sizeof(libraw_processed_image_t)); + ret->type = LIBRAW_IMAGE_BITMAP; + ret->height = T.theight; + ret->width = T.twidth; + if (T.tcolors > 0 && T.tcolors < 4) + ret->colors = T.tcolors; + else + ret->colors = 3; // defaults + ret->bits = 8; + ret->data_size = T.tlength; + memmove(ret->data, T.thumb, T.tlength); + if (errcode) + *errcode = 0; + return ret; + } + else if (T.tformat == LIBRAW_THUMBNAIL_JPEG) + { + ushort exif[5]; + int mk_exif = 0; + if (strcmp(T.thumb + 6, "Exif")) + mk_exif = 1; + + int dsize = T.tlength + mk_exif * (sizeof(exif) + sizeof(tiff_hdr)); + + libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( + sizeof(libraw_processed_image_t) + dsize); + + if (!ret) + { + if (errcode) + *errcode = ENOMEM; + return NULL; + } + + memset(ret, 0, sizeof(libraw_processed_image_t)); + + ret->type = LIBRAW_IMAGE_JPEG; + ret->data_size = dsize; + + ret->data[0] = 0xff; + ret->data[1] = 0xd8; + if (mk_exif) + { + struct tiff_hdr th; + memcpy(exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons(8 + sizeof th); + memmove(ret->data + 2, exif, sizeof(exif)); + tiff_head(&th, 0); + memmove(ret->data + (2 + sizeof(exif)), &th, sizeof(th)); + memmove(ret->data + (2 + sizeof(exif) + sizeof(th)), T.thumb + 2, + T.tlength - 2); + } + else + { + memmove(ret->data + 2, T.thumb + 2, T.tlength - 2); + } + if (errcode) + *errcode = 0; + return ret; + } + else + { + if (errcode) + *errcode = LIBRAW_UNSUPPORTED_THUMBNAIL; + return NULL; + } +} + +// jlb +// macros for copying pixels to either BGR or RGB formats +#define FORBGR for (c = P1.colors - 1; c >= 0; c--) +#define FORRGB for (c = 0; c < P1.colors; c++) + +void LibRaw::get_mem_image_format(int *width, int *height, int *colors, + int *bps) const + +{ + *width = S.width; + *height = S.height; + if (imgdata.progress_flags < LIBRAW_PROGRESS_FUJI_ROTATE) + { + if (O.use_fuji_rotate) + { + if (IO.fuji_width) + { + int fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink; + *width = (ushort)(fuji_width / sqrt(0.5)); + *height = (ushort)((*height - fuji_width) / sqrt(0.5)); + } + else + { + if (S.pixel_aspect < 0.995) + *height = (ushort)(*height / S.pixel_aspect + 0.5); + if (S.pixel_aspect > 1.005) + *width = (ushort)(*width * S.pixel_aspect + 0.5); + } + } + } + if (S.flip & 4) + { + std::swap(*width, *height); + } + *colors = P1.colors; + *bps = O.output_bps; +} + +int LibRaw::copy_mem_image(void *scan0, int stride, int bgr) + +{ + // the image memory pointed to by scan0 is assumed to be in the format + // returned by get_mem_image_format + if ((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < + LIBRAW_PROGRESS_PRE_INTERPOLATE) + return LIBRAW_OUT_OF_ORDER_CALL; + + if (libraw_internal_data.output_data.histogram) + { + int perc, val, total, t_white = 0x2000, c; + perc = S.width * S.height * O.auto_bright_thr; + if (IO.fuji_width) + perc /= 2; + if (!((O.highlight & ~2) || O.no_auto_bright)) + for (t_white = c = 0; c < P1.colors; c++) + { + for (val = 0x2000, total = 0; --val > 32;) + if ((total += libraw_internal_data.output_data.histogram[c][val]) > + perc) + break; + if (t_white < val) + t_white = val; + } + gamma_curve(O.gamm[0], O.gamm[1], 2, (t_white << 3) / O.bright); + } + + int s_iheight = S.iheight; + int s_iwidth = S.iwidth; + int s_width = S.width; + int s_hwight = S.height; + + S.iheight = S.height; + S.iwidth = S.width; + + if (S.flip & 4) + SWAP(S.height, S.width); + uchar *ppm; + ushort *ppm2; + int c, row, col, soff, rstep, cstep; + + soff = flip_index(0, 0); + cstep = flip_index(0, 1) - soff; + rstep = flip_index(1, 0) - flip_index(0, S.width); + + for (row = 0; row < S.height; row++, soff += rstep) + { + uchar *bufp = ((uchar *)scan0) + row * stride; + ppm2 = (ushort *)(ppm = bufp); + // keep trivial decisions in the outer loop for speed + if (bgr) + { + if (O.output_bps == 8) + { + for (col = 0; col < S.width; col++, soff += cstep) + FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]] >> 8; + } + else + { + for (col = 0; col < S.width; col++, soff += cstep) + FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]]; + } + } + else + { + if (O.output_bps == 8) + { + for (col = 0; col < S.width; col++, soff += cstep) + FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]] >> 8; + } + else + { + for (col = 0; col < S.width; col++, soff += cstep) + FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]]; + } + } + + // bufp += stride; // go to the next line + } + + S.iheight = s_iheight; + S.iwidth = s_iwidth; + S.width = s_width; + S.height = s_hwight; + + return 0; +} +#undef FORBGR +#undef FORRGB + +libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode) + +{ + int width, height, colors, bps; + get_mem_image_format(&width, &height, &colors, &bps); + int stride = width * (bps / 8) * colors; + unsigned ds = height * stride; + libraw_processed_image_t *ret = (libraw_processed_image_t *)::malloc( + sizeof(libraw_processed_image_t) + ds); + if (!ret) + { + if (errcode) + *errcode = ENOMEM; + return NULL; + } + memset(ret, 0, sizeof(libraw_processed_image_t)); + + // metadata init + ret->type = LIBRAW_IMAGE_BITMAP; + ret->height = height; + ret->width = width; + ret->colors = colors; + ret->bits = bps; + ret->data_size = ds; + copy_mem_image(ret->data, stride, 0); + + return ret; +} + +void LibRaw::dcraw_clear_mem(libraw_processed_image_t *p) +{ + if (p) + ::free(p); +} diff --git a/src/postprocessing/postprocessing_aux.cpp b/src/postprocessing/postprocessing_aux.cpp new file mode 100644 index 000000000..57473400d --- /dev/null +++ b/src/postprocessing/postprocessing_aux.cpp @@ -0,0 +1,406 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::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))]; +} + +#if !defined(LIBRAW_USE_OPENMP) +void LibRaw::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.8002f, 0.2735f, 0.1202f, 0.0585f, + 0.0291f, 0.0152f, 0.0080f, 0.0044f}; + + + 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 + 128) * sizeof *fimg); + 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((double)(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((double)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); +} +#else /* LIBRAW_USE_OPENMP */ +void LibRaw::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}; + + 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); + temp = fimg + size * 3; + if ((nc = colors) == 3 && filters) + nc++; +#pragma omp parallel default(shared) private( \ + i, col, row, thold, lev, lpass, hpass, temp, c) firstprivate(scale, size) + { + temp = (float *)malloc((iheight + iwidth) * sizeof *fimg); + FORC(nc) + { /* denoise R,G1,B,G3 individually */ +#pragma omp for + for (i = 0; i < size; i++) + fimg[i] = 256 * sqrt((double)(image[i][c] << scale)); + for (hpass = lev = 0; lev < 5; lev++) + { + lpass = size * ((lev & 1) + 1); +#pragma omp for + 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; + } +#pragma omp for + 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]; +#pragma omp for + 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; + } +#pragma omp for + for (i = 0; i < size; i++) + image[i][c] = CLIP(SQR(fimg[i] + fimg[lpass + i]) / 0x10000); + } + free(temp); + } /* end omp parallel */ + /* the following loops are hard to parallelize, no idea yes, + * problem is wlast which is carrying dependency + * second part should be easier, but did not yet get it right. + */ + 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((double)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); +} + +#endif +void LibRaw::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++) + { + RUN_CALLBACK(LIBRAW_PROGRESS_MEDIAN_FILTER, pass - 1, med_passes); + 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 < int(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 LibRaw::blend_highlights() +{ + int clip = INT_MAX, row, col, c, i, j; + static const float trans[2][4][4] = { + {{1, 1, 1}, {1.7320508f, -1.7320508f, 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.8660254f, -0.5}, {1, -0.8660254f, -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; + RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, 0, 2); + 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; + } + RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, 1, 2); +} + +#define SCALE (4 >> shrink) +void LibRaw::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}}; + + grow = pow(2.0, 4 - highlight); + FORC(unsigned(colors)) hsat[c] = 32000 * pre_mul[c]; + for (kc = 0, c = 1; c < (unsigned)colors; c++) + if (pre_mul[kc] < pre_mul[c]) + kc = c; + high = height / SCALE; + wide = width / SCALE; + map = (float *)calloc(high, wide * sizeof *map); + FORC(unsigned(colors)) if (c != kc) + { + RUN_CALLBACK(LIBRAW_PROGRESS_HIGHLIGHTS, c - 1, colors - 1); + 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 < int(high * wide); i++) + if (map[i] < 0) + { + map[i] = -map[i]; + change = 1; + } + if (!change) + break; + } + for (i = 0; i < int(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 diff --git a/src/postprocessing/postprocessing_ph.cpp b/src/postprocessing/postprocessing_ph.cpp new file mode 100644 index 000000000..3af0939dd --- /dev/null +++ b/src/postprocessing/postprocessing_ph.cpp @@ -0,0 +1,31 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + Placeholder functions to build LibRaw w/o postprocessing tools + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +int LibRaw::dcraw_process(void) +{ + return LIBRAW_NOT_IMPLEMENTED; +} + +void LibRaw::fuji_rotate() {} +void LibRaw::convert_to_rgb_loop(float /*out_cam*/ [3][4]) {} +libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *) { + return NULL; +} +libraw_processed_image_t *LibRaw::dcraw_make_mem_thumb(int *){ return NULL;} +void LibRaw::lin_interpolate_loop(int * /*code*/, int /*size*/) {} +void LibRaw::scale_colors_loop(float /*scale_mul*/[4]) {} diff --git a/src/postprocessing/postprocessing_utils.cpp b/src/postprocessing/postprocessing_utils.cpp new file mode 100644 index 000000000..986b5bbfa --- /dev/null +++ b/src/postprocessing/postprocessing_utils.cpp @@ -0,0 +1,190 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#define TBLN 65535 + +void LibRaw::exp_bef(float shift, float smooth) +{ + // params limits + if (shift > 8) + shift = 8; + if (shift < 0.25) + shift = 0.25; + if (smooth < 0.0) + smooth = 0.0; + if (smooth > 1.0) + smooth = 1.0; + + unsigned short *lut = (ushort *)malloc((TBLN + 1) * sizeof(unsigned short)); + + if (shift <= 1.0) + { + for (int i = 0; i <= TBLN; i++) + lut[i] = (unsigned short)((float)i * shift); + } + else + { + float x1, x2, y1, y2; + + float cstops = log(shift) / log(2.0f); + float room = cstops * 2; + float roomlin = powf(2.0f, room); + x2 = (float)TBLN; + x1 = (x2 + 1) / roomlin - 1; + y1 = x1 * shift; + y2 = x2 * (1 + (1 - smooth) * (shift - 1)); + float sq3x = powf(x1 * x1 * x2, 1.0f / 3.0f); + float B = (y2 - y1 + shift * (3 * x1 - 3.0f * sq3x)) / + (x2 + 2.0f * x1 - 3.0f * sq3x); + float A = (shift - B) * 3.0f * powf(x1 * x1, 1.0f / 3.0f); + float CC = y2 - A * powf(x2, 1.0f / 3.0f) - B * x2; + for (int i = 0; i <= TBLN; i++) + { + float X = (float)i; + float Y = A * powf(X, 1.0f / 3.0f) + B * X + CC; + if (i < x1) + lut[i] = (unsigned short)((float)i * shift); + else + lut[i] = Y < 0 ? 0 : (Y > TBLN ? TBLN : (unsigned short)(Y)); + } + } + for (int i = 0; i < S.height * S.width; i++) + { + imgdata.image[i][0] = lut[imgdata.image[i][0]]; + imgdata.image[i][1] = lut[imgdata.image[i][1]]; + imgdata.image[i][2] = lut[imgdata.image[i][2]]; + imgdata.image[i][3] = lut[imgdata.image[i][3]]; + } + + if (C.data_maximum <= TBLN) + C.data_maximum = lut[C.data_maximum]; + if (C.maximum <= TBLN) + C.maximum = lut[C.maximum]; + free(lut); +} + +void LibRaw::convert_to_rgb_loop(float out_cam[3][4]) +{ + int row, col, c; + float out[3]; + ushort *img; + memset(libraw_internal_data.output_data.histogram, 0, + sizeof(int) * LIBRAW_HISTOGRAM_SIZE * 4); + if (libraw_internal_data.internal_output_params.raw_color) + { + for (img = imgdata.image[0], row = 0; row < S.height; row++) + { + for (col = 0; col < S.width; col++, img += 4) + { + for (c = 0; c < imgdata.idata.colors; c++) + { + libraw_internal_data.output_data.histogram[c][img[c] >> 3]++; + } + } + } + } + else if (imgdata.idata.colors == 3) + { + for (img = imgdata.image[0], row = 0; row < S.height; row++) + { + for (col = 0; col < S.width; col++, img += 4) + { + out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] + + out_cam[0][2] * img[2]; + out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] + + out_cam[1][2] * img[2]; + out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] + + out_cam[2][2] * img[2]; + img[0] = CLIP((int)out[0]); + img[1] = CLIP((int)out[1]); + img[2] = CLIP((int)out[2]); + libraw_internal_data.output_data.histogram[0][img[0] >> 3]++; + libraw_internal_data.output_data.histogram[1][img[1] >> 3]++; + libraw_internal_data.output_data.histogram[2][img[2] >> 3]++; + } + } + } + else if (imgdata.idata.colors == 4) + { + for (img = imgdata.image[0], row = 0; row < S.height; row++) + { + for (col = 0; col < S.width; col++, img += 4) + { + out[0] = out_cam[0][0] * img[0] + out_cam[0][1] * img[1] + + out_cam[0][2] * img[2] + out_cam[0][3] * img[3]; + out[1] = out_cam[1][0] * img[0] + out_cam[1][1] * img[1] + + out_cam[1][2] * img[2] + out_cam[1][3] * img[3]; + out[2] = out_cam[2][0] * img[0] + out_cam[2][1] * img[1] + + out_cam[2][2] * img[2] + out_cam[2][3] * img[3]; + img[0] = CLIP((int)out[0]); + img[1] = CLIP((int)out[1]); + img[2] = CLIP((int)out[2]); + libraw_internal_data.output_data.histogram[0][img[0] >> 3]++; + libraw_internal_data.output_data.histogram[1][img[1] >> 3]++; + libraw_internal_data.output_data.histogram[2][img[2] >> 3]++; + libraw_internal_data.output_data.histogram[3][img[3] >> 3]++; + } + } + } +} + +void LibRaw::scale_colors_loop(float scale_mul[4]) +{ + unsigned size = S.iheight * S.iwidth; + + if (C.cblack[4] && C.cblack[5]) + { + int val; + for (unsigned i = 0; i < size; i++) + { + for (unsigned c = 0; c < 4; c++) + { + if (!(val = imgdata.image[i][c])) continue; + val -= C.cblack[6 + i / S.iwidth % C.cblack[4] * C.cblack[5] + + i % S.iwidth % C.cblack[5]]; + val -= C.cblack[c]; + val *= scale_mul[c]; + imgdata.image[i][c] = CLIP(val); + } + } + } + else if (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3]) + { + for (unsigned i = 0; i < size; i++) + { + for (unsigned c = 0; c < 4; c++) + { + int val = imgdata.image[i][c]; + if (!val) continue; + val -= C.cblack[c]; + val *= scale_mul[c]; + imgdata.image[i][c] = CLIP(val); + } + } + } + else // BL is zero + { + for (unsigned i = 0; i < size; i++) + { + for (unsigned c = 0; c < 4; c++) + { + int val = imgdata.image[i][c]; + val *= scale_mul[c]; + imgdata.image[i][c] = CLIP(val); + } + } + } +} diff --git a/src/postprocessing/postprocessing_utils_dcrdefs.cpp b/src/postprocessing/postprocessing_utils_dcrdefs.cpp new file mode 100644 index 000000000..98ea0618e --- /dev/null +++ b/src/postprocessing/postprocessing_utils_dcrdefs.cpp @@ -0,0 +1,308 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::convert_to_rgb() +{ + float out_cam[3][4]; + double num, inverse[3][3]; + static const double(*out_rgb[])[3] = { + LibRaw_constants::rgb_rgb, LibRaw_constants::adobe_rgb, + LibRaw_constants::wide_rgb, LibRaw_constants::prophoto_rgb, + LibRaw_constants::xyz_rgb, LibRaw_constants::aces_rgb, + LibRaw_constants::dcip3d65_rgb, LibRaw_constants::rec2020_rgb}; + static const char *name[] = {"sRGB", "Adobe RGB (1998)", + "WideGamut D65", "ProPhoto D65", + "XYZ", "ACES", + "DCI-P3 D65", "Rec. 2020"}; + 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, 60, /* desc, len is strlen(longest_string) + 12 */ + 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}; + + RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 0, 2); + + gamma_curve(gamm[0], gamm[1], 0, 0); + memcpy(out_cam, rgb_cam, sizeof out_cam); + raw_color |= colors == 1 || output_color < 1 || output_color > 8; + if (!raw_color) + { + size_t prof_desc_len; + std::vector prof_desc; + int i, j, k; + prof_desc_len = snprintf(NULL, 0, "%s gamma %g toe slope %g", name[output_color - 1], + floorf(1000.f / gamm[0] + .5f) / 1000.f, floorf(gamm[1] * 1000.0f + .5f) / 1000.f) + + 1; + prof_desc.resize(prof_desc_len); + sprintf(prof_desc.data(), "%s gamma %g toe slope %g", name[output_color - 1], floorf(1000.f / gamm[0] + .5f) / 1000.f, + floorf(gamm[1] * 1000.0f + .5f) / 1000.f); + + oprof = (unsigned *)calloc(phead[0], 1); + memcpy(oprof, phead, sizeof phead); + if (output_color == 5) + oprof[4] = oprof[5]; + oprof[0] = 132 + 12 * pbody[0]; + for (i = 0; i < (int)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] = unsigned(prof_desc_len + 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 += LibRaw_constants::xyzd50_srgb[i][k] * inverse[j][k]; + oprof[pbody[j * 3 + 23] / 4 + i + 2] = num * 0x10000 + 0.5; + } + for (i = 0; i < (int)phead[0] / 4; i++) + oprof[i] = htonl(oprof[i]); + strcpy((char *)oprof + pbody[2] + 8, "auto-generated by dcraw"); + if (pbody[5] + 12 + prof_desc.size() < phead[0]) + strcpy((char *)oprof + pbody[5] + 12, prof_desc.data()); + 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]; + } + convert_to_rgb_loop(out_cam); + + if (colors == 4 && output_color) + colors = 3; + + RUN_CALLBACK(LIBRAW_PROGRESS_CONVERT_RGB, 1, 2); +} + +void LibRaw::scale_colors() +{ + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; + int val; + double dsum[8], dmin, dmax; + float scale_mul[4], fr, fc; + ushort *img = 0, *pix; + + RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 0, 2); + + if (user_mul[0]) + memcpy(pre_mul, user_mul, sizeof pre_mul); + if (use_auto_wb || (use_camera_wb && + (cam_mul[0] < -0.5 // LibRaw 0.19 and older: fallback to auto only if cam_mul[0] is set to -1 + || (cam_mul[0] <= 0.00001f // New default: fallback to auto if no cam_mul parsed from metadata + && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CAMERAWB_FALLBACK_TO_DAYLIGHT)) + ))) + { + 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 > (int)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] > 0.00001f) + { + 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 (imgdata.color.as_shot_wb_applied) + { + // Nikon sRAW: camera WB already applied: + pre_mul[0] = pre_mul[1] = pre_mul[2] = pre_mul[3] = 1.0; + } + else if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = (float)sum[c + 4] / sum[c]; + else if (cam_mul[0] > 0.00001f && cam_mul[2] > 0.00001f) + memcpy(pre_mul, cam_mul, sizeof pre_mul); + else + { + imgdata.process_warnings |= LIBRAW_WARN_BAD_CAMERA_WB; + } + } + // Nikon sRAW, daylight + if (imgdata.color.as_shot_wb_applied && !use_camera_wb && !use_auto_wb && + cam_mul[0] > 0.00001f && cam_mul[1] > 0.00001f && cam_mul[2] > 0.00001f) + { + for (c = 0; c < 3; c++) + pre_mul[c] /= cam_mul[c]; + } + if (pre_mul[1] == 0) + pre_mul[1] = 1; + if (pre_mul[3] == 0) + pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + 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; + if (dmax > 0.00001 && maximum > 0) + FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; + else + FORC4 scale_mul[c] = 1.0; + + if (filters > 1000 && (cblack[4] + 1) / 2 == 1 && (cblack[5] + 1) / 2 == 1) + { + FORC4 cblack[FC(c / 2, c % 2)] += + cblack[6 + c / 2 % cblack[4] * cblack[5] + c % 2 % cblack[5]]; + cblack[4] = cblack[5] = 0; + } + size = iheight * iwidth; + scale_colors_loop(scale_mul); + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) + { + for (c = 0; c < 4; c += 2) + { + if (aber[c] == 1) + continue; + img = (ushort *)malloc(size * sizeof *img); + 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 > (unsigned)iheight - 2) + continue; + fr -= ur; + for (col = 0; col < iwidth; col++) + { + uc = fc = (col - iwidth * 0.5) * aber[c] + iwidth * 0.5; + if (uc > (unsigned)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); + } + } + RUN_CALLBACK(LIBRAW_PROGRESS_SCALE_COLORS, 1, 2); +} + +// green equilibration +void LibRaw::green_matching() +{ + int i, j; + double m1, m2, c1, c2; + int o1_1, o1_2, o1_3, o1_4; + int o2_1, o2_2, o2_3, o2_4; + ushort(*img)[4]; + const int margin = 3; + int oj = 2, oi = 2; + float f; + const float thr = 0.01f; + if (half_size || shrink) + return; + if (FC(oj, oi) != 3) + oj++; + if (FC(oj, oi) != 3) + oi++; + if (FC(oj, oi) != 3) + oj--; + + img = (ushort(*)[4])calloc(height * width, sizeof *image); + memcpy(img, image, height * width * sizeof *image); + + for (j = oj; j < height - margin; j += 2) + for (i = oi; i < width - margin; i += 2) + { + o1_1 = img[(j - 1) * width + i - 1][1]; + o1_2 = img[(j - 1) * width + i + 1][1]; + o1_3 = img[(j + 1) * width + i - 1][1]; + o1_4 = img[(j + 1) * width + i + 1][1]; + o2_1 = img[(j - 2) * width + i][3]; + o2_2 = img[(j + 2) * width + i][3]; + o2_3 = img[j * width + i - 2][3]; + o2_4 = img[j * width + i + 2][3]; + + m1 = (o1_1 + o1_2 + o1_3 + o1_4) / 4.0; + m2 = (o2_1 + o2_2 + o2_3 + o2_4) / 4.0; + + c1 = (abs(o1_1 - o1_2) + abs(o1_1 - o1_3) + abs(o1_1 - o1_4) + + abs(o1_2 - o1_3) + abs(o1_3 - o1_4) + abs(o1_2 - o1_4)) / + 6.0; + c2 = (abs(o2_1 - o2_2) + abs(o2_1 - o2_3) + abs(o2_1 - o2_4) + + abs(o2_2 - o2_3) + abs(o2_3 - o2_4) + abs(o2_2 - o2_4)) / + 6.0; + if ((img[j * width + i][3] < maximum * 0.95) && (c1 < maximum * thr) && + (c2 < maximum * thr)) + { + f = image[j * width + i][3] * m1 / m2; + image[j * width + i][3] = f > 0xffff ? 0xffff : f; + } + } + free(img); +} diff --git a/src/preprocessing/ext_preprocess.cpp b/src/preprocessing/ext_preprocess.cpp new file mode 100644 index 000000000..8f2ec4957 --- /dev/null +++ b/src/preprocessing/ext_preprocess.cpp @@ -0,0 +1,127 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_fileio_defs.h" + +/* + Search from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void LibRaw::bad_pixels(const char *cfname) +{ + FILE *fp = NULL; + char *cp, line[128]; + int time, row, col, r, c, rad, tot, n; + + if (!filters) + return; + RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 0, 2); + if (cfname) + fp = fopen(cfname, "r"); + if (!fp) + { + imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP; + 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++; + } + if (n > 0) + BAYER2(row, col) = tot / n; + } + fclose(fp); + RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS, 1, 2); +} + +void LibRaw::subtract(const char *fname) +{ + FILE *fp; + int dim[3] = {0, 0, 0}, comment = 0, number = 0, error = 0, nd = 0, c, row, + col; + RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 0, 2); + + if (!(fp = fopen(fname, "rb"))) + { + imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE; + 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) + { + fclose(fp); + return; + } + else if (dim[0] != width || dim[1] != height || dim[2] != 65535) + { + imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM; + fclose(fp); + return; + } + std::vector pixel(width, 0); + for (row = 0; row < height; row++) + { + fread(pixel.data(), 2, width, fp); + for (col = 0; col < width; col++) + BAYER(row, col) = MAX(BAYER(row, col) - ntohs(pixel[col]), 0); + } + fclose(fp); + memset(cblack, 0, sizeof cblack); + black = 0; + RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME, 1, 2); +} diff --git a/src/preprocessing/preprocessing_ph.cpp b/src/preprocessing/preprocessing_ph.cpp new file mode 100644 index 000000000..44868ed55 --- /dev/null +++ b/src/preprocessing/preprocessing_ph.cpp @@ -0,0 +1,24 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + Placeholder functions to build LibRaw w/o postprocessing + and preprocessing calls + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +void LibRaw::copy_fuji_uncropped(unsigned short /*cblack*/[4], + unsigned short * /*dmaxp*/) {} +void LibRaw::copy_bayer(unsigned short /*cblack*/[4], unsigned short * /*dmaxp*/){} +void LibRaw::raw2image_start(){} + diff --git a/src/preprocessing/raw2image.cpp b/src/preprocessing/raw2image.cpp new file mode 100644 index 000000000..e65e2ad73 --- /dev/null +++ b/src/preprocessing/raw2image.cpp @@ -0,0 +1,558 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +void LibRaw::raw2image_start() +{ + // restore color,sizes and internal data into raw_image fields + memmove(&imgdata.color, &imgdata.rawdata.color, sizeof(imgdata.color)); + memmove(&imgdata.sizes, &imgdata.rawdata.sizes, sizeof(imgdata.sizes)); + memmove(&imgdata.idata, &imgdata.rawdata.iparams, sizeof(imgdata.idata)); + memmove(&libraw_internal_data.internal_output_params, + &imgdata.rawdata.ioparams, + sizeof(libraw_internal_data.internal_output_params)); + + if (O.user_flip >= 0) + S.flip = O.user_flip; + + switch ((S.flip + 3600) % 360) + { + case 270: + S.flip = 5; + break; + case 180: + S.flip = 3; + break; + case 90: + S.flip = 6; + break; + } + + // adjust for half mode! + IO.shrink = + P1.filters && + (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); + + S.iheight = (S.height + IO.shrink) >> IO.shrink; + S.iwidth = (S.width + IO.shrink) >> IO.shrink; +} + +int LibRaw::raw2image(void) +{ + + CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); + + try + { + raw2image_start(); + + if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) + { + phase_one_allocate_tempbuffer(); + int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, + imgdata.rawdata.raw_image); + if (rc == 0) + rc = phase_one_correct(); + if (rc != 0) + { + phase_one_free_tempbuffer(); + return rc; + } + } + + // free and re-allocate image bitmap + if (imgdata.image) + { + imgdata.image = (ushort(*)[4])realloc( + imgdata.image, S.iheight * S.iwidth * sizeof(*imgdata.image)); + memset(imgdata.image, 0, S.iheight * S.iwidth * sizeof(*imgdata.image)); + } + else + imgdata.image = + (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image)); + + + libraw_decoder_info_t decoder_info; + get_decoder_info(&decoder_info); + + // Copy area size + int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); + int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); + + // Move saved bitmap to imgdata.image + if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) + { + if (IO.fuji_width) + { + unsigned r, c; + int row, col; + for (row = 0; row < S.raw_height - S.top_margin * 2; row++) + { + for (col = 0; + col < IO.fuji_width + << int(!libraw_internal_data.unpacker_data.fuji_layout); + col++) + { + if (libraw_internal_data.unpacker_data.fuji_layout) + { + r = IO.fuji_width - 1 - col + (row >> 1); + c = col + ((row + 1) >> 1); + } + else + { + r = IO.fuji_width - 1 + row - (col >> 1); + c = row + ((col + 1) >> 1); + } + if (r < S.height && c < S.width && col + int(S.left_margin) < int(S.raw_width)) + imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)] + [FC(r, c)] = + imgdata.rawdata + .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + + (col + S.left_margin)]; + } + } + } + else + { + int row, col; + for (row = 0; row < copyheight; row++) + for (col = 0; col < copywidth; col++) + imgdata.image[((row) >> IO.shrink) * S.iwidth + + ((col) >> IO.shrink)][fcol(row, col)] = + imgdata.rawdata + .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + + (col + S.left_margin)]; + } + } + else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) + { + if (imgdata.rawdata.color4_image) + { + if (S.width * 8u == S.raw_pitch && S.height == S.raw_height) + memmove(imgdata.image, imgdata.rawdata.color4_image, + S.width * S.height * sizeof(*imgdata.image)); + else + { + for (int row = 0; row < copyheight; row++) + memmove(&imgdata.image[row * S.width], + &imgdata.rawdata + .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + + S.left_margin], + copywidth * sizeof(*imgdata.image)); + } + } + else if (imgdata.rawdata.color3_image) + { + unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; + for (int row = 0; row < copyheight; row++) + { + ushort(*srcrow)[3] = + (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; + ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; + for (int col = 0; col < copywidth; col++) + { + for (int c = 0; c < 3; c++) + dstrow[col][c] = srcrow[S.left_margin + col][c]; + dstrow[col][3] = 0; + } + } + } + else + { + // legacy decoder, but no data? + throw LIBRAW_EXCEPTION_DECODE_RAW; + } + } + + // Free PhaseOne separate copy allocated at function start + if (is_phaseone_compressed()) + { + phase_one_free_tempbuffer(); + } + // hack - clear later flags! + + if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) + { + canon_600_correct(); + } + + imgdata.progress_flags = + LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | + LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | + LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; + return 0; + } + catch (const std::bad_alloc&) + { + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } +} + +void LibRaw::copy_fuji_uncropped(unsigned short cblack[4], + unsigned short *dmaxp) +{ +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(dynamic) default(none) firstprivate(cblack) shared(dmaxp) +#endif + for (int row = 0; row < int(S.raw_height) - int(S.top_margin) * 2; row++) + { + int col; + unsigned short ldmax = 0; + for (col = 0; + col < IO.fuji_width << int(!libraw_internal_data.unpacker_data.fuji_layout) + && col + int(S.left_margin) < int(S.raw_width); + col++) + { + unsigned r, c; + if (libraw_internal_data.unpacker_data.fuji_layout) + { + r = IO.fuji_width - 1 - col + (row >> 1); + c = col + ((row + 1) >> 1); + } + else + { + r = IO.fuji_width - 1 + row - (col >> 1); + c = row + ((col + 1) >> 1); + } + if (r < S.height && c < S.width) + { + unsigned short val = + imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + + (col + S.left_margin)]; + int cc = FC(r, c); + if (val > cblack[cc]) + { + val -= cblack[cc]; + if (val > ldmax) + ldmax = val; + } + else + val = 0; + imgdata.image[((r) >> IO.shrink) * S.iwidth + ((c) >> IO.shrink)][cc] = + val; + } + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp critical(dataupdate) +#endif + { + if (*dmaxp < ldmax) + *dmaxp = ldmax; + } + } +} + +void LibRaw::copy_bayer(unsigned short cblack[4], unsigned short *dmaxp) +{ + // Both cropped and uncropped + int maxHeight = MIN(int(S.height),int(S.raw_height)-int(S.top_margin)); +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for schedule(dynamic) default(none) shared(dmaxp) firstprivate(cblack, maxHeight) +#endif + for (int row = 0; row < maxHeight ; row++) + { + int col; + unsigned short ldmax = 0; + for (col = 0; col < S.width && col + S.left_margin < S.raw_width; col++) + { + unsigned short val = + imgdata.rawdata.raw_image[(row + S.top_margin) * S.raw_pitch / 2 + + (col + S.left_margin)]; + int cc = fcol(row, col); + if (val > cblack[cc]) + { + val -= cblack[cc]; + if (val > ldmax) + ldmax = val; + } + else + val = 0; + imgdata.image[((row) >> IO.shrink) * S.iwidth + ((col) >> IO.shrink)][cc] = val; + } +#if defined(LIBRAW_USE_OPENMP) +#pragma omp critical(dataupdate) +#endif + { + if (*dmaxp < ldmax) + *dmaxp = ldmax; + } + } +} + +int LibRaw::raw2image_ex(int do_subtract_black) +{ + + CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); + + try + { + raw2image_start(); + + // Compressed P1 files with bl data! + if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) + { + phase_one_allocate_tempbuffer(); + int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, + imgdata.rawdata.raw_image); + if (rc == 0) + rc = phase_one_correct(); + if (rc != 0) + { + phase_one_free_tempbuffer(); + return rc; + } + } + + // process cropping + int do_crop = 0; + if (~O.cropbox[2] && ~O.cropbox[3]) + { + int crop[4], c, filt; + for (int q = 0; q < 4; q++) + { + crop[q] = O.cropbox[q]; + if (crop[q] < 0) + crop[q] = 0; + } + + if (IO.fuji_width && imgdata.idata.filters >= 1000) + { + crop[0] = (crop[0] / 4) * 4; + crop[1] = (crop[1] / 4) * 4; + if (!libraw_internal_data.unpacker_data.fuji_layout) + { + crop[2] *= sqrt(2.0); + crop[3] /= sqrt(2.0); + } + crop[2] = (crop[2] / 4 + 1) * 4; + crop[3] = (crop[3] / 4 + 1) * 4; + } + else if (imgdata.idata.filters == 1) + { + crop[0] = (crop[0] / 16) * 16; + crop[1] = (crop[1] / 16) * 16; + } + else if (imgdata.idata.filters == LIBRAW_XTRANS) + { + crop[0] = (crop[0] / 6) * 6; + crop[1] = (crop[1] / 6) * 6; + } + do_crop = 1; + + crop[2] = MIN(crop[2], (signed)S.width - crop[0]); + crop[3] = MIN(crop[3], (signed)S.height - crop[1]); + if (crop[2] <= 0 || crop[3] <= 0) + throw LIBRAW_EXCEPTION_BAD_CROP; + + // adjust sizes! + S.left_margin += crop[0]; + S.top_margin += crop[1]; + S.width = crop[2]; + S.height = crop[3]; + + S.iheight = (S.height + IO.shrink) >> IO.shrink; + S.iwidth = (S.width + IO.shrink) >> IO.shrink; + if (!IO.fuji_width && imgdata.idata.filters && + imgdata.idata.filters >= 1000) + { + for (filt = c = 0; c < 16; c++) + filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; + imgdata.idata.filters = filt; + } + } + + int alloc_width = S.iwidth; + int alloc_height = S.iheight; + + if (IO.fuji_width && do_crop) + { + int IO_fw = S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); + int t_alloc_width = + (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO_fw; + int t_alloc_height = t_alloc_width - 1; + alloc_height = (t_alloc_height + IO.shrink) >> IO.shrink; + alloc_width = (t_alloc_width + IO.shrink) >> IO.shrink; + } + int alloc_sz = alloc_width * alloc_height; + + if (imgdata.image) + { + imgdata.image = (ushort(*)[4])realloc(imgdata.image, + alloc_sz * sizeof(*imgdata.image)); + memset(imgdata.image, 0, alloc_sz * sizeof(*imgdata.image)); + } + else + imgdata.image = (ushort(*)[4])calloc(alloc_sz, sizeof(*imgdata.image)); + + libraw_decoder_info_t decoder_info; + get_decoder_info(&decoder_info); + + // Adjust black levels + unsigned short cblack[4] = {0, 0, 0, 0}; + unsigned short dmax = 0; + if (do_subtract_black) + { + adjust_bl(); + for (int i = 0; i < 4; i++) + cblack[i] = (unsigned short)C.cblack[i]; + } + + // Max area size to definitely not overrun in/out buffers + int copyheight = MAX(0, MIN(int(S.height), int(S.raw_height) - int(S.top_margin))); + int copywidth = MAX(0, MIN(int(S.width), int(S.raw_width) - int(S.left_margin))); + + // Move saved bitmap to imgdata.image + if ((imgdata.idata.filters || P1.colors == 1) && imgdata.rawdata.raw_image) + { + if (IO.fuji_width) + { + if (do_crop) + { + IO.fuji_width = + S.width >> int(!libraw_internal_data.unpacker_data.fuji_layout); + int IO_fwidth = + (S.height >> int(libraw_internal_data.unpacker_data.fuji_layout)) + + IO.fuji_width; + int IO_fheight = IO_fwidth - 1; + + int row, col; + for (row = 0; row < S.height; row++) + { + for (col = 0; col < S.width; col++) + { + int r, c; + if (libraw_internal_data.unpacker_data.fuji_layout) + { + r = IO.fuji_width - 1 - col + (row >> 1); + c = col + ((row + 1) >> 1); + } + else + { + r = IO.fuji_width - 1 + row - (col >> 1); + c = row + ((col + 1) >> 1); + } + + unsigned short val = + imgdata.rawdata + .raw_image[(row + S.top_margin) * S.raw_pitch / 2 + + (col + S.left_margin)]; + int cc = FCF(row, col); + if (val > cblack[cc]) + { + val -= cblack[cc]; + if (dmax < val) + dmax = val; + } + else + val = 0; + imgdata.image[((r) >> IO.shrink) * alloc_width + + ((c) >> IO.shrink)][cc] = val; + } + } + S.height = IO_fheight; + S.width = IO_fwidth; + S.iheight = (S.height + IO.shrink) >> IO.shrink; + S.iwidth = (S.width + IO.shrink) >> IO.shrink; + S.raw_height -= 2 * S.top_margin; + } + else + { + copy_fuji_uncropped(cblack, &dmax); + } + } // end Fuji + else + { + copy_bayer(cblack, &dmax); + } + } + else // if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY) + { + if (imgdata.rawdata.color4_image) + { + if (S.raw_pitch != S.width * 8u || S.height != S.raw_height) + { + for (int row = 0; row < copyheight; row++) + memmove(&imgdata.image[row * S.width], + &imgdata.rawdata + .color4_image[(row + S.top_margin) * S.raw_pitch / 8 + + S.left_margin], + copywidth * sizeof(*imgdata.image)); + } + else + { + // legacy is always 4channel and not shrinked! + memmove(imgdata.image, imgdata.rawdata.color4_image, + S.width*copyheight * sizeof(*imgdata.image)); + } + } + else if (imgdata.rawdata.color3_image) + { + unsigned char *c3image = (unsigned char *)imgdata.rawdata.color3_image; + for (int row = 0; row < copyheight; row++) + { + ushort(*srcrow)[3] = + (ushort(*)[3]) & c3image[(row + S.top_margin) * S.raw_pitch]; + ushort(*dstrow)[4] = (ushort(*)[4]) & imgdata.image[row * S.width]; + for (int col = 0; col < copywidth; col++) + { + for (int c = 0; c < 3; c++) + dstrow[col][c] = srcrow[S.left_margin + col][c]; + dstrow[col][3] = 0; + } + } + } + else + { + // legacy decoder, but no data? + throw LIBRAW_EXCEPTION_DECODE_RAW; + } + } + + // Free PhaseOne separate copy allocated at function start + if (is_phaseone_compressed()) + { + phase_one_free_tempbuffer(); + } + if (load_raw == &LibRaw::canon_600_load_raw && S.width < S.raw_width) + { + canon_600_correct(); + } + + if (do_subtract_black) + { + C.data_maximum = (int)dmax; + C.maximum -= C.black; + // ZERO(C.cblack); + C.cblack[0] = C.cblack[1] = C.cblack[2] = C.cblack[3] = 0; + C.black = 0; + } + + // hack - clear later flags! + imgdata.progress_flags = + LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | + LIBRAW_PROGRESS_RAW2_IMAGE | LIBRAW_PROGRESS_IDENTIFY | + LIBRAW_PROGRESS_SIZE_ADJUST | LIBRAW_PROGRESS_LOAD_RAW; + return 0; + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } +} diff --git a/src/preprocessing/subtract_black.cpp b/src/preprocessing/subtract_black.cpp new file mode 100644 index 000000000..42bbe4fac --- /dev/null +++ b/src/preprocessing/subtract_black.cpp @@ -0,0 +1,91 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +int LibRaw::subtract_black() +{ + adjust_bl(); + return subtract_black_internal(); +} + +int LibRaw::subtract_black_internal() +{ + CHECK_ORDER_LOW(LIBRAW_PROGRESS_RAW2_IMAGE); + + try + { + if (!is_phaseone_compressed() && + (C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3] || + (C.cblack[4] && C.cblack[5]))) + { + int cblk[4], i; + for (i = 0; i < 4; i++) + cblk[i] = C.cblack[i]; + + int size = S.iheight * S.iwidth; + int dmax = 0; + if (C.cblack[4] && C.cblack[5]) + { + for (unsigned q = 0; q < (unsigned)size; q++) + { + for (unsigned c = 0; c < 4; c++) + { + int val = imgdata.image[q][c]; + val -= C.cblack[6 + q / S.iwidth % C.cblack[4] * C.cblack[5] + + q % S.iwidth % C.cblack[5]]; + val -= cblk[c]; + imgdata.image[q][c] = CLIP(val); + if (dmax < val) dmax = val; + } + } + } + else + { + for (unsigned q = 0; q < (unsigned)size; q++) + { + for (unsigned c = 0; c < 4; c++) + { + int val = imgdata.image[q][c]; + val -= cblk[c]; + imgdata.image[q][c] = CLIP(val); + if (dmax < val) dmax = val; + } + } + } + C.data_maximum = dmax & 0xffff; + C.maximum -= C.black; + ZERO(C.cblack); // Yeah, we used cblack[6+] values too! + C.black = 0; + } + else + { + // Nothing to Do, maximum is already calculated, black level is 0, so no + // change only calculate channel maximum; + int idx; + ushort *p = (ushort *)imgdata.image; + int dmax = 0; + for (idx = 0; idx < S.iheight * S.iwidth * 4; idx++) + if (dmax < p[idx]) + dmax = p[idx]; + C.data_maximum = dmax; + } + return 0; + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } +} diff --git a/src/tables/cameralist.cpp b/src/tables/cameralist.cpp new file mode 100644 index 000000000..da7f48164 --- /dev/null +++ b/src/tables/cameralist.cpp @@ -0,0 +1,1269 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#ifdef USE_RAWSPEED +/* we need separate file for that */ +#include "../../RawSpeed/rawspeed_xmldata.cpp" +const int RAWSPEED_DATA_COUNT = + (sizeof(_rawspeed_data_xml) / sizeof(_rawspeed_data_xml[0])); +#endif +// clang-format off +// Supported cameras: +static const char *static_camera_list[] = { + "Adobe Digital Negative (DNG)", + "AgfaPhoto DC-833m", + "Alcatel 5035D", + "Apple iPad Pro", + "Apple iPhone SE", + "Apple iPhone 6s", + "Apple iPhone 6 plus", + "Apple iPhone 7", + "Apple iPhone 7 plus", + "Apple iPhone 8", + "Apple iPhone 8 plus", + "Apple iPhone X", + "Apple iPhone 12 Pro", + "Apple iPhone 12 Pro Max", + "Apple iPhone 13 Pro", + "Apple QuickTake 100", + "Apple QuickTake 150", + "Apple QuickTake 200", +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + "ARRI ALEXA", + "ARRI ALEXA65", + "ARRI ALEXA LF", + "ARRI ALEXA XT", + "ARRI ALEXA SXT", +#endif + "ASUS ZenPhone4", + "ASUS ZenPhone6", + "AutelRobotics XB015", + "AutelRobotics XT705 (EVO II)", + "AVT F-080C", + "AVT F-145C", + "AVT F-201C", + "AVT F-510C", + "AVT F-810C", + "Baumer TXG14", + "BlackMagic Cinema Camera", + "BlackMagic Micro Cinema Camera", + "BlackMagic Pocket Cinema Camera", + "BlackMagic Production Camera 4k", + "BlackMagic URSA", + "BlackMagic URSA Mini 4k", + "BlackMagic URSA Mini 4.6k", + "BlackMagic URSA Mini Pro 4.6k", + "BQ Aquarius U", + "Canon PowerShot 600", + "Canon PowerShot A5", + "Canon PowerShot A5 Zoom", + "Canon PowerShot A50", + "Canon PowerShot A410 (CHDK hack)", + "Canon PowerShot A460 (CHDK hack)", + "Canon PowerShot A470 (CHDK hack)", + "Canon PowerShot A480 (CHDK hack)", + "Canon PowerShot A530 (CHDK hack)", + "Canon PowerShot A540 (CHDK hack)", + "Canon PowerShot A550 (CHDK hack)", + "Canon PowerShot A560 (CHDK hack)", + "Canon PowerShot A570 IS (CHDK hack)", + "Canon PowerShot A590 IS (CHDK hack)", + "Canon PowerShot A610 (CHDK hack)", + "Canon PowerShot A620 (CHDK hack)", + "Canon PowerShot A630 (CHDK hack)", + "Canon PowerShot A640 (CHDK hack)", + "Canon PowerShot A650 IS (CHDK hack)", + "Canon PowerShot A710 IS (CHDK hack)", + "Canon PowerShot A720 IS (CHDK hack)", + "Canon PowerShot A3300 IS (CHDK hack)", + "Canon PowerShot D10 (CHDK hack)", + "Canon PowerShot ELPH 130 IS / IXUS 140 / IXY 110F (CHDK hack)", + "Canon PowerShot ELPH 160 / IXUS 160 (CHDK hack)", + "Canon PowerShot Pro70", + "Canon PowerShot Pro90 IS", + "Canon PowerShot Pro1", + "Canon PowerShot G1", + "Canon PowerShot G1 X", + "Canon PowerShot G1 X Mark II", + "Canon PowerShot G1 X Mark III", + "Canon PowerShot G2", + "Canon PowerShot G3", + "Canon PowerShot G3 X", + "Canon PowerShot G5", + "Canon PowerShot G5 X", + "Canon PowerShot G5 X Mark II", + "Canon PowerShot G6", + "Canon PowerShot G7 (CHDK hack)", + "Canon PowerShot G7 X", + "Canon PowerShot G7 X Mark II", + "Canon PowerShot G7 X Mark III", + "Canon PowerShot G9", + "Canon PowerShot G9 X", + "Canon PowerShot G9 X Mark II", + "Canon PowerShot G10", + "Canon PowerShot G11", + "Canon PowerShot G12", + "Canon PowerShot G15", + "Canon PowerShot G16", + "Canon PowerShot S2 IS (CHDK hack)", + "Canon PowerShot S3 IS (CHDK hack)", + "Canon PowerShot S5 IS (CHDK hack)", + "Canon PowerShot SD300 / IXUS 40 / IXY Digital 50 (CHDK hack)", + "Canon PowerShot SD750 / IXUS 75 / IXY Digital 90 (CHDK hack)", + "Canon PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000 (CHDK hack)", + "Canon PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS (CHDK hack)", + "Canon PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS (CHDK hack)", + "Canon PowerShot S30", + "Canon PowerShot S40", + "Canon PowerShot S45", + "Canon PowerShot S50", + "Canon PowerShot S60", + "Canon PowerShot S70", + "Canon PowerShot S90", + "Canon PowerShot S95", + "Canon PowerShot S100", + "Canon PowerShot S110", + "Canon PowerShot S120", + "Canon PowerShot SX1 IS", + "Canon PowerShot SX40 HS (CHDK hack, CR2)", + "Canon PowerShot SX50 HS", + "Canon PowerShot SX60 HS", + "Canon PowerShot SX70 HS", + "Canon PowerShot SX100 IS (CHDK hack)", + "Canon PowerShot SX110 IS (CHDK hack)", + "Canon PowerShot SX120 IS (CHDK hack)", + "Canon PowerShot SX130 IS (CHDK hack)", + "Canon PowerShot SX160 IS (CHDK hack)", + "Canon PowerShot SX220 HS (CHDK hack)", + "Canon PowerShot SX510 HS (CHDK hack)", + "Canon PowerShot SX710 HS (CHDK hack)", + "Canon PowerShot SX10 IS (CHDK hack)", + "Canon PowerShot SX20 IS (CHDK hack)", + "Canon PowerShot SX30 IS (CHDK hack)", + "Canon EOS R", + "Canon EOS RP", + "Canon EOS R3", + "Canon EOS R5", + "Canon EOS R6", + "Canon EOS R7", + "Canon EOS R10", + "Canon EOS D30", + "Canon EOS D60", + "Canon EOS 5DS", + "Canon EOS 5DS R", + "Canon EOS 5D", + "Canon EOS 5D Mark II", + "Canon EOS 5D Mark III", + "Canon EOS 5D Mark IV", + "Canon EOS 6D", + "Canon EOS 6D Mark II", + "Canon EOS 7D", + "Canon EOS 7D Mark II", + "Canon EOS 10D", + "Canon EOS 20D", + "Canon EOS 20Da", + "Canon EOS 30D", + "Canon EOS 40D", + "Canon EOS 50D", + "Canon EOS 60D", + "Canon EOS 60Da", + "Canon EOS 70D", + "Canon EOS 77D / 9000D", + "Canon EOS 80D", + "Canon EOS 90D", + "Canon EOS 100D / Rebel SL1 / Kiss X7", + "Canon EOS 200D / Rebel SL2 / Kiss X9", + "Canon EOS 250D / 200D II / Rebel SL3 / Kiss X10", + "Canon EOS 300D / Digital Rebel / Kiss Digital", + "Canon EOS 350D / Digital Rebel XT / Kiss Digital N", + "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X", + "Canon EOS 450D / Digital Rebel XSi / Kiss X2", + "Canon EOS 500D / Rebel T1i / Kiss X3", + "Canon EOS 550D / Rebel T2i / Kiss X4", + "Canon EOS 600D / Rebel T3i / Kiss X5", + "Canon EOS 650D / Rebel T4i / Kiss X6i", + "Canon EOS 700D / Rebel T5i / Kiss X7i", + "Canon EOS 750D / Rebel T6i / Kiss X8i", + "Canon EOS 760D / Rebel T6S / 8000D", + "Canon EOS 800D / Rebel T7i / Kiss X9i", + "Canon EOS 850D / Rebel T8i / Kiss X10i", + "Canon EOS 1000D / Digital Rebel XS / Kiss F", + "Canon EOS 1100D / Rebel T3 / Kiss X50", + "Canon EOS 1200D / Kiss X70 / REBEL T5 / Hi", + "Canon EOS 1300D / Rebel T6 / Kiss X80", + "Canon EOS 1500D / 2000D / Rebel T7 / Kiss X90", + "Canon EOS 3000D / 4000D / Rebel T100", +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + "Canon EOS C500", +#endif + "Canon EOS D2000", + "Canon EOS M", + "Canon EOS M2", + "Canon EOS M3", + "Canon EOS M5", + "Canon EOS M6", + "Canon EOS M6 Mark II", + "Canon EOS M10", + "Canon EOS M50 / Kiss M", + "Canon EOS M50 Mark II", + "Canon EOS M100", + "Canon EOS M200", + "Canon EOS-1D C", + "Canon EOS-1D X", + "Canon EOS-1D X Mark II", + "Canon EOS-1D X Mark III", + "Canon EOS-1D", + "Canon EOS-1D Mark II", + "Canon EOS-1D Mark II N", + "Canon EOS-1D Mark III", + "Canon EOS-1D Mark IV", + "Canon EOS-1Ds", + "Canon EOS-1Ds Mark II", + "Canon EOS-1Ds Mark III", + "Casio QV-2000UX (secret menu hack)", + "Casio QV-3000EX (secret menu hack)", + "Casio QV-3500EX (secret menu hack)", + "Casio QV-4000 (secret menu hack)", + "Casio QV-5700 (secret menu hack)", + "Casio QV-R41", + "Casio QV-R51", + "Casio QV-R61", + "Casio EX-F1", + "Casio EX-FC300S", + "Casio EX-FC400S", + "Casio EX-FH20", + "Casio EX-FH25", + "Casio EX-FH100", + "Casio EX-S20 / M20", + "Casio EX-S100", + "Casio EX-Z4", + "Casio EX-Z50", + "Casio EX-Z500", + "Casio EX-Z55", + "Casio EX-Z60", + "Casio EX-Z75", + "Casio EX-Z750", + "Casio EX-Z8", + "Casio EX-Z850", + "Casio EX-Z1050", + "Casio EX-ZR100", + "Casio EX-Z1080", + "Casio EX-ZR700", + "Casio EX-ZR710", + "Casio EX-ZR750", + "Casio EX-ZR800", + "Casio EX-ZR850", + "Casio EX-ZR1000", + "Casio EX-ZR1100", + "Casio EX-ZR1200", + "Casio EX-ZR1300", + "Casio EX-ZR1500", + "Casio EX-ZR3000", + "Casio EX-ZR3100", + "Casio EX-ZR3200", + "Casio EX-ZR3500", + "Casio EX-ZR3600", + "Casio EX-ZR3700", + "Casio EX-ZR4000 / 5000", + "Casio EX-ZR4100 / 5100", + "Casio EX-100", + "Casio EX-100F", + "Casio EX-100PRO", + "Casio EX-10", + "Casio EX-P505 (secret menu hack)", + "Casio EX-P600 (secret menu hack)", + "Casio EX-P700 (secret menu hack)", + "CLAUSS pix500", + "Contax N Digital", + "Creative PC-CAM 600", + "Digital Bolex D16", + "Digital Bolex D16M", + "DJI 4384x3288", + "DJI Mavic Air", + "DJI Mavic Air2", + "DJI Mavic Air 2S", + "DJI Mavic Mini2", + "DJI Mavic 3", + "DJI Osmo Action", + "DJI Pocket", + "DJI Phantom4 Pro/Pro+", + "DJI Zenmuse X5", + "DJI Zenmuse X5R", + "DXO One", + "Epson R-D1", + "Epson R-D1s", + "Epson R-D1x", + "Eyedeas E1", + "Foculus 531C", + "FujiFilm DBP for GX680 / DX-2000", + "FujiFilm E550", + "FujiFilm E900", + "FujiFilm F500EXR / F505EXR", + "FujiFilm F550EXR", + "FujiFilm F600EXR / F605EXR", + "FujiFilm F700", + "FujiFilm F710", + "FujiFilm F770EXR / F775EXR", + "FujiFilm F800EXR", + "FujiFilm F810", + "FujiFilm F900EXR", + "FujiFilm S2Pro", + "FujiFilm S3Pro", + "FujiFilm S5Pro", + "FujiFilm S20Pro", + "FujiFilm S1", + "FujiFilm S100FS", + "FujiFilm S5000", + "FujiFilm S5100 / S5500", + "FujiFilm S5200 / S5600", + "FujiFilm S6000fd / S6500fd", + "FujiFilm S7000", + "FujiFilm S9000 / S9500", + "FujiFilm S9100 / S9600", + "FujiFilm S200EXR / S205EXR", + "FujiFilm SL1000", + "FujiFilm HS10/HS11", + "FujiFilm HS20EXR / HS22EXR", + "FujiFilm HS30EXR / HS33EXR / HS35EXR", + "FujiFilm HS50EXR", + "FujiFilm GFX 50S", + "FujiFilm GFX 50S II", + "FujiFilm GFX 50R", + "FujiFilm GFX 100", + "FujiFilm GFX 100S", + "FujiFilm X-Pro1", + "FujiFilm X-Pro2", + "FujiFilm X-Pro3", + "FujiFilm X-S1", + "FujiFilm XQ1", + "FujiFilm XQ2", + "FujiFilm X100", + "FujiFilm X100F", + "FujiFilm X100S", + "FujiFilm X100T", + "FujiFilm X100V", + "FujiFilm X10", + "FujiFilm X20", + "FujiFilm X30", + "FujiFilm X70", + "FujiFilm X-A1", + "FujiFilm X-A2", + "FujiFilm X-A3", + "FujiFilm X-A5", + "FujiFilm X-A7", + "FujiFilm X-A10", + "FujiFilm X-A20", + "FujiFilm X-E1", + "FujiFilm X-E2", + "FujiFilm X-E2S", + "FujiFilm X-E3", + "FujiFilm X-E4", + "FujiFilm X-M1", + "FujiFilm XF1", + "FujiFilm XF10", + "FujiFilm X-H1", + "FujiFilm X-H2S", + "FujiFilm X-T1", + "FujiFilm X-S10", + "FujiFilm X-T1 Graphite Silver", + "FujiFilm X-T2", + "FujiFilm X-T3", + "FujiFilm X-T4", + "FujiFilm X-T10", + "FujiFilm X-T20", + "FujiFilm X-T30", + "FujiFilm X-T30 II", + "FujiFilm X-T100", + "FujiFilm X-T200", + "FujiFilm IS-1", + "Gione E7", + "GITUP GIT2", + "GITUP GIT2P", + "GITUP G3 DUO (16:9 mode only)", + "Google Pixel", + "Google Pixel XL", + "Google Pixel 3a", + "Google Pixel 4 XL", + "Google Pixel 4a (5G)", + "Google Pixel 5", +#ifdef USE_GPRSDK + "GoPro Fusion", + "GoPro HERO5", + "GoPro HERO6", + "GoPro HERO7", + "GoPro HERO8", + "GoPro HERO9", + "GoPro HERO10", +#endif + "Hasselblad H2D-22", + "Hasselblad H2D-39", + "Hasselblad H3DII-22", + "Hasselblad H3DII-31", + "Hasselblad H3DII-39", + "Hasselblad H3DII-50", + "Hasselblad H3D-22", + "Hasselblad H3D-31", + "Hasselblad H3D-39", + "Hasselblad H4D-60", + "Hasselblad H4D-50", + "Hasselblad H4D-40", + "Hasselblad H4D-31", + "Hasselblad H5D-60", + "Hasselblad H5D-50", + "Hasselblad H5D-50c", + "Hasselblad H5D-40", + "Hasselblad H6D-100c", + "Hasselblad A6D-100c", // Aerial camera + "Hasselblad CFV", + "Hasselblad CFV-50", + "Hasselblad CFV II 50C", + "Hasselblad CFH", + "Hasselblad CF-22", + "Hasselblad CF-31", + "Hasselblad CF-39", + "Hasselblad V96C", + "Hasselblad L1D-20c (DJI Mavic 2 Pro)", + "Hasselblad Lusso", + "Hasselblad Lunar", + "Hasselblad True Zoom", + "Hasselblad Stellar", + "Hasselblad Stellar II", + "Hasselblad HV", + "Hasselblad X1D", + "Hasselblad X1D II 50C", + "HTC UltraPixel", + "HTC MyTouch 4G", + "HTC One (A9)", + "HTC One (M9)", + "HTC 10", + "HTC U12", + "Huawei P8 Lite (PRA-LX1)", + "Huawei P9 (EVA-L09/AL00)", + "Huawei P10 (VTR-L09)", + "Huawei P10+ (VKY-L09)", + "Huawei P10 Lite (WAS-LX1A)", + "Huawei P20 (EML-L09)", + "Huawei P20 Lite (ANE-LX1)", + "Huawei P20 Pro (CLT-L29/L09)", + "Huawei P30 Pro (VOG-L29)", + "Huawei Honor6a", + "Huawei Honor7a pro", + "Huawei Honor8 (FRD-L09)", + "Huawei Honor9", + "Huawei Honor10", + "Huawei Honor20", + "Huawei Honor View 10 (BKL-L09)", + "Huawei Honor View 20 (PCT-L29)", + "Huawei Honor 20 Pro (YAL-L41)", + "Huawei Mate8 (NXT-L29)", + "Huawei Mate10 (BLA-L29)", + "Huawei Mate20 Pro (LYA-L29)", + "Huawei Mate20 Lite (SNE-LX1)", + "Imacon Ixpress 96, 96C", + "Imacon Ixpress 384, 384C (single shot only)", + "Imacon Ixpress 132C", + "Imacon Ixpress 528C (single shot only)", + "ISG 2020x1520", + "Ikonoskop A-Cam dII Panchromatic", + "Ikonoskop A-Cam dII", + "Kandao QooCam 8K", + "Kinefinity KineMINI", + "Kinefinity KineRAW Mini", + "Kinefinity KineRAW S35", + "Kodak DC20", + "Kodak DC25", + "Kodak DC40", + "Kodak DC50", + "Kodak DC120", + "Kodak DCS200", + "Kodak DCS315C", + "Kodak DCS330C", + "Kodak DCS420", + "Kodak DCS460", + "Kodak DCS460M", + "Kodak DCS460", + "Kodak DCS520C", + "Kodak DCS560C", + "Kodak DCS620C", + "Kodak DCS620X", + "Kodak DCS660C", + "Kodak DCS660M", + "Kodak DCS720X", + "Kodak DCS760C", + "Kodak DCS760M", + "Kodak EOSDCS1", + "Kodak EOSDCS3", + "Kodak NC2000", + "Kodak ProBack", + "Kodak PB645C", + "Kodak PB645H", + "Kodak PB645M", + "Kodak DCS Pro 14n", + "Kodak DCS Pro 14nx", + "Kodak DCS Pro SLR/c", + "Kodak DCS Pro SLR/n", + "Kodak C330", + "Kodak C603", + "Kodak P850", + "Kodak P880", + "Kodak PIXPRO AZ901", + "Kodak PIXPRO S-1", + "Kodak Z980", + "Kodak Z981", + "Kodak Z990", + "Kodak Z1015", + "Kodak KAI-0340", + "Konica KD-400Z", + "Konica KD-510Z", + "Leaf AFi 5", + "Leaf AFi 6", + "Leaf AFi 7", + "Leaf AFi-II 6", + "Leaf AFi-II 7", + "Leaf AFi-II 10", + "Leaf AFi-II 10R", + "Leaf Aptus-II 5", + "Leaf Aptus-II 6", + "Leaf Aptus-II 7", + "Leaf Aptus-II 8", + "Leaf Aptus-II 10", + "Leaf Aptus-II 12", + "Leaf Aptus-II 12R", + "Leaf Aptus 17", + "Leaf Aptus 22", + "Leaf Aptus 54S", + "Leaf Aptus 65", + "Leaf Aptus 65S", + "Leaf Aptus 75", + "Leaf Aptus 75S", + "Leaf Cantare", + "Leaf Cantare XY", + "Leaf CatchLight", + "Leaf CMost", + "Leaf Credo 40", + "Leaf Credo 50", + "Leaf Credo 60", + "Leaf Credo 80", + "Leaf DCB-II", + "Leaf Valeo 6", + "Leaf Valeo 11", + "Leaf Valeo 17", + "Leaf Valeo 17wi", + "Leaf Valeo 22", + "Leaf Valeo 22wi", + "Leaf Volare", + "Lenovo a820", + "Leica C (Typ 112)", + "Leica CL", + "Leica C-Lux / CAM-DC25", + "Leica Digilux 2", + "Leica Digilux 3", + "Leica Digital-Modul-R", + "Leica D-LUX2", + "Leica D-LUX3", + "Leica D-LUX4", + "Leica D-LUX5", + "Leica D-LUX6", + "Leica D-LUX7", + "Leica D-Lux (Typ 109)", + "Leica M8", + "Leica M8.2", + "Leica M9", + "Leica M10", + "Leica M10-D", + "Leica M10-P", + "Leica M10-R", + "Leica M10 Monochrom", + "Leica M11", + "Leica M (Typ 240)", + "Leica M (Typ 262)", + "Leica Monochrom (Typ 240)", + "Leica Monochrom (Typ 246)", + "Leica M-D (Typ 262)", + "Leica M-E", + "Leica M-P", + "Leica R8", + "Leica Q (Typ 116)", + "Leica Q-P", + "Leica Q2", + "Leica Q2 Monochrom", + "Leica S", + "Leica S2", + "Leica S3", + "Leica S (Typ 007)", + "Leica SL (Typ 601)", + "Leica SL2", + "Leica SL2-S", + "Leica T (Typ 701)", + "Leica TL", + "Leica TL2", + "Leica X1", + "Leica X (Typ 113)", + "Leica X2", + "Leica X-E (Typ 102)", + "Leica X-U (Typ 113)", + "Leica V-LUX1", + "Leica V-LUX2", + "Leica V-LUX3", + "Leica V-LUX4", + "Leica V-LUX5", + "Leica V-Lux (Typ 114)", + "Leica X VARIO (Typ 107)", + "LG G3", + "LG G4", + "LG G5 (H850)", + "LG G6", + "LG V20 (F800K)", + "LG V20 (H910)", + "LG VS995", + "Logitech Fotoman Pixtura", + "Mamiya ZD", + "Matrix 4608x3288", + "Meizy MX4", + "Micron 2010", + "Minolta RD175 / Agfa ActionCam", + "Minolta DiMAGE 5", + "Minolta DiMAGE 7", + "Minolta DiMAGE 7i", + "Minolta DiMAGE 7Hi", + "Minolta DiMAGE A1", + "Minolta DiMAGE A2", + "Minolta DiMAGE A200", + "Minolta DiMAGE G400", + "Minolta DiMAGE G500", + "Minolta DiMAGE G530", + "Minolta DiMAGE G600", + "Minolta DiMAGE Z2", + "Minolta Alpha/Dynax/Maxxum 5D", + "Minolta Alpha/Dynax/Maxxum 7D", + "Motorola PIXL", + "Motorola Moto G (5S)", + "Motorola Moto G7 Play", + "Nikon D1", + "Nikon D1H", + "Nikon D1X", + "Nikon D2H", + "Nikon D2Hs", + "Nikon D2X", + "Nikon D2Xs", + "Nikon D3", + "Nikon D3s", + "Nikon D3X", + "Nikon D4", + "Nikon D4s", + "Nikon D40", + "Nikon D40X", + "Nikon D5", + "Nikon D50", + "Nikon D6", + "Nikon D60", + "Nikon D70", + "Nikon D70s", + "Nikon D80", + "Nikon D90", + "Nikon D100", + "Nikon D200", + "Nikon D300", + "Nikon D300s", + "Nikon D500", + "Nikon D600", + "Nikon D610", + "Nikon D700", + "Nikon D750", + "Nikon D780", + "Nikon D800", + "Nikon D800E", + "Nikon D810", + "Nikon D810A", + "Nikon D850", + "Nikon D3000", + "Nikon D3100", + "Nikon D3200", + "Nikon D3300", + "Nikon D3400", + "Nikon D3500", + "Nikon D5000", + "Nikon D5100", + "Nikon D5200", + "Nikon D5300", + "Nikon D5500", + "Nikon D5600", + "Nikon D7000", + "Nikon D7100", + "Nikon D7200", + "Nikon D7500", + "Nikon Df", + "Nikon Z 5", + "Nikon Z 6", + "Nikon Z 6 II", + "Nikon Z 7", + "Nikon Z 7 II", + "Nikon Z 9 (HE/HE* formats are not supported yet)", + "Nikon Z 50", + "Nikon Z fc", + "Nikon 1 AW1", + "Nikon 1 J1", + "Nikon 1 J2", + "Nikon 1 J3", + "Nikon 1 J4", + "Nikon 1 J5", + "Nikon 1 S1", + "Nikon 1 S2", + "Nikon 1 V1", + "Nikon 1 V2", + "Nikon 1 V3", + "Nikon Coolpix 700 (\"DIAG RAW\" hack)", + "Nikon Coolpix 800 (\"DIAG RAW\" hack)", + "Nikon Coolpix 880 (\"DIAG RAW\" hack)", + "Nikon Coolpix 900 (\"DIAG RAW\" hack)", + "Nikon Coolpix 950 (\"DIAG RAW\" hack)", + "Nikon Coolpix 990 (\"DIAG RAW\" hack)", + "Nikon Coolpix 995 (\"DIAG RAW\" hack)", + "Nikon Coolpix 2100 (\"DIAG RAW\" hack)", + "Nikon Coolpix 2500 (\"DIAG RAW\" hack)", + "Nikon Coolpix 3200 (\"DIAG RAW\" hack)", + "Nikon Coolpix 3700 (\"DIAG RAW\" hack)", + "Nikon Coolpix 4300 (\"DIAG RAW\" hack)", + "Nikon Coolpix 4500 (\"DIAG RAW\" hack)", + "Nikon Coolpix 5000", + "Nikon Coolpix 5400", + "Nikon Coolpix 5700", + "Nikon Coolpix 8400", + "Nikon Coolpix 8700", + "Nikon Coolpix 8800", + "Nikon Coolpix A", + "Nikon Coolpix A1000", + "Nikon Coolpix B700", + "Nikon Coolpix P330", + "Nikon Coolpix P340", + "Nikon Coolpix P950", + "Nikon Coolpix P6000", + "Nikon Coolpix P1000", + "Nikon Coolpix P7000", + "Nikon Coolpix P7100", + "Nikon Coolpix P7700", + "Nikon Coolpix P7800", + "Nikon Coolpix S6 (\"DIAG RAW\" hack)", + "Nikon Coolscan NEF", + "Nokia 7 Plus", + "Nokia 8.3 5G", + "Nokia 9", + "Nokia N95", + "Nokia X2", + "Nokia 1200x1600", + "Nokia Lumia 930", + "Nokia Lumia 950 XL", + "Nokia Lumia 1020", + "Nokia Lumia 1520", + "Olympus AIR A01", + "Olympus C-3030Z", + "Olympus C-5050Z", + "Olympus C-5060WZ", + "Olympus C-7070WZ", + "Olympus C-70Z / C-7000Z", + "Olympus C-740UZ", + "Olympus C-770UZ", + "Olympus C-8080WZ", + "Olympus X200 / D-560Z / C-350Z", + "Olympus E-1", + "Olympus E-3", + "Olympus E-5", + "Olympus E-10", + "Olympus E-20 / E-20N / E-20P", + "Olympus E-30", + "Olympus E-300", + "Olympus E-330", + "Olympus E-400", + "Olympus E-410", + "Olympus E-420", + "Olympus E-450", + "Olympus E-500", + "Olympus E-510", + "Olympus E-520", + "Olympus E-600", + "Olympus E-620", + "Olympus E-P1", + "Olympus E-P2", + "Olympus E-P3", + "Olympus E-P5", + "Olympus E-P7", + "Olympus E-PL1", + "Olympus E-PL1s", + "Olympus E-PL2", + "Olympus E-PL3", + "Olympus E-PL5", + "Olympus E-PL6", + "Olympus E-PL7", + "Olympus E-PL8", + "Olympus E-PL9", + "Olympus E-PL10", + "Olympus E-PM1", + "Olympus E-PM2", + "Olympus E-M1", + "Olympus E-M1 Mark II", + "Olympus E-M1 Mark III", + "Olympus E-M1X", + "Olympus E-M10", + "Olympus E-M10 Mark II", + "Olympus E-M10 Mark III", + "Olympus E-M10 Mark IV", + "Olympus E-M5", + "Olympus E-M5 Mark II", + "Olympus E-M5 Mark III", + "Olympus Pen-F", + "Olympus SP-310", + "Olympus SP-320", + "Olympus SP-350", + "Olympus SP-500UZ", + "Olympus SP-510UZ", + "Olympus SP-550UZ", + "Olympus SP-560UZ", + "Olympus SP-565UZ", + "Olympus SP-570UZ", + "Olympus Stylus 1", + "Olympus Stylus 1s", + "Olympus SH-2", + "Olympus SH-3", + "Olympus TG-4", + "Olympus TG-5", + "Olympus TG-6", + "Olympus XZ-1", + "Olympus XZ-2", + "Olympus XZ-10", + "OM Digital Solutions OM-1", + "OmniVision 4688", + "OmniVision OV5647", + "OmniVision OV5648", + "OmniVision OV8850", + "OmniVision 13860", + "OnePlus 6 (A6003)", + "OnePlus 6T", + "OnePlus 7 Pro (GM1913)", + "OnePlus 8 Pro (IN2023)", + "OnePlus One", + "OnePlus A3303", + "OnePlus A5000", + "Panasonic DMC-CM1", + "Panasonic DMC-FZ8", + "Panasonic DMC-FZ18", + "Panasonic DMC-FZ28", + "Panasonic DMC-FZ30", + "Panasonic DMC-FZ35 / FZ38", + "Panasonic DMC-FZ40 / FZ42 / FZ45", + "Panasonic DMC-FZ50", + "Panasonic DMC-FZ70 / FZ72", + "Panasonic DC-FZ80 / FZ81 / FZ82 / FZ83 / FZ85", + "Panasonic DMC-FZ100", + "Panasonic DMC-FZ150", + "Panasonic DMC-FZ200", + "Panasonic DMC-FZ300 / FZ330", + "Panasonic DMC-FZ1000", + "Panasonic DC-FZ1000 II / FZ1000M2 / DC-FZ10002", + "Panasonic DMC-FZ2000 / FZ2500 / FZH1", + "Panasonic DMC-FX150 / FX180", + "Panasonic DMC-G1", + "Panasonic DMC-G10", + "Panasonic DMC-G2", + "Panasonic DMC-G3", + "Panasonic DMC-G5", + "Panasonic DMC-G6", + "Panasonic DMC-G7 / G70", + "Panasonic DMC-G8 / G80 / G81 / G85", + "Panasonic DC-G9", + "Panasonic DC-G90 / G95 / G91 / G99", + "Panasonic DC-G100 / G110", + "Panasonic DMC-GF1", + "Panasonic DMC-GF2", + "Panasonic DMC-GF3", + "Panasonic DMC-GF5", + "Panasonic DMC-GF6", + "Panasonic DMC-GF7", + "Panasonic DC-GF10 / GF90", + "Panasonic DMC-GH1", + "Panasonic DMC-GH2", + "Panasonic DMC-GH3", + "Panasonic DMC-GH4", + "Panasonic AG-GH4", + "Panasonic DC-GH5", + "Panasonic DC-GH5S", + "Panasonic DC-GH5 Mark II", + "Panasonic DMC-GM1", + "Panasonic DMC-GM1s", + "Panasonic DMC-GM5", + "Panasonic DMC-GX1", + "Panasonic DMC-GX7", + "Panasonic DMC-GX8", + "Panasonic DC-GX9 / GX7mkIII", + "Panasonic DMC-GX80 / GX85, DMC-GX7mkII", + "Panasonic DC-GX800 / GX850, DC-GF9", + "Panasonic DMC-L1", + "Panasonic DMC-L10", + "Panasonic DMC-LC1", + "Panasonic DMC-LF1", + "Panasonic DMC-LX1", + "Panasonic DMC-LX2", + "Panasonic DMC-LX3", + "Panasonic DMC-LX5", + "Panasonic DMC-LX7", + "Panasonic DMC-LX9 / LX10 / LX15", + "Panasonic DMC-LX100", + "Panasonic DC-LX100M2", + "Panasonic DC-S1", + "Panasonic DC-S1H", + "Panasonic DC-S1R", + "Panasonic DC-S5", + "Panasonic DMC-ZS40, DMC-TZ60 / TZ61", + "Panasonic DMC-ZS50, DMC-TZ70 / TZ71", + "Panasonic DMC-ZS60, DMC-TZ80 / TZ81 / TZ82 / TZ85", + "Panasonic DC-ZS70, DC-TZ90 / TZ91 / TZ92 / TZ93", + "Panasonic DC-ZS80, DC-TZ95 / TZ96 / TZ97", + "Panasonic DMC-ZS100 / ZS110, DMC-TZ100 / TZ101 / TZ110, DMC-TX1", + "Panasonic DC-ZS200 / ZS220, DC-TZ200 / TZ202 / TZ220, DC-TX2", + "PARROT Anafi", + "PARROT Bebop 2", + "PARROT Bebop Drone", + "Pentax *ist D", + "Pentax *ist DL", + "Pentax *ist DL2", + "Pentax *ist DS", + "Pentax *ist DS2", + "Pentax K10D", + "Pentax K20D", + "Pentax K100D", + "Pentax K100D Super", + "Pentax K110D", + "Pentax K200D", + "Pentax K2000/K-m", + "Pentax KP", + "Pentax K-x", + "Pentax K-r", + "Pentax K-01", + "Pentax K-1", + "Pentax K-1 Mark II", + "Pentax K-3", + "Pentax K-3 Mark II", + "Pentax K-3 Mark III", + "Pentax K-30", + "Pentax K-5", + "Pentax K-5 II", + "Pentax K-5 IIs", + "Pentax K-50", + "Pentax K-500", + "Pentax K-7", + "Pentax K-70", + "Pentax K-S1", + "Pentax K-S2", + "Pentax MX-1", + "Pentax Q", + "Pentax Q7", + "Pentax Q10", + "Pentax QS-1", + "Pentax Optio S (secret menu or hack)", + "Pentax Optio S4 (secret menu or hack)", + "Pentax Optio 33WR (secret menu or hack)", + "Pentax Optio 750Z (secret menu or hack)", + "Pentax 645D", + "Pentax 645Z", + "PhaseOne IQ140", + "PhaseOne IQ150", + "PhaseOne IQ160", + "PhaseOne IQ180", + "PhaseOne IQ180 IR", + "PhaseOne IQ250", + "PhaseOne IQ260", + "PhaseOne IQ260 Achromatic", + "PhaseOne IQ280", + "PhaseOne IQ3 50MP", + "PhaseOne IQ3 60MP", + "PhaseOne IQ3 80MP", + "PhaseOne IQ3 100MP", + "PhaseOne IQ3 100MP Trichromatic", + "PhaseOne IQ4 150MP", + "PhaseOne LightPhase", + "PhaseOne Achromatic+", + "PhaseOne H 10", + "PhaseOne H 20", + "PhaseOne H 25", + "PhaseOne P 20", + "PhaseOne P 20+", + "PhaseOne P 21", + "PhaseOne P 25", + "PhaseOne P 25+", + "PhaseOne P 30", + "PhaseOne P 30+", + "PhaseOne P 40+", + "PhaseOne P 45", + "PhaseOne P 45+", + "PhaseOne P 65", + "PhaseOne P 65+", + "Photron BC2-HD", + "Pixelink A782", +#ifdef USE_X3FTOOLS + "Polaroid x530", +#endif + "RaspberryPi Camera", + "RaspberryPi Camera V2", +#ifdef USE_6BY9RPI + "RaspberryPi HQ Camera", +#endif + "Ricoh GR", + "Realme 3 Pro", + "Ricoh GR II", + "Ricoh GR III", + "Ricoh GR IIIx", + "Ricoh GR Digital", + "Ricoh GR Digital II", + "Ricoh GR Digital III", + "Ricoh GR Digital IV", + "Ricoh Caplio GX100", + "Ricoh Caplio GX200", + "Ricoh GXR Mount A12", + "Ricoh GXR GR Lens A12 50mm F2.5 Macro", + "Ricoh GXR GR Lens A12 28mm F2.5", + "Ricoh GXR Ricoh Lens A16 24-85mm F3.5-5.5", + "Ricoh GXR Ricoh Lens S10 24-72mm F2.5-4.4 VC", + "Ricoh GXR Ricoh Lens P10 28-300 mm F3.5-5.6 VC", +#ifdef LIBRAW_OLD_VIDEO_SUPPORT +#ifndef NO_JASPER + "Redcode R3D format", +#endif +#endif + "Rollei d530flex", + "RoverShot 3320af", + "Samsung EX1 / TL500", + "Samsung EX2F", + "Samsung GX-1L", + "Samsung GX-1S", + "Samsung GX10", + "Samsung GX20", + "Samsung Galaxy Nexus", + "Samsung Galaxy Note 9", + "Samsung Galaxy NX (EK-GN120)", + "Samsung Galaxy S3", + "Samsung Galaxy S6 (SM-G920F)", + "Samsung Galaxy S7", + "Samsung Galaxy S7 Edge", + "Samsung Galaxy S8 (SM-G950U)", + "Samsung Galaxy S9 (SM-G960F)", + "Samsung Galaxy S9+ (SM-G965U / 965F)", + "Samsung Galaxy S10 (SM-G973F)", + "Samsung Galaxy S10+ (SM-G975U)", + "Samsung NX1", + "Samsung NX5", + "Samsung NX10", + "Samsung NX11", + "Samsung NX100", + "Samsung NX1000", + "Samsung NX1100", + "Samsung NX20", + "Samsung NX200", + "Samsung NX210", + "Samsung NX2000", + "Samsung NX30", + "Samsung NX300", + "Samsung NX300M", + "Samsung NX3000", + "Samsung NX500", + "Samsung NX mini / NXF1", + "Samsung Pro815", + "Samsung WB550 / WB560 / HZ15W", + "Samsung WB2000 / TL350", + "Samsung WB5000 / HZ25W", + "Samsung S85 (hacked)", + "Samsung S850 (hacked)", + "Sarnoff 4096x5440", + "Seitz 6x17", + "Seitz Roundshot D3", + "Seitz Roundshot D2X", + "Seitz Roundshot D2Xs", + "Sigma fp", +#ifdef USE_X3FTOOLS + "Sigma SD9 (raw decode only)", + "Sigma SD10 (raw decode only)", + "Sigma SD14 (raw decode only)", + "Sigma SD15 (raw decode only)", + "Sigma SD1", + "Sigma SD1 Merrill", + "Sigma DP1", + "Sigma DP1 Merrill", + "Sigma DP1S", + "Sigma DP1X", + "Sigma DP2", + "Sigma DP2 Merrill", + "Sigma DP2S", + "Sigma DP2X", + "Sigma DP3 Merrill", + "Sigma dp0 Quattro", + "Sigma dp1 Quattro", + "Sigma dp2 Quattro", + "Sigma dp3 Quattro", + "Sigma sd Quattro", + "Sigma sd Quattro H", +#else + "Sigma dp0 Quattro (DNG only)", + "Sigma dp1 Quattro (DNG only)", + "Sigma dp2 Quattro (DNG only)", + "Sigma dp3 Quattro (DNG only)", + "Sigma sd Quattro (DNG only)", + "Sigma sd Quattro H (DNG only)", +#endif + "Sinar eMotion 22", + "Sinar eMotion 54", + "Sinar eSpirit 65", + "Sinar eMotion 75", + "Sinar eVolution 75", + "Sinar 3072x2048 (Sinarback 23)", + "Sinar 4080x4080 (Sinarback 44)", + "Sinar 4080x5440", + "Sinar STI format", + "Sinar Sinarback 54", + "SMaL Ultra-Pocket 3", + "SMaL Ultra-Pocket 4", + "SMaL Ultra-Pocket 5", + "Sony ILCE-1 (A1)", + "Sony ILCE-7 (A7)", + "Sony ILCE-7M2 (A7 II)", + "Sony ILCE-7M3 (A7 III)", + "Sony ILCE-7M4 (A7 IV)", + "Sony ILCE-7C (A7C)", + "Sony ILCE-7R (A7R)", + "Sony ILCE-7RM2 (A7R II)", + "Sony ILCE-7RM3 (A7R III)", + "Sony ILCE-7RM3A (A7R IIIA)", + "Sony ILCE-7RM4 (A7R IV)", + "Sony ILCE-7RM4A (A7R IVA)", + "Sony ILCE-7S (A7S)", + "Sony ILCE-7SM2 (A7S II)", + "Sony ILCE-7SM3 (A7S III)", + "Sony ILCE-9 (A9)", + "Sony ILCE-9M2 (A9 II)", + "Sony ILCA-68 (A68)", + "Sony ILCA-77M2 (A77-II)", + "Sony ILCA-99M2 (A99-II)", + "Sony ILCE-3000 / 3500", + "Sony ILCE-5000", + "Sony ILCE-5100", + "Sony ILCE-6000", + "Sony ILCE-6100", + "Sony ILCE-6300", + "Sony ILCE-6400", + "Sony ILCE-6500", + "Sony ILCE-6600", + "Sony ILCE-QX1", + "Sony DSC-F828", + "Sony DSC-HX95", + "Sony DSC-HX99", + "Sony DSC-R1", + "Sony DSC-RX0", + "Sony DSC-RX0 II", + "Sony DSC-RX1", + "Sony DSC-RX1R", + "Sony DSC-RX1R II", + "Sony DSC-RX10", + "Sony DSC-RX10 II", + "Sony DSC-RX10 III", + "Sony DSC-RX10 IV", + "Sony DSC-RX100", + "Sony DSC-RX100 II", + "Sony DSC-RX100 III", + "Sony DSC-RX100 IV", + "Sony DSC-RX100 V", + "Sony DSC-RX100 VA", + "Sony DSC-RX100 VI", + "Sony DSC-RX100 VII", + "Sony DSC-V3", + "Sony DSLR-A100", + "Sony DSLR-A200", + "Sony DSLR-A230", + "Sony DSLR-A290", + "Sony DSLR-A300", + "Sony DSLR-A330", + "Sony DSLR-A350", + "Sony DSLR-A380 / A390", + "Sony DSLR-A450", + "Sony DSLR-A500", + "Sony DSLR-A550", + "Sony DSLR-A560", + "Sony DSLR-A580", + "Sony DSLR-A700", + "Sony DSLR-A850", + "Sony DSLR-A900", + "Sony NEX-3", + "Sony NEX-3N", + "Sony NEX-5", + "Sony NEX-5N", + "Sony NEX-5R", + "Sony NEX-5T", + "Sony NEX-6", + "Sony NEX-7", + "Sony NEX-C3", + "Sony NEX-F3", + "Sony NEX-VG20", + "Sony NEX-VG30", + "Sony NEX-VG900", + "Sony SLT-A33", + "Sony SLT-A35", + "Sony SLT-A37", + "Sony SLT-A55(V)", + "Sony SLT-A57", + "Sony SLT-A58", + "Sony SLT-A65(V)", + "Sony SLT-A77(V)", + "Sony SLT-A99(V)", + "Sony XCD-SX910CR", + "Sony IMX135-mipi 13mp", + "Sony IMX135-QCOM", + "Sony IMX072-mipi", + "Sony IMX214", + "Sony IMX219", + "Sony IMX230", + "Sony IMX298-mipi 16mp", + "Sony IMX219-mipi 8mp", + "Sony Xperia 5 II (XQ-AS52)", + "Sony Xperia L", + "Sony Xperia 1 III", + "Sony ZV-1 (DCZV1/B)", + "Sony ZV-E10", + "STV680 VGA", + "PtGrey GRAS-50S5C", + "JaiPulnix BB-500CL", + "JaiPulnix BB-500GE", + "SVS SVS625CL", + "Vivo X51 5G (V2006)", + "Yi M1", + "YUNEEC CGO3", + "YUNEEC CGO3P", + "YUNEEC CGO4", + "Xiaomi MI3", + "Xiaomi MI 8", + "Xiaomi MI 9 Lite", + "Xiaomi MI MAX", + "Xiaomi POCO M3", + "Xiaomi RedMi Note3 Pro", + "Xiaomi RedMi Note7", + "Xiaomi RedMi Note 8T", + "Xiaomi FIMI X8SE", + "Xiaoyi YIAC3 (YI 4k)", + "Zeiss ZX1", + "Zenit M", + NULL +}; +// clang-format on + +const char **LibRaw::cameraList() { return static_camera_list; } +int LibRaw::cameraCount() +{ + return (sizeof(static_camera_list) / sizeof(static_camera_list[0])) - 1; +} diff --git a/src/tables/colorconst.cpp b/src/tables/colorconst.cpp new file mode 100644 index 000000000..ad5a649cf --- /dev/null +++ b/src/tables/colorconst.cpp @@ -0,0 +1,57 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +const double LibRaw_constants::xyz_rgb[3][3] = { + {0.4124564, 0.3575761, 0.1804375}, + {0.2126729, 0.7151522, 0.0721750}, + {0.0193339, 0.1191920, 0.9503041}}; + +const float LibRaw_constants::d65_white[3] = {0.95047f, 1.0f, 1.08883f}; + +const double LibRaw_constants::xyzd50_srgb[3][3] = { + {0.436083, 0.385083, 0.143055}, + {0.222507, 0.716888, 0.060608}, + {0.013930, 0.097097, 0.714022}}; +const double LibRaw_constants::rgb_rgb[3][3] = { + {1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; +const double LibRaw_constants::adobe_rgb[3][3] = { + {0.715146, 0.284856, 0.000000}, + {0.000000, 1.000000, 0.000000}, + {0.000000, 0.041166, 0.958839}}; +const double LibRaw_constants::wide_rgb[3][3] = { + {0.593087, 0.404710, 0.002206}, + {0.095413, 0.843149, 0.061439}, + {0.011621, 0.069091, 0.919288}}; +const double LibRaw_constants::prophoto_rgb[3][3] = { + {0.529317, 0.330092, 0.140588}, + {0.098368, 0.873465, 0.028169}, + {0.016879, 0.117663, 0.865457}}; +const double LibRaw_constants::aces_rgb[3][3] = { +// Coffin's values (commented out) are not adapted from ACES "D60-like" WP to D65 +// {0.432996, 0.375380, 0.189317}, +// {0.089427, 0.816523, 0.102989}, +// {0.019165, 0.118150, 0.941914}}; + {0.43968015, 0.38295299, 0.17736686}, + {0.08978964, 0.81343316, 0.09677734}, + {0.01754827, 0.11156156, 0.87089017}}; +const double LibRaw_constants::dcip3d65_rgb[3][3] = { + {0.822488, 0.177511, 0.000000}, + {0.033200, 0.966800, 0.000000}, + {0.017089, 0.072411, 0.910499}}; +const double LibRaw_constants::rec2020_rgb[3][3] = { + {0.627452, 0.329249, 0.043299}, + {0.069109, 0.919531, 0.011360}, + {0.016398, 0.088030, 0.895572}}; diff --git a/src/tables/colordata.cpp b/src/tables/colordata.cpp new file mode 100644 index 000000000..fc9f100f7 --- /dev/null +++ b/src/tables/colordata.cpp @@ -0,0 +1,1841 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +/* + All matrices are from Adobe DNG Converter unless otherwise noted. + */ +int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, + int internal_only) +{ + // clang-format off + static const struct + { + unsigned m_idx; + const char *prefix; + int t_black, t_maximum, trans[12]; + } table[] = { + { LIBRAW_CAMERAMAKER_Agfa, "DC-833m", 0, 0, + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Apple, "QuickTake", 0, 0, + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Broadcom, "RPi IMX219", 66, 0x3ff, + { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_Broadcom, "RPi OV5647", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Broadcom, "Pi", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ + +#ifdef USE_6BY9RPI // this code normalizes model to LIBRAW_CAMERAMAKER_RaspberryPi + { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx477", 0, 0, // Do not set black, it is set at parser to 256 or 64 + { 5603, -1351, -600, -2872, 11180, 2132, 600, 453, 5821 } }, /* PyDNG */ + { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx", 66, 0x3ff, + { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_RaspberryPi, "ov5647", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ +#endif + { LIBRAW_CAMERAMAKER_Canon, "EOS D30", 0, 0, + { 9900,-2771,-1324,-7072,14229,3140,-2790,3344,8861 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS D60", 0, 0xfa0, + { 6211,-1358,-896,-8557,15766,3012,-3001,3507,8567 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5DS", 0, 0x3c96, // same CMs: 5DS, "5DS R" */ + { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, // v.2 + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark IV", 0, 0, + { 6446,-366,-864,-4436,12204,2513,-952,2496,6348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark III", 0, 0x3c80, + { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 6D Mark II", 0, 0x38de, + { 6875,-970,-932,-4691,12459,2501,-874,1953,5809 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 6D", 0, 0x3c82, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 77D", 0, 0, + { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 850D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS 800D", 0, 0, + { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 80D", 0, 0, + { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 10D", 0, 0xfa0, + { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 250D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 200D", 0, 0, + { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 60Da", 0, 0x2ff7, + { 17492,-7240,-2023,-1791,10323,1701,-186,1329,5406 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 60D", 0, 0x2ff7, + { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 100D", 0, 0x350f, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 300D", 0, 0xfa0, + { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 3000D", 0, 0, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 550D", 0, 0x3dd7, + { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 600D", 0, 0x3510, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 650D", 0, 0x354d, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 750D", 0, 0x3c00, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 760D", 0, 0x3c00, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 700D", 0, 0x3c00, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 90D", 0, 0, + { 11498, -3759, -1516, -5073, 12954, 2349, -892, 1867, 6118}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1100D", 0, 0x3510, + { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1200D", 0, 0x37c2, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1300D", 0, 0x37c2, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1500D", 0, 0, + { 8300,-2110,-1120,-4917,12694,2482,-938,2141,5666 } }, // v.2 + + { LIBRAW_CAMERAMAKER_Canon, "EOS RP", 0, 0, + { 8608,-2097,-1178,-5425,13265,2383,-1149,2238,5680 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R3", 0, 0, + { 9423,-2839,-1195,-4532,12377,2415,-483,1374,5276 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R5", 0, 0, + { 9766,-2953,-1254,-4276,12116,2433,-437,1336,5131 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R6", 0, 0, + { 8293,-1611,-1132,-4759,12711,2275,-1013,2415,5509 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R7", 0, 0, + { 10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R10", 0, 0, + { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R", 0, 0, + { 8293,-1789,-1094,-5025,12925,2327,-1199,2769,6108 } }, // v.2 + + { LIBRAW_CAMERAMAKER_Canon, "EOS M6 Mark II", 0, 0, + { 11498,-3759,-1516,-5073,12954,2349,-892,1867,6118 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M6", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M50 Mark II", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M50", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M5", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M3", 0, 0, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M200", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M2", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M100", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M10", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M", 0, 0, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds", 0, 0xe20, + { 3925,4060,-1739,-8973,16552,2545,-3287,3945,8243 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D C", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark III", 0, 0, + { 8971, -2022, -1242, -5405, 13249, 2380, -1280, 2483, 6072}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark II", 0, 0x3c4e, + { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS C500", 853, 0, + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Canon, "IXUS 160", 0, 0, + { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, /* DJC */ + {LIBRAW_CAMERAMAKER_Canon, "PowerShot 600", 0, 0, + { -3822,10019,1311,4085,-157,3386,-5341,10829,4812,-1969,10969,1126 } }, + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A3300 IS", 0, 0, + { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A460", 0, 0, + { 6493,-2338,-885,-1589,5934,697,-445,1368,2543 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A470", 0, 0, + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A530", 0, 0, + { 7252,-2405,-1223,-2102,6560,523,-112,704,3007 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A50", 0, 0, + { -6233,10706,1825,3260,821,3980,-6512,10745,6287,-2539,12232,262 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A5", 0, 0, + { -5707,10308,2002,2662,1829,4139,-6265,11063,6033,-2659,11911,593 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A610", 0, 0, + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A620", 0, 0, + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A630", 0, 0, + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A640", 0, 0, + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A650 IS", 0, 0, + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A720 IS", 0, 0, + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot D10", 127, 0, + { 14052,-5229,-1156,-1325,9420,2252,-498,1957,4116 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G12", 0, 0, + { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G15", 0, 0, + { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark III", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark II", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1", 0, 0, + { -5686,10300,2223,4725,-1157,4383,-6128,10783,6163,-2688,12093,604 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G2", 0, 0, + { 9194,-2787,-1059,-8098,15657,2608,-2610,3064,7867 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3 X", 0, 0, + { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3", 0, 0, + { 9326,-2882,-1084,-7940,15447,2677,-2620,3090,7740 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X Mark II",0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X",0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5", 0, 0, + { 9869,-2972,-942,-7314,15098,2369,-1898,2536,7282 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G6", 0, 0, + { 9876,-3774,-871,-7613,14807,3071,-1448,1305,7485 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark III", 0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark II", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X Mark II", 0, 0, + { 10056,-4131,-944,-2576,11143,1625,-238,1294,5179 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X",0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S2 IS", 0, 0, + { 5477,-1435,-992,-1868,6639,510,-58,792,2670 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S3 IS", 0, 0, + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S30", 0, 0, + { 10744,-3813,-1142,-7962,15966,2075,-2492,2805,7744 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S40", 0, 0, + { 8606,-2573,-949,-8237,15489,2974,-2649,3076,9100 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S45", 0, 0, // + + { 8251,-2410,-964,-8047,15430,2823,-2380,2824,8119 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S50", 0, 0, + { 8979,-2658,-871,-7721,15500,2357,-1773,2366,6634 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S60", 0, 0, + { 8794,-2482,-797,-7804,15403,2572,-1422,1996,7083 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S95", 0, 0, + { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S110", 0, 0, + { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S100", 0, 0, + { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SD300", 0, 0, + { 6526,-1720,-1075,-1390,5945,602,-90,820,2380 } }, // CHDK + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX20 IS", 0, 0, + { 8275,-2904,-1260,-128,5305,505,51,481,2450 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX30 IS", 0, 0, + { 13014,-4698,-1026,-2001,9615,2386,-164,1423,3759 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX40 HS", 0, 0, + { 54480,-17404,-8039,-7505,44044,1136,-580,7158,11891 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX50 HS", 0, 0, + { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX70 HS", 0, 0, + { 18285,-8907,-1951,-1845,10688,1323,364,1101,5139 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX110 IS", 0, 0, + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX120 IS", 0, 0, + { 7286,-2242,-1047,41,4401,457,269,684,1864 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX220 HS", 0, 0, + { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX710 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro1", 0, 0, + { 10062,-3522,-1000,-7643,15117,2730,-765,817,7322 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro70", 34, 0, + { -5106,10695,1576,3820,53,4566,-6497,10736,6701,-3336,11887,1394 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro90", 0, 0, + { -5912,10768,2288,4612,-989,4333,-6153,10897,5944,-2907,12288,624 } }, + + { LIBRAW_CAMERAMAKER_Casio, "EX-F1", 0, 0, + { 9084,-2016,-848,-6711,14351,2570,-1059,1725,6135 } }, + { LIBRAW_CAMERAMAKER_Casio, "EX-FH100", 0, 0, + { 12771,-4179,-1558,-2149,10938,1375,-453,1751,4494 } }, + { LIBRAW_CAMERAMAKER_Casio, "EX-S20", 0, 0, + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Casio, "EX-Z750", 0, 0, + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Casio, "EX-Z10", 128, 0xfff, + { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_CINE, "650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { LIBRAW_CAMERAMAKER_CINE, "660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { LIBRAW_CAMERAMAKER_CINE, "", 0, 0, /* empty camera name*/ + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + + { LIBRAW_CAMERAMAKER_Contax, "N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + + { LIBRAW_CAMERAMAKER_DXO, "ONE", 0, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + + { LIBRAW_CAMERAMAKER_Epson, "R-D1", 0, 0, // same CMs: R-D1, R-D1s, R-D1x + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "DBP for GX680", -128, 0x0fff, + { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, /* temp, copy from S2Pro */ + + { LIBRAW_CAMERAMAKER_Fujifilm, "E550", 0, 0, + { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F5", 0, 0, // F500EXR/F505EXR; F550EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F6", 0, 0, // F600EXR/F605EXR; F660EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F77", 0, 0xfe9, // F770EXR/F775EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F7", 0, 0, // same CMs: F700, F710EXR + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F810", 0, 0, + { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F8", 0, 0, // F800EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 100", 0, 0, // same CMs: "GFX 100", "GFX 100S"/"GFX100S", "GFX 100 IR" + { 16212,-8423,-1583,-4336,12583,1937,-195,726,6199 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 50", 0, 0, // same CMs: "GFX 50S", "GFX 50R", "GFX 50S II" + { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "HS10", 0, 0xf68, + { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0, // HS20EXR/HS22EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS3", 0, 0, // HS30EXR/HS33EXR/HS35EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS50EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5100", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5200", 0, 0, // S5200/S5600 + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S6", 0, 0, // S6000fd/S6500fd + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S9000", 0, 0, // S9000/S9500 + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S9100", 0, 0, // S9100/S9600 + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "S100FS", -514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S20", -512, 0x3fff, // S200EXR/S205EXR + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "SL1000", 0, 0, + { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S2Pro", -128, 0, + { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "X100F", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100S", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100T", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100V", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100", 0, 0, + { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X20", 0, 0, + { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X70", 0, 0, + { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "XF10", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "XQ", 0, 0, // same CMs: XQ1, XQ2 + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro2", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro3", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A10", 0, 0, + { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A20", 0, 0, + { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A3", 0, 0, + { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A5", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A7", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2S", 0, 0, + { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E3", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E4", 0, 0, + { 13426, -6334, -1177, -4244, 12136, 2371, -580, 1303, 5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-H1", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-H2S", 0, 0, + { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-S10", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T100", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T1", 0, 0, /* same CMs: X-T1, "X-T1IR", "X-T1 IR", X-T10 */ + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T200", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T2", 0, 0, // same CMs: X-T2, X-T20 + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T3", 0, 0, // same CMs: X-T3, X-T30, "X-T30 II" + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // v.2 + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T4", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + + { LIBRAW_CAMERAMAKER_GITUP, "G3DUO", 130, 62000, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + + { LIBRAW_CAMERAMAKER_GITUP, "GIT2P", 4160, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { LIBRAW_CAMERAMAKER_GITUP, "GIT2", 3200, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + + { LIBRAW_CAMERAMAKER_GoPro, "HERO5 Black", 0, 0, + { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } }, + + {LIBRAW_CAMERAMAKER_Hasselblad, "L1D-20c", 0, 0, + { 7310, -2746, -646, -2991, 10847, 2469, 163, 585, 6324}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-3FR", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-FFF", 0, 0, + { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-3FR", 0, 0, + { 8523, -3257, -280, -5078, 13458, 1743, -1449, 2961, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-FFF", 0, 0, + { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + + {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated-FFF", 0, 0, + { 5155, -1201, 200, -5841, 13197, 2950, -1101, 2317, 6988}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated", 0, 0, + { 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710}}, + + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-3FR", 0, 0, + { 3904, -100, 262, -4318, 12407, 2128, -1598, 3594, 6233}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-FFF", 0, 0, + { 4739, -932, 295, -4829, 12220, 2952, -1027, 2341, 7083}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated", 0, 0, + { 3894, -110, 287, -4672, 12610, 2295, -2092, 4100, 6196}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-3FR", 0, 0, + { 5427, -1147, 173, -3834, 12073, 1969, -1444, 3320, 5621}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-FFF", 0, 0, + { 5323, -1233, 399, -4926, 12362, 2894, -856, 2471, 5961}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated", 0, 0, + { 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718}}, + + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-3FR", 0, 0, + { 7014, -2067, -540, -4821, 13016, 1980, -1663, 3089, 6940}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-FFF", 0, 0, + { 5963, -1357, -172, -5439, 12762, 3007, -964, 2222, 7172}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5", 0, 0, + { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-3FR", 0, 0, + { 6550, -1681, -399, -4626, 12598, 2257, -1807, 3354, 6486}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-FFF", 0, 0, + { 6041, -1375, -174, -5439, 10000, 3007, -930, 2145, 6923}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated", 0, 0, + { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-3FR", 0, 0, + { 5707, -693, -382, -4285, 12669, 1773, -1615, 3519, 5410}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-FFF", 0, 0, + { 5263, -612, 39, -4950, 12426, 2843, -935, 2423, 5941}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5", 0, 0, + { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-3FR", 0, 0, + { 5656, -659, -346, -3923, 12305, 1790, -1602, 3509, 5442}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-FFF", 0, 0, + { 5280, -614, 39, -4950, 12426, 2843, -939, 2434, 5968}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated", 0, 0, + { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-3FR", 0, 0, + { 10887, -6152, 1034, -3564, 12412, 4224, 63, 626, 10123}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-FFF", 0, 0, + { 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II", 0, 0, + { 8737, -4937, 830, -2860, 9961, 3390, 51, 502, 8124}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5", 0, 0, + { 4932,-835,141,-4878,11868,3437,-1138,1961,7067 } }, + + { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated-3FR", 0, 0, + { 9296, 336, -1088, -6442, 14323, 2289, -1433, 2942, 5756}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated", 0, 0, + { 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}}, + + { LIBRAW_CAMERAMAKER_Hasselblad, "100-17-Coated5", 0, 0, + { 5110, -1357, -308, -5573, 12835, 3077, -1279, 2025, 7010}}, + + { LIBRAW_CAMERAMAKER_HTC, "One A9", 64, 1023, + { 101,-20,-2,-11,145,41,-24,1,56 } }, /* this is FM1 transposed */ + + { LIBRAW_CAMERAMAKER_Imacon, "Ixpress", 0, 0, + { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Kodak, "NC2000", 0, 0, // AP Nikon + { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS315C", -8, 0, + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS330C", -8, 0, + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS420", 0, 0, + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS46", 0, 0, // same CM as EOSDCS1 and DCS465 DB + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS520C", -178, 0, // same CamID: DCS520C, "EOS D2000C" + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS560C", -177, 0, // same CamID: DCS560C, "EOS D6000C" + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS620C", -177, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS620X", -176, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS660C", -173, 0, + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS720X", 0, 0, + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS760C", 0, 0, + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro SLR", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro 14nx", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { LIBRAW_CAMERAMAKER_Kodak, "DCS Pro 14", 0, 0, // same CamID: "DCS Pro 14N", "Photo Control Camerz ZDS 14" + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { LIBRAW_CAMERAMAKER_Kodak, "EOSDCS1", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { LIBRAW_CAMERAMAKER_Kodak, "EOSDCS3", 0, 0, + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { LIBRAW_CAMERAMAKER_Kodak, "ProBack645", 0, 0, + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { LIBRAW_CAMERAMAKER_Kodak, "ProBack", 0, 0, + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + + {LIBRAW_CAMERAMAKER_Kodak, "PIXPRO AZ901", 0, 0, // dng + { 21875, -8006, -2558, 634, 8194, 1104, 1535, 951, 6969}}, + { LIBRAW_CAMERAMAKER_Kodak, "P712", 0, 3963, + { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, + { LIBRAW_CAMERAMAKER_Kodak, "P850", 0, 3964, + { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, + { LIBRAW_CAMERAMAKER_Kodak, "P880", 0, 3963, + { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, + { LIBRAW_CAMERAMAKER_Kodak, "Z980", 0, 0, + { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, + { LIBRAW_CAMERAMAKER_Kodak, "Z981", 0, 0, + { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } }, + { LIBRAW_CAMERAMAKER_Kodak, "Z990", 0, 0xfed, + { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } }, + { LIBRAW_CAMERAMAKER_Kodak, "Z1015", 0, 0xef1, + { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + + {LIBRAW_CAMERAMAKER_Leaf, "AFi 54S", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "AFi 65S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "AFi 75S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 17", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 22", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 54S", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 65S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 65", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 75S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "Aptus 75", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, + {LIBRAW_CAMERAMAKER_Leaf, "C-Most", 0, 0, + { 3952, 2188, 449, -6701, 14584, 2275, -4536, 7349, 6535}}, + {LIBRAW_CAMERAMAKER_Leaf, "Credo 40", 0, 0, + { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, + {LIBRAW_CAMERAMAKER_Leaf, "Credo 50", 0, 0, // emb + { 10325, 845, -604, -4113, 13385, 481, -1791, 4163, 6924}}, + {LIBRAW_CAMERAMAKER_Leaf, "Credo 60", 0, 0, + { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, + {LIBRAW_CAMERAMAKER_Leaf, "Credo 80", 0, 0, + { 6294, 686, -712, -5435, 13417, 2211, -1006, 2435, 5042}}, + {LIBRAW_CAMERAMAKER_Leaf, "Valeo 11", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Valeo 17", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Valeo 22", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, + {LIBRAW_CAMERAMAKER_Leaf, "Valeo 6", 0, 0, + { 3952, 2188, 449, -6701, 14584, 2275, -4536, 7349, 6535}}, + +// { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 6", 0, 0, + { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 7", 0, 0, + { 7691,-108,-339,-6185,13627,2833,-2046,3899,5952 } }, + { LIBRAW_CAMERAMAKER_Leaf, "AFi-II 10", 0, 0, + { 6719,1147,-148,-6929,14061,3176,-1781,3343,5424 } }, + + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 5", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 6", 0, 0, + { 7989,-113,-352,-6185,13627,2833,-2028,3866,5901 } }, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 7", 0, 0, + { 8209,-116,-362,-6185,13627,2833,-1962,3740,5709 } }, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 8", 0, 0, + { 7361,1257,-163,-6929,14061,3176,-1839,3454,5603 } }, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 10R", 0, 0, + { 7167,1224,-158,-6929,14061,3176,-1826,3429,5562 } }, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 10", 0, 0, + { 7527,1285,-166,-6929,14061,3176,-1995,3747,6077 } }, +// { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 12R", 0, 0, + { LIBRAW_CAMERAMAKER_Leaf, "Aptus-II 12", 0, 0, + { 7361,1257,-163,-6929,14061,3176,-1695,3182,5162 } }, + + { LIBRAW_CAMERAMAKER_Leica, "CL", 0, 0, + { 7743,-2896,-921,-4211,12271,2169,-697,1562,5491 } }, + + { LIBRAW_CAMERAMAKER_Leica, "M8", 0, 0, + { 7675,-2196,-305,-5860,14119,1856,-2425,4006,6578 } }, + { LIBRAW_CAMERAMAKER_Leica, "M9", 0, 0, + { 6687,-1751,-291,-3556,11373,2492,-548,2204,7146 } }, + { LIBRAW_CAMERAMAKER_Leica, "M10", 0, 0, // same CMs: M10, M10-D, M10-P + { 9090,-3342,-740,-4006,13456,493,-569,2266,6871 } }, + { LIBRAW_CAMERAMAKER_Leica, "M (Typ 2", 0, 0, // same CMs: "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)" + { 7199,-2140,-712,-4005,13327,649,-810,2521,6673 } }, + + { LIBRAW_CAMERAMAKER_Leica, "Q (Typ 116)", 0, 0, + { 10068,-4043,-1068,-5319,14268,1044,-765,1701,6522 } }, + { LIBRAW_CAMERAMAKER_Leica, "Q2", 0, 0, + { 12312,-5440,-1307,-6408,15499,824,-1075,1677,7220 } }, + + { LIBRAW_CAMERAMAKER_Leica, "SL (Typ 601)", 0, 0, + { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, + { LIBRAW_CAMERAMAKER_Leica, "S (Typ 007)", 0, 0, + { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } }, + { LIBRAW_CAMERAMAKER_Leica, "S2", 0, 0, + { 5627,-721,-447,-4423,12456,2192,-1048,2948,7379 } }, + { LIBRAW_CAMERAMAKER_Leica, "S3", 0, 0, +// { 5147,-1464,-318,-5374,13263,2325,-1425,2918,6450 } }, + { 5092,-1630,-470,-6313,14297,2170,-1603,3135,5982 } }, + {LIBRAW_CAMERAMAKER_Leica, "S", 0, 0, // same CMs: "S-E (Typ 006)", "S (Typ 006)" + { 5749,-1072,-382,-4274,12432,2048,-1166,3104,7105 } }, + + { LIBRAW_CAMERAMAKER_Leica, "TL2", 0, 0, + { 6375,-2062,-732,-4878,12838,2262,-877,1705,6204 } }, + { LIBRAW_CAMERAMAKER_Leica, "T", 0, 0, // same CMs: TL, "T (Typ 701)" + { 6295,-1679,-475,-5586,13046,2837,-1410,1889,7075 } }, + + { LIBRAW_CAMERAMAKER_Leica, "X2", 0, 0, + { 8336,-2853,-699,-4425,11989,2760,-954,1625,6396 } }, + { LIBRAW_CAMERAMAKER_Leica, "X1", 0, 0, + { 9055,-2611,-666,-4906,12652,2519,-555,1384,7417 } }, + { LIBRAW_CAMERAMAKER_Leica, "X", 0, 0, /* same CMs: "X (Typ 113)", "X-U (Typ 113)", XV, "X Vario (Typ 107)" */ + { 9062,-3198,-828,-4065,11772,2603,-761,1468,6458 } }, + + { LIBRAW_CAMERAMAKER_Mamiya,"ZD", 0, 0, + { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, + + { LIBRAW_CAMERAMAKER_Micron, "2010", 110, 0, + { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 5", 0, 0xf7d, + { 9117,-3063,-973,-7949,15763,2306,-2752,3136,8093 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7Hi", 0, 0xf7d, + { 11555,-4064,-1256,-7903,15633,2409,-2811,3320,7358 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7i", 0, 0xf7d, + { 11050,-3791,-1199,-7875,15585,2434,-2797,3359,7560 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE 7", 0, 0xf7d, + { 9258,-2879,-1008,-8076,15847,2351,-2806,3280,7821 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A1", 0, 0xf8b, + { 9274,-2548,-1167,-8220,16324,1943,-2273,2721,8340 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A200", 0, 0, + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE A2", 0, 0xf8f, + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DiMAGE Z2", 0, 0, + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Minolta, "DG-5D", 0, 0xffb, // same CamID: "ALPHA 5D", "DYNAX 5D", "MAXXUM 5D", "Alpha Sweet Digital" + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { LIBRAW_CAMERAMAKER_Minolta, "DG-7D", 0, 0xffb, // same CamID: "ALPHA 7D", "DYNAX 7D", "MAXXUM 7D" + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + + { LIBRAW_CAMERAMAKER_Motorola, "PIXL", 0, 0, + { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Nikon, "1 AW1", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 J3", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 J4", 0, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 J5", 0, 0, + { 7520,-2518,-645,-3844,12102,1945,-913,2249,6835 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 S2", -200, 0, + { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 V2", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 V3", -200, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { LIBRAW_CAMERAMAKER_Nikon, "1 ", 0, 0, /* same CMs: "1 J1", "1 J2", "1 S1", "1 V1" */ + { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 2100", 0, 0, // a.k.a. E2100 + { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711 } }, /* DJC, copied from Z2, new white balance */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 2500", 0, 0, // a.k.a. E2500, possibly same CM as for E5000 + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 3200", 0, 0, // a.k.a. E3200 + { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 4300", 0, 0, // a.k.a. E4300 + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, /* DJC, copied from Minolta DiMAGE Z2 */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 4500", 0, 0, // a.k.a. E4500, possibly same CM as for E5000 + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5000", 0, 0, // a.k.a. E5000 + { -6678,12805,2248,5725,-499,3375,-5903,10713,6034,-270,9976,134 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5400", 0, 0, // a.k.a. E5400 + { 9349,-2988,-1001,-7918,15766,2266,-2097,2680,6839 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 5700", 0, 0, // a.k.a. E5700 + { -6475,12496,2428,5409,-16,3180,-5965,10912,5866,-177,9918,248 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8400", 0, 0, // a.k.a. E8400 + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8700", 0, 0, // a.k.a. E8700 + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 8800", 0, 0, // a.k.a. E8800 + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 700", 0, 0x3dd, // a.k.a. E700 + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 800", 0, 0x3dd, // a.k.a. E800 + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 950", 0, 0x3dd, // a.k.a. E950 + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX 995", 0, 0, // a.k.a. E995 + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, /* DJC, copied from E5000 */ + + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX A1000", 0, 0, + { 10601,-3487,-1127,-2931,11443,1676,-587,1740,5278 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX B700", 0, 0, + { 14387,-6014,-1299,-1357,9975,1616,467,1047,4744 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX A", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P1000", 0, 0, + { 14294,-6116,-1333,-1628,10219,1637,-14,1158,5022 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P6000", 0, 0, + { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7000", 0, 0, + { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7100", 0, 0, + { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7700", -3200, 0, // same CamID: "COOLPIX P7700", "COOLPIX Deneb" + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P7800", -3200, 0, // same CamID: "COOLPIX P7800", "COOLPIX Kalon" + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P330", -200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { LIBRAW_CAMERAMAKER_Nikon, "COOLPIX P340", -200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Coolpix P950", 0, 0, + { 13307, -5641, -1290, -2048, 10581, 1689, -64, 1222, 5176}}, + + { LIBRAW_CAMERAMAKER_Nikon, "D3000", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3100", 0, 0, + { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3200", 0, 0xfb9, + { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3400", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5000", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5100", 0, 0x3de6, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5600", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D7000", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D7100", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D7200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D7500", 0, 0, + { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "D100", 0, 0, + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D200", 0, 0xfbc, + { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D300", 0, 0, // same CMs: D300, D300s + { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D500", 0, 0, + { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D600", 0, 0x3e07, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D610",0, 0, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D700", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D750", -600, 0, + { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D780", -600, 0, + { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D800", 0, 0, // same CMs: D800, D800E + { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D810A", 0, 0, + { 11973,-5685,-888,-1965,10326,1901,-115,1123,7169 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D810", 0, 0, + { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D850", 0, 0, + { 10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "D40X", 0, 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D40", 0, 0, + { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D70", 0, 0, // same CMs: D70, D70s + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D80", 0, 0, + { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D90", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "D1H", 0, 0, + { 7659,-2238,-935,-8942,16969,2004,-2701,3051,8690 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D1X", 0, 0, + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D1", 0, 0, +// { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, /* multiplied by 2.218750, 1.0, 1.148438 */ + { 7637,-2199,-974,-9109,17099,2043,-2822,3306,8372 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D2H", 0, 0, // same CMs: D2H, D2Hs + { 5733,-911,-629,-7967,15987,2055,-3050,4013,7048 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D2X", 0, 0, // same CMs: D2X, D2Xs + { 10231,-2768,-1254,-8302,15900,2551,-797,681,7148 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3S", 0, 0, + { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3X", 0, 0, + { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D3", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D4", 0, 0, // same CMs: D4, D4S (and Df) + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D5", 0, 0, + { 9200,-3522,-992,-5755,13803,2117,-753,1486,6338 } }, + { LIBRAW_CAMERAMAKER_Nikon, "D6", 0, 0, + { 9028,-3423,-1035,-6321,14265,2217,-1013,1683,6928 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Df", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + + { LIBRAW_CAMERAMAKER_Nikon, "Z 50", 0, 0, + { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Z 5", 0, 0, + { 8695,-2558,-648,-5015,12711,2575,-1279,2215,7514 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Z 6", 0, 0, + { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, // 'Z 6'(v.2), 'Z 6_2' + { LIBRAW_CAMERAMAKER_Nikon, "Z 7", 0, 0, + { 13705,-6004,-1400,-5464,13568,2062,-940,1706,7618 } }, // 'Z 7'(v.2), 'Z 7_2' + { LIBRAW_CAMERAMAKER_Nikon, "Z 9", 0, 0, + { 13389,-6049,-1441,-4544,12757,1969,229,498,7390 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Z fc", 0, 0, + { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "AIR A01", 0, 0xfe1, + { 8992,-3093,-639,-2563,10721,2122,-437,1270,5473 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "C-5050Z", 0, 0, + { 10633,-3234,-1285,-7460,15570,1967,-1917,2510,6299 } }, + { LIBRAW_CAMERAMAKER_Olympus, "C-5060WZ", 0, 0, + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { LIBRAW_CAMERAMAKER_Olympus, "C-7070WZ", 0, 0, + { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, + { LIBRAW_CAMERAMAKER_Olympus, "C-7000Z", 0, 0, + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { LIBRAW_CAMERAMAKER_Olympus, "C-8080WZ", 0, 0, + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-300", 0, 0, + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-330", 0, 0, + { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-400", 0, 0, + { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-410", 0, 0xf6a, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-420", 0, 0xfd7, + { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-450", 0, 0xfd2, + { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-500", 0, 0, + { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-510", 0, 0xf6a, + { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-520", 0, 0xfd2, + { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-600", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-620", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-10", 0, 0x3ff, + { 12970,-4703,-1433,-7466,15843,1644,-2191,2451,6668 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-20", 0, 0x3ff, // model is "E-20,E-20N,E-20P" + { 13414,-4950,-1517,-7166,15293,1960,-2325,2664,7212 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-30", 0, 0xfbc, + { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-1", 0, 0, + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-3", 0, 0xf99, + { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-5", 0, 0xeec, + { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-P1", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-P2", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-P3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-P5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-P7", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-PL10", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL1s", 0, 0, + { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL1", 0, 0, + { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL2", 0, 0xcf3, + { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL5", 0, 0xfcb, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL6", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL7", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL8", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PL9", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-PM2", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-M10 Mark IV", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M10", 0, 0, // Same CMs: E-M10, E-M10 Mark II, E-M10 Mark III; "CLAUSS piX 5oo" + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M1X", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-M1 Mark III", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M1 Mark II", 0, 0, + { 9383,-3170,-763,-2457,10702,2020,-384,1236,5552 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M1", 0, 0, + { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "E-M5 Mark III", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M5 Mark II", 0, 0, + { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, + { LIBRAW_CAMERAMAKER_Olympus, "E-M5", 0, 0xfe1, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "PEN-F",0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "SH-2", 0, 0, // same CamID: SH-2, SH-3 + { 10156,-3425,-1077,-2611,11177,1624,-385,1592,5080 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "SP-350", 0, 0, + { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-3", 0, 0, // Same CMs: SP310, SP320 + { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-500UZ", 0, 0xfff, + { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-510UZ", 0, 0xffe, + { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-550UZ", 0, 0xffe, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-560UZ", 0, 0xff9, + { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-565UZ", 0, 0, + { 11856,-4469,-1159,-4814,12368,2756,-993,1779,5589 } }, + { LIBRAW_CAMERAMAKER_Olympus, "SP-570UZ", 0, 0, + { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "STYLUS 1",0, 0, // Olympus "STYLUS 1 and STYLUS 1s have the same CamID, cameras are slightly different + { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "TG-4", 0, 0, + { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } }, + { LIBRAW_CAMERAMAKER_Olympus, "TG-", 0, 0, // same CMs: TG-5, TG-6 + { 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "XZ-10", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + { LIBRAW_CAMERAMAKER_Olympus, "XZ-1", 0, 0, + { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, + { LIBRAW_CAMERAMAKER_Olympus, "XZ-2", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + + { LIBRAW_CAMERAMAKER_Olympus, "OM-1", 0, 0, + { 9488, -3984, -714, -2887, 10945, 2229, -137, 960, 5786 } }, + + { LIBRAW_CAMERAMAKER_OmniVison, "", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Pentax, "*istDL2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { LIBRAW_CAMERAMAKER_Pentax, "*istDL", 0, 0, + { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, + { LIBRAW_CAMERAMAKER_Pentax, "*istDS2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { LIBRAW_CAMERAMAKER_Pentax, "*istDS", 0, 0, + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { LIBRAW_CAMERAMAKER_Pentax, "*istD", 0, 0, + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + + { LIBRAW_CAMERAMAKER_Pentax, "K-01", 0, 0, + { 8134,-2728,-645,-4365,11987,2694,-838,1509,6498 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K10D", 0, 0, + { 9679,-2965,-811,-8622,16514,2182,-975,883,9793 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K1", 0, 0, // same CMs: K100D, "K100D Super", K110D + { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K20D", 0, 0, + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K200D", 0, 0, + { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-m", 0, 0, + { 9730,-2989,-970,-8527,16258,2381,-1060,970,8362 } }, + { LIBRAW_CAMERAMAKER_Pentax, "KP", 0, 0, + { 7825,-2160,-1403,-4841,13555,1349,-1559,2449,5814 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-x", 0, 0, + { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-r", 0, 0, + { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-1", 0, 0, // same CMs: K-1, "K-1 Mark II" + { 8596,-2981,-639,-4202,12046,2431,-685,1424,6122 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-30", 0, 0, + { 8134,-2728,-645,-4365,11987,2694,-838,1509,6498 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-3 Mark III", 0, 0, + { 9251, -3817, -1069, -4627, 12667, 2175, -798, 1660, 5633 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-3", 0, 0, // same CMs: K-3, "K-3 II" + { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-500", 0, 0, + { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-50", 0, 0, + { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-5 II", 0, 0, // same CMs: "K-5 II" and "K-5 IIs" + { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-5", 0, 0, + { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-70", 0, 0, + { 8766,-3149,-747,-3976,11943,2292,-517,1259,5552 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-7", 0, 0, + { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { LIBRAW_CAMERAMAKER_Pentax, "KP", 0, 0, + { 8617,-3228,-1034,-4674,12821,2044,-803,1577,5728 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-S1", 0, 0, + { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, + { LIBRAW_CAMERAMAKER_Pentax, "K-S2", 0, 0, + { 8662,-3280,-798,-3928,11771,2444,-586,1232,6054 } }, + + { LIBRAW_CAMERAMAKER_Pentax, "Q-S1", 0, 0, + { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } }, + { LIBRAW_CAMERAMAKER_Pentax, "Q7", 0, 0, + { 10901,-3938,-1025,-2743,11210,1738,-823,1805,5344 } }, + { LIBRAW_CAMERAMAKER_Pentax, "Q10", 0, 0, + { 11562,-4183,-1172,-2357,10919,1641,-582,1726,5112 } }, + { LIBRAW_CAMERAMAKER_Pentax, "Q", 0, 0, + { 11731,-4169,-1267,-2015,10727,1473,-217,1492,4870 } }, + + { LIBRAW_CAMERAMAKER_Pentax, "MX-1", 0, 0, + { 9296,-3146,-888,-2860,11287,1783,-618,1698,5151 } }, + + { LIBRAW_CAMERAMAKER_Pentax, "645D", 0, 0x3e00, + { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { LIBRAW_CAMERAMAKER_Pentax, "645Z", 0, 0, + { 9519,-3591,-664,-4074,11725,2671,-624,1501,6653 } }, + + + {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1R", 0, 0, + { 11822,-5321,-1249,-5958,15114,766,-614,1264,7043 } }, + {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1H", 0, 0, + { 9397,-3719,-805,-5425,13326,2309,-972,1715,6034 } }, + {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1", 0, 0, + { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, + {LIBRAW_CAMERAMAKER_Panasonic, "DC-S5", 0, 0, + { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-CM1", -15, 0, // same CMs: DMC-CM1, DMC-CM10 + { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DC-FZ1000M2", -15, 0, + { 9803,-4185,-992,-4066,12578,1628,-838,1824,5288 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ1000", -15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ2500", -15, 0, + { 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ100", -15, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ150", -15, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ200", -15, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ300", -15, 0xfff, + { 8378,-2798,-769,-3068,11410,1877,-538,1792,4623 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ18", 0, 0, + { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ28", -15, 0xf96, + { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ30", 0, 0xf94, + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ35", -15, 0, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ40", -15, 0, + { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ50", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ70", -15, 0, + { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-FZ80", -15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FZ8", 0, 0xf7f, + { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, + + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-L10", -15, 0xf96, + { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-L1", 0, 0xf7f, + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LC1", 0, 0, + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LF1", -15, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DC-LX100M2", -15, 0, + { 8585,-3127,-833,-4005,12250,1953,-650,1494,4862 } }, // v.2 + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX100", -15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX1", 0, 0xf7f, + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX2", 0, 0, + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX3", -15, 0, + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX5", -15, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX7", -15, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-LX9", -15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-FX150", -15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DC-G99", -15, 0, + { 9657,-3963,-748,-3361,11378,2258,-568,1415,5158 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-G100", -15, 0, + { 8370,-2869,-710,-3389,11372,2298,-640,1599,4887 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G10", 0, 0, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G1", -15, 0xf94, + { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G2", -15, 0xf3c, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G3", -15, 0xfff, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G5", -15, 0xfff, + { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G6", -15, 0xfff, + { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G7", -15, 0xfff, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G8", -15, 0xfff, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-G9", -15, 0, + { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH1", -15, 0xf92, + { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH2", -15, 0xf95, + { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH3", -15, 0, + { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GH4", -15, 0, + { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5s", -15, 0, + { 6929,-2355,-708,-4192,12534,1828,-1097,1989,5195 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5M2", 0, 0, + { 9300, -3659, -755, -2981, 10988, 2287, -190, 1077, 5016 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5", -15, 0, + { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GM1", -15, 0, + { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GM5", -15, 0, + { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GF10", -15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF1", -15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF2", -15, 0xfff, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF3", -15, 0xfff, + { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF5", -15, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF6", -15, 0, + { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF7", -15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GF8", -15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GF9", -15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX85", -15, 0, + { 7771,-3020,-629,-4029,11950,2345,-821,1977,6119 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX1", -15, 0, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX7", -15,0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GX8", -15,0, + { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GX9", -15, 0, + { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS100", -15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS200", -15, 0, + { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS40", -15, 0, + { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS50", -15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS60", -15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS70", -15, 0, + { 9052,-3117,-883,-3045,11346,1927,-205,1520,4730 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS80", -15, 0, + { 12194,-5340,-1329,-3035,11394,1858,-50,1418,5219 } }, + + { LIBRAW_CAMERAMAKER_PhaseOne, "H20", 0, 0, + { 3906,1422,-467,-9953,18472,1365,-3307,4496,6406 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "H25", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ4 150MP", 0, 0, + { 6644, -2257, -804, -6459, 14562, 2019, -1221, 1876, 6411}}, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ140", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ150", 0, 0, + {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* temp */ /* emb */ +// { 3984,0,0,0,10000,0,0,0,7666 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ160", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ180", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, + + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ250",0, 0, +// {3984,0,0,0,10000,0,0,0,7666}}, + {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* emb */ + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ260", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ280", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, + + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 100MP", 0, 0, +// {2423,0,0,0,9901,0,0,0,7989}}, + { 10999,354,-742,-4590,13342,937,-1060,2166,8120} }, /* emb */ + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 50MP", 0, 0, +// { 3984,0,0,0,10000,0,0,0,7666 } }, + {10058,1079,-587,-4135,12903,944,-916,2726,7480}}, /* emb */ + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 60MP", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "IQ3 80MP", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, + + { LIBRAW_CAMERAMAKER_PhaseOne, "P21", 0, 0, + { 6516,-2050,-507,-8217,16703,1479,-3492,4741,8489 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "P30", 0, 0, + { 4516,-244,-36,-7020,14976,2174,-3206,4670,7087 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "P40", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "P45", 0, 0, + { 5053,-24,-117,-5685,14077,1703,-2619,4491,5850 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "P65", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { LIBRAW_CAMERAMAKER_PhaseOne, "P2", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + + { LIBRAW_CAMERAMAKER_Photron, "BC2-HD", 0, 0, + { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Polaroid, "x530", 0, 0, + { 13458,-2556,-510,-5444,15081,205,0,0,12120 } }, + + { LIBRAW_CAMERAMAKER_RED, "One", 704, 0xffff, + { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Ricoh, "S10 24-72mm F2.5-4.4 VC", 0, 0, + { 10531,-4043,-878,-2038,10270,2052,-107,895,4577 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR A12 50mm F2.5 MACRO", 0, 0, + { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 2", 0, 0, + { 8846,-2704,-729,-5265,12708,2871,-1471,1955,6218 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 3", 0, 0, + { 8170,-2496,-655,-5147,13056,2312,-1367,1859,5265 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR DIGITAL 4", 0, 0, + { 8771,-3151,-837,-3097,11015,2389,-703,1343,4924 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR III", 0, 0, + { 6127,-1777,-585,-5913,13699,2428,-1088,1780,6017 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR II", 0, 0, + { 5329,-1459,-390,-5407,12930,2768,-1119,1772,6046 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GR", 0, 0, + { 5329,-1459,-390,-5407,12930,2768,-1119,1772,6046 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GX200", 0, 0, + { 8040,-2368,-626,-4659,12543,2363,-1125,1581,5660 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR Mount A12", 0, 0, + { 7834,-2182,-739,-5453,13409,2241,-952,2005,6620 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR A12 50mm", 0, 0, + { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR A12 28mm", 0, 0, + { 10228,-3159,-933,-5304,13158,2371,-943,1873,6685 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR A16", 0, 0, + { 7837,-2538,-730,-4370,12184,2461,-868,1648,5830 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR P10", 0, 0, + { 13168,-5128,-1663,-3006,11569,1611,-373,1244,4907 } }, + { LIBRAW_CAMERAMAKER_Ricoh, "GXR S10", 0, 0, + { 8963,-2926,-754,-4881,12921,2164,-1464,1944,4901 } }, + + { LIBRAW_CAMERAMAKER_Samsung, "EX1", 0, 0x3e00, + { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, + { LIBRAW_CAMERAMAKER_Samsung, "EX2F", 0, 0x7ff, + { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, +// { LIBRAW_CAMERAMAKER_Samsung, "GX20", 0, 0, +// { 23213,-14575,-4840,-7077,16564,316,385,-1656,9398 } }, // Adobe DNG +// { 27717,-17403,-5779,-8450,19778,377,459,1978,11221 } }, // Samsung DNG +// { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, // Adobe DCP + +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6 Edge Rear Camera", 0, 0, +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6 Rear Camera", 0, 0, + { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S6", 0, 0, // same CMs: "Galaxy S6", "Galaxy S6 Edge" + { 13699,-5767,-1384,-4449,13879,499,-467,1691,5892 } }, + +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7 Edge Rear Camera", 0, 0, +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7 Rear Camera", 0, 0, + { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S7", 0, 0, // same CMs: "Galaxy S7", "Galaxy S7 Edge" + { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, + +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8+ Rear Camera", 0, 0, +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8 Rear Camera", 0, 0, + { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S8", 0, 0, // same CMs: "Galaxy S8", "Galaxy S8+" + { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, + +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9+ Rear Camera", 0, 0, +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9 Rear Camera", 0, 0, + { LIBRAW_CAMERAMAKER_Samsung, "Galaxy S9", 0, 0, // same CMs: "Galaxy S9", "Galaxy S9+" + { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, +// { LIBRAW_CAMERAMAKER_Samsung, "Galaxy Note 9 Rear Telephoto Camera", 0, 0, + { LIBRAW_CAMERAMAKER_Samsung, "Galaxy Note 9 Rear Camera", 0, 0, + { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, + + { LIBRAW_CAMERAMAKER_Samsung, "NX U", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX3300", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX3000", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX30", 0, 0, // same CMs: NX30, NX300, NX300M + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX2000", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX2", 0, 0xfff, // same CMs: NX20, NX200, NX210 + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX1000", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX1100", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX11", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX10", 0, 0, // same CMs: NX10, NX100 + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX500", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX5", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX1", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, + { LIBRAW_CAMERAMAKER_Samsung, "NX mini", 0, 0, + { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + + { LIBRAW_CAMERAMAKER_Samsung, "WB2000", 0, 0xfff, + { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, + { LIBRAW_CAMERAMAKER_Samsung, "WB5000", 0, 0, + { 7675, -2195, -305, -5860, 14118, 1857, -2425, 4007, 6578}}, + { LIBRAW_CAMERAMAKER_Samsung, "S85", 0, 0, + { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, /* DJC */ + +// Foveon: LibRaw color data + { LIBRAW_CAMERAMAKER_Sigma, "dp0 Quattro", 2047, 0, + { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, + { LIBRAW_CAMERAMAKER_Sigma, "dp1 Quattro", 2047, 0, + { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, + { LIBRAW_CAMERAMAKER_Sigma, "dp2 Quattro", 2047, 0, + { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, + { LIBRAW_CAMERAMAKER_Sigma, "dp3 Quattro", 2047, 0, + { 13801,-3390,-1016,5535,3802,877,1848,4245,3730 } }, + { LIBRAW_CAMERAMAKER_Sigma, "sd Quattro H", 256, 0, + { 1295,108,-311,256,828,-65,-28,750,254 } }, /* temp */ + { LIBRAW_CAMERAMAKER_Sigma, "sd Quattro", 2047, 0, + { 1295,108,-311,256,828,-65,-28,750,254 } }, /* temp */ + { LIBRAW_CAMERAMAKER_Sigma, "SD9", 15, 4095, + { 13564,-2537,-751,-5465,15154,194,-67,116,10425 } }, + { LIBRAW_CAMERAMAKER_Sigma, "SD10", 15, 16383, + { 6787,-1682,575,-3091,8357,160,217,-369,12314 } }, + { LIBRAW_CAMERAMAKER_Sigma, "SD14", 15, 16383, + { 13589,-2509,-739,-5440,15104,193,-61,105,10554 } }, + { LIBRAW_CAMERAMAKER_Sigma, "SD15", 15, 4095, + { 13556,-2537,-730,-5462,15144,195,-61,106,10577 } }, +// Merrills + SD1 + { LIBRAW_CAMERAMAKER_Sigma, "SD1", 31, 4095, + { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_Sigma, "DP1 Merrill", 31, 4095, + { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_Sigma, "DP2 Merrill", 31, 4095, + { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_Sigma, "DP3 Merrill", 31, 4095, + { 5133,-1895,-353,4978,744,144,3837,3069,2777 } }, /* LibRaw */ +// Sigma DP (non-Merrill Versions) + { LIBRAW_CAMERAMAKER_Sigma, "DP1X", 0, 4095, + { 13704,-2452,-857,-5413,15073,186,-89,151,9820 } }, + { LIBRAW_CAMERAMAKER_Sigma, "DP1", 0, 4095, + { 12774,-2591,-394,-5333,14676,207,15,-21,12127 } }, + { LIBRAW_CAMERAMAKER_Sigma, "DP", 0, 4095, + // { 7401,-1169,-567,2059,3769,1510,664,3367,5328 } }, + { 13100,-3638,-847,6855,2369,580,2723,3218,3251 } }, /* LibRaw */ + + { LIBRAW_CAMERAMAKER_Sinar, "", 0, 0, + { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, /* DJC */ + + { LIBRAW_CAMERAMAKER_Sony, "DSC-F828", 0, 0, + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-R1", 0, 0, + { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-V3", 0, 0, + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + + { LIBRAW_CAMERAMAKER_Sony, "DSC-HX9", -800, 0, // same CMs: DSC-HX95, DSC-HX99 + { 13076,-5686,-1481,-4027,12851,1251,-167,725,4937 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ZV-1", -800, 0, + { 8280,-2987,-703,-3531,11645,2133,-550,1542,5312 } }, + { LIBRAW_CAMERAMAKER_Sony, "ZV-E10", 0, 0, + { 6355,-2067,-490,-3653,11542,2400,-406,1258,5506 } }, + + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M7", -800, 0, + {10315, -4390, -937, -4859, 12734, 2365, -734, 1537, 5997 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M6", -800, 0, + { 7325,-2321,-596,-3494,11674,2055,-668,1562,5031 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M5A", -800, 0, + { 11176,-4700,-965,-4004,12184,2032,-763,1726,5876 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M", -800, 0, // same CMs: DSC-RX100M2, DSC-RX100M3, DSC-RX100M4, DSC-RX100M5 + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100", 0, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX10M4", -800, 0, + { 7699,-2566,-629,-2967,11270,1928,-378,1286,4807 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX10",0, 0, // same CMs: DSC-RX10, DSC-RX10M2, DSC-RX10M3 + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1R", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX1", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + + { LIBRAW_CAMERAMAKER_Sony, "DSC-RX0", -800, 0, // same CMs: DSC-RX0, DSC-RX0M2 + { 9396,-3507,-843,-2497,11111,1572,-343,1355,5089 } }, + + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A290", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A2", 0, 0, // same CMs: DSLR-A200, DSLR-A230 + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A300", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A330", 0, 0, + { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A3", 0, 0, // same CMs: DSLR-A350, DSLR-A380, DSLR-A390 + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A450", 0, 0, // close to 16596 if arw is 14-bit + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A580", 0, 16596, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A500", 0, 16596, + { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A5", 0, 16596, // same CMs: DSLR-A550, DSLR-A560 + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A700", 0, 0, + { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A850", 0, 0, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { LIBRAW_CAMERAMAKER_Sony, "DSLR-A900", 0, 0, + { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCA-68", 0, 0, + { 6435,-1903,-536,-4722,12449,2550,-663,1363,6517 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCA-77M2", 0, 0, + { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCA-99M2", 0, 0, + { 6660,-1918,-471,-4613,12398,2485,-649,1433,6447 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-1", 0, 0, + { 8161, -2947, -739, -4811, 12668, 2389, -437, 1229, 6524}}, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM4", 0, 0, // same CMs: ILCE-7RM4, ILCE-7RM4A + { 7662, -2686,-660,-5240, 12965,2530, -796, 1508, 6167 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM3", 0, 0, // same CMs: ILCE-7RM3, ILCE-7RM3A + { 6640,-1847,-503,-5238,13010,2474,-993,1673,6527 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM2", 0, 0, + { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7R", 0, 0, + { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7SM3", 0, 0, + { 6912,-2127,-469,-4470,12175,2587,-398,1478,6492 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7S", 0, 0, // same CMs: ILCE-7S, ILCE-7SM2 + { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7C", 0, 0, + { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7M4", 0, 0, + { 7460,-2365,-588,-5687,13442,2474,-624,1156,6584 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7M3", 0, 0, + { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7", 0, 0, // same CMs: ILCE-7, ILCE-7M2 + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-9", 0, 0, // same CMs: ILCE-9, ILCE-9M2 + { 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6100", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6300", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6400", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6500", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6600", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE", 0, 0, // same CMs: ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1 + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + + { LIBRAW_CAMERAMAKER_Sony, "ILME-FX3", 0, 0, + { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } }, + + { LIBRAW_CAMERAMAKER_Sony, "NEX-5N", 0, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-5R", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-5T", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-5", 0, 0, + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-3N", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-3", 0, 0, + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-6", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-7", 0, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-VG30", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX-VG900", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { LIBRAW_CAMERAMAKER_Sony, "NEX", 0, 0, // same CMs: NEX-C3, NEX-F3, NEX-VG20 + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A33", 0, 0, + { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A35", 0, 0, + { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A37", 0, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A55", 0, 0, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A5", 0, 0, // same CMs: SLT-A57, SLT-A58 + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A65", 0, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A77", 0, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { LIBRAW_CAMERAMAKER_Sony, "SLT-A99", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { LIBRAW_CAMERAMAKER_Sony, "MODEL-NAME", 0, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + + { LIBRAW_CAMERAMAKER_YI, "M1", 0, 0, + { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } }, + }; + // clang-format on + + double cam_xyz[4][3]; + //char name[130]; + int i, j; + + if (colors > 4 || colors < 1) + return 1; + + int bl4 = (cblack[0] + cblack[1] + cblack[2] + cblack[3]) / 4, bl64 = 0; + if (cblack[4] * cblack[5] > 0) + { + for (unsigned c = 0; c < 4096 && c < cblack[4] * cblack[5]; c++) + bl64 += cblack[c + 6]; + bl64 /= cblack[4] * cblack[5]; + } + int rblack = black + bl4 + bl64; + + for (i = 0; i < int(sizeof table / sizeof *table); i++) + { + if (table[i].m_idx == make_idx) + { + size_t l = strlen(table[i].prefix); + if (!l || !strncasecmp(t_model, table[i].prefix, l)) + { + if (!dng_version) + { + if (table[i].t_black > 0) + { + black = (ushort)table[i].t_black; + memset(cblack, 0, sizeof(cblack)); + } + else if (table[i].t_black < 0 && rblack == 0) + { + black = (ushort)(-table[i].t_black); + memset(cblack, 0, sizeof(cblack)); + } + if (table[i].t_maximum) + maximum = (ushort)table[i].t_maximum; + } + if (table[i].trans[0]) + { + for (raw_color = j = 0; j < 12; j++) + if (internal_only) + imgdata.color.cam_xyz[j / 3][j % 3] = table[i].trans[j] / 10000.f; + else + ((double *)cam_xyz)[j] = imgdata.color.cam_xyz[j / 3][j % 3] = table[i].trans[j] / 10000.f; + if (!internal_only) + cam_xyz_coeff(rgb_cam, cam_xyz); + } + return 1; // CM found + } + } + } + return 0; // CM not found +} +void LibRaw::simple_coeff(int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + {1.4032f, -0.2231f, -0.1016f, -0.5263f, 1.4816f, 0.017f, -0.0112f, 0.0183f, + 0.9113f}, + /* index 1 -- Kodak DC20 and DC25 */ + {2.25f, 0.75f, -1.75f, -0.25f, -0.25f, 0.75f, 0.75f, -0.25f, -0.25f, -1.75f, 0.75f, + 2.25f}, + /* index 2 -- Logitech Fotoman Pixtura */ + {1.893f, -0.418f, -0.476f, -0.495f, 1.773f, -0.278f, -1.017f, -0.655f, 2.672f}, + /* index 3 -- Nikon E880, E900, and E990 */ + {-1.936280f, 1.800443f, -1.448486f, 2.584324f, 1.405365f, -0.524955f, -0.289090f, + 0.408680f, -1.204965f, 1.082304f, 2.941367f, -1.818705f}}; + int i, c; + + for (raw_color = i = 0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i * MIN(colors,4) + c]; +} diff --git a/src/tables/wblists.cpp b/src/tables/wblists.cpp new file mode 100644 index 000000000..f377cd3ec --- /dev/null +++ b/src/tables/wblists.cpp @@ -0,0 +1,217 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + + +#define _ARR_SZ(a) (sizeof(a)/sizeof(a[0])) + +static const int _tagtype_dataunit_bytes [19] = { + 1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8 +}; + +libraw_static_table_t LibRaw::tagtype_dataunit_bytes(_tagtype_dataunit_bytes, _ARR_SZ(_tagtype_dataunit_bytes)); + +int libraw_tagtype_dataunit_bytes(int tagtype) +{ + return _tagtype_dataunit_bytes[((unsigned)tagtype <= _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0]; +} + + +static const int _Canon_wbi2std[] = { // Canon WB index to standard indexes +// std. number wbi - Canon number + LIBRAW_WBI_Auto, // 0 + LIBRAW_WBI_Daylight, // 1 + LIBRAW_WBI_Cloudy, // 2 + LIBRAW_WBI_Tungsten, // 3 + LIBRAW_WBI_Fluorescent, // 4 + LIBRAW_WBI_Flash, // 5 + LIBRAW_WBI_Custom, // 6 + LIBRAW_WBI_BW, // 7 + LIBRAW_WBI_Shade, // 8 + LIBRAW_WBI_Kelvin, // 9 + LIBRAW_WBI_PC_Set1, // 10 + LIBRAW_WBI_PC_Set2, // 11 + LIBRAW_WBI_PC_Set3, // 12 + LIBRAW_WBI_Unknown, // 13, unlucky number "13", not used + LIBRAW_WBI_FluorescentHigh, // 14 + LIBRAW_WBI_Custom1, // 15 + LIBRAW_WBI_Custom2, // 16 + LIBRAW_WBI_Underwater, // 17, last one for older PowerShot models + LIBRAW_WBI_Custom3, // 18 + LIBRAW_WBI_Custom4, // 19 + LIBRAW_WBI_PC_Set4, // 20 + LIBRAW_WBI_PC_Set5, // 21 + LIBRAW_WBI_Unknown, // 22 + LIBRAW_WBI_Auto1 // 23 +}; + +libraw_static_table_t LibRaw::Canon_wbi2std(_Canon_wbi2std, _ARR_SZ(_Canon_wbi2std)); + +static const int _Canon_KeyIsZero_Len2048_linenums_2_StdWBi[] = { // Appendix A: G2, S30, S40; G3, G5, S45, S50 + LIBRAW_WBI_Custom1, + LIBRAW_WBI_Custom2, + LIBRAW_WBI_Daylight, + LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, + LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_Unknown, // ? FluorescentHigh, Shade, Custom, Kelvin + LIBRAW_WBI_Flash +}; + +libraw_static_table_t LibRaw::Canon_KeyIsZero_Len2048_linenums_2_StdWBi(_Canon_KeyIsZero_Len2048_linenums_2_StdWBi, + _ARR_SZ(_Canon_KeyIsZero_Len2048_linenums_2_StdWBi)); + +static const int _Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi[] = { // G6, S60, S70; offset +16 + LIBRAW_WBI_Custom1, + LIBRAW_WBI_Custom2, + LIBRAW_WBI_Daylight, + LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, + LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_FluorescentHigh, // LIBRAW_WBI_Unknown, // ? FluorescentHigh, Shade, Custom, Kelvin + LIBRAW_WBI_Unknown, + LIBRAW_WBI_Underwater, // LIBRAW_WBI_Unknown, + LIBRAW_WBI_Unknown, + LIBRAW_WBI_Flash +}; + +libraw_static_table_t LibRaw::Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi(_Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi, + _ARR_SZ(_Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi)); + +static const int _Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi[] = { // Pro1; offset +8 + LIBRAW_WBI_Custom1, + LIBRAW_WBI_Custom2, + LIBRAW_WBI_Daylight, + LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, + LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_Unknown, + LIBRAW_WBI_Flash, // LIBRAW_WBI_Unknown, + LIBRAW_WBI_Unknown, + LIBRAW_WBI_Unknown, + LIBRAW_WBI_Unknown // LIBRAW_WBI_Flash +}; + +libraw_static_table_t LibRaw::Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi(_Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi, + _ARR_SZ(_Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi)); + +static const int _Canon_G9_linenums_2_StdWBi[] = { + LIBRAW_WBI_Auto, + LIBRAW_WBI_Daylight, + LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, + LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_FluorescentHigh, + LIBRAW_WBI_Flash, + LIBRAW_WBI_Underwater, + LIBRAW_WBI_Custom1, + LIBRAW_WBI_Custom2 +}; +libraw_static_table_t LibRaw::Canon_G9_linenums_2_StdWBi(_Canon_G9_linenums_2_StdWBi, _ARR_SZ(_Canon_G9_linenums_2_StdWBi)); + +static const int _Canon_D30_linenums_2_StdWBi[] = { + LIBRAW_WBI_Daylight, + LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, + LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_Flash, + LIBRAW_WBI_Custom +}; +libraw_static_table_t LibRaw::Canon_D30_linenums_2_StdWBi(_Canon_D30_linenums_2_StdWBi, _ARR_SZ(_Canon_D30_linenums_2_StdWBi)); + +static const int _Fuji_wb_list1[] = { + LIBRAW_WBI_FineWeather, LIBRAW_WBI_Shade, LIBRAW_WBI_FL_D, + LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_Tungsten + +}; +libraw_static_table_t LibRaw::Fuji_wb_list1(_Fuji_wb_list1, _ARR_SZ(_Fuji_wb_list1)); + +static const int _FujiCCT_K[31] = { + 2500, 2550, 2650, 2700, 2800, 2850, 2950, 3000, 3100, 3200, 3300, + 3400, 3600, 3700, 3800, 4000, 4200, 4300, 4500, 4800, 5000, 5300, + 5600, 5900, 6300, 6700, 7100, 7700, 8300, 9100, 10000 +}; +libraw_static_table_t LibRaw::FujiCCT_K(_FujiCCT_K, _ARR_SZ(_FujiCCT_K)); + +static const int _Fuji_wb_list2[] = { + LIBRAW_WBI_Auto, 0, LIBRAW_WBI_Custom, 6, LIBRAW_WBI_FineWeather, 1, + LIBRAW_WBI_Shade, 8, LIBRAW_WBI_FL_D, 10, LIBRAW_WBI_FL_N, 11, + LIBRAW_WBI_FL_W, 12, LIBRAW_WBI_Tungsten, 2, LIBRAW_WBI_Underwater, 35, + LIBRAW_WBI_Ill_A, 82, LIBRAW_WBI_D65, 83 +}; +libraw_static_table_t LibRaw::Fuji_wb_list2(_Fuji_wb_list2, _ARR_SZ(_Fuji_wb_list2)); + +static const int _Pentax_wb_list1[] = { + LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, + LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, + LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, + LIBRAW_WBI_FL_W, LIBRAW_WBI_Flash +}; +libraw_static_table_t LibRaw::Pentax_wb_list1(_Pentax_wb_list1, _ARR_SZ(_Pentax_wb_list1)); + +static const int _Pentax_wb_list2[] = { + LIBRAW_WBI_Daylight, LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, + LIBRAW_WBI_Tungsten, LIBRAW_WBI_FL_D, LIBRAW_WBI_FL_N, + LIBRAW_WBI_FL_W, LIBRAW_WBI_Flash, LIBRAW_WBI_FL_L +}; +libraw_static_table_t LibRaw::Pentax_wb_list2(_Pentax_wb_list2, _ARR_SZ(_Pentax_wb_list2)); + + +static const int _Oly_wb_list1[] = { + LIBRAW_WBI_Shade, LIBRAW_WBI_Cloudy, LIBRAW_WBI_FineWeather, + LIBRAW_WBI_Tungsten, LIBRAW_WBI_Sunset, LIBRAW_WBI_FL_D, + LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_W, LIBRAW_WBI_FL_WW +}; +libraw_static_table_t LibRaw::Oly_wb_list1(_Oly_wb_list1, _ARR_SZ(_Oly_wb_list1)); + +static const int _Oly_wb_list2[] = { + LIBRAW_WBI_Auto, 0, + LIBRAW_WBI_Tungsten, 3000, + 0x100, 3300, + 0x100, 3600, + 0x100, 3900, + LIBRAW_WBI_FL_W, 4000, + 0x100, 4300, + LIBRAW_WBI_FL_D, 4500, + 0x100, 4800, + LIBRAW_WBI_FineWeather, 5300, + LIBRAW_WBI_Cloudy, 6000, + LIBRAW_WBI_FL_N, 6600, + LIBRAW_WBI_Shade, 7500, + LIBRAW_WBI_Custom1, 0, + LIBRAW_WBI_Custom2, 0, + LIBRAW_WBI_Custom3, 0, + LIBRAW_WBI_Custom4, 0 +}; +libraw_static_table_t LibRaw::Oly_wb_list2(_Oly_wb_list2, _ARR_SZ(_Oly_wb_list2)); + +static const int _Sony_SRF_wb_list[] = { + LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Fluorescent, + LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash +}; +libraw_static_table_t LibRaw::Sony_SRF_wb_list(_Sony_SRF_wb_list, _ARR_SZ(_Sony_SRF_wb_list)); + +static const int _Sony_SR2_wb_list[] = { + LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash, + 4500, LIBRAW_WBI_Unknown, LIBRAW_WBI_Fluorescent +}; +libraw_static_table_t LibRaw::Sony_SR2_wb_list(_Sony_SR2_wb_list, _ARR_SZ(_Sony_SR2_wb_list)); + +static const int _Sony_SR2_wb_list1[] = { + LIBRAW_WBI_Daylight, LIBRAW_WBI_Cloudy, LIBRAW_WBI_Tungsten, LIBRAW_WBI_Flash, + 4500, LIBRAW_WBI_Shade, LIBRAW_WBI_FL_W, LIBRAW_WBI_FL_N, LIBRAW_WBI_FL_D, + LIBRAW_WBI_FL_L, 8500, 6000, 3200, 2500 +}; +libraw_static_table_t LibRaw::Sony_SR2_wb_list1(_Sony_SR2_wb_list1, _ARR_SZ(_Sony_SR2_wb_list1)); diff --git a/src/utils/curves.cpp b/src/utils/curves.cpp new file mode 100644 index 000000000..03b1253bb --- /dev/null +++ b/src/utils/curves.cpp @@ -0,0 +1,151 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +void LibRaw::cubic_spline(const int *x_, const int *y_, const int len) +{ + float **A, *b, *c, *d, *x, *y; + int i, j; + + A = (float **)calloc(((2 * len + 4) * sizeof **A + sizeof *A), 2 * len); + if (!A) + return; + A[0] = (float *)(A + 2 * len); + for (i = 1; i < 2 * len; i++) + A[i] = A[0] + 2 * len * i; + y = len + (x = i + (d = i + (c = i + (b = A[0] + i * i)))); + for (i = 0; i < len; i++) + { + x[i] = x_[i] / 65535.0; + y[i] = y_[i] / 65535.0; + } + for (i = len - 1; i > 0; i--) + { + b[i] = (y[i] - y[i - 1]) / (x[i] - x[i - 1]); + d[i - 1] = x[i] - x[i - 1]; + } + for (i = 1; i < len - 1; i++) + { + A[i][i] = 2 * (d[i - 1] + d[i]); + if (i > 1) + { + A[i][i - 1] = d[i - 1]; + A[i - 1][i] = d[i - 1]; + } + A[i][len - 1] = 6 * (b[i + 1] - b[i]); + } + for (i = 1; i < len - 2; i++) + { + float v = A[i + 1][i] / A[i][i]; + for (j = 1; j <= len - 1; j++) + A[i + 1][j] -= v * A[i][j]; + } + for (i = len - 2; i > 0; i--) + { + float acc = 0; + for (j = i; j <= len - 2; j++) + acc += A[i][j] * c[j]; + c[i] = (A[i][len - 1] - acc) / A[i][i]; + } + for (i = 0; i < 0x10000; i++) + { + float x_out = (float)(i / 65535.0); + float y_out = 0; + for (j = 0; j < len - 1; j++) + { + if (x[j] <= x_out && x_out <= x[j + 1]) + { + float v = x_out - x[j]; + y_out = y[j] + + ((y[j + 1] - y[j]) / d[j] - + (2 * d[j] * c[j] + c[j + 1] * d[j]) / 6) * + v + + (c[j] * 0.5) * v * v + + ((c[j + 1] - c[j]) / (6 * d[j])) * v * v * v; + } + } + curve[i] = y_out < 0.0 + ? 0 + : (y_out >= 1.0 ? 65535 : (ushort)(y_out * 65535.0 + 0.5)); + } + free(A); +} +void LibRaw::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 LibRaw::linear_table(unsigned len) +{ + int i; + if (len > 0x10000) + len = 0x10000; + else if (len < 1) + return; + read_shorts(curve, len); + for (i = len; i < 0x10000; i++) + curve[i] = curve[i - 1]; + maximum = curve[len < 0x1000 ? 0xfff : len - 1]; +} diff --git a/src/utils/decoder_info.cpp b/src/utils/decoder_info.cpp new file mode 100644 index 000000000..cc440db4d --- /dev/null +++ b/src/utils/decoder_info.cpp @@ -0,0 +1,413 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#include "../../internal/libraw_cxx_defs.h" + +const char *LibRaw::unpack_function_name() +{ + libraw_decoder_info_t decoder_info; + get_decoder_info(&decoder_info); + return decoder_info.decoder_name; +} + +int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) +{ + if (!d_info) + return LIBRAW_UNSPECIFIED_ERROR; + d_info->decoder_name = 0; + d_info->decoder_flags = 0; + if (!load_raw) + return LIBRAW_OUT_OF_ORDER_CALL; + + // dcraw.c names order + if (load_raw == &LibRaw::android_tight_load_raw) + { + d_info->decoder_name = "android_tight_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::android_loose_load_raw) + { + d_info->decoder_name = "android_loose_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) + { + d_info->decoder_name = "vc5_dng_load_raw_placeholder()"; +#ifndef USE_GPRSDK + d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; +#endif + } + else if (load_raw == &LibRaw::canon_600_load_raw) + { + d_info->decoder_name = "canon_600_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::fuji_compressed_load_raw) + { + d_info->decoder_name = "fuji_compressed_load_raw()"; + } + else if (load_raw == &LibRaw::fuji_14bit_load_raw) + { + d_info->decoder_name = "fuji_14bit_load_raw()"; + } + else if (load_raw == &LibRaw::canon_load_raw) + { + d_info->decoder_name = "canon_load_raw()"; + } + else if (load_raw == &LibRaw::lossless_jpeg_load_raw) + { + d_info->decoder_name = "lossless_jpeg_load_raw()"; + d_info->decoder_flags = + LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::canon_sraw_load_raw) + { + d_info->decoder_name = "canon_sraw_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::crxLoadRaw) + { + d_info->decoder_name = "crxLoadRaw()"; + } + else if (load_raw == &LibRaw::lossless_dng_load_raw) + { + d_info->decoder_name = "lossless_dng_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | + LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | + LIBRAW_DECODER_ADOBECOPYPIXEL; + } + else if (load_raw == &LibRaw::packed_dng_load_raw) + { + d_info->decoder_name = "packed_dng_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | + LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | + LIBRAW_DECODER_ADOBECOPYPIXEL; + } + else if (load_raw == &LibRaw::pentax_load_raw) + { + d_info->decoder_name = "pentax_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::nikon_load_raw) + { + d_info->decoder_name = "nikon_load_raw()"; + d_info->decoder_flags = + LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::nikon_coolscan_load_raw) + { + d_info->decoder_name = "nikon_coolscan_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::nikon_he_load_raw_placeholder) + { + d_info->decoder_name = "nikon_he_load_raw_placeholder()"; + d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; + } + else if (load_raw == &LibRaw::nikon_load_sraw) + { + d_info->decoder_name = "nikon_load_sraw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::nikon_yuv_load_raw) + { + d_info->decoder_name = "nikon_load_yuv_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::rollei_load_raw) + { + // UNTESTED + d_info->decoder_name = "rollei_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::phase_one_load_raw) + { + d_info->decoder_name = "phase_one_load_raw()"; + } + else if (load_raw == &LibRaw::phase_one_load_raw_c) + { + d_info->decoder_name = "phase_one_load_raw_c()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; /* FIXME: need to make sure correction not applied*/ + } + else if (load_raw == &LibRaw::phase_one_load_raw_s) + { + d_info->decoder_name = "phase_one_load_raw_s()"; + } + else if (load_raw == &LibRaw::hasselblad_load_raw) + { + d_info->decoder_name = "hasselblad_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; /* FIXME: need to make sure correction not applied*/ + } + else if (load_raw == &LibRaw::leaf_hdr_load_raw) + { + d_info->decoder_name = "leaf_hdr_load_raw()"; + } + else if (load_raw == &LibRaw::unpacked_load_raw) + { + d_info->decoder_name = "unpacked_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FLATDATA; + } + else if (load_raw == &LibRaw::unpacked_load_raw_reversed) + { + d_info->decoder_name = "unpacked_load_raw_reversed()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::sinar_4shot_load_raw) + { + // UNTESTED + d_info->decoder_name = "sinar_4shot_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_SINAR4SHOT; + } + else if (load_raw == &LibRaw::imacon_full_load_raw) + { + d_info->decoder_name = "imacon_full_load_raw()"; + } + else if (load_raw == &LibRaw::hasselblad_full_load_raw) + { + d_info->decoder_name = "hasselblad_full_load_raw()"; + } + else if (load_raw == &LibRaw::packed_load_raw) + { + d_info->decoder_name = "packed_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::broadcom_load_raw) + { + // UNTESTED + d_info->decoder_name = "broadcom_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::nokia_load_raw) + { + // UNTESTED + d_info->decoder_name = "nokia_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + else if (load_raw == &LibRaw::canon_rmf_load_raw) + { + // UNTESTED + d_info->decoder_name = "canon_rmf_load_raw()"; + } +#endif + else if (load_raw == &LibRaw::panasonic_load_raw) + { + d_info->decoder_name = "panasonic_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED; + } + else if (load_raw == &LibRaw::panasonicC6_load_raw) + { + d_info->decoder_name = "panasonicC6_load_raw()"; + /* FIXME: No rawspeed3: not sure it handles 12-bit data too */ + } + else if (load_raw == &LibRaw::panasonicC7_load_raw) + { + d_info->decoder_name = "panasonicC7_load_raw()"; + } + else if (load_raw == &LibRaw::olympus_load_raw) + { + d_info->decoder_name = "olympus_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3;; + } + else if (load_raw == &LibRaw::minolta_rd175_load_raw) + { + // UNTESTED + d_info->decoder_name = "minolta_rd175_load_raw()"; + } + else if (load_raw == &LibRaw::quicktake_100_load_raw) + { + // UNTESTED + d_info->decoder_name = "quicktake_100_load_raw()"; + } + else if (load_raw == &LibRaw::kodak_radc_load_raw) + { + d_info->decoder_name = "kodak_radc_load_raw()"; + } + else if (load_raw == &LibRaw::kodak_jpeg_load_raw) + { + // UNTESTED + RBAYER + d_info->decoder_name = "kodak_jpeg_load_raw()"; + } + else if (load_raw == &LibRaw::lossy_dng_load_raw) + { + // Check rbayer + d_info->decoder_name = "lossy_dng_load_raw()"; + d_info->decoder_flags = + LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_HASCURVE; + } + else if (load_raw == &LibRaw::kodak_dc120_load_raw) + { + d_info->decoder_name = "kodak_dc120_load_raw()"; + } + else if (load_raw == &LibRaw::eight_bit_load_raw) + { + d_info->decoder_name = "eight_bit_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::kodak_c330_load_raw) + { + d_info->decoder_name = "kodak_yrgb_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::kodak_c603_load_raw) + { + d_info->decoder_name = "kodak_yrgb_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::kodak_262_load_raw) + { + d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED! + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::kodak_65000_load_raw) + { + d_info->decoder_name = "kodak_65000_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE; + } + else if (load_raw == &LibRaw::kodak_ycbcr_load_raw) + { + // UNTESTED + d_info->decoder_name = "kodak_ycbcr_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::kodak_rgb_load_raw) + { + // UNTESTED + d_info->decoder_name = "kodak_rgb_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::sony_load_raw) + { + d_info->decoder_name = "sony_load_raw()"; + } + else if (load_raw == &LibRaw::sony_ljpeg_load_raw) + { + d_info->decoder_name = "sony_ljpeg_load_raw()"; + } + else if (load_raw == &LibRaw::sony_arw_load_raw) + { + d_info->decoder_name = "sony_arw_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::sony_arw2_load_raw) + { + d_info->decoder_name = "sony_arw2_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE | + LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3 | + LIBRAW_DECODER_SONYARW2; + } + else if (load_raw == &LibRaw::sony_arq_load_raw) + { + d_info->decoder_name = "sony_arq_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_LEGACY_WITH_MARGINS | LIBRAW_DECODER_FLATDATA | LIBRAW_DECODER_FLAT_BG2_SWAPPED; + } + else if (load_raw == &LibRaw::samsung_load_raw) + { + d_info->decoder_name = "samsung_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED | LIBRAW_DECODER_TRYRAWSPEED3; + } + else if (load_raw == &LibRaw::samsung2_load_raw) + { + d_info->decoder_name = "samsung2_load_raw()"; + } + else if (load_raw == &LibRaw::samsung3_load_raw) + { + d_info->decoder_name = "samsung3_load_raw()"; + } + else if (load_raw == &LibRaw::smal_v6_load_raw) + { + // UNTESTED + d_info->decoder_name = "smal_v6_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } + else if (load_raw == &LibRaw::smal_v9_load_raw) + { + // UNTESTED + d_info->decoder_name = "smal_v9_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; + } +#ifdef LIBRAW_OLD_VIDEO_SUPPORT + else if (load_raw == &LibRaw::redcine_load_raw) + { + d_info->decoder_name = "redcine_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_HASCURVE; + } +#endif + else if (load_raw == &LibRaw::x3f_load_raw) + { + d_info->decoder_name = "x3f_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC | LIBRAW_DECODER_FIXEDMAXC | + LIBRAW_DECODER_LEGACY_WITH_MARGINS; + } + else if (load_raw == &LibRaw::pentax_4shot_load_raw) + { + d_info->decoder_name = "pentax_4shot_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; + } + else if (load_raw == &LibRaw::deflate_dng_load_raw) + { + d_info->decoder_name = "deflate_dng_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; + } + else if (load_raw == &LibRaw::uncompressed_fp_dng_load_raw) + { + d_info->decoder_name = "uncompressed_fp_dng_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_OWNALLOC; + } + else if (load_raw == &LibRaw::nikon_load_striped_packed_raw) + { + d_info->decoder_name = "nikon_load_striped_packed_raw()"; + } + else if (load_raw == &LibRaw::nikon_load_padded_packed_raw) + { + d_info->decoder_name = "nikon_load_padded_packed_raw()"; + } + else if (load_raw == &LibRaw::nikon_14bit_load_raw) + { + d_info->decoder_name = "nikon_14bit_load_raw()"; + } + /* -- added 07/02/18 -- */ + else if (load_raw == &LibRaw::unpacked_load_raw_fuji_f700s20) + { + d_info->decoder_name = "unpacked_load_raw_fuji_f700s20()"; + } + else if (load_raw == &LibRaw::unpacked_load_raw_FujiDBP) + { + d_info->decoder_name = "unpacked_load_raw_FujiDBP()"; + } +#ifdef USE_6BY9RPI + else if (load_raw == &LibRaw::rpi_load_raw8) + { + d_info->decoder_name = "rpi_load_raw8"; + } + else if (load_raw == &LibRaw::rpi_load_raw12) + { + d_info->decoder_name = "rpi_load_raw12"; + } + else if (load_raw == &LibRaw::rpi_load_raw14) + { + d_info->decoder_name = "rpi_load_raw14"; + } + else if (load_raw == &LibRaw::rpi_load_raw16) + { + d_info->decoder_name = "rpi_load_raw16"; + } +#endif + else + { + d_info->decoder_name = "Unknown unpack function"; + d_info->decoder_flags = LIBRAW_DECODER_NOTSET; + } + return LIBRAW_SUCCESS; +} diff --git a/src/utils/init_close_utils.cpp b/src/utils/init_close_utils.cpp new file mode 100644 index 000000000..26478d88c --- /dev/null +++ b/src/utils/init_close_utils.cpp @@ -0,0 +1,340 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#ifdef USE_RAWSPEED3 +#include "rawspeed3_capi.h" +#endif + +static void cleargps(libraw_gps_info_t *q) +{ + for (int i = 0; i < 3; i++) + q->latitude[i] = q->longitude[i] = q->gpstimestamp[i] = 0.f; + q->altitude = 0.f; + q->altref = q->latref = q->longref = q->gpsstatus = q->gpsparsed = 0; +} + +LibRaw::LibRaw(unsigned int flags) : memmgr(1024) +{ + double aber[4] = {1, 1, 1, 1}; + double gamm[6] = {0.45, 4.5, 0, 0, 0, 0}; + unsigned greybox[4] = {0, 0, UINT_MAX, UINT_MAX}; + unsigned cropbox[4] = {0, 0, UINT_MAX, UINT_MAX}; + ZERO(imgdata); + + cleargps(&imgdata.other.parsed_gps); + ZERO(libraw_internal_data); + ZERO(callbacks); + + _rawspeed_camerameta = _rawspeed_decoder = NULL; + _rawspeed3_handle = NULL; + dnghost = NULL; + dngnegative = NULL; + dngimage = NULL; + _x3f_data = NULL; + +#ifdef USE_RAWSPEED + CameraMetaDataLR *camerameta = + make_camera_metadata(); // May be NULL in case of exception in + // make_camera_metadata() + _rawspeed_camerameta = static_cast(camerameta); +#endif + callbacks.data_cb = (flags & LIBRAW_OPTIONS_NO_DATAERR_CALLBACK) + ? NULL + : &default_data_callback; + callbacks.exif_cb = NULL; // no default callback + callbacks.pre_identify_cb = NULL; + callbacks.post_identify_cb = NULL; + callbacks.pre_subtractblack_cb = callbacks.pre_scalecolors_cb = + callbacks.pre_preinterpolate_cb = callbacks.pre_interpolate_cb = + callbacks.interpolate_bayer_cb = callbacks.interpolate_xtrans_cb = + callbacks.post_interpolate_cb = callbacks.pre_converttorgb_cb = + callbacks.post_converttorgb_cb = NULL; + + memmove(&imgdata.params.aber, &aber, sizeof(aber)); + memmove(&imgdata.params.gamm, &gamm, sizeof(gamm)); + memmove(&imgdata.params.greybox, &greybox, sizeof(greybox)); + memmove(&imgdata.params.cropbox, &cropbox, sizeof(cropbox)); + + imgdata.params.bright = 1; + imgdata.params.use_camera_matrix = 1; + imgdata.params.user_flip = -1; + imgdata.params.user_black = -1; + imgdata.params.user_cblack[0] = imgdata.params.user_cblack[1] = + imgdata.params.user_cblack[2] = imgdata.params.user_cblack[3] = -1000001; + imgdata.params.user_sat = -1; + imgdata.params.user_qual = -1; + imgdata.params.output_color = 1; + imgdata.params.output_bps = 8; + imgdata.params.use_fuji_rotate = 1; + imgdata.params.exp_shift = 1.0; + imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD; + imgdata.params.adjust_maximum_thr = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; + imgdata.rawparams.use_rawspeed = 1; + imgdata.rawparams.use_dngsdk = LIBRAW_DNG_DEFAULT; + imgdata.params.no_auto_scale = 0; + imgdata.params.no_interpolation = 0; + imgdata.rawparams.specials = 0; /* was inverted : LIBRAW_PROCESSING_DP2Q_INTERPOLATERG | LIBRAW_PROCESSING_DP2Q_INTERPOLATEAF; */ + imgdata.rawparams.options = LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT; + imgdata.rawparams.sony_arw2_posterization_thr = 0; + imgdata.rawparams.max_raw_memory_mb = LIBRAW_MAX_ALLOC_MB_DEFAULT; + imgdata.params.green_matching = 0; + imgdata.rawparams.custom_camera_strings = 0; + imgdata.rawparams.coolscan_nef_gamma = 1.0f; + imgdata.parent_class = this; + imgdata.progress_flags = 0; + imgdata.color.dng_levels.baseline_exposure = -999.f; + imgdata.color.dng_levels.LinearResponseLimit = 1.0f; + MN.hasselblad.nIFD_CM[0] = + MN.hasselblad.nIFD_CM[1] = -1; + MN.kodak.ISOCalibrationGain = 1.0f; + _exitflag = 0; + tls = new LibRaw_TLS; + tls->init(); +} + +LibRaw::~LibRaw() +{ + recycle(); + delete tls; +#ifdef USE_RAWSPEED3 + if (_rawspeed3_handle) + rawspeed3_close(_rawspeed3_handle); + _rawspeed3_handle = NULL; +#endif + +#ifdef USE_RAWSPEED + if (_rawspeed_camerameta) + { + CameraMetaDataLR *cmeta = + static_cast(_rawspeed_camerameta); + delete cmeta; + _rawspeed_camerameta = NULL; + } +#endif +} + +void x3f_clear(void *); + +void LibRaw::recycle() +{ + recycle_datastream(); +#define FREE(a) \ + do \ + { \ + if (a) \ + { \ + free(a); \ + a = NULL; \ + } \ + } while (0) + + FREE(imgdata.image); + + // explicit cleanup of afdata allocations; entire array is zeroed below + for (int i = 0; i < LIBRAW_AFDATA_MAXCOUNT; i++) + FREE(MN.common.afdata[i].AFInfoData); + + FREE(imgdata.thumbnail.thumb); + FREE(libraw_internal_data.internal_data.meta_data); + FREE(libraw_internal_data.output_data.histogram); + FREE(libraw_internal_data.output_data.oprof); + FREE(imgdata.color.profile); + FREE(imgdata.rawdata.ph1_cblack); + FREE(imgdata.rawdata.ph1_rblack); + FREE(imgdata.rawdata.raw_alloc); + FREE(imgdata.idata.xmpdata); + + parseCR3_Free(); + +#undef FREE + + ZERO(imgdata.sizes); + imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[1].cleft = 0xffff; + imgdata.sizes.raw_inset_crops[0].ctop = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff; + + ZERO(imgdata.idata); + ZERO(imgdata.color); + ZERO(imgdata.lens); + ZERO(imgdata.other); + ZERO(imgdata.rawdata); + ZERO(imgdata.shootinginfo); + ZERO(imgdata.thumbnail); + ZERO(imgdata.thumbs_list); + ZERO(MN); + cleargps(&imgdata.other.parsed_gps); + ZERO(libraw_internal_data); + + imgdata.lens.makernotes.FocalUnits = 1; + imgdata.lens.makernotes.LensID = LIBRAW_LENS_NOT_SET; + imgdata.shootinginfo.DriveMode = -1; + imgdata.shootinginfo.FocusMode = -1; + imgdata.shootinginfo.MeteringMode = -1; + imgdata.shootinginfo.AFPoint = -1; + imgdata.shootinginfo.ExposureMode = -1; + imgdata.shootinginfo.ExposureProgram = -1; + imgdata.shootinginfo.ImageStabilization = -1; + + imgdata.color.dng_levels.baseline_exposure = -999.f; + imgdata.color.dng_levels.LinearResponseLimit = 1.f; + imgdata.color.dng_color[0].illuminant = + imgdata.color.dng_color[1].illuminant = LIBRAW_WBI_None; + for (int i = 0; i < 4; i++) imgdata.color.dng_levels.analogbalance[i] = 1.0f; + + MN.canon.DefaultCropAbsolute.l = -1; + MN.canon.DefaultCropAbsolute.t = -1; + MN.canon.AutoLightingOptimizer = 3; // 'off' value + + MN.fuji.WB_Preset = 0xffff; + MN.fuji.ExpoMidPointShift = -999.f; + MN.fuji.DynamicRange = 0xffff; + MN.fuji.FilmMode = 0xffff; + MN.fuji.DynamicRangeSetting = 0xffff; + MN.fuji.DevelopmentDynamicRange = 0xffff; + MN.fuji.AutoDynamicRange = 0xffff; + MN.fuji.DRangePriority = 0xffff; + MN.fuji.FocusMode = 0xffff; + MN.fuji.AFMode = 0xffff; + MN.fuji.FocusPixel[0] = MN.fuji.FocusPixel[1] = 0xffff; + MN.fuji.FocusSettings = 0xffffffff; + MN.fuji.AF_C_Settings = 0xffffffff; + MN.fuji.FocusWarning = 0xffff; + for (int i = 0; i < 3; i++) MN.fuji.ImageStabilization[i] = 0xffff; + MN.fuji.DriveMode = -1; + MN.fuji.ImageCount = -1; + MN.fuji.AutoBracketing = -1; + MN.fuji.SequenceNumber = -1; + MN.fuji.SeriesLength = -1; + MN.fuji.PixelShiftOffset[0] = MN.fuji.PixelShiftOffset[1] = -999.f; + + MN.hasselblad.nIFD_CM[0] = MN.hasselblad.nIFD_CM[1] = -1; + + MN.kodak.BlackLevelTop = 0xffff; + MN.kodak.BlackLevelBottom = 0xffff; + MN.kodak.ISOCalibrationGain = 1.0f; + + MN.nikon.SensorHighSpeedCrop.cleft = 0xffff; + MN.nikon.SensorHighSpeedCrop.ctop = 0xffff; + + MN.olympus.FocusMode[0] = 0xffff; + MN.olympus.AutoFocus = 0xffff; + MN.olympus.AFPoint = 0xffff; + MN.olympus.AFResult = 0xffff; + MN.olympus.AFFineTune = 0xff; + for (int i = 0; i < 3; i++) { + MN.olympus.AFFineTuneAdj[i] = -32768; + MN.olympus.SpecialMode[i] = 0xffffffff; + } + MN.olympus.ZoomStepCount = 0xffff; + MN.olympus.FocusStepCount = 0xffff; + MN.olympus.FocusStepInfinity = 0xffff; + MN.olympus.FocusStepNear = 0xffff; + MN.olympus.FocusDistance = -999.0; + for (int i = 0; i < 4; i++) MN.olympus.AspectFrame[i] = 0xffff; + MN.olympus.StackedImage[0] = 0xffffffff; + + MN.panasonic.LensManufacturer = 0xffffffff; + + MN.pentax.FocusMode[0] = + MN.pentax.FocusMode[1] = 0xffff; + MN.pentax.AFPointSelected[1] = 0xffff; + MN.pentax.AFPointSelected_Area = 0xffff; + MN.pentax.AFPointsInFocus = 0xffffffff; + MN.pentax.AFPointMode = 0xff; + + MN.ricoh.AFStatus = 0xffff; + MN.ricoh.AFAreaMode = 0xffff; + MN.ricoh.WideAdapter = 0xffff; + MN.ricoh.CropMode = 0xffff; + MN.ricoh.NDFilter = 0xffff; + MN.ricoh.AutoBracketing = 0xffff; + MN.ricoh.MacroMode = 0xffff; + MN.ricoh.FlashMode = 0xffff; + MN.ricoh.FlashExposureComp = -999.0; + MN.ricoh.ManualFlashOutput = -999.0; + + MN.samsung.ColorSpace[0] = MN.samsung.ColorSpace[1] = -1; + + MN.sony.CameraType = LIBRAW_SONY_CameraType_UNKNOWN; + MN.sony.group2010 = 0; + MN.sony.real_iso_offset = 0xffff; + MN.sony.ImageCount3_offset = 0xffff; + MN.sony.MeteringMode_offset = 0xffff; + MN.sony.ExposureProgram_offset = 0xffff; + MN.sony.ReleaseMode2_offset = 0xffff; + MN.sony.ElectronicFrontCurtainShutter = 0xffffffff; + MN.sony.MinoltaCamID = 0xffffffff; + MN.sony.RAWFileType = 0xffff; + MN.sony.AFAreaModeSetting = 0xff; + MN.sony.AFAreaMode = 0xffff; + MN.sony.FlexibleSpotPosition[0] = + MN.sony.FlexibleSpotPosition[1] = 0xffff; + MN.sony.AFPointSelected = MN.sony.AFPointSelected_0x201e = 0xff; + MN.sony.AFTracking = 0xff; + MN.sony.FocusPosition = 0xffff; + MN.sony.LongExposureNoiseReduction = 0xffffffff; + MN.sony.Quality = 0xffffffff; + MN.sony.HighISONoiseReduction = 0xffff; + MN.sony.SonyRawFileType = 0xffff; + MN.sony.RawSizeType = 0xffff; + MN.sony.AFMicroAdjValue = 0x7f; + MN.sony.AFMicroAdjOn = -1; + MN.sony.AFMicroAdjRegisteredLenses = 0xff; + + _exitflag = 0; +#ifdef USE_RAWSPEED + if (_rawspeed_decoder) + { + RawSpeed::RawDecoder *d = + static_cast(_rawspeed_decoder); + delete d; + } + _rawspeed_decoder = 0; +#endif +#ifdef USE_RAWSPEED3 + if (_rawspeed3_handle) + rawspeed3_release(_rawspeed3_handle); +#endif +#ifdef USE_DNGSDK + if (dngnegative) + { + dng_negative *ng = (dng_negative *)dngnegative; + delete ng; + dngnegative = 0; + } + if(dngimage) + { + dng_image *dimage = (dng_image*)dngimage; + delete dimage; + dngimage = 0; + } +#endif +#ifdef USE_X3FTOOLS + if (_x3f_data) + { + x3f_clear(_x3f_data); + _x3f_data = 0; + } +#endif + memmgr.cleanup(); + + imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN; + libraw_internal_data.unpacker_data.thumb_format = LIBRAW_INTERNAL_THUMBNAIL_UNKNOWN; + imgdata.progress_flags = 0; + + load_raw = 0; + + tls->init(); +} diff --git a/src/utils/open.cpp b/src/utils/open.cpp new file mode 100644 index 000000000..2adca43b5 --- /dev/null +++ b/src/utils/open.cpp @@ -0,0 +1,1259 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#include "../../internal/libraw_cameraids.h" + +#ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM +int LibRaw::open_file(const char *fname, INT64 max_buf_size) +{ + int big = 0; + if (max_buf_size == LIBRAW_OPEN_BIGFILE) + big = 1; + else if (max_buf_size == LIBRAW_OPEN_FILE) + big = 0; + else + { +#ifndef LIBRAW_WIN32_CALLS + struct stat st; + if (stat(fname, &st)) + return LIBRAW_IO_ERROR; + big = (st.st_size > max_buf_size) ? 1 : 0; +#else + struct _stati64 st; + if (_stati64(fname, &st)) + return LIBRAW_IO_ERROR; + big = (st.st_size > max_buf_size) ? 1 : 0; +#endif + } + + LibRaw_abstract_datastream *stream; + try + { + if (big) + stream = new LibRaw_bigfile_datastream(fname); + else + stream = new LibRaw_file_datastream(fname); + } + + catch (const std::bad_alloc& ) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if (!stream->valid()) + { + delete stream; + return LIBRAW_IO_ERROR; + } + ID.input_internal = 0; // preserve from deletion on error + int ret = open_datastream(stream); + if (ret == LIBRAW_SUCCESS) + { + ID.input_internal = 1; // flag to delete datastream on recycle + } + else + { + delete stream; + ID.input_internal = 0; + } + return ret; +} + +#if defined(WIN32) || defined(_WIN32) +#ifndef LIBRAW_WIN32_UNICODEPATHS +int LibRaw::open_file(const wchar_t *, INT64) +{ + return LIBRAW_NOT_IMPLEMENTED; +} +#else +int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size) +{ + int big = 0; + if (max_buf_size == LIBRAW_OPEN_BIGFILE) + big = 1; + else if (max_buf_size == LIBRAW_OPEN_FILE) + big = 0; + else + { + struct _stati64 st; + if (_wstati64(fname, &st)) + return LIBRAW_IO_ERROR; + big = (st.st_size > max_buf_size) ? 1 : 0; + } + + LibRaw_abstract_datastream *stream; + try + { + if (big) + stream = new LibRaw_bigfile_datastream(fname); + else + stream = new LibRaw_file_datastream(fname); + } + + catch (const std::bad_alloc&) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if (!stream->valid()) + { + delete stream; + return LIBRAW_IO_ERROR; + } + ID.input_internal = 0; // preserve from deletion on error + int ret = open_datastream(stream); + if (ret == LIBRAW_SUCCESS) + { + ID.input_internal = 1; // flag to delete datastream on recycle + } + else + { + delete stream; + ID.input_internal = 0; + } + return ret; +} +#endif +#endif + +#else /* LIBRAW_NO_IOSTREAMS_DATASTREAM*/ + +int LibRaw::libraw_openfile_tail(LibRaw_abstract_datastream *stream) +{ + if (!stream->valid()) + { + delete stream; + return LIBRAW_IO_ERROR; + } + ID.input_internal = 0; // preserve from deletion on error + int ret = open_datastream(stream); + if (ret == LIBRAW_SUCCESS) + { + ID.input_internal = 1; // flag to delete datastream on recycle + } + else + { + delete stream; + ID.input_internal = 0; + } + return ret; +} + +int LibRaw::open_file(const char *fname) +{ + LibRaw_abstract_datastream *stream; + try + { +#ifdef LIBRAW_WIN32_CALLS + stream = new LibRaw_bigfile_buffered_datastream(fname); +#else + stream = new LibRaw_bigfile_datastream(fname); +#endif + } + catch (const std::bad_alloc&) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if ((stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE)) + { + delete stream; + return LIBRAW_TOO_BIG; + } + return libraw_openfile_tail(stream); +} + +#if defined(WIN32) || defined(_WIN32) +#ifndef LIBRAW_WIN32_UNICODEPATHS +int LibRaw::open_file(const wchar_t *) +{ + return LIBRAW_NOT_IMPLEMENTED; +} +#else +int LibRaw::open_file(const wchar_t *fname) +{ + LibRaw_abstract_datastream *stream; + try + { +#ifdef LIBRAW_WIN32_CALLS + stream = new LibRaw_bigfile_buffered_datastream(fname); +#else + stream = new LibRaw_bigfile_datastream(fname); +#endif + } + catch (const std::bad_alloc&) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) + { + delete stream; + return LIBRAW_TOO_BIG; + } + + return libraw_openfile_tail(stream); +} +#endif +#endif + +#endif + +int LibRaw::open_buffer(const void *buffer, size_t size) +{ + // this stream will close on recycle() + if (!buffer || buffer == (const void *)-1) + return LIBRAW_IO_ERROR; + + if ((size > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (size > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) + return LIBRAW_TOO_BIG; + + LibRaw_buffer_datastream *stream; + try + { + stream = new LibRaw_buffer_datastream(buffer, size); + } + catch (const std::bad_alloc& ) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if (!stream->valid()) + { + delete stream; + return LIBRAW_IO_ERROR; + } + ID.input_internal = 0; // preserve from deletion on error + int ret = open_datastream(stream); + if (ret == LIBRAW_SUCCESS) + { + ID.input_internal = 1; // flag to delete datastream on recycle + } + else + { + delete stream; + ID.input_internal = 0; + } + return ret; +} + +int LibRaw::open_bayer(const unsigned char *buffer, unsigned datalen, + ushort _raw_width, ushort _raw_height, + ushort _left_margin, ushort _top_margin, + ushort _right_margin, ushort _bottom_margin, + unsigned char procflags, unsigned char bayer_pattern, + unsigned unused_bits, unsigned otherflags, + unsigned black_level) +{ + // this stream will close on recycle() + if (!buffer || buffer == (const void *)-1) + return LIBRAW_IO_ERROR; + + LibRaw_buffer_datastream *stream; + try + { + stream = new LibRaw_buffer_datastream(buffer, datalen); + } + catch (const std::bad_alloc& ) + { + recycle(); + return LIBRAW_UNSUFFICIENT_MEMORY; + } + if (!stream->valid()) + { + delete stream; + return LIBRAW_IO_ERROR; + } + ID.input = stream; + SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); + // From identify + initdata(); + strcpy(imgdata.idata.make, "BayerDump"); + snprintf(imgdata.idata.model, sizeof(imgdata.idata.model) - 1, + "%u x %u pixels", _raw_width, _raw_height); + S.flip = procflags >> 2; + libraw_internal_data.internal_output_params.zero_is_bad = procflags & 2; + libraw_internal_data.unpacker_data.data_offset = 0; + S.raw_width = _raw_width; + S.raw_height = _raw_height; + S.left_margin = _left_margin; + S.top_margin = _top_margin; + S.width = S.raw_width - S.left_margin - _right_margin; + S.height = S.raw_height - S.top_margin - _bottom_margin; + + imgdata.idata.filters = 0x1010101 * bayer_pattern; + imgdata.idata.colors = + 4 - !((imgdata.idata.filters & imgdata.idata.filters >> 1) & 0x5555); + libraw_internal_data.unpacker_data.load_flags = otherflags; + switch (libraw_internal_data.unpacker_data.tiff_bps = + (datalen)*8 / (S.raw_width * S.raw_height)) + { + case 8: + load_raw = &LibRaw::eight_bit_load_raw; + break; + case 10: + if ((datalen) / S.raw_height * 3u >= S.raw_width * 4u) + { + load_raw = &LibRaw::android_loose_load_raw; + break; + } + else if (libraw_internal_data.unpacker_data.load_flags & 1) + { + load_raw = &LibRaw::android_tight_load_raw; + break; + } + case 12: + libraw_internal_data.unpacker_data.load_flags |= 128; + load_raw = &LibRaw::packed_load_raw; + break; + case 16: + libraw_internal_data.unpacker_data.order = + 0x4949 | 0x404 * (libraw_internal_data.unpacker_data.load_flags & 1); + libraw_internal_data.unpacker_data.tiff_bps -= + libraw_internal_data.unpacker_data.load_flags >> 4; + libraw_internal_data.unpacker_data.tiff_bps -= + libraw_internal_data.unpacker_data.load_flags = + libraw_internal_data.unpacker_data.load_flags >> 1 & 7; + load_raw = &LibRaw::unpacked_load_raw; + } + C.maximum = + (1 << libraw_internal_data.unpacker_data.tiff_bps) - (1 << unused_bits); + C.black = black_level; + S.iwidth = S.width; + S.iheight = S.height; + imgdata.idata.colors = 3; + imgdata.idata.filters |= ((imgdata.idata.filters >> 2 & 0x22222222) | + (imgdata.idata.filters << 2 & 0x88888888)) & + imgdata.idata.filters << 1; + + imgdata.idata.raw_count = 1; + for (int i = 0; i < 4; i++) + imgdata.color.pre_mul[i] = 1.0; + + strcpy(imgdata.idata.cdesc, "RGBG"); + + ID.input_internal = 1; + SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); + return LIBRAW_SUCCESS; +} + +struct foveon_data_t +{ + const char *make; + const char *model; + const int raw_width, raw_height; + const int white; + const int left_margin, top_margin; + const int width, height; +} foveon_data[] = { + {"Sigma", "SD9", 2304, 1531, 12000, 20, 8, 2266, 1510}, + {"Sigma", "SD9", 1152, 763, 12000, 10, 2, 1132, 755}, + {"Sigma", "SD10", 2304, 1531, 12000, 20, 8, 2266, 1510}, + {"Sigma", "SD10", 1152, 763, 12000, 10, 2, 1132, 755}, + {"Sigma", "SD14", 2688, 1792, 14000, 18, 12, 2651, 1767}, + {"Sigma", "SD14", 2688, 896, 14000, 18, 6, 2651, 883}, // 2/3 + {"Sigma", "SD14", 1344, 896, 14000, 9, 6, 1326, 883}, // 1/2 + {"Sigma", "SD15", 2688, 1792, 2900, 18, 12, 2651, 1767}, + {"Sigma", "SD15", 2688, 896, 2900, 18, 6, 2651, 883}, // 2/3 ? + {"Sigma", "SD15", 1344, 896, 2900, 9, 6, 1326, 883}, // 1/2 ? + {"Sigma", "DP1", 2688, 1792, 2100, 18, 12, 2651, 1767}, + {"Sigma", "DP1", 2688, 896, 2100, 18, 6, 2651, 883}, // 2/3 ? + {"Sigma", "DP1", 1344, 896, 2100, 9, 6, 1326, 883}, // 1/2 ? + {"Sigma", "DP1S", 2688, 1792, 2200, 18, 12, 2651, 1767}, + {"Sigma", "DP1S", 2688, 896, 2200, 18, 6, 2651, 883}, // 2/3 + {"Sigma", "DP1S", 1344, 896, 2200, 9, 6, 1326, 883}, // 1/2 + {"Sigma", "DP1X", 2688, 1792, 3560, 18, 12, 2651, 1767}, + {"Sigma", "DP1X", 2688, 896, 3560, 18, 6, 2651, 883}, // 2/3 + {"Sigma", "DP1X", 1344, 896, 3560, 9, 6, 1326, 883}, // 1/2 + {"Sigma", "DP2", 2688, 1792, 2326, 13, 16, 2651, 1767}, + {"Sigma", "DP2", 2688, 896, 2326, 13, 8, 2651, 883}, // 2/3 ?? + {"Sigma", "DP2", 1344, 896, 2326, 7, 8, 1325, 883}, // 1/2 ?? + {"Sigma", "DP2S", 2688, 1792, 2300, 18, 12, 2651, 1767}, + {"Sigma", "DP2S", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 + {"Sigma", "DP2S", 1344, 896, 2300, 9, 6, 1326, 883}, // 1/2 + {"Sigma", "DP2X", 2688, 1792, 2300, 18, 12, 2651, 1767}, + {"Sigma", "DP2X", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 + {"Sigma", "DP2X", 1344, 896, 2300, 9, 6, 1325, 883}, // 1/2 + {"Sigma", "SD1", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size + {"Sigma", "SD1", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size + {"Sigma", "SD1", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size + {"Sigma", "SD1 Merrill", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size + {"Sigma", "SD1 Merrill", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size + {"Sigma", "SD1 Merrill", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size + {"Sigma", "DP1 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, + {"Sigma", "DP1 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size + {"Sigma", "DP1 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size + {"Sigma", "DP2 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, + {"Sigma", "DP2 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size + {"Sigma", "DP2 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size + {"Sigma", "DP3 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, + {"Sigma", "DP3 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size + {"Sigma", "DP3 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size + {"Polaroid", "x530", 1440, 1088, 2700, 10, 13, 1419, 1059}, + // dp2 Q + {"Sigma", "dp3 Quattro", 5888, 3776, 16383, 204, 76, 5446, + 3624}, // full size, new fw ?? + {"Sigma", "dp3 Quattro", 5888, 3672, 16383, 204, 24, 5446, + 3624}, // full size + {"Sigma", "dp3 Quattro", 2944, 1836, 16383, 102, 12, 2723, + 1812}, // half size + {"Sigma", "dp3 Quattro", 2944, 1888, 16383, 102, 38, 2723, + 1812}, // half size, new fw?? + + {"Sigma", "dp2 Quattro", 5888, 3776, 16383, 204, 76, 5446, + 3624}, // full size, new fw + {"Sigma", "dp2 Quattro", 5888, 3672, 16383, 204, 24, 5446, + 3624}, // full size + {"Sigma", "dp2 Quattro", 2944, 1836, 16383, 102, 12, 2723, + 1812}, // half size + {"Sigma", "dp2 Quattro", 2944, 1888, 16383, 102, 38, 2723, + 1812}, // half size, new fw + + {"Sigma", "dp1 Quattro", 5888, 3776, 16383, 204, 76, 5446, + 3624}, // full size, new fw?? + {"Sigma", "dp1 Quattro", 5888, 3672, 16383, 204, 24, 5446, + 3624}, // full size + {"Sigma", "dp1 Quattro", 2944, 1836, 16383, 102, 12, 2723, + 1812}, // half size + {"Sigma", "dp1 Quattro", 2944, 1888, 16383, 102, 38, 2723, + 1812}, // half size, new fw + + {"Sigma", "dp0 Quattro", 5888, 3776, 16383, 204, 76, 5446, + 3624}, // full size, new fw?? + {"Sigma", "dp0 Quattro", 5888, 3672, 16383, 204, 24, 5446, + 3624}, // full size + {"Sigma", "dp0 Quattro", 2944, 1836, 16383, 102, 12, 2723, + 1812}, // half size + {"Sigma", "dp0 Quattro", 2944, 1888, 16383, 102, 38, 2723, + 1812}, // half size, new fw + // Sigma sd Quattro + {"Sigma", "sd Quattro", 5888, 3776, 16383, 204, 76, 5446, + 3624}, // full size + {"Sigma", "sd Quattro", 2944, 1888, 16383, 102, 38, 2723, + 1812}, // half size + // Sd Quattro H + {"Sigma", "sd Quattro H", 6656, 4480, 4000, 224, 160, 6208, + 4160}, // full size + {"Sigma", "sd Quattro H", 3328, 2240, 4000, 112, 80, 3104, + 2080}, // half size + {"Sigma", "sd Quattro H", 5504, 3680, 4000, 0, 4, 5496, 3668}, // full size + {"Sigma", "sd Quattro H", 2752, 1840, 4000, 0, 2, 2748, 1834}, // half size +}; +const int foveon_count = sizeof(foveon_data) / sizeof(foveon_data[0]); + +int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) +{ + + if (!stream) + return ENOENT; + if (!stream->valid()) + return LIBRAW_IO_ERROR; + if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) + return LIBRAW_TOO_BIG; + + recycle(); + if (callbacks.pre_identify_cb) + { + int r = (callbacks.pre_identify_cb)(this); + if (r == 1) + goto final; + } + + try + { + ID.input = stream; + SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); + + identify(); + + // Fuji layout files: either DNG or unpacked_load_raw should be used + if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout) + { + if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw) + return LIBRAW_FILE_UNSUPPORTED; + } + + // promote the old single thumbnail to the thumbs_list if not present already + if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) + { + bool already = false; + if(imgdata.thumbnail.tlength || libraw_internal_data.internal_data.toffset) + for(int i = 0; i < imgdata.thumbs_list.thumbcount; i++) + if (imgdata.thumbs_list.thumblist[i].toffset == libraw_internal_data.internal_data.toffset + && imgdata.thumbs_list.thumblist[i].tlength == imgdata.thumbnail.tlength) + { + already = true; + break; + } + if (!already) + { + int idx = imgdata.thumbs_list.thumbcount; + imgdata.thumbs_list.thumblist[idx].toffset = libraw_internal_data.internal_data.toffset; + imgdata.thumbs_list.thumblist[idx].tlength = imgdata.thumbnail.tlength; + imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; + imgdata.thumbs_list.thumblist[idx].tformat = libraw_internal_data.unpacker_data.thumb_format; + imgdata.thumbs_list.thumblist[idx].tmisc = libraw_internal_data.unpacker_data.thumb_misc; + // promote if set + imgdata.thumbs_list.thumblist[idx].twidth = imgdata.thumbnail.twidth; + imgdata.thumbs_list.thumblist[idx].theight = imgdata.thumbnail.theight; + imgdata.thumbs_list.thumbcount++; + } + } + + + imgdata.lens.Lens[sizeof(imgdata.lens.Lens) - 1] = 0; // make sure lens is 0-terminated + + if (callbacks.post_identify_cb) + (callbacks.post_identify_cb)(this); + +#define isRIC imgdata.sizes.raw_inset_crops[0] + + if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) + && (!strcmp(imgdata.idata.normalized_model, "S3Pro") + || !strcmp(imgdata.idata.normalized_model, "S5Pro") + || !strcmp(imgdata.idata.normalized_model, "S2Pro"))) + { + isRIC.cleft = isRIC.ctop = 0xffff; + isRIC.cwidth = isRIC.cheight = 0; + } + // Wipe out canon incorrect in-camera crop + if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Canon) + && isRIC.cleft == 0 && isRIC.ctop == 0 // non symmetric! + && isRIC.cwidth < (imgdata.sizes.raw_width * 4 / 5)) // less than 80% of sensor width + { + isRIC.cleft = isRIC.ctop = 0xffff; + isRIC.cwidth = isRIC.cheight = 0; + } + + // Wipe out non-standard WB + if (!imgdata.idata.dng_version && + (makeIs(LIBRAW_CAMERAMAKER_Sony) && !strcmp(imgdata.idata.normalized_model, "DSC-F828")) + && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB)) + { + for (int i = 0; i < 4; i++) imgdata.color.cam_mul[i] = (i == 1); + memset(imgdata.color.WB_Coeffs, 0, sizeof(imgdata.color.WB_Coeffs)); + memset(imgdata.color.WBCT_Coeffs, 0, sizeof(imgdata.color.WBCT_Coeffs)); + } + + if (load_raw == &LibRaw::nikon_load_raw) + nikon_read_curve(); + + if (load_raw == &LibRaw::lossless_jpeg_load_raw && + MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && + /* Not normalized models here, it is intentional */ + (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || // if we want something different for B&W cameras, + !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) // it's better to compare with CamIDs + { + imgdata.color.black = 0; + imgdata.color.maximum = 4501; + memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); + memset(imgdata.sizes.mask, 0, sizeof(imgdata.sizes.mask)); + imgdata.sizes.mask[0][3] = 1; // to skip mask re-calc + libraw_internal_data.unpacker_data.load_flags |= 512; + } + + if (load_raw == &LibRaw::panasonic_load_raw) + { + if (libraw_internal_data.unpacker_data.pana_encoding == 6 || + libraw_internal_data.unpacker_data.pana_encoding == 7) + { + for (int i = 0; i < 3; i++) + imgdata.color.cblack[i] = + libraw_internal_data.internal_data.pana_black[i]; + imgdata.color.cblack[3] = imgdata.color.cblack[1]; + imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; + imgdata.color.black = 0; + imgdata.color.maximum = + MAX(imgdata.color.linear_max[0], + MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2])); + } + + if (libraw_internal_data.unpacker_data.pana_encoding == 6) + { + int rowbytes11 = imgdata.sizes.raw_width / 11 * 16; + int rowbytes14 = imgdata.sizes.raw_width / 14 * 16; + INT64 ds = INT64(libraw_internal_data.unpacker_data.data_size); + if (!ds) + ds = libraw_internal_data.internal_data.input->size() - libraw_internal_data.unpacker_data.data_offset; + if ((imgdata.sizes.raw_width % 11) == 0 && + (INT64(imgdata.sizes.raw_height) * rowbytes11 == ds)) + load_raw = &LibRaw::panasonicC6_load_raw; + else if ((imgdata.sizes.raw_width % 14) == 0 && + (INT64(imgdata.sizes.raw_height) * rowbytes14 == ds)) + load_raw = &LibRaw::panasonicC6_load_raw; + else + imgdata.idata.raw_count = 0; // incorrect size + } + else if (libraw_internal_data.unpacker_data.pana_encoding == 7) + { + int pixperblock = + libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; + int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; + if ((imgdata.sizes.raw_width % pixperblock) == 0 && + (INT64(imgdata.sizes.raw_height) * rowbytes == + INT64(libraw_internal_data.unpacker_data.data_size))) + load_raw = &LibRaw::panasonicC7_load_raw; + else + imgdata.idata.raw_count = 0; // incorrect size + } + } + +#define NIKON_14BIT_SIZE(rw, rh) \ + (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.0)) * 16) * rh) + + // Ugly hack, replace with proper data/line size for different + // cameras/format when available + if (makeIs(LIBRAW_CAMERAMAKER_Nikon) + && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strcasecmp(imgdata.idata.model,"D6")) + && NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) == + libraw_internal_data.unpacker_data.data_size) + { + load_raw = &LibRaw::nikon_14bit_load_raw; + } +#undef NIKON_14BIT_SIZE + + // Linear max from 14-bit camera, but on 12-bit data? + if (makeIs(LIBRAW_CAMERAMAKER_Sony) && + imgdata.color.maximum > 0 && + imgdata.color.linear_max[0] > (long)imgdata.color.maximum && + imgdata.color.linear_max[0] <= (long)imgdata.color.maximum * 4) + for (int c = 0; c < 4; c++) + imgdata.color.linear_max[c] /= 4; + + if (makeIs(LIBRAW_CAMERAMAKER_Canon)) + { + if (MN.canon.DefaultCropAbsolute.l != -1) // tag 0x00e0 SensorInfo was parsed + { + if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) + { // tag 0x009a AspectInfo was parsed + isRIC.cleft += MN.canon.DefaultCropAbsolute.l; + isRIC.ctop += MN.canon.DefaultCropAbsolute.t; + } + else + { + isRIC.cleft = MN.canon.DefaultCropAbsolute.l; + isRIC.ctop = MN.canon.DefaultCropAbsolute.t; + isRIC.cwidth = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; + isRIC.cheight = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; + } + } + else + { + if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) + { + } + else + { // Canon PowerShot S2 IS + } + } +#undef isRIC + if (imgdata.color.raw_bps < 14 && !imgdata.idata.dng_version && load_raw != &LibRaw::canon_sraw_load_raw) + { + int xmax = (1 << imgdata.color.raw_bps) - 1; + if (MN.canon.SpecularWhiteLevel > xmax) // Adjust 14-bit metadata to real bps + { + int div = 1 << (14 - imgdata.color.raw_bps); + for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= div; + for (int c = 0; c < 4; c++) MN.canon.ChannelBlackLevel[c] /= div; + MN.canon.AverageBlackLevel /= div; + MN.canon.SpecularWhiteLevel /= div; + MN.canon.NormalWhiteLevel /= div; + } + } + } + + if (makeIs(LIBRAW_CAMERAMAKER_Canon) && + (load_raw == &LibRaw::canon_sraw_load_raw) && + imgdata.sizes.raw_width > 0) + { + float ratio = + float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width); + if ((ratio < 0.57 || ratio > 0.75) && + MN.canon.SensorHeight > 1 && + MN.canon.SensorWidth > 1) + { + imgdata.sizes.raw_width = MN.canon.SensorWidth; + imgdata.sizes.left_margin = MN.canon.DefaultCropAbsolute.l; + imgdata.sizes.iwidth = imgdata.sizes.width = + MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; + imgdata.sizes.raw_height = MN.canon.SensorHeight; + imgdata.sizes.top_margin = MN.canon.DefaultCropAbsolute.t; + imgdata.sizes.iheight = imgdata.sizes.height = + MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; + libraw_internal_data.unpacker_data.load_flags |= + 256; // reset width/height in canon_sraw_load_raw() + imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; + } + else if (imgdata.sizes.raw_width == 4032 && + imgdata.sizes.raw_height == 3402 && + !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded + { + imgdata.sizes.raw_width = 4536; + imgdata.sizes.left_margin = 28; + imgdata.sizes.iwidth = imgdata.sizes.width = + imgdata.sizes.raw_width - imgdata.sizes.left_margin; + imgdata.sizes.raw_height = 3024; + imgdata.sizes.top_margin = 8; + imgdata.sizes.iheight = imgdata.sizes.height = + imgdata.sizes.raw_height - imgdata.sizes.top_margin; + libraw_internal_data.unpacker_data.load_flags |= 256; + imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; + } + } + +#ifdef USE_DNGSDK + if (imgdata.idata.dng_version + &&libraw_internal_data.unpacker_data.tiff_compress == 34892 + && libraw_internal_data.unpacker_data.tiff_bps == 8 + && libraw_internal_data.unpacker_data.tiff_samples == 3 + && load_raw == &LibRaw::lossy_dng_load_raw) + { + // Data should be linearized by DNG SDK + C.black = 0; + memset(C.cblack, 0, sizeof(C.cblack)); + } +#endif + + // XTrans Compressed? + if (!imgdata.idata.dng_version && + makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && + (load_raw == &LibRaw::unpacked_load_raw)) + { + if (imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 2ul) != + libraw_internal_data.unpacker_data.data_size) + { + if ((imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 7ul)) / 4 == + libraw_internal_data.unpacker_data.data_size) + load_raw = &LibRaw::fuji_14bit_load_raw; + else + parse_fuji_compressed_header(); + } + else if (!strcmp(imgdata.idata.normalized_model, "X-H2S") + && libraw_internal_data.internal_data.input->size() + < (libraw_internal_data.unpacker_data.data_size + libraw_internal_data.unpacker_data.data_offset)) + { + parse_fuji_compressed_header(); // try to use compressed header: X-H2S may record wrong data size + } + } + // set raw_inset_crops[1] via raw_aspect + if (imgdata.sizes.raw_aspect >= LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE + && imgdata.sizes.raw_aspect <= LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE + /* crops[0] is valid*/ + && (imgdata.sizes.raw_inset_crops[0].cleft < 0xffff) + && (imgdata.sizes.raw_inset_crops[0].cleft + imgdata.sizes.raw_inset_crops[0].cwidth <= imgdata.sizes.raw_width) + && (imgdata.sizes.raw_inset_crops[0].ctop < 0xffff) + && (imgdata.sizes.raw_inset_crops[0].ctop + imgdata.sizes.raw_inset_crops[0].cheight <= imgdata.sizes.raw_height) + && imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cheight >0 + /* crops[1] is not set*/ + && (imgdata.sizes.raw_inset_crops[1].cleft == 0xffff) + && (imgdata.sizes.raw_inset_crops[1].ctop == 0xffff) + ) + { + float c0_ratio = float(imgdata.sizes.raw_inset_crops[0].cwidth) / float(imgdata.sizes.raw_inset_crops[0].cheight); + float c1_ratio = float(imgdata.sizes.raw_aspect) / 1000.f; + if (c0_ratio / c1_ratio < 0.98 || c0_ratio / c1_ratio > 1.02) // set crops[1] + { + if (c1_ratio > c0_ratio) // requested image is wider, cut from top/bottom + { + int newheight = int(imgdata.sizes.raw_inset_crops[0].cwidth / c1_ratio); + int dtop = (imgdata.sizes.raw_inset_crops[0].cheight - newheight) / 2; + imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dtop; + imgdata.sizes.raw_inset_crops[1].cheight = newheight; + imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft; + imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[0].cwidth; + } + else + { + int newwidth = int(imgdata.sizes.raw_inset_crops[0].cheight * c1_ratio); + int dleft = (imgdata.sizes.raw_inset_crops[0].cwidth - newwidth) / 2; + imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dleft; + imgdata.sizes.raw_inset_crops[1].cwidth = newwidth; + imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop; + imgdata.sizes.raw_inset_crops[1].cheight = imgdata.sizes.raw_inset_crops[0].cheight; + } + } + } + + int adjust_margins = 0; + if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (imgdata.idata.filters == 9)) + { + // Adjust top/left margins for X-Trans + int newtm = imgdata.sizes.top_margin % 6 + ? (imgdata.sizes.top_margin / 6 + 1) * 6 + : imgdata.sizes.top_margin; + int newlm = imgdata.sizes.left_margin % 6 + ? (imgdata.sizes.left_margin / 6 + 1) * 6 + : imgdata.sizes.left_margin; + if (newtm != imgdata.sizes.top_margin || + newlm != imgdata.sizes.left_margin) + { + imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin); + imgdata.sizes.top_margin = newtm; + imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin); + imgdata.sizes.left_margin = newlm; + for (int c1 = 0; c1 < 6; c1++) + for (int c2 = 0; c2 < 6; c2++) + imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2]; + } + adjust_margins = 6; + } + else if (!libraw_internal_data.internal_output_params.fuji_width + && imgdata.idata.filters >= 1000) + { + if ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin % 2)) + { + int crop[2] = { 0,0 }; + unsigned filt; + int c; + if (imgdata.sizes.top_margin % 2) + { + imgdata.sizes.top_margin += 1; + imgdata.sizes.height -= 1; + crop[1] = 1; + } + if (imgdata.sizes.left_margin % 2) + { + imgdata.sizes.left_margin += 1; + imgdata.sizes.width -= 1; + crop[0] = 1; + } + for (filt = c = 0; c < 16; c++) + filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; + imgdata.idata.filters = filt; + } + adjust_margins = 2; + } + + if(adjust_margins) // adjust crop_inset margins + for (int i = 0; i < 2; i++) + { + if (imgdata.sizes.raw_inset_crops[i].cleft && imgdata.sizes.raw_inset_crops[i].cleft < 0xffff + && imgdata.sizes.raw_inset_crops[i].cwidth && imgdata.sizes.raw_inset_crops[i].cwidth < 0xffff + && (imgdata.sizes.raw_inset_crops[i].cleft%adjust_margins) + && (imgdata.sizes.raw_inset_crops[i].cwidth > adjust_margins)) + { + int newleft = ((imgdata.sizes.raw_inset_crops[i].cleft / adjust_margins) + 1) * adjust_margins; + int diff = newleft - imgdata.sizes.raw_inset_crops[i].cleft; + if (diff > 0) + { + imgdata.sizes.raw_inset_crops[i].cleft += diff; + imgdata.sizes.raw_inset_crops[i].cwidth -= diff; + } + } + if (imgdata.sizes.raw_inset_crops[i].ctop && imgdata.sizes.raw_inset_crops[i].ctop < 0xffff + && imgdata.sizes.raw_inset_crops[i].cheight && imgdata.sizes.raw_inset_crops[i].cheight < 0xffff + && (imgdata.sizes.raw_inset_crops[i].ctop%adjust_margins) + && (imgdata.sizes.raw_inset_crops[i].cheight > adjust_margins)) + { + int newtop = ((imgdata.sizes.raw_inset_crops[i].ctop / adjust_margins) + 1) * adjust_margins; + int diff = newtop - imgdata.sizes.raw_inset_crops[i].ctop; + if (diff > 0) + { + imgdata.sizes.raw_inset_crops[i].ctop += diff; + imgdata.sizes.raw_inset_crops[i].cheight -= diff; + } + } + } + + +#ifdef USE_DNGSDK + if ( + imgdata.rawparams.use_dngsdk && + !(imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2 | LIBRAW_RAWOPTIONS_DNG_STAGE3 | LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST))) +#endif + { + // Fix DNG white balance if needed: observed only for Kalpanika X3F tools produced DNGs + if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) && + imgdata.idata.colors > 1 && imgdata.idata.colors < 5) + { + float delta[4] = { 0.f, 0.f, 0.f, 0.f }; + int black[4]; + for (int c = 0; c < 4; c++) + black[c] = imgdata.color.dng_levels.dng_black + + imgdata.color.dng_levels.dng_cblack[c]; + for (int c = 0; c < imgdata.idata.colors; c++) + delta[c] = imgdata.color.dng_levels.dng_whitelevel[c] - black[c]; + float mindelta = delta[0], maxdelta = delta[0]; + for (int c = 1; c < imgdata.idata.colors; c++) + { + if (mindelta > delta[c]) + mindelta = delta[c]; + if (maxdelta < delta[c]) + maxdelta = delta[c]; + } + if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety + { + for (int c = 0; c < imgdata.idata.colors; c++) + { + imgdata.color.cam_mul[c] /= (delta[c] / maxdelta); + imgdata.color.pre_mul[c] /= (delta[c] / maxdelta); + } + imgdata.color.maximum = imgdata.color.cblack[0] + maxdelta; + } + } + } + + if (imgdata.idata.dng_version && + makeIs(LIBRAW_CAMERAMAKER_Panasonic) + && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100")) + imgdata.sizes.width = 4288; + + if (imgdata.idata.dng_version + && makeIs(LIBRAW_CAMERAMAKER_Leica) + && !strcasecmp(imgdata.idata.normalized_model, "SL2")) + imgdata.sizes.height -= 16; + + if (makeIs(LIBRAW_CAMERAMAKER_Sony) && + imgdata.idata.dng_version) + { + if (S.raw_width == 3984) + S.width = 3925; + else if (S.raw_width == 4288) + S.width = S.raw_width - 32; + else if (S.raw_width == 4928 && S.height < 3280) + S.width = S.raw_width - 8; + else if (S.raw_width == 5504) + S.width = S.raw_width - (S.height > 3664 ? 8 : 32); + } + + if (makeIs(LIBRAW_CAMERAMAKER_Sony) && + !imgdata.idata.dng_version) + { + if(load_raw ==&LibRaw::sony_arq_load_raw) + { + if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS + S.width = S.raw_width - 64; + else // A7RM3/M4 4x merge + S.width = S.raw_width - 32; + } + + if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) || + !strcasecmp(imgdata.idata.model, "ILCA-99M2")) && + (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C + || + (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 && + S.raw_width < 5020) // A7R in crop mode, no samples, so size est. + || (!strcasecmp(imgdata.idata.model, "ILCE-7") && + S.raw_width == 3968) // A7 in crop mode + || + ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) || + !strcasecmp(imgdata.idata.model, "ILCE-9") || +#if 0 + !strcasecmp(imgdata.idata.model, + "SLT-A99V")) // Does SLT-A99 also have APS-C mode?? +#endif + (mnCamID == SonyID_SLT_A99)) // 2 reasons: some cameras are SLT-A99, no 'V'; some are Hasselblad HV + && S.raw_width > 3750 && + S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width + // is 3968 (same w/ A7), but no samples, so guess + || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) && + S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too + ) + S.width = S.raw_width - 32; + } + + + // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4 + if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && + /*!strcasecmp(imgdata.idata.model,"K-3 II") &&*/ + imgdata.idata.raw_count == 4 && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES)) + { + imgdata.idata.raw_count = 1; + imgdata.idata.filters = 0; + imgdata.idata.colors = 4; + imgdata.sizes.top_margin+=2; + imgdata.sizes.left_margin+=2; + imgdata.sizes.width-=4; + imgdata.sizes.height-=4; + IO.mix_green = 1; + pentax_component_load_raw = load_raw; + load_raw = &LibRaw::pentax_4shot_load_raw; + } + + if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) && + !strcmp(imgdata.idata.model, "Credo 50")) + { + imgdata.color.pre_mul[0] = 1.f / 0.3984f; + imgdata.color.pre_mul[2] = 1.f / 0.7666f; + imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0; + } + + if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && + (!strncmp(imgdata.idata.model, "S20Pro", 6) || + !strncmp(imgdata.idata.model, "F700", 4))) + { + imgdata.sizes.raw_width /= 2; + load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20; + } + + if (load_raw == &LibRaw::packed_load_raw && + makeIs(LIBRAW_CAMERAMAKER_Nikon) && + !libraw_internal_data.unpacker_data.load_flags && + (!strncasecmp(imgdata.idata.model, "D810", 4) || + !strcasecmp(imgdata.idata.model, "D4S")) && + libraw_internal_data.unpacker_data.data_size * 2u == + imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3u) + { + libraw_internal_data.unpacker_data.load_flags = 80; + } + // Adjust BL for Sony A900/A850 + if (load_raw == &LibRaw::packed_load_raw && + makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range + { + if (C.maximum > 4095) + C.maximum = 4095; + if (C.black > 256 || C.cblack[0] > 256) + { + C.black /= 4; + for (int c = 0; c < 4; c++) + C.cblack[c] /= 4; + for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) + C.cblack[6 + c] /= 4; + } + } + + if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW? + { + load_raw = &LibRaw::nikon_load_sraw; + C.black = 0; + memset(C.cblack, 0, sizeof(C.cblack)); + imgdata.idata.filters = 0; + libraw_internal_data.unpacker_data.tiff_samples = 3; + imgdata.idata.colors = 3; + double beta_1 = -5.79342238397656E-02; + double beta_2 = 3.28163551282665; + double beta_3 = -8.43136004842678; + double beta_4 = 1.03533181861023E+01; + for (int i = 0; i <= 3072; i++) + { + double x = (double)i / 3072.; + double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x - + beta_4 * x * x * x * x)); + if (y < 0.) + y = 0.; + imgdata.color.curve[i] = (y * 16383.); + } + for (int i = 0; i < 3; i++) + for (int j = 0; j < 4; j++) + imgdata.color.rgb_cam[i][j] = float(i == j); + } + // Adjust BL for Nikon 12bit + if ((load_raw == &LibRaw::nikon_load_raw || + load_raw == &LibRaw::packed_load_raw || + load_raw == &LibRaw::nikon_load_padded_packed_raw) && + makeIs(LIBRAW_CAMERAMAKER_Nikon) && + strncmp(imgdata.idata.model, "COOLPIX", 7) && + libraw_internal_data.unpacker_data.tiff_bps == 12) + { + C.maximum = 4095; + C.black /= 4; + for (int c = 0; c < 4; c++) + C.cblack[c] /= 4; + for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) + C.cblack[6 + c] /= 4; + } + + // Adjust wb_already_applied + if (load_raw == &LibRaw::nikon_load_sraw) + imgdata.color.as_shot_wb_applied = + LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW; + else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && + MN.canon.multishot[0] >= 8 && + MN.canon.multishot[1] > 0) + imgdata.color.as_shot_wb_applied = + LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON; + else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && + MN.nikon.ExposureMode == 1) + imgdata.color.as_shot_wb_applied = + LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON; + else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && + ((MN.pentax.MultiExposure & 0x01) == 1)) + imgdata.color.as_shot_wb_applied = + LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX; + else + imgdata.color.as_shot_wb_applied = 0; + + // Adjust Highlight Linearity limit + if (C.linear_max[0] < 0) + { + if (imgdata.idata.dng_version) + { + for (int c = 0; c < 4; c++) + C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6]; + } + else + { + for (int c = 0; c < 4; c++) + C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c]; + } + } + + if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && + (!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw)) + { + C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] = + (long)((float)(C.maximum) / 1.07f); + } + + // Correct WB for Samsung GX20 + if ( +#if 0 + /* GX20 should be corrected, but K20 is not */ + makeIs(LIBRAW_CAMERAMAKER_Pentax) && + !strcasecmp(imgdata.idata.normalized_model, "K20D") +#endif +#if 0 + !strcasecmp(imgdata.idata.make, "Samsung") && + !strcasecmp(imgdata.idata.model, "GX20") +#endif + makeIs(LIBRAW_CAMERAMAKER_Pentax) && + (mnCamID == PentaxID_GX20) // Samsung rebranding + ) + { + for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) { + if (C.WB_Coeffs[cnt][1]) { + C.WB_Coeffs[cnt][0] = (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f); + C.WB_Coeffs[cnt][2] = (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f); + } + } + for (int cnt = 0; cnt < 64; cnt++) { + if (C.WBCT_Coeffs[cnt][0] > 0.0f) { + C.WBCT_Coeffs[cnt][1] *= 1.0503f; + C.WBCT_Coeffs[cnt][3] *= 2.2867f; + } + } + for(int cnt = 0; cnt < 4; cnt++) + imgdata.color.pre_mul[cnt] = + C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt]; + } + + // Adjust BL for Panasonic + if (load_raw == &LibRaw::panasonic_load_raw && + makeIs(LIBRAW_CAMERAMAKER_Panasonic) && + ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2]) + { + if (libraw_internal_data.unpacker_data.pana_encoding == 5) + libraw_internal_data.internal_output_params.zero_is_bad = 0; + C.black = 0; + int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0; + C.cblack[0] = ID.pana_black[0] + add; + C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add; + C.cblack[2] = ID.pana_black[2] + add; + unsigned i = C.cblack[3]; + for (int c = 0; c < 3; c++) + if (i > C.cblack[c]) + i = C.cblack[c]; + for (int c = 0; c < 4; c++) + C.cblack[c] -= i; + C.black = i; + } + + // Adjust sizes for X3F processing +#ifdef USE_X3FTOOLS + if (load_raw == &LibRaw::x3f_load_raw) + { + for (int i = 0; i < foveon_count; i++) + if (!strcasecmp(imgdata.idata.make, foveon_data[i].make) && + !strcasecmp(imgdata.idata.model, foveon_data[i].model) && + imgdata.sizes.raw_width == foveon_data[i].raw_width && + imgdata.sizes.raw_height == foveon_data[i].raw_height) + { + imgdata.sizes.top_margin = foveon_data[i].top_margin; + imgdata.sizes.left_margin = foveon_data[i].left_margin; + imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width; + imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height; + C.maximum = foveon_data[i].white; + break; + } + } +#endif +#if 0 + size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset; + float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height); + float bpp2 = float(bytes)/float(S.width)/float(S.height); + if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f) + { + load_raw = &LibRaw::hasselblad_full_load_raw; + S.width = S.raw_width; + S.height = S.raw_height; + P1.filters = 0; + P1.colors=3; + P1.raw_count=1; + C.maximum=0xffff; + } +#endif + if (C.profile_length) + { + if (C.profile) + free(C.profile); + C.profile = malloc(C.profile_length); + ID.input->seek(ID.profile_offset, SEEK_SET); + ID.input->read(C.profile, C.profile_length, 1); + } + + SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); + } + catch (const std::bad_alloc&) + { + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); + } + catch (const LibRaw_exceptions& err) + { + EXCEPTION_HANDLER(err); + } + catch (const std::exception& ) + { + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); + } + +final:; + + if (P1.raw_count < 1) + return LIBRAW_FILE_UNSUPPORTED; + + write_fun = &LibRaw::write_ppm_tiff; + + if (load_raw == &LibRaw::kodak_ycbcr_load_raw) + { + S.height += S.height & 1; + S.width += S.width & 1; + } + + IO.shrink = + P1.filters && + (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); + if (IO.shrink && P1.filters >= 1000) + { + S.width &= 65534; + S.height &= 65534; + } + + S.iheight = (S.height + IO.shrink) >> IO.shrink; + S.iwidth = (S.width + IO.shrink) >> IO.shrink; + + // Save color,sizes and internal data into raw_image fields + memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); + memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); + memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); + memmove(&imgdata.rawdata.ioparams, + &libraw_internal_data.internal_output_params, + sizeof(libraw_internal_data.internal_output_params)); + + SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST); + + return LIBRAW_SUCCESS; +} diff --git a/src/utils/phaseone_processing.cpp b/src/utils/phaseone_processing.cpp new file mode 100644 index 000000000..b82988b69 --- /dev/null +++ b/src/utils/phaseone_processing.cpp @@ -0,0 +1,101 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +void LibRaw::phase_one_allocate_tempbuffer() +{ + // Allocate temp raw_image buffer + imgdata.rawdata.raw_image = (ushort *)malloc(S.raw_pitch * S.raw_height); +} +void LibRaw::phase_one_free_tempbuffer() +{ + free(imgdata.rawdata.raw_image); + imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; +} + +int LibRaw::phase_one_subtract_black(ushort *src, ushort *dest) +{ + + try + { + if (O.user_black < 0 && O.user_cblack[0] <= -1000000 && + O.user_cblack[1] <= -1000000 && O.user_cblack[2] <= -1000000 && + O.user_cblack[3] <= -1000000) + { + if (!imgdata.rawdata.ph1_cblack || !imgdata.rawdata.ph1_rblack) + { + int bl = imgdata.color.phase_one_data.t_black; + for (int row = 0; row < S.raw_height; row++) + { + checkCancel(); + for (int col = 0; col < S.raw_width; col++) + { + int idx = row * S.raw_width + col; + int val = int(src[idx]) - bl; + dest[idx] = val > 0 ? val : 0; + } + } + } + else + { + int bl = imgdata.color.phase_one_data.t_black; + for (int row = 0; row < S.raw_height; row++) + { + checkCancel(); + for (int col = 0; col < S.raw_width; col++) + { + int idx = row * S.raw_width + col; + int val = + int(src[idx]) - bl + + imgdata.rawdata + .ph1_cblack[row][col >= imgdata.rawdata.color.phase_one_data + .split_col] + + imgdata.rawdata + .ph1_rblack[col][row >= imgdata.rawdata.color.phase_one_data + .split_row]; + dest[idx] = val > 0 ? val : 0; + } + } + } + } + else // black set by user interaction + { + // Black level in cblack! + for (int row = 0; row < S.raw_height; row++) + { + checkCancel(); + unsigned short cblk[16]; + for (int cc = 0; cc < 16; cc++) + cblk[cc] = C.cblack[fcol(row, cc)]; + for (int col = 0; col < S.raw_width; col++) + { + int idx = row * S.raw_width + col; + ushort val = src[idx]; + ushort bl = cblk[col & 0xf]; + dest[idx] = val > bl ? val - bl : 0; + } + } + } + return 0; + } + catch (const LibRaw_exceptions& ) + { + return LIBRAW_CANCELLED_BY_CALLBACK; + } +} diff --git a/src/utils/read_utils.cpp b/src/utils/read_utils.cpp new file mode 100644 index 000000000..974ffc07b --- /dev/null +++ b/src/utils/read_utils.cpp @@ -0,0 +1,176 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +ushort LibRaw::sget2Rev(uchar *s) // specific to some Canon Makernotes fields, + // where they have endian in reverse +{ + if (order == 0x4d4d) /* "II" means little-endian, and we reverse to "MM" - big + endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian... */ + return s[0] << 8 | s[1]; +} + +ushort libraw_sget2_static(short _order, 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 LibRaw::sget2(uchar *s) +{ + return libraw_sget2_static(order, s); +} + + +ushort LibRaw::get2() +{ + uchar str[2] = {0xff, 0xff}; + fread(str, 1, 2, ifp); + return sget2(str); +} + +unsigned LibRaw::sget4(uchar *s) +{ + return libraw_sget4_static(order, s); +} + + +unsigned libraw_sget4_static(short _order, 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]; +} + +unsigned LibRaw::get4() +{ + uchar str[4] = {0xff, 0xff, 0xff, 0xff}; + fread(str, 1, 4, ifp); + return sget4(str); +} + +unsigned LibRaw::getint(int type) { return tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) ? get2() : get4(); } + +float libraw_int_to_float(int i) +{ + union { + int i; + float f; + } u; + u.i = i; + return u.f; +} + +float LibRaw::int_to_float(int i) { return libraw_int_to_float(i); } + +double LibRaw::getreal(int type) +{ + union { + char c[8]; + double d; + } u, v; + int i, rev; + + switch (type) + { + case LIBRAW_EXIFTAG_TYPE_SHORT: + return (unsigned short)get2(); + case LIBRAW_EXIFTAG_TYPE_LONG: + return (unsigned int)get4(); + case LIBRAW_EXIFTAG_TYPE_RATIONAL: // (unsigned, unsigned) + u.d = (unsigned int)get4(); + v.d = (unsigned int)get4(); + return u.d / (v.d ? v.d : 1); + case LIBRAW_EXIFTAG_TYPE_SSHORT: + return (signed short)get2(); + case LIBRAW_EXIFTAG_TYPE_SLONG: + return (signed int)get4(); + case LIBRAW_EXIFTAG_TYPE_SRATIONAL: // (int, int) + u.d = (signed int)get4(); + v.d = (signed int)get4(); + return u.d / (v.d ? v.d : 1); + case LIBRAW_EXIFTAG_TYPE_FLOAT: + return int_to_float(get4()); + case LIBRAW_EXIFTAG_TYPE_DOUBLE: + 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); + } +} + +double LibRaw::sgetreal(int type, uchar *s) +{ + return libraw_sgetreal_static(order, type, s); +} + + +double libraw_sgetreal_static(short _order, int type, uchar *s) +{ + union { + char c[8]; + double d; + } u, v; + int i, rev; + + switch (type) + { + case LIBRAW_EXIFTAG_TYPE_SHORT: + return (unsigned short) libraw_sget2_static(_order,s); + case LIBRAW_EXIFTAG_TYPE_LONG: + return (unsigned int)libraw_sget4_static(_order, s); + case LIBRAW_EXIFTAG_TYPE_RATIONAL: // (unsigned, unsigned) + u.d = (unsigned int)libraw_sget4_static(_order,s); + v.d = (unsigned int)libraw_sget4_static(_order,s+4); + return u.d / (v.d ? v.d : 1); + case LIBRAW_EXIFTAG_TYPE_SSHORT: + return (signed short)libraw_sget2_static(_order,s); + case LIBRAW_EXIFTAG_TYPE_SLONG: + return (signed int) libraw_sget4_static(_order,s); + case LIBRAW_EXIFTAG_TYPE_SRATIONAL: // (int, int) + u.d = (signed int)libraw_sget4_static(_order,s); + v.d = (signed int)libraw_sget4_static(_order,s+4); + return u.d / (v.d ? v.d : 1); + case LIBRAW_EXIFTAG_TYPE_FLOAT: + return libraw_int_to_float(libraw_sget4_static(_order,s)); + case LIBRAW_EXIFTAG_TYPE_DOUBLE: + rev = 7 * ((_order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i = 0; i < 8; i++) + u.c[i ^ rev] = *(s+1); + return u.d; + default: + return *(s+1); + } +} + + +void LibRaw::read_shorts(ushort *pixel, unsigned count) +{ + if ((unsigned)fread(pixel, 2, count, ifp) < count) + derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + libraw_swab(pixel, count * 2); +} diff --git a/src/utils/thumb_utils.cpp b/src/utils/thumb_utils.cpp new file mode 100644 index 000000000..ffdb80247 --- /dev/null +++ b/src/utils/thumb_utils.cpp @@ -0,0 +1,328 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +void LibRaw::kodak_thumb_loader() +{ + INT64 est_datasize = + T.theight * T.twidth / 3; // is 0.3 bytes per pixel good estimate? + if (ID.toffset < 0) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (ID.toffset + est_datasize > ID.input->size() + THUMB_READ_BEYOND) + throw LIBRAW_EXCEPTION_IO_EOF; + + if(INT64(T.theight) * INT64(T.twidth) > 1024ULL * 1024ULL * LIBRAW_MAX_THUMBNAIL_MB) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if (INT64(T.theight) * INT64(T.twidth) < 64ULL) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + if(T.twidth < 16 || T.twidth > 8192 || T.theight < 16 || T.theight > 8192) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + // some kodak cameras + ushort s_height = S.height, s_width = S.width, s_iwidth = S.iwidth, + s_iheight = S.iheight; + ushort s_flags = libraw_internal_data.unpacker_data.load_flags; + libraw_internal_data.unpacker_data.load_flags = 12; + int s_colors = P1.colors; + unsigned s_filters = P1.filters; + ushort(*s_image)[4] = imgdata.image; + + S.height = T.theight; + S.width = T.twidth; + P1.filters = 0; + +#define Tformat libraw_internal_data.unpacker_data.thumb_format + + + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR) + { + S.height += S.height & 1; + S.width += S.width & 1; + } + + S.iheight = S.height; + S.iwidth = S.width; + + imgdata.image = + (ushort(*)[4])calloc(S.iheight * S.iwidth, sizeof(*imgdata.image)); + + ID.input->seek(ID.toffset, SEEK_SET); + // read kodak thumbnail into T.image[] + try + { + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR) + kodak_ycbcr_load_raw(); + else if(Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB) + kodak_rgb_load_raw(); + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB) + kodak_thumb_load_raw(); + } + catch (...) + { + free(imgdata.image); + imgdata.image = s_image; + + T.twidth = 0; + S.width = s_width; + + S.iwidth = s_iwidth; + S.iheight = s_iheight; + + T.theight = 0; + S.height = s_height; + + T.tcolors = 0; + P1.colors = s_colors; + + P1.filters = s_filters; + T.tlength = 0; + libraw_internal_data.unpacker_data.load_flags = s_flags; + return; + } + + // from scale_colors + { + double dmax; + float scale_mul[4]; + int c, val; + for (dmax = DBL_MAX, c = 0; c < 3; c++) + if (dmax > C.pre_mul[c]) + dmax = C.pre_mul[c]; + + for (c = 0; c < 3; c++) + scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum; + scale_mul[3] = scale_mul[1]; + + size_t size = S.height * S.width; + for (unsigned i = 0; i < size * 4; i++) + { + val = imgdata.image[0][i]; + if (!val) + continue; + val *= scale_mul[i & 3]; + imgdata.image[0][i] = CLIP(val); + } + } + + // from convert_to_rgb + ushort *img; + int row, col; + + int(*t_hist)[LIBRAW_HISTOGRAM_SIZE] = + (int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(sizeof(*t_hist), 4); + + float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0}, + {-0.111855984f, 1.73688626f, -0.625030339f, 0}, + {-0.0379119813f, -0.891268849f, 1.92918086f, 0}}; + + for (img = imgdata.image[0], row = 0; row < S.height; row++) + for (col = 0; col < S.width; col++, img += 4) + { + out[0] = out[1] = out[2] = 0; + int c; + for (c = 0; c < 3; c++) + { + out[0] += out_cam[0][c] * img[c]; + out[1] += out_cam[1][c] * img[c]; + out[2] += out_cam[2][c] * img[c]; + } + for (c = 0; c < 3; c++) + img[c] = CLIP((int)out[c]); + for (c = 0; c < P1.colors; c++) + t_hist[c][img[c] >> 3]++; + } + + // from gamma_lut + int(*save_hist)[LIBRAW_HISTOGRAM_SIZE] = + libraw_internal_data.output_data.histogram; + libraw_internal_data.output_data.histogram = t_hist; + + // make curve output curve! + ushort *t_curve = (ushort *)calloc(sizeof(C.curve), 1); + memmove(t_curve, C.curve, sizeof(C.curve)); + memset(C.curve, 0, sizeof(C.curve)); + { + int perc, val, total, t_white = 0x2000, c; + + perc = S.width * S.height * 0.01; /* 99th percentile white level */ + if (IO.fuji_width) + perc /= 2; + if (!((O.highlight & ~2) || O.no_auto_bright)) + for (t_white = c = 0; c < P1.colors; c++) + { + for (val = 0x2000, total = 0; --val > 32;) + if ((total += libraw_internal_data.output_data.histogram[c][val]) > + perc) + break; + if (t_white < val) + t_white = val; + } + gamma_curve(O.gamm[0], O.gamm[1], 2, (t_white << 3) / O.bright); + } + + libraw_internal_data.output_data.histogram = save_hist; + free(t_hist); + + // from write_ppm_tiff - copy pixels into bitmap + + int s_flip = imgdata.sizes.flip; + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS) + imgdata.sizes.flip = 0; + + S.iheight = S.height; + S.iwidth = S.width; + if (S.flip & 4) + SWAP(S.height, S.width); + + if (T.thumb) + free(T.thumb); + T.thumb = (char *)calloc(S.width * S.height, P1.colors); + T.tlength = S.width * S.height * P1.colors; + + // from write_tiff_ppm + { + int soff = flip_index(0, 0); + int cstep = flip_index(0, 1) - soff; + int rstep = flip_index(1, 0) - flip_index(0, S.width); + + for (int rr = 0; rr < S.height; rr++, soff += rstep) + { + char *ppm = T.thumb + rr * S.width * P1.colors; + for (int cc = 0; cc < S.width; cc++, soff += cstep) + for (int c = 0; c < P1.colors; c++) + ppm[cc * P1.colors + c] = + imgdata.color.curve[imgdata.image[soff][c]] >> 8; + } + } + + memmove(C.curve, t_curve, sizeof(C.curve)); + free(t_curve); + + // restore variables + free(imgdata.image); + imgdata.image = s_image; + + if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_NO_ROTATE_FOR_KODAK_THUMBNAILS) + imgdata.sizes.flip = s_flip; + + T.twidth = S.width; + S.width = s_width; + + S.iwidth = s_iwidth; + S.iheight = s_iheight; + + T.theight = S.height; + S.height = s_height; + + T.tcolors = P1.colors; + P1.colors = s_colors; + + P1.filters = s_filters; + libraw_internal_data.unpacker_data.load_flags = s_flags; +} + +// ������� thumbnail �� �����, ������ thumb_format � ������������ � �������� + +int LibRaw::thumbOK(INT64 maxsz) +{ + if (!ID.input) + return 0; + if (!ID.toffset && !(imgdata.thumbnail.tlength > 0 && + load_raw == &LibRaw::broadcom_load_raw) // RPi +#ifdef USE_6BY9RPI + && !(imgdata.thumbnail.tlength > 0 && libraw_internal_data.unpacker_data.load_flags & 0x4000 && + (load_raw == &LibRaw::rpi_load_raw8 || load_raw == &LibRaw::nokia_load_raw || + load_raw == &LibRaw::rpi_load_raw12 || load_raw == &LibRaw::rpi_load_raw14)) +#endif + ) + return 0; + INT64 fsize = ID.input->size(); + if (fsize > 0xffffffffU) + return 0; // No thumb for raw > 4Gb-1 + int tsize = 0; + int tcol = (T.tcolors > 0 && T.tcolors < 4) ? T.tcolors : 3; + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) + tsize = T.tlength; + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) + tsize = tcol * T.twidth * T.theight; + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM16) + tsize = tcol * T.twidth * T.theight * + ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1); +#ifdef USE_X3FTOOLS + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) + { + tsize = x3f_thumb_size(); + } +#endif + else // Kodak => no check + tsize = 1; + if (tsize < 0) + return 0; + if (maxsz > 0 && tsize > maxsz) + return 0; + return (tsize + ID.toffset <= fsize) ? 1 : 0; +} + +int LibRaw::dcraw_thumb_writer(const char *fname) +{ + // CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD); + + if (!fname) + return ENOENT; + + FILE *tfp = fopen(fname, "wb"); + + if (!tfp) + return errno; + + if (!T.thumb) + { + fclose(tfp); + return LIBRAW_OUT_OF_ORDER_CALL; + } + + try + { + switch (T.tformat) + { + case LIBRAW_THUMBNAIL_JPEG: + jpeg_thumb_writer(tfp, T.thumb, T.tlength); + break; + case LIBRAW_THUMBNAIL_BITMAP: + fprintf(tfp, "P%d\n%d %d\n255\n", T.tcolors == 1 ? 5 : 6, T.twidth, T.theight); + fwrite(T.thumb, 1, T.tlength, tfp); + break; + default: + fclose(tfp); + return LIBRAW_UNSUPPORTED_THUMBNAIL; + } + fclose(tfp); + return 0; + } + catch (const std::bad_alloc&) + { + fclose(tfp); + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); + } + catch (const LibRaw_exceptions& err) + { + fclose(tfp); + EXCEPTION_HANDLER(err); + } +} diff --git a/src/utils/utils_dcraw.cpp b/src/utils/utils_dcraw.cpp new file mode 100644 index 000000000..97d14552e --- /dev/null +++ b/src/utils/utils_dcraw.cpp @@ -0,0 +1,330 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" + +int LibRaw::fcol(int row, int col) +{ + static const char filter[16][16] = { + {2, 1, 1, 3, 2, 3, 2, 0, 3, 2, 3, 0, 1, 2, 1, 0}, + {0, 3, 0, 2, 0, 1, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2}, + {2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 1, 2, 0, 0, 3}, + {0, 1, 0, 1, 0, 2, 0, 2, 2, 0, 3, 0, 1, 3, 2, 1}, + {3, 1, 1, 2, 0, 1, 0, 2, 1, 3, 1, 3, 0, 1, 3, 0}, + {2, 0, 0, 3, 3, 2, 3, 1, 2, 0, 2, 0, 3, 2, 2, 1}, + {2, 3, 3, 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 0, 0, 1}, + {1, 0, 0, 2, 3, 0, 0, 3, 0, 3, 0, 3, 2, 1, 2, 3}, + {2, 3, 3, 1, 1, 2, 1, 0, 3, 2, 3, 0, 2, 3, 1, 3}, + {1, 0, 2, 0, 3, 0, 3, 2, 0, 1, 1, 2, 0, 1, 0, 2}, + {0, 1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 0, 2, 1, 3, 2}, + {2, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 2, 3, 0, 1, 0}, + {1, 3, 1, 2, 3, 2, 3, 2, 0, 2, 0, 1, 1, 0, 3, 0}, + {0, 2, 0, 3, 1, 0, 0, 1, 1, 3, 3, 2, 3, 2, 2, 1}, + {2, 1, 3, 2, 3, 1, 2, 1, 0, 3, 0, 2, 0, 2, 0, 2}, + {0, 3, 1, 0, 0, 2, 0, 3, 2, 1, 3, 1, 1, 3, 1, 3}}; + + if (filters == 1) + return filter[(row + top_margin) & 15][(col + left_margin) & 15]; + if (filters == 9) + return xtrans[(row + 6) % 6][(col + 6) % 6]; + return FC(row, col); +} + +size_t LibRaw::strnlen(const char *s, size_t n) +{ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) + const char *p = (const char *)memchr(s, 0, n); + return (p ? p - s : n); +#else + return ::strnlen(s, n); +#endif +} + +void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle, + size_t needlelen) +{ +#if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp(c, needle, needlelen)) + return c; + return 0; +#else + return ::memmem(haystack, haystacklen, needle, needlelen); +#endif +} + +char *LibRaw::strcasestr(char *haystack, const char *needle) +{ + char *c; + for (c = haystack; *c; c++) + if (!strncasecmp(c, needle, strlen(needle))) + return c; + return 0; +} + +void LibRaw::initdata() +{ + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + iso_speed = shutter = aperture = focal_len = 0; + unique_id = 0ULL; + tiff_nifds = 0; + memset(tiff_ifd, 0, sizeof tiff_ifd); + for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++) + { + tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = + 0xffff; + for (int c = 0; c < 4; c++) + tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f; + } + for (int i = 0; i < 0x10000; i++) + curve[i] = i; + 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 = 0; + thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG + data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = 0; + metadata_blocks = 0; + is_NikonTransfer = 0; + is_Olympus = 0; + OlympusDNG_SubDirOffsetValid = 0; + is_Sony = 0; + is_pana_raw = 0; + maker_index = LIBRAW_CAMERAMAKER_Unknown; + FujiCropMode = 0; + is_PentaxRicohMakernotes = 0; + normalized_model[0] = 0; + normalized_make[0] = 0; + CM_found = 0; +} + +void LibRaw::aRGB_coeff(double aRGB_cam[3][3]) +{ + static const double rgb_aRGB[3][3] = { + {1.39828313770000, -0.3982830047, 9.64980900741708E-8}, + {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8}, + {2.17237099975343E-8, -0.0429383201, 1.04293828050000}}; + + double cmatrix_tmp[3][3] = { + {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; + int i, j, k; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + { + for (k = 0; k < 3; k++) + cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j]; + cmatrix[i][j] = (float)cmatrix_tmp[i][j]; + } +} + +void LibRaw::romm_coeff(float romm_cam[3][3]) +{ + static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ + {{2.034193f, -0.727420f, -0.306766f}, + {-0.228811f, 1.231729f, -0.002922f}, + {-0.008565f, -0.153273f, 1.161839f}}; + 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 LibRaw::remove_zeroes() +{ + unsigned row, col, tot, n; + int r, c; + + RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 0, 2); + + for (row = 0; row < height; row++) + for (col = 0; col < width; col++) + if (BAYER(row, col) == 0) + { + tot = n = 0; + for (r = (int)row - 2; r <= (int)row + 2; r++) + for (c = (int)col - 2; c <= (int)col + 2; c++) + if (r >= 0 && r < height && c >= 0 && c < width && + FC(r, c) == FC(row, col) && BAYER(r, c)) + tot += (n++, BAYER(r, c)); + if (n) + BAYER(row, col) = tot / n; + } + RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2); +} +void LibRaw::crop_masked_pixels() +{ + int row, col; + unsigned c, m, zero, val; +#define mblack imgdata.color.black_stat + + if (mask[0][3] > 0) + goto mask_set; + if (load_raw == &LibRaw::canon_load_raw || + load_raw == &LibRaw::lossless_jpeg_load_raw || + load_raw == &LibRaw::crxLoadRaw) + { + mask[0][1] = mask[1][1] += 2; + mask[0][3] -= 2; + goto sides; + } + if (load_raw == &LibRaw::canon_600_load_raw || + load_raw == &LibRaw::sony_load_raw || + (load_raw == &LibRaw::eight_bit_load_raw && strncmp(model, "DC2", 3)) || + load_raw == &LibRaw::kodak_262_load_raw || + (load_raw == &LibRaw::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 == &LibRaw::nokia_load_raw) + { + mask[0][2] = top_margin; + mask[0][3] = width; + } + if (load_raw == &LibRaw::broadcom_load_raw) + { + mask[0][2] = top_margin; + mask[0][3] = width; + } +mask_set: + memset(mblack, 0, sizeof mblack); + for (zero = m = 0; m < 8; m++) + for (row = MAX(mask[m][0], 0); row < MIN(mask[m][2], raw_height); row++) + for (col = MAX(mask[m][1], 0); col < MIN(mask[m][3], raw_width); col++) + { + /* No need to subtract margins because full area and active area filters are the same */ + c = FC(row, col); + mblack[c] += val = raw_image[(row)*raw_pitch / 2 + (col)]; + mblack[4 + c]++; + zero += !val; + } + if (load_raw == &LibRaw::canon_600_load_raw && width < raw_width) + { + black = (mblack[0] + mblack[1] + mblack[2] + mblack[3]) / + MAX(1, (mblack[4] + mblack[5] + mblack[6] + mblack[7])) - + 4; + } + else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) + { + FORC4 cblack[c] = mblack[c] / MAX(1, mblack[4 + c]); + black = cblack[4] = cblack[5] = cblack[6] = 0; + } +} +#undef mblack + +void LibRaw::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 < 4; 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++) + if (fabs(num) > 0.00001f) + 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 < 4; 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 LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i = 0; i < colors && i < 4; 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] * LibRaw_constants::xyz_rgb[k][j]; + + for (i = 0; i < colors && i < 4; 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]; + if (num > 0.00001) + { + for (j = 0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + else + { + for (j = 0; j < 3; j++) + cam_rgb[i][j] = 0.0; + pre_mul[i] = 1.0; + } + } + pseudoinverse(cam_rgb, inverse, colors); + for (i = 0; i < 3; i++) + for (j = 0; j < colors && j < 4; j++) + _rgb_cam[i][j] = inverse[j][i]; +} + +void LibRaw::tiff_get(unsigned base, unsigned *tag, unsigned *type, + unsigned *len, unsigned *save) +{ +#ifdef LIBRAW_IOSPACE_CHECK + INT64 pos = ftell(ifp); + INT64 fsize = ifp->size(); + if (fsize < 12 || (fsize - pos) < 12) + throw LIBRAW_EXCEPTION_IO_EOF; +#endif + *tag = get2(); + *type = get2(); + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * tagtype_dataunit_bytes[(*type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *type : 0] > 4) + fseek(ifp, get4() + base, SEEK_SET); +} diff --git a/src/utils/utils_libraw.cpp b/src/utils/utils_libraw.cpp new file mode 100644 index 000000000..15a7b6551 --- /dev/null +++ b/src/utils/utils_libraw.cpp @@ -0,0 +1,673 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + void default_data_callback(void *, const char *file, const int offset) + { + if (offset < 0) + fprintf(stderr, "%s: Unexpected end of file\n", + file ? file : "unknown file"); + else + fprintf(stderr, "%s: data corrupted at %d\n", + file ? file : "unknown file", offset); + } + const char *libraw_strerror(int e) + { + enum LibRaw_errors errorcode = (LibRaw_errors)e; + switch (errorcode) + { + case LIBRAW_SUCCESS: + return "No error"; + case LIBRAW_UNSPECIFIED_ERROR: + return "Unspecified error"; + case LIBRAW_FILE_UNSUPPORTED: + return "Unsupported file format or not RAW file"; + case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE: + return "Request for nonexisting image number"; + case LIBRAW_OUT_OF_ORDER_CALL: + return "Out of order call of libraw function"; + case LIBRAW_NO_THUMBNAIL: + return "No thumbnail in file"; + case LIBRAW_UNSUPPORTED_THUMBNAIL: + return "Unsupported thumbnail format"; + case LIBRAW_INPUT_CLOSED: + return "No input stream, or input stream closed"; + case LIBRAW_NOT_IMPLEMENTED: + return "Decoder not implemented for this data format"; + case LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL: + return "Request for nonexisting thumbnail number"; + case LIBRAW_MEMPOOL_OVERFLOW: + return "Libraw internal mempool overflowed"; + case LIBRAW_UNSUFFICIENT_MEMORY: + return "Unsufficient memory"; + case LIBRAW_DATA_ERROR: + return "Corrupted data or unexpected EOF"; + case LIBRAW_IO_ERROR: + return "Input/output error"; + case LIBRAW_CANCELLED_BY_CALLBACK: + return "Cancelled by user callback"; + case LIBRAW_BAD_CROP: + return "Bad crop box"; + case LIBRAW_TOO_BIG: + return "Image too big for processing"; + default: + return "Unknown error code"; + } + } + +#ifdef __cplusplus +} +#endif + +unsigned LibRaw::parse_custom_cameras(unsigned limit, + libraw_custom_camera_t table[], + char **list) +{ + if (!list) + return 0; + unsigned index = 0; + for (unsigned i = 0; i < limit; i++) + { + if (!list[i]) + break; + if (strlen(list[i]) < 10) + continue; + char *string = (char *)malloc(strlen(list[i]) + 1); + strcpy(string, list[i]); + char *start = string; + memset(&table[index], 0, sizeof(table[0])); + for (int j = 0; start && j < 14; j++) + { + char *end = strchr(start, ','); + if (end) + { + *end = 0; + end++; + } // move to next char + while (isspace(*start) && *start) + start++; // skip leading spaces? + unsigned val = strtol(start, 0, 10); + switch (j) + { + case 0: + table[index].fsize = val; + break; + case 1: + table[index].rw = val; + break; + case 2: + table[index].rh = val; + break; + case 3: + table[index].lm = val; + break; + case 4: + table[index].tm = val; + break; + case 5: + table[index].rm = val; + break; + case 6: + table[index].bm = val; + break; + case 7: + table[index].lf = val; + break; + case 8: + table[index].cf = val; + break; + case 9: + table[index].max = val; + break; + case 10: + table[index].flags = val; + break; + case 11: + strncpy(table[index].t_make, start, sizeof(table[index].t_make) - 1); + break; + case 12: + strncpy(table[index].t_model, start, sizeof(table[index].t_model) - 1); + break; + case 13: + table[index].offset = val; + break; + default: + break; + } + start = end; + } + free(string); + if (table[index].t_make[0]) + index++; + } + return index; +} + +void LibRaw::derror() +{ + if (!libraw_internal_data.unpacker_data.data_error && + libraw_internal_data.internal_data.input) + { + if (libraw_internal_data.internal_data.input->eof()) + { + if (callbacks.data_cb) + (*callbacks.data_cb)(callbacks.datacb_data, + libraw_internal_data.internal_data.input->fname(), + -1); + throw LIBRAW_EXCEPTION_IO_EOF; + } + else + { + if (callbacks.data_cb) + (*callbacks.data_cb)(callbacks.datacb_data, + libraw_internal_data.internal_data.input->fname(), + libraw_internal_data.internal_data.input->tell()); + // throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + libraw_internal_data.unpacker_data.data_error++; +} + +const char *LibRaw::version() { return LIBRAW_VERSION_STR; } +int LibRaw::versionNumber() { return LIBRAW_VERSION; } +const char *LibRaw::strerror(int p) { return libraw_strerror(p); } + +unsigned LibRaw::capabilities() +{ + unsigned ret = 0; +#ifdef USE_RAWSPEED + ret |= LIBRAW_CAPS_RAWSPEED; +#endif +#ifdef USE_RAWSPEED3 + ret |= LIBRAW_CAPS_RAWSPEED3; +#endif +#ifdef USE_RAWSPEED_BITS + ret |= LIBRAW_CAPS_RAWSPEED_BITS; +#endif +#ifdef USE_DNGSDK + ret |= LIBRAW_CAPS_DNGSDK; +#ifdef USE_GPRSDK + ret |= LIBRAW_CAPS_GPRSDK; +#endif +#ifdef LIBRAW_WIN32_UNICODEPATHS + ret |= LIBRAW_CAPS_UNICODEPATHS; +#endif +#endif +#ifdef USE_X3FTOOLS + ret |= LIBRAW_CAPS_X3FTOOLS; +#endif +#ifdef USE_6BY9RPI + ret |= LIBRAW_CAPS_RPI6BY9; +#endif +#ifdef USE_ZLIB + ret |= LIBRAW_CAPS_ZLIB; +#endif +#ifdef USE_JPEG + ret |= LIBRAW_CAPS_JPEG; +#endif + return ret; +} + +int LibRaw::is_sraw() +{ + return load_raw == &LibRaw::canon_sraw_load_raw || + load_raw == &LibRaw::nikon_load_sraw; +} +int LibRaw::is_coolscan_nef() +{ + return load_raw == &LibRaw::nikon_coolscan_load_raw; +} +int LibRaw::is_jpeg_thumb() +{ + return libraw_internal_data.unpacker_data.thumb_format == LIBRAW_INTERNAL_THUMBNAIL_JPEG; +} + +int LibRaw::is_nikon_sraw() { return load_raw == &LibRaw::nikon_load_sraw; } +int LibRaw::sraw_midpoint() +{ + if (load_raw == &LibRaw::canon_sraw_load_raw) + return 8192; + else if (load_raw == &LibRaw::nikon_load_sraw) + return 2048; + else + return 0; +} + +void *LibRaw::malloc(size_t t) +{ + void *p = memmgr.malloc(t); + if (!p) + throw LIBRAW_EXCEPTION_ALLOC; + return p; +} +void *LibRaw::realloc(void *q, size_t t) +{ + void *p = memmgr.realloc(q, t); + if (!p) + throw LIBRAW_EXCEPTION_ALLOC; + return p; +} + +void *LibRaw::calloc(size_t n, size_t t) +{ + void *p = memmgr.calloc(n, t); + if (!p) + throw LIBRAW_EXCEPTION_ALLOC; + return p; +} +void LibRaw::free(void *p) { memmgr.free(p); } + +void LibRaw::recycle_datastream() +{ + if (libraw_internal_data.internal_data.input && + libraw_internal_data.internal_data.input_internal) + { + delete libraw_internal_data.internal_data.input; + libraw_internal_data.internal_data.input = NULL; + } + libraw_internal_data.internal_data.input_internal = 0; +} + +void LibRaw::clearCancelFlag() +{ +#ifdef _MSC_VER + InterlockedExchange(&_exitflag, 0); +#else + __sync_fetch_and_and(&_exitflag, 0); +#endif +#ifdef RAWSPEED_FASTEXIT + if (_rawspeed_decoder) + { + RawSpeed::RawDecoder *d = + static_cast(_rawspeed_decoder); + d->resumeProcessing(); + } +#endif +} + +void LibRaw::setCancelFlag() +{ +#ifdef _MSC_VER + InterlockedExchange(&_exitflag, 1); +#else + __sync_fetch_and_add(&_exitflag, 1); +#endif +#ifdef RAWSPEED_FASTEXIT + if (_rawspeed_decoder) + { + RawSpeed::RawDecoder *d = + static_cast(_rawspeed_decoder); + d->cancelProcessing(); + } +#endif +} + +void LibRaw::checkCancel() +{ +#ifdef _MSC_VER + if (InterlockedExchange(&_exitflag, 0)) + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; +#else + if (__sync_fetch_and_and(&_exitflag, 0)) + throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; +#endif +} + +int LibRaw::is_curve_linear() +{ + for (int i = 0; i < 0x10000; i++) + if (imgdata.color.curve[i] != i) + return 0; + return 1; +} + +void LibRaw::free_image(void) +{ + if (imgdata.image) + { + free(imgdata.image); + imgdata.image = 0; + imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | + LIBRAW_PROGRESS_IDENTIFY | + LIBRAW_PROGRESS_SIZE_ADJUST | + LIBRAW_PROGRESS_LOAD_RAW; + } +} + +int LibRaw::is_phaseone_compressed() +{ + return (load_raw == &LibRaw::phase_one_load_raw_c || + load_raw == &LibRaw::phase_one_load_raw_s || + load_raw == &LibRaw::phase_one_load_raw); +} + +int LibRaw::is_canon_600() { return load_raw == &LibRaw::canon_600_load_raw; } +const char *LibRaw::strprogress(enum LibRaw_progress p) +{ + switch (p) + { + case LIBRAW_PROGRESS_START: + return "Starting"; + case LIBRAW_PROGRESS_OPEN: + return "Opening file"; + case LIBRAW_PROGRESS_IDENTIFY: + return "Reading metadata"; + case LIBRAW_PROGRESS_SIZE_ADJUST: + return "Adjusting size"; + case LIBRAW_PROGRESS_LOAD_RAW: + return "Reading RAW data"; + case LIBRAW_PROGRESS_REMOVE_ZEROES: + return "Clearing zero values"; + case LIBRAW_PROGRESS_BAD_PIXELS: + return "Removing dead pixels"; + case LIBRAW_PROGRESS_DARK_FRAME: + return "Subtracting dark frame data"; + case LIBRAW_PROGRESS_FOVEON_INTERPOLATE: + return "Interpolating Foveon sensor data"; + case LIBRAW_PROGRESS_SCALE_COLORS: + return "Scaling colors"; + case LIBRAW_PROGRESS_PRE_INTERPOLATE: + return "Pre-interpolating"; + case LIBRAW_PROGRESS_INTERPOLATE: + return "Interpolating"; + case LIBRAW_PROGRESS_MIX_GREEN: + return "Mixing green channels"; + case LIBRAW_PROGRESS_MEDIAN_FILTER: + return "Median filter"; + case LIBRAW_PROGRESS_HIGHLIGHTS: + return "Highlight recovery"; + case LIBRAW_PROGRESS_FUJI_ROTATE: + return "Rotating Fuji diagonal data"; + case LIBRAW_PROGRESS_FLIP: + return "Flipping image"; + case LIBRAW_PROGRESS_APPLY_PROFILE: + return "ICC conversion"; + case LIBRAW_PROGRESS_CONVERT_RGB: + return "Converting to RGB"; + case LIBRAW_PROGRESS_STRETCH: + return "Stretching image"; + case LIBRAW_PROGRESS_THUMB_LOAD: + return "Loading thumbnail"; + default: + return "Some strange things"; + } +} +int LibRaw::adjust_sizes_info_only(void) +{ + CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); + + raw2image_start(); + if (O.use_fuji_rotate) + { + if (IO.fuji_width) + { + IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink; + S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5)); + S.iheight = (ushort)((S.iheight - IO.fuji_width) / sqrt(0.5)); + } + else + { + if (S.pixel_aspect < 0.995) + S.iheight = (ushort)(S.iheight / S.pixel_aspect + 0.5); + if (S.pixel_aspect > 1.005) + S.iwidth = (ushort)(S.iwidth * S.pixel_aspect + 0.5); + } + } + SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); + if (S.flip & 4) + { + unsigned short t = S.iheight; + S.iheight = S.iwidth; + S.iwidth = t; + SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP); + } + return 0; +} +int LibRaw::adjust_maximum() +{ + ushort real_max; + float auto_threshold; + + if (O.adjust_maximum_thr < 0.00001) + return LIBRAW_SUCCESS; + else if (O.adjust_maximum_thr > 0.99999) + auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; + else + auto_threshold = O.adjust_maximum_thr; + + real_max = C.data_maximum; + if (real_max > 0 && real_max < C.maximum && + real_max > C.maximum * auto_threshold) + { + C.maximum = real_max; + } + return LIBRAW_SUCCESS; +} +void LibRaw::adjust_bl() +{ + int clear_repeat = 0; + if (O.user_black >= 0) + { + C.black = O.user_black; + clear_repeat = 1; + } + for (int i = 0; i < 4; i++) + if (O.user_cblack[i] > -1000000) + { + C.cblack[i] = O.user_cblack[i]; + clear_repeat = 1; + } + + if (clear_repeat) + C.cblack[4] = C.cblack[5] = 0; + + // Add common part to cblack[] early + if (imgdata.idata.filters > 1000 && (C.cblack[4] + 1) / 2 == 1 && + (C.cblack[5] + 1) / 2 == 1) + { + int clrs[4]; + int lastg = -1, gcnt = 0; + for (int c = 0; c < 4; c++) + { + clrs[c] = FC(c / 2, c % 2); + if (clrs[c] == 1) + { + gcnt++; + lastg = c; + } + } + if (gcnt > 1 && lastg >= 0) + clrs[lastg] = 3; + for (int c = 0; c < 4; c++) + C.cblack[clrs[c]] += + C.cblack[6 + c / 2 % C.cblack[4] * C.cblack[5] + c % 2 % C.cblack[5]]; + C.cblack[4] = C.cblack[5] = 0; + // imgdata.idata.filters = sfilters; + } + else if (imgdata.idata.filters <= 1000 && C.cblack[4] == 1 && + C.cblack[5] == 1) // Fuji RAF dng + { + for (int c = 0; c < 4; c++) + C.cblack[c] += C.cblack[6]; + C.cblack[4] = C.cblack[5] = 0; + } + // remove common part from C.cblack[] + int i = C.cblack[3]; + int c; + for (c = 0; c < 3; c++) + if (i > (int)C.cblack[c]) + i = C.cblack[c]; + + for (c = 0; c < 4; c++) + C.cblack[c] -= i; // remove common part + C.black += i; + + // Now calculate common part for cblack[6+] part and move it to C.black + + if (C.cblack[4] && C.cblack[5]) + { + i = C.cblack[6]; + for (c = 1; c < int(C.cblack[4] * C.cblack[5]); c++) + if (i > int(C.cblack[6 + c])) + i = C.cblack[6 + c]; + // Remove i from cblack[6+] + int nonz = 0; + for (c = 0; c < int(C.cblack[4] * C.cblack[5]); c++) + { + C.cblack[6 + c] -= i; + if (C.cblack[6 + c]) + nonz++; + } + C.black += i; + if (!nonz) + C.cblack[4] = C.cblack[5] = 0; + } + for (c = 0; c < 4; c++) + C.cblack[c] += C.black; +} +int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen) +{ + line[maxlen - 1] = 0; + unsigned char *p = (unsigned char*)line; + int nwords = 0; + + while (1) + { + while (isspace(*p)) + p++; + if (*p == '\0') + return nwords; + words[nwords++] = (char*)p; + while (!isspace(*p) && *p != '\0') + p++; + if (*p == '\0') + return nwords; + *p++ = '\0'; + if (nwords >= maxwords) + return nwords; + } +} +int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp) +{ + if (len > 0) + { + int r = fp->read(buf, len, 1); + buf[len - 1] = 0; + return r; + } + else + return 0; +} + +int LibRaw::find_ifd_by_offset(int o) +{ + for(unsigned i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++) + if(tiff_ifd[i].offset == o) + return i; + return -1; +} + +short LibRaw::tiff_sget (unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset, + unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, + unsigned *tag_datalen, int *tag_dataunitlen) { + uchar *pos = buf + *tag_offset; + if ((((*tag_offset) + 12) > buf_len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun + return -1; + } + *tag_id = sget2(pos); pos += 2; + *tag_type = sget2(pos); pos += 2; + *tag_datalen = sget4(pos); pos += 4; + *tag_dataunitlen = tagtype_dataunit_bytes[(*tag_type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *tag_type : 0]; + if ((*tag_datalen * (*tag_dataunitlen)) > 4) { + *tag_dataoffset = sget4(pos) - save; + if ((*tag_dataoffset + *tag_datalen) > buf_len) { // abnormal, tag data buffer overrun + return -2; + } + } else *tag_dataoffset = *tag_offset + 8; + *tag_offset += 12; + return 0; +} + +#define rICC imgdata.sizes.raw_inset_crops +#define S imgdata.sizes +#define RS imgdata.rawdata.sizes +int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop) + +{ + int adjindex = -1; + int limwidth = S.width * maxcrop; + int limheight = S.height * maxcrop; + + for(int i = 1; i >= 0; i--) + if (mask & (1<= limwidth && rICC[i].cheight >= limheight) + { + adjindex = i; + break; + } + + if (adjindex >= 0) + { + RS.left_margin = S.left_margin = rICC[adjindex].cleft; + RS.top_margin = S.top_margin = rICC[adjindex].ctop; + RS.width = S.width = MIN(rICC[adjindex].cwidth, int(S.raw_width) - int(S.left_margin)); + RS.height = S.height = MIN(rICC[adjindex].cheight, int(S.raw_height) - int(S.top_margin)); + } + return adjindex + 1; +} + +char** LibRaw::malloc_omp_buffers(int buffer_count, size_t buffer_size) +{ + char** buffers = (char**)calloc(sizeof(char*), buffer_count); + + for (int i = 0; i < buffer_count; i++) + { + buffers[i] = (char*)malloc(buffer_size); + } + return buffers; +} + +void LibRaw::free_omp_buffers(char** buffers, int buffer_count) +{ + for (int i = 0; i < buffer_count; i++) + if(buffers[i]) + free(buffers[i]); + free(buffers); +} + +void LibRaw::libraw_swab(void *arr, size_t len) +{ +#ifdef LIBRAW_OWN_SWAB + uint16_t *array = (uint16_t*)arr; + size_t bytes = len/2; + for(; bytes; --bytes) + { + *array = ((*array << 8) & 0xff00) | ((*array >> 8) & 0xff); + array++; + } +#else + swab((char*)arr,(char*)arr,len); +#endif + +} diff --git a/src/write/apply_profile.cpp b/src/write/apply_profile.cpp new file mode 100644 index 000000000..0bcb16dca --- /dev/null +++ b/src/write/apply_profile.cpp @@ -0,0 +1,76 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_fileio_defs.h" + +#ifndef NO_LCMS +void LibRaw::apply_profile(const char *input, const char *output) +{ + char *prof; + cmsHPROFILE hInProfile = 0, hOutProfile = 0; + cmsHTRANSFORM hTransform; + FILE *fp; + unsigned size; + + if (strcmp(input, "embed")) + hInProfile = cmsOpenProfileFromFile(input, "r"); + else if (profile_length) + { + hInProfile = cmsOpenProfileFromMem(imgdata.color.profile, profile_length); + } + else + { + imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE; + } + if (!hInProfile) + { + imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE; + 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)); + fread(oprof, 1, size, fp); + fclose(fp); + if (!(hOutProfile = cmsOpenProfileFromMem(oprof, size))) + { + free(oprof); + oprof = 0; + } + } + if (!hOutProfile) + { + imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE; + goto quit; + } + RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 0, 2); + 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); + RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE, 1, 2); +} +#endif diff --git a/src/write/file_write.cpp b/src/write/file_write.cpp new file mode 100644 index 000000000..bf17ea2b4 --- /dev/null +++ b/src/write/file_write.cpp @@ -0,0 +1,338 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/dcraw_defs.h" +#include + +int LibRaw::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; +} + +void LibRaw::tiff_set(struct tiff_hdr *th, ushort *ntag, ushort tag, + ushort type, int count, int val) +{ + struct libraw_tiff_tag *tt; + int c; + + tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++; + tt->val.i = val; + if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) && count <= 4) + FORC(4) tt->val.c[c] = val >> (c << 3); + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) + { + count = int(strnlen((char *)th + val, count - 1)) + 1; + if (count <= 4) + FORC(4) tt->val.c[c] = ((char *)th)[val + c]; + } + else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && count <= 2) + FORC(2) tt->val.s[c] = val >> (c << 4); + tt->count = count; + tt->type = type; + tt->tag = tag; +} + +#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) + +void LibRaw::tiff_head(struct tiff_hdr *th, int full) +{ + int c, psize = 0; + struct tm *t; + + memset(th, 0, sizeof *th); + th->t_order = htonl(0x4d4d4949) >> 16; + th->magic = 42; + th->ifd = 10; + 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->t_desc, desc, 512); + strncpy(th->t_make, make, 64); + strncpy(th->t_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->t_artist, artist, 64); + if (full) + { + tiff_set(th, &th->ntag, 254, 4, 1, 0); + tiff_set(th, &th->ntag, 256, 4, 1, width); + tiff_set(th, &th->ntag, 257, 4, 1, height); + tiff_set(th, &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, &th->ntag, 259, 3, 1, 1); + tiff_set(th, &th->ntag, 262, 3, 1, 1 + (colors > 1)); + } + tiff_set(th, &th->ntag, 270, 2, 512, TOFF(th->t_desc)); + tiff_set(th, &th->ntag, 271, 2, 64, TOFF(th->t_make)); + tiff_set(th, &th->ntag, 272, 2, 64, TOFF(th->t_model)); + if (full) + { + if (oprof) + psize = ntohl(oprof[0]); + tiff_set(th, &th->ntag, 273, 4, 1, sizeof *th + psize); + tiff_set(th, &th->ntag, 277, 3, 1, colors); + tiff_set(th, &th->ntag, 278, 4, 1, height); + tiff_set(th, &th->ntag, 279, 4, 1, + height * width * colors * output_bps / 8); + } + else + tiff_set(th, &th->ntag, 274, 3, 1, "12435867"[flip] - '0'); + tiff_set(th, &th->ntag, 282, 5, 1, TOFF(th->rat[0])); + tiff_set(th, &th->ntag, 283, 5, 1, TOFF(th->rat[2])); + tiff_set(th, &th->ntag, 284, 3, 1, 1); + tiff_set(th, &th->ntag, 296, 3, 1, 2); + tiff_set(th, &th->ntag, 305, 2, 32, TOFF(th->soft)); + tiff_set(th, &th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set(th, &th->ntag, 315, 2, 64, TOFF(th->t_artist)); + tiff_set(th, &th->ntag, 34665, 4, 1, TOFF(th->nexif)); + if (psize) + tiff_set(th, &th->ntag, 34675, 7, psize, sizeof *th); + tiff_set(th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4])); + tiff_set(th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6])); + tiff_set(th, &th->nexif, 34855, 3, 1, iso_speed); + tiff_set(th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8])); + if (gpsdata[1]) + { + uchar latref[4] = { (uchar)(gpsdata[29]),0,0,0 }, + lonref[4] = { (uchar)(gpsdata[30]),0,0,0 }; + tiff_set(th, &th->ntag, 34853, 4, 1, TOFF(th->ngps)); + tiff_set(th, &th->ngps, 0, 1, 4, 0x202); + tiff_set(th, &th->ngps, 1, 2, 2, TOFF(latref)); + tiff_set(th, &th->ngps, 2, 5, 3, TOFF(th->gps[0])); + tiff_set(th, &th->ngps, 3, 2, 2, TOFF(lonref)); + tiff_set(th, &th->ngps, 4, 5, 3, TOFF(th->gps[6])); + tiff_set(th, &th->ngps, 5, 1, 1, gpsdata[31]); + tiff_set(th, &th->ngps, 6, 5, 1, TOFF(th->gps[18])); + tiff_set(th, &th->ngps, 7, 5, 3, TOFF(th->gps[12])); + tiff_set(th, &th->ngps, 18, 2, 12, TOFF(th->gps[20])); + tiff_set(th, &th->ngps, 29, 2, 12, TOFF(th->gps[23])); + memcpy(th->gps, gpsdata, sizeof th->gps); + } +} + +void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length) +{ + ushort exif[5]; + struct tiff_hdr th; + fputc(0xff, tfp); + fputc(0xd8, tfp); + if (strcmp(t_humb + 6, "Exif")) + { + memcpy(exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons(8 + sizeof th); + fwrite(exif, 1, sizeof exif, tfp); + tiff_head(&th, 0); + fwrite(&th, 1, sizeof th, tfp); + } + fwrite(t_humb + 2, 1, t_humb_length - 2, tfp); +} +void LibRaw::write_ppm_tiff() +{ + try + { + struct tiff_hdr th; + ushort *ppm2; + int c, row, col, soff, rstep, cstep; + int perc, val, total, t_white = 0x2000; + + perc = width * height * auto_bright_thr; + + if (fuji_width) + perc /= 2; + if (!((highlight & ~2) || no_auto_bright)) + for (t_white = c = 0; c < colors; c++) + { + for (val = 0x2000, total = 0; --val > 32;) + if ((total += histogram[c][val]) > perc) + break; + if (t_white < val) + t_white = val; + } + gamma_curve(gamm[0], gamm[1], 2, (t_white << 3) / bright); + iheight = height; + iwidth = width; + if (flip & 4) + SWAP(height, width); + + std::vector ppm(width * colors * output_bps / 8); + ppm2 = (ushort *)ppm.data(); + 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) + { + if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) + fprintf(ofp, + "P7\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n# ISOSPEED=%d\n" + "# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n# MAKE=%s\n# MODEL=%s\n" + "WIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + shutter, (int)timestamp, (int)iso_speed,aperture, + focal_len, make, model, + width, height, colors, (1 << output_bps) - 1, cdesc); + else + fprintf( + ofp, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + width, height, colors, (1 << output_bps) - 1, cdesc); + } + else + { + if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) + fprintf(ofp, "P%d\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n" + "# ISOSPEED=%d\n# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n" + "# MAKE=%s\n# MODEL=%s\n%d %d\n%d\n", + colors/2+5, + shutter, (int)timestamp, (int)iso_speed,aperture,focal_len, + make,model, + width, height, (1 << output_bps)-1); + 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) + libraw_swab(ppm2, width * colors * 2); + fwrite(ppm.data(), colors * output_bps / 8, width, ofp); + } + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} +#if 0 +void LibRaw::ppm_thumb() +{ + try + { + thumb_length = thumb_width * thumb_height * 3; + std::vector thumb(thumb_length); + fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fread(thumb.data(), 1, thumb_length, ifp); + fwrite(thumb.data(), 1, thumb_length, ofp); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} + +void LibRaw::ppm16_thumb() +{ + try + { + unsigned i; + thumb_length = thumb_width * thumb_height * 3; + std::vector thumb(thumb_length * 2, 0); + read_shorts((ushort *)thumb.data(), thumb_length); + for (i = 0; i < thumb_length; i++) + thumb[i] = ((ushort *)thumb.data())[i] >> 8; + fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fwrite(thumb.data(), 1, thumb_length, ofp); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} + +void LibRaw::layer_thumb() +{ + try + { + unsigned int i; + int c; + char map[][4] = { "012", "102" }; + + colors = thumb_misc >> 5 & 7; + thumb_length = thumb_width * thumb_height; + std::vector thumb(colors * thumb_length, 0); + fprintf(ofp, "P%d\n%d %d\n255\n", 5 + (colors >> 1), thumb_width, + thumb_height); + fread(thumb.data(), thumb_length, colors, ifp); + for (i = 0; i < thumb_length; i++) + FORCC putc(thumb[i + thumb_length * (map[thumb_misc >> 8][c] - '0')], ofp); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} + +void LibRaw::rollei_thumb() +{ + try + { + unsigned i; + thumb_length = thumb_width * thumb_height; + std::vector thumb(thumb_length, 0); + fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + read_shorts(thumb.data(), 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); + } + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} + +void LibRaw::jpeg_thumb() +{ + try + { + std::vector thumb(thumb_length); + fread(thumb.data(), 1, thumb_length, ifp); + jpeg_thumb_writer(ofp, thumb.data(), thumb_length); + } + catch (...) + { + throw LIBRAW_EXCEPTION_ALLOC; // rethrow + } +} +#endif diff --git a/src/write/tiff_writer.cpp b/src/write/tiff_writer.cpp new file mode 100644 index 000000000..895b18e52 --- /dev/null +++ b/src/write/tiff_writer.cpp @@ -0,0 +1,73 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, + dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. + LibRaw do not use RESTRICTED code from dcraw.c + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" + +int LibRaw::dcraw_ppm_tiff_writer(const char *filename) +{ + CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW); + + if (!imgdata.image) + return LIBRAW_OUT_OF_ORDER_CALL; + + if (!filename) + return ENOENT; + FILE *f = NULL; + if (!strcmp(filename, "-")) + { +#ifdef LIBRAW_WIN32_CALLS + _setmode(_fileno(stdout), _O_BINARY); +#endif + f = stdout; + } + else + f = fopen(filename, "wb"); + + if (!f) + return errno; + + try + { + if (!libraw_internal_data.output_data.histogram) + { + libraw_internal_data.output_data.histogram = + (int(*)[LIBRAW_HISTOGRAM_SIZE])malloc( + sizeof(*libraw_internal_data.output_data.histogram) * 4); + } + libraw_internal_data.internal_data.output = f; + write_ppm_tiff(); + SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP); + libraw_internal_data.internal_data.output = NULL; + if (strcmp(filename, "-")) + fclose(f); + return 0; + } + catch (const LibRaw_exceptions& err) + { + if (strcmp(filename, "-")) + fclose(f); + EXCEPTION_HANDLER(err); + } + catch (const std::bad_alloc&) + { + if (strcmp(filename, "-")) + fclose(f); + EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); + } + +} diff --git a/src/write/write_ph.cpp b/src/write/write_ph.cpp new file mode 100644 index 000000000..8151f108f --- /dev/null +++ b/src/write/write_ph.cpp @@ -0,0 +1,39 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + Placeholder functions to build LibRaw w/o postprocessing + and preprocessing calls + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + + +#include "../../internal/dcraw_defs.h" +int LibRaw::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; +} + +void LibRaw::write_ppm_tiff(){} +void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length){} +#if 0 +void LibRaw::ppm_thumb(){} +void LibRaw::jpeg_thumb(){} +void LibRaw::rollei_thumb(){} +void LibRaw::ppm16_thumb(){} +void LibRaw::layer_thumb(){} +#endif \ No newline at end of file diff --git a/src/x3f/x3f_parse_process.cpp b/src/x3f/x3f_parse_process.cpp new file mode 100644 index 000000000..354e46737 --- /dev/null +++ b/src/x3f/x3f_parse_process.cpp @@ -0,0 +1,708 @@ +/* -*- C++ -*- + * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * + + LibRaw is free software; you can redistribute it and/or modify + it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + */ + +/* Library for accessing X3F Files +---------------------------------------------------------------- +BSD-style License +---------------------------------------------------------------- + +* Copyright (c) 2010, Roland Karlsson (roland@proxel.se) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the organization 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 ROLAND KARLSSON ''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 ROLAND KARLSSON 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. + +*/ + +#ifdef USE_X3FTOOLS + +#include "../../internal/libraw_cxx_defs.h" + +#if defined __sun && defined DS +#undef DS +#endif +#ifdef ID +#undef ID /* used in x3f utils */ +#endif + +#include "../../internal/x3f_tools.h" + +#define Sigma_X3F 22 + +void x3f_clear(void *p) { x3f_delete((x3f_t *)p); } + +static void utf2char(utf16_t *str, char *buffer, unsigned bufsz) +{ + if (bufsz < 1) + return; + buffer[bufsz - 1] = 0; + char *b = buffer; + + while (*str != 0x00 && --bufsz > 0) + { + char *chr = (char *)str; + *b++ = *chr; + str++; + } + *b = 0; +} + +static void *lr_memmem(const void *l, size_t l_len, const void *s, size_t s_len) +{ + char *cur, *last; + const char *cl = (const char *)l; + const char *cs = (const char *)s; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return (void *)memchr(l, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = (char *)cl + l_len - s_len; + + for (cur = (char *)cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + return NULL; +} + +void LibRaw::parse_x3f() +{ + x3f_t *x3f = x3f_new_from_file(libraw_internal_data.internal_data.input); + if (!x3f) + return; + _x3f_data = x3f; + + x3f_header_t *H = NULL; + + H = &x3f->header; + // Parse RAW size from RAW section + x3f_directory_entry_t *DE = x3f_get_raw(x3f); + if (!DE) + return; + imgdata.sizes.flip = H->rotation; + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + imgdata.sizes.raw_width = ID->columns; + imgdata.sizes.raw_height = ID->rows; + // Parse other params from property section + + DE = x3f_get_prop(x3f); + if ((x3f_load_data(x3f, DE) == X3F_OK)) + { + // Parse property list + DEH = &DE->header; + x3f_property_list_t *PL = &DEH->data_subsection.property_list; + utf16_t *datap = (utf16_t *)PL->data; + uint32_t maxitems = PL->data_size / sizeof(utf16_t); + if (PL->property_table.size != 0) + { + int i; + x3f_property_t *P = PL->property_table.element; + for (i = 0; i < (int)PL->num_properties; i++) + { + char name[100], value[100]; + int noffset = (P[i].name - datap); + int voffset = (P[i].value - datap); + if (noffset < 0 || noffset > (int)maxitems || voffset < 0 || + voffset > (int)maxitems) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + int maxnsize = maxitems - (P[i].name - datap); + int maxvsize = maxitems - (P[i].value - datap); + utf2char(P[i].name, name, MIN(maxnsize, ((int)sizeof(name)))); + utf2char(P[i].value, value, MIN(maxvsize, ((int)sizeof(value)))); + if (!strcmp(name, "ISO")) + imgdata.other.iso_speed = atoi(value); + if (!strcmp(name, "CAMMANUF")) + strcpy(imgdata.idata.make, value); + if (!strcmp(name, "CAMMODEL")) + strcpy(imgdata.idata.model, value); + if (!strcmp(name, "CAMSERIAL")) + strcpy(imgdata.shootinginfo.BodySerial, value); + if (!strcmp(name, "WB_DESC")) + strcpy(imgdata.color.model2, value); + if (!strcmp(name, "TIME")) + imgdata.other.timestamp = atoi(value); + if (!strcmp(name, "SHUTTER")) + imgdata.other.shutter = atof(value); + if (!strcmp(name, "APERTURE")) + imgdata.other.aperture = atof(value); + if (!strcmp(name, "FLENGTH")) + imgdata.other.focal_len = atof(value); + if (!strcmp(name, "FLEQ35MM")) + imgdata.lens.makernotes.FocalLengthIn35mmFormat = atof(value); + if (!strcmp(name, "IMAGERTEMP")) + MN.common.SensorTemperature = atof(value); + if (!strcmp(name, "LENSARANGE")) + { + char *sp; + imgdata.lens.makernotes.MaxAp4CurFocal = + imgdata.lens.makernotes.MinAp4CurFocal = atof(value); + sp = strrchr(value, ' '); + if (sp) + { + imgdata.lens.makernotes.MinAp4CurFocal = atof(sp); + if (imgdata.lens.makernotes.MaxAp4CurFocal > + imgdata.lens.makernotes.MinAp4CurFocal) + my_swap(float, imgdata.lens.makernotes.MaxAp4CurFocal, + imgdata.lens.makernotes.MinAp4CurFocal); + } + } + if (!strcmp(name, "LENSFRANGE")) + { + char *sp; + imgdata.lens.makernotes.MinFocal = imgdata.lens.makernotes.MaxFocal = + atof(value); + sp = strrchr(value, ' '); + if (sp) + { + imgdata.lens.makernotes.MaxFocal = atof(sp); + if ((imgdata.lens.makernotes.MaxFocal + 0.17f) < + imgdata.lens.makernotes.MinFocal) + my_swap(float, imgdata.lens.makernotes.MaxFocal, + imgdata.lens.makernotes.MinFocal); + } + } + if (!strcmp(name, "LENSMODEL")) + { + char *sp; + imgdata.lens.makernotes.LensID = + strtol(value, &sp, 16); // atoi(value); + if (imgdata.lens.makernotes.LensID) + imgdata.lens.makernotes.LensMount = Sigma_X3F; + } + } + imgdata.idata.raw_count = 1; + load_raw = &LibRaw::x3f_load_raw; + imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6; + imgdata.idata.is_foveon = 1; + libraw_internal_data.internal_output_params.raw_color = + 1; // Force adobe coeff + imgdata.color.maximum = 0x3fff; // To be reset by color table + libraw_internal_data.unpacker_data.order = 0x4949; + } + } + else + { + // No property list + if (imgdata.sizes.raw_width == 5888 || imgdata.sizes.raw_width == 2944 || + imgdata.sizes.raw_width == 6656 || imgdata.sizes.raw_width == 3328 || + imgdata.sizes.raw_width == 5504 || + imgdata.sizes.raw_width == 2752) // Quattro + { + imgdata.idata.raw_count = 1; + load_raw = &LibRaw::x3f_load_raw; + imgdata.sizes.raw_pitch = imgdata.sizes.raw_width * 6; + imgdata.idata.is_foveon = 1; + libraw_internal_data.internal_output_params.raw_color = + 1; // Force adobe coeff + libraw_internal_data.unpacker_data.order = 0x4949; + strcpy(imgdata.idata.make, "SIGMA"); +#if 1 + // Try to find model number in first 2048 bytes; + int pos = libraw_internal_data.internal_data.input->tell(); + libraw_internal_data.internal_data.input->seek(0, SEEK_SET); + unsigned char buf[2048]; + libraw_internal_data.internal_data.input->read(buf, 2048, 1); + libraw_internal_data.internal_data.input->seek(pos, SEEK_SET); + unsigned char *fnd = (unsigned char *)lr_memmem(buf, 2048, "SIGMA dp", 8); + unsigned char *fndsd = + (unsigned char *)lr_memmem(buf, 2048, "sd Quatt", 8); + if (fnd) + { + unsigned char *nm = fnd + 8; + snprintf(imgdata.idata.model, 64, "dp%c Quattro", + *nm <= '9' && *nm >= '0' ? *nm : '2'); + } + else if (fndsd) + { + snprintf(imgdata.idata.model, 64, "%s", fndsd); + } + else +#endif + if (imgdata.sizes.raw_width == 6656 || + imgdata.sizes.raw_width == 3328) + strcpy(imgdata.idata.model, "sd Quattro H"); + else + strcpy(imgdata.idata.model, "dp2 Quattro"); + } + // else + } + // Try to get thumbnail data + LibRaw_thumbnail_formats format = LIBRAW_THUMBNAIL_UNKNOWN; + if ((DE = x3f_get_thumb_jpeg(x3f))) + { + format = LIBRAW_THUMBNAIL_JPEG; + } + else if ((DE = x3f_get_thumb_plain(x3f))) + { + format = LIBRAW_THUMBNAIL_BITMAP; + } + if (DE) + { + x3f_directory_entry_header_t *_DEH = &DE->header; + x3f_image_data_t *_ID = &_DEH->data_subsection.image_data; + imgdata.thumbnail.twidth = _ID->columns; + imgdata.thumbnail.theight = _ID->rows; + imgdata.thumbnail.tcolors = 3; + imgdata.thumbnail.tformat = format; + libraw_internal_data.internal_data.toffset = DE->input.offset; + libraw_internal_data.unpacker_data.thumb_format = LIBRAW_INTERNAL_THUMBNAIL_X3F; + } + DE = x3f_get_camf(x3f); + if (DE && DE->input.size > 28) + { + libraw_internal_data.unpacker_data.meta_offset = DE->input.offset + 8; + libraw_internal_data.unpacker_data.meta_length = DE->input.size - 28; + } +} + +INT64 LibRaw::x3f_thumb_size() +{ + try + { + x3f_t *x3f = (x3f_t *)_x3f_data; + if (!x3f) + return -1; // No data pointer set + x3f_directory_entry_t *DE = x3f_get_thumb_jpeg(x3f); + if (!DE) + DE = x3f_get_thumb_plain(x3f); + if (!DE) + return -1; + int64_t p = x3f_load_data_size(x3f, DE); + if (p < 0 || p > 0xffffffff) + return -1; + return p; + } + catch (...) + { + return -1; + } +} + +void LibRaw::x3f_thumb_loader() +{ + try + { + x3f_t *x3f = (x3f_t *)_x3f_data; + if (!x3f) + return; // No data pointer set + x3f_directory_entry_t *DE = x3f_get_thumb_jpeg(x3f); + if (!DE) + DE = x3f_get_thumb_plain(x3f); + if (!DE) + return; + if (X3F_OK != x3f_load_data(x3f, DE)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + imgdata.thumbnail.twidth = ID->columns; + imgdata.thumbnail.theight = ID->rows; + imgdata.thumbnail.tcolors = 3; + if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG) + { + imgdata.thumbnail.thumb = (char *)malloc(ID->data_size); + memmove(imgdata.thumbnail.thumb, ID->data, ID->data_size); + imgdata.thumbnail.tlength = ID->data_size; + } + else if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_BITMAP) + { + imgdata.thumbnail.tlength = ID->columns * ID->rows * 3; + imgdata.thumbnail.thumb = (char *)malloc(ID->columns * ID->rows * 3); + char *src0 = (char *)ID->data; + for (int row = 0; row < (int)ID->rows; row++) + { + int offset = row * ID->row_stride; + if (offset + ID->columns * 3 > ID->data_size) + break; + char *dest = &imgdata.thumbnail.thumb[row * ID->columns * 3]; + char *src = &src0[offset]; + memmove(dest, src, ID->columns * 3); + } + } + } + catch (...) + { + // do nothing + } +} + +void LibRaw::x3f_dpq_interpolate_rg() +{ + int w = imgdata.sizes.raw_width / 2; + int h = imgdata.sizes.raw_height / 2; + unsigned short *image = (ushort *)imgdata.rawdata.color3_image; + + for (int color = 0; color < 2; color++) + { + for (int y = 2; y < (h - 2); y++) + { + uint16_t *row0 = + &image[imgdata.sizes.raw_width * 3 * (y * 2) + color]; // dst[1] + uint16_t *row1 = + &image[imgdata.sizes.raw_width * 3 * (y * 2 + 1) + color]; // dst1[1] + for (int x = 2; x < (w - 2); x++) + { + row1[0] = row1[3] = row0[3] = row0[0]; + row0 += 6; + row1 += 6; + } + } + } +} + +#ifdef _ABS +#undef _ABS +#endif +#define _ABS(a) ((a) < 0 ? -(a) : (a)) + +#undef CLIP +#define CLIP(value, high) ((value) > (high) ? (high) : (value)) + +void LibRaw::x3f_dpq_interpolate_af(int xstep, int ystep, int scale) +{ + unsigned short *image = (ushort *)imgdata.rawdata.color3_image; + for (int y = 0; + y < imgdata.rawdata.sizes.height + imgdata.rawdata.sizes.top_margin; + y += ystep) + { + if (y < imgdata.rawdata.sizes.top_margin) + continue; + if (y < scale) + continue; + if (y > imgdata.rawdata.sizes.raw_height - scale) + break; + uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * y]; // Ðаша Ñтрока + uint16_t *row_minus = + &image[imgdata.sizes.raw_width * 3 * (y - scale)]; // Строка выше + uint16_t *row_plus = + &image[imgdata.sizes.raw_width * 3 * (y + scale)]; // Строка ниже + for (int x = 0; + x < imgdata.rawdata.sizes.width + imgdata.rawdata.sizes.left_margin; + x += xstep) + { + if (x < imgdata.rawdata.sizes.left_margin) + continue; + if (x < scale) + continue; + if (x > imgdata.rawdata.sizes.raw_width - scale) + break; + uint16_t *pixel0 = &row0[x * 3]; + uint16_t *pixel_top = &row_minus[x * 3]; + uint16_t *pixel_bottom = &row_plus[x * 3]; + uint16_t *pixel_left = &row0[(x - scale) * 3]; + uint16_t *pixel_right = &row0[(x + scale) * 3]; + uint16_t *pixf = pixel_top; + if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_bottom[2] - pixel0[2])) + pixf = pixel_bottom; + if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_left[2] - pixel0[2])) + pixf = pixel_left; + if (_ABS(pixf[2] - pixel0[2]) > _ABS(pixel_right[2] - pixel0[2])) + pixf = pixel_right; + int blocal = pixel0[2], bnear = pixf[2]; + if (blocal < (int)imgdata.color.black + 16 || bnear < (int)imgdata.color.black + 16) + { + if (pixel0[0] < imgdata.color.black) + pixel0[0] = imgdata.color.black; + if (pixel0[1] < imgdata.color.black) + pixel0[1] = imgdata.color.black; + pixel0[0] = CLIP( + (pixel0[0] - imgdata.color.black) * 4 + imgdata.color.black, 16383); + pixel0[1] = CLIP( + (pixel0[1] - imgdata.color.black) * 4 + imgdata.color.black, 16383); + } + else + { + float multip = float(bnear - imgdata.color.black) / + float(blocal - imgdata.color.black); + if (pixel0[0] < imgdata.color.black) + pixel0[0] = imgdata.color.black; + if (pixel0[1] < imgdata.color.black) + pixel0[1] = imgdata.color.black; + float pixf0 = pixf[0]; + if (pixf0 < imgdata.color.black) + pixf0 = imgdata.color.black; + float pixf1 = pixf[1]; + if (pixf1 < imgdata.color.black) + pixf1 = imgdata.color.black; + + pixel0[0] = CLIP( + ((float(pixf0 - imgdata.color.black) * multip + + imgdata.color.black) + + ((pixel0[0] - imgdata.color.black) * 3.75 + imgdata.color.black)) / + 2, + 16383); + pixel0[1] = CLIP( + ((float(pixf1 - imgdata.color.black) * multip + + imgdata.color.black) + + ((pixel0[1] - imgdata.color.black) * 3.75 + imgdata.color.black)) / + 2, + 16383); + // pixel0[1] = float(pixf[1]-imgdata.color.black)*multip + + // imgdata.color.black; + } + } + } +} + +void LibRaw::x3f_dpq_interpolate_af_sd(int xstart, int ystart, int xend, + int yend, int xstep, int ystep, + int scale) +{ + unsigned short *image = (ushort *)imgdata.rawdata.color3_image; + for (int y = ystart; y <= yend && y < imgdata.rawdata.sizes.height + + imgdata.rawdata.sizes.top_margin; + y += ystep) + { + uint16_t *row0 = &image[imgdata.sizes.raw_width * 3 * y]; // Ðаша Ñтрока + uint16_t *row1 = + &image[imgdata.sizes.raw_width * 3 * (y + 1)]; // Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтрока + uint16_t *row_minus = + &image[imgdata.sizes.raw_width * 3 * (y - scale)]; // Строка выше + uint16_t *row_plus = + &image[imgdata.sizes.raw_width * 3 * + (y + scale)]; // Строка ниже AF-point (scale=2 -> ниже row1 + uint16_t *row_minus1 = &image[imgdata.sizes.raw_width * 3 * (y - 1)]; + for (int x = xstart; x < xend && x < imgdata.rawdata.sizes.width + + imgdata.rawdata.sizes.left_margin; + x += xstep) + { + uint16_t *pixel00 = &row0[x * 3]; // Current pixel + float sumR = 0.f, sumG = 0.f; + float cnt = 0.f; + for (int xx = -scale; xx <= scale; xx += scale) + { + sumR += row_minus[(x + xx) * 3]; + sumR += row_plus[(x + xx) * 3]; + sumG += row_minus[(x + xx) * 3 + 1]; + sumG += row_plus[(x + xx) * 3 + 1]; + cnt += 1.f; + if (xx) + { + cnt += 1.f; + sumR += row0[(x + xx) * 3]; + sumG += row0[(x + xx) * 3 + 1]; + } + } + pixel00[0] = sumR / 8.f; + pixel00[1] = sumG / 8.f; + + if (scale == 2) + { + uint16_t *pixel0B = &row0[x * 3 + 3]; // right pixel + uint16_t *pixel1B = &row1[x * 3 + 3]; // right pixel + float sumG0 = 0, sumG1 = 0.f; + float _cnt = 0.f; + for (int xx = -scale; xx <= scale; xx += scale) + { + sumG0 += row_minus1[(x + xx) * 3 + 2]; + sumG1 += row_plus[(x + xx) * 3 + 2]; + _cnt += 1.f; + if (xx) + { + sumG0 += row0[(x + xx) * 3 + 2]; + sumG1 += row1[(x + xx) * 3 + 2]; + _cnt += 1.f; + } + } + if (_cnt > 1.0) + { + pixel0B[2] = sumG0 / _cnt; + pixel1B[2] = sumG1 / _cnt; + } + } + + // uint16_t* pixel10 = &row1[x*3]; // Pixel below current + // uint16_t* pixel_bottom = &row_plus[x*3]; + } + } +} + +void LibRaw::x3f_load_raw() +{ + // already in try/catch + int raise_error = 0; + x3f_t *x3f = (x3f_t *)_x3f_data; + if (!x3f) + return; // No data pointer set + if (X3F_OK == x3f_load_data(x3f, x3f_get_raw(x3f))) + { + x3f_directory_entry_t *DE = x3f_get_raw(x3f); + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + if (!ID) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + x3f_quattro_t *Q = ID->quattro; + x3f_huffman_t *HUF = ID->huffman; + x3f_true_t *TRU = ID->tru; + uint16_t *data = NULL; + if (ID->rows != S.raw_height || ID->columns != S.raw_width) + { + raise_error = 1; + goto end; + } + if (HUF != NULL) + data = HUF->x3rgb16.data; + if (TRU != NULL) + data = TRU->x3rgb16.data; + if (data == NULL) + { + raise_error = 1; + goto end; + } + + size_t datasize = S.raw_height * S.raw_width * 3 * sizeof(unsigned short); + S.raw_pitch = S.raw_width * 3 * sizeof(unsigned short); + if (!(imgdata.rawdata.raw_alloc = malloc(datasize))) + throw LIBRAW_EXCEPTION_ALLOC; + + imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; + // swap R/B channels for known old cameras + if (!strcasecmp(P1.make, "Polaroid") && !strcasecmp(P1.model, "x530")) + { + ushort(*src)[3] = (ushort(*)[3])data; + for (int p = 0; p < S.raw_height * S.raw_width; p++) + { + imgdata.rawdata.color3_image[p][0] = src[p][2]; + imgdata.rawdata.color3_image[p][1] = src[p][1]; + imgdata.rawdata.color3_image[p][2] = src[p][0]; + } + } + else if (HUF) + memmove(imgdata.rawdata.raw_alloc, data, datasize); + else if (TRU && (!Q || !Q->quattro_layout)) + memmove(imgdata.rawdata.raw_alloc, data, datasize); + else if (TRU && Q) + { + // Move quattro data in place + // R/B plane + for (int prow = 0; prow < (int)TRU->x3rgb16.rows && prow < S.raw_height / 2; + prow++) + { + ushort(*destrow)[3] = + (unsigned short(*)[3]) & + imgdata.rawdata + .color3_image[prow * 2 * S.raw_pitch / 3 / sizeof(ushort)][0]; + ushort(*srcrow)[3] = + (unsigned short(*)[3]) & data[prow * TRU->x3rgb16.row_stride]; + for (int pcol = 0; + pcol < (int)TRU->x3rgb16.columns && pcol < S.raw_width / 2; pcol++) + { + destrow[pcol * 2][0] = srcrow[pcol][0]; + destrow[pcol * 2][1] = srcrow[pcol][1]; + } + } + for (int row = 0; row < (int)Q->top16.rows && row < S.raw_height; row++) + { + ushort(*destrow)[3] = + (unsigned short(*)[3]) & + imgdata.rawdata + .color3_image[row * S.raw_pitch / 3 / sizeof(ushort)][0]; + ushort *srcrow = + (unsigned short *)&Q->top16.data[row * Q->top16.columns]; + for (int col = 0; col < (int)Q->top16.columns && col < S.raw_width; col++) + destrow[col][2] = srcrow[col]; + } + } + +#if 1 + if (TRU && Q && + !(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATEAF)) + { + if (imgdata.sizes.raw_width == 5888 && + imgdata.sizes.raw_height == 3672) // dpN Quattro normal + { + x3f_dpq_interpolate_af(32, 8, 2); + } + else if (imgdata.sizes.raw_width == 5888 && + imgdata.sizes.raw_height == 3776) // sd Quattro normal raw + { + x3f_dpq_interpolate_af_sd(216, 464, imgdata.sizes.raw_width - 1, 3312, + 16, 32, 2); + } + else if (imgdata.sizes.raw_width == 6656 && + imgdata.sizes.raw_height == 4480) // sd Quattro H normal raw + { + x3f_dpq_interpolate_af_sd(232, 592, imgdata.sizes.raw_width - 1, 3920, + 16, 32, 2); + } + else if (imgdata.sizes.raw_width == 3328 && + imgdata.sizes.raw_height == 2240) // sd Quattro H half size + { + x3f_dpq_interpolate_af_sd(116, 296, imgdata.sizes.raw_width - 1, 2200, + 8, 16, 1); + } + else if (imgdata.sizes.raw_width == 5504 && + imgdata.sizes.raw_height == 3680) // sd Quattro H APS-C raw + { + x3f_dpq_interpolate_af_sd(8, 192, imgdata.sizes.raw_width - 1, 3185, 16, + 32, 2); + } + else if (imgdata.sizes.raw_width == 2752 && + imgdata.sizes.raw_height == 1840) // sd Quattro H APS-C half size + { + x3f_dpq_interpolate_af_sd(4, 96, imgdata.sizes.raw_width - 1, 1800, 8, + 16, 1); + } + else if (imgdata.sizes.raw_width == 2944 && + imgdata.sizes.raw_height == 1836) // dpN Quattro small raw + { + x3f_dpq_interpolate_af(16, 4, 1); + } + else if (imgdata.sizes.raw_width == 2944 && + imgdata.sizes.raw_height == 1888) // sd Quattro small + { + x3f_dpq_interpolate_af_sd(108, 232, imgdata.sizes.raw_width - 1, 1656, + 8, 16, 1); + } + } +#endif + if (TRU && Q && Q->quattro_layout && + !(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_NODP2Q_INTERPOLATERG)) + x3f_dpq_interpolate_rg(); + } + else + raise_error = 1; +end: + if (raise_error) + throw LIBRAW_EXCEPTION_IO_CORRUPT; +} +#endif diff --git a/src/x3f/x3f_utils_patched.cpp b/src/x3f/x3f_utils_patched.cpp new file mode 100644 index 000000000..6b20b9074 --- /dev/null +++ b/src/x3f/x3f_utils_patched.cpp @@ -0,0 +1,2119 @@ +#ifdef USE_X3FTOOLS + +/* Library for accessing X3F Files +---------------------------------------------------------------- +BSD-style License +---------------------------------------------------------------- + +* Copyright (c) 2010, Roland Karlsson (roland@proxel.se) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the organization 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 ROLAND KARLSSON ''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 ROLAND KARLSSON 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. + +*/ + +#include "../../internal/libraw_cxx_defs.h" + +#if defined __sun && defined DS +#undef DS +#endif +#ifdef ID +#undef ID /* used in x3f utils */ +#endif + +#include "../../internal/x3f_tools.h" + +/* extern */ int legacy_offset = 0; +/* extern */ bool_t auto_legacy_offset = 1; + +/* --------------------------------------------------------------------- */ +/* Reading and writing - assuming little endian in the file */ +/* --------------------------------------------------------------------- */ + +static int x3f_get1(LibRaw_abstract_datastream *f) +{ + /* Little endian file */ + return f->get_char(); +} + +static int x3f_sget2(uchar *s) { return s[0] | s[1] << 8; } + +static int x3f_get2(LibRaw_abstract_datastream *f) +{ + uchar str[2] = {0xff, 0xff}; + f->read(str, 1, 2); + return x3f_sget2(str); +} + +unsigned x3f_sget4(uchar *s) +{ + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; +} + +unsigned x3f_get4(LibRaw_abstract_datastream *f) +{ + uchar str[4] = {0xff, 0xff, 0xff, 0xff}; + f->read(str, 1, 4); + return x3f_sget4(str); +} + +#define FREE(P) \ + do \ + { \ + free(P); \ + (P) = NULL; \ + } while (0) + +#define PUT_GET_N(_buffer, _size, _file, _func) \ + do \ + { \ + int _left = _size; \ + while (_left != 0) \ + { \ + int _cur = _file->_func(_buffer, 1, _left); \ + if (_cur == 0) \ + { \ + throw LIBRAW_EXCEPTION_IO_CORRUPT; \ + } \ + _left -= _cur; \ + } \ + } while (0) + +#define GET1(_v) \ + do \ + { \ + (_v) = x3f_get1(I->input.file); \ + } while (0) +#define GET2(_v) \ + do \ + { \ + (_v) = x3f_get2(I->input.file); \ + } while (0) +#define GET4(_v) \ + do \ + { \ + (_v) = x3f_get4(I->input.file); \ + } while (0) + +#define GET4F(_v) \ + do \ + { \ + union { \ + int32_t i; \ + float f; \ + } _tmp; \ + _tmp.i = x3f_get4(I->input.file); \ + (_v) = _tmp.f; \ + } while (0) + +#define GETN(_v, _s) PUT_GET_N(_v, _s, I->input.file, read) + +#define GET_TABLE(_T, _GETX, _NUM, _TYPE) \ + do \ + { \ + int _i; \ + (_T).size = (_NUM); \ + (_T).element = \ + (_TYPE *)realloc((_T).element, (_NUM) * sizeof((_T).element[0])); \ + for (_i = 0; _i < (int)(_T).size; _i++) \ + _GETX((_T).element[_i]); \ + } while (0) + +#define GET_PROPERTY_TABLE(_T, _NUM) \ + do \ + { \ + int _i; \ + (_T).size = (_NUM); \ + (_T).element = (x3f_property_t *)realloc( \ + (_T).element, (_NUM) * sizeof((_T).element[0])); \ + for (_i = 0; _i < (int)(_T).size; _i++) \ + { \ + GET4((_T).element[_i].name_offset); \ + GET4((_T).element[_i].value_offset); \ + } \ + } while (0) + +#define GET_TRUE_HUFF_TABLE(_T) \ + do \ + { \ + int _i; \ + (_T).element = NULL; \ + for (_i = 0;; _i++) \ + { \ + (_T).size = _i + 1; \ + (_T).element = (x3f_true_huffman_element_t *)realloc( \ + (_T).element, (_i + 1) * sizeof((_T).element[0])); \ + GET1((_T).element[_i].code_size); \ + GET1((_T).element[_i].code); \ + if ((_T).element[_i].code_size == 0) \ + break; \ + } \ + } while (0) + +/* --------------------------------------------------------------------- */ +/* Allocating Huffman tree help data */ +/* --------------------------------------------------------------------- */ + +static void cleanup_huffman_tree(x3f_hufftree_t *HTP) { free(HTP->nodes); } + +static void new_huffman_tree(x3f_hufftree_t *HTP, int bits) +{ + int leaves = 1 << bits; + + HTP->free_node_index = 0; + HTP->total_node_index = HUF_TREE_MAX_NODES(leaves); + HTP->nodes = (x3f_huffnode_t *)calloc(1, HUF_TREE_MAX_NODES(leaves) * + sizeof(x3f_huffnode_t)); +} + +/* --------------------------------------------------------------------- */ +/* Allocating TRUE engine RAW help data */ +/* --------------------------------------------------------------------- */ + +static void cleanup_true(x3f_true_t **TRUP) +{ + x3f_true_t *TRU = *TRUP; + + if (TRU == NULL) + return; + + FREE(TRU->table.element); + FREE(TRU->plane_size.element); + cleanup_huffman_tree(&TRU->tree); + FREE(TRU->x3rgb16.buf); + + FREE(TRU); + + *TRUP = NULL; +} + +static x3f_true_t *new_true(x3f_true_t **TRUP) +{ + x3f_true_t *TRU = (x3f_true_t *)calloc(1, sizeof(x3f_true_t)); + + cleanup_true(TRUP); + + TRU->table.size = 0; + TRU->table.element = NULL; + TRU->plane_size.size = 0; + TRU->plane_size.element = NULL; + TRU->tree.nodes = NULL; + TRU->x3rgb16.data = NULL; + TRU->x3rgb16.buf = NULL; + + *TRUP = TRU; + + return TRU; +} + +static void cleanup_quattro(x3f_quattro_t **QP) +{ + x3f_quattro_t *Q = *QP; + + if (Q == NULL) + return; + + FREE(Q->top16.buf); + FREE(Q); + + *QP = NULL; +} + +static x3f_quattro_t *new_quattro(x3f_quattro_t **QP) +{ + x3f_quattro_t *Q = (x3f_quattro_t *)calloc(1, sizeof(x3f_quattro_t)); + int i; + + cleanup_quattro(QP); + + for (i = 0; i < TRUE_PLANES; i++) + { + Q->plane[i].columns = 0; + Q->plane[i].rows = 0; + } + + Q->unknown = 0; + + Q->top16.data = NULL; + Q->top16.buf = NULL; + + *QP = Q; + + return Q; +} + +/* --------------------------------------------------------------------- */ +/* Allocating Huffman engine help data */ +/* --------------------------------------------------------------------- */ + +static void cleanup_huffman(x3f_huffman_t **HUFP) +{ + x3f_huffman_t *HUF = *HUFP; + + if (HUF == NULL) + return; + + FREE(HUF->mapping.element); + FREE(HUF->table.element); + cleanup_huffman_tree(&HUF->tree); + FREE(HUF->row_offsets.element); + FREE(HUF->rgb8.buf); + FREE(HUF->x3rgb16.buf); + FREE(HUF); + + *HUFP = NULL; +} + +static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP) +{ + x3f_huffman_t *HUF = (x3f_huffman_t *)calloc(1, sizeof(x3f_huffman_t)); + + cleanup_huffman(HUFP); + + /* Set all not read data block pointers to NULL */ + HUF->mapping.size = 0; + HUF->mapping.element = NULL; + HUF->table.size = 0; + HUF->table.element = NULL; + HUF->tree.nodes = NULL; + HUF->row_offsets.size = 0; + HUF->row_offsets.element = NULL; + HUF->rgb8.data = NULL; + HUF->rgb8.buf = NULL; + HUF->x3rgb16.data = NULL; + HUF->x3rgb16.buf = NULL; + + *HUFP = HUF; + + return HUF; +} + +/* --------------------------------------------------------------------- */ +/* Creating a new x3f structure from file */ +/* --------------------------------------------------------------------- */ + +/* extern */ x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile) +{ + if (!infile) + return NULL; + INT64 fsize = infile->size(); + x3f_t *x3f = (x3f_t *)calloc(1, sizeof(x3f_t)); + if (!x3f) + throw LIBRAW_EXCEPTION_ALLOC; + try + { + x3f_info_t *I = NULL; + x3f_header_t *H = NULL; + x3f_directory_section_t *DS = NULL; + int i, d; + + I = &x3f->info; + I->error = NULL; + I->input.file = infile; + I->output.file = NULL; + + /* Read file header */ + H = &x3f->header; + infile->seek(0, SEEK_SET); + GET4(H->identifier); + + if (H->identifier != X3F_FOVb) + { + free(x3f); + return NULL; + } + + GET4(H->version); + GETN(H->unique_identifier, SIZE_UNIQUE_IDENTIFIER); + /* TODO: the meaning of the rest of the header for version >= 4.0 (Quattro) + * is unknown */ + if (H->version < X3F_VERSION_4_0) + { + GET4(H->mark_bits); + GET4(H->columns); + GET4(H->rows); + GET4(H->rotation); + if (H->version >= X3F_VERSION_2_1) + { + int num_ext_data = + H->version >= X3F_VERSION_3_0 ? NUM_EXT_DATA_3_0 : NUM_EXT_DATA_2_1; + + GETN(H->white_balance, SIZE_WHITE_BALANCE); + if (H->version >= X3F_VERSION_2_3) + GETN(H->color_mode, SIZE_COLOR_MODE); + GETN(H->extended_types, num_ext_data); + for (i = 0; i < num_ext_data; i++) + GET4F(H->extended_data[i]); + } + } + + /* Go to the beginning of the directory */ + infile->seek(-4, SEEK_END); + infile->seek(x3f_get4(infile), SEEK_SET); + + /* Read the directory header */ + DS = &x3f->directory_section; + GET4(DS->identifier); + GET4(DS->version); + GET4(DS->num_directory_entries); + + if (DS->num_directory_entries > 50) + goto _err; // too much direntries, most likely broken file + + if (DS->num_directory_entries > 0) + { + size_t size = DS->num_directory_entries * sizeof(x3f_directory_entry_t); + DS->directory_entry = (x3f_directory_entry_t *)calloc(1, size); + } + + /* Traverse the directory */ + for (d = 0; d < (int)DS->num_directory_entries; d++) + { + x3f_directory_entry_t *DE = &DS->directory_entry[d]; + x3f_directory_entry_header_t *DEH = &DE->header; + uint32_t save_dir_pos; + + /* Read the directory entry info */ + GET4(DE->input.offset); + GET4(DE->input.size); + if (DE->input.offset + DE->input.size > fsize * 2) + goto _err; + + DE->output.offset = 0; + DE->output.size = 0; + + GET4(DE->type); + + /* Save current pos and go to the entry */ + save_dir_pos = infile->tell(); + infile->seek(DE->input.offset, SEEK_SET); + + /* Read the type independent part of the entry header */ + DEH = &DE->header; + GET4(DEH->identifier); + GET4(DEH->version); + + /* NOTE - the tests below could be made on DE->type instead */ + + if (DEH->identifier == X3F_SECp) + { + x3f_property_list_t *PL = &DEH->data_subsection.property_list; + if (!PL) + goto _err; + /* Read the property part of the header */ + GET4(PL->num_properties); + GET4(PL->character_format); + GET4(PL->reserved); + GET4(PL->total_length); + + /* Set all not read data block pointers to NULL */ + PL->data = NULL; + PL->data_size = 0; + } + + if (DEH->identifier == X3F_SECi) + { + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + if (!ID) + goto _err; + /* Read the image part of the header */ + GET4(ID->type); + GET4(ID->format); + ID->type_format = (ID->type << 16) + (ID->format); + GET4(ID->columns); + GET4(ID->rows); + GET4(ID->row_stride); + + /* Set all not read data block pointers to NULL */ + ID->huffman = NULL; + + ID->data = NULL; + ID->data_size = 0; + } + + if (DEH->identifier == X3F_SECc) + { + x3f_camf_t *CAMF = &DEH->data_subsection.camf; + if (!CAMF) + goto _err; + /* Read the CAMF part of the header */ + GET4(CAMF->type); + GET4(CAMF->tN.val0); + GET4(CAMF->tN.val1); + GET4(CAMF->tN.val2); + GET4(CAMF->tN.val3); + + /* Set all not read data block pointers to NULL */ + CAMF->data = NULL; + CAMF->data_size = 0; + + /* Set all not allocated help pointers to NULL */ + CAMF->table.element = NULL; + CAMF->table.size = 0; + CAMF->tree.nodes = NULL; + CAMF->decoded_data = NULL; + CAMF->decoded_data_size = 0; + CAMF->entry_table.element = NULL; + CAMF->entry_table.size = 0; + } + + /* Reset the file pointer back to the directory */ + infile->seek(save_dir_pos, SEEK_SET); + } + + return x3f; + _err: + if (x3f) + { + DS = &x3f->directory_section; + if (DS && DS->directory_entry) + free(DS->directory_entry); + free(x3f); + } + return NULL; + } + catch (...) + { + x3f_directory_section_t *DS = &x3f->directory_section; + if (DS && DS->directory_entry) + free(DS->directory_entry); + free(x3f); + return NULL; + } +} + +/* --------------------------------------------------------------------- */ +/* Clean up an x3f structure */ +/* --------------------------------------------------------------------- */ + +static void free_camf_entry(camf_entry_t *entry) +{ + FREE(entry->property_name); + FREE(entry->property_value); + FREE(entry->matrix_decoded); + FREE(entry->matrix_dim_entry); +} + +/* extern */ x3f_return_t x3f_delete(x3f_t *x3f) +{ + x3f_directory_section_t *DS; + int d; + + if (x3f == NULL) + return X3F_ARGUMENT_ERROR; + + DS = &x3f->directory_section; + if (DS->num_directory_entries > 50) + return X3F_ARGUMENT_ERROR; + + for (d = 0; d < (int)DS->num_directory_entries; d++) + { + x3f_directory_entry_t *DE = &DS->directory_entry[d]; + x3f_directory_entry_header_t *DEH = &DE->header; + if (DEH->identifier == X3F_SECp) + { + x3f_property_list_t *PL = &DEH->data_subsection.property_list; + FREE(PL->property_table.element); + FREE(PL->data); + } + + if (DEH->identifier == X3F_SECi) + { + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + if (ID) + { + cleanup_huffman(&ID->huffman); + cleanup_true(&ID->tru); + cleanup_quattro(&ID->quattro); + FREE(ID->data); + } + } + + if (DEH->identifier == X3F_SECc) + { + x3f_camf_t *CAMF = &DEH->data_subsection.camf; + int i; + if (CAMF) + { + FREE(CAMF->data); + FREE(CAMF->table.element); + cleanup_huffman_tree(&CAMF->tree); + FREE(CAMF->decoded_data); + for (i = 0; i < (int)CAMF->entry_table.size; i++) + { + free_camf_entry(&CAMF->entry_table.element[i]); + } + } + FREE(CAMF->entry_table.element); + } + } + + FREE(DS->directory_entry); + FREE(x3f); + + return X3F_OK; +} + +/* --------------------------------------------------------------------- */ +/* Getting a reference to a directory entry */ +/* --------------------------------------------------------------------- */ + +/* TODO: all those only get the first instance */ + +static x3f_directory_entry_t *x3f_get(x3f_t *x3f, uint32_t type, + uint32_t image_type) +{ + x3f_directory_section_t *DS; + int d; + + if (x3f == NULL) + return NULL; + + DS = &x3f->directory_section; + + for (d = 0; d < (int)DS->num_directory_entries; d++) + { + x3f_directory_entry_t *DE = &DS->directory_entry[d]; + x3f_directory_entry_header_t *DEH = &DE->header; + + if (DEH->identifier == type) + { + switch (DEH->identifier) + { + case X3F_SECi: + { + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + if (ID->type_format == image_type) + return DE; + } + break; + default: + return DE; + } + } + } + + return NULL; +} + +/* extern */ x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f) +{ + x3f_directory_entry_t *DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_X530)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_HUFFMAN_10BIT)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_TRUE)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_MERRILL)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_QUATTRO)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQ)) != NULL) + return DE; + + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQH)) != NULL) + return DE; + if ((DE = x3f_get(x3f, X3F_SECi, X3F_IMAGE_RAW_SDQH2)) != NULL) + return DE; + + return NULL; +} + +/* extern */ x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f) +{ + return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_PLAIN); +} + +/* extern */ x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f) +{ + return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_HUFFMAN); +} + +/* extern */ x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f) +{ + return x3f_get(x3f, X3F_SECi, X3F_IMAGE_THUMB_JPEG); +} + +/* extern */ x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f) +{ + return x3f_get(x3f, X3F_SECc, 0); +} + +/* extern */ x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f) +{ + return x3f_get(x3f, X3F_SECp, 0); +} + +/* For some obscure reason, the bit numbering is weird. It is + generally some kind of "big endian" style - e.g. the bit 7 is the + first in a byte and bit 31 first in a 4 byte int. For patterns in + the huffman pattern table, bit 27 is the first bit and bit 26 the + next one. */ + +#define PATTERN_BIT_POS(_len, _bit) ((_len) - (_bit)-1) +#define MEMORY_BIT_POS(_bit) PATTERN_BIT_POS(8, _bit) + +/* --------------------------------------------------------------------- */ +/* Huffman Decode */ +/* --------------------------------------------------------------------- */ + +/* Make the huffman tree */ + +#ifdef DBG_PRNT +static char *display_code(int length, uint32_t code, char *buffer) +{ + int i; + + for (i = 0; i < length; i++) + { + int pos = PATTERN_BIT_POS(length, i); + buffer[i] = ((code >> pos) & 1) == 0 ? '0' : '1'; + } + + buffer[i] = 0; + + return buffer; +} +#endif + +static x3f_huffnode_t *new_node(x3f_hufftree_t *tree) +{ + if (tree->free_node_index >= tree->total_node_index) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + x3f_huffnode_t *t = &tree->nodes[tree->free_node_index]; + + t->branch[0] = NULL; + t->branch[1] = NULL; + t->leaf = UNDEFINED_LEAF; + + tree->free_node_index++; + + return t; +} + +static void add_code_to_tree(x3f_hufftree_t *tree, int length, uint32_t code, + uint32_t value) +{ + int i; + + x3f_huffnode_t *t = tree->nodes; + + for (i = 0; i < length; i++) + { + int pos = PATTERN_BIT_POS(length, i); + int bit = (code >> pos) & 1; + x3f_huffnode_t *t_next = t->branch[bit]; + + if (t_next == NULL) + t_next = t->branch[bit] = new_node(tree); + + t = t_next; + } + + t->leaf = value; +} + +static void populate_true_huffman_tree(x3f_hufftree_t *tree, + x3f_true_huffman_t *table) +{ + int i; + + new_node(tree); + + for (i = 0; i < (int)table->size; i++) + { + x3f_true_huffman_element_t *element = &table->element[i]; + uint32_t length = element->code_size; + + if (length != 0) + { + /* add_code_to_tree wants the code right adjusted */ + uint32_t code = ((element->code) >> (8 - length)) & 0xff; + uint32_t value = i; + + add_code_to_tree(tree, length, code, value); + +#ifdef DBG_PRNT + { + char buffer[100]; + + x3f_printf(DEBUG, "H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n", i, i, + value, length, code, value, + display_code(length, code, buffer)); + } +#endif + } + } +} + +static void populate_huffman_tree(x3f_hufftree_t *tree, x3f_table32_t *table, + x3f_table16_t *mapping) +{ + int i; + + new_node(tree); + + for (i = 0; i < (int)table->size; i++) + { + uint32_t element = table->element[i]; + + if (element != 0) + { + uint32_t length = HUF_TREE_GET_LENGTH(element); + uint32_t code = HUF_TREE_GET_CODE(element); + uint32_t value; + + /* If we have a valid mapping table - then the value from the + mapping table shall be used. Otherwise we use the current + index in the table as value. */ + if (table->size == mapping->size) + value = mapping->element[i]; + else + value = i; + + add_code_to_tree(tree, length, code, value); + +#ifdef DBG_PRNT + { + char buffer[100]; + + x3f_printf(DEBUG, "H %5d : %5x : %5d : %02x %08x (%08x) (%s)\n", i, i, + value, length, code, element, + display_code(length, code, buffer)); + } +#endif + } + } +} + +#ifdef DBG_PRNT +static void print_huffman_tree(x3f_huffnode_t *t, int length, uint32_t code) +{ + char buf1[100]; + char buf2[100]; + + x3f_printf(DEBUG, "%*s (%s,%s) %s (%s)\n", length, + length < 1 ? "-" : (code & 1) ? "1" : "0", + t->branch[0] == NULL ? "-" : "0", t->branch[1] == NULL ? "-" : "1", + t->leaf == UNDEFINED_LEAF ? "-" + : (sprintf(buf1, "%x", t->leaf), buf1), + display_code(length, code, buf2)); + + code = code << 1; + if (t->branch[0]) + print_huffman_tree(t->branch[0], length + 1, code + 0); + if (t->branch[1]) + print_huffman_tree(t->branch[1], length + 1, code + 1); +} +#endif + +/* Help machinery for reading bits in a memory */ + +typedef struct bit_state_s +{ + uint8_t *next_address; + uint8_t bit_offset; + uint8_t bits[8]; +} bit_state_t; + +static void set_bit_state(bit_state_t *BS, uint8_t *address) +{ + BS->next_address = address; + BS->bit_offset = 8; +} + +static uint8_t get_bit(bit_state_t *BS) +{ + if (BS->bit_offset == 8) + { + uint8_t byte = *BS->next_address; + int i; + + for (i = 7; i >= 0; i--) + { + BS->bits[i] = byte & 1; + byte = byte >> 1; + } + BS->next_address++; + BS->bit_offset = 0; + } + + return BS->bits[BS->bit_offset++]; +} + +/* Decode use the TRUE algorithm */ + +static int32_t get_true_diff(bit_state_t *BS, x3f_hufftree_t *HTP) +{ + int32_t diff; + x3f_huffnode_t *node = &HTP->nodes[0]; + uint8_t bits; + + while (node->branch[0] != NULL || node->branch[1] != NULL) + { + uint8_t bit = get_bit(BS); + x3f_huffnode_t *new_node = node->branch[bit]; + + node = new_node; + if (node == NULL) + { + /* TODO: Shouldn't this be treated as a fatal error? */ + return 0; + } + } + + bits = node->leaf; + + if (bits == 0) + diff = 0; + else + { + uint8_t first_bit = get_bit(BS); + int i; + + diff = first_bit; + + for (i = 1; i < bits; i++) + diff = (diff << 1) + get_bit(BS); + + if (first_bit == 0) + diff -= (1 << bits) - 1; + } + + return diff; +} + +/* This code (that decodes one of the X3F color planes, really is a + decoding of a compression algorithm suited for Bayer CFA data. In + Bayer CFA the data is divided into 2x2 squares that represents + (R,G1,G2,B) data. Those four positions are (in this compression) + treated as one data stream each, where you store the differences to + previous data in the stream. The reason for this is, of course, + that the date is more often than not near to the next data in a + stream that represents the same color. */ + +/* TODO: write more about the compression */ + +static void true_decode_one_color(x3f_image_data_t *ID, int color) +{ + x3f_true_t *TRU = ID->tru; + x3f_quattro_t *Q = ID->quattro; + uint32_t seed = TRU->seed[color]; /* TODO : Is this correct ? */ + int row; + + x3f_hufftree_t *tree = &TRU->tree; + bit_state_t BS; + + int32_t row_start_acc[2][2]; + uint32_t rows = ID->rows; + uint32_t cols = ID->columns; + x3f_area16_t *area = &TRU->x3rgb16; + uint16_t *dst = area->data + color; + + set_bit_state(&BS, TRU->plane_address[color]); + + row_start_acc[0][0] = seed; + row_start_acc[0][1] = seed; + row_start_acc[1][0] = seed; + row_start_acc[1][1] = seed; + + if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || + ID->type_format == X3F_IMAGE_RAW_SDQ || + ID->type_format == X3F_IMAGE_RAW_SDQH || + ID->type_format == X3F_IMAGE_RAW_SDQH2) + { + rows = Q->plane[color].rows; + cols = Q->plane[color].columns; + + if (Q->quattro_layout && color == 2) + { + area = &Q->top16; + dst = area->data; + } + } + else + { + } + + if (rows != area->rows || cols < area->columns) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + for (row = 0; row < (int)rows; row++) + { + int col; + bool_t odd_row = row & 1; + int32_t acc[2]; + + for (col = 0; col < (int)cols; col++) + { + bool_t odd_col = col & 1; + int32_t diff = get_true_diff(&BS, tree); + int32_t prev = col < 2 ? row_start_acc[odd_row][odd_col] : acc[odd_col]; + int32_t value = prev + diff; + + acc[odd_col] = value; + if (col < 2) + row_start_acc[odd_row][odd_col] = value; + + /* Discard additional data at the right for binned Quattro plane 2 */ + if (col >= (int)area->columns) + continue; + + *dst = value; + dst += area->channels; + } + } +} + +static void true_decode(x3f_info_t * /*I*/, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + int color; + + for (color = 0; color < 3; color++) + { + true_decode_one_color(ID, color); + } +} + +/* Decode use the huffman tree */ + +static int32_t get_huffman_diff(bit_state_t *BS, x3f_hufftree_t *HTP) +{ + int32_t diff; + x3f_huffnode_t *node = &HTP->nodes[0]; + + while (node->branch[0] != NULL || node->branch[1] != NULL) + { + uint8_t bit = get_bit(BS); + x3f_huffnode_t *new_node = node->branch[bit]; + + node = new_node; + if (node == NULL) + { + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + return 0; /* unreachable code */ + } + } + + diff = node->leaf; + + return diff; +} + +static void huffman_decode_row(x3f_info_t * /*I*/, x3f_directory_entry_t *DE, + int /*bits*/, int row, int offset, int *minimum) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_huffman_t *HUF = ID->huffman; + + int16_t c[3] = {(int16_t)offset, (int16_t)offset, (int16_t)offset}; + int col; + bit_state_t BS; + + if (HUF->row_offsets.element[row] > ID->data_size - 1) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + set_bit_state(&BS, (uint8_t *)ID->data + HUF->row_offsets.element[row]); + + for (col = 0; col < (int)ID->columns; col++) + { + int color; + + for (color = 0; color < 3; color++) + { + uint16_t c_fix; + + c[color] += get_huffman_diff(&BS, &HUF->tree); + if (c[color] < 0) + { + c_fix = 0; + if (c[color] < *minimum) + *minimum = c[color]; + } + else + { + c_fix = c[color]; + } + + switch (ID->type_format) + { + case X3F_IMAGE_RAW_HUFFMAN_X530: + case X3F_IMAGE_RAW_HUFFMAN_10BIT: + HUF->x3rgb16.data[3 * (row * ID->columns + col) + color] = + (uint16_t)c_fix; + break; + case X3F_IMAGE_THUMB_HUFFMAN: + HUF->rgb8.data[3 * (row * ID->columns + col) + color] = (uint8_t)c_fix; + break; + default: + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + } +} + +static void huffman_decode(x3f_info_t *I, x3f_directory_entry_t *DE, int bits) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + int row; + int minimum = 0; + int offset = legacy_offset; + + for (row = 0; row < (int)ID->rows; row++) + huffman_decode_row(I, DE, bits, row, offset, &minimum); + + if (auto_legacy_offset && minimum < 0) + { + offset = -minimum; + for (row = 0; row < (int)ID->rows; row++) + huffman_decode_row(I, DE, bits, row, offset, &minimum); + } +} + +static int32_t get_simple_diff(x3f_huffman_t *HUF, uint16_t index) +{ + if (HUF->mapping.size == 0) + return index; + else + return HUF->mapping.element[index]; +} + +static void simple_decode_row(x3f_info_t * /*I*/, x3f_directory_entry_t *DE, + int bits, int row, int row_stride) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_huffman_t *HUF = ID->huffman; + + if (row*row_stride > (int)(ID->data_size - (ID->columns*sizeof(uint32_t)))) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + uint32_t *data = (uint32_t *)((unsigned char *)ID->data + row * row_stride); + + uint16_t c[3] = {0, 0, 0}; + int col; + + uint32_t mask = 0; + + switch (bits) + { + case 8: + mask = 0x0ff; + break; + case 9: + mask = 0x1ff; + break; + case 10: + mask = 0x3ff; + break; + case 11: + mask = 0x7ff; + break; + case 12: + mask = 0xfff; + break; + default: + mask = 0; + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + break; + } + + for (col = 0; col < (int)ID->columns; col++) + { + int color; + uint32_t val = data[col]; + + for (color = 0; color < 3; color++) + { + uint16_t c_fix; + c[color] += get_simple_diff(HUF, (val >> (color * bits)) & mask); + + switch (ID->type_format) + { + case X3F_IMAGE_RAW_HUFFMAN_X530: + case X3F_IMAGE_RAW_HUFFMAN_10BIT: + c_fix = (int16_t)c[color] > 0 ? c[color] : 0; + + HUF->x3rgb16.data[3 * (row * ID->columns + col) + color] = c_fix; + break; + case X3F_IMAGE_THUMB_HUFFMAN: + c_fix = (int8_t)c[color] > 0 ? c[color] : 0; + + HUF->rgb8.data[3 * (row * ID->columns + col) + color] = c_fix; + break; + default: + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + } +} + +static void simple_decode(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, + int row_stride) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + int row; + + for (row = 0; row < (int)ID->rows; row++) + simple_decode_row(I, DE, bits, row, row_stride); +} + +/* --------------------------------------------------------------------- */ +/* Loading the data in a directory entry */ +/* --------------------------------------------------------------------- */ + +/* First you set the offset to where to start reading the data ... */ + +static void read_data_set_offset(x3f_info_t *I, x3f_directory_entry_t *DE, + uint32_t header_size) +{ + uint32_t i_off = DE->input.offset + header_size; + + I->input.file->seek(i_off, SEEK_SET); +} + +/* ... then you read the data, block for block */ + +static uint32_t read_data_block(void **data, x3f_info_t *I, + x3f_directory_entry_t *DE, uint32_t footer) +{ + INT64 fpos = I->input.file->tell(); + uint32_t size = DE->input.size + DE->input.offset - fpos - footer; + + if (fpos + size > I->input.file->size()) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + *data = (void *)malloc(size); + + GETN(*data, size); + + return size; +} + +static uint32_t data_block_size(void ** /*data*/, x3f_info_t *I, + x3f_directory_entry_t *DE, uint32_t footer) +{ + uint32_t size = + DE->input.size + DE->input.offset - I->input.file->tell() - footer; + return size; +} + +static void x3f_load_image_verbatim(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + if (!ID->data_size) + ID->data_size = read_data_block(&ID->data, I, DE, 0); +} + +static int32_t x3f_load_image_verbatim_size(x3f_info_t *I, + x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + return data_block_size(&ID->data, I, DE, 0); +} + +static void x3f_load_property_list(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_property_list_t *PL = &DEH->data_subsection.property_list; + int i; + + read_data_set_offset(I, DE, X3F_PROPERTY_LIST_HEADER_SIZE); + + GET_PROPERTY_TABLE(PL->property_table, PL->num_properties); + + if (!PL->data_size) + PL->data_size = read_data_block(&PL->data, I, DE, 0); + uint32_t maxoffset = PL->data_size / sizeof(utf16_t) - + 2; // at least 2 chars, value + terminating 0x0000 + + for (i = 0; i < (int)PL->num_properties; i++) + { + x3f_property_t *P = &PL->property_table.element[i]; + if (P->name_offset > maxoffset || P->value_offset > maxoffset) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + P->name = ((utf16_t *)PL->data + P->name_offset); + P->value = ((utf16_t *)PL->data + P->value_offset); + } +} + +static void x3f_load_true(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_true_t *TRU = new_true(&ID->tru); + x3f_quattro_t *Q = NULL; + int i; + + if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || + ID->type_format == X3F_IMAGE_RAW_SDQ || + ID->type_format == X3F_IMAGE_RAW_SDQH || + ID->type_format == X3F_IMAGE_RAW_SDQH2) + { + Q = new_quattro(&ID->quattro); + + for (i = 0; i < TRUE_PLANES; i++) + { + GET2(Q->plane[i].columns); + GET2(Q->plane[i].rows); + } + + if (Q->plane[0].rows == ID->rows / 2) + { + Q->quattro_layout = 1; + } + else if (Q->plane[0].rows == ID->rows) + { + Q->quattro_layout = 0; + } + else + { + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + } + + /* Read TRUE header data */ + GET2(TRU->seed[0]); + GET2(TRU->seed[1]); + GET2(TRU->seed[2]); + GET2(TRU->unknown); + GET_TRUE_HUFF_TABLE(TRU->table); + + if (ID->type_format == X3F_IMAGE_RAW_QUATTRO || + ID->type_format == X3F_IMAGE_RAW_SDQ || + ID->type_format == X3F_IMAGE_RAW_SDQH || + ID->type_format == X3F_IMAGE_RAW_SDQH2) + { + GET4(Q->unknown); + } + + GET_TABLE(TRU->plane_size, GET4, TRUE_PLANES, uint32_t); + + /* Read image data */ + if (!ID->data_size) + ID->data_size = read_data_block(&ID->data, I, DE, 0); + + /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ + new_huffman_tree(&TRU->tree, 8); + + populate_true_huffman_tree(&TRU->tree, &TRU->table); + +#ifdef DBG_PRNT + print_huffman_tree(TRU->tree.nodes, 0, 0); +#endif + + TRU->plane_address[0] = (uint8_t *)ID->data; + for (i = 1; i < TRUE_PLANES; i++) + TRU->plane_address[i] = TRU->plane_address[i - 1] + + (((TRU->plane_size.element[i - 1] + 15) / 16) * 16); + + if ((ID->type_format == X3F_IMAGE_RAW_QUATTRO || + ID->type_format == X3F_IMAGE_RAW_SDQ || + ID->type_format == X3F_IMAGE_RAW_SDQH || + ID->type_format == X3F_IMAGE_RAW_SDQH2) && + Q->quattro_layout) + { + uint32_t columns = Q->plane[0].columns; + uint32_t rows = Q->plane[0].rows; + uint32_t channels = 3; + uint32_t size = columns * rows * channels; + + TRU->x3rgb16.columns = columns; + TRU->x3rgb16.rows = rows; + TRU->x3rgb16.channels = channels; + TRU->x3rgb16.row_stride = columns * channels; + TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size); + TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf; + + columns = Q->plane[2].columns; + rows = Q->plane[2].rows; + channels = 1; + size = columns * rows * channels; + + Q->top16.columns = columns; + Q->top16.rows = rows; + Q->top16.channels = channels; + Q->top16.row_stride = columns * channels; + Q->top16.buf = malloc(sizeof(uint16_t) * size); + Q->top16.data = (uint16_t *)Q->top16.buf; + } + else + { + uint32_t size = ID->columns * ID->rows * 3; + + TRU->x3rgb16.columns = ID->columns; + TRU->x3rgb16.rows = ID->rows; + TRU->x3rgb16.channels = 3; + TRU->x3rgb16.row_stride = ID->columns * 3; + TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size); + TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf; + } + + true_decode(I, DE); +} + +static void x3f_load_huffman_compressed(x3f_info_t *I, + x3f_directory_entry_t *DE, int bits, + int /*use_map_table*/) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_huffman_t *HUF = ID->huffman; + int table_size = 1 << bits; + int row_offsets_size = ID->rows * sizeof(HUF->row_offsets.element[0]); + + GET_TABLE(HUF->table, GET4, table_size, uint32_t); + + if (!ID->data_size) + ID->data_size = read_data_block(&ID->data, I, DE, row_offsets_size); + + GET_TABLE(HUF->row_offsets, GET4, ID->rows, uint32_t); + + new_huffman_tree(&HUF->tree, bits); + populate_huffman_tree(&HUF->tree, &HUF->table, &HUF->mapping); + + huffman_decode(I, DE, bits); +} + +static void x3f_load_huffman_not_compressed(x3f_info_t *I, + x3f_directory_entry_t *DE, int bits, + int /*use_map_table*/, int row_stride) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + if (!ID->data_size) + ID->data_size = read_data_block(&ID->data, I, DE, 0); + + simple_decode(I, DE, bits, row_stride); +} + +static void x3f_load_huffman(x3f_info_t *I, x3f_directory_entry_t *DE, int bits, + int use_map_table, int row_stride) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_huffman_t *HUF = new_huffman(&ID->huffman); + uint32_t size; + + if (use_map_table) + { + int table_size = 1 << bits; + + GET_TABLE(HUF->mapping, GET2, table_size, uint16_t); + } + + switch (ID->type_format) + { + case X3F_IMAGE_RAW_HUFFMAN_X530: + case X3F_IMAGE_RAW_HUFFMAN_10BIT: + size = ID->columns * ID->rows * 3; + HUF->x3rgb16.columns = ID->columns; + HUF->x3rgb16.rows = ID->rows; + HUF->x3rgb16.channels = 3; + HUF->x3rgb16.row_stride = ID->columns * 3; + HUF->x3rgb16.buf = malloc(sizeof(uint16_t) * size); + HUF->x3rgb16.data = (uint16_t *)HUF->x3rgb16.buf; + break; + case X3F_IMAGE_THUMB_HUFFMAN: + size = ID->columns * ID->rows * 3; + HUF->rgb8.columns = ID->columns; + HUF->rgb8.rows = ID->rows; + HUF->rgb8.channels = 3; + HUF->rgb8.row_stride = ID->columns * 3; + HUF->rgb8.buf = malloc(sizeof(uint8_t) * size); + HUF->rgb8.data = (uint8_t *)HUF->rgb8.buf; + break; + default: + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + + if (row_stride == 0) + return x3f_load_huffman_compressed(I, DE, bits, use_map_table); + else + return x3f_load_huffman_not_compressed(I, DE, bits, use_map_table, + row_stride); +} + +static void x3f_load_pixmap(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_load_image_verbatim(I, DE); +} + +static uint32_t x3f_load_pixmap_size(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + return x3f_load_image_verbatim_size(I, DE); +} + +static void x3f_load_jpeg(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_load_image_verbatim(I, DE); +} + +static uint32_t x3f_load_jpeg_size(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + return x3f_load_image_verbatim_size(I, DE); +} + +static void x3f_load_image(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + if (ID->rows > 65535 || ID->columns > 65535) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); + + switch (ID->type_format) + { + case X3F_IMAGE_RAW_TRUE: + case X3F_IMAGE_RAW_MERRILL: + case X3F_IMAGE_RAW_QUATTRO: + case X3F_IMAGE_RAW_SDQ: + case X3F_IMAGE_RAW_SDQH: + case X3F_IMAGE_RAW_SDQH2: + x3f_load_true(I, DE); + break; + case X3F_IMAGE_RAW_HUFFMAN_X530: + case X3F_IMAGE_RAW_HUFFMAN_10BIT: + x3f_load_huffman(I, DE, 10, 1, ID->row_stride); + break; + case X3F_IMAGE_THUMB_PLAIN: + x3f_load_pixmap(I, DE); + break; + case X3F_IMAGE_THUMB_HUFFMAN: + x3f_load_huffman(I, DE, 8, 0, ID->row_stride); + break; + case X3F_IMAGE_THUMB_JPEG: + x3f_load_jpeg(I, DE); + break; + default: + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } +} + +// Used only for thumbnail size estimation +static uint32_t x3f_load_image_size(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + + read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); + + switch (ID->type_format) + { + case X3F_IMAGE_THUMB_PLAIN: + return x3f_load_pixmap_size(I, DE); + case X3F_IMAGE_THUMB_JPEG: + return x3f_load_jpeg_size(I, DE); + break; + default: + return 0; + } +} + +static void x3f_load_camf_decode_type2(x3f_camf_t *CAMF) +{ + uint32_t key = CAMF->t2.crypt_key; + int i; + + CAMF->decoded_data_size = CAMF->data_size; + CAMF->decoded_data = malloc(CAMF->decoded_data_size); + + for (i = 0; i < (int)CAMF->data_size; i++) + { + uint8_t old, _new; + uint32_t tmp; + + old = ((uint8_t *)CAMF->data)[i]; + key = (key * 1597 + 51749) % 244944; + tmp = (uint32_t)(key * ((int64_t)301593171) >> 24); + _new = (uint8_t)(old ^ (uint8_t)(((((key << 8) - tmp) >> 1) + tmp) >> 17)); + ((uint8_t *)CAMF->decoded_data)[i] = _new; + } +} + +/* NOTE: the unpacking in this code is in big respects identical to + true_decode_one_color(). The difference is in the output you + build. It might be possible to make some parts shared. NOTE ALSO: + This means that the meta data is obfuscated using an image + compression algorithm. */ + +static void camf_decode_type4(x3f_camf_t *CAMF) +{ + uint32_t seed = CAMF->t4.decode_bias; + int row; + + uint8_t *dst; + uint32_t dst_size = CAMF->t4.decoded_data_size; + uint8_t *dst_end; + + bool_t odd_dst = 0; + + x3f_hufftree_t *tree = &CAMF->tree; + bit_state_t BS; + + int32_t row_start_acc[2][2]; + uint32_t rows = CAMF->t4.block_count; + uint32_t cols = CAMF->t4.block_size; + + CAMF->decoded_data_size = dst_size; + + CAMF->decoded_data = malloc(CAMF->decoded_data_size); + memset(CAMF->decoded_data, 0, CAMF->decoded_data_size); + + dst = (uint8_t *)CAMF->decoded_data; + dst_end = dst + dst_size; + + set_bit_state(&BS, CAMF->decoding_start); + + row_start_acc[0][0] = seed; + row_start_acc[0][1] = seed; + row_start_acc[1][0] = seed; + row_start_acc[1][1] = seed; + + for (row = 0; row < (int)rows; row++) + { + int col; + bool_t odd_row = row & 1; + int32_t acc[2]; + + /* We loop through all the columns and the rows. But the actual + data is smaller than that, so we break the loop when reaching + the end. */ + for (col = 0; col < (int)cols; col++) + { + bool_t odd_col = col & 1; + int32_t diff = get_true_diff(&BS, tree); + int32_t prev = col < 2 ? row_start_acc[odd_row][odd_col] : acc[odd_col]; + int32_t value = prev + diff; + + acc[odd_col] = value; + if (col < 2) + row_start_acc[odd_row][odd_col] = value; + + switch (odd_dst) + { + case 0: + *dst++ = (uint8_t)((value >> 4) & 0xff); + + if (dst >= dst_end) + { + goto ready; + } + + *dst = (uint8_t)((value << 4) & 0xf0); + break; + case 1: + *dst++ |= (uint8_t)((value >> 8) & 0x0f); + + if (dst >= dst_end) + { + goto ready; + } + + *dst++ = (uint8_t)((value << 0) & 0xff); + + if (dst >= dst_end) + { + goto ready; + } + + break; + } + + odd_dst = !odd_dst; + } /* end col */ + } /* end row */ + +ready:; +} + +static void x3f_load_camf_decode_type4(x3f_camf_t *CAMF) +{ + int i; + uint8_t *p; + x3f_true_huffman_element_t *element = NULL; + + for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++) + { + /* TODO: Is this too expensive ??*/ + element = (x3f_true_huffman_element_t *)realloc(element, + (i + 1) * sizeof(*element)); + + element[i].code_size = *p++; + element[i].code = *p++; + } + + CAMF->table.size = i; + CAMF->table.element = element; + + /* TODO: where does the values 28 and 32 come from? */ +#define CAMF_T4_DATA_SIZE_OFFSET 28 +#define CAMF_T4_DATA_OFFSET 32 + CAMF->decoding_size = + *(uint32_t *)((unsigned char *)CAMF->data + CAMF_T4_DATA_SIZE_OFFSET); + CAMF->decoding_start = (uint8_t *)CAMF->data + CAMF_T4_DATA_OFFSET; + + /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ + new_huffman_tree(&CAMF->tree, 8); + + populate_true_huffman_tree(&CAMF->tree, &CAMF->table); + +#ifdef DBG_PRNT + print_huffman_tree(CAMF->tree.nodes, 0, 0); +#endif + + camf_decode_type4(CAMF); +} + +static void camf_decode_type5(x3f_camf_t *CAMF) +{ + int32_t acc = CAMF->t5.decode_bias; + + uint8_t *dst; + + x3f_hufftree_t *tree = &CAMF->tree; + bit_state_t BS; + + int32_t i; + + CAMF->decoded_data_size = CAMF->t5.decoded_data_size; + CAMF->decoded_data = malloc(CAMF->decoded_data_size); + + dst = (uint8_t *)CAMF->decoded_data; + + set_bit_state(&BS, CAMF->decoding_start); + + for (i = 0; i < (int)CAMF->decoded_data_size; i++) + { + int32_t diff = get_true_diff(&BS, tree); + + acc = acc + diff; + *dst++ = (uint8_t)(acc & 0xff); + } +} + +static void x3f_load_camf_decode_type5(x3f_camf_t *CAMF) +{ + int i; + uint8_t *p; + x3f_true_huffman_element_t *element = NULL; + + for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++) + { + /* TODO: Is this too expensive ??*/ + element = (x3f_true_huffman_element_t *)realloc(element, + (i + 1) * sizeof(*element)); + + element[i].code_size = *p++; + element[i].code = *p++; + } + + CAMF->table.size = i; + CAMF->table.element = element; + + /* TODO: where does the values 28 and 32 come from? */ +#define CAMF_T5_DATA_SIZE_OFFSET 28 +#define CAMF_T5_DATA_OFFSET 32 + CAMF->decoding_size = + *(uint32_t *)((uint8_t *)CAMF->data + CAMF_T5_DATA_SIZE_OFFSET); + CAMF->decoding_start = (uint8_t *)CAMF->data + CAMF_T5_DATA_OFFSET; + + /* TODO: can it be fewer than 8 bits? Maybe taken from TRU->table? */ + new_huffman_tree(&CAMF->tree, 8); + + populate_true_huffman_tree(&CAMF->tree, &CAMF->table); + +#ifdef DBG_PRNT + print_huffman_tree(CAMF->tree.nodes, 0, 0); +#endif + + camf_decode_type5(CAMF); +} + +static void x3f_setup_camf_text_entry(camf_entry_t *entry) +{ + entry->text_size = *(uint32_t *)entry->value_address; + entry->text = (char *)entry->value_address + 4; +} + +static void x3f_setup_camf_property_entry(camf_entry_t *entry) +{ + int i; + uint8_t *e = (uint8_t *)entry->entry; + uint8_t *v = (uint8_t *)entry->value_address; + uint32_t num = entry->property_num = *(uint32_t *)v; + uint32_t off = *(uint32_t *)(v + 4); + + entry->property_name = (char **)malloc(num * sizeof(uint8_t *)); + entry->property_value = (uint8_t **)malloc(num * sizeof(uint8_t *)); + + for (i = 0; i < (int)num; i++) + { + uint32_t name_off = off + *(uint32_t *)(v + 8 + 8 * i); + uint32_t value_off = off + *(uint32_t *)(v + 8 + 8 * i + 4); + + entry->property_name[i] = (char *)(e + name_off); + entry->property_value[i] = e + value_off; + } +} + +static void set_matrix_element_info(uint32_t type, uint32_t *size, + matrix_type_t *decoded_type) +{ + switch (type) + { + case 0: + *size = 2; + *decoded_type = M_INT; /* known to be true */ + break; + case 1: + *size = 4; + *decoded_type = M_UINT; /* TODO: unknown ???? */ + break; + case 2: + *size = 4; + *decoded_type = M_UINT; /* TODO: unknown ???? */ + break; + case 3: + *size = 4; + *decoded_type = M_FLOAT; /* known to be true */ + break; + case 5: + *size = 1; + *decoded_type = M_UINT; /* TODO: unknown ???? */ + break; + case 6: + *size = 2; + *decoded_type = M_UINT; /* TODO: unknown ???? */ + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } +} + +static void get_matrix_copy(camf_entry_t *entry) +{ + uint32_t element_size = entry->matrix_element_size; + uint32_t elements = entry->matrix_elements; + int i, size = (entry->matrix_decoded_type == M_FLOAT ? sizeof(double) + : sizeof(uint32_t)) * + elements; + + entry->matrix_decoded = malloc(size); + + switch (element_size) + { + case 4: + switch (entry->matrix_decoded_type) + { + case M_INT: + case M_UINT: + memcpy(entry->matrix_decoded, entry->matrix_data, size); + break; + case M_FLOAT: + for (i = 0; i < (int)elements; i++) + ((double *)entry->matrix_decoded)[i] = + (double)((float *)entry->matrix_data)[i]; + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + break; + case 2: + switch (entry->matrix_decoded_type) + { + case M_INT: + for (i = 0; i < (int)elements; i++) + ((int32_t *)entry->matrix_decoded)[i] = + (int32_t)((int16_t *)entry->matrix_data)[i]; + break; + case M_UINT: + for (i = 0; i < (int)elements; i++) + ((uint32_t *)entry->matrix_decoded)[i] = + (uint32_t)((uint16_t *)entry->matrix_data)[i]; + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + break; + case 1: + switch (entry->matrix_decoded_type) + { + case M_INT: + for (i = 0; i < (int)elements; i++) + ((int32_t *)entry->matrix_decoded)[i] = + (int32_t)((int8_t *)entry->matrix_data)[i]; + break; + case M_UINT: + for (i = 0; i < (int)elements; i++) + ((uint32_t *)entry->matrix_decoded)[i] = + (uint32_t)((uint8_t *)entry->matrix_data)[i]; + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } +} + +static void x3f_setup_camf_matrix_entry(camf_entry_t *entry) +{ + int i; + int totalsize = 1; + + uint8_t *e = (uint8_t *)entry->entry; + uint8_t *v = (uint8_t *)entry->value_address; + uint32_t type = entry->matrix_type = *(uint32_t *)(v + 0); + uint32_t dim = entry->matrix_dim = *(uint32_t *)(v + 4); + uint32_t off = entry->matrix_data_off = *(uint32_t *)(v + 8); + camf_dim_entry_t *dentry = entry->matrix_dim_entry = + (camf_dim_entry_t *)malloc(dim * sizeof(camf_dim_entry_t)); + + for (i = 0; i < (int)dim; i++) + { + uint32_t size = dentry[i].size = *(uint32_t *)(v + 12 + 12 * i + 0); + dentry[i].name_offset = *(uint32_t *)(v + 12 + 12 * i + 4); + dentry[i].n = *(uint32_t *)(v + 12 + 12 * i + 8); + dentry[i].name = (char *)(e + dentry[i].name_offset); + + if ((int)dentry[i].n != i) + { + } + + totalsize *= size; + } + + set_matrix_element_info(type, &entry->matrix_element_size, + &entry->matrix_decoded_type); + entry->matrix_data = (void *)(e + off); + + entry->matrix_elements = totalsize; + entry->matrix_used_space = entry->entry_size - off; + + /* This estimate only works for matrices above a certain size */ + entry->matrix_estimated_element_size = entry->matrix_used_space / totalsize; + + get_matrix_copy(entry); +} + +static void x3f_setup_camf_entries(x3f_camf_t *CAMF) +{ + uint8_t *p = (uint8_t *)CAMF->decoded_data; + uint8_t *end = p + CAMF->decoded_data_size; + camf_entry_t *entry = NULL; + int i; + + for (i = 0; p < end; i++) + { + uint32_t *p4 = (uint32_t *)p; + + switch (*p4) + { + case X3F_CMbP: + case X3F_CMbT: + case X3F_CMbM: + break; + default: + goto stop; + } + + /* TODO: lots of realloc - may be inefficient */ + entry = (camf_entry_t *)realloc(entry, (i + 1) * sizeof(camf_entry_t)); + + /* Pointer */ + entry[i].entry = p; + + /* Header */ + entry[i].id = *p4++; + entry[i].version = *p4++; + entry[i].entry_size = *p4++; + entry[i].name_offset = *p4++; + entry[i].value_offset = *p4++; + + /* Compute addresses and sizes */ + entry[i].name_address = (char *)(p + entry[i].name_offset); + entry[i].value_address = p + entry[i].value_offset; + entry[i].name_size = entry[i].value_offset - entry[i].name_offset; + entry[i].value_size = entry[i].entry_size - entry[i].value_offset; + + entry[i].text_size = 0; + entry[i].text = NULL; + entry[i].property_num = 0; + entry[i].property_name = NULL; + entry[i].property_value = NULL; + entry[i].matrix_type = 0; + entry[i].matrix_dim = 0; + entry[i].matrix_data_off = 0; + entry[i].matrix_data = NULL; + entry[i].matrix_dim_entry = NULL; + + entry[i].matrix_decoded = NULL; + + switch (entry[i].id) + { + case X3F_CMbP: + x3f_setup_camf_property_entry(&entry[i]); + break; + case X3F_CMbT: + x3f_setup_camf_text_entry(&entry[i]); + break; + case X3F_CMbM: + x3f_setup_camf_matrix_entry(&entry[i]); + break; + } + + p += entry[i].entry_size; + } + +stop: + + CAMF->entry_table.size = i; + CAMF->entry_table.element = entry; +} + +static void x3f_load_camf(x3f_info_t *I, x3f_directory_entry_t *DE) +{ + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_camf_t *CAMF = &DEH->data_subsection.camf; + + read_data_set_offset(I, DE, X3F_CAMF_HEADER_SIZE); + + if (!CAMF->data_size) + CAMF->data_size = read_data_block(&CAMF->data, I, DE, 0); + + switch (CAMF->type) + { + case 2: /* Older SD9-SD14 */ + x3f_load_camf_decode_type2(CAMF); + break; + case 4: /* TRUE ... Merrill */ + x3f_load_camf_decode_type4(CAMF); + break; + case 5: /* Quattro ... */ + x3f_load_camf_decode_type5(CAMF); + break; + default: + /* TODO: Shouldn't this be treated as a fatal error? */ + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + + if (CAMF->decoded_data != NULL) + x3f_setup_camf_entries(CAMF); + else + throw LIBRAW_EXCEPTION_IO_CORRUPT; +} + +/* extern */ x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE) +{ + x3f_info_t *I = &x3f->info; + + if (DE == NULL) + return X3F_ARGUMENT_ERROR; + + switch (DE->header.identifier) + { + case X3F_SECp: + x3f_load_property_list(I, DE); + break; + case X3F_SECi: + x3f_load_image(I, DE); + break; + case X3F_SECc: + x3f_load_camf(I, DE); + break; + default: + return X3F_INTERNAL_ERROR; + } + return X3F_OK; +} + +/* extern */ int64_t x3f_load_data_size(x3f_t *x3f, x3f_directory_entry_t *DE) +{ + x3f_info_t *I = &x3f->info; + + if (DE == NULL) + return -1; + + switch (DE->header.identifier) + { + case X3F_SECi: + return x3f_load_image_size(I, DE); + default: + return 0; + } +} + +/* extern */ x3f_return_t x3f_load_image_block(x3f_t *x3f, + x3f_directory_entry_t *DE) +{ + x3f_info_t *I = &x3f->info; + + if (DE == NULL) + return X3F_ARGUMENT_ERROR; + + switch (DE->header.identifier) + { + case X3F_SECi: + read_data_set_offset(I, DE, X3F_IMAGE_HEADER_SIZE); + x3f_load_image_verbatim(I, DE); + break; + default: + throw LIBRAW_EXCEPTION_IO_CORRUPT; + return X3F_INTERNAL_ERROR; /* unreachable code*/ + } + + return X3F_OK; +} + +/* --------------------------------------------------------------------- */ +/* The End */ +/* --------------------------------------------------------------------- */ + +#endif diff --git a/version.sh b/version.sh new file mode 100755 index 000000000..c40036771 --- /dev/null +++ b/version.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +vfile=./libraw/libraw_version.h + +major=`grep LIBRAW_MAJOR_VERSION $vfile |head -1 | awk '{print $3}'` +minor=`grep LIBRAW_MINOR_VERSION $vfile | head -1 | awk '{print $3}'` +patch=`grep LIBRAW_PATCH_VERSION $vfile | head -1 | awk '{print $3}'` +tail=`grep LIBRAW_VERSION_TAIL $vfile | head -1 | awk '{print $3}'` + +if [ x$tail = xRelease ] ; then + echo "$major.$minor.$patch" | awk '{printf $1}' +else + echo "$major.$minor.$patch-$tail" | awk '{printf $1}' +fi + + From 1e7cedf3cb8614d9807ff7bbf72d08e19dae9978 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Fri, 17 Nov 2023 09:38:46 +0100 Subject: [PATCH 060/291] Ftblockdn - remove unwanted messages in console --- rtengine/FTblockDN.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 278c6806f..d187bee93 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -1246,7 +1246,9 @@ BENCHFUN chresid = sqrt(chresid / (6 * (levwav))); highresi = chresid + 0.66f * (sqrt(chmaxresid) - chresid); //evaluate sigma nresi = chresid; - printf("Nresi=%f Highresi=%f lev=%i\n", (double) nresi, (double) highresi, levwav); + if (settings->verbose) { + printf("Nresi=%f Highresi=%f lev=%i\n", (double) nresi, (double) highresi, levwav); + } } bdecomp->reconstruct(labdn->b[0]); @@ -1773,7 +1775,6 @@ BENCHFUN //median 3x3 in complement on RGB if (dnparams.methodmed == "RGB" && dnparams.median) { -//printf("RGB den\n"); int wid = dst->getWidth(), hei = dst->getHeight(); float** tm; tm = new float*[hei]; @@ -2381,7 +2382,10 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition& Wavelet bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition& WaveletCoeffs_L, wavelet_decomposition& WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels) { int maxlvl = WaveletCoeffs_L.maxlevel(); - printf("Ftblockdn ab bishrink\n"); + + if (settings->verbose) { + printf("Ftblockdn ab bishrink\n"); + } if (local == 1) { maxlvl = 6; //for local denoise @@ -2463,7 +2467,6 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition& Wavele float* const* WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); if (lvl == maxlvl - 1) { - //printf("Shrink ab bis\n"); ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], nullptr, 0, madab[lvl], true); } else { //simple wavelet shrinkage From a95a58a8a399173e6947ff12a4b82b5d83ae80d9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:22:43 -0800 Subject: [PATCH 061/291] Fix sRGB working profile crash The sRGB working profile cannot be found under some conditions because the profile name is stored as a Glib::ustring and the same strings may not be equal when using different locales. Use std::string whenever comparing profile names. --- rtengine/iccstore.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 8ba5fb4af..af1b94fbe 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -18,6 +18,7 @@ */ #include #include +#include #include #include @@ -51,9 +52,9 @@ namespace // Not recursive void loadProfiles( const Glib::ustring& dirName, - std::map* profiles, - std::map* profileContents, - std::map* profileNames, + std::map* profiles, + std::map* profileContents, + std::map* profileNames, bool nameUpper ) { @@ -114,8 +115,8 @@ void loadProfiles( bool loadProfile( const Glib::ustring& profile, const Glib::ustring& dirName, - std::map* profiles, - std::map* profileContents + std::map* profiles, + std::map* profileContents ) { if (dirName.empty() || profiles == nullptr) { @@ -996,10 +997,10 @@ parse_error: return false; } - using ProfileMap = std::map; - using MatrixMap = std::map; - using ContentMap = std::map; - using NameMap = std::map; + using ProfileMap = std::map; + using MatrixMap = std::map; + using ContentMap = std::map; + using NameMap = std::map; ProfileMap wProfiles; // ProfileMap wProfilesGamma; From 330f99832e44fc5c8d3d673525cd7936f7611b2e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:25:06 -0800 Subject: [PATCH 062/291] Fix WB method reset when not using English Use the GUI label for "Camera" instead of hard-coding it. --- rtgui/whitebalance.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index f72f3bc51..2f3686242 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -1079,7 +1079,7 @@ void WhiteBalance::setWB (int vtemp, double vgreen) void WhiteBalance::resetWB () { - setActiveMethod("Camera"); + setActiveMethod(M("TP_WBALANCE_CAMERA")); } void WhiteBalance::setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd) From 20d3311931c3974d188acb9d1c5ac7ed4a7bdd04 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 18 Nov 2023 21:23:55 -0800 Subject: [PATCH 063/291] Add decoding through LibRaw Decode raw files with LibRaw and fall back to dcraw if LibRaw is unable to read the file. --- .github/workflows/macos.yml | 4 +- .github/workflows/windows.yml | 1 + CMakeLists.txt | 11 + rtengine/CMakeLists.txt | 11 + rtengine/LibRaw.cmake | 124 ++++++++ rtengine/dcraw.h | 1 + rtengine/init.cc | 3 + rtengine/panasonic_decoders.cc | 5 + rtengine/rawimage.cc | 531 +++++++++++++++++++++++++++++---- rtengine/rawimage.h | 26 +- rtengine/rtthumbnail.cc | 53 ++-- 11 files changed, 669 insertions(+), 101 deletions(-) create mode 100644 rtengine/LibRaw.cmake diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 992bf4db3..1e054b33d 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -22,7 +22,7 @@ jobs: mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 | tee -a depslog + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 automake | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring @@ -42,6 +42,7 @@ jobs: export REF=${GITHUB_REF##*/} export C_FLAGS=$(echo -e $C_FLAGS | tr -d '\n') cd build && date -u && date +%s > configstamp + curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ @@ -66,7 +67,6 @@ jobs: -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DOSX_CONTINUOUS=ON \ .. - curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' - name: Compile RawTherapee run: | diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1143c948d..146b4144b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -43,6 +43,7 @@ jobs: cc:p pkgconf:p cmake:p + autotools:p ninja:p gtkmm3:p lcms2:p diff --git a/CMakeLists.txt b/CMakeLists.txt index abb86a108..820ff6f5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,6 +226,7 @@ option(WITH_LTO "Build with link-time optimizations" OFF) option(WITH_SAN "Build with run-time sanitizer" OFF) option(WITH_PROF "Build with profiling instrumentation" OFF) option(WITH_SYSTEM_KLT "Build using system KLT library." OFF) +option(WITH_SYSTEM_LIBRAW "Build using system LibRaw library." OFF) option(OPTION_OMP "Build with OpenMP support" ON) option( STRICT_MUTEX @@ -522,6 +523,13 @@ foreach(l ${_exiv2_libs}) set(EXIV2_LIBRARIES ${EXIV2_LIBRARIES} ${_el}) endforeach() +if(NOT WITH_SYSTEM_LIBRAW) + set(LIBRAW_LIBRARIES "${CMAKE_CURRENT_BINARY_DIR}/rtengine/libraw/lib/.libs/libraw_r.a") + if(WIN32) + set(LIBRAW_LIBRARIES ${LIBRAW_LIBRARIES} -lws2_32) + endif() +endif() + if(WIN32) add_definitions(-DWIN32) add_definitions(-D_WIN32) @@ -551,6 +559,9 @@ find_package(ZLIB REQUIRED) if(WITH_SYSTEM_KLT) find_package(KLT REQUIRED) endif() +if(WITH_SYSTEM_LIBRAW) + pkg_check_modules(LIBRAW REQUIRED libraw_r>=0.21) +endif() # Check for libcanberra-gtk3 (sound events on Linux): if(UNIX AND (NOT APPLE)) diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 5a9b2d953..793f24601 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -45,6 +45,11 @@ endif() if(EXIV2_INCLUDE_DIRS) include_directories("${EXIV2_INCLUDE_DIRS}") endif() +if(NOT WITH_SYSTEM_LIBRAW) + include_directories("${CMAKE_SOURCE_DIR}/rtengine/libraw") +else() + include_directories("${LIBRAW_INCLUDE_DIRS}") +endif() link_directories( "${EXPAT_LIBRARY_DIRS}" @@ -245,10 +250,16 @@ target_link_libraries(rtengine ${RSVG_LIBRARIES} ${KLT_LIBRARIES} ${EXIV2_LIBRARIES} + ${LIBRAW_LIBRARIES} ) if(OpenMP_FOUND) target_link_libraries(rtengine ${OpenMP_CXX_LIBRARIES}) endif() +# Configure LibRaw +if(NOT WITH_SYSTEM_LIBRAW) + include(LibRaw.cmake) +endif() + install(FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/LibRaw.cmake b/rtengine/LibRaw.cmake new file mode 100644 index 000000000..433312212 --- /dev/null +++ b/rtengine/LibRaw.cmake @@ -0,0 +1,124 @@ +# LibRaw has its own configuration script and uses make to build. Here we add +# the LibRaw configuration commands so they run during the CMake configuration. +# Also, add a target which always runs make. + +set(LIBRAW_DIR "${CMAKE_CURRENT_BINARY_DIR}/libraw") +set(LIBRAW_LIB_DIR "${LIBRAW_DIR}/lib") +set(LIBRAW_PHANTOM_FILE "${LIBRAW_LIB_DIR}/phantom_file") +if(DEFINED ENV{SHELL}) + set(SHELL "$ENV{SHELL}") +else() + set(SHELL "sh") +endif() + +add_custom_target( + LibRaw ALL + DEPENDS ${LIBRAW_PHANTOM_FILE} # Ensures target always executes. +) + +# Configuration flags. +set(CONFIGURE_FLAGS "--disable-examples") +set(LIBRAW_CXX_FLAGS "${CXX_FLAGS} -std=gnu++11 -Wno-error=unknown-pragmas") +# Let the configure script handle OpenMP flags. +string(REPLACE "${OpenMP_CXX_FLAGS}" "" LIBRAW_CXX_FLAGS "${LIBRAW_CXX_FLAGS}") +if(OPTION_OMP) + set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} --enable-openmp") +else() + set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} --disable-openmp") +endif() +set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CC=\"${CMAKE_C_COMPILER}\"") +set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CXX=\"${CMAKE_CXX_COMPILER}\"") +set(CONFIGURE_FLAGS "${CONFIGURE_FLAGS} CXXFLAGS=\"${LIBRAW_CXX_FLAGS}\"") + +# Configuration commands. +message(STATUS "Configuring LibRaw") +execute_process( + COMMAND cp -p -R "${CMAKE_CURRENT_SOURCE_DIR}/libraw" . + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE PROCESS_RESULT + COMMAND_ECHO STDOUT +) +if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + message(FATAL_ERROR "Could not copy LibRaw files into build directory") +endif() +execute_process( + COMMAND "${SHELL}" -l -c "autoreconf -v --install" + WORKING_DIRECTORY "${LIBRAW_DIR}" + RESULT_VARIABLE PROCESS_RESULT + COMMAND_ECHO STDOUT +) +if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + message(FATAL_ERROR "Could not generate LibRaw configuration script") +endif() +execute_process( + COMMAND "${SHELL}" -l -c "./configure ${CONFIGURE_FLAGS}" + WORKING_DIRECTORY "${LIBRAW_DIR}" + RESULT_VARIABLE PROCESS_RESULT + COMMAND_ECHO STDOUT +) +if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + execute_process( + COMMAND cat config.log + WORKING_DIRECTORY "${LIBRAW_DIR}" + COMMAND_ECHO STDOUT + ) + message(FATAL_ERROR "LibRaw configure failed") +endif() + +# Build flags. +set(LIBRAW_MAKE_FLAGS "") +if(CMAKE_GENERATOR MATCHES ".*Makefiles.*") + set(LIBRAW_MAKE_COMMAND "$(MAKE)") +else() + # If not using Makefiles, set number of jobs equal to logical processors + # count. Not necessary for make because of the jobserver. + execute_process( + COMMAND "${SHELL}" -l -c "nproc" + OUTPUT_VARIABLE LOGICAL_PROCESSORS + RESULT_VARIABLE PROCESS_RESULT + ERROR_QUIET + ) + if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + execute_process( + COMMAND "${SHELL}" -l -c "sysctl -n hw.ncpu" + OUTPUT_VARIABLE LOGICAL_PROCESSORS + RESULT_VARIABLE PROCESS_RESULT + ERROR_QUIET + ) + endif() + if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + execute_process( + COMMAND "${SHELL}" -l -c "getconf _NPROCESSORS_ONLN" + OUTPUT_VARIABLE LOGICAL_PROCESSORS + RESULT_VARIABLE PROCESS_RESULT + ERROR_QUIET + ) + endif() + if(PROCESS_RESULT AND NOT PROCESS_RESULT EQUAL 0) + set(LOGICAL_PROCESSORS "1") + endif() + string(STRIP "${LOGICAL_PROCESSORS}" LOGICAL_PROCESSORS) + set(LIBRAW_MAKE_FLAGS "${LIBRAW_MAKE_FLAGS} -j${LOGICAL_PROCESSORS}") + + set(LIBRAW_MAKE_COMMAND "make") +endif() + +# Build commands. +add_custom_command( + OUTPUT "${LIBRAW_PHANTOM_FILE}" "${LIBRAW_LIB_DIR}/.libs/libraw_r.a" + COMMAND cp -p -R "${CMAKE_CURRENT_SOURCE_DIR}/libraw" .. + COMMAND "${SHELL}" -l -c "${LIBRAW_MAKE_COMMAND} ${LIBRAW_MAKE_FLAGS}" + COMMENT "Building LibRaw" + WORKING_DIRECTORY libraw + VERBATIM +) + +# Add a `make clean-libraw` command because there's no good way to automatically +# clean the LibRaw build with `make`clean`. +add_custom_target( + clean-libraw + COMMAND make clean + COMMAND rm -rf lib + WORKING_DIRECTORY libraw +) + diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 4f1db420c..4501aef67 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -67,6 +67,7 @@ public: ,getbithuff(this,ifp,zero_after_ff) ,nikbithuff(ifp) { + shrink=0; memset(&hbd, 0, sizeof(hbd)); aber[0]=aber[1]=aber[2]=aber[3]=1; gamm[0]=0.45;gamm[1]=4.5;gamm[2]=gamm[3]=gamm[4]=gamm[5]=0; diff --git a/rtengine/init.cc b/rtengine/init.cc index 04faa98a8..731c26a20 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -44,6 +44,7 @@ const Settings* settings; MyMutex* lcmsMutex = nullptr; MyMutex *fftwMutex = nullptr; +MyMutex *librawMutex = nullptr; int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& userSettingsDir, bool loadAll) { @@ -120,6 +121,8 @@ int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring& delete lcmsMutex; lcmsMutex = new MyMutex; fftwMutex = new MyMutex; + delete librawMutex; + librawMutex = new MyMutex; return 0; } diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index bbbfb7c20..c68ec153f 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -58,6 +58,9 @@ unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) } } +namespace +{ + class pana_cs6_page_decoder { unsigned int pixelbuffer[14], lastoffset, maxoffset; @@ -99,6 +102,8 @@ void pana_cs6_page_decoder::read_page() } #undef wbuffer +} + void DCraw::panasonic_load_raw() { int enc_blck_size = RT_pana_info.bpp == 12 ? 10 : 9; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index dc026d83a..d96993a0d 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -1,6 +1,8 @@ /* * This file is part of RawTherapee. * + * LibRaw integration adapted from ART. + * * Created on: 20/nov/2010 */ @@ -11,17 +13,24 @@ #include #endif +#include "image8.h" #include "rawimage.h" #include "settings.h" #include "camconst.h" #include "utils.h" #include "rtengine.h" +#include "libraw/libraw/libraw.h" namespace rtengine { + +extern MyMutex *librawMutex; + + RawImage::RawImage(const Glib::ustring &name) - : data(nullptr) + : DCraw() + , data(nullptr) , prefilters(0) , filename(name) , rotate_deg(0) @@ -29,9 +38,12 @@ RawImage::RawImage(const Glib::ustring &name) , allocation(nullptr) { memset(maximum_c4, 0, sizeof(maximum_c4)); + memset(white, 0, sizeof(white)); RT_matrix_from_constant = ThreeValBool::X; RT_blacklevel_from_constant = ThreeValBool::X; RT_whitelevel_from_constant = ThreeValBool::X; + memset(make, 0, sizeof(make)); + memset(model, 0, sizeof(model)); } RawImage::~RawImage() @@ -41,7 +53,7 @@ RawImage::~RawImage() ifp = nullptr; } - if (image) { + if (image && decoder == Decoder::DCRAW) { free(image); } @@ -66,6 +78,18 @@ RawImage::~RawImage() } } +void RawImage::pre_interpolate() +{ + int w = width, h = height; + if (decoder == Decoder::LIBRAW) { + width = iwidth; + height = iheight; + } + DCraw::pre_interpolate(); + width = w; + height = h; +} + eSensorType RawImage::getSensorType() const { if (isBayer()) { @@ -467,7 +491,176 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog // set the number of the frame to extract. If the number is larger then number of existing frames - 1, dcraw will handle that correctly shot_select = imageNum; - identify(); + + libraw.reset(new LibRaw()); + int libraw_error = [&]() -> int { + libraw->imgdata.params.use_camera_wb = 1; + + int err = libraw->open_buffer(ifp->data, ifp->size); + if (err == LIBRAW_FILE_UNSUPPORTED || err == LIBRAW_TOO_BIG) { + // fallback to the internal one + return err; + } else if (err != LIBRAW_SUCCESS && strncmp(libraw->imgdata.idata.software, "make_arq", 8) == 0) { + return err; + } else if (err == LIBRAW_FILE_UNSUPPORTED && (strncmp(libraw->unpack_function_name(), "sony_arq_load_raw", 17) == 0 || strncmp(libraw->imgdata.idata.software, "HDRMerge", 8) == 0)) { + return err; + } else if (err != LIBRAW_SUCCESS) { + decoder = Decoder::LIBRAW; + return err; + } else if (libraw->is_floating_point() && libraw->imgdata.idata.dng_version) { + return err; + } + + auto &d = libraw->imgdata.idata; + is_raw = d.raw_count; + strncpy(make, d.normalized_make, sizeof(make)-1); + make[sizeof(make)-1] = 0; + strncpy(model, d.normalized_model, sizeof(model)-1); + model[sizeof(model)-1] = 0; + RT_software = d.software; + dng_version = d.dng_version; + filters = d.filters; + is_foveon = d.is_foveon; + colors = d.colors; + tiff_bps = 0; + + for (int i = 0; i < 6; ++i) { + for (int j = 0; j < 6; ++j) { + xtrans[i][j] = d.xtrans[i][j]; + xtrans_abs[i][j] = d.xtrans_abs[i][j]; + } + } + auto &s = libraw->imgdata.sizes; + raw_width = s.raw_width; + raw_height = s.raw_height; + width = s.width; + height = s.height; + top_margin = s.top_margin; + left_margin = s.left_margin; + iheight = s.iheight; + iwidth = s.iwidth; + flip = s.flip; + + auto &o = libraw->imgdata.other; + iso_speed = o.iso_speed; + shutter = o.shutter; + aperture = o.aperture; + focal_len = o.focal_len; + timestamp = o.timestamp; + shot_order = o.shot_order; + + auto &io = libraw->imgdata.rawdata.ioparams; + shrink = io.shrink; + zero_is_bad = io.zero_is_bad; + fuji_width = io.fuji_width; + raw_color = io.raw_color; + mix_green = io.mix_green; + + auto &cd = libraw->imgdata.color; + black = cd.black; + maximum = cd.maximum; + tiff_bps = cd.raw_bps; + + for (size_t i = 0; i < sizeof(cblack)/sizeof(unsigned); ++i) { + cblack[i] = cd.cblack[i]; + } + for (int i = 0; i < 4; ++i) { + cam_mul[i] = cd.cam_mul[i]; + pre_mul[i] = cd.pre_mul[i]; + } + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 4; ++j) { + cmatrix[i][j] = cd.cmatrix[i][j]; + rgb_cam[i][j] = cd.rgb_cam[i][j]; + } + } + + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + white[i][j] = cd.white[i][j]; + } + } + + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 4; ++j) { + mask[i][j] = s.mask[i][j]; + } + } + + auto &mkn = libraw->imgdata.makernotes; + + // if (!strcmp(make, "Panasonic") && mkn.panasonic.BlackLevelDim > 0) { + // memset(cblack, 0, sizeof(cblack)); + // if (mkn.panasonic.BlackLevelDim >= 4) { + // for (size_t i = 0; i < 4; ++i) { + // cblack[i] = mkn.panasonic.BlackLevel[i]; + // } + // black = 0; + // } else { + // black = mkn.panasonic.BlackLevel[0]; + // } + // } else + if (!strcmp(make, "Canon") && isBayer() && !dng_version) { + if (mkn.canon.AverageBlackLevel) { + memset(cblack, 0, sizeof(cblack)); + for (size_t i = 0; i < 4; ++i) { + cblack[i] = mkn.canon.ChannelBlackLevel[i]; + } + black = 0; + } + if (mkn.canon.SpecularWhiteLevel) { + maximum = mkn.canon.SpecularWhiteLevel; + } else if (mkn.canon.NormalWhiteLevel) { + maximum = mkn.canon.NormalWhiteLevel; + } + } + while (tiff_bps < 16 && (size_t(1) << size_t(tiff_bps)) < maximum) { + ++tiff_bps; + } + + if (dng_version) { + RT_whitelevel_from_constant = ThreeValBool::F; + RT_blacklevel_from_constant = ThreeValBool::F; + if (!isBayer() && !isXtrans()) { + RT_matrix_from_constant = ThreeValBool::F; + } + } else if (strcmp(make, "Panasonic") != 0) { + RT_whitelevel_from_constant = ThreeValBool::T; + RT_blacklevel_from_constant = ThreeValBool::T; + } + + if (is_foveon) { + raw_width = width; + raw_height = height; + top_margin = 0; + left_margin = 0; + } + + decoder = Decoder::LIBRAW; + return err; + }(); + + if (libraw_error && verbose) { + printf("LibRaw could not load image."); + if (decoder == Decoder::DCRAW) { + printf(" Falling back to dcraw."); + } + printf("\n"); + } + + if (decoder == Decoder::LIBRAW) { + if (libraw_error) { + return libraw_error; + } + } else { + libraw->recycle(); + } + + if (decoder == Decoder::DCRAW) { + identify(); + } + // in case dcraw didn't handle the above mentioned case... shot_select = std::min(shot_select, std::max(is_raw, 1u) - 1); @@ -482,7 +675,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog return 2; } - if (!strcmp(make, "Fujifilm") && raw_height * raw_width * 2u != raw_size) { + if (decoder == Decoder::DCRAW && !strcmp(make, "Fujifilm") && raw_height * raw_width * 2u != raw_size) { if (raw_width * raw_height * 7u / 4u == raw_size) { load_raw = &RawImage::fuji_14bit_load_raw; } else { @@ -514,29 +707,87 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog iheight = height; iwidth = width; - if (filters || colors == 1) { - raw_image = (ushort *) calloc ((static_cast(raw_height) + 7u) * static_cast(raw_width), 2); - merror(raw_image, "main()"); - } + if (decoder == Decoder::DCRAW) { + if (filters || colors == 1) { + raw_image = (ushort *) calloc ((static_cast(raw_height) + 7u) * static_cast(raw_width), 2); + merror(raw_image, "main()"); + } - // dcraw needs this global variable to hold pixel data - image = (dcrawImage_t)calloc (static_cast(height) * static_cast(width) * sizeof * image + meta_length, 1); - if(!image) { - return 200; - } - meta_data = (char *) (image + static_cast(height) * static_cast(width)); + // dcraw needs this global variable to hold pixel data + image = (dcrawImage_t)calloc (static_cast(height) * static_cast(width) * sizeof * image + meta_length, 1); + if(!image) { + return 200; + } + meta_data = (char *) (image + static_cast(height) * static_cast(width)); - /* Issue 2467 - if (setjmp (failure)) { - if (image) { free (image); image=NULL; } - if (raw_image) { free(raw_image); raw_image=NULL; } - fclose(ifp); ifp=NULL; - return 100; - } - */ - // Load raw pixels data - fseek(ifp, data_offset, SEEK_SET); - (this->*load_raw)(); + /* Issue 2467 + if (setjmp (failure)) { + if (image) { free (image); image=NULL; } + if (raw_image) { free(raw_image); raw_image=NULL; } + fclose(ifp); ifp=NULL; + return 100; + } + */ + // Load raw pixels data + fseek(ifp, data_offset, SEEK_SET); + (this->*load_raw)(); + } else if (decoder == Decoder::LIBRAW) { + libraw->imgdata.rawparams.shot_select = shot_select; + + int err = libraw->open_buffer(ifp->data, ifp->size); + if (err) { + return err; + } + { +#ifdef LIBRAW_USE_OPENMP + MyMutex::MyLock lock(*librawMutex); +#endif + err = libraw->unpack(); + } + if (err) { + return err; + } + + auto &rd = libraw->imgdata.rawdata; + raw_image = rd.raw_image; + if (rd.float_image) { + float_raw_image = new float[raw_width * raw_height]; + for (int y = 0; y < raw_height; ++y) { + for (int x = 0; x < raw_width; ++x) { + size_t idx = y * raw_width + x; + float_raw_image[idx] = rd.float_image[idx]; + } + } + } else { +#ifdef LIBRAW_USE_OPENMP + MyMutex::MyLock lock(*librawMutex); +#endif + float_raw_image = nullptr; + err = libraw->raw2image(); + if (err) { + return err; + } + image = libraw->imgdata.image; + } + + // get our custom camera matrices, but don't mess with black/white levels yet + // (if we have custom levels in json files, we will get them later) + auto bl = RT_blacklevel_from_constant; + auto wl = RT_whitelevel_from_constant; + RT_blacklevel_from_constant = ThreeValBool::F; + RT_whitelevel_from_constant = ThreeValBool::F; + + adobe_coeff(make, model); + + RT_blacklevel_from_constant = bl; + RT_whitelevel_from_constant = wl; + + if (libraw->imgdata.color.profile_length) { + profile_length = libraw->imgdata.color.profile_length; + profile_data = new char[profile_length]; + memcpy(profile_data, libraw->imgdata.color.profile, profile_length); + } + } if (!float_raw_image) { // apply baseline exposure only for float DNGs RT_baseline_exposure = 0; @@ -551,6 +802,10 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog bool raw_crop_cc = false; int orig_raw_width = width; int orig_raw_height = height; + // For raw crop when using LibRaw. + int raw_top_margin = 0; + int raw_left_margin = 0; + bool adjust_margins = false; if (raw_image) { orig_raw_width = raw_width; @@ -561,33 +816,82 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog int lm, tm, w, h; cc->get_rawCrop(raw_width, raw_height, lm, tm, w, h); - if (isXtrans()) { - shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6)); + if ((w < 0 || h < 0) && decoder != Decoder::DCRAW) { + raw_crop_cc = false; } else { - if (((int)top_margin - tm) & 1) { // we have an odd border difference - filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits + // protect against DNG files that are already cropped + if (int(raw_width) <= w+lm) { + lm = max(int(raw_width) - w, 0); + } + if (int(raw_height) <= h+tm) { + tm = max(int(raw_height) - h, 0); } - } - left_margin = lm; - top_margin = tm; + if (decoder == Decoder::DCRAW) { + if (isXtrans()) { + shiftXtransMatrix(6 - ((top_margin - tm) % 6), 6 - ((left_margin - lm) % 6)); + } else { + if (((int)top_margin - tm) & 1) { // we have an odd border difference + filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits + } + } - if (w < 0) { - iwidth += w; - iwidth -= left_margin; - width += w; - width -= left_margin; - } else if (w > 0) { - iwidth = width = min((int)width, w); - } + left_margin = lm; + top_margin = tm; + } else { + if (lm < left_margin) { + lm = left_margin; + } + if (tm < top_margin) { + tm = top_margin; + } + // make sure we do not rotate filters + if (isXtrans()) { + if ((tm - top_margin) % 6) { + tm = top_margin; + } + if ((lm - left_margin) % 6) { + lm = left_margin; + } + } else { + if ((tm - top_margin) & 1) { + tm = top_margin; + } + if ((lm - left_margin) & 1) { + lm = left_margin; + } + } + raw_left_margin = lm - left_margin; + raw_top_margin = tm - top_margin; + } - if (h < 0) { - iheight += h; - iheight -= top_margin; - height += h; - height -= top_margin; - } else if (h > 0) { - iheight = height = min((int)height, h); + if (w < 0) { + iwidth += w; + iwidth -= left_margin; + width += w; + width -= left_margin; + } else if (w > 0) { + width = min((int)width, w); + if (decoder == Decoder::DCRAW) { + iwidth = width; + } else if (width > iwidth) { + width = iwidth; + } + } + + if (h < 0) { + iheight += h; + iheight -= top_margin; + height += h; + height -= top_margin; + } else if (h > 0) { + height = min((int)height, h); + if (decoder == Decoder::DCRAW) { + iheight = height; + } else if (height > iheight) { + height = iheight; + } + } } } @@ -597,11 +901,14 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog } } - crop_masked_pixels(); - free(raw_image); + if (decoder == Decoder::DCRAW) { + crop_masked_pixels(); + free(raw_image); + } raw_image = nullptr; + adjust_margins = !float_raw_image; //true; } else { - if (get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images + if (decoder == Decoder::DCRAW && get_maker() == "Sigma" && cc && cc->has_rawCrop(width, height)) { // foveon images raw_crop_cc = true; int lm, tm, w, h; cc->get_rawCrop(width, height, lm, tm, w, h); @@ -611,21 +918,27 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog if (w < 0) { width += w; width -= left_margin; + iwidth += w; + iwidth -= left_margin; } else if (w > 0) { width = min((int)width, w); + iwidth = width; } if (h < 0) { height += h; height -= top_margin; + iheight += h; + iheight -= top_margin; } else if (h > 0) { height = min((int)height, h); + iheight = height; } } } // Load embedded profile - if (profile_length) { + if (decoder == Decoder::DCRAW && profile_length) { profile_data = new char[profile_length]; fseek(ifp, profile_offset, SEEK_SET); fread(profile_data, 1, profile_length, ifp); @@ -690,23 +1003,30 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog for (int c = 0; c < 4; c++) { if (static_cast(cblack[c]) < black_c4[c]) { cblack[c] = black_c4[c]; + cblack[4] = cblack[5] = 0; } } if (settings->verbose) { + const char *decoder_name = decoder == Decoder::DCRAW ? "dcraw" : decoder == Decoder::LIBRAW ? "libraw" : "unknown"; if (cc) { printf("constants exists for \"%s %s\" in camconst.json\n", make, model); } else { - printf("no constants in camconst.json exists for \"%s %s\" (relying only on dcraw defaults)\n", make, model); + printf("no constants in camconst.json exists for \"%s %s\" (relying only on %s defaults)\n", make, model, decoder_name); } printf("raw dimensions: %d x %d\n", orig_raw_width, orig_raw_height); - printf("black levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_cblack(0), get_cblack(1), get_cblack(2), get_cblack(3), - black_from_cc ? "provided by camconst.json" : "provided by dcraw"); - printf("white levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_white(0), get_white(1), get_white(2), get_white(3), - white_from_cc ? "provided by camconst.json" : "provided by dcraw"); - printf("raw crop: %d %d %d %d (provided by %s)\n", left_margin, top_margin, iwidth, iheight, raw_crop_cc ? "camconst.json" : "dcraw"); - printf("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : "dcraw"); + printf("black levels: R:%d G1:%d B:%d G2:%d (provided by %s)\n", get_cblack(0), get_cblack(1), get_cblack(2), get_cblack(3), + black_from_cc ? "camconst.json" : decoder_name); + printf("white levels: R:%d G1:%d B:%d G2:%d (provided by %s)\n", get_white(0), get_white(1), get_white(2), get_white(3), + white_from_cc ? "camconst.json" : decoder_name); + printf("raw crop: %d %d %d %d (provided by %s)\n", left_margin, top_margin, iwidth, iheight, raw_crop_cc ? "camconst.json" : decoder_name); + printf("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : decoder_name); + } + + if (adjust_margins) { + top_margin = raw_top_margin; + left_margin = raw_left_margin; } } @@ -779,7 +1099,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) 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)]; + this->data[row][col] = image[(row + top_margin) * iwidth + col + left_margin][FC(row, col)]; } } else if (isXtrans()) { #ifdef _OPENMP @@ -788,7 +1108,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) for (int row = 0; row < height; row++) for (int col = 0; col < width; col++) { - this->data[row][col] = image[row * width + col][XTRANSFC(row, col)]; + this->data[row][col] = image[(row + top_margin) * iwidth + col + left_margin][XTRANSFC(row, col)]; } } else if (colors == 1) { #ifdef _OPENMP @@ -797,7 +1117,7 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) for (int row = 0; row < height; row++) for (int col = 0; col < width; col++) { - this->data[row][col] = image[row * width + col][0]; + this->data[row][col] = image[row * iwidth + col][0]; } } else { if((get_maker() == "Sigma" || get_maker() == "Pentax" || get_maker() == "Sony") && dng_version) { // Hack to prevent sigma dng files and dng files from PixelShift2DNG from crashing @@ -817,7 +1137,11 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) } if (freeImage) { - free(image); // we don't need this anymore + if (decoder == Decoder::DCRAW) { + free(image); // we don't need this anymore + } else if (decoder == Decoder::LIBRAW) { + libraw->recycle(); + } image = nullptr; } @@ -872,6 +1196,89 @@ RawImage::get_thumbSwap() const return (order == 0x4949) == (ntohs(0x1234) == 0x1234); } + +bool RawImage::checkThumbOk() const +{ + if (!is_supportedThumb()) { + return false; + } + + if (get_thumbOffset() >= get_file()->size) { + return false; + } + + const ssize_t length = + fdata (get_thumbOffset(), get_file())[1] != 0xD8 && is_ppmThumb() + ? get_thumbWidth() * get_thumbHeight() * (get_thumbBPS() / 8) * 3 + : get_thumbLength(); + + return get_thumbOffset() + length <= get_file()->size; +} + + +Image8 *RawImage::getThumbnail() const +{ + if (decoder == Decoder::DCRAW) { + if (!checkThumbOk()) { + return nullptr; + } + + Image8 *img = new Image8(); + img->setSampleFormat(IIOSF_UNSIGNED_CHAR); + img->setSampleArrangement(IIOSA_CHUNKY); + + const char *data = reinterpret_cast(fdata(get_thumbOffset(), get_file())); + + int err = 1; + if ((unsigned char)data[1] == 0xd8) { + err = img->loadJPEGFromMemory(data, get_thumbLength()); + } else if (is_ppmThumb()) { + err = img->loadPPMFromMemory(data, get_thumbWidth(), get_thumbHeight(), get_thumbSwap(), get_thumbBPS()); + } + + // did we succeed? + if (err) { + delete img; + img = nullptr; + } + + return img; + } + + if (!ifp) { + return nullptr; + } else { + int err = libraw->unpack_thumb(); + if (err) { + return nullptr; + } + auto &t = libraw->imgdata.thumbnail; + if (!t.thumb) { + return nullptr; + } else if (t.tformat != LIBRAW_THUMBNAIL_JPEG && t.tformat != LIBRAW_THUMBNAIL_BITMAP) { + return nullptr; + } else { + Image8 *img = new Image8(); + img->setSampleFormat(IIOSF_UNSIGNED_CHAR); + img->setSampleArrangement(IIOSA_CHUNKY); + if (t.tformat == LIBRAW_THUMBNAIL_JPEG) { + err = img->loadJPEGFromMemory(t.thumb, t.tlength); + } else { + err = img->loadPPMFromMemory(t.thumb, t.twidth, t.theight, false, 8); + } + if (err) { + delete img; + return nullptr; + } else { + return img; + } + } + } + + return nullptr; +} + + } //namespace rtengine bool diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 2b1cd2156..19d3a4bc6 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -21,14 +21,23 @@ #include #include #include +#include #include #include "dcraw.h" #include "imageformat.h" + +class LibRaw; + + namespace rtengine { + +class Image8; + + class RawImage: public DCraw { public: @@ -57,11 +66,18 @@ public: double getBaselineExposure() const { return RT_baseline_exposure; } protected: + enum class Decoder { + DCRAW, + LIBRAW, + }; + Glib::ustring filename; // complete filename int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif char* profile_data; // Embedded ICC color profile float* allocation; // pointer to allocated memory int maximum_c4[4]; + Decoder decoder{Decoder::DCRAW}; + std::unique_ptr libraw; bool isFoveon() const { return is_foveon; @@ -261,10 +277,7 @@ public: public: // dcraw functions - void pre_interpolate() - { - DCraw::pre_interpolate(); - } + void pre_interpolate(); public: bool ISRED(unsigned row, unsigned col) const @@ -304,6 +317,11 @@ public: { return dng_version; } + +public: + bool checkThumbOk() const; + Image8 *getThumbnail() const; + }; } diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index bc832661a..f497dce47 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -495,32 +495,14 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, eSensorType sensorType = ri->getSensorType(); - Image8* img = new Image8 (); - // No sample format detection occurred earlier, so we set them here, - // as they are mandatory for the setScanline method - img->setSampleFormat (IIOSF_UNSIGNED_CHAR); - img->setSampleArrangement (IIOSA_CHUNKY); - - int err = 1; - - // See if it is something we support - if (checkRawImageThumb (*ri)) { - 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 if (ri->is_ppmThumb()) { - err = img->loadPPMFromMemory (data, ri->get_thumbWidth(), ri->get_thumbHeight(), ri->get_thumbSwap(), ri->get_thumbBPS()); - } - } + Image8 *img = ri->getThumbnail(); // did we succeed? - if ( err ) { + if (!img) { if (settings->verbose) { std::cout << "Could not extract thumb from " << fname.c_str() << std::endl; } delete tpp; - delete img; delete ri; return nullptr; } @@ -627,6 +609,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens int width = ri->get_width(); int height = ri->get_height(); + int iwidth = ri->get_iwidth(); + int iheight = ri->get_iheight(); + int left_margin = ri->get_leftmargin(); + int top_margin = ri->get_topmargin(); + rtengine::Thumbnail* tpp = new rtengine::Thumbnail; tpp->isRaw = true; @@ -717,19 +704,19 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens if (ri->getSensorType() == ST_BAYER) { // demosaicing! (sort of) for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { - rofs = row * width; + rofs = (row + top_margin) * iwidth; for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col += hskip, x++) { - int ofs = rofs + col; + int ofs = rofs + col + left_margin; 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; + b = (image[ofs + iwidth][2] + image[ofs - iwidth][2]) >> 1; } else { b = (image[ofs + 1 ][2] + image[ofs - 1 ][2]) >> 1; - r = (image[ofs + width][0] + image[ofs - width][0]) >> 1; + r = (image[ofs + iwidth][0] + image[ofs - iwidth][0]) >> 1; } tmpImg->r (y, x) = r; @@ -739,28 +726,28 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens } } else if (ri->get_colors() == 1) { for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { - rofs = row * width; + rofs = (row + top_margin) * iwidth; for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col += hskip, x++) { - int ofs = rofs + col; + int ofs = rofs + col + left_margin; tmpImg->r (y, x) = tmpImg->g (y, x) = tmpImg->b (y, x) = image[ofs][0]; } } } else { if (ri->getSensorType() == ST_FUJI_XTRANS) { for ( int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { - rofs = row * width; + rofs = (row + top_margin) * iwidth; for ( int col = 1, x = 0; col < width - 1 && x < tmpw; col += hskip, x++ ) { - int ofs = rofs + col; + int ofs = rofs + col + left_margin; float sum[3] = {}; int c; for (int v = -1; v <= 1; v++) { for (int h = -1; h <= 1; h++) { c = ri->XTRANSFC (row + v, col + h); - sum[c] += image[ofs + v * width + h][c]; + sum[c] += image[ofs + v * iwidth + h][c]; } } @@ -788,11 +775,11 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, eSensorType &sens } } } else { - int iwidth = ri->get_iwidth(); - int iheight = ri->get_iheight(); - int left_margin = ri->get_leftmargin(); + // int iwidth = ri->get_iwidth(); + // int iheight = ri->get_iheight(); + // int left_margin = ri->get_leftmargin(); firstgreen += left_margin; - int top_margin = ri->get_topmargin(); + // int top_margin = ri->get_topmargin(); int wmax = tmpw; int hmax = tmph; From 32aca270ecfc8ac6b7ce2da658479e3743ce8041 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 2 Dec 2023 08:24:42 +0100 Subject: [PATCH 064/291] LA exposure hide show sliders when expcomp different from zero (#6892) --- rtgui/locallabtools.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 8bf88724c..562cbf674 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -3056,6 +3056,23 @@ void LocallabExposure::read(const rtengine::procparams::ProcParams* pp, const Pa structexp->setValue(spot.structexp); blurexpde->setValue(spot.blurexpde); expcomp->setValue(spot.expcomp); + + if(expcomp->getValue()== 0.) { + black->hide(); + hlcompr->hide(); + hlcomprthresh->hide(); + shadex->hide(); + shcompr->hide(); + expchroma->hide(); + } else { + black->show(); + hlcompr->show(); + hlcomprthresh->show(); + shadex->show(); + shcompr->show(); + expchroma->show(); + } + black->setValue(spot.black); hlcompr->setValue(spot.hlcompr); hlcomprthresh->setValue(spot.hlcomprthresh); @@ -3353,6 +3370,22 @@ void LocallabExposure::adjusterChanged(Adjuster* a, double newval) } if (a == expcomp) { + if(expcomp->getValue()== 0.) { + black->hide(); + hlcompr->hide(); + hlcomprthresh->hide(); + shadex->hide(); + shcompr->hide(); + expchroma->hide(); + } else { + black->show(); + hlcompr->show(); + hlcomprthresh->show(); + shadex->show(); + shcompr->show(); + expchroma->show(); + } + if (listener) { listener->panelChanged(Evlocallabexpcomp, expcomp->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); From 478e04e307bd37334b89c8e2eb9075cf952a13d8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 2 Dec 2023 12:00:47 -0800 Subject: [PATCH 065/291] Remove pre-dev publish branches --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index c9965b9b3..0d3c76399 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:ladehazeblack"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1143c948d..9b49edd91 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:ladehazeblack"]' + publish_pre_dev_labels: '[]' jobs: build: From 92b3c46ba3e59feacdd02db8d6bbc3cc87296ce5 Mon Sep 17 00:00:00 2001 From: Christian Kr Date: Mon, 4 Dec 2023 13:09:14 +0100 Subject: [PATCH 066/291] Exclude cmake-build directory from git. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e67dc3511..dbb6d72ad 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ cmake_install.cmake install_manifest.txt build* +cmake-build* Build* Debug RelWithDebInfo From 31bf942d9294bbb8bd174cd4cc77ec7c87833b91 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 17 Dec 2023 08:37:20 +0100 Subject: [PATCH 067/291] Local adjustments - Show additional settings - link with complexity (#6899) * Change hishow -additional seeting - with complexity * Modify windows.yml and appimage.yml * Fixed bug in duplicate spot * Remove pre-dev builds --- rtengine/procparams.cc | 2 +- rtgui/locallab.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e9101a5aa..afbce8849 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2987,7 +2987,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : avoidrad(0.), transitweak(1.0), transitgrad(0.0), - hishow(false), + hishow(options.complexity != 2), activ(true), blwh(false), recurs(false), diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index e7725a005..51fccd412 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -845,6 +845,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r->colorde = newSpot->colorde; r->colorscope = newSpot->colorscope; r->avoidrad = newSpot->avoidrad; + r->hishow = newSpot->hishow; r->activ = newSpot->activ; r->blwh = newSpot->blwh; r->recurs = newSpot->recurs; From f296991419715c9fed59d57805741897c0d88c3a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:45:03 -0800 Subject: [PATCH 068/291] Implement DNG gain map for LibRaw --- rtengine/dcraw.cc | 108 +----------------------- rtengine/dcraw.h | 8 -- rtengine/imagedata.cc | 166 +++++++++++++++++++++++++++++++++++++ rtengine/imagedata.h | 3 + rtengine/imagesource.h | 6 +- rtengine/rawimagesource.cc | 65 ++++++++++++++- rtengine/rtengine.h | 8 +- rtgui/cacheimagedata.cc | 4 + rtgui/cacheimagedata.h | 2 + 9 files changed, 248 insertions(+), 122 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index efa119d07..4fd01259c 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6958,48 +6958,8 @@ it under the terms of the one of two licenses as you choose: break; } case 51009: /* OpcodeList2 */ - { - meta_offset = ftell(ifp); - const unsigned oldOrder = order; - order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7 - unsigned ntags = get4(); // read the number of opcodes - if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310) - while (ntags-- && !ifp->eof) { - unsigned opcode = get4(); - if (opcode == 9 && gainMaps.size() < 4) { - fseek(ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte - fseek(ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently - GainMap gainMap; - gainMap.Top = get4(); - gainMap.Left = get4(); - gainMap.Bottom = get4(); - gainMap.Right = get4(); - gainMap.Plane = get4(); - gainMap.Planes = get4(); - gainMap.RowPitch = get4(); - gainMap.ColPitch = get4(); - gainMap.MapPointsV = get4(); - gainMap.MapPointsH = get4(); - gainMap.MapSpacingV = getreal(12); - gainMap.MapSpacingH = getreal(12); - gainMap.MapOriginV = getreal(12); - gainMap.MapOriginH = getreal(12); - gainMap.MapPlanes = get4(); - const std::size_t n = static_cast(gainMap.MapPointsV) * static_cast(gainMap.MapPointsH) * static_cast(gainMap.MapPlanes); - gainMap.MapGain.reserve(n); - for (std::size_t i = 0; i < n; ++i) { - gainMap.MapGain.push_back(getreal(11)); - } - gainMaps.push_back(std::move(gainMap)); - } else { - fseek(ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently - fseek(ifp, get4(), SEEK_CUR); - } - } - } - order = oldOrder; - break; - } + meta_offset = ftell(ifp); + break; case 64772: /* Kodak P-series */ if (len < 13) break; fseek (ifp, 16, SEEK_CUR); @@ -11123,70 +11083,6 @@ void CLASS nikon_14bit_load_raw() free(buf); } -bool CLASS isGainMapSupported() const { - if (!(dng_version && isBayer())) { - return false; - } - const auto n = gainMaps.size(); - if (n != 4) { // we need 4 gainmaps for bayer files - if (rtengine::settings->verbose) { - std::cout << "GainMap has " << n << " maps, but 4 are needed" << std::endl; - } - return false; - } - unsigned int check = 0; - bool noOp = true; - for (const auto &m : gainMaps) { - if (m.MapGain.size() < 1) { - if (rtengine::settings->verbose) { - std::cout << "GainMap has invalid size of " << m.MapGain.size() << std::endl; - } - return false; - } - if (m.MapGain.size() != static_cast(m.MapPointsV) * static_cast(m.MapPointsH) * static_cast(m.MapPlanes)) { - if (rtengine::settings->verbose) { - std::cout << "GainMap has size of " << m.MapGain.size() << ", but needs " << m.MapPointsV * m.MapPointsH * m.MapPlanes << std::endl; - } - return false; - } - if (m.RowPitch != 2 || m.ColPitch != 2) { - if (rtengine::settings->verbose) { - std::cout << "GainMap needs Row/ColPitch of 2/2, but has " << m.RowPitch << "/" << m.ColPitch << std::endl; - } - return false; - } - if (m.Top == 0){ - if (m.Left == 0) { - check += 1; - } else if (m.Left == 1) { - check += 2; - } - } else if (m.Top == 1) { - if (m.Left == 0) { - check += 4; - } else if (m.Left == 1) { - check += 8; - } - } - for (size_t i = 0; noOp && i < m.MapGain.size(); ++i) { - if (m.MapGain[i] != 1.f) { // we have at least one value != 1.f => map is not a nop - noOp = false; - } - } - } - if (noOp || check != 15) { // all maps are nops or the structure of the combination of 4 maps is not correct - if (rtengine::settings->verbose) { - if (noOp) { - std::cout << "GainMap is a nop" << std::endl; - } else { - std::cout << "GainMap has unsupported type : " << check << std::endl; - } - } - return false; - } - return true; -} - /* RT: Delete from here */ /*RT*/#undef SQR /*RT*/#undef MAX diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 4501aef67..2bf8f2965 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -24,7 +24,6 @@ #include "myfile.h" #include -#include "dnggainmap.h" #include "settings.h" class DCraw @@ -170,7 +169,6 @@ protected: PanasonicRW2Info(): bpp(0), encoding(0) {} }; PanasonicRW2Info RT_pana_info; - std::vector gainMaps; public: struct CanonCR3Data { @@ -206,12 +204,6 @@ public: return (filters != 0 && filters != 9); } - const std::vector& getGainMaps() const { - return gainMaps; - } - - bool isGainMapSupported() const; - struct CanonLevelsData { unsigned cblack[4]; unsigned white; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 735519d99..eff903ce6 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -16,6 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include #include #include @@ -27,6 +28,7 @@ #include #include +#include "dnggainmap.h" #include "imagedata.h" #include "imagesource.h" #include "metadata.h" @@ -63,6 +65,154 @@ auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( #endif } +/** + * Convenience class for reading data from a metadata tag's bytes value. + * + * It maintains an offset. Data is read starting from the offset, then the + * offset is advanced to the byte after the last byte read. + */ +class TagValueReader +{ + using DataContainer = std::vector; + using DataOffset = DataContainer::difference_type; + + DataContainer data; + DataOffset offset{0}; + Exiv2::ByteOrder defaultByteOrder; + + /** + * Reads a value at the current offset. + * + * @tparam T Value's type. + * @tparam getter Function that interprets the data using a given byte order + * and returns the value at a given location. + * @return The value. + */ + template + T readValue() + { + T value = getter(data.data() + offset, defaultByteOrder); + offset += sizeof(T); + return value; + } + +public: + /** + * Creates a reader for the given value with the given byte order. + * + * @param value The value. + * @param defaultByteOrder The byte order of the value's data. + */ + TagValueReader(const Exiv2::Value &value, Exiv2::ByteOrder defaultByteOrder = Exiv2::bigEndian) : + data(value.size()), + defaultByteOrder(defaultByteOrder) + { + value.copy(data.data(), Exiv2::invalidByteOrder); + } + + /** + * Returns the value's size in bytes. + */ + std::size_t size() const + { + return data.size(); + } + + /** + * Checks if the current offset is at or beyond the end of the data. + */ + bool isEnd() const + { + return offset > 0 && static_cast(offset) >= data.size(); + } + + /** + * Reads a double from the current offset and advances the offset. + */ + double readDouble() + { + return readValue(); + } + + /** + * Reads a float from the current offset and advances the offset. + */ + float readFloat() + { + return readValue(); + } + + /** + * Reads an unsigned integer from the current offset and advances the + * offset. + */ + std::uint32_t readUInt() + { + return readValue(); + } + + /** + * Sets the offset. + */ + void seekAbsolute(DataOffset newOffset) + { + offset = newOffset; + } + + /** + * Advances the offset by the given amount. + */ + void seekRelative(DataOffset offsetDifference) + { + offset += offsetDifference; + } +}; + +GainMap readGainMap(TagValueReader &reader) +{ + reader.seekRelative(4); // skip 4 bytes as we know that the opcode 4 takes 4 byte + reader.seekRelative(8); // skip 8 bytes as they don't interest us currently + GainMap gainMap; + gainMap.Top = reader.readUInt(); + gainMap.Left = reader.readUInt(); + gainMap.Bottom = reader.readUInt(); + gainMap.Right = reader.readUInt(); + gainMap.Plane = reader.readUInt(); + gainMap.Planes = reader.readUInt(); + gainMap.RowPitch = reader.readUInt(); + gainMap.ColPitch = reader.readUInt(); + gainMap.MapPointsV = reader.readUInt(); + gainMap.MapPointsH = reader.readUInt(); + gainMap.MapSpacingV = reader.readDouble(); + gainMap.MapSpacingH = reader.readDouble(); + gainMap.MapOriginV = reader.readDouble(); + gainMap.MapOriginH = reader.readDouble(); + gainMap.MapPlanes = reader.readUInt(); + const std::size_t n = static_cast(gainMap.MapPointsV) * static_cast(gainMap.MapPointsH) * static_cast(gainMap.MapPlanes); + gainMap.MapGain.reserve(n); + for (std::size_t i = 0; i < n; ++i) { + gainMap.MapGain.push_back(reader.readFloat()); + } + return gainMap; +} + +void readOpcodesList(const Exiv2::Value &value, std::vector &gainMaps) +{ + TagValueReader reader(value); + std::uint32_t ntags = reader.readUInt(); // read the number of opcodes + if (ntags >= reader.size() / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310) + return; + } + while (ntags-- && !reader.isEnd()) { + unsigned opcode = reader.readUInt(); + if (opcode == 9 && gainMaps.size() < 4) { + gainMaps.push_back(readGainMap(reader)); + } else { + reader.seekRelative(8); // skip 8 bytes as they don't interest us currently + reader.seekRelative(reader.readUInt()); + } + } +} } namespace rtengine { @@ -675,6 +825,18 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : #endif } } + + uint32_t dngVersion = 0; + if (find_exif_tag("Exif.Image.DNGVersion") && pos->count() == 4) { + for (int i = 0; i < 4; i++) { + dngVersion = (dngVersion << 8) + static_cast(to_long(pos, i)); + } + } + + // Read gain maps. + if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList2") || find_exif_tag("Exif.Image.OpcodeList2"))) { + readOpcodesList(pos->value(), gain_maps_); + } } catch (const std::exception& e) { if (settings->verbose) { std::cerr << "EXIV2 ERROR: " << e.what() << std::endl; @@ -916,6 +1078,10 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const set_exif(exif, "Exif.Photo.DateTimeOriginal", buf); } +std::vector FramesData::getGainMaps() const +{ + return gain_maps_; +} void FramesData::getDimensions(int &w, int &h) const { diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 08f55bd62..434b96a52 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -22,6 +22,7 @@ #include #include +#include "dnggainmap.h" #include "imageio.h" #include "metadata.h" @@ -59,6 +60,7 @@ private: time_t modTimeStamp; bool isPixelShift; bool isHDR; + std::vector gain_maps_; int w_; int h_; @@ -88,6 +90,7 @@ public: std::string getOrientation() const override; Glib::ustring getFileName() const override; int getRating() const override; + std::vector getGainMaps() const override; void getDimensions(int &w, int &h) const override; void fillBasicTags(Exiv2::ExifData &exif) const; diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 95fd77d21..058ef8ff2 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -177,15 +177,15 @@ public: return dirpyrdenoiseExpComp; } // functions inherited from the InitialImage interface - Glib::ustring getFileName () final + Glib::ustring getFileName() const final override { return fileName; } - cmsHPROFILE getEmbeddedProfile () final + cmsHPROFILE getEmbeddedProfile() const final override { return embProfile; } - const FramesMetaData* getMetaData () final + const FramesMetaData *getMetaData() const final override { return idata; } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index eabeb2fc9..7c77d57c6 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1503,7 +1503,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens //FLATFIELD end if (raw.ff_FromMetaData && isGainMapSupported()) { - applyDngGainMap(c_black, ri->getGainMaps()); + applyDngGainMap(c_black, getMetaData()->getGainMaps()); } // Always correct camera badpixels from .badpixels file @@ -8308,7 +8308,68 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int bool RawImageSource::isGainMapSupported() const { - return ri->isGainMapSupported(); + if (!(ri->DNGVERSION() && ri->isBayer())) { + return false; + } + const auto &gainMaps = getMetaData()->getGainMaps(); + const auto n = gainMaps.size(); + if (n != 4) { // we need 4 gainmaps for bayer files + if (rtengine::settings->verbose) { + std::cout << "GainMap has " << n << " maps, but 4 are needed" << std::endl; + } + return false; + } + unsigned int check = 0; + bool noOp = true; + for (const auto &m : gainMaps) { + if (m.MapGain.size() < 1) { + if (rtengine::settings->verbose) { + std::cout << "GainMap has invalid size of " << m.MapGain.size() << std::endl; + } + return false; + } + if (m.MapGain.size() != static_cast(m.MapPointsV) * static_cast(m.MapPointsH) * static_cast(m.MapPlanes)) { + if (rtengine::settings->verbose) { + std::cout << "GainMap has size of " << m.MapGain.size() << ", but needs " << m.MapPointsV * m.MapPointsH * m.MapPlanes << std::endl; + } + return false; + } + if (m.RowPitch != 2 || m.ColPitch != 2) { + if (rtengine::settings->verbose) { + std::cout << "GainMap needs Row/ColPitch of 2/2, but has " << m.RowPitch << "/" << m.ColPitch << std::endl; + } + return false; + } + if (m.Top == 0) { + if (m.Left == 0) { + check += 1; + } else if (m.Left == 1) { + check += 2; + } + } else if (m.Top == 1) { + if (m.Left == 0) { + check += 4; + } else if (m.Left == 1) { + check += 8; + } + } + for (size_t i = 0; noOp && i < m.MapGain.size(); ++i) { + if (m.MapGain[i] != 1.f) { // we have at least one value != 1.f => map is not a nop + noOp = false; + } + } + } + if (noOp || check != 15) { // all maps are nops or the structure of the combination of 4 maps is not correct + if (rtengine::settings->verbose) { + if (noOp) { + std::cout << "GainMap is a nop" << std::endl; + } else { + std::cout << "GainMap has unsupported type : " << check << std::endl; + } + } + return false; + } + return true; } void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ba4d2ed60..0db06849a 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -51,6 +51,7 @@ class LUT; using LUTu = LUT; class EditDataProvider; +class GainMap; namespace rtengine { @@ -158,6 +159,7 @@ public: static FramesMetaData* fromFile(const Glib::ustring& fname); virtual Glib::ustring getFileName() const = 0; + virtual std::vector getGainMaps() const = 0; virtual void getDimensions(int &w, int &h) const = 0; }; @@ -192,13 +194,13 @@ class InitialImage public: /** Returns the file name of the image. * @return The file name of the image */ - virtual Glib::ustring getFileName () = 0; + virtual Glib::ustring getFileName() const = 0; /** Returns the embedded icc profile of the image. * @return The handle of the embedded profile */ - virtual cmsHPROFILE getEmbeddedProfile () = 0; + virtual cmsHPROFILE getEmbeddedProfile() const = 0; /** Returns a class providing access to the exif and iptc metadata tags of all frames of the image. * @return An instance of the FramesMetaData class */ - virtual const FramesMetaData* getMetaData () = 0; + virtual const FramesMetaData *getMetaData() const = 0; /** This is a function used for internal purposes only. */ virtual ImageSource* getImageSource () = 0; /** This class has manual reference counting. You have to call this function each time to make a new reference to an instance. */ diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index bfc4e920a..13a2e31e0 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -362,3 +362,7 @@ int CacheImageData::save (const Glib::ustring& fname) } } +std::vector CacheImageData::getGainMaps() const +{ + return std::vector(); +} diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 8c0fa6513..12c4ed476 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -22,6 +22,7 @@ #include "options.h" +#include "../rtengine/dnggainmap.h" #include "../rtengine/imageformat.h" #include "../rtengine/rtengine.h" @@ -116,6 +117,7 @@ public: bool getHDR() const override { return isHDR; } std::string getImageType() const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat() const override { return sampleFormat; } + std::vector getGainMaps() const override; void getDimensions(int &w, int &h) const override { w = width; From 2b7889b6455aaee2abd9ef6ad49ae0c9ac002cd0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 17 Dec 2023 15:34:12 -0800 Subject: [PATCH 069/291] Add option to disable LibRaw in preferences --- rtdata/languages/default | 2 ++ rtengine/rawimage.cc | 12 ++++++++++-- rtengine/settings.h | 1 + rtgui/options.cc | 11 +++++++++++ rtgui/preferences.cc | 12 ++++++++++++ rtgui/preferences.h | 2 ++ 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 185191bcd..70e351595 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1994,6 +1994,8 @@ PREFERENCES_PROPERTY;Property PREFERENCES_PRTINTENT;Rendering intent PREFERENCES_PRTPROFILE;Color profile PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_RAW_DECODER;Raw Decoder +PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index d96993a0d..4577a3f63 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -492,8 +492,14 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog shot_select = imageNum; - libraw.reset(new LibRaw()); + if (settings->enableLibRaw) { + libraw.reset(new LibRaw()); + } int libraw_error = [&]() -> int { + if (!settings->enableLibRaw) { + return LIBRAW_SUCCESS; + } + libraw->imgdata.params.use_camera_wb = 1; int err = libraw->open_buffer(ifp->data, ifp->size); @@ -654,7 +660,9 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog return libraw_error; } } else { - libraw->recycle(); + if (libraw) { + libraw->recycle(); + } } if (decoder == Decoder::DCRAW) { diff --git a/rtengine/settings.h b/rtengine/settings.h index fbbb51bbb..383611c2a 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -51,6 +51,7 @@ public: Glib::ustring flatFieldsPath; ///< The default directory for flat fields Glib::ustring cameraProfilesPath; ///< The default directory for camera profiles Glib::ustring lensProfilesPath; ///< The default directory for lens profiles + bool enableLibRaw; ///< Use LibRaw to decode raw images. Glib::ustring adobe; // filename of AdobeRGB1998 profile (default to the bundled one) Glib::ustring prophoto; // filename of Prophoto profile (default to the bundled one) diff --git a/rtgui/options.cc b/rtgui/options.cc index 61d67f9b6..cc3ca6cca 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -591,6 +591,7 @@ void Options::setDefaults() #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif + rtSettings.enableLibRaw = true; // rtSettings.viewingdevice = 0; // rtSettings.viewingdevicegrey = 3; // rtSettings.viewinggreySc = 1; @@ -1745,6 +1746,14 @@ void Options::readFromFile(Glib::ustring fname) } } + const Glib::ustring groupRawDecoder = "Raw Decoder"; + if (keyFile.has_group(groupRawDecoder)) { + const Glib::ustring keyEnableLibRaw = "EnableLibRaw"; + if (keyFile.has_key(groupRawDecoder, keyEnableLibRaw)) { + rtSettings.enableLibRaw = keyFile.get_boolean(groupRawDecoder, keyEnableLibRaw); + } + } + if (keyFile.has_group("Color Management")) { if (keyFile.has_key("Color Management", "ICCDirectory")) { rtSettings.iccDirectory = keyFile.get_string("Color Management", "ICCDirectory"); @@ -2590,6 +2599,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("Crop Settings", "GuidesMode", cropGuides); keyFile.set_boolean("Crop Settings", "AutoFit", cropAutoFit); + keyFile.set_boolean("Raw Decoder", "EnableLibRaw", rtSettings.enableLibRaw); + keyFile.set_string("Color Management", "PrinterProfile", rtSettings.printerProfile); keyFile.set_integer("Color Management", "PrinterIntent", rtSettings.printerIntent); keyFile.set_boolean("Color Management", "PrinterBPC", rtSettings.printerBPC); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 103075274..c9d360e7e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -744,6 +744,14 @@ Gtk::Widget* Preferences::getImageProcessingPanel () cropFrame->add(*cropGrid); vbImageProcessing->pack_start(*cropFrame, Gtk::PACK_SHRINK, 4); + Gtk::Frame *rawDecoderFrame = Gtk::manage(new Gtk::Frame(M("PREFERENCES_RAW_DECODER"))); + Gtk::Box *rawDecoderContainer = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + rawDecoderFrame->add(*rawDecoderContainer); + enableLibRaw = Gtk::manage(new Gtk::CheckButton()); + enableLibRaw->add(*Gtk::manage(new Gtk::Label(M("PREFERENCES_RAW_DECODER_ENABLE_LIBRAW")))); + rawDecoderContainer->pack_start(*enableLibRaw); + vbImageProcessing->pack_start(*rawDecoderFrame, Gtk::PACK_SHRINK, 4); + swImageProcessing->add(*vbImageProcessing); return swImageProcessing; @@ -1995,6 +2003,8 @@ void Preferences::storePreferences() moptions.cropGuides = Options::CropGuidesMode(cropGuidesCombo->get_active_row_number()); moptions.cropAutoFit = cropAutoFitCB->get_active(); + moptions.rtSettings.enableLibRaw = enableLibRaw->get_active(); + toolLocationPreference->updateOptions(); moptions.rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync(metadataSyncCombo->get_active_row_number()); @@ -2229,6 +2239,8 @@ void Preferences::fillPreferences() cropGuidesCombo->set_active(moptions.cropGuides); cropAutoFitCB->set_active(moptions.cropAutoFit); + enableLibRaw->set_active(moptions.rtSettings.enableLibRaw); + addc.block(false); setc.block(false); cpfconn.block(false); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 219844d55..4135b9792 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -249,6 +249,8 @@ class Preferences final : Gtk::ComboBoxText *cropGuidesCombo; Gtk::CheckButton *cropAutoFitCB; + Gtk::CheckButton *enableLibRaw; + Gtk::ComboBoxText *metadataSyncCombo; Gtk::ComboBoxText *xmpSidecarCombo; From dca44bb89aabc4ea17dae6e80dac7b7311160aef Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 31 Dec 2023 12:00:45 -0800 Subject: [PATCH 070/291] Fix crash loading multi-frame RAFs with LibRaw Set the frame number when reading image metadata. --- rtengine/rawimage.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 4577a3f63..45c89ca7c 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -501,6 +501,7 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog } libraw->imgdata.params.use_camera_wb = 1; + libraw->imgdata.rawparams.shot_select = shot_select; int err = libraw->open_buffer(ifp->data, ifp->size); if (err == LIBRAW_FILE_UNSUPPORTED || err == LIBRAW_TOO_BIG) { From e599f71bf21bdaa03f7c172cf886271a9775bc8e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 31 Dec 2023 12:03:16 -0800 Subject: [PATCH 071/291] Remove unused rawimage functions Prevent accidental use of these functions that will not supply the correct data when using LibRaw. --- rtengine/rawimage.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 19d3a4bc6..cc19998f8 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -207,19 +207,6 @@ public: 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; From ebf5b422be49cbae1bbf983db40276c18cf8e706 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 31 Dec 2023 12:33:01 -0800 Subject: [PATCH 072/291] Use proper include for LibRaw The include directory for LibRaw is properly set by CMake so `#include ` will work for both the internal and system versions. --- rtengine/rawimage.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 45c89ca7c..c7aca8b05 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -13,13 +13,14 @@ #include #endif +#include + #include "image8.h" #include "rawimage.h" #include "settings.h" #include "camconst.h" #include "utils.h" #include "rtengine.h" -#include "libraw/libraw/libraw.h" namespace rtengine { From de5f92937857cccc45080c59c6236561416e5ece Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 31 Dec 2023 12:52:34 -0800 Subject: [PATCH 073/291] Squashed 'rtengine/libraw/' changes from cccb97647..1ef70158d 1ef70158d 0.21.2 release 62f042366 tag type => tag size mapping fixed ee087e3fe cubic_spline: better handling of non-integer data af755b991 extra metadata check in arq_load_raw 0fadd8819 Better incorrect data handling in cubic_spline d7fb66053 skip invalid pattern in xtrans_interpolate d059ed280 Check HL recovery coeffs before processing 104730519 limit wavelet denoise minimum size cae09838e raw-identify: use fallback if PATH_MAX not available d6c677608 additional check against corrupted ljpeg layout 1001a6ac1 Disable color conversion for Canon 16-bit thumbnails a5130b01b docs/changelog: explained the case when no thumbnail is found in specific file 600c0c63d rename swapXX to libraw_swapXX to avoid name conflict 299c8a11b Check against corrupted LJPEG header in Canon sRAW decoder ec8671ad9 Limit embedded color profile allocation/read size 5229d5942 Wrong alloc result check for 16-bit bitmap thumbnail b278b775f check pana_data/buffer offset before use 7f4b8d3af Check P1 quadrant linearization coeff[15] against zero e942a7db6 avoid integer overflow in buffer space check f6a57cfb8 prevent buffer overrun in buffer_datastream::scanf_one 3e62ed304 ensure correct T.tlength for 16b bitmap thumbnails(2) 8e52d81cd ensure correct T.tlength for 16b bitmap thumbnails 8e1af15e2 Do not run sraw decoder on (crafted) bayer files 0ace959c2 better striped thumbnails handling 477e0719f do not set shrink flag for 3/4 component images c8efae6c5 allow more decoders for fuji-rotated RAWs git-subtree-dir: rtengine/libraw git-subtree-split: 1ef70158d7fde1ced6aaddb0b9443c32a7121d3d --- Changelog.txt | 28 +++++++++++++- doc/API-datastruct.html | 6 +++ libraw/libraw_const.h | 4 ++ libraw/libraw_version.h | 2 +- samples/raw-identify.cpp | 4 ++ src/decoders/decoders_dcraw.cpp | 11 ++++++ src/decoders/decoders_libraw.cpp | 3 ++ src/decoders/fp_dng.cpp | 8 ++-- src/decoders/load_mfbacks.cpp | 13 +++++-- src/decoders/unpack_thumb.cpp | 23 +++++++----- src/demosaic/xtrans_demosaic.cpp | 4 ++ src/libraw_datastream.cpp | 2 +- src/metadata/fuji.cpp | 6 +-- src/postprocessing/postprocessing_aux.cpp | 7 ++++ src/preprocessing/raw2image.cpp | 2 + src/tables/wblists.cpp | 6 +-- src/utils/curves.cpp | 7 +++- src/utils/open.cpp | 17 +++++++-- src/utils/thumb_utils.cpp | 46 ++++++++++++++--------- 19 files changed, 150 insertions(+), 49 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 7534563b6..42c2bb2b5 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,25 @@ +2023-12-19 Alex Tutubalin + + LibRaw 0.21.2-Release + + * New compile-defined limit LIBRAW_MAX_PROFILE_SIZE_MB: + limits allocation/read size for embedded color profile (default: 256Mb) + + * Embedded color profile allocation/read size: limited by input file size. + + * Multiple fixes (mostly inspired by oss-fuzz) to improve library stability and/or input checks. + + * raw-identify: use fallback if PATH_MAX not available + + * Disabled color conversion for Canon 16-bit thumbnails + + * docs/changelog: explained the case when no thumbnail is found in specific file + + * swapXX renamed to libraw_swapXX to avoid name conflict + + * better striped thumbnails handling + + 2023-01-05 Alex Tutubalin LibRaw 0.21.1-Release * fixed typo in panasonic metadata parser @@ -52,7 +74,11 @@ Notes: - Only TIFF-based and CR3 files are parsed for thumbnail list, other formats will have - thumbcount = 1 (or 0 if no thumbnail found in file). + thumbcount = 1. + + - If no thumbnails are found in file: thumbcount will be set to 1 and + thumblist[0] will be initialized with data from thumbnail fields, + so LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb() - Thumbnail image size may be unknown (not recorded in metadata), in this case twidth and theight are zero. Usually small(er) thumbnails will always have twidth/theight filled, while largest one may have these fields set to zero. diff --git a/doc/API-datastruct.html b/doc/API-datastruct.html index 09c05ac76..5c2ddb3bf 100644 --- a/doc/API-datastruct.html +++ b/doc/API-datastruct.html @@ -427,6 +427,12 @@ +

+ Note: even if no thumbnails were found in TIFF/CR3 structure, the + thumbcount field will be initialized to 1 and thumblist[0] will be + initialized to thumbnail data from the thumbnail data, so + LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb(). +

Structure libraw_lensinfo_t: parsed lens data

The following parameters are extracted from Makernotes and EXIF, to help diff --git a/libraw/libraw_const.h b/libraw/libraw_const.h index 599306b6f..61f8028b2 100644 --- a/libraw/libraw_const.h +++ b/libraw/libraw_const.h @@ -24,6 +24,10 @@ it under the terms of the one of two licenses as you choose: #define LIBRAW_MAX_ALLOC_MB_DEFAULT 2048L #endif +#ifndef LIBRAW_MAX_PROFILE_SIZE_MB +#define LIBRAW_MAX_PROFILE_SIZE_MB 256LL +#endif + #ifndef LIBRAW_MAX_NONDNG_RAW_FILE_SIZE #define LIBRAW_MAX_NONDNG_RAW_FILE_SIZE 2147483647ULL #endif diff --git a/libraw/libraw_version.h b/libraw/libraw_version.h index 3845a5e46..c6f5c72a3 100644 --- a/libraw/libraw_version.h +++ b/libraw/libraw_version.h @@ -22,7 +22,7 @@ it under the terms of the one of two licenses as you choose: #define LIBRAW_MAJOR_VERSION 0 #define LIBRAW_MINOR_VERSION 21 -#define LIBRAW_PATCH_VERSION 1 +#define LIBRAW_PATCH_VERSION 2 #define LIBRAW_VERSION_TAIL Release #define LIBRAW_SHLIB_CURRENT 23 diff --git a/samples/raw-identify.cpp b/samples/raw-identify.cpp index ced518175..31c770d34 100644 --- a/samples/raw-identify.cpp +++ b/samples/raw-identify.cpp @@ -40,7 +40,11 @@ it under the terms of the one of two licenses as you choose: #include #include #ifndef MAX_PATH +#ifdef PATH_MAX #define MAX_PATH PATH_MAX +#else +#define MAX_PATH 4096 +#endif #endif #endif diff --git a/src/decoders/decoders_dcraw.cpp b/src/decoders/decoders_dcraw.cpp index 721d38577..090a6b726 100644 --- a/src/decoders/decoders_dcraw.cpp +++ b/src/decoders/decoders_dcraw.cpp @@ -577,6 +577,9 @@ void LibRaw::lossless_jpeg_load_raw() i = jidx / (cr2_slice[1] * raw_height); if ((j = i >= cr2_slice[0])) i = cr2_slice[0]; + if(!cr2_slice[1+j]) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + jidx -= i * (cr2_slice[1] * raw_height); row = jidx / cr2_slice[1 + j]; col = jidx % cr2_slice[1 + j] + i * cr2_slice[1]; @@ -609,10 +612,16 @@ void LibRaw::canon_sraw_load_raw() int saved_w = width, saved_h = height; char *cp; + if(!image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (!ljpeg_start(&jh, 0) || jh.clrs < 4) return; jwide = (jh.wide >>= 1) * jh.clrs; + if (jwide < 32 || jwide > 65535) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (load_flags & 256) { width = raw_width; @@ -1170,6 +1179,8 @@ void LibRaw::panasonic_load_raw() } else { + if (load_flags >= 0x4000) + throw LIBRAW_EXCEPTION_IO_CORRUPT; for (row = 0; row < raw_height; row++) { checkCancel(); diff --git a/src/decoders/decoders_libraw.cpp b/src/decoders/decoders_libraw.cpp index 332e2af21..bc62a6c2d 100644 --- a/src/decoders/decoders_libraw.cpp +++ b/src/decoders/decoders_libraw.cpp @@ -22,6 +22,9 @@ void LibRaw::sony_arq_load_raw() { int row, col; + if (imgdata.idata.filters || imgdata.idata.colors < 3) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + read_shorts(imgdata.rawdata.raw_image, imgdata.sizes.raw_width * imgdata.sizes.raw_height * 4); libraw_internal_data.internal_data.input->seek( diff --git a/src/decoders/fp_dng.cpp b/src/decoders/fp_dng.cpp index 0566ad2ca..72631dbbd 100644 --- a/src/decoders/fp_dng.cpp +++ b/src/decoders/fp_dng.cpp @@ -556,7 +556,7 @@ _forceinline #else inline #endif -void swap24(uchar *data, int len) +void libraw_swap24(uchar *data, int len) { for (int i = 0; i < len - 2; i += 3) { @@ -572,7 +572,7 @@ _forceinline #else inline #endif -void swap32(uchar *data, int len) +void libraw_swap32(uchar *data, int len) { unsigned *d = (unsigned*)data; for (int i = 0; i < len / 4; i++) @@ -646,9 +646,9 @@ void LibRaw::uncompressed_fp_dng_load_raw() if (bytesps == 2 && difford) libraw_swab(dst, fullrowbytes); else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit - swap24(dst, fullrowbytes); + libraw_swap24(dst, fullrowbytes); if (bytesps == 4 && difford) - swap32(dst, fullrowbytes); + libraw_swap32(dst, fullrowbytes); float lmax = expandFloats( dst, diff --git a/src/decoders/load_mfbacks.cpp b/src/decoders/load_mfbacks.cpp index 493c7859f..cddc33ebc 100644 --- a/src/decoders/load_mfbacks.cpp +++ b/src/decoders/load_mfbacks.cpp @@ -352,10 +352,17 @@ int LibRaw::phase_one_correct() { /* Quadrant linearization */ ushort lc[2][2][16], ref[16]; int qr, qc; + bool baddiv = false; for (qr = 0; qr < 2; qr++) - for (qc = 0; qc < 2; qc++) - for (i = 0; i < 16; i++) - lc[qr][qc][i] = get4(); + for (qc = 0; qc < 2; qc++) + { + for (i = 0; i < 16; i++) + lc[qr][qc][i] = get4(); + if (lc[qr][qc][15] == 0) + baddiv = true; + } + if(baddiv) + continue; for (i = 0; i < 16; i++) { int v = 0; diff --git a/src/decoders/unpack_thumb.cpp b/src/decoders/unpack_thumb.cpp index 1f01ddc12..4298c3750 100644 --- a/src/decoders/unpack_thumb.cpp +++ b/src/decoders/unpack_thumb.cpp @@ -266,8 +266,9 @@ int LibRaw::unpack_thumb(void) tiff_ifd[pifd].strip_byte_counts_count) { // We found it, calculate final size - unsigned total_size = 0; - for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count; i++) + INT64 total_size = 0; + for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count + && i < tiff_ifd[pifd].strip_offsets_count; i++) total_size += tiff_ifd[pifd].strip_byte_counts[i]; if (total_size != (unsigned)t_length) // recalculate colors { @@ -284,15 +285,15 @@ int LibRaw::unpack_thumb(void) char *dest = T.thumb; INT64 pos = ID.input->tell(); + INT64 remain = T.tlength; for (int i = 0; i < tiff_ifd[pifd].strip_byte_counts_count && i < tiff_ifd[pifd].strip_offsets_count; i++) { - int remain = T.tlength; int sz = tiff_ifd[pifd].strip_byte_counts[i]; - int off = tiff_ifd[pifd].strip_offsets[i]; - if (off >= 0 && off + sz <= ID.input->size() && sz <= remain) + INT64 off = tiff_ifd[pifd].strip_offsets[i]; + if (off >= 0 && off + sz <= ID.input->size() && sz > 0 && INT64(sz) <= remain) { ID.input->seek(off, SEEK_SET); ID.input->read(dest, sz, 1); @@ -332,13 +333,13 @@ int LibRaw::unpack_thumb(void) int o_bps = (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1; int o_length = T.twidth * T.theight * t_colors * o_bps; int i_length = T.twidth * T.theight * t_colors * 2; - if (!T.tlength) - T.tlength = o_length; - THUMB_SIZE_CHECKTNZ(o_length); + + THUMB_SIZE_CHECKTNZ(o_length); THUMB_SIZE_CHECKTNZ(i_length); - THUMB_SIZE_CHECKTNZ(T.tlength); ushort *t_thumb = (ushort *)calloc(i_length, 1); + if (!t_thumb) + throw LIBRAW_EXCEPTION_ALLOC; ID.input->read(t_thumb, 1, i_length); if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234)) @@ -350,14 +351,18 @@ int LibRaw::unpack_thumb(void) { T.thumb = (char *)t_thumb; T.tformat = LIBRAW_THUMBNAIL_BITMAP16; + T.tlength = i_length; } else { T.thumb = (char *)malloc(o_length); + if (!T.thumb) + throw LIBRAW_EXCEPTION_ALLOC; for (int i = 0; i < o_length; i++) T.thumb[i] = t_thumb[i] >> 8; free(t_thumb); T.tformat = LIBRAW_THUMBNAIL_BITMAP; + T.tlength = o_length; } SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; diff --git a/src/demosaic/xtrans_demosaic.cpp b/src/demosaic/xtrans_demosaic.cpp index 5dbc3c3f6..2d96c62ef 100644 --- a/src/demosaic/xtrans_demosaic.cpp +++ b/src/demosaic/xtrans_demosaic.cpp @@ -265,6 +265,10 @@ void LibRaw::xtrans_interpolate(int passes) { rix = &rgb[0][row - top][col - left]; int h = fcol(row, col + 1); + + if (h == 1) // Incorrect pattern + break; + float diff[6]; memset(diff, 0, sizeof diff); for (int i = 1, d = 0; d < 6; d++, i ^= LIBRAW_AHD_TILE ^ 1, h ^= 2) diff --git a/src/libraw_datastream.cpp b/src/libraw_datastream.cpp index 898761de7..60593b42f 100644 --- a/src/libraw_datastream.cpp +++ b/src/libraw_datastream.cpp @@ -460,7 +460,7 @@ int LibRaw_buffer_datastream::scanf_one(const char *fmt, void *val) if (scanf_res > 0) { int xcnt = 0; - while (streampos < streamsize) + while (streampos < streamsize-1) { streampos++; xcnt++; diff --git a/src/metadata/fuji.cpp b/src/metadata/fuji.cpp index 4c9fe5025..feb394ef6 100644 --- a/src/metadata/fuji.cpp +++ b/src/metadata/fuji.cpp @@ -132,7 +132,7 @@ void LibRaw::parseAdobeRAFMakernote() } #define CHECKSPACE(s) \ - if (posPrivateMknBuf + (s) > PrivateMknLength) \ + if (INT64(posPrivateMknBuf) + INT64(s) > INT64(PrivateMknLength)) \ { \ free(PrivateMknBuf); \ return; \ @@ -209,7 +209,7 @@ void LibRaw::parseAdobeRAFMakernote() PrivateOrder = sget2(PrivateMknBuf); unsigned s, l; s = ifd_start = sget4(PrivateMknBuf +2)+6; - CHECKSPACE(ifd_start+4); + CHECKSPACE(INT64(ifd_start)+4LL); l = ifd_len = sget4(PrivateMknBuf +ifd_start); CHECKSPACE_ABS3(ifd_start, ifd_len, 4); @@ -767,7 +767,7 @@ void LibRaw::parseAdobeRAFMakernote() if (wb_section_offset) { - CHECKSPACE(wb_section_offset + 12); + CHECKSPACE(INT64(wb_section_offset) + 12LL); } if (wb_section_offset && diff --git a/src/postprocessing/postprocessing_aux.cpp b/src/postprocessing/postprocessing_aux.cpp index 57473400d..c8c53fa66 100644 --- a/src/postprocessing/postprocessing_aux.cpp +++ b/src/postprocessing/postprocessing_aux.cpp @@ -39,6 +39,7 @@ void LibRaw::wavelet_denoise() static const float noise[] = {0.8002f, 0.2735f, 0.1202f, 0.0585f, 0.0291f, 0.0152f, 0.0080f, 0.0044f}; + if (iwidth < 65 || iheight < 65) return; while (maximum << scale < 0x10000) scale++; @@ -135,6 +136,9 @@ void LibRaw::wavelet_denoise() static const float noise[] = {0.8002, 0.2735, 0.1202, 0.0585, 0.0291, 0.0152, 0.0080, 0.0044}; + if (iwidth < 65 || iheight < 65) + return; + while (maximum << scale < 0x10000) scale++; maximum <<= --scale; @@ -324,6 +328,9 @@ void LibRaw::recover_highlights() grow = pow(2.0, 4 - highlight); FORC(unsigned(colors)) hsat[c] = 32000 * pre_mul[c]; + FORC(unsigned(colors)) + if(hsat[c]<1) + return; for (kc = 0, c = 1; c < (unsigned)colors; c++) if (pre_mul[kc] < pre_mul[c]) kc = c; diff --git a/src/preprocessing/raw2image.cpp b/src/preprocessing/raw2image.cpp index e65e2ad73..702cf2902 100644 --- a/src/preprocessing/raw2image.cpp +++ b/src/preprocessing/raw2image.cpp @@ -43,6 +43,8 @@ void LibRaw::raw2image_start() // adjust for half mode! IO.shrink = + !imgdata.rawdata.color4_image && !imgdata.rawdata.color3_image && + !imgdata.rawdata.float4_image && !imgdata.rawdata.float3_image && P1.filters && (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); diff --git a/src/tables/wblists.cpp b/src/tables/wblists.cpp index f377cd3ec..1f8ae172b 100644 --- a/src/tables/wblists.cpp +++ b/src/tables/wblists.cpp @@ -17,15 +17,15 @@ #define _ARR_SZ(a) (sizeof(a)/sizeof(a[0])) -static const int _tagtype_dataunit_bytes [19] = { - 1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8 +static const int _tagtype_dataunit_bytes [20] = { + 1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4, 2, 8, 8, 8, 8, 8 }; libraw_static_table_t LibRaw::tagtype_dataunit_bytes(_tagtype_dataunit_bytes, _ARR_SZ(_tagtype_dataunit_bytes)); int libraw_tagtype_dataunit_bytes(int tagtype) { - return _tagtype_dataunit_bytes[((unsigned)tagtype <= _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0]; + return _tagtype_dataunit_bytes[((unsigned)tagtype < _ARR_SZ(_tagtype_dataunit_bytes)) ? tagtype : 0]; } diff --git a/src/utils/curves.cpp b/src/utils/curves.cpp index 03b1253bb..b14f19b79 100644 --- a/src/utils/curves.cpp +++ b/src/utils/curves.cpp @@ -37,8 +37,11 @@ void LibRaw::cubic_spline(const int *x_, const int *y_, const int len) } for (i = len - 1; i > 0; i--) { - b[i] = (y[i] - y[i - 1]) / (x[i] - x[i - 1]); - d[i - 1] = x[i] - x[i - 1]; + float _div = x[i] - x[i - 1]; + if (fabs(_div) < 1.0e-15) + _div = 1; + b[i] = (y[i] - y[i - 1]) / _div; + d[i - 1] = _div; } for (i = 1; i < len - 1; i++) { diff --git a/src/utils/open.cpp b/src/utils/open.cpp index 2adca43b5..12b0cb878 100644 --- a/src/utils/open.cpp +++ b/src/utils/open.cpp @@ -482,7 +482,10 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) // Fuji layout files: either DNG or unpacked_load_raw should be used if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout) { - if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw) + if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw + && load_raw != &LibRaw::unpacked_load_raw_FujiDBP + && load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20 + ) return LIBRAW_FILE_UNSUPPORTED; } @@ -1200,9 +1203,15 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) { if (C.profile) free(C.profile); - C.profile = malloc(C.profile_length); - ID.input->seek(ID.profile_offset, SEEK_SET); - ID.input->read(C.profile, C.profile_length, 1); + INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset); + if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL) + { + C.profile = malloc(size_t(profile_sz)); + ID.input->seek(ID.profile_offset, SEEK_SET); + ID.input->read(C.profile, size_t(profile_sz), 1); + } + else + C.profile = NULL; } SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); diff --git a/src/utils/thumb_utils.cpp b/src/utils/thumb_utils.cpp index ffdb80247..b468b0b06 100644 --- a/src/utils/thumb_utils.cpp +++ b/src/utils/thumb_utils.cpp @@ -127,26 +127,36 @@ void LibRaw::kodak_thumb_loader() int(*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int(*)[LIBRAW_HISTOGRAM_SIZE])calloc(sizeof(*t_hist), 4); - float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0}, - {-0.111855984f, 1.73688626f, -0.625030339f, 0}, - {-0.0379119813f, -0.891268849f, 1.92918086f, 0}}; - - for (img = imgdata.image[0], row = 0; row < S.height; row++) - for (col = 0; col < S.width; col++, img += 4) - { - out[0] = out[1] = out[2] = 0; - int c; - for (c = 0; c < 3; c++) + if (imgdata.idata.maker_index == LIBRAW_CAMERAMAKER_Canon) // Skip color conversion for canon PPM tiffs + { + for (img = imgdata.image[0], row = 0; row < S.height; row++) + for (col = 0; col < S.width; col++, img += 4) + for (int c = 0; c < P1.colors; c++) + t_hist[c][img[c] >> 3]++; + } + else + { + float out[3], out_cam[3][4] = {{2.81761312f, -1.98369181f, 0.166078627f, 0}, + {-0.111855984f, 1.73688626f, -0.625030339f, 0}, + {-0.0379119813f, -0.891268849f, 1.92918086f, 0}}; + + for (img = imgdata.image[0], row = 0; row < S.height; row++) + for (col = 0; col < S.width; col++, img += 4) { - out[0] += out_cam[0][c] * img[c]; - out[1] += out_cam[1][c] * img[c]; - out[2] += out_cam[2][c] * img[c]; + out[0] = out[1] = out[2] = 0; + int c; + for (c = 0; c < 3; c++) + { + out[0] += out_cam[0][c] * img[c]; + out[1] += out_cam[1][c] * img[c]; + out[2] += out_cam[2][c] * img[c]; + } + for (c = 0; c < 3; c++) + img[c] = CLIP((int)out[c]); + for (c = 0; c < P1.colors; c++) + t_hist[c][img[c] >> 3]++; } - for (c = 0; c < 3; c++) - img[c] = CLIP((int)out[c]); - for (c = 0; c < P1.colors; c++) - t_hist[c][img[c] >> 3]++; - } + } // from gamma_lut int(*save_hist)[LIBRAW_HISTOGRAM_SIZE] = From 380d96407751668e80d20976843b1d5bfc9cf1b5 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 6 Jan 2024 16:00:19 -0500 Subject: [PATCH 074/291] Add destination path preview label to batch queue panel. Label initially says "Destination path for the first selected image appears here" so the feature is discoverable. Select a file and it shows the destination path that would be used if it is the first file to be processed and the file does not already exist. Label is updated as the template is edited, so you can see the effect of the edits. If "Save to folder" is selected, the previewed path uses that folder. --- rtdata/languages/default | 2 ++ rtgui/batchqueue.cc | 40 ++++++++++++++++++++++++++++++++++++++++ rtgui/batchqueue.h | 3 +++ rtgui/batchqueuepanel.cc | 11 +++++++++++ rtgui/batchqueuepanel.h | 2 ++ 5 files changed, 58 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index 403fccdf0..2f22b4642 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2101,6 +2101,8 @@ QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) QUEUE_AUTOSTART;Auto-start QUEUE_AUTOSTART_TOOLTIP;Start processing automatically when a new job arrives. QUEUE_DESTFILENAME;Path and file name +QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 6ab75bd47..8d2ad176e 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -567,6 +567,41 @@ void BatchQueue::openLastSelectedItemInEditor() } } +void BatchQueue::updateDestinationPathPreview() +{ + MYWRITERLOCK(l, entryRW); + + if (selected.size()) + { + auto &entry = *selected.at(0); + int sequence = 0; // Sequence during subsequent queue processing can't be determined here + Glib::ustring baseDestination; + if (options.saveUsePathTemplate) + { + baseDestination = calcAutoFileNameBase(entry.filename, sequence); + } + else + { + Glib::ustring baseFilename; + int extpos = entry.filename.size() - 1; + for (; extpos >= 0 && entry.filename[extpos] != '.'; extpos--) + { + } + for (int k = extpos - 1; k >= 0 && entry.filename[k] != '/' && entry.filename[k] != '\\'; k--) + { + baseFilename = entry.filename[k] + baseFilename; + } + baseDestination = options.savePathFolder + '/' + baseFilename; + } + Glib::ustring destination = Glib::ustring::compose ("%1.%2", baseDestination, options.saveFormatBatch.format); + + if (listener) + { + listener->setDestinationPreviewText(destination); + } + } +} + void BatchQueue::openItemInEditor(ThumbBrowserEntryBase* item) { if (item) { @@ -1021,3 +1056,8 @@ void BatchQueue::redrawNeeded (LWButton* button) GThreadLock lock; queue_draw (); } + +void BatchQueue::selectionChanged() +{ + updateDestinationPathPreview(); +} diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 5cde37748..f8f1cf255 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -38,6 +38,7 @@ public: virtual ~BatchQueueListener() = default; virtual void queueSizeChanged(int qsize, bool queueRunning, bool queueError, const Glib::ustring& queueErrorMessage) = 0; virtual bool canStartNext() = 0; + virtual void setDestinationPreviewText(const Glib::ustring& destinationPath) = 0; }; class FileCatalog; @@ -59,6 +60,7 @@ public: void selectAll (); void openItemInEditor(ThumbBrowserEntryBase* item); void openLastSelectedItemInEditor(); + void updateDestinationPathPreview(); void startProcessing (); @@ -79,6 +81,7 @@ public: bool keyPressed (GdkEventKey* event) override; void buttonPressed (LWButton* button, int actionCode, void* actionData) override; void redrawNeeded (LWButton* button) override; + void selectionChanged () override; void setBatchQueueListener (BatchQueueListener* l) { diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 8a6dd25b4..59201d9f3 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -108,6 +108,9 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) #endif odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); + destinationPreviewLabel = Gtk::manage (new Gtk::Label ()); + destinationPreviewLabel->set_tooltip_markup(M("QUEUE_DESTPREVIEW_TOOLTIP")); + odvb->pack_start (*destinationPreviewLabel); Gtk::RadioButton::Group g = useTemplate->get_group(); useFolder->set_group (g); fdir->add (*odvb); @@ -122,6 +125,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) outdirTemplate->set_text (options.savePathTemplate); useTemplate->set_active (options.saveUsePathTemplate); useFolder->set_active (!options.saveUsePathTemplate); + destinationPreviewLabel->set_text (M("QUEUE_DESTPREVIEW_TITLE")); // setup signal handlers outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); @@ -329,6 +333,7 @@ void BatchQueuePanel::saveOptions () options.savePathTemplate = outdirTemplate->get_text(); options.saveUsePathTemplate = useTemplate->get_active(); options.procQueueEnabled = qAutoStart->get_active(); + batchQueue->updateDestinationPathPreview(); } bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event) @@ -358,6 +363,11 @@ bool BatchQueuePanel::canStartNext () return queueShouldRun; } +void BatchQueuePanel::setDestinationPreviewText(const Glib::ustring &destinationPath) +{ + destinationPreviewLabel->set_text(destinationPath); +} + void BatchQueuePanel::pathFolderButtonPressed () { @@ -381,6 +391,7 @@ void BatchQueuePanel::pathFolderButtonPressed () void BatchQueuePanel::pathFolderChanged () { options.savePathFolder = outdirFolder->get_filename(); + batchQueue->updateDestinationPathPreview(); } void BatchQueuePanel::formatChanged(const Glib::ustring& format) diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index db4e243e9..d73f8b893 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -42,6 +42,7 @@ class BatchQueuePanel : public Gtk::Box, Gtk::CheckButton* qAutoStart; Gtk::Entry* outdirTemplate; + Gtk::Label* destinationPreviewLabel; MyFileChooserButton* outdirFolder; Gtk::Button* outdirFolderButton; Gtk::RadioButton* useTemplate; @@ -72,6 +73,7 @@ public: // batchqueuelistener interface void queueSizeChanged(int qsize, bool queueRunning, bool queueError, const Glib::ustring& queueErrorMessage) override; bool canStartNext() override; + void setDestinationPreviewText(const Glib::ustring& destinationPath) override; private: void startBatchProc (); From 587e0c67829259c68fac020ffc3b43fba965a836 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 6 Jan 2024 16:32:14 -0500 Subject: [PATCH 075/291] Simplified BatchQueue::updateDestinationPathPreview after noticing that calcAutoFileNameBase handles all cases --- rtgui/batchqueue.cc | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 8d2ad176e..27b4400e1 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -575,24 +575,7 @@ void BatchQueue::updateDestinationPathPreview() { auto &entry = *selected.at(0); int sequence = 0; // Sequence during subsequent queue processing can't be determined here - Glib::ustring baseDestination; - if (options.saveUsePathTemplate) - { - baseDestination = calcAutoFileNameBase(entry.filename, sequence); - } - else - { - Glib::ustring baseFilename; - int extpos = entry.filename.size() - 1; - for (; extpos >= 0 && entry.filename[extpos] != '.'; extpos--) - { - } - for (int k = extpos - 1; k >= 0 && entry.filename[k] != '/' && entry.filename[k] != '\\'; k--) - { - baseFilename = entry.filename[k] + baseFilename; - } - baseDestination = options.savePathFolder + '/' + baseFilename; - } + Glib::ustring baseDestination = calcAutoFileNameBase(entry.filename, sequence); Glib::ustring destination = Glib::ustring::compose ("%1.%2", baseDestination, options.saveFormatBatch.format); if (listener) From b8d3f90ca041779cbd8052ba25ba926ab32114a6 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 6 Jan 2024 18:01:56 -0500 Subject: [PATCH 076/291] Reimplement template %dN specifier, making %d-N count from start of path, not end Also made %pN selectively skip the next character only if it's a slash or backslash, so for example %p2/a, %p2\a and %p2a produce the same result. --- rtgui/batchqueue.cc | 62 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 27b4400e1..732580599 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -824,6 +824,47 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) return processing ? processing->job : nullptr; } +// Combine a range of elements from "names" into a slash-delimited path +static inline Glib::ustring combineDirectoryNames(unsigned startIndex, unsigned endIndex, const std::vector & names) +{ + Glib::ustring resultPath; + for (unsigned i = startIndex; i <= endIndex && i < names.size(); ++i) + { + resultPath = resultPath + names[i] + '/'; + } + return resultPath; +} + +// Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" +// For N, return Nth index from the end, and for -N return the Nth index from the start +static inline unsigned decodePathIndex(unsigned & ix, Glib::ustring & templateText, size_t numPathElements) +{ + unsigned pathIndex = numPathElements; // means input was invalid + bool fromStart = false; + if (ix < templateText.size()) + { + if (templateText[ix] == '-') + { + fromStart = true; // minus sign means N is from the start rather than the end of the path + ix++; + } + } + if (ix < templateText.size()) + { + unsigned n = templateText[ix] - '1'; + if (!fromStart) + { + // n=1 is the last element, n=2 is the one before that + n = numPathElements - n - 1; + } + if (n < numPathElements) + { + pathIndex = n; + } + } + return pathIndex; +} + // Calculates automatic filename of processed batch entry, but just the base name // example output: "c:\out\converted\dsc0121" Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence) @@ -847,7 +888,9 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam tok = tok + origFileName[i++]; } - da.push_back (tok); + if (i < origFileName.size()) { // omit the last token, which is the file name + da.push_back (tok); + } } if (origFileName[0] == '/') { @@ -898,19 +941,24 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam if (options.savePathTemplate[ix] == 'p') { ix++; - unsigned int i = options.savePathTemplate[ix] - '0'; + unsigned int i = options.savePathTemplate[ix] - '1'; if (i < pa.size()) { path = path + pa[pa.size() - i - 1] + '/'; } - + // If the next template character is a slash or backslash, skip it, because path already has a trailing slash ix++; + if (ix < options.savePathTemplate.size() && options.savePathTemplate[ix] != '/' && options.savePathTemplate[ix] != '\\') { + ix--; + } } else if (options.savePathTemplate[ix] == 'd') { + // insert a single directory name from the file's path + // da.size()-1 omits the last element, which is the filename ix++; - unsigned i = options.savePathTemplate[ix] - '0'; - - if (i < da.size()) { - path = path + da[da.size() - i - 1]; + unsigned n = decodePathIndex(ix, options.savePathTemplate, da.size()); + if (n < da.size()) + { + path += da[n]; } } else if (options.savePathTemplate[ix] == 'f') { path = path + filename; From 21c53823ee766c90d57a0e7d1b3b8882d0ffb4db Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 6 Jan 2024 18:21:59 -0500 Subject: [PATCH 077/291] Reimplemented %p template specifier to use new method, added %P specifier The %P specifier includes directories from the start of the file path, whereas the original %p specifier includes them from the end. In both cases N is from the last directory in the path, and -N is from the first directory in the path (N=1..9). --- rtgui/batchqueue.cc | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 732580599..cb9127333 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -837,6 +837,7 @@ static inline Glib::ustring combineDirectoryNames(unsigned startIndex, unsigned // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" // For N, return Nth index from the end, and for -N return the Nth index from the start +// N is a digit 1 through 9 static inline unsigned decodePathIndex(unsigned & ix, Glib::ustring & templateText, size_t numPathElements) { unsigned pathIndex = numPathElements; // means input was invalid @@ -854,7 +855,6 @@ static inline unsigned decodePathIndex(unsigned & ix, Glib::ustring & templateTe unsigned n = templateText[ix] - '1'; if (!fromStart) { - // n=1 is the last element, n=2 is the one before that n = numPathElements - n - 1; } if (n < numPathElements) @@ -870,7 +870,6 @@ static inline unsigned decodePathIndex(unsigned & ix, Glib::ustring & templateTe Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence) { - std::vector pa; std::vector da; for (size_t i = 0; i < origFileName.size(); i++) { @@ -893,26 +892,8 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } } - if (origFileName[0] == '/') { - pa.push_back ("/" + da[0]); - } else if (origFileName[0] == '\\') { - if (origFileName.size() > 1 && origFileName[1] == '\\') { - pa.push_back ("\\\\" + da[0]); - } else { - pa.push_back ("/" + da[0]); - } - } else { - pa.push_back (da[0]); - } - - for (size_t i = 1; i < da.size(); i++) { - pa.push_back (pa[i - 1] + "/" + da[i]); - } - // for (int i=0; i Date: Mon, 1 Jan 2024 16:09:04 -0800 Subject: [PATCH 078/291] Implement Sony Pixel Shift for LibRaw --- rtengine/dcraw.h | 10 +++++++ rtengine/rawimage.cc | 66 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 2bf8f2965..a6551b515 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -136,6 +136,15 @@ protected: ushort *linebuf[_ltotal]; }; + /** + * Metadata for merged pixel-shift image. + */ + struct MergedPixelshift + { + bool is_merged_pixelshift = false; + unsigned sub_frame_shot_select; + }; + int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, fuji_raw_type; ushort raw_height, raw_width, height, width, top_margin, left_margin; @@ -162,6 +171,7 @@ protected: ThreeValBool RT_matrix_from_constant; std::string RT_software; double RT_baseline_exposure; + struct MergedPixelshift merged_pixelshift; struct PanasonicRW2Info { ushort bpp; diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index c7aca8b05..51ef67630 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -505,6 +505,22 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog libraw->imgdata.rawparams.shot_select = shot_select; int err = libraw->open_buffer(ifp->data, ifp->size); + + merged_pixelshift.is_merged_pixelshift = + err == LIBRAW_SUCCESS && + (strncmp(libraw->unpack_function_name(), "sony_arq_load_raw", 17) == 0 && + libraw->imgdata.idata.raw_count == 1 && + libraw->imgdata.idata.colors == 4); + + if (err == LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE || (merged_pixelshift.is_merged_pixelshift && shot_select)) { + // Try again last valid frame. Sony Pixel Shift, for example, has a + // single frame, but we want to represent the data as four. + shot_select = merged_pixelshift.is_merged_pixelshift ? shot_select / 4 : shot_select; + shot_select = std::min(shot_select, std::max(libraw->imgdata.idata.raw_count, 1u) - 1); + libraw->imgdata.rawparams.shot_select = shot_select; + err = libraw->open_buffer(ifp->data, ifp->size); + } + if (err == LIBRAW_FILE_UNSUPPORTED || err == LIBRAW_TOO_BIG) { // fallback to the internal one return err; @@ -532,6 +548,18 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog colors = d.colors; tiff_bps = 0; + if (merged_pixelshift.is_merged_pixelshift || + (strncmp(libraw->unpack_function_name(), "sony_arq_load_raw", 17) == 0 && + is_raw == 1 && colors == 4)) { + // Represent merged pixelshift as 4 sub-frames. + merged_pixelshift.is_merged_pixelshift = true; + merged_pixelshift.sub_frame_shot_select = imageNum % 4; + + filters = 0x94949494; + colors = 3; + is_raw = 4; + } + for (int i = 0; i < 6; ++i) { for (int j = 0; j < 6; ++j) { xtrans[i][j] = d.xtrans[i][j]; @@ -576,6 +604,9 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog cam_mul[i] = cd.cam_mul[i]; pre_mul[i] = cd.pre_mul[i]; } + if (merged_pixelshift.is_merged_pixelshift) { + pre_mul[3] = 0.f; // 4th value is undefined after reducing to 3 colors. + } for (int i = 0; i < 3; ++i) { for (int j = 0; j < 4; ++j) { @@ -1102,6 +1133,41 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) delete [] float_raw_image; float_raw_image = nullptr; + } else if (merged_pixelshift.is_merged_pixelshift) { + // Frame 0 is not shifted. Frame 1 is shifted down. Frame 2 is shifted + // down and right. Frame 3 is shifted right. + int h_shift = (merged_pixelshift.sub_frame_shot_select >> 1) & 1; + int v_shift = ((merged_pixelshift.sub_frame_shot_select + 1u) >> 1) & 1; + + // Reset edges to 0. + for (int row = 0; row < v_shift; ++row) { + for (int col = 0; col < width; ++col) { + this->data[row][col] = 0; + } + } + for (int col = 0; col < h_shift; ++col) { + for (int row = 0; row < height; ++row) { + this->data[row][col] = 0; + } + } + + const int image_v_shift = top_margin - v_shift; + const int image_h_shift = left_margin - h_shift; + const unsigned original_filters = filters; + + filters = 0xb4b4b4b4; // R G1 B G2. + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int row = v_shift; row < height; row++) { + for (int col = h_shift; col < width; col++) { + this->data[row][col] = image[(row + image_v_shift) * iwidth + col + image_h_shift][FC(row, col)]; + } + } + + filters = original_filters; } else if (filters != 0 && !isXtrans()) { #ifdef _OPENMP #pragma omp parallel for From d96809ecab85e74940e2589781627f0e99f8e885 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:33:54 -0800 Subject: [PATCH 079/291] Copy missing camera constants from dcraw to LibRaw Update white level for Fujifilm HS20EXR/HS22EXR and add constants for Panasonic DMC-TZ82. --- rtengine/libraw/src/tables/colordata.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtengine/libraw/src/tables/colordata.cpp b/rtengine/libraw/src/tables/colordata.cpp index fc9f100f7..1926943b1 100644 --- a/rtengine/libraw/src/tables/colordata.cpp +++ b/rtengine/libraw/src/tables/colordata.cpp @@ -402,7 +402,7 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Fujifilm, "HS10", 0, 0xf68, { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0, // HS20EXR/HS22EXR + { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0xfef, // HS20EXR/HS22EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "HS3", 0, 0, // HS30EXR/HS33EXR/HS35EXR { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, @@ -1388,6 +1388,9 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GX9", -15, 0, { 7564,-2263,-606,-3148,11239,2177,-540,1435,4853 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-TZ82", -15, 0, + { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DMC-ZS100", -15, 0, { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-ZS200", -15, 0, From d13badbbe0b940c45ea81140809422ac54737a04 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 1 Jan 2024 17:55:05 -0800 Subject: [PATCH 080/291] Implement DNG bad pixels constant for LibRaw Works if the FixBadPixelsConstant is zero, as implemented for dcraw. Other constant values may be implemented in the future. --- rtengine/dcraw.cc | 22 ----------------- rtengine/imagedata.cc | 49 +++++++++++++++++++++++++++++++------- rtengine/imagedata.h | 4 ++++ rtengine/rawimagesource.cc | 2 +- rtengine/rtengine.h | 3 +++ rtgui/cacheimagedata.cc | 10 ++++++++ rtgui/cacheimagedata.h | 2 ++ 7 files changed, 60 insertions(+), 32 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 4fd01259c..533c30eeb 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6935,28 +6935,6 @@ it under the terms of the one of two licenses as you choose: ((int *)mask)[i] = getint(type); black = 0; break; - case 51008: /* OpcodeList1 */ - { - unsigned oldOrder = order; - order = 0x4d4d; // always big endian per definition in https://www.adobe.com/content/dam/acom/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf chapter 7 - unsigned ntags = get4(); // read the number of opcodes - if (ntags < ifp->size / 12) { // rough check for wrong value (happens for example with DNG files from DJI FC6310) - while (ntags-- && !ifp->eof) { - unsigned opcode = get4(); - fseek (ifp, 8, SEEK_CUR); // skip 8 bytes as they don't interest us currently - if (opcode == 4) { // FixBadPixelsConstant - fseek (ifp, 4, SEEK_CUR); // skip 4 bytes as we know that the opcode 4 takes 4 byte - if(get4() == 0) { // if raw 0 values should be treated as bad pixels, set zero_is_bad to true (1). That's the only value currently supported by rt - zero_is_bad = 1; - } - } else { - fseek (ifp, get4(), SEEK_CUR); - } - } - } - order = oldOrder; - break; - } case 51009: /* OpcodeList2 */ meta_offset = ftell(ifp); break; diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index eff903ce6..44a37f296 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -168,10 +168,15 @@ public: } }; +std::uint32_t readFixBadPixelsConstant(TagValueReader &reader) +{ + reader.seekRelative(12); // Skip DNG spec version, flags, and tag size. + return reader.readUInt(); +} + GainMap readGainMap(TagValueReader &reader) { - reader.seekRelative(4); // skip 4 bytes as we know that the opcode 4 takes 4 byte - reader.seekRelative(8); // skip 8 bytes as they don't interest us currently + reader.seekRelative(12); // Skip DNG spec version, flags, and tag size. GainMap gainMap; gainMap.Top = reader.readUInt(); gainMap.Left = reader.readUInt(); @@ -196,7 +201,11 @@ GainMap readGainMap(TagValueReader &reader) return gainMap; } -void readOpcodesList(const Exiv2::Value &value, std::vector &gainMaps) +void readOpcodesList( + const Exiv2::Value &value, + std::uint32_t *fixBadPixelsConstant, + bool *hasFixBadPixelsConstant, + std::vector *gainMaps) { TagValueReader reader(value); std::uint32_t ntags = reader.readUInt(); // read the number of opcodes @@ -205,8 +214,16 @@ void readOpcodesList(const Exiv2::Value &value, std::vector &gainMaps) } while (ntags-- && !reader.isEnd()) { unsigned opcode = reader.readUInt(); - if (opcode == 9 && gainMaps.size() < 4) { - gainMaps.push_back(readGainMap(reader)); + if (opcode == 4 && (fixBadPixelsConstant || hasFixBadPixelsConstant)) { + const auto constant = readFixBadPixelsConstant(reader); + if (fixBadPixelsConstant) { + *fixBadPixelsConstant = constant; + } + if (hasFixBadPixelsConstant) { + *hasFixBadPixelsConstant = true; + } + } else if (opcode == 9 && gainMaps && gainMaps->size() < 4) { + gainMaps->push_back(readGainMap(reader)); } else { reader.seekRelative(8); // skip 8 bytes as they don't interest us currently reader.seekRelative(reader.readUInt()); @@ -826,16 +843,20 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } } - uint32_t dngVersion = 0; + std::uint32_t dngVersion = 0; if (find_exif_tag("Exif.Image.DNGVersion") && pos->count() == 4) { for (int i = 0; i < 4; i++) { - dngVersion = (dngVersion << 8) + static_cast(to_long(pos, i)); + dngVersion = (dngVersion << 8) + static_cast(to_long(pos, i)); } } - // Read gain maps. + // Read DNG OpcodeList1. + if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList1") || find_exif_tag("Exif.Image.OpcodeList1"))) { + readOpcodesList(pos->value(), &fixBadPixelsConstant, &hasFixBadPixelsConstant_, nullptr); + } + // Read DNG OpcodeList2. if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList2") || find_exif_tag("Exif.Image.OpcodeList2"))) { - readOpcodesList(pos->value(), gain_maps_); + readOpcodesList(pos->value(), nullptr, nullptr, &gain_maps_); } } catch (const std::exception& e) { if (settings->verbose) { @@ -1078,6 +1099,16 @@ void FramesData::fillBasicTags(Exiv2::ExifData &exif) const set_exif(exif, "Exif.Photo.DateTimeOriginal", buf); } +std::uint32_t FramesData::getFixBadPixelsConstant() const +{ + return fixBadPixelsConstant; +} + +bool FramesData::hasFixBadPixelsConstant() const +{ + return hasFixBadPixelsConstant_; +} + std::vector FramesData::getGainMaps() const { return gain_maps_; diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 434b96a52..1d7f715d3 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -60,6 +60,8 @@ private: time_t modTimeStamp; bool isPixelShift; bool isHDR; + std::uint32_t fixBadPixelsConstant; + bool hasFixBadPixelsConstant_{false}; std::vector gain_maps_; int w_; int h_; @@ -90,6 +92,8 @@ public: std::string getOrientation() const override; Glib::ustring getFileName() const override; int getRating() const override; + std::uint32_t getFixBadPixelsConstant() const override; + bool hasFixBadPixelsConstant() const override; std::vector getGainMaps() const override; void getDimensions(int &w, int &h) const override; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 7c77d57c6..53c850dac 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1439,7 +1439,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens int totBP = 0; // Hold count of bad pixels to correct - if (ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica) + if (ri->zeroIsBad() || (getMetaData()->hasFixBadPixelsConstant() && getMetaData()->getFixBadPixelsConstant() == 0)) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica) bitmapBads.reset(new PixelsMap(W, H)); totBP = findZeroPixels(*bitmapBads); diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 0db06849a..e5b374faa 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -20,6 +20,7 @@ #pragma once #include +#include #include #include #include @@ -159,6 +160,8 @@ public: static FramesMetaData* fromFile(const Glib::ustring& fname); virtual Glib::ustring getFileName() const = 0; + virtual std::uint32_t getFixBadPixelsConstant() const = 0; + virtual bool hasFixBadPixelsConstant() const = 0; virtual std::vector getGainMaps() const = 0; virtual void getDimensions(int &w, int &h) const = 0; }; diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 13a2e31e0..0f9826fb0 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -362,6 +362,16 @@ int CacheImageData::save (const Glib::ustring& fname) } } +std::uint32_t CacheImageData::getFixBadPixelsConstant() const +{ + return 0; +} + +bool CacheImageData::hasFixBadPixelsConstant() const +{ + return false; +} + std::vector CacheImageData::getGainMaps() const { return std::vector(); diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 12c4ed476..91abdbf83 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -117,6 +117,8 @@ public: bool getHDR() const override { return isHDR; } std::string getImageType() const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat() const override { return sampleFormat; } + std::uint32_t getFixBadPixelsConstant() const override; + bool hasFixBadPixelsConstant() const override; std::vector getGainMaps() const override; void getDimensions(int &w, int &h) const override { From 0f66d4327288f2dcdc8f2b6bcce77eacb1a451e3 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 10:09:45 -0500 Subject: [PATCH 081/291] Update destination preview whenever the save format changes. --- rtgui/batchqueuepanel.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 59201d9f3..fb6e37c46 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -397,4 +397,5 @@ void BatchQueuePanel::pathFolderChanged () void BatchQueuePanel::formatChanged(const Glib::ustring& format) { options.saveFormatBatch = saveFormatPanel->getFormat(); + batchQueue->updateDestinationPathPreview(); } From 5accf1e9dbe381de17942e3b7c1fc006ab560e58 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 10:31:05 -0500 Subject: [PATCH 082/291] Add myself to the list of authors --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 374a7935b..3afd09dc2 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -20,6 +20,7 @@ Development contributors, in last name alphabetical order: Rüdiger Franke Jean-Christophe Frisch Ilias Giarimis + Scott Gilbertson Alberto Griggio Steve Herrell Philippe Hupé From d9511d9af8b55e6771bc2665132a3b196013e4e4 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 10:42:44 -0500 Subject: [PATCH 083/291] Update QUEUE_LOCATION_TEMPLATE_TOOLTIP text to describe new specifiers Describe %dN, %d-N, %pN, %p-N, %PN, %P-N and %f specifiers Add examples using the new P specifier and -N terms --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2f22b4642..3af6b108c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2106,7 +2106,7 @@ QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = photo1\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 photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p2/converted/%d1/%f +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f will be replaced with the base name of the file, without the extension removed.\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s SAMPLEFORMAT_0;Unknown data format From f92e07e5cf904757e19f9da61f44aa19b0c4e5eb Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 10:52:01 -0500 Subject: [PATCH 084/291] Make destination path preview label selectable, so its contents can be copied to the clipboard --- rtgui/batchqueuepanel.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index fb6e37c46..3fd52df93 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -110,6 +110,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); destinationPreviewLabel = Gtk::manage (new Gtk::Label ()); destinationPreviewLabel->set_tooltip_markup(M("QUEUE_DESTPREVIEW_TOOLTIP")); + destinationPreviewLabel->set_selectable(true); // so users can copy the path to the clipboard odvb->pack_start (*destinationPreviewLabel); Gtk::RadioButton::Group g = useTemplate->get_group(); useFolder->set_group (g); From 6df930b639a833354772747f43ac3e46d14e8b30 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 11:09:24 -0500 Subject: [PATCH 085/291] Minor tooltip change: shorter explanation of %f location template specifier --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3af6b108c..bf43596dc 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2106,7 +2106,7 @@ QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f will be replaced with the base name of the file, without the extension removed.\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s SAMPLEFORMAT_0;Unknown data format From df4102846831f67aa960d7ff74346014f92be85b Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 7 Jan 2024 11:10:05 -0500 Subject: [PATCH 086/291] On Windows, use backslashes in template-generated paths (but continue to accept either / or \ in input strings, on any platform) Also deleted an unused helper function. --- rtgui/batchqueue.cc | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index cb9127333..61f1c082d 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -43,6 +43,12 @@ using namespace std; using namespace rtengine; +#ifdef _WIN32 +#define PATH_SEPARATOR '\\'; +#else +#define PATH_SEPARATOR '/'; +#endif + BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCatalog(aFileCatalog), sequence(0), listener(nullptr) { @@ -824,17 +830,6 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) return processing ? processing->job : nullptr; } -// Combine a range of elements from "names" into a slash-delimited path -static inline Glib::ustring combineDirectoryNames(unsigned startIndex, unsigned endIndex, const std::vector & names) -{ - Glib::ustring resultPath; - for (unsigned i = startIndex; i <= endIndex && i < names.size(); ++i) - { - resultPath = resultPath + names[i] + '/'; - } - return resultPath; -} - // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" // For N, return Nth index from the end, and for -N return the Nth index from the start // N is a digit 1 through 9 @@ -926,7 +921,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam unsigned n = decodePathIndex(ix, options.savePathTemplate, da.size()); if (n < da.size()) { for (unsigned i=n; i Date: Sun, 7 Jan 2024 11:14:52 -0500 Subject: [PATCH 087/291] Minor comment clarification --- rtgui/batchqueue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 61f1c082d..bdf6c6e5e 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -924,7 +924,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam path = path + da[i] + PATH_SEPARATOR; } } - // If the next template character is a slash or backslash, skip it, because path already has a trailing slash + // If the next template character is a separator, skip it, because path already has one ix++; if (ix < options.savePathTemplate.size() && options.savePathTemplate[ix] != '/' && options.savePathTemplate[ix] != '\\') { ix--; @@ -936,7 +936,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam for (unsigned i=0; i<=n && i Date: Sun, 7 Jan 2024 11:49:19 -0500 Subject: [PATCH 088/291] Reversed %p and %P processing cases for location templates, which were opposite to what the help says. --- rtgui/batchqueue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index bdf6c6e5e..c3723515f 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -915,7 +915,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam if (options.savePathTemplate[ix] == '%') { ix++; - if (options.savePathTemplate[ix] == 'p') { + if (options.savePathTemplate[ix] == 'P') { // insert path elements from given index to the end ix++; unsigned n = decodePathIndex(ix, options.savePathTemplate, da.size()); @@ -929,7 +929,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam if (ix < options.savePathTemplate.size() && options.savePathTemplate[ix] != '/' && options.savePathTemplate[ix] != '\\') { ix--; } - } else if (options.savePathTemplate[ix] == 'P') { + } else if (options.savePathTemplate[ix] == 'p') { // insert path elements from the start of the path up to the given index ix++; unsigned n = decodePathIndex(ix, options.savePathTemplate, da.size()); From 9e310b7454a604ae298ef11d05806809129a9b87 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Wed, 10 Jan 2024 18:47:14 -0500 Subject: [PATCH 089/291] Minor changes per feedback in issue #6915 (mostly code formatting) --- rtgui/batchqueue.cc | 87 +++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index c3723515f..349cefddf 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -49,6 +49,34 @@ using namespace rtengine; #define PATH_SEPARATOR '/'; #endif +namespace // local helper functions +{ + // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" + // For N, return Nth index from the end, and for -N return the Nth index from the start + // N is a digit 1 through 9 + unsigned int decodePathIndex(unsigned int & ix, Glib::ustring & templateText, size_t numPathElements) + { + unsigned int pathIndex = numPathElements; // means input was invalid + bool fromStart = false; + if (ix < templateText.size()) { + if (templateText[ix] == '-') { + fromStart = true; // minus sign means N is from the start rather than the end of the path + ix++; + } + } + if (ix < templateText.size()) { + unsigned int n = templateText[ix] - '1'; + if (!fromStart) { + n = numPathElements - n - 1; + } + if (n < numPathElements) { + pathIndex = n; + } + } + return pathIndex; + } +} + BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCatalog(aFileCatalog), sequence(0), listener(nullptr) { @@ -567,7 +595,7 @@ void BatchQueue::openLastSelectedItemInEditor() { MYREADERLOCK(l, entryRW); - if (selected.size() > 0) { + if (!selected.empty()) { openItemInEditor(selected.back()); } } @@ -577,15 +605,13 @@ void BatchQueue::updateDestinationPathPreview() { MYWRITERLOCK(l, entryRW); - if (selected.size()) - { + if (!selected.empty()) { auto &entry = *selected.at(0); int sequence = 0; // Sequence during subsequent queue processing can't be determined here Glib::ustring baseDestination = calcAutoFileNameBase(entry.filename, sequence); Glib::ustring destination = Glib::ustring::compose ("%1.%2", baseDestination, options.saveFormatBatch.format); - if (listener) - { + if (listener) { listener->setDestinationPreviewText(destination); } } @@ -830,36 +856,6 @@ rtengine::ProcessingJob* BatchQueue::imageReady(rtengine::IImagefloat* img) return processing ? processing->job : nullptr; } -// Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" -// For N, return Nth index from the end, and for -N return the Nth index from the start -// N is a digit 1 through 9 -static inline unsigned decodePathIndex(unsigned & ix, Glib::ustring & templateText, size_t numPathElements) -{ - unsigned pathIndex = numPathElements; // means input was invalid - bool fromStart = false; - if (ix < templateText.size()) - { - if (templateText[ix] == '-') - { - fromStart = true; // minus sign means N is from the start rather than the end of the path - ix++; - } - } - if (ix < templateText.size()) - { - unsigned n = templateText[ix] - '1'; - if (!fromStart) - { - n = numPathElements - n - 1; - } - if (n < numPathElements) - { - pathIndex = n; - } - } - return pathIndex; -} - // Calculates automatic filename of processed batch entry, but just the base name // example output: "c:\out\converted\dsc0121" Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence) @@ -918,10 +914,10 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam if (options.savePathTemplate[ix] == 'P') { // insert path elements from given index to the end ix++; - unsigned n = decodePathIndex(ix, options.savePathTemplate, da.size()); + unsigned int n = decodePathIndex(ix, options.savePathTemplate, da.size()); if (n < da.size()) { - for (unsigned i=n; i Date: Wed, 10 Jan 2024 18:55:52 -0500 Subject: [PATCH 090/291] Code formatting: move ampersands next to types --- rtgui/batchqueue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 349cefddf..df653976c 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -54,7 +54,7 @@ namespace // local helper functions // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" // For N, return Nth index from the end, and for -N return the Nth index from the start // N is a digit 1 through 9 - unsigned int decodePathIndex(unsigned int & ix, Glib::ustring & templateText, size_t numPathElements) + unsigned int decodePathIndex(unsigned int& ix, Glib::ustring& templateText, size_t numPathElements) { unsigned int pathIndex = numPathElements; // means input was invalid bool fromStart = false; @@ -606,7 +606,7 @@ void BatchQueue::updateDestinationPathPreview() MYWRITERLOCK(l, entryRW); if (!selected.empty()) { - auto &entry = *selected.at(0); + auto& entry = *selected.at(0); int sequence = 0; // Sequence during subsequent queue processing can't be determined here Glib::ustring baseDestination = calcAutoFileNameBase(entry.filename, sequence); Glib::ustring destination = Glib::ustring::compose ("%1.%2", baseDestination, options.saveFormatBatch.format); From 2b6789b4ac89a5897e79cc49097e24ba8f9b1bd6 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:32:09 -0800 Subject: [PATCH 091/291] Fix Hasselblad model name when using LibRaw The model, rather than the normalized model, gives the name that matches those given by dcraw for Hasselblad cameras. This is important for matching the model name in camconst.json. --- rtengine/rawimage.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 51ef67630..704db176f 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -548,6 +548,12 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog colors = d.colors; tiff_bps = 0; + if (!strcmp("Hasselblad", make)) { + // For Hasselblad, "model" provides the better name. + strncpy(model, d.model, sizeof(model) - 1); + model[sizeof(model) - 1] = 0; + } + if (merged_pixelshift.is_merged_pixelshift || (strncmp(libraw->unpack_function_name(), "sony_arq_load_raw", 17) == 0 && is_raw == 1 && colors == 4)) { From 67da8a9634bffd992cc73fa56c49bd110c2a3f72 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:35:26 -0800 Subject: [PATCH 092/291] Implement Hasselblad flat-field and levels --- .../libraw/internal/libraw_internal_funcs.h | 2 + rtengine/libraw/libraw/libraw_types.h | 4 + rtengine/libraw/src/decoders/load_mfbacks.cpp | 248 ++++++++++++++++++ .../libraw/src/metadata/hasselblad_model.cpp | 94 +++++++ rtengine/libraw/src/metadata/makernotes.cpp | 3 + .../libraw/src/preprocessing/raw2image.cpp | 4 + 6 files changed, 355 insertions(+) diff --git a/rtengine/libraw/internal/libraw_internal_funcs.h b/rtengine/libraw/internal/libraw_internal_funcs.h index 6abdb6bde..9c864d642 100644 --- a/rtengine/libraw/internal/libraw_internal_funcs.h +++ b/rtengine/libraw/internal/libraw_internal_funcs.h @@ -119,6 +119,8 @@ it under the terms of the one of two licenses as you choose: const char* HassyRawFormat_idx2HR(unsigned idx); void process_Hassy_Lens (int LensMount); void parseHassyModel (); + void parse_hasselblad_gain(); // RT + void hasselblad_correct(); // RT void setLeicaBodyFeatures(int LeicaMakernoteSignature); void parseLeicaLensID(); diff --git a/rtengine/libraw/libraw/libraw_types.h b/rtengine/libraw/libraw/libraw_types.h index ec413b68b..55aa1b90e 100644 --- a/rtengine/libraw/libraw/libraw_types.h +++ b/rtengine/libraw/libraw/libraw_types.h @@ -357,6 +357,10 @@ typedef unsigned long long UINT64; */ double mnColorMatrix[4][3]; + off_t levels; // RT + off_t unknown1; // RT + off_t flatfield; // RT + } libraw_hasselblad_makernotes_t; typedef struct diff --git a/rtengine/libraw/src/decoders/load_mfbacks.cpp b/rtengine/libraw/src/decoders/load_mfbacks.cpp index cddc33ebc..28bdb52c8 100644 --- a/rtengine/libraw/src/decoders/load_mfbacks.cpp +++ b/rtengine/libraw/src/decoders/load_mfbacks.cpp @@ -690,6 +690,254 @@ void LibRaw::phase_one_load_raw_c() maximum = 0xfffc - ph1.t_black; } +// RT: From dcraw.cc. +void LibRaw::hasselblad_correct() +{ + unsigned col, row; + + /* + + This function applies 3FR calibration data. At the time of writing it supports a + subset, so here's a todo list: + + TODO: + - Support all gain tag formats + - The 0x19 tag varies a bit between models. We don't have parsers for all models. + - The reference model used was during initial reverse-engineering was a H4D-50, + we probably support the Hasselblads with Kodak 31, 39, 40 and 50 megapixels + well, but more work is needed for Kodak 16 and 22, Dalsa 60 and Sony 50. + - Apply bad column(?) data (hbd.unknown1) + - It was left out in this initial release since the effect is very small. + - Apply black(?) data, tag 0x1a and 0x1b is not parsed, it has however marginal + effect (at least for shorter exposures) so it's not too important. + + While there are things to do, the current implementation supports the most + important aspects, the faltfield and levels calibrations applied can have strong + visible effects. + + */ + + const auto &hbd = imHassy; + + if (hbd.levels) { + int i; + fseek(ifp, hbd.levels, SEEK_SET); + /* skip the first set (not used as we don't apply on first/last row), we look at it though to see if + the levels format is one that we support (there are other formats on some models which is not + supported here) */ + short test[10]; + for (i = 0; i < 10; i++) test[i] = (short)get2(); + if (test[5] == 0 && test[6] == 0 && test[7] == 0 && test[8] == 0 && test[9] == 0) { + int corr[4]; + ushort *row_above = (ushort *)malloc(sizeof(ushort) * raw_width); // we need to cache row above as we write new values as we go + for (col = 0; col < raw_width; col++) row_above[col] = RAW(0,col); + for (row = 1; row < raw_height-1; row++) { + for (i = 0; i < 4; i++) corr[i] = (short)get2(); + fseek(ifp, 6 * 2, SEEK_CUR); + for (col = 0; col < raw_width; col++) { + unsigned v = RAW(row,col); + if (v >= 65534) { + v = 65535; + } else { + if (corr[((col & 1)<<1)+0] && row_above[col] > black) v += 2 * ((corr[((col & 1)<<1)+0] * (row_above[col]-(int)black)) / 32767) - 2; + if (corr[((col & 1)<<1)+1] && RAW(row+1,col) > black) v += 2 * ((corr[((col & 1)<<1)+1] * (RAW(row+1,col)-(int)black)) / 32767) - 2; + } + row_above[col] = RAW(row,col); + RAW(row,col) = CLIP(v); + } + } + free(row_above); + } + } + + if (hbd.flatfield) { + int bw, bh, ffrows, ffcols, i, c; + ushort ref[4], ref_max; + fseek(ifp, hbd.flatfield, SEEK_SET); + get2(); + bw = get2(); + bh = get2(); + ffcols = get2(); + ffrows = get2(); + fseek(ifp, hbd.flatfield + 16 * 2, SEEK_SET); + unsigned toRead = sizeof(ushort) * 4 * ffcols * ffrows; + if (toRead > ifp->size()) { // there must be something wrong, see Issue #4748 + return; + } + + ushort *ffmap = (ushort *)malloc(toRead); + for (i = 0; i < 4 * ffcols * ffrows; i++) ffmap[i] = get2(); + + /* Get reference values from center of field. This seems to be what Phocus does too, + but haven't cared to figure out exactly at which coordinate */ + i = 4 * (ffcols * ffrows / 2 + ffcols / 2); + ref[0] = ffmap[i+0]; + ref[1] = ffmap[i+1]; + ref[3] = ffmap[i+2]; // G2 = index 3 in dcraw, 2 in 3FR + ref[2] = ffmap[i+3]; + ref_max = 0; + FORC4 if (ref[c] > ref_max) ref_max = ref[c]; + if (ref_max == 0) ref[0] = ref[1] = ref[2] = ref[3] = ref_max = 10000; + + /* Convert measured flatfield values to actual multipliers. The measured flatfield + can have vignetting which should be normalized, only color cast should be corrected. */ + for (i = 0; i < 4 * ffcols * ffrows; i += 4) { + double base, min = 65535.0, max = 0; + double cur[4]; + cur[0] = (double)ffmap[i+0] / ref[0]; + cur[1] = (double)ffmap[i+1] / ref[1]; + cur[3] = (double)ffmap[i+2] / ref[3]; // G2 index differs in dcraw and 3FR + cur[2] = (double)ffmap[i+3] / ref[2]; + FORC4 { + if (cur[c] < min) min = cur[c]; + if (cur[c] > max) max = cur[c]; + } + if (max == 0) max = 1.0; + base = (cur[0]+cur[1]+cur[2]+cur[3])/(max*4); + FORC4 cur[c] = cur[c] == 0 ? 1.0 : (base * max) / cur[c]; + /* convert to integer multiplier and store back to ffmap, we limit + range to 4 (16384*4) which should be fine for flatfield */ + FORC4 { + cur[c] *= 16384.0; + if (cur[c] > 65535.0) cur[c] = 65535.0; + ffmap[i+c] = (ushort)cur[c]; + } + } + + // of the cameras we've tested we know the exact placement of the flatfield map + int row_offset, col_offset; + switch (raw_width) { + case 8282: // 50 megapixel Kodak + row_offset = 21; + col_offset = 71; + break; + default: + /* Default case for camera models we've not tested. We center the map, which may + not be exactly where it should be but close enough for the smooth flatfield */ + row_offset = (raw_height - bh * ffrows) / 2; + col_offset = (raw_width - bw * ffcols) / 2; + break; + } + + /* + Concerning smoothing between blocks in the map Phocus makes it only vertically, + probably because it's simpler and faster. Looking at actual flatfield data it seems + like it's better to smooth in both directions. Possibly flatfield could be used for + correcting tiling on Dalsa sensors (H4D-60) like partly done in Phase One IIQ format, + and then sharp edges may be beneficial at least at the tiling seams, but at the time + of writing I've had no H4D-60 3FR files to test with to verify that. + + Meanwhile we do both vertical and horizontal smoothing/blurring. + */ + + /* pre-calculate constants for blurring. We probably should make a more efficient + blur than this, but this does not need any buffer and makes nice-looking + radial gradients */ + ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); + const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, + { {0,1}, {0,2}, {1,1}, {1,2} }, + { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, + { {1,1}, {-1,-1}, {-1,-1}, {-1,-1} }, + { {1,1}, {1,2}, {-1,-1}, {-1,-1} }, + { {1,0}, {1,1}, {2,0}, {2,1} }, + { {1,1}, {2,1}, {-1,-1}, {-1,-1} }, + { {1,1}, {1,2}, {2,1}, {2,2} } }; + const ushort corners_shift[9] = { 2, 1, 2, 1, 0, 1, 2, 1, 2 }; + for (row = 0; row < bh; row++) { + const ushort maxdist = bw < bh ? bw/2-1 : bh/2-1; + const unsigned bwu = (unsigned)bw; + const unsigned bhu = (unsigned)bh; + const unsigned corners[9][2] = {{0,0}, {0,bwu/2}, {0,bwu-1}, + {bhu/2,0},{bhu/2,bwu/2},{bhu/2,bwu-1}, + {bhu-1,0},{bhu-1,bwu/2},{bhu-1,bwu-1}}; + for (col = 0; col < bw; col++) { + for (i = 0; i < 9; i++) { + ushort dist = (ushort)sqrt(abs((int)(corners[i][0] - row)) * abs((int)(corners[i][0] - row)) + abs((int)(corners[i][1] - col)) * abs((int)(corners[i][1] - col))); + ushort weight = dist > maxdist ? 0 : maxdist - dist; + corners_weight[9*(row*bw+col)+i] = weight; + } + } + } + + // apply flatfield +#if defined(LIBRAW_USE_OPENMP) +#pragma omp parallel for +#endif + for (int row = 0; row < raw_height; row++) { + int ffs, cur_ffr, i, c; + if (row < row_offset) { + cur_ffr = row_offset; + ffs = 0; + } else if (row >= row_offset + ffrows * bh) { + cur_ffr = row_offset + (ffrows-1) * bh; + ffs = 4 * ffcols * (ffrows-1); + } else { + cur_ffr = row_offset + bh * ((row - row_offset) / bh); + ffs = 4 * ffcols * ((row - row_offset) / bh); + } + int next_ffc = 0, cur_ffc = col_offset; + int ffc = ffs; + ushort *cur[3][3]; // points to local ffmap entries with center at cur[1][1] + for (int col = 0; col < raw_width; col++) { + if (col == next_ffc) { + int rowsub = ffs == 0 ? 0 : ffcols*4; + int rowadd = ffs == 4 * ffcols * (ffrows-1) ? 0 : ffcols * 4; + int colsub = ffc == ffs ? 0 : 4; + int coladd = ffc == ffs + 4 * (ffcols-1) ? 0 : 4; + if (col != 0) cur_ffc = next_ffc; + else next_ffc += col_offset; + next_ffc += bw; + + cur[0][0] = &ffmap[ffc-rowsub-colsub]; + cur[0][1] = &ffmap[ffc-rowsub]; + cur[0][2] = &ffmap[ffc-rowsub+coladd]; + + cur[1][0] = &ffmap[ffc-colsub]; + cur[1][1] = &ffmap[ffc]; + cur[1][2] = &ffmap[ffc+coladd]; + + cur[2][0] = &ffmap[ffc+rowadd-colsub]; + cur[2][1] = &ffmap[ffc+rowadd]; + cur[2][2] = &ffmap[ffc+rowadd+coladd]; + + ffc += 4; + if (ffc == ffs + 4 * ffcols) next_ffc += raw_width; // last col in map, avoid stepping further + } + unsigned v = RAW(row,col); + if (v > black && v < 65535) { + c = FC(row - top_margin, col - left_margin); + unsigned x = col < cur_ffc ? 0 : col - cur_ffc; + unsigned y = row < cur_ffr ? 0 : row - cur_ffr; + if (x >= bw) x = bw-1; + if (y >= bh) y = bh-1; + unsigned wsum = 0; + unsigned mul = 0; + for (i = 0; i < 9; i++) { + ushort cw = corners_weight[9*(y*bw+x)+i]; + if (cw) { + unsigned m = 0; + int j; + for (j = 0; j < 1 << corners_shift[i]; j++) { + int cr = corners_mix[i][j][0], cc = corners_mix[i][j][1]; + m += cur[cr][cc][c]; + } + m >>= corners_shift[i]; + mul += m * cw; + wsum += cw; + } + } + mul /= wsum; + v = black + ((v-black) * mul) / 16384; + RAW(row,col) = v > 65535 ? 65535 : v; + } + } + } + free(ffmap); + free(corners_weight); + } +} + void LibRaw::hasselblad_load_raw() { struct jhead jh; diff --git a/rtengine/libraw/src/metadata/hasselblad_model.cpp b/rtengine/libraw/src/metadata/hasselblad_model.cpp index b20da5efa..bcd82d44b 100644 --- a/rtengine/libraw/src/metadata/hasselblad_model.cpp +++ b/rtengine/libraw/src/metadata/hasselblad_model.cpp @@ -536,3 +536,97 @@ static const char *Hasselblad_SensorEnclosures[] = { if (normalized_model[0] && !CM_found) CM_found = adobe_coeff(maker_index, normalized_model); } + +// RT: From dcraw.cc. +void LibRaw::parse_hasselblad_gain() +{ + /* + Reverse-engineer's notes: + + The Hasselblad gain tag (0x19 in makernotes) is only available in the 3FR format and + is applied and removed when Hasselblad Phocus converts it to the FFF format. It's + always 0x300000 bytes large regardless of (tested) model, not all space in it is + used though. + + It contains individual calibration information from the factory to tune the sensor + performance. + + There is more calibration data in the tag than what is applied in conversion to FFF, + I've only cared to figure out the data which is actually used, but have some leads on + remaining info. + + The format is not equal between all models. Due to lack of 3FR files (harder to get + than FFF) only a subset of the models have been reverse-engineered. + + The header space is 512 bytes and is a mix of 16 and 32 bit values. Offset to blocks + are 32 bit values, but all information seems to be encoded in 16 bit values. Many + values in the header can be zeroed with no effect on FFF conversion, and their + meaning, if any, have not been further investigated. + + Formats: + hdr16[22] = raw width + hdr16[23] = raw height + hdr32[24] = offset to level corr block + Data block format. Seems to differ depending on sensor type. For tested H4D-50 + and H3D-31: 10 16 bit signed values per row + value 0: a correction factor (k) used on even columns, where the new pixel value is + calculated as follows: + new_value = old_value + (2 * ((k * (old_value_on_row_above-256)) / 32767) - 2) + note the connection to the value on the row above, seems to be some sort of signal + leakage correction. + value 1: same as value 0 but using old value on row below instead of above + value 2-3: same as value 0-1 but for odd columns + value 4-9: has some effect if non-zero (probably similar to the others) but not + investigated which, as it's seems to be always zero for the tested cameras. + + hdr32[25] = probably offset to "bad/unreliable pixels" info, always 512 as it starts + directly after the header. Not applied in FFF conversion (at least + typically). + Data block format guess: raw_height packets of + + + hdr32[27] = offset to unknown data (bad colulmns?), of the form: + <0> + packet: . + + hdr32[34] = curves offset, seems to be A/D curves (one per channel) on newer models + and some sort of a film curve on older. Not applied in FFF conversion. + + hdr32[36] = flatfield correction, not available in older models. Data format: + <1><11 * 2 pad> + packet: + + The header pad is not zeroed and might seem to contain some sort of + information, but it makes no difference if set to zero. See + hasselblad_correct() how the flatfield is applied. + + Applied in FFF conversion is levels, flatfield correction, and the bad columns(?) + data. A/D curves are surprisingly not applied, maybe pre-applied in hardware and + only available as information? Levels are applied before flatfield, further + ordering has not been investigated. + + Not all combinations/models have been tested so there may be gaps. + + Most clipped pixels in a 3FR is at 65535, but there's also some at 65534. Both + are set to 65535 when calibrated, while 65533 is treated as a normal value. In + the calibration process smaller values can be scaled to 65534 (which should + not be seen as clipped). + */ + + auto &hbd = imHassy; + int offset; + off_t base; + + base = ftell(ifp); + fseek(ifp, 2 * 23, SEEK_CUR); + get2(); + fseek(ifp, 48, SEEK_CUR); + offset = get4(); + hbd.levels = offset ? base + offset : 0; + fseek(ifp, 8, SEEK_CUR); + offset = get4(); + hbd.unknown1 = offset ? base + offset : 0; + fseek(ifp, 32, SEEK_CUR); + offset = get4(); + hbd.flatfield = (offset && (base + offset < ifp->size())) ? base + offset : 0; +} diff --git a/rtengine/libraw/src/metadata/makernotes.cpp b/rtengine/libraw/src/metadata/makernotes.cpp index b8ed4d3c7..a51615fb9 100644 --- a/rtengine/libraw/src/metadata/makernotes.cpp +++ b/rtengine/libraw/src/metadata/makernotes.cpp @@ -664,6 +664,9 @@ void LibRaw::parse_makernote(int base, int uptag) imHassy.SensorCode = getint(type); else if (tag == 0x0016) imHassy.CoatingCode = getint(type); + else if (tag == 0x0019 && len == 0x300000) { // RT + parse_hasselblad_gain(); // RT + } else if ((tag == 0x002a) && tagtypeIs(LIBRAW_EXIFTAG_TYPE_SRATIONAL) && (len == 12)) { diff --git a/rtengine/libraw/src/preprocessing/raw2image.cpp b/rtengine/libraw/src/preprocessing/raw2image.cpp index 702cf2902..4407a3b67 100644 --- a/rtengine/libraw/src/preprocessing/raw2image.cpp +++ b/rtengine/libraw/src/preprocessing/raw2image.cpp @@ -75,6 +75,10 @@ int LibRaw::raw2image(void) } } + if (load_raw == &LibRaw::hasselblad_load_raw) { // RT + hasselblad_correct(); // RT + } + // free and re-allocate image bitmap if (imgdata.image) { From 343b5ecc683d4a5f7ed71bf99e6800b8d1d470d8 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 15 Jan 2024 14:40:56 -0500 Subject: [PATCH 093/291] Left-justify the queue destination preview label and allow it to scroll horizontally --- rtgui/batchqueuepanel.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 3fd52df93..e35149326 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -109,9 +109,13 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); destinationPreviewLabel = Gtk::manage (new Gtk::Label ()); - destinationPreviewLabel->set_tooltip_markup(M("QUEUE_DESTPREVIEW_TOOLTIP")); - destinationPreviewLabel->set_selectable(true); // so users can copy the path to the clipboard - odvb->pack_start (*destinationPreviewLabel); + destinationPreviewLabel->set_tooltip_markup (M("QUEUE_DESTPREVIEW_TOOLTIP")); + destinationPreviewLabel->set_selectable (true); // so users can copy the path to the clipboard + destinationPreviewLabel->set_halign (Gtk::ALIGN_START); + auto destinationPreviewScrolledWindow = Gtk::manage(new Gtk::ScrolledWindow ()); + destinationPreviewScrolledWindow->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + destinationPreviewScrolledWindow->add (*destinationPreviewLabel); + odvb->pack_start (*destinationPreviewScrolledWindow, Gtk::PACK_SHRINK); Gtk::RadioButton::Group g = useTemplate->get_group(); useFolder->set_group (g); fdir->add (*odvb); From a39e6779e4cee8b92ff035a9cd21fbb3d2843657 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 15 Jan 2024 15:27:09 -0500 Subject: [PATCH 094/291] Fix: If %p or %P queue template term includes start of file path, prepend the leading /, \ or \\ from the file path --- rtgui/batchqueue.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index df653976c..bb2d7526f 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -75,6 +75,23 @@ namespace // local helper functions } return pathIndex; } + + // Extract the initial characters from a canonical absolute path, and append + // those to a path string. Initial characters are '/' for Unix/Linux paths and + // '\\' for UNC paths. A single backslash is also accepted, for driveless + // Windows paths. + void appendAbsolutePathPrefix(Glib::ustring& path, const Glib::ustring& absolutePath) + { + if (absolutePath[0] == '/') { + path += '/'; // Start of a Unix/Linux path + } else if (absolutePath[0] == '\\') { + if (absolutePath.size() > 1 && absolutePath[1] == '\\') { + path += "\\\\"; // Start of a UNC path + } else { + path += '\\'; // Start of a Windows path that does not include a drive letter + } + } + } } BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCatalog(aFileCatalog), sequence(0), listener(nullptr) @@ -916,6 +933,9 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam ix++; unsigned int n = decodePathIndex(ix, options.savePathTemplate, da.size()); if (n < da.size()) { + if (n == 0) { + appendAbsolutePathPrefix(path, origFileName); + } for (unsigned int i=n; i < da.size(); i++) { path += da[i] + PATH_SEPARATOR; } @@ -930,6 +950,9 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam ix++; unsigned int n = decodePathIndex(ix, options.savePathTemplate, da.size()); for (unsigned int i=0; i <= n && i < da.size(); i++) { + if (i == 0) { + appendAbsolutePathPrefix(path, origFileName); + } path += da[i] + PATH_SEPARATOR; } // If the next template character is a separator, skip it, because path already has one From 1df9b4869e379f8f937831c6487b88c7208f015e Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 15 Jan 2024 16:39:38 -0500 Subject: [PATCH 095/291] Make %p and %P queue output template specifiers limit invalid range rather than treating that as an error. For example in a 4-element path "first 5 elements" and "last 5 elements" now return all four elements. --- rtgui/batchqueue.cc | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index bb2d7526f..53d31d76b 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -51,12 +51,13 @@ using namespace rtengine; namespace // local helper functions { - // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start" - // For N, return Nth index from the end, and for -N return the Nth index from the start - // N is a digit 1 through 9 - unsigned int decodePathIndex(unsigned int& ix, Glib::ustring& templateText, size_t numPathElements) + // Look for N or -N in templateText at position ix, meaning "index from end" and "index from start". + // For N, return Nth index from the end, and for -N return the Nth index from the start. + // N is a digit 1 through 9. The returned value is not range-checked, so it may be >=numPathElements. + // or negative. The caller performs any required range-checking. + int decodePathIndex(unsigned int& ix, Glib::ustring& templateText, size_t numPathElements) { - unsigned int pathIndex = numPathElements; // means input was invalid + int pathIndex = (int)numPathElements; // a value that means input was invalid bool fromStart = false; if (ix < templateText.size()) { if (templateText[ix] == '-') { @@ -65,12 +66,9 @@ namespace // local helper functions } } if (ix < templateText.size()) { - unsigned int n = templateText[ix] - '1'; + pathIndex = templateText[ix] - '1'; if (!fromStart) { - n = numPathElements - n - 1; - } - if (n < numPathElements) { - pathIndex = n; + pathIndex = numPathElements - pathIndex - 1; } } return pathIndex; @@ -900,8 +898,8 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } } -// for (int i=0; i 0) { + appendAbsolutePathPrefix(path, origFileName); + } + for (unsigned int i=0; (int)i <= n && i < da.size(); i++) { path += da[i] + PATH_SEPARATOR; } // If the next template character is a separator, skip it, because path already has one @@ -962,10 +963,9 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } } else if (options.savePathTemplate[ix] == 'd') { // insert a single directory name from the file's path - // da.size()-1 omits the last element, which is the filename ix++; unsigned int n = decodePathIndex(ix, options.savePathTemplate, da.size()); - if (n < da.size()) { + if (n >= 0 && n < da.size()) { path += da[n]; } } else if (options.savePathTemplate[ix] == 'f') { From 6cbc448f63f16bf660d590306b666ecac0d3d85c Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 15 Jan 2024 17:13:40 -0500 Subject: [PATCH 096/291] Handle Samba-style UNC prefix '//' in %p and %P queue output template specifiers --- rtgui/batchqueue.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 53d31d76b..e7de30d30 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -76,12 +76,16 @@ namespace // local helper functions // Extract the initial characters from a canonical absolute path, and append // those to a path string. Initial characters are '/' for Unix/Linux paths and - // '\\' for UNC paths. A single backslash is also accepted, for driveless + // '\\' or '//' for UNC paths. A single backslash is also accepted, for driveless // Windows paths. void appendAbsolutePathPrefix(Glib::ustring& path, const Glib::ustring& absolutePath) { if (absolutePath[0] == '/') { - path += '/'; // Start of a Unix/Linux path + if (absolutePath.size() > 1 && absolutePath[1] == '/') { + path += "//"; // Start of a Samba UNC path + } else { + path += '/'; // Start of a Unix/Linux path + } } else if (absolutePath[0] == '\\') { if (absolutePath.size() > 1 && absolutePath[1] == '\\') { path += "\\\\"; // Start of a UNC path From 11a0a0b6975a62aa28d6623770b60f9dbcbd7063 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Tue, 16 Jan 2024 07:54:12 -0500 Subject: [PATCH 097/291] Fixes per pull request comments: fix %p-1 missing slash, use static_cast, fix int/unsigned mismatches --- rtgui/batchqueue.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index e7de30d30..2811e3445 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -57,7 +57,7 @@ namespace // local helper functions // or negative. The caller performs any required range-checking. int decodePathIndex(unsigned int& ix, Glib::ustring& templateText, size_t numPathElements) { - int pathIndex = (int)numPathElements; // a value that means input was invalid + int pathIndex = static_cast(numPathElements); // a value that means input was invalid bool fromStart = false; if (ix < templateText.size()) { if (templateText[ix] == '-') { @@ -447,7 +447,7 @@ Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring &filenam timeval tv; gettimeofday(&tv, nullptr); char mseconds[11]; - snprintf(mseconds, sizeof(mseconds), "%d", (int)(tv.tv_usec / 1000)); + snprintf(mseconds, sizeof(mseconds), "%d", static_cast((tv.tv_usec / 1000))); time_t rawtime; struct tm *timeinfo; char stringTimestamp [80]; @@ -937,11 +937,11 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam if (n < 0) { n = 0; // if too many elements specified, return all available elements } - if (n < (int)da.size()) { + if (n < static_cast(da.size())) { if (n == 0) { appendAbsolutePathPrefix(path, origFileName); } - for (unsigned int i = (unsigned int)n; i < da.size(); i++) { + for (unsigned int i = static_cast(n); i < da.size(); i++) { path += da[i] + PATH_SEPARATOR; } } @@ -954,10 +954,10 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam // insert path elements from the start of the path up to the given index ix++; int n = decodePathIndex(ix, options.savePathTemplate, da.size()); - if (n > 0) { + if (n >= 0) { appendAbsolutePathPrefix(path, origFileName); } - for (unsigned int i=0; (int)i <= n && i < da.size(); i++) { + for (unsigned int i=0; static_cast(i) <= n && i < da.size(); i++) { path += da[i] + PATH_SEPARATOR; } // If the next template character is a separator, skip it, because path already has one @@ -968,8 +968,8 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } else if (options.savePathTemplate[ix] == 'd') { // insert a single directory name from the file's path ix++; - unsigned int n = decodePathIndex(ix, options.savePathTemplate, da.size()); - if (n >= 0 && n < da.size()) { + int n = decodePathIndex(ix, options.savePathTemplate, da.size()); + if (n >= 0 && n < static_cast(da.size())) { path += da[n]; } } else if (options.savePathTemplate[ix] == 'f') { From 7c781aa7b1884c51dec6fab15fae19f70d695ad9 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sat, 27 Jan 2024 22:21:28 -0800 Subject: [PATCH 098/291] bump macos CI workflow to macos-12 macos-11 is obsolete to homebrew --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 992bf4db3..d075594fd 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,7 +13,7 @@ on: jobs: build: - runs-on: macos-11 + runs-on: macos-12 steps: - uses: actions/checkout@v3 - name: Install dependencies From e4087e2fa2f4b0bcee08e1aa903df1a3201c86d2 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 1 Feb 2024 07:48:07 +0100 Subject: [PATCH 099/291] White balance auto temperature correlation - improve behavior with non raw files (#6903) * Improve Itcwb with non-raw files * Change pre-dev builds wbrefinement * Change template in pre-dev * Improvment improccordinator.cc * Forgotten observer convert * Reenable wbauto autogrey as 5.8 * Remove wrong code * Missing getrgbloc references * Fixed bug due to bias in queu with temperaure correlation issue 6911 * Simpleprocess queue compatibility tif-jpg * Preserve AWB edits from 5.9 In 5.9 for non-raw files, 1. RGB grey uses the unit multipliers with temperature bias applied. 2. Temperature correlation uses the equivalent of temperature 5000, green 1, and red/blue equalizer 1. * Refactor temperature correlation AWB code * Fix inaccurate RGB grey WB preview after using ITC The RGB grey automatic white balance algorithm caches the multipliers. Temperature correlation automatic white balance also caches results to the same location, but never uses it. This causes the RGB grey method to produce incorrect results in the editor. Removing the temperature correlation cache fixes the issue and does not have side-effects. --------- Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 4 +- rtengine/CMakeLists.txt | 1 + rtengine/imagesource.cc | 275 ++++++++++++++++++++++++++++ rtengine/imagesource.h | 27 +++ rtengine/improccoordinator.cc | 317 ++++++++++----------------------- rtengine/improccoordinator.h | 1 - rtengine/procparams.cc | 23 ++- rtengine/procparams.h | 20 +++ rtengine/rawimagesource.cc | 8 +- rtengine/rtengine.h | 9 +- rtengine/rtthumbnail.cc | 14 +- rtengine/simpleprocess.cc | 267 +++++---------------------- rtengine/stdimagesource.cc | 4 + rtengine/stdimagesource.h | 2 +- rtgui/paramsedited.cc | 6 + rtgui/paramsedited.h | 1 + rtgui/whitebalance.cc | 43 ++++- rtgui/whitebalance.h | 3 +- 20 files changed, 561 insertions(+), 468 deletions(-) create mode 100644 rtengine/imagesource.cc diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 0d3c76399..94bee4ebf 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:wbrefinement"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 9b49edd91..b466ec265 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:wbrefinement"]' jobs: build: diff --git a/rtdata/languages/default b/rtdata/languages/default index bf43596dc..dfa149857 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2040,7 +2040,7 @@ PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles PREFERENCES_WBA;White Balance PREFERENCES_WBACORR;White Balance - Automatic temperature correlation PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -PREFERENCES_WBAENA;Show White Balance auto Temperature correlation Settings +PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings PREFERENCES_WBAENACUSTOM;Use Custom temperature & tint PREFERENCES_WBAFORC;Forces Extra algoritm PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) @@ -4170,7 +4170,7 @@ TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop TP_WBALANCE_ITCWB_FGREEN;Find green student TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram -TP_WBALANCE_ITCWB_FRA;Auto Temperature correlation Settings +TP_WBALANCE_ITCWB_FRA;Auto temperature correlation settings TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimum size TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple color diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 5a9b2d953..6f329f7be 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -120,6 +120,7 @@ set(RTENGINESOURCEFILES imagedimensions.cc imagefloat.cc imageio.cc + imagesource.cc improccoordinator.cc improcfun.cc impulse_denoise.cc diff --git a/rtengine/imagesource.cc b/rtengine/imagesource.cc new file mode 100644 index 000000000..049c6b562 --- /dev/null +++ b/rtengine/imagesource.cc @@ -0,0 +1,275 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2024 RawTherapee team + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#include "imagesource.h" +#include "procparams.h" + + +namespace rtengine +{ + +void ImageSource::getAutoWBMultipliersItcGreen( + procparams::ProcParams ¶ms, + bool forcewbgrey, + int kcam, + double greenitc, + bool extra, + float &temp0, + float &delta, + int &bia, + int &dread, + int nocam, + float &studgood, + float &minchrom, + int &kmin, + float &minhist, + float &maxhist, + int fh, + int fw, + ColorTemp &currWB, + int tempnotisraw, + double greennotisraw, + bool skipRecalculate, + ColorTemp &autoWB, + double &rm, + double &gm, + double &bm + ) +{ + float tem = 5000.f; + float gre = 1.f; + double tempref0bias = 5000.; + double tempitc = 5000.f; + bool autowb1 = true; + double green_thres = 0.8; + + if (isRAW()) {// only with Raw files + + auto currWBitc = getWB(); + + double greenref = currWBitc.getGreen(); + double tempref0bias0 = currWBitc.getTemp(); + + if (greenref > green_thres && params.wb.itcwb_prim == "srgb") { + forcewbgrey = true; + } + + if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 + if (settings->verbose) { + printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); + } + + autowb1 = true; + kcam = 1; + } + + if (autowb1) { + //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera + // kcam = 0; + params.wb.method = "autold"; + tempitc = 5000.f; + greenitc = 1.; + currWBitc = getWB(); + tempref0bias = currWBitc.getTemp(); + double greenref = currWBitc.getGreen(); + bool pargref = true; + bool pargre = true; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust... + getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + wbMul2Camera(rm, gm, bm); + wbCamera2Mul(rm, gm, bm); + ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); + tem = ct.getTemp(); + gre = ct.getGreen(); + + if (gre > 1.3f) { + pargre = false; + } + + if (greenref > 1.3f) { + pargref = false; + } + + double deltemp = tem - tempref0bias; + + if (gre > 1.5f && !forcewbgrey) { //probable wrong value + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out + } else { + if (!forcewbgrey) { + gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + nocam = 0; + } else {//set temp and green to init itcwb algorithm + double grepro = LIM(greenref, green_thres, 1.15); + gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey + + if (abs(deltemp) < 400.) { //arbitraries thresholds to refine + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 1; + } else { + nocam = 2; + } + } else if (abs(deltemp) < 900.) { //other arbitrary threshold + tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 3; + } else { + nocam = 4; + } + } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 5; + } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 6; + } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { + if (tem >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 7; + } else { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 8; + } + } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { + if (tem >= 10000.f) { + tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 9; + } else { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 10; + } + } else { + tem = 0.4 * tem + 0.6 * tempref0bias; + nocam = 11; + } + } + } + + tempitc = tem ; + + extra = true; + + if (settings->verbose) { + printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); + } + } + } + + params.wb.method = "autitcgreen"; + + } else if (!isRAW()) { // Itcwb and no raw + params.wb.temperature = tempnotisraw; + params.wb.green = greennotisraw; + params.wb.equal = 1.; + } + float greenitc_low = 1.f; + float tempitc_low = 5000.f; + //raw files and autitcgreen + if (isRAW() || !skipRecalculate) { + greenitc = 1.; + auto currWBitc = getWB(); + currWBitc = currWBitc.convertObserver(params.wb.observer);//change the temp/green couple with the same multipliers + + double tempref = currWBitc.getTemp() * (1. + params.wb.tempBias); + double greenref = currWBitc.getGreen(); + greenitc = greenref; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? + tempref = tem * (1. + params.wb.tempBias); + greenref = gre; + } else { + + } + + if(params.wb.itcwb_sampling) { + greenitc_low = greenref; + tempitc_low = tempref; + } + + if (settings->verbose) { + printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); + } + + getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + + params.wb.temperature = tempitc; + params.wb.green = greenitc; + if(params.wb.itcwb_sampling) { + params.wb.temperature = tempitc_low; + params.wb.green = greenitc_low; + } + + currWB = ColorTemp(params.wb.temperature, params.wb.green, 1., params.wb.method, params.wb.observer); + currWB.getMultipliers(rm, gm, bm); + autoWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, 0.); //params.wb.tempBias already used before + + } +} + +} // namespace rtengine + diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 95fd77d21..50bc38baf 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -118,6 +118,33 @@ public: virtual void convertColorSpace (Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0; virtual void getAutoWBMultipliersitc(bool extra, double &tempref, double &greenref, double &tempitc, double & greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0; + virtual void getAutoWBMultipliersItcGreen( + procparams::ProcParams ¶ms, + bool forcewbgrey, + int kcam, + double greenitc, + bool extra, + float &temp0, + float &delta, + int &bia, + int &dread, + int nocam, + float &studgood, + float &minchrom, + int &kmin, + float &minhist, + float &maxhist, + int fh, + int fw, + ColorTemp &currWB, + int tempnotisraw, + double greennotisraw, + bool skipRecalculate, + ColorTemp &autoWB, + double &rm, + double &gm, + double &bm + ); virtual ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) = 0; virtual void WBauto(bool extra, double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ef8dc8dbf..5a5dd12af 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -518,7 +518,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } - const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); + // const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); if (settings->verbose) { printf("automethod=%s \n", params->wb.method.c_str()); @@ -534,6 +534,24 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); + int tempnotisraw = 6501;//D65 with Observer 2° - 6473 with Observer 10° + double greennotisraw = 1.;//D65 with Observer 2° - 0.967 with Observer 10° + + if (!imgsrc->isRAW() && params->wb.method == "autitcgreen") { + if (params->wb.compat_version == 1) { + // ITCWB compatibility version 1 used 5000 K and observer 10 + // degrees for non-raw files. + auto currWBitc = ColorTemp(5000., 1., 1., params->wb.method, StandardObserver::TEN_DEGREES); + currWBitc = currWBitc.convertObserver(params->wb.observer); + tempnotisraw = currWBitc.getTemp(); + greennotisraw = currWBitc.getGreen(); + } else { + auto currWBitc = imgsrc->getWB();//if jpg TIF with another illuminant + currWBitc = currWBitc.convertObserver(params->wb.observer); + tempnotisraw = currWBitc.getTemp(); + greennotisraw = currWBitc.getGreen(); + } + } int dread = 0; int bia = 1; @@ -545,7 +563,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) int kmin = 20; float minhist = 1000000000.f; float maxhist = -1000.f; - double tempitc = 5000.f; double greenitc = 1.; float temp0 = 5000.f; bool extra = false; @@ -556,230 +573,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } else if (params->wb.method == "Camera") { currWB = imgsrc->getWB(); lastAwbauto = ""; //reinitialize auto - } else if (autowb) { - float tem = 5000.f; - float gre = 1.f; - double tempref0bias = 5000.; - tempitc = 5000.f; - bool autowb1 = true; - double green_thres = 0.8; - - if (params->wb.method == "autitcgreen") { - - currWBitc = imgsrc->getWB(); - - double greenref = currWBitc.getGreen(); - double tempref0bias0 = currWBitc.getTemp(); - - if (greenref > green_thres && params->wb.itcwb_prim == "srgb") { - forcewbgrey = true; - } - - if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 - if (settings->verbose) { - printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); - } - - autowb1 = true; - kcam = 1; - } - - if (autowb1) { - //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera - // kcam = 0; - params->wb.method = "autold"; - double rm, gm, bm; - tempitc = 5000.f; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - tempref0bias = currWBitc.getTemp(); - double greenref = currWBitc.getGreen(); - bool pargref = true; - bool pargre = true; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust... - imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); - imgsrc->wbMul2Camera(rm, gm, bm); - imgsrc->wbCamera2Mul(rm, gm, bm); - ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); - tem = ct.getTemp(); - gre = ct.getGreen(); - - if (gre > 1.3f) { - pargre = false; - } - - if (greenref > 1.3f) { - pargref = false; - } - - double deltemp = tem - tempref0bias; - - if (gre > 1.5f && !forcewbgrey) { //probable wrong value - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out - } else { - if (!forcewbgrey) { - gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - nocam = 0; - } else {//set temp and green to init itcwb algorithm - double grepro = LIM(greenref, green_thres, 1.15); - gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey - - if (abs(deltemp) < 400.) { //arbitraries thresholds to refine - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 1; - } else { - nocam = 2; - } - } else if (abs(deltemp) < 900.) { //other arbitrary threshold - tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 3; - } else { - nocam = 4; - } - } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 5; - } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 6; - } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { - if (tem >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 7; - } else { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 8; - } - } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { - if (tem >= 10000.f) { - tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 9; - } else { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 10; - } - } else { - tem = 0.4 * tem + 0.6 * tempref0bias; - nocam = 11; - } - } - } - - tempitc = tem ; - - extra = true; - - if (settings->verbose) { - printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); - } - } - } - - params->wb.method = "autitcgreen"; - - } - float greenitc_low = 1.f; - float tempitc_low = 5000.f; - if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { + + } else if (params->wb.method == "autold") { + if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { double rm, gm, bm; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - currWBitc = currWBitc.convertObserver(params->wb.observer);//change the temp/green couple with the same multipliers - - double tempref = currWBitc.getTemp() * (1. + params->wb.tempBias); - double greenref = currWBitc.getGreen(); - greenitc = greenref; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? - tempref = tem * (1. + params->wb.tempBias); - greenref = gre; + if (params->wb.compat_version == 1 && !imgsrc->isRAW()) { + // RGB grey compatibility version 1 used the identity + // multipliers plus temperature bias for non-raw files. + rm = gm = bm = 1.; } else { - - } - - if(params->wb.itcwb_sampling) { - greenitc_low = greenref; - tempitc_low = tempref; - } - - if (settings->verbose && params->wb.method == "autitcgreen") { - printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); - } - - imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); - - if (params->wb.method == "autitcgreen") { - params->wb.temperature = tempitc; - params->wb.green = greenitc; - if(params->wb.itcwb_sampling) { - params->wb.temperature = tempitc_low; - params->wb.green = greenitc_low; - } - - currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method, params->wb.observer); - currWB.getMultipliers(rm, gm, bm); - autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, params->wb.tempBias); + imgsrc->getAutoWBMultipliers(rm, gm, bm); } if (rm != -1.) { - double bias = params->wb.tempBias; - if (params->wb.method == "autitcgreen") { - bias = 0.; - } - autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, bias); lastAwbEqual = params->wb.equal; lastAwbObserver = params->wb.observer; @@ -791,6 +599,58 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lastAwbTempBias = 0.0; lastAwbauto = ""; autoWB.useDefaults(params->wb.equal, params->wb.observer); + + } + + //double rr,gg,bb; + //autoWB.getMultipliers(rr,gg,bb); + } + currWB = autoWB; + // lastAwbauto = ""; //reinitialize auto + } else if (params->wb.method == "autitcgreen") { //(// autowb) { + double rm; + double gm; + double bm; + imgsrc->getAutoWBMultipliersItcGreen( + *params, + forcewbgrey, + kcam, + greenitc, + extra, + temp0, + delta, + bia, + dread, + nocam, + studgood, + minchrom, + kmin, + minhist, + maxhist, + fh, + fw, + currWB, + tempnotisraw, + greennotisraw, + lastAwbEqual == params->wb.equal && lastAwbObserver == params->wb.observer && lastAwbTempBias == params->wb.tempBias && lastAwbauto == params->wb.method, + autoWB, + rm, + gm, + bm); + + if (imgsrc->isRAW() || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { + if (rm != -1.) { + autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer); + lastAwbEqual = params->wb.equal; + lastAwbObserver = params->wb.observer; + lastAwbTempBias = params->wb.tempBias; + lastAwbauto = params->wb.method; + } else { + lastAwbEqual = -1.; + lastAwbObserver = ColorTemp::DEFAULT_OBSERVER; + lastAwbTempBias = 0.0; + lastAwbauto = ""; + autoWB.useDefaults(params->wb.equal, params->wb.observer); } } @@ -822,12 +682,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) int met = 0; - if (awbListener) { - if (params->wb.method == "autitcgreen") { + if (awbListener && params->wb.enabled) { + if (params->wb.method == "autitcgreen" && imgsrc->isRAW()) {//Raw files if (params->wb.itcwb_sampling) { dread = 1; studgood = 1.f; - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW); } else { minchrom = LIM(minchrom, 0.f, 0.9f); @@ -836,10 +696,19 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) maxhist = std::max(maxhist, 1000.f); kmin = std::max(kmin, 18); dread = LIM(dread, 10, 239); - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW); } + } else if (params->wb.method == "autitcgreen" && !imgsrc->isRAW()) {//non raw files + params->wb.temperature = tempnotisraw; + params->wb.green = greennotisraw; + currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); + + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::TEMP_CORRELATION_NON_RAW);//false => hide settings + + } else if (params->wb.method == "autold"){ + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::RGB_GREY); } else { - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::NONE); } } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 7e4e3bb06..e236aed17 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -78,7 +78,6 @@ protected: ColorTemp autoWB; ColorTemp currWBloc; ColorTemp autoWBloc; - ColorTemp currWBitc; double lastAwbEqual; StandardObserver lastAwbObserver{ColorTemp::DEFAULT_OBSERVER}; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index afbce8849..4f6285ac9 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1409,7 +1409,8 @@ WBParams::WBParams() : itcwb_nopurple(false),//keep for settings itcwb_alg(false),//checkbox itcwb_prim("beta"),//combobox - itcwb_sampling(false)//keep for 5.9 and for settings + itcwb_sampling(false),//keep for 5.9 and for settings + compat_version(WBParams::CURRENT_COMPAT_VERSION) { } @@ -1434,6 +1435,7 @@ bool WBParams::isPanningRelatedChange(const WBParams& other) const && itcwb_green == other.itcwb_green && itcwb_prim == other.itcwb_prim && itcwb_alg == other.itcwb_alg + && compat_version == other.compat_version ) ) @@ -1455,7 +1457,8 @@ bool WBParams::operator ==(const WBParams& other) const && itcwb_nopurple == other.itcwb_nopurple && itcwb_alg == other.itcwb_alg && itcwb_prim == other.itcwb_prim - && itcwb_sampling == other.itcwb_sampling; + && itcwb_sampling == other.itcwb_sampling + && compat_version == other.compat_version; } @@ -6316,6 +6319,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wb.itcwb_alg, "White Balance", "Itcwb_alg", wb.itcwb_alg, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_prim, "White Balance", "Itcwb_prim", wb.itcwb_prim, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_sampling, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, keyFile); + saveToKeyfile(!pedited || pedited->wb.compat_version, "White Balance", "CompatibilityVersion", wb.compat_version, keyFile); // Colorappearance saveToKeyfile(!pedited || pedited->colorappearance.enabled, "Color appearance", "Enabled", colorappearance.enabled, keyFile); @@ -8293,7 +8297,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "White Balance", "Enabled", wb.enabled, pedited->wb.enabled); assignFromKeyfile(keyFile, "White Balance", "Setting", wb.method, pedited->wb.method); if (wb.method == "Auto") { - wb.method = "autold"; + wb.method = "autitcgreen"; //"autold"; } assignFromKeyfile(keyFile, "White Balance", "Temperature", wb.temperature, pedited->wb.temperature); assignFromKeyfile(keyFile, "White Balance", "Green", wb.green, pedited->wb.green); @@ -8318,6 +8322,19 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, pedited->wb.itcwb_sampling); + if (!assignFromKeyfile(keyFile, "White Balance", "CompatibilityVersion", wb.compat_version, pedited->wb.compat_version)) { + bool compat_version_edited = true; + if (ppVersion <= 346) { // 5.8 and earlier. + wb.compat_version = 0; + } else if (ppVersion <= 349) { // 5.9. + wb.compat_version = 1; + } else { + compat_version_edited = false; + } + if (pedited) { + pedited->wb.compat_version = pedited->wb.compat_version || compat_version_edited; + } + } } if (keyFile.has_group("Defringing")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index b748a7027..9b0f6463a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -636,6 +636,8 @@ struct WBEntry { }; struct WBParams { + static constexpr int CURRENT_COMPAT_VERSION = 2; + bool enabled; Glib::ustring method; int temperature; @@ -649,6 +651,24 @@ struct WBParams { bool itcwb_alg; Glib::ustring itcwb_prim; bool itcwb_sampling; + /** + * Used to maintain edits from previous versions of RawTherapee where + * compatibility cannot be maintained simply by converting the parameters, + * for example, when the output depends on the file type. + * + * Version 0: + * - Base version. + * Version 1 (5.9): + * - RGB Gray fixed to (1, 1, 1) RGB multipliers before temperature bias + * for non-raw files. + * - Temperature correlation fixed to temperature 5000, green 1, and equal + * 1 or equivalent for non-raw files. + * Version 2 (5.10): + * - RGB grey restored to version 0. + * - Temperature correlation equivalent to method "Camera" for non-raw + * files. + */ + int compat_version; WBParams(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index fdecf638a..8149c0464 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -7414,7 +7414,6 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int int precision = 3;//must be 3 5 or 9 bool oldsampling = wbpar.itcwb_sampling; - if (oldsampling == true) { precision = 5; } @@ -7701,12 +7700,7 @@ void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, doubl printf("RGB grey AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); } - if (wbpar.method == "autitcgreen") { - //not used - redAWBMul = rm = avg_rm * refwb_red; - greenAWBMul = gm = avg_gm * refwb_green; - blueAWBMul = bm = avg_bm * refwb_blue; - } else { + if (wbpar.method != "autitcgreen") { const double reds = avg_r / std::max(1, rn) * refwb_red; const double greens = avg_g / std::max(1, gn) * refwb_green; const double blues = avg_b / std::max(1, bn) * refwb_blue; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ba4d2ed60..fb669e1c8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -458,8 +458,15 @@ public: class AutoWBListener { public: + enum class AWBMode { + NONE, + RGB_GREY, + TEMP_CORRELATION_NON_RAW, + TEMP_CORRELATION_RAW, + }; + virtual ~AutoWBListener() = default; - virtual void WBChanged(int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) = 0; + virtual void WBChanged(int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) = 0; }; class FrameCountListener diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index bc832661a..4337477da 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1202,7 +1202,19 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT double cam_b = colorMatrix[2][0] * camwbRed + colorMatrix[2][1] * camwbGreen + colorMatrix[2][2] * camwbBlue; currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal, params.wb.observer); } else if (params.wb.method == "autold") { - currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom", wbObserver); + if (params.wb.compat_version == 1 && !isRaw) { + // RGB grey compatibility version 1 used the identity multipliers + // plus temperature bias for non-raw files. + currWB.update(1., 1., 1., params.wb.equal, params.wb.observer, params.wb.tempBias); + } else { + currWB = ColorTemp(autoWBTemp, autoWBGreen, wbEqual, "Custom", wbObserver); + } + } else if (params.wb.method == "autitcgreen") { + if (params.wb.compat_version == 1 && !isRaw) { + currWB = ColorTemp(5000., 1., 1., params.wb.method, StandardObserver::TEN_DEGREES); + } else { + // TODO: Temperature correlation AWB. + } } double rm, gm, bm; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 319ba7f3b..b82c7fe79 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -275,7 +275,7 @@ private: if (params.wb.method == "autitcgreen" && flush) { imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw, params.wb); } - const bool autowb = params.wb.method == "autitcgreen"; + const bool autowb = (params.wb.method == "autitcgreen" && imgsrc->isRAW() && flush); ColorTemp autoWB; int dread = 0; int bia = 1; @@ -295,233 +295,60 @@ private: if (!params.wb.enabled) { currWB = ColorTemp(); - } else if (params.wb.method == "Camera") { + } else if (params.wb.method == "Camera" || (params.wb.method == "autitcgreen" && params.wb.compat_version >= 2 && !imgsrc->isRAW() && flush)) {//Use also Camera settings for Temperature correlation and TIF/Jpg currWB = imgsrc->getWB(); } else if (params.wb.method == "autold") {//for Auto RGB double rm, gm, bm; - imgsrc->getAutoWBMultipliers(rm, gm, bm); + if (params.wb.compat_version == 1 && !imgsrc->isRAW()) { + // RGB grey compatibility version 1 used the identity + // multipliers plus temperature bias for non-raw files. + rm = gm = bm = 1.; + } else { + imgsrc->getAutoWBMultipliers(rm, gm, bm); + } currWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); - } else if (autowb && flush) {//for auto Itcwb - flush to enable only when batch + } else if (autowb) {//for auto Itcwb - flush to enable only when batch only with Raw files //code similar to that present in improccoordinator.cc - float tem = 5000.f; - float gre = 1.f; - double tempref0bias = 5000.; - tempitc = 5000.f; - bool autowb1 = true; - double green_thres = 0.8; - - { - currWBitc = imgsrc->getWB(); - - double greenref = currWBitc.getGreen(); - double tempref0bias0 = currWBitc.getTemp(); - - if (greenref > green_thres && params.wb.itcwb_prim == "srgb") { - forcewbgrey = true; - } - - if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 - if (settings->verbose) { - printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); - } - - autowb1 = true; - kcam = 1; - } - - if (autowb1) { - //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera - // kcam = 0; - params.wb.method = "autold"; - double rm, gm, bm; - tempitc = 5000.f; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - tempref0bias = currWBitc.getTemp(); - double greenref = currWBitc.getGreen(); - bool pargref = true; - bool pargre = true; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust... - imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); - imgsrc->wbMul2Camera(rm, gm, bm); - imgsrc->wbCamera2Mul(rm, gm, bm); - ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); - tem = ct.getTemp(); - gre = ct.getGreen(); - - if (gre > 1.3f) { - pargre = false; - } - - if (greenref > 1.3f) { - pargref = false; - } - - double deltemp = tem - tempref0bias; - - if (gre > 1.5f && !forcewbgrey) { //probable wrong value - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out - } else { - if (!forcewbgrey) { - gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - nocam = 0; - } else {//set temp and green to init itcwb algorithm - double grepro = LIM(greenref, green_thres, 1.15); - gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey - - if (abs(deltemp) < 400.) { //arbitraries thresholds to refine - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 1; - } else { - nocam = 2; - } - } else if (abs(deltemp) < 900.) { //other arbitrary threshold - tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 3; - } else { - nocam = 4; - } - } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 5; - } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 6; - } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { - if (tem >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 7; - } else { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 8; - } - } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { - if (tem >= 10000.f) { - tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 9; - } else { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 10; - } - } else { - tem = 0.4 * tem + 0.6 * tempref0bias; - nocam = 11; - } - } - } - - tempitc = tem ; - - extra = true; - - if (settings->verbose) { - printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); - } - } - } - - params.wb.method = "autitcgreen"; - - } - - float greenitc_low = 1.f; - float tempitc_low = 5000.f; - { - double rm, gm, bm; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - currWBitc = currWBitc.convertObserver(params.wb.observer);//change the temp/green couple with the same multipliers - - double tempref = currWBitc.getTemp() * (1. + params.wb.tempBias); - double greenref = currWBitc.getGreen(); - greenitc = greenref; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? - tempref = tem * (1. + params.wb.tempBias); - greenref = gre; - } else { - - } - - if(params.wb.itcwb_sampling) { - greenitc_low = greenref; - tempitc_low = tempref; - } - - if (settings->verbose && params.wb.method == "autitcgreen") { - printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); - } - - imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); - - - params.wb.temperature = tempitc; - params.wb.green = greenitc; - - if(params.wb.itcwb_sampling) { - params.wb.temperature = tempitc_low; - params.wb.green = greenitc_low; - } - - currWB = ColorTemp(params.wb.temperature, params.wb.green, 1., params.wb.method, params.wb.observer); - currWB.getMultipliers(rm, gm, bm); - autoWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); - - } + double rm; + double gm; + double bm; + imgsrc->getAutoWBMultipliersItcGreen( + params, + forcewbgrey, + kcam, + greenitc, + extra, + temp0, + delta, + bia, + dread, + nocam, + studgood, + minchrom, + kmin, + minhist, + maxhist, + fh, + fw, + currWB, + 0, + 0., + false, + autoWB, + rm, + gm, + bm); currWB = autoWB; + } else if (params.wb.method == "autitcgreen" && params.wb.compat_version == 1 && !imgsrc->isRAW() && flush) { + // ITCWB compatibility version 1 used 5000 K and observer 10 degrees + // for non-raw files. + currWB = ColorTemp(5000., 1., 1., params.wb.method, StandardObserver::TEN_DEGREES); + currWB.convertObserver(params.wb.observer); + params.wb.temperature = currWB.getTemp(); + params.wb.green = currWB.getGreen(); + params.wb.equal = currWB.getEqual(); } //end WB auto diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 9363c84cb..435f2f9a0 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -315,6 +315,10 @@ void StdImageSource::WBauto(bool extra, double &tempref, double &greenref, array { } +void StdImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) +{ +} + void StdImageSource::getAutoWBMultipliersitc(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const WBParams & wbpar, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp) { if (redAWBMul != -1.) { diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 8c2a54a3b..1ffb0158d 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -59,7 +59,7 @@ public: int load (const Glib::ustring &fname) override; void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const override {}; void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; - void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) override {}; + void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) override; ColorTemp getWB () const override { return wb; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ea7c4adc2..ed7ad2754 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -273,6 +273,7 @@ void ParamsEdited::set(bool v) wb.itcwb_alg = v; wb.itcwb_prim = v; wb.itcwb_sampling = v; + wb.compat_version = v; //colorShift.a = v; //colorShift.b = v; //lumaDenoise.enabled = v; @@ -988,6 +989,7 @@ void ParamsEdited::initFrom(const std::vector& wb.itcwb_alg = wb.itcwb_alg && p.wb.itcwb_alg == other.wb.itcwb_alg; wb.itcwb_prim = wb.itcwb_prim && p.wb.itcwb_prim == other.wb.itcwb_prim; wb.itcwb_sampling = wb.itcwb_sampling && p.wb.itcwb_sampling == other.wb.itcwb_sampling; + wb.compat_version = wb.compat_version && p.wb.compat_version == other.wb.compat_version; //colorShift.a = colorShift.a && p.colorShift.a == other.colorShift.a; //colorShift.b = colorShift.b && p.colorShift.b == other.colorShift.b; //lumaDenoise.enabled = lumaDenoise.enabled && p.lumaDenoise.enabled == other.lumaDenoise.enabled; @@ -2897,6 +2899,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wb.temperature = dontforceSet && options.baBehav[ADDSET_WB_TEMPERATURE] ? toEdit.wb.temperature + mods.wb.temperature : mods.wb.temperature; } + if (wb.compat_version) { + toEdit.wb.compat_version = mods.wb.compat_version; + } + //if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a; //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 9f9e4f620..565eca36a 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -255,6 +255,7 @@ struct WBParamsEdited { bool itcwb_prim; bool itcwb_sampling; bool itcwb_green; + bool compat_version; }; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 2f3686242..f245e42f2 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -396,8 +396,9 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC itcwb_prim->set_active(1); itcwb_primconn = itcwb_prim->signal_changed().connect(sigc::mem_fun(*this, &WhiteBalance::itcwb_prim_changed)); itcwb_prim ->set_tooltip_markup (M("TP_WBALANCE_ITCWPRIM_TOOLTIP")); - - + + compatVersionAdjuster.reset(new Adjuster("", 0., procparams::WBParams::CURRENT_COMPAT_VERSION, 1., procparams::WBParams::CURRENT_COMPAT_VERSION)); + /* Gtk::Box* boxgreen = Gtk::manage (new Gtk::Box ()); boxgreen->show (); @@ -624,6 +625,7 @@ void WhiteBalance::optChanged () equal->setEditedState (UnEdited); tempBias->setEditedState (UnEdited); observer10->setEdited(false); + compatVersionAdjuster->setEditedState(UnEdited); } else { unsigned int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI); const WBEntry& currMethod = WBParams::getWbEntries()[methodId]; @@ -723,6 +725,17 @@ void WhiteBalance::optChanged () break; } + + if (compatVersionAdjuster->getIntValue() == 1 && + (!batchMode || currMethod.type != WBEntry::Type::AUTO)) { + // Safe to upgrade version because method changed. In batch + // mode, this method may be called even if there is no change, + // so it's only safe to upgrade if the new method is not auto. + compatVersionAdjuster->setValue(procparams::WBParams::CURRENT_COMPAT_VERSION); + if (batchMode) { + compatVersionAdjuster->setEditedState(Edited); + } + } } if (listener && getEnabled()) { @@ -768,6 +781,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) lastitcwb_alg = pp->wb.itcwb_alg; itcwb_green->setValue (pp->wb.itcwb_green); + compatVersionAdjuster->setValue(pp->wb.compat_version); itcwb_primconn.block (true); @@ -806,6 +820,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) observer10->setEdited(pedited->wb.observer); itcwb_alg->set_inconsistent (!pedited->wb.itcwb_alg); itcwb_green->setEditedState (pedited->wb.itcwb_green ? Edited : UnEdited); + compatVersionAdjuster->setEditedState(pedited->wb.compat_version ? Edited : UnEdited); } if (pedited && !pedited->wb.method) { @@ -961,6 +976,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pedited->wb.enabled = !get_inconsistent(); pedited->wb.itcwb_prim = itcwb_prim->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wb.itcwb_green = itcwb_green->getEditedState (); + pedited->wb.compat_version = compatVersionAdjuster->getEditedState(); } pp->wb.enabled = getEnabled(); @@ -996,6 +1012,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pp->wb.itcwb_alg = itcwb_alg->get_active (); pp->wb.tempBias = tempBias->getValue (); pp->wb.itcwb_green = itcwb_green->getValue (); + pp->wb.compat_version = compatVersionAdjuster->getIntValue(); } void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) @@ -1044,6 +1061,7 @@ void WhiteBalance::setBatchMode (bool batchMode) green->showEditedCB (); equal->showEditedCB (); tempBias->showEditedCB (); + compatVersionAdjuster->showEditedCB(); Gtk::TreeModel::Row row = *(refTreeModel->append()); row[methodColumns.colId] = WBParams::getWbEntries().size(); row[methodColumns.colLabel] = M("GENERAL_UNCHANGED"); @@ -1184,10 +1202,10 @@ inline Gtk::TreeRow WhiteBalance::getActiveMethod () return *(method->get_active()); } -void WhiteBalance::WBChanged(int met, double temperature, double greenVal, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) +void WhiteBalance::WBChanged(int met, double temperature, double greenVal, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) { idle_register.add( - [this, met, temperature, greenVal, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, histmin, histmax]() -> bool + [this, met, temperature, greenVal, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, histmin, histmax, aWBMode]() -> bool { disableListener(); temp->setValue(temperature); @@ -1239,7 +1257,22 @@ void WhiteBalance::WBChanged(int met, double temperature, double greenVal, doubl Glib::ustring::format(std::fixed, std::setprecision(0), histmin), Glib::ustring::format(std::fixed, std::setprecision(0), histmax)) ); - + if (aWBMode == AWBMode::TEMP_CORRELATION_RAW) { + itcwb_green->set_sensitive(true); + tempBias->set_sensitive(true); + itcwb_alg->set_sensitive(true); + itcwb_prim->set_sensitive(true); + } else if (aWBMode == AWBMode::RGB_GREY) { + itcwb_green->set_sensitive(false); + tempBias->set_sensitive(true); + itcwb_alg->set_sensitive(false); + itcwb_prim->set_sensitive(false); + } else { + itcwb_green->set_sensitive(false); + tempBias->set_sensitive(false); + itcwb_alg->set_sensitive(false); + itcwb_prim->set_sensitive(false); + } temp->setDefault(temperature); green->setDefault(greenVal); enableListener(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 060026a48..4667a2fdf 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -85,6 +85,7 @@ protected: Gtk::CheckButton* itcwb_alg; MyComboBoxText* itcwb_prim; Adjuster* itcwb_green; + std::unique_ptr compatVersionAdjuster; bool lastitcwb_alg; @@ -142,7 +143,7 @@ public: } void setWB (int temp, double green); void resetWB (); - void WBChanged (int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) override; + void WBChanged (int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) override; void itcwb_alg_toggled (); void itcwb_prim_changed (); void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd); From 542946ef43b5e0282b067697256e2c9856c5d93c Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Thu, 1 Feb 2024 08:20:12 +0100 Subject: [PATCH 100/291] Restore windows.yml and appimage.yml --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 94bee4ebf..0d3c76399 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:wbrefinement"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b466ec265..9b49edd91 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:wbrefinement"]' + publish_pre_dev_labels: '[]' jobs: build: From 5349f7a860af322b24b08a12a80dbe1d96c0e5e7 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 2 Feb 2024 07:42:34 +0100 Subject: [PATCH 101/291] Improve Dynamic Range Compression - for some images with very high DR - Main and LA (#6931) * Improve Dynamic Range Compression - for some images with very high DR * Clean code * Improve TM fattal with saturation control in LA * Saturation control fattal in LA * Re-order paramsedit * Change history_msg_tmo_satur with saturation --- rtdata/languages/default | 2 ++ rtengine/dcrop.cc | 2 +- rtengine/improccoordinator.cc | 2 +- rtengine/improcfun.h | 2 +- rtengine/iplocallab.cc | 14 +++++--- rtengine/procparams.cc | 4 +++ rtengine/procparams.h | 1 + rtengine/rtthumbnail.cc | 2 +- rtengine/simpleprocess.cc | 2 +- rtengine/tmo_fattal02.cc | 60 +++++++++++++++++++++++------------ rtgui/locallabtools.cc | 26 ++++++++++++++- rtgui/locallabtools.h | 5 ++- rtgui/paramsedited.cc | 7 ++++ rtgui/paramsedited.h | 1 + 14 files changed, 99 insertions(+), 31 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index dfa149857..38f3201c1 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1450,6 +1450,7 @@ HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze - black HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2962,6 +2963,7 @@ TP_LOCALLAB_EXP_TOOLNAME;Dynamic Range & Exposure TP_LOCALLAB_FATAMOUNT;Amount TP_LOCALLAB_FATANCHOR;Anchor TP_LOCALLAB_FATDETAIL;Detail +TP_LOCALLAB_FATSAT;Saturation control TP_LOCALLAB_FATFRA;Dynamic Range Compression Æ’ TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. TP_LOCALLAB_FATLEVEL;Sigma diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 6abfc7aba..85661edd3 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -781,7 +781,7 @@ void Crop::update(int todo) if (need_fattal) { parent->ipf.dehaze(f, params.dehaze); - parent->ipf.ToneMapFattal02(f, params.fattal, 3, 0, nullptr, 0, 0, 0); + parent->ipf.ToneMapFattal02(f, params.fattal, 3, 0, nullptr, 0, 0, 0, false); } // crop back to the size expected by the rest of the pipeline diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5a5dd12af..5358f2880 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -849,7 +849,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } ipf.dehaze(orig_prev, params->dehaze); - ipf.ToneMapFattal02(orig_prev, params->fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(orig_prev, params->fattal, 3, 0, nullptr, 0, 0, 0, false); if (oprevi != orig_prev) { delete oprevi; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 62dfba0a0..b956e6c4b 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -492,7 +492,7 @@ enum class BlurType { void dehaze(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams); void dehazeloc(Imagefloat *rgb, const procparams::DehazeParams &dehazeParams, int sk, int sp); - void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo); + void ToneMapFattal02(Imagefloat *rgb, const procparams::FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo, bool sat); void localContrast(LabImage *lab, float **destination, const procparams::LocalContrastParams &localContrastParams, bool fftwlc, double scale); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); //void shadowsHighlights(LabImage *lab); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index bf7d1a391..3d02c9df6 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -6590,7 +6590,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int Imagefloat *tmpImagefat = nullptr; tmpImagefat = new Imagefloat(bfw, bfh); lab2rgb(*bufmaskblurcol, *tmpImagefat, params->icm.workingProfile); - ToneMapFattal02(tmpImagefat, fatParams, nlev, 0, nullptr, 0, 0, 0); + ToneMapFattal02(tmpImagefat, fatParams, nlev, 0, nullptr, 0, 0, 0, false); rgb2lab(*tmpImagefat, *bufmaskblurcol, params->icm.workingProfile); delete tmpImagefat; } @@ -8699,8 +8699,10 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const float dE = rsob + std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - maskptr->L[y][x])); //reduction action with deltaE - const float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); - + float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); + if(varsens == 100.f) { + reducdE = 1.f; + } float cli = (bufexpfin->L[y][x] - bufexporig->L[y][x]); float cla = (bufexpfin->a[y][x] - bufexporig->a[y][x]); float clb = (bufexpfin->b[y][x] - bufexporig->b[y][x]); @@ -17054,7 +17056,11 @@ void ImProcFunctions::Lab_Local( if(fatParams.anchor == 50.f) { alg = 1; } - ToneMapFattal02(tmpImagefat.get(), fatParams, 3, 0, nullptr, 0, 0, alg);//last parameter = 1 ==>ART algorithm + bool satu = false; + if(params->locallab.spots.at(sp).fatsatur) { + satu = true; + } + ToneMapFattal02(tmpImagefat.get(), fatParams, 3, 0, nullptr, 0, 0, alg, satu);//last parameter alg = 1 ==>ART algorithm rgb2lab(*tmpImagefat, *bufexpfin, params->icm.workingProfile); if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "dr") { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 4f6285ac9..99e7d8b7a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3348,6 +3348,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : gamm(0.4), fatamount(1.0), fatdetail(40.0), + fatsatur(false), fatanchor(50.0), fatlevel(1.), recothrese(1.), @@ -4828,6 +4829,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && gamm == other.gamm && fatamount == other.fatamount && fatdetail == other.fatdetail + && fatsatur == other.fatsatur && fatanchor == other.fatanchor && fatlevel == other.fatlevel && recothrese == other.recothrese @@ -6714,6 +6716,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->gamm, "Locallab", "Gamm_" + index_str, spot.gamm, keyFile); saveToKeyfile(!pedited || spot_edited->fatamount, "Locallab", "Fatamount_" + index_str, spot.fatamount, keyFile); saveToKeyfile(!pedited || spot_edited->fatdetail, "Locallab", "Fatdetail_" + index_str, spot.fatdetail, keyFile); + saveToKeyfile(!pedited || spot_edited->fatsatur, "Locallab", "Fatsatur_" + index_str, spot.fatsatur, keyFile); saveToKeyfile(!pedited || spot_edited->fatanchor, "Locallab", "Fatanchor_" + index_str, spot.fatanchor, keyFile); saveToKeyfile(!pedited || spot_edited->fatlevel, "Locallab", "Fatlevel_" + index_str, spot.fatlevel, keyFile); saveToKeyfile(!pedited || spot_edited->recothrese, "Locallab", "Recothrese_" + index_str, spot.recothrese, keyFile); @@ -8907,6 +8910,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Gamm_" + index_str, spot.gamm, spotEdited.gamm); assignFromKeyfile(keyFile, "Locallab", "Fatamount_" + index_str, spot.fatamount, spotEdited.fatamount); assignFromKeyfile(keyFile, "Locallab", "Fatdetail_" + index_str, spot.fatdetail, spotEdited.fatdetail); + assignFromKeyfile(keyFile, "Locallab", "Fatsatur_" + index_str, spot.fatsatur, spotEdited.fatsatur); assignFromKeyfile(keyFile, "Locallab", "Fatanchor_" + index_str, spot.fatanchor, spotEdited.fatanchor); assignFromKeyfile(keyFile, "Locallab", "Fatlevel_" + index_str, spot.fatlevel, spotEdited.fatlevel); assignFromKeyfile(keyFile, "Locallab", "Recothrese_" + index_str, spot.recothrese, spotEdited.recothrese); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 9b0f6463a..5ffcf9c6f 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1211,6 +1211,7 @@ struct LocallabParams { double gamm; double fatamount; double fatdetail; + bool fatsatur; double fatanchor; double fatlevel; double recothrese; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 4337477da..95b1a24c9 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1343,7 +1343,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.firstAnalysis (baseImg, params, hist16); ipf.dehaze(baseImg, params.dehaze); - ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0, false); // perform transform int origFW; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index b82c7fe79..ad0ce9cc0 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -967,7 +967,7 @@ private: ipf.firstAnalysis(baseImg, params, hist16); ipf.dehaze(baseImg, params.dehaze); - ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0); + ipf.ToneMapFattal02(baseImg, params.fattal, 3, 0, nullptr, 0, 0, 0, false); // perform transform (excepted resizing) if (ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData())) { diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index f49fe9c53..50b795f61 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -84,7 +84,6 @@ namespace rtengine /****************************************************************************** * RT code ******************************************************************************/ - extern MyMutex *fftwMutex; using namespace std; @@ -310,7 +309,7 @@ float calculateGradients(Array2Df* H, Array2Df* G, int k, bool multithread) // however, the impact is not visible so we ignore this here (*G)(x, y) = sqrt(gx * gx + gy * gy) / divider; - avgGrad += static_cast((*G) (x, y)); + avgGrad += (*G) (x, y); } } @@ -378,6 +377,7 @@ void calculateFiMatrix(Array2Df* FI, Array2Df* gradients[], // only apply gradients to levels>=detail_level but at least to the coarsest if ((k >= detail_level || k == nlevels - 1) && beta != 1.f) { + const float a = alfa * avgGrad[k]; //DEBUG_STR << "calculateFiMatrix: apply gradient to level " << k << endl; #ifdef _OPENMP #pragma omp parallel for shared(fi,avgGrad) if(multithread) @@ -385,8 +385,7 @@ void calculateFiMatrix(Array2Df* FI, Array2Df* gradients[], for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4f : (*gradients[k]) (x, y); - float a = alfa * avgGrad[k]; + float grad = ((*gradients[k]) (x, y) < 1e-4f) ? 1e-4 : (*gradients[k]) (x, y); float value = pow((grad + noise) / a, beta - 1.0f); (*fi[k])(x, y) *= value; @@ -470,7 +469,7 @@ void tmo_fattal02(size_t width, //paramet // find max value, normalize to range 0..100 and take logarithm // float minLum = Y (0, 0); - float maxLum = Y(0, 0); + float maxLum = Y(0, 0); #ifdef _OPENMP #pragma omp parallel for reduction(max:maxLum) if(multithread) @@ -482,7 +481,7 @@ void tmo_fattal02(size_t width, Array2Df* H = new Array2Df(width, height); float temp = 100.f / maxLum; - + float eps = 1e-4f; if (algo == 1) { temp = 1.f; } @@ -491,7 +490,6 @@ void tmo_fattal02(size_t width, #pragma omp parallel if(multithread) #endif { - const float eps = 1e-4f; #ifdef __SSE2__ const vfloat epsv = F2V(eps); const vfloat tempv = F2V(temp); @@ -567,9 +565,9 @@ void tmo_fattal02(size_t width, gradients[k] = new Array2Df(pyramids[k]->getCols(), pyramids[k]->getRows()); avgGrad[k] = calculateGradients(pyramids[k], gradients[k], k, multithread); - if (k != 0) { // pyramids[0] is H. Will be deleted later + if (k != 0) // pyramids[0] is H. Will be deleted later delete pyramids[k]; - } + } @@ -615,8 +613,8 @@ void tmo_fattal02(size_t width, // sets index+1 based on the boundary assumption H(N+1)=H(N-1) unsigned int xp1 = (x + 1 >= width ? width - 2 : x + 1); // forward differences in H, so need to use between-points approx of FI - (*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5f * ((*FI) (xp1, y) + (*FI) (x, y)); - (*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5f * ((*FI) (x, yp1) + (*FI) (x, y)); + (*Gx) (x, y) = ((*H) (xp1, y) - (*H) (x, y)) * 0.5 * ((*FI) (xp1, y) + (*FI) (x, y)); + (*Gy) (x, y) = ((*H) (x, yp1) - (*H) (x, y)) * 0.5 * ((*FI) (x, yp1) + (*FI) (x, y)); } } @@ -759,7 +757,7 @@ void transform_ev2normal(Array2Df *A, Array2Df *T, bool multithread) } for (int y = 1 ; y < height - 1 ; y++) { - (*A) (0, y) *= 0.5f; + (*A) (0, y) *= 0.5; (*A)(width - 1, y) *= 0.5f; } @@ -889,7 +887,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in if (multithread) { fftwf_init_threads(); - fftwf_plan_with_nthreads(omp_get_max_threads()); + fftwf_plan_with_nthreads(omp_get_num_procs()); } // #else @@ -924,7 +922,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in for (int y = 0 ; y < height ; y++) { for (int x = 0 ; x < width ; x++) { - (*F_tr) (x, y) = static_cast((*F_tr) (x, y)) / (l1[y] + l2[x]); + (*F_tr) (x, y) = (*F_tr) (x, y) / (l1[y] + l2[x]); } } @@ -932,7 +930,7 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in // transforms F_tr back to the normal space transform_ev2normal(F_tr, U, multithread); - +/* // the solution U as calculated will satisfy something like int U = 0 // since for any constant c, U-c is also a solution and we are mainly // working in the logspace of (0,1) data we prefer to have @@ -957,6 +955,8 @@ void solve_pde_fft(Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread, in (*U)(i) -= maxVal; } } + + */ } @@ -1064,7 +1064,7 @@ inline int find_fast_dim(int dim) } // namespace -void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo) +void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingParams &fatParams, int detail_level, int Lalone, float **Lum, int WW, int HH, int algo, bool sat) //algo allows to use ART algorithme algo = 0 RT, algo = 1 ART //Lalone allows to use L without RGB values in RT mode { @@ -1073,7 +1073,7 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa } BENCHFUN -// const int detail_level = 3; + // const int detail_level = 3; float alpha = 1.f; @@ -1137,7 +1137,7 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa Array2Df L(w2, h2); { #ifdef _OPENMP - int num_threads = multiThread ? omp_get_max_threads() : 1; + int num_threads = multiThread ? omp_get_num_procs() : 1; #else int num_threads = 1; #endif @@ -1224,16 +1224,18 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa } + const bool satcontrol = sat; + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif for (int y = 0; y < h; y++) { - int yy = y * hr + 1; + int yy = std::min(int(y * hr + 1), h2-1); for (int x = 0; x < w; x++) { - int xx = x * wr + 1; + int xx = std::min(int(x * wr + 1), w2-1); float Y = std::max(Yr(x, y), epsilon); float l = std::max(L(xx, yy), epsilon) * (scale / Y); @@ -1242,15 +1244,33 @@ void ImProcFunctions::ToneMapFattal02(Imagefloat *rgb, const FattalToneMappingPa float &r = rgb->r(y, x); float &g = rgb->g(y, x); float &b = rgb->b(y, x); + float s = 1.f; if(l > 1.f) { r = max(r * l - offset, r); g = max(g * l - offset, g); b = max(b * l - offset, b); + if (satcontrol) { + s = pow_F(1.f / l, 0.3f); + } } else { r *= l; g *= l; b *= l; + if (satcontrol) { + s = pow_F(l, 0.3f); + } } + + if (satcontrol && s != 1.f) { + float ll = luminance(r, g, b, ws); + float rl = r - ll; + float gl = g - ll; + float bl = b - ll; + r = ll + s * rl; + g = ll + s * gl; + b = ll + s * bl; + } + assert(std::isfinite(rgb->r(y, x))); assert(std::isfinite(rgb->g(y, x))); assert(std::isfinite(rgb->b(y, x))); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 562cbf674..f659d3dfd 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -2568,6 +2568,7 @@ LocallabExposure::LocallabExposure(): expfat(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_FATFRA")))), fatamount(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATAMOUNT"), 1., 100., 1., 1.))), fatdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATDETAIL"), -100., 300., 1., 0.))), + fatsatur(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FATSAT")))), norm(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EQUIL")))), fatlevel(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATLEVEL"), 0.5, 2.0, 0.01, 1.))), fatanchor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 0.1, 100.0, 0.01, 50., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), @@ -2617,7 +2618,9 @@ LocallabExposure::LocallabExposure(): strmaskexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2., 2., 0.05, 0.))), angmaskexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180., 180., 0.1, 0.))), mask2expCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), - Lmaskexpshape(static_cast(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) + Lmaskexpshape(static_cast(mask2expCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), + Evlocallabtmosatur(ProcEventMapper::getInstance()->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_TMO_SATUR")) + { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -2705,6 +2708,7 @@ LocallabExposure::LocallabExposure(): decaye->setAdjusterListener(this); setExpandAlignProperties(exprecove, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); normConn = norm->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::normChanged)); + fatsaturConn = fatsatur->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::fatsaturChanged)); inversexConn = inversex->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::inversexChanged)); inversex->set_tooltip_text(M("TP_LOCALLAB_INVERS_TOOLTIP")); @@ -2799,6 +2803,7 @@ LocallabExposure::LocallabExposure(): // fatBox->pack_start(*norm); // fatBox->pack_start(*fatlevel); fatBox->pack_start(*fatanchor); + fatBox->pack_start(*fatsatur); // fatFrame->add(*fatBox); expfat->add(*fatBox, false); // pack_start(*fatFrame); @@ -2985,6 +2990,7 @@ void LocallabExposure::disableListener() exnoiseMethodConn.block(true); inversexConn.block(true); normConn.block(true); + fatsaturConn.block(true); showmaskexpMethodConn.block(true); showmaskexpMethodConninv.block(true); enaExpMaskConn.block(true); @@ -2999,6 +3005,7 @@ void LocallabExposure::enableListener() exnoiseMethodConn.block(false); inversexConn.block(false); normConn.block(false); + fatsaturConn.block(false); showmaskexpMethodConn.block(false); showmaskexpMethodConninv.block(false); enaExpMaskConn.block(false); @@ -3084,6 +3091,7 @@ void LocallabExposure::read(const rtengine::procparams::ProcParams* pp, const Pa angexp->setValue(spot.angexp); softradiusexp->setValue(spot.softradiusexp); norm->set_active(spot.norm); + fatsatur->set_active(spot.fatsatur); inversex->set_active(spot.inversex); enaExpMask->set_active(spot.enaExpMask); enaExpMaskaft->set_active(spot.enaExpMaskaft); @@ -3175,6 +3183,7 @@ void LocallabExposure::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.softradiusexp = softradiusexp->getValue(); spot.inversex = inversex->get_active(); spot.norm = norm->get_active(); + spot.fatsatur = fatsatur->get_active(); spot.enaExpMask = enaExpMask->get_active(); spot.enaExpMaskaft = enaExpMaskaft->get_active(); spot.CCmaskexpcurve = CCmaskexpshape->getCurve(); @@ -3780,6 +3789,21 @@ void LocallabExposure::normChanged() } } +void LocallabExposure::fatsaturChanged() +{ + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (fatsatur->get_active()) { + listener->panelChanged(Evlocallabtmosatur, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabtmosatur, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} void LocallabExposure::inversexChanged() { diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 627be34bd..f99b3bc41 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -345,6 +345,7 @@ private: MyExpander* const expfat; Adjuster* const fatamount; Adjuster* const fatdetail; + Gtk::CheckButton* const fatsatur; Gtk::CheckButton* const norm; Adjuster* const fatlevel; Adjuster* const fatanchor; @@ -395,8 +396,9 @@ private: Adjuster* const angmaskexp; CurveEditorGroup* const mask2expCurveEditorG; DiagonalCurveEditor* const Lmaskexpshape; + rtengine::ProcEvent Evlocallabtmosatur; - sigc::connection expMethodConn, exnoiseMethodConn, inversexConn, normConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; + sigc::connection expMethodConn, exnoiseMethodConn, inversexConn, normConn, fatsaturConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; public: LocallabExposure(); @@ -429,6 +431,7 @@ private: void exnoiseMethodChanged(); void inversexChanged(); void normChanged(); + void fatsaturChanged(); void showmaskexpMethodChanged(); void showmaskexpMethodChangedinv(); void enaExpMaskChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ed7ad2754..ca705682b 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1265,6 +1265,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).gamm = locallab.spots.at(j).gamm && pSpot.gamm == otherSpot.gamm; locallab.spots.at(j).fatamount = locallab.spots.at(j).fatamount && pSpot.fatamount == otherSpot.fatamount; locallab.spots.at(j).fatdetail = locallab.spots.at(j).fatdetail && pSpot.fatdetail == otherSpot.fatdetail; + locallab.spots.at(j).fatsatur = locallab.spots.at(j).fatsatur && pSpot.fatsatur == otherSpot.fatsatur; locallab.spots.at(j).fatanchor = locallab.spots.at(j).fatanchor && pSpot.fatanchor == otherSpot.fatanchor; locallab.spots.at(j).fatlevel = locallab.spots.at(j).fatlevel && pSpot.fatlevel == otherSpot.fatlevel; locallab.spots.at(j).recothrese = locallab.spots.at(j).recothrese && pSpot.recothrese == otherSpot.recothrese; @@ -4109,6 +4110,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).fatdetail = mods.locallab.spots.at(i).fatdetail; } + if (locallab.spots.at(i).fatsatur) { + toEdit.locallab.spots.at(i).fatsatur = mods.locallab.spots.at(i).fatsatur; + } + if (locallab.spots.at(i).fatanchor) { toEdit.locallab.spots.at(i).fatanchor = mods.locallab.spots.at(i).fatanchor; } @@ -7670,6 +7675,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : fatdetail(v), fatanchor(v), fatlevel(v), + fatsatur(v), recothrese(v), lowthrese(v), higthrese(v), @@ -8361,6 +8367,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) gamm = v; fatamount = v; fatdetail = v; + fatsatur = v; fatanchor = v; fatlevel = v; recothrese = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 565eca36a..260779a7f 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -567,6 +567,7 @@ public: bool fatdetail; bool fatanchor; bool fatlevel; + bool fatsatur; bool recothrese; bool lowthrese; bool higthrese; From bfcfaca0ba0b392ad76144f8a5adb78c1a35d1f4 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 3 Feb 2024 13:02:02 -0500 Subject: [PATCH 102/291] First try at adding expandable queue template help, using a Gtx::Paned. Hiding doesn't work right yet. Click a thumbnail and the text disappears, but the border between widgets doesn't move to the left side. I tried using a Gtk::Expander, but couldn't get it to expand horizontally. --- rtgui/batchqueuepanel.cc | 20 +++++++++++++++++++- rtgui/batchqueuepanel.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index e35149326..4e03b2a74 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -147,8 +147,25 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) topBox->pack_start (*fdir, Gtk::PACK_EXPAND_WIDGET, 4); topBox->pack_start (*fformat, Gtk::PACK_EXPAND_WIDGET, 4); + // FIXME: THIS IS SO FAR JUST A TEST THING + middleSplitPane = Gtk::manage (new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL)); + templateHelpTextView = Gtk::manage (new Gtk::TextView()); + templateHelpTextView->set_editable(false); + templateHelpTextView->set_wrap_mode(Gtk::WRAP_WORD); + Gtk::ScrolledWindow* scrolledTemplateHelpWindow = Gtk::manage(new Gtk::ScrolledWindow()); + scrolledTemplateHelpWindow->add(*templateHelpTextView); + { + auto helptext = M("QUEUE_LOCATION_TEMPLATE_TOOLTIP"); + auto buffer = templateHelpTextView->get_buffer(); + buffer->create_tag("bold"); + buffer->create_tag("italic"); + buffer->insert_markup(buffer->begin(), helptext); + } + middleSplitPane->pack1 (*scrolledTemplateHelpWindow); + middleSplitPane->pack2 (*batchQueue); + // add middle browser area - pack_start (*batchQueue); + pack_start (*middleSplitPane); // lower box with thumbnail zoom bottomBox = Gtk::manage (new Gtk::Box ()); @@ -371,6 +388,7 @@ bool BatchQueuePanel::canStartNext () void BatchQueuePanel::setDestinationPreviewText(const Glib::ustring &destinationPath) { destinationPreviewLabel->set_text(destinationPath); + templateHelpTextView->hide(); // FIXME: REMOVE TESTING THING } void BatchQueuePanel::pathFolderButtonPressed () diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index d73f8b893..ce04b2257 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -52,8 +52,10 @@ class BatchQueuePanel : public Gtk::Box, RTWindow* parent; BatchQueue* batchQueue; + Gtk::TextView* templateHelpTextView; Gtk::Box* bottomBox; Gtk::Box* topBox; + Gtk::Paned* middleSplitPane; std::atomic queueShouldRun; From 7632d0df7c9f839e7a436b4a0170830d751f5008 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 3 Feb 2024 13:13:25 -0500 Subject: [PATCH 103/291] Got template help show/hide working (I had been hiding the wrong widget) --- rtgui/batchqueuepanel.cc | 9 +++++++-- rtgui/batchqueuepanel.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 4e03b2a74..8dfde876c 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -152,7 +152,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) templateHelpTextView = Gtk::manage (new Gtk::TextView()); templateHelpTextView->set_editable(false); templateHelpTextView->set_wrap_mode(Gtk::WRAP_WORD); - Gtk::ScrolledWindow* scrolledTemplateHelpWindow = Gtk::manage(new Gtk::ScrolledWindow()); + scrolledTemplateHelpWindow = Gtk::manage(new Gtk::ScrolledWindow()); scrolledTemplateHelpWindow->add(*templateHelpTextView); { auto helptext = M("QUEUE_LOCATION_TEMPLATE_TOOLTIP"); @@ -388,7 +388,12 @@ bool BatchQueuePanel::canStartNext () void BatchQueuePanel::setDestinationPreviewText(const Glib::ustring &destinationPath) { destinationPreviewLabel->set_text(destinationPath); - templateHelpTextView->hide(); // FIXME: REMOVE TESTING THING + static bool remove_me = false; + remove_me = !remove_me; + if(remove_me) + scrolledTemplateHelpWindow->hide(); // FIXME: REMOVE TESTING THING + else + scrolledTemplateHelpWindow->show(); // FIXME: REMOVE TESTING THING } void BatchQueuePanel::pathFolderButtonPressed () diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index ce04b2257..70cf5d506 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -53,6 +53,7 @@ class BatchQueuePanel : public Gtk::Box, RTWindow* parent; BatchQueue* batchQueue; Gtk::TextView* templateHelpTextView; + Gtk::ScrolledWindow* scrolledTemplateHelpWindow; Gtk::Box* bottomBox; Gtk::Box* topBox; Gtk::Paned* middleSplitPane; From e332446627b84daae0287d282a3b0c6102268174 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 3 Feb 2024 15:28:46 -0500 Subject: [PATCH 104/291] Added "?" toggle button to show/hide template help. I haven't figured out how to make it initially hidden. --- rtgui/batchqueuepanel.cc | 18 +++++++++++------- rtgui/batchqueuepanel.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 8dfde876c..4d150f4f9 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -73,7 +73,10 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) 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); + templateHelpButton = Gtk::manage (new Gtk::ToggleButton("?")); + templateHelpButton->set_tooltip_markup (M ("GENERAL_HELP")); // FIXME: Specific tooltip for this button + hb2->pack_start (*templateHelpButton, Gtk::PACK_SHRINK, 0); + odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 0); outdirTemplate->set_tooltip_markup (M("QUEUE_LOCATION_TEMPLATE_TOOLTIP")); useTemplate->set_tooltip_markup (M("QUEUE_LOCATION_TEMPLATE_TOOLTIP")); Gtk::Box* hb3 = Gtk::manage (new Gtk::Box ()); @@ -136,6 +139,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); useTemplate->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); useFolder->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + templateHelpButton->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::templateHelpButtonToggled)); saveFormatPanel->setListener (this); // setup button bar @@ -163,6 +167,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) } middleSplitPane->pack1 (*scrolledTemplateHelpWindow); middleSplitPane->pack2 (*batchQueue); + scrolledTemplateHelpWindow->set_visible(false); // initially hidden, templateHelpButton shows it // add middle browser area pack_start (*middleSplitPane); @@ -339,6 +344,11 @@ void BatchQueuePanel::setGuiFromBatchState(bool queueRunning, int qsize) updateTab(qsize); } +void BatchQueuePanel::templateHelpButtonToggled() +{ + scrolledTemplateHelpWindow->set_visible(templateHelpButton->get_active()); +} + void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) { batchQueue->addEntries(entries, head); @@ -388,12 +398,6 @@ bool BatchQueuePanel::canStartNext () void BatchQueuePanel::setDestinationPreviewText(const Glib::ustring &destinationPath) { destinationPreviewLabel->set_text(destinationPath); - static bool remove_me = false; - remove_me = !remove_me; - if(remove_me) - scrolledTemplateHelpWindow->hide(); // FIXME: REMOVE TESTING THING - else - scrolledTemplateHelpWindow->show(); // FIXME: REMOVE TESTING THING } void BatchQueuePanel::pathFolderButtonPressed () diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index 70cf5d506..bdd4ef6de 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -54,6 +54,7 @@ class BatchQueuePanel : public Gtk::Box, BatchQueue* batchQueue; Gtk::TextView* templateHelpTextView; Gtk::ScrolledWindow* scrolledTemplateHelpWindow; + Gtk::ToggleButton* templateHelpButton; Gtk::Box* bottomBox; Gtk::Box* topBox; Gtk::Paned* middleSplitPane; @@ -83,6 +84,7 @@ private: void stopBatchProc (); void startOrStopBatchProc(); void setGuiFromBatchState(bool queueRunning, int qsize); + void templateHelpButtonToggled(); void pathFolderChanged (); void pathFolderButtonPressed (); From c7500becb851c26a5322731ea4cd3ceb23a6b490 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 3 Feb 2024 19:24:07 -0500 Subject: [PATCH 105/291] Make template help initially hidden --- rtgui/batchqueuepanel.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 4d150f4f9..3797a7a48 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -168,6 +168,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) middleSplitPane->pack1 (*scrolledTemplateHelpWindow); middleSplitPane->pack2 (*batchQueue); scrolledTemplateHelpWindow->set_visible(false); // initially hidden, templateHelpButton shows it + scrolledTemplateHelpWindow->set_no_show_all(true); // add middle browser area pack_start (*middleSplitPane); @@ -346,7 +347,10 @@ void BatchQueuePanel::setGuiFromBatchState(bool queueRunning, int qsize) void BatchQueuePanel::templateHelpButtonToggled() { - scrolledTemplateHelpWindow->set_visible(templateHelpButton->get_active()); + bool visible = templateHelpButton->get_active(); + //scrolledTemplateHelpWindow->set_no_show_all(!visible); + scrolledTemplateHelpWindow->set_visible(visible); + templateHelpTextView->set_visible(visible); } void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) From 8df9a605d1345dac78fec7570ff0d35c7f66c984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batty=C3=A1nyi=20D=C3=A1niel?= <86350313+LoKolbasz@users.noreply.github.com> Date: Wed, 7 Feb 2024 00:03:07 +0100 Subject: [PATCH 106/291] Update AUTHORS.txt --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 3afd09dc2..f9aafd927 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -8,6 +8,7 @@ Development contributors, in last name alphabetical order: Harald Aust Roel Baars Richard E Barber + Dániel Battyányi Martin Burri Pierre Cabrera Javier Celaya From 3fb7296cd130c25234d4e97670288d18982a3ea9 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 10 Feb 2024 13:44:12 -0500 Subject: [PATCH 107/291] Create template help Pango markdown programmatically (partial). Do that the first time the text is shown, rather than at startup. --- rtdata/languages/default | 12 +++++++- rtgui/batchqueuepanel.cc | 64 +++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index bf43596dc..b2c1cf890 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2106,7 +2106,17 @@ QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +REMOVE_ME_OLD___QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. +QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;C:\users\tom\photos\2010-10-31\photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: + QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s SAMPLEFORMAT_0;Unknown data format diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 3797a7a48..439134977 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -23,6 +23,57 @@ #include "soundman.h" #include "rtimage.h" +namespace // helper functions +{ + + // Populate the buffer of a Gtk::TextView with help text for the location template field + void populateTemplateHelpBuffer(Glib::RefPtr buffer) + { + auto pos = buffer->begin(); + auto insertHeading1 = [&pos, buffer](const Glib::ustring& text) { + pos = buffer->insert_markup(pos, Glib::ustring::format("", text, "\n")); + }; + auto insertHeading2 = [&pos, buffer](const Glib::ustring& text) { + pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n", text, "\n")); + }; + insertHeading1(M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); + insertHeading2(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); + printf("[[[%s]]]", M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO").c_str()); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); + pos = buffer->insert(pos, "\n"); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1")); +#ifdef _WIN32 + auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); +#else + auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); +#endif + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleString, "\n")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); + pos = buffer->insert(pos, "\n"); + /* FIXME: Still to do here: + Generate text like the original below, but use the actual conversion function to create it: + %d4 = %d-1 = home + %d3 = %d-2 = tom + %d2 = %d-3 = photos + %d1 = %d-4 = 2010-10-31 + %p1 = %p-4 = /home/tom/photos/2010-10-31/ + %p2 = %p-3 = /home/tom/photos/ + %p3 = %p-2 = /home/tom/ + %p4 = %p-1 = /home/ + %P1 = %P-4 = 2010-10-31/ + %P2 = %P-3 = photos/2010-10-31/ + %P3 = %P-2 = tom/photos/2010-10-31/ + %P4 = %P-1 = /home/tom/photos/2010-10-31/ + %f = photo1 + Insert sections for the remaining specifiers: + %r = rank + %s# = queue position, with padding + Insert an examples section + */ + } +} + static Glib::ustring makeFolderLabel(Glib::ustring path) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { @@ -158,13 +209,6 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) templateHelpTextView->set_wrap_mode(Gtk::WRAP_WORD); scrolledTemplateHelpWindow = Gtk::manage(new Gtk::ScrolledWindow()); scrolledTemplateHelpWindow->add(*templateHelpTextView); - { - auto helptext = M("QUEUE_LOCATION_TEMPLATE_TOOLTIP"); - auto buffer = templateHelpTextView->get_buffer(); - buffer->create_tag("bold"); - buffer->create_tag("italic"); - buffer->insert_markup(buffer->begin(), helptext); - } middleSplitPane->pack1 (*scrolledTemplateHelpWindow); middleSplitPane->pack2 (*batchQueue); scrolledTemplateHelpWindow->set_visible(false); // initially hidden, templateHelpButton shows it @@ -348,7 +392,11 @@ void BatchQueuePanel::setGuiFromBatchState(bool queueRunning, int qsize) void BatchQueuePanel::templateHelpButtonToggled() { bool visible = templateHelpButton->get_active(); - //scrolledTemplateHelpWindow->set_no_show_all(!visible); + auto buffer = templateHelpTextView->get_buffer(); + if (buffer->get_text().empty()) { + // Populate the help text the first time it's shown + populateTemplateHelpBuffer(buffer); + } scrolledTemplateHelpWindow->set_visible(visible); templateHelpTextView->set_visible(visible); } From ed5792bb9f496968007a0fbb39779c6d0668c4a7 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sat, 10 Feb 2024 13:49:19 -0500 Subject: [PATCH 108/291] Make populateTemplateHelpBuffer a private member of class BatchQueuePanel --- rtgui/batchqueuepanel.cc | 97 +++++++++++++++++++--------------------- rtgui/batchqueuepanel.h | 1 + 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 439134977..d150adc94 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -23,57 +23,6 @@ #include "soundman.h" #include "rtimage.h" -namespace // helper functions -{ - - // Populate the buffer of a Gtk::TextView with help text for the location template field - void populateTemplateHelpBuffer(Glib::RefPtr buffer) - { - auto pos = buffer->begin(); - auto insertHeading1 = [&pos, buffer](const Glib::ustring& text) { - pos = buffer->insert_markup(pos, Glib::ustring::format("", text, "\n")); - }; - auto insertHeading2 = [&pos, buffer](const Glib::ustring& text) { - pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n", text, "\n")); - }; - insertHeading1(M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE")); - pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); - insertHeading2(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); - printf("[[[%s]]]", M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO").c_str()); - pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); - pos = buffer->insert(pos, "\n"); - pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1")); -#ifdef _WIN32 - auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); -#else - auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); -#endif - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleString, "\n")); - pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); - pos = buffer->insert(pos, "\n"); - /* FIXME: Still to do here: - Generate text like the original below, but use the actual conversion function to create it: - %d4 = %d-1 = home - %d3 = %d-2 = tom - %d2 = %d-3 = photos - %d1 = %d-4 = 2010-10-31 - %p1 = %p-4 = /home/tom/photos/2010-10-31/ - %p2 = %p-3 = /home/tom/photos/ - %p3 = %p-2 = /home/tom/ - %p4 = %p-1 = /home/ - %P1 = %P-4 = 2010-10-31/ - %P2 = %P-3 = photos/2010-10-31/ - %P3 = %P-2 = tom/photos/2010-10-31/ - %P4 = %P-1 = /home/tom/photos/2010-10-31/ - %f = photo1 - Insert sections for the remaining specifiers: - %r = rank - %s# = queue position, with padding - Insert an examples section - */ - } -} - static Glib::ustring makeFolderLabel(Glib::ustring path) { if (!Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { @@ -401,6 +350,52 @@ void BatchQueuePanel::templateHelpButtonToggled() templateHelpTextView->set_visible(visible); } +void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr buffer) +{ + auto pos = buffer->begin(); + auto insertHeading1 = [&pos, buffer](const Glib::ustring& text) { + pos = buffer->insert_markup(pos, Glib::ustring::format("", text, "\n")); + }; + auto insertHeading2 = [&pos, buffer](const Glib::ustring& text) { + pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n", text, "\n")); + }; + insertHeading1(M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); + insertHeading2(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); + printf("[[[%s]]]", M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO").c_str()); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); + pos = buffer->insert(pos, "\n"); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1")); +#ifdef _WIN32 + auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); +#else + auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); +#endif + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleString, "\n")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); + pos = buffer->insert(pos, "\n"); + /* FIXME: Still to do here: + Generate text like the original below, but use the actual conversion function to create it: + %d4 = %d-1 = home + %d3 = %d-2 = tom + %d2 = %d-3 = photos + %d1 = %d-4 = 2010-10-31 + %p1 = %p-4 = /home/tom/photos/2010-10-31/ + %p2 = %p-3 = /home/tom/photos/ + %p3 = %p-2 = /home/tom/ + %p4 = %p-1 = /home/ + %P1 = %P-4 = 2010-10-31/ + %P2 = %P-3 = photos/2010-10-31/ + %P3 = %P-2 = tom/photos/2010-10-31/ + %P4 = %P-1 = /home/tom/photos/2010-10-31/ + %f = photo1 + Insert sections for the remaining specifiers: + %r = rank + %s# = queue position, with padding + Insert an examples section + */ +} + void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) { batchQueue->addEntries(entries, head); diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h index bdd4ef6de..417d8a4cb 100644 --- a/rtgui/batchqueuepanel.h +++ b/rtgui/batchqueuepanel.h @@ -85,6 +85,7 @@ private: void startOrStopBatchProc(); void setGuiFromBatchState(bool queueRunning, int qsize); void templateHelpButtonToggled(); + void populateTemplateHelpBuffer(Glib::RefPtr buffer); void pathFolderChanged (); void pathFolderButtonPressed (); From 2690e27dea191af5f6cd3ded978fc314fe9cd596 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 11 Feb 2024 14:03:58 -0500 Subject: [PATCH 109/291] Generate help examples (Windows or Linux, as appropriate) for %d, %p and %P specifiers. Also make the help pane half the overall width when first shown (and it's resizeable). --- rtdata/languages/default | 4 +- rtgui/batchqueuepanel.cc | 85 +++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index b2c1cf890..4129bf314 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2111,11 +2111,13 @@ QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteris QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;C:\users\tom\photos\2010-10-31\photo1.raw QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index d150adc94..f4e97689b 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -1,3 +1,4 @@ +#define CHECKPOINT printf("CHECKPOINT: %d\n", __LINE__); // FIXME: REMOVE /* * This file is part of RawTherapee. * @@ -345,6 +346,8 @@ void BatchQueuePanel::templateHelpButtonToggled() if (buffer->get_text().empty()) { // Populate the help text the first time it's shown populateTemplateHelpBuffer(buffer); + auto fullWidth = middleSplitPane->get_width(); + middleSplitPane->set_position(fullWidth / 2); } scrolledTemplateHelpWindow->set_visible(visible); templateHelpTextView->set_visible(visible); @@ -362,38 +365,82 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b insertHeading1(M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); insertHeading2(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); - printf("[[[%s]]]", M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO").c_str()); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); pos = buffer->insert(pos, "\n"); +#ifdef _WIN32 + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS")); + pos = buffer->insert(pos, "\n"); +#endif + pos = buffer->insert(pos, "\n"); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1")); #ifdef _WIN32 - auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); + auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); #else - auto exampleString = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); + auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); #endif - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleString, "\n")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); - pos = buffer->insert(pos, "\n"); + // Examples are generated from exampleFilePath using the actual template processing function + Options savedOptions = options; // to be restored after generating example results + options.saveUsePathTemplate = true; + // Since this code only ever runs once (the first time the help text is presented), no attempt is + // made to be efficient. Use a brute-force method to discover the number of elements in exampleFilePath. + int pathElementCount = 0; + for (int n=9; n>=0; n--) + { + options.savePathTemplate = Glib::ustring::format("%d",n); + auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); + if (!result.empty()) + { + // The 'd' specifier returns an empty string if N exceeds the number of path elements, so + // the largest N that does not return an empty string is the number of elements in exampleFilePath. + pathElementCount = n; + break; + } + } + // Function inserts examples for a particular specifier, with every valid N value for the + // number of elements in the path. + auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2) + { + Glib::ustring startMonospace(""); + Glib::ustring endMonospace(""); + auto buildBuffer = Gtk::TextBuffer::create(); + auto buildpos = buildBuffer->begin(); + buildpos = buildBuffer->insert(buildpos, startMonospace); + for (int n=0; n%d4 = %d-1 = home + auto path1 = Glib::ustring::format("%",letter,offset1+n*mult1); + auto path2 = Glib::ustring::format("%",letter,offset2+n*mult2); + options.savePathTemplate = path1; + auto result1 = BatchQueue::calcAutoFileNameBase(exampleFilePath); + options.savePathTemplate = path2; + auto result2 = BatchQueue::calcAutoFileNameBase(exampleFilePath); + buildpos = buildBuffer->insert (buildpos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); + if (result1 != result2) + { + buildpos = buildBuffer->insert(buildpos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2)); + } + } + buildpos = buildBuffer->insert(buildpos, endMonospace); + pos = buffer->insert_markup(pos, buildBuffer->get_text()); + }; + // Example outputs in comments below are for a 4-element path. + // %d4 = %d-1 = home + insertPathExamples('d', pathElementCount, -1, -1, -1); + // %p1 = %p-4 = /home/tom/photos/2010-10-31/ + insertPathExamples('p', 1, 1, -pathElementCount, 1); + // %P1 = %P-4 = 2010-10-31/ + insertPathExamples('P', 1, 1, -pathElementCount, 1); + /* FIXME: Still to do here: - Generate text like the original below, but use the actual conversion function to create it: - %d4 = %d-1 = home - %d3 = %d-2 = tom - %d2 = %d-3 = photos - %d1 = %d-4 = 2010-10-31 - %p1 = %p-4 = /home/tom/photos/2010-10-31/ - %p2 = %p-3 = /home/tom/photos/ - %p3 = %p-2 = /home/tom/ - %p4 = %p-1 = /home/ - %P1 = %P-4 = 2010-10-31/ - %P2 = %P-3 = photos/2010-10-31/ - %P3 = %P-2 = tom/photos/2010-10-31/ - %P4 = %P-1 = /home/tom/photos/2010-10-31/ - %f = photo1 Insert sections for the remaining specifiers: %r = rank %s# = queue position, with padding Insert an examples section */ + options = savedOptions; } void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) From 353a4d472a27845186a16c180f70452e42975427 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 11 Feb 2024 14:28:03 -0500 Subject: [PATCH 110/291] Added help sections for %r and %s tags, and for common examples --- rtdata/languages/default | 8 ++++++-- rtgui/batchqueuepanel.cc | 30 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 4129bf314..ee08b0ba7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2106,7 +2106,6 @@ QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template -REMOVE_ME_OLD___QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\n%dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) will be replaced by elements of the image file's directory path (not including the file name):\n%dN = Nth directory from the end of the path\n%d-N = Nth directory from the start of the path\n%pN = all directories up to the Nth from the end of the path\n%p-N = the first N directories in the path\n%PN = the last N directories in the path\n%P-N = all directories from the Nth to the end of the path\n%f = base filename (no extension)\nFor Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. @@ -2118,7 +2117,12 @@ QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/pho QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;C:\users\tom\photos\2010-10-31\photo1.raw QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: - +QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s SAMPLEFORMAT_0;Unknown data format diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index f4e97689b..a0587d442 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -356,15 +356,16 @@ void BatchQueuePanel::templateHelpButtonToggled() void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr buffer) { auto pos = buffer->begin(); - auto insertHeading1 = [&pos, buffer](const Glib::ustring& text) { - pos = buffer->insert_markup(pos, Glib::ustring::format("", text, "\n")); - }; - auto insertHeading2 = [&pos, buffer](const Glib::ustring& text) { + auto insertTopicHeading = [&pos, buffer](const Glib::ustring& text) { pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n", text, "\n")); }; - insertHeading1(M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE")); + auto insertTopicBody = [&pos, buffer](const Glib::ustring& text) { + pos = buffer->insert_markup(pos, Glib::ustring::format("\n", text, "\n")); + }; + auto mainTitle = M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE"); + pos = buffer->insert_markup(pos, Glib::ustring::format("", mainTitle, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); - insertHeading2(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); pos = buffer->insert(pos, "\n"); #ifdef _WIN32 @@ -409,8 +410,6 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b buildpos = buildBuffer->insert(buildpos, startMonospace); for (int n=0; n%d4 = %d-1 = home auto path1 = Glib::ustring::format("%",letter,offset1+n*mult1); auto path2 = Glib::ustring::format("%",letter,offset2+n*mult2); options.savePathTemplate = path1; @@ -420,6 +419,8 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b buildpos = buildBuffer->insert (buildpos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); if (result1 != result2) { + // If this error appears, it indicates a coding error in either BatchQueue::calcAutoFileNameBase + // or BatchQueuePanel::populateTemplateHelpBuffer. buildpos = buildBuffer->insert(buildpos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2)); } } @@ -434,11 +435,16 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b // %P1 = %P-4 = 2010-10-31/ insertPathExamples('P', 1, 1, -pathElementCount, 1); + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY")); + + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY")); + + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY")); /* FIXME: Still to do here: - Insert sections for the remaining specifiers: - %r = rank - %s# = queue position, with padding - Insert an examples section + Insert section for time/date specifiers */ options = savedOptions; } From bc054ea5065523b61526d19f27eb4098a381a299 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 11 Feb 2024 15:07:50 -0500 Subject: [PATCH 111/291] Added help for time/date template specifiers --- rtdata/languages/default | 2 ++ rtgui/batchqueuepanel.cc | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ee08b0ba7..00c3089d7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2121,6 +2121,8 @@ QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TITLE;Output Location diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index a0587d442..9935da212 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -1,4 +1,3 @@ -#define CHECKPOINT printf("CHECKPOINT: %d\n", __LINE__); // FIXME: REMOVE /* * This file is part of RawTherapee. * @@ -365,6 +364,10 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b auto mainTitle = M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE"); pos = buffer->insert_markup(pos, Glib::ustring::format("", mainTitle, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); + + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY")); + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO")); pos = buffer->insert(pos, "\n"); @@ -441,12 +444,21 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY")); - insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE")); - pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY")); - /* FIXME: Still to do here: - Insert section for time/date specifiers - */ - options = savedOptions; + insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE")); + pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY")); + Glib::ustring dateTimeFormatExamples[] = { + "%Y-%m-%d", + "%Y%m%d_%H%M%S", + "%y/%b/%-d/" + }; + auto timeNow = Glib::DateTime::create_now_local(); + for (auto fmt : dateTimeFormatExamples) { + auto result = timeNow.format(fmt); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n %tE\"", fmt, "\" = ", result, "")); + } + + pos = buffer->insert(pos, "\n"); + options = savedOptions; // Do not add any lines in this function below here } void BatchQueuePanel::addBatchQueueJobs(const std::vector& entries, bool head) From ccc667e3905f305e908f12df00e1eba2d083d8b3 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 11 Feb 2024 15:10:02 -0500 Subject: [PATCH 112/291] Added specific tooltip for the location template "?" help toggle button --- rtdata/languages/default | 1 + rtgui/batchqueuepanel.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 00c3089d7..e5ce63a20 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2107,6 +2107,7 @@ QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. +QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 9935da212..991ff0239 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -74,7 +74,7 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) outdirTemplate = Gtk::manage (new Gtk::Entry ()); hb2->pack_start (*outdirTemplate); templateHelpButton = Gtk::manage (new Gtk::ToggleButton("?")); - templateHelpButton->set_tooltip_markup (M ("GENERAL_HELP")); // FIXME: Specific tooltip for this button + templateHelpButton->set_tooltip_markup (M ("QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP")); hb2->pack_start (*templateHelpButton, Gtk::PACK_SHRINK, 0); odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 0); outdirTemplate->set_tooltip_markup (M("QUEUE_LOCATION_TEMPLATE_TOOLTIP")); From 5d7586bab4be69ab23614c79af080e199cd10355 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 11 Feb 2024 15:28:39 -0500 Subject: [PATCH 113/291] Simplify path help, add '%f' to generated examples --- rtdata/languages/default | 2 +- rtgui/batchqueuepanel.cc | 26 +++++++++++--------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e5ce63a20..b089b69cb 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2115,7 +2115,7 @@ QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;C:\users\tom\photos\2010-10-31\photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 991ff0239..1fa0b7169 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -406,11 +406,6 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b // number of elements in the path. auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2) { - Glib::ustring startMonospace(""); - Glib::ustring endMonospace(""); - auto buildBuffer = Gtk::TextBuffer::create(); - auto buildpos = buildBuffer->begin(); - buildpos = buildBuffer->insert(buildpos, startMonospace); for (int n=0; n b auto result1 = BatchQueue::calcAutoFileNameBase(exampleFilePath); options.savePathTemplate = path2; auto result2 = BatchQueue::calcAutoFileNameBase(exampleFilePath); - buildpos = buildBuffer->insert (buildpos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); if (result1 != result2) { // If this error appears, it indicates a coding error in either BatchQueue::calcAutoFileNameBase // or BatchQueuePanel::populateTemplateHelpBuffer. - buildpos = buildBuffer->insert(buildpos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2)); + pos = buffer->insert_markup(pos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2)); } } - buildpos = buildBuffer->insert(buildpos, endMonospace); - pos = buffer->insert_markup(pos, buildBuffer->get_text()); }; // Example outputs in comments below are for a 4-element path. - // %d4 = %d-1 = home - insertPathExamples('d', pathElementCount, -1, -1, -1); - // %p1 = %p-4 = /home/tom/photos/2010-10-31/ - insertPathExamples('p', 1, 1, -pathElementCount, 1); - // %P1 = %P-4 = 2010-10-31/ - insertPathExamples('P', 1, 1, -pathElementCount, 1); + insertPathExamples('d', pathElementCount, -1, -1, -1); // %d4 = %d-1 = home + insertPathExamples('p', 1, 1, -pathElementCount, 1); // %p1 = %p-4 = /home/tom/photos/2010-10-31/ + insertPathExamples('P', 1, 1, -pathElementCount, 1); // %P1 = %P-4 = 2010-10-31/ + { + Glib::ustring fspecifier("%f"); + options.savePathTemplate = fspecifier; + auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", fspecifier, " = ", result, "")); + } insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY")); From 10050fd9b19d3b420cd2db894d41c0e20d3529c0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:02:28 -0800 Subject: [PATCH 114/291] Add ILCE-7CR raw crop, PDAF pattern, dcraw matrix Also use the same values for the Sony ILCE-7RM5 which should have the same sensor. Copy the PDAF pattern to the ILCE-7RM4, which has the same size sensor. --- rtengine/camconst.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 59a2110b2..22e816794 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -3076,7 +3076,17 @@ Camera constants: { // Quality C, "make_model": "Sony ILCE-7RM4", "dcraw_matrix": [ 7662, -2686, -660, -5240, 12965, 2530, -796, 1508, 6167 ], - "raw_crop": [ 0, 0, -32, 0 ] // full raw frame 9600x6376 - 32 rightmost columns are garbage. Using -32 instead of 9568 to support also 16-shot pixelshift files + "raw_crop": [ 0, 0, -32, 0 ], // full raw frame 9600x6376 - 32 rightmost columns are garbage. Using -32 instead of 9568 to support also 16-shot pixelshift files + "pdaf_pattern": [ 0,12,18,36,42,60,66,72,78,96,108,120,126,138,156,168,180,186,192,198,210,222,228,240,246,252,270,276,282,288,306,312,318,330,336,348,360,366,372,378,390,396,408,420 ], // Assume the pattern is the same as the ILCE-7CR. + "pdaf_offset": 1 + }, + + { // Quality B + "make_model": [ "Sony ILCE-7CR", "Sony ILCE-7RM5" ], // 7RM5 is assumed to have the same sensor as the 7CR. + "dcraw_matrix": [ 8200, -2976, -719, -4296, 12053, 2532, -429, 1282, 5774 ], // DNG v15.2 for ILCE-7CR and ILCE-7RM5. + "raw_crop": [ 0, 0, -32, 0 ], // A few repeated pixels on the right edge. + "pdaf_pattern": [ 0,12,18,36,42,60,66,72,78,96,108,120,126,138,156,168,180,186,192,198,210,222,228,240,246,252,270,276,282,288,306,312,318,330,336,348,360,366,372,378,390,396,408,420 ], // From issue #6938. Slightly different every repetition, maybe the real pattern is 3 or more multiples of 420 pixels. This is a composite. + "pdaf_offset": 1 }, { // Quality B, assumed correct for 9M2 as well From 79134ecc9f85f9f772faffcd9be70945f69b273d Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 12 Feb 2024 17:06:08 -0500 Subject: [PATCH 115/291] Instead of time now, in help examples use 2001-02-03T04:05:06.123456 local time --- rtgui/batchqueuepanel.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 1fa0b7169..f234c734c 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -447,9 +447,10 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b "%Y%m%d_%H%M%S", "%y/%b/%-d/" }; - auto timeNow = Glib::DateTime::create_now_local(); + auto timezone = Glib::DateTime::create_now_local().get_timezone(); + auto timeForExamples = Glib::DateTime::create_from_iso8601("2001-02-03T04:05:06.123456", timezone); for (auto fmt : dateTimeFormatExamples) { - auto result = timeNow.format(fmt); + auto result = timeForExamples.format(fmt); pos = buffer->insert_markup(pos, Glib::ustring::format("\n %tE\"", fmt, "\" = ", result, "")); } From dbd0829e61f541b787cc353a3caabf23bfa065ef Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 12 Feb 2024 18:35:01 -0500 Subject: [PATCH 116/291] Obtain the export, shooting or save time, per letter after %t output template specifier Print the result (not yet processing a time formatting string) --- rtgui/batchqueue.cc | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 2811e3445..8654ce45e 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -18,8 +18,10 @@ */ #include #include +#include #include #include +#include "../rtengine/imagedata.h" #include "../rtengine/rt_math.h" #include "../rtengine/procparams.h" @@ -1001,6 +1003,45 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam seqstr << sequence; path += seqstr.str (); + } else if (options.savePathTemplate[ix] == 't') { + // Insert formatted date/time value. Character after 't' defines time source + if (++ix < options.savePathTemplate.size()) + { + Glib::DateTime dateTime; + bool dateTimeIsValid = true; + switch(options.savePathTemplate[ix]) + { + case 'E': // (approximate) time when export started + dateTime = Glib::DateTime::create_now_local(); + break; + case 'F': // time when file was last saved + { + struct stat fileStat; + if (stat(origFileName.c_str(), &fileStat) == 0) { + time_t timestamp = fileStat.st_mtime; + dateTime = Glib::DateTime::create_now_local(timestamp); + } else { + dateTimeIsValid = false; // file not found, access denied, etc. + } + } + break; + case 'P': // time when picture was taken + { + auto timestamp = FramesData(origFileName).getDateTimeAsTS(); + dateTime = Glib::DateTime::create_now_local(timestamp); + } + break; + default: + dateTimeIsValid = false; + break; + } + if (dateTimeIsValid) + { + // FIXME: Call a function that looks for a double-quoted format string, and + // format dateTime accordingly, adding it to path. + printf("Time %s\n", dateTime.format_iso8601().c_str()); + } + } } } From 437a86712195ed39484a2fc446e41c1c2cd448d3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:40:06 -0800 Subject: [PATCH 117/291] Preparing to merge back to dev --- RELEASE_NOTES.txt | 95 +++--------------------------------- rtdata/images/svg/splash.svg | 86 +++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 90 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 0ef0b255b..b4d4a3523 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,6 +1,6 @@ -RAWTHERAPEE 5.10 RELEASE NOTES +RAWTHERAPEE 5.10-dev RELEASE NOTES -This is RawTherapee 5.10, released on 2024-02-16. +This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them. @@ -22,99 +22,18 @@ In order to use RawTherapee efficiently you should know that: -NEW FEATURES SINCE 5.9 +NEW FEATURES SINCE 5.10 -- Multiple custom external editors can be added and the external editor can be chosen in the Editor tab. -- The Favorites tab can be configured in Preferences. An option to display Favorite tools in their original location has been added. -- Metadata is now handled by Exiv2. CR3 metadata is supported. -- When saving images in the TIFF file format, there is a new option to use the BigTIFF format. -- The DCP and LCP file paths saved to processing profiles have better interoperability between Windows and Linux, and between different computers. -- The Tone Equalizer in Local Adjustments is now also available in the Exposure tab. They have a new Pivot adjuster to shift the range of affected tones. The Tone Equalizer in the Exposure tab can display a tonal map for visualizing the tones. -- The ICC profiles in the user configuration directory are recognized. -- The language selection in Preferences now show all language names in their own language. -- The Lensfun database directory can be changed in Preferences. -- The color pickers in Film Negative (Color tab) now have adjustable size. -- Dynamic Profile Rules now has a File path filter. -- The context menu for images (File Browser tab) received a new option to sort images by name, date, rank, color label, or EXIF. -- The Flat-Field tool (Raw tab) has a new From Metadata option for applying DNG gain maps. -- Temporary files generated by the external editor feature now have more private file permissions. -- The Color Appearance & Lighting tool (Advanced tab) received various improvements. -- The Abstract Profile in the Color Management tool (Color tab) received a Gamut control option. -- The L*a*b* Adjustments (Exposure tab) and Local Adjustments (Local tab) tools received improvements to the Avoid color shift option. -- The Highlight reconstruction in the Exposure tool (Exposure tab) has a new Inpaint Opposed method that usually offers better reconstructed details than the Blend method and higher reliability compared to the Color Propagation method. -- The Temperature correlation automatic white balance method in the White Balance tool (Color tab) received various improvements. -- The Denoise section of the Blur/Grain & Denoise tool in Local Adjustments (Local tab) has an improved interface. -- Raw files from OM Digital Solutions cameras are supported. -- The Dynamic Range Compression tool in the Exposure tab and in Local Adjustments (Local tab) has improved behavior. The tool in Local Adjustments received a Saturation control option. -- The default value for the Show additional settings option for new spots in Local Adjustments (Local tab) is now linked to the Default complexity for Local Adjustments set in Preferences. +- TODO - Added or improved support for cameras, raw formats and color profiles: - - Canon EOS 250D (DCP) - - Canon EOS 7D Mark II - - Canon EOS 800D (DCP) - - Canon EOS 90D - - Canon EOS Kiss X10 - - Canon EOS M100 - - Canon EOS M50 (DCP) - - Canon EOS M50m2 - - Canon EOS M6 Mark II - - Canon EOS R - - Canon EOS R10 - - Canon EOS R3 - - Canon EOS R5 - - Canon EOS R6 - - Canon EOS R6m2 - - Canon EOS R7 - - Canon EOS R8 - - Canon EOS RP - - Canon EOS Rebel SL3 - - Canon EOS-1D X Mark II - - Canon PowerShot G7 X Mark II - - Canon Powershot G5 X MARK II (DCP) - - FUJIFILM DBP for GX680 (DCP) - - FUJIFILM GFX 100 - - FUJIFILM GFX100S - - FUJIFILM X-A7 (DCP) - - FUJIFILM X-E3 (DCP) - - FUJIFILM X-H2 - - FUJIFILM X-PRO3 - - FUJIFILM X-S10 (DCP) - - FUJIFILM X-T3 - - FUJIFILM X-T30 - - FUJIFILM X-T30 II - - FUJIFILM X-T4 - - FUJIFILM X-T5 - - FUJIFILM X100V - - LEICA D-LUX 7 - - NIKON D3300 (DCP) - - NIKON Z 5 (DCP) - - NIKON Z 6_2 (DCP) - - NIKON Z 9 - - OLYMPUS E-M1 (DCP) - - OLYMPUS E-M10MarkIV - - OM Digital Solutions OM-1 - - OM Digital Solutions OM-5 - - PANASONIC DC-GX880 - - PANASONIC DMC-LX100 (DCP) - - Panasonic DC-G100 - - Panasonic DC-G110 - - Panasonic DC-LX100M2 - - Sony DSC-RX100M6 (DCP) - - Sony DSC-RX1RM2 - - Sony ILCE-7 (DCP) - - Sony ILCE-7C (DCP) - - Sony ILCE-7M4 - - Sony ILCE-7RM2 - - Sony ILCE-7S - - Sony ILCE-7SM2 - - Sony ILCE-7SM3 (DCP) - - Sony ZV-1 + - TODO NEWS RELEVANT TO PACKAGE MAINTAINERS -New since 5.9: -- Dependency on Exiv2 >= 0.24. +New since 5.10: +- TODO In general: - To get the source code, either clone from git or use the tarball from https://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. diff --git a/rtdata/images/svg/splash.svg b/rtdata/images/svg/splash.svg index 5d407161a..9e91d054e 100644 --- a/rtdata/images/svg/splash.svg +++ b/rtdata/images/svg/splash.svg @@ -936,6 +936,37 @@ in2="blur" id="feComposite4757-6-9" /> + + + + + + + style="display:inline"> + + + + + + + + + + + + + + From 6dd99ca3d97583844babf504c4c0afcfd6980d50 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Sun, 18 Feb 2024 15:59:09 +0100 Subject: [PATCH 118/291] Nederlands rtdata languages - by Paul Matthijsse --- rtdata/languages/Nederlands | 4670 +++++++++++++++++------------------ 1 file changed, 2333 insertions(+), 2337 deletions(-) diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index f92f4ab04..76e9befdd 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -15,6 +15,7 @@ #015 2016-07-21 update by wim ter meer #016 2017-04-21 update by wim ter meer #017 2020-06-05 update by dheijl +#018 2024-02-18 update to RawTherapee 5.10 by Paul Matthijsse #100 #101 @LANGUAGE_DISPLAY_NAME=Nederlands @@ -24,7 +25,7 @@ ABOUT_TAB_LICENSE;Licentie ABOUT_TAB_RELEASENOTES;Uitgave-opmerkingen ABOUT_TAB_SPLASH;Splash ADJUSTER_RESET_TO_DEFAULT;Klik - terug naar standaardwaarde.\nCtrl+klik - terug naar laatst opgeslagen waarde. -BATCH_PROCESSING;Batch-verwerking +BATCH_PROCESSING;Groepsverwerking CURVEEDITOR_AXIS_IN;I: CURVEEDITOR_AXIS_LEFT_TAN;LT: CURVEEDITOR_AXIS_OUT;O: @@ -34,12 +35,12 @@ CURVEEDITOR_CURVE;Curve CURVEEDITOR_CURVES;Curven CURVEEDITOR_CUSTOM;Handmatig CURVEEDITOR_DARKS;Schaduwen -CURVEEDITOR_EDITPOINT_HINT;Activeer wijzigen van node in/uit waardes.\n\nRechts-klik op een node om het te selecteren.\nRechts-klik in een leeg gebied om de node te de-selecteren. +CURVEEDITOR_EDITPOINT_HINT;Activeer wijzigen van node in/uit-waarden.\n\nRechtsklik op een node om die te selecteren.\nRechtsklik in een leeg gebied om de node te deselecteren. CURVEEDITOR_HIGHLIGHTS;Hoge lichten CURVEEDITOR_LIGHTS;Lichten CURVEEDITOR_LINEAR;Lineair CURVEEDITOR_LOADDLGLABEL;Laad curve... -CURVEEDITOR_MINMAXCPOINTS;Min/Max controlepunten +CURVEEDITOR_MINMAXCPOINTS;Min/max-controlepunten CURVEEDITOR_NURBS;Kooicurve CURVEEDITOR_PARAMETRIC;Parametrisch CURVEEDITOR_SAVEDLGLABEL;Bewaar curve... @@ -54,23 +55,23 @@ DIRBROWSER_FOLDERS;Mappen DONT_SHOW_AGAIN;Dit bericht niet meer tonen DYNPROFILEEDITOR_DELETE;Verwijder DYNPROFILEEDITOR_EDIT;Wijzig -DYNPROFILEEDITOR_EDIT_RULE;Wijzig Dynamisch Profielregel -DYNPROFILEEDITOR_ENTRY_TOOLTIP;Het zoeken is niet hoofdlettergevoelig.\nGebruik het "re:" voorvoegsel om\n een reguliere expressie uit te voeren +DYNPROFILEEDITOR_EDIT_RULE;Wijzig dynamische profielregel +DYNPROFILEEDITOR_ENTRY_TOOLTIP;Het zoeken is niet hoofdlettergevoelig.\nGebruik het "re:" voorvoegsel om\n een reguliere expressie in te voeren DYNPROFILEEDITOR_IMGTYPE_ANY;Alles DYNPROFILEEDITOR_IMGTYPE_HDR;HDR -DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift +DYNPROFILEEDITOR_IMGTYPE_PS;Pixel-shift DYNPROFILEEDITOR_IMGTYPE_STD;Standaard DYNPROFILEEDITOR_MOVE_DOWN;Naar beneden DYNPROFILEEDITOR_MOVE_UP;Naar boven DYNPROFILEEDITOR_NEW;Nieuw -DYNPROFILEEDITOR_NEW_RULE;Nieuw Dynamisch Profielregelegel +DYNPROFILEEDITOR_NEW_RULE;Nieuwe dynamische profielregel DYNPROFILEEDITOR_PROFILE;Profiel verwerken EDITWINDOW_TITLE;Bewerk afbeelding -EDIT_OBJECT_TOOLTIP;Toont een widget in het voorbeeld scherm waarmee de werking van het gereedschap kan worden aangepast. -EDIT_PIPETTE_TOOLTIP;Voeg een punt toe aan de curve door de Ctrl toets ingedrukt te houden en tegelijkertijd te links-klikken op de gewenste plek op het voorbeeld.\nOm een punt te wijzigen, hou de Ctrl toets ingedrukt en links-klik tegelijkertijd op het gewenste gebied in het voorbeeld, en laat daarna de Ctrl toets los (behalve wanneer fijne controle is gewenst), blijf de linker muis knop ingedrukt houden en beweeg de muis naar boven of beneden om dit punt te verschuiven op de curve. +EDIT_OBJECT_TOOLTIP;Toont een widget in het voorbeeldscherm waarmee de werking van het gereedschap kan worden aangepast. +EDIT_PIPETTE_TOOLTIP;Voeg een punt aan de curve toe met Ctrl+muisklik op de gewenste plek in het voorbeeld.\nKlik op een punt in de tooncurve om deze te selecteren (wordt rood), verplaats 'm vervolgens met de linkermuisknop ingedrukt.\n Hou de Ctrl-toets ingedrukt voor fijnmazige controle. EXIFFILTER_APERTURE;Diafragma EXIFFILTER_CAMERA;Camera -EXIFFILTER_EXPOSURECOMPENSATION;Belichtingscompensatie (EV) +EXIFFILTER_EXPOSURECOMPENSATION;Belichtingscompensatie (LW) EXIFFILTER_FILETYPE;Bestandstype EXIFFILTER_FOCALLEN;Brandpuntsafstand EXIFFILTER_IMAGETYPE;Type afbeelding @@ -89,8 +90,8 @@ EXIFPANEL_REMOVE;Verwijder EXIFPANEL_REMOVEHINT;Verwijder geselecteerde tags in doelbestand EXIFPANEL_RESET;Herstel EXIFPANEL_RESETALL;Herstel alles -EXIFPANEL_RESETALLHINT;Zet alle tags terug naar oorspronkelijke waarden -EXIFPANEL_RESETHINT;Zet geselecteerde tags terug naar oorspronkelijke waarden +EXIFPANEL_RESETALLHINT;Zet alle tags terug naar hun oorspronkelijke waarden +EXIFPANEL_RESETHINT;Zet geselecteerde tags terug naar hun oorspronkelijke waarden EXIFPANEL_SHOWALL;Toon alles EXIFPANEL_SUBDIRECTORY;Submap EXPORT_BYPASS;Verwerkingsstappen die worden overgeslagen @@ -98,8 +99,8 @@ EXPORT_BYPASS_ALL;Alles selecteren/deselecteren EXPORT_BYPASS_DEFRINGE;Verzachten niet toepassen EXPORT_BYPASS_DIRPYRDENOISE;Ruisonderdrukking niet toepassen EXPORT_BYPASS_DIRPYREQUALIZER;Detailcontrast niet toepassen -EXPORT_BYPASS_EQUALIZER;Wavelet Niveau niet toepassen -EXPORT_BYPASS_RAW_CA;Correctie Chromatische Aberratie niet toepassen [raw] +EXPORT_BYPASS_EQUALIZER;Wavelet-niveaus niet toepassen +EXPORT_BYPASS_RAW_CA;Correctie Chromatische afwijking 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] @@ -107,7 +108,7 @@ EXPORT_BYPASS_RAW_DF;Donkerframe niet toepassen [raw] EXPORT_BYPASS_RAW_FF;Vlakveld niet toepassen [raw] EXPORT_BYPASS_RAW_GREENTHRESH;Groenbalans niet toepassen [raw] EXPORT_BYPASS_RAW_LINENOISE;Lijnruisfilter niet toepassen [raw] -EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;LMMSE Verbetering niet toeppassen [raw] +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;LMMSE-verbetering niet toeppassen [raw] EXPORT_BYPASS_SHARPENEDGE;Randen verscherpen niet toepassen EXPORT_BYPASS_SHARPENING;Verscherpen niet toepassen EXPORT_BYPASS_SHARPENMICRO;Microcontrast niet toepassen @@ -119,7 +120,7 @@ EXPORT_PIPELINE;Verwerken EXPORT_PUTTOQUEUEFAST;Plaats in verwerkingsrij voor Snelle Export EXPORT_RAW_DMETHOD;Demozaïekmethode EXPORT_USE_FAST_PIPELINE;Snel (volledige verwerking op gewijzigd formaat van de afbeelding) -EXPORT_USE_FAST_PIPELINE_TOOLTIP;Gebruikt een speciale verwerkingslijn waarbij kwaliteit ten koste gaat van snelheid. Het formaat van de afbeelding wordt zo snel mogelijk gewijzigd, ipv aan het eind van de verwerking. De snelheidswinst is aanzienlijk, maar de kwaliteit van de afbeelding zal minder zijn. +EXPORT_USE_FAST_PIPELINE_TOOLTIP;Gebruikt een speciale verwerkingslijn waarbij kwaliteit ten koste gaat van snelheid. Het formaat van de afbeelding wordt zo snel mogelijk gewijzigd, in plaats van aan het eind van de verwerking. De snelheidswinst is aanzienlijk, maar de kwaliteit van de afbeelding zal minder zijn. EXPORT_USE_NORMAL_PIPELINE;Standaard (wijzigt formaat aan het eind) EXTPROGTARGET_1;raw EXTPROGTARGET_2;verwerkingsrij @@ -127,13 +128,13 @@ FILEBROWSER_APPLYPROFILE;Pas profiel toe FILEBROWSER_APPLYPROFILE_PARTIAL;Pas profiel toe (gedeeltelijk) FILEBROWSER_AUTODARKFRAME;Automatisch donkerframe FILEBROWSER_AUTOFLATFIELD;Selecteer automatisch vlakveldopname -FILEBROWSER_BROWSEPATHBUTTONHINT;Klik om de opgegeven map te laden, en het zoekfilter opnieuw toe te passen. -FILEBROWSER_BROWSEPATHHINT;Typ het pad naar de doelmap.\nCtrl-O markeer het pad in het tekstveld.\nEnter / Ctrl-Enter open de map.\nEsc maak het tekstveld leeg.\nShift-Esc verwijder markering.\n\n\nSneltoetsen:\n ~ - gebruikers home directory\n ! - gebruikers afbeeldingen map +FILEBROWSER_BROWSEPATHBUTTONHINT;Klik om de opgegeven map te laden en het zoekfilter opnieuw toe te passen. +FILEBROWSER_BROWSEPATHHINT;Typ het pad naar de doelmap.\nCtrl+O markeer het pad in het tekstveld.\nEnter / Ctrl+Enter open de map.\nEsc maak het tekstveld leeg.\nShift+Esc verwijder markering.\n\nsneltoetsen:\n ~ - thuismap van de gebruiker\n ! - afbeeldingenmap van de gebruiker FILEBROWSER_CACHE;Cache FILEBROWSER_CACHECLEARFROMFULL;Wis alles inclusief opgeslagen profielen FILEBROWSER_CACHECLEARFROMPARTIAL;Wis alles behalve opgeslagen profielen FILEBROWSER_CLEARPROFILE;Verwijder profiel -FILEBROWSER_COLORLABEL_TOOLTIP;Kleur label\n\nGebruik keuzemenu of nSneltoets:\nShift-Ctrl-0 Geen kleur\nShift-Ctrl-1 Rood\nShift-Ctrl-2 Geel\nShift-Ctrl-3 Groen\nShift-Ctrl-4 Blauw\nShift-Ctrl-5 Paars +FILEBROWSER_COLORLABEL_TOOLTIP;Kleur label\n\nGebruik keuzemenu of nSneltoets:\nShift+Ctrl+0 Geen kleur\nShift+Ctrl+1 Rood\nShift+Ctrl+2 Geel\nShift+Ctrl+3 Groen\nShift+Ctrl+4 Blauw\nShift+Ctrl+5 Paars FILEBROWSER_COPYPROFILE;Kopieer profiel FILEBROWSER_CURRENT_NAME;Huidige naam: FILEBROWSER_DARKFRAME;Donkerframe @@ -148,11 +149,11 @@ FILEBROWSER_FLATFIELD;Vlakveld FILEBROWSER_MOVETODARKFDIR;Verplaats naar map met donkerframes FILEBROWSER_MOVETOFLATFIELDDIR;Verplaats naar vlakveldmap FILEBROWSER_NEW_NAME;Nieuwe naam: -FILEBROWSER_OPENDEFAULTVIEWER;Windows standaard viewer (verwerkingsrij) +FILEBROWSER_OPENDEFAULTVIEWER;Windows standaardfoto-viewer (verwerkingsrij) FILEBROWSER_PARTIALPASTEPROFILE;Gedeeltelijk plakken FILEBROWSER_PASTEPROFILE;Plak profiel FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij -FILEBROWSER_POPUPCOLORLABEL;Kleur label +FILEBROWSER_POPUPCOLORLABEL;Labelkleur FILEBROWSER_POPUPCOLORLABEL0;Label: Geen FILEBROWSER_POPUPCOLORLABEL1;Label: Rood FILEBROWSER_POPUPCOLORLABEL2;Label: Geel @@ -161,8 +162,8 @@ FILEBROWSER_POPUPCOLORLABEL4;Label: Blauw FILEBROWSER_POPUPCOLORLABEL5;Label: Paars FILEBROWSER_POPUPCOPYTO;Kopieer naar... FILEBROWSER_POPUPFILEOPERATIONS;Bestandsbewerkingen -FILEBROWSER_POPUPMOVEEND;Naar eind van verwerkingsrij -FILEBROWSER_POPUPMOVEHEAD;Naar begin verwerkingsrij +FILEBROWSER_POPUPMOVEEND;Naar einde van de verwerkingsrij +FILEBROWSER_POPUPMOVEHEAD;Naar begin van de verwerkingsrij FILEBROWSER_POPUPMOVETO;Verplaats naar... FILEBROWSER_POPUPOPEN;Open FILEBROWSER_POPUPOPENINEDITOR;Open in Bewerkingsvenster @@ -184,7 +185,7 @@ FILEBROWSER_POPUPTRASH;Verplaats naar prullenbak FILEBROWSER_POPUPUNRANK;Verwijder sterwaardering FILEBROWSER_POPUPUNTRASH;Haal terug uit prullenbak FILEBROWSER_QUERYBUTTONHINT;Wis zoekopdracht -FILEBROWSER_QUERYHINT;Zoeken op bestandsnamen. Ondersteund gedeeltelijke bestandsnamen. Scheidt de zoektermen door komma's, bv.\n1001,1004,1199\n\nSluit zoektermen uit door ze te prefixen met != bv.\n!=1001,1004,1199 \n\nSneltoets:\nCtrl-f - focus het zoekveld,\nEnter - zoek,\nEsc - verwijder zoekresultaat, \nShift-Esc - verwijder focus van het zoekveld. +FILEBROWSER_QUERYHINT;Zoeken op bestandsnamen. Ondersteunt gedeeltelijke bestandsnamen. Scheid de zoektermen door komma's, bv.\n1001,1004,1199 (zonder spaties!)\n\nSluit zoektermen uit door er != voor te plaatsen bijvoorbeeld\n!=1001,1004,1199 \n\nSneltoets:\nCtrl+F - focus op het zoekveld,\nEnter - zoek,\nEsc - verwijder zoekresultaat, \nShift+Esc - verwijder focus van het zoekveld. FILEBROWSER_QUERYLABEL; Zoeken: FILEBROWSER_RANK1_TOOLTIP;Waardering 1 *\nSneltoets: 1 FILEBROWSER_RANK2_TOOLTIP;Waardering 2 *\nSneltoets: 2 @@ -195,42 +196,42 @@ FILEBROWSER_RENAMEDLGLABEL;Hernoem bestand FILEBROWSER_RESETDEFAULTPROFILE;Terugzetten naar standaardwaarde FILEBROWSER_SELECTDARKFRAME;Selecteer donkerframe... FILEBROWSER_SELECTFLATFIELD;Kies vlakveldopname... -FILEBROWSER_SHOWCOLORLABEL1HINT;Toon foto's met label Rood\nSneltoets: Alt-1 -FILEBROWSER_SHOWCOLORLABEL2HINT;Toon foto's met label Geel\nSneltoets: Alt-2 -FILEBROWSER_SHOWCOLORLABEL3HINT;Toon foto's met label Groen\nSneltoets: Alt-3 -FILEBROWSER_SHOWCOLORLABEL4HINT;Toon foto's met label Blauw\nSneltoets: Alt-4 -FILEBROWSER_SHOWCOLORLABEL5HINT;Toon foto's met label Paars\nSneltoets: Alt-5 +FILEBROWSER_SHOWCOLORLABEL1HINT;Toon foto's met label Rood\nSneltoets: Alt+1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Toon foto's met label Geel\nSneltoets: Alt+2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Toon foto's met label Groen\nSneltoets: Alt+3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Toon foto's met label Blauw\nSneltoets: Alt+4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Toon foto's met label Paars\nSneltoets: Alt+5 FILEBROWSER_SHOWDIRHINT;Verwijder alle filters.\nSneltoets: d -FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's\nSneltoets: Shift-7 -FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's\nSneltoets: Shift-6 -FILEBROWSER_SHOWEXIFINFO;Toon EXIF-info +FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's\nSneltoets: Shift+7 +FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's\nSneltoets: Shift+6 +FILEBROWSER_SHOWEXIFINFO;Toon Exif-info FILEBROWSER_SHOWNOTTRASHHINT;Toon alleen niet-verwijderde afbeeldingen. -FILEBROWSER_SHOWORIGINALHINT;Toon alleen originele afbeelding.\n\nAls er meerdere afbeeldingen zijn met dezelfde naam maar verschillende extensies, dan wordt de afbeelding waarvan de extensie het hoogst staat in de lijst met extensies in Voorkeuren > Bestandsnavigator > Extensies -FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster.\nSneltoets: Shift-1 -FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren.\nSneltoets: Shift-2 -FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren.\nSneltoets: Shift-3 -FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren.\nSneltoets: Shift-4 -FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren.\nSneltoets: Shift-5 -FILEBROWSER_SHOWRECENTLYSAVEDHINT;Toon recent opgeslagen/verwerkte foto's.\nSneltoets: Alt-7 -FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte foto's.\nSneltoets: Alt-6 -FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak\nSneltoets: Ctrl-t -FILEBROWSER_SHOWUNCOLORHINT;Toon foto's zonder kleurlabel.\nSneltoets: Alt-0 -FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering.\nSneltoets: Shift-0 +FILEBROWSER_SHOWORIGINALHINT;Toon alleen originele afbeelding.\n\nAls er meerdere afbeeldingen zijn met dezelfde naam maar verschillende extensies, dan wordt de afbeelding gekozen waarvan de extensie het hoogst staat in de lijst met extensies in Voorkeuren > Bestandsnavigator > Extensies +FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster.\nSneltoets: Shift+1 +FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren.\nSneltoets: Shift+2 +FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren.\nSneltoets: Shift+3 +FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren.\nSneltoets: Shift+4 +FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren.\nSneltoets: Shift+5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Toon recent opgeslagen/verwerkte foto's.\nSneltoets: Alt+7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte foto's.\nSneltoets: Alt+6 +FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak\nSneltoets: Ctrl+T +FILEBROWSER_SHOWUNCOLORHINT;Toon foto's zonder kleurlabel.\nSneltoets: Alt+0 +FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering.\nSneltoets: Shift+0 FILEBROWSER_THUMBSIZE;Miniaturen FILEBROWSER_UNRANK_TOOLTIP;Verwijder sterwaardering\nSneltoets: 0 FILEBROWSER_ZOOMINHINT;Groter FILEBROWSER_ZOOMOUTHINT;Kleiner FILECHOOSER_FILTER_ANY;Alle bestanden FILECHOOSER_FILTER_COLPROF;Kleurprofielen -FILECHOOSER_FILTER_CURVE;Curve bestanden -FILECHOOSER_FILTER_LCP;Lens correctieprofielen +FILECHOOSER_FILTER_CURVE;Curve-bestanden +FILECHOOSER_FILTER_LCP;Lenscorrectieprofielen FILECHOOSER_FILTER_PP;Profiel verwerken -FILECHOOSER_FILTER_SAME;Hetzelfe formaat als huidige foto -FILECHOOSER_FILTER_TIFF;TIFF bestanden +FILECHOOSER_FILTER_SAME;Hetzelfde formaat als huidige foto +FILECHOOSER_FILTER_TIFF;TIFF-bestanden GENERAL_ABOUT;Over RawTherapee GENERAL_AFTER;Na GENERAL_APPLY;Toepassen -GENERAL_ASIMAGE;Als Afbeelding +GENERAL_ASIMAGE;Als afbeelding GENERAL_AUTO;Automatisch GENERAL_BEFORE;Voor GENERAL_CANCEL;Annuleren @@ -258,10 +259,10 @@ GENERAL_WARNING;Waarschuwing GIMP_PLUGIN_INFO;Welkom bij de RawTherapee GIMP plug-in!\nAls uw bewerking gereed is, sluit dan het hoofdvenster van RawTherapee en uw afbeelding wordt automatisch in GIMP geladen. HISTOGRAM_TOOLTIP_B;Toon/verberg blauw histogram HISTOGRAM_TOOLTIP_BAR;Toon/verberg RGB-indicatie\nRechtermuisklik op foto om te starten/stoppen -HISTOGRAM_TOOLTIP_CHRO;Toon/Verberg Chromaticiteit histogram +HISTOGRAM_TOOLTIP_CHRO;Toon/Verberg chromaticiteitshistogram HISTOGRAM_TOOLTIP_G;Toon/verberg groen histogram HISTOGRAM_TOOLTIP_L;Toon/verberg CIELAB-luminantiehistogram -HISTOGRAM_TOOLTIP_MODE;Wissel tussen lineair, log-lineair and log-log schalen van het histogram. +HISTOGRAM_TOOLTIP_MODE;Wissel tussen lineair, log-lineair en log-log schalen van het histogram. HISTOGRAM_TOOLTIP_R;Toon/verberg rood histogram HISTORY_CHANGED;Veranderd HISTORY_CUSTOMCURVE;Handmatig @@ -274,40 +275,40 @@ HISTORY_MSG_5;Helderheid HISTORY_MSG_6;Contrast HISTORY_MSG_7;Schaduwen HISTORY_MSG_8;Belichtingscompensatie -HISTORY_MSG_9;Hoge lichten Comprimeren +HISTORY_MSG_9;Hoge lichten comprimeren HISTORY_MSG_10;Schaduwcompressie HISTORY_MSG_11;Tooncurve 1 HISTORY_MSG_12;Automatische belichting HISTORY_MSG_13;Drempel HISTORY_MSG_14;L*a*b* - Helderheid HISTORY_MSG_15;L*a*b* - Contrast -HISTORY_MSG_19;L*a*b* - L* curve +HISTORY_MSG_19;L*a*b* - L*-curve HISTORY_MSG_20;Verscherpen -HISTORY_MSG_21;OSM - Straal -HISTORY_MSG_22;OSM - Hoeveelheid -HISTORY_MSG_23;OSM - Drempel -HISTORY_MSG_24;OSM - Randen -HISTORY_MSG_25;OSM - Randen Straal -HISTORY_MSG_26;OSM - Randtolerantie -HISTORY_MSG_27;OSM - Halocontrole -HISTORY_MSG_28;OSM - Halo hoeveelheid +HISTORY_MSG_21;Onscherpmasker - Straal +HISTORY_MSG_22;Onscherpmasker - Hoeveelheid +HISTORY_MSG_23;Onscherpmasker - Drempel +HISTORY_MSG_24;Onscherpmasker - Randen +HISTORY_MSG_25;Onscherpmasker - Randen straal +HISTORY_MSG_26;Onscherpmasker - Randtolerantie +HISTORY_MSG_27;Onscherpmasker - Halocontrole +HISTORY_MSG_28;Onscherpmasker - Halo hoeveelheid HISTORY_MSG_29;Verscherpingsmethode HISTORY_MSG_30;RL-verscherping - Straal HISTORY_MSG_31;RL-verscherping - Hoeveelheid HISTORY_MSG_32;RL-verscherping - Demping HISTORY_MSG_33;RL-verscherping - Herhaling -HISTORY_MSG_34;Lensvervorming correctie -HISTORY_MSG_35;Vignettering correctie -HISTORY_MSG_36;CA correctie -HISTORY_MSG_37;Automatische Niveaus -HISTORY_MSG_38;Witbalans Methode +HISTORY_MSG_34;Lensvervormingscorrectie +HISTORY_MSG_35;Vignetteringscorrectie +HISTORY_MSG_36;CA-correctie +HISTORY_MSG_37;Automatische niveaus +HISTORY_MSG_38;Witbalans - Methode HISTORY_MSG_39;Kleurtemperatuur HISTORY_MSG_40;Witbalans Groentint HISTORY_MSG_41;Tooncurve Mode 1 HISTORY_MSG_42;Tooncurve 2 HISTORY_MSG_43;Tooncurve Mode 2 -HISTORY_MSG_48;Gebruik DCP's toon curve -HISTORY_MSG_49;DCP Illuminant +HISTORY_MSG_48;Gebruik DCP-tooncurve +HISTORY_MSG_49;DCP-illuminant HISTORY_MSG_50;Schaduwen/hoge lichten HISTORY_MSG_51;S/HL - Hoge lichten HISTORY_MSG_52;S/HL - Schaduwen @@ -324,12 +325,12 @@ HISTORY_MSG_63;Snapshot HISTORY_MSG_64;Bijsnijden HISTORY_MSG_65;CA-correctie HISTORY_MSG_66;Hoge lichten herstellen -HISTORY_MSG_68;HL herstellen methode +HISTORY_MSG_68;HL herstellen - methode HISTORY_MSG_69;Kleurwerkruimte HISTORY_MSG_70;Uitvoerkleurruimte HISTORY_MSG_71;Invoerkleurruimte HISTORY_MSG_72;VC - Hoeveelheid -HISTORY_MSG_73;Kleurkanaal Mixer +HISTORY_MSG_73;Kleurkanaalmixer HISTORY_MSG_74;Schalingsinstelling HISTORY_MSG_75;Schalingsmethode HISTORY_MSG_76;Exif-metadata @@ -339,26 +340,26 @@ HISTORY_MSG_80;Schalen - Hoogte HISTORY_MSG_81;Schalen geactiveerd HISTORY_MSG_82;Profiel veranderd HISTORY_MSG_84;Perspectiefcorrectie -HISTORY_MSG_85;Lenscorrectie Profiel -HISTORY_MSG_86;RGB Curven - Luminos. Mode +HISTORY_MSG_85;Lenscorrectieprofiel +HISTORY_MSG_86;RGB-curven - Luminos. Modus HISTORY_MSG_87;Spot-ruisonderdrukking -HISTORY_MSG_88;Spot-ruis drempel +HISTORY_MSG_88;Spot ruisdrempel HISTORY_MSG_89;Ruisonderdrukking -HISTORY_MSG_90;RO -Luminantie -HISTORY_MSG_91;RO -Chrominantie leidend -HISTORY_MSG_92;RO -Gamma -HISTORY_MSG_93;DC waarde +HISTORY_MSG_90;RO - Luminantie +HISTORY_MSG_91;RO - Chrominantie leidend +HISTORY_MSG_92;RO - Gamma +HISTORY_MSG_93;DC-waarde HISTORY_MSG_94;Detailcontrast -HISTORY_MSG_95;L*a*b* -Chromaticiteit -HISTORY_MSG_96;L*a*b* -'a*'-curve -HISTORY_MSG_97;L*a*b* -'b*'-curve +HISTORY_MSG_95;L*a*b* - Chromaticiteit +HISTORY_MSG_96;L*a*b* - 'a*'-curve +HISTORY_MSG_97;L*a*b* - 'b*'-curve HISTORY_MSG_98;Demozaïekmethode -HISTORY_MSG_99;Hete pixels filter -HISTORY_MSG_100;RGB Verzadiging +HISTORY_MSG_99;Hetepixels-filter +HISTORY_MSG_100;RGB-verzadiging HISTORY_MSG_101;HSV - Tint HISTORY_MSG_102;HSV - Verzadiging HISTORY_MSG_103;HSV - Waarde -HISTORY_MSG_104;HSV Balans +HISTORY_MSG_104;HSV-balans HISTORY_MSG_105;Randverzachting HISTORY_MSG_106;RV - Straal HISTORY_MSG_107;RV - Drempel @@ -368,22 +369,22 @@ HISTORY_MSG_110;Herschalen van: HISTORY_MSG_111;L*a*b* - Vermijd kleurversch. HISTORY_MSG_112;--unused-- HISTORY_MSG_113;L*a*b* - Beschermen -HISTORY_MSG_114;DCB Herhalingen +HISTORY_MSG_114;DCB-herhalingen HISTORY_MSG_115;Valse kleuren onderdrukken HISTORY_MSG_116;Verbeterd DCB HISTORY_MSG_117;RAW CA-correctie - Rood HISTORY_MSG_118;RAW CA-correctie - Blauw HISTORY_MSG_119;Lijnruis -HISTORY_MSG_120;Groenbalans drempel +HISTORY_MSG_120;Drempel groenbalans HISTORY_MSG_121;RAW CA-correctie - Auto HISTORY_MSG_122;Donkerframe - Autom. selectie HISTORY_MSG_123;Donkerframe - Bestand -HISTORY_MSG_124;Witpunt correctie +HISTORY_MSG_124;Witpuntcorrectie HISTORY_MSG_126;Vlakveld - Bestand HISTORY_MSG_127;Vlakveld - Autom. selectie HISTORY_MSG_128;Vlakveld - Verzachten straal HISTORY_MSG_129;Vlakveld - Verzachten type -HISTORY_MSG_130;Auto correctie lensvervorming +HISTORY_MSG_130;Autocorrectie lensvervorming HISTORY_MSG_137;Zwartniveau - Groen 1 HISTORY_MSG_138;Zwartniveau - Rood HISTORY_MSG_139;Zwartniveau - Blauw @@ -404,7 +405,7 @@ HISTORY_MSG_153;LV - Verzadigde tinten HISTORY_MSG_154;LV - Bescherm huidtinten HISTORY_MSG_155;LV - Vermijd verschuiving HISTORY_MSG_156;LV - Koppel pastel/verzadig -HISTORY_MSG_157;LV - P/S Drempel +HISTORY_MSG_157;LV - P/S-drempel HISTORY_MSG_158;TK - Sterkte HISTORY_MSG_159;TK - Randen HISTORY_MSG_160;TK - Schaal @@ -415,75 +416,75 @@ HISTORY_MSG_164;RGB-curve - G HISTORY_MSG_165;RGB-curve - B HISTORY_MSG_166;Belichting - Teruggezet HISTORY_MSG_167;Demozaïekmethode -HISTORY_MSG_168;L*a*b* - CC curve -HISTORY_MSG_169;L*a*b* - CH curve -HISTORY_MSG_170;Levendigheid curve -HISTORY_MSG_171;L*a*b* - LC curve +HISTORY_MSG_168;L*a*b* - CC-curve +HISTORY_MSG_169;L*a*b* - CH-curve +HISTORY_MSG_170;Levendigheidscurve +HISTORY_MSG_171;L*a*b* - LC-curve HISTORY_MSG_172;L*a*b* - Beperk LC HISTORY_MSG_173;NR - Detailbehoud HISTORY_MSG_174;CIECAM02 -HISTORY_MSG_175;CAM02 - CAT02 toepassing -HISTORY_MSG_176;CAM02 - Weergave omgeving -HISTORY_MSG_177;CAM02 - Opname Luminositeit -HISTORY_MSG_178;CAM02 - Weergave Luminositeit -HISTORY_MSG_179;CAM02 - Witpunt model +HISTORY_MSG_175;CAM02 - CAT02-toepassing +HISTORY_MSG_176;CAM02 - Weergave-omgeving +HISTORY_MSG_177;CAM02 - Luminositeit scène (opname) +HISTORY_MSG_178;CAM02 - Luminositeit weergave (bv. monitor) +HISTORY_MSG_179;CAM02 - Witpuntmodel HISTORY_MSG_180;CAM02 - Lichtheid (J) HISTORY_MSG_181;CAM02 - Chroma (C) HISTORY_MSG_182;CAM02 - Automatisch CAT02 HISTORY_MSG_183;CAM02 - Contrast (J) -HISTORY_MSG_184;CAM02 - Opname omgeving -HISTORY_MSG_185;CAM02 - Gamut controle +HISTORY_MSG_184;CAM02 - Scène-omgeving +HISTORY_MSG_185;CAM02 - Beperk kleurenscala HISTORY_MSG_186;CAM02 - Algoritme -HISTORY_MSG_187;CAM02 - Rode/Huidtint bescher. +HISTORY_MSG_187;CAM02 - Rode/huidtint. bescher. HISTORY_MSG_188;CAM02 - Helderheid (Q) HISTORY_MSG_189;CAM02 - Contrast (Q) HISTORY_MSG_190;CAM02 - Verzadiging (S) HISTORY_MSG_191;CAM02 - Kleurrijkheid (M) HISTORY_MSG_192;CAM02 - Tint (h) -HISTORY_MSG_193;CAM02 - Toon curve 1 -HISTORY_MSG_194;CAM02 - Toon curve 2 -HISTORY_MSG_195;CAM02 - Toon curve 1 -HISTORY_MSG_196;CAM02 - Toon curve 2 -HISTORY_MSG_197;CAM02 - Kleur curve -HISTORY_MSG_198;CAM02 - Kleur curve -HISTORY_MSG_199;CAM02 - Toont in histogram -HISTORY_MSG_200;CAM02 - Tonemapping +HISTORY_MSG_193;CAM02 - Tooncurve 1 +HISTORY_MSG_194;CAM02 - Tooncurve 2 +HISTORY_MSG_195;CAM02 - Tooncurve 1 +HISTORY_MSG_196;CAM02 - Tooncurve 2 +HISTORY_MSG_197;CAM02 - Kleurcurve +HISTORY_MSG_198;CAM02 - Kleurcurve +HISTORY_MSG_199;CAM02 - Toon in histogram +HISTORY_MSG_200;CAM02 - Toonmappen HISTORY_MSG_201;RO - Chromin. rood-groen HISTORY_MSG_202;RO - Chromin. blauw-geel HISTORY_MSG_203;NR - Kleurruimte -HISTORY_MSG_204;LMMSE Verbetering +HISTORY_MSG_204;LMMSE-verbetering HISTORY_MSG_205;CAM02 hete/dode pixels -HISTORY_MSG_206;CAT02 - Opname Lum. Auto -HISTORY_MSG_207;Verzachten Tint curve -HISTORY_MSG_208;WB - Blauw/Rood balans +HISTORY_MSG_206;CAT02 - Scène Lum. Auto +HISTORY_MSG_207;Verzachten tintcurve +HISTORY_MSG_208;WB - Blauw/Rood-balans HISTORY_MSG_210;GF - Hoek -HISTORY_MSG_211;Grijsverloop Filter +HISTORY_MSG_211;Grijsverloopfilter HISTORY_MSG_212;VF - Sterkte -HISTORY_MSG_213;Vignettering Filter -HISTORY_MSG_214;Zwart-Wit +HISTORY_MSG_213;Vignetteringsfilter +HISTORY_MSG_214;Zwart-wit HISTORY_MSG_215;ZW - KM - Rood HISTORY_MSG_216;ZW - KM - Groen HISTORY_MSG_217;ZW - KM - Blauw HISTORY_MSG_218;ZW - Gamma - Rood HISTORY_MSG_219;ZW - Gamma - Groen HISTORY_MSG_220;ZW - Gamma - Blauw -HISTORY_MSG_221;ZW - Kleur Filter +HISTORY_MSG_221;ZW - Filterkleur HISTORY_MSG_222;ZW - Voorinstelling HISTORY_MSG_223;ZW - KM - Oranje HISTORY_MSG_224;ZW - KM - Geel HISTORY_MSG_225;ZW - KM - Cyaan HISTORY_MSG_226;ZW - KM - Magenta HISTORY_MSG_227;ZW - KM - Paars -HISTORY_MSG_228;ZW - Luminantie Mixer -HISTORY_MSG_229;ZW - Luminantie Mixer -HISTORY_MSG_230;ZW - Mode -HISTORY_MSG_231;ZW - 'Voor' curve -HISTORY_MSG_232;ZW - 'Voor' curve type -HISTORY_MSG_233;ZW - 'Na' curve -HISTORY_MSG_234;ZW - 'Na' curve type -HISTORY_MSG_235;B&W - CM - Auto +HISTORY_MSG_228;ZW - Luminantiemixer +HISTORY_MSG_229;ZW - Luminantiemixer +HISTORY_MSG_230;ZW - Modus +HISTORY_MSG_231;ZW - 'Voor'-curve +HISTORY_MSG_232;ZW - Type 'Voor'-curve +HISTORY_MSG_233;ZW - 'Na'-curve +HISTORY_MSG_234;ZW - Type 'Na' curve +HISTORY_MSG_235;B&W - CM - Auto HISTORY_MSG_236;- -HISTORY_MSG_237;B&W - CM +HISTORY_MSG_237;BW - CM HISTORY_MSG_238;GF - Straal HISTORY_MSG_239;GF - Sterkte HISTORY_MSG_240;GF - Centrum @@ -492,22 +493,22 @@ HISTORY_MSG_242;VF - Vorm HISTORY_MSG_243;VC - Straal HISTORY_MSG_244;VC - Sterkte HISTORY_MSG_245;VC - Centrum -HISTORY_MSG_246;L*a*b* - CL curve -HISTORY_MSG_247;L*a*b* - LH curve -HISTORY_MSG_248;L*a*b* - HH curve +HISTORY_MSG_246;L*a*b* - CL-curve +HISTORY_MSG_247;L*a*b* - LH-curve +HISTORY_MSG_248;L*a*b* - HH-curve HISTORY_MSG_249;DC - Drempel HISTORY_MSG_251;ZW - Algoritme HISTORY_MSG_252;DC - Huidtonen -HISTORY_MSG_253;DC - Verminder artefacten +HISTORY_MSG_253;DC - Verminder onregelmatigheden HISTORY_MSG_254;DC - Huidtint HISTORY_MSG_255;DC - Algoritme HISTORY_MSG_256;NR - Mediaan - Type HISTORY_MSG_257;Kleurtint -HISTORY_MSG_258;KT - Kleur curve +HISTORY_MSG_258;KT - Kleurcurve HISTORY_MSG_259;KT - Dekking -HISTORY_MSG_260;KT - a*[b*] Dekking +HISTORY_MSG_260;KT - a*[b*]-dekking HISTORY_MSG_261;KT - Methode -HISTORY_MSG_262;KT - b* Dekking +HISTORY_MSG_262;KT - b*-dekking HISTORY_MSG_263;KT - Schaduwen - Rood HISTORY_MSG_264;KT - Schaduwen - Groen HISTORY_MSG_265;KT - Schaduwen - Blauw @@ -524,131 +525,131 @@ HISTORY_MSG_277;--unused-- HISTORY_MSG_278;KT - Behoud luminantie HISTORY_MSG_279;KT - Schaduwen HISTORY_MSG_280;KT - Hoge lichten -HISTORY_MSG_281;KT - Verz. sterkte -HISTORY_MSG_282;KT - Verz. drempel +HISTORY_MSG_281;KT - Sterkte verzadiging +HISTORY_MSG_282;KT - Drempel verzadiging HISTORY_MSG_283;KT - Sterkte -HISTORY_MSG_284;KT - Auto verz. bescherming +HISTORY_MSG_284;KT - Auto-bescherming verzadiging HISTORY_MSG_285;RO - Mediaan - Methode HISTORY_MSG_286;RO - Mediaan - Type HISTORY_MSG_287;RO - Mediaan - Herhalingen -HISTORY_MSG_288;Vlakveld - Clip Controle -HISTORY_MSG_289;Vlakveld - Clip Controle - Auto +HISTORY_MSG_288;Vlakveld - Afkapcontrole +HISTORY_MSG_289;Vlakveld - Afkapcontrole - Auto HISTORY_MSG_290;Zwartniveau - Rood HISTORY_MSG_291;Zwartniveau - Groen HISTORY_MSG_292;Zwartniveau - Blauw -HISTORY_MSG_293;Film Simuleren +HISTORY_MSG_293;Filmsimulatie HISTORY_MSG_294;Film - Sterkte HISTORY_MSG_295;Film - Film -HISTORY_MSG_296;RO - Luminantie curve -HISTORY_MSG_297;NR - Modus -HISTORY_MSG_298;Dode pixels filter -HISTORY_MSG_299;RO - Chrominantie curve -HISTORY_MSG_301;RO - Luma controle -HISTORY_MSG_302;RO - Chroma methode -HISTORY_MSG_303;RO - Chroma methode -HISTORY_MSG_304;W niveau -HISTORY_MSG_305;W niveau -HISTORY_MSG_306;W N° niveau -HISTORY_MSG_307;W Ch niveau -HISTORY_MSG_308;W richting -HISTORY_MSG_309;W tegels -HISTORY_MSG_310;W Tinten lucht -HISTORY_MSG_311;W Max niveaus -HISTORY_MSG_312;W Schaduwen drempel -HISTORY_MSG_313;W Pastel Verzadigd -HISTORY_MSG_314;W Artefacten blauwe lucht -HISTORY_MSG_315;W Contrast Rest afbeelding -HISTORY_MSG_316;W Tinten huid -HISTORY_MSG_317;W Tinten reeks Huid -HISTORY_MSG_318;W Hoge lichten niveau -HISTORY_MSG_319;W Hoge lichten reeks -HISTORY_MSG_320;W Schaduwen reeks -HISTORY_MSG_321;W Schaduwen niveau -HISTORY_MSG_322;W kleurverschuiving -HISTORY_MSG_323;W Chroma niveau -HISTORY_MSG_324;W Chroma pastel -HISTORY_MSG_325;W Chroma verzadigd -HISTORY_MSG_326;W Chroma methode -HISTORY_MSG_327;W Contrast methode -HISTORY_MSG_328;W Chroma koppelen -HISTORY_MSG_329;W Dekking Rood-Groen -HISTORY_MSG_330;W Dekking Blauw-Geel -HISTORY_MSG_331;W Extra -HISTORY_MSG_332;W Tegels Methode -HISTORY_MSG_333;W Schaduwen Rest afbeelding -HISTORY_MSG_334;W Chroma -HISTORY_MSG_335;W Hoge lichten Rest afbeelding -HISTORY_MSG_336;W Hoge lichten drempel -HISTORY_MSG_337;W Tinten reeks Lucht -HISTORY_MSG_338;W Randen Straal -HISTORY_MSG_339;W Randen Waarde -HISTORY_MSG_340;W Sterkte -HISTORY_MSG_341;W - Rand prestaties -HISTORY_MSG_342;W - RS - Eerste niveau -HISTORY_MSG_343;W - Chroma niveau -HISTORY_MSG_344;W - Meth chroma balk/curve -HISTORY_MSG_345;W - RS - Lokaal contrast -HISTORY_MSG_346;W - RS - Lokaal contrast methode -HISTORY_MSG_347;W - RO - Niveau 0 -HISTORY_MSG_348;W - RO - Niveau 1 -HISTORY_MSG_349;W - RO - Niveau 2 -HISTORY_MSG_350;W - RS - Rand detectie -HISTORY_MSG_351;W - Rest - HH curve -HISTORY_MSG_352;W - Achtergrond -HISTORY_MSG_353;W - RS - Gradiënt gevoeligheid -HISTORY_MSG_354;W - RS - Verbeteren -HISTORY_MSG_355;W - RS - Drempel laag -HISTORY_MSG_356;W - RS - Drempel hoog -HISTORY_MSG_357;W - RO - Koppel met RS -HISTORY_MSG_358;W - Gamut - CH +HISTORY_MSG_296;RO - Luminantiecurve +HISTORY_MSG_297;RO - Modus +HISTORY_MSG_298;Dodepixels-filter +HISTORY_MSG_299;RO - Chrominantiecurve +HISTORY_MSG_301;RO - Luma-controle +HISTORY_MSG_302;RO - Chroma-methode +HISTORY_MSG_303;RO - Chroma-methode +HISTORY_MSG_304;Wavelets - Contrastniveaus +HISTORY_MSG_305;Wavelets - Niveaus +HISTORY_MSG_306;Wavelets - Proces +HISTORY_MSG_307;Wavelets - Ch-niveau +HISTORY_MSG_308;Wavelets - richting +HISTORY_MSG_309;Wavelets - tegels +HISTORY_MSG_310;Wavelets - Tinten lucht +HISTORY_MSG_311;Wavelets - Max. niveaus +HISTORY_MSG_312;Wavelets - Schaduwen drempel +HISTORY_MSG_313;Wavelets - Pastel Verzadigd +HISTORY_MSG_314;Wavelets - Artefacten blauwe lucht +HISTORY_MSG_315;Wavelets - Contrast Residuele afbeelding +HISTORY_MSG_316;Wavelets - Tinten huid +HISTORY_MSG_317;Wavelets - Tinten reeks Huid +HISTORY_MSG_318;Wavelets - Hoge lichten niveau +HISTORY_MSG_319;Wavelets - Hoge lichten reeks +HISTORY_MSG_320;Wavelets - Schaduwen reeks +HISTORY_MSG_321;Wavelets - Schaduwen niveau +HISTORY_MSG_322;Wavelets - kleurverschuiving +HISTORY_MSG_323;Wavelets - Chroma niveau +HISTORY_MSG_324;Wavelets - Chroma pastel +HISTORY_MSG_325;Wavelets - Chroma verzadigd +HISTORY_MSG_326;Wavelets - Chroma methode +HISTORY_MSG_327;Wavelets - Contrast methode +HISTORY_MSG_328;Wavelets - Chroma koppelen +HISTORY_MSG_329;Wavelets - Dekking Rood-Groen +HISTORY_MSG_330;Wavelets - Dekking Blauw-Geel +HISTORY_MSG_331;Wavelets - Extra +HISTORY_MSG_332;Wavelets - Tegels Methode +HISTORY_MSG_333;Wavelets - Schaduwen Residuele afbeelding +HISTORY_MSG_334;Wavelets - Chroma +HISTORY_MSG_335;Wavelets - Hoge lichten Residuele afbeelding +HISTORY_MSG_336;Wavelets - Hoge lichten drempel +HISTORY_MSG_337;Wavelets - Tinten reeks Lucht +HISTORY_MSG_338;Wavelets - Randen Straal +HISTORY_MSG_339;Wavelets - Randen Waarde +HISTORY_MSG_340;Wavelets - Sterkte +HISTORY_MSG_341;Wavelets - Rand prestaties +HISTORY_MSG_342;Wavelets - RS - Eerste niveau +HISTORY_MSG_343;Wavelets - Chroma niveau +HISTORY_MSG_344;Wavelets - Meth chroma balk/curve +HISTORY_MSG_345;Wavelets - RS - Lokaal contrast +HISTORY_MSG_346;Wavelets - RS - Lokaal contrast methode +HISTORY_MSG_347;Wavelets - RO - Niveau 0 +HISTORY_MSG_348;Wavelets - RO - Niveau 1 +HISTORY_MSG_349;Wavelets - RO - Niveau 2 +HISTORY_MSG_350;Wavelets - RS - Randdetectie +HISTORY_MSG_351;Wavelets - Rest - HH-curve +HISTORY_MSG_352;Wavelets - Achtergrond +HISTORY_MSG_353;Wavelets - RS - Gradiënt gevoeligheid +HISTORY_MSG_354;Wavelets - RS - Verbeteren +HISTORY_MSG_355;Wavelets - RS - Drempel laag +HISTORY_MSG_356;Wavelets - RS - Drempel hoog +HISTORY_MSG_357;Wavelets - RO - Koppel met RS +HISTORY_MSG_358;Wavelets - Gamut - CH HISTORY_MSG_359;Hete/Dode - Drempel HISTORY_MSG_360;TM Gamma -HISTORY_MSG_361;W - Finale - Chroma balans -HISTORY_MSG_362;W - Rest - Compressie methode -HISTORY_MSG_363;W - Rest - Compressie sterkte -HISTORY_MSG_364;W - Finale - Contrast balans -HISTORY_MSG_365;W - Finale - Balans niveau -HISTORY_MSG_366;W - Rest - Compressie gamma -HISTORY_MSG_367;W - RS - Lokaal contrast curve -HISTORY_MSG_368;W - Finale - Contrast balans -HISTORY_MSG_369;W - Finale - Balans methode -HISTORY_MSG_370;W - Finale - Lokaal contrast curve +HISTORY_MSG_361;Wavelets - Finale - Chroma balans +HISTORY_MSG_362;Wavelets - Residueel - Compressiemethode +HISTORY_MSG_363;Wavelets - Residueel - Compressiesterkte +HISTORY_MSG_364;Wavelets - Finale - Contrastbalans +HISTORY_MSG_365;Wavelets - Finale - Balansniveau +HISTORY_MSG_366;Wavelets - Residueel - Compressie gamma +HISTORY_MSG_367;Wavelets - RS - Lokaal contrast curve +HISTORY_MSG_368;Wavelets - Finale - Contrast balans +HISTORY_MSG_369;Wavelets - Finale - Balans methode +HISTORY_MSG_370;Wavelets - Finale - Lokaal contrastcurve HISTORY_MSG_371;Post-Verkleinen Verscherpen HISTORY_MSG_372;PVV OSM - Straal HISTORY_MSG_373;PVV OSM - Hoeveelheid HISTORY_MSG_374;PVV OSM - Drempel HISTORY_MSG_375;PVV OSM - Verscherp alleen randen -HISTORY_MSG_376;PVV OSM - Rand detectie straal -HISTORY_MSG_377;PVV OSM - Rand tolerantie -HISTORY_MSG_378;PVV OSM - Halo controle -HISTORY_MSG_379;PVV OSM - Halo controle hoeveelheid +HISTORY_MSG_376;PVV OSM - Randdetectie straal +HISTORY_MSG_377;PVV OSM - Randtolerantie +HISTORY_MSG_378;PVV OSM - Halocontrole +HISTORY_MSG_379;PVV OSM - Halocontrole hoeveelheid HISTORY_MSG_380;PVV - Methode HISTORY_MSG_381;PVV RLV - Straal HISTORY_MSG_382;PVV RLV - Hoeveelheid HISTORY_MSG_383;PVV RLV - Demping HISTORY_MSG_384;PVV RLV - Herhalingen -HISTORY_MSG_385;W - Rest - Kleurbalans -HISTORY_MSG_386;W - Rest - KB groen hoog -HISTORY_MSG_387;W - Rest - KB blauw hoog -HISTORY_MSG_388;W - Rest - KB groen midden -HISTORY_MSG_389;W - Rest - KB blauw midden -HISTORY_MSG_390;W - Rest - KB groen laag -HISTORY_MSG_391;W - Rest - KB blauw laag -HISTORY_MSG_392;W - Overblijvend - Kleurbalans -HISTORY_MSG_393;DCP 'Look'tabel -HISTORY_MSG_394;DCP Basis belichting -HISTORY_MSG_395;DCP Basis tabel -HISTORY_MSG_396;W - Contrast sub-tool -HISTORY_MSG_397;W - Chroma sub-tool -HISTORY_MSG_398;W - Randscherpte sub-tool -HISTORY_MSG_399;W - Rest sub-tool -HISTORY_MSG_400;W - Finale sub-tool -HISTORY_MSG_401;W - Tinten sub-tool -HISTORY_MSG_402;W - RO sub-tool -HISTORY_MSG_403;W - RS - Randgevoeligheid -HISTORY_MSG_404;W - RS - Basis versterken -HISTORY_MSG_405;W - RO - Niveau 4 -HISTORY_MSG_406;W - RS - Naburige pixels +HISTORY_MSG_385;Wavelets - Residueel - Kleurbalans +HISTORY_MSG_386;Wavelets - Residueel - KB groen hoog +HISTORY_MSG_387;Wavelets - Residueel - KB blauw hoog +HISTORY_MSG_388;Wavelets - Residueel - KB groen midden +HISTORY_MSG_389;Wavelets - Residueel - KB blauw midden +HISTORY_MSG_390;Wavelets - Residueel - KB groen laag +HISTORY_MSG_391;Wavelets - Residueel - KB blauw laag +HISTORY_MSG_392;Wavelets - Residueel - Kleurbalans +HISTORY_MSG_393;DCP 'Look'-tabel +HISTORY_MSG_394;DCP Basisbelichting +HISTORY_MSG_395;DCP Basistabel +HISTORY_MSG_396;Wavelets - Contrast sub-tool +HISTORY_MSG_397;Wavelets - Chroma sub-tool +HISTORY_MSG_398;Wavelets - Randscherpte sub-tool +HISTORY_MSG_399;Wavelets - Residueel sub-tool +HISTORY_MSG_400;Wavelets - Finale sub-tool +HISTORY_MSG_401;Wavelets - Tinten sub-tool +HISTORY_MSG_402;Wavelets - RO sub-tool +HISTORY_MSG_403;Wavelets - RS - Randgevoeligheid +HISTORY_MSG_404;Wavelets - RS - Basis versterken +HISTORY_MSG_405;Wavelets - RO - Niveau 4 +HISTORY_MSG_406;Wavelets - RS - Naburige pixels HISTORY_MSG_407;Retinex - Methode HISTORY_MSG_408;Retinex - Naburig HISTORY_MSG_410;Retinex - Beginpunt @@ -658,21 +659,21 @@ HISTORY_MSG_413;Retinex - Variantie HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmissie HISTORY_MSG_416;Retinex -HISTORY_MSG_417;Retinex - Transmissie mediaan +HISTORY_MSG_417;Retinex - Transmissiemediaan HISTORY_MSG_418;Retinex - Drempel HISTORY_MSG_419;Retinex - Kleurruimte HISTORY_MSG_420;Retinex - Histogram - HSL HISTORY_MSG_421;Retinex - Gamma HISTORY_MSG_422;Retinex - Gamma HISTORY_MSG_423;Retinex - Gamma helling -HISTORY_MSG_424;Retinex - HL drempel +HISTORY_MSG_424;Retinex - HL-drempel HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Tint balans -HISTORY_MSG_427;Uitvoer grafische weergave -HISTORY_MSG_428;Monitor grafische weergave +HISTORY_MSG_427;Weergave-intentie uitvoerprofiel +HISTORY_MSG_428;Weergave-intentie monitorprofiel HISTORY_MSG_429;Retinex - Herhalingen -HISTORY_MSG_430;Retinex - Transmissie Verloop -HISTORY_MSG_431;Retinex - Sterkte Verloop +HISTORY_MSG_430;Retinex - Transmissieverloop +HISTORY_MSG_431;Retinex - Sterkteverloop HISTORY_MSG_432;Retinex - M - Hoge lichten HISTORY_MSG_433;Retinex - M - Hoge lichten TW HISTORY_MSG_434;Retinex - M - Schaduwen @@ -684,28 +685,28 @@ HISTORY_MSG_439;Retinex - Verwerken HISTORY_MSG_440;DC - Methode HISTORY_MSG_441;Retinex - Toename transmissie HISTORY_MSG_442;Retinex - Schaal -HISTORY_MSG_443;Uivoer Zwartpunt Compensatie -HISTORY_MSG_444;WB - Temp afwijking +HISTORY_MSG_443;Zwartpuntcompensatie uitvoerprofiel +HISTORY_MSG_444;WB - Temp. afwijking HISTORY_MSG_445;Raw Sub-afbeelding HISTORY_MSG_449;PV ISO toepassen HISTORY_MSG_452;PV Toon beweging HISTORY_MSG_453;PV Toon alleen masker HISTORY_MSG_457;PV Controleer rood/blauw HISTORY_MSG_462;PV Controleer groen -HISTORY_MSG_464;PV Vervagen bewagingsmasker +HISTORY_MSG_464;PV Vervagen bewegingsmasker HISTORY_MSG_465;PV Vervagen straal HISTORY_MSG_468;PV Vul holtes -HISTORY_MSG_469;PV Mediaann +HISTORY_MSG_469;PV Mediaan HISTORY_MSG_471;PV Bewegingscorrectie HISTORY_MSG_472;PV Zachte overgang HISTORY_MSG_474;PV Balans HISTORY_MSG_475;PS - Kanaalbalans -HISTORY_MSG_476;CAM02 - Temp uit +HISTORY_MSG_476;CAM02 - Temp. uit HISTORY_MSG_477;CAM02 - Groen uit HISTORY_MSG_478;CAM02 - Yb uit HISTORY_MSG_479;CAM02 - CAT02 aanpassing uit HISTORY_MSG_480;CAM02 - Automatische CAT02 uit -HISTORY_MSG_481;CAM02 - Temp scène +HISTORY_MSG_481;CAM02 - Temp. scène HISTORY_MSG_482;CAM02 - Groen scène HISTORY_MSG_483;CAM02 - Yb scène HISTORY_MSG_484;CAM02 - Auto Yb scène @@ -716,56 +717,56 @@ HISTORY_MSG_488;Compressie Dynamisch Bereik HISTORY_MSG_489;DRC - Detail HISTORY_MSG_490;DRC - Hoeveelheid HISTORY_MSG_491;Witbalans -HISTORY_MSG_492;RGB Curven -HISTORY_MSG_493;L*a*b* Adjustments +HISTORY_MSG_492;RGB-curven +HISTORY_MSG_493;L*a*b* aanpassingen HISTORY_MSG_494;verscherpen HISTORY_MSG_CLAMPOOG;Kleuren afkappen die buiten het gamma vallen HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Kleurcorrectie HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Kleurcorrectie HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Kanaal -HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - gebied C masker -HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H masker +HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - gebied C-masker +HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H-masker HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Licht -HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L masker +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L-masker HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - Lijst HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - verzachtingsmasker gebied -HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - offset gebied +HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - verschuiving gebied HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - sterkte gebied HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Verzadiging HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - toon gebiedsmasker HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - hellingsgebied -HISTORY_MSG_DEHAZE_DEPTH;Nevelvermindering - Diepte -HISTORY_MSG_DEHAZE_ENABLED;Nevelvermindering -HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Nevelvermindering - Toon dieptemap -HISTORY_MSG_DEHAZE_STRENGTH;Nevelvermindering - Sterkte +HISTORY_MSG_DEHAZE_DEPTH;Ontnevelen - Diepte +HISTORY_MSG_DEHAZE_ENABLED;Ontnevelen +HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Ontnevelen - Toon dieptemap +HISTORY_MSG_DEHAZE_STRENGTH;Ontnevelen - Sterkte HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual-demozaïek - auto-drempel HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual-demozaïek - Contrastdrempel HISTORY_MSG_FILMNEGATIVE_ENABLED;Filmnegatief HISTORY_MSG_FILMNEGATIVE_VALUES;Filmnegatief waarden -HISTORY_MSG_HISTMATCHING;Auto-matched tooncurve -HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaries +HISTORY_MSG_HISTMATCHING;Auto-tooncurve +HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaire kleuren HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 illuminant D HISTORY_MSG_ICM_OUTPUT_TYPE;Uitvoer - Type -HISTORY_MSG_ICM_WORKING_GAMMA;Working - Gamma -HISTORY_MSG_ICM_WORKING_SLOPE;Working - Helling -HISTORY_MSG_ICM_WORKING_TRC_METHOD;Working - TRC methode -HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Hoeveelheid -HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Donker +HISTORY_MSG_ICM_WORKING_GAMMA;Werkend - Gamma +HISTORY_MSG_ICM_WORKING_SLOPE;Werkend - Helling +HISTORY_MSG_ICM_WORKING_TRC_METHOD;Werkend - TRC-methode +HISTORY_MSG_LOCALCONTRAST_AMOUNT;Lokaal Contrast - Hoeveelheid +HISTORY_MSG_LOCALCONTRAST_DARKNESS;Lokaal Contrast - Donker HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokaal Contrast HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokaal Contrast - Licht HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokaal Contrast - Radius HISTORY_MSG_METADATA_MODE;Metadata kopieermodus HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrastdrempel -HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto drempel -HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius -HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limiet herhalingen +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto-drempel +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto-radius +HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto-limiet herhalingen HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrastdrempel HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Herhalingen -HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius -HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Toename hoekradius +HISTORY_MSG_PDSHARPEN_RADIUS;CS - Straal +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Toename hoekstraal HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demozaïekmethode voor beweging -HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;lijnruisfilter richting -HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lijnfilter +HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Lijnruisfilter richting +HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrastdrempel HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correctie - Herhalingen HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correctie - Vermijd kleurverschuiving @@ -779,7 +780,7 @@ HISTORY_MSG_SOFTLIGHT_STRENGTH;Zacht licht - Sterkte HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anker HISTORY_MSG_TRANS_METHOD;Geometrie - Methode HISTORY_NEWSNAPSHOT;Nieuw -HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt-s +HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt+S HISTORY_SNAPSHOT;Nieuw HISTORY_SNAPSHOTS;Snapshots ICCPROFCREATOR_COPYRIGHT;Copyright: @@ -787,9 +788,9 @@ ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Zet terug naar standaard copyright, verle ICCPROFCREATOR_CUSTOM;Handmatig ICCPROFCREATOR_DESCRIPTION;Beschriiving: ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Voeg gamma- en hellingwaarden toe aan de beschrijving -ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Laat leeg voor de standaard beschrijving. +ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Laat leeg voor de standaardbeschrijving. ICCPROFCREATOR_GAMMA;Gamma -ICCPROFCREATOR_ICCVERSION;ICC versie: +ICCPROFCREATOR_ICCVERSION;ICC-versie: ICCPROFCREATOR_ILL;Illuminant: ICCPROFCREATOR_ILL_41;D41 ICCPROFCREATOR_ILL_50;D50 @@ -817,10 +818,10 @@ ICCPROFCREATOR_PRIM_REDX;Rood X ICCPROFCREATOR_PRIM_REDY;Rood Y ICCPROFCREATOR_PRIM_SRGB;sRGB ICCPROFCREATOR_PRIM_TOOLTIP;U kunt alleen aangepaste primaries voor ICC v4-profielen instellen. -ICCPROFCREATOR_PRIM_WIDEG;Widegamut +ICCPROFCREATOR_PRIM_WIDEG;Wijd kleurenscala ICCPROFCREATOR_PROF_V2;ICC v2 ICCPROFCREATOR_PROF_V4;ICC v4 -ICCPROFCREATOR_SAVEDIALOG_TITLE;Bewaar ICC profiel als... +ICCPROFCREATOR_SAVEDIALOG_TITLE;Bewaar ICC-profiel als... ICCPROFCREATOR_SLOPE;Helling ICCPROFCREATOR_TRC_PRESET;Toonresponscurve: IPTCPANEL_CATEGORY;Categorie @@ -828,8 +829,8 @@ IPTCPANEL_CATEGORYHINT;Het onderwerp van de afbeelding. IPTCPANEL_CITY;Plaats IPTCPANEL_CITYHINT;Plaats waar de afbeelding is genomen. IPTCPANEL_COPYHINT;Kopieer IPTC-instellingen naar klembord -IPTCPANEL_COPYRIGHT;Copyright melding -IPTCPANEL_COPYRIGHTHINT;Melding over de huidige copyright houder van de afbeelding, bijvoorbeeld ©2008 Jane Doe. +IPTCPANEL_COPYRIGHT;Copyright-melding +IPTCPANEL_COPYRIGHTHINT;Melding over de huidige copyright-houder van de afbeelding, bijvoorbeeld ©2008 Jane Doe. IPTCPANEL_COUNTRY;Land IPTCPANEL_COUNTRYHINT;Land waar de afbeelding is genomen. IPTCPANEL_CREATOR;Maker @@ -841,7 +842,7 @@ IPTCPANEL_CREDITHINT;Naam van de leverancier van de foto, niet noodzakelijkerwij IPTCPANEL_DATECREATED;Opnamedatum IPTCPANEL_DATECREATEDHINT;Datum waarop de afbeelding is genomen. IPTCPANEL_DESCRIPTION;Beschrijving -IPTCPANEL_DESCRIPTIONHINT;Bijschrift dat het wie, wat of waarom beschrijft van wat er gebeurt in de afbeelding. Dit kan inclusief de namen van de persone zijn en of hun rol in de actie die plaatsvindt in de afbeelding. +IPTCPANEL_DESCRIPTIONHINT;Bijschrift dat het wie, wat of waarom beschrijft van wat er gebeurt in de afbeelding. Dit kan inclusief de namen van de personen zijn en of hun rol in de actie die plaatsvindt in de afbeelding. IPTCPANEL_DESCRIPTIONWRITER;Schrijver van de beschrijving. IPTCPANEL_DESCRIPTIONWRITERHINT;De naam van de persoon die is betrokken bij het schrijven, wijzigen of corrigeren van de beschrijving van de afbeelding. IPTCPANEL_EMBEDDED;Ingebed @@ -867,27 +868,27 @@ IPTCPANEL_TRANSREFERENCE;Referentienummer IPTCPANEL_TRANSREFERENCEHINT;Het nummer dat wordt gebruikt voor de 'workflow control' of voor de tracking. MAIN_BUTTON_FULLSCREEN;Volledig scherm MAIN_BUTTON_ICCPROFCREATOR;ICC Profielmaker -MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nSneltoets: Shift-F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 -MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nSneltoets: Shift-F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 -MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Editor om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB de miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Fotobewerker om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB. De miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) MAIN_BUTTON_PREFERENCES;Voorkeuren MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij.\nSneltoets: Ctrl+B MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto.\nSneltoets: Ctrl+S -MAIN_BUTTON_SENDTOEDITOR;Bewerk afbeelding in externe editor +MAIN_BUTTON_SENDTOEDITOR;Bewerk afbeelding in externe fotobewerker MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma.\nSneltoets: Ctrl+E -MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: m +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: M MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm MAIN_FRAME_EDITOR;Fotobewerker -MAIN_FRAME_EDITOR_TOOLTIP; Bewerking.\nSneltoets: Ctrl-F4 +MAIN_FRAME_EDITOR_TOOLTIP; Bewerking.\nSneltoets: Ctrl+F4 MAIN_FRAME_FILEBROWSER;Bestandsnavigator -MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator.\nSneltoets: Ctrl-F2 +MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator.\nSneltoets: Ctrl+F2 MAIN_FRAME_PLACES;Locaties MAIN_FRAME_PLACES_ADD;Nieuw MAIN_FRAME_PLACES_DEL;Verwijderen MAIN_FRAME_QUEUE;Verwerkingsrij -MAIN_FRAME_QUEUE_TOOLTIP; Verwerkingsrij.\nSneltoets: Ctrl-F3 +MAIN_FRAME_QUEUE_TOOLTIP; Verwerkingsrij.\nSneltoets: Ctrl+F3 MAIN_FRAME_RECENT;Recente mappen -MAIN_MSG_ALREADYEXISTS;Bestand bestaat reeds. +MAIN_MSG_ALREADYEXISTS;Bestand bestaat al MAIN_MSG_CANNOTLOAD;Fout bij laden MAIN_MSG_CANNOTSAVE;Fout bij opslaan van de afbeelding MAIN_MSG_CANNOTSTARTEDITOR;Kan fotoprogramma niet starten. @@ -896,51 +897,51 @@ MAIN_MSG_EMPTYFILENAME;Geen bestandsnaam opgegeven! MAIN_MSG_IMAGEUNPROCESSED;Deze opdracht vereist dat alle geselecteerde foto's eerst moeten zijn verwerkt. MAIN_MSG_NAVIGATOR;Navigator MAIN_MSG_OPERATIONCANCELLED;Opdracht afgebroken -MAIN_MSG_PATHDOESNTEXIST;Het pad\n\n%1\n\nbestaat niet. Zet een correct pad bij Voorkeuren. +MAIN_MSG_PATHDOESNTEXIST;Het pad\n\n%1\n\nbestaat niet. Geef een correct pad op in Voorkeuren. MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? -MAIN_MSG_SETPATHFIRST;Specificeer eerst een doelmap in Voorkeuren \nom deze functionaliteit te kunnen gebruiken! +MAIN_MSG_SETPATHFIRST;Specificeer eerst een doelmap in Voorkeuren\nom deze functionaliteit te kunnen gebruiken! MAIN_MSG_TOOMANYOPENEDITORS;Teveel open fotobewerkers.\nSluit er een om verder te kunnen. MAIN_MSG_WRITEFAILED;Niet opgeslagen\n\n"%1"\n\nControleer of de map bestaat en dat u schrijfrechten heeft. MAIN_TAB_ADVANCED;Geavanceerd -MAIN_TAB_ADVANCED_TOOLTIP;Sneltoets: Alt-a +MAIN_TAB_ADVANCED_TOOLTIP;Sneltoets: Alt+A MAIN_TAB_COLOR;Kleur -MAIN_TAB_COLOR_TOOLTIP;Sneltoets: Alt-c +MAIN_TAB_COLOR_TOOLTIP;Sneltoets: Alt+C MAIN_TAB_DETAIL;Detail -MAIN_TAB_DETAIL_TOOLTIP;Sneltoets: Alt-d +MAIN_TAB_DETAIL_TOOLTIP;Sneltoets: Alt+D MAIN_TAB_DEVELOP;Ontwikkel MAIN_TAB_EXIF;Exif MAIN_TAB_EXPORT; Exporteren MAIN_TAB_EXPOSURE;Belichting -MAIN_TAB_EXPOSURE_TOOLTIP;Sneltoets: Alt-e +MAIN_TAB_EXPOSURE_TOOLTIP;Sneltoets: Alt+E MAIN_TAB_FAVORITES;Favorieten -MAIN_TAB_FAVORITES_TOOLTIP;Sneltoets: Alt-u +MAIN_TAB_FAVORITES_TOOLTIP;Sneltoets: Alt+U MAIN_TAB_FILTER;Filter -MAIN_TAB_INSPECT; Inspecteren +MAIN_TAB_INSPECT; Inspecteer MAIN_TAB_IPTC;IPTC MAIN_TAB_METADATA;Metadata -MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt-m +MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt+M MAIN_TAB_RAW;RAW -MAIN_TAB_RAW_TOOLTIP;Sneltoets: Alt-r +MAIN_TAB_RAW_TOOLTIP;Sneltoets: Alt+R MAIN_TAB_TRANSFORM;Transformeer -MAIN_TAB_TRANSFORM_TOOLTIP;Sneltoets: Alt-t -MAIN_TOOLTIP_BACKCOLOR0;Achtergrond kleur van het voorbeeld: Thema-based\nSneltoets: 8 +MAIN_TAB_TRANSFORM_TOOLTIP;Sneltoets: Alt+T +MAIN_TOOLTIP_BACKCOLOR0;Achtergrond kleur van het voorbeeld: Gebaseerd op thema\nSneltoets: 8 MAIN_TOOLTIP_BACKCOLOR1;Achtergrond kleur van het voorbeeld: Zwart\nSneltoets: 9 MAIN_TOOLTIP_BACKCOLOR2;Achtergrond kleur van het voorbeeld: Wit\nSneltoets: 0 -MAIN_TOOLTIP_BACKCOLOR3;Achtergrondkleur van het voorbeeld: middelgrijs\nSneltoets: 9 -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_BACKCOLOR3;Achtergrondkleur van het voorbeeld: Middelgrijs\nSneltoets: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vergrendel/Ontgrendel de Voorafbeelding.\n\nVergrendeld: 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\nOntgrendeld: de Voorafbeelding volgt een stap achter de Naafbeelding en laat de afbeelding zien zonder het effect van het huidige gereedschap. MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis).\nSneltoets: H MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: > MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: < -MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: b -MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focus Masker.\nSneltoets: Shift-F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focus Masker aanstaat. -MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: g -MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSneltoets: v\n\n0.299*R + 0.587*G + 0.114*B -MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSneltoets: r -MAIN_TOOLTIP_PREVIEWSHARPMASK;Bekijk het scherptecontrastmasker.\nSneltoets: p\nWerkt alleen als verscherping is geactiveerd en het zoomniveau >= 100%. +MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: B +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focusmasker.\nSneltoets: Shift+F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focusmasker aanstaat. +MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: G +MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSneltoets: V\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSneltoets: R +MAIN_TOOLTIP_PREVIEWSHARPMASK;Bekijk het Scherptecontrastmasker.\nSneltoets: P\nWerkt alleen als verscherping is geactiveerd en het zoomniveau >= 100%. MAIN_TOOLTIP_QINFO;Beknopte fotogegevens -MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel.\nSneltoets: l -MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt-l -MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift-L +MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel.\nSneltoets: L +MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt+L +MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift+L MAIN_TOOLTIP_THRESHOLD;Drempel MAIN_TOOLTIP_TOGGLE;Vergelijk origineel en bewerking MONITOR_PROFILE_SYSTEM;Systeem standaardwaarde @@ -957,13 +958,13 @@ NAVIGATOR_V;V: NAVIGATOR_XY_FULL;Breedte: %1, Hoogte: %2 NAVIGATOR_XY_NA;x: --, y: -- OPTIONS_BUNDLED_MISSING;Het gebundelde profiel "%1" werd niet gevonden!\n\nUw installatie kan beschadigd zijn.\n\nDaarom worden interne standaardwaarden gebruikt. -OPTIONS_DEFIMG_MISSING;Het standaardprofiel voor niet-raw- foto's werd niet gevonden of is niet ingesteld.\n\nControleer de profielenmap, het kan ontbreken of beschadigd zijn.\n\n"%1" wordt daarom gebruikt. -OPTIONS_DEFRAW_MISSING;Het standaardprofiel voor raw-foto's werd niet gevonden of is niet ingesteld.\n\nControleer de profielenmap, het kan ontbreken of beschadigd zijn.\n\n"%1" wordt daarom gebruikt. +OPTIONS_DEFIMG_MISSING;Het standaardprofiel voor niet-RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. +OPTIONS_DEFRAW_MISSING;Het standaardprofiel voor RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. PARTIALPASTE_ADVANCEDGROUP;Geavanceerd PARTIALPASTE_BASICGROUP;Basisinstellingen PARTIALPASTE_CACORRECTION;C/A-correctie -PARTIALPASTE_CHANNELMIXER;Kleurkanaal mixer -PARTIALPASTE_CHANNELMIXERBW;Zwart-Wit +PARTIALPASTE_CHANNELMIXER;Kleurkanaalmixer +PARTIALPASTE_CHANNELMIXERBW;Zwart-wit PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen @@ -974,42 +975,42 @@ PARTIALPASTE_CROP;Bijsnijden PARTIALPASTE_DARKFRAMEAUTOSELECT;Donkerframe autom. selectie PARTIALPASTE_DARKFRAMEFILE;Donkerframe-opname PARTIALPASTE_DEFRINGE;Verzachten -PARTIALPASTE_DEHAZE;Nevel verminderen +PARTIALPASTE_DEHAZE;Ontnevelen PARTIALPASTE_DETAILGROUP;Detailinstellingen PARTIALPASTE_DIALOGLABEL;Profiel gedeeltelijk plakken... PARTIALPASTE_DIRPYRDENOISE;Ruisonderdrukking PARTIALPASTE_DIRPYREQUALIZER;Detailcontrast PARTIALPASTE_DISTORTION;Corrigeer lensvervorming -PARTIALPASTE_EPD;Tonemapping +PARTIALPASTE_EPD;Toonmappen PARTIALPASTE_EQUALIZER;Wavelet Balans PARTIALPASTE_EVERYTHING;Alles PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens PARTIALPASTE_EXPOSURE;Belichting -PARTIALPASTE_FILMNEGATIVE;Film Negatief -PARTIALPASTE_FILMSIMULATION;Film Simuleren +PARTIALPASTE_FILMNEGATIVE;Filmnegatief +PARTIALPASTE_FILMSIMULATION;Filmsimulatie PARTIALPASTE_FLATFIELDAUTOSELECT;Vlakveld autoselectie PARTIALPASTE_FLATFIELDBLURRADIUS;Vlakveld verzachting straal PARTIALPASTE_FLATFIELDBLURTYPE;Vlakveld verzachting type -PARTIALPASTE_FLATFIELDCLIPCONTROL;Vlakveld clip controle +PARTIALPASTE_FLATFIELDCLIPCONTROL;Vlakveld afkapcontrole PARTIALPASTE_FLATFIELDFILE;Vlakveldopname -PARTIALPASTE_GRADIENT;Grijsverloop Filter +PARTIALPASTE_GRADIENT;Grijsverloopfilter PARTIALPASTE_HSVEQUALIZER;HSV-balans PARTIALPASTE_ICMSETTINGS;ICM-instellingen -PARTIALPASTE_IMPULSEDENOISE;Spot ruisonderdrukking +PARTIALPASTE_IMPULSEDENOISE;Spot-ruisonderdrukking PARTIALPASTE_IPTCINFO;IPTC-informatie PARTIALPASTE_LABCURVE;LAB-curve PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen -PARTIALPASTE_LENSPROFILE;Lens correctie profiel +PARTIALPASTE_LENSPROFILE;Lenscorrectieprofiel PARTIALPASTE_LOCALCONTRAST;Lokaal contrast PARTIALPASTE_METADATA;Metadata modus PARTIALPASTE_METAGROUP;Metadata -PARTIALPASTE_PCVIGNETTE;Vignettering Filter +PARTIALPASTE_PCVIGNETTE;Vignetteringsfilter PARTIALPASTE_PERSPECTIVE;Perspectief -PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dode pixels filter +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dodepixels-filter PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans -PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hete pixels filter +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hetepixels-filter PARTIALPASTE_PREPROCESS_LINEDENOISE;Lijnruisfilter -PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lijnfilter +PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter PARTIALPASTE_PRSHARPENING;Verscherp na verkleinen PARTIALPASTE_RAWCACORR_AUTO;Autom. C/A-correctie PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA vermijd kleurverschuiving @@ -1023,8 +1024,8 @@ PARTIALPASTE_RAW_DCBITERATIONS;aantal DCB-herhalingen PARTIALPASTE_RAW_DMETHOD;Demozaïekmethode PARTIALPASTE_RAW_FALSECOLOR;Demozaïek stapgrootte kleurfoutonderdrukking PARTIALPASTE_RAW_IMAGENUM;Sub-afbeelding -PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE verbetering -PARTIALPASTE_RAW_PIXELSHIFT;PixelVerschuiving +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE-verbetering +PARTIALPASTE_RAW_PIXELSHIFT;Pixelverschuiving PARTIALPASTE_RESIZE;Wijzig grootte PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;RGB-curven @@ -1041,53 +1042,53 @@ PARTIALPASTE_WHITEBALANCE;Witbalans PREFERENCES_ADD;Toevoegen PREFERENCES_APPEARANCE;Uiterlijk PREFERENCES_APPEARANCE_COLORPICKERFONT;Lettertype kleurenkiezer -PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kleur bijsnijdmasker +PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kleur bijsnijmasker PREFERENCES_APPEARANCE_MAINFONT;Standaard lettertype PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator randkleur PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI modus PREFERENCES_APPEARANCE_THEME;Thema PREFERENCES_APPLNEXTSTARTUP;herstart vereist -PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingsysteem +PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingssysteem PREFERENCES_AUTOSAVE_TP_OPEN;Bewaar positie gereedschappen (open/dicht) bij afsluiten -PREFERENCES_BATCH_PROCESSING;Batch-verwerking +PREFERENCES_BATCH_PROCESSING;Groepsverwerking PREFERENCES_BEHADDALL;Alles op 'Toevoegen' -PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen mode.\nWijzigingen van parameters in de batch tool zijn deltas op de opgeslagen waarden. +PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen-modus.\nWijzigingen van de parameters voor groepsverwerking zijn deltas op de opgeslagen waarden. PREFERENCES_BEHAVIOR;Gedrag PREFERENCES_BEHSETALL;Alles op 'Activeer' -PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer mode.\nWijzigingen van parameters in de batch tool zijn absoluut. De actuele waarden worden gebruikt. +PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer-modus.\nWijzigingen van de parameters voor groepsverwerking zijn absoluut. De actuele waarden worden gebruikt. PREFERENCES_CACHECLEAR;Wissen PREFERENCES_CACHECLEAR_ALL;Wis alle bestanden in de cache: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Wis alle bestanden in de cache behalve verwerkingsprofielen: PREFERENCES_CACHECLEAR_ONLYPROFILES;Wis alleen verwerkingsprofielen in de cache: PREFERENCES_CACHECLEAR_SAFETY;Alleen bestanden in de cache worden gewist. Verwerkingsprofielen van de oorspronkelijke afbeeldingen blijven ongemoeid. -PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in cache +PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in de cache PREFERENCES_CACHEOPTS;Cache-opties PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen PREFERENCES_CHUNKSIZES;Tegels per thread -PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaïek -PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correctie -PREFERENCES_CHUNKSIZE_RAW_RCD;RCD demosaïek -PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaïek -PREFERENCES_CHUNKSIZE_RGB;RGB verwerking +PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE-demozaïek +PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA-correctie +PREFERENCES_CHUNKSIZE_RAW_RCD;RCD-demozaïek +PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans-demozaïek +PREFERENCES_CHUNKSIZE_RGB;RGB-verwerking PREFERENCES_CLIPPINGIND;Indicatie over-/onderbelichting -PREFERENCES_CLUTSCACHE;HaldCLUT cache -PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cached Cluts -PREFERENCES_CLUTSDIR;HaldCLUT map -PREFERENCES_CMMBPC;Zwartpunt Compensatie +PREFERENCES_CLUTSCACHE;HaldCLUT-cache +PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cluts in de cache +PREFERENCES_CLUTSDIR;HaldCLUT-map +PREFERENCES_CMMBPC;Zwartpuntcompensatie PREFERENCES_CROP;Uitsnijden PREFERENCES_CROP_AUTO_FIT;Automatisch zoomen tot de uitsnede PREFERENCES_CROP_GUIDES;Getoonde hulplijnen als uitsnede niet bewerkt wordt PREFERENCES_CROP_GUIDES_FRAME;Frame PREFERENCES_CROP_GUIDES_FULL;Origineel PREFERENCES_CROP_GUIDES_NONE;Geen -PREFERENCES_CURVEBBOXPOS;Positie copy/paste knoppen bij Curves +PREFERENCES_CURVEBBOXPOS;Positie kopieer/plak-knoppen bij Curves PREFERENCES_CURVEBBOXPOS_ABOVE;Boven PREFERENCES_CURVEBBOXPOS_BELOW;Beneden PREFERENCES_CURVEBBOXPOS_LEFT;Links PREFERENCES_CURVEBBOXPOS_RIGHT;Rechts PREFERENCES_CUSTPROFBUILD;Eigen/externe profielgenerator -PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor foto te maken.\nOntvangt terminalparameters voor het genereren van pp3's gebaseerd op regels:\n[Pad RAW/JPG] [Pad default profiel] [f-getal] [belichting in sec] [brandpuntsafstand in mm] [ISO] [lens] [Camera make] [camera model]\n\n WAARSCHUWING: Indien een pad spaties bevat moeten er dubbele quotes worden gezet om het pad. -PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys formaat +PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor een foto te maken.\nOntvangt terminalparameters voor het genereren van pp3's gebaseerd op regels:\n[Pad RAW/JPG] [Pad standaardprofiel] [f-getal] [belichting in sec] [brandpuntsafstand in mm] [ISO] [lens] [Camerafabrikant] [cameramodel]\n\n Let op: Indien een pad spaties bevat moeten er dubbele quotes om het pad worden gezet. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;'Keys'-formaat PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Naam PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID PREFERENCES_CUSTPROFBUILDPATH;Pad naar programma of script @@ -1095,7 +1096,7 @@ PREFERENCES_DARKFRAMEFOUND;Gevonden PREFERENCES_DARKFRAMESHOTS;foto's PREFERENCES_DARKFRAMETEMPLATES;sjablonen PREFERENCES_DATEFORMAT;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_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is \n%d/%m/%y PREFERENCES_DIRDARKFRAMES;Map met donkerframes PREFERENCES_DIRECTORIES;Mappen PREFERENCES_DIRHOME;Standaardmap @@ -1122,9 +1123,9 @@ PREFERENCES_HISTOGRAM_TOOLTIP;Het werkprofiel wordt gebruikt voor het Hoofdhisto PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting PREFERENCES_ICCDIR;Map met ICC-profielen PREFERENCES_IMPROCPARAMS;Standaardprofiel -PREFERENCES_INSPECT_LABEL;Inspecteren -PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum aantal afbeeldingen in cache -PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Het maximum aantal afbeeldingen in de cache wanneer je in de Bestandsnavigator met de cursor over de miniaturen beweegt. Op computers met weinig RAM geheugen (2 Gb) moet deze waarde op 1 of 2 worden gezet. +PREFERENCES_INSPECT_LABEL;Inspecteer +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum aantal afbeeldingen in de cache +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Het maximum aantal afbeeldingen in de cache wanneer je in de Bestandsnavigator met de cursor over de miniaturen beweegt. Op computers met erg weinig RAM-geheugen (2 GB) moet deze waarde op 1 of 2 worden gezet. PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie @@ -1139,32 +1140,32 @@ PREFERENCES_MENUGROUPLABEL;Groepeer labelen PREFERENCES_MENUGROUPPROFILEOPERATIONS;Groepeer profielbewerkingen PREFERENCES_MENUGROUPRANK;Groepeer markering PREFERENCES_MENUOPTIONS;Menu-opties -PREFERENCES_MONINTENT;Standaard monitor weergave +PREFERENCES_MONINTENT;Standaard weergave-intentie monitor PREFERENCES_MONITOR;Monitor PREFERENCES_MONPROFILE;Standaard kleurprofiel -PREFERENCES_MONPROFILE_WARNOSX;Als gevolg van MacOS beperkingen wordt alleen sRGB ondersteund. +PREFERENCES_MONPROFILE_WARNOSX;Als gevolg van beperkingen van macOS wordt alleen sRGB ondersteund. PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor PREFERENCES_NAVIGATIONFRAME;Navigatie PREFERENCES_OVERLAY_FILENAMES;Toon bestandsnamen over miniaturen PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Toon bestandsnaam over miniaturen in het Bewerkingsvenster -PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande output-bestanden +PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande uitvoerbestanden PREFERENCES_PANFACTORLABEL;Factor PREFERENCES_PARSEDEXT;Extensies (verwerkingsvolgorde) PREFERENCES_PARSEDEXTADD;Voeg extensie toe -PREFERENCES_PARSEDEXTADDHINT;Typ nieuwe extensie en druk op knop om aan lijst toe te voegen +PREFERENCES_PARSEDEXTADDHINT;Geef nieuwe extensie op en druk op de knop om aan de lijst toe te voegen PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst PREFERENCES_PARSEDEXTDOWNHINT;Verplaats extensie naar beneden PREFERENCES_PARSEDEXTUPHINT;Verplaats extensie naar boven PREFERENCES_PERFORMANCE_MEASURE;Meting -PREFERENCES_PERFORMANCE_MEASURE_HINT;Log verwerkingstijden in de console +PREFERENCES_PERFORMANCE_MEASURE_HINT;Log de verwerkingstijden in de console PREFERENCES_PERFORMANCE_THREADS;Threads -PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximaal aantal threads voor ruisvermindering and Wavelet Niveaus (0 = Automatisch) -PREFERENCES_PREVDEMO;Voorbeeld Demozaïekmethode +PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximaal aantal threads voor ruisvermindering en Wavelet-niveaus (0 = automatisch) +PREFERENCES_PREVDEMO;Voorbeeld demozaïekmethode PREFERENCES_PREVDEMO_FAST;Snel PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: PREFERENCES_PREVDEMO_SIDECAR;Gelijk aan PP3 -PREFERENCES_PRINTER;Printer (Proefafdruk) +PREFERENCES_PRINTER;Printer (soft-proof) PREFERENCES_PROFILEHANDLING;Verwerking profielen PREFERENCES_PROFILELOADPR;Laadprioriteit profielen PREFERENCES_PROFILEPRCACHE;Profiel in cache @@ -1175,16 +1176,16 @@ PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand PREFERENCES_PROFILESAVELOCATION;Opslaglocatie profielen PREFERENCES_PROFILE_NONE;Geen PREFERENCES_PROPERTY;Eigenschap -PREFERENCES_PRTINTENT;Grafische weergave +PREFERENCES_PRTINTENT;Weergave-intentie PREFERENCES_PRTPROFILE;Kleurprofiel PREFERENCES_PSPATH;Installatiemap Adobe Photoshop -PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom % en pan startpunt -PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Onthoud het zoom % en pan startpunt van de huidige afbeelding als er een nieuwe afbeelding wordt geopend.\n\nDeze optie werkt alleen in "Single Editor Tab Mode" en wanneer "Demozaïekmethode van het voorbeeld <100% zoom" hetzelfde is als "Gelijk aan PP3". +PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom% en pan-startpunt +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Onthoud het zoompercentage en pan-startpunt van de huidige afbeelding als er een nieuwe afbeelding wordt geopend.\n\nDeze optie werkt alleen in Enkeltab-modus en wanneer "Demozaïekmethode van het voorbeeld <100% zoom" hetzelfde is als "Gelijk aan PP3". PREFERENCES_SAVE_TP_OPEN_NOW;Bewaar open/dicht-status van de gereedschappen nu PREFERENCES_SELECTLANG;Selecteer taal -PREFERENCES_SERIALIZE_TIFF_READ;TIFF Lees Instellingen -PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serieel lezen van TIFF bestanden -PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Als een map veel ongecomprimeerde TIFF bestanden bevat dan versnelt deze optie het genereren van de miniaturen. +PREFERENCES_SERIALIZE_TIFF_READ;TIFF-leesinstellingen +PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serieel lezen van TIFF-bestanden +PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Als een map veel ongecomprimeerde TIFF-bestanden bevat dan versnelt deze optie het aanmaken van de miniaturen. PREFERENCES_SET;Activeer PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info PREFERENCES_SHOWDATETIME;Toon datum en tijd @@ -1200,14 +1201,14 @@ PREFERENCES_SND_THRESHOLDSECS;na seconden PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten PREFERENCES_TAB_BROWSER;Bestandsnavigator PREFERENCES_TAB_COLORMGR;Kleurbeheer -PREFERENCES_TAB_DYNAMICPROFILE;Dynamisch Profielregel +PREFERENCES_TAB_DYNAMICPROFILE;Dynamische Profielregel PREFERENCES_TAB_GENERAL;Algemeen PREFERENCES_TAB_IMPROC;Beeldverwerking -PREFERENCES_TAB_PERFORMANCE;Performantie +PREFERENCES_TAB_PERFORMANCE;Prestaties PREFERENCES_TAB_SOUND;Geluiden -PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Ingesloten JPEG voorbeeld +PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Ingesloten JPEG-voorbeeld PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Te tonen foto -PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrale raw rendering +PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrale raw-rendering PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Ingesloten JPEG indien vol formaat, anders neutrale raw PREFERENCES_TP_LABEL;Gereedschapspaneel: PREFERENCES_TP_VSCROLLBAR;Verberg de schuifbalk van het gereedschapspaneel @@ -1218,7 +1219,7 @@ PROFILEPANEL_GLOBALPROFILES;Gebundelde profielen PROFILEPANEL_LABEL;Profielen PROFILEPANEL_LOADDLGLABEL;Kies profiel... PROFILEPANEL_LOADPPASTE;Te laden parameters -PROFILEPANEL_MODE_TOOLTIP;Profiel aanvullen.\n\nKnop ingedrukt: gedeeltelijke profielen worden omgezet naar volledige profielen. De ontbrekende waarden worden vervangen door hard-coded defaults.\n\nKnop neutraal: profielen worden toegepast zo als ze zijn, alleen de aanwezige waarden worden gewijzigd. +PROFILEPANEL_MODE_TOOLTIP;Profiel aanvullen.\n\nKnop ingedrukt: gedeeltelijke profielen worden omgezet naar volledige profielen. De ontbrekende waarden worden vervangen door standaardwaarden.\n\nKnop neutraal: profielen worden toegepast zoals ze zijn, alleen de aanwezige waarden worden gewijzigd. PROFILEPANEL_MYPROFILES;Mijn profielen PROFILEPANEL_PASTEPPASTE;Te plakken parameters PROFILEPANEL_PCUSTOM;Handmatig @@ -1230,13 +1231,13 @@ PROFILEPANEL_SAVEDLGLABEL;Bewaar profiel... PROFILEPANEL_SAVEPPASTE;Te bewaren parameters PROFILEPANEL_TOOLTIPCOPY;Kopieer huidig profiel naar klembord PROFILEPANEL_TOOLTIPLOAD;Laad profiel uit bestand -PROFILEPANEL_TOOLTIPPASTE; Plak profiel van klembord -PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel.\nCtrl-click voor het selecteren van de instellingen voor opslaan. +PROFILEPANEL_TOOLTIPPASTE;Plak profiel van klembord +PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel.\nCtrl+klik voor het selecteren van de instellingen voor opslaan. PROGRESSBAR_DECODING;Decoderen... -PROGRESSBAR_GREENEQUIL;Groen blancering... +PROGRESSBAR_GREENEQUIL;Groenbalancering... PROGRESSBAR_HLREC;Reconstructie hoge lichten... -PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... -PROGRESSBAR_LINEDENOISE;Lijnruis filter... +PROGRESSBAR_HOTDEADPIXELFILTER;Hete/dodepixels-filter... +PROGRESSBAR_LINEDENOISE;Lijnruisfilter... PROGRESSBAR_LOADING;Afbeelding laden... PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... @@ -1245,28 +1246,28 @@ PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... PROGRESSBAR_NOIMAGES;Geen afbeeldingen PROGRESSBAR_PROCESSING;Foto verwerken... PROGRESSBAR_PROCESSING_PROFILESAVED;Uitvoeren 'Profiel opslaan' -PROGRESSBAR_RAWCACORR;Raw CA correctie... +PROGRESSBAR_RAWCACORR;Raw CA-correctie... PROGRESSBAR_READY;Gereed PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... PROGRESSBAR_SNAPSHOT_ADDED;Snapshot toegevoegd -PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in bestandsnavigator +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in Bestandsnavigator QINFO_FRAMECOUNT;%2 frames QINFO_HDR;HDR / %2 frame(s) QINFO_ISO;ISO QINFO_NOEXIF;Exif-gegevens niet beschikbaar. -QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +QINFO_PIXELSHIFT;Pixel-Shift / %2 frame(s) QUEUE_AUTOSTART;Autostart QUEUE_AUTOSTART_TOOLTIP;Start verwerking automatisch wanneer nieuwe foto arriveert QUEUE_DESTFILENAME;Pad en bestandsnaam QUEUE_FORMAT_TITLE;Bestandstype QUEUE_LOCATION_FOLDER;Sla op in map QUEUE_LOCATION_TEMPLATE;Gebruik sjabloon -QUEUE_LOCATION_TEMPLATE_TOOLTIP;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2006/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2006, %d2=foto, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de rank van de foto. Als de foto geen rank heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f +QUEUE_LOCATION_TEMPLATE_TOOLTIP;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2024/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2024, %d2=foto, ...\n%p1=/home/tom/image/02-09-2024, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de waardering van de foto. Als de foto geen waardering heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f QUEUE_LOCATION_TITLE;Uitvoerlocatie -QUEUE_STARTSTOP_TOOLTIP;;Start of stop de verwerking van foto's in de rij.\n\nSneltoets: Ctrl+s -SAMPLEFORMAT_0;onbekend data formaat +QUEUE_STARTSTOP_TOOLTIP;Start of stop de verwerking van foto's in de rij.\n\nSneltoets: Ctrl+S +SAMPLEFORMAT_0;onbekend dataformaat SAMPLEFORMAT_1;8-bit unsigned SAMPLEFORMAT_2;16-bit unsigned SAMPLEFORMAT_4;24-bit LogLuv @@ -1288,7 +1289,7 @@ SAVEDLG_SUBSAMP;Subsampling SAVEDLG_SUBSAMP_1;Beste compressie SAVEDLG_SUBSAMP_2;Gebalanceerd SAVEDLG_SUBSAMP_3;Beste kwaliteit -SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en vertikaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma subsampling. +SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en verticaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma-subsampling. SAVEDLG_TIFFUNCOMPRESSED;Geen compressie SAVEDLG_WARNFILENAME;Bestandsnaam wordt SHCSELECTOR_TOOLTIP;Klik op de rechtermuisknop om\nde 3 knoppen te verschuiven @@ -1297,29 +1298,29 @@ SOFTPROOF_TOOLTIP;Soft-proofing simuleert hoe een foto wordt getoond:\n- als dez THRESHOLDSELECTOR_B;Onderkant THRESHOLDSELECTOR_BL;Onderkant-links THRESHOLDSELECTOR_BR;Onderkant-rechts -THRESHOLDSELECTOR_HINT;Houdt de Shift-toets ingedrukt om individuele controle punten te verschuiven. +THRESHOLDSELECTOR_HINT;Houd de Shift-toets ingedrukt om individuele controlepunten te verschuiven. THRESHOLDSELECTOR_T;Bovenkant THRESHOLDSELECTOR_TL;Bovenkant-links THRESHOLDSELECTOR_TR;Bovenkant-rechts -TOOLBAR_TOOLTIP_COLORPICKER;Vergrendelbare Kleurkiezer\n\nKlik met de linkermuisknop in het voorbeeld om een kleurkiezer toe te voegen\nBeweeg het punt door de linkermuisknop ingedrukt te houden\nVerwijder de kleurkiezer met een rechtermuisknop klik\nVerwijder allle kleurkiezers met Shift + rechtermuisknop klik\nMet een rechtermuisklik naast een kleurkiezer komt het selecteer handje terug. -TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: c -TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: h -TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtmaken / Kleine rotaties.\nSneltoets: s\n\nBepaal de vertikale of horizontale as door het trekken van een hulplijn over de afbeelding. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. -TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: w +TOOLBAR_TOOLTIP_COLORPICKER;Vergrendelbare kleurkiezer\n\nKlik met de linkermuisknop in het voorbeeld om een kleurkiezer toe te voegen\nBeweeg het punt door de linkermuisknop ingedrukt te houden\nVerwijder de kleurkiezer met rechts-klik\nVerwijder alle kleurkiezers met Shift+rechtsklik\nMet een rechtermuisklik naast een kleurkiezer komt het selectiehandje terug. +TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: C +TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: H +TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtzetten/Kleine rotaties.\nSneltoets: S\n\nBepaal de verticale of horizontale as door een hulplijn over de afbeelding te trekken. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. +TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: W TP_BWMIX_ALGO;Algoritme OYCPM TP_BWMIX_ALGO_LI;Lineair TP_BWMIX_ALGO_SP;Speciale effecten -TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire response.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen.TP_BWMIX_AUTOCH;Auto +TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire respons.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen. TP_BWMIX_AUTOCH;Auto TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur -TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM mode. -TP_BWMIX_CHANNEL;Luminantie Balans -TP_BWMIX_CURVEEDITOR1;'Voor' curve -TP_BWMIX_CURVEEDITOR2;'Na' curve -TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Toon curve wordt toegepast na de Zwart-Wit conversie. -TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Toon curve wordt toegepast voor de Zwart-Wit conversie\nHoudt rekening met de kleur componenten. -TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Wijzig luminantie in de functie van hue\nNegatieve waarden kunnen artefacten of onregelmatigheden veroorzaken. -TP_BWMIX_FILTER;Kleur Filter +TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM-modus. +TP_BWMIX_CHANNEL;Luminantiebalans +TP_BWMIX_CURVEEDITOR1;'Voor'-curve +TP_BWMIX_CURVEEDITOR2;'Na'-curve +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tooncurve wordt toegepast na de zwart-witconversie. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tooncurve wordt toegepast voor de zwart-witconversie.\nHoud rekening met de kleurcomponenten. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminantie als functie van tint (L=f(T).\nPas op met extreme waarden, deze kunnen onregelmatigheden veroorzaken. +TP_BWMIX_FILTER;Filterkleur TP_BWMIX_FILTER_BLUE;Blauw TP_BWMIX_FILTER_BLUEGREEN;Blauw-Groen TP_BWMIX_FILTER_GREEN;Groen @@ -1328,56 +1329,56 @@ TP_BWMIX_FILTER_NONE;Geen TP_BWMIX_FILTER_PURPLE;Paars TP_BWMIX_FILTER_RED;Rood TP_BWMIX_FILTER_REDYELLOW;Rood-Geel -TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beïnvloeden de helderheid. Bv. een rood filter maak een blauwe lucht donkerder. +TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beïnvloeden de helderheid. Zo maakt een rood filter een blauwe lucht donkerder. TP_BWMIX_FILTER_YELLOW;Geel -TP_BWMIX_GAMMA;Gamma Correctie -TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB kanaal -TP_BWMIX_LABEL;Zwart-Wit +TP_BWMIX_GAMMA;Gammacorrectie +TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB-kanaal +TP_BWMIX_LABEL;Zwart-wit TP_BWMIX_MET;Methode TP_BWMIX_MET_CHANMIX;Kanaalmixer TP_BWMIX_MET_DESAT;Desatureren -TP_BWMIX_MET_LUMEQUAL;Luminantie Balans -TP_BWMIX_MIXC;Kanaal Mixer +TP_BWMIX_MET_LUMEQUAL;Luminantie-equalizer +TP_BWMIX_MIXC;Kanalenmixer TP_BWMIX_NEUTRAL;Terugzetten TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totaal: %4%% -TP_BWMIX_RGBLABEL_HINT;RGB omrekeningsfactoren. Hierin zijn alle gekozen opties vewerkt.\nTotaal toont de som van de uit te voeren RGB factoren:\n- dit is altijd 100% in relatieve mode\n- hoger (lichter) of lager (donkerder) dan 100% in absolute mode. -TP_BWMIX_RGB_TOOLTIP;Mix de RGB kanalen. Gebruik Voorinstellingen voor aanwijzingen.\nNegatieve waarden kunnen artefacten of onregelmatigheden veroorzaken. +TP_BWMIX_RGBLABEL_HINT;RGB-omrekeningsfactoren. Hierin zijn alle gekozen opties verwerkt.\nTotaal toont de som van de uit te voeren RGB-factoren:\n- dit is altijd 100% in relatieve modus\n- groter (lichter) of kleiner (donkerder) dan 100% in absolute modus. +TP_BWMIX_RGB_TOOLTIP;Mix de RGB-kanalen. Gebruik Voorinstellingen voor aanwijzingen.\nNegatieve waarden kunnen onregelmatigheden veroorzaken. TP_BWMIX_SETTING;Voorinstellingen TP_BWMIX_SETTING_TOOLTIP;Verschillende voorinstellingen (film, landschap, etc.) of handmatige instellingen van de kanaalmixer. -TP_BWMIX_SET_HIGHCONTAST;Hoog Contrast -TP_BWMIX_SET_HIGHSENSIT;Hoge Gevoeligheid -TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatisch +TP_BWMIX_SET_HIGHCONTAST;Hoog contrast +TP_BWMIX_SET_HIGHSENSIT;Hoge gevoeligheid +TP_BWMIX_SET_HYPERPANCHRO;Hyperpanchromatisch TP_BWMIX_SET_INFRARED;Infrarood TP_BWMIX_SET_LANDSCAPE;Landschap -TP_BWMIX_SET_LOWSENSIT;Lage Gevoeligheid +TP_BWMIX_SET_LOWSENSIT;Lage gevoeligheid TP_BWMIX_SET_LUMINANCE;Luminantie -TP_BWMIX_SET_NORMCONTAST;Normaal Contrast +TP_BWMIX_SET_NORMCONTAST;Normaal contrast TP_BWMIX_SET_ORTHOCHRO;Orthochromatisch TP_BWMIX_SET_PANCHRO;Panchromatisch TP_BWMIX_SET_PORTRAIT;Portret -TP_BWMIX_SET_RGBABS;Absolute RGB -TP_BWMIX_SET_RGBREL;Relatieve RGB -TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM -TP_BWMIX_SET_ROYGCBPMREL;Relatieve ROYGCBPM -TP_BWMIX_TCMODE_FILMLIKE;Z&W Film-achtig -TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadiging en Waarde menging +TP_BWMIX_SET_RGBABS;RGB-absoluut +TP_BWMIX_SET_RGBREL;RGB-relatief +TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM-absoluut +TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM-relatief +TP_BWMIX_TCMODE_FILMLIKE;Z-W Filmachtig +TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadiging en Waarde mengen TP_BWMIX_TCMODE_STANDARD;Z-W Standaard -TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen Standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen standaard TP_BWMIX_VAL;L TP_CACORRECTION_BLUE;Blauw -TP_CACORRECTION_LABEL;Corrigeer chromatische aberratie +TP_CACORRECTION_LABEL;Corrigeer chromatische afwijking TP_CACORRECTION_RED;Rood -TP_CBDL_AFT;Na Zwart-Wit -TP_CBDL_BEF;Voor Zwart-Wit +TP_CBDL_AFT;Na zwart-wit +TP_CBDL_BEF;Voor zwart-wit TP_CBDL_METHOD;Uitvoeren -TP_CBDL_METHOD_TOOLTIP;Kies of Detailcontrast moet worden uitgevoerd na de Zwart-Wit bewerking waardoor het werkt in L*a*b*, of voor de Zwart-Wit bewerking waardoor het werkt in RGB +TP_CBDL_METHOD_TOOLTIP;Kies of Detailcontrast moet worden uitgevoerd ná de zwart-witbewerking waardoor het werkt in L*a*b*, of vòòr de zwart-witbewerking waardoor het werkt in RGB TP_CHMIXER_BLUE;Blauw TP_CHMIXER_GREEN;Groen -TP_CHMIXER_LABEL;Kleurkanaal mixer +TP_CHMIXER_LABEL;Kleurkanaalmixer TP_CHMIXER_RED;Rood TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen -TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\n\nSneltoets:\n[ - Multi-tab Mode,\nAlt-[ - Enkel-tab Mode. -TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multi-tab Mode,\nAlt-] - Enkel-tab Mode. +TP_COARSETRAF_TOOLTIP_ROTLEFT;Roteer links.\n\nSneltoets:\n[ - Multitab-modus,\nAlt+[ - Enkeltab-modus. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminantie TP_COLORAPP_ALGO;Algoritme @@ -1386,64 +1387,64 @@ TP_COLORAPP_ALGO_JC;Lichtheid + Chroma (JC) TP_COLORAPP_ALGO_JS;Lichtheid + Verzadiging (JS) TP_COLORAPP_ALGO_QM;Helderheid + Kleurrijkheid (QM) TP_COLORAPP_ALGO_TOOLTIP;Keuze uit parameters -TP_COLORAPP_BADPIXSL;Hete/dode pixel filter -TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0=geen effect 1=mediaan 2=gaussian.\n\nDeze artefacten zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. +TP_COLORAPP_BADPIXSL;Hete/dode-pixelsfilter +TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0 = geen effect 1 = mediaan 2 = gaussiaans.\n\nDeze onregelmatigheden zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. TP_COLORAPP_BRIGHT;Helderheid (Q) TP_COLORAPP_BRIGHT_TOOLTIP;Helderheid in CIECAM02 is verschillend van Lab en RGB, hou rekening met de luminositeit van wit -TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Bij manuele aanpassing worden waardon boven 65 aanbevolen. +TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Bij handmatige aanpassing worden waarden boven 65 aanbevolen. TP_COLORAPP_CHROMA;Chroma (C) TP_COLORAPP_CHROMA_M;Kleurrijkheid (M) TP_COLORAPP_CHROMA_M_TOOLTIP;Kleurrijkheid in CIECAM02 is verschillend van Lab en RGB TP_COLORAPP_CHROMA_S;Verzadiging (S) TP_COLORAPP_CHROMA_S_TOOLTIP;Verzadiging in CIECAM02 is verschillend van Lab en RGB TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CIECAT_DEGREE;CAT02 toepassen +TP_COLORAPP_CIECAT_DEGREE;Chromatische aanpassing Scène TP_COLORAPP_CONTRAST;Contrast (J) TP_COLORAPP_CONTRAST_Q;Contrast (Q) -TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q)in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM02 is verschillend van Lab en RGB TP_COLORAPP_CONTRAST_TOOLTIP;Contrast (J) in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CURVEEDITOR1;Toon curve 1 -TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM wijzigingen.\n\nHet histogram toont J,Q na toepassing van CIECAM, indien het selectievakje 'Toon CIECAM uitvoer' is aangezet.\n(J,Q) worden niet getoond in het hoofd histogram. \n\nRaadpleeg voor de definitieve uitvoer het Histogram paneel. -TP_COLORAPP_CURVEEDITOR2;Toon curve 2 -TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings 'Toon Curve 2'. -TP_COLORAPP_CURVEEDITOR3;Chroma curve -TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het Histogram toont chromaticiteit (Lab) voor CIECAM wijzigingen.\nHet Histogram toont C,s,M na toepassing van CIECAM indien het selectievakje 'Toon CIECAM uitvoer' is aangezet.\n(C,s,M) worden niet getoond in het Hoofd histogram paneel. \nRaadpleeg het Histogram paneel voor de definitieve uitvoer -TP_COLORAPP_DATACIE;CIECAM02 uitvoer histogram in de curven -TP_COLORAPP_DATACIE_TOOLTIP;Indien aangezet, tonen de histogrammen van de CIECAM02 curven bij benadering de waarden/reeksen voor J of Q, en C, s of M na de CIECAM02 aanpassingen.\nDit beïnvloed niet het hoofd histogram paneel.\n\nIndien uitgezet tonen de histogrammen van de CIECAM02 curven de Lab waarden zoals deze waren voor de CIECAM02 aanpassingen -TP_COLORAPP_FREE;Vrije temp+groen + CAT02 + [uitvoer] -TP_COLORAPP_GAMUT;Gamut controle (Lab) +TP_COLORAPP_CURVEEDITOR1;Tooncurve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM-wijzigingen.\n\nHet histogram toont J,Q na toepassing van CIECAM, indien het selectievakje 'Toon CIECAM-uitvoer' is aangezet.\n(J,Q) worden niet getoond in het hoofdhistogram. \n\nZie voor de definitieve uitvoer het Histogrampaneel. +TP_COLORAPP_CURVEEDITOR2;Tooncurve 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings-tooncurve 2. +TP_COLORAPP_CURVEEDITOR3;Chroma-curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. +TP_COLORAPP_DATACIE;CIECAM02 uitvoerhistogram in de curven +TP_COLORAPP_DATACIE_TOOLTIP;Indien aangevinkt tonen de histogrammen van de CIECAM02-curven bij benadering de waarden/reeksen voor J of Q, en C, S of M na de CIECAM02-aanpassingen.\nDit heeft geen invloed op het hoofdhistogram.\n\nIndien uitgevinkt tonen de histogrammen van de CIECAM02-curven de Lab-waarden zoals deze waren voor de CIECAM02-aanpassingen +TP_COLORAPP_FREE;Vrije temp + groen + CAT02 + [uitvoer] +TP_COLORAPP_GAMUT;Beperk kleurbereik (Lab) TP_COLORAPP_HUE;Tint (h) TP_COLORAPP_HUE_TOOLTIP;Tint (h) - hoek tussen 0° en 360° TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen -TP_COLORAPP_LABEL_SCENE;Opnameomstandigheden +TP_COLORAPP_LABEL_SCENE;Scène-omstandigheden TP_COLORAPP_LABEL_VIEWING;Weergaveomstandigheden TP_COLORAPP_LIGHT;Lichtheid (J) -TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB lichtheid +TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB TP_COLORAPP_MEANLUMINANCE;Gemiddelde luminantie (Yb%) -TP_COLORAPP_MODEL;Witpunt Model -TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [uitvoer]:\nRT's WB wordt gebruikt voor de opname, CIECAM02 wordt gezet op D50. Het uitvoerapparaat's wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02] + [output]:\nRT's WB instellingen worden gebruikt door CAT02 en het uitvoerapparaat's wit gebruikt de waarde van de Voorkeuren. +TP_COLORAPP_MODEL;Witpuntmodel +TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. TP_COLORAPP_NEUTRAL;Terugzetten TP_COLORAPP_NEUTRAL_TOOLTIP;Zet alle regelaars, vinkjes en curves terug naar hun standaardwaarde -TP_COLORAPP_RSTPRO;Rode en Huidtinten bescherming -TP_COLORAPP_RSTPRO_TOOLTIP;Rode en Huidtinten bescherming (schuifbalk en curven) +TP_COLORAPP_RSTPRO;Bescherming huid- en rode tinten +TP_COLORAPP_RSTPRO_TOOLTIP;Bescherm huid- en rode tinten (schuifbalk en curven) TP_COLORAPP_SURROUND;Omgeving -TP_COLORAPP_SURROUND_AVER;Gemmiddeld +TP_COLORAPP_SURROUND_AVER;Gemiddeld TP_COLORAPP_SURROUND_DARK;Donker TP_COLORAPP_SURROUND_DIM;Gedimd TP_COLORAPP_SURROUND_EXDARK;Duister -TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden +TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden. TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid TP_COLORAPP_TCMODE_CHROMA;Chroma TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid TP_COLORAPP_TCMODE_LABEL1;Curve modus 1 TP_COLORAPP_TCMODE_LABEL2;Curve modus 2 -TP_COLORAPP_TCMODE_LABEL3;Curve chroma modus -TP_COLORAPP_TCMODE_LIGHTNESS;lichtheid +TP_COLORAPP_TCMODE_LABEL3;Curve chroma-modus +TP_COLORAPP_TCMODE_LIGHTNESS;Lichtheid TP_COLORAPP_TCMODE_SATUR;Verzadiging TP_COLORAPP_TEMP_TOOLTIP;Zet altijd Tint=1 om een lichtbron te selecteren.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 -TP_COLORAPP_TONECIE;Tonemapping gebruik makend van CIECAM -TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgezet zal tonemapping plaats vinden in Lab.\nIndien aangezet zal tonemapping gebruik maken van CIECAM02.\nVoorwaarde is dat Tonemapping (Lab/CIECAM02) actief is. +TP_COLORAPP_TONECIE;Tonemappen met CIECAM +TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgevinkt zal het toonmappen plaatsvinden in Lab.\nIndien aangevinkt zal toonmappen gebruikmaken van CIECAM02.\nVoorwaarde is dat Tonemappen (Lab/CIECAM02) actief is. TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m²) TP_COLORAPP_WBCAM;WB [RT+CAT02] + [uitvoer] TP_COLORAPP_WBRT;WB [RT] + [uitvoer] @@ -1453,14 +1454,14 @@ TP_COLORTONING_BALANCE;Balans TP_COLORTONING_BY;o C/L TP_COLORTONING_CHROMAC;Dekking TP_COLORTONING_COLOR;Kleur -TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma dekking als een functie van Luminantie oC=f(L) +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma-dekking als functie van Luminantie oC=f(L) TP_COLORTONING_HIGHLIGHT;Hoge lichten TP_COLORTONING_HUE;Kleurtint -TP_COLORTONING_LAB;L*a*b* menging +TP_COLORTONING_LAB;L*a*b*-menging TP_COLORTONING_LABEL;Kleurtinten -TP_COLORTONING_LABGRID;L*a*b* kleurcorrectie raster +TP_COLORTONING_LABGRID;L*a*b* kleurcorrectieraster TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 -TP_COLORTONING_LABREGIONS;Kleurcorrectie gebieden +TP_COLORTONING_LABREGIONS;Kleurcorrectiegebieden TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 TP_COLORTONING_LABREGION_CHANNEL;Kanaal TP_COLORTONING_LABREGION_CHANNEL_ALL;Alle @@ -1469,12 +1470,12 @@ TP_COLORTONING_LABREGION_CHANNEL_G;Groen TP_COLORTONING_LABREGION_CHANNEL_R;Rood TP_COLORTONING_LABREGION_CHROMATICITYMASK;C TP_COLORTONING_LABREGION_HUEMASK;H -TP_COLORTONING_LABREGION_LIGHTNESS;Helderheid(L) +TP_COLORTONING_LABREGION_LIGHTNESS;Helderheid (L) TP_COLORTONING_LABREGION_LIGHTNESSMASK;L TP_COLORTONING_LABREGION_LIST_TITLE;Correctie TP_COLORTONING_LABREGION_MASK;Masker TP_COLORTONING_LABREGION_MASKBLUR;Verzachtingsmasker -TP_COLORTONING_LABREGION_OFFSET;Offset +TP_COLORTONING_LABREGION_OFFSET;Verschuiving TP_COLORTONING_LABREGION_POWER;Kracht TP_COLORTONING_LABREGION_SATURATION;Verzadiging TP_COLORTONING_LABREGION_SHOWMASK;Toon masker @@ -1483,26 +1484,26 @@ TP_COLORTONING_LUMA;Luminantie TP_COLORTONING_LUMAMODE;Behoud luminantie TP_COLORTONING_LUMAMODE_TOOLTIP;Wanneer de kleur wijzigt (rood, groen, cyaan, blauw, etc.) blijft de luminatie van elke pixel behouden. TP_COLORTONING_METHOD;Methode -TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* menging", "RGB schuifbalk" en "RGB curven" gebruiken interpolatie kleurmenging.\n"Kleurbalans" (Schaduwen/Midden tonen/Hoge lichten) en "Verzadigen 2 kleuren" gebruiken directe kleuren.\nAlle methodes werken ook op Zwart-Wit. -TP_COLORTONING_MIDTONES;Midden tonen +TP_COLORTONING_METHOD_TOOLTIP;L*a*b*-menging, RGB-schuifbalken en RGB-curven gebruiken geïnterpoleerde kleurmenging.\nKleurbalans SMH en Verzadiging twee kleuren gebruiken directe kleuren.\nAlle methodes werken ook met zwart-wit. +TP_COLORTONING_MIDTONES;Middentonen TP_COLORTONING_NEUTRAL;Terug naar beginstand -TP_COLORTONING_NEUTRAL_TOOLTIP;Zet alle waarden (Schaduwen, Midden tonen, Hoge lichten) terug naar default. +TP_COLORTONING_NEUTRAL_TOOLTIP;Zet alle waarden (schaduwen, middentonen, hoge lichten) terug naar hun standaardwaarden. TP_COLORTONING_OPACITY;Dekking TP_COLORTONING_RGBCURVES;RGB - Curven TP_COLORTONING_RGBSLIDERS;RGB - Schuifbalken -TP_COLORTONING_SA;Verzadiging bescherming +TP_COLORTONING_SA;Bescherm verzadiging TP_COLORTONING_SATURATEDOPACITY;Sterkte TP_COLORTONING_SATURATIONTHRESHOLD;Drempel TP_COLORTONING_SHADOWS;Schaduwen -TP_COLORTONING_SPLITCO;Schaduwen/Midden tonen/Hoge lichten +TP_COLORTONING_SPLITCO;Schaduwen/Middentonen/Hoge lichten TP_COLORTONING_SPLITCOCO;Kleurbalans SMH -TP_COLORTONING_SPLITLR;Verzadiging 2 kleuren +TP_COLORTONING_SPLITLR;Verzadiging twee kleuren TP_COLORTONING_STR;Sterkte TP_COLORTONING_STRENGTH;Sterkte -TP_COLORTONING_TWO2;Speciaal chroma '2 kleuren' +TP_COLORTONING_TWO2;Speciaal chroma twee kleuren TP_COLORTONING_TWOALL;Speciaal chroma TP_COLORTONING_TWOBY;Speciaal a* en b* -TP_COLORTONING_TWOCOLOR_TOOLTIP;Standaard chroma:\nLineaire response, a* = b*.\n\nSpeciaal chroma:\nLineaire response, a* = b*, maar zonder begrenzing - probeer beneden de diagonaal.\n\nSpeciaal a* en b*:\nLineaire response zonder begrenzing met aparte curves voor a* en b*. Bedoeld voor speciale effecten.\n\nSpeciaal chroma 2 kleuren: meest voorspelbare uitkomst. +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standaard chroma:\nLineaire respons, a* = b*.\n\nSpeciaal chroma:\nLineaire respons, a* = b*, maar ontbonden - gebruik de diagonaal hieronder.\n\nSpeciaal a* en b*:\nLineair ontbonden respons met aparte curves voor a* en b*. Bedoeld voor speciale effecten.\n\nSpeciaal chroma twee kleuren: beter voorspelbaar. TP_COLORTONING_TWOSTD;Standaard chroma TP_CROP_FIXRATIO;Verhouding: TP_CROP_GTDIAGONALS;Diagonaalmethode @@ -1529,79 +1530,79 @@ TP_DEFRINGE_LABEL;Verzachten (Lab/CIECAM02) TP_DEFRINGE_RADIUS;Straal TP_DEFRINGE_THRESHOLD;Drempel TP_DEHAZE_DEPTH;Diepte -TP_DEHAZE_LABEL;Nevel vermindering -TP_DEHAZE_SHOW_DEPTH_MAP;Toon de dieptemap +TP_DEHAZE_LABEL;Nevelvermindering +TP_DEHAZE_SHOW_DEPTH_MAP;Toon dieptemap TP_DEHAZE_STRENGTH;Sterkte TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zone TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatisch algemeen TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Chrominantie Blauw & Geel -TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Chrominantie curve -TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Verhoog (vermenigvuldig) de waarde van alle chrominantie regelaars.\nDeze curve regelt de sterkte van de chromatische ruisvermindering als een functie van de chromaticiteit, om bijvoorbeeld het effect te vergroten in gebieden met lage verzadiging en te verminderen in deze met lage verzadiging. +TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Chrominantie-curve +TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Verhoog (vermenigvuldig) de waarde van alle chrominantieschuiven.\nDeze curve regelt de sterkte van de chromatische ruisvermindering als een functie van de chromaticiteit, om bijvoorbeeld het effect te verhogen in gebieden met weinig verzadiging en te verlagen in gebieden met veel verzadiging. TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominantie TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Handmatig TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Chrominantie (master) -TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Auto methode -TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\n9 gebieden worden gebruikt om de chroma ruisonderdrukking te bepalen.\n\nVoorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma ruisonderdrukking te bepalen. -TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\n9 gebieden worden gebruikt om de chroma ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de "Voorbeeld" methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Auto-methode +TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nVoorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de Voorbeeld-methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma-ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Voorbeeld multi-zone TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Voorbeeld -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Toont de overgebleven ruisniveaus van het zichtbare deel van de afbeelding in het voorbeeld na wavelet.\n\n>300 Veel ruis\n100-300 Gemiddeld ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB en L*a*b* mode. De RGB waarden zijn minder accuraat omdat de RGB mode luminantie en chrominantie niet volledig scheidt. +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Toont de overgebleven ruisniveaus van het zichtbare deel van de afbeelding in het voorbeeld na Wavelet.\n\n>300 Veel ruis\n100-300 Gemiddelde ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB- en L*a*b*-modus. De RGB-waarden zijn minder accuraat omdat de RGB-modus luminantie en chrominantie niet volledig scheidt. TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Voorbeeld grootte=%1, Centrum: Px=%2 Py=%3 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Voorbeeld ruis: Gemiddeld=%1 Hoog=%2 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Voorbeeld ruis: Gemiddeld= - Hoog= - -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Tegel grootte=%1, Centrum: Tx=%2 Ty=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Tegelgrootte=%1, Centrum: Tx=%2 Ty=%3 TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Chrominantie Rood & Groen TP_DIRPYRDENOISE_LABEL;Ruisvermindering TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Type gereedschap -TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminantie curve -TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminantie Detail +TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminantie-curve +TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminantie-detail TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminantie TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminantie TP_DIRPYRDENOISE_MAIN_COLORSPACE;Methode TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB -TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Voor raw afbeeldingen kan RGB of Lab methode worden gebruikt.\n\nVoor niet-raw afbeeldingen zal altijd de Lab methode worden gebruikt, ongeacht de geselecteerde methode. +TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Voor RAW-afbeeldingen kan de RGB- of Lab-methode worden gebruikt.\n\nVoor niet-RAW-afbeeldingen zal altijd de Lab-methode worden gebruikt, ongeacht de geselecteerde methode. TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma -TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten +TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten. TP_DIRPYRDENOISE_MAIN_MODE;Kwaliteit TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Hoog TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Standaard TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;De kwaliteit kan worden aangepast aan de hoeveelheid ruis. \nHoog verbetert de ruisonderdrukking, maar verlengt de verwerkingstijd TP_DIRPYRDENOISE_MEDIAN_METHOD;Methode -TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Alleen chroma +TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Alleen Chroma TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* -TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Mediaan filter +TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Mediaan-filter TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Alleen Luminantie TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB -TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;De "Alleen Luminantie" en "L*a*b*" methodes worden meteen na de wavelet stap uitgevoerd bij het onderdrukken van ruis.\nDe "RGB" methode, wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. +TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;De Alleen Luminantie- en L*a*b*-methodes worden meteen na de Wavelet-stap uitgevoerd bij het onderdrukken van ruis.\nDe RGB-methode wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Gewogen L* (weinig) + a*b* (normaal) -TP_DIRPYRDENOISE_MEDIAN_PASSES;Mediaan herhalingen -TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Het gebruik van drie mediaan filter herhalingen met een 3×3 venster grootte geeft meestal een beter resultaat dan het gebruik van één mediaan filter herhaling met eeen 7×7 venster grootte. +TP_DIRPYRDENOISE_MEDIAN_PASSES;Mediaan-herhalingen +TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Het gebruik van drie mediaanfilter-herhalingen met een 3×3 venstergrootte geeft meestal een beter resultaat dan het gebruik van één mediaanfilter-herhaling met een 7×7 venstergrootte. TP_DIRPYRDENOISE_MEDIAN_TYPE;Type -TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Gebruik een mediaan filter van gewenste venster grootte. Hoe groter het venster hoe langer het duurt.\n\n3×3 zacht: behandeld 5 pixels in een 3×3 pixel venster.\n3×3: behandeld 9 pixels in een 3×3 pixel venster.\n5×5 zacht: behandeld 13 pixels in een 5×5 pixel venster.\n5×5: behandeld 25 pixels in een 5×5 pixel venster.\n7×7: behandeld 49 pixels in een 7×7 pixel venster.\n9×9: behandeld 81 pixels in a 9×9 pixel venster.\n\nSoms is het mogelijk om een betere kwaliteit te krijgen door het uitvoeren van meerdere herhalingen met een kleiner venster dan één uitvoering met een groter venster. +TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Gebruik een mediaanfilter van gewenste venstergrootte. Hoe groter het venster hoe langer het duurt.\n\n3×3 zacht: behandelt 5 pixels in een 3×3 pixelvenster.\n3×3: behandelt 9 pixels in een 3×3 pixelvenster.\n5×5 zacht: behandelt 13 pixels in een 5×5 pixelvenster.\n5×5: behandelt 25 pixels in een 5×5 pixelvenster.\n7×7: behandelt 49 pixels in een 7×7 pixelvenster.\n9×9: behandelt 81 pixels in een 9×9 pixelvenster.\n\nSoms is het mogelijk om een betere kwaliteit te krijgen door het uitvoeren van meerdere herhalingen met een kleiner venster dan één uitvoering met een groter venster. TP_DIRPYRDENOISE_TYPE_3X3;3×3 TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 zacht TP_DIRPYRDENOISE_TYPE_5X5;5×5 TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 zacht TP_DIRPYRDENOISE_TYPE_7X7;7×7 TP_DIRPYRDENOISE_TYPE_9X9;9×9 -TP_DIRPYREQUALIZER_ALGO;Algoritme Huid -TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de kleuren van de huid, minimaliseert de actie op andere kleuren\nGroot: vermijd artefacten -TP_DIRPYREQUALIZER_ARTIF;Verminder artefacten +TP_DIRPYREQUALIZER_ALGO;Huid-algoritme +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de huidskleuren, minimaliseert de actie op andere kleuren\nGroot: vermijd onregelmatigheden +TP_DIRPYREQUALIZER_ARTIF;Verminder onregelmatigheden TP_DIRPYREQUALIZER_HUESKIN;Huidtint -TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitie zone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigzins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitiezone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigszins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) TP_DIRPYREQUALIZER_LUMACOARSEST;grofste -TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast- -TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+ +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;< Contrast +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast > TP_DIRPYREQUALIZER_LUMAFINEST;fijnste TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutraal TP_DIRPYREQUALIZER_SKIN;Huidtinten Wijzigen/Beschermen -TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Bij -100 huidtinten worden gewijzigd.\nBij 0 alle tinten worden gelijk behandeld.\nBij +100 huidtinten worden beschermd en alle andere tinten worden gewijzigd +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Bij -100 worden huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd en alle andere tinten worden gewijzigd TP_DIRPYREQUALIZER_THRESHOLD;Drempel -TP_DIRPYREQUALIZER_TOOLTIP;Probeert artefacten te verminderen die het gevolg zijn van kleurverschuiving van de huidtinten(hue, chroma, luma) en de rest van de afbeelding +TP_DIRPYREQUALIZER_TOOLTIP;Probeer onregelmatigheden te verminderen die het gevolg zijn van een kleurverschuiving van de huidtinten (tint, chroma, luma) en de rest van de afbeelding TP_DISTORTION_AMOUNT;Hoeveelheid -TP_DISTORTION_AUTO_TOOLTIP;Corrigeert automatisch lens afwijkingen in raw afbeeldingen op basis van de ingebedde JPEG indien deze is gecorrigeerd door de camera. +TP_DISTORTION_AUTO_TOOLTIP;Corrigeert automatisch lensafwijkingen in RAW-afbeeldingen op basis van de ingebedde JPEG indien deze is gecorrigeerd door de camera. TP_DISTORTION_LABEL;Corrigeer lensvervorming TP_EPD_EDGESTOPPING;Randen TP_EPD_GAMMA;Gamma @@ -1613,42 +1614,42 @@ TP_EXPOSURE_AUTOLEVELS;Autom. niveaus TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Activeer automatische niveaus\nActiveer Herstel Hoge lichten indien nodig. TP_EXPOSURE_BLACKLEVEL;Schaduwen TP_EXPOSURE_BRIGHTNESS;Helderheid -TP_EXPOSURE_CLAMPOOG;Knip kleuren die buiten het gamma vallen -TP_EXPOSURE_CLIP;Clip % +TP_EXPOSURE_CLAMPOOG;Kap kleuren die buiten het gamma vallen af +TP_EXPOSURE_CLIP;Afkap % TP_EXPOSURE_CLIP_TOOLTIP;Het deel van de pixels dat moet worden hersteld bij gebruik van automatische niveaus. -TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten Comprimeren -TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel Hoge lichten Comprimeren +TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel compressie hoge lichten TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie TP_EXPOSURE_CONTRAST;Contrast TP_EXPOSURE_CURVEEDITOR;Tooncurve -TP_EXPOSURE_CURVEEDITOR1;Toon curve 1 -TP_EXPOSURE_CURVEEDITOR2;Toon curve 2 +TP_EXPOSURE_CURVEEDITOR1;Tooncurve 1 +TP_EXPOSURE_CURVEEDITOR2;Tooncurve 2 TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\n The Toolbox > Exposure Tab > Exposure Panel > Tone Curve TP_EXPOSURE_EXPCOMP;Belichtingscompensatie -TP_EXPOSURE_HISTMATCHING;Automatische Tooncurve -TP_EXPOSURE_HISTMATCHING_TOOLTIP;Pas automatisch de curves en schuifregelaars aan (behalve belichtingscompensatie) om overeen te komen met de ingesloten JPEG miniatuur. +TP_EXPOSURE_HISTMATCHING;Automatische tooncurve +TP_EXPOSURE_HISTMATCHING_TOOLTIP;Pas automatisch de curves en schuifregelaars aan (behalve belichtingscompensatie) volgens de in de RAW ingebedde JPEG-afbeelding. TP_EXPOSURE_LABEL;Belichting TP_EXPOSURE_SATURATION;Verzadiging -TP_EXPOSURE_TCMODE_FILMLIKE;Film-achtig +TP_EXPOSURE_TCMODE_FILMLIKE;Filmachtig TP_EXPOSURE_TCMODE_LABEL1;Curve modus 1 TP_EXPOSURE_TCMODE_LABEL2;Curve modus 2 TP_EXPOSURE_TCMODE_LUMINANCE;Luminantie TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptueel TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Verzadiging en Waarde mengen TP_EXPOSURE_TCMODE_STANDARD;Standaard -TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen Standaard -TP_EXPOS_BLACKPOINT_LABEL;Raw Zwartpunten -TP_EXPOS_WHITEPOINT_LABEL;Raw Witpunten -TP_FILMNEGATIVE_BLUE;Blauw verhouding -TP_FILMNEGATIVE_GREEN;Referentie exponent (contrast) -TP_FILMNEGATIVE_GUESS_TOOLTIP;Zet automatisch de rood/groen verhouding door 2 gebieden te kiezen met een neutrale tint (geen kleur) in het origineel. De gebieden moeten verschillen in helderheid. Zet de witbalans nadien. -TP_FILMNEGATIVE_LABEL;Film Negatief +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen standaard +TP_EXPOS_BLACKPOINT_LABEL;Raw-zwartpunten +TP_EXPOS_WHITEPOINT_LABEL;Raw-witpunten +TP_FILMNEGATIVE_BLUE;Blauw-verhouding +TP_FILMNEGATIVE_GREEN;Referentie-exponent (contrast) +TP_FILMNEGATIVE_GUESS_TOOLTIP;Bepaal automatisch de rood/groen-verhouding door twee gebieden te kiezen met een neutrale tint (geen kleur) in het origineel. De gebieden moeten verschillen in helderheid. Kies de witbalans nadien. +TP_FILMNEGATIVE_LABEL;Filmnegatief TP_FILMNEGATIVE_PICK;Kies neutrale punten -TP_FILMNEGATIVE_RED;Rood verhouding -TP_FILMSIMULATION_LABEL;Film Simuleren -TP_FILMSIMULATION_SLOWPARSEDIR;Map met Hald CLUT afbeeldingen. Deze worden gebruikt voor Film Simuleren.\nGa naar Voorkeuren > Beeldverwerking > Film Simuleren\nDe aanbeveling is om een map te gebruiken die alleen Hald CLUT afbeeldingen bevat.\n\nLees het Film Simuleren artikel in RawPedia voor meer informatie.\n\nWilt u de scan afbreken? +TP_FILMNEGATIVE_RED;Rood-verhouding +TP_FILMSIMULATION_LABEL;Filmsimulatie +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee zoekt naar HaldCLUT-afbeeldingen om de Filmsimulatie uit te voeren, maar deze bevinden zich in een map die teveel tijd kost om te lezen.\n Kijk bij Voorkeuren > Beeldverwerking > Filmsimulatie om te zien welke map gebruikt wordt\nAanbevolen wordt om een map te gebruiken die alleen HaldCLUT-afbeeldingen bevat of kies een lege folder als u Filmsimulatie niet wilt gebruiken.\n\nMeer informatie is te vinden in het (Engelstalige) artikel over Filmsimulatie op RawPedia.\n\nWilt u de scan nu afbreken? TP_FILMSIMULATION_STRENGTH;Sterkte -TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT map in Voorkeuren +TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT-map in Voorkeuren TP_FLATFIELD_AUTOSELECT;Automatische selectie TP_FLATFIELD_BLURRADIUS;Verzachten: straal TP_FLATFIELD_BLURTYPE;Verzachten: type @@ -1656,8 +1657,8 @@ TP_FLATFIELD_BT_AREA;Gebied TP_FLATFIELD_BT_HORIZONTAL;Horizontaal TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. TP_FLATFIELD_BT_VERTICAL;Verticaal -TP_FLATFIELD_CLIPCONTROL;Clip controle -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip controle vermijd geclipte hoge lichten veroorzaakt door het toepassen van vlakveld. Als er al geclipte hoge lichten waren voor het toepassen van vlakveld dan kan clip controle kleurzweem veroorzaken. +TP_FLATFIELD_CLIPCONTROL;Afkapcontrole +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Afkapcontrole vermijdt uitgevreten hoge lichten veroorzaakt door het toepassen van een vlakveld. Als er al uitgevreten hoge lichten waren voor het toepassen van het vlakveld, dan kan afkapcontrole kleurzweem veroorzaken. TP_FLATFIELD_LABEL;Vlakveld TP_GENERAL_11SCALE_TOOLTIP;De werking is alleen zichtbaar op schaal 1:1 van het voorbeeld TP_GRADIENT_CENTER;Centrum @@ -1666,17 +1667,17 @@ TP_GRADIENT_CENTER_X_TOOLTIP;Rotatiepunt X-as: \n-100=linkerkant \n0=centrum \n+ TP_GRADIENT_CENTER_Y;Centrum Y TP_GRADIENT_CENTER_Y_TOOLTIP;Rotatiepunt Y-as: \n-100=bovenkant \n0=centrum \n+100=onderkant TP_GRADIENT_DEGREE;Hoek -TP_GRADIENT_DEGREE_TOOLTIP;Rotatie hoek in graden +TP_GRADIENT_DEGREE_TOOLTIP;Rotatiehoek in graden TP_GRADIENT_FEATHER;Verloop TP_GRADIENT_FEATHER_TOOLTIP;Verloop als percentage van de afbeeldingsdiagonaal -TP_GRADIENT_LABEL;Grijsverloop Filter +TP_GRADIENT_LABEL;Grijsverloopfilter TP_GRADIENT_STRENGTH;Sterkte TP_GRADIENT_STRENGTH_TOOLTIP;Filtersterkte in stops TP_HLREC_BLEND;Mengen -TP_HLREC_CIELAB;CIELab-blending +TP_HLREC_CIELAB;CIELab-menging TP_HLREC_COLOR;Kleurherstel TP_HLREC_ENA_TOOLTIP;Kan worden geactiveerd door automatische niveaus -TP_HLREC_LABEL;Hoge lichten Herstellen +TP_HLREC_LABEL;Hoge lichten herstellen TP_HLREC_LUMINANCE;Lichtherstel TP_HLREC_METHOD;Methode: TP_HSVEQUALIZER_CHANNEL;HSV-balans @@ -1684,20 +1685,20 @@ TP_HSVEQUALIZER_HUE;Tint TP_HSVEQUALIZER_LABEL;HSV-balans TP_HSVEQUALIZER_SAT;Verzadiging TP_HSVEQUALIZER_VAL;Waarde -TP_ICM_APPLYBASELINEEXPOSUREOFFSET;DCP basis belichting -TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebedde DCP basis belichting. De instelling is allen actief als de DCP een basis belichting heeft. -TP_ICM_APPLYHUESATMAP;DCP basis tabel -TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP basis tabel (HueSatMap). De instelling is allen actief als de DCP een basis tabel heeft. -TP_ICM_APPLYLOOKTABLE;DCP 'look' tabel -TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP 'look' tabel. De instelling is allen actief als de DCP een looktable heeft. -TP_ICM_BPC;Zwartpunt Compensatie +TP_ICM_APPLYBASELINEEXPOSUREOFFSET;DCP-basisbelichting +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebedde DCP-basisbelichting. De instelling is alleen actief als de DCP een basisbelichting heeft. +TP_ICM_APPLYHUESATMAP;DCP-basistabel +TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP-basistabel (HueSatMap). De instelling is alleen actief als de DCP een basistabel heeft. +TP_ICM_APPLYLOOKTABLE;DCP-look-tabel +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP-look-tabel. De instelling is alleen actief als de DCP een look-tabel heeft. +TP_ICM_BPC;Zwartpuntcompensatie TP_ICM_DCPILLUMINANT;Illuminant TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren -TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP illuminant moet worden gebruikt. Standaard is dit "interpoleren". Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. +TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. TP_ICM_INPUTCAMERA;Camera standaard TP_ICM_INPUTCAMERAICC;Camera-specifiek kleurprofiel -TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-kleurprofiel dat preciezer is dan een eenvoudige matrix. Beschikbaar voor sommige camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en worden automatisch opgehaald gebaseerd op de exacte overeenkomst van bestandsnaam met de modelnaam van de camera. -TP_ICM_INPUTCAMERA_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_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-invoerkleurprofielen. Deze zijn preciezer dan een eenvoudige matrix maar niet beschikbaar voor alle camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en /dccprofiles en worden automatisch geladen gebaseerd op een bestandsnaam die exact overeenkomt met de modelnaam van de camera. +TP_ICM_INPUTCAMERA_TOOLTIP;Gebruik een eenvoudige kleurenmatrix van dcraw, een 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... @@ -1709,16 +1710,16 @@ TP_ICM_INPUTPROFILE;Invoerprofiel TP_ICM_LABEL;Kleurbeheer TP_ICM_NOICM;Geen ICM: sRGB-uitvoer TP_ICM_OUTPUTPROFILE;Uitvoerprofiel -TP_ICM_PROFILEINTENT;Grafische weergave -TP_ICM_SAVEREFERENCE;Bewaar Referentie Afbeelding +TP_ICM_PROFILEINTENT;Weergave-intentie +TP_ICM_SAVEREFERENCE;Bewaar referentie-afbeelding TP_ICM_SAVEREFERENCE_APPLYWB;Toepassen witbalans -TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Gebruik witbalans bij het opslaan van afbeeldingen voor het maken van ICC profielen. Gebruik geen witbalans bij het maken van DCP profielen. -TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF afbeelding op voordat het invoer profiel is toegepast. Het resultaat kan worden gebruikt voor calibratie en het genereren van een camera profiel. -TP_ICM_TONECURVE;Gebruik DCP's toon curve -TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP toon curve. De instelling is alleen actief als de geselecteerd DCP een toon curve heeft. +TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Gebruik witbalans bij het opslaan van afbeeldingen voor het maken van ICC-profielen. Gebruik geen witbalans bij het maken van DCP-profielen. +TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF-afbeelding op voordat het invoerprofiel is toegepast. Het resultaat kan worden gebruikt voor kalibratie en het genereren van een cameraprofiel. +TP_ICM_TONECURVE;Gebruik DCP-tooncurve +TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP-tooncurve. De instelling is alleen actief als de geselecteerde DCP een tooncurve bevat. TP_ICM_WORKINGPROFILE;Werkprofiel TP_ICM_WORKING_TRC;Tooncurve: -TP_ICM_WORKING_TRC_CUSTOM;Gebruiker gedefinieerd +TP_ICM_WORKING_TRC_CUSTOM;Door gebruiker gedefinieerd TP_ICM_WORKING_TRC_GAMMA;Gamma TP_ICM_WORKING_TRC_NONE;Geen TP_ICM_WORKING_TRC_SLOPE;Helling @@ -1726,10 +1727,10 @@ TP_ICM_WORKING_TRC_TOOLTIP;Enkel voor ingebouwde profielen. TP_IMPULSEDENOISE_LABEL;Spot-ruisonderdrukking TP_IMPULSEDENOISE_THRESH;Drempel TP_LABCURVE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Plaats de kleuren in het gamut van de kleurruimte van het werkprofiel\nen pas Munsell correctie toe +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Plaats de kleuren in het bereik van de kleurruimte van het werkprofiel\nen pas Munsell-correctie toe TP_LABCURVE_BRIGHTNESS;Helderheid TP_LABCURVE_CHROMATICITY;Chromaticiteit -TP_LABCURVE_CHROMA_TOOLTIP;Voor Z-W tonen, zet Chromaticiteit op -100 +TP_LABCURVE_CHROMA_TOOLTIP;Voor zwartwit, zet Chromaticiteit op -100 TP_LABCURVE_CONTRAST;Contrast TP_LABCURVE_CURVEEDITOR;Luminantiecurve TP_LABCURVE_CURVEEDITOR_A_RANGE1;Groen verzadigd @@ -1742,44 +1743,44 @@ TP_LABCURVE_CURVEEDITOR_B_RANGE3;Geel pastel TP_LABCURVE_CURVEEDITOR_B_RANGE4;Geel verzadigd TP_LABCURVE_CURVEEDITOR_CC;CC TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutraal -TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Saai +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Slap TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Verzadigd -TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticiteit volgens chromaticeit C=f(C) +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticiteit volgens Chromaticiteit C=f(C) TP_LABCURVE_CURVEEDITOR_CH;CH -TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticiteit volgens Tint C=f(H) +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticiteit volgens Tint C=f(T) TP_LABCURVE_CURVEEDITOR_CL;CL TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticiteit volgens Luminantie C=f(L) TP_LABCURVE_CURVEEDITOR_HH;HH -TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue volgens hue H=f(H) +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue volgens Tint H=f(T) TP_LABCURVE_CURVEEDITOR_LC;LC -TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminantie volgens chromaticiteit L=f(C) +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminantie volgens Chromaticiteit L=f(C) TP_LABCURVE_CURVEEDITOR_LH;LH -TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens hue L=f(H) -TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens luminantie L=f(L) +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens Tint L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens Luminantie L=f(L) TP_LABCURVE_LABEL;Lab -TP_LABCURVE_LCREDSK;Beperkt LC tot Rode en Huidtinten -TP_LABCURVE_LCREDSK_TOOLTIP;Indien ingeschakeld, beïnvloed de LC Curve alleen rode en huidtinten\nIndien uitgeschakeld, is het van toepassing op all tinten -TP_LABCURVE_RSTPROTECTION;Rode en huidtinten Bescherming -TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits schuifbalk en de CC curve. +TP_LABCURVE_LCREDSK;Beperk LC tot huid- en rode tinten +TP_LABCURVE_LCREDSK_TOOLTIP;Indien ingeschakeld beïnvloedt de LC-curve alleen huid- en rode tinten.\nIndien uitgeschakeld is het van toepassing op alle tinten. +TP_LABCURVE_RSTPROTECTION;Bescherming huid- en rode tinten +TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits-schuifbalk en de CC-curve. TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden TP_LENSGEOM_FILL;Automatisch uitvullen TP_LENSGEOM_LABEL;Objectief / Geometrie TP_LENSGEOM_LIN;Lineair TP_LENSGEOM_LOG;Logarithmisch TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatische selectie -TP_LENSPROFILE_CORRECTION_LCPFILE;LCP bestand -TP_LENSPROFILE_CORRECTION_MANUAL;Manuele selectie -TP_LENSPROFILE_LABEL;Lenscorrectie Profielen -TP_LENSPROFILE_LENS_WARNING;Waarschuwing: de gebruikte lens profiel crop factor komt niet overeen met de camera crop factor, de resultaten kunnen verkeerd zijn. -TP_LENSPROFILE_MODE_HEADER;Lens Profiel +TP_LENSPROFILE_CORRECTION_LCPFILE;LCP-bestand +TP_LENSPROFILE_CORRECTION_MANUAL;Handmatige selectie +TP_LENSPROFILE_LABEL;Lenscorrectieprofielen +TP_LENSPROFILE_LENS_WARNING;Waarschuwing: de gebruikte bijsnijdfactor van het lensprofiel komt niet overeen met de bijsnijdfactor van de camera, de resultaten kunnen onjuist zijn. +TP_LENSPROFILE_MODE_HEADER;Lensprofiel TP_LENSPROFILE_USE_CA;Chromatische afwijking TP_LENSPROFILE_USE_GEOMETRIC;Geometrische vervorming TP_LENSPROFILE_USE_HEADER;Lenscorrecties TP_LENSPROFILE_USE_VIGNETTING;Vignettering TP_LOCALCONTRAST_AMOUNT;Hoeveelheid TP_LOCALCONTRAST_DARKNESS;Donker niveau -TP_LOCALCONTRAST_LABEL;Lokaal Contrast +TP_LOCALCONTRAST_LABEL;Lokaal contrast TP_LOCALCONTRAST_LIGHTNESS;helderheidsniveau TP_LOCALCONTRAST_RADIUS;Straal TP_METADATA_EDIT;Pas wijzigingen toe @@ -1790,7 +1791,7 @@ TP_NEUTRAL;Terugzetten TP_NEUTRAL_TOOLTIP;Alle belichtingsinstellingen naar 0 TP_PCVIGNETTE_FEATHER;Straal TP_PCVIGNETTE_FEATHER_TOOLTIP;Straal: \n0=alleen hoeken \n50=halverwege tot het centrum \n100=tot aan het centrum -TP_PCVIGNETTE_LABEL;Vignettering Filter +TP_PCVIGNETTE_LABEL;Vignetteringsfilter TP_PCVIGNETTE_ROUNDNESS;Vorm TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Vorm: \n0=rechthoek \n50=ellips \n100=circel TP_PCVIGNETTE_STRENGTH;Sterkte @@ -1801,10 +1802,10 @@ TP_PERSPECTIVE_LABEL;Perspectief TP_PERSPECTIVE_VERTICAL;Verticaal TP_PFCURVE_CURVEEDITOR_CH;Tint TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Bepaalt de mate van verzachten per kleur. Hoger = meer, lager = minder. -TP_PREPROCESS_DEADPIXFILT;Dode pixels filter +TP_PREPROCESS_DEADPIXFILT;Dodepixels-filter TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Onderdrukt dode pixels. TP_PREPROCESS_GREENEQUIL;Groenbalans -TP_PREPROCESS_HOTPIXFILT;Hete pixels filter +TP_PREPROCESS_HOTPIXFILT;Hetepixels-filter TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Onderdrukt hete pixels. TP_PREPROCESS_LABEL;Voorbewerking TP_PREPROCESS_LINEDENOISE;Lijnruisfilter @@ -1814,16 +1815,16 @@ TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontaal TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontaal enkel op PDAF-rijen TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Verticaal TP_PREPROCESS_NO_FOUND;Niet gevonden -TP_PREPROCESS_PDAFLINESFILTER;PDAF lijnfilter +TP_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter TP_PRSHARPENING_LABEL;Verscherp na verkleinen -TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen actief is en Verkleinen methode 'Lanczos' is. Omdat 'verkleinen' geen effect heeft op het voorbeeld, heeft 'post verkleinen verscherping' ook geen effect op het voorbeeld. +TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen actief is en de methode 'Lanczos' is. Omdat verkleinen geen effect heeft op het voorbeeld, heeft 'post-verkleinen verscherping' ook geen effect op het voorbeeld. TP_RAWCACORR_AUTO;Automatische CA-correctie TP_RAWCACORR_AUTOIT;Herhalingen -TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische aberratie.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. +TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische afwijkingen.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. TP_RAWCACORR_AVOIDCOLORSHIFT;Vermijd kleurverschuiving TP_RAWCACORR_CABLUE;Blauw TP_RAWCACORR_CARED;Rood -TP_RAWCACORR_LABEL;Corrigeer chromatische aberratie +TP_RAWCACORR_LABEL;Corrigeer chromatische afwijking TP_RAWEXPOS_BLACK_0;Groen 1 (leidend) TP_RAWEXPOS_BLACK_1;Rood TP_RAWEXPOS_BLACK_2;Blauw @@ -1831,77 +1832,77 @@ TP_RAWEXPOS_BLACK_3;Groen 2 TP_RAWEXPOS_BLACK_BLUE;Blauw TP_RAWEXPOS_BLACK_GREEN;Groen TP_RAWEXPOS_BLACK_RED;Rood -TP_RAWEXPOS_LINEAR;Witpunt Correctie +TP_RAWEXPOS_LINEAR;Witpuntcorrectie TP_RAWEXPOS_RGB;Rood, Groen, Blauw TP_RAWEXPOS_TWOGREEN;Koppel Groen 1 en 2 -TP_RAW_1PASSMEDIUM;1 keer (Gemiddeld) -TP_RAW_2PASS;1-pass+snel -TP_RAW_3PASSBEST;3 keer (Beste) -TP_RAW_4PASS;3-pass+snel +TP_RAW_1PASSMEDIUM;1 keer (Markesteijn) +TP_RAW_2PASS;1-gang+snel +TP_RAW_3PASSBEST;3 gangen (Markesteijn) +TP_RAW_4PASS;3-gangen+snel TP_RAW_AHD;AHD TP_RAW_AMAZE;AMaZE TP_RAW_AMAZEVNG4;AMaZE+VNG4 TP_RAW_BORDER;Rand TP_RAW_DCB;DCB -TP_RAW_DCBENHANCE;DCB Verbetering +TP_RAW_DCBENHANCE;DCB-verbetering TP_RAW_DCBITERATIONS;Aantal DCB-herhalingen TP_RAW_DCBVNG4;DCB+VNG4 TP_RAW_DMETHOD;Methode TP_RAW_DMETHOD_PROGRESSBAR;%1 Demozaïeken... -TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demozaïek verfijning... -TP_RAW_DMETHOD_TOOLTIP;IGV en LMMSE zijn speciaal bedoeld voor hoge ISO afbeeldingen -TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto drempel -TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Als checkbox is aangevinkt (aanbevolen), berekent RT een optimale waarde gebaseerd op vlakke gebieden in de foto.\nIndien die niet gevonden worden of de foto bevat veel ruis, wordt de waarde op 0 gezet.\nOm de waarde handmatig in te voeren moet u eerst de checkbox uitvinken (redelijke waarden zijn afhankelijk van het soort foto). -TP_RAW_DUALDEMOSAICCONTRAST;Contrast drempel +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demozaïekverfijning... +TP_RAW_DMETHOD_TOOLTIP;IGV en LMMSE zijn speciaal bedoeld voor afbeeldingen met hoge ISO-waarden +TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto-drempel +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Als checkbox is aangevinkt (aanbevolen), berekent RT een optimale waarde gebaseerd op vlakke gebieden in de foto.\nIndien die niet gevonden worden of de foto veel ruis bevat, wordt de waarde op 0 gezet.\nOm de waarde handmatig in te voeren moet u eerst de checkbox uitvinken (redelijke waarden zijn afhankelijk van het soort foto). +TP_RAW_DUALDEMOSAICCONTRAST;Contrastdrempel TP_RAW_EAHD;EAHD TP_RAW_FALSECOLOR;Stapgrootte kleurfoutonderdrukking TP_RAW_FAST;Snel TP_RAW_HD;Drempel -TP_RAW_HD_TOOLTIP;Lagere waarden maken Hete/Dode pixel detectie agressiever, maar valse positieven kunnen leiden tot meer artefacten. Als er artefacten verschijnen bij het gebruik van de Hete/Dode Pixel Filters verminder dan geleidelijk de drempelwaarde totdat ze verdwijnen. +TP_RAW_HD_TOOLTIP;Lagere waarden maken hete/dodepixel-detectie agressiever, maar valse positieven kunnen leiden tot meer onregelmatigheden. Als er onregelmatigheden verschijnen bij het gebruik van de hete/dodepixel-filters, verminder dan geleidelijk de drempelwaarde tot ze verdwijnen. TP_RAW_HPHD;HPHD TP_RAW_IGV;IGV TP_RAW_IMAGENUM;Sub-afbeelding -TP_RAW_IMAGENUM_SN;SN modus -TP_RAW_IMAGENUM_TOOLTIP;Sommige raw bestanden bestaan uit verschillende sub-afbeeldingen (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\Als een andere demozaïek methode dan Pixel Shift gebruikt wordt, selecteert dit de gebruikte sub-afbeelding.\n\nBij gebruik van de Pixel Shift demozaïek methode op een Pixel Shift raw, worden alle sub-afbeeldingen gebruikt, and dit selecteert de subafbeeldijg die gebruikt wordt voor bewegende moving gebieden. +TP_RAW_IMAGENUM_SN;SN-modus +TP_RAW_IMAGENUM_TOOLTIP;Sommige RAW-bestanden bestaan uit verschillende sub-afbeeldingen (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\Als een andere demozaïekmethode dan Pixel Shift gebruikt wordt, selecteert deze de gebruikte sub-afbeelding.\n\nBij gebruik van de Pixel Shift demozaïekmethode op een Pixel Shift RAW worden alle sub-afbeeldingen gebruikt en dit selecteert de sub-afbeelding die gebruikt wordt voor bewegende gebieden. TP_RAW_LABEL;Demozaïekproces TP_RAW_LMMSE;LMMSE -TP_RAW_LMMSEITERATIONS;LMMSE Verbetering Stappen -TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1), mediaan (stappen 2-4), en verfijnen (stappen 5-6) om artefacten te verwijderen en de signaal/ruis ratio te verbeteren. +TP_RAW_LMMSEITERATIONS;LMMSE-verbeterstappen +TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1), mediaan (stappen 2-4) en verfijnen (stappen 5-6) om onregelmatigheden te verwijderen en de signaal/ruis-ratio te verbeteren. TP_RAW_MONO;Mono -TP_RAW_NONE;Geen (Toont sensor patroon) -TP_RAW_PIXELSHIFT;Pixel Verschuiven +TP_RAW_NONE;Geen (Toont sensorpatroon) +TP_RAW_PIXELSHIFT;Pixel Shift TP_RAW_PIXELSHIFTBLUR;Vervaag bewegingsmasker TP_RAW_PIXELSHIFTDMETHOD;Demozaïek voor beweging TP_RAW_PIXELSHIFTEPERISO;Gevoeligheid TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;De standaardwaarde 0 werkt goed voor lage ISO-waarden.\nHogere waarden vergroten de gevoeligheid van bewegingsdetectie.\nWijzig in kleine stappen en controleer het bewegingsmasker.\nVerhoog gevoeligheid voor onderbelichte foto's of foto's met hoge ISO-waarden. -TP_RAW_PIXELSHIFTEQUALBRIGHT;Balanseer de helderheid van de frames +TP_RAW_PIXELSHIFTEQUALBRIGHT;Balanceer de helderheid van de frames TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Balanceer per kanaal -TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Ingeschakeld: Balanceer elk RGB kanaal afzonderlijk.\nUitgeschakeld: Balanceer alle kanalen evenveel. -TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Balanseer de helderheid van de frames t.o.v. de helderheid van het geslecteerde frame.\nAls er overbelichte gebieden zijn in de frames, selecteer dan het helderste frame om een magenta kleurzweem te vermijden of selecteer bewegingsorrectie. +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Ingeschakeld: balanceer elk RGB-kanaal afzonderlijk.\nUitgeschakeld: balanceer alle kanalen evenveel. +TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Balanceer de helderheid van de frames ten opzichte van de helderheid van het geselecteerde frame.\nAls er overbelichte gebieden zijn in de frames, selecteer dan het helderste frame om een magenta kleurzweem te vermijden of selecteer bewegingscorrectie. TP_RAW_PIXELSHIFTGREEN;Controleer groene kanaal voor beweging TP_RAW_PIXELSHIFTHOLEFILL;Vul holtes in verschuivingsmasker TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Vul holtes in het verschuivingsmasker op TP_RAW_PIXELSHIFTMEDIAN;Mediaan -TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Gebruik mediaan voor alle frames inplaats van alleen het geselecteerd frame voor gebieden met beweging.\nVerwijder objecten die voorkomen op verschillende plekken in alle frames.\nGeeft bewegingseffect voor langzaam bewegende (overlappende) objecten. +TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Gebruik mediaan voor alle frames inplaats van alleen het geselecteerde frame voor gebieden met beweging.\nVerwijder objecten die voorkomen op verschillende plekken in alle frames.\nGeeft bewegingseffect voor langzaam bewegende (overlappende) objecten. TP_RAW_PIXELSHIFTMM_AUTO;Automatisch TP_RAW_PIXELSHIFTMM_CUSTOM;Eigen TP_RAW_PIXELSHIFTMM_OFF;Uit -TP_RAW_PIXELSHIFTMOTION;Beweging detectie niveau (vervallen) -TP_RAW_PIXELSHIFTMOTIONMETHOD;Beweging Correctie -TP_RAW_PIXELSHIFTNONGREENCROSS;Controleer rood/blauw kanaal voor beweging +TP_RAW_PIXELSHIFTMOTION;Bewegingsdetectie-niveau (vervallen) +TP_RAW_PIXELSHIFTMOTIONMETHOD;Bewegingscorrectie +TP_RAW_PIXELSHIFTNONGREENCROSS;Controleer rood/blauw-kanaal voor beweging TP_RAW_PIXELSHIFTSHOWMOTION;Toon beweging TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Toon alleen masker TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Toont het bewegingsmasker zonder de afbeelding TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Toont de foto met een groen masker dat de bewegingsgebieden toont. TP_RAW_PIXELSHIFTSIGMA;Vervagen straal -TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;De standaard straal van 1.0 is goed voor normale ISO. Verhoog de waarde voor hogere ISO.\n5.0 is een goed startpunt voor hoge ISO afbeeldingen.\nControleer het bewegingsmasker bij het veranderen van de waarde. +TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;De standaardstraal van 1,0 is goed voor normale ISO-waarden. Verhoog de waarde voor hogere ISO.\n5,0 is een goed startpunt voor afbeeldingen met hoge ISO-waarden.\nControleer het bewegingsmasker bij het veranderen van de waarde. TP_RAW_PIXELSHIFTSMOOTH;Zachte overgang TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Zachte overgang tussen gebieden met en zonder beweging.\nKies 0 om Zachte overgang uit te zetten\nKies 1 voor Amaze/lmmse of Mediaan TP_RAW_RCD;RCD TP_RAW_RCDVNG4;RCD+VNG4 -TP_RAW_SENSOR_BAYER_LABEL;Sensor met Bayer matrix -TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass geeft het beste resultaat (aanbevolen voor lage ISO afbeeldingen)\n1-pass geeft hetzelfde resultaat als 3-pass voor hoge ISO afbeeldingen en is sneller. -TP_RAW_SENSOR_XTRANS_LABEL;Sensor met X-Trans matrix +TP_RAW_SENSOR_BAYER_LABEL;Sensor met Bayer-matrix +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-gang geeft het beste resultaat (aanbevolen voor lage ISO-waarden)\n1-gang geeft hetzelfde resultaat als 3-gang voor hoge ISO-afbeeldingen en is sneller. +TP_RAW_SENSOR_XTRANS_LABEL;Sensor met X-Transmatrix TP_RAW_VNG4;VNG4 TP_RAW_XTRANS;X-Trans TP_RAW_XTRANSFAST;Snelle X-Trans @@ -1920,81 +1921,81 @@ TP_RESIZE_SCALE;Schaal TP_RESIZE_SPECIFY;Specificeer: TP_RESIZE_W;B: TP_RESIZE_WIDTH;Breedte -TP_RETINEX_CONTEDIT_HSL;Histogram balans HSL -TP_RETINEX_CONTEDIT_LAB;Histogram balans L*a*b* -TP_RETINEX_CONTEDIT_LH;Tint balans +TP_RETINEX_CONTEDIT_HSL;Histogrambalans HSL +TP_RETINEX_CONTEDIT_LAB;Histogrambalans L*a*b* +TP_RETINEX_CONTEDIT_LH;Tintbalans TP_RETINEX_CONTEDIT_MAP;Equalizer TP_RETINEX_CURVEEDITOR_CD;L=f(L) -TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminantie volgens luminantie L=f(L)\nCorrigeert ruwe data om halo's and artefacte te verminderen. +TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminantie volgens luminantie L=f(L).\nCorrigeert ruwe data om halo's en onregelmatigheden te verminderen. TP_RETINEX_CURVEEDITOR_LH;Sterkte=f(H) -TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Sterkte volgens tint Sterkte=f(H)\nDeze curve wijzigt ook chroma wanneer de "Hooglicht" retinex methode wordt gebruikt. +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Sterkte volgens tint, Sterkte=f(H).\nDeze curve wijzigt ook chroma wanneer de Retinex-methode Hoge lichten wordt gebruikt. TP_RETINEX_CURVEEDITOR_MAP;L=f(L) -TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Deze curve kan zowel alleen worden gebruikt of in combinatie met een Gaussiaans masker of wavelet masker.\nHou rekening met artefacten! +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Deze curve kan zowel losstaand worden gebruikt of in combinatie met een Gaussiaans of wavelet-masker.\nHoud rekening met onregelmatigheden. TP_RETINEX_EQUAL;Mixer TP_RETINEX_FREEGAMMA;Vrij gamma TP_RETINEX_GAIN;Verbeteren -TP_RETINEX_GAINOFFS;Versterking en Offset (helderheid) -TP_RETINEX_GAINTRANSMISSION;Transmissie versterking -TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Versterk of verzwak de transmssiemap om de gewenste luminantie te bekomen.\nThe x-as is the transmissie.\nThe y-as is the versterking. +TP_RETINEX_GAINOFFS;Versterking en verschuiving (helderheid) +TP_RETINEX_GAINTRANSMISSION;Transmissieversterking +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Versterk of verzwak de transmissiemap om de gewenste luminantie te verkrijgen.\nDe x-as is de transmissie.\nDe y-as is de versterking. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Vrij TP_RETINEX_GAMMA_HIGH;Hoog TP_RETINEX_GAMMA_LOW;Laag TP_RETINEX_GAMMA_MID;Midden TP_RETINEX_GAMMA_NONE;Geen -TP_RETINEX_GAMMA_TOOLTIP;Hersteld tinten door gamma voor en na Retinex toe te passen. Verschilt van Retinex curves en andere curves (Lab, Exposure, etc.). -TP_RETINEX_GRAD;Transmissie verloop -TP_RETINEX_GRADS;Sterkte verloop +TP_RETINEX_GAMMA_TOOLTIP;Herstel tinten door gamma voor en na Retinex toe te passen. Verschilt van Retinex-curves en andere curves (Lab, Exposure, etc.). +TP_RETINEX_GRAD;Transmissieverloop +TP_RETINEX_GRADS;Sterkteverloop TP_RETINEX_GRADS_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Sterkte verminderd en herhaling vergroot, en omgekeerd. TP_RETINEX_GRAD_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Variantie en Drempel worden verkleind als herhaling toeneemt, en omgekeerd. TP_RETINEX_HIGH;Hoog -TP_RETINEX_HIGHLIG;Hooglicht -TP_RETINEX_HIGHLIGHT;Drempel hooglicht -TP_RETINEX_HIGHLIGHT_TOOLTIP;Versterkt de werking van de Hooglicht methode.\nMogelijk moet de "Naburige pixels" worden aangepast en moet de "Witpunt Correctie" in de Raw tab -> Raw Witpuntent worden vergroot. -TP_RETINEX_HSLSPACE_LIN;HSL-Linear +TP_RETINEX_HIGHLIG;Hoge lichten +TP_RETINEX_HIGHLIGHT;Drempel hoge lichten +TP_RETINEX_HIGHLIGHT_TOOLTIP;Versterkt de werking van de Hoge lichten-methode.\nMogelijk moet Naburige pixels worden aangepast en moet de Witpuntcorrectie in de Raw-tab -> Raw Witpunten worden vergroot. +TP_RETINEX_HSLSPACE_LIN;HSL-Lineair TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmisch -TP_RETINEX_ITER;Herhalingen (Tonemapping) -TP_RETINEX_ITERF;Tonemapping -TP_RETINEX_ITER_TOOLTIP;Simuleert tonemapping.\nHoge waarden verlengen de bewerkingstijd. +TP_RETINEX_ITER;Herhalingen (Toonmappen) +TP_RETINEX_ITERF;Toonmappen +TP_RETINEX_ITER_TOOLTIP;Simuleert toonmappen.\nHoge waarden verlengen de bewerkingstijd. TP_RETINEX_LABEL;Retinex TP_RETINEX_LABEL_MASK;Masker TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Laag TP_RETINEX_MAP;Methode TP_RETINEX_MAP_GAUS;Gaussiaans masker -TP_RETINEX_MAP_MAPP;Verscherp masker (wavelet gedeeltelijk) -TP_RETINEX_MAP_MAPT;Verscherp masker (wavelet totaal) -TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en artefacten te verminderen.\n\nCurve: past een diagonale contrast curve toe op het masker.\nHou rekening met artefacten!\n\n Gausiaans: genereerd en gebruikt een ‘Gausiaanse blur’ op het masker.\nVerscherpen: genereert en gebruikt een ‘wavelet’ op het masker.\nLangzaam. +TP_RETINEX_MAP_MAPP;Scherptemasker (wavelet gedeeltelijk) +TP_RETINEX_MAP_MAPT;Scherptemasker (wavelet totaal) +TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en onregelmatigheden te verminderen.\n\nCurve: past een diagonale contrastcurve toe op het masker.\nHou rekening met onregelmatigheden!\n\n Gausiaans: genereert en gebruikt een Gausiaanse vervaging op het masker.\nVerscherpen: genereert en gebruikt een wavelet op het masker.\nLangzaam. TP_RETINEX_MAP_NONE;Geen -TP_RETINEX_MEDIAN;Transmissie mediaan filter +TP_RETINEX_MEDIAN;Transmissiemediaan-filter TP_RETINEX_METHOD;Methode -TP_RETINEX_METHOD_TOOLTIP;Laag = versterk lage lichten,\nUniform = gelijkmatig,\nHoog = versterk hoge lichten,\nHooglicht = verwijder magenta in hooglicht. -TP_RETINEX_MLABEL;Teruggeplaatst sluier-vrij Min=%1 Max=%2 -TP_RETINEX_MLABEL_TOOLTIP;Zou min=0 en max=32768 moeten benaderen\nTeruggeplaatste afbeelding zonder mixture. +TP_RETINEX_METHOD_TOOLTIP;Laag: schaduwen ophelderen,\nUniform: gelijkmatig,\nHoog: versterk hoge lichten,\nHoge lichten: verwijder magenta in hoge lichten. +TP_RETINEX_MLABEL;Teruggeplaatst sluiervrij Min=%1 Max=%2 +TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. TP_RETINEX_NEIGHBOR;Naburige pixels TP_RETINEX_NEUTRAL;Beginwaarde TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarde. TP_RETINEX_OFFSET;Beginpunt TP_RETINEX_SCALES;Gaussiaans verloop -TP_RETINEX_SCALES_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Schaal en straal worden verkleind als herhaling toeneemt, en omgekeerd. +TP_RETINEX_SCALES_TOOLTIP;Als schuifbalk = 0, dan zijn alle herhalingen gelijk.\nIndien > 0 dan worden schaal en straal verkleind als de herhaling toeneemt, en omgekeerd. TP_RETINEX_SETTINGS;Instellingen TP_RETINEX_SKAL;Schaal -TP_RETINEX_SLOPE;Vrij gamma helling +TP_RETINEX_SLOPE;Helling vrij gamma TP_RETINEX_STRENGTH;Sterkte TP_RETINEX_THRESHOLD;Drempel -TP_RETINEX_THRESHOLD_TOOLTIP;Beperkt in/uit.\nIn = afbeelding,\nUit = afbeeldings gauss. +TP_RETINEX_THRESHOLD_TOOLTIP;Beperkt in/uit.\nIn = bron,\nUit = afbeeldings-gauss. TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sigma=%4 TP_RETINEX_TLABEL2;TM Tm=%1 TM=%2 -TP_RETINEX_TLABEL_TOOLTIP;Transmissie resultaat.\nMin en Max worden gebruikt door Variantie.\nMeeste en Sigma\nTm=Min TM=Max van de transmissie. +TP_RETINEX_TLABEL_TOOLTIP;Transmissieresultaat.\nMin en Max worden gebruikt door Variantie.\nMeeste en Sigma\nTm=Min TM=Max van de transmissie. TP_RETINEX_TRANF;Transmissie -TP_RETINEX_TRANSMISSION;Transmissie plan -TP_RETINEX_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde, en positieve waarden (max).\nOrdinaat: versterken of verminderen. +TP_RETINEX_TRANSMISSION;Transmissiemap +TP_RETINEX_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde, en positieve waarden (max).\nOrdinaat: versterking of vermindering. TP_RETINEX_UNIFORM;Uniform TP_RETINEX_VARIANCE;Variantie TP_RETINEX_VARIANCE_TOOLTIP;Lage variantie versterkt lokaal contrast en verzadiging, maar dit kan artefacten veroorzaken. TP_RETINEX_VIEW;Proces TP_RETINEX_VIEW_MASK;Masker -TP_RETINEX_VIEW_METHOD_TOOLTIP;Standaard - Normale afbeelding.\nMasker - Toont het masker.\nOnscherp masker - Toont de afbeelding met een hoge straal.\nTransmissie - Auto/Vast - Toont de transmissie-map, voor enige actie op kontrast en helderheid.\n\nLet op: het masker komt niet overeen met de werkelijkheid, maar is versterkt om het effect beter zichtbaar te maken. +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standaard - Normale weergave.\nMasker - Toont het masker.\nOnscherp masker - Toont de afbeelding met een onscherptemasker met grote straal.\nTransmissie - Auto/Vast - Toont de transmissiemap, voordat actie wordt ondernomen op contrast en helderheid.\n\nLet op: het masker komt niet overeen met de werkelijkheid, maar is versterkt om het effect beter zichtbaar te maken. TP_RETINEX_VIEW_NONE;Standaard TP_RETINEX_VIEW_TRAN;Transmissie - Auto TP_RETINEX_VIEW_TRAN2;Transmissie - Vast @@ -2003,13 +2004,13 @@ TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Kanaal TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;RGB-curven -TP_RGBCURVES_LUMAMODE;Luminositeit Mode -TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminositeit ModeVarieert de toewijzing van de R, G en B kanalen aan de Luminositeit van de afbeelding, zonder dat de kleur van de afbeelding wijzigt. +TP_RGBCURVES_LUMAMODE;Luminositeitsmodus +TP_RGBCURVES_LUMAMODE_TOOLTIP;LuminositeitsmodusVarieert de toewijzing van de R-, G- en B-kanalen aan de luminositeit van de afbeelding, zonder dat de kleur van de afbeelding wijzigt. TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;Graden TP_ROTATE_LABEL;Roteren TP_ROTATE_SELECTLINE;Bepaal rechte lijn -TP_SAVEDIALOG_OK_TOOLTIP;Sneltoets: Ctrl-Enter +TP_SAVEDIALOG_OK_TOOLTIP;Sneltoets: Ctrl+Enter TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hoge lichten TP_SHADOWSHLIGHTS_HLTONALW;Toonomvang TP_SHADOWSHLIGHTS_LABEL;Schaduwen/hoge lichten @@ -2022,7 +2023,7 @@ TP_SHARPENEDGE_PASSES;Herhaling TP_SHARPENEDGE_THREE;Alleen luminantie TP_SHARPENING_AMOUNT;Hoeveelheid TP_SHARPENING_BLUR;Vervagen straal -TP_SHARPENING_CONTRAST;Contrast drempel +TP_SHARPENING_CONTRAST;Contrastdrempel TP_SHARPENING_EDRADIUS;Straal TP_SHARPENING_EDTOLERANCE;Randtolerantie TP_SHARPENING_HALOCONTROL;Halocontrole @@ -2040,7 +2041,7 @@ TP_SHARPENING_RLD_ITERATIONS;Herhaling TP_SHARPENING_THRESHOLD;Drempel TP_SHARPENING_USM;Onscherpmasker TP_SHARPENMICRO_AMOUNT;Hoeveelheid -TP_SHARPENMICRO_CONTRAST;Contrast drempel +TP_SHARPENMICRO_CONTRAST;Contrastdrempel TP_SHARPENMICRO_LABEL;Microcontrast (Lab/CIECAM02) TP_SHARPENMICRO_MATRIX;3×3-matrix ipv. 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformiteit @@ -2048,7 +2049,7 @@ TP_SOFTLIGHT_LABEL;Zacht licht TP_SOFTLIGHT_STRENGTH;Sterkte TP_TM_FATTAL_AMOUNT;Hoeveelheid TP_TM_FATTAL_ANCHOR;Anker -TP_TM_FATTAL_LABEL;Dynamisch bereik compressie +TP_TM_FATTAL_LABEL;Compressie dynamisch bereik TP_TM_FATTAL_THRESHOLD;Detail TP_VIBRANCE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH @@ -2063,15 +2064,15 @@ TP_VIBRANCE_PASTELS;Pasteltinten TP_VIBRANCE_PASTSATTOG;Koppel pastel- en verzadigde tinten TP_VIBRANCE_PROTECTSKINS;Bescherm huidtinten TP_VIBRANCE_PSTHRESHOLD;Drempel pastel/verzadiging -TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Drempel Verzadiging -TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;De verticale as vertegenwoordigt aan de onderkant de pastel tinten en aan de bovenkanten de verzadigde tinten.\nDe horizontale as vertegenwoordigt de verzadigde reeks. -TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/verzadigings transitie weging +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Drempel verzadiging +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;De verticale as vertegenwoordigt pasteltinten aan de onderkant en verzadigde tinten aan de bovenkant.\nDe horizontale as vertegenwoordigt het verzadigingsbereik. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Gewicht pastel/verzadigingtransitie TP_VIBRANCE_SATURATED;Verzadigde tinten TP_VIGNETTING_AMOUNT;Hoeveelheid TP_VIGNETTING_CENTER;Centrum TP_VIGNETTING_CENTER_X;Centrum X TP_VIGNETTING_CENTER_Y;Centrum Y -TP_VIGNETTING_LABEL;Vignettering Correctie +TP_VIGNETTING_LABEL;Vignetteringscorrectie TP_VIGNETTING_RADIUS;Straal TP_VIGNETTING_STRENGTH;Sterkte TP_WAVELET_1;Niveau 1 @@ -2091,44 +2092,44 @@ TP_WAVELET_B2;Rest TP_WAVELET_BACKGROUND;Achtergrond TP_WAVELET_BACUR;Curve TP_WAVELET_BALANCE;Contrastbalans d/v-h -TP_WAVELET_BALANCE_TOOLTIP;Wijzigt de balans tussen de wavelet richtingen: vertikaal-horizontaal en diagonaal.\nAls contrast, chromaticiteit of 'rest' tonemapping actief zijn, wordt het effect als gevolg van de balans versterkt. -TP_WAVELET_BALCHRO;Chroma balans -TP_WAVELET_BALCHRO_TOOLTIP;De 'Contrastbalans' curve en schuifbalk wijzigen ook de chromaticiteit balans. +TP_WAVELET_BALANCE_TOOLTIP;Wijzigt de balans tussen de wavelet-richtingen: vertikaal-horizontaal en diagonaal.\nAls tonemapping in contrast, chromaticiteit of residueel actief zijn, wordt het effect als gevolg van de balans versterkt. +TP_WAVELET_BALCHRO;Chroma-balans +TP_WAVELET_BALCHRO_TOOLTIP;De Contrastbalans-curve en schuifbalk wijzigen ook de chromaticiteit-balans. TP_WAVELET_BANONE;Geen TP_WAVELET_BASLI;Schuifbalk -TP_WAVELET_BATYPE;Balans methode +TP_WAVELET_BATYPE;Balansmethode TP_WAVELET_CBENAB;Kleurtint en kleurbalans -TP_WAVELET_CB_TOOLTIP;Voor hoge waarden: kleurcorrectie door al of niet te combineren met niveau decompositie 'toning'\nVoor lage waarden de witbalans van de achtergrond (hemel, ...) wijzigen zonder die van de voorgrond, meestal meer contrastrijk +TP_WAVELET_CB_TOOLTIP;Met hoge waarden kun je speciale effecten creëren, gelijkend op wat je met de Chroma-module kunt bereiken, maar nu gericht op het residuele beeld. Met kleinere waarden kun je handmatig de witbalans corrigeren. TP_WAVELET_CCURVE;Lokaal contrast TP_WAVELET_CH1;Alle chroma's TP_WAVELET_CH2;Pastel - Verzadigd -TP_WAVELET_CH3;Koppel contrast niveaus +TP_WAVELET_CH3;Koppel contrastniveaus TP_WAVELET_CHCU;Curve -TP_WAVELET_CHR;Koppel Chroma aan contrast +TP_WAVELET_CHR;Koppel Chroma aan Contrast TP_WAVELET_CHRO;Verzadigd - Pastel TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel -TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met Contrast niveaus +TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met contrastniveaus TP_WAVELET_CHSL;Schuifbalken -TP_WAVELET_CHTYPE;Chrominantie methode -TP_WAVELET_COLORT;Dekking Rood-Groen Niveau +TP_WAVELET_CHTYPE;Chrominantiemethode +TP_WAVELET_COLORT;Dekking Rood-Groen niveau TP_WAVELET_COMPCONT;Contrast TP_WAVELET_COMPGAMMA;Compressie gamma -TP_WAVELET_COMPGAMMA_TOOLTIP;Wijzig de gamma van de 'rest afbeelding' zodat data en histogram gelijk kunnen worden gemaakt. -TP_WAVELET_COMPTM;Tonemapping -TP_WAVELET_CONTEDIT;'Na' contrast curve -TP_WAVELET_CONTR;Gamut - controle +TP_WAVELET_COMPGAMMA_TOOLTIP;Door het gamma van het residuele beeld te wijzigen, kun je data en histogram in balans brengen. +TP_WAVELET_COMPTM;Toonmappen +TP_WAVELET_CONTEDIT;'Na'-contrastcurve +TP_WAVELET_CONTR;Kleurenscala - controle TP_WAVELET_CONTRA;Contrast -TP_WAVELET_CONTRAST_MINUS;Contrast - -TP_WAVELET_CONTRAST_PLUS;Contrast + -TP_WAVELET_CONTRA_TOOLTIP;Wijzigt het contrast van de 'rest afbeelding'. -TP_WAVELET_CTYPE;Chrominantie sterkte -TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Wijzigt lokaal contrast als een functie van het oorspronkelijke lokale contrast (abscis).\nLage abscis waarden vertegenwoordigen klein lokaal contrast (werkelijke waarden rond 10..20).\n50% abscis vertegenwoordigd gemiddeld lokaal contrast (werkelijke waarden rond 100..300).\n66% abscis vertegenwoordigd standaard deviatie van lokaal contrast (werkelijke waarden rond 300..800).\n100% abscis vertegenwoordigd maximaal lokaal contrast (werkelijke waarden rond 3000..8000). -TP_WAVELET_CURVEEDITOR_CH;Contrast niveau=f(Hue) -TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Wijzigt het contrast van elk niveau als een functie van hue.\nZorg er voor dat de wijzigingen die zijn gemaakt bij de Gamut Hue toepassing niet worden overschreven.\nDe curve werkt alleen als de 'wavelet contrast niveau schuifbalken' groter dan nul zijn. +TP_WAVELET_CONTRAST_MINUS;< Contrast +TP_WAVELET_CONTRAST_PLUS;Contrast > +TP_WAVELET_CONTRA_TOOLTIP;Wijzigt het contrast van de residuele afbeelding. +TP_WAVELET_CTYPE;Chrominantiesterkte +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Wijzigt lokaal contrast als een functie van het oorspronkelijke lokale contrast (abscis).\nLage absciswaarden vertegenwoordigen weinig lokaal contrast (werkelijke waarden rond 10..20).\n50% abscis vertegenwoordigt gemiddeld lokaal contrast (werkelijke waarden rond 100..300).\n66% abscis vertegenwoordigt de standaarddeviatie van lokaal contrast (werkelijke waarden rond 300..800).\n100% abscis vertegenwoordigt maximaal lokaal contrast (werkelijke waarden rond 3000..8000). +TP_WAVELET_CURVEEDITOR_CH;Contrastniveau=f(Tint) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Wijzigt het contrast van elk niveau als een functie van tint.\nZorg er voor dat de wijzigingen die zijn gemaakt bij de Gamut Tint-toepassing niet worden overschreven.\nDe curve werkt alleen als de Wavelet contrastniveauschuifbalken groter zijn dan nul. TP_WAVELET_CURVEEDITOR_CL;L -TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Contrast luminantie curve. Wordt uitgevoerd aan het einde van de wavelet niveau behandeling. +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Contrast luminantiecurve. Wordt uitgevoerd aan het einde van de Wavelet niveaubehandeling. TP_WAVELET_CURVEEDITOR_HH;HH -TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de rest van de afbeelding 's tint als een functie van tint. +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de tint van de residuele afbeelding als functie van tint. TP_WAVELET_DALL;Alle richtingen TP_WAVELET_DAUB;Randen TP_WAVELET_DAUB2;D2 - laag @@ -2136,62 +2137,62 @@ TP_WAVELET_DAUB4;D4 - standaard TP_WAVELET_DAUB6;D6 - standaard plus TP_WAVELET_DAUB10;D10 - medium TP_WAVELET_DAUB14;D14 - hoog -TP_WAVELET_DAUB_TOOLTIP;Wijzigt Daubechies coëfficiënt:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere verwerkingstijd.\n\nBeïnvloed zowel rand detectie als het algemen resultaat van de eerste niveau´s. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan variëren per afbeelding en toepassing. -TP_WAVELET_DONE;Richting: Vertikaal -TP_WAVELET_DTHR;Richting: Diagonaal -TP_WAVELET_DTWO;Richting: Horizontaal +TP_WAVELET_DAUB_TOOLTIP;Wijzigt de Daubechies-coëfficiënten:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere verwerkingstijd.\n\nBeïnvloed zowel randdetectie als het algemene resultaat van de eerste niveaus. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan variëren per afbeelding en toepassing. +TP_WAVELET_DONE;Verticaal +TP_WAVELET_DTHR;Diagonaal +TP_WAVELET_DTWO;Horizontaal TP_WAVELET_EDCU;Curve TP_WAVELET_EDGCONT;Lokaal contrast -TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen. Naar rechts schuiven vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev, maximum. +TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen, naar rechts vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev en maximum. TP_WAVELET_EDGE;Randen verscherpen (Luminantie) -TP_WAVELET_EDGEAMPLI;Basis versterking -TP_WAVELET_EDGEDETECT;Gradiënt gevoeligheid +TP_WAVELET_EDGEAMPLI;Basisversterking +TP_WAVELET_EDGEDETECT;Gradiëntgevoeligheid TP_WAVELET_EDGEDETECTTHR;Drempel laag (ruis) TP_WAVELET_EDGEDETECTTHR2;Drempel hoog (detectie) -TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Wijzigt de rand detectie. Bijvoorbeeld om randverscherping te voorkomen bij fijne details zoals ruis in de lucht. +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Wijzigt de randdetectie. Bijvoorbeeld om randverscherping te voorkomen bij fijne details zoals ruis in de lucht. TP_WAVELET_EDGEDETECT_TOOLTIP;Beweeg de schuifbalk naar rechts om de randgevoeligheid te vergroten. Dit wijzigt lokaal contrast, randscherpte en ruis. TP_WAVELET_EDGESENSI;Randgevoeligheid -TP_WAVELET_EDGREINF_TOOLTIP;Versterk of verminder de aktie van het eerste niveau en doe het tegenovergestelde voor het tweede niveau en laat de rest ongewijzigd. +TP_WAVELET_EDGREINF_TOOLTIP;Versterk of verminder de actie van het eerste niveau en doe het tegenovergestelde voor het tweede niveau; laat de rest ongewijzigd. TP_WAVELET_EDGTHRESH;Drempel TP_WAVELET_EDGTHRESH_TOOLTIP;Wijzigt de interactie tussen de eerste niveaus en de andere niveaus. Hoe hoger de drempel hoe meer de actie is gecentreerd op de eerste niveaus. Wees voorzichtig met negatieve waarden. Deze versterken de hogere niveaus en kunnen artefacten veroorzaken. TP_WAVELET_EDRAD;Straal -TP_WAVELET_EDRAD_TOOLTIP;Deze straalaanpassing verschilt erg van die in de andere verscherpings tools. De waarde wordt vergeleken met elk niveau op basis van een complexe functie. In dit geval heeft zelfs een nul waarde effect. +TP_WAVELET_EDRAD_TOOLTIP;Deze straalaanpassing verschilt erg van die in de andere verscherpingsgereedschappen. De waarde wordt vergeleken met elk niveau op basis van een complexe functie. In dit geval heeft zelfs een nulwaarde effect. TP_WAVELET_EDSL;Drempel schuifbalk -TP_WAVELET_EDTYPE;Lokaal contrast methode +TP_WAVELET_EDTYPE;Lokaal contrastmethode TP_WAVELET_EDVAL;Waarde TP_WAVELET_FINAL;Finale Bewerking TP_WAVELET_FINEST;fijn -TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantie Reeks (0..100) +TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantiereeks (0..100) TP_WAVELET_HS1;Alle luminanties -TP_WAVELET_HS2;Hoge lichten/Schaduwen +TP_WAVELET_HS2;Hoge lichten/schaduwen TP_WAVELET_HUESKIN;Tint reeks (huid) -TP_WAVELET_HUESKIN_TOOLTIP;De laagste punten vormen het begin van de transitie zone, en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. +TP_WAVELET_HUESKIN_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. TP_WAVELET_HUESKY;Tint Reeks (lucht) -TP_WAVELET_HUESKY_TOOLTIP;De laagste punten vormen het begin van de transitie zone, en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. -TP_WAVELET_ITER;Balans niveau +TP_WAVELET_HUESKY_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. +TP_WAVELET_ITER;Balansniveau TP_WAVELET_ITER_TOOLTIP;Links: verhoog lage niveaus en verlaag hoge niveaus.\nRechts: verlaag lage niveaus en verhoog hoge niveaus. -TP_WAVELET_LABEL;Wavelet niveaus +TP_WAVELET_LABEL;Wavelet-niveaus TP_WAVELET_LARGEST;grof TP_WAVELET_LEVCH;Chromaticiteit TP_WAVELET_LEVDIR_ALL;Alle niveaus in alle richtingen TP_WAVELET_LEVDIR_INF;Onder of gelijk aan het niveau -TP_WAVELET_LEVDIR_ONE;Eén Niveau +TP_WAVELET_LEVDIR_ONE;Eén niveau TP_WAVELET_LEVDIR_SUP;Boven het niveau -TP_WAVELET_LEVELS;Wavelet niveaus -TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detail niveaus. Meer niveaus vereisen meer RAM en de verwerking duurt langer. +TP_WAVELET_LEVELS;Wavelet-niveaus +TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detailniveaus. Meer niveaus vereisen meer RAM en de verwerking duurt langer. TP_WAVELET_LEVF;Contrast TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveaus=%1 TP_WAVELET_LEVONE;Niveau 2 TP_WAVELET_LEVTHRE;Niveau 4 TP_WAVELET_LEVTWO;Niveau 3 TP_WAVELET_LEVZERO;Niveau 1 -TP_WAVELET_LINKEDG;Koppel met Randscherpte Waarde +TP_WAVELET_LINKEDG;Koppel met Randscherptewaarde TP_WAVELET_LIPST;Verbeterde methode -TP_WAVELET_LOWLIGHT;Schaduwen: Luminantie Reeks (0..100) -TP_WAVELET_MEDGREINF;Eerste Niveau +TP_WAVELET_LOWLIGHT;Grovere niveaus luminantiebereik (0..100) +TP_WAVELET_MEDGREINF;Eerste niveau TP_WAVELET_MEDI;Verminder artefacten in blauwe lucht -TP_WAVELET_MEDILEV;Rand detectie -TP_WAVELET_MEDILEV_TOOLTIP;Bij gebruik van Rand detectie:\n- Maak geen gebruik van de lage contrast niveaus's. Dit voorkomt artefacten.\n- Gebruik de hoge waarden van de Gradiënt gevoeligheid.\n\nJe kunt de sterkte moduleren met 'verfijnen' van Ruisonderdrukking. +TP_WAVELET_MEDILEV;Randdetectie +TP_WAVELET_MEDILEV_TOOLTIP;Bij gebruik van Randdetectie:\n- Maak geen gebruik van de lagecontrast-niveaus. Dit voorkomt artefacten.\n- Gebruik de hoge waarden van de Gradiënt-gevoeligheid.\n\nJe kunt de sterkte moduleren met 'verfijnen' van Ruisonderdrukking. TP_WAVELET_NEUTRAL;Neutraal TP_WAVELET_NOIS;Ruisonderdrukking TP_WAVELET_NOISE;Ruisonderdrukking @@ -2200,52 +2201,52 @@ TP_WAVELET_NPLOW;Laag TP_WAVELET_NPNONE;Geen TP_WAVELET_NPTYPE;Naburige pixels TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan worden randen verscherpt. -TP_WAVELET_OPACITY;Dekking Blauw-Geel Niveau -TP_WAVELET_OPACITYW;Contrast balans d/v-h curve -TP_WAVELET_OPACITYWL;Finale lokaal contrast -TP_WAVELET_OPACITYWL_TOOLTIP;Wijzigt het lokaal contrast aan het einde van de wavelet toepassing.\n\nHet lokaal contrast wordt sterker van links naar rechts. -TP_WAVELET_PASTEL;Pastel chromaciteit -TP_WAVELET_PROC;Process +TP_WAVELET_OPACITY;Dekking Blauw-Geel niveau +TP_WAVELET_OPACITYW;Contrastbalans d/v-h curve +TP_WAVELET_OPACITYWL;Uiteindelijk lokaal contrast +TP_WAVELET_OPACITYWL_TOOLTIP;Wijzigt het lokaal contrast aan het einde van de wavelet-toepassing.\n\nHet lokaal contrast wordt sterker van links naar rechts. +TP_WAVELET_PASTEL;Pastel-chromaciteit +TP_WAVELET_PROC;Proces TP_WAVELET_RE1;Versterkt TP_WAVELET_RE2;Ongewijzigd TP_WAVELET_RE3;Verminderd TP_WAVELET_RESCHRO;Chromaticiteit TP_WAVELET_RESCON;Schaduwen TP_WAVELET_RESCONH;Hoge lichten -TP_WAVELET_RESID;Rest van de afbeelding +TP_WAVELET_RESID;Residuele afbeelding TP_WAVELET_SAT;Verzadigd chromaciteit -TP_WAVELET_SETTINGS;Wavelet Instellingen -TP_WAVELET_SKIN;Huidtinten Wijzigen/Beschermen +TP_WAVELET_SETTINGS;Wavelet-instellingen +TP_WAVELET_SKIN;Huidtinten wijzigen/beschermen TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen -TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in de tint reeks\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... +TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in het tintbereik\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... TP_WAVELET_STREN;Sterkte TP_WAVELET_STRENGTH;Sterkte TP_WAVELET_SUP;Boven het niveau + overblijvend TP_WAVELET_SUPE;Extra -TP_WAVELET_THR;Drempel Schaduwen -TP_WAVELET_THRES;Max niveau +TP_WAVELET_THR;Drempel schaduwen +TP_WAVELET_THRES;Max. niveau TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) -TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus tussen '9' en '9 minus gekozen waarde' worden behandeld als schaduwen\nDe andere niveaus worden volledig behandeld\nHet maximum niveau voor schaduwen wordt beperkt door het aantal Hoge lichten niveaus (9- hoge lichten niveau) -TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus boven de gekozen waarde worden behandeld als hoge lichten\nDe andere niveaus worden volledig behandeld -TP_WAVELET_THRH;Drempel Hoge lichten -TP_WAVELET_TILES;Tegel grootte (* 128) -TP_WAVELET_TILESBIG;Grote Tegels -TP_WAVELET_TILESFULL;Volldige afbeelding -TP_WAVELET_TILESIZE;Tegel grootte -TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer Tegels als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugen aanbevelingen. -TP_WAVELET_TMSTRENGTH;Compressie sterkte -TP_WAVELET_TMSTRENGTH_TOOLTIP;Bepaalt de sterkte van tonemapping of contrast compressie. Als de waarde anders is dan 0, dan worden de Sterkte en Gamma schuifbalken van Tonemapping in de Belichtings tab inactief. -TP_WAVELET_TMTYPE;Compressie methode +TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus van de gekozen waarde tot het gekozen aantal Wavelet-niveaus zullen worden beïnvloed door het Schaduwluminantiebereik. +TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus beneden en inclusief de gekozen waarde zullen worden beïnvloed door het luminantiebereik van de hoge lichten. +TP_WAVELET_THRH;Drempel hoge lichten +TP_WAVELET_TILES;Tegelgrootte (* 128) +TP_WAVELET_TILESBIG;Grote tegels +TP_WAVELET_TILESFULL;Volledige afbeelding +TP_WAVELET_TILESIZE;Tegelgrootte +TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer 'Grote tegels' als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugenaanbevelingen. +TP_WAVELET_TMSTRENGTH;Compressiesterkte +TP_WAVELET_TMSTRENGTH_TOOLTIP;Bepaalt de sterkte van het toonmappen of de contrastcompressie. Als de waarde anders is dan 0, dan worden de Sterkte- en Gamma-schuifbalken van Toonmappen in de Belichtingstab inactief. +TP_WAVELET_TMTYPE;Compressiemethode TP_WAVELET_TON;Kleurtinten TP_WBALANCE_AUTO;Automatisch TP_WBALANCE_CAMERA;Camera TP_WBALANCE_CLOUDY;Bewolkt TP_WBALANCE_CUSTOM;Handmatig TP_WBALANCE_DAYLIGHT;Daglicht (zonnig) -TP_WBALANCE_EQBLUERED;Blauw/Rood Balans -TP_WBALANCE_EQBLUERED_TOOLTIP;Wijzigt het normale gedrag van "witbalans" door de blauw/rood balans te verschuiven.\nToepassen wanneer de opname-omstandigheden sterk afwijken van: \na) standaard belichting (bv. onderwater)\nb) de condities waar de calibraties zijn uitgevoerd\nc) de matrices of ICC profielen. +TP_WBALANCE_EQBLUERED;Blauw/Rood-balans +TP_WBALANCE_EQBLUERED_TOOLTIP;Wijzigt het normale gedrag van 'witbalans' door de blauw/rood-balans te veranderen.\nToepassen wanneer de opname-omstandigheden sterk afwijken van: \na) standaardbelichting (bv. onderwater)\nb) de condities waar de kalibraties zijn uitgevoerd\nc) de matrices of ICC-profielen. TP_WBALANCE_FLASH55;Leica TP_WBALANCE_FLASH60;Standaard, Canon, Pentax, Olympus TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta @@ -2281,8 +2282,8 @@ 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_TEMPBIAS;AWB temperatuur afwijking -TP_WBALANCE_TEMPBIAS_TOOLTIP;Wijzigt de berekening van "auto wit balans"\ndoor een afwijking naar warmere of koelere temperatuur \nDe afwijking wordt uitgedrukt als percentage van de berekende temperatuur,\nszodat het resultaat is "computedTemp + computedTemp * afwijking". +TP_WBALANCE_TEMPBIAS;AWB temperatuur-afwijking +TP_WBALANCE_TEMPBIAS_TOOLTIP;Wijzigt de berekening van auto-witbalans\ndoor een afwijking naar warmere of koelere temperatuur.\nDe afwijking wordt uitgedrukt als percentage van de berekende temperatuur,\nzodat het resultaat is: computedTemp + computedTemp * afwijking. TP_WBALANCE_TEMPERATURE;Kleurtemperatuur TP_WBALANCE_TUNGSTEN;Tungsten (wolfraam) TP_WBALANCE_WATER1;Onderwater 1 @@ -2290,9 +2291,9 @@ TP_WBALANCE_WATER2;Onderwater 2 TP_WBALANCE_WATER_HEADER;Onderwater ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;Open (nieuw) detailvenster -ZOOMPANEL_ZOOM100;Zoom naar 100%\nSneltoets: z -ZOOMPANEL_ZOOMFITCROPSCREEN;Maak uitsnede passend in het scherm\nSneltoets: f -ZOOMPANEL_ZOOMFITSCREEN;Passend in venster\nSneltoets: Alt-f +ZOOMPANEL_ZOOM100;Zoom naar 100%\nSneltoets: Z +ZOOMPANEL_ZOOMFITCROPSCREEN;Maak uitsnede passend in het scherm\nSneltoets: F +ZOOMPANEL_ZOOMFITSCREEN;Passend in venster\nSneltoets: Alt+F ZOOMPANEL_ZOOMIN;Zoom in\nSneltoets: + ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - @@ -2300,27 +2301,27 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!EXIFFILTER_PATH;File path -!EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags -!EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags -!EXIFPANEL_BASIC_GROUP;Basic -!EXIFPANEL_VALUE_NOT_SHOWN;Not shown -!FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_DELETE_ALL;Delete all -!GENERAL_EDIT;Edit -!GENERAL_OTHER;Other -!HISTOGRAM_TOOLTIP_CROSSHAIR;Show/Hide indicator crosshair. -!HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toggle visibility of the scope option buttons. -!HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Adjust scope brightness. -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw Histogram -!HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB Parade -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Hue-Chroma Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Hue-Saturation Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Waveform +ERROR_MSG_METADATA_VALUE;Metadata: fout bij omzetting %1 naar %2 +EXIFFILTER_PATH;Bestandspad +EXIFPANEL_ACTIVATE_ALL_HINT;Selecteer alle tags +EXIFPANEL_ACTIVATE_NONE_HINT;Deselecteer alle tags +EXIFPANEL_BASIC_GROUP;Basis +EXIFPANEL_VALUE_NOT_SHOWN;Niet getoond +FILEBROWSER_POPUPINSPECT;Inspecteer +FILEBROWSER_POPUPSORTBY;Sorteer bestanden +FILECHOOSER_FILTER_EXECUTABLE;Uitvoerbare bestanden +GENERAL_DELETE_ALL;Wis alles +GENERAL_EDIT;Bewerk +GENERAL_OTHER;Ander +HISTOGRAM_TOOLTIP_CROSSHAIR;Toon/verberg indicatorkruis +HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toon/verberg optieknoppen +HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Pas helderheid aan +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw-histogram +HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-Parade +HISTOGRAM_TOOLTIP_TYPE_VECTORbereik_HC;Tint-Chroma vectorscope +HISTOGRAM_TOOLTIP_TYPE_VECTORbereik_HS;Tint-Verzadiging vectorscope +HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Golfvorm !HISTORY_MSG_446;--unused-- !HISTORY_MSG_447;--unused-- !HISTORY_MSG_448;--unused-- @@ -2337,1093 +2338,1089 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_466;--unused-- !HISTORY_MSG_467;--unused-- !HISTORY_MSG_470;--unused-- -!HISTORY_MSG_496;Local Spot deleted -!HISTORY_MSG_497;Local Spot selected -!HISTORY_MSG_498;Local - Spot name -!HISTORY_MSG_499;Local - Spot visibility -!HISTORY_MSG_500;Local - Spot shape -!HISTORY_MSG_501;Local - Spot method -!HISTORY_MSG_502;Local - SC - Shape method -!HISTORY_MSG_503;Local - Spot - Right -!HISTORY_MSG_504;Local - Spot - Left -!HISTORY_MSG_505;Local - Spot - Bottom -!HISTORY_MSG_506;Local - Spot - Top -!HISTORY_MSG_507;Local - Spot - Center -!HISTORY_MSG_508;Local - Spot - Size -!HISTORY_MSG_509;Local - Spot quality method -!HISTORY_MSG_510;Local - TG - Transition value -!HISTORY_MSG_511;Local - SD - ΔE scope threshold -!HISTORY_MSG_512;Local - SD - ΔE decay -!HISTORY_MSG_513;Local - Spot - Excluding - Scope -!HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments -!HISTORY_MSG_516;Local - Color and light -!HISTORY_MSG_517;Local - Enable super -!HISTORY_MSG_518;Local - Lightness -!HISTORY_MSG_519;Local - Contrast -!HISTORY_MSG_520;Local - Chrominance -!HISTORY_MSG_521;Local - Scope -!HISTORY_MSG_522;Local - Curve method -!HISTORY_MSG_523;Local - LL Curve -!HISTORY_MSG_524;Local - CC curve -!HISTORY_MSG_525;Local - LH Curve -!HISTORY_MSG_526;Local - H curve -!HISTORY_MSG_527;Local - Color Inverse -!HISTORY_MSG_528;Local - Exposure -!HISTORY_MSG_529;Local - Exp Compensation -!HISTORY_MSG_530;Local - Exp Hlcompr -!HISTORY_MSG_531;Local - Exp hlcomprthresh -!HISTORY_MSG_532;Local - Exp black -!HISTORY_MSG_533;Local - Exp Shcompr -!HISTORY_MSG_534;Local - Warm Cool -!HISTORY_MSG_535;Local - Exp Scope -!HISTORY_MSG_536;Local - Exp Contrast curve -!HISTORY_MSG_537;Local - Vibrance -!HISTORY_MSG_538;Local - Vib Saturated -!HISTORY_MSG_539;Local - Vib Pastel -!HISTORY_MSG_540;Local - Vib Threshold -!HISTORY_MSG_541;Local - Vib Protect skin tones -!HISTORY_MSG_542;Local - Vib avoid colorshift -!HISTORY_MSG_543;Local - Vib link -!HISTORY_MSG_544;Local - Vib Scope -!HISTORY_MSG_545;Local - Vib H curve -!HISTORY_MSG_546;Local - Blur and noise -!HISTORY_MSG_547;Local - Radius -!HISTORY_MSG_548;Local - Noise -!HISTORY_MSG_549;Local - Blur scope -!HISTORY_MSG_550;Local - Blur method -!HISTORY_MSG_551;Local - Blur Luminance only -!HISTORY_MSG_552;Local - Tone mapping -!HISTORY_MSG_553;Local - TM compression strength -!HISTORY_MSG_554;Local - TM gamma -!HISTORY_MSG_555;Local - TM edge stopping -!HISTORY_MSG_556;Local - TM scale -!HISTORY_MSG_557;Local - TM Reweighting -!HISTORY_MSG_558;Local - TM scope -!HISTORY_MSG_559;Local - Retinex -!HISTORY_MSG_560;Local - Retinex method -!HISTORY_MSG_561;Local - Retinex strength -!HISTORY_MSG_562;Local - Retinex chroma -!HISTORY_MSG_563;Local - Retinex radius -!HISTORY_MSG_564;Local - Retinex contrast -!HISTORY_MSG_565;Local - scope -!HISTORY_MSG_566;Local - Retinex Gain curve -!HISTORY_MSG_567;Local - Retinex Inverse -!HISTORY_MSG_568;Local - Sharpening -!HISTORY_MSG_569;Local - Sh Radius -!HISTORY_MSG_570;Local - Sh Amount -!HISTORY_MSG_571;Local - Sh Damping -!HISTORY_MSG_572;Local - Sh Iterations -!HISTORY_MSG_573;Local - Sh Scope -!HISTORY_MSG_574;Local - Sh Inverse -!HISTORY_MSG_575;Local - CBDL -!HISTORY_MSG_576;Local - cbdl mult -!HISTORY_MSG_577;Local - cbdl chroma -!HISTORY_MSG_578;Local - cbdl threshold -!HISTORY_MSG_579;Local - cbdl scope +HISTORY_MSG_496;LA - Spot verwijderd +HISTORY_MSG_497;LA - Spot geselecteerd +!HISTORY_MSG_498;--unused-- +!HISTORY_MSG_499;--unused-- +HISTORY_MSG_500;LA - Spotvorm +HISTORY_MSG_501;LA - Spotmethode +HISTORY_MSG_502;LA - SC - Vorm method +HISTORY_MSG_503;LA - Spot - Rechts +HISTORY_MSG_504;LA - Spot - Links +HISTORY_MSG_505;LA - Spot - Onder +HISTORY_MSG_506;LA - Spot - Boven +HISTORY_MSG_507;LA - Spot - Centrum +HISTORY_MSG_508;LA - Spot - Grootte +HISTORY_MSG_509;LA - Spot kwaliteitsmethode +HISTORY_MSG_510;LA - TG - Transitiewaarde +HISTORY_MSG_511;LA - SD - Drempel ΔE-bereik +HISTORY_MSG_512;LA - SD - ΔE-verval +HISTORY_MSG_513;LA - Spot - Uitsluiting - bereik +HISTORY_MSG_514;LA - Spotstructuur +HISTORY_MSG_515;LA - Aanpassingen +HISTORY_MSG_516;LA - Kleur en Licht +HISTORY_MSG_517;LA - Activeer super +HISTORY_MSG_518;LA - Lichtheid +HISTORY_MSG_519;LA - Contrast +HISTORY_MSG_520;LA - Chrominantie +HISTORY_MSG_521;LA - Bereik +HISTORY_MSG_522;LA - Curvemethode +HISTORY_MSG_523;LA - LL-curve +HISTORY_MSG_524;LA - CC-curve +HISTORY_MSG_525;LA - LH-curve +HISTORY_MSG_526;LA - H-curve +HISTORY_MSG_527;LA - Inverteer kleur +HISTORY_MSG_528;LA - Belichting +HISTORY_MSG_529;LA - Belichtingscompensatie +HISTORY_MSG_530;LA - Bel. Hlcompr +HISTORY_MSG_531;LA - Bel. hlcomprthresh +HISTORY_MSG_532;LA - Bel. zwart +HISTORY_MSG_533;LA - Bel. Shcompr +HISTORY_MSG_534;LA - Warm Koel +HISTORY_MSG_535;LA - Bel. Bereik +HISTORY_MSG_536;LA - Bel. Contrastcurve +HISTORY_MSG_537;LA - Levendigheid +HISTORY_MSG_538;LA - Lev. Verzadigd +HISTORY_MSG_539;LA - Lev. Pastel +HISTORY_MSG_540;LA - Lev. Drempel +HISTORY_MSG_541;LA - Lev. Bescherm huidtonen +HISTORY_MSG_542;LA - Lev. Vermijd kleurverschuiving +HISTORY_MSG_543;LA - Lev. Koppel +HISTORY_MSG_544;LA - Lev. Bereik +HISTORY_MSG_545;LA - Lev. H-curve +HISTORY_MSG_546;LA - Vervaging en Ruisvermindering +HISTORY_MSG_547;LA - Straal +HISTORY_MSG_548;LA - Ruis +HISTORY_MSG_549;LA - Bereik ruisvermindering +HISTORY_MSG_550;LA - Methode ruisvermindering +HISTORY_MSG_551;LA - Ruisvermindering alleen Luminantie +HISTORY_MSG_552;LA - Toonmappen +HISTORY_MSG_553;LA - TM compressiesterkte +HISTORY_MSG_554;LA - TM gamma +HISTORY_MSG_555;LA - TM edge stopping +HISTORY_MSG_556;LA - TM Schaal +HISTORY_MSG_557;LA - TM Herwogen +HISTORY_MSG_558;LA - TM Bereik +HISTORY_MSG_559;LA - Retinex +HISTORY_MSG_560;LA - Retinex methode +HISTORY_MSG_561;LA - Retinex kracht +HISTORY_MSG_562;LA - Retinex chroma +HISTORY_MSG_563;LA - Retinex straal +HISTORY_MSG_564;LA - Retinex contrast +HISTORY_MSG_565;LA - Bereik +HISTORY_MSG_566;LA - Retinex versterkingscurve +HISTORY_MSG_567;LA - Retinex Omgekeerd +HISTORY_MSG_568;LA - Verscherping +HISTORY_MSG_569;LA - Sh Straal +HISTORY_MSG_570;LA - Sh Hoeveelheid +HISTORY_MSG_571;LA - Sh Demping +HISTORY_MSG_572;LA - Sh Herhalingen +HISTORY_MSG_573;LA - Sh Bereik +HISTORY_MSG_574;LA - Sh Omgekeerd +HISTORY_MSG_575;LA - CBDL +HISTORY_MSG_576;LA - cbdl mult +HISTORY_MSG_577;LA - cbdl chroma +HISTORY_MSG_578;LA - cbdl drempel +HISTORY_MSG_579;LA - cbdl bereik !HISTORY_MSG_580;--unused-- -!HISTORY_MSG_581;Local - Denoise lum f 1 -!HISTORY_MSG_582;Local - Denoise lum c -!HISTORY_MSG_583;Local - Denoise lum detail -!HISTORY_MSG_584;Local - Denoise equalizer White-Black -!HISTORY_MSG_585;Local - Denoise chro f -!HISTORY_MSG_586;Local - Denoise chro c -!HISTORY_MSG_587;Local - Denoise chro detail -!HISTORY_MSG_588;Local - Denoise equalizer Blue-Red -!HISTORY_MSG_589;Local - Denoise bilateral -!HISTORY_MSG_590;Local - Denoise Scope -!HISTORY_MSG_591;Local - Avoid color shift -!HISTORY_MSG_592;Local - Sh Contrast -!HISTORY_MSG_593;Local - Local contrast -!HISTORY_MSG_594;Local - Local contrast radius -!HISTORY_MSG_595;Local - Local contrast amount -!HISTORY_MSG_596;Local - Local contrast darkness -!HISTORY_MSG_597;Local - Local contrast lightness -!HISTORY_MSG_598;Local - Local contrast scope -!HISTORY_MSG_599;Local - Retinex dehaze -!HISTORY_MSG_600;Local - Soft Light enable -!HISTORY_MSG_601;Local - Soft Light strength -!HISTORY_MSG_602;Local - Soft Light scope -!HISTORY_MSG_603;Local - Sh Blur radius -!HISTORY_MSG_605;Local - Mask preview choice -!HISTORY_MSG_606;Local Spot selected -!HISTORY_MSG_607;Local - Color Mask C -!HISTORY_MSG_608;Local - Color Mask L -!HISTORY_MSG_609;Local - Exp Mask C -!HISTORY_MSG_610;Local - Exp Mask L -!HISTORY_MSG_611;Local - Color Mask H -!HISTORY_MSG_612;Local - Color Structure -!HISTORY_MSG_613;Local - Exp Structure -!HISTORY_MSG_614;Local - Exp Mask H -!HISTORY_MSG_615;Local - Blend color -!HISTORY_MSG_616;Local - Blend Exp -!HISTORY_MSG_617;Local - Blur Exp -!HISTORY_MSG_618;Local - Use Color Mask -!HISTORY_MSG_619;Local - Use Exp Mask -!HISTORY_MSG_620;Local - Blur col -!HISTORY_MSG_621;Local - Exp inverse -!HISTORY_MSG_622;Local - Spot - Excluding - Spot structure -!HISTORY_MSG_623;Local - Exp Chroma compensation -!HISTORY_MSG_624;Local - Color correction grid -!HISTORY_MSG_625;Local - Color correction strength -!HISTORY_MSG_626;Local - Color correction Method -!HISTORY_MSG_627;Local - Shadow Highlight -!HISTORY_MSG_628;Local - SH Highlight -!HISTORY_MSG_629;Local - SH H tonalwidth -!HISTORY_MSG_630;Local - SH Shadows -!HISTORY_MSG_631;Local - SH S tonalwidth -!HISTORY_MSG_632;Local - SH radius -!HISTORY_MSG_633;Local - SH Scope -!HISTORY_MSG_634;Local - radius color -!HISTORY_MSG_635;Local - radius Exp -!HISTORY_MSG_636;Local - Tool added -!HISTORY_MSG_637;Local - SH Mask C -!HISTORY_MSG_638;Local - SH Mask L -!HISTORY_MSG_639;Local - SH Mask H -!HISTORY_MSG_640;Local - SH blend -!HISTORY_MSG_641;Local - Use SH mask -!HISTORY_MSG_642;Local - radius SH -!HISTORY_MSG_643;Local - Blur SH -!HISTORY_MSG_644;Local - inverse SH -!HISTORY_MSG_645;Local - SD - ab-L balance -!HISTORY_MSG_646;Local - Exp mask chroma -!HISTORY_MSG_647;Local - Exp mask gamma -!HISTORY_MSG_648;Local - Exp mask slope -!HISTORY_MSG_649;Local - Exp soft radius -!HISTORY_MSG_650;Local - Color mask chroma -!HISTORY_MSG_651;Local - Color mask gamma -!HISTORY_MSG_652;Local - Color mask slope -!HISTORY_MSG_653;Local - SH mask chroma -!HISTORY_MSG_654;Local - SH mask gamma -!HISTORY_MSG_655;Local - SH mask slope -!HISTORY_MSG_656;Local - Color soft radius -!HISTORY_MSG_657;Local - Retinex Reduce artifacts -!HISTORY_MSG_658;Local - CBDL soft radius -!HISTORY_MSG_659;Local - TG - Transition decay -!HISTORY_MSG_660;Local - cbdl clarity -!HISTORY_MSG_661;Local - cbdl contrast residual -!HISTORY_MSG_662;Local - Denoise lum f 0 -!HISTORY_MSG_663;Local - Denoise lum f 2 +HISTORY_MSG_581;LA - Ruisverm. lum f 1 +HISTORY_MSG_582;LA - Ruisverm. lum c +HISTORY_MSG_583;LA - Ruisverm. lum detail +HISTORY_MSG_584;LA - Ruisverm. equalizer Wit-Zwart +HISTORY_MSG_585;LA - Ruisverm. chro f +HISTORY_MSG_586;LA - Ruisverm. chro c +HISTORY_MSG_587;LA - Ruisverm. chro detail +HISTORY_MSG_588;LA - Ruisverm. equalizer Blauw-Rood +HISTORY_MSG_589;LA - Ruisverm. bilateraal +HISTORY_MSG_590;LA - Ruisverm. bereik +HISTORY_MSG_591;LA - Voorkom kleurverschuiving +HISTORY_MSG_592;LA - Sh Contrast +HISTORY_MSG_593;LA - LA contrast +HISTORY_MSG_594;LA - Lokaal contrast straal +HISTORY_MSG_595;LA - Lokaal contrast hoeveelheid +HISTORY_MSG_596;LA - Lokaal contrast donkerte +HISTORY_MSG_597;LA - Lokaal contrast lichtheid +HISTORY_MSG_598;LA - Lokaal contrast bereik +HISTORY_MSG_599;LA - Retinex ontnevel +HISTORY_MSG_600;LA - Zacht licht activeer +HISTORY_MSG_601;LA - Zacht licht kracht +HISTORY_MSG_602;LA - Zacht licht bereik +HISTORY_MSG_603;LA - Sh Vervagingsradius +HISTORY_MSG_605;LA - Keuze maskervoorbeeld +HISTORY_MSG_606;LA - Spot geslecteerd +HISTORY_MSG_607;LA - Kleurmasker C +HISTORY_MSG_608;LA - Kleurmasker L +HISTORY_MSG_609;LA - Bel.masker C +HISTORY_MSG_610;LA - Bel.masker L +HISTORY_MSG_611;LA - Kleurmasker H +HISTORY_MSG_612;LA - Kleur structuur +HISTORY_MSG_613;LA - Bel. structuur +HISTORY_MSG_614;LA - Bel.masker H +HISTORY_MSG_615;LA - Meng kleur +HISTORY_MSG_616;LA - Meng bel. +HISTORY_MSG_617;LA - Vervaag Bel. +HISTORY_MSG_618;LA - Gebruik kleurmasker +HISTORY_MSG_619;LA - Gebruik bel.masker +HISTORY_MSG_620;LA - Meng col +HISTORY_MSG_621;LA - Bel. omgekeerd +HISTORY_MSG_622;LA - Spot - Uitsluiting - Spotstructuur +HISTORY_MSG_623;LA - Bel. Chroma-compensatie +HISTORY_MSG_624;LA - Kleurcorrectieraster +HISTORY_MSG_625;LA - Kleurcorrectie kracht +HISTORY_MSG_626;LA - Kleurcorrectie methode +HISTORY_MSG_627;LA - Schaduw Hoge lichten +HISTORY_MSG_628;LA - SH Hoge lichten +HISTORY_MSG_629;LA - SH H tonaalomvang +HISTORY_MSG_630;LA - SH Schaduwen +HISTORY_MSG_631;LA - SH S tonaalomvang +HISTORY_MSG_632;LA - SH straal +HISTORY_MSG_633;LA - SH bereik +HISTORY_MSG_634;LA - straal kleur +HISTORY_MSG_635;LA - straal Bel. +HISTORY_MSG_636;LA - Gereedschap toegevoegd +HISTORY_MSG_637;LA - SH Masker C +HISTORY_MSG_638;LA - SH Masker L +HISTORY_MSG_639;LA - SH Masker H +HISTORY_MSG_640;LA - SH meng +HISTORY_MSG_641;LA - Gebruik SH-masker +HISTORY_MSG_642;LA - Straal SH +HISTORY_MSG_643;LA - Vervaag SH +HISTORY_MSG_644;LA - Keer SH om +HISTORY_MSG_645;LA - SD - ab-L-balans +HISTORY_MSG_646;LA - Bel.masker chroma +HISTORY_MSG_647;LA - Bel.masker gamma +HISTORY_MSG_648;LA - Bel.masker helling +HISTORY_MSG_649;LA - Bel. verzachting straal +HISTORY_MSG_650;LA - Kleurmasker chroma +HISTORY_MSG_651;LA - Kleurmasker gamma +HISTORY_MSG_652;LA - Kleurmasker helling +HISTORY_MSG_653;LA - SH-masker chroma +HISTORY_MSG_654;LA - SH-masker gamma +HISTORY_MSG_655;LA - SH-masker helling +HISTORY_MSG_656;LA - Kleur zachte radius +HISTORY_MSG_657;LA - Retinex verminder onregelmatigheden +HISTORY_MSG_658;LA - CBDL zachte radius +HISTORY_MSG_659;LA - TG - Transitieverval +HISTORY_MSG_660;LA - CBDL klaarheid +HISTORY_MSG_661;LA - CBDL residueel contrast +HISTORY_MSG_662;LA - Verminder ruis lum f 0 +HISTORY_MSG_663;LA - Verminder ruis lum f 2 !HISTORY_MSG_664;--unused-- -!HISTORY_MSG_665;Local - cbdl mask Blend -!HISTORY_MSG_666;Local - cbdl mask radius -!HISTORY_MSG_667;Local - cbdl mask chroma -!HISTORY_MSG_668;Local - cbdl mask gamma -!HISTORY_MSG_669;Local - cbdl mask slope -!HISTORY_MSG_670;Local - cbdl mask C -!HISTORY_MSG_671;Local - cbdl mask L -!HISTORY_MSG_672;Local - cbdl mask CL -!HISTORY_MSG_673;Local - Use cbdl mask -!HISTORY_MSG_674;Local - Tool removed -!HISTORY_MSG_675;Local - TM soft radius -!HISTORY_MSG_676;Local - TG - Transition differentiation -!HISTORY_MSG_677;Local - TM amount -!HISTORY_MSG_678;Local - TM saturation -!HISTORY_MSG_679;Local - Retinex mask C -!HISTORY_MSG_680;Local - Retinex mask L -!HISTORY_MSG_681;Local - Retinex mask CL -!HISTORY_MSG_682;Local - Retinex mask -!HISTORY_MSG_683;Local - Retinex mask Blend -!HISTORY_MSG_684;Local - Retinex mask radius -!HISTORY_MSG_685;Local - Retinex mask chroma -!HISTORY_MSG_686;Local - Retinex mask gamma -!HISTORY_MSG_687;Local - Retinex mask slope -!HISTORY_MSG_688;Local - Tool removed -!HISTORY_MSG_689;Local - Retinex mask transmission map -!HISTORY_MSG_690;Local - Retinex scale -!HISTORY_MSG_691;Local - Retinex darkness -!HISTORY_MSG_692;Local - Retinex lightness -!HISTORY_MSG_693;Local - Retinex threshold -!HISTORY_MSG_694;Local - Retinex Laplacian threshold -!HISTORY_MSG_695;Local - Soft method -!HISTORY_MSG_696;Local - Retinex Normalize -!HISTORY_MSG_697;Local - TM Normalize -!HISTORY_MSG_698;Local - Local contrast Fast Fourier -!HISTORY_MSG_699;Local - Retinex Fast Fourier -!HISTORY_MSG_701;Local - Exp Shadows -!HISTORY_MSG_702;Local - Exp Method -!HISTORY_MSG_703;Local - Exp Laplacian threshold -!HISTORY_MSG_704;Local - Exp PDE balance -!HISTORY_MSG_705;Local - Exp linearity -!HISTORY_MSG_706;Local - TM mask C -!HISTORY_MSG_707;Local - TM mask L -!HISTORY_MSG_708;Local - TM mask CL -!HISTORY_MSG_709;Local - use TM mask -!HISTORY_MSG_710;Local - TM mask Blend -!HISTORY_MSG_711;Local - TM mask radius -!HISTORY_MSG_712;Local - TM mask chroma -!HISTORY_MSG_713;Local - TM mask gamma -!HISTORY_MSG_714;Local - TM mask slope -!HISTORY_MSG_716;Local - Local method -!HISTORY_MSG_717;Local - Local contrast -!HISTORY_MSG_718;Local - Local contrast levels -!HISTORY_MSG_719;Local - Local contrast residual L -!HISTORY_MSG_720;Local - Blur mask C -!HISTORY_MSG_721;Local - Blur mask L -!HISTORY_MSG_722;Local - Blur mask CL -!HISTORY_MSG_723;Local - use Blur mask -!HISTORY_MSG_725;Local - Blur mask Blend -!HISTORY_MSG_726;Local - Blur mask radius -!HISTORY_MSG_727;Local - Blur mask chroma -!HISTORY_MSG_728;Local - Blur mask gamma -!HISTORY_MSG_729;Local - Blur mask slope -!HISTORY_MSG_730;Local - Blur method -!HISTORY_MSG_731;Local - median method -!HISTORY_MSG_732;Local - median iterations -!HISTORY_MSG_733;Local - soft radius -!HISTORY_MSG_734;Local - detail -!HISTORY_MSG_738;Local - Local contrast Merge L -!HISTORY_MSG_739;Local - Local contrast Soft radius -!HISTORY_MSG_740;Local - Local contrast Merge C -!HISTORY_MSG_741;Local - Local contrast Residual C -!HISTORY_MSG_742;Local - Exp Laplacian gamma -!HISTORY_MSG_743;Local - Exp Fattal Amount -!HISTORY_MSG_744;Local - Exp Fattal Detail -!HISTORY_MSG_745;Local - Exp Fattal Offset -!HISTORY_MSG_746;Local - Exp Fattal Sigma -!HISTORY_MSG_747;Local Spot created -!HISTORY_MSG_748;Local - Exp Denoise -!HISTORY_MSG_749;Local - Reti Depth -!HISTORY_MSG_750;Local - Reti Mode log - lin -!HISTORY_MSG_751;Local - Reti Dehaze saturation -!HISTORY_MSG_752;Local - Reti Offset -!HISTORY_MSG_753;Local - Reti Transmission map -!HISTORY_MSG_754;Local - Reti Clip -!HISTORY_MSG_755;Local - TM use tm mask -!HISTORY_MSG_756;Local - Exp use algo exposure mask -!HISTORY_MSG_757;Local - Exp Laplacian mask -!HISTORY_MSG_758;Local - Reti Laplacian mask -!HISTORY_MSG_759;Local - Exp Laplacian mask -!HISTORY_MSG_760;Local - Color Laplacian mask -!HISTORY_MSG_761;Local - SH Laplacian mask -!HISTORY_MSG_762;Local - cbdl Laplacian mask -!HISTORY_MSG_763;Local - Blur Laplacian mask -!HISTORY_MSG_764;Local - Solve PDE Laplacian mask -!HISTORY_MSG_765;Local - Denoise Detail threshold -!HISTORY_MSG_766;Local - Blur Fast Fourier -!HISTORY_MSG_767;Local - Grain Iso -!HISTORY_MSG_768;Local - Grain Strength -!HISTORY_MSG_769;Local - Grain Scale -!HISTORY_MSG_770;Local - Color Mask contrast curve -!HISTORY_MSG_771;Local - Exp Mask contrast curve -!HISTORY_MSG_772;Local - SH Mask contrast curve -!HISTORY_MSG_773;Local - TM Mask contrast curve -!HISTORY_MSG_774;Local - Reti Mask contrast curve -!HISTORY_MSG_775;Local - CBDL Mask contrast curve -!HISTORY_MSG_776;Local - Blur Denoise Mask contrast curve -!HISTORY_MSG_777;Local - Blur Mask local contrast curve -!HISTORY_MSG_778;Local - Mask highlights -!HISTORY_MSG_779;Local - Color Mask local contrast curve -!HISTORY_MSG_780;Local - Color Mask shadows -!HISTORY_MSG_781;Local - Contrast Mask Wavelet level -!HISTORY_MSG_782;Local - Blur Denoise Mask Wavelet levels -!HISTORY_MSG_783;Local - Color Wavelet levels -!HISTORY_MSG_784;Local - Mask - ΔE Image Mask -!HISTORY_MSG_785;Local - Mask - Scope -!HISTORY_MSG_786;Local - SH method -!HISTORY_MSG_787;Local - Equalizer multiplier -!HISTORY_MSG_788;Local - Equalizer detail -!HISTORY_MSG_789;Local - SH mask amount -!HISTORY_MSG_790;Local - SH mask anchor -!HISTORY_MSG_791;Local - Mask Short L curves -!HISTORY_MSG_792;Local - Mask - Background -!HISTORY_MSG_793;Local - SH TRC gamma -!HISTORY_MSG_794;Local - SH TRC slope -!HISTORY_MSG_795;Local - Mask save restore image -!HISTORY_MSG_796;Local - SC - Recursive references -!HISTORY_MSG_797;Local - Merge Original method -!HISTORY_MSG_798;Local - Opacity -!HISTORY_MSG_799;Local - Color RGB ToneCurve -!HISTORY_MSG_800;Local - Color ToneCurve Method -!HISTORY_MSG_801;Local - Color ToneCurve Special -!HISTORY_MSG_802;Local - Contrast threshold -!HISTORY_MSG_803;Local - Color Merge -!HISTORY_MSG_804;Local - Color mask Structure -!HISTORY_MSG_805;Local - Blur Noise mask Structure -!HISTORY_MSG_806;Local - Color mask Structure as tool -!HISTORY_MSG_807;Local - Blur Noise mask Structure as tool -!HISTORY_MSG_808;Local - Color mask curve H(H) -!HISTORY_MSG_809;Local - Vib mask curve C(C) -!HISTORY_MSG_810;Local - Vib mask curve L(L) -!HISTORY_MSG_811;Local - Vib mask curve LC(H) -!HISTORY_MSG_813;Local - Use Vib mask -!HISTORY_MSG_814;Local - Vib mask Blend -!HISTORY_MSG_815;Local - Vib mask radius -!HISTORY_MSG_816;Local - Vib mask chroma -!HISTORY_MSG_817;Local - Vib mask gamma -!HISTORY_MSG_818;Local - Vib mask slope -!HISTORY_MSG_819;Local - Vib mask laplacian -!HISTORY_MSG_820;Local - Vib mask contrast curve -!HISTORY_MSG_821;Local - color grid background -!HISTORY_MSG_822;Local - color background merge -!HISTORY_MSG_823;Local - color background luminance -!HISTORY_MSG_824;Local - Exp gradient mask strength -!HISTORY_MSG_825;Local - Exp gradient mask angle -!HISTORY_MSG_826;Local - Exp gradient strength -!HISTORY_MSG_827;Local - Exp gradient angle -!HISTORY_MSG_828;Local - SH gradient strength -!HISTORY_MSG_829;Local - SH gradient angle -!HISTORY_MSG_830;Local - Color gradient strength L -!HISTORY_MSG_831;Local - Color gradient angle -!HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient -!HISTORY_MSG_834;Local - Color gradient strength H -!HISTORY_MSG_835;Local - Vib gradient strength L -!HISTORY_MSG_836;Local - Vib gradient angle -!HISTORY_MSG_837;Local - Vib gradient strength C -!HISTORY_MSG_838;Local - Vib gradient strength H -!HISTORY_MSG_839;Local - Software complexity -!HISTORY_MSG_840;Local - CL Curve -!HISTORY_MSG_841;Local - LC curve -!HISTORY_MSG_842;Local - Blur mask Radius -!HISTORY_MSG_843;Local - Blur mask Contrast Threshold -!HISTORY_MSG_844;Local - Blur mask FFTW -!HISTORY_MSG_845;Local - Log encoding -!HISTORY_MSG_846;Local - Log encoding auto -!HISTORY_MSG_847;Local - Log encoding Source -!HISTORY_MSG_849;Local - Log encoding Source auto -!HISTORY_MSG_850;Local - Log encoding B_Ev -!HISTORY_MSG_851;Local - Log encoding W_Ev -!HISTORY_MSG_852;Local - Log encoding Target -!HISTORY_MSG_853;Local - Log encodind loc contrast -!HISTORY_MSG_854;Local - Log encodind Scope -!HISTORY_MSG_855;Local - Log encoding Whole image -!HISTORY_MSG_856;Local - Log encoding Shadows range -!HISTORY_MSG_857;Local - Wavelet blur residual -!HISTORY_MSG_858;Local - Wavelet blur luminance only -!HISTORY_MSG_859;Local - Wavelet max blur -!HISTORY_MSG_860;Local - Wavelet blur levels -!HISTORY_MSG_861;Local - Wavelet contrast levels -!HISTORY_MSG_862;Local - Wavelet contrast attenuation -!HISTORY_MSG_863;Local - Wavelet merge original image -!HISTORY_MSG_864;Local - Wavelet dir contrast attenuation -!HISTORY_MSG_865;Local - Wavelet dir contrast delta -!HISTORY_MSG_866;Local - Wavelet dir compression -!HISTORY_MSG_868;Local - SD - C-H balance -!HISTORY_MSG_869;Local - Denoise by level -!HISTORY_MSG_870;Local - Wavelet mask curve H -!HISTORY_MSG_871;Local - Wavelet mask curve C -!HISTORY_MSG_872;Local - Wavelet mask curve L -!HISTORY_MSG_873;Local - Wavelet mask -!HISTORY_MSG_875;Local - Wavelet mask blend -!HISTORY_MSG_876;Local - Wavelet mask smooth -!HISTORY_MSG_877;Local - Wavelet mask chroma -!HISTORY_MSG_878;Local - Wavelet mask contrast curve -!HISTORY_MSG_879;Local - Wavelet contrast chroma -!HISTORY_MSG_880;Local - Wavelet blur chroma -!HISTORY_MSG_881;Local - Wavelet contrast offset -!HISTORY_MSG_882;Local - Wavelet blur -!HISTORY_MSG_883;Local - Wavelet contrast by level -!HISTORY_MSG_884;Local - Wavelet dir contrast -!HISTORY_MSG_885;Local - Wavelet tone mapping -!HISTORY_MSG_886;Local - Wavelet tone mapping compress -!HISTORY_MSG_887;Local - Wavelet tone mapping compress residual -!HISTORY_MSG_888;Local - Contrast Wavelet Balance Threshold -!HISTORY_MSG_889;Local - Contrast Wavelet Graduated Strength -!HISTORY_MSG_890;Local - Contrast Wavelet Graduated angle -!HISTORY_MSG_891;Local - Contrast Wavelet Graduated -!HISTORY_MSG_892;Local - Log Encoding Graduated Strength -!HISTORY_MSG_893;Local - Log Encoding Graduated angle -!HISTORY_MSG_894;Local - SD - ΔE preview color intensity -!HISTORY_MSG_897;Local - Contrast Wavelet ES strength -!HISTORY_MSG_898;Local - Contrast Wavelet ES radius -!HISTORY_MSG_899;Local - Contrast Wavelet ES detail -!HISTORY_MSG_900;Local - Contrast Wavelet ES gradient -!HISTORY_MSG_901;Local - Contrast Wavelet ES threshold low -!HISTORY_MSG_902;Local - Contrast Wavelet ES threshold high -!HISTORY_MSG_903;Local - Contrast Wavelet ES local contrast -!HISTORY_MSG_904;Local - Contrast Wavelet ES first level -!HISTORY_MSG_905;Local - Contrast Wavelet Edge Sharpness -!HISTORY_MSG_906;Local - Contrast Wavelet ES sensitivity -!HISTORY_MSG_907;Local - Contrast Wavelet ES amplification -!HISTORY_MSG_908;Local - Contrast Wavelet ES neighboring -!HISTORY_MSG_909;Local - Contrast Wavelet ES show -!HISTORY_MSG_910;Local - SC - Wavelet Edge performance -!HISTORY_MSG_911;Local - Blur Chroma Luma -!HISTORY_MSG_912;Local - Blur Guide filter strength -!HISTORY_MSG_913;Local - Contrast Wavelet Sigma DR -!HISTORY_MSG_914;Local - Blur Wavelet Sigma BL -!HISTORY_MSG_915;Local - Edge Wavelet Sigma ED -!HISTORY_MSG_916;Local - Residual wavelet shadows -!HISTORY_MSG_917;Local - Residual wavelet shadows threshold -!HISTORY_MSG_918;Local - Residual wavelet highlights -!HISTORY_MSG_919;Local - Residual wavelet highlights threshold -!HISTORY_MSG_920;Local - Wavelet sigma LC -!HISTORY_MSG_921;Local - Wavelet Graduated sigma LC2 -!HISTORY_MSG_922;Local - SC - Changes in B/W -!HISTORY_MSG_923;Local - Tool complexity mode -!HISTORY_MSG_924;--unused-- -!HISTORY_MSG_925;Local - Scope (color tools) -!HISTORY_MSG_926;Local - Show mask type -!HISTORY_MSG_927;Local - Shadow -!HISTORY_MSG_928;Local - Common color mask -!HISTORY_MSG_929;Local - Mask common scope -!HISTORY_MSG_930;Local - Mask Common blend luma -!HISTORY_MSG_931;Local - Mask Common enable -!HISTORY_MSG_932;Local - Mask Common radius soft -!HISTORY_MSG_933;Local - Mask Common laplacian -!HISTORY_MSG_934;Local - Mask Common chroma -!HISTORY_MSG_935;Local - Mask Common gamma -!HISTORY_MSG_936;Local - Mask Common slope -!HISTORY_MSG_937;Local - Mask Common curve C(C) -!HISTORY_MSG_938;Local - Mask Common curve L(L) -!HISTORY_MSG_939;Local - Mask Common curve LC(H) -!HISTORY_MSG_940;Local - Mask Common structure as tool -!HISTORY_MSG_941;Local - Mask Common structure strength -!HISTORY_MSG_942;Local - Mask Common H(H) curve -!HISTORY_MSG_943;Local - Mask Common FFT -!HISTORY_MSG_944;Local - Mask Common Blur radius -!HISTORY_MSG_945;Local - Mask Common contrast threshold -!HISTORY_MSG_946;Local - Mask Common shadows -!HISTORY_MSG_947;Local - Mask Common Contrast curve -!HISTORY_MSG_948;Local - Mask Common Wavelet curve -!HISTORY_MSG_949;Local - Mask Common Threshold levels -!HISTORY_MSG_950;Local - Mask Common GF strength -!HISTORY_MSG_951;Local - Mask Common GF angle -!HISTORY_MSG_952;Local - Mask Common soft radius -!HISTORY_MSG_953;Local - Mask Common blend chroma -!HISTORY_MSG_954;Local - Show-hide tools -!HISTORY_MSG_955;Local - Enable Spot -!HISTORY_MSG_956;Local - CH Curve -!HISTORY_MSG_957;Local - Denoise mode -!HISTORY_MSG_958;Local - Show/hide settings -!HISTORY_MSG_959;Local - Inverse blur -!HISTORY_MSG_960;Local - Log encoding - cat16 -!HISTORY_MSG_961;Local - Log encoding Ciecam -!HISTORY_MSG_962;Local - Log encoding Absolute luminance source -!HISTORY_MSG_963;Local - Log encoding Absolute luminance target -!HISTORY_MSG_964;Local - Log encoding Surround -!HISTORY_MSG_965;Local - Log encoding Saturation s -!HISTORY_MSG_966;Local - Log encoding Contrast J -!HISTORY_MSG_967;Local - Log encoding Mask curve C -!HISTORY_MSG_968;Local - Log encoding Mask curve L -!HISTORY_MSG_969;Local - Log encoding Mask curve H -!HISTORY_MSG_970;Local - Log encoding Mask enable -!HISTORY_MSG_971;Local - Log encoding Mask blend -!HISTORY_MSG_972;Local - Log encoding Mask radius -!HISTORY_MSG_973;Local - Log encoding Mask chroma -!HISTORY_MSG_974;Local - Log encoding Mask contrast -!HISTORY_MSG_975;Local - Log encoding Lightness J -!HISTORY_MSG_977;Local - Log encoding Contrast Q -!HISTORY_MSG_978;Local - Log encoding Sursource -!HISTORY_MSG_979;Local - Log encoding Brightness Q -!HISTORY_MSG_980;Local - Log encoding Colorfulness M -!HISTORY_MSG_981;Local - Log encoding Strength -!HISTORY_MSG_982;Local - Equalizer hue -!HISTORY_MSG_983;Local - denoise threshold mask high -!HISTORY_MSG_984;Local - denoise threshold mask low -!HISTORY_MSG_985;Local - denoise Laplacian -!HISTORY_MSG_986;Local - denoise reinforce -!HISTORY_MSG_987;Local - GF recovery threshold -!HISTORY_MSG_988;Local - GF threshold mask low -!HISTORY_MSG_989;Local - GF threshold mask high -!HISTORY_MSG_990;Local - Denoise recovery threshold -!HISTORY_MSG_991;Local - Denoise threshold mask low -!HISTORY_MSG_992;Local - Denoise threshold mask high -!HISTORY_MSG_993;Local - Denoise Inverse algo -!HISTORY_MSG_994;Local - GF Inverse algo -!HISTORY_MSG_995;Local - Denoise decay -!HISTORY_MSG_996;Local - Color recovery threshold -!HISTORY_MSG_997;Local - Color threshold mask low -!HISTORY_MSG_998;Local - Color threshold mask high -!HISTORY_MSG_999;Local - Color decay -!HISTORY_MSG_1000;Local - Denoise luminance gray -!HISTORY_MSG_1001;Local - Log recovery threshold -!HISTORY_MSG_1002;Local - Log threshold mask low -!HISTORY_MSG_1003;Local - Log threshold mask high -!HISTORY_MSG_1004;Local - Log decay -!HISTORY_MSG_1005;Local - Exp recovery threshold -!HISTORY_MSG_1006;Local - Exp threshold mask low -!HISTORY_MSG_1007;Local - Exp threshold mask high -!HISTORY_MSG_1008;Local - Exp decay -!HISTORY_MSG_1009;Local - SH recovery threshold -!HISTORY_MSG_1010;Local - SH threshold mask low -!HISTORY_MSG_1011;Local - SH threshold mask high -!HISTORY_MSG_1012;Local - SH decay -!HISTORY_MSG_1013;Local - vib recovery threshold -!HISTORY_MSG_1014;Local - vib threshold mask low -!HISTORY_MSG_1015;Local - vib threshold mask high -!HISTORY_MSG_1016;Local - vib decay -!HISTORY_MSG_1017;Local - lc recovery threshold -!HISTORY_MSG_1018;Local - lc threshold mask low -!HISTORY_MSG_1019;Local - lc threshold mask high -!HISTORY_MSG_1020;Local - lc decay -!HISTORY_MSG_1021;Local - Denoise chrominance gray -!HISTORY_MSG_1022;Local - TM recovery threshold -!HISTORY_MSG_1023;Local - TM threshold mask low -!HISTORY_MSG_1024;Local - TM threshold mask high -!HISTORY_MSG_1025;Local - TM decay -!HISTORY_MSG_1026;Local - cbdl recovery threshold -!HISTORY_MSG_1027;Local - cbdl threshold mask low -!HISTORY_MSG_1028;Local - cbdl threshold mask high -!HISTORY_MSG_1029;Local - cbdl decay -!HISTORY_MSG_1030;Local - reti recovery threshold -!HISTORY_MSG_1031;Local - reti threshold mask low -!HISTORY_MSG_1032;Local - reti threshold mask high -!HISTORY_MSG_1033;Local - reti decay -!HISTORY_MSG_1034;Local - Nlmeans - strength -!HISTORY_MSG_1035;Local - Nlmeans - detail -!HISTORY_MSG_1036;Local - Nlmeans - patch -!HISTORY_MSG_1037;Local - Nlmeans - radius -!HISTORY_MSG_1038;Local - Nlmeans - gamma -!HISTORY_MSG_1039;Local - Grain - gamma -!HISTORY_MSG_1040;Local - SC - Soft radius -!HISTORY_MSG_1041;Local - Spot - Munsell -!HISTORY_MSG_1042;Local - Log encoding - threshold -!HISTORY_MSG_1043;Local - Exp - normalize -!HISTORY_MSG_1044;Local - Local contrast strength -!HISTORY_MSG_1045;Local - Color and Light strength -!HISTORY_MSG_1046;Local - Denoise strength -!HISTORY_MSG_1047;Local - SH and Tone Equalizer strength -!HISTORY_MSG_1048;Local - DR and Exposure strength -!HISTORY_MSG_1049;Local - TM strength -!HISTORY_MSG_1050;Local - Log encoding chroma -!HISTORY_MSG_1051;Local - Residual wavelet gamma -!HISTORY_MSG_1052;Local - Residual wavelet slope -!HISTORY_MSG_1053;Local - Denoise gamma -!HISTORY_MSG_1054;Local - Wavelet gamma -!HISTORY_MSG_1055;Local - Color and Light gamma -!HISTORY_MSG_1056;Local - DR and Exposure gamma -!HISTORY_MSG_1057;Local - CIECAM Enabled -!HISTORY_MSG_1058;Local - CIECAM Overall strength -!HISTORY_MSG_1059;Local - CIECAM Autogray -!HISTORY_MSG_1060;Local - CIECAM Mean luminance source -!HISTORY_MSG_1061;Local - CIECAM Source absolute -!HISTORY_MSG_1062;Local - CIECAM Surround Source -!HISTORY_MSG_1063;Local - CIECAM Saturation -!HISTORY_MSG_1064;Local - CIECAM Chroma -!HISTORY_MSG_1065;Local - CIECAM lightness J -!HISTORY_MSG_1066;Local - CIECAM brightness -!HISTORY_MSG_1067;Local - CIECAM Contrast J -!HISTORY_MSG_1068;Local - CIECAM threshold -!HISTORY_MSG_1069;Local - CIECAM contrast Q -!HISTORY_MSG_1070;Local - CIECAM colorfullness -!HISTORY_MSG_1071;Local - CIECAM Absolute luminance -!HISTORY_MSG_1072;Local - CIECAM Mean luminance -!HISTORY_MSG_1073;Local - CIECAM Cat16 -!HISTORY_MSG_1074;Local - CIECAM Local contrast -!HISTORY_MSG_1075;Local - CIECAM Surround viewing -!HISTORY_MSG_1076;Local - CIECAM Scope -!HISTORY_MSG_1077;Local - CIECAM Mode -!HISTORY_MSG_1078;Local - Red and skin protection -!HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J -!HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold -!HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv -!HISTORY_MSG_1083;Local - CIECAM Hue -!HISTORY_MSG_1084;Local - Uses Black Ev - White Ev -!HISTORY_MSG_1085;Local - Jz lightness -!HISTORY_MSG_1086;Local - Jz contrast -!HISTORY_MSG_1087;Local - Jz chroma -!HISTORY_MSG_1088;Local - Jz hue -!HISTORY_MSG_1089;Local - Jz Sigmoid strength -!HISTORY_MSG_1090;Local - Jz Sigmoid threshold -!HISTORY_MSG_1091;Local - Jz Sigmoid blend -!HISTORY_MSG_1092;Local - Jz adaptation -!HISTORY_MSG_1093;Local - CAM model -!HISTORY_MSG_1094;Local - Jz highligths -!HISTORY_MSG_1095;Local - Jz highligths thr -!HISTORY_MSG_1096;Local - Jz shadows -!HISTORY_MSG_1097;Local - Jz shadows thr -!HISTORY_MSG_1098;Local - Jz radius SH -!HISTORY_MSG_1099;Local - Cz(Hz) Curve -!HISTORY_MSG_1100;Local - Jz reference 100 -!HISTORY_MSG_1101;Local - Jz PQ remap -!HISTORY_MSG_1102;Local - Jz(Hz) Curve -!HISTORY_MSG_1103;Local - Vibrance gamma -!HISTORY_MSG_1104;Local - Sharp gamma -!HISTORY_MSG_1105;Local - CIECAM Tone method -!HISTORY_MSG_1106;Local - CIECAM Tone curve -!HISTORY_MSG_1107;Local - CIECAM Color method -!HISTORY_MSG_1108;Local - CIECAM Color curve -!HISTORY_MSG_1109;Local - Jz(Jz) curve -!HISTORY_MSG_1110;Local - Cz(Cz) curve -!HISTORY_MSG_1111;Local - Cz(Jz) curve -!HISTORY_MSG_1112;Local - forcejz -!HISTORY_MSG_1113;Local - HDR PQ -!HISTORY_MSG_1114;Local - Cie mask enable -!HISTORY_MSG_1115;Local - Cie mask curve C -!HISTORY_MSG_1116;Local - Cie mask curve L -!HISTORY_MSG_1117;Local - Cie mask curve H -!HISTORY_MSG_1118;Local - Cie mask blend -!HISTORY_MSG_1119;Local - Cie mask radius -!HISTORY_MSG_1120;Local - Cie mask chroma -!HISTORY_MSG_1121;Local - Cie mask contrast curve -!HISTORY_MSG_1122;Local - Cie mask recovery threshold -!HISTORY_MSG_1123;Local - Cie mask recovery dark -!HISTORY_MSG_1124;Local - Cie mask recovery light -!HISTORY_MSG_1125;Local - Cie mask recovery decay -!HISTORY_MSG_1126;Local - Cie mask laplacian -!HISTORY_MSG_1127;Local - Cie mask gamma -!HISTORY_MSG_1128;Local - Cie mask slope -!HISTORY_MSG_1129;Local - Cie Relative luminance -!HISTORY_MSG_1130;Local - Cie Saturation Jz -!HISTORY_MSG_1131;Local - Mask - Denoise -!HISTORY_MSG_1132;Local - Cie Wav sigma Jz -!HISTORY_MSG_1133;Local - Cie Wav level Jz -!HISTORY_MSG_1134;Local - Cie Wav local contrast Jz -!HISTORY_MSG_1135;Local - Cie Wav clarity Jz -!HISTORY_MSG_1136;Local - Cie Wav clarity Cz -!HISTORY_MSG_1137;Local - Cie Wav clarity Soft -!HISTORY_MSG_1138;Local - Local - Hz(Hz) Curve -!HISTORY_MSG_1139;Local - Jz soft Curves H -!HISTORY_MSG_1140;Local - Jz Threshold chroma -!HISTORY_MSG_1141;Local - chroma curve Jz(Hz) -!HISTORY_MSG_1142;Local - strength soft -!HISTORY_MSG_1143;Local - Jz blackev -!HISTORY_MSG_1144;Local - Jz whiteev -!HISTORY_MSG_1145;Local - Jz Log encoding -!HISTORY_MSG_1146;Local - Jz Log encoding target gray -!HISTORY_MSG_1147;Local - Jz BlackEv WhiteEv -!HISTORY_MSG_1148;Local - Jz Sigmoid -!HISTORY_MSG_1149;Local - Q Sigmoid -!HISTORY_MSG_1150;Local - Log encoding Q instead Sigmoid Q -!HISTORY_MSG_BLSHAPE;Blur by level -!HISTORY_MSG_BLURCWAV;Blur chroma -!HISTORY_MSG_BLURWAV;Blur luminance -!HISTORY_MSG_BLUWAV;Attenuation response -!HISTORY_MSG_CATCAT;CAL - Settings - Mode -!HISTORY_MSG_CATCOMPLEX;CAL - Settings - Complexity -!HISTORY_MSG_CATMODEL;CAL - Settings - CAM -!HISTORY_MSG_COMPLEX;Wavelet complexity -!HISTORY_MSG_COMPLEXRETI;Retinex complexity -!HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation -!HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness -!HISTORY_MSG_EDGEFFECT;Edge Attenuation response -!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata -!HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output -!HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Film negative color space -!HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Reference input -!HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell -!HISTORY_MSG_HLBL;Color propagation - blur -!HISTORY_MSG_HLTH;Inpaint opposed - gain threshold -!HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy -!HISTORY_MSG_ICM_AINTENT;Abstract profile intent -!HISTORY_MSG_ICM_BLUX;Primaries Blue X -!HISTORY_MSG_ICM_BLUY;Primaries Blue Y -!HISTORY_MSG_ICM_FBW;Black and White -!HISTORY_MSG_ICM_GAMUT;Gamut control -!HISTORY_MSG_ICM_GREX;Primaries Green X -!HISTORY_MSG_ICM_GREY;Primaries Green Y -!HISTORY_MSG_ICM_PRESER;Preserve neutral -!HISTORY_MSG_ICM_REDX;Primaries Red X -!HISTORY_MSG_ICM_REDY;Primaries Red Y -!HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method -!HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method -!HISTORY_MSG_ILLUM;CAL - SC - Illuminant -!HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -!HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift -!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera -!HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera -!HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera -!HISTORY_MSG_PERSP_CTRL_LINE;Perspective - Control lines -!HISTORY_MSG_PERSP_METHOD;Perspective - Method -!HISTORY_MSG_PERSP_PROJ_ANGLE;Perspective - Recovery -!HISTORY_MSG_PERSP_PROJ_ROTATE;Perspective - PCA rotation -!HISTORY_MSG_PERSP_PROJ_SHIFT;Perspective - PCA -!HISTORY_MSG_PIXELSHIFT_AVERAGE;PS - Average -!HISTORY_MSG_PREPROCWB_MODE;Preprocess WB Mode -!HISTORY_MSG_PROTAB;Protection -!HISTORY_MSG_RANGEAB;Range ab -!HISTORY_MSG_RESIZE_LONGEDGE;Resize - Long Edge -!HISTORY_MSG_RESIZE_SHORTEDGE;Resize - Short Edge -!HISTORY_MSG_SIGMACOL;Chroma Attenuation response -!HISTORY_MSG_SIGMADIR;Dir Attenuation response -!HISTORY_MSG_SIGMAFIN;Final contrast Attenuation response -!HISTORY_MSG_SIGMATON;Toning Attenuation response -!HISTORY_MSG_SPOT;Spot removal -!HISTORY_MSG_SPOT_ENTRY;Spot removal - Point modif. -!HISTORY_MSG_TEMPOUT;CAM02 automatic temperature -!HISTORY_MSG_THRESWAV;Balance threshold -!HISTORY_MSG_TONE_EQUALIZER_BANDS;Tone equalizer - Bands -!HISTORY_MSG_TONE_EQUALIZER_ENABLED;Tone equalizer -!HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot -!HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization -!HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map -!HISTORY_MSG_WAVBALCHROM;Equalizer chrominance -!HISTORY_MSG_WAVBALLUM;Equalizer luminance -!HISTORY_MSG_WAVBL;Blur levels -!HISTORY_MSG_WAVCHR;Blur levels - blur chroma -!HISTORY_MSG_WAVCHROMCO;Chroma coarse -!HISTORY_MSG_WAVCHROMFI;Chroma fine -!HISTORY_MSG_WAVCLARI;Clarity -!HISTORY_MSG_WAVDENLH;Level 5 -!HISTORY_MSG_WAVDENOISE;Local contrast -!HISTORY_MSG_WAVDENOISEH;High levels Local contrast -!HISTORY_MSG_WAVDETEND;Details soft -!HISTORY_MSG_WAVEDGS;Edge stopping -!HISTORY_MSG_WAVGUIDH;Local contrast-Hue equalizer -!HISTORY_MSG_WAVHUE;Equalizer hue -!HISTORY_MSG_WAVLABGRID_VALUE;Toning - exclude colors -!HISTORY_MSG_WAVLEVDEN;High level local contrast -!HISTORY_MSG_WAVLEVELSIGM;Denoise - radius -!HISTORY_MSG_WAVLEVSIGM;Radius -!HISTORY_MSG_WAVLIMDEN;Interaction 56 14 -!HISTORY_MSG_WAVLOWTHR;Threshold low contrast -!HISTORY_MSG_WAVMERGEC;Merge C -!HISTORY_MSG_WAVMERGEL;Merge L -!HISTORY_MSG_WAVMIXMET;Reference local contrast -!HISTORY_MSG_WAVOFFSET;Offset -!HISTORY_MSG_WAVOLDSH;Old algorithm -!HISTORY_MSG_WAVQUAMET;Denoise mode -!HISTORY_MSG_WAVRADIUS;Radius shadows-highlights -!HISTORY_MSG_WAVSCALE;Scale -!HISTORY_MSG_WAVSHOWMASK;Show wavelet mask -!HISTORY_MSG_WAVSIGM;Sigma -!HISTORY_MSG_WAVSIGMA;Attenuation response -!HISTORY_MSG_WAVSLIMET;Method -!HISTORY_MSG_WAVSOFTRAD;Soft radius clarity -!HISTORY_MSG_WAVSOFTRADEND;Soft radius final -!HISTORY_MSG_WAVSTREND;Strength soft -!HISTORY_MSG_WAVTHRDEN;Threshold local contrast -!HISTORY_MSG_WAVTHREND;Threshold local contrast -!HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° -!HISTORY_MSG_WBITC_CUSTOM;Itcwb Custom -!HISTORY_MSG_WBITC_DELTA;Itcwb Delta green -!HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student -!HISTORY_MSG_WBITC_FORCE;Itcwb Force -!HISTORY_MSG_WBITC_GREEN;Green refinement -!HISTORY_MSG_WBITC_MINSIZE;Patch min size -!HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple -!HISTORY_MSG_WBITC_OBS;Remove algo 2 passes -!HISTORY_MSG_WBITC_PONDER;Itcwb ponderated -!HISTORY_MSG_WBITC_PRECIS;Itcwb Precision -!HISTORY_MSG_WBITC_PRIM;Primaries -!HISTORY_MSG_WBITC_RGREEN;Itcwb Green range -!HISTORY_MSG_WBITC_SAMPLING;Low sampling -!HISTORY_MSG_WBITC_SIZE;Itcwb Size -!HISTORY_MSG_WBITC_SORTED;Itcwb ponderated -!HISTORY_MSG_WBITC_THRES;Itcwb Threshold -!ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater -!ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 -!INSPECTOR_WINDOW_TITLE;Inspector -!MAIN_TAB_LOCALLAB;Local -!MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings -!PARTIALPASTE_PREPROCWB;Preprocess White Balance -!PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory -!PREFERENCES_CIE;Ciecam -!PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments -!PREFERENCES_COMPLEXITY_EXP;Advanced -!PREFERENCES_COMPLEXITY_NORM;Standard -!PREFERENCES_COMPLEXITY_SIMP;Basic -!PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Bypass output profile -!PREFERENCES_EXTEDITOR_DIR;Output directory -!PREFERENCES_EXTEDITOR_DIR_CURRENT;Same as input image -!PREFERENCES_EXTEDITOR_DIR_CUSTOM;Custom -!PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir -!PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output -!PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application -!PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable -!PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command -!PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name -!PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Native command -!PREFERENCES_INSPECTORWINDOW;Open inspector in own window or fullscreen -!PREFERENCES_LENSFUNDBDIR;Lensfun database directory -!PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. -!PREFERENCES_LENSPROFILESDIR;Lens profiles directory -!PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) -!PREFERENCES_METADATA;Metadata -!PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars -!PREFERENCES_METADATA_SYNC_NONE;Off -!PREFERENCES_METADATA_SYNC_READ;Read only -!PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips -!PREFERENCES_TAB_FAVORITES;Favorites -!PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. -!PREFERENCES_TOOLPANEL_FAVORITE;Favorite -!PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel -!PREFERENCES_TOOLPANEL_TOOL;Tool -!PREFERENCES_WBA;White Balance -!PREFERENCES_WBACORR;White Balance - Automatic temperature correlation +HISTORY_MSG_665;LA - cbdl masker meng +HISTORY_MSG_666;LA - cbdl masker straal +HISTORY_MSG_667;LA - cbdl masker chroma +HISTORY_MSG_668;LA - cbdl masker gamma +HISTORY_MSG_669;LA - cbdl masker helling +HISTORY_MSG_670;LA - cbdl masker C +HISTORY_MSG_671;LA - cbdl masker L +HISTORY_MSG_672;LA - cbdl masker CL +HISTORY_MSG_673;LA - Gebruik cbdl masker +HISTORY_MSG_674;LA - Gereedschap verwijderd +HISTORY_MSG_675;LA - TM zacht straal +HISTORY_MSG_676;LA - TG - Transitiedifferentie +HISTORY_MSG_677;LA - TM hoeveelheid +HISTORY_MSG_678;LA - TM verzadiging +HISTORY_MSG_679;LA - Retinex masker C +HISTORY_MSG_680;LA - Retinex masker L +HISTORY_MSG_681;LA - Retinex masker CL +HISTORY_MSG_682;LA - Retinex masker +HISTORY_MSG_683;LA - Retinex masker meng +HISTORY_MSG_684;LA - Retinex masker straal +HISTORY_MSG_685;LA - Retinex masker chroma +HISTORY_MSG_686;LA - Retinex masker gamma +HISTORY_MSG_687;LA - Retinex masker helling +HISTORY_MSG_688;LA - Gereedschap verwijderd +HISTORY_MSG_689;LA - Retinex masker transmissiemap +HISTORY_MSG_690;LA - Retinex schaal +HISTORY_MSG_691;LA - Retinex donkerte +HISTORY_MSG_692;LA - Retinex lichtheid +HISTORY_MSG_693;LA - Retinex drempel +HISTORY_MSG_694;LA - Retinex Laplacian drempel +HISTORY_MSG_695;LA - Verzachting methode +HISTORY_MSG_696;LA - Retinex Normaliseer +HISTORY_MSG_697;LA - TM Normaliseer +HISTORY_MSG_698;LA - LA contrast Fast Fourier +HISTORY_MSG_699;LA - Retinex Fast Fourier +HISTORY_MSG_701;LA - Bel. Schaduwen +HISTORY_MSG_702;LA - Bel. Methode +HISTORY_MSG_703;LA - Bel. Laplacian drempel +HISTORY_MSG_704;LA - Bel. PDE-balans +HISTORY_MSG_705;LA - Bel. lineariteit +HISTORY_MSG_706;LA - TM masker C +HISTORY_MSG_707;LA - TM masker L +HISTORY_MSG_708;LA - TM masker CL +HISTORY_MSG_709;LA - gebruik TM-masker +HISTORY_MSG_710;LA - TM-masker meng +HISTORY_MSG_711;LA - TM-masker straal +HISTORY_MSG_712;LA - TM-masker chroma +HISTORY_MSG_713;LA - TM-masker gamma +HISTORY_MSG_714;LA - TM-masker helling +HISTORY_MSG_716;LA - LA methode +HISTORY_MSG_717;LA - LA contrast +HISTORY_MSG_718;LA - LA contrastniveaus +HISTORY_MSG_719;LA - LA contrast residueel L +HISTORY_MSG_720;LA - Vervagingsmasker C +HISTORY_MSG_721;LA - Vervagingsmasker L +HISTORY_MSG_722;LA - Vervagingsmasker CL +HISTORY_MSG_723;LA - Gebruik vervagingsmasker +HISTORY_MSG_725;LA - Vervagingsmasker meng +HISTORY_MSG_726;LA - Vervagingsmasker straal +HISTORY_MSG_727;LA - Vervagingsmasker chroma +HISTORY_MSG_728;LA - Vervagingsmasker gamma +HISTORY_MSG_729;LA - Vervagingsmasker helling +HISTORY_MSG_730;LA - Vervaging methode +HISTORY_MSG_731;LA - mediaanmethod +HISTORY_MSG_732;LA - mediaan herhalingen +HISTORY_MSG_733;LA - straal zacht +HISTORY_MSG_734;LA - detail +HISTORY_MSG_738;LA - Lokaal contrast meng L +HISTORY_MSG_739;LA - Lokaal contrast zacht straal +HISTORY_MSG_740;LA - Lokaal contrast Meng C +HISTORY_MSG_741;LA - Lokaal contrast Residueel C +HISTORY_MSG_742;LA - Exp Laplacian gamma +HISTORY_MSG_743;LA - Bel. Fattal Hoeveelheid +HISTORY_MSG_744;LA - Bel. Fattal Detail +HISTORY_MSG_745;LA - Bel. Fattal verschuiving +HISTORY_MSG_746;LA - Bel. Fattal Sigma +HISTORY_MSG_747;LA - Spot aangemaakt +HISTORY_MSG_748;LA - Bel. Ruisvermindering +HISTORY_MSG_749;LA - Reti Diepte +HISTORY_MSG_750;LA - Reti Modus log - lin +HISTORY_MSG_751;LA - Reti Ontnevel verzadiging +HISTORY_MSG_752;LA - Reti Verschuiving +HISTORY_MSG_753;LA - Reti Transmissiemap +HISTORY_MSG_754;LA - Reti Kap +HISTORY_MSG_755;LA - TM gebruik tm-masker +HISTORY_MSG_756;LA - Bel. gebruik algo belichtingsmasker +HISTORY_MSG_757;LA - Bel. Laplacian-masker +HISTORY_MSG_758;LA - Reti Laplacian-masker +HISTORY_MSG_759;LA - Bel. Laplacian-masker +HISTORY_MSG_760;LA - Kleur Laplacian masker +HISTORY_MSG_761;LA - SH Laplacian-masker +HISTORY_MSG_762;LA - cbdl Laplacian-masker +HISTORY_MSG_763;LA - Blur Laplacian-masker +HISTORY_MSG_764;LA - Solve PDE Laplacian-masker +HISTORY_MSG_765;LA - Ruisvermindering detaildrempel +HISTORY_MSG_766;LA - Vervaag Fast Fourier +HISTORY_MSG_767;LA - Korrel ISO +HISTORY_MSG_768;LA - Korrel Sterkte +HISTORY_MSG_769;LA - Korrel Schaal +HISTORY_MSG_770;LA - Kleurmasker contrastcurve +HISTORY_MSG_771;LA - Bel.masker contrastcurve +HISTORY_MSG_772;LA - SH-masker contrastcurve +HISTORY_MSG_773;LA - TM-Masker contrastcurve +HISTORY_MSG_774;LA - Reti masker contrastcurve +HISTORY_MSG_775;LA - CBDL masker contrastcurve +HISTORY_MSG_776;LA - Vervaag-Ruisverminderingmasker contrastcurve +HISTORY_MSG_777;LA - Vervaagmasker lokale contrastcurve +HISTORY_MSG_778;LA - Maskeer hoge lichten +HISTORY_MSG_779;LA - Kleurmasker lokale contrastcurve +HISTORY_MSG_780;LA - Kleurmasker schaduwen +HISTORY_MSG_781;LA - Contrastmasker Wavelet-niveau +HISTORY_MSG_782;LA - Vervaag-Ruisverminderingmasker Wavelet-niveaus +HISTORY_MSG_783;LA - Kleur Wavelet-niveaus +HISTORY_MSG_784;LA - masker - ΔE beeldmasker +HISTORY_MSG_785;LA - masker - bereik +HISTORY_MSG_786;LA - SH-methode +HISTORY_MSG_787;LA - Equalizer vermenigvuldiger +HISTORY_MSG_788;LA - Equalizer detail +HISTORY_MSG_789;LA - SH-masker hoeveelheid +HISTORY_MSG_790;LA - SH-masker anker +HISTORY_MSG_791;LA - masker Short L-curven +HISTORY_MSG_792;LA - masker - Achtergrond +HISTORY_MSG_793;LA - SH TRC gamma +HISTORY_MSG_794;LA - SH TRC helling +HISTORY_MSG_795;LA - masker bewaar herstel beeld +HISTORY_MSG_796;LA - SC - Recursieve referenties +HISTORY_MSG_797;LA - Meng Originele methode +HISTORY_MSG_798;LA - Opaciteit +HISTORY_MSG_799;LA - Kleur RGB Tooncurve +HISTORY_MSG_800;LA - Kleur Tooncurve Methode +HISTORY_MSG_801;LA - Kleur Tooncurve Speciaal +HISTORY_MSG_802;LA - Contrastdrempel +HISTORY_MSG_803;LA - Kleur Meng +HISTORY_MSG_804;LA - Kleur masker structuur +HISTORY_MSG_805;LA - Vervaging Ruisonderdrukking maskerstructuur +HISTORY_MSG_806;LA - Kleur masker structuur als gereedschap +HISTORY_MSG_807;LA - Vervaging Ruisonderdrukkingsmasker structuur als gereedschap +HISTORY_MSG_808;LA - Kleur masker curve H(H) +HISTORY_MSG_809;LA - Lev. maskercurve C(C) +HISTORY_MSG_810;LA - Lev. maskercurve L(L) +HISTORY_MSG_811;LA - Lev. maskercurve LC(H) +HISTORY_MSG_813;LA - Gebruik Levendigheid masker +HISTORY_MSG_814;LA - Lev. masker Meng +HISTORY_MSG_815;LA - Lev. masker straal +HISTORY_MSG_816;LA - Lev. masker chroma +HISTORY_MSG_817;LA - Lev. masker gamma +HISTORY_MSG_818;LA - Lev. masker helling +HISTORY_MSG_819;LA - Lev. masker laplacian +HISTORY_MSG_820;LA - Lev. masker contrastcurve +HISTORY_MSG_821;LA - kleurenraster achtergrond +HISTORY_MSG_822;LA - kleur achtergrond meng +HISTORY_MSG_823;LA - kleur achtergrond luminantie +HISTORY_MSG_824;LA - Bel. verloopmasker kracht +HISTORY_MSG_825;LA - Bel. verloopmasker hoek +HISTORY_MSG_826;LA - Bel. verloop kracht +HISTORY_MSG_827;LA - Bel. verloop hoek +HISTORY_MSG_828;LA - SH verloop kracht +HISTORY_MSG_829;LA - SH verloop hoek +HISTORY_MSG_830;LA - Keurverloop kracht L +HISTORY_MSG_831;LA - Keurverloop hoek +HISTORY_MSG_832;LA - Keurverloop kracht C +HISTORY_MSG_833;LA - TG - Veer verloop +HISTORY_MSG_834;LA - Keurverloop kracht H +HISTORY_MSG_835;LA - Lev. verloop kracht L +HISTORY_MSG_836;LA - Lev. verloop hoek +HISTORY_MSG_837;LA - Lev. verloop kracht C +HISTORY_MSG_838;LA - Lev. verloop kracht H +HISTORY_MSG_839;LA - Softwarecomplexiteit +HISTORY_MSG_840;LA - CL-curve +HISTORY_MSG_841;LA - LC-curve +HISTORY_MSG_842;LA - Vervagingsmasker Straal +HISTORY_MSG_843;LA - Vervagingsmasker Contrastdrempel +HISTORY_MSG_844;LA - Vervagingsmasker FFTW +HISTORY_MSG_845;LA - Log-codering +HISTORY_MSG_846;LA - Log-codering auto +HISTORY_MSG_847;LA - Log-codering Bron +HISTORY_MSG_849;LA - Log-codering Bron auto +HISTORY_MSG_850;LA - Log-codering B_Ev +HISTORY_MSG_851;LA - Log-codering W_Ev +HISTORY_MSG_852;LA - Log-codering Doel +HISTORY_MSG_853;LA - Log encodind lokaal contrast +HISTORY_MSG_854;LA - Log encodind bereik +HISTORY_MSG_855;LA - Log-codering gehele beeld +HISTORY_MSG_856;LA - Log-codering Schaduwen bereik +HISTORY_MSG_857;LA - Wavelet vervaging residueel +HISTORY_MSG_858;LA - Wavelet vervaging alleen luminantie +HISTORY_MSG_859;LA - Wavelet max. vervaging +HISTORY_MSG_860;LA - Wavelet vervaging niveaus +HISTORY_MSG_861;LA - Wavelet contrastniveaus +HISTORY_MSG_862;LA - Wavelet contrastversterking +HISTORY_MSG_863;LA - Wavelet meng met originele afbeelding +HISTORY_MSG_864;LA - Wavelet dir contrastversterking +HISTORY_MSG_865;LA - Wavelet dir contrast delta +HISTORY_MSG_866;LA - Wavelet dir compressie +HISTORY_MSG_868;LA - SD - C-H balans +HISTORY_MSG_869;LA - Ruisonderdrukking per niveau +HISTORY_MSG_870;LA - Wavelet masker curve H +HISTORY_MSG_871;LA - Wavelet masker curve C +HISTORY_MSG_872;LA - Wavelet masker curve L +HISTORY_MSG_873;LA - Wavelet masker +HISTORY_MSG_875;LA - Wavelet masker voeg samen +HISTORY_MSG_876;LA - Wavelet masker zacht +HISTORY_MSG_877;LA - Wavelet masker chroma +HISTORY_MSG_878;LA - Wavelet masker contrastcurve +HISTORY_MSG_879;LA - Wavelet contrast chroma +HISTORY_MSG_880;LA - Wavelet vervaging chroma +HISTORY_MSG_881;LA - Wavelet contrast verschuiving +HISTORY_MSG_882;LA - Wavelet vervaging +HISTORY_MSG_883;LA - Wavelet contrast per niveau +HISTORY_MSG_884;LA - Wavelet dir contrast +HISTORY_MSG_885;LA - Wavelet toonmapping +HISTORY_MSG_886;LA - Wavelet toonmapping comprimeer +HISTORY_MSG_887;LA - Wavelet toonmapping comprimeer residueel +HISTORY_MSG_888;LA - Contrast Wavelet Balans Drempel +HISTORY_MSG_889;LA - Contrast Wavelet Verloop Sterkte +HISTORY_MSG_890;LA - Contrast Wavelet Verloop hoek +HISTORY_MSG_891;LA - Contrast Wavelet Verloop +HISTORY_MSG_892;LA - Log Encoding Verloop kracht +HISTORY_MSG_893;LA - Log Encoding Verloop hoek +HISTORY_MSG_894;LA - SD - ΔE voorbeeld kleurintensiteit +HISTORY_MSG_897;LA - Contrast Wavelet ES kracht +HISTORY_MSG_898;LA - Contrast Wavelet ES straal +HISTORY_MSG_899;LA - Contrast Wavelet ES detail +HISTORY_MSG_900;LA - Contrast Wavelet ES verloop +HISTORY_MSG_901;LA - Contrast Wavelet ES drempel laag +HISTORY_MSG_902;LA - Contrast Wavelet ES drempel hoog +HISTORY_MSG_903;LA - Contrast Wavelet ES LA contrast +HISTORY_MSG_904;LA - Contrast Wavelet ES eerste niveau +HISTORY_MSG_905;LA - Contrast Wavelet Randscherpte +HISTORY_MSG_906;LA - Contrast Wavelet ES gevoeligheid +HISTORY_MSG_907;LA - Contrast Wavelet ES versterking +HISTORY_MSG_908;LA - Contrast Wavelet ES nabuur +HISTORY_MSG_909;LA - Contrast Wavelet ES toon +HISTORY_MSG_910;LA - SC - Wavelet Randprestaties +HISTORY_MSG_911;LA - Vervaging Chroma Luma +HISTORY_MSG_912;LA - Vervaging Gids filterkracht +HISTORY_MSG_913;LA - Contrast Wavelet Sigma DR +HISTORY_MSG_914;LA - Vervaging Wavelet Sigma BL +HISTORY_MSG_915;LA - Rand Wavelet Sigma ED +HISTORY_MSG_916;LA - Residueel wavelet schaduwen +HISTORY_MSG_917;LA - Residueel wavelet schaduwen drempel +HISTORY_MSG_918;LA - Residueel wavelet hoge lichten +HISTORY_MSG_919;LA - Residueel wavelet hoge lichten drempel +HISTORY_MSG_920;LA - Wavelet sigma LC +HISTORY_MSG_921;LA - Wavelet Gradueel sigma LC2 +HISTORY_MSG_922;LA - SC - Veranderingen in Z-W +HISTORY_MSG_923;LA - Gereedschapscomplexiteit modus +HISTORY_MSG_924;--unused-- +HISTORY_MSG_925;LA - bereik (kleurgereedschappen) +HISTORY_MSG_926;LA - Toon maskertype +HISTORY_MSG_927;LA - Schaduw +HISTORY_MSG_928;LA - Algemeen kleurenmasker +HISTORY_MSG_929;LA - Masker Algemeen Bereik +HISTORY_MSG_930;LA - Masker Algemeen Meng luma +HISTORY_MSG_931;LA - Masker Algemeen activeer +HISTORY_MSG_932;LA - Masker Algemeen straal zacht +HISTORY_MSG_933;LA - Masker Algemeen laplacian +HISTORY_MSG_934;LA - Masker Algemeen chroma +HISTORY_MSG_935;LA - Masker Algemeen gamma +HISTORY_MSG_936;LA - Masker Algemeen helling +HISTORY_MSG_937;LA - Masker Algemeen curve C(C) +HISTORY_MSG_938;LA - Masker Algemeen curve L(L) +HISTORY_MSG_939;LA - Masker Algemeen curve LC(H) +HISTORY_MSG_940;LA - Masker Algemeen structuur als gereedschap +HISTORY_MSG_941;LA - Masker Algemeen structuurkracht +HISTORY_MSG_942;LA - Masker Algemeen H(H) curve +HISTORY_MSG_943;LA - Masker Algemeen FFT +HISTORY_MSG_944;LA - Masker Algemeen Vervaging straal +HISTORY_MSG_945;LA - Masker Algemeen contrastdrempel +HISTORY_MSG_946;LA - Masker Algemeen schaduwen +HISTORY_MSG_947;LA - Masker Algemeen Contrastcurve +HISTORY_MSG_948;LA - Masker Algemeen Wavelet-curve +HISTORY_MSG_949;LA - Masker Algemeen Drempel niveaus +HISTORY_MSG_950;LA - Masker Algemeen GF kracht +HISTORY_MSG_951;LA - Masker Algemeen GF hoek +HISTORY_MSG_952;LA - Masker Algemeen zacht straal +HISTORY_MSG_953;LA - Masker Algemeen meng chroma +HISTORY_MSG_954;LA - Toon/verberg gereedschappen +HISTORY_MSG_955;LA - Activeer Spot +HISTORY_MSG_956;LA - CH-curve +HISTORY_MSG_957;LA - Ruisonderdrukking modus +HISTORY_MSG_958;LA - Toon/verberg instellingen +HISTORY_MSG_959;LA - Inverteer vervaging +HISTORY_MSG_960;LA - Log-codering - cat16 +HISTORY_MSG_961;LA - Log-codering Ciecam +HISTORY_MSG_962;LA - Log-codering Absolute luminantie bron +HISTORY_MSG_963;LA - Log-codering Absolute luminantie doel +HISTORY_MSG_964;LA - Log-codering Omgeving +HISTORY_MSG_965;LA - Log-codering Verzadiging s +HISTORY_MSG_966;LA - Log-codering Contrast J +HISTORY_MSG_967;LA - Log-codering masker curve C +HISTORY_MSG_968;LA - Log-codering masker curve L +HISTORY_MSG_969;LA - Log-codering masker curve H +HISTORY_MSG_970;LA - Log-codering masker geactiveerd +HISTORY_MSG_971;LA - Log-codering masker meng +HISTORY_MSG_972;LA - Log-codering masker straal +HISTORY_MSG_973;LA - Log-codering masker chroma +HISTORY_MSG_974;LA - Log-codering masker contrast +HISTORY_MSG_975;LA - Log-codering Lichtheid J +HISTORY_MSG_977;LA - Log-codering Contrast Q +HISTORY_MSG_978;LA - Log-codering Sursource +HISTORY_MSG_979;LA - Log-codering Helderheid Q +HISTORY_MSG_980;LA - Log-codering Kleurrijkheid M +HISTORY_MSG_981;LA - Log-codering Kracht +HISTORY_MSG_982;LA - Equalizer tint +HISTORY_MSG_983;LA - Ruisonderdrukking drempel masker hoog +HISTORY_MSG_984;LA - Ruisonderdrukking drempel masker laag +HISTORY_MSG_985;LA - Ruisonderdrukking Laplacian +HISTORY_MSG_986;LA - Ruisonderdrukking versterk +HISTORY_MSG_987;LA - GF herstel drempel +HISTORY_MSG_988;LA - GF drempel masker laag +HISTORY_MSG_989;LA - GF drempel masker hoog +HISTORY_MSG_990;LA - Ruisonderdrukking herstel drempel +HISTORY_MSG_991;LA - Ruisonderdrukking drempel masker laag +HISTORY_MSG_992;LA - Ruisonderdrukking drempel masker hoog +HISTORY_MSG_993;LA - Ruisonderdrukking Omgekeerd algo +HISTORY_MSG_994;LA - GF Omgekeerd algo +HISTORY_MSG_995;LA - Ruisonderdrukking verval +HISTORY_MSG_996;LA - Kleurherstel drempel +HISTORY_MSG_997;LA - Kleurherstel masker laag +HISTORY_MSG_998;LA - Kleur drempel masker hoog +HISTORY_MSG_999;LA - Kleur verval +HISTORY_MSG_1000;LA - Ruisonderdrukking luminantie grijs +HISTORY_MSG_1001;LA - Log herstel drempel +HISTORY_MSG_1002;LA - Log drempel masker laag +HISTORY_MSG_1003;LA - Log drempel masker hoog +HISTORY_MSG_1004;LA - Log verval +HISTORY_MSG_1005;LA - Bel. herstel drempel +HISTORY_MSG_1006;LA - Bel. drempel masker laag +HISTORY_MSG_1007;LA - Bel. drempel masker hoog +HISTORY_MSG_1008;LA - Bel. verval +HISTORY_MSG_1009;LA - SH herstel drempel +HISTORY_MSG_1010;LA - SH drempel masker laag +HISTORY_MSG_1011;LA - SH drempel masker hoog +HISTORY_MSG_1012;LA - SH verval +HISTORY_MSG_1013;LA - lev. herstel drempel +HISTORY_MSG_1014;LA - lev. drempel masker laag +HISTORY_MSG_1015;LA - lev. drempel masker hoog +HISTORY_MSG_1016;LA - lev. verval +HISTORY_MSG_1017;LA - lc herstel drempel +HISTORY_MSG_1018;LA - lc drempel masker laag +HISTORY_MSG_1019;LA - lc drempel masker hoog +HISTORY_MSG_1020;LA - lc verval +HISTORY_MSG_1021;LA - Ruisonderdrukking chrominantie grijs +HISTORY_MSG_1022;LA - TM herstel drempel +HISTORY_MSG_1023;LA - TM drempel masker laag +HISTORY_MSG_1024;LA - TM drempel masker hoog +HISTORY_MSG_1025;LA - TM verval +HISTORY_MSG_1026;LA - cbdl herstel drempel +HISTORY_MSG_1027;LA - cbdl drempel masker laag +HISTORY_MSG_1028;LA - cbdl drempel masker hoog +HISTORY_MSG_1029;LA - cbdl verval +HISTORY_MSG_1030;LA - reti herstel drempel +HISTORY_MSG_1031;LA - reti drempel masker laag +HISTORY_MSG_1032;LA - reti drempel masker hoog +HISTORY_MSG_1033;LA - reti verval +HISTORY_MSG_1034;LA - Nlmeans - kracht +HISTORY_MSG_1035;LA - Nlmeans - detail +HISTORY_MSG_1036;LA - Nlmeans - patch +HISTORY_MSG_1037;LA - Nlmeans - straal +HISTORY_MSG_1038;LA - Nlmeans - gamma +HISTORY_MSG_1039;LA - Korrel - gamma +HISTORY_MSG_1040;LA - SC - Verzachtingsstraal +HISTORY_MSG_1041;LA - Spot - Munsell +HISTORY_MSG_1042;LA - Log-codring - drempel +HISTORY_MSG_1043;LA - Bel. - normaliseer +HISTORY_MSG_1044;LA - LA contrast kracht +HISTORY_MSG_1045;LA - Kleur en Licht kracht +HISTORY_MSG_1046;LA - Ruisonderdrukking kracht +HISTORY_MSG_1047;LA - SH en Toonequalizer kracht +HISTORY_MSG_1048;LA - DR en Belichting kracht +HISTORY_MSG_1049;LA - TM kracht +HISTORY_MSG_1050;LA - Log-codering chroma +HISTORY_MSG_1051;LA - residueel wavelet gamma +HISTORY_MSG_1052;LA - residueel wavelet helling +HISTORY_MSG_1053;LA - ruisonderdrukking gamma +HISTORY_MSG_1054;LA - Wavelet gamma +HISTORY_MSG_1055;LA - Kleur en Licht gamma +HISTORY_MSG_1056;LA - DR en Belichting gamma +HISTORY_MSG_1057;LA - CIECAM Geactiveerd +HISTORY_MSG_1058;LA - CIECAM Overall kracht +HISTORY_MSG_1059;LA - CIECAM Autogrijs +HISTORY_MSG_1060;LA - CIECAM Gemiddelde luminantie bron +HISTORY_MSG_1061;LA - CIECAM bron absoluut +HISTORY_MSG_1062;LA - CIECAM omgeving bron +HISTORY_MSG_1063;LA - CIECAM verzadiging +HISTORY_MSG_1064;LA - CIECAM Chroma +HISTORY_MSG_1065;LA - CIECAM lichtheid J +HISTORY_MSG_1066;LA - CIECAM helderheid +HISTORY_MSG_1067;LA - CIECAM Contrast J +HISTORY_MSG_1068;LA - CIECAM drempel +HISTORY_MSG_1069;LA - CIECAM contrast Q +HISTORY_MSG_1070;LA - CIECAM kleurrijkheid +HISTORY_MSG_1071;LA - CIECAM Absolute luminantie +HISTORY_MSG_1072;LA - CIECAM Gemiddelde luminantie +HISTORY_MSG_1073;LA - CIECAM Cat16 +HISTORY_MSG_1074;LA - CIECAM LA contrast +HISTORY_MSG_1075;LA - CIECAM kijkomgeving +HISTORY_MSG_1076;LA - CIECAM bereik +HISTORY_MSG_1077;LA - CIECAM modus +HISTORY_MSG_1078;LA - Rood/huidbescherming +HISTORY_MSG_1079;LA - CIECAM Sigmoid kracht J +HISTORY_MSG_1080;LA - CIECAM Sigmoid drempel +HISTORY_MSG_1081;LA - CIECAM Sigmoid meng +HISTORY_MSG_1082;LA - CIECAM Sigmoid Q BlackEv WhiteEv +HISTORY_MSG_1083;LA - CIECAM tint +HISTORY_MSG_1084;LA - Gebruikt Black Ev - White Ev +HISTORY_MSG_1085;LA - Jz lichtheid +HISTORY_MSG_1086;LA - Jz contrast +HISTORY_MSG_1087;LA - Jz chroma +HISTORY_MSG_1088;LA - Jz tint +HISTORY_MSG_1089;LA - Jz Sigmoid kracht +HISTORY_MSG_1090;LA - Jz Sigmoid drempel +HISTORY_MSG_1091;LA - Jz Sigmoid meng +HISTORY_MSG_1092;LA - Jz aanpassing +HISTORY_MSG_1093;LA - CAM model +HISTORY_MSG_1094;LA - Jz hoge lichten +HISTORY_MSG_1095;LA - Jz hoge lichten thr +HISTORY_MSG_1096;LA - Jz schaduwen +HISTORY_MSG_1097;LA - Jz schaduwen thr +HISTORY_MSG_1098;LA - Jz straal SH +HISTORY_MSG_1099;LA - Cz(Hz) Curve +HISTORY_MSG_1100;LA - Jz referentie 100 +HISTORY_MSG_1101;LA - Jz PQ remap +HISTORY_MSG_1102;LA - Jz(Hz) Curve +HISTORY_MSG_1103;LA - Levendigheid gamma +HISTORY_MSG_1104;LA - Scherp gamma +HISTORY_MSG_1105;LA - CIECAM Toon methode +HISTORY_MSG_1106;LA - CIECAM Toon curve +HISTORY_MSG_1107;LA - CIECAM Kleur methode +HISTORY_MSG_1108;LA - CIECAM Kleur curve +HISTORY_MSG_1109;LA - Jz(Jz) curve +HISTORY_MSG_1110;LA - Cz(Cz) curve +HISTORY_MSG_1111;LA - Cz(Jz) curve +HISTORY_MSG_1112;LA - forcejz +HISTORY_MSG_1113;LA - HDR PQ +HISTORY_MSG_1114;LA - Cie masker activeer +HISTORY_MSG_1115;LA - Cie masker curve C +HISTORY_MSG_1116;LA - Cie masker curve L +HISTORY_MSG_1117;LA - Cie masker curve H +HISTORY_MSG_1118;LA - Cie masker meng +HISTORY_MSG_1119;LA - Cie masker straal +HISTORY_MSG_1120;LA - Cie masker chroma +HISTORY_MSG_1121;LA - Cie masker contrast curve +HISTORY_MSG_1122;LA - Cie masker herstel drempel +HISTORY_MSG_1123;LA - Cie masker herstel donker +HISTORY_MSG_1124;LA - Cie masker herstel licht +HISTORY_MSG_1125;LA - Cie masker herstel verval +HISTORY_MSG_1126;LA - Cie masker laplacian +HISTORY_MSG_1127;LA - Cie masker gamma +HISTORY_MSG_1128;LA - Cie masker helling +HISTORY_MSG_1129;LA - Cie Relatieve luminantie +HISTORY_MSG_1130;LA - Cie Verzadiging Jz +HISTORY_MSG_1131;LA - masker - Ruisvermindering +HISTORY_MSG_1132;LA - Cie Wav sigma Jz +HISTORY_MSG_1133;LA - Cie Wav level Jz +HISTORY_MSG_1134;LA - Cie Wav LA contrast Jz +HISTORY_MSG_1135;LA - Cie Wav klaarheid Jz +HISTORY_MSG_1136;LA - Cie Wav klaarheid Cz +HISTORY_MSG_1137;LA - Cie Wav klaarheid Zacht +HISTORY_MSG_1138;LA - LA - Hz(Hz) Curve +HISTORY_MSG_1139;LA - Jz zacht Curven H +HISTORY_MSG_1140;LA - Jz Drempel chroma +HISTORY_MSG_1141;LA - chroma curve Jz(Hz) +HISTORY_MSG_1142;LA - kracht zacht +HISTORY_MSG_1143;LA - Jz blackev +HISTORY_MSG_1144;LA - Jz whiteev +HISTORY_MSG_1145;LA - Jz Log-codering +HISTORY_MSG_1146;LA - Jz Log-codering doel grijs +HISTORY_MSG_1147;LA - Jz BlackEv WhiteEv +HISTORY_MSG_1148;LA - Jz Sigmoid +HISTORY_MSG_1149;LA - Q Sigmoid +HISTORY_MSG_1150;LA - Log-codering Q in plaats van Sigmoid Q +HISTORY_MSG_BLSHAPE;Vervaag per niveau +HISTORY_MSG_BLURCWAV;Vervaging chroma +HISTORY_MSG_BLURWAV;Vervaging luminantie +HISTORY_MSG_BLUWAV;Versterkinsrespons +HISTORY_MSG_CATCAT;CAL - Instellingen - Modus +HISTORY_MSG_CATCOMPLEX;CAL - Instellingen - Complexiteit +HISTORY_MSG_CATMODEL;CAL - Instellingen - CAM +HISTORY_MSG_COMPLEX;Wavelet complexiteit +HISTORY_MSG_COMPLEXRETI;Retinex complexiteit +HISTORY_MSG_DEHAZE_SATURATION;Ontnevel - Verzadiging +HISTORY_MSG_EDGEFFECT;Randversterking respons +HISTORY_MSG_FF_FROMMETADATA;Flat-Field - Uit metadata +HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Referentie-uitvoer +HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Filmnegatief kleurruimte +HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Referentie-invoer +HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell +HISTORY_MSG_HLBL;Kleurpropagatie - vervaging +HISTORY_MSG_HLTH;Tegenovergestelde Inpainting - versterking drempel +HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy +HISTORY_MSG_ICM_AINTENT;Abstract profiel - weergave-intentie +HISTORY_MSG_ICM_BLUX;Primair blauw X +HISTORY_MSG_ICM_BLUY;Primair blauw Y +HISTORY_MSG_ICM_FBW;Zwart en wit +HISTORY_MSG_ICM_GAMUT;Beperk kleurbereik +HISTORY_MSG_ICM_GREX;Primair groen X +HISTORY_MSG_ICM_GREY;Primair groen Y +HISTORY_MSG_ICM_PRESER;Behoud neutraal +HISTORY_MSG_ICM_REDX;Primair rood X +HISTORY_MSG_ICM_REDY;Primair rood Y +HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Methode lichtsterkte +HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Methode primaire kleuren +HISTORY_MSG_ILLUM;CAL - SC - Lichtsterkte +HISTORY_MSG_LOCALLAB_TE_PIVOT;Lokaal - draaipunt Equalizer +HISTORY_MSG_LOCAL_GAMUTMUNSEL;Lokaal - SC - Voorkom kleurverschuiving +HISTORY_MSG_PERSP_CAM_ANGLE;Perspectief - Camera +HISTORY_MSG_PERSP_CAM_FL;Perspectief - Camera +HISTORY_MSG_PERSP_CAM_SHIFT;Perspectief - Camera +HISTORY_MSG_PERSP_CTRL_LINE;Perspectief - Controlelijnen +HISTORY_MSG_PERSP_METHOD;Perspectief - Methode +HISTORY_MSG_PERSP_PROJ_ANGLE;Perspectief - Herstel +HISTORY_MSG_PERSP_PROJ_ROTATE;Perspectief - PCA-rotatie +HISTORY_MSG_PERSP_PROJ_SHIFT;Perspectief - PCA +HISTORY_MSG_PIXELSHIFT_AVERAGE;PS - Gemiddeld +HISTORY_MSG_PREPROCWB_MODE;Voorproces WB Modus +HISTORY_MSG_PROTAB;Protectie +HISTORY_MSG_RANGEAB;Reeks ab +HISTORY_MSG_RESIZE_LONGEDGE;Verander grootte - Lange zijde +HISTORY_MSG_RESIZE_SHORTEDGE;Verander grootte - Korte zijde +HISTORY_MSG_SIGMACOL;Chroma-versterking respons +HISTORY_MSG_SIGMADIR;Dir versterking respons +HISTORY_MSG_SIGMAFIN;Finale contrastversterking respons +HISTORY_MSG_SIGMATON;Toning versterking respons +HISTORY_MSG_SPOT;Verwijder vlekken +HISTORY_MSG_SPOT_ENTRY;Vlekverwijdering - punt gewijzigd +HISTORY_MSG_TEMPOUT;CAM02 automatische temperatuur +HISTORY_MSG_THRESWAV;Balance drempel +HISTORY_MSG_TONE_EQUALIZER_BANDS;Toonequalizer - Banden +HISTORY_MSG_TONE_EQUALIZER_ENABLED;Toonequalizer +HISTORY_MSG_TONE_EQUALIZER_PIVOT;Toonequalizer - Draaipunt +HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Toonequalizer - Regularisatie +HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Toonequalizer - Tonale map +HISTORY_MSG_WAVBALCHROM;Equalizer chrominantie +HISTORY_MSG_WAVBALLUM;Equalizer luminantie +HISTORY_MSG_WAVBL;Vervagingsniveaus +HISTORY_MSG_WAVCHR;Vervagingsniveaus - vervaag chroma +HISTORY_MSG_WAVCHROMCO;Chroma ruw +HISTORY_MSG_WAVCHROMFI;Chroma fijn +HISTORY_MSG_WAVCLARI;Klaarheid +HISTORY_MSG_WAVDENLH;Nineau 5 +HISTORY_MSG_WAVDENOISE;Lokaal contrast +HISTORY_MSG_WAVDENOISEH;Hoge niveaus lokaal contrast +HISTORY_MSG_WAVDETEND;Details zacht +HISTORY_MSG_WAVEDGS;Rand stopping +HISTORY_MSG_WAVGUIDH;Lokaal contrast - Tintequalizer +HISTORY_MSG_WAVHUE;Equalizer tint +HISTORY_MSG_WAVLABGRID_VALUE;Toning - sluit kleuren uit +HISTORY_MSG_WAVLEVDEN;Hoog niveau lokaal contrast +HISTORY_MSG_WAVLEVELSIGM;Ruisvermindering - straal +HISTORY_MSG_WAVLEVSIGM;Straal +HISTORY_MSG_WAVLIMDEN;Interactie 56 14 +HISTORY_MSG_WAVLOWTHR;Drempel laag contrast +HISTORY_MSG_WAVMERGEC;Meng C +HISTORY_MSG_WAVMERGEL;Meng L +HISTORY_MSG_WAVMIXMET;Referentie lokaal contrast +HISTORY_MSG_WAVOFFSET;Verschuiving +HISTORY_MSG_WAVOLDSH;Oud algoritme +HISTORY_MSG_WAVQUAMET;Ruisvermindering modus +HISTORY_MSG_WAVRADIUS;Straal schaduwen-hoge lichten +HISTORY_MSG_WAVSCALE;Schaal +HISTORY_MSG_WAVSHOWMASK;Toon wavelet-masker +HISTORY_MSG_WAVSIGM;Sigma +HISTORY_MSG_WAVSIGMA;Versterkingsrespons +HISTORY_MSG_WAVSLIMET;Methode +HISTORY_MSG_WAVSOFTRAD;Zacht straal klaarheid +HISTORY_MSG_WAVSOFTRADEND;Zacht straal finaal +HISTORY_MSG_WAVSTREND;Kracht zacht +HISTORY_MSG_WAVTHRDEN;Drempel lokaal contrast +HISTORY_MSG_WAVTHREND;Drempel lokaal contrast +HISTORY_MSG_WAVUSHAMET;Klaarheid methode +HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° +HISTORY_MSG_WBITC_CUSTOM;Itcwb Aangepast +HISTORY_MSG_WBITC_DELTA;Itcwb Delta groen +HISTORY_MSG_WBITC_FGREEN;Itcwb Groen - student +HISTORY_MSG_WBITC_FORCE;Itcwb Kracht +HISTORY_MSG_WBITC_GREEN;Groenverfijning +HISTORY_MSG_WBITC_MINSIZE;Patch min grootte +HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple +HISTORY_MSG_WBITC_OBS;Verwijder algo 2x +HISTORY_MSG_WBITC_PONDER;Itcwb gewogen +HISTORY_MSG_WBITC_PRECIS;Itcwb Precisie +HISTORY_MSG_WBITC_PRIM;Primaire kleuren +HISTORY_MSG_WBITC_RGREEN;Itcwb Groenreeks +HISTORY_MSG_WBITC_SAMPLING;Laag sampling +HISTORY_MSG_WBITC_SIZE;Itcwb Grootte +HISTORY_MSG_WBITC_SORTED;Itcwb gewogen +HISTORY_MSG_WBITC_THRES;Itcwb drempel +ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater +ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 +INSPECTOR_WINDOW_TITLE;Inspecteur +MAIN_TAB_LOCALLAB;Lokale aanpassingen +MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt+O +PARTIALPASTE_FLATFIELDFROMMETADATA;Vlakveld uit metadata +PARTIALPASTE_LOCALLAB;Lokale aanpassingen +PARTIALPASTE_LOCALLABGROUP;Instellingen Lokale aanpassingen +PARTIALPASTE_PREPROCWB;Pre-proces witbalans +PARTIALPASTE_SPOT;Spot verwijder +PARTIALPASTE_TONE_EQUALIZER;Toonequalizer +PREFERENCES_CAMERAPROFILESDIR;Map met cameraprofielen +PREFERENCES_CIE;Ciecam +PREFERENCES_CIEARTIF;Vermijd onregelmatigheden +PREFERENCES_COMPLEXITYLOC;Standaard complexiteit voor Lokale Aanpassingen +PREFERENCES_COMPLEXITY_EXP;Geavanceerd +PREFERENCES_COMPLEXITY_NORM;Standaard +PREFERENCES_COMPLEXITY_SIMP;Basis +PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Passeer uitvoerprofiel +PREFERENCES_EXTEDITOR_DIR;Uitvoermap +PREFERENCES_EXTEDITOR_DIR_CURRENT;Zelfde als invoerbeeld +PREFERENCES_EXTEDITOR_DIR_CUSTOM;Aangepast +PREFERENCES_EXTEDITOR_DIR_TEMP;temp map dir besturingssysteem +PREFERENCES_EXTEDITOR_FLOAT32;32-bit decimale TIFF_uitvoer +PREFERENCES_EXTERNALEDITOR_CHANGE;Verander applicatie +PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Verander uitvoerbaar bestand +PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Opdracht +PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Naam +PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Standaard opdracht +PREFERENCES_INSPECTORWINDOW;Open de Inspecteur in eigen venster of volledig scherm +PREFERENCES_LENSFUNDBDIR;Map met Lensfun-database +PREFERENCES_LENSFUNDBDIR_TOOLTIP;Map met de Lensfun-database. Laat leeg om de standaardmappen te gebruiken. +PREFERENCES_LENSPROFILESDIR;Map met lensprofielen +PREFERENCES_LENSPROFILESDIR_TOOLTIP;Map met Adobe Lens Correction Profiles (LCP's) +PREFERENCES_METADATA;Metadata +PREFERENCES_METADATA_SYNC;Synchronisatie metadata met XMP-zijspanbestanden +PREFERENCES_METADATA_SYNC_NONE;Geen +PREFERENCES_METADATA_SYNC_READ;Alleen lezen +PREFERENCES_METADATA_SYNC_READWRITE;Bidirectioneel +PREFERENCES_SHOWTOOLTIP;Toon schermtips voor Lokale aanpassingen +PREFERENCES_TAB_FAVORITES;Favorieten +PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Beschikbare gereedschappen +PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Toon favoriete gereedschappen ook op hun oorspronkelijke locatie +PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Indien aangevinkt zullen de favoriete gereedschappen zowel in de Favorieten-tab als op hun oorspronkelijke locatie te vinden zijn.\n\nOpmerking: als deze optie is aangevinkt kunt u een lichte vertraging verwachten tijdens het wisselen van tabs. +PREFERENCES_TOOLPANEL_FAVORITE;Favoriet +PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorietenpaneel +PREFERENCES_TOOLPANEL_TOOL;Gereedschap +PREFERENCES_WBA;Witbalans +PREFERENCES_WBACORR;Witbalans - Automatische temperatuurcorrelatie !PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -!PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings -!PREFERENCES_WBAENACUSTOM;Use Custom temperature & tint -!PREFERENCES_WBAFORC;Forces Extra algoritm -!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) -!PREFERENCES_WBANOPURP;No purple color used -!PREFERENCES_WBAPATCH;Number maximum of colors used in picture -!PREFERENCES_WBAPRECIS;Precision algorithm - scale used -!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color -!PREFERENCES_WBASORT;Sort in chroma order instead of histogram -!PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style -!PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) -!PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) -!PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling -!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) -!SORT_ASCENDING;Ascending -!SORT_BY_DATE;By Date -!SORT_BY_EXIF;By EXIF -!SORT_BY_LABEL;By Color Label -!SORT_BY_NAME;By Name -!SORT_BY_RANK;By Rank -!SORT_DESCENDING;Descending -!TC_PRIM_BLUX;Bx -!TC_PRIM_BLUY;By -!TC_PRIM_GREX;Gx -!TC_PRIM_GREY;Gy -!TC_PRIM_REDX;Rx -!TC_PRIM_REDY;Ry +PREFERENCES_WBAENA;Witbalans - Toon instellingen automatische temperatuurcorrelatie +PREFERENCES_WBAENACUSTOM;Gebruik aangepaste temperatuur & tint +PREFERENCES_WBAFORC;Forceer extra algoritme +PREFERENCES_WBAGREENDELTA;Delta temperatuur in groene herhalingslus (indien Forceer extra geactiveerd) +PREFERENCES_WBANOPURP;Geen paarse kleur gebruikt +PREFERENCES_WBAPATCH;Maximaal aantal kleuren gebruikt in afbeelding +PREFERENCES_WBAPRECIS;Precisie-algoritme - schaal toegepast +PREFERENCES_WBASIZEREF;Grootte referentiekleur vergelijken met grootte histogramkleur +PREFERENCES_WBASORT;Sorteer in chroma-volgorde in plaats van histogram +PREFERENCES_XMP_SIDECAR_MODE;XMP zijspanbestand stijl +PREFERENCES_XMP_SIDECAR_MODE_EXT;Zoals darktable (FILENAME.ext.xmp voor FILENAME.ext) +PREFERENCES_XMP_SIDECAR_MODE_STD;Standaard (FILENAME.xmp voor FILENAME.ext) +PREFERENCES_ZOOMONSCROLL;Zoom afbeeldingen door te scrollen +SAVEDLG_BIGTIFF;BigTIFF (geen metadata-ondersteuning) +SORT_ASCENDING;Oplopend +SORT_BY_DATE;Op datum +SORT_BY_EXIF;Op EXIF +SORT_BY_LABEL;Op kleurlabel +SORT_BY_NAME;Op naam +SORT_BY_RANK;Volgens sterwaardering +SORT_DESCENDING;Aflopend +TC_PRIM_BLUX;Bx +TC_PRIM_BLUY;By +TC_PRIM_GREX;Gx +TC_PRIM_GREY;Gy +TC_PRIM_REDX;Rx +TC_PRIM_REDY;Ry !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. -!TP_COLORAPP_CATCLASSIC;Classic +TP_COLORAPP_CATCLASSIC;Klassiek !TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. -!TP_COLORAPP_CATMOD;Mode -!TP_COLORAPP_CATSYMGEN;Automatic Symmetric -!TP_COLORAPP_CATSYMSPE;Mixed -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing +TP_COLORAPP_CATMOD;Modus +TP_COLORAPP_CATSYMGEN;Auto-symmetrisch +TP_COLORAPP_CATSYMSPE;Gemengd +TP_COLORAPP_CIECAT_DEGREEOUT;Chromatische aanpassing weergave !TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). !TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D50) into new values whose white point is that of the new illuminant - see WP model (for example D75). -!TP_COLORAPP_GEN;Settings +TP_COLORAPP_GEN;Instellingen !TP_COLORAPP_GEN_TOOLTIP;This module is based on the CIECAM color appearance models, which were designed to better simulate how human vision perceives colors under different lighting conditions, e.g. against different backgrounds. It takes into account the environment of each color and modifies its appearance to get as close as possible to human perception. It also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic appearance is preserved across the scene and display environments. -!TP_COLORAPP_IL41;D41 -!TP_COLORAPP_IL50;D50 -!TP_COLORAPP_IL55;D55 -!TP_COLORAPP_IL60;D60 -!TP_COLORAPP_IL65;D65 -!TP_COLORAPP_IL75;D75 -!TP_COLORAPP_ILA;Incandescent StdA 2856K -!TP_COLORAPP_ILFREE;Free -!TP_COLORAPP_ILLUM;Illuminant +TP_COLORAPP_IL41;D41 +TP_COLORAPP_IL50;D50 +TP_COLORAPP_IL55;D55 +TP_COLORAPP_IL60;D60 +TP_COLORAPP_IL65;D65 +TP_COLORAPP_IL75;D75 +TP_COLORAPP_ILA;Incandescent StdA 2856K +TP_COLORAPP_ILFREE;Vrij +TP_COLORAPP_ILLUM;Illuminant !TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and latitude. -!TP_COLORAPP_MOD02;CAM02 -!TP_COLORAPP_MOD16;CAM16 -!TP_COLORAPP_MODELCAT;CAM +TP_COLORAPP_MOD02;CAM02 +TP_COLORAPP_MOD16;CAM16 +TP_COLORAPP_MODELCAT;CAM !TP_COLORAPP_MODELCAT_TOOLTIP;Allows you to choose between CAM02 or CAM16.\nCAM02 will sometimes be more accurate.\nCAM16 should generate fewer artifacts. !TP_COLORAPP_SOURCEF_TOOLTIP;Corresponds to the shooting conditions and how to bring the conditions and data back to a 'normal' area. Normal means average or standard conditions and data, i.e. without taking into account CIECAM corrections. -!TP_COLORAPP_SURROUNDSRC;Surround +TP_COLORAPP_SURROUNDSRC;Omgevingsverlichting !TP_COLORAPP_SURSOURCE_TOOLTIP;Changes tones and colors to take into account the surround conditions of the scene lighting. The darker the surround conditions, the brighter the image will become. Image brightness will not be changed when the surround is set to average. !TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 !TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. !TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. !TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. !TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_CROP_GTCENTEREDSQUARE;Centered square -!TP_DEHAZE_SATURATION;Saturation -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images. -!TP_FILMNEGATIVE_BLUEBALANCE;Cool/Warm -!TP_FILMNEGATIVE_COLORSPACE;Inversion color space: -!TP_FILMNEGATIVE_COLORSPACE_INPUT;Input color space -!TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Select the color space used to perform the negative inversion:\nInput color space : perform inversion before the input profile is applied, as in the previous versions of RT.\nWorking color space : perform inversion after input profile, using the currently selected working profile. -!TP_FILMNEGATIVE_COLORSPACE_WORKING;Working color space -!TP_FILMNEGATIVE_GREENBALANCE;Magenta/Green -!TP_FILMNEGATIVE_OUT_LEVEL;Output level -!TP_FILMNEGATIVE_PICK_SIZE;Size: -!TP_FILMNEGATIVE_REF_LABEL;Input RGB: %1 -!TP_FILMNEGATIVE_REF_PICK;Pick white balance spot -!TP_FILMNEGATIVE_REF_SIZE;Size: -!TP_FILMNEGATIVE_REF_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. -!TP_FLATFIELD_FROMMETADATA;From Metadata -!TP_HLREC_COLOROPP;Inpaint Opposed -!TP_HLREC_HLBLUR;Blur -!TP_HLREC_HLTH;Gain threshold -!TP_ICM_FBW;Black-and-White -!TP_ICM_GAMUT;Gamut control +TP_CROP_GTCENTEREDSQUARE;Vierkant gecentreerd +TP_DEHAZE_SATURATION;Verzadiging +TP_FILMNEGATIVE_BLUEBALANCE;Koel/Warm +TP_FILMNEGATIVE_COLORSPACE;Omkeerkleurruimte: +TP_FILMNEGATIVE_COLORSPACE_INPUT;Invoerkleurruimte +TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Kies de kleurruimte voor de negatieve omkering:\nInvoerkleurruimte: voer de omkering uit voordat het invoerprofiel wordt toegepast, zoals in eerdere versies van RT.\nWerkkleurruimte: voer de omkering uit na het invoerprofiel en gebruik het momenteel geselecteerde werkprofiel. +TP_FILMNEGATIVE_COLORSPACE_WORKING;Werkkleurruimte +TP_FILMNEGATIVE_GREENBALANCE;Magenta/Groen +TP_FILMNEGATIVE_OUT_LEVEL;Uitvoerniveau +TP_FILMNEGATIVE_PICK_SIZE;Grootte: +TP_FILMNEGATIVE_REF_LABEL;Invoer RGB: %1 +TP_FILMNEGATIVE_REF_PICK;Kies witbalans +TP_FILMNEGATIVE_REF_SIZE;Grootte: +TP_FILMNEGATIVE_REF_TOOLTIP;Kies een grijspunt om de witbalans van het positieve beeld te bepalen. +TP_FLATFIELD_FROMMETADATA;Uit metadata +TP_HLREC_COLOROPP;Tegenovergestelde Inpainting +TP_HLREC_HLBLUR;Vervaging +TP_HLREC_HLTH;Versterking drempel +TP_ICM_FBW;Zwart-wit +TP_ICM_GAMUT;Begrens kleurruimte !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. -!TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 -!TP_ICM_NEUTRAL;Reset -!TP_ICM_OUTPUTPROFILE_TOOLTIP;By default all RTv4 or RTv2 profiles are with TRC - sRGB: g=2.4 s=12.92\n\nWith 'ICC Profile Creator' you can generate v4 or v2 profiles with the following choices;\n-Primaries: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Custom\n-TRC: BT709, sRGB, linear, standard g=2.2, standard g=1.8, Custom\n-Illuminant: D41, D50, D55, D60, D65, D80, stdA 2856K +TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 +TP_ICM_NEUTRAL;Zet terug +TP_ICM_OUTPUTPROFILE_TOOLTIP;Alle RTv4- of RTv2-profielen zijn met TRC - sRGB: g=2,4 s=12,92\n\nMet de ICC-profielmaker kunt u v4- of v2-profielen creëren met de volgende keuzen:\n-Primaire kleuren: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB en Aangepast\n-TRC: BT709, sRGB, lineair, standaard g=2,2, standaard g=1,8, Aangepast\n-Illuminant: D41, D50, D55, D60, D65, D80, stdA 2856K !TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 !TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 !TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different color mode for an image, you permanently change the color values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic color adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 -!TP_ICM_REDFRAME;Custom Primaries -!TP_ICM_TRCFRAME;Abstract Profile +TP_ICM_REDFRAME;Aangepaste primaire kleuren +TP_ICM_TRCFRAME;Abstract Profiel !TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. -!TP_ICM_WORKING_CIEDIAG;CIE xy diagram -!TP_ICM_WORKING_ILLU;Illuminant -!TP_ICM_WORKING_ILLU_1500;Tungsten 1500K -!TP_ICM_WORKING_ILLU_2000;Tungsten 2000K -!TP_ICM_WORKING_ILLU_D41;D41 -!TP_ICM_WORKING_ILLU_D50;D50 -!TP_ICM_WORKING_ILLU_D55;D55 -!TP_ICM_WORKING_ILLU_D60;D60 -!TP_ICM_WORKING_ILLU_D65;D65 -!TP_ICM_WORKING_ILLU_D80;D80 -!TP_ICM_WORKING_ILLU_D120;D120 -!TP_ICM_WORKING_ILLU_NONE;Default -!TP_ICM_WORKING_ILLU_STDA;stdA 2875K -!TP_ICM_WORKING_PRESER;Preserves Pastel tones -!TP_ICM_WORKING_PRIM;Destination primaries +TP_ICM_WORKING_CIEDIAG;CIE xy diagram +TP_ICM_WORKING_ILLU;Illuminant +TP_ICM_WORKING_ILLU_1500;Tungsten 1500K +TP_ICM_WORKING_ILLU_2000;Tungsten 2000K +TP_ICM_WORKING_ILLU_D41;D41 +TP_ICM_WORKING_ILLU_D50;D50 +TP_ICM_WORKING_ILLU_D55;D55 +TP_ICM_WORKING_ILLU_D60;D60 +TP_ICM_WORKING_ILLU_D65;D65 +TP_ICM_WORKING_ILLU_D80;D80 +TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_NONE;Standaard +TP_ICM_WORKING_ILLU_STDA;stdA 2875K +TP_ICM_WORKING_PRESER;Beschermt pasteltinten +TP_ICM_WORKING_PRIM;Bestemming primaire kleuren !TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. -!TP_ICM_WORKING_PRIM_AC0;ACESp0 -!TP_ICM_WORKING_PRIM_ACE;ACESp1 -!TP_ICM_WORKING_PRIM_ADOB;Adobe RGB -!TP_ICM_WORKING_PRIM_BET;Beta RGB -!TP_ICM_WORKING_PRIM_BRU;BruceRGB -!TP_ICM_WORKING_PRIM_BST;BestRGB -!TP_ICM_WORKING_PRIM_CUS;Custom (sliders) -!TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) -!TP_ICM_WORKING_PRIM_JDCMAX;JDC Max -!TP_ICM_WORKING_PRIM_NONE;Default -!TP_ICM_WORKING_PRIM_PROP;ProPhoto -!TP_ICM_WORKING_PRIM_REC;Rec2020 -!TP_ICM_WORKING_PRIM_SRGB;sRGB -!TP_ICM_WORKING_PRIM_WID;WideGamut -!TP_ICM_WORKING_TRC_18;Prophoto g=1.8 -!TP_ICM_WORKING_TRC_22;Adobe g=2.2 -!TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 -!TP_ICM_WORKING_TRC_LIN;Linear g=1 -!TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 -!TP_LOCALLAB_ACTIV;Luminance only -!TP_LOCALLAB_ACTIVSPOT;Enable Spot -!TP_LOCALLAB_ADJ;Equalizer Color -!TP_LOCALLAB_AMOUNT;Amount -!TP_LOCALLAB_ARTIF;Shape detection -!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. -!TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto -!TP_LOCALLAB_AVOID;Avoid color shift +TP_ICM_WORKING_PRIM_AC0;ACESp0 +TP_ICM_WORKING_PRIM_ACE;ACESp1 +TP_ICM_WORKING_PRIM_ADOB;Adobe RGB +TP_ICM_WORKING_PRIM_BET;Beta RGB +TP_ICM_WORKING_PRIM_BRU;BruceRGB +TP_ICM_WORKING_PRIM_BST;BestRGB +TP_ICM_WORKING_PRIM_CUS;Aangepast (schuiven) +TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy diagram) +TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_NONE;Standaard +TP_ICM_WORKING_PRIM_PROP;ProPhoto +TP_ICM_WORKING_PRIM_REC;Rec2020 +TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_WID;WideGamut +TP_ICM_WORKING_TRC_18;Prophoto g=1,8 +TP_ICM_WORKING_TRC_22;Adobe g=2,2 +TP_ICM_WORKING_TRC_BT709;BT709 g=2,22 s=4,5 +TP_ICM_WORKING_TRC_LIN;Linear g=1 +TP_ICM_WORKING_TRC_SRGB;sRGB g=2,4 s=12,92 +TP_LOCALLAB_ACTIV;Alleen luminantie +TP_LOCALLAB_ACTIVSPOT;Activeer spot +TP_LOCALLAB_ADJ;Kleurequalizer +TP_LOCALLAB_AMOUNT;Hoeveelheid +TP_LOCALLAB_ARTIF;Vormdetectie +!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE bereik threshold increases the range of ΔE bereik. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the bereik. +TP_LOCALLAB_AUTOGRAY;Autom. gemiddelde luminantie (Yb%) +TP_LOCALLAB_AUTOGRAYCIE;Auto +TP_LOCALLAB_AVOID;Voorkom kleurverschuiving !TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. -!TP_LOCALLAB_AVOIDMUN;Munsell correction only +TP_LOCALLAB_AVOIDMUN;Alleen Munsell-correctie !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. -!TP_LOCALLAB_AVOIDRAD;Soft radius -!TP_LOCALLAB_BALAN;ab-L balance (ΔE) -!TP_LOCALLAB_BALANEXP;Laplacian balance -!TP_LOCALLAB_BALANH;C-H balance (ΔE) +TP_LOCALLAB_AVOIDRAD;Verzachtingsstraal +TP_LOCALLAB_BALAN;ab-L-balans (ΔE) +TP_LOCALLAB_BALANEXP;Laplacian-balans +TP_LOCALLAB_BALANH;C-H-balans (ΔE) !TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. -!TP_LOCALLAB_BASELOG;Shadows range (logarithm base) -!TP_LOCALLAB_BILATERAL;Bilateral filter -!TP_LOCALLAB_BLACK_EV;Black Ev -!TP_LOCALLAB_BLCO;Chrominance only -!TP_LOCALLAB_BLENDMASKCOL;Blend -!TP_LOCALLAB_BLENDMASKMASK;Add/subtract luma mask -!TP_LOCALLAB_BLENDMASKMASKAB;Add/subtract chroma mask +TP_LOCALLAB_BASELOG;Bereik schaduwen (logaritmische basis) +TP_LOCALLAB_BILATERAL;Bilateraal filter +TP_LOCALLAB_BLACK_EV;Zwart LW +TP_LOCALLAB_BLCO;Alleen chrominantie +TP_LOCALLAB_BLENDMASKCOL;Meng +TP_LOCALLAB_BLENDMASKMASK;Voeg toe/trek af luma-masker +TP_LOCALLAB_BLENDMASKMASKAB;Voeg toe/trek af chroma-masker !TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;If this slider = 0 no action.\nAdd or subtract the mask from the original image. !TP_LOCALLAB_BLENDMASK_TOOLTIP;If blend = 0 only shape detection is improved.\nIf blend > 0 the mask is added to the image. If blend < 0 the mask is subtracted from the image. -!TP_LOCALLAB_BLGUID;Guided Filter -!TP_LOCALLAB_BLINV;Inverse -!TP_LOCALLAB_BLLC;Luminance & Chrominance -!TP_LOCALLAB_BLLO;Luminance only -!TP_LOCALLAB_BLMED;Median +TP_LOCALLAB_BLGUID;Begeleid filter +TP_LOCALLAB_BLINV;Inverteer +TP_LOCALLAB_BLLC;Luminantie & Chrominantie +TP_LOCALLAB_BLLO;Alleen luminantie +TP_LOCALLAB_BLMED;Mediaan !TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal: direct blur and noise with all settings.\nInverse: blur and noise with all settings. Warning, some settings may give curious results. -!TP_LOCALLAB_BLNOI_EXP;Blur & Noise -!TP_LOCALLAB_BLNORM;Normal -!TP_LOCALLAB_BLUFR;Blur/Grain & Denoise -!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for scope and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the scope.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. -!TP_LOCALLAB_BLUR;Gaussian Blur - Noise - Grain -!TP_LOCALLAB_BLURCOL;Radius +TP_LOCALLAB_BLNOI_EXP;Vervaging & Ruis +TP_LOCALLAB_BLNORM;Normaal +TP_LOCALLAB_BLUFR;Vervaging/Korrel & Ruisvermindering +!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for bereik and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the bereik.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. +TP_LOCALLAB_BLUR;Gaussiaanse vervaging - Ruis - Korrel +TP_LOCALLAB_BLURCOL;Straal !TP_LOCALLAB_BLURCOLDE_TOOLTIP;The image used to calculate dE is blurred slightly to avoid taking isolated pixels into account. -!TP_LOCALLAB_BLURDE;Blur shape detection -!TP_LOCALLAB_BLURLC;Luminance only -!TP_LOCALLAB_BLURLEVELFRA;Blur levels +TP_LOCALLAB_BLURDE;Vormdetectie vervaging +TP_LOCALLAB_BLURLC;Alleen luminantie +TP_LOCALLAB_BLURLEVELFRA;Vervagingsniveaus !TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. !TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). -!TP_LOCALLAB_BLUR_TOOLNAME;Blur/Grain & Denoise -!TP_LOCALLAB_BLWH;All changes forced in Black-and-White +TP_LOCALLAB_BLUR_TOOLNAME;Vervaging/Korrel & Ruisvermindering +TP_LOCALLAB_BLWH;Alle veranderingen forceren in Zwart-wit !TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. -!TP_LOCALLAB_BUTTON_ADD;Add -!TP_LOCALLAB_BUTTON_DEL;Delete -!TP_LOCALLAB_BUTTON_DUPL;Duplicate -!TP_LOCALLAB_BUTTON_REN;Rename -!TP_LOCALLAB_BUTTON_VIS;Show/Hide -!TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev -!TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) +TP_LOCALLAB_BUTTON_ADD;Voeg toe +TP_LOCALLAB_BUTTON_DEL;Wis +TP_LOCALLAB_BUTTON_DUPL;Dupliceer +TP_LOCALLAB_BUTTON_REN;Hernoem +TP_LOCALLAB_BUTTON_VIS;Toon/verberg +TP_LOCALLAB_BWFORCE;Gebruik Zwart LW & Wit LW +TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Piekluminantie) !TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. -!TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments -!TP_LOCALLAB_CAMMODE;CAM model -!TP_LOCALLAB_CAMMODE_CAM16;CAM 16 -!TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz -!TP_LOCALLAB_CATAD;Chromatic adaptation/Cat16 -!TP_LOCALLAB_CBDL;Contrast by Detail Levels +TP_LOCALLAB_CAM16_FRA;Cam16 Beeldaanpassingen +TP_LOCALLAB_CAMMODE;CAM-model +TP_LOCALLAB_CAMMODE_CAM16;CAM 16 +TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz +TP_LOCALLAB_CATAD;Chromatische aanpassing/Cat16 +TP_LOCALLAB_CBDL;Contrast per Detailniveaus !TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. !TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. !TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. -!TP_LOCALLAB_CBDL_TOOLNAME;Contrast by Detail Levels -!TP_LOCALLAB_CENTER_X;Center X -!TP_LOCALLAB_CENTER_Y;Center Y -!TP_LOCALLAB_CH;CL - LC -!TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_CHROMA;Chrominance -!TP_LOCALLAB_CHROMABLU;Chroma levels +TP_LOCALLAB_CBDL_TOOLNAME;Contrast per Detailniveaus +TP_LOCALLAB_CENTER_X;Centrum X +TP_LOCALLAB_CENTER_Y;Centrum Y +TP_LOCALLAB_CH;CL - LC +TP_LOCALLAB_CHRO46LABEL;Chroma-niveaus 456: Gemiddeld=%1 Hoog=%2 +TP_LOCALLAB_CHROLABEL;Chroma-niveaus 0123: Gemiddeld=%1 Hoog=%2 +TP_LOCALLAB_CHROMA;Chrominantie +TP_LOCALLAB_CHROMABLU;Chroma-niveaus !TP_LOCALLAB_CHROMABLU_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMACBDL;Chroma +TP_LOCALLAB_CHROMACBDL;Chroma !TP_LOCALLAB_CHROMACB_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMALEV;Chroma levels -!TP_LOCALLAB_CHROMASKCOL;Chroma +TP_LOCALLAB_CHROMALEV;Chroma-niveaus +TP_LOCALLAB_CHROMASKCOL;Chroma !TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). -!TP_LOCALLAB_CHROML;Chroma (C) -!TP_LOCALLAB_CHRRT;Chroma -!TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) -!TP_LOCALLAB_CIEC;Use Ciecam environment parameters +TP_LOCALLAB_CHROML;Chroma (C) +TP_LOCALLAB_CHRRT;Chroma +TP_LOCALLAB_CIE;Kleurweergave (Cam16 & JzCzHz) +TP_LOCALLAB_CIEC;Gebruik Ciecam omgevingsparameters !TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. -!TP_LOCALLAB_CIECOLORFRA;Color -!TP_LOCALLAB_CIECONTFRA;Contrast -!TP_LOCALLAB_CIELIGHTCONTFRA;Lighting & Contrast -!TP_LOCALLAB_CIELIGHTFRA;Lighting -!TP_LOCALLAB_CIEMODE;Change tool position -!TP_LOCALLAB_CIEMODE_COM;Default -!TP_LOCALLAB_CIEMODE_DR;Dynamic Range -!TP_LOCALLAB_CIEMODE_TM;Tone-Mapping +TP_LOCALLAB_CIECOLORFRA;Kleur +TP_LOCALLAB_CIECONTFRA;Contrast +TP_LOCALLAB_CIELIGHTCONTFRA;Verlichting & Contrast +TP_LOCALLAB_CIELIGHTFRA;Verlichting +TP_LOCALLAB_CIEMODE;Verander gereedschapspositie +TP_LOCALLAB_CIEMODE_COM;Standaard +TP_LOCALLAB_CIEMODE_DR;Dynamisch bereik +TP_LOCALLAB_CIEMODE_TM;Toonmappen !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. -!TP_LOCALLAB_CIEMODE_WAV;Wavelet -!TP_LOCALLAB_CIETOOLEXP;Curves -!TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) -!TP_LOCALLAB_CIRCRADIUS;Spot size +TP_LOCALLAB_CIEMODE_WAV;Wavelet +TP_LOCALLAB_CIETOOLEXP;Curven +TP_LOCALLAB_CIE_TOOLNAME;Kleurweergave (Cam16 & JzCzHz) +TP_LOCALLAB_CIRCRADIUS;Spotgrootte !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. -!TP_LOCALLAB_CLARICRES;Merge chroma -!TP_LOCALLAB_CLARIFRA;Clarity & Sharp mask/Blend & Soften Images +TP_LOCALLAB_CLARICRES;Meng chroma +TP_LOCALLAB_CLARIFRA;Klaarheid (Clarity) & Scherptemasker/Meng & Verzacht beelden !TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. -!TP_LOCALLAB_CLARILRES;Merge luma -!TP_LOCALLAB_CLARISOFT;Soft radius +TP_LOCALLAB_CLARILRES;Meng luma +TP_LOCALLAB_CLARISOFT;Verzacht straal !TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. !TP_LOCALLAB_CLARISOFT_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and all wavelet pyramid processes. To deactivate, set slider to zero. -!TP_LOCALLAB_CLARITYML;Clarity +TP_LOCALLAB_CLARITYML;Klaarheid (Clarity) !TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. -!TP_LOCALLAB_CLIPTM;Clip restored data (gain) -!TP_LOCALLAB_COFR;Color & Light -!TP_LOCALLAB_COLORDE;ΔE preview color - intensity +TP_LOCALLAB_CLIPTM;Kap herstelde data af (versterking) +TP_LOCALLAB_COFR;Kleur & Licht +TP_LOCALLAB_COLORDE;ΔE Voorbeeldkleur - intensiteit !TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. -!TP_LOCALLAB_COLORSCOPE;Scope (color tools) -!TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. -!TP_LOCALLAB_COLOR_CIE;Color curve -!TP_LOCALLAB_COLOR_TOOLNAME;Color & Light -!TP_LOCALLAB_COL_NAME;Name -!TP_LOCALLAB_COL_VIS;Status -!TP_LOCALLAB_COMPFRA;Directional contrast -!TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping -!TP_LOCALLAB_CONTCOL;Contrast threshold -!TP_LOCALLAB_CONTFRA;Contrast by level -!TP_LOCALLAB_CONTRAST;Contrast +TP_LOCALLAB_COLOR;Bereik (kleurgereedschappen) +!TP_LOCALLAB_COLOR_TOOLTIP;Common bereik slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own bereik controls. +TP_LOCALLAB_COLOR_CIE;Kleurcurve +TP_LOCALLAB_COLOR_TOOLNAME;Kleur & Licht +TP_LOCALLAB_COL_NAME;Naam +TP_LOCALLAB_COL_VIS;Status +TP_LOCALLAB_COMPFRA;Directioneel contrast +TP_LOCALLAB_COMPREFRA;Wavelet-niveau toonmappen +TP_LOCALLAB_CONTCOL;Contrastdrempel +TP_LOCALLAB_CONTFRA;Contrast per niveau +TP_LOCALLAB_CONTRAST;Contrast !TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. -!TP_LOCALLAB_CONTRESID;Contrast +TP_LOCALLAB_CONTRESID;Contrast !TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. -!TP_LOCALLAB_CONTTHR;Contrast Threshold -!TP_LOCALLAB_CONTWFRA;Local contrast -!TP_LOCALLAB_CSTHRESHOLD;Wavelet levels -!TP_LOCALLAB_CSTHRESHOLDBLUR;Wavelet level selection -!TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance 'Super' -!TP_LOCALLAB_CURVCURR;Normal +TP_LOCALLAB_CONTTHR;Contrastdrempel +TP_LOCALLAB_CONTWFRA;Lokaal contrast +TP_LOCALLAB_CSTHRESHOLD;Wavelet-niveaus +TP_LOCALLAB_CSTHRESHOLDBLUR;Selecteer Wavelet-niveau +TP_LOCALLAB_CURV;Lichtheid - Contrast - Chrominantie 'Super' +TP_LOCALLAB_CURVCURR;Normaal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. -!TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve +TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tooncurve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. -!TP_LOCALLAB_CURVES_CIE;Tone curve -!TP_LOCALLAB_CURVNONE;Disable curves -!TP_LOCALLAB_DARKRETI;Darkness -!TP_LOCALLAB_DEHAFRA;Dehaze -!TP_LOCALLAB_DEHAZ;Strength +TP_LOCALLAB_CURVES_CIE;Tooncurven +TP_LOCALLAB_CURVNONE;De-activeer curven +TP_LOCALLAB_DARKRETI;Donker +TP_LOCALLAB_DEHAFRA;Ontnevelen +TP_LOCALLAB_DEHAZ;Kracht !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. -!TP_LOCALLAB_DELTAD;Delta balance -!TP_LOCALLAB_DELTAEC;ΔE Image mask -!TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask -!TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask +TP_LOCALLAB_DELTAD;Delta-balans +TP_LOCALLAB_DELTAEC;ΔE Beeldmasker +TP_LOCALLAB_DENOI1_EXP;Ruisvermindering volgens luminantiemasker +TP_LOCALLAB_DENOI2_EXP;Herstel volgens luminantiemasker !TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). @@ -3431,57 +3428,57 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Allows you to direct the chroma noise reduction towards either the blue-yellow or red-green colors. !TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Allows you to carry out more or less noise reduction in either the shadows or the highlights. !TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOIMASK;Denoise chroma mask +TP_LOCALLAB_DENOIMASK;Chroma-masker ruisvermindering !TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. !TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. !TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. -!TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance -!TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance -!TP_LOCALLAB_DENOI_EXP;Denoise -!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. -!TP_LOCALLAB_DEPTH;Depth -!TP_LOCALLAB_DETAIL;Local contrast -!TP_LOCALLAB_DETAILFRA;Edge detection - DCT -!TP_LOCALLAB_DETAILSH;Details -!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold -!TP_LOCALLAB_DIVGR;Gamma -!TP_LOCALLAB_DUPLSPOTNAME;Copy -!TP_LOCALLAB_EDGFRA;Edge sharpness -!TP_LOCALLAB_EDGSHOW;Show all tools -!TP_LOCALLAB_ELI;Ellipse -!TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping -!TP_LOCALLAB_ENABLE_MASK;Enable mask -!TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominantie +TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminantie +TP_LOCALLAB_DENOI_EXP;Ruisvermindering +!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n bereik allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. +TP_LOCALLAB_DEPTH;Diepte +TP_LOCALLAB_DETAIL;Lokaal contrast +TP_LOCALLAB_DETAILFRA;Randdetectie - DCT +TP_LOCALLAB_DETAILSH;Details +TP_LOCALLAB_DETAILTHR;Detaildrempel Lum/chrom +TP_LOCALLAB_DIVGR;Gamma +TP_LOCALLAB_DUPLSPOTNAME;Kopieer +TP_LOCALLAB_EDGFRA;Randscherpte +TP_LOCALLAB_EDGSHOW;Toon alle gereedschappen +TP_LOCALLAB_ELI;Ellips +TP_LOCALLAB_ENABLE_AFTER_MASK;Gebruik toonmappen +TP_LOCALLAB_ENABLE_MASK;Activeer masker +TP_LOCALLAB_ENABLE_MASKAFT;Gebruik alle algoritmen Belichting !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. -!TP_LOCALLAB_ENH;Enhanced -!TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise -!TP_LOCALLAB_EPSBL;Detail -!TP_LOCALLAB_EQUIL;Normalize luminance +TP_LOCALLAB_ENH;Verbeterd +TP_LOCALLAB_ENHDEN;Verbeterd + chroma-ruisonderdrukking +TP_LOCALLAB_EPSBL;Detail +TP_LOCALLAB_EQUIL;Normaliseer luminantie !TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. -!TP_LOCALLAB_ESTOP;Edge stopping -!TP_LOCALLAB_EV_DUPL;Copy of -!TP_LOCALLAB_EV_NVIS;Hide -!TP_LOCALLAB_EV_NVIS_ALL;Hide all -!TP_LOCALLAB_EV_VIS;Show -!TP_LOCALLAB_EV_VIS_ALL;Show all -!TP_LOCALLAB_EXCLUF;Excluding -!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. -!TP_LOCALLAB_EXCLUTYPE;Spot method +TP_LOCALLAB_ESTOP;Edge stopping +TP_LOCALLAB_EV_DUPL;Kopie van +TP_LOCALLAB_EV_NVIS;Verberg +TP_LOCALLAB_EV_NVIS_ALL;Verberg allemaal +TP_LOCALLAB_EV_VIS;Toon +TP_LOCALLAB_EV_VIS_ALL;Toon alles +TP_LOCALLAB_EXCLUF;Uitsluiting +!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'bereik' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. +TP_LOCALLAB_EXCLUTYPE;Spotmethode !TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. -!TP_LOCALLAB_EXECLU;Excluding spot -!TP_LOCALLAB_EXFULL;Full image -!TP_LOCALLAB_EXNORM;Normal spot +TP_LOCALLAB_EXECLU;Sluit spot uit +TP_LOCALLAB_EXFULL;Volledige afbeelding +TP_LOCALLAB_EXNORM;Normale spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). -!TP_LOCALLAB_EXPCHROMA;Chroma compensation +TP_LOCALLAB_EXPCHROMA;Chroma-compensatie !TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. !TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. -!TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ -!TP_LOCALLAB_EXPCOMPINV;Exposure compensation -!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' +TP_LOCALLAB_EXPCOMP;Belichtingscompensatie Æ’ +TP_LOCALLAB_EXPCOMPINV;Belichtingscompensatie +!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE bereik threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' !TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. -!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. -!TP_LOCALLAB_EXPCURV;Curves -!TP_LOCALLAB_EXPGRAD;Graduated Filter +!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'bereik' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. +TP_LOCALLAB_EXPCURV;Curven +TP_LOCALLAB_EXPGRAD;Verloopfilter !TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. @@ -3489,213 +3486,212 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_EXPLAP_TOOLTIP;Moving the slider to the right progressively reduces the contrast. !TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a color and luminance background (fewer possibilties). !TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applies a median filter before the Laplace transform to prevent artifacts (noise).\nYou can also use the 'Denoise' tool. -!TP_LOCALLAB_EXPOSE;Dynamic Range & Exposure +TP_LOCALLAB_EXPOSE;Dynamisch bereik & Belichting !TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. -!TP_LOCALLAB_EXPRETITOOLS;Advanced Retinex Tools -!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'Scope' values to simulate smaller spots. -!TP_LOCALLAB_EXPTOOL;Exposure Tools -!TP_LOCALLAB_EXP_TOOLNAME;Dynamic Range & Exposure -!TP_LOCALLAB_FATAMOUNT;Amount -!TP_LOCALLAB_FATANCHOR;Anchor -!TP_LOCALLAB_FATDETAIL;Detail -!TP_LOCALLAB_FATFRA;Dynamic Range Compression Æ’ +TP_LOCALLAB_EXPRETITOOLS;Geavanceerde Retinex-gereedschappen +!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'bereik' values to simulate smaller spots. +TP_LOCALLAB_EXPTOOL;Belichtingsgereedschappen +TP_LOCALLAB_EXP_TOOLNAME;Dynamisch bereik & Belichting +TP_LOCALLAB_FATAMOUNT;Hoeveelheid +TP_LOCALLAB_FATANCHOR;Anker +TP_LOCALLAB_FATDETAIL;Detail +TP_LOCALLAB_FATFRA;Compressie dynamisch bereik Æ’ !TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. -!TP_LOCALLAB_FATLEVEL;Sigma -!TP_LOCALLAB_FATSAT;Saturation control -!TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ +TP_LOCALLAB_FATLEVEL;Sigma +TP_LOCALLAB_FATSHFRA;Masker compressie dynamisch bereik Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) -!TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ +TP_LOCALLAB_FEATVALUE;'Veer'verloop (Verloopfilters) +TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). -!TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform -!TP_LOCALLAB_FFTWBLUR;Æ’ - Always Use Fast Fourier Transform +TP_LOCALLAB_FFTW;Æ’ - Gebruik Fast Fourier-transformatie +TP_LOCALLAB_FFTWBLUR;Æ’ - Gebruik altijd Fast Fourier-transformatie !TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image !TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. -!TP_LOCALLAB_GAM;Gamma -!TP_LOCALLAB_GAMC;Gamma +TP_LOCALLAB_GAM;Gamma +TP_LOCALLAB_GAMC;Gamma !TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMFRA;Tone response curve (TRC) -!TP_LOCALLAB_GAMM;Gamma -!TP_LOCALLAB_GAMMASKCOL;Gamma +TP_LOCALLAB_GAMFRA;Toonresponscurve (TRC) +TP_LOCALLAB_GAMM;Gamma +TP_LOCALLAB_GAMMASKCOL;Gamma !TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_GAMSH;Gamma -!TP_LOCALLAB_GAMUTLABRELA;Lab -!TP_LOCALLAB_GAMUTMUNSELL;Munsell only -!TP_LOCALLAB_GAMUTNON;None -!TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute -!TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative -!TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) -!TP_LOCALLAB_GRADANG;Gradient angle +TP_LOCALLAB_GAMSH;Gamma +TP_LOCALLAB_GAMUTLABRELA;Lab +TP_LOCALLAB_GAMUTMUNSELL;Alleen Munsell +TP_LOCALLAB_GAMUTNON;Geen +TP_LOCALLAB_GAMUTXYZABSO;XYZ absoluut +TP_LOCALLAB_GAMUTXYZRELA;XYZ relatief +TP_LOCALLAB_GAMW;Gamma (wavelet-pyramiden) +TP_LOCALLAB_GRADANG;Hoek verloop !TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. -!TP_LOCALLAB_GRADFRA;Graduated Filter Mask +TP_LOCALLAB_GRADFRA;Masker Verloopfilter !TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. -!TP_LOCALLAB_GRADLOGFRA;Graduated Filter Luminance -!TP_LOCALLAB_GRADSTR;Gradient strength +TP_LOCALLAB_GRADLOGFRA;Verloopfilter - Luminantie +TP_LOCALLAB_GRADSTR;Verloopsterkte !TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. -!TP_LOCALLAB_GRADSTRCHRO;Chroma gradient strength -!TP_LOCALLAB_GRADSTRHUE;Hue gradient strength -!TP_LOCALLAB_GRADSTRHUE2;Hue gradient strength +TP_LOCALLAB_GRADSTRCHRO;Chroma verloopsterkte +TP_LOCALLAB_GRADSTRHUE;Tint verloopsterkte +TP_LOCALLAB_GRADSTRHUE2;Tint verloopsterkte !TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength. -!TP_LOCALLAB_GRADSTRLUM;Luma gradient strength -!TP_LOCALLAB_GRAINFRA;Film Grain 1:1 -!TP_LOCALLAB_GRAINFRA2;Coarseness +TP_LOCALLAB_GRADSTRLUM;Luma verloopsterkte +TP_LOCALLAB_GRAINFRA;Filmkorrel 1:1 +TP_LOCALLAB_GRAINFRA2;Grofheid !TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. -!TP_LOCALLAB_GRALWFRA;Graduated filter (local contrast) +TP_LOCALLAB_GRALWFRA;Verloopfilter (lokaal contrast) !TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). !TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. -!TP_LOCALLAB_GRIDONE;Color Toning -!TP_LOCALLAB_GRIDTWO;Direct -!TP_LOCALLAB_GUIDBL;Soft radius +TP_LOCALLAB_GRIDONE;Kleurtoning +TP_LOCALLAB_GRIDTWO;Direct +TP_LOCALLAB_GUIDBL;Verzachtingsstraal !TP_LOCALLAB_GUIDBL_TOOLTIP;Applies a guided filter with adjustable radius. Allows you to reduce artifacts or blur the image. !TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Changes the distribution function of the guided filter. Negative values simulate a Gaussian blur. -!TP_LOCALLAB_GUIDFILTER;Guided filter radius +TP_LOCALLAB_GUIDFILTER;Straal Begeleid filter !TP_LOCALLAB_GUIDFILTER_TOOLTIP;Can reduce or increase artifacts. !TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensity of the guided filter. !TP_LOCALLAB_HHMASK_TOOLTIP;Fine hue adjustments for example for the skin. -!TP_LOCALLAB_HIGHMASKCOL;Highlights -!TP_LOCALLAB_HLH;H -!TP_LOCALLAB_HUECIE;Hue -!TP_LOCALLAB_IND;Independent (mouse) -!TP_LOCALLAB_INDSL;Independent (mouse + sliders) -!TP_LOCALLAB_INVBL;Inverse +TP_LOCALLAB_HIGHMASKCOL;Hoge lichten +TP_LOCALLAB_HLH;H +TP_LOCALLAB_HUECIE;Tint +TP_LOCALLAB_IND;Onafhankelijk (muis) +TP_LOCALLAB_INDSL;Onafhankelijk (muis + schuiven) +TP_LOCALLAB_INVBL;Inverteer !TP_LOCALLAB_INVBL_TOOLTIP;Alternative to 'Inverse' mode: use two spots\nFirst Spot:\n Full Image\n\nSecond spot: Excluding spot. -!TP_LOCALLAB_INVERS;Inverse +TP_LOCALLAB_INVERS;Inverteer !TP_LOCALLAB_INVERS_TOOLTIP;Fewer possibilities if selected (Inverse).\n\nAlternative: use two spots\nFirst Spot:\n Full Image\n \nSecond spot: Excluding spot\n\n Inverse will enable this tool for the area outside the spot, while the area within the spot will remain unaffected by the tool. -!TP_LOCALLAB_INVMASK;Inverse algorithm -!TP_LOCALLAB_ISOGR;Distribution (ISO) -!TP_LOCALLAB_JAB;Uses Black Ev & White Ev +TP_LOCALLAB_INVMASK;Keer algoritme om +TP_LOCALLAB_ISOGR;Distributie (ISO) +TP_LOCALLAB_JAB;Gebruikt Zwart Ev & Wit Ev !TP_LOCALLAB_JABADAP_TOOLTIP;Perceptual Uniform adaptation.\nAutomatically adjusts the relationship between Jz and saturation taking into account 'Absolute luminance'. -!TP_LOCALLAB_JZ100;Jz reference 100cd/m2 +TP_LOCALLAB_JZ100;Jz-referentie 100cd/m2 !TP_LOCALLAB_JZ100_TOOLTIP;Automatically adjusts the reference Jz 100 cd/m2 level (image signal).\nChanges the saturation level and action of 'PU adaptation' (Perceptual Uniform adaptation). -!TP_LOCALLAB_JZADAP;PU adaptation -!TP_LOCALLAB_JZCH;Chroma -!TP_LOCALLAB_JZCHROM;Chroma -!TP_LOCALLAB_JZCLARICRES;Merge chroma Cz -!TP_LOCALLAB_JZCLARILRES;Merge Jz -!TP_LOCALLAB_JZCONT;Contrast -!TP_LOCALLAB_JZFORCE;Force max Jz to 1 +TP_LOCALLAB_JZADAP;PU-adaptatie +TP_LOCALLAB_JZCH;Chroma +TP_LOCALLAB_JZCHROM;Chroma +TP_LOCALLAB_JZCLARICRES;Voeg samen met chroma Cz +TP_LOCALLAB_JZCLARILRES;Voeg samen Jz +TP_LOCALLAB_JZCONT;Contrast +TP_LOCALLAB_JZFORCE;Forceer max Jz tot 1 !TP_LOCALLAB_JZFORCE_TOOLTIP;Allows you to force the maximum Jz value to 1 for better slider and curve response. -!TP_LOCALLAB_JZFRA;Jz Cz Hz Image Adjustments -!TP_LOCALLAB_JZHFRA;Curves Hz -!TP_LOCALLAB_JZHJZFRA;Curve Jz(Hz) -!TP_LOCALLAB_JZHUECIE;Hue Rotation -!TP_LOCALLAB_JZLIGHT;Brightness -!TP_LOCALLAB_JZLOG;Log encoding Jz +TP_LOCALLAB_JZFRA;Jz Cz Hz Beeldaanpassingen +TP_LOCALLAB_JZHFRA;Curven Hz +TP_LOCALLAB_JZHJZFRA;Curve Jz(Hz) +TP_LOCALLAB_JZHUECIE;Tintrotatie +TP_LOCALLAB_JZLIGHT;Helderheid +TP_LOCALLAB_JZLOG;Log-codering Jz !TP_LOCALLAB_JZLOGWBS_TOOLTIP;Black Ev and White Ev adjustments can be different depending on whether Log encoding or Sigmoid is used.\nFor Sigmoid, a change (increase in most cases) of White Ev may be necessary to obtain a better rendering of highlights, contrast and saturation. !TP_LOCALLAB_JZLOGWB_TOOLTIP;If Auto is enabled, it will calculate and adjust the Ev levels and the 'Mean luminance Yb%' for the spot area. The resulting values will be used by all Jz operations including 'Log Encoding Jz'.\nAlso calculates the absolute luminance at the time of shooting. !TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed as a percentage of gray. 18% gray corresponds to a background luminance of 50% when expressed in CIE L.\nThe data is based on the mean luminance of the image.\nWhen used with Log Encoding, the mean luminance is used to determine the amount of gain that needs to be applied to the signal prior to the log encoding. Lower values of mean luminance will result in increased gain. !TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (only in 'Advanced' mode). Only operational if the output device (monitor) is HDR (peak luminance higher than 100 cd/m2 - ideally between 4000 and 10000 cd/m2. Black point luminance inferior to 0.005 cd/m2). This supposes a) the ICC-PCS for the screen uses Jzazbz (or XYZ), b) works in real precision, c) that the monitor is calibrated (if possible with a DCI-P3 or Rec-2020 gamut), d) that the usual gamma (sRGB or BT709) is replaced by a Perceptual Quantiser (PQ) function. -!TP_LOCALLAB_JZPQFRA;Jz remapping +TP_LOCALLAB_JZPQFRA;Jz herindeling !TP_LOCALLAB_JZPQFRA_TOOLTIP;Allows you to adapt the Jz algorithm to an SDR environment or to the characteristics (performance) of an HDR environment as follows:\n a) for luminance values between 0 and 100 cd/m2, the system behaves as if it were in an SDR environment.\n b) for luminance values between 100 and 10000 cd/m2, you can adapt the algorithm to the HDR characteristics of the image and the monitor.\n\nIf 'PQ - Peak luminance' is set to 10000, 'Jz remappping' behaves in the same way as the original Jzazbz algorithm. -!TP_LOCALLAB_JZPQREMAP;PQ - Peak luminance +TP_LOCALLAB_JZPQREMAP;PQ - Piekluminantie !TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - allows you to change the internal PQ function (usually 10000 cd/m2 - default 120 cd/m2).\nCan be used to adapt to different images, processes and devices. -!TP_LOCALLAB_JZQTOJ;Relative luminance +TP_LOCALLAB_JZQTOJ;Relatieve luminantie !TP_LOCALLAB_JZQTOJ_TOOLTIP;Allows you to use 'Relative luminance' instead of 'Absolute luminance' - Brightness becomes Lightness.\nThe changes affect: the Brightness slider, the Contrast slider and the Jz(Jz) curve. -!TP_LOCALLAB_JZSAT;Saturation -!TP_LOCALLAB_JZSHFRA;Shadows/Highlights Jz -!TP_LOCALLAB_JZSOFTCIE;Soft radius (GuidedFilter) -!TP_LOCALLAB_JZSTRSOFTCIE;Strength GuidedFilter -!TP_LOCALLAB_JZTARGET_EV;Viewing Mean luminance (Yb%) -!TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) -!TP_LOCALLAB_JZWAVEXP;Wavelet Jz -!TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments -!TP_LOCALLAB_LABGRID;Color correction grid -!TP_LOCALLAB_LABGRIDMERG;Background -!TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 -!TP_LOCALLAB_LABSTRUM;Structure Mask +TP_LOCALLAB_JZSAT;Verzadiging +TP_LOCALLAB_JZSHFRA;Schaduwen/Hoge lichten Jz +TP_LOCALLAB_JZSOFTCIE;Verzachtingsstraal (Begeleid filter) +TP_LOCALLAB_JZSTRSOFTCIE;Kracht Begeleid filter +TP_LOCALLAB_JZTARGET_EV;Bezie gemiddelde luminantie (Yb%) +TP_LOCALLAB_JZTHRHCIE;Chroma-drempel voor Jz(Hz) +TP_LOCALLAB_JZWAVEXP;Wavelet Jz +TP_LOCALLAB_LABBLURM;Vervagingsmasker +TP_LOCALLAB_LABEL;Lokale aanpassingen +TP_LOCALLAB_LABGRID;Kleurcorrectierooster +TP_LOCALLAB_LABGRIDMERG;Achtergrond +TP_LOCALLAB_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 +TP_LOCALLAB_LABSTRUM;Structuurmasker !TP_LOCALLAB_LAPLACC;ΔØ Mask Laplacian solve PDE -!TP_LOCALLAB_LAPLACE;Laplacian threshold ΔE -!TP_LOCALLAB_LAPLACEXP;Laplacian threshold -!TP_LOCALLAB_LAPMASKCOL;Laplacian threshold +TP_LOCALLAB_LAPLACE;Laplacian-drempel ΔE +TP_LOCALLAB_LAPLACEXP;Laplacian-drempel +TP_LOCALLAB_LAPMASKCOL;Laplacian-drempel !TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the luminance values of the lighter areas. Can be used in conjunction with the L(L) and LC(H) curves. !TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. !TP_LOCALLAB_LAPRAD_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. !TP_LOCALLAB_LAP_MASK_TOOLTIP;Solves PDEs for all Laplacian masks.\nIf enabled the Laplacian threshold mask reduces artifacts and smooths the result.\nIf disabled the response is linear. -!TP_LOCALLAB_LCLABELS;Residual noise levels +TP_LOCALLAB_LCLABELS;Residuele ruisniveaus !TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. !TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improves quality and allows the use of large radii, but increases processing time (depends on the area to be processed). Preferable to use only for large radii. The size of the area can be reduced by a few pixels to optimize the FFTW. This can reduce the processing time by a factor of 1.5 to 10. -!TP_LOCALLAB_LC_TOOLNAME;Local Contrast & Wavelets -!TP_LOCALLAB_LEVELBLUR;Maximum blur levels -!TP_LOCALLAB_LEVELWAV;Wavelet levels +TP_LOCALLAB_LC_TOOLNAME;Lokaal Contrast & Wavelets +TP_LOCALLAB_LEVELBLUR;Maximum vervagingsniveaus +TP_LOCALLAB_LEVELWAV;Wavelet-niveaus !TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4. -!TP_LOCALLAB_LEVFRA;Levels -!TP_LOCALLAB_LIGHTNESS;Lightness +TP_LOCALLAB_LEVFRA;Niveaus +TP_LOCALLAB_LIGHTNESS;Lichtheid !TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse mode: selection = -100 forces luminance to zero. -!TP_LOCALLAB_LIGHTRETI;Lightness -!TP_LOCALLAB_LINEAR;Linearity -!TP_LOCALLAB_LIST_NAME;Add tool to current spot... +TP_LOCALLAB_LIGHTRETI;Lichtheid +TP_LOCALLAB_LINEAR;Lineariteit +TP_LOCALLAB_LIST_NAME;Voeg gereedschap toe aan huidige spot... !TP_LOCALLAB_LIST_TOOLTIP;You can select 3 levels of complexity for each tool: Basic, Standard and Advanced.\nThe default setting for all tools is Basic but this can be changed in the Preferences window.\nYou can also change the level of complexity on a per-tool basis while you are editing. !TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Allows you to decrease or increase the effect on particular levels of detail in the mask by targeting certain luminance zones (in general the lightest). !TP_LOCALLAB_LMASK_LL_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts). May create artifacts. -!TP_LOCALLAB_LOCCONT;Unsharp Mask -!TP_LOCALLAB_LOC_CONTRAST;Local Contrast & Wavelets -!TP_LOCALLAB_LOC_CONTRASTPYR;Pyramid 1: -!TP_LOCALLAB_LOC_CONTRASTPYR2;Pyramid 2: -!TP_LOCALLAB_LOC_CONTRASTPYR2LAB; Contrast by level/TM/Directional contrast -!TP_LOCALLAB_LOC_CONTRASTPYRLAB; Graduated Filter/Edge Sharpness/Blur -!TP_LOCALLAB_LOC_RESIDPYR;Residual image (Main) -!TP_LOCALLAB_LOG;Log Encoding -!TP_LOCALLAB_LOG1FRA;CAM16 Image Adjustments -!TP_LOCALLAB_LOG2FRA;Viewing Conditions -!TP_LOCALLAB_LOGAUTO;Automatic +TP_LOCALLAB_LOCCONT;Onscherptemasker +TP_LOCALLAB_LOC_CONTRAST;Lokaal Contrast & Wavelets +TP_LOCALLAB_LOC_CONTRASTPYR;Pyramide 1: +TP_LOCALLAB_LOC_CONTRASTPYR2;Pyramide 2: +TP_LOCALLAB_LOC_CONTRASTPYR2LAB;Contrast per niveau/TM/Directioneel contrast +TP_LOCALLAB_LOC_CONTRASTPYRLAB;Verloopfilter/Randscherpte/Vervaging +TP_LOCALLAB_LOC_RESIDPYR;Residueel beeld (Main) +TP_LOCALLAB_LOG;Log-codering +TP_LOCALLAB_LOG1FRA;CAM16 Beeldaanpassingen +TP_LOCALLAB_LOG2FRA;Kijkomstandigheden +TP_LOCALLAB_LOGAUTO;Automatisch !TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions. !TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid +TP_LOCALLAB_LOGCIE;Log-codering ipv. Sigmoid !TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. -!TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) +TP_LOCALLAB_LOGCOLORFL;Kleurrijkheid (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. -!TP_LOCALLAB_LOGCONQL;Contrast (Q) -!TP_LOCALLAB_LOGCONTHRES;Contrast threshold (J & Q) -!TP_LOCALLAB_LOGCONTL;Contrast (J) +TP_LOCALLAB_LOGCONQL;Contrast (Q) +TP_LOCALLAB_LOGCONTHRES;Contrastdrempel (J & Q) +TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. !TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. -!TP_LOCALLAB_LOGEXP;All tools -!TP_LOCALLAB_LOGFRA;Scene Conditions +TP_LOCALLAB_LOGEXP;Alle gereedschappen +TP_LOCALLAB_LOGFRA;Scène-omstandigheden !TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. !TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). -!TP_LOCALLAB_LOGLIGHTL;Lightness (J) +TP_LOCALLAB_LOGLIGHTL;Lichtheid (J) !TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. -!TP_LOCALLAB_LOGLIGHTQ;Brightness (Q) +TP_LOCALLAB_LOGLIGHTQ;Helderheid (Q) !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. -!TP_LOCALLAB_LOGLIN;Logarithm mode -!TP_LOCALLAB_LOGPFRA;Relative Exposure Levels -!TP_LOCALLAB_LOGREPART;Overall strength +TP_LOCALLAB_LOGLIN;Logaritmische modus +TP_LOCALLAB_LOGPFRA;Relatieve Belichtingsniveaus +TP_LOCALLAB_LOGREPART;Overall kracht !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. !TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. !TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the Scene conditions.\n\nAverage: Average light conditions (standard). The image will not change.\n\nDim: Dim conditions. The image will become slightly brighter.\n\nDark: Dark conditions. The image will become more bright. !TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. -!TP_LOCALLAB_LOG_TOOLNAME;Log Encoding -!TP_LOCALLAB_LUM;LL - CC -!TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_LUMADARKEST;Darkest -!TP_LOCALLAB_LUMASK;Background color/luma mask +TP_LOCALLAB_LOG_TOOLNAME;Log-codering +TP_LOCALLAB_LUM;LL - CC +TP_LOCALLAB_LUM46LABEL;Luma-niveaus 456: Gemiddeld=%1 Hoog=%2 +TP_LOCALLAB_LUMADARKEST;Donkerst +TP_LOCALLAB_LUMASK;Achtergrondkleur/luma-masker !TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). -!TP_LOCALLAB_LUMAWHITESEST;Lightest -!TP_LOCALLAB_LUMFRA;L*a*b* standard -!TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_MASFRAME;Mask and Merge +TP_LOCALLAB_LUMAWHITESEST;Lichtst +TP_LOCALLAB_LUMFRA;L*a*b* standaard +TP_LOCALLAB_LUMLABEL;Luma-niveaus 0123: Gemiddeld=%1 Hoog=%2 +TP_LOCALLAB_MASFRAME;Masker en Combineer !TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. -!TP_LOCALLAB_MASK;Curves -!TP_LOCALLAB_MASK2;Contrast curve -!TP_LOCALLAB_MASKCOM;Common Color Mask -!TP_LOCALLAB_MASKCOM_TOOLNAME;Common Color Mask -!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of Scope. +TP_LOCALLAB_MASK;Curven +TP_LOCALLAB_MASK2;Contrastcurve +TP_LOCALLAB_MASKCOM;Gemeenschappelijk Kleurmasker +!TP_LOCALLAB_MASKCOM_TOOLNAME;Gemeenschappelijk Kleurmasker +!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of bereik. !TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. -!TP_LOCALLAB_MASKDDECAY;Decay strength +TP_LOCALLAB_MASKDDECAY;Vervalsterkte !TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. !TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. !TP_LOCALLAB_MASKDE_TOOLTIP;Used to target the denoise as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the Denoise will be applied progressively.\n iIf the mask is above the 'light' threshold, then the Denoise will be applied progressively.\n Between the two, the image settings without the Denoise will be maintained, unless you adjust the sliders 'Gray area luminance denoise' or 'Gray area chrominance denoise'. !TP_LOCALLAB_MASKGF_TOOLTIP;Used to target the Guided Filter as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the GF will be applied progressively.\n If the mask is above the 'light' threshold, then the GF will be applied progressively.\n Between the two, the image settings without the GF will be maintained. -!TP_LOCALLAB_MASKH;Hue curve +TP_LOCALLAB_MASKH;Tintcurve !TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lighter-tone limit above which CBDL (Luminance only) parameters will be restored progressively to their original values prior to being modified by the CBDL settings .\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\nUse a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. @@ -3707,14 +3703,14 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLCTHR;Light area luminance threshold -!TP_LOCALLAB_MASKLCTHR2;Light area luma threshold -!TP_LOCALLAB_MASKLCTHRLOW;Dark area luminance threshold -!TP_LOCALLAB_MASKLCTHRLOW2;Dark area luma threshold -!TP_LOCALLAB_MASKLCTHRMID;Gray area luma denoise -!TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise +TP_LOCALLAB_MASKLCTHR;Lichte gebieden luminantiedrempel +TP_LOCALLAB_MASKLCTHR2;Lichte gebieden luma-drempel +TP_LOCALLAB_MASKLCTHRLOW;Donkere gebieden luminantiedrempel +TP_LOCALLAB_MASKLCTHRLOW2;Donkere gebieden luma-drempel +TP_LOCALLAB_MASKLCTHRMID;Grijze gebieden luma-ruisvermindering +!TP_LOCALLAB_MASKLCTHRMIDCH;Grijze gebieden chroma-ruisvermindering !TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. -!TP_LOCALLAB_MASKLNOISELOW;Reinforce dark/light areas +TP_LOCALLAB_MASKLNOISELOW;Versterk donkere/lichte gebieden !TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;The denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. @@ -3727,7 +3723,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;The Guided Filter is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKRECOL_TOOLTIP;Used to modulate the effect of the Color and Light settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Color and Light settings \n In between these two areas, the full value of the Color and Light settings will be applied. -!TP_LOCALLAB_MASKRECOTHRES;Recovery threshold +TP_LOCALLAB_MASKRECOTHRES;Hersteldrempel !TP_LOCALLAB_MASKREEXP_TOOLTIP;Used to modulate the effect of the 'Dynamic range and Exposure' settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings \n In between these two areas, the full value of the 'Dynamic range and Exposure' settings will be applied. !TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Log encoding settings - can be used to restore highlights reconstructed by Color propagation \n In between these two areas, the full value of the Log encoding settings will be applied. !TP_LOCALLAB_MASKRESCB_TOOLTIP;Used to modulate the effect of the CBDL (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the CBDL settings \n In between these two areas, the full value of the CBDL settings will be applied. @@ -3736,289 +3732,289 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) -!TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) +TP_LOCALLAB_MASKUNUSABLE;Masker uitgeschakeld (Masker & modificaties) +TP_LOCALLAB_MASKUSABLE;Masker ingeschakeld (Masker & modificaties) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. -!TP_LOCALLAB_MEDIAN;Median Low +TP_LOCALLAB_MEDIAN;Mediaan Laag !TP_LOCALLAB_MEDIANITER_TOOLTIP;The number of successive iterations carried out by the median filter. !TP_LOCALLAB_MEDIAN_TOOLTIP;You can choose a median value in the range 3x3 to 9x9 pixels. Higher values increase noise reduction and blur. -!TP_LOCALLAB_MEDNONE;None -!TP_LOCALLAB_MERCOL;Color -!TP_LOCALLAB_MERDCOL;Merge background (ΔE) -!TP_LOCALLAB_MERELE;Lighten only -!TP_LOCALLAB_MERFIV;Addition -!TP_LOCALLAB_MERFOR;Color Dodge -!TP_LOCALLAB_MERFOU;Multiply -!TP_LOCALLAB_MERGE1COLFRA;Merge with Original/Previous/Background -!TP_LOCALLAB_MERGECOLFRA;Mask: LCh & Structure +TP_LOCALLAB_MEDNONE;Geen +TP_LOCALLAB_MERCOL;Kleur +TP_LOCALLAB_MERDCOL;Voeg samen met achtergrond (ΔE) +TP_LOCALLAB_MERELE;Alleen ophelderen +TP_LOCALLAB_MERFIV;Optellinh +TP_LOCALLAB_MERFOR;Kleur tegenhouden +TP_LOCALLAB_MERFOU;Vermenigvuldig +TP_LOCALLAB_MERGE1COLFRA;Voeg samen met Origineel/Vorige/Achtergrond +TP_LOCALLAB_MERGECOLFRA;Masker: LCh & Structuur !TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Allows you to create masks based on the 3 LCh curves and/or a structure-detection algorithm. -!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of scope in this case). +!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of bereik in this case). !TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. -!TP_LOCALLAB_MERHEI;Overlay -!TP_LOCALLAB_MERHUE;Hue -!TP_LOCALLAB_MERLUCOL;Luminance -!TP_LOCALLAB_MERLUM;Luminosity -!TP_LOCALLAB_MERNIN;Screen -!TP_LOCALLAB_MERONE;Normal -!TP_LOCALLAB_MERSAT;Saturation -!TP_LOCALLAB_MERSEV;Soft Light (legacy) -!TP_LOCALLAB_MERSEV0;Soft Light Illusion -!TP_LOCALLAB_MERSEV1;Soft Light W3C -!TP_LOCALLAB_MERSEV2;Hard Light -!TP_LOCALLAB_MERSIX;Divide -!TP_LOCALLAB_MERTEN;Darken only -!TP_LOCALLAB_MERTHI;Color Burn -!TP_LOCALLAB_MERTHR;Difference -!TP_LOCALLAB_MERTWE;Exclusion -!TP_LOCALLAB_MERTWO;Subtract +TP_LOCALLAB_MERHEI;Overlap +TP_LOCALLAB_MERHUE;Tint +TP_LOCALLAB_MERLUCOL;Luminantie +TP_LOCALLAB_MERLUM;Luminositeit +TP_LOCALLAB_MERNIN;Scherm +TP_LOCALLAB_MERONE;Normaal +TP_LOCALLAB_MERSAT;Verzadiging +TP_LOCALLAB_MERSEV;Zacht licht (legacy) +TP_LOCALLAB_MERSEV0;Zacht licht Illusie +TP_LOCALLAB_MERSEV1;Zacht licht W3C +TP_LOCALLAB_MERSEV2;Hard Licht +TP_LOCALLAB_MERSIX;Deel +TP_LOCALLAB_MERTEN;Alleen donker maken +TP_LOCALLAB_MERTHI;Brand kleur +TP_LOCALLAB_MERTHR;Verschil +TP_LOCALLAB_MERTWE;Uitsluiting +TP_LOCALLAB_MERTWO;Aftrekken !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. -!TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 +TP_LOCALLAB_MLABEL;Herstelde data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. -!TP_LOCALLAB_MODE_EXPERT;Advanced -!TP_LOCALLAB_MODE_NORMAL;Standard -!TP_LOCALLAB_MODE_SIMPLE;Basic -!TP_LOCALLAB_MRFIV;Background -!TP_LOCALLAB_MRFOU;Previous Spot -!TP_LOCALLAB_MRONE;None -!TP_LOCALLAB_MRTHR;Original Image +TP_LOCALLAB_MODE_EXPERT;Geavanceerd +TP_LOCALLAB_MODE_NORMAL;Standaard +TP_LOCALLAB_MODE_SIMPLE;Basis +TP_LOCALLAB_MRFIV;Achtergrond +TP_LOCALLAB_MRFOU;Voorgaande spot +TP_LOCALLAB_MRONE;Geen +TP_LOCALLAB_MRTHR;Originele afbeelding !TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. -!TP_LOCALLAB_NEIGH;Radius +TP_LOCALLAB_NEIGH;Radius !TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. !TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. !TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. -!TP_LOCALLAB_NLDET;Detail recovery -!TP_LOCALLAB_NLFRA;Non-local Means: Luminance +TP_LOCALLAB_NLDET;Detailherstel +TP_LOCALLAB_NLFRA;Non-local Means: Luminantie !TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. -!TP_LOCALLAB_NLGAM;Gamma -!TP_LOCALLAB_NLLUM;Strength -!TP_LOCALLAB_NLPAT;Maximum patch size -!TP_LOCALLAB_NLRAD;Maximum radius size -!TP_LOCALLAB_NOISECHROCOARSE;Coarse chroma (Wav) +TP_LOCALLAB_NLGAM;Gamma +TP_LOCALLAB_NLLUM;Kracht +TP_LOCALLAB_NLPAT;Maximale patch-grootte +TP_LOCALLAB_NLRAD;Maximale straalgrootte +TP_LOCALLAB_NOISECHROCOARSE;Ruw chroma (Wav) !TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=0.02. -!TP_LOCALLAB_NOISECHRODETAIL;Chroma detail recovery -!TP_LOCALLAB_NOISECHROFINE;Fine chroma (Wav) -!TP_LOCALLAB_NOISEGAM;Gamma +TP_LOCALLAB_NOISECHRODETAIL;Chroma detailherstel +TP_LOCALLAB_NOISECHROFINE;Fijn chroma (Wav) +TP_LOCALLAB_NOISEGAM;Gamma !TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. -!TP_LOCALLAB_NOISELEQUAL;Equalizer white-black -!TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) -!TP_LOCALLAB_NOISELUMDETAIL;Luma detail recovery -!TP_LOCALLAB_NOISELUMFINE;Luminance fine 1 (Wav) -!TP_LOCALLAB_NOISELUMFINETWO;Luminance fine 2 (Wav) -!TP_LOCALLAB_NOISELUMFINEZERO;Luminance fine 0 (Wav) -!TP_LOCALLAB_NOISEMETH;Denoise -!TP_LOCALLAB_NOISE_TOOLTIP;Adds luminance noise. -!TP_LOCALLAB_NONENOISE;None -!TP_LOCALLAB_NUL_TOOLTIP;. -!TP_LOCALLAB_OFFS;Offset -!TP_LOCALLAB_OFFSETWAV;Offset -!TP_LOCALLAB_OPACOL;Opacity -!TP_LOCALLAB_ORIGLC;Merge only with original image -!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). +TP_LOCALLAB_NOISELEQUAL;Equalizer wit-zwart +TP_LOCALLAB_NOISELUMCOARSE;Luminantie grof coarse (Wav) +TP_LOCALLAB_NOISELUMDETAIL;Luma detailherstel +TP_LOCALLAB_NOISELUMFINE;Luminantie fijn 1 (Wav) +TP_LOCALLAB_NOISELUMFINETWO;Luminantie fijn 2 (Wav) +TP_LOCALLAB_NOISELUMFINEZERO;Luminantie fijn 0 (Wav) +TP_LOCALLAB_NOISEMETH;Onderdruk ruis +TP_LOCALLAB_NOISE_TOOLTIP;Voegt luminantieruis toe. +TP_LOCALLAB_NONENOISE;Geen +TP_LOCALLAB_NUL_TOOLTIP;. +TP_LOCALLAB_OFFS;Verschuiving +TP_LOCALLAB_OFFSETWAV;Verschuiving +TP_LOCALLAB_OPACOL;Opaciteit +TP_LOCALLAB_ORIGLC;Voeg alleen samen met originele afbeelding +!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'bereik'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). !TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. -!TP_LOCALLAB_PASTELS2;Vibrance -!TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression -!TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ +TP_LOCALLAB_PASTELS2;Levendigheid +TP_LOCALLAB_PDE;Contrastversterker - Compressie Dynamisch bereik +TP_LOCALLAB_PDEFRA;Contrastversterker Æ’ !TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. -!TP_LOCALLAB_PREVHIDE;Hide additional settings -!TP_LOCALLAB_PREVIEW;Preview ΔE -!TP_LOCALLAB_PREVSHOW;Show additional settings -!TP_LOCALLAB_PROXI;ΔE decay -!TP_LOCALLAB_QUAAGRES;Aggressive -!TP_LOCALLAB_QUACONSER;Conservative -!TP_LOCALLAB_QUALCURV_METHOD;Curve type -!TP_LOCALLAB_QUAL_METHOD;Global quality -!TP_LOCALLAB_QUANONEALL;Off -!TP_LOCALLAB_QUANONEWAV;Non-local means only -!TP_LOCALLAB_RADIUS;Radius +TP_LOCALLAB_PREVHIDE;Verberg extra instellingen +TP_LOCALLAB_PREVIEW;Voorbeeld ΔE +TP_LOCALLAB_PREVSHOW;Toon extra instellingen +TP_LOCALLAB_PROXI;ΔE-verval +TP_LOCALLAB_QUAAGRES;Aggressief +TP_LOCALLAB_QUACONSER;Conservatief +TP_LOCALLAB_QUALCURV_METHOD;Soort curve +TP_LOCALLAB_QUAL_METHOD;Globale kwaliteit +TP_LOCALLAB_QUANONEALL;Uit +TP_LOCALLAB_QUANONEWAV;Alleen Non-local means +TP_LOCALLAB_RADIUS;Radius !TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. -!TP_LOCALLAB_RADMASKCOL;Smooth radius +TP_LOCALLAB_RADMASKCOL;Verzachtingsstraal !TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). -!TP_LOCALLAB_RECT;Rectangle -!TP_LOCALLAB_RECURS;Recursive references +TP_LOCALLAB_RECT;Rechthoek +TP_LOCALLAB_RECURS;Recursieve referenties !TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. -!TP_LOCALLAB_REN_DIALOG_LAB;Enter the new Control Spot name -!TP_LOCALLAB_REN_DIALOG_NAME;Renaming Control Spot +TP_LOCALLAB_REN_DIALOG_LAB;Geef de nieuwe Control Spot-naam +TP_LOCALLAB_REN_DIALOG_NAME;Hernoem Control Spot !TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Color and Light image with respect to the original image. !TP_LOCALLAB_REPARDEN_TOOLTIP;Allows you to adjust the relative strength of the Denoise image with respect to the original image. !TP_LOCALLAB_REPAREXP_TOOLTIP;Allows you to adjust the relative strength of the Dynamic Range and Exposure image with respect to the original image. !TP_LOCALLAB_REPARSH_TOOLTIP;Allows you to adjust the relative strength of the Shadows/Highlights and Tone Equalizer image with respect to the original image. !TP_LOCALLAB_REPARTM_TOOLTIP;Allows you to adjust the relative strength of the Tone mapping image with respect to the original image. !TP_LOCALLAB_REPARW_TOOLTIP;Allows you to adjust the relative strength of the local contrast and wavelet image with respect to the original image. -!TP_LOCALLAB_RESID;Residual Image -!TP_LOCALLAB_RESIDBLUR;Blur residual image -!TP_LOCALLAB_RESIDCHRO;Residual image Chroma -!TP_LOCALLAB_RESIDCOMP;Compress residual image -!TP_LOCALLAB_RESIDCONT;Residual image Contrast -!TP_LOCALLAB_RESIDHI;Highlights -!TP_LOCALLAB_RESIDHITHR;Highlights threshold -!TP_LOCALLAB_RESIDSHA;Shadows -!TP_LOCALLAB_RESIDSHATHR;Shadows threshold -!TP_LOCALLAB_RETI;Dehaze & Retinex -!TP_LOCALLAB_RETIFRA;Retinex +TP_LOCALLAB_RESID;Residuele afbeelding +TP_LOCALLAB_RESIDBLUR;Vervaag residuele afbeelding +TP_LOCALLAB_RESIDCHRO;Residuele afbeelding Chroma +TP_LOCALLAB_RESIDCOMP;Comprimmeer Residuele afbeelding +TP_LOCALLAB_RESIDCONT;Residuele afbeelding Contrast +TP_LOCALLAB_RESIDHI;Hoge lichten +TP_LOCALLAB_RESIDHITHR;Drempel hoge lichten +TP_LOCALLAB_RESIDSHA;Schaduwen +TP_LOCALLAB_RESIDSHATHR;Drempel schaduwen +TP_LOCALLAB_RETI;Ontnevel & Retinex +TP_LOCALLAB_RETIFRA;Retinex !TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex can be useful for processing images: \nthat are blurred, foggy or hazy (in addition to Dehaze).\nthat contain large differences in luminance.\nIt can also be used for special effects (tone mapping). -!TP_LOCALLAB_RETIM;Original Retinex -!TP_LOCALLAB_RETITOOLFRA;Retinex Tools +TP_LOCALLAB_RETIM;Originele Retinex +TP_LOCALLAB_RETITOOLFRA;Retinex-gereedschappen !TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Has no effect when the value of 'Lightness = 1' or 'Darkness =2'.\nFor other values, the last step of a 'Multiple scale Retinex' algorithm (similar to 'local contrast') is applied. These 2 cursors, associated with 'Strength' allow you to make adjustments upstream of local contrast. !TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Adjusts the internal parameters to optimize the response.\nPreferable to keep the 'Restored data' values close to Min=0 and Max=32768 (log mode), but other values are possible. !TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logarithm mode introduces more contrast but will also generate more halos. !TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. !TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. -!TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex -!TP_LOCALLAB_REWEI;Reweighting iterates -!TP_LOCALLAB_RGB;RGB Tone Curve +TP_LOCALLAB_RET_TOOLNAME;Ontnevel & Retinex +TP_LOCALLAB_REWEI;Herhaling herweging +TP_LOCALLAB_RGB;RGB-tooncurve !TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. -!TP_LOCALLAB_ROW_NVIS;Not visible -!TP_LOCALLAB_ROW_VIS;Visible +TP_LOCALLAB_ROW_NVIS;Niet zichtbaar +TP_LOCALLAB_ROW_VIS;Zichtbaar !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. -!TP_LOCALLAB_SATUR;Saturation -!TP_LOCALLAB_SATURV;Saturation (s) -!TP_LOCALLAB_SCALEGR;Scale -!TP_LOCALLAB_SCALERETI;Scale -!TP_LOCALLAB_SCALTM;Scale -!TP_LOCALLAB_SCOPEMASK;Scope (ΔE image mask) -!TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. -!TP_LOCALLAB_SENSI;Scope -!TP_LOCALLAB_SENSIEXCLU;Scope +TP_LOCALLAB_SATUR;Verzadiging +TP_LOCALLAB_SATURV;Verzadiging (s) +TP_LOCALLAB_SCALEGR;Schaal +TP_LOCALLAB_SCALERETI;Schaal +TP_LOCALLAB_SCALTM;Schaal +TP_LOCALLAB_bereikMASK;Bereik (ΔE beeldmasker) +!TP_LOCALLAB_bereikMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. +TP_LOCALLAB_SENSI;Bereik +TP_LOCALLAB_SENSIEXCLU;Bereik !TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. -!TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. -!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. -!TP_LOCALLAB_SETTINGS;Settings -!TP_LOCALLAB_SH1;Shadows Highlights -!TP_LOCALLAB_SH2;Equalizer -!TP_LOCALLAB_SHADEX;Shadows -!TP_LOCALLAB_SHADEXCOMP;Shadow compression -!TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer +!TP_LOCALLAB_SENSIMASK_TOOLTIP;bereik adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'bereik (ΔE image mask)' in 'Settings' > 'Mask and Merge'. +!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the bereik of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. +TP_LOCALLAB_SETTINGS;Instellingen +TP_LOCALLAB_SH1;Schaduwen Hoge lichten +TP_LOCALLAB_SH2;Equalizer +TP_LOCALLAB_SHADEX;Schaduwen +TP_LOCALLAB_SHADEXCOMP;Schaduwcompressie +TP_LOCALLAB_SHADHIGH;Schaduwen/hoge lichten & Toonequalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. -!TP_LOCALLAB_SHAMASKCOL;Shadows -!TP_LOCALLAB_SHAPETYPE;Spot shape +TP_LOCALLAB_SHAMASKCOL;Schaduwen +TP_LOCALLAB_SHAPETYPE;Spot-vorm !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. -!TP_LOCALLAB_SHARAMOUNT;Amount -!TP_LOCALLAB_SHARBLUR;Blur radius -!TP_LOCALLAB_SHARDAMPING;Damping -!TP_LOCALLAB_SHARFRAME;Modifications -!TP_LOCALLAB_SHARITER;Iterations -!TP_LOCALLAB_SHARP;Sharpening -!TP_LOCALLAB_SHARP_TOOLNAME;Sharpening -!TP_LOCALLAB_SHARRADIUS;Radius -!TP_LOCALLAB_SHORTC;Short Curves 'L' Mask +TP_LOCALLAB_SHARAMOUNT;Hoeveelheid +TP_LOCALLAB_SHARBLUR;Vervagingsradius +TP_LOCALLAB_SHARDAMPING;Demping +TP_LOCALLAB_SHARFRAME;Modificaties +TP_LOCALLAB_SHARITER;Herhalingen +TP_LOCALLAB_SHARP;Schaduwen +TP_LOCALLAB_SHARP_TOOLNAME;Schaduwen +TP_LOCALLAB_SHARRADIUS;Straal +TP_LOCALLAB_SHORTC;Korte curves L-masker !TP_LOCALLAB_SHORTCMASK_TOOLTIP;Short circuit the 2 curves L(L) and L(H).\nAllows you to mix the current image with the original image modified by the mask job.\nUsable with masks 2, 3, 4, 6, 7. -!TP_LOCALLAB_SHOWC;Mask and modifications -!TP_LOCALLAB_SHOWC1;Merge file -!TP_LOCALLAB_SHOWCB;Mask and modifications -!TP_LOCALLAB_SHOWDCT;Show Fourier (Æ’) process -!TP_LOCALLAB_SHOWE;Mask and modifications -!TP_LOCALLAB_SHOWFOURIER;Fourier Æ’(dct) -!TP_LOCALLAB_SHOWLAPLACE;∆ Laplacian (first) -!TP_LOCALLAB_SHOWLC;Mask and modifications -!TP_LOCALLAB_SHOWMASK;Show mask +TP_LOCALLAB_SHOWC;Masker en modificaties +TP_LOCALLAB_SHOWC1;Voeg bestand samen +TP_LOCALLAB_SHOWCB;Masker en modificaties +TP_LOCALLAB_SHOWDCT;Toon Fourier (Æ’) proces +TP_LOCALLAB_SHOWE;Masker en modificaties +TP_LOCALLAB_SHOWFOURIER;Fourier Æ’(dct) +TP_LOCALLAB_SHOWLAPLACE;∆ Laplacian (eerste) +TP_LOCALLAB_SHOWLC;Masker en modificaties +TP_LOCALLAB_SHOWMASK;Toon masker !TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Displays masks and modifications.\nBeware, you can only view one tool mask at a time.\nShow modified image: shows the modified image including the effect of any adjustments and masks.\nShow modified areas without mask: shows the modifications before any masks are applied.\nShow modified areas with mask: shows the modifications after a mask has been applied.\nShow mask: shows the aspect of the mask including the effect of any curves and filters.\nShow spot structure: allows you to see the structure-detection mask when the 'Spot structure' cursor is activated (when available).\nNote: The mask is applied before the shape detection algorithm. !TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. -!TP_LOCALLAB_SHOWMASKTYP1;Blur & Noise -!TP_LOCALLAB_SHOWMASKTYP2;Denoise -!TP_LOCALLAB_SHOWMASKTYP3;Blur & Noise + Denoise -!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the Scope sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. -!TP_LOCALLAB_SHOWMNONE;Show modified image -!TP_LOCALLAB_SHOWMODIF;Show modified areas without mask -!TP_LOCALLAB_SHOWMODIF2;Show modified areas -!TP_LOCALLAB_SHOWMODIFMASK;Show modified areas with mask -!TP_LOCALLAB_SHOWNORMAL;No luminance normalization -!TP_LOCALLAB_SHOWPLUS;Mask and modifications (Blur & Denoise) -!TP_LOCALLAB_SHOWPOISSON;Poisson (pde Æ’) -!TP_LOCALLAB_SHOWR;Mask and modifications -!TP_LOCALLAB_SHOWREF;Preview ΔE -!TP_LOCALLAB_SHOWS;Mask and modifications -!TP_LOCALLAB_SHOWSTRUC;Show spot structure(Advanced) -!TP_LOCALLAB_SHOWSTRUCEX;Show spot structure(Advanced) -!TP_LOCALLAB_SHOWT;Mask and modifications -!TP_LOCALLAB_SHOWVI;Mask and modifications -!TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC +TP_LOCALLAB_SHOWMASKTYP1;Vervaging & Ruis +TP_LOCALLAB_SHOWMASKTYP2;Ruisvermindering +TP_LOCALLAB_SHOWMASKTYP3;Vervaging & Ruis + Ruisvermindering +!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the bereik sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. +TP_LOCALLAB_SHOWMNONE;Toon gemodificeerde afbeelding +TP_LOCALLAB_SHOWMODIF;Toon gemodificeerde gebieden zonder masker +TP_LOCALLAB_SHOWMODIF2;Toon gemodificeerde gebieden +TP_LOCALLAB_SHOWMODIFMASK;Toon gemodificeerde gebieden met masker +TP_LOCALLAB_SHOWNORMAL;Geen luminantie-normalisatie +TP_LOCALLAB_SHOWPLUS;Masker en modificaties (Vervaging & Ruisvermindering) +TP_LOCALLAB_SHOWPOISSON;Poisson (pde Æ’) +TP_LOCALLAB_SHOWR;Masker en modificaties +TP_LOCALLAB_SHOWREF;Voorbeeld ΔE +TP_LOCALLAB_SHOWS;Masker en modificaties +TP_LOCALLAB_SHOWSTRUC;Toon spotstructuur (Geavanceerd) +TP_LOCALLAB_SHOWSTRUCEX;Toon spotstructuur (Geavanceerd) +TP_LOCALLAB_SHOWT;Masker en modificaties +TP_LOCALLAB_SHOWVI;Masker en modificaties +TP_LOCALLAB_SHRESFRA;Schaduwen/Hoge lichten & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -!TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q -!TP_LOCALLAB_SIGJZFRA;Sigmoid Jz -!TP_LOCALLAB_SIGMAWAV;Attenuation response -!TP_LOCALLAB_SIGMOIDBL;Blend -!TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev -!TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) +TP_LOCALLAB_SH_TOOLNAME;Schaduwen/Hoge lichten & Toonequalizer +TP_LOCALLAB_SIGFRA;Sigmoid Q & Log-codering Q +TP_LOCALLAB_SIGJZFRA;Sigmoid Jz +TP_LOCALLAB_SIGMAWAV;Versterkingsrespons +TP_LOCALLAB_SIGMOIDBL;Samenvoegen +TP_LOCALLAB_SIGMOIDLAMBDA;Contrast +TP_LOCALLAB_SIGMOIDQJ;Gebruikt Zwart Ev & Wit Ev +TP_LOCALLAB_SIGMOIDTH;Drempel (Grijspunt) !TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. -!TP_LOCALLAB_SLOMASKCOL;Slope +TP_LOCALLAB_SLOMASKCOL;Helling !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_SLOSH;Slope -!TP_LOCALLAB_SOFT;Soft Light & Original Retinex -!TP_LOCALLAB_SOFTM;Soft Light +TP_LOCALLAB_SLOSH;Helling +TP_LOCALLAB_SOFT;Zacht licht & Originele Retinex +TP_LOCALLAB_SOFTM;Zacht licht !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. -!TP_LOCALLAB_SOFTRADIUSCOL;Soft radius +TP_LOCALLAB_SOFTRADIUSCOL;Radius verzachting !TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. -!TP_LOCALLAB_SOFTRETI;Reduce ΔE artifacts -!TP_LOCALLAB_SOFT_TOOLNAME;Soft Light & Original Retinex -!TP_LOCALLAB_SOURCE_ABS;Absolute luminance -!TP_LOCALLAB_SOURCE_GRAY;Mean luminance (Yb%) -!TP_LOCALLAB_SPECCASE;Specific cases -!TP_LOCALLAB_SPECIAL;Special use of RGB curves -!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. -!TP_LOCALLAB_SPOTNAME;New Spot -!TP_LOCALLAB_STD;Standard -!TP_LOCALLAB_STR;Strength -!TP_LOCALLAB_STRBL;Strength -!TP_LOCALLAB_STREN;Compression strength -!TP_LOCALLAB_STRENG;Strength -!TP_LOCALLAB_STRENGR;Strength -!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). -!TP_LOCALLAB_STRENGTH;Noise -!TP_LOCALLAB_STRGRID;Strength -!TP_LOCALLAB_STRUC;Structure -!TP_LOCALLAB_STRUCCOL;Spot structure -!TP_LOCALLAB_STRUCCOL1;Spot structure +TP_LOCALLAB_SOFTRETI;Verminder ΔE-onregelmatgheden +TP_LOCALLAB_SOFT_TOOLNAME;Zacht licht & Originele Retinex +TP_LOCALLAB_SOURCE_ABS;Absolute luminantie +TP_LOCALLAB_SOURCE_GRAY;Gemiddelde luminantie (Yb%) +TP_LOCALLAB_SPECCASE;Specifieke gevallen +TP_LOCALLAB_SPECIAL;Speciaal gebruik van RGB-curven +!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'bereik', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. +TP_LOCALLAB_SPOTNAME;Nieuwe spot +TP_LOCALLAB_STD;Standaard +TP_LOCALLAB_STR;Kracht +TP_LOCALLAB_STRBL;Kracht +TP_LOCALLAB_STREN;Compressiesterkte +TP_LOCALLAB_STRENG;Kracht +TP_LOCALLAB_STRENGR;Kracht +!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'bereik' function which allows you to delimit the action (e.g. to isolate a particular color). +TP_LOCALLAB_STRENGTH;Ruis +TP_LOCALLAB_STRGRID;Kracht +TP_LOCALLAB_STRUC;Structuur +TP_LOCALLAB_STRUCCOL;Spotstructuur +TP_LOCALLAB_STRUCCOL1;Spotstructuur !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. -!TP_LOCALLAB_STRUMASKCOL;Structure mask strength +TP_LOCALLAB_STRUMASKCOL;Kracht qstructuurmasker !TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! -!TP_LOCALLAB_STYPE;Shape method +TP_LOCALLAB_STYPE;Vorm Shape methode !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. -!TP_LOCALLAB_SYM;Symmetrical (mouse) -!TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) -!TP_LOCALLAB_TARGET_GRAY;Mean luminance (Yb%) -!TP_LOCALLAB_TE_PIVOT;Pivot (Ev) -!TP_LOCALLAB_THRES;Threshold structure -!TP_LOCALLAB_THRESDELTAE;ΔE scope threshold -!TP_LOCALLAB_THRESRETI;Threshold -!TP_LOCALLAB_THRESWAV;Balance threshold -!TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Mean=%3 Sig=%4 +TP_LOCALLAB_SYM;Symmetrisch (muis) +TP_LOCALLAB_SYMSL;Symmetrisch (muis + schuiven) +TP_LOCALLAB_TARGET_GRAY;Gemiddelde luminantie (Yb%) +TP_LOCALLAB_TE_PIVOT;Draaipunt (LW) +TP_LOCALLAB_THRES;Drempel structuur +TP_LOCALLAB_THRESDELTAE;Drempel ΔE-bereik +TP_LOCALLAB_THRESRETI;Drempel +TP_LOCALLAB_THRESWAV;Balansdrempel +TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sig=%4 !TP_LOCALLAB_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. -!TP_LOCALLAB_TM;Tone Mapping -!TP_LOCALLAB_TM_MASK;Use transmission map +TP_LOCALLAB_TM;Toonmappen +TP_LOCALLAB_TM_MASK;Gebruik transmissiemap !TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;This slider affects edge sensitivity.\n The greater the value, the more likely a change in contrast will be interpreted as an 'edge'.\n If set to zero the tone mapping will have an effect similar to unsharp masking. !TP_LOCALLAB_TONEMAPGAM_TOOLTIP;The Gamma slider shifts the tone-mapping effect towards either the shadows or the highlights. !TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In some cases tone mapping may result in a cartoonish appearance, and in some rare cases soft but wide halos may appear.\n Increasing the number of reweighting iterates will help fight some of these problems. !TP_LOCALLAB_TONEMAP_TOOLTIP;Same as the tone mapping tool in the main menu.\nThe main-menu tool must be deactivated if this tool is used. !TP_LOCALLAB_TONEMASCALE_TOOLTIP;This slider allows you to adjust the transition between 'local' and 'global' contrast.\nThe greater the value, the larger a detail needs to be for it to be boosted. -!TP_LOCALLAB_TONE_TOOLNAME;Tone Mapping -!TP_LOCALLAB_TOOLCOL;Structure mask as tool +TP_LOCALLAB_TONE_TOOLNAME;Toonmappen +TP_LOCALLAB_TOOLCOL;Structuurmasker als gereedschap !TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Allows you to modify the mask, if one exists. -!TP_LOCALLAB_TOOLMASK;Mask Tools -!TP_LOCALLAB_TOOLMASK_2;Wavelets +TP_LOCALLAB_TOOLMASK;Maskergereedschappen +TP_LOCALLAB_TOOLMASK_2;Wavelets !TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. -!TP_LOCALLAB_TRANSIT;Transition Gradient -!TP_LOCALLAB_TRANSITGRAD;Transition differentiation XY +TP_LOCALLAB_TRANSIT;Transitieverloop +TP_LOCALLAB_TRANSITGRAD;Transitie-differentiatie XY !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. -!TP_LOCALLAB_TRANSITVALUE;Transition value -!TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) +TP_LOCALLAB_TRANSITVALUE;Transitiewaarde +TP_LOCALLAB_TRANSITWEAK;Transitieverval (lineair-log) !TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. -!TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain -!TP_LOCALLAB_TRANSMISSIONMAP;Transmission map +TP_LOCALLAB_TRANSMISSIONGAIN;Transmissieversterking +TP_LOCALLAB_TRANSMISSIONMAP;Transmissiemap !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. -!TP_LOCALLAB_USEMASK;Laplacian -!TP_LOCALLAB_VART;Variance (contrast) -!TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool +TP_LOCALLAB_USEMASK;Laplacian +TP_LOCALLAB_VART;Variantie (contrast) +TP_LOCALLAB_VIBRANCE;Levendigheid & Warm/Koel !TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. -!TP_LOCALLAB_VIB_TOOLNAME;Vibrance & Warm/Cool +TP_LOCALLAB_VIB_TOOLNAME;Levendigheid & Warm/Koel !TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtrl+click to show/hide all Control Spot. -!TP_LOCALLAB_WARM;Warm/Cool & Color artifacts +TP_LOCALLAB_WARM;Warm/Koel & Kleuronregelmatigheden !TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases. !TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve including the dark-gray/light-gray boundary corresponds to the first 3 levels 0, 1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3, 4, 5, 6). !TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balances the action within each level. @@ -4046,172 +4042,172 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Allows you to adjust the maximum effect of blurring on the levels. !TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Low to high local contrast from left to right on the x-axis\nIncrease or decrease local contrast on the y-axis. !TP_LOCALLAB_WAT_WAVTM_TOOLTIP;The lower (negative) part compresses each level of decomposition creating a tone mapping effect.\nThe upper (positive) part attenuates the contrast by level.\nThe finest to coarsest levels of decomposition are from left to right on the x-axis. -!TP_LOCALLAB_WAV;Local contrast +TP_LOCALLAB_WAV;Lokaal contrast !TP_LOCALLAB_WAVBLUR_TOOLTIP;Allows you to blur each level of the decomposition, as well as the residual image. -!TP_LOCALLAB_WAVCOMP;Compression by level -!TP_LOCALLAB_WAVCOMPRE;Compression by level +TP_LOCALLAB_WAVCOMP;Compressie per niveau +TP_LOCALLAB_WAVCOMPRE;Compressie per niveau !TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Allows you to apply tone mapping or reduce local contrast on individual levels.\nFine to coarse detail levels from left to right on the x-axis. !TP_LOCALLAB_WAVCOMP_TOOLTIP;Allows you to apply local contrast based on the direction of the wavelet decomposition : horizontal, vertical, diagonal. -!TP_LOCALLAB_WAVCON;Contrast by level +TP_LOCALLAB_WAVCON;Contrast per niveau !TP_LOCALLAB_WAVCONTF_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAVDEN;Luminance denoise -!TP_LOCALLAB_WAVE;Wavelets -!TP_LOCALLAB_WAVEDG;Local contrast +TP_LOCALLAB_WAVDEN;Luminantie ruisvermindering +TP_LOCALLAB_WAVE;Wavelets +TP_LOCALLAB_WAVEDG;Lokaal contrast !TP_LOCALLAB_WAVEEDG_TOOLTIP;Improves sharpness by targeting the action of local contrast on the edges. It has the same functions as the corresponding module in Wavelet Levels and uses the same settings. !TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Range of wavelet levels used in 'Local contrast' (by wavelet level). !TP_LOCALLAB_WAVGRAD_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. !TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. -!TP_LOCALLAB_WAVLEV;Blur by level -!TP_LOCALLAB_WAVMASK;Local contrast +TP_LOCALLAB_WAVLEV;Vervaag per niveau +TP_LOCALLAB_WAVMASK;Lokaal contrast !TP_LOCALLAB_WAVMASK_TOOLTIP;Uses wavelets to modify the local contrast of the mask and reinforce or reduce the structure (skin, buildings, etc.). -!TP_LOCALLAB_WEDIANHI;Median Hi -!TP_LOCALLAB_WHITE_EV;White Ev -!TP_LOCALLAB_ZCAMFRA;ZCAM Image Adjustments -!TP_LOCALLAB_ZCAMTHRES;Retrieve high datas -!TP_LOCAL_HEIGHT;Bottom -!TP_LOCAL_HEIGHT_T;Top -!TP_LOCAL_WIDTH;Right -!TP_LOCAL_WIDTH_L;Left +TP_LOCALLAB_WEDIANHI;Mediaan Hi +TP_LOCALLAB_WHITE_EV;Wit Ev +TP_LOCALLAB_ZCAMFRA;ZCAM Beeldaanpassingen +TP_LOCALLAB_ZCAMTHRES;Haal hoge data op +TP_LOCAL_HEIGHT;Onder +TP_LOCAL_HEIGHT_T;Boven +TP_LOCAL_WIDTH;Rechts +TP_LOCAL_WIDTH_L;Links !TP_LOCRETI_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Evenly distributed.\nHigh = Reinforce strong light. -!TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor -!TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length -!TP_PERSPECTIVE_CAMERA_FRAME;Correction -!TP_PERSPECTIVE_CAMERA_PITCH;Vertical -!TP_PERSPECTIVE_CAMERA_ROLL;Rotation -!TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift -!TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Vertical shift -!TP_PERSPECTIVE_CAMERA_YAW;Horizontal -!TP_PERSPECTIVE_CONTROL_LINES;Control lines +TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Bijsnijdfactor +TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Brandpuntsafstand +TP_PERSPECTIVE_CAMERA_FRAME;Correctie +TP_PERSPECTIVE_CAMERA_PITCH;Verticaal +TP_PERSPECTIVE_CAMERA_ROLL;Rotatie +TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontale verschuiving +TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Verticale verschuiving +TP_PERSPECTIVE_CAMERA_YAW;Horizontaal +TP_PERSPECTIVE_CONTROL_LINES;Controlelijnen !TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+drag: Draw new line\nRight-click: Delete line !TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;At least two horizontal or two vertical control lines required. -!TP_PERSPECTIVE_METHOD;Method -!TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-based -!TP_PERSPECTIVE_METHOD_SIMPLE;Simple -!TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment -!TP_PERSPECTIVE_PROJECTION_PITCH;Vertical -!TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation -!TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontal shift -!TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Vertical shift -!TP_PERSPECTIVE_PROJECTION_YAW;Horizontal -!TP_PERSPECTIVE_RECOVERY_FRAME;Recovery -!TP_PREPROCWB_LABEL;Preprocess White Balance -!TP_PREPROCWB_MODE;Mode -!TP_PREPROCWB_MODE_AUTO;Auto -!TP_PREPROCWB_MODE_CAMERA;Camera -!TP_RAW_AMAZEBILINEAR;AMaZE+Bilinear -!TP_RAW_DCBBILINEAR;DCB+Bilinear -!TP_RAW_PIXELSHIFTAVERAGE;Use average for moving parts +TP_PERSPECTIVE_METHOD;Methode +TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-gebaseerd +TP_PERSPECTIVE_METHOD_SIMPLE;Simpel +TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correctie aanpassingen +TP_PERSPECTIVE_PROJECTION_PITCH;Verticaal +TP_PERSPECTIVE_PROJECTION_ROTATE;Rotatie +TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontale verschuiving +TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Verticale verschuiving +TP_PERSPECTIVE_PROJECTION_YAW;Horizontaal +TP_PERSPECTIVE_RECOVERY_FRAME;Herstel +TP_PREPROCWB_LABEL;Pre-proces witbalans +TP_PREPROCWB_MODE;Modus +TP_PREPROCWB_MODE_AUTO;Auto +TP_PREPROCWB_MODE_CAMERA;Camera +TP_RAW_AMAZEBILINEAR;AMaZE+Bilineair +TP_RAW_DCBBILINEAR;DCB+Bilineair +TP_RAW_PIXELSHIFTAVERAGE;Gebruik gemiddelde voor bewegende delen !TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Use average of all frames instead of selected frame for regions with motion.\nGives motion effect on slow moving (overlapping) objects. -!TP_RAW_RCDBILINEAR;RCD+Bilinear -!TP_RESIZE_LE;Long Edge: -!TP_RESIZE_LONG;Long Edge -!TP_RESIZE_SE;Short Edge: -!TP_RESIZE_SHORT;Short Edge -!TP_SPOT_COUNTLABEL;%1 point(s) -!TP_SPOT_DEFAULT_SIZE;Default spot size -!TP_SPOT_ENTRYCHANGED;Point changed -!TP_SPOT_HINT;Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. -!TP_SPOT_LABEL;Spot Removal -!TP_TONE_EQUALIZER_BANDS;Bands -!TP_TONE_EQUALIZER_BAND_0;Blacks -!TP_TONE_EQUALIZER_BAND_1;Shadows -!TP_TONE_EQUALIZER_BAND_2;Midtones -!TP_TONE_EQUALIZER_BAND_3;Highlights -!TP_TONE_EQUALIZER_BAND_4;Whites -!TP_TONE_EQUALIZER_DETAIL;Regularization -!TP_TONE_EQUALIZER_LABEL;Tone Equalizer -!TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) -!TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map -!TP_WAVELET_BALCHROM;Equalizer Color -!TP_WAVELET_BALLUM;Denoise equalizer White-Black -!TP_WAVELET_BL;Blur levels -!TP_WAVELET_BLCURVE;Blur by levels -!TP_WAVELET_BLURFRAME;Blur -!TP_WAVELET_BLUWAV;Attenuation response -!TP_WAVELET_CHROFRAME;Denoise chrominance -!TP_WAVELET_CHROMAFRAME;Chroma -!TP_WAVELET_CHROMCO;Chrominance Coarse -!TP_WAVELET_CHROMFI;Chrominance Fine -!TP_WAVELET_CHRWAV;Blur chroma -!TP_WAVELET_CLA;Clarity -!TP_WAVELET_CLARI;Sharp-mask and Clarity -!TP_WAVELET_COMPEXPERT;Advanced -!TP_WAVELET_COMPLEXLAB;Complexity -!TP_WAVELET_COMPLEX_TOOLTIP;Standard: shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. -!TP_WAVELET_COMPNORMAL;Standard -!TP_WAVELET_CONTFRAME;Contrast - Compression -!TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabled if zoom > about 300%. -!TP_WAVELET_DAUBLOCAL;Wavelet Edge performance -!TP_WAVELET_DEN5THR;Guided threshold -!TP_WAVELET_DENCURV;Curve -!TP_WAVELET_DENL;Correction structure -!TP_WAVELET_DENLH;Guided threshold levels 1-4 +TP_RAW_RCDBILINEAR;RCD+Bilineair +TP_RESIZE_LE;Lange zijde: +TP_RESIZE_LONG;Korte zijde +TP_RESIZE_SE;Korte zijde: +TP_RESIZE_SHORT;Korte zijde +TP_SPOT_COUNTLABEL;%1 punt(en) +TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte +TP_SPOT_ENTRYCHANGED;Punt veranderd +TP_SPOT_HINT;Klik op deze button... Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. +TP_SPOT_LABEL;Verwijder vlekken +TP_TONE_EQUALIZER_BANDS;Banden +TP_TONE_EQUALIZER_BAND_0;Zwarten +TP_TONE_EQUALIZER_BAND_1;Schaduwen +TP_TONE_EQUALIZER_BAND_2;Middentonen +TP_TONE_EQUALIZER_BAND_3;Hoge lichten +TP_TONE_EQUALIZER_BAND_4;Witten +TP_TONE_EQUALIZER_DETAIL;Fijnafstemming +TP_TONE_EQUALIZER_LABEL;Toonequalizer +TP_TONE_EQUALIZER_PIVOT;Draaipunt (LW) +TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Toon kleurenmap +TP_WAVELET_BALCHROM;Equalizer kleur +TP_WAVELET_BALLUM;Ruisonderdrukkings-equalizer wit-zwart +TP_WAVELET_BL;Vervagingsniveaus +TP_WAVELET_BLCURVE;Vervaag per niveau +TP_WAVELET_BLURFRAME;Vervaag +TP_WAVELET_BLUWAV;Versterkingsrespons +TP_WAVELET_CHROFRAME;Vervaag chrominantie +TP_WAVELET_CHROMAFRAME;Chroma +TP_WAVELET_CHROMCO;Chrominantie grof +TP_WAVELET_CHROMFI;Chrominantie fijn +TP_WAVELET_CHRWAV;Vervaging chroma +TP_WAVELET_CLA;Klaarheid (Clarity) +TP_WAVELET_CLARI;Scherptemasker en Clarity +TP_WAVELET_COMPEXPERT;Geavanceerd +TP_WAVELET_COMPLEXLAB;Complexiteit +TP_WAVELET_COMPLEX_TOOLTIP;Standaard: toont... shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. +TP_WAVELET_COMPNORMAL;Standaard +TP_WAVELET_CONTFRAME;Contrast - Compressie +TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Uitgeschakeld als zoom > ~300% +TP_WAVELET_DAUBLOCAL;Wavelet Rand-performance +TP_WAVELET_DEN5THR;Begeleid drempel +TP_WAVELET_DENCURV;Curve +TP_WAVELET_DENL;Correctie structuur +TP_WAVELET_DENLH;Begeleid drempel niveaus 1-4 !TP_WAVELET_DENLOCAL_TOOLTIP;Use a curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained. !TP_WAVELET_DENMIX_TOOLTIP;The local-contrast reference value used by the guided filter.\nDepending on the image, results can vary depending on whether the noise is measured before or after the noise reduction. These four choices allow you to take into account various combinations of the original and modified (denoised) images to find the best compromise. -!TP_WAVELET_DENOISE;Guide curve based on Local contrast -!TP_WAVELET_DENOISEGUID;Guided threshold based on hue -!TP_WAVELET_DENOISEH;High levels Curve Local contrast -!TP_WAVELET_DENOISEHUE;Denoise hue equalizer -!TP_WAVELET_DENQUA;Mode -!TP_WAVELET_DENSIGMA_TOOLTIP;Adapts the shape of the guide. -!TP_WAVELET_DENSLI;Slider -!TP_WAVELET_DENSLILAB;Method -!TP_WAVELET_DENWAVGUID_TOOLTIP;Uses hue to reduce or increase the action of the guided filter. -!TP_WAVELET_DENWAVHUE_TOOLTIP;Amplify or reduce denoising depending on the color. -!TP_WAVELET_DETEND;Details -!TP_WAVELET_DIRFRAME;Directional contrast -!TP_WAVELET_EDEFFECT;Attenuation response +TP_WAVELET_DENOISE;Gids curve gebaseerd op Lokaal contrast +TP_WAVELET_DENOISEGUID;Begeleide drempel gebaseerd op tint +TP_WAVELET_DENOISEH;Hoge niveaus curve Lokaal contrast +TP_WAVELET_DENOISEHUE;Ruisonderdrukking Tint-equalizer +TP_WAVELET_DENQUA;Modus +TP_WAVELET_DENSIGMA_TOOLTIP;Wijzigt de vorm van de gids +TP_WAVELET_DENSLI;Schuif +TP_WAVELET_DENSLILAB;Methode +TP_WAVELET_DENWAVGUID_TOOLTIP;Gebruikt tint om de actie van het begeleid filter te verminderen of te vermeerderen +TP_WAVELET_DENWAVHUE_TOOLTIP;Versterk of verminder ruisvermindering afhankelijk van de kleur +TP_WAVELET_DETEND;Details +TP_WAVELET_DIRFRAME;Directioneel contrast +TP_WAVELET_EDEFFECT;Versterkingsrespons !TP_WAVELET_EDEFFECT_TOOLTIP;This slider selects the range of contrast values that will receive the full effect of any adjustment. -!TP_WAVELET_FINCFRAME;Final local contrast +TP_WAVELET_FINCFRAME;Finaal lokaal contrast !TP_WAVELET_FINTHR_TOOLTIP;Uses local contrast to reduce or increase the action of the guided filter. -!TP_WAVELET_GUIDFRAME;Final smoothing (guided filter) -!TP_WAVELET_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 -!TP_WAVELET_LEVDEN;Level 5-6 denoise -!TP_WAVELET_LEVELHIGH;Radius 5-6 -!TP_WAVELET_LEVELLOW;Radius 1-4 -!TP_WAVELET_LEVELSIGM;Radius -!TP_WAVELET_LEVFOUR;Level 5-6 denoise and guided threshold -!TP_WAVELET_LIMDEN;Interaction levels 5-6 on levels 1-4 -!TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise. -!TP_WAVELET_MERGEC;Merge chroma -!TP_WAVELET_MERGEL;Merge luma -!TP_WAVELET_MIXCONTRAST;Reference -!TP_WAVELET_MIXDENOISE;Denoise -!TP_WAVELET_MIXMIX;Mixed 50% noise - 50% denoise -!TP_WAVELET_MIXMIX70;Mixed 30% noise - 70% denoise -!TP_WAVELET_MIXNOISE;Noise +TP_WAVELET_GUIDFRAME;Uiteindelijke verzachting (begeleid filter) +TP_WAVELET_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 +TP_WAVELET_LEVDEN;Niveau 5-6 ruisvermindering +TP_WAVELET_LEVELHIGH;Straal 5-6 +TP_WAVELET_LEVELLOW;Straal 1-4 +TP_WAVELET_LEVELSIGM;Straal +TP_WAVELET_LEVFOUR;Niveau 5-6 ruisvermindering en begeleide drempel +TP_WAVELET_LIMDEN;Interactie niveaus 5-6 op niveaus 1-4 +TP_WAVELET_LOWTHR_TOOLTIP;Voorkomt versterking van fijne texturen en ruis +TP_WAVELET_MERGEC;Meng chroma +TP_WAVELET_MERGEL;Meng luma +TP_WAVELET_MIXCONTRAST;Referentie +TP_WAVELET_MIXDENOISE;Ruisvermindering +TP_WAVELET_MIXMIX;Gemengd 50% ruis - 50% ruisvermindering +TP_WAVELET_MIXMIX70;Gemengd 30% ruis - 70% ruisvermindering +TP_WAVELET_MIXNOISE;Ruis !TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between low contrast and high contrast details.\nHigh values will amplify contrast changes to the higher contrast details, whereas low values will amplify contrast changes to low contrast details.\nBy using a low Attenuation response value you can select which contrast values will be enhanced. -!TP_WAVELET_OLDSH;Algorithm using negatives values -!TP_WAVELET_PROTAB;Protection -!TP_WAVELET_QUAAGRES;Aggressive -!TP_WAVELET_QUACONSER;Conservative -!TP_WAVELET_RADIUS;Radius shadows - highlight -!TP_WAVELET_RANGEAB;Range a and b % -!TP_WAVELET_RESBLUR;Blur luminance -!TP_WAVELET_RESBLURC;Blur chroma -!TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500%. -!TP_WAVELET_SHA;Sharp mask -!TP_WAVELET_SHFRAME;Shadows/Highlights -!TP_WAVELET_SHOWMASK;Show wavelet 'mask' -!TP_WAVELET_SIGM;Radius -!TP_WAVELET_SIGMA;Attenuation response -!TP_WAVELET_SIGMAFIN;Attenuation response +TP_WAVELET_OLDSH;Algoritme met negatieve waarden +TP_WAVELET_PROTAB;Bescherming +TP_WAVELET_QUAAGRES;Agressief +TP_WAVELET_QUACONSER;Conservatief +TP_WAVELET_RADIUS;Straal schaduwen - hoge lichten +TP_WAVELET_RANGEAB;Reeks a en b % +TP_WAVELET_RESBLUR;Vervaging luminantie +TP_WAVELET_RESBLURC;Vervaging chroma +TP_WAVELET_RESBLUR_TOOLTIP;Uitgeschakeld als zoom > ~500% +TP_WAVELET_SHA;Scherptemasker +TP_WAVELET_SHFRAME;Schaduwen/hoge lichten +TP_WAVELET_SHOWMASK;Toon wavelet-masker +TP_WAVELET_SIGM;Straal +TP_WAVELET_SIGMA;Verzwakkingsrespons +TP_WAVELET_SIGMAFIN;Verzwakkingsrespons !TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values. -!TP_WAVELET_SOFTRAD;Soft radius -!TP_WAVELET_STREND;Strength +TP_WAVELET_SOFTRAD;Verzachtingsstraal +TP_WAVELET_STREND;Kracht !TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. -!TP_WAVELET_THREND;Local contrast threshold -!TP_WAVELET_TMEDGS;Edge stopping -!TP_WAVELET_TMSCALE;Scale -!TP_WAVELET_TONFRAME;Excluded colors -!TP_WAVELET_USH;None -!TP_WAVELET_USHARP;Clarity method +TP_WAVELET_THREND;Drempel lokaal contrast +TP_WAVELET_TMEDGS;Edge stopping +TP_WAVELET_TMSCALE;Schaal +TP_WAVELET_TONFRAME;Uitgesloten kleuren +TP_WAVELET_USH;Geen +TP_WAVELET_USHARP;'Clarity'-methode !TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, you can choose any level (in Settings) from 1 to 4 for processing.\nIf you select Clarity, you can choose any level (in Settings) between 5 and Extra. -!TP_WAVELET_WAVLOWTHR;Low contrast threshold -!TP_WAVELET_WAVOFFSET;Offset -!TP_WBALANCE_AUTOITCGREEN;Temperature correlation -!TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +TP_WAVELET_WAVLOWTHR;Laag contrast drempel +TP_WAVELET_WAVOFFSET;Verschuiving +TP_WBALANCE_AUTOITCGREEN;Temperatuurcorrelatie +TP_WBALANCE_AUTOOLD;RGB grijs +TP_WBALANCE_AUTO_HEADER;Automatisch & Verfijning !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4222,46 +4218,46 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;This setting sets the size of color datas used by algorithm. !TP_WBALANCE_ITCWBSIZE_TOOLTIP;This setting sets the number of iterations to find the best correspondence between the reference spectral colors and those in xyY value of the image. A value of 3 seams a good compromise. !TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. -!TP_WBALANCE_ITCWB_ALG;Remove 2 pass algorithm -!TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint -!TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop -!TP_WBALANCE_ITCWB_FGREEN;Find green student -!TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram -!TP_WBALANCE_ITCWB_FRA;Auto temperature correlation settings +TP_WBALANCE_ITCWB_ALG;Verwijder 2-pas algoritme +TP_WBALANCE_ITCWB_CUSTOM;Gebruik aangepaste temperatuur & tint +TP_WBALANCE_ITCWB_DELTA;Delta temperatuur in groene lus +TP_WBALANCE_ITCWB_FGREEN;Vind groene student +TP_WBALANCE_ITCWB_FORCED;Dichtbij volledig CIE-diagram +TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie !TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. -!TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimum size -!TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple color -!TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used -!TP_WBALANCE_ITCWB_PRIM_ACE;Forces use of the entire CIE diagram -!TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling -!TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - near Pointer's gamut -!TP_WBALANCE_ITCWB_PRIM_JDCMAX;Close to full CIE diagram -!TP_WBALANCE_ITCWB_PRIM_REC;High sampling -!TP_WBALANCE_ITCWB_PRIM_SRGB;Low sampling & Ignore Camera settings -!TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ matrix -!TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax after Camera XYZ matrix -!TP_WBALANCE_ITCWB_RGREEN;Green range -!TP_WBALANCE_ITCWB_SAMPLING;Low sampling 5.9 -!TP_WBALANCE_ITCWB_SIZE;Size of ref. color compare to histogram -!TP_WBALANCE_ITCWB_SIZEPATCH;Size of color patch -!TP_WBALANCE_ITCWB_THRES;Colors used in picture (preset) +TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimumgrootte +TP_WBALANCE_ITCWB_NOPURPLE;Filter op paars +TP_WBALANCE_ITCWB_PRECIS;Precisie-algoritme - schaal gebruikt +TP_WBALANCE_ITCWB_PRIM_ACE;Forceer gebruik van het gehele CIE-diagram +TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling +TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - nabij Pointer's kleurenscala +TP_WBALANCE_ITCWB_PRIM_JDCMAX;Nabij volledig CIE-diagram +TP_WBALANCE_ITCWB_PRIM_REC;Hoge sampling +TP_WBALANCE_ITCWB_PRIM_SRGB;Lage sampling & Gebruik geen camera-instellingen +TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ-matrix +TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax na camera XYZ-matrix +TP_WBALANCE_ITCWB_RGREEN;Groen bereik +TP_WBALANCE_ITCWB_SAMPLING;Lage sampling 5,9 +TP_WBALANCE_ITCWB_SIZE;Grootte ref.kleur vergelijk met histogram +TP_WBALANCE_ITCWB_SIZEPATCH;Grootte kleur-patch +TP_WBALANCE_ITCWB_THRES;Kleuren gebruikt in afbeelding (voorinstelling) !TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and Green (tint).\n\nUsage tips:\n1) start Itcwb , enable 'Use Custom temperature and tint'.\n2) Set 'Temperature and tint' to your liking :free, Pick,...(Custom)\n3) go back to 'Temperature correlation'.\n\nYou cannot use : 2 passes, AWB temperature bias, Green refinement. !TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. -!TP_WBALANCE_ITCWGREEN;Green refinement +TP_WBALANCE_ITCWGREEN;Groen verfijning !TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. +!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and No use camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) not to use camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. !TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). -!TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 +TP_WBALANCE_MULLABEL;Vermenigvuldigers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. -!TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° +TP_WBALANCE_OBSERVER10;Observer 10° in plaats van Observer 2° !TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. -!TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 +TP_WBALANCE_PATCHLABEL;Lees kleuren:%1 Patch: Chroma:%2 Grootte=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. -!TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 +TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - data x 9 Min:%2 Max=%3 !TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Display ΔE patch (this assumes there is enough spectral data), between image and spectral datas.\n Display read datas found. The 2 values correspond to the minimum and maximum data values taken into account. The coefficient x9 must be taken into account to obtain the number of pixels concerned in the image. -!TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 -!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 -!TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 +TP_WBALANCE_STUDLABEL;Correlatiefactor: %1 Doorgangen:%2 Slechtst=%3 +TP_WBALANCE_STUDLABEL0;Correlatiefactor: %1 Doorgangen:%2 Alt=%3 +TP_WBALANCE_STUDLABEL1;Correlatiefactor: %1 Doorgangen:%2 Best_alt=%3 !TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. !//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. -!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram + From 94cd3d46265b2d4009005305c390405bcc5f7b82 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 18 Feb 2024 11:30:43 -0500 Subject: [PATCH 119/291] Apply time/date format for %t output template specifier --- rtgui/batchqueue.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 8654ce45e..df7842bc7 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -96,6 +96,21 @@ namespace // local helper functions } } } + + // Look in templateText at index ix for quoted string containing a time format string, and + // use that string to format dateTime. Append the formatted time to path. + void appendFormattedTime(Glib::ustring& path, unsigned int& ix, Glib::ustring& templateText, const Glib::DateTime& dateTime) + { + constexpr unsigned int quoteMark = (unsigned int)'"'; + if ((ix + 1) < templateText.size() && templateText[ix] == quoteMark) { + auto endPos = templateText.find_first_of(quoteMark, ++ix); + if (endPos != Glib::ustring::npos) { + Glib::ustring formatString(templateText, ix, endPos-ix); + path += dateTime.format(formatString); + ix = endPos; + } + } + } } BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(nullptr), fileCatalog(aFileCatalog), sequence(0), listener(nullptr) @@ -1009,7 +1024,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam { Glib::DateTime dateTime; bool dateTimeIsValid = true; - switch(options.savePathTemplate[ix]) + switch(options.savePathTemplate[ix++]) { case 'E': // (approximate) time when export started dateTime = Glib::DateTime::create_now_local(); @@ -1037,9 +1052,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } if (dateTimeIsValid) { - // FIXME: Call a function that looks for a double-quoted format string, and - // format dateTime accordingly, adding it to path. - printf("Time %s\n", dateTime.format_iso8601().c_str()); + appendFormattedTime(path, ix, options.savePathTemplate, dateTime); } } } From 703a81ae0c005c6b19350dacf71bd5180aed000a Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 18 Feb 2024 12:22:36 -0500 Subject: [PATCH 120/291] Removed FIXME comment --- rtgui/batchqueuepanel.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index f234c734c..2daccc5ec 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -151,7 +151,6 @@ BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) : parent(nullptr) topBox->pack_start (*fdir, Gtk::PACK_EXPAND_WIDGET, 4); topBox->pack_start (*fformat, Gtk::PACK_EXPAND_WIDGET, 4); - // FIXME: THIS IS SO FAR JUST A TEST THING middleSplitPane = Gtk::manage (new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL)); templateHelpTextView = Gtk::manage (new Gtk::TextView()); templateHelpTextView->set_editable(false); From 547ac41ad4b236cf311c1870ee80050e9144e7f2 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 18 Feb 2024 12:28:00 -0500 Subject: [PATCH 121/291] Make brace placement consistent --- rtgui/batchqueue.cc | 6 ++---- rtgui/batchqueuepanel.cc | 12 ++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index df7842bc7..622124be4 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -1020,8 +1020,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam path += seqstr.str (); } else if (options.savePathTemplate[ix] == 't') { // Insert formatted date/time value. Character after 't' defines time source - if (++ix < options.savePathTemplate.size()) - { + if (++ix < options.savePathTemplate.size()) { Glib::DateTime dateTime; bool dateTimeIsValid = true; switch(options.savePathTemplate[ix++]) @@ -1050,8 +1049,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam dateTimeIsValid = false; break; } - if (dateTimeIsValid) - { + if (dateTimeIsValid) { appendFormattedTime(path, ix, options.savePathTemplate, dateTime); } } diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 2daccc5ec..b74998738 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -389,12 +389,10 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b // Since this code only ever runs once (the first time the help text is presented), no attempt is // made to be efficient. Use a brute-force method to discover the number of elements in exampleFilePath. int pathElementCount = 0; - for (int n=9; n>=0; n--) - { + for (int n=9; n>=0; n--) { options.savePathTemplate = Glib::ustring::format("%d",n); auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); - if (!result.empty()) - { + if (!result.empty()) { // The 'd' specifier returns an empty string if N exceeds the number of path elements, so // the largest N that does not return an empty string is the number of elements in exampleFilePath. pathElementCount = n; @@ -405,8 +403,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b // number of elements in the path. auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2) { - for (int n=0; n b options.savePathTemplate = path2; auto result2 = BatchQueue::calcAutoFileNameBase(exampleFilePath); pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); - if (result1 != result2) - { + if (result1 != result2) { // If this error appears, it indicates a coding error in either BatchQueue::calcAutoFileNameBase // or BatchQueuePanel::populateTemplateHelpBuffer. pos = buffer->insert_markup(pos, Glib::ustring::format(" ", M("QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH"), " ", result2)); From b39ab15659ebc26701157731b6089b832a596ffd Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 19 Feb 2024 11:35:46 -0500 Subject: [PATCH 122/291] Eliminated use of stat() instead using Gio::FileInfo to get file modification date --- rtgui/batchqueue.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 622124be4..2d46d9766 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -18,7 +18,6 @@ */ #include #include -#include #include #include #include "../rtengine/imagedata.h" @@ -99,7 +98,7 @@ namespace // local helper functions // Look in templateText at index ix for quoted string containing a time format string, and // use that string to format dateTime. Append the formatted time to path. - void appendFormattedTime(Glib::ustring& path, unsigned int& ix, Glib::ustring& templateText, const Glib::DateTime& dateTime) + void appendFormattedTime(Glib::ustring& path, unsigned int& ix, const Glib::ustring& templateText, const Glib::DateTime& dateTime) { constexpr unsigned int quoteMark = (unsigned int)'"'; if ((ix + 1) < templateText.size() && templateText[ix] == quoteMark) { @@ -1030,12 +1029,16 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam break; case 'F': // time when file was last saved { - struct stat fileStat; - if (stat(origFileName.c_str(), &fileStat) == 0) { - time_t timestamp = fileStat.st_mtime; - dateTime = Glib::DateTime::create_now_local(timestamp); - } else { - dateTimeIsValid = false; // file not found, access denied, etc. + dateTimeIsValid = false; // becomes true below if no errors + Glib::RefPtr file = Gio::File::create_for_path(origFileName); + if (file) { + Glib::RefPtr info = file->query_info("time::modified"); + if (info) { + dateTime = info->get_modification_date_time(); + if (dateTime) { + dateTimeIsValid = true; + } + } } } break; From 7c67739b9de12f3dff9847ca15af7d2b34c11e60 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Mon, 19 Feb 2024 11:43:04 -0500 Subject: [PATCH 123/291] Eliminated dateTimeIsValid, instead null-checking dateTime -- non-null means it's valid. --- rtgui/batchqueue.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 2d46d9766..ab9c14c7c 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -1021,7 +1021,6 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam // Insert formatted date/time value. Character after 't' defines time source if (++ix < options.savePathTemplate.size()) { Glib::DateTime dateTime; - bool dateTimeIsValid = true; switch(options.savePathTemplate[ix++]) { case 'E': // (approximate) time when export started @@ -1029,15 +1028,11 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam break; case 'F': // time when file was last saved { - dateTimeIsValid = false; // becomes true below if no errors Glib::RefPtr file = Gio::File::create_for_path(origFileName); if (file) { Glib::RefPtr info = file->query_info("time::modified"); if (info) { dateTime = info->get_modification_date_time(); - if (dateTime) { - dateTimeIsValid = true; - } } } } @@ -1049,10 +1044,9 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam } break; default: - dateTimeIsValid = false; break; } - if (dateTimeIsValid) { + if (dateTime) { appendFormattedTime(path, ix, options.savePathTemplate, dateTime); } } From 65a14051feea1497fd39f38d24637761dc989f8c Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 18 Jan 2024 14:19:30 +0100 Subject: [PATCH 124/291] rawimage: put global black level (as found in DNG converted files) for xtrans files where the code expects to find it --- rtengine/rawimage.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 704db176f..301107034 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -606,6 +606,11 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog for (size_t i = 0; i < sizeof(cblack)/sizeof(unsigned); ++i) { cblack[i] = cd.cblack[i]; } + // put the global black level where the rest of the code expects to find it + if (dng_version && isXtrans() && cblack[6] == 0 && black > 0) { + cblack[6] = black; + } + for (int i = 0; i < 4; ++i) { cam_mul[i] = cd.cam_mul[i]; pre_mul[i] = cd.pre_mul[i]; From 3f80708555ef6ec2df7f8a8fb629d681f70a27ce Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 25 Feb 2024 01:08:32 -0800 Subject: [PATCH 125/291] mac: update codesign procedures --- tools/osx/macosx_bundle.sh | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 4a6509403..89b10c5af 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -155,8 +155,9 @@ fi # In: OSX_CONTINUOUS:BOOL=ON # Out: ON -OSX_CONTINUOUS="$(cmake .. -L -N | grep OSX_CONTINUOUS)"; NIGHTLY="${OSX_CONTINUOUS#*=}" && CONTINUOUS="${OSX_CONTINUOUS#*=}" +OSX_CONTINUOUS="$(cmake .. -L -N | grep OSX_CONTINUOUS)"; CONTINUOUS="${OSX_CONTINUOUS#*=}" if [[ -n $CONTINUOUS ]]; then + NIGHTLY="${OSX_CONTINUOUS#*=}" echo "Continuous/generically-named zip is ON." fi @@ -313,13 +314,17 @@ done install_name_tool -delete_rpath RawTherapee.app/Contents/Frameworks "${EXECUTABLE}"-cli 2>/dev/null install_name_tool -add_rpath /Applications/"${LIB}" "${EXECUTABLE}"-cli 2>/dev/null +# Link to libomp instead of libgomp +sudo install_name_tool -change /Applications/RawTherapee.app/Contents/Frameworks/libgomp.1.dylib /Applications/RawTherapee.app/Contents/Frameworks/libomp.dylib RawTherapee.app/Contents/Frameworks/libfftw3f_omp.3.dylib +rm RawTherapee.app/Contents/Frameworks/libgomp.1.dylib + # Merge the app with the other architecture to create the Universal app. if [[ -n $UNIVERSAL_URL ]]; then msg "Getting Universal countercomponent." curl -L ${UNIVERSAL_URL} -o univ.zip msg "Extracting app." unzip univ.zip -d univapp - hdiutil attach -mountpoint ./RawTherapeeuniv univapp/*dmg + hdiutil attach -mountpoint ./RawTherapeeuniv univapp/*folder/*dmg if [[ $arch = "arm64" ]]; then cp -R RawTherapee.app RawTherapee-arm64.app minimum_arm64_version=$(f=$(cat RawTherapee-arm64.app/Contents/Resources/AboutThisBuild.txt | grep mmacosx-version); echo "${f#*min=}" | cut -d ' ' -f1) @@ -336,6 +341,7 @@ if [[ -n $UNIVERSAL_URL ]]; then cat RawTherapee-arm64.app/Contents/Resources/AboutThisBuild.txt >> RawTherapee.app/Contents/Resources/AboutThisBuild.txt fi cmake -DPROJECT_SOURCE_DATA_DIR=${PROJECT_SOURCE_DATA_DIR} -DCONTENTS=${CONTENTS} -Dversion=${PROJECT_FULL_VERSION} -DshortVersion=${PROJECT_VERSION} -Dminimum_arm64_version=${minimum_arm64_version} -Dminimum_x86_64_version=${minimum_x86_64_version} -Darch=${arch} -P ${PROJECT_SOURCE_DATA_DIR}/info-plist.cmake + plutil -convert xml1 ${APP}/Contents/Info.plist hdiutil unmount ./RawTherapeeuniv rm -r univapp # Create the fat main RawTherapee binary and move it into the new bundle @@ -360,9 +366,26 @@ fi if [[ -n $CODESIGNID ]]; then msg "Codesigning Application." iconv -f UTF-8 -t ASCII "${PROJECT_SOURCE_DATA_DIR}"/rt.entitlements > "${CMAKE_BUILD_TYPE}"/rt.entitlements -# mv "${EXECUTABLE}"-cli "${LIB}" - codesign --force --deep --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee-cli "${APP}"/Contents/MacOS/rawtherapee-cli - codesign --force --deep --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}" + plutil -convert xml1 "${CMAKE_BUILD_TYPE}"/rt.entitlements + for frame in ${APP}/Contents/Frameworks/* ; do + echo $frame + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements $frame + done + for resource in ${APP}/Contents/Resources/* ; do + echo $resource + if [ ! -d $resource ]; then + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements $resource + else + for subresource in ${APP}/Contents/Resources/$(basename $resource)/* ; do + if [ ! -d $subresource ]; then + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements $subresource + fi + done + fi + done + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}"/Contents/MacOS/rawtherapee-cli + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}"/Contents/MacOS/rawtherapee + codesign --preserve-metadata=identifier --digest-algorithm=sha1,sha256 --force --timestamp --strict -v -s "${CODESIGNID}" -i com.rawtherapee.RawTherapee -o runtime --entitlements "${CMAKE_BUILD_TYPE}"/rt.entitlements "${APP}" spctl -a -vvvv "${APP}" fi @@ -436,7 +459,7 @@ function CreateDmg { # Sign disk image if [[ -n $CODESIGNID ]]; then msg "Signing disk image" - codesign --deep --force -v -s "${CODESIGNID}" --timestamp "${dmg_name}.dmg" + codesign --digest-algorithm=sha1,sha256 --force -v -s "${CODESIGNID}" --timestamp "${dmg_name}.dmg" fi # Notarize the dmg From fbeaace607d5ecdd207d49a4523025335d1d97fb Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 25 Feb 2024 10:14:10 -0500 Subject: [PATCH 126/291] Change literal to G_FILE_ATTRIBUTE_TIME_MODIFIED, change line spacing in template help --- rtgui/batchqueue.cc | 2 +- rtgui/batchqueuepanel.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index ab9c14c7c..3a82ef511 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -1030,7 +1030,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam { Glib::RefPtr file = Gio::File::create_for_path(origFileName); if (file) { - Glib::RefPtr info = file->query_info("time::modified"); + Glib::RefPtr info = file->query_info(G_FILE_ATTRIBUTE_TIME_MODIFIED); if (info) { dateTime = info->get_modification_date_time(); } diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index b74998738..619a5f896 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -381,7 +381,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b #else auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); #endif - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); // Examples are generated from exampleFilePath using the actual template processing function Options savedOptions = options; // to be restored after generating example results From 50f27c099cb2443286c2ec4170afd185f7c27d79 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 25 Feb 2024 17:38:42 -0500 Subject: [PATCH 127/291] Make indentation consistent in queue template help --- rtgui/batchqueuepanel.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 619a5f896..27df872d3 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -381,7 +381,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b #else auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); #endif - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n\n")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); // Examples are generated from exampleFilePath using the actual template processing function Options savedOptions = options; // to be restored after generating example results @@ -410,7 +410,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b auto result1 = BatchQueue::calcAutoFileNameBase(exampleFilePath); options.savePathTemplate = path2; auto result2 = BatchQueue::calcAutoFileNameBase(exampleFilePath); - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", path1, " = ", path2, " = ", result1, "")); if (result1 != result2) { // If this error appears, it indicates a coding error in either BatchQueue::calcAutoFileNameBase // or BatchQueuePanel::populateTemplateHelpBuffer. @@ -426,7 +426,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b Glib::ustring fspecifier("%f"); options.savePathTemplate = fspecifier; auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", fspecifier, " = ", result, "")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", fspecifier, " = ", result, "")); } insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE")); @@ -446,7 +446,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b auto timeForExamples = Glib::DateTime::create_from_iso8601("2001-02-03T04:05:06.123456", timezone); for (auto fmt : dateTimeFormatExamples) { auto result = timeForExamples.format(fmt); - pos = buffer->insert_markup(pos, Glib::ustring::format("\n %tE\"", fmt, "\" = ", result, "")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n %tE\"", fmt, "\" = ", result, "")); } pos = buffer->insert(pos, "\n"); From 1db8b0d64323144baf83db6abc9b546add2b6ff3 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Sun, 25 Feb 2024 17:49:00 -0500 Subject: [PATCH 128/291] Indent example path the same amount as other indented items in the queue template help --- rtgui/batchqueuepanel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 27df872d3..f7e46fa7c 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -381,7 +381,7 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b #else auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); #endif - pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); + pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); // Examples are generated from exampleFilePath using the actual template processing function Options savedOptions = options; // to be restored after generating example results From 3672e0f34dc09355296521960b117659c6389dcc Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Wed, 28 Feb 2024 15:26:17 +0100 Subject: [PATCH 129/291] Clean appimage.yml & windows.yml --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5f447fe8a..5d36fc444 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:wbrefinement"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 2e1d3bc69..875dce60e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:wbrefinement"]' + publish_pre_dev_labels: '[]' jobs: build: From cd64ced60fd4053c1603ec55f2e2ef6ab5c1aaa0 Mon Sep 17 00:00:00 2001 From: Scott Gilbertson Date: Wed, 28 Feb 2024 13:09:25 -0500 Subject: [PATCH 130/291] Address comments in pull request: - use "const" where possible - add spaces after commas - use dateTimeFormatExamples by reference (don't copy) - fix incorrect cast to unsigned int (declare variable as gunichar) --- rtgui/batchqueue.cc | 14 +++++++++----- rtgui/batchqueuepanel.cc | 38 +++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 3a82ef511..c275ee675 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -100,9 +100,9 @@ namespace // local helper functions // use that string to format dateTime. Append the formatted time to path. void appendFormattedTime(Glib::ustring& path, unsigned int& ix, const Glib::ustring& templateText, const Glib::DateTime& dateTime) { - constexpr unsigned int quoteMark = (unsigned int)'"'; + constexpr gunichar quoteMark('"'); if ((ix + 1) < templateText.size() && templateText[ix] == quoteMark) { - auto endPos = templateText.find_first_of(quoteMark, ++ix); + const auto endPos = templateText.find_first_of(quoteMark, ++ix); if (endPos != Glib::ustring::npos) { Glib::ustring formatString(templateText, ix, endPos-ix); path += dateTime.format(formatString); @@ -1024,8 +1024,10 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam switch(options.savePathTemplate[ix++]) { case 'E': // (approximate) time when export started + { dateTime = Glib::DateTime::create_now_local(); break; + } case 'F': // time when file was last saved { Glib::RefPtr file = Gio::File::create_for_path(origFileName); @@ -1035,16 +1037,18 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam dateTime = info->get_modification_date_time(); } } - } break; + } case 'P': // time when picture was taken { - auto timestamp = FramesData(origFileName).getDateTimeAsTS(); + const auto timestamp = FramesData(origFileName).getDateTimeAsTS(); dateTime = Glib::DateTime::create_now_local(timestamp); + break; } - break; default: + { break; + } } if (dateTime) { appendFormattedTime(path, ix, options.savePathTemplate, dateTime); diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index f7e46fa7c..bf6cc0772 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -344,7 +344,7 @@ void BatchQueuePanel::templateHelpButtonToggled() if (buffer->get_text().empty()) { // Populate the help text the first time it's shown populateTemplateHelpBuffer(buffer); - auto fullWidth = middleSplitPane->get_width(); + const auto fullWidth = middleSplitPane->get_width(); middleSplitPane->set_position(fullWidth / 2); } scrolledTemplateHelpWindow->set_visible(visible); @@ -354,13 +354,13 @@ void BatchQueuePanel::templateHelpButtonToggled() void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr buffer) { auto pos = buffer->begin(); - auto insertTopicHeading = [&pos, buffer](const Glib::ustring& text) { + const auto insertTopicHeading = [&pos, buffer](const Glib::ustring& text) { pos = buffer->insert_markup(pos, Glib::ustring::format("\n\n", text, "\n")); }; - auto insertTopicBody = [&pos, buffer](const Glib::ustring& text) { + const auto insertTopicBody = [&pos, buffer](const Glib::ustring& text) { pos = buffer->insert_markup(pos, Glib::ustring::format("\n", text, "\n")); }; - auto mainTitle = M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE"); + const auto mainTitle = M("QUEUE_LOCATION_TEMPLATE_HELP_TITLE"); pos = buffer->insert_markup(pos, Glib::ustring::format("", mainTitle, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_INTRO")); @@ -377,21 +377,21 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b pos = buffer->insert(pos, "\n"); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1")); #ifdef _WIN32 - auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); + const auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS"); #else - auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); + const auto exampleFilePath = M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX"); #endif pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", exampleFilePath, "\n")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2")); // Examples are generated from exampleFilePath using the actual template processing function - Options savedOptions = options; // to be restored after generating example results + const Options savedOptions = options; // to be restored after generating example results options.saveUsePathTemplate = true; // Since this code only ever runs once (the first time the help text is presented), no attempt is // made to be efficient. Use a brute-force method to discover the number of elements in exampleFilePath. int pathElementCount = 0; for (int n=9; n>=0; n--) { - options.savePathTemplate = Glib::ustring::format("%d",n); - auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); + options.savePathTemplate = Glib::ustring::format("%d", n); + const auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); if (!result.empty()) { // The 'd' specifier returns an empty string if N exceeds the number of path elements, so // the largest N that does not return an empty string is the number of elements in exampleFilePath. @@ -401,11 +401,11 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b } // Function inserts examples for a particular specifier, with every valid N value for the // number of elements in the path. - auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2) + const auto insertPathExamples = [&buffer, &pos, pathElementCount, exampleFilePath](char letter, int offset1, int mult1, int offset2, int mult2) { for (int n=0; n b insertPathExamples('p', 1, 1, -pathElementCount, 1); // %p1 = %p-4 = /home/tom/photos/2010-10-31/ insertPathExamples('P', 1, 1, -pathElementCount, 1); // %P1 = %P-4 = 2010-10-31/ { - Glib::ustring fspecifier("%f"); + const Glib::ustring fspecifier("%f"); options.savePathTemplate = fspecifier; - auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); + const auto result = BatchQueue::calcAutoFileNameBase(exampleFilePath); pos = buffer->insert_markup(pos, Glib::ustring::format("\n ", fspecifier, " = ", result, "")); } @@ -437,15 +437,15 @@ void BatchQueuePanel::populateTemplateHelpBuffer(Glib::RefPtr b insertTopicHeading(M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE")); pos = buffer->insert_markup(pos, M("QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY")); - Glib::ustring dateTimeFormatExamples[] = { + const Glib::ustring dateTimeFormatExamples[] = { "%Y-%m-%d", "%Y%m%d_%H%M%S", "%y/%b/%-d/" }; - auto timezone = Glib::DateTime::create_now_local().get_timezone(); - auto timeForExamples = Glib::DateTime::create_from_iso8601("2001-02-03T04:05:06.123456", timezone); - for (auto fmt : dateTimeFormatExamples) { - auto result = timeForExamples.format(fmt); + const auto timezone = Glib::DateTime::create_now_local().get_timezone(); + const auto timeForExamples = Glib::DateTime::create_from_iso8601("2001-02-03T04:05:06.123456", timezone); + for (auto && fmt : dateTimeFormatExamples) { + const auto result = timeForExamples.format(fmt); pos = buffer->insert_markup(pos, Glib::ustring::format("\n %tE\"", fmt, "\" = ", result, "")); } From 6daf3f6a239fb6bf03d24ef57ef1d2bc6535bc9e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 2 Mar 2024 20:55:07 -0800 Subject: [PATCH 131/291] Fix possible infinite loop in dcraw Use same type for variable comparison in loop condition. Fixes CodeQL alert 96. --- rtengine/libraw/src/decoders/decoders_dcraw.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtengine/libraw/src/decoders/decoders_dcraw.cpp b/rtengine/libraw/src/decoders/decoders_dcraw.cpp index 090a6b726..6aff40e39 100644 --- a/rtengine/libraw/src/decoders/decoders_dcraw.cpp +++ b/rtengine/libraw/src/decoders/decoders_dcraw.cpp @@ -345,7 +345,10 @@ int LibRaw::ljpeg_start(struct jhead *jh, int info_only) if (jh->sraw) { FORC(4) jh->huff[2 + c] = jh->huff[1]; - FORC(jh->sraw) jh->huff[1 + c] = jh->huff[0]; + { + int c; + FORC(jh->sraw) jh->huff[1 + c] = jh->huff[0]; + } } jh->row = (ushort *)calloc(jh->wide * jh->clrs, 16); return zero_after_ff = 1; From 484f1a29dec2ed1e1572fc7e7afb629fc0c369aa Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 3 Mar 2024 07:28:37 +0100 Subject: [PATCH 132/291] Local adjustments - Chromaticity curve C(h) (#6964) * Chromaticity curve C(h) * Appimage.yml windows.yml lachroma --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtengine/iplocallab.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5d36fc444..a697bfee9 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:lachroma"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 875dce60e..fe83c5f6b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:lachroma"]' jobs: build: diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 3d02c9df6..4e9072f7e 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -17813,7 +17813,7 @@ void ImProcFunctions::Lab_Local( } if (locchCurve && CHcurve && lp.qualcurvemet != 0) {//C=f(H) curve const float rhue = xatan2f(bufcolcalcb, bufcolcalca); - const float valparam = 2.f * locchCurve[500.f * static_cast(Color::huelab_to_huehsv2(rhue))] - 0.5f; //get valp=f(H) + const float valparam = locchCurve[500.f * static_cast(Color::huelab_to_huehsv2(rhue))] - 0.5f; //get valp=f(H) float chromaChfactor = 1.0f + valparam; bufcolcalca *= chromaChfactor;//apply C=f(H) bufcolcalcb *= chromaChfactor; From 619b1866fbef8c25a0b3c93b502b53941053b8fe Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Sun, 3 Mar 2024 08:09:24 +0100 Subject: [PATCH 133/291] Remove appimage.yml and windows.yml --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index a697bfee9..5d36fc444 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:lachroma"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index fe83c5f6b..875dce60e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:lachroma"]' + publish_pre_dev_labels: '[]' jobs: build: From 4e22e32459e7bb8ded0395280b26f783e30423ed Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:53:56 -0800 Subject: [PATCH 134/291] Update Italian translation Translation provided by capejeaspaje (https://github.com/Beep6581/RawTherapee/issues/6971). --- rtdata/languages/Italiano | 6330 ++++++++++++++++++------------------- 1 file changed, 3165 insertions(+), 3165 deletions(-) diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index c150994ee..5ef63de7b 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -3,6 +3,7 @@ #003 2011-08-26 v3.0 joker, chelidon, ffsup2 #004 2011-08-31 v4.0 chelidon, ffsup2 #005 2014-04-21 crx +#006 2024-03-04 capejeaspaje #100 #101 @LANGUAGE_DISPLAY_NAME=Italiano @@ -11,11 +12,18 @@ ABOUT_TAB_CREDITS;Riconoscimenti ABOUT_TAB_LICENSE;Licenza ABOUT_TAB_RELEASENOTES;Note di rilascio ABOUT_TAB_SPLASH;Emblema +ADJUSTER_RESET_TO_DEFAULT;Click - ripristina i valori di default.\nCtrl+click - ripristina i valori iniziali. BATCH_PROCESSING;Sviluppo in serie +CURVEEDITOR_AXIS_IN;I: +CURVEEDITOR_AXIS_LEFT_TAN;LT: +CURVEEDITOR_AXIS_OUT;O: +CURVEEDITOR_AXIS_RIGHT_TAN;RT: +CURVEEDITOR_CATMULLROM;Flessibile CURVEEDITOR_CURVE;Curva CURVEEDITOR_CURVES;Curve CURVEEDITOR_CUSTOM;Personalizzata CURVEEDITOR_DARKS;Toni Scuri +CURVEEDITOR_EDITPOINT_HINT;Abilita la modifica dei valori di ingresso/uscita del nodo.\n\n Click-destro su un nodo per selezionarlo.\nClick-destro su uno spazio vuoto per deselezionare il nodo. CURVEEDITOR_HIGHLIGHTS;Alteluci CURVEEDITOR_LIGHTS;Toni chiari CURVEEDITOR_LINEAR;Lineare @@ -32,23 +40,43 @@ CURVEEDITOR_TOOLTIPPASTE;Incolla la curva dagli appunti CURVEEDITOR_TOOLTIPSAVE;Salva la curva corrente CURVEEDITOR_TYPE;Tipologia: DIRBROWSER_FOLDERS;Cartelle -EDITWINDOW_TITLE;Modifica immagine +DONT_SHOW_AGAIN;Non mostrare più questo messaggio. +DYNPROFILEEDITOR_DELETE;Elimina +DYNPROFILEEDITOR_EDIT_RULE;Modifica regola profilo dinamico +DYNPROFILEEDITOR_EDIT;Modifica +DYNPROFILEEDITOR_ENTRY_TOOLTIP;La corrispondenza non fa distinzione tra maiuscole e minuscole.\nUtilizzare il prefisso 're:' per inserire\na un'espressione regolare. +DYNPROFILEEDITOR_IMGTYPE_ANY;Qualsiasi +DYNPROFILEEDITOR_IMGTYPE_HDR;HDR +DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift +DYNPROFILEEDITOR_IMGTYPE_STD;Standard +DYNPROFILEEDITOR_MOVE_DOWN;Muovi Giù +DYNPROFILEEDITOR_MOVE_UP;Muovi Sù +DYNPROFILEEDITOR_NEW_RULE;Nuova regola del profilo dinamico +DYNPROFILEEDITOR_NEW;Nuovo +DYNPROFILEEDITOR_PROFILE;Profilo di elaborazione EDIT_OBJECT_TOOLTIP;Mostra un widget nella finestra anteprima che ti permette di configurare questo strumento. EDIT_PIPETTE_TOOLTIP;Per aggiungere un punto di regolazione alla curva, tieni premuto il tasto Ctrl e fai click sul punto desiderato nell'anteprima dell'immagine.\nPer sistemare il punto, tieni premuto il tasto Ctrl mentre fai click sulla corrispondente area nell'anteprima, poi lascia il tasto Ctrl (a meno che non desideri un controllo fine) e mentre tieni premuto il tasto sinistro del mouse, muovilo in su e in giù per muovere il punto su e giù sulla curva. +EDITWINDOW_TITLE;Modifica immagine +ERROR_MSG_METADATA_VALUE;Metadata: errore di setting %1 di %2 EXIFFILTER_APERTURE;Diaframma EXIFFILTER_CAMERA;Fotocamera EXIFFILTER_EXPOSURECOMPENSATION;Compensazione dell'Esposizione (EV) EXIFFILTER_FILETYPE;Tipo file EXIFFILTER_FOCALLEN;Lunghezza focale +EXIFFILTER_IMAGETYPE;Tipo di immagine EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Obiettivo EXIFFILTER_METADATAFILTER;Abilita filtri metadati +EXIFFILTER_PATH;Percorso del file EXIFFILTER_SHUTTER;Tempo d'esposizione +EXIFPANEL_ACTIVATE_ALL_HINT;Seleziona tutti i tags +EXIFPANEL_ACTIVATE_NONE_HINT;Deseleziona tutti i tags EXIFPANEL_ADDEDIT;Aggiungi/Modifica EXIFPANEL_ADDEDITHINT;Aggiungi un nuovo campo o modificane uno esistente EXIFPANEL_ADDTAGDLG_ENTERVALUE;Inserisci il valore EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleziona un campo EXIFPANEL_ADDTAGDLG_TITLE;Aggiungi/Modifica un campo +EXIFPANEL_BASIC_GROUP;Di base EXIFPANEL_KEEP;Mantieni EXIFPANEL_KEEPHINT;Mantieni i campi selezionati nel file di uscita EXIFPANEL_REMOVE;Rimuovi @@ -58,10 +86,12 @@ EXIFPANEL_RESETALL;Ripristina tutto EXIFPANEL_RESETALLHINT;Ripristina tutti i campi al loro valore originario EXIFPANEL_RESETHINT;Ripristina i campi selezionati ai loro valori originari EXIFPANEL_SUBDIRECTORY;Sottocartella +EXIFPANEL_VALUE_NOT_SHOWN;Non mostrare EXPORT_BYPASS_ALL;Seleziona/Deseleziona Tutto EXPORT_BYPASS_DEFRINGE;Ignora Defringe EXPORT_BYPASS_DIRPYRDENOISE;Ignora Riduzione Rumore EXPORT_BYPASS_DIRPYREQUALIZER;Ignora Contrasto per livelli di dettaglio +EXPORT_BYPASS_EQUALIZER;Bypassare i livelli wavelet EXPORT_BYPASS_RAW_CA;Ignora Correzione Aberrazione Cromatica [raw] EXPORT_BYPASS_RAW_CCSTEPS;Ignora Soppressione Falsi Colori [raw] EXPORT_BYPASS_RAW_DCB_ENHANCE;Ignora Passaggi di Miglioramento DCB [raw] @@ -74,27 +104,39 @@ EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Ignora i Passaggi di Miglioramento LMMSE EXPORT_BYPASS_SHARPENEDGE;Ignora Nitidezza dei bordi EXPORT_BYPASS_SHARPENING;Ignora Nitidezza EXPORT_BYPASS_SHARPENMICRO;Ignora Microcontrasto +EXPORT_BYPASS;Passaggi di elaborazione da bypassare EXPORT_FASTEXPORTOPTIONS;Opzioni di Esportazione Rapida EXPORT_INSTRUCTIONS;Le opzioni di Esportazione Rapida forniscono opzioni per ignorare le impostazioni di sviluppo ad elevato consumo di tempo e risorse ed avviare quindi la coda di sviluppo usando solo le impostazioni veloci. Questo metodo è consigliato per la lavorazione veloce di immagini a bassa risoluzione quando è importante la rapidità, oppure quando si desidera ridimensionare una o più immagini senza apportare modifiche ai parametri di sviluppo salvati. EXPORT_MAXHEIGHT;Altezza Massima: EXPORT_MAXWIDTH;Larghezza Massima: +EXPORT_PIPELINE;Pipeline di elaborazione EXPORT_PUTTOQUEUEFAST; Aggiungi alla Coda di sviluppo per l'Esportazione Rapida EXPORT_RAW_DMETHOD;Metodo di Demosaicizzazione +EXPORT_USE_FAST_PIPELINE_TOOLTIP;Utilizza una pipeline di elaborazione dedicata per le immagini in modalità Esportazione rapida, che baratta la velocità con la qualità. Il ridimensionamento dell'immagine viene effettuato il prima possibile, invece di farlo alla fine come nella pipeline normale. L'accelerazione può essere significativa, ma preparati a vedere artefatti e un generale degrado della qualità dell'output. +EXPORT_USE_FAST_PIPELINE;Dedicato (elaborazione completa sull'immagine ridimensionata) +EXPORT_USE_NORMAL_PIPELINE;Standard (ignora alcuni passaggi, ridimensiona alla fine) EXTPROGTARGET_1;raw EXTPROGTARGET_2;Lavorato dalla Coda -FILEBROWSER_APPLYPROFILE;Applica FILEBROWSER_APPLYPROFILE_PARTIAL;Applica (parziale) +FILEBROWSER_APPLYPROFILE;Applica FILEBROWSER_AUTODARKFRAME;Dark Frame automatico FILEBROWSER_AUTOFLATFIELD;Flat Field automatico +FILEBROWSER_BROWSEPATHBUTTONHINT;Fare clic per aprire il percorso specificato, ricaricare la cartella e applicare le parole chiave "trova". FILEBROWSER_BROWSEPATHHINT;Inserisci il percorso da aprire\nCtrl-o seleziona il percorso\nEnter, Ctrl-Enter (solo nel Navigatore) porta alla destinazione ;\nScorciatoie:\n ~ - Cartella home\n ! - Cartella Immagini FILEBROWSER_CACHE;Memoria +FILEBROWSER_CACHECLEARFROMFULL;Cancella tutto, compresi i profili memorizzati nella cache +FILEBROWSER_CACHECLEARFROMPARTIAL;Cancella tutto tranne i profili memorizzati nella cache FILEBROWSER_CLEARPROFILE;Cancella FILEBROWSER_COLORLABEL_TOOLTIP;Etichetta colore.\n\nUsa il menù o le scorciatoie:\nShift-Ctrl-0 Nessun Colore\nShift-Ctrl-1 Rosso\nShift-Ctrl-2 Giallo\nShift-Ctrl-3 Verde\nShift-Ctrl-4 Blu\nShift-Ctrl-5 Viola FILEBROWSER_COPYPROFILE;Copia FILEBROWSER_CURRENT_NAME;Nome corrente: FILEBROWSER_DARKFRAME;Dark Frame +FILEBROWSER_DELETEDIALOG_ALL;Vuoi eliminare permanentemente tutti i file %1 nel cestino? FILEBROWSER_DELETEDIALOG_HEADER;Conferma eliminazione del file +FILEBROWSER_DELETEDIALOG_SELECTED;Sei sicuro di voler eliminare permanentemente i file %1 selezionati? +FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Sei sicuro di voler eliminare permanentemente i file %1 selezionati, inclusa una versione elaborata in coda? FILEBROWSER_EMPTYTRASH;Svuota cestino +FILEBROWSER_EMPTYTRASHHINT;Elimina permanentemente tutti i file nel cestino. FILEBROWSER_EXTPROGMENU;Apri con FILEBROWSER_FLATFIELD;Flat Field FILEBROWSER_MOVETODARKFDIR;Sposta nella cartella dei Dark Frame @@ -113,6 +155,7 @@ FILEBROWSER_POPUPCOLORLABEL4;Etichetta: Blu FILEBROWSER_POPUPCOLORLABEL5;Etichetta: Viola FILEBROWSER_POPUPCOPYTO;Copia in... FILEBROWSER_POPUPFILEOPERATIONS;Operazioni sul file +FILEBROWSER_POPUPINSPECT;Ispezionare FILEBROWSER_POPUPMOVEEND;Sposta in fondo alla coda FILEBROWSER_POPUPMOVEHEAD;Sposta in cima alla coda FILEBROWSER_POPUPMOVETO;Sposta in... @@ -128,8 +171,11 @@ FILEBROWSER_POPUPRANK2;Punteggio 2 ** FILEBROWSER_POPUPRANK3;Punteggio 3 *** FILEBROWSER_POPUPRANK4;Punteggio 4 **** FILEBROWSER_POPUPRANK5;Punteggio 5 ***** +FILEBROWSER_POPUPREMOVE;Elimina in modo permanente +FILEBROWSER_POPUPREMOVEINCLPROC;Elimina in modo permanente, inclusa la versione elaborata in coda FILEBROWSER_POPUPRENAME;Rinomina FILEBROWSER_POPUPSELECTALL;Seleziona tutto +FILEBROWSER_POPUPSORTBY;Ordina file FILEBROWSER_POPUPTRASH;Sposta nel cestino FILEBROWSER_POPUPUNRANK;Rimuovi il punteggio FILEBROWSER_POPUPUNTRASH;Rimuovi dal cestino @@ -142,6 +188,7 @@ FILEBROWSER_RANK3_TOOLTIP;Punteggio 3 *\nScorciatoia: 3 FILEBROWSER_RANK4_TOOLTIP;Punteggio 4 *\nScorciatoia: 4 FILEBROWSER_RANK5_TOOLTIP;Punteggio 5 *\nScorciatoia: 5 FILEBROWSER_RENAMEDLGLABEL;Rinomina il file +FILEBROWSER_RESETDEFAULTPROFILE;Riportare alle condizioni originali FILEBROWSER_SELECTDARKFRAME;Seleziona un Dark Frame... FILEBROWSER_SELECTFLATFIELD;Seleziona un Flat Field... FILEBROWSER_SHOWCOLORLABEL1HINT;Mostra le immagini con etichetta Rossa.\nScorciatoia: Alt-1 @@ -153,6 +200,8 @@ FILEBROWSER_SHOWDIRHINT;Rimuovi tutti i filtri.\nScorciatoia: d FILEBROWSER_SHOWEDITEDHINT;Mostra immagini modificate.\nScorciatoia: Shift-7 FILEBROWSER_SHOWEDITEDNOTHINT;Mostra immagini non modificate.\nScorciatoia: Shift-6 FILEBROWSER_SHOWEXIFINFO;Mostra informazioni Exif.\nScorciatoie:\ni - Modalità a Schede Multiple,\nAlt-i - Modalità a Schede Singole. +FILEBROWSER_SHOWNOTTRASHHINT;Mostra solo le immagini non nel cestino. +FILEBROWSER_SHOWORIGINALHINT;Mostra solo immagini originali.\n\nQuando esistono più immagini con lo stesso nome file ma estensioni diverse, quella considerata originale è quella la cui estensione è più vicina alla parte superiore dell'elenco delle estensioni analizzate in Preferenze > Browser file > Estensioni analizzate. FILEBROWSER_SHOWRANK1HINT;Mostra le immagini classificate con 1 stella.\nScorciatoia: Shift-1 FILEBROWSER_SHOWRANK2HINT;Mostra le immagini classificate con 2 stelle.\nScorciatoia: Shift-2 FILEBROWSER_SHOWRANK3HINT;Mostra le immagini classificate con 3 stelle.\nScorciatoia: Shift-3 @@ -167,32 +216,62 @@ FILEBROWSER_THUMBSIZE;Dimensione miniature FILEBROWSER_UNRANK_TOOLTIP;Nessun Punteggio.\nScorciatoia: 0 FILEBROWSER_ZOOMINHINT;Aumenta la dimensione delle miniature.\n\nScorciatoie:\n+ - Modalità a Schede Multiple,\nAlt-+ - Modalità a Schede Singole. FILEBROWSER_ZOOMOUTHINT;Diminuisci la dimensione delle miniature.\n\nScorciatoie:\n- - Modalità a Schede Multiple,\nAlt-- - Modalità a Schede Singole. +FILECHOOSER_FILTER_ANY;Tutti i files +FILECHOOSER_FILTER_COLPROF;Profili colore (*.icc) +FILECHOOSER_FILTER_CURVE;File di curve +FILECHOOSER_FILTER_EXECUTABLE;File eseguibili +FILECHOOSER_FILTER_LCP;Profili di correzione delle lenti +FILECHOOSER_FILTER_PP;Profili di elaborazione +FILECHOOSER_FILTER_SAME;Stesso formato della foto attuale +FILECHOOSER_FILTER_TIFF;File TIFF GENERAL_ABOUT;Informazioni GENERAL_AFTER;Dopo +GENERAL_APPLY;Applica +GENERAL_ASIMAGE;Come immagine GENERAL_AUTO;Automatico GENERAL_BEFORE;Prima GENERAL_CANCEL;Annulla GENERAL_CLOSE;Chiudi +GENERAL_CURRENT;Attuale +GENERAL_DELETE_ALL;Cancella tutto GENERAL_DISABLE;Disabilita GENERAL_DISABLED;Disabilitato +GENERAL_EDIT;Modifica GENERAL_ENABLE;Abilita GENERAL_ENABLED;Abilitato GENERAL_FILE;File +GENERAL_HELP;Aiuto GENERAL_LANDSCAPE;Panorama GENERAL_NA;n/a GENERAL_NO;No GENERAL_NONE;Nessuno GENERAL_OK;OK +GENERAL_OPEN;Apri +GENERAL_OTHER;Altro GENERAL_PORTRAIT;Ritratto +GENERAL_RESET;Ripristina +GENERAL_SAVE_AS;Salva come… GENERAL_SAVE;Salva +GENERAL_SLIDER;Cursore GENERAL_UNCHANGED;(Invariato) GENERAL_WARNING;Attenzione +GIMP_PLUGIN_INFO;Benvenuto nel plugin GIMP di RawTherapee!\nUna volta terminata la modifica, chiudi semplicemente la finestra principale di RawTherapee e l'immagine verrà automaticamente importata in GIMP. HISTOGRAM_TOOLTIP_B;Mostra/Nascondi l'istogramma del Blu. HISTOGRAM_TOOLTIP_BAR;Mostra/Nascondi la barra RBG.\nPremi il tasto destro del mouse sull'anteprima dell'immagine per bloccarla/sbloccarla. HISTOGRAM_TOOLTIP_CHRO;Mostra/Nascondi l'istogramma di cromaticità. +HISTOGRAM_TOOLTIP_CROSSHAIR;Mostra/nascondi mirino indicatore. HISTOGRAM_TOOLTIP_G;Mostra/Nascondi l'istogramma del Verde. HISTOGRAM_TOOLTIP_L;Mostra/Nascondi l'istogramma di Luminanza CIELAB. +HISTOGRAM_TOOLTIP_MODE;Alterna tra il ridimensionamento lineare, log-lineare e log-log dell'istogramma. HISTOGRAM_TOOLTIP_R;Mostra/Nascondi l'istogramma del Rosso. +HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Attiva/disattiva la visibilità dei pulsanti di opzione dell'ambito. +HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Regola la luminosità dell'oscilloscopio. +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Istogramma grezzo +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Istogramma +HISTOGRAM_TOOLTIP_TYPE_PARADE;Parata RGB +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Vectorscope tonalità-croma +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Vectorscope tonalità-saturazione +HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Forma d'onda HISTORY_CHANGED;Modificato HISTORY_CUSTOMCURVE;Curva personalizzata HISTORY_FROMCLIPBOARD;Dagli appunti @@ -224,7 +303,7 @@ HISTORY_MSG_28;USM - Quantità Controllo Alone HISTORY_MSG_29;Nitidezza - Metodo HISTORY_MSG_30;RLD - Raggio HISTORY_MSG_31;RLD - Quantità -HISTORY_MSG_32;RLD - Smorzamento +HISTORY_MSG_32;RLD - Attenuazione HISTORY_MSG_33;RLD - Iterazioni HISTORY_MSG_34;Correzione Distorsione HISTORY_MSG_35;Correzione Vignettatura @@ -335,7 +414,7 @@ HISTORY_MSG_154;Vividezza - Proteggi Incarnato HISTORY_MSG_155;Vividezza - Evita il color shift HISTORY_MSG_156;Vividezza - Lega toni Pastello/Saturi HISTORY_MSG_157;Vividezza - Soglia Pastello/Saturi -HISTORY_MSG_158;TM - Forza +HISTORY_MSG_158;TM - Intensità HISTORY_MSG_159;TM - Blocco ai Bordi HISTORY_MSG_160;TM - Scala HISTORY_MSG_161;TM - Iterazioni di Ribilanciamento @@ -343,12 +422,14 @@ HISTORY_MSG_162;Tone Mapping (TM) HISTORY_MSG_163;Curve RGB - R (Rosso) HISTORY_MSG_164;Curve RGB - G (Verde) HISTORY_MSG_165;Curve RGB - B (Blu) +HISTORY_MSG_166;Esposizione – Reimposta HISTORY_MSG_167;Demosaicizzazione - Metodo HISTORY_MSG_168;Curva 'CC' HISTORY_MSG_169;Curva 'CH' HISTORY_MSG_170;Vividezza - Curva HISTORY_MSG_171;Curva 'LC' HISTORY_MSG_172;Lab - Limita LC +HISTORY_MSG_173;NR - Recupero dettaglio HISTORY_MSG_174;CIECAM02 HISTORY_MSG_175;CAM02 - Adattamento CAT02 HISTORY_MSG_176;CAM02 - Ambiente di Visualizzazione @@ -378,6 +459,7 @@ HISTORY_MSG_199;CAM02 - Mostra negli istogrammi HISTORY_MSG_200;CAM02 - Tone mapping HISTORY_MSG_201;NR - Crominanza R,G HISTORY_MSG_202;NR - Crominanza B,Y +HISTORY_MSG_203;NR - Spazio colore HISTORY_MSG_204;Passaggi di miglioramento LMMSE HISTORY_MSG_205;CAM02 - Pixel Surriscaldati/Guasti HISTORY_MSG_206;CAT02 - Lum. automatica della scena @@ -385,7 +467,7 @@ HISTORY_MSG_207;Defringe - Curva Tonalità HISTORY_MSG_208;WB - B-R Equalizzatore HISTORY_MSG_210;GF - Angolo HISTORY_MSG_211;Filtro Graduato (GF) -HISTORY_MSG_212;VF - Forza +HISTORY_MSG_212;VF - Intensità HISTORY_MSG_213;Filtro Vignettatura (VF) HISTORY_MSG_214;Bianco-Nero (BN) HISTORY_MSG_215;BN - CM - Rosso @@ -408,14 +490,16 @@ HISTORY_MSG_231;BN - Curva 'Prima' HISTORY_MSG_232;BN - Tipo Curva 'Prima' HISTORY_MSG_233;BN - Curva 'Dopo' HISTORY_MSG_234;BN - Tipo Curva 'Dopo' +HISTORY_MSG_235;B&W - CM – Auto HISTORY_MSG_236;--unused-- +HISTORY_MSG_237;B&W – CM HISTORY_MSG_238;GF - Scia -HISTORY_MSG_239;GF - Forza +HISTORY_MSG_239;GF - intensità HISTORY_MSG_240;GF - Centro HISTORY_MSG_241;VF - Scia HISTORY_MSG_242;VF - Rotondità HISTORY_MSG_243;VC - Raggio -HISTORY_MSG_244;VC - Forza +HISTORY_MSG_244;VC - intensità HISTORY_MSG_245;VC - Centro HISTORY_MSG_246;Curva 'CL' HISTORY_MSG_247;Curva 'LH' @@ -426,28 +510,1151 @@ HISTORY_MSG_252;CbDL Toni della Pelle HISTORY_MSG_253;CbDL Riduzione Artefatti HISTORY_MSG_254;CbDL - Tonalità Incarnato HISTORY_MSG_255;CbDL - Algoritmo -HISTORY_NEWSNAPSHOT;Aggiungi +HISTORY_MSG_256;NR - Mediana - Tipo +HISTORY_MSG_257;Tono colore +HISTORY_MSG_258;CT - Curva colore +HISTORY_MSG_259;CT - Opacità curva +HISTORY_MSG_260;CT - a*[b*] opacità +HISTORY_MSG_261;CT - Metodo +HISTORY_MSG_262;CT - b* opacità +HISTORY_MSG_263;CT - Ombre - Rosso +HISTORY_MSG_264;CT - Ombre - Verde +HISTORY_MSG_265;CT - Ombre - Blu +HISTORY_MSG_266;CT - Medio - Rosso +HISTORY_MSG_267;CT - Medio - Verde +HISTORY_MSG_268;CT - Medio - Blu +HISTORY_MSG_269;CT - Alto - Rosso +HISTORY_MSG_270;CT - Alto - Verde +HISTORY_MSG_271;CT - Alto - Blu +HISTORY_MSG_272;CT - Bilanciamento +HISTORY_MSG_273;CT - Bilanciamento Colore SMH +HISTORY_MSG_276;CT - Opacità +HISTORY_MSG_277;--inutilizzato-- +HISTORY_MSG_278;CT - Preserva la luminanza +HISTORY_MSG_279;CT - Ombre +HISTORY_MSG_280;CT - Alteluci +HISTORY_MSG_281;CT - Intensità di saturazione +HISTORY_MSG_282;CT - Soglia di saturazione +HISTORY_MSG_283;CT - intensità +HISTORY_MSG_284;CT - Protezione Sat. Auto +HISTORY_MSG_285;NR - Metodo Medio +HISTORY_MSG_286;NR - Tipo Medio +HISTORY_MSG_287;NR - Iterazione Media +HISTORY_MSG_288;Controllo della clip del Flat-Field +HISTORY_MSG_289;Controllo della clip Flat-Field automatico +HISTORY_MSG_290;Livello del Nero - Rosso +HISTORY_MSG_291;Livello del Nero - Verde +HISTORY_MSG_292;Livello del Nero - Blu +HISTORY_MSG_293;Film Simulation +HISTORY_MSG_294;Film Simulation - intensità +HISTORY_MSG_295;Film Simulation - Film +HISTORY_MSG_296;NR - Curva di Luminanza +HISTORY_MSG_297;NR - Modo +HISTORY_MSG_298;Filtro pixel bruciati +HISTORY_MSG_299;NR - Curva di Crominanza +HISTORY_MSG_301;NR - Controllo Luma +HISTORY_MSG_302;NR - Metodo Cromatico +HISTORY_MSG_303;NR - Metodo Cromatico +HISTORY_MSG_304;W - Livello di contrasto +HISTORY_MSG_305;Livello di Wavelet +HISTORY_MSG_306;W - Processo +HISTORY_MSG_307;W - Processo +HISTORY_MSG_308;W - Direzione del Processo +HISTORY_MSG_309;W - ES - Dettaglio +HISTORY_MSG_310;W - Cromia Residua - proteggi le tonalità del cielo +HISTORY_MSG_311;W - Livello di Wavelet +HISTORY_MSG_312;W - Soglia delle ombre residuale +HISTORY_MSG_313;W - Cromia - Saturazione/Pastello +HISTORY_MSG_314;W - Riduzione artefatti di Gamut +HISTORY_MSG_315;W - Contrasto Residuale +HISTORY_MSG_316;W - Gamma - Proteggi le tonalità della pelle +HISTORY_MSG_317;W - Gamma - Tonalità della pelle +HISTORY_MSG_318;W - Livelli più fini di Contrasto +HISTORY_MSG_319;W - Gamma più fine di Contrasto +HISTORY_MSG_320;W - Gamma più grossolana di Contrasto +HISTORY_MSG_321;W - Livelli più grossolani di Contrasto +HISTORY_MSG_322;W - Evita il cambiamento di colore di Gamut +HISTORY_MSG_323;W - ES - Contrasto Locale +HISTORY_MSG_324;W - Pastello cromatico +HISTORY_MSG_325;W - Saturazione cromatica +HISTORY_MSG_326;W - Metodo cromatico +HISTORY_MSG_327;W - Applica a Contrasto +HISTORY_MSG_328;W - Intensità del collegamento cromatico +HISTORY_MSG_329;W - Tonalità - Opacità RG +HISTORY_MSG_330;W - Tonalità - Opacità BY +HISTORY_MSG_331;W - Livello di Contrasto - Extra +HISTORY_MSG_332;W - Metodo di piastrellatura +HISTORY_MSG_333;W - Ombre residue +HISTORY_MSG_334;W - Cromaticità residua +HISTORY_MSG_335;W - Alteluci residue +HISTORY_MSG_336;W - Soglia alteluci residue +HISTORY_MSG_337;W - Tonalità del cielo residue +HISTORY_MSG_338;W - ES - Raggio +HISTORY_MSG_339;W - ES - Intensità +HISTORY_MSG_340;W - Intensità +HISTORY_MSG_341;W - Prestazioni ai bordi +HISTORY_MSG_342;W - ES - Primo Livello +HISTORY_MSG_343;W - Livello di Cromaticità +HISTORY_MSG_344;W - Metodo colore - Cursore Curva +HISTORY_MSG_345;W - ES - Contrasto Locale +HISTORY_MSG_346;W - ES - Metodo per il Contrasto Locale +HISTORY_MSG_347;W - Eliminazione del rumore - Levello 1 +HISTORY_MSG_348;W - Eliminazione del rumore - Levello 2 +HISTORY_MSG_349;W - Eliminazione del rumore - Levello 3 +HISTORY_MSG_350;W - ES - Rilevamento dei bordi +HISTORY_MSG_351;W - Curva HH residuale +HISTORY_MSG_352;W - Background +HISTORY_MSG_353;W - ES - Sensibilità gradiente +HISTORY_MSG_354;W - ES - Migliorata +HISTORY_MSG_355;W - ES - Soglia bassa +HISTORY_MSG_356;W - ES - Soglia alta +HISTORY_MSG_357;W - Eliminazione del rumore - Collegamento con ES +HISTORY_MSG_358;W - Gamut - CH +HISTORY_MSG_359;Soglia di Caldo/Morto +HISTORY_MSG_360;TM - Gamma +HISTORY_MSG_361;W - Bilanciamento cromatico finale +HISTORY_MSG_362;W - Metodo di compressione residuo +HISTORY_MSG_363;W - Intensità di compressione residua +HISTORY_MSG_364;W - Bilanciamento di contrasto finale +HISTORY_MSG_365;W - Bilanciamento variazione finale +HISTORY_MSG_366;W - Compressione di gamma finale +HISTORY_MSG_367;W - 'Dopo' le curve di contrasto +HISTORY_MSG_368;W - Bilanciamento di contrasto finale +HISTORY_MSG_369;W - Metodo di bilanciamento finale +HISTORY_MSG_370;W - Curva di contrasto locale finale +HISTORY_MSG_371;Nitidezza post-ridimensionamento +HISTORY_MSG_372;PRS USM - Raggio +HISTORY_MSG_373;PRS USM - Quantità +HISTORY_MSG_374;PRS USM - Soglia +HISTORY_MSG_375;PRS USM - Affila solo i bordi +HISTORY_MSG_376;PRS USM - Raggio di rilevamento del bordo +HISTORY_MSG_377;PRS USM - Tolleranza del bordo +HISTORY_MSG_378;PRS USM - Controllo dell'alone +HISTORY_MSG_379;PRS USM - Quantità di controllo dell'alone +HISTORY_MSG_380;PRS - Metodo +HISTORY_MSG_381;PRS RLD - Raggio +HISTORY_MSG_382;PRS RLD - Quantità +HISTORY_MSG_383;PRS RLD - Attenuazione +HISTORY_MSG_384;PRS RLD - Iterazioni +HISTORY_MSG_385;W - Bilanciamento del colore residuo +HISTORY_MSG_386;W - CB verde alto residuo +HISTORY_MSG_387;W - CB blu alto residuo +HISTORY_MSG_388;W - CB verde medio residuo +HISTORY_MSG_389;W - CB blu medio residuo +HISTORY_MSG_390;W - CB verde basso residuo +HISTORY_MSG_391;W - CB blu basso residuo +HISTORY_MSG_392;W - Bilanciamento del colore residuo +HISTORY_MSG_393;DCP - Guarda la tabella +HISTORY_MSG_394;DCP - Esposizione di base +HISTORY_MSG_395;DCP - Tabella di base +HISTORY_MSG_396;W - Sotto-strumento di contrasto +HISTORY_MSG_397;W - Sotto-strumento di Cromaticità +HISTORY_MSG_398;W - Sotto-strumento di ES +HISTORY_MSG_399;W - Sotto-strumento residuale +HISTORY_MSG_400;W - Sotto-strumento finale +HISTORY_MSG_401;W - Sotto-strumento di tono +HISTORY_MSG_402;W - Sotto-strumento di eliminazione del rumore +HISTORY_MSG_403;W - ES - Sensibilità dei bordi +HISTORY_MSG_404;W - ES - Amplificazione di base +HISTORY_MSG_405;W - Eliminazione del rumore - Level 4 +HISTORY_MSG_406;W - ES - Pixel vicini +HISTORY_MSG_407;Retinex - Metodo +HISTORY_MSG_408;Retinex - Raggio +HISTORY_MSG_410;Retinex - Compensare +HISTORY_MSG_411;Retinex - Intensità +HISTORY_MSG_412;Retinex - Gradiente Gaussiano +HISTORY_MSG_413;Retinex - Contrasto +HISTORY_MSG_414;Retinex - Istogramma - Lab +HISTORY_MSG_415;Retinex - Trasmissione +HISTORY_MSG_416;Retinex +HISTORY_MSG_417;Retinex - Trasmissione media +HISTORY_MSG_418;Retinex - Soglia +HISTORY_MSG_419;Retinex - Spazio Colore +HISTORY_MSG_420;Retinex - Istogramma - HSL +HISTORY_MSG_421;Retinex - Gamma +HISTORY_MSG_422;Retinex - Gamma +HISTORY_MSG_423;Retinex - Pendenza di Gamma +HISTORY_MSG_424;Retinex - Soglia HL +HISTORY_MSG_425;--inutilizzato-- +HISTORY_MSG_426;Retinex - Equalizzatore di tonalità +HISTORY_MSG_427;Intento di rendering dell'output +HISTORY_MSG_428;Monitorare l'intento di rendering +HISTORY_MSG_429;Retinex - Iterazione +HISTORY_MSG_430;Retinex - Gradiente di trasmissione +HISTORY_MSG_431;Retinex - Gradiente di forza +HISTORY_MSG_432;Retinex - M - Alteluci +HISTORY_MSG_433;Retinex - M - Alteluci TW +HISTORY_MSG_434;Retinex - M - Ombre +HISTORY_MSG_435;Retinex - M - Ombre TW +HISTORY_MSG_436;Retinex - M - Raggio +HISTORY_MSG_437;Retinex - M - Metodo +HISTORY_MSG_438;Retinex - M - Equalizzatore +HISTORY_MSG_439;Retinex - Processo +HISTORY_MSG_440;CbDL - Metodo +HISTORY_MSG_441;Retinex - Guadagno di trasmissione +HISTORY_MSG_442;Retinex - Scala +HISTORY_MSG_443;Compensazione del punto nero in uscita +HISTORY_MSG_444;WB - Pregiudizio della temperatura +HISTORY_MSG_445;Sotto-immagine RAW +HISTORY_MSG_446;--inutilizzato-- +HISTORY_MSG_447;--inutilizzato-- +HISTORY_MSG_448;--inutilizzato-- +HISTORY_MSG_449;Adattamento ISO PS +HISTORY_MSG_450;--inutilizzato-- +HISTORY_MSG_451;--inutilizzato-- +HISTORY_MSG_452;Mostra movimento PS +HISTORY_MSG_453;Mostra solo la maschera PS +HISTORY_MSG_454;--inutilizzato-- +HISTORY_MSG_455;--inutilizzato-- +HISTORY_MSG_456;--inutilizzato-- +HISTORY_MSG_457;Controllo rosso/blu PS +HISTORY_MSG_458;--inutilizzato-- +HISTORY_MSG_459;--inutilizzato-- +HISTORY_MSG_460;--inutilizzato-- +HISTORY_MSG_461;--inutilizzato-- +HISTORY_MSG_462;Controllo verde PS +HISTORY_MSG_463;--inutilizzato-- +HISTORY_MSG_464;Maschera di movimento sfocato PS +HISTORY_MSG_465;Raggio di sfocatura PS +HISTORY_MSG_466;--inutilizzato-- +HISTORY_MSG_467;--inutilizzato-- +HISTORY_MSG_468;Riempi i buchi PS +HISTORY_MSG_469;Mediano PS +HISTORY_MSG_470;--inutilizzato-- +HISTORY_MSG_471;Correzione del movimento PS +HISTORY_MSG_472;Transizioni fluide PS +HISTORY_MSG_474;Equalizza PS +HISTORY_MSG_475;Equalizza il canale PS +HISTORY_MSG_476;CAL - VC - Temperatura +HISTORY_MSG_477;CAL - VC - Tinta +HISTORY_MSG_478;CAL - VC - Luminanza media +HISTORY_MSG_479;CAL - VC - Adattamento +HISTORY_MSG_480;CAL - VC - Auto adattamento +HISTORY_MSG_481;CAL - SC - Temperatura +HISTORY_MSG_482;CAL - SC - Tinta +HISTORY_MSG_483;CAL - SC - Luminanza media +HISTORY_MSG_484;CAL - SC - Auto luminanza media +HISTORY_MSG_485;Correzione delle lenti +HISTORY_MSG_486;Correzione delle lenti - Camera +HISTORY_MSG_487;Correzione delle lenti - Obiettivo +HISTORY_MSG_488;Compressione della gamma dinamica +HISTORY_MSG_489;Dettagli della compressione della gamma dinamica +HISTORY_MSG_490;Quantità della compressione della gamma dinamica +HISTORY_MSG_491;Bilanciamento del bianco +HISTORY_MSG_492;Curve RGB +HISTORY_MSG_493;Aggiustamenti L*a*b* +HISTORY_MSG_494;Acquisisci nitidezza +HISTORY_MSG_496;Spot locale eliminato +HISTORY_MSG_497;Spot locale selezionato +HISTORY_MSG_498;--inutilizzato-- +HISTORY_MSG_499;--inutilizzato-- +HISTORY_MSG_500;Local - Forma dello Spot +HISTORY_MSG_501;Local - Metodo di Spot +HISTORY_MSG_502;Local - SC - Metodo di forma +HISTORY_MSG_503;Local - Spot - Destro +HISTORY_MSG_504;Local - Spot - Sinistro +HISTORY_MSG_505;Local - Spot - Basso +HISTORY_MSG_506;Local - Spot - Alto +HISTORY_MSG_507;Local - Spot - Centro +HISTORY_MSG_508;Local - Spot - Misurare +HISTORY_MSG_509;Local - Metodo di qualità dello Spot +HISTORY_MSG_510;Local - TG - Valore di transizione +HISTORY_MSG_511;Local - SD - ΔE soglia di ambito +HISTORY_MSG_512;Local - SD - ΔE decadimento +HISTORY_MSG_513;Local - Spot - Escluso - Ambito +HISTORY_MSG_514;Local - Struttura dello spot +HISTORY_MSG_515;Aggiustamenti locali +HISTORY_MSG_516;Local - Colore e luce +HISTORY_MSG_517;Local - Abilita super +HISTORY_MSG_518;Local - Luminosità +HISTORY_MSG_519;Local - Contrasto +HISTORY_MSG_520;Local - Crominanza +HISTORY_MSG_521;Local - Scopo +HISTORY_MSG_522;Local - Metodo delle curve +HISTORY_MSG_523;Local - Curve LL +HISTORY_MSG_524;Local - Curve CC +HISTORY_MSG_525;Local - Curve LH +HISTORY_MSG_526;Local - Curve H +HISTORY_MSG_527;Local - Inversione Colore +HISTORY_MSG_528;Local - Esposizione +HISTORY_MSG_529;Local - Compensazione esposizione +HISTORY_MSG_530;Local - Compressione esposizione delle alteluci +HISTORY_MSG_531;Local - Compressione raccolta della esposizione delle alteluci +HISTORY_MSG_532;Local - Esposizione dei Neutri +HISTORY_MSG_533;Local - Compressione dell'Esposizione +HISTORY_MSG_534;Local - Caldo freddo +HISTORY_MSG_535;Local - Scopo dell'esposizione +HISTORY_MSG_536;Local - Esposizione con curve di contrasto +HISTORY_MSG_537;Local - Vibranza +HISTORY_MSG_538;Local - Vibranza saturata +HISTORY_MSG_539;Local - Vibranza delicata +HISTORY_MSG_540;Local - Soglia di vibranza +HISTORY_MSG_541;Local - Vibranza con protezzione dei toni della pelle +HISTORY_MSG_542;Local - Vibranza evitando cambiamenti colore +HISTORY_MSG_543;Local - Vibranza collegamento +HISTORY_MSG_544;Local - Ambito di vibranza +HISTORY_MSG_545;Local - Vibranza su curve H +HISTORY_MSG_546;Local - Sfocatura e rumore +HISTORY_MSG_547;Local - Raggio +HISTORY_MSG_548;Local - Rumore +HISTORY_MSG_549;Local - Ambito di sfocatura +HISTORY_MSG_550;Local - Metodo di sfocatura +HISTORY_MSG_551;Local - Solo sfocatura di luminanza +HISTORY_MSG_552;Local - Mappatura dei toni +HISTORY_MSG_553;Local - Intensità di compressione della mappatura dei toni +HISTORY_MSG_554;Local - Gamma della mappatura dei toni +HISTORY_MSG_555;Local - Arresto al bordo della mappatura dei toni +HISTORY_MSG_556;Local - Scala della mappatura dei toni +HISTORY_MSG_557;Local - Riponderazione della mappatura dei toni +HISTORY_MSG_558;Local - Ambito della mappatura dei toni +HISTORY_MSG_559;Local - Retinex +HISTORY_MSG_560;Local - Metodo Retinex +HISTORY_MSG_561;Local - Intensità del Retinex +HISTORY_MSG_562;Local - Cromia del Retinex +HISTORY_MSG_563;Local - Raggio del Retinex +HISTORY_MSG_564;Local - Contrasto del Retinex +HISTORY_MSG_565;Local - Ambito +HISTORY_MSG_566;Local - Curva di guadagno del Retinex +HISTORY_MSG_567;Local - Inverso del Retinex +HISTORY_MSG_568;Local - Nitidezza +HISTORY_MSG_569;Local - Raggio di nitidezza +HISTORY_MSG_570;Local - Quantità di nitidezza +HISTORY_MSG_571;Local - Attenuazione della nitidezza +HISTORY_MSG_572;Local - Iterazione della nitidezza +HISTORY_MSG_573;Local - Ambito della nitidezza +HISTORY_MSG_574;Local - Inverso della nitidezza +HISTORY_MSG_575;Local - CBDL +HISTORY_MSG_576;Local - cbdl multiplo +HISTORY_MSG_577;Local - cbdl cromia +HISTORY_MSG_578;Local - cbdl soglia +HISTORY_MSG_579;Local - cbdl ambito +HISTORY_MSG_580;--inutilizzato-- +HISTORY_MSG_581;Local - Eliminazione del rumore mediante luminanza f1 +HISTORY_MSG_582;Local - Eliminazione del rumore mediante luminanza c +HISTORY_MSG_583;Local - Eliminazione del rumore mediante dettagli di luminanza +HISTORY_MSG_584;Local - Eliminazione del rumore mediante equalizzatore Bianco-Nero +HISTORY_MSG_585;Local - Eliminazione del rumore mediante cromia f +HISTORY_MSG_586;Local - Eliminazione del rumore mediante cromia c +HISTORY_MSG_587;Local - Eliminazione del rumore mediante dettagli di cromia +HISTORY_MSG_588;Local - Eliminazione del mediante equalizzatore Blu-Rosso +HISTORY_MSG_589;Local - Eliminazione del rumore bilaterale +HISTORY_MSG_590;Local - Ambito di eliminazione del rumore +HISTORY_MSG_591;Local - Evita il cambiamento di colore +HISTORY_MSG_592;Local - Contrasto di nitidezza +HISTORY_MSG_593;Local - Contrasto locale +HISTORY_MSG_594;Local - Raggio del contrasto locale +HISTORY_MSG_595;Local - Quantità del contrasto locale +HISTORY_MSG_596;Local - Durezza del contrasto locale +HISTORY_MSG_597;Local - Luminosità del contrasto locale +HISTORY_MSG_598;Local - Ambito del contrasto locale +HISTORY_MSG_599;Local - Defoschia Retinex +HISTORY_MSG_600;Local - Abilitazione luce soffusa +HISTORY_MSG_601;Local - Intensità luce soffusa +HISTORY_MSG_602;Local - Ambito luce soffusa +HISTORY_MSG_603;Local - Raggio di sfocaura della nitidezza +HISTORY_MSG_605;Local - Scelta dell'anteprima della maschera +HISTORY_MSG_606;Local Selezione Spot +HISTORY_MSG_607;Local - Maschera di colore C +HISTORY_MSG_608;Local - Maschera di colore L +HISTORY_MSG_609;Local - Maschera di esposizione C +HISTORY_MSG_610;Local - Maschera di esposizione L +HISTORY_MSG_611;Local - Maschera di colore H +HISTORY_MSG_612;Local - Struttura colore +HISTORY_MSG_613;Local - Struttura esposizione +HISTORY_MSG_614;Local - Maschera di esposizione H +HISTORY_MSG_615;Local - Miscela il colore +HISTORY_MSG_616;Local - Miscela l'esposizione +HISTORY_MSG_617;Local - Sfoca l'esposizione +HISTORY_MSG_618;Local - Usa la maschera di colore +HISTORY_MSG_619;Local - Usa la maschera di esposizione +HISTORY_MSG_620;Local - Sfocatura colore +HISTORY_MSG_621;Local - Esposizione inversa +HISTORY_MSG_622;Local - Spot - Escluso - Struttura Spot +HISTORY_MSG_623;Local - Compensazione della cromia di esposizione +HISTORY_MSG_624;Local - Griglia di correzione colore +HISTORY_MSG_625;Local - Intensità di correzione colore +HISTORY_MSG_626;Local - Metodo di correzione colore +HISTORY_MSG_627;Local - Ombre e Alteluci +HISTORY_MSG_628;Local - SH Alteluci +HISTORY_MSG_629;Local - SH Larghezza tonale alteluci +HISTORY_MSG_630;Local - SH Ombre +HISTORY_MSG_631;Local - SH Larghezza tonale Ombre +HISTORY_MSG_632;Local - SH Raggio +HISTORY_MSG_633;Local - SH Ambito +HISTORY_MSG_634;Local - Raggio colore +HISTORY_MSG_635;Local - Raggio esposizione +HISTORY_MSG_636;Local - Strumento aggiunto +HISTORY_MSG_637;Local - SH Maschera C +HISTORY_MSG_638;Local - SH Maschera L +HISTORY_MSG_639;Local - SH Maschera H +HISTORY_MSG_640;Local - SH Miscela +HISTORY_MSG_641;Local - Usa maschera alteluci +HISTORY_MSG_642;Local - Raggio alteluci +HISTORY_MSG_643;Local - Sfocatura alteluci +HISTORY_MSG_644;Local - Inverti alteluci +HISTORY_MSG_645;Local - SD - ab-L bilanciamento +HISTORY_MSG_646;Local - Maschera di cromia dell'esposizione +HISTORY_MSG_647;Local - Maschera di gamma dell'esposizione +HISTORY_MSG_648;Local - Maschera di pendenza dell'esposizione +HISTORY_MSG_649;Local - Raggio morbido dell'esposizione +HISTORY_MSG_650;Local - Maschera di cromia colore +HISTORY_MSG_651;Local - Maschera di gamma colore +HISTORY_MSG_652;Local - Maschera di pendenza colore +HISTORY_MSG_653;Local - Maschera di cromia alteluci +HISTORY_MSG_654;Local - Maschera di gamma alteluci +HISTORY_MSG_655;Local - Maschera di pendenza alteluci +HISTORY_MSG_656;Local - Raggio morbido colore +HISTORY_MSG_657;Local - Riduzione artefatti Retinex +HISTORY_MSG_658;Local - Raggio morbido CBDL +HISTORY_MSG_659;Local - TG - Decadimento transizione +HISTORY_MSG_660;Local - cbdl chiarezza +HISTORY_MSG_661;Local - cbdl contrasto residuale +HISTORY_MSG_662;Local - Eliminazione del rumore mediante luminanza f0 +HISTORY_MSG_663;Local - Eliminazione del rumore mediante luminanza f2 +HISTORY_MSG_664;--inutilizzato-- +HISTORY_MSG_665;Local - cbdl maschera miscelazione +HISTORY_MSG_666;Local - cbdl maschera raggio +HISTORY_MSG_667;Local - cbdl maschera cromia +HISTORY_MSG_668;Local - cbdl maschera gamma +HISTORY_MSG_669;Local - cbdl maschera pendenza +HISTORY_MSG_670;Local - cbdl maschera C +HISTORY_MSG_671;Local - cbdl maschera L +HISTORY_MSG_672;Local - cbdl maschera CL +HISTORY_MSG_673;Local - Usa maschera cbdl +HISTORY_MSG_674;Local - Strumenti di rimozione +HISTORY_MSG_675;Local - Raggio morbido di strumenti di rimozione +HISTORY_MSG_676;Local - TG - Differenziazione della transizione +HISTORY_MSG_677;Local - Ambito di strumenti di rimozione +HISTORY_MSG_678;Local - Saturazione con strumenti di rimozione +HISTORY_MSG_679;Local - Retinex maschera C +HISTORY_MSG_680;Local - Retinex maschera L +HISTORY_MSG_681;Local - Retinex maschera CL +HISTORY_MSG_682;Local - Retinex maschera +HISTORY_MSG_683;Local - Retinex maschera miscela +HISTORY_MSG_684;Local - Retinex maschera raggio +HISTORY_MSG_685;Local - Retinex maschera cromia +HISTORY_MSG_686;Local - Retinex maschera gamma +HISTORY_MSG_687;Local - Retinex maschera pendenza +HISTORY_MSG_688;Local - Strumenti di rimozione +HISTORY_MSG_689;Local - Retinex maschera della mappa di transmissione +HISTORY_MSG_690;Local - Retinex scala +HISTORY_MSG_691;Local - Retinex durezza +HISTORY_MSG_692;Local - Retinex luminosità +HISTORY_MSG_693;Local - Retinex intensità +HISTORY_MSG_694;Local - Retinex soglia Laplacian +HISTORY_MSG_695;Local - Metodo morbio +HISTORY_MSG_696;Local - Retinex Normalizza +HISTORY_MSG_697;Local - TM Normalizza +HISTORY_MSG_698;Local - Contrasto locale velocità di Fourier +HISTORY_MSG_699;Local - Retinex velocità di Fourier +HISTORY_MSG_701;Local - Esposizione Ombre +HISTORY_MSG_702;Local - Esposizione metodo +HISTORY_MSG_703;Local - Esposizione soglia Laplacian +HISTORY_MSG_704;Local - Bilanciamento esposizione PDE +HISTORY_MSG_705;Local - Linearità esposizione +HISTORY_MSG_706;Local - TM maschera C +HISTORY_MSG_707;Local - TM maschera L +HISTORY_MSG_708;Local - TM maschera CL +HISTORY_MSG_709;Local - Usa maschera di TM +HISTORY_MSG_710;Local - TM maschera miscela +HISTORY_MSG_711;Local - TM maschera raggio +HISTORY_MSG_712;Local - TM maschera cromia +HISTORY_MSG_713;Local - TM maschera gamma +HISTORY_MSG_714;Local - TM maschera pendenza +HISTORY_MSG_716;Local - Metodo locale +HISTORY_MSG_717;Local - Contrasto locale +HISTORY_MSG_718;Local - Livelli di contrasto locale +HISTORY_MSG_719;Local - Contrasto locale residuo L +HISTORY_MSG_720;Local - Maschera di sfocatura C +HISTORY_MSG_721;Local - Maschera di sfocatura L +HISTORY_MSG_722;Local - Maschera di sfocatura CL +HISTORY_MSG_723;Local - Usa la maschera di sfocatura +HISTORY_MSG_725;Local - Miscela la maschera di sfocatura +HISTORY_MSG_726;Local - Raggio della maschera di sfocatura +HISTORY_MSG_727;Local - Cromia della maschera di sfocatura +HISTORY_MSG_728;Local - Gamma della maschera di sfocatura +HISTORY_MSG_729;Local - Pendenza della maschera di sfocatura +HISTORY_MSG_730;Local - Metodo di sfocatura +HISTORY_MSG_731;Local - Metodo mediano +HISTORY_MSG_732;Local - Iterazioni mediane +HISTORY_MSG_733;Local - Raggio morbido +HISTORY_MSG_734;Local - Dettaglio +HISTORY_MSG_738;Local - Contrasto locale Unisci L +HISTORY_MSG_739;Local - Contrasto locale Raggio morbido +HISTORY_MSG_740;Local - Contrasto locale Unisci C +HISTORY_MSG_741;Local - Residuo di contrasto locale C +HISTORY_MSG_742;Local - Esposizione della gamma Laplacian +HISTORY_MSG_743;Local - Esposizione quantità fattale +HISTORY_MSG_744;Local - Esposizione dettaglio fattale +HISTORY_MSG_745;Local - Compensazione fattale dell'esposizione +HISTORY_MSG_746;Local - Sigma fattale dell'esposizione +HISTORY_MSG_747;Local Spot creato +HISTORY_MSG_748;Local - Esposizione di riduzione rumore +HISTORY_MSG_749;Local - Profondità Reti +HISTORY_MSG_750;Local - Modalità reti log - lin +HISTORY_MSG_751;Local - Defoschia della saturazione Reti +HISTORY_MSG_752;Local - Compensazione reti +HISTORY_MSG_753;Local - Mappa trasmissione reti +HISTORY_MSG_754;Local - Reti Clip +HISTORY_MSG_755;Local - Usa la maschera di TM +HISTORY_MSG_756;Local - Usa algoritmo della maschera di esposizione +HISTORY_MSG_757;Local - Maschera di esposizione Laplacian +HISTORY_MSG_758;Local - Maschera di reti Laplacian +HISTORY_MSG_759;Local - Maschera di esposizione Laplacian +HISTORY_MSG_760;Local - Maschera colore Laplacian +HISTORY_MSG_761;Local - Maschera Ombre Alteluci Laplacian +HISTORY_MSG_762;Local - Maschera cbdl Laplacian +HISTORY_MSG_763;Local - Maschera di sfocatura Laplacian +HISTORY_MSG_764;Local - Risolve la maschera PDE Laplacian +HISTORY_MSG_765;Local - Soglia dettaglio riduzione rumore +HISTORY_MSG_766;Local - Sfocatura veloce Fourier +HISTORY_MSG_767;Local - Grana ISO +HISTORY_MSG_768;Local - Intensità della grana +HISTORY_MSG_769;Local - Scala della grana +HISTORY_MSG_770;Local - Curva di contrasto della maschera colore +HISTORY_MSG_771;Local - Curva di contrasto della maschera dell'esposizione +HISTORY_MSG_772;Local - Curva di contrasto della maschera Ombre/Alteluci +HISTORY_MSG_773;Local - Curva di contrasto della maschera TM +HISTORY_MSG_774;Local - Curva di contrasto della maschera Reti +HISTORY_MSG_775;Local - Curva di contrasto della maschera CBDL +HISTORY_MSG_776;Local - Curva di contrasto della maschera riduzione del rumore della sfocatura +HISTORY_MSG_777;Local - Curva di contrasto della maschera sfocatura +HISTORY_MSG_778;Local - Maschera alteluci +HISTORY_MSG_779;Local - Curva di contrasto della maschera colore +HISTORY_MSG_780;Local - Ombre della maschera di colore +HISTORY_MSG_781;Local - Livello Wavelet della maschera di contrasto +HISTORY_MSG_782;Local - Livelli wavelet della maschera di riduzione del rumore della sfocatura +HISTORY_MSG_783;Local - Livelli Wavelet di colore +HISTORY_MSG_784;Local - Maschera - ΔE maschera immagine +HISTORY_MSG_785;Local - Maschera - Ambito +HISTORY_MSG_786;Local - Metodo Ombre/Alteluci +HISTORY_MSG_787;Local - Moltiplicatore dell'equalizzatore +HISTORY_MSG_788;Local - Moltiplicatore di dettaglio +HISTORY_MSG_789;Local - Maschera di quantitè ombre/alteluci +HISTORY_MSG_790;Local - ancoraggio della maschera ombre/alteluci +HISTORY_MSG_791;Local - Maschera corta di curva L +HISTORY_MSG_792;Local - Maschera - Sfondo +HISTORY_MSG_793;Local - Gamma ombre/alteluci TRC +HISTORY_MSG_794;Local - Pendenza ombre/alteluci TRC +HISTORY_MSG_795;Local - Maschera salva ripristina immagine +HISTORY_MSG_796;Local - SC - Riferimenti ricorsivi +HISTORY_MSG_797;Local - Metodo Unisci originale +HISTORY_MSG_798;Local - Opacità +HISTORY_MSG_799;Local - Curva di tono colore RGB +HISTORY_MSG_800;Local - Metodo curva di tono colore +HISTORY_MSG_801;Local - Speciale curva toni colore +HISTORY_MSG_802;Local - Soglia di contrasto +HISTORY_MSG_803;Local - Fusione colori +HISTORY_MSG_804;Local - Struttura maschera colore +HISTORY_MSG_805;Local - Struttura maschera riduzione di rumore della sfocatura +HISTORY_MSG_806;Local - Struttura maschera colore come strumento +HISTORY_MSG_807;Local - Struttura maschera colore come strumento di sfocatura +HISTORY_MSG_808;Local - Curva H(H) della maschera di colore +HISTORY_MSG_809;Local - Curva C(C) della maschera di vibranza +HISTORY_MSG_810;Local - Curva L(L) della maschera di vibranza +HISTORY_MSG_811;Local - Curva LC(H) della maschera di vibranza +HISTORY_MSG_813;Local - Usa la maschera di vibranza +HISTORY_MSG_814;Local - Miscela la maschera di vibranza +HISTORY_MSG_815;Local - Raggio della maschera di vibranza +HISTORY_MSG_816;Local - Cromia della maschera di vibranza +HISTORY_MSG_817;Local - Gamma della maschera di vibranza +HISTORY_MSG_818;Local - Pendenza della maschera di vibranza +HISTORY_MSG_819;Local - Laplacian della maschera di vibranza +HISTORY_MSG_820;Local - Curva di contrasto della maschera di vibranza +HISTORY_MSG_821;Local - sfondo della griglia di colore +HISTORY_MSG_822;Local - unione dello sfondo a colori +HISTORY_MSG_823;Local - luminanza dello sfondo colorato +HISTORY_MSG_824;Local - Intensità della maschera del gradiente dell'esposizione +HISTORY_MSG_825;Local - Angolo della maschera del gradiente di esposizione +HISTORY_MSG_826;Local - Intensità del gradiente dell'esposizione +HISTORY_MSG_827;Local - Angolo di gradiente dell'esposizione +HISTORY_MSG_828;Local - Intensità di gradiente delle ombre/alteluci +HISTORY_MSG_829;Local - Angolo di gradiente delle ombre/alteluci +HISTORY_MSG_830;Local - Intensità del gradiente di colore L +HISTORY_MSG_831;Local - Angolo del gradiente di colore +HISTORY_MSG_832;Local - Intensità del gradiente di coloreh C +HISTORY_MSG_833;Local - TG - Gradiente di piume +HISTORY_MSG_834;Local - Intensità del gradiente di colore H +HISTORY_MSG_835;Local - Intensità del gradiente di vibranza L +HISTORY_MSG_836;Local - Angolo del gradiente di vibranza +HISTORY_MSG_837;Local - Intensità del gradiente di vibranza C +HISTORY_MSG_838;Local - Intensità del gradiente di vibranzah H +HISTORY_MSG_839;Local - Complessità del software +HISTORY_MSG_840;Local - Curva CL +HISTORY_MSG_841;Local - Curva LC +HISTORY_MSG_842;Local - Raggio della maschera di sfocatura +HISTORY_MSG_843;Local - Soglia di contrasto della maschera di sfocatura +HISTORY_MSG_844;Local - Maschera di sfocatura FFTW +HISTORY_MSG_845;Local - Log codifica +HISTORY_MSG_846;Local - Log codifica automatica +HISTORY_MSG_847;Local - Log codifica origine +HISTORY_MSG_849;Local - Log codifica origine automatica +HISTORY_MSG_850;Local - Log codifica B_Ev +HISTORY_MSG_851;Local - Log codifica W_Ev +HISTORY_MSG_852;Local - Log codifica bersaglio +HISTORY_MSG_853;Local - Log codifica contrasto locale +HISTORY_MSG_854;Local - Log ambito di codifica +HISTORY_MSG_855;Local - Log codifica immagine intera +HISTORY_MSG_856;Local - Log codifica gamma di ombre +HISTORY_MSG_857;Local - Residuo di sfocatura Wavelet +HISTORY_MSG_858;Local - Solo luminanza con sfocatura wavelet +HISTORY_MSG_859;Local - Sfocatura massima wavelet +HISTORY_MSG_860;Local - Livelli di sfocatura wavelet +HISTORY_MSG_861;Local - Livelli di contrasto wavelet +HISTORY_MSG_862;Local - Attenuazione del contrasto wavelet +HISTORY_MSG_863;Local - Wavelet unisce l'immagine originale +HISTORY_MSG_864;Local - Attenuazione del contrasto wavelet +HISTORY_MSG_865;Local - Wavelet di contrasto delta +HISTORY_MSG_866;Local - Compressione delle wavelet +HISTORY_MSG_868;Local - SD - C-H bilanciamento +HISTORY_MSG_869;Local - Riduzione rumore per livello +HISTORY_MSG_870;Local - Curva H della maschera wavelet +HISTORY_MSG_871;Local - Curva C della maschera wavelet +HISTORY_MSG_872;Local - Curva L della maschera wavelet +HISTORY_MSG_873;Local - Maschera wavelet +HISTORY_MSG_875;Local - Miscela di maschere Wavelet +HISTORY_MSG_876;Local - Maschera Wavelet liscia +HISTORY_MSG_877;Local - Crominanza della maschera Wavelet +HISTORY_MSG_878;Local - Curva di contrasto della maschera wavelet +HISTORY_MSG_879;Local - Crominanza a contrasto wavelet +HISTORY_MSG_880;Local - Crominanza di sfocatura wavelet +HISTORY_MSG_881;Local - Offset del contrasto wavelet +HISTORY_MSG_882;Local - Sfocatura wavelet +HISTORY_MSG_883;Local - Contrasto wavelet per livello +HISTORY_MSG_884;Local - Wavelet di contrasto +HISTORY_MSG_885;Local - Mappatura dei toni wavelet +HISTORY_MSG_886;Local - Compressione della mappatura dei toni wavelet +HISTORY_MSG_887;Local - Residuo di compressione della mappatura dei toni wavelet +HISTORY_MSG_888;Local - Soglia di bilanciamento di contrasto wavelet +HISTORY_MSG_889;Local - Intensità graduata dell'onda di contrasto +HISTORY_MSG_890;Local - Contrasto Wavelet Angolo graduato +HISTORY_MSG_891;Local - Contrasto Wavelet graduato +HISTORY_MSG_892;Local - Codifica log della intensità graduata +HISTORY_MSG_893;Local - Codifica log Angolo graduato +HISTORY_MSG_894;Local - SD - ΔE visualizzare in anteprima l'intensità del colore +HISTORY_MSG_897;Local - Intensità del contrasto Wavelet ES +HISTORY_MSG_898;Local - Contrasto raggio Wavelet ES +HISTORY_MSG_899;Local - Dettaglio Wavelet ES a contrasto +HISTORY_MSG_900;Local - Contrasto gradiente Wavelet ES +HISTORY_MSG_901;Local - Soglia di contrasto Wavelet ES bassa +HISTORY_MSG_902;Local - Soglia di contrasto Wavelet ES alta +HISTORY_MSG_903;Local - Contrasto locale Wavelet ES +HISTORY_MSG_904;Local - Contrasto Wavelet ES primo livello +HISTORY_MSG_905;Local - Contrasto Nitidezza bordo Wavelet +HISTORY_MSG_906;Local - Sensibilità del contrasto Wavelet ES +HISTORY_MSG_907;Local - Amplificazione Wavelet ES a contrasto +HISTORY_MSG_908;Local - Contrasto Wavelet ES adiacente +HISTORY_MSG_909;Local - Visualizzazione Wavelet ES di contrasto +HISTORY_MSG_910;Local - SC - Prestazioni di Wavelet ai bordi +HISTORY_MSG_911;Local - Sfocatura Crominanza Luminanza +HISTORY_MSG_912;Local - Intensità del filtro guida sfocatura +HISTORY_MSG_913;Local - Contrasto Wavelet Sigma DR +HISTORY_MSG_914;Local - Sfocatura Wavelet Sigma BL +HISTORY_MSG_915;Local - Bordi Wavelet Sigma ED +HISTORY_MSG_916;Local - Ombre wavelet residue +HISTORY_MSG_917;Local - Soglia delle ombre wavelet residue +HISTORY_MSG_918;Local - Alteluci wavelet residue +HISTORY_MSG_919;Local - Soglia delle alteluci wavelet residue +HISTORY_MSG_920;Local - Wavelet sigma LC +HISTORY_MSG_921;Local - Wavelet graduato sigma LC2 +HISTORY_MSG_922;Local - SC - Cambia in B/W +HISTORY_MSG_923;Local - Modalità di complessità dello strumento +HISTORY_MSG_924;--inutilizzato-- +HISTORY_MSG_925;Local - Ambito (strumenti colore) +HISTORY_MSG_926;Local - Mostra il tipo di maschera +HISTORY_MSG_927;Local - Ombre +HISTORY_MSG_928;Local - Maschera di colore comune +HISTORY_MSG_929;Local - Maschera l'ambito comune +HISTORY_MSG_930;Local - Maschera di fusione luminanza comune +HISTORY_MSG_931;Local - Abilitazione maschera comune +HISTORY_MSG_932;Local - Raggio morbido di maschera comune +HISTORY_MSG_933;Local - Maschera comune di laplacian +HISTORY_MSG_934;Local - Maschera comune di crominanza +HISTORY_MSG_935;Local - Maschera comune di gamma +HISTORY_MSG_936;Local - Maschera comune di pendenza +HISTORY_MSG_937;Local - Maschera comune di curva C(C) +HISTORY_MSG_938;Local - Maschera comune di curva L(L) +HISTORY_MSG_939;Local - Maschera comune di curva LC(H) +HISTORY_MSG_940;Local - Maschera comune della struttura dello strumento +HISTORY_MSG_941;Local - Maschera Resistenza strutturale comune +HISTORY_MSG_942;Local - Maschera comune di curva H(H) +HISTORY_MSG_943;Local - Maschera comune FFT +HISTORY_MSG_944;Local - Raggio di sfocatura maschera comune +HISTORY_MSG_945;Local - Soglia di contrasto maschera comune +HISTORY_MSG_946;Local - Maschera comune di ombre +HISTORY_MSG_947;Local - Curva di contrasto maschera comune +HISTORY_MSG_948;Local - Maschera curva Wavelet comune +HISTORY_MSG_949;Local - Maschera i livelli di soglia comuni +HISTORY_MSG_950;Local - Maschera comune di intensità GF +HISTORY_MSG_951;Local - Maschera comune di angolo GF +HISTORY_MSG_952;Local - Raggio morbido di maschera comune +HISTORY_MSG_953;Local - Maschera crominanza di fusione comune +HISTORY_MSG_954;Local - Strumenti mostra-nascondi +HISTORY_MSG_955;Local - Abilita Spot +HISTORY_MSG_956;Local - Curva CH +HISTORY_MSG_957;Local - Modo di riduzione rumore +HISTORY_MSG_958;Local - Mostra/nascondi le impostazioni +HISTORY_MSG_959;Local - Sfocatura inversa +HISTORY_MSG_960;Local - Log codifica - cat16 +HISTORY_MSG_961;Local - Log codifica Ciecam +HISTORY_MSG_962;Local - Log codifica sorgente di luminanza assoluta +HISTORY_MSG_963;Local - Log codifica bersaglio di luminanza assoluta +HISTORY_MSG_964;Local - Log codifica contorni +HISTORY_MSG_965;Local - Log codifica saturazione s +HISTORY_MSG_966;Local - Log codifica contrasto J +HISTORY_MSG_967;Local - Log codifica maschera di curva C +HISTORY_MSG_968;Local - Log codifica maschera di curva L +HISTORY_MSG_969;Local - Log codifica maschera di curva H +HISTORY_MSG_970;Local - Log codifica abilita maschera +HISTORY_MSG_971;Local - Log codifica miscela maschera +HISTORY_MSG_972;Local - Log codifica raggio maschera +HISTORY_MSG_973;Local - Log codifica maschera di crominanza +HISTORY_MSG_974;Local - Log codifica maschera di contrasto +HISTORY_MSG_975;Local - Log codifica luminosità J +HISTORY_MSG_977;Local - Log codifica contrasto Q +HISTORY_MSG_978;Local - Log codifica sorgente +HISTORY_MSG_979;Local - Log codifica luminosità Q +HISTORY_MSG_980;Local - Log codifica Colorazione M +HISTORY_MSG_981;Local - Log codifica intensità +HISTORY_MSG_982;Local - Tonalità dell'equalizzatore +HISTORY_MSG_983;Local - maschera con soglia di riduzione del rumore alta +HISTORY_MSG_984;Local - maschera con soglia di riduzione del rumore bassa +HISTORY_MSG_985;Local - riduzione del rumore Laplacian +HISTORY_MSG_986;Local - rinforzo riduzione del rumore +HISTORY_MSG_987;Local - GF soglia di recupero +HISTORY_MSG_988;Local - GF maschera soglia bassa +HISTORY_MSG_989;Local - GF maschera soglia alta +HISTORY_MSG_990;Local - Soglia di ripristino del rumore +HISTORY_MSG_991;Local - Maschera soglia rumore bassa +HISTORY_MSG_992;Local - Maschera soglia rumore alta +HISTORY_MSG_993;Local - Algoritmo inverso riduzione rumore +HISTORY_MSG_994;Local - GF algoritmo inverso +HISTORY_MSG_995;Local - Decadimento del rumore +HISTORY_MSG_996;Local - Soglia di recupero colore +HISTORY_MSG_997;Local - Maschera soglia colore bassa +HISTORY_MSG_998;Local - Maschera soglia colore alta +HISTORY_MSG_999;Local - Decadimento colore +HISTORY_MSG_1000;Local - Riduzione rumore del grigio di luminanza +HISTORY_MSG_1001;Local - Soglia di recupero logaritmico +HISTORY_MSG_1002;Local - Maschera soglia registro bassa +HISTORY_MSG_1003;Local - Maschera soglia registro alta +HISTORY_MSG_1004;Local - Decadimento logaritmico +HISTORY_MSG_1005;Local - Soglia di recupero esposizione +HISTORY_MSG_1006;Local - Maschera soglia esposizione bassa +HISTORY_MSG_1007;Local - Maschera soglia esposizione alta +HISTORY_MSG_1008;Local - Decadimento esposizione +HISTORY_MSG_1009;Local - Soglia di recupero ombre/alteluci +HISTORY_MSG_1010;Local - Maschera soglia ombre/alteluci bassa +HISTORY_MSG_1011;Local - Maschera soglia ombre/alteluci alta +HISTORY_MSG_1012;Local - Decadimento ombre/alteluci +HISTORY_MSG_1013;Local - Soglia di recupero vibranza +HISTORY_MSG_1014;Local - Maschera soglia vibranza bassa +HISTORY_MSG_1015;Local - Maschera soglia vibranza alta +HISTORY_MSG_1016;Local - Decadimento vibranza +HISTORY_MSG_1017;Local - Soglia di recupero lc +HISTORY_MSG_1018;Local - Maschera soglia lc bassa +HISTORY_MSG_1019;Local - Maschera soglia lc alta +HISTORY_MSG_1020;Local - Decadimento lc +HISTORY_MSG_1021;Local - Riduzione rumore del grigio di crominanza +HISTORY_MSG_1022;Local - Soglia di recupero TM +HISTORY_MSG_1023;Local - Maschera soglia TM bassa +HISTORY_MSG_1024;Local - Maschera soglia TM alta +HISTORY_MSG_1025;Local - Decadimento TM +HISTORY_MSG_1026;Local - Soglia di recupero cbdl +HISTORY_MSG_1027;Local - Maschera soglia cbdl bassa +HISTORY_MSG_1028;Local - Maschera soglia cbdl alta +HISTORY_MSG_1029;Local - Decadimento cbdl +HISTORY_MSG_1030;Local - Soglia di recupero reti +HISTORY_MSG_1031;Local - Maschera soglia reti bassa +HISTORY_MSG_1032;Local - Maschera soglia reti alta +HISTORY_MSG_1033;Local - Decadimento reti +HISTORY_MSG_1034;Local - Nlmeans - intensità +HISTORY_MSG_1035;Local - Nlmeans - dettaglio +HISTORY_MSG_1036;Local - Nlmeans - percorso +HISTORY_MSG_1037;Local - Nlmeans - raggio +HISTORY_MSG_1038;Local - Nlmeans - gamma +HISTORY_MSG_1039;Local - Grana - gamma +HISTORY_MSG_1040;Local - SC - Raggio morbido +HISTORY_MSG_1041;Local - Spot - Munsell +HISTORY_MSG_1042;Local - Decodifica logaritmica - soglia +HISTORY_MSG_1043;Local - Esposizione - normalizza +HISTORY_MSG_1044;Local - Intensità di contrasto locale +HISTORY_MSG_1045;Local - Intensità colore e luci +HISTORY_MSG_1046;Local - Intensità riduzione rumore +HISTORY_MSG_1047;Local - Intensità Ombre/Alteluci e equalizzatore toni +HISTORY_MSG_1048;Local - Intensità DR e esposizione +HISTORY_MSG_1049;Local - Intensità TM +HISTORY_MSG_1050;Local - Decodifica logaritmica crominanza +HISTORY_MSG_1051;Local - Gamma residuale wavelet +HISTORY_MSG_1052;Local - Pendenza residuale wavelet +HISTORY_MSG_1053;Local - Gamma riduzione rumore +HISTORY_MSG_1054;Local - Gamma Wavelet +HISTORY_MSG_1055;Local - Gamma colore e luci +HISTORY_MSG_1056;Local - Gamma DR e esposizione +HISTORY_MSG_1057;Local - Abilita CIECAM +HISTORY_MSG_1058;Local - Forza complessiva CIECAM +HISTORY_MSG_1059;Local - Grigio automatico CIECAM +HISTORY_MSG_1060;Local - Sorgente di luminanza media CIECAM +HISTORY_MSG_1061;Local - Fonte assoluta CIECAM +HISTORY_MSG_1062;Local - Sorgente circostante CIECAM +HISTORY_MSG_1063;Local - Saturazione CIECAM +HISTORY_MSG_1064;Local - Crominanza CIECAM +HISTORY_MSG_1065;Local - Luminosità J CIECAM +HISTORY_MSG_1066;Local - Luminosità CIECAM +HISTORY_MSG_1067;Local - Contrasto J CIECAM +HISTORY_MSG_1068;Local - Soglia CIECAM +HISTORY_MSG_1069;Local - Contrasto Q CIECAM +HISTORY_MSG_1070;Local - Colorazione CIECAM +HISTORY_MSG_1071;Local - Luminanza assoluta CIECAM +HISTORY_MSG_1072;Local - Luminanza media CIECAM +HISTORY_MSG_1073;Local - Cat16 CIECAM +HISTORY_MSG_1074;Local - Contrasto locale CIECAM +HISTORY_MSG_1075;Local - Visualizzazione circostante CIECAM +HISTORY_MSG_1076;Local - Ambito CIECAM +HISTORY_MSG_1077;Local - Modo CIECAM +HISTORY_MSG_1078;Local - Protezione del rosso e della pelle +HISTORY_MSG_1079;Local - Forza del sigmoide J CIECAM +HISTORY_MSG_1080;Local - Soglia del sigmoide CIECAM +HISTORY_MSG_1081;Local - Miscela sigmoidea CIECAM +HISTORY_MSG_1082;Local - Sigmoide Q di compensazione esposizione dei neri e compensazione esposizione dei bianchi CIECAM +HISTORY_MSG_1083;Local - Tonalità CIECAM +HISTORY_MSG_1084;Local - Usa la compensazione esposizione dei neri e la compensazione esposizione dei bianchi +HISTORY_MSG_1085;Local - Luminosità Jz +HISTORY_MSG_1086;Local - Contrasto Jz +HISTORY_MSG_1087;Local - Crominanza Jz +HISTORY_MSG_1088;Local - Tonalità Jz +HISTORY_MSG_1089;Local - Forza del sigmoide Jz +HISTORY_MSG_1090;Local - Soglia del sigmoide Jz +HISTORY_MSG_1091;Local - Miscela sigmoidea Jz +HISTORY_MSG_1092;Local - Adattamento Jz +HISTORY_MSG_1093;Local - modello CAM +HISTORY_MSG_1094;Local - Alteluci Jz +HISTORY_MSG_1095;Local - Soglia alteluci Jz +HISTORY_MSG_1096;Local - Ombre Jz +HISTORY_MSG_1097;Local - Soglia ombre Jz +HISTORY_MSG_1098;Local - Raggio Ombre/Alteluci Jz +HISTORY_MSG_1099;Local - Curva Cz(Hz) +HISTORY_MSG_1100;Local - Referenza 100 Jz +HISTORY_MSG_1101;Local - Jz PQ rimappa +HISTORY_MSG_1102;Local - Curva Jz(Hz) +HISTORY_MSG_1103;Local - Gamma di vibranza +HISTORY_MSG_1104;Local - Gamma netta +HISTORY_MSG_1105;Local - Metodo tono CIECAM +HISTORY_MSG_1106;Local - Curva di tono CIECAM +HISTORY_MSG_1107;Local - Metodo colore CIECAM +HISTORY_MSG_1108;Local - Curva colore CIECAM +HISTORY_MSG_1109;Local - Curva Jz(Jz) +HISTORY_MSG_1110;Local - Curva Cz(Cz) +HISTORY_MSG_1111;Local - Curva Cz(Jz) +HISTORY_MSG_1112;Local - Forzatura Jz +HISTORY_MSG_1113;Local - HDR PQ +HISTORY_MSG_1114;Local - Abilta maschera Cie +HISTORY_MSG_1115;Local - Maschera curva C Cie +HISTORY_MSG_1116;Local - Maschera curva L Cie +HISTORY_MSG_1117;Local - Maschera curva H Cie +HISTORY_MSG_1118;Local - Miscela maschera Cie +HISTORY_MSG_1119;Local - Maschera raggio Cie +HISTORY_MSG_1120;Local - Maschera di crominanza Cie +HISTORY_MSG_1121;Local - Maschera curva di contrasto Cie +HISTORY_MSG_1122;Local - Soglia di ripristino della maschera Cie +HISTORY_MSG_1123;Local - Maschera recupero duro Cie +HISTORY_MSG_1124;Local - Luce di recupero della maschera Cie +HISTORY_MSG_1125;Local - Decadimento del recupero della maschera Cie +HISTORY_MSG_1126;Local - Maschera laplacian Cie +HISTORY_MSG_1127;Local - Maschera di gamma Cie +HISTORY_MSG_1128;Local - Maschera di pendenza Cie +HISTORY_MSG_1129;Local - Luminanza relativa Cie +HISTORY_MSG_1130;Local - Saturazione Jz Cie +HISTORY_MSG_1131;Local - Maschera - Riduzione rumore +HISTORY_MSG_1132;Local - Wav sigma Jz Cie +HISTORY_MSG_1133;Local - Livello di Wav Jz Cie +HISTORY_MSG_1134;Local - Wav di contrasto locale Jz Cie +HISTORY_MSG_1135;Local - Wav di chiarezza Jz Cie +HISTORY_MSG_1136;Local - Wav di chiarezza Cz Cie +HISTORY_MSG_1137;Local - Wav di chiarezza morbida Cie +HISTORY_MSG_1138;Local - Local - Curva Hz(Hz) +HISTORY_MSG_1139;Local - Curva H morbida Jz +HISTORY_MSG_1140;Local - Soglia di crominanza Jz +HISTORY_MSG_1141;Local - Curva di chominanza Jz(Hz) +HISTORY_MSG_1142;Local - Intensità morbida +HISTORY_MSG_1143;Local - compensazione esposizione dei neri Jz +HISTORY_MSG_1144;Local - compensazione esposizione dei bianchi Jz +HISTORY_MSG_1145;Local - Decodifica logaritmica Jz +HISTORY_MSG_1146;Local - Decodifica logaritmica del grigio puntuale Jz +HISTORY_MSG_1147;Local - Compensazione esposizione dei neri e compensazione esposizione dei bianchi Jz +HISTORY_MSG_1148;Local - Sigmoide Jz +HISTORY_MSG_1149;Local - Sigmoide Q +HISTORY_MSG_1150;Local - Decodifica logaritmica Q invece del Sigmoideo Q +HISTORY_MSG_BLSHAPE;Sfocatura per livello +HISTORY_MSG_BLURCWAV;Sfocatura cromatica +HISTORY_MSG_BLURWAV;Luminanza sfocata +HISTORY_MSG_BLUWAV;Risposta di attenuazione +HISTORY_MSG_CATCAT;CAL - Impostazioni - Modalità +HISTORY_MSG_CATCOMPLEX;CAL - Impostazioni - Complessità +HISTORY_MSG_CATMODEL;CAL - Impostazioni - CAM +HISTORY_MSG_CLAMPOOG;Ritaglia i colori fuori gamma +HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Correzione del colore +HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Correzione del colore +HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Canale +HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - maschera della regione C +HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - maschra H +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Luminosità +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - Maschera L +HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - Lista +HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - sfocatura della maschera della regione +HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - compensazione della regione +HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - potenza della regione +HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturazione +HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - la regione mostra la maschera +HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - pendenza della regione +HISTORY_MSG_COMPLEX;Complessità delle wavelet +HISTORY_MSG_COMPLEXRETI;Complessità del Retinex +HISTORY_MSG_DEHAZE_DEPTH;Rimozione foschia - Profondità +HISTORY_MSG_DEHAZE_ENABLED;Rimozione della foschia +HISTORY_MSG_DEHAZE_SATURATION;Rimozione foschia - Saturazione +HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Rimozione foschia - mostra la mappa di profondità +HISTORY_MSG_DEHAZE_STRENGTH;Rimozione foschia - Intensità +HISTORY_MSG_DIRPYRDENOISE_GAIN;Riduzione del rumore - Compensazione per leggerezza +HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Doppia demosaicizzazione - Soglia automatica +HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Doppia demosaicizzazione - Soglia di contrasto +HISTORY_MSG_EDGEFFECT;Risposta di attenuazione del bordo +HISTORY_MSG_FF_FROMMETADATA;Flat-Field - Dai metadati +HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Uscita di riferimento +HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Spazio colore negativo della pellicola +HISTORY_MSG_FILMNEGATIVE_ENABLED;Negativo della pellicola +HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Ingresso di riferimento +HISTORY_MSG_FILMNEGATIVE_VALUES;Valori negativi della pellicola +HISTORY_MSG_GAMUTMUNSEL;Gamma-Munsell +HISTORY_MSG_HISTMATCHING;Curva di tono con abbinamento automatico +HISTORY_MSG_HLBL;Propagazione colore - sfocatura +HISTORY_MSG_HLTH;Inpaint opposto - soglia di guadagno +HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy +HISTORY_MSG_ICM_AINTENT;Intento del profilo astratto +HISTORY_MSG_ICM_BLUX;Blu X primario +HISTORY_MSG_ICM_BLUY;Blu Y primario +HISTORY_MSG_ICM_FBW;Bianco e Nero +HISTORY_MSG_ICM_GAMUT;Controllo di Gamma +HISTORY_MSG_ICM_GREX;Verde X primario +HISTORY_MSG_ICM_GREY;Verde Y primario +HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uscita - Primari +HISTORY_MSG_ICM_OUTPUT_TEMP;Uscita - ICC-v4 illuminante D +HISTORY_MSG_ICM_OUTPUT_TYPE;Uscita - Tipo +HISTORY_MSG_ICM_PRESER;Conservare il neutro +HISTORY_MSG_ICM_REDX;Rosso X primario +HISTORY_MSG_ICM_REDY;Rosso Y primario +HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma +HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Metodo illuminante +HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Metodo delle primarie +HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Pendenza +HISTORY_MSG_ICM_WORKING_TRC_METHOD;Metodo TRC +HISTORY_MSG_ILLUM;CAL - SC - Illuminante +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Riduzione Foschia - Nero +HISTORY_MSG_LOCAL_GAMUTMUNSEL;Locale - SC - Evita il cambiamento di colore +HISTORY_MSG_LOCAL_TMO_SATUR;Local Saturazione Fattale dell'esposizione +HISTORY_MSG_LOCALCONTRAST_AMOUNT;Contrasto Locale - Quantità +HISTORY_MSG_LOCALCONTRAST_DARKNESS;Contrasto Locale - Durezza +HISTORY_MSG_LOCALCONTRAST_ENABLED;Contrasto Locale +HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Contrasto Locale - Luminosità +HISTORY_MSG_LOCALCONTRAST_RADIUS;Contrasto Locale - Raggio +HISTORY_MSG_LOCALLAB_TE_PIVOT;Locale - Perno dell'equalizzatore +HISTORY_MSG_METADATA_MODE;Modalità di copia dei metadati +HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrasto - Soglia di contrasto +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Soglia automatica +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Raggio automatico +HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Iterazioni di limite automatico +HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Soglia di contrasto +HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterazione +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Aumento del raggio d'angolo +HISTORY_MSG_PDSHARPEN_RADIUS;CS - Raggio +HISTORY_MSG_PERSP_CAM_ANGLE;Prospettiva - Camera +HISTORY_MSG_PERSP_CAM_FL;Prospettiva - Camera +HISTORY_MSG_PERSP_CAM_SHIFT;Prospettiva - Camera +HISTORY_MSG_PERSP_CTRL_LINE;Prospettiva - Linee di controllo +HISTORY_MSG_PERSP_METHOD;Prospettiva - Metodo +HISTORY_MSG_PERSP_PROJ_ANGLE;Prospettiva - Recupero +HISTORY_MSG_PERSP_PROJ_ROTATE;Prospettiva - PCA rotazione +HISTORY_MSG_PERSP_PROJ_SHIFT;Prospettiva - PCA +HISTORY_MSG_PIXELSHIFT_AVERAGE;PS - Media +HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Metodo demosaico per il movimento +HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Direzione del filtro del rumore di linea +HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF filtro delle linee +HISTORY_MSG_PREPROCWB_MODE;Preelabora la modalità WB +HISTORY_MSG_PROTAB;Protezione +HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Soglia di contrasto +HISTORY_MSG_RANGEAB;Allineare ab +HISTORY_MSG_RAW_BORDER;Raw confine +HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correzione - Iterazione +HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correzione - Evita il cambiamento di colore +HISTORY_MSG_RESIZE_ALLOWUPSCALING;Ridimensiona - Consente l'ingrandimento +HISTORY_MSG_RESIZE_LONGEDGE;Ridimensiona - Bordo lungo +HISTORY_MSG_RESIZE_SHORTEDGE;Ridimensiona - Bordo corto +HISTORY_MSG_SH_COLORSPACE;S/H - Spazio colore +HISTORY_MSG_SHARPENING_BLUR;Nitidezza - Raggio di sfocatura +HISTORY_MSG_SHARPENING_CONTRAST;Nitidezza - Soglia di contrasto +HISTORY_MSG_SIGMACOL;Risposta all'attenuazione cromatica +HISTORY_MSG_SIGMADIR;Risposta di attenuazione Dir +HISTORY_MSG_SIGMAFIN;Risposta di attenuazione del contrasto finale +HISTORY_MSG_SIGMATON;Risposta all'attenuazione toni +HISTORY_MSG_SOFTLIGHT_ENABLED;Luce soffusa +HISTORY_MSG_SOFTLIGHT_STRENGTH;Luce soffusa - Intensità +HISTORY_MSG_SPOT_ENTRY;Rimozione delle macchie - modifica punto +HISTORY_MSG_SPOT;Rimozione delle macchie +HISTORY_MSG_TEMPOUT;CAM02 temperature automatica +HISTORY_MSG_THRESWAV;Soglia bilanciamento +HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Ancora +HISTORY_MSG_TONE_EQUALIZER_BANDS;Equalizzatore di tono - Bande +HISTORY_MSG_TONE_EQUALIZER_ENABLED;Equalizzatore di tono +HISTORY_MSG_TONE_EQUALIZER_PIVOT;Equalizzatore di tono - Perno +HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Equalizzatore di tono - Regolarizzazione +HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Equalizzatore di tono - Mappa tonale +HISTORY_MSG_TRANS_METHOD;Geometria - Metodo +HISTORY_MSG_WAVBALCHROM;Equalizzatore di crominanza +HISTORY_MSG_WAVBALLUM;Equalizzatore di luminanza +HISTORY_MSG_WAVBL;Livelli di sfocatura +HISTORY_MSG_WAVCHR;Livelli di sfocatura - sfocatura cromatica +HISTORY_MSG_WAVCHROMCO;Croma grossolana +HISTORY_MSG_WAVCHROMFI;Croma fine +HISTORY_MSG_WAVCLARI;Chiarezza +HISTORY_MSG_WAVDENLH;Livello 5 +HISTORY_MSG_WAVDENOISE;Contrasto locale +HISTORY_MSG_WAVDENOISEH;Livelli elevati Contrasto locale +HISTORY_MSG_WAVDETEND;Dettagli morbidi +HISTORY_MSG_WAVEDGS;Arresto del bordo +HISTORY_MSG_WAVGUIDH;Equalizzatore locale di contrasto-tonalità +HISTORY_MSG_WAVHUE;Equalizzatore di tonalità +HISTORY_MSG_WAVLABGRID_VALUE;Tonalità - Esclude i colori +HISTORY_MSG_WAVLEVDEN;Contrasto locale di alto livello +HISTORY_MSG_WAVLEVELSIGM;Riduzione rumore - Raggio +HISTORY_MSG_WAVLEVSIGM;Raggio +HISTORY_MSG_WAVLIMDEN;Interazione 56 14 +HISTORY_MSG_WAVLOWTHR;Soglia di basso contrasto +HISTORY_MSG_WAVMERGEC;Unire C +HISTORY_MSG_WAVMERGEL;Unire L +HISTORY_MSG_WAVMIXMET;Contrasto locale di riferimento +HISTORY_MSG_WAVOFFSET;Compensare +HISTORY_MSG_WAVOLDSH;Vecchio algoritmo +HISTORY_MSG_WAVQUAMET;Modo riduzione rumore +HISTORY_MSG_WAVRADIUS;Raggio ombre-alteluci +HISTORY_MSG_WAVSCALE;Scala +HISTORY_MSG_WAVSHOWMASK;Mostra maschera di wavelet +HISTORY_MSG_WAVSIGM;Sigma +HISTORY_MSG_WAVSIGMA;Risposta di attenuazione +HISTORY_MSG_WAVSLIMET;Metodo +HISTORY_MSG_WAVSOFTRAD;Raggio morbido di chiarezza +HISTORY_MSG_WAVSOFTRADEND;Raggio morbido finale +HISTORY_MSG_WAVSTREND;Intensità morbida +HISTORY_MSG_WAVTHRDEN;Soglia di contrasto locale +HISTORY_MSG_WAVTHREND;Soglia di contrasto locale +HISTORY_MSG_WAVUSHAMET;Metodo chiarezza +HISTORY_MSG_WBALANCE_OBSERVER10;Osservatore 10° +HISTORY_MSG_WBITC_CUSTOM;Itcwb personalizzato +HISTORY_MSG_WBITC_DELTA;Itcwb Verde delta +HISTORY_MSG_WBITC_FGREEN;Itcwb Verde - Studente +HISTORY_MSG_WBITC_FORCE;Itcwb Forza +HISTORY_MSG_WBITC_GREEN;Raffina il verde +HISTORY_MSG_WBITC_MINSIZE;Dimensione minima della toppa +HISTORY_MSG_WBITC_NOPURPLE;Itcwb No Porpora +HISTORY_MSG_WBITC_OBS;Rimuovere l'algoritmo 2 passaggi +HISTORY_MSG_WBITC_PONDER;Itcwb Ponderata +HISTORY_MSG_WBITC_PRECIS;Itcwb Precisione +HISTORY_MSG_WBITC_PRIM;Primari +HISTORY_MSG_WBITC_RGREEN;Itcwb Intervalli del verde +HISTORY_MSG_WBITC_SAMPLING;Campionamento basso +HISTORY_MSG_WBITC_SIZE;Itcwb Dimensione +HISTORY_MSG_WBITC_SORTED;Itcwb Ponderata +HISTORY_MSG_WBITC_THRES;Itcwb Soglia HISTORY_NEWSNAPSHOT_TOOLTIP;Scorciatoia: Alt-s +HISTORY_NEWSNAPSHOT;Aggiungi HISTORY_SNAPSHOT;Istantanea HISTORY_SNAPSHOTS;Istantanee +ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Ripristina il copyright predefinito, concesso a "RawTherapee, CC0". +ICCPROFCREATOR_COPYRIGHT;Copyright: +ICCPROFCREATOR_CUSTOM;Predefinito +ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Aggiungi i valori gamma e pendenza alla descrizione +ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Lascia vuoto per impostare la descrizione predefinita. +ICCPROFCREATOR_DESCRIPTION;Descrizione: +ICCPROFCREATOR_GAMMA;Gamma +ICCPROFCREATOR_ICCVERSION;ICC versione: +ICCPROFCREATOR_ILL_41;D41 +ICCPROFCREATOR_ILL_50;D50 +ICCPROFCREATOR_ILL_55;D55 +ICCPROFCREATOR_ILL_60;D60 +ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Teatro +ICCPROFCREATOR_ILL_65;D65 +ICCPROFCREATOR_ILL_80;D80 +ICCPROFCREATOR_ILL_DEF;Default +ICCPROFCREATOR_ILL_INC;StdA 2856K +ICCPROFCREATOR_ILL_TOOLTIP;È possibile impostare l'illuminante per i profili ICC v4 e anche per i profili ICC v2. +ICCPROFCREATOR_ILL;Illuminante: +ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 +ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 +ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) +ICCPROFCREATOR_PRIM_BEST;BestRGB +ICCPROFCREATOR_PRIM_BETA;BetaRGB +ICCPROFCREATOR_PRIM_BLUX;Blu X +ICCPROFCREATOR_PRIM_BLUY;Blu Y +ICCPROFCREATOR_PRIM_BRUCE;BruceRGB +ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 +ICCPROFCREATOR_PRIM_GREX;Verde X +ICCPROFCREATOR_PRIM_GREY;Verde Y +ICCPROFCREATOR_PRIM_PROPH;Prophoto +ICCPROFCREATOR_PRIM_REC2020;Rec2020 +ICCPROFCREATOR_PRIM_REDX;Rosso X +ICCPROFCREATOR_PRIM_REDY;Rosso Y +ICCPROFCREATOR_PRIM_SRGB;sRGB +ICCPROFCREATOR_PRIM_TOOLTIP;È possibile impostare primari personalizzati per i profili ICC v4 e anche per i profili ICC v2. +ICCPROFCREATOR_PRIM_WIDEG;Ampia gamma +ICCPROFCREATOR_PRIMARIES;Primarie: +ICCPROFCREATOR_PROF_V2;ICC v2 +ICCPROFCREATOR_PROF_V4;ICC v4 +ICCPROFCREATOR_SAVEDIALOG_TITLE;Salva il profilo ICC come... +ICCPROFCREATOR_SLOPE;Pendenza +ICCPROFCREATOR_TRC_PRESET;Curva di risposta tonale +INSPECTOR_WINDOW_TITLE;Ispettore IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CATEGORYHINT;Identifica il soggetto dell'immagine secondo il parere del fornitore. IPTCPANEL_CITY;Città +IPTCPANEL_CITYHINT;Inserisci il nome della città raffigurata in questa immagine. IPTCPANEL_COPYHINT;Copia le impostazioni IPTC negli appunti +IPTCPANEL_COPYRIGHT;Notizie sul Copyright +IPTCPANEL_COPYRIGHTHINT;Inserisci un avviso sull'attuale proprietario del copyright per questa immagine, ad esempio ©2008 Jane Doe. IPTCPANEL_COUNTRY;Stato +IPTCPANEL_COUNTRYHINT;Inserisci il nome del paese raffigurato in questa immagine. +IPTCPANEL_CREATOR;Creatore +IPTCPANEL_CREATORHINT;Inserisci il nome della persona che ha creato questa immagine. +IPTCPANEL_CREATORJOBTITLE;Titolo della professione del creatore +IPTCPANEL_CREATORJOBTITLEHINT;Inserisci la qualifica professionale della persona elencata nel campo Creatore. IPTCPANEL_CREDIT;Riconoscimento IPTCPANEL_CREDITHINT;Identifica il fornitore dell'immagine, non necessariamente il possessore/creatore (Credit). IPTCPANEL_DATECREATED;Data di creazione +IPTCPANEL_DATECREATEDHINT;Inserisci la data in cui è stata scattata l'immagine. +IPTCPANEL_DESCRIPTION;Descrizione +IPTCPANEL_DESCRIPTIONHINT;Inserisci una "didascalia" che descriva chi, cosa e perché di ciò che sta accadendo in questa immagine. Ciò potrebbe includere nomi di persone e/o il loro ruolo nell'azione che si sta svolgendo all'interno dell'immagine. +IPTCPANEL_DESCRIPTIONWRITER;Scrittore di descrizioni +IPTCPANEL_DESCRIPTIONWRITERHINT;Inserisci il nome della persona coinvolta nella scrittura, modifica o correzione della descrizione dell'immagine. IPTCPANEL_EMBEDDED;Incorporato IPTCPANEL_EMBEDDEDHINT;Ripristina i dati IPTC incorporati nel file d'immagine IPTCPANEL_HEADLINE;Intestazione +IPTCPANEL_HEADLINEHINT;Inserisci una breve sinossi pubblicabile o un riepilogo dei contenuti dell'immagine. IPTCPANEL_INSTRUCTIONS;Istruzioni +IPTCPANEL_INSTRUCTIONSHINT;Inserisci informazioni sugli embarghi o altre restrizioni non coperte dal campo Copyright. IPTCPANEL_KEYWORDS;Parole Chiave +IPTCPANEL_KEYWORDSHINT;Inserisci un numero qualsiasi di parole chiave, termini o frasi utilizzate per esprimere l'oggetto dell'immagine. IPTCPANEL_PASTEHINT;Incolla le impostazioni IPTC dagli appunti +IPTCPANEL_PROVINCE;Provincia o stato +IPTCPANEL_PROVINCEHINT;Inserisci il nome della provincia o dello stato raffigurato in questa immagine. IPTCPANEL_RESET;Ripristina IPTCPANEL_RESETHINT;Ripristina il profilo predefinito IPTCPANEL_SOURCE;Origine +IPTCPANEL_SOURCEHINT;Inserisci o modifica il nome di una persona o di un soggetto che ha un ruolo nella catena di fornitura dei contenuti, ad esempio una persona o entità da cui hai ricevuto questa immagine. +IPTCPANEL_SUPPCATEGORIES;Categorie supplementari +IPTCPANEL_SUPPCATEGORIESHINT;Perfeziona ulteriormente il soggetto dell'immagine. IPTCPANEL_TITLE;Titolo +IPTCPANEL_TITLEHINT;Inserisci un breve nome verbale e leggibile per l'immagine, questo potrebbe essere il nome del file. +IPTCPANEL_TRANSREFERENCE;ID lavoro +IPTCPANEL_TRANSREFERENCEHINT;Inserisci un numero o un identificatore necessario per il controllo o il monitoraggio del flusso di lavoro. MAIN_BUTTON_FULLSCREEN;Schermo intero +MAIN_BUTTON_ICCPROFCREATOR;Creatore di profili ICC MAIN_BUTTON_NAVNEXT_TOOLTIP;Passa all'immagine successiva rispetto all'immagine aperta per la Modifica\nScorciatoia: Shift-F4\n\nPer passare all'immagine successiva rispetto alla miniatura selezionata nel Navigatore o nel Rullino:\nScorciatoia: F4 MAIN_BUTTON_NAVPREV_TOOLTIP;Passa all'immagine precedente rispetto all'immagine aperta per la Modifica\nScorciatoia: Shift-F3\n\nPer passare all'immagine precedente rispetto alla miniatura selezionata nel Navigatore o nel Rullino:\nScorciatoia: F3 MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizza il Navigatore o il Rullino con la scheda di Modifica per trovare la miniatura dell'immagine attualmente aperta e rimuovere tutti i filtri di ricerca\nScorciatoia: x\n\nCome sopra, ma senza cancellare i filtri di ricerca\nScorciatoia: y\n(Nota che la miniatura del file aperto, se filtrato, non verrà mostrata). @@ -455,22 +1662,24 @@ MAIN_BUTTON_PREFERENCES;Preferenze MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Aggiungi l'immagine corrente alla coda di sviluppo.\nScorciatoia: Ctrl+B MAIN_BUTTON_SAVE_TOOLTIP;Salva l'immagine corrente.\nSscorciatoia: Ctrl+S MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Modifica l'immagine corrente con un programma di fotoritocco.\nScorciatoia: Ctrl+E +MAIN_BUTTON_SENDTOEDITOR;Modifica l'immagine nell'editor esterno MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/Nascondi tutti i pannelli laterali.\nScorciatoia: m MAIN_BUTTON_UNFULLSCREEN;Esci da schermo intero -MAIN_FRAME_EDITOR;Modifica MAIN_FRAME_EDITOR_TOOLTIP;Modifica.\nScorciatoia: Ctrl-F4 -MAIN_FRAME_FILEBROWSER;Navigatore +MAIN_FRAME_EDITOR;Modifica MAIN_FRAME_FILEBROWSER_TOOLTIP;Navigatore.\nScorciatoia: Ctrl-F2 -MAIN_FRAME_PLACES;Risorse +MAIN_FRAME_FILEBROWSER;Navigatore MAIN_FRAME_PLACES_ADD;Aggiungi -MAIN_FRAME_QUEUE;Coda di sviluppo +MAIN_FRAME_PLACES_DEL;Rimuovere +MAIN_FRAME_PLACES;Risorse MAIN_FRAME_QUEUE_TOOLTIP;Coda di sviluppo.\nScorciatoia: Ctrl-F3 +MAIN_FRAME_QUEUE;Coda di sviluppo MAIN_FRAME_RECENT;Cartelle recenti MAIN_MSG_ALREADYEXISTS;File già esistente MAIN_MSG_CANNOTLOAD;Impossibile caricare l'immagine MAIN_MSG_CANNOTSAVE;Errore nel salvataggio del file -MAIN_MSG_CANNOTSTARTEDITOR;Non riesco ad avviare il programma di fotoritocco. MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Inserisci il percorso corretto nelle "Preferenze". +MAIN_MSG_CANNOTSTARTEDITOR;Non riesco ad avviare il programma di fotoritocco. MAIN_MSG_EMPTYFILENAME;Nome del file non specificato! MAIN_MSG_IMAGEUNPROCESSED;Questo comando richiede che tutte le immagini selezionate vengano prima elaborate nella coda. MAIN_MSG_NAVIGATOR;Navigatore @@ -478,27 +1687,36 @@ MAIN_MSG_OPERATIONCANCELLED;Operatione annullata MAIN_MSG_PATHDOESNTEXIST;Il percorso\n\n%1\n\nnon esiste. Imposta un percorso corretto nella finestra Preferenze. MAIN_MSG_QOVERWRITE;Vuoi sovrascriverlo? MAIN_MSG_SETPATHFIRST;Per utilizzare questa funzione\ndevi impostare un percorso nelle Preferenze. +MAIN_MSG_TOOMANYOPENEDITORS;Troppi editor aperti.\nChiudi un editor per continuare. MAIN_MSG_WRITEFAILED;Impossibile scrivere\n\n"%1"\n\nAssicurati che la cartella esista e di averne i permessi di scrittura. -MAIN_TAB_COLOR;Colore +MAIN_TAB_ADVANCED_TOOLTIP;Scorciatoia: Alt-a +MAIN_TAB_ADVANCED;Avanzate MAIN_TAB_COLOR_TOOLTIP;Scorciatoia: Alt-c -MAIN_TAB_DETAIL;Dettaglio +MAIN_TAB_COLOR;Colore MAIN_TAB_DETAIL_TOOLTIP;Scorciatoia: Alt-d -MAIN_TAB_DEVELOP; Modifiche Batch +MAIN_TAB_DETAIL;Dettaglio +MAIN_TAB_DEVELOP; Modifiche Batch MAIN_TAB_EXIF;Exif -MAIN_TAB_EXPORT; Esportazione Rapida -MAIN_TAB_EXPOSURE;Esposizione +MAIN_TAB_EXPORT; Esportazione Rapida MAIN_TAB_EXPOSURE_TOOLTIP;Scorciatoia: Alt-e -MAIN_TAB_FILTER; Filtro +MAIN_TAB_EXPOSURE;Esposizione +MAIN_TAB_FAVORITES_TOOLTIP;Scorciatoia: Alt-u +MAIN_TAB_FAVORITES;Preferiti +MAIN_TAB_FILTER; Filtro +MAIN_TAB_INSPECT; Inspect MAIN_TAB_IPTC;IPTC -MAIN_TAB_METADATA;Metadati +MAIN_TAB_LOCALLAB_TOOLTIP;Scorciatoia: Alt-o +MAIN_TAB_LOCALLAB;Local MAIN_TAB_METADATA_TOOLTIP;Scorciatoia: Alt-m -MAIN_TAB_RAW;Raw +MAIN_TAB_METADATA;Metadati MAIN_TAB_RAW_TOOLTIP;Scorciatoia: Alt-r -MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TAB_RAW;Raw MAIN_TAB_TRANSFORM_TOOLTIP;Scorciatoia: Alt-t +MAIN_TAB_TRANSFORM;Trasformazione MAIN_TOOLTIP_BACKCOLOR0;Colore di sfondo dell'anteprima: Basato sul tema\nScorciatoia: 9 MAIN_TOOLTIP_BACKCOLOR1;Colore di sfondo dell'anteprima: Nero\nScorciatoia: 9 MAIN_TOOLTIP_BACKCOLOR2;Colore di sfondo dell'anteprima: Bianco\nScorciatoia: 9 +MAIN_TOOLTIP_BACKCOLOR3;Colore di sfondo dell'anteprima: grigio medio\nScorciatoia: 9 MAIN_TOOLTIP_BEFOREAFTERLOCK;Blocca/Sblocca la vista Prima\n\nBlocca: Conserva la vista Prima.\nUtile per valutare l'effetto cumulativo di diversi strumenti.\nIn più, possono essere confrontati diversi passi della cronologia.\n\nSblocca: la vista Prima segue di un passo la vista Dopo, mostrando l'immagine prima dell'effetto dello strumento corrente. MAIN_TOOLTIP_HIDEHP;Mostra/Nascondi il pannello sinistro (inclusa la cronologia)\nScorciatoia: l MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate.\nScorciatoia: > @@ -508,12 +1726,14 @@ MAIN_TOOLTIP_PREVIEWFOCUSMASK;Anteprima della Focus Mask.\nScorciatoia: < MAIN_TOOLTIP_PREVIEWG;Anteprima del Canale Verde.\nScorciatoia: g MAIN_TOOLTIP_PREVIEWL;Anteprima della Luminosità.\nScorciatoia: v\n\n0.299*R + 0.587*G + 0.114*B MAIN_TOOLTIP_PREVIEWR;Anteprima del Canale Rosso.\nScorciatoia: r +MAIN_TOOLTIP_PREVIEWSHARPMASK;Visualizza l'anteprima della maschera di contrasto per la nitidezza.\nScorciatoia: p\n\nFunziona solo quando la nitidezza è abilitata e lo zoom >= 100%. MAIN_TOOLTIP_QINFO;Informazioni generali sullo scatto.\nScorciatoia: i MAIN_TOOLTIP_SHOWHIDELP1;Mostra/Nascondi il pannello sinistro.\nScorciatoia: l MAIN_TOOLTIP_SHOWHIDERP1;Mostra/Nascondi il pannello destro.\nScorciatoia: Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Mostra/Nascondi il pannello superiore.\nScorciatoia: Maiuscolo-l MAIN_TOOLTIP_THRESHOLD;Soglia MAIN_TOOLTIP_TOGGLE;Vista Prima/Dopo.\nScorciatoia: Maiuscolo-b +MONITOR_PROFILE_SYSTEM;Default del sistema NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -526,6 +1746,10 @@ NAVIGATOR_S;S: NAVIGATOR_V;V: NAVIGATOR_XY_FULL;Larghezza: %1, Altezza: %2 NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_BUNDLED_MISSING;Impossibile trovare il profilo in bundle '%1'!\in\L'installazione potrebbe essere danneggiata.\non Verranno utilizzati invece i valori interni predefiniti. +OPTIONS_DEFIMG_MISSING;Impossibile trovare o non è impostato il profilo predefinito per foto non RAW.\n\nControlla la directory dei profili, potrebbe essere mancante o danneggiata.\n\n'% Verrà invece utilizzato 1'. +OPTIONS_DEFRAW_MISSING;Impossibile trovare o non è impostato il profilo predefinito per foto RAW.\n\nControlla la directory dei profili, potrebbe essere mancante o danneggiata.\n\n'%1< /b>' verrà invece utilizzato. +PARTIALPASTE_ADVANCEDGROUP;Impostazioni avanzate PARTIALPASTE_BASICGROUP;Parametri principali PARTIALPASTE_CACORRECTION;Correzione AC PARTIALPASTE_CHANNELMIXER;Miscelatore Canali @@ -533,25 +1757,32 @@ PARTIALPASTE_CHANNELMIXERBW;Bianco-Nero PARTIALPASTE_COARSETRANS;Rotazione di 90°/Riflessione PARTIALPASTE_COLORAPP;Modello di Aspetto Colore CIE 2002 PARTIALPASTE_COLORGROUP;Parametri relativi al colore +PARTIALPASTE_COLORTONING;Tonalità colore PARTIALPASTE_COMMONTRANSFORMPARAMS;Riadatta PARTIALPASTE_COMPOSITIONGROUP;Parametri di composizione PARTIALPASTE_CROP;Ritaglio PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame - Autoselezione PARTIALPASTE_DARKFRAMEFILE;File Dark Frame PARTIALPASTE_DEFRINGE;Defringe +PARTIALPASTE_DEHAZE;Rimozione della foschia PARTIALPASTE_DETAILGROUP;Parametri di dettaglio PARTIALPASTE_DIALOGLABEL;Incolla una parte del profilo di sviluppo PARTIALPASTE_DIRPYRDENOISE;Riduzione Rumore PARTIALPASTE_DIRPYREQUALIZER;Contrasto per livelli di dettaglio PARTIALPASTE_DISTORTION;Correzione Distorsione PARTIALPASTE_EPD;Tone mapping +PARTIALPASTE_EQUALIZER;Livelli wavelet PARTIALPASTE_EVERYTHING;Tutto PARTIALPASTE_EXIFCHANGES;Modifiche ai dati Exif PARTIALPASTE_EXPOSURE;Esposizione +PARTIALPASTE_FILMNEGATIVE;Negativo della pellicola +PARTIALPASTE_FILMSIMULATION;Simulazione della pellicola PARTIALPASTE_FLATFIELDAUTOSELECT;Flat Field - Autoselezione PARTIALPASTE_FLATFIELDBLURRADIUS;Flat Field - Raggio di sfocamento PARTIALPASTE_FLATFIELDBLURTYPE;Flat Field - Modalità di sfocamento +PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field controllo della clip PARTIALPASTE_FLATFIELDFILE;File Flat Field +PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field dai metadati PARTIALPASTE_GRADIENT;Filtro Graduato PARTIALPASTE_HSVEQUALIZER;Equalizzatore HSV PARTIALPASTE_ICMSETTINGS;Impostazioni Gestione Colore @@ -560,49 +1791,108 @@ PARTIALPASTE_IPTCINFO;Informazioni IPTC PARTIALPASTE_LABCURVE;Regolazioni Lab PARTIALPASTE_LENSGROUP;Impostazioni dell'Obiettivo PARTIALPASTE_LENSPROFILE;Profilo di Correzione dell'Obiettivo +PARTIALPASTE_LOCALCONTRAST;Contrasto locale +PARTIALPASTE_LOCALLAB;Aggiustamenti locali +PARTIALPASTE_LOCALLABGROUP;Impostazioni aggiustamenti locali +PARTIALPASTE_METADATA;Modo metadati PARTIALPASTE_METAGROUP;Impostazioni di metadati PARTIALPASTE_PCVIGNETTE;Filtro Vignettatura PARTIALPASTE_PERSPECTIVE;Prospettiva +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtro pixel bruciati/morti PARTIALPASTE_PREPROCESS_GREENEQUIL;Bilanciamento del verde +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtro pixel bruciati PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro per rumore a bande -PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC -PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero -PARTIALPASTE_RAWEXPOS_LINEAR;Correzione Punto del Bianco -PARTIALPASTE_RAWGROUP;Impostazioni del Raw +PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;Filtro linee PDAF +PARTIALPASTE_PREPROCWB;Preelaborare il bilanciamento del bianco +PARTIALPASTE_PRSHARPENING;Affinamento post-ridimensionamento +PARTIALPASTE_RAW_BORDER;Bordo del raw PARTIALPASTE_RAW_DCBENHANCE;Miglioramento DCB PARTIALPASTE_RAW_DCBITERATIONS;Numero di iterazioni DCB PARTIALPASTE_RAW_DMETHOD;Metodo di demosaicizzazione PARTIALPASTE_RAW_FALSECOLOR;Soppressione di falsi colori demosaicizzati +PARTIALPASTE_RAW_IMAGENUM;Sotto-immagine PARTIALPASTE_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE +PARTIALPASTE_RAW_PIXELSHIFT;Spostamento dei pixel +PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC +PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA evitare cambiamenti di colore +PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rosso e blu +PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero +PARTIALPASTE_RAWEXPOS_LINEAR;Correzione Punto del Bianco +PARTIALPASTE_RAWGROUP;Impostazioni del Raw PARTIALPASTE_RESIZE;Ridimensionamento +PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;Curve RGB PARTIALPASTE_ROTATION;Rotazione PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombre/Alteluci PARTIALPASTE_SHARPENEDGE;Bordi PARTIALPASTE_SHARPENING;Nitidezza (USM/RL) PARTIALPASTE_SHARPENMICRO;Microcontrasto +PARTIALPASTE_SOFTLIGHT;Luce soffusa +PARTIALPASTE_SPOT;Rimozione delle macchie +PARTIALPASTE_TM_FATTAL;Compressione della gamma dinamica +PARTIALPASTE_TONE_EQUALIZER;Equalizzatore di tono PARTIALPASTE_VIBRANCE;Vividezza PARTIALPASTE_VIGNETTING;Correzione Vignettatura PARTIALPASTE_WHITEBALANCE;Bilanciamento del bianco PREFERENCES_ADD;Somma +PREFERENCES_APPEARANCE_COLORPICKERFONT;Carattere di selezione colore +PREFERENCES_APPEARANCE_CROPMASKCOLOR;Colore della maschera di ritaglio +PREFERENCES_APPEARANCE_MAINFONT;Carattere principale PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Colore delle guide del Navigatore +PREFERENCES_APPEARANCE_PSEUDOHIDPI;Modo Pseudo-HiDPI +PREFERENCES_APPEARANCE_THEME;Tema +PREFERENCES_APPEARANCE;Aspetto PREFERENCES_APPLNEXTSTARTUP;applicato al prossimo avvio PREFERENCES_AUTOMONPROFILE;Usa il profilo colore dello schermo principale del sistema operativo +PREFERENCES_AUTOSAVE_TP_OPEN;Salva lo stato compresso/espanso dello strumento all'uscita PREFERENCES_BATCH_PROCESSING;Sviluppo in serie PREFERENCES_BEHADDALL;Tutti a 'Somma' PREFERENCES_BEHADDALLHINT;Imposta tutti i parametri nella modalità Somma.\nLe regolazioni dei parametri nel pannello strumenti batch saranno differenze dei valori memorizzati. PREFERENCES_BEHAVIOR;Comportamento PREFERENCES_BEHSETALL;Tutti a 'Imposta' PREFERENCES_BEHSETALLHINT;Imposta tutti i parametri nella modalità Imposta.\nLe regolazioni dei parametri nel pannello strumenti batch saranno assoluti, verranno mostrati i valori reali. +PREFERENCES_CACHECLEAR_ALL;Pulisci tutti i file della cache: +PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Cancella tutti i file memorizzati nella cache ad eccezione dei profili di elaborazione memorizzati nella cache: +PREFERENCES_CACHECLEAR_ONLYPROFILES;Cancella solo i profili di elaborazione memorizzati nella cache: +PREFERENCES_CACHECLEAR_SAFETY;Vengono cancellati solo i file nella cache. I profili di elaborazione memorizzati insieme alle immagini sorgente non vengono toccati. +PREFERENCES_CACHECLEAR;Pulisci PREFERENCES_CACHEMAXENTRIES;Numero massimo di voci in memoria PREFERENCES_CACHEOPTS;Opzioni della memoria PREFERENCES_CACHETHUMBHEIGHT;Massima altezza delle miniature +PREFERENCES_CAMERAPROFILESDIR;Directory dei profili della fotocamera +PREFERENCES_CHUNKSIZE_RAW_AMAZE;Demosaicizzazione AMaZE +PREFERENCES_CHUNKSIZE_RAW_CA;Correzione CA Raw +PREFERENCES_CHUNKSIZE_RAW_RCD;Demosaicizzazione RCD +PREFERENCES_CHUNKSIZE_RAW_XT;Demosaicizzazione Xtrans +PREFERENCES_CHUNKSIZE_RGB;Elaborazione RGB +PREFERENCES_CHUNKSIZES;Riquadri per tipo di esecuzione +PREFERENCES_CIE;Ciecam +PREFERENCES_CIEARTIF;Evita artefatti PREFERENCES_CLIPPINGIND;Indicazione di tosaggio +PREFERENCES_CLUTSCACHE_LABEL;Numero massimo di cache CLUTs +PREFERENCES_CLUTSCACHE;HaldCLUT Cache +PREFERENCES_CLUTSDIR;Directory HaldCLUT +PREFERENCES_CMMBPC;Compensazione del punti di Nero +PREFERENCES_COMPLEXITY_EXP;Avanzate +PREFERENCES_COMPLEXITY_NORM;Standard +PREFERENCES_COMPLEXITY_SIMP;Di base +PREFERENCES_COMPLEXITYLOC;Complessità predefinita per le regolazioni locali +PREFERENCES_CROP_AUTO_FIT;Zoom automaticamente per adattare il ritaglio +PREFERENCES_CROP_GUIDES_FRAME;Frame +PREFERENCES_CROP_GUIDES_FULL;Originale +PREFERENCES_CROP_GUIDES_NONE;Nessuno +PREFERENCES_CROP_GUIDES;Guide visualizzate quando non si modifica il ritaglio +PREFERENCES_CROP;Modifica del ritaglio +PREFERENCES_CURVEBBOXPOS_ABOVE;Sopra +PREFERENCES_CURVEBBOXPOS_BELOW;Sotto +PREFERENCES_CURVEBBOXPOS_LEFT;Sinistra +PREFERENCES_CURVEBBOXPOS_RIGHT;Destra +PREFERENCES_CURVEBBOXPOS;Posizione dei pulsanti copia e incolla della curva PREFERENCES_CUSTPROFBUILD;Generatore profili personalizzati PREFERENCES_CUSTPROFBUILDHINT;File eseguibile (o script) richiamato quando è necessario generare un nuovo profilo per un'immagine.\nIl percorso del file di comunicazione (del tipo *.ini, detto "Keyfile") è aggiunto come parametro da linea di comando. Contiene diversi paramentri necessari agli script e ai dati Exif per generare un profilo di elaborazione.\n\nATTENZIONE:: Devi utilizzare le virgolette doppie quando necessario se utilizzi percorsi contenenti spazi. -PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formato tasti PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nome PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formato tasti PREFERENCES_CUSTPROFBUILDPATH;Percorso dell'eseguibile PREFERENCES_DARKFRAMEFOUND;Trovati PREFERENCES_DARKFRAMESHOTS;fotogrammi @@ -610,40 +1900,77 @@ PREFERENCES_DARKFRAMETEMPLATES;modelli PREFERENCES_DATEFORMAT;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_DIRDARKFRAMES;Cartella dei fotogrammi di fondo (Dark Frame) +PREFERENCES_DIRECTORIES;Directories 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;Riga di comando personalizzata PREFERENCES_EDITORLAYOUT;Disposizione +PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Ignora profilo di destinazione +PREFERENCES_EXTEDITOR_DIR_CURRENT;Uguale all'immagine di input +PREFERENCES_EXTEDITOR_DIR_CUSTOM;Personalizza +PREFERENCES_EXTEDITOR_DIR_TEMP;OS Directory temporanea +PREFERENCES_EXTEDITOR_DIR;Cartella di destinazione +PREFERENCES_EXTEDITOR_FLOAT32;Output TIFF in virgola mobile a 32 bit +PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Modifica eseguibile +PREFERENCES_EXTERNALEDITOR_CHANGE;Cambia applicazione +PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Comando +PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Nome +PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Comando nativo PREFERENCES_EXTERNALEDITOR;Programma di ritocco esterni PREFERENCES_FBROWSEROPTS;Opzioni del Navigatore e delle miniature +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barre degli strumenti compatte nel browser dei file PREFERENCES_FLATFIELDFOUND;Trovati PREFERENCES_FLATFIELDSDIR;Cartella dei fotogrammi di campo (Flat Field) PREFERENCES_FLATFIELDSHOTS;fotogrammi PREFERENCES_FLATFIELDTEMPLATES;modelli PREFERENCES_FORIMAGE;Per foto non raw PREFERENCES_FORRAW;Per foto raw +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Avere dimensioni delle miniature separate richiederà più tempo di elaborazione ogni volta che passerai dalla scheda Editor singolo al Browser file. +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Stessa altezza della miniatura tra la pellicola e il browser dei file PREFERENCES_GIMPPATH;Cartella d'installazione di GIMP -PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro PREFERENCES_HISTOGRAM_TOOLTIP;Se abilitato, Navigatore e Istogramma usano il Profilo di Lavoro anziché il Profilo di Uscita (con gamma) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro PREFERENCES_HLTHRESHOLD;Soglia per le alteluci tosate PREFERENCES_ICCDIR;Cartella profili colore PREFERENCES_IMPROCPARAMS;Parametri predefiniti di elaborazione dell'immagine +PREFERENCES_INSPECT_LABEL;Ispezionare +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Numero massimo di immagini memorizzate nella cache +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Imposta il numero massimo di immagini archiviate nella cache quando passi il mouse sopra di esse nel Browser file; i sistemi con poca RAM (2GB) dovrebbero mantenere questo valore impostato su 1 o 2. +PREFERENCES_INSPECTORWINDOW;Apri la visualizzazione nella tua finestra o a schermo intero PREFERENCES_INTENT_ABSOLUTE;Colorimetrico Assoluto PREFERENCES_INTENT_PERCEPTUAL;Percettivo PREFERENCES_INTENT_RELATIVE;Colorimetrico Relativo PREFERENCES_INTENT_SATURATION;Saturazione PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostra miniatura JPEG incorporata, se il raw non è stato lavorato +PREFERENCES_LANG;Lingua PREFERENCES_LANGAUTODETECT;Usa l'impostazione di lingua del sistema +PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory contenente il database Lensfun. Lascia vuoto per utilizzare le directory predefinite. +PREFERENCES_LENSFUNDBDIR;Directory del database di Lensfun +PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory contenente i profili di correzione dell'obiettivo Adobe (LCP) +PREFERENCES_LENSPROFILESDIR;Directory dei profili degli obiettivi +PREFERENCES_MAXRECENTFOLDERS;Numero massimo di cartelle recenti PREFERENCES_MENUGROUPEXTPROGS;Raggruppa "Apri con" PREFERENCES_MENUGROUPFILEOPERATIONS;Raggruppa "Operazioni sui file" PREFERENCES_MENUGROUPLABEL;Raggruppa "Etichette Colore" PREFERENCES_MENUGROUPPROFILEOPERATIONS;Raggruppa "Operazioni sui profili" PREFERENCES_MENUGROUPRANK;Raggruppa "Classificazioni" PREFERENCES_MENUOPTIONS;Opzioni del menù a discesa +PREFERENCES_METADATA_SYNC_NONE;Spento +PREFERENCES_METADATA_SYNC_READ;Solo lettura +PREFERENCES_METADATA_SYNC_READWRITE;Bidirezionale +PREFERENCES_METADATA_SYNC;Sincronizzazione dei metadati con sidecar XMP +PREFERENCES_METADATA;Metadata +PREFERENCES_MONINTENT;Intento di rendering predefinito +PREFERENCES_MONITOR;Monitor +PREFERENCES_MONPROFILE_WARNOSX;A causa delle limitazioni di MacOS, è supportato solo sRGB. +PREFERENCES_MONPROFILE;Profilo colore predefinito PREFERENCES_MULTITAB;Modalità a Schede Multiple PREFERENCES_MULTITABDUALMON;Modalità a Schede Multiple (se disponibile sul secondo schermo) +PREFERENCES_NAVIGATIONFRAME;Navigazione +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Sovrapponi i nomi dei file alle miniature nel pannello dell'editor PREFERENCES_OVERLAY_FILENAMES;Mostra i nomi dei file sovrapposti alle miniature PREFERENCES_OVERWRITEOUTPUTFILE;Sovrascrivi file esistenti PREFERENCES_PANFACTORLABEL;Fattore @@ -651,19 +1978,43 @@ PREFERENCES_PARSEDEXT;Estensioni riconosciute PREFERENCES_PARSEDEXTADD;Aggiungi un'estensione PREFERENCES_PARSEDEXTADDHINT;Aggiungi l'estensione alla lista. PREFERENCES_PARSEDEXTDELHINT;Rimuovi l'estensione selezionata dalla lista. +PREFERENCES_PARSEDEXTDOWNHINT;Sposta l'estensione selezionata verso il basso nell'elenco. +PREFERENCES_PARSEDEXTUPHINT;Sposta l'estensione selezionata in alto nell'elenco. +PREFERENCES_PERFORMANCE_MEASURE_HINT;Registra i tempi di elaborazione nella console +PREFERENCES_PERFORMANCE_MEASURE;Misurare +PREFERENCES_PERFORMANCE_THREADS_LABEL;Numero massimo di thread per la riduzione del rumore e i livelli wavelet (0 = automatico) +PREFERENCES_PERFORMANCE_THREADS;Discussioni +PREFERENCES_PREVDEMO_FAST;Veloce +PREFERENCES_PREVDEMO_LABEL;Metodo di demosaicizzazione utilizzato per l'anteprima con zoom <100%: +PREFERENCES_PREVDEMO_SIDECAR;Come in PP3 +PREFERENCES_PREVDEMO;Anteprima metodo di Demosaicizzazione +PREFERENCES_PRINTER;Stampa (Soft-Proofing) +PREFERENCES_PROFILE_NONE;Nessuno PREFERENCES_PROFILEHANDLING;Gestione dei profilo di sviluppo PREFERENCES_PROFILELOADPR;Priorità nel caricamento del profilo PREFERENCES_PROFILEPRCACHE;Profilo nella memoria PREFERENCES_PROFILEPRFILE;Profilo a fianco del file originario +PREFERENCES_PROFILESAVEBOTH;Salva il profilo di elaborazione sia nella cache che accanto al file di input PREFERENCES_PROFILESAVECACHE;Salva il profilo di sviluppo nella memoria PREFERENCES_PROFILESAVEINPUT;Salva il profilo di sviluppo a fianco del file originario +PREFERENCES_PROFILESAVELOCATION;Posizione di salvataggio del profilo di elaborazione PREFERENCES_PROPERTY;Proprietà +PREFERENCES_PRTINTENT;Intento di rendering +PREFERENCES_PRTPROFILE;Profilo Colore PREFERENCES_PSPATH;Cartella d'installazione di Adobe Photoshop +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Ricorda la percentuale di zoom e l'offset di panoramica dell'immagine corrente quando si apre una nuova immagine.\n\nQuesta opzione funziona solo in 'Modalità scheda editor singola' e quando 'Metodo di demosaicizzazione utilizzato per l'anteprima con zoom <100%' è impostato su ' Come in PP3'. +PREFERENCES_REMEMBERZOOMPAN;Ricorda la percentuale di zoom e l'offset del pan +PREFERENCES_SAVE_TP_OPEN_NOW;Salva ora lo stato compresso/espanso dello strumento PREFERENCES_SELECTLANG;Seleziona la lingua +PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serializza la lettura dei file TIFF +PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Abilitando questa opzione quando si lavora con cartelle contenenti file TIFF non compressi è possibile aumentare le prestazioni di generazione delle miniature. +PREFERENCES_SERIALIZE_TIFF_READ;Impostazioni di lettura TIFF PREFERENCES_SET;Imposta PREFERENCES_SHOWBASICEXIF;Mostra dati Exif di base PREFERENCES_SHOWDATETIME;Mostra data e ora PREFERENCES_SHOWEXPOSURECOMPENSATION;Accoda compensazione dell'esposizione +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Mostra la barra degli strumenti della sequenza +PREFERENCES_SHOWTOOLTIP;Mostra le descrizioni comandi dei consigli sulle regolazioni locali PREFERENCES_SHTHRESHOLD;Soglia per le ombre tosate PREFERENCES_SINGLETAB;Modalità a Scheda Singola PREFERENCES_SINGLETABVERTAB;Modalità a Scheda Singola, schede verticali @@ -674,13 +2025,42 @@ PREFERENCES_SND_THRESHOLDSECS;dopo un tempo in secondi PREFERENCES_STARTUPIMDIR;Cartella delle immagini all'avvio PREFERENCES_TAB_BROWSER;Navigatore PREFERENCES_TAB_COLORMGR;Gestione Colore +PREFERENCES_TAB_DYNAMICPROFILE;Regole del profilo dinamico +PREFERENCES_TAB_FAVORITES;Preferiti PREFERENCES_TAB_GENERAL;Generale PREFERENCES_TAB_IMPROC;Elaborazione immagine +PREFERENCES_TAB_PERFORMANCE;Prestazione PREFERENCES_TAB_SOUND;Suoni +PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Anteprima JPEG incorporata +PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Immagine da mostrare +PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;JPEG incorporato se a grandezza naturale, raw neutro altrimenti +PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Rendering RAW neutro +PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Strumenti disponibili +PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Se impostati, gli strumenti preferiti verranno visualizzati sia nella scheda dei preferiti che nelle relative schede originali.\n\nNota: l'abilitazione di questa opzione potrebbe comportare un leggero ritardo quando si passa da una scheda all'altra. +PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Mantieni gli strumenti preferiti nelle posizioni originali +PREFERENCES_TOOLPANEL_FAVORITE;Preferito +PREFERENCES_TOOLPANEL_FAVORITESPANEL;Pannello Preferiti +PREFERENCES_TOOLPANEL_TOOL;Strumento PREFERENCES_TP_LABEL;Pannello Strumenti: PREFERENCES_TP_VSCROLLBAR;Nascondi la barra di scorrimento verticale PREFERENCES_USEBUNDLEDPROFILES;Usa profili inclusi +PREFERENCES_WBA;Bilanciamento del bianco +PREFERENCES_WBACORR_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di file raw, colorimetria, ecc.), un adattamento dell'algoritmo "Correlazione della temperatura" per ottenere i migliori risultati complessivi. Non esiste una regola assoluta, che lega questi parametri ai risultati ottenuti.\n\nLe impostazioni sono di 3 tipi: \n* quelle accessibili all'utente dalla GUI.\n* quelle accessibili solo in lettura da ogni file pp3 : Itcwb_minsize =20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (Vedi Rawpedia)\n* quelli accessibili all'utente in 'opzioni' (vedi Rawpedia)\n Puoi usare "Bias temperatura Awb" e "Raffinamento verde" per regolare il risultati. Ogni movimento di questi comandi comporta un nuovo calcolo di temperatura, tinta e correlazione.\n\nNota che i 3 indicatori "Fattore di correlazione", "Crominanza patch" e ΔE sono forniti solo a titolo informativo. Non è perché uno di questi indicatori è migliore che il risultato sarà necessariamente migliore. +PREFERENCES_WBACORR;Bilanciamento del bianco - correlazione automatica della temperatura +PREFERENCES_WBAENA;Mostra le impostazioni automatiche di correlazione della temperatura del bilanciamento del bianco +PREFERENCES_WBAENACUSTOM;Utilizza temperatura e tinta personalizzate +PREFERENCES_WBAFORC;Algoritmo Intensità Extra +PREFERENCES_WBAGREENDELTA;Delta temperatura nel ciclo iterativo verde (se Force Extra è abilitato) +PREFERENCES_WBANOPURP;Nessun colore viola utilizzato +PREFERENCES_WBAPATCH;Numero massimo di colori utilizzati nell'immagine +PREFERENCES_WBAPRECIS;Algoritmo di precisione - scala utilizzata +PREFERENCES_WBASIZEREF;La dimensione del colore di riferimento viene confrontata con la dimensione del colore dell'istogramma +PREFERENCES_WBASORT;Ordina in ordine cromatico anziché in istogramma PREFERENCES_WORKFLOW;Disposizione +PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) +PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) +PREFERENCES_XMP_SIDECAR_MODE;Stile sidecar XMP +PREFERENCES_ZOOMONSCROLL;Ingrandire le immagini scorrendole PROFILEPANEL_COPYPPASTE;Parametri da copiare PROFILEPANEL_GLOBALPROFILES;Profili inclusi PROFILEPANEL_LABEL;Profili di sviluppo @@ -690,6 +2070,7 @@ PROFILEPANEL_MODE_TOOLTIP;Modalità di riempimento del Profilo di Sviluppo.\n\nP PROFILEPANEL_MYPROFILES;Miei profili PROFILEPANEL_PASTEPPASTE;Parametri da incollare PROFILEPANEL_PCUSTOM;Personalizzato +PROFILEPANEL_PDYNAMIC;Dinamico PROFILEPANEL_PFILE;Da file PROFILEPANEL_PINTERNAL;Neutral PROFILEPANEL_PLASTSAVED;Ultimo salvato @@ -699,30 +2080,53 @@ PROFILEPANEL_TOOLTIPCOPY;Copia il profilo corrente negli appunti.\nCtrl-click PROFILEPANEL_TOOLTIPLOAD;Carica profilo da file.\nCtrl-click per selezionare i parametri da caricare. PROFILEPANEL_TOOLTIPPASTE;Incolla il profilo dagli appunti.\nCtrl-click per selezionare i parametri da incollare. PROFILEPANEL_TOOLTIPSAVE;Salva il profilo corrente.\nCtrl-click per selezionare i parametri da salvare. +PROGRESSBAR_DECODING;Decodifica... +PROGRESSBAR_GREENEQUIL;Equilibrio verde... +PROGRESSBAR_HLREC;Ricostruzione alteluci... +PROGRESSBAR_HOTDEADPIXELFILTER;Filtro pixel bruciati/morti... +PROGRESSBAR_LINEDENOISE;Filtro antirumore di linea... PROGRESSBAR_LOADING;Caricamento immagine... PROGRESSBAR_LOADINGTHUMBS;Caricamento miniature... PROGRESSBAR_LOADJPEG;Caricamento JPEG... PROGRESSBAR_LOADPNG;Caricamento PNG... PROGRESSBAR_LOADTIFF;Caricamento TIFF... PROGRESSBAR_NOIMAGES;Nessuna immagine trovata -PROGRESSBAR_PROCESSING;Elaborazione dell'immagine... PROGRESSBAR_PROCESSING_PROFILESAVED;Profilo di sviluppo salvato +PROGRESSBAR_PROCESSING;Elaborazione dell'immagine... +PROGRESSBAR_RAWCACORR;Correzione CA RAW... PROGRESSBAR_READY;Pronto PROGRESSBAR_SAVEJPEG;Salvataggio del file JPEG... PROGRESSBAR_SAVEPNG;Salvataggio del file PNG... PROGRESSBAR_SAVETIFF;Salvataggio del file TIFF... PROGRESSBAR_SNAPSHOT_ADDED;Istantanea aggiunta PROGRESSDLG_PROFILECHANGEDINBROWSER;Profilo di sviluppo modificato nel navigatore +QINFO_FRAMECOUNT;%2 frames +QINFO_HDR;HDR / %2 frame(s) QINFO_ISO;ISO QINFO_NOEXIF;Dati Exif non disponibili. -QUEUE_AUTOSTART;Autoavvia +QINFO_PIXELSHIFT;Spostamento dei pixel / %2 frame(s) QUEUE_AUTOSTART_TOOLTIP;Inizia a sviluppare automaticamente quando un nuovo lavoro viene accodato +QUEUE_AUTOSTART;Autoavvia QUEUE_DESTFILENAME;Percorso e nome file +QUEUE_DESTPREVIEW_TITLE;Seleziona una miniatura per visualizzare qui l'anteprima del percorso di destinazione +QUEUE_DESTPREVIEW_TOOLTIP;Il percorso di destinazione per la prima immagine selezionata viene visualizzato qui QUEUE_FORMAT_TITLE;Formato file QUEUE_LOCATION_FOLDER;Salva nella cartella -QUEUE_LOCATION_TEMPLATE;Usa lo schema QUEUE_LOCATION_TEMPLATE_TOOLTIP;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono ai vari livelli del percorso in cui si trova la foto.\n\nPer esempio, se la foto sviluppata si trovasse nel seguente percorso:\n/home/mario/foto/31-10-2010/dsc0042.nef\nil significato delle stringhe di formattazione sarebbe:\n%d4 = home\n%d3 = mario\n%d2 = foto\n%d1 = 31-10-2010\n%f = dsc0042\n%p1 = /home/mario/foto/31-10-2010/\n%p2 = /home/mario/foto/\n%p3 = /home/mario/\n%p4 = /home/\n\nPer salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nPer salvare l'immagine finale in una cartella chiamata "sviluppate" situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nPer salvare l'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f +QUEUE_LOCATION_TEMPLATE;Usa lo schema +QUEUE_LOCATION_TITLE;Posizione di uscita +QUEUE_STARTSTOP_TOOLTIP;Avvia o interrompe l'elaborazione delle immagini in coda.\n\nScorciatoia: Ctrl+s +SAMPLEFORMAT_0;Formato dati sconosciuto +SAMPLEFORMAT_1;8-bit non firmato +SAMPLEFORMAT_16;16-bit virgola mobile +SAMPLEFORMAT_2;16-bit non firmato +SAMPLEFORMAT_32;24-bit virgola mobile +SAMPLEFORMAT_4;24-bit LogLuv +SAMPLEFORMAT_64;32-bit virgola mobile +SAMPLEFORMAT_8;32-bit LogLuv SAVEDLG_AUTOSUFFIX;Aggiungi automaticamente un suffisso se il file esiste già +SAVEDLG_BIGTIFF;Grande TIFF (no supporto ai metadati) +SAVEDLG_FILEFORMAT_FLOAT; virgola mobile SAVEDLG_FILEFORMAT;Formato file SAVEDLG_FORCEFORMATOPTS;Opzioni di salvataggio forzato SAVEDLG_JPEGQUAL;Qualità JPEG @@ -731,13 +2135,29 @@ SAVEDLG_PUTTOQUEUEHEAD;Metti in cima alla coda di sviluppo SAVEDLG_PUTTOQUEUETAIL;Metti in fondo alla coda di sviluppo SAVEDLG_SAVEIMMEDIATELY;Salva subito SAVEDLG_SAVESPP;Salva i parametri di elaborazione con l'immagine -SAVEDLG_SUBSAMP;Sottocampionamento SAVEDLG_SUBSAMP_1;Migliore Compressione SAVEDLG_SUBSAMP_2;Bilanciato SAVEDLG_SUBSAMP_3;Migliore Qualità +SAVEDLG_SUBSAMP_TOOLTIP;Migliore compressione:\nJ:a:b 4:2:0\nh/v 2/2\nCromaticità dimezzata orizzontalmente e verticalmente.\n\nBilanciato:\nJ:a:b 4:2:2\nh/v 2/ 1\nCromazia dimezzata orizzontalmente.\n\nQualità migliore:\nJ:a:b 4:4:4\nh/v 1/1\nNessun sottocampionamento della crominanza. +SAVEDLG_SUBSAMP;Sottocampionamento SAVEDLG_TIFFUNCOMPRESSED;TIFF non compresso SAVEDLG_WARNFILENAME;Il file verrà chiamato SHCSELECTOR_TOOLTIP;Click destro per ripristinare la posizione di questi tre cursori. +SOFTPROOF_GAMUTCHECK_TOOLTIP;Evidenzia i pixel con colori fuori gamma rispetto a:\n- il profilo della stampante, se impostato e la prova a video abilitata,\n- il profilo di destinazione, se non è impostato un profilo della stampante e la prova a video è abilitata abilitato,\n- il profilo del monitor, se il soft-proof è disabilitato. +SOFTPROOF_TOOLTIP;La prova colore simula l'aspetto dell'immagine:\n- quando viene stampata, se è impostato un profilo stampante in Preferenze > Gestione colore,\n- quando viene visualizzata su un display che utilizza il profilo di destinazione corrente, se non è impostato un profilo stampante . +SORT_ASCENDING;Ascendente +SORT_BY_DATE;Per data +SORT_BY_EXIF;Per EXIF +SORT_BY_LABEL;Per etichetta colore +SORT_BY_NAME;Per nome +SORT_BY_RANK;Per posizione +SORT_DESCENDING;Discendente +TC_PRIM_BLUX;Bx +TC_PRIM_BLUY;By +TC_PRIM_GREX;Gx +TC_PRIM_GREY;Gy +TC_PRIM_REDX;Rx +TC_PRIM_REDY;Ry THRESHOLDSELECTOR_B;Basso THRESHOLDSELECTOR_BL;Basso-Sinistra THRESHOLDSELECTOR_BR;Basso-Destra @@ -745,24 +2165,25 @@ THRESHOLDSELECTOR_HINT;Tieni premuto Maiuscolo per muovere un singolo pun THRESHOLDSELECTOR_T;Alto THRESHOLDSELECTOR_TL;Alto-Sinistra THRESHOLDSELECTOR_TR;Alto-Destra +TOOLBAR_TOOLTIP_COLORPICKER;Selettore colore bloccabile\n\nQuando lo strumento è attivo:\n- Aggiungi un selettore: fai clic con il pulsante sinistro del mouse.\n- Trascina un selettore: fai clic con il pulsante sinistro del mouse e trascina. \n- Elimina un selettore: fai clic con il pulsante destro del mouse.\n- Elimina tutti i selettori: Ctrl+Maiusc+fai clic con il pulsante destro del mouse< /b>.\n- Torna allo strumento manuale: fai clic con il pulsante destro del mouse all'esterno di qualsiasi selettore. TOOLBAR_TOOLTIP_CROP;Ritaglia la selezione.\nScorciatoia: c\nSposta l'area di ritaglio tenendo premuto Maiuscolo mentre muovi il mouse TOOLBAR_TOOLTIP_HAND;Strumento mano.\nScorciatoia: h +TOOLBAR_TOOLTIP_PERSPECTIVE;Correzione prospettica\n\nModifica le linee di controllo per correggere la distorsione prospettica. Fare di nuovo clic su questo pulsante per applicare la correzione. TOOLBAR_TOOLTIP_STRAIGHTEN;Linea Dritta/Rotazione Precisa.\nScorciatoia: s\n\nTraccia il verticale o l'orizzontale disegnando una linea sull'anteprima dell'immagine. L'angolo di rotazione verrà mostrato accanto alla linea guida. Il centro della rotazione è il centro geometrico dell'immagine. TOOLBAR_TOOLTIP_WB;Bilanciamento del bianco puntuale.\nScorciatoia: w -TP_BWMIX_ALGO;Algoritmo OYCPM TP_BWMIX_ALGO_LI;Lineare TP_BWMIX_ALGO_SP;Effetti speciali TP_BWMIX_ALGO_TOOLTIP;Lineare: produrrà una risposta normale lineare.\nEffetti speciali: produrrà effetti speciali miscelando i canali non-linearmente. +TP_BWMIX_ALGO;Algoritmo OYCPM TP_BWMIX_AUTOCH;Auto TP_BWMIX_CC_ENABLED;Regola il colore complementare TP_BWMIX_CC_TOOLTIP;Abilita per consentire le regolazioni automatiche dei colori complementari nella modalità ROYGCBPM. TP_BWMIX_CHANNEL;Equalizzatore di Luminanza -TP_BWMIX_CURVEEDITOR1;Curva 'Prima' -TP_BWMIX_CURVEEDITOR2;Curva 'Dopo' TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Curva Tono, dopo la conversione B&W, alla fine del trattamento. TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Curva Tono, appena prima della conversione B&W.\nPuò prendere in considerazione le componenti colore. TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminosità secondo Tonalità L=f(H).\nFai attenzione ai valori estermi: possono generare artefatti. -TP_BWMIX_FILTER;Filtro Colore +TP_BWMIX_CURVEEDITOR1;Curva 'Prima' +TP_BWMIX_CURVEEDITOR2;Curva 'Dopo' TP_BWMIX_FILTER_BLUE;Blu TP_BWMIX_FILTER_BLUEGREEN;Blu-Verde TP_BWMIX_FILTER_GREEN;Verde @@ -773,18 +2194,19 @@ TP_BWMIX_FILTER_RED;Rosso TP_BWMIX_FILTER_REDYELLOW;Rosso-Giallo TP_BWMIX_FILTER_TOOLTIP;Il filtro colore simula uno scatto con un filtro colorato posto davanti all'obiettivo. I filtri colorati riducono la trasmissione di uno specifico intervallo di colori modificando la loro luminosità. Ad esempio, un filtro rosso scurisce i cieli blu. TP_BWMIX_FILTER_YELLOW;Giallo -TP_BWMIX_GAMMA;Correzione Gamma +TP_BWMIX_FILTER;Filtro Colore TP_BWMIX_GAM_TOOLTIP;Corregge il gamma per ogni canale RGB. +TP_BWMIX_GAMMA;Correzione Gamma TP_BWMIX_LABEL;Bianco-Nero -TP_BWMIX_MET;Metodo TP_BWMIX_MET_CHANMIX;Miscelatore Canali TP_BWMIX_MET_DESAT;Desaturazione TP_BWMIX_MET_LUMEQUAL;Equalizzatore di Luminanza -TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totale: %4%% -TP_BWMIX_RGBLABEL_HINT;Fattori RGB finali che si occupano di tutte le opzioni del miscelatore.\n"Totale" mostra la somma dei valori RGB:\n- sempre 100% nella modalità relativa\n- Più alto (luminoso) or più basso (scuro) del 100% nella modalità assoluta. +TP_BWMIX_MET;Metodo +TP_BWMIX_MIXC;Miscelatore di canali +TP_BWMIX_NEUTRAL;Ripristina TP_BWMIX_RGB_TOOLTIP;Miscela i canali RGB. Usa i valori preimpostati per orientarti.\nFai attenzione ai valori negativi: possono causare artefatti o comportamenti imprevisti. -TP_BWMIX_SETTING;Preimpostazioni -TP_BWMIX_SETTING_TOOLTIP;Impostazioni delle Preimpostazioni (pellicola, panorama, etc.) o del Miscelatore Canali manuale. +TP_BWMIX_RGBLABEL_HINT;Fattori RGB finali che si occupano di tutte le opzioni del miscelatore.\n"Totale" mostra la somma dei valori RGB:\n- sempre 100% nella modalità relativa\n- Più alto (luminoso) or più basso (scuro) del 100% nella modalità assoluta. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totale: %4%% TP_BWMIX_SET_HIGHCONTAST;Contrasto Elevato TP_BWMIX_SET_HIGHSENSIT;Sensibilità Elevata TP_BWMIX_SET_HYPERPANCHRO;Iper-Pancromatica @@ -800,6 +2222,8 @@ TP_BWMIX_SET_RGBABS;RGB assoluto TP_BWMIX_SET_RGBREL;RGB relativo TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM assoluto TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM relativo +TP_BWMIX_SETTING_TOOLTIP;Impostazioni delle Preimpostazioni (pellicola, panorama, etc.) o del Miscelatore Canali manuale. +TP_BWMIX_SETTING;Preimpostazioni TP_BWMIX_TCMODE_FILMLIKE;BN tipo pellicola TP_BWMIX_TCMODE_SATANDVALBLENDING;BN Fusione Saturazione e Valore TP_BWMIX_TCMODE_STANDARD;BN Standard @@ -808,6 +2232,10 @@ TP_BWMIX_VAL;L TP_CACORRECTION_BLUE;Blu TP_CACORRECTION_LABEL;Correzione AC TP_CACORRECTION_RED;Rosso +TP_CBDL_AFT;Dopo il bianco e nero +TP_CBDL_BEF;Prima del bianco e nero +TP_CBDL_METHOD_TOOLTIP;Scegliere se lo strumento Contrasto per livelli di dettaglio deve essere posizionato dopo lo strumento Bianco e nero, che lo fa funzionare nello spazio L*a*b*, o prima di esso, che lo fa funzionare nello spazio RGB. +TP_CBDL_METHOD;Processo individuato TP_CHMIXER_BLUE;Canale Blu TP_CHMIXER_GREEN;Canale Verde TP_CHMIXER_LABEL;Miscelatore Canali @@ -816,54 +2244,88 @@ TP_COARSETRAF_TOOLTIP_HFLIP;Rifletti orizzontalmente. TP_COARSETRAF_TOOLTIP_ROTLEFT;Ruota a sinistra.\nScorciatoie:\n[ - Modalità a Scheda Multipla,\nAlt-[ - Modalità a Scheda Singola. TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra.\nScorciatoie:\n] - Modalità a Scheda Multipla,\nAlt-] - Modalità a Scheda Singola. TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente -TP_COLORAPP_ALGO;Algoritmo +TP_COLORAPP_ABSOLUTELUMINANCE;Luminanza assoluta +TP_COLORAPP_ADAPSCEN_TOOLTIP;Corrisponde alla luminanza in candele per m2 al momento dello scatto, calcolata automaticamente dai dati EXIF. TP_COLORAPP_ALGO_ALL;Tutto TP_COLORAPP_ALGO_JC;Chiarezza + Croma (JC) TP_COLORAPP_ALGO_JS;Chiarezza + Saturazione (JS) TP_COLORAPP_ALGO_QM;Brillanza + Pienezza (QM) TP_COLORAPP_ALGO_TOOLTIP;Scegli un sottoinsieme di parametri o tutti -TP_COLORAPP_BADPIXSL;Filtro pixel surriscaldati/guasti +TP_COLORAPP_ALGO;Algoritmo TP_COLORAPP_BADPIXSL_TOOLTIP;Soppressione dei pixel surriscaldati/guasti (eccessivamente colorati).\n0 = nessun effetto\n1 = mediana\n2 = gaussiana.\n\nQuesti artefatti derivano dalle limitazioni di CIECAM02. Alternativamente, regola l'immagine per evitare ombre eccessivamente scure. -TP_COLORAPP_BRIGHT;Brillanza (Q) +TP_COLORAPP_BADPIXSL;Filtro pixel surriscaldati/guasti TP_COLORAPP_BRIGHT_TOOLTIP;La Brillanza in CIECAM02 prende in considerazione la luminosità del bianco ed è diversa da quella in Lab e RGB. -TP_COLORAPP_CHROMA;Croma (C) -TP_COLORAPP_CHROMA_M;Pienezza (M) +TP_COLORAPP_BRIGHT;Brillanza (Q) +TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Quando si imposta manualmente, si consigliano valori superiori a 65. +TP_COLORAPP_CATCLASSIC;Classico +TP_COLORAPP_CATMET_TOOLTIP;Classico - funzionamento tradizionale CIECAM. Le trasformazioni dell'adattamento cromatico vengono applicate separatamente su 'Condizioni della scena' e illuminante di base da un lato, e su illuminante di base e 'Condizioni di visualizzazione' dall'altro.\n\nSimmetrico: l'adattamento cromatico si basa sul bilanciamento del bianco. Le impostazioni 'Condizioni scena', 'Regolazioni immagine' e 'Condizioni di visualizzazione' vengono neutralizzate.\n\nMisto: come l'opzione 'Classico' ma in questo caso l'adattamento cromatico si basa sul bilanciamento del bianco. +TP_COLORAPP_CATMOD;Modo +TP_COLORAPP_CATSYMGEN;Simmetrico automatico +TP_COLORAPP_CATSYMSPE;Misto TP_COLORAPP_CHROMA_M_TOOLTIP;La Pienezza in CIECAM02 è diversa da quella in Lab e RGB. -TP_COLORAPP_CHROMA_S;Saturazione (S) +TP_COLORAPP_CHROMA_M;Pienezza (M) TP_COLORAPP_CHROMA_S_TOOLTIP;La Saturazione in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA_S;Saturazione (S) TP_COLORAPP_CHROMA_TOOLTIP;Il Croma in CIECAM02 è diverso da quello in Lab e RGB. +TP_COLORAPP_CHROMA;Croma (C) TP_COLORAPP_CIECAT_DEGREE;Adattamento CAT02 -TP_COLORAPP_CONTRAST;Contrasto (J) -TP_COLORAPP_CONTRAST_Q;Contrasto (Q) +TP_COLORAPP_CIECAT_DEGREEOUT;Visualizzazione dell'adattamento cromatico TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrasto per il cursore Q in CIECAM02; è diverso da quello in Lab e RGB. +TP_COLORAPP_CONTRAST_Q;Contrasto (Q) TP_COLORAPP_CONTRAST_TOOLTIP;Contrasto per il cursore J in CIECAM02; è diverso da quello in Lab e RGB. -TP_COLORAPP_CURVEEDITOR1;Curva Tono 1 +TP_COLORAPP_CONTRAST;Contrasto (J) TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Mostra l'istogramma di L (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, mostra gli istogrammi di J o Q dopo CIECAM02.\n\nJ e Q non sono mostrati nel pannello Istogramma.\n\nPer l'output finale fare riferimento al pannello Istogramma -TP_COLORAPP_CURVEEDITOR2;Curva Tono 2 +TP_COLORAPP_CURVEEDITOR1;Curva Tono 1 TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Stesso utilizzo della Curva Tono 2 di Esposizione -TP_COLORAPP_CURVEEDITOR3;Curva Colore +TP_COLORAPP_CURVEEDITOR2;Curva Tono 2 TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Regola Croma, Saturazione o Pienezza.\nL'Istogramma mostra la Cromaticità (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, l'Istogramma mostra C, s e M dopo CIECAM02.\nC, s e M non sono mostrati direttamente nel pannello Istogramma.\nPer l'output finale fare riferimento al pannello Istogramma -TP_COLORAPP_DATACIE;Mostra gli istogrammi di uscita CIECAM02 nelle curve +TP_COLORAPP_CURVEEDITOR3;Curva Colore TP_COLORAPP_DATACIE_TOOLTIP;Quando abilitato, gli istogrammi nelle curve CIECAM02 mostrano valori e intervalli approssimati di J o Q, e C, s o M dopo le regolazioni CIECAM02.\nQuesta selezione non ha effetto nel pannello Istogramma principale.\n\nQuando disabilitato, gli istogrammi nelle curve CIECAM02 mostrano i valori Lab, come sono prima delle regolazioni CIECAM02. +TP_COLORAPP_DATACIE;Mostra gli istogrammi di uscita CIECAM02 nelle curve +TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 è un adattamento cromatico. Converte i valori di un'immagine il cui punto di bianco è quello di un dato illuminante (ad esempio D65) in nuovi valori il cui punto di bianco è quello del nuovo illuminante - vedi modello WP (ad esempio D50 o D55). +TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 è un adattamento cromatico. Converte i valori di un'immagine il cui punto di bianco è quello di un dato illuminante (ad esempio D50) in nuovi valori il cui punto di bianco è quello del nuovo illuminante - vedi modello WP (ad esempio D75). +TP_COLORAPP_FREE;Temp. libera + tinta + CAT02/16 +[uscita] TP_COLORAPP_GAMUT;Controllo Gamut (Lab) -TP_COLORAPP_HUE;Tinta (h) +TP_COLORAPP_GEN_TOOLTIP;Questo modulo si basa sui modelli di aspetto del colore CIECAM, progettati per simulare meglio il modo in cui la visione umana percepisce i colori in diverse condizioni di illuminazione, ad es. contro contesti diversi. Tiene conto dell'ambiente di ciascun colore e ne modifica l'aspetto per avvicinarsi il più possibile alla percezione umana. Inoltre, adatta l'output alle condizioni di visualizzazione previste (monitor, TV, proiettore, stampante, ecc.) in modo che l'aspetto cromatico venga preservato nella scena e negli ambienti di visualizzazione. +TP_COLORAPP_GEN;Impostazioni TP_COLORAPP_HUE_TOOLTIP;Tinta (h) - angolo tra 0° e 360° -TP_COLORAPP_LABEL;Modello di Aspetto Colore CIE 2002 +TP_COLORAPP_HUE;Tinta (h) +TP_COLORAPP_IL41;D41 +TP_COLORAPP_IL50;D50 +TP_COLORAPP_IL55;D55 +TP_COLORAPP_IL60;D60 +TP_COLORAPP_IL65;D65 +TP_COLORAPP_IL75;D75 +TP_COLORAPP_ILA;Incandescente StdA 2856K +TP_COLORAPP_ILFREE;Libero +TP_COLORAPP_ILLUM_TOOLTIP;Seleziona l'illuminante più vicino alle condizioni di scatto.\nIn generale D50, ma può cambiare a seconda dell'ora e della latitudine. +TP_COLORAPP_ILLUM;Illuminante TP_COLORAPP_LABEL_CAM02;Regolazioni Immagine TP_COLORAPP_LABEL_SCENE;Caratteristiche della scena TP_COLORAPP_LABEL_VIEWING;Caratteristiche della visualizzazione -TP_COLORAPP_LIGHT;Chiarezza (J) +TP_COLORAPP_LABEL;Modello di Aspetto Colore CIE 2002 TP_COLORAPP_LIGHT_TOOLTIP;La Chiarezza in CIECAM02 è diversa da quella in Lab e RGB. -TP_COLORAPP_MODEL;Modello del Punto di Bianco +TP_COLORAPP_LIGHT;Chiarezza (J) +TP_COLORAPP_MEANLUMINANCE;Luminanza media (Yb%) +TP_COLORAPP_MOD02;CAM02 +TP_COLORAPP_MOD16;CAM16 TP_COLORAPP_MODEL_TOOLTIP;Modello del Punto di bianco.\n\nWB [RT] + [output]: Per la scena viene usato il Bilanciamento del Bianco di RT, CIECAM02 è impostato a D50, il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore.\n\nWB [RT+CAT02] + [output]: Le impostazioni di Bilanciamento del Bianco di RT sono utilizzate da CAT02 e il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore. -TP_COLORAPP_RSTPRO;Protezione rossi e incarnato +TP_COLORAPP_MODEL;Modello del Punto di Bianco +TP_COLORAPP_MODELCAT_TOOLTIP;Ti consente di scegliere tra CAM02 o CAM16.\nCAM02 a volte sarà più preciso.\nCAM16 dovrebbe generare meno artefatti. +TP_COLORAPP_MODELCAT;CAM +TP_COLORAPP_NEUTRAL_TOOLTIP;Ripristina tutte le caselle di controllo e le curve dei cursori ai valori predefiniti. +TP_COLORAPP_NEUTRAL;Reset TP_COLORAPP_RSTPRO_TOOLTIP;Protezione dei toni rossi e dell'incarnato (cursori e curve) -TP_COLORAPP_SURROUND;Ambiente +TP_COLORAPP_RSTPRO;Protezione rossi e incarnato +TP_COLORAPP_SOURCEF_TOOLTIP;Corrisponde alle condizioni di ripresa e a come riportare le condizioni e i dati in un'area "normale". Normale significa condizioni e dati medi o standard, ovvero senza tenere conto delle correzioni CIECAM. TP_COLORAPP_SURROUND_AVER;Medio TP_COLORAPP_SURROUND_DARK;Scuro TP_COLORAPP_SURROUND_DIM;Fioco TP_COLORAPP_SURROUND_EXDARK;Estremamente Scuro (Pieghevole) TP_COLORAPP_SURROUND_TOOLTIP;Cambia toni e colori per tenere conto delle condizioni di visualizzazione del dispositivo di uscita\n\nMedio: Ambiente mediamente illuminato (standard)\nL'immagine non verrà modificata.\n\nFioco: Ambiente fioco (TV)\nL'immagine diverrà leggermente più scura\n\nScuro: Ambiente scuro (proiettore)\nL'immagine diventerà più scura\n\nEstremamente Scuro: Ambiente buio (Pieghevole)\nL'immagine diventerà molto più scura. +TP_COLORAPP_SURROUND;Ambiente +TP_COLORAPP_SURROUNDSRC;Circondare +TP_COLORAPP_SURSOURCE_TOOLTIP;Modifica toni e colori per tenere conto delle condizioni circostanti dell'illuminazione della scena. Quanto più scure sono le condizioni circostanti, tanto più luminosa risulterà l'immagine. La luminosità dell'immagine non verrà modificata quando il surround è impostato su medio. TP_COLORAPP_TCMODE_BRIGHTNESS;Brillanza TP_COLORAPP_TCMODE_CHROMA;Croma TP_COLORAPP_TCMODE_COLORF;Pienezza @@ -872,21 +2334,91 @@ TP_COLORAPP_TCMODE_LABEL2;Modo Curva 2 TP_COLORAPP_TCMODE_LABEL3;Modo Curva Croma TP_COLORAPP_TCMODE_LIGHTNESS;Chiarezza TP_COLORAPP_TCMODE_SATUR;Saturazione -TP_COLORAPP_TONECIE;Tone mapping con CIECAM02 +TP_COLORAPP_TEMP_TOOLTIP;Per selezionare un illuminante impostare sempre Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TEMP2_TOOLTIP;Modalità simmetrica Temp = Bilanciamento del bianco.\nSeleziona illuminante impostato sempre Tinta=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504 \nD75 temperatura=7504 +TP_COLORAPP_TEMPOUT_TOOLTIP;Temperatura e Tinta.\nA seconda delle scelte effettuate in precedenza, la temperatura selezionata è:\nBilanciamento del bianco\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504 \nD75 temp=7504\nLibero. TP_COLORAPP_TONECIE_TOOLTIP;Se questa opzione è disabilitata, il Tone Mapping è eseguito nello spazio Lab.\nSe l'opzione è abilitata, il Tone Mapping è fatto usando CIECAM02.\nLo strumento Tone Mapping (Lab/CIECAM02) deve essere abilitato affinché questa impostazione abbia effetto. +TP_COLORAPP_TONECIE;Tone mapping con CIECAM02 TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Luminanza assoluta dell'ambiente di visualizzazione\n(normalmente 16cd/m²). +TP_COLORAPP_VIEWINGF_TOOLTIP;Tiene conto del supporto su cui verrà visualizzata l'immagine finale (monitor, TV, proiettore, stampante, ecc.), nonché del suo ambiente. Questo processo prenderà i dati provenienti dal processo 'Regolazioni immagine' e li 'porterà' al supporto in modo tale che le condizioni di visualizzazione e il suo ambiente siano presi in considerazione. TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] TP_COLORAPP_WBRT;WB [RT] + [output] +TP_COLORAPP_YBOUT_TOOLTIP;Yb è la luminanza relativa dello sfondo, espressa in % di grigio. Il 18% di grigio corrisponde ad una luminanza di sfondo del 50% espressa in CIE L.\nI dati si basano sulla luminanza media dell'immagine. +TP_COLORAPP_YBSCEN_TOOLTIP;Yb è la luminanza relativa dello sfondo, espressa in % di grigio. Il 18% di grigio corrisponde ad una luminanza di sfondo del 50% espressa in CIE L.\nI dati si basano sulla luminanza media dell'immagine. +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatico +TP_COLORTONING_BALANCE;Balanciato +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Opacità +TP_COLORTONING_COLOR;Colore: +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Opacità cromatica in funzione della luminanza oC=f(L). +TP_COLORTONING_HIGHLIGHT;Alteluci +TP_COLORTONING_HUE;Tonalità +TP_COLORTONING_LAB;L*a*b* miscelazione +TP_COLORTONING_LABEL;Toni Colore +TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 +TP_COLORTONING_LABGRID;L*a*b* griglia correzione colore +TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 +TP_COLORTONING_LABREGION_CHANNEL_ALL;Tutto +TP_COLORTONING_LABREGION_CHANNEL_B;Blu +TP_COLORTONING_LABREGION_CHANNEL_G;Verde +TP_COLORTONING_LABREGION_CHANNEL_R;Rosso +TP_COLORTONING_LABREGION_CHANNEL;Canale +TP_COLORTONING_LABREGION_CHROMATICITYMASK;C +TP_COLORTONING_LABREGION_HUEMASK;H +TP_COLORTONING_LABREGION_LIGHTNESS;Luminosità +TP_COLORTONING_LABREGION_LIGHTNESSMASK;L +TP_COLORTONING_LABREGION_LIST_TITLE;Correzione +TP_COLORTONING_LABREGION_MASK;Maschera +TP_COLORTONING_LABREGION_MASKBLUR;Maschera di sfocatura +TP_COLORTONING_LABREGION_OFFSET;Compensazione +TP_COLORTONING_LABREGION_POWER;Potenza +TP_COLORTONING_LABREGION_SATURATION;Saturazione +TP_COLORTONING_LABREGION_SHOWMASK;Mostra maschera +TP_COLORTONING_LABREGION_SLOPE;Pendenza +TP_COLORTONING_LABREGIONS;Zona correzione colore +TP_COLORTONING_LUMA;Luminanza +TP_COLORTONING_LUMAMODE_TOOLTIP;Se abilitato, quando si cambia colore (rosso, verde, ciano, blu, ecc.) viene preservata la luminanza di ciascun pixel. +TP_COLORTONING_LUMAMODE;Preserva la luminanza +TP_COLORTONING_METHOD_TOOLTIP;"Miscelazione L*a*b*", "Cursori RGB" e "Curve RGB" utilizzano la fusione dei colori interpolati.\n"Bilanciamento colore (ombre/mezzitoni/luci)" e "Saturazione 2 colori" utilizzano colori diretti.\n\ nLo strumento Bianco e nero può essere abilitato quando si utilizza qualsiasi metodo di tonalità del colore che consenta la tonalità del colore. +TP_COLORTONING_METHOD;Metodo +TP_COLORTONING_MIDTONES;Mezzitoni +TP_COLORTONING_NEUTRAL_TOOLTIP;Ripristina tutti i valori (ombre, mezzitoni, luci) ai valori predefiniti. +TP_COLORTONING_NEUTRAL;Ripristina i cursori +TP_COLORTONING_OPACITY;Opacità: +TP_COLORTONING_RGBCURVES;RGB - Curve +TP_COLORTONING_RGBSLIDERS;RGB - Cursori +TP_COLORTONING_SA;Protezione dalla saturazione +TP_COLORTONING_SATURATEDOPACITY;Intensità +TP_COLORTONING_SATURATIONTHRESHOLD;Soglia +TP_COLORTONING_SHADOWS;Ombre +TP_COLORTONING_SPLITCO;Ombre/Mezzitoni/Alteluci +TP_COLORTONING_SPLITCOCO;Balanciamento Colore Ombre/Mezzitoni/Alteluci +TP_COLORTONING_SPLITLR;Saturazione 2 colori +TP_COLORTONING_STR;Intensità +TP_COLORTONING_STRENGTH;Intensità +TP_COLORTONING_TWO2;Cromia Speciale '2 colori' +TP_COLORTONING_TWOALL;Cromia speciale +TP_COLORTONING_TWOBY;Speciale a* e b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Crominanza standard:\nRisposta lineare, a* = b*.\n\nCrominanza speciale:\nRisposta lineare, a* = b*, ma non legata: provare sotto la diagonale.\n\nSpeciale a* e b*:\nRisposta lineare non legato con curve separate per a* e b*. Destinato agli effetti speciali.\n\nColori speciali Chroma 2:\nPiù prevedibili. +TP_COLORTONING_TWOSTD;Cromia Standard TP_CROP_FIXRATIO;Rapporto fisso: +TP_CROP_GTCENTEREDSQUARE;Quadrato centrato TP_CROP_GTDIAGONALS;Regola delle diagonali TP_CROP_GTEPASSPORT;Passaporto Biometrico TP_CROP_GTFRAME;Fotogramma TP_CROP_GTGRID;Griglia +TP_CROP_GTHARMMEANS;Mezzi armonici TP_CROP_GTNONE;Nessuna TP_CROP_GTRULETHIRDS;Regola dei terzi +TP_CROP_GTTRIANGLE1;Triangoli d'oro 1 +TP_CROP_GTTRIANGLE2;Triangoli d'oro 2 TP_CROP_GUIDETYPE;Tipo di guida: TP_CROP_H;A TP_CROP_LABEL;Ritaglio +TP_CROP_PPI;PPI +TP_CROP_RESETCROP;Ripristina +TP_CROP_SELECTCROP;Selezione TP_CROP_W;L TP_CROP_X;X TP_CROP_Y;Y @@ -895,60 +2427,141 @@ TP_DARKFRAME_LABEL;Dark Frame TP_DEFRINGE_LABEL;Defringe TP_DEFRINGE_RADIUS;Raggio TP_DEFRINGE_THRESHOLD;Soglia +TP_DEHAZE_DEPTH;Doppio +TP_DEHAZE_LABEL;Rimuove foschia +TP_DEHAZE_SATURATION;Saturazione +TP_DEHAZE_SHOW_DEPTH_MAP;Mostra doppia mappa +TP_DEHAZE_STRENGTH;Intensità +TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Multizona automatica +TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Globale automatico TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Crominanza - Blu-Giallo +TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Aumenta (moltiplica) il valore di tutti i cursori della crominanza.\nQuesta curva consente di regolare l'intensità della riduzione del rumore cromatico in funzione della cromaticità, ad esempio per aumentare l'azione nelle aree a bassa saturazione e per diminuirla in quelle ad alta saturazione. +TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Curva di crominanza +TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Crominanza +TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Manuale TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Crominanza (Principale) +TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manuale\nAgisce sull'immagine intera.\nControlli manualmente le impostazioni di riduzione del rumore.\n\nGlobale automatico\nAgisce sull'immagine intera.\n9 zone vengono utilizzate per calcolare un'impostazione globale di riduzione del rumore della crominanza.\n\nMultizone automatiche \nNessuna anteprima: funziona solo durante il salvataggio, ma utilizzando il metodo 'Anteprima' facendo corrispondere la dimensione e il centro della tessera alla dimensione e al centro dell'anteprima puoi avere un'idea dei risultati attesi.\nL'immagine è divisa in tessere (da circa 10 a 70 a seconda della dimensione dell'immagine) e ogni riquadro riceve le proprie impostazioni di riduzione del rumore della crominanza.\n\nAnteprima\nAgisce sull'intera immagine.\nLa parte dell'immagine visibile nell'anteprima viene utilizzata per calcolare le impostazioni globali di riduzione del rumore della crominanza. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Metodo +TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Manuale\nAgisce sull'immagine intera.\nControlli manualmente le impostazioni di riduzione del rumore.\n\nGlobale automatico\nAgisce sull'immagine intera.\n9 zone vengono utilizzate per calcolare un'impostazione globale di riduzione del rumore della crominanza.\n\nAnteprima\nAgisce su l'intera immagine.\nLa parte dell'immagine visibile nell'anteprima viene utilizzata per calcolare le impostazioni globali di riduzione del rumore della crominanza. +TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Anteprima multizona +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Dimensione anteprima=%1, Centro: Px=%2 Py=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Preview noise: Mean= - High= - +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Rumore dell'anteprima: Medio=%1 Alto=%2 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Dimensione tessera=%1, Centro: Tx=%2 Ty=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Anteprima +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Visualizza i livelli di rumore rimanenti della parte dell'immagine visibile nell'anteprima dopo il wavelet.\n\n>300 Molto rumoroso\n100-300 Rumoroso\n50-100 Un po' rumoroso\n<50 Rumore molto basso\n\nAttenzione, i valori differiranno tra la modalità RGB e L*a*b*. I valori RGB sono meno accurati perché la modalità RGB non separa completamente luminanza e crominanza. TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Crominanza - Rosso-Verde +TP_DIRPYRDENOISE_LABEL;Riduzione del rumore +TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Controllo della luminanza +TP_DIRPYRDENOISE_LUMINANCE_CURVE;Curva di luminanza TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Dettaglio di Luminanza +TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminanza TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminanza -TP_DIRPYRDENOISE_MAIN_COLORSPACE;Metodo +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Modificare l'intensità della riduzione del rumore in base alla luminosità dell'immagine. L'intensità viene ridotta per le immagini scure e aumentata per le immagini luminose. +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensazione per leggerezza TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;Lab TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Per immagini raw può essere usato il metodo RGB o Lab.\n\nPer immagini non raw verrà utilizzato il metodo Lab, indipendentemente dalla selezione. -TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma +TP_DIRPYRDENOISE_MAIN_COLORSPACE;Metodo TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Il gamma varia la forza della riduzione rumore su tutto l'intervallo di toni. Valori più piccoli incideranno sulle ombre, mentre valori maggiori estenderanno l'effetto ai toni più luminosi. -TP_DIRPYREQUALIZER_ALGO;Algoritmo Pelle +TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma +TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Aggressivo +TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Conservativo +TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;Il conservativo preserva i modelli di crominanza a bassa frequenza, mentre l'aggressivo li cancella. +TP_DIRPYRDENOISE_MAIN_MODE;Modo +TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Solo crominanza +TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* +TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Filtro mediano +TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Solo luminanza +TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB +TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;Quando si utilizzano i metodi "Solo luminanza" e "L*a*b*", il filtraggio mediano verrà eseguito subito dopo il passaggio wavelet nella pipeline di riduzione del rumore.\nQuando si utilizza la modalità "RGB", verrà eseguito proprio fine del gasdotto di riduzione del rumore. +TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Ponderato L* (poco) + a*b* (normale) +TP_DIRPYRDENOISE_MEDIAN_METHOD;Metodo mediano +TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;L'applicazione di tre iterazioni del filtro mediano con una dimensione della finestra 3×3 spesso porta a risultati migliori rispetto all'utilizzo di un'iterazione del filtro mediano con una dimensione della finestra 7×7. +TP_DIRPYRDENOISE_MEDIAN_PASSES;Iterazioni mediane +TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Applicare un filtro medio della dimensione della finestra desiderata. Maggiore è la dimensione della finestra, maggiore è il tempo necessario.\n\n3×3 soft: tratta 5 pixel in una finestra di 3×3 pixel.\n3×3: tratta 9 pixel in una finestra di 3×3 pixel.\n5×5 soft: tratta 13 pixel in una finestra da 5×5 pixel.\n5×5: tratta 25 pixel in una finestra da 5×5 pixel.\n7×7: tratta 49 pixel in una finestra da 7×7 pixel.\n9×9: tratta 81 pixel in una finestra di 9×9 pixel.\n\nA volte è possibile ottenere una qualità superiore eseguendo diverse iterazioni con una dimensione della finestra più piccola rispetto a un'iterazione con una più grande. +TP_DIRPYRDENOISE_MEDIAN_TYPE;Tipo mediano +TP_DIRPYRDENOISE_TYPE_3X3;3×3 +TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 soft +TP_DIRPYRDENOISE_TYPE_5X5;5×5 +TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 soft +TP_DIRPYRDENOISE_TYPE_7X7;7×7 +TP_DIRPYRDENOISE_TYPE_9X9;9×9 TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: più simile ai colori dell'incarnato, minimizzando l'azione di altri colori\nAmpio: evita ulteriori artefatti -TP_DIRPYREQUALIZER_HUESKIN;Tonalità della Pelle +TP_DIRPYREQUALIZER_ALGO;Algoritmo Pelle +TP_DIRPYREQUALIZER_ARTIF;Ridurre gli artefatti TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Questa piramide è per la parte superiore, con l'algoritmo alla sua massima efficienza.\nNella parte inferiore, le zone di transizione.\nSe devi muovere in modo significativo la zona verso destra o verso sinistra (o se ci sono artefatti): il bilanciamento del bianco è sbagliato\nPuoi ridurre leggermente la zona per evitare che la parte rimante dell'immagine ne sia influenzata +TP_DIRPYREQUALIZER_HUESKIN;Tonalità della Pelle TP_DIRPYREQUALIZER_LABEL;Contrasto per livelli di dettaglio (CbDL) TP_DIRPYREQUALIZER_LUMACOARSEST;Estesissimo TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrasto- TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrasto+ TP_DIRPYREQUALIZER_LUMAFINEST;Finissimo TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutro -TP_DIRPYREQUALIZER_SKIN;Toni della Pelle - Elaborazione/Protezione TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100 i toni della pelle sono elaborati.\nA 0 tutti i toni sono trattati allo stesso modo.\nA +100 i toni della pelle sono protetti mentre gli altri toni sono elaborati. +TP_DIRPYREQUALIZER_SKIN;Toni della Pelle - Elaborazione/Protezione TP_DIRPYREQUALIZER_THRESHOLD;Soglia TP_DIRPYREQUALIZER_TOOLTIP;Tenta di ridurre gli artefatti dovuti alle transizioni tra colori (tonalità, croma, luma) dell'incarnato e del resto dell'immagine TP_DISTORTION_AMOUNT;Quantità +TP_DISTORTION_AUTO_TOOLTIP;Corregge automaticamente la distorsione dell'obiettivo nei file raw confrontandolo con l'immagine JPEG incorporata, se ne esiste una e la distorsione dell'obiettivo è stata corretta automaticamente dalla fotocamera. TP_DISTORTION_LABEL;Distorsione TP_EPD_EDGESTOPPING;Blocco ai Bordi +TP_EPD_GAMMA;Gamma TP_EPD_LABEL;Tone Mapping TP_EPD_REWEIGHTINGITERATES;Iterazioni di Ribilanciamento TP_EPD_SCALE;Scala -TP_EPD_STRENGTH;Forza -TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EPD_STRENGTH;Intensità +TP_EXPOS_BLACKPOINT_LABEL;Raw Punto di nero +TP_EXPOS_WHITEPOINT_LABEL;Raw Punto di bianco TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Abilita l'esecuzione dei livelli automatici per impostare automaticamente il cursore Esposizione in base all'analisi dell'immagine.\nSe necessario, abilita Ricostruzione Alteluci. +TP_EXPOSURE_AUTOLEVELS;Livelli automatici TP_EXPOSURE_BLACKLEVEL;Livello del nero TP_EXPOSURE_BRIGHTNESS;Luminosità -TP_EXPOSURE_CLIP;Tosaggio % +TP_EXPOSURE_CLAMPOOG;Ritaglia i colori fuori gamma TP_EXPOSURE_CLIP_TOOLTIP;La frazione di pixel da tosare nell'operazione di livelli automatici. +TP_EXPOSURE_CLIP;Tosaggio % TP_EXPOSURE_COMPRHIGHLIGHTS;Compressione Alteluci TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Soglia di Compressione Alteluci TP_EXPOSURE_COMPRSHADOWS;Compressione Ombre TP_EXPOSURE_CONTRAST;Contrasto TP_EXPOSURE_CURVEEDITOR1;Curva Tono 1 -TP_EXPOSURE_CURVEEDITOR2;Curva Tono 2 TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Fare riferimento alla pagina "Exposure > Tone Curves" di RawPedia per capire come ottenere i risultati migliori con le doppie curve. +TP_EXPOSURE_CURVEEDITOR2;Curva Tono 2 TP_EXPOSURE_EXPCOMP;Compensazione Esposizione +TP_EXPOSURE_HISTMATCHING_TOOLTIP;Regola automaticamente i cursori e le curve (eccetto la compensazione dell'esposizione) per adattarli all'aspetto della miniatura JPEG incorporata. +TP_EXPOSURE_HISTMATCHING;Curva di tono con abbinamento automatico TP_EXPOSURE_LABEL;Esposizione TP_EXPOSURE_SATURATION;Saturazione TP_EXPOSURE_TCMODE_FILMLIKE;Pellicola TP_EXPOSURE_TCMODE_LABEL1;Tipo Curva 1 TP_EXPOSURE_TCMODE_LABEL2;Tipo Curva 2 +TP_EXPOSURE_TCMODE_LUMINANCE;Luminanza +TP_EXPOSURE_TCMODE_PERCEPTUAL;Percentule TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Fusione Saturazione/Valore TP_EXPOSURE_TCMODE_STANDARD;Standard TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Standard Pesata +TP_FILMNEGATIVE_BLUE;Rapporto blu +TP_FILMNEGATIVE_BLUEBALANCE;Caldo/Freddo +TP_FILMNEGATIVE_COLORSPACE_INPUT;Spazio colore in ingresso +TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Seleziona lo spazio colore utilizzato per eseguire l'inversione negativa:\nSpazio colore di input: esegue l'inversione prima che venga applicato il profilo di input, come nelle versioni precedenti di RT.\nSpazio colore di lavoro< /b>: esegue l'inversione dopo il profilo di input, utilizzando il profilo di lavoro attualmente selezionato. +TP_FILMNEGATIVE_COLORSPACE_WORKING;Spazio colore di lavoro +TP_FILMNEGATIVE_COLORSPACE;Inversione spazio colore: +TP_FILMNEGATIVE_GREEN;Esponente di riferimento +TP_FILMNEGATIVE_GREENBALANCE;Magenta/Verde +TP_FILMNEGATIVE_GUESS_TOOLTIP;Imposta automaticamente i rapporti rosso e blu selezionando due patch che avevano una tonalità neutra (nessun colore) nella scena originale. Le patch dovrebbero differire in luminosità. +TP_FILMNEGATIVE_LABEL;Negativo Pellicola +TP_FILMNEGATIVE_OUT_LEVEL;Livelli di uscita +TP_FILMNEGATIVE_PICK_SIZE;Misura: +TP_FILMNEGATIVE_PICK;Scegli punti neutri +TP_FILMNEGATIVE_RED;Rapporto rosso +TP_FILMNEGATIVE_REF_LABEL;Ingresso RGB: %1 +TP_FILMNEGATIVE_REF_PICK;Scegli il punto di WB +TP_FILMNEGATIVE_REF_SIZE;Misura: +TP_FILMNEGATIVE_REF_TOOLTIP;Scegli una zona grigia per bilanciare il bianco dell'output, immagine positiva. +TP_FILMSIMULATION_LABEL;Simulazione pellicola +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee è configurato per cercare immagini Hald CLUT, che vengono utilizzate per lo strumento Simulazione pellicola, in una cartella che impiega troppo tempo a caricarsi.\nVai su Preferenze > Elaborazione immagine > Simulazione pellicola\nper vedere quale cartella viene utilizzata. Dovresti indirizzare RawTherapee a una cartella che contiene solo immagini Hald CLUT e niente altro, oppure a una cartella vuota se non vuoi utilizzare lo strumento Simulazione film.\n\nLeggi l'articolo Simulazione film in RawPedia per maggiori informazioni. \n\nVuoi annullare la scansione adesso? +TP_FILMSIMULATION_STRENGTH;Intensità +TP_FILMSIMULATION_ZEROCLUTSFOUND;Imposta la directory HaldCLUT nelle Preferenze TP_FLATFIELD_AUTOSELECT;Autoselezione TP_FLATFIELD_BLURRADIUS;Raggio di sfocamento TP_FLATFIELD_BLURTYPE;Modalità di sfocamento @@ -956,24 +2569,30 @@ TP_FLATFIELD_BT_AREA;Area TP_FLATFIELD_BT_HORIZONTAL;Orizzontale TP_FLATFIELD_BT_VERTHORIZ;Vert. + Oriz. TP_FLATFIELD_BT_VERTICAL;Verticale +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Il controllo clip evita le evidenziazioni ritagliate causate dall'applicazione del flat field. Se sono già presenti luci ritagliate prima dell'applicazione del flat field, viene utilizzato il valore 0. +TP_FLATFIELD_CLIPCONTROL;Controllo della clip +TP_FLATFIELD_FROMMETADATA;Da Metadata TP_FLATFIELD_LABEL;Flat Field TP_GENERAL_11SCALE_TOOLTIP;L'effetto di questo strumento è visibile solo (o è accurato solo) con l'anteprima in scala 1:1. -TP_GRADIENT_CENTER;Centro -TP_GRADIENT_CENTER_X;Centro X TP_GRADIENT_CENTER_X_TOOLTIP;Sposta il gradiente a sinistra (valori negativi) o a destra (valori positivi). -TP_GRADIENT_CENTER_Y;Centro Y +TP_GRADIENT_CENTER_X;Centro X TP_GRADIENT_CENTER_Y_TOOLTIP;Sposta il gradiente su (valori negativi) o giù (valori positivi). -TP_GRADIENT_DEGREE;Angolo +TP_GRADIENT_CENTER_Y;Centro Y +TP_GRADIENT_CENTER;Centro TP_GRADIENT_DEGREE_TOOLTIP;Angolo di rotazione in gradi. -TP_GRADIENT_FEATHER;Scia +TP_GRADIENT_DEGREE;Angolo TP_GRADIENT_FEATHER_TOOLTIP;Ampiezza del gradiente in percento della diagonale dell'immagine. +TP_GRADIENT_FEATHER;Scia TP_GRADIENT_LABEL;Filtro Graduato -TP_GRADIENT_STRENGTH;Forza -TP_GRADIENT_STRENGTH_TOOLTIP;Forza del filtro in stop. +TP_GRADIENT_STRENGTH_TOOLTIP;intensità del filtro in stop. +TP_GRADIENT_STRENGTH;intensità TP_HLREC_BLEND;Fusione TP_HLREC_CIELAB;Fusione in CIELab TP_HLREC_COLOR;Propagazione di crominanza +TP_HLREC_COLOROPP;Riverniciare opposto TP_HLREC_ENA_TOOLTIP;Può essere attivato dai Livelli Automatici. +TP_HLREC_HLBLUR;Sfoca +TP_HLREC_HLTH;Soglia di guadagno TP_HLREC_LABEL;Ricostruzione Alteluci TP_HLREC_LUMINANCE;Recupero di Luminanza TP_HLREC_METHOD;Metodo: @@ -982,37 +2601,102 @@ TP_HSVEQUALIZER_HUE;H TP_HSVEQUALIZER_LABEL;Equalizzatore HSV TP_HSVEQUALIZER_SAT;S TP_HSVEQUALIZER_VAL;V -TP_ICM_DCPILLUMINANT;Illuminazione +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Utilizzare la compensazione dell'esposizione di base DCP incorporata. L'impostazione è disponibile solo se il DCP selezionato ne ha uno. +TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Esposizione di base +TP_ICM_APPLYHUESATMAP_TOOLTIP;Utilizza la tabella base DCP incorporata (HueSatMap). L'impostazione è disponibile solo se il DCP selezionato ne ha uno. +TP_ICM_APPLYHUESATMAP;Tabella base +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. +TP_ICM_APPLYLOOKTABLE;Guarda la tabella +TP_ICM_BPC;Compensazione punto di nero TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolato TP_ICM_DCPILLUMINANT_TOOLTIP;Seleziona il DCP del tipo di illuminazione da utilizzare. Il predefinito è "interpolato", un mix tra i due basato sul bilanciamento del bianco. Questa impostazione è abilitata solo se è selezionato Doppia Illuminazione con supporto interpolato. -TP_ICM_INPUTCAMERA;Predefinito della fotocamera -TP_ICM_INPUTCAMERAICC;Specifico della fotocamera -TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilizza i profili colore di ingresso DCP o ICC di RawTherapee specifici per la fotocamera. Questi profili sono più precisi dei semplici matrix. Non sono però disponibili per tutte le fotocamere. Questi profili sono archiviati nelle cartelle /iccprofiles/input e /dcpprofiles e sono recuperati automaticamente in base all'esatta corrispondenza tra nome del file e modello di fotocamera. +TP_ICM_DCPILLUMINANT;Illuminazione +TP_ICM_FBW;Bianco e Nero +TP_ICM_GAMUT;Controllo della gamma +TP_ICM_ILLUMPRIM_TOOLTIP;Scegli l'illuminante più vicino alle condizioni di ripresa.\nLe modifiche possono essere apportate solo quando la selezione "Destinazione primarie" è impostata su "Personalizzato (cursori)". TP_ICM_INPUTCAMERA_TOOLTIP;Utilizza i semplici color matrix di dcraw, migliorati nella versione di RawTherapee (qualunque sia disponibile in base al modello di fotocamera) o inclusi nel DNG. -TP_ICM_INPUTCUSTOM;Personalizzato +TP_ICM_INPUTCAMERA;Predefinito della fotocamera +TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilizza i profili colore di ingresso DCP o ICC di RawTherapee specifici per la fotocamera. Questi profili sono più precisi dei semplici matrix. Non sono però disponibili per tutte le fotocamere. Questi profili sono archiviati nelle cartelle /iccprofiles/input e /dcpprofiles e sono recuperati automaticamente in base all'esatta corrispondenza tra nome del file e modello di fotocamera. +TP_ICM_INPUTCAMERAICC;Specifico della fotocamera TP_ICM_INPUTCUSTOM_TOOLTIP;Seleziona il tuo profilo colore DCP/ICC per la fotocamera. +TP_ICM_INPUTCUSTOM;Personalizzato TP_ICM_INPUTDLGLABEL;Seleziona il profilo DCP/ICC di ingresso... -TP_ICM_INPUTEMBEDDED;Incorporato, se disponibile TP_ICM_INPUTEMBEDDED_TOOLTIP;Utilizza il profilo colore incluso nei file non-raw. -TP_ICM_INPUTNONE;Nessun profilo +TP_ICM_INPUTEMBEDDED;Incorporato, se disponibile TP_ICM_INPUTNONE_TOOLTIP;Non applicare un profilo colore.\nDa utilizzare solo in casi particolari. +TP_ICM_INPUTNONE;Nessun profilo TP_ICM_INPUTPROFILE;Profilo di ingresso TP_ICM_LABEL;Gestione Colore +TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 +TP_ICM_NEUTRAL;Ripristina TP_ICM_NOICM;Nessun ICM: uscita in sRGB +TP_ICM_OUTPUTPROFILE_TOOLTIP;Per impostazione predefinita tutti i profili RTv4 o RTv2 sono con TRC - sRGB: g=2.4 s=12.92\n\nCon 'ICC Profile Creator' puoi generare profili v4 o v2 con le seguenti scelte;\n-Primarie: Aces AP0, Aces AP1 , AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Personalizzato\n-TRC: BT709, sRGB, lineare, standard g=2,2, standard g=1,8, Personalizzato\n-Illuminante: D41, D50, D55 , D60, D65, D80, standard A 2856K TP_ICM_OUTPUTPROFILE;Profilo di Uscita +TP_ICM_PRIMBLU_TOOLTIP;Blu primari:\nsRGB x=0,15 y=0,06\nAdobe x=0,15 y=0,06\nWidegamut x=0,157 y=0,018\nRec2020 x=0,131 y=0,046\nACES P1 x=0,128 y= 0,044\nACES P0 x=0,0001 y=-0,077\nProphoto x=0,0366 y=0,0001\nBruceRGB x=0,15 y=0,06\nBeta RGB x=0,1265 y=0,0352\nBestRGB x=0,131 y=0,046 +TP_ICM_PRIMGRE_TOOLTIP;Verde primario:\nsRGB x=0,3 y=0,6\nAdobe x=0,21 y=0,71\nWidegamut x=0,115 y=0,826\nRec2020 x=0,17 y=0,797\nACES P1 x=0,165 y= 0,83\n ASSI P0 x=0,0 y=1,0\nProphoto x=0,1596 y=0,8404\nBruceRGB x=0,28 y=0,65\nBeta RGB x=0,1986 y=0,7551\nMigliore RGB x=0,2150 0,7750 +TP_ICM_PRIMILLUM_TOOLTIP;È possibile modificare un'immagine dalla modalità originale ("profilo di lavoro") a una modalità diversa ("primarie di destinazione"). Quando scegli una modalità colore diversa per un'immagine, modifichi in modo permanente i valori del colore nell'immagine.\n\nCambiare i "primari" è piuttosto complesso e difficile da usare. Richiede molta sperimentazione.\n È in grado di apportare regolazioni esotiche ai colori come primari del Mixer canali.\n Consente di modificare la calibrazione della fotocamera con personalizzazione (cursori). +TP_ICM_PRIMRED_TOOLTIP;Rosso primario:\nsRGB x=0,64 y=0,33\nAdobe x=0,64 y=0,33\nWidegamut x=0,735 y=0,265\nRec2020 x=0,708 y=0,292\nACES P1 x=0,713 y= 0,293\nACES P0 x=0,7347 y=0,2653\nProphoto x=0,7347 y=0,2653\nBruceRGB x=0,64 y=0,33\nBeta RGB x=0,688 y=0,3112\nBestRGB x=0,7347 y=0,2653 +TP_ICM_PROFILEINTENT;Intento di rendering +TP_ICM_REDFRAME;Primarie personalizzate +TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;In genere, applicare il bilanciamento del bianco quando si salvano le immagini per creare profili ICC e non applicare il bilanciamento del bianco per creare profili DCP. +TP_ICM_SAVEREFERENCE_APPLYWB;Applicare il bilanciamento del bianco TP_ICM_SAVEREFERENCE_TOOLTIP;Salva l'immagine TIFF lineare prima che sia applicato il profilo colore. Il risultato può essere utilizzato per la calibrazione e generazione del profilo della fotocamera. -TP_ICM_TONECURVE;Usa la curva tono del DCP +TP_ICM_SAVEREFERENCE;Salva immagine di riferimento TP_ICM_TONECURVE_TOOLTIP;Utilizza le curve tono incluse nel DCP. Questa opzione è abilitata solo se il DCP selezionato possiede una curva tono. +TP_ICM_TONECURVE;Usa la curva tono del DCP +TP_ICM_TRC_TOOLTIP;Ti consente di modificare la "curva di risposta tonale" sRGB predefinita in RT (g=2,4 s=12,92).\nQuesto TRC modifica i toni dell'immagine. I valori RGB e Lab, l'istogramma e l'output (schermo, TIF, JPG) vengono modificati:\n-Gamma agisce principalmente sui toni chiari -Slope agisce principalmente sui toni scuri.\nPuoi scegliere qualsiasi coppia di 'gamma e pendenza' (valori >1) e l'algoritmo garantirà che vi sia continuità tra le parti lineari e paraboliche della curva.\nUna selezione diversa da "nessuno" attiva i menu "Illuminante" e "Destinazione primari". +TP_ICM_TRCFRAME_TOOLTIP;Noti anche come profili "sintetici" o "virtuali", che vengono applicati alla fine della pipeline di elaborazione (prima di ciecam) consentendo di creare effetti immagine personalizzati.\nÈ possibile apportare modifiche a:\n "Curva di risposta tonale" , che modifica i toni dell'immagine.\n 'Illuminante': che permette di modificare i primari del profilo per adattarli alle condizioni di ripresa.\n 'Primari di destinazione': che permette di modificare i primari di destinazione con due utilizzi principali - mixer canali e calibrazione.\nNota: i profili astratti tengono conto dei profili di lavoro integrati senza modificarli. Non funzionano con i profili di lavoro personalizzati. +TP_ICM_TRCFRAME;Profilo astratto +TP_ICM_WORKING_CIEDIAG;Diagramma xy di CIE +TP_ICM_WORKING_ILLU_1500;Tungsteno 1500K +TP_ICM_WORKING_ILLU_2000;Tungsteno 2000K +TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_D41;D41 +TP_ICM_WORKING_ILLU_D50;D50 +TP_ICM_WORKING_ILLU_D55;D55 +TP_ICM_WORKING_ILLU_D60;D60 +TP_ICM_WORKING_ILLU_D65;D65 +TP_ICM_WORKING_ILLU_D80;D80 +TP_ICM_WORKING_ILLU_NONE;Default +TP_ICM_WORKING_ILLU_STDA;stdA 2875K +TP_ICM_WORKING_ILLU;Illuminante +TP_ICM_WORKING_PRESER;Preserva i toni pastello +TP_ICM_WORKING_PRIM_AC0;ACESp0 +TP_ICM_WORKING_PRIM_ACE;ACESp1 +TP_ICM_WORKING_PRIM_ADOB;Adobe RGB +TP_ICM_WORKING_PRIM_BET;Beta RGB +TP_ICM_WORKING_PRIM_BRU;BruceRGB +TP_ICM_WORKING_PRIM_BST;BestRGB +TP_ICM_WORKING_PRIM_CUS;Custom (sliders) +TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_NONE;Default +TP_ICM_WORKING_PRIM_PROP;ProPhoto +TP_ICM_WORKING_PRIM_REC;Rec2020 +TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_WID;Ampia gamma +TP_ICM_WORKING_PRIM;Destinatione primaria +TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Quando è selezionato 'Diagramma xy CIE personalizzato' nella casella combinata 'Destinazione- primarie', è possibile modificare i valori dei 3 primari direttamente sul grafico.\nNota che in questo caso, la posizione del punto bianco sul grafico non verrà aggiornata . +TP_ICM_WORKING_TRC_18;Prophoto g=1.8 +TP_ICM_WORKING_TRC_22;Adobe g=2.2 +TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 +TP_ICM_WORKING_TRC_CUSTOM;Custom +TP_ICM_WORKING_TRC_GAMMA;Gamma +TP_ICM_WORKING_TRC_LIN;Lineare g=1 +TP_ICM_WORKING_TRC_NONE;Nessuno +TP_ICM_WORKING_TRC_SLOPE;Pendenza +TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 +TP_ICM_WORKING_TRC_TOOLTIP;Solo per profili integrati. +TP_ICM_WORKING_TRC;Curva di risposta tonale: TP_ICM_WORKINGPROFILE;Profilo di lavoro TP_IMPULSEDENOISE_LABEL;Riduzione Rumore Puntuale TP_IMPULSEDENOISE_THRESH;Soglia -TP_LABCURVE_AVOIDCOLORSHIFT;Evita il color shift -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori all'interno del gamut dello spazio colore di lavoro e applica la correzione Munsell. +#TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori all'interno del gamut dello spazio colore di lavoro e applica la correzione Munsell. +#TP_LABCURVE_AVOIDCOLORSHIFT;Evita il color shift TP_LABCURVE_BRIGHTNESS;Luminosità -TP_LABCURVE_CHROMATICITY;Cromaticità TP_LABCURVE_CHROMA_TOOLTIP;Per applicare il toning BN impostare la Cromaticità a -100. +TP_LABCURVE_CHROMATICITY;Cromaticità TP_LABCURVE_CONTRAST;Contrasto -TP_LABCURVE_CURVEEDITOR;Curva di luminanza TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verde Saturo TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verde Pastello TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rosso Pastello @@ -1021,65 +2705,1000 @@ TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blu Saturo TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blu Pastello TP_LABCURVE_CURVEEDITOR_B_RANGE3;Giallo Pastello TP_LABCURVE_CURVEEDITOR_B_RANGE4;Giallo Saturo -TP_LABCURVE_CURVEEDITOR_CC;CC TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutri TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Opachi TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastello TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturi TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticità secondo Cromaticità C=f(C) -TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CC;CC TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticità secondo Tonalità C=f(H) -TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CH;CH TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Cromaticità secondo Luminanza C=f(L) -TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_CL;CL TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Tonalità secondo Tonalità H=f(H) -TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_HH;HH TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanza secondo Cromaticità L=f(C) -TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LC;LC TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminanza secondo Tonalità L=f(H) +TP_LABCURVE_CURVEEDITOR_LH;LH TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminanza secondo Luminanza L=f(L) +TP_LABCURVE_CURVEEDITOR;Curva di luminanza TP_LABCURVE_LABEL;Regolazioni Lab -TP_LABCURVE_LCREDSK;Limita LC ai toni rossi e all'incarnato TP_LABCURVE_LCREDSK_TOOLTIP;Se abilitato, la Curva LC è applicata solo ai toni rossi e dell'incarnato.\nSe disabilitato, ha effetto su tutti i toni. -TP_LABCURVE_RSTPROTECTION;Protezione Toni rossi e dell'incarnato +TP_LABCURVE_LCREDSK;Limita LC ai toni rossi e all'incarnato TP_LABCURVE_RSTPRO_TOOLTIP;Può essere utilizzato con il cursore Cromaticità e la curva CC. +TP_LABCURVE_RSTPROTECTION;Protezione Toni rossi e dell'incarnato TP_LENSGEOM_AUTOCROP; Ritaglio automatico TP_LENSGEOM_FILL;Adattamento automatico TP_LENSGEOM_LABEL;Obiettivo/Geometria +TP_LENSGEOM_LIN;Lineare +TP_LENSGEOM_LOG;Logaritmico +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Selezione Automatica +TP_LENSPROFILE_CORRECTION_LCPFILE;File LCP +TP_LENSPROFILE_CORRECTION_MANUAL;Selezione Manuale TP_LENSPROFILE_LABEL;Profilo di Correzione dell'Obiettivo +TP_LENSPROFILE_LENS_WARNING;Attenzione: il fattore di crop utilizzato per la profilazione dell'obiettivo è maggiore del fattore di crop della fotocamera, i risultati potrebbero essere errati. +TP_LENSPROFILE_MODE_HEADER;Profilo lenti +TP_LENSPROFILE_USE_CA;Aberrazione Cromatica +TP_LENSPROFILE_USE_GEOMETRIC;Distorsione geometrica +TP_LENSPROFILE_USE_HEADER;Correzione +TP_LENSPROFILE_USE_VIGNETTING;Vignettatura +TP_LOCAL_HEIGHT_T;Alto +TP_LOCAL_HEIGHT;Basso +TP_LOCAL_WIDTH_L;Sinistro +TP_LOCAL_WIDTH;Destro +TP_LOCALCONTRAST_AMOUNT;Quantità +TP_LOCALCONTRAST_DARKNESS;Livello durezza +TP_LOCALCONTRAST_LABEL;Contrasto locale +TP_LOCALCONTRAST_LIGHTNESS;Livello di luminosità +TP_LOCALCONTRAST_RADIUS;Raggio +TP_LOCALLAB_ACTIV;Solo Luminanza +TP_LOCALLAB_ACTIVSPOT;Abilita Spot +TP_LOCALLAB_ADJ;Equalizzatore Colore +TP_LOCALLAB_AMOUNT;Quantità +TP_LOCALLAB_ARTIF_TOOLTIP;La soglia dell'ambito ΔE aumenta la portata dell'ambito ΔE. I valori elevati si riferiscono a immagini con una gamma molto ampia.\nL'aumento del decadimento ΔE può migliorare il rilevamento della forma, ma può anche ridurre l'ambito. +TP_LOCALLAB_ARTIF;Rilevamento della forma +TP_LOCALLAB_AUTOGRAY;Luminanza media automatica (Yb%) +TP_LOCALLAB_AUTOGRAYCIE;Auto +TP_LOCALLAB_AVOID;Evita il cambiamento di colore +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori alla gamma dello spazio colore di lavoro e applica la correzione Munsell (Uniform Perceptual Lab).\nLa correzione Munsell è sempre disabilitata quando si utilizza Jz o CAM16 o Aspetto colore e illuminazione.\n\nPredefinito: Munsell.\nCorrezione Munsell: corregge la modalità Lab la tonalità si sposta a causa della non linearità, quando la cromaticità viene modificata (Uniform Perceptual Lab).\nLab: applica un controllo della gamma, in colorimetrico relativo, viene quindi applicato Munsell.\nXYZ Assoluto, applica il controllo della gamma, in colorimetrico assoluto, viene quindi applicato Munsell. applicato.\nXYZ Relativo, applica il controllo gamma, in colorimetrico relativo, viene quindi applicato Munsell. +TP_LOCALLAB_AVOIDMUN_TOOLTIP;La correzione Munsell è sempre disabilitata quando si utilizza Jz o CAM16. +TP_LOCALLAB_AVOIDMUN;Solo correzione Munsell +TP_LOCALLAB_AVOIDRAD;Raggio Morbido +TP_LOCALLAB_BALAN_TOOLTIP;Modifica i parametri dell'algoritmo ΔE.\nPrende in considerazione più o meno a*b* o L*, o più o meno C o H.\nNon per Denoise. +TP_LOCALLAB_BALAN;ab-L bilanciato (ΔE) +TP_LOCALLAB_BALANEXP;Bilanciamento Laplacian +TP_LOCALLAB_BALANH;C-H bilanciato (ΔE) +TP_LOCALLAB_BASELOG;Intervallo delle ombre (base logaritmica) +TP_LOCALLAB_BILATERAL;Filtro bilateralte +TP_LOCALLAB_BLACK_EV;Compensazione dell'esposizione dei neri +TP_LOCALLAB_BLCO;Solo crominanza +TP_LOCALLAB_BLENDMASK_TOOLTIP;Se fusione = 0 viene migliorato solo il rilevamento della forma.\nSe fusione > 0 la maschera viene aggiunta all'immagine. Se la mescola < 0 la maschera viene sottratta dall'immagine. +TP_LOCALLAB_BLENDMASKCOL;Miscela +TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;Se questo cursore = 0 nessuna azione.\nAggiungi o sottrai la maschera dall'immagine originale. +TP_LOCALLAB_BLENDMASKMASK;Aggiungi/sottrai la maschera luminanza +TP_LOCALLAB_BLENDMASKMASKAB;Aggiungi/sottrai la maschera crominanza +TP_LOCALLAB_BLGUID;Filtro guidato +TP_LOCALLAB_BLINV;Inverso +TP_LOCALLAB_BLLC;Luminanza e Crominanza +TP_LOCALLAB_BLLO;Solo Luminanza +TP_LOCALLAB_BLMED;Mediano +TP_LOCALLAB_BLMETHOD_TOOLTIP;Normale: sfocatura e rumore diretti con tutte le impostazioni.\nInverso: sfocatura e rumore con tutte le impostazioni. Attenzione, alcune impostazioni potrebbero dare risultati curiosi. +TP_LOCALLAB_BLNOI_EXP;Sfocatura e rumore +TP_LOCALLAB_BLNORM;Normale +TP_LOCALLAB_BLUFR;Sfocatura/grana e riduzione rumore +TP_LOCALLAB_BLUMETHOD_TOOLTIP;Per sfocare lo sfondo e isolare il primo piano:\n-sfoca lo sfondo coprendo completamente l'immagine con un punto (valori elevati per ambito e transizione e 'Normale' o 'Inverso' nella casella di controllo).\n-Isola il primo piano utilizzando uno o più punti 'Esclusioni' e aumentare l'ambito.\n\nQuesto modulo (incluso il 'mediano' e il 'Filtro guidato') può essere utilizzato in aggiunta alla riduzione del rumore nel menu principale. +TP_LOCALLAB_BLUR_TOOLNAME;Sfocatura/grana e riduzione rumore +TP_LOCALLAB_BLUR;Sfocatura gaussiana - Rumore - Grana +TP_LOCALLAB_BLURCOL;Raggio +TP_LOCALLAB_BLURCOLDE_TOOLTIP;L'immagine utilizzata per calcolare ΔE è leggermente sfocata per evitare di prendere in considerazione i pixel isolati. +TP_LOCALLAB_BLURDE;Rilevamento della forma sfocata +TP_LOCALLAB_BLURLC;Solo luminanza +TP_LOCALLAB_BLURLEVELFRA;Livello di sfocatura +TP_LOCALLAB_BLURMASK_TOOLTIP;Utilizza una sfocatura ad ampio raggio per creare una maschera che consente di variare il contrasto dell'immagine e/o scurire/schiarire parti di essa. +TP_LOCALLAB_BLURRMASK_TOOLTIP;Permette di variare il 'raggio' della sfocatura gaussiana (da 0 a 1000). +TP_LOCALLAB_BLWH_TOOLTIP;Forza i componenti del colore 'a' e 'b' a zero.\nUtile per l'elaborazione in bianco e nero o la simulazione di film. +TP_LOCALLAB_BLWH;Tutti i cambiamenti forzati in bianco e nero +TP_LOCALLAB_BUTTON_ADD;Aggiungi +TP_LOCALLAB_BUTTON_DEL;Elimina +TP_LOCALLAB_BUTTON_DUPL;Duplica +TP_LOCALLAB_BUTTON_REN;Rinomina +TP_LOCALLAB_BUTTON_VIS;Mostra/Nascondi +TP_LOCALLAB_BWFORCE;Usa la compensazione dell'esposizione dei neri e la compensazione dell'esposizione dei bianchi +TP_LOCALLAB_CAM16_FRA;Regolazioni dell'immagine Cam16 +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (quantizzatore percettivo) adattato al CAM16. Consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 100 cd/m2 - disabilitato per 100 cd/m2).\nPuò essere utilizzato per adattarsi a diversi dispositivi e immagini. +TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Luminanza di picco) +TP_LOCALLAB_CAMMODE_CAM16;CAM 16 +TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz +TP_LOCALLAB_CAMMODE;Modello CAM +TP_LOCALLAB_CATAD;Adattamento cromatico/Cat16 +TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Come le wavelet.\nIl primo livello (0) agisce su dettagli di 2x2 pixel.\nL'ultimo livello (5) agisce su dettagli di 64x64 pixel. +TP_LOCALLAB_CBDL_THRES_TOOLTIP;Previene l'acutizzazione del rumore. +TP_LOCALLAB_CBDL_TOOLNAME;Contrasto per livelli di dettaglio +TP_LOCALLAB_CBDL;Contrasto per livelli di dettaglio +TP_LOCALLAB_CBDLCLARI_TOOLTIP;Migliora il contrasto locale dei mezzitoni. +TP_LOCALLAB_CENTER_X;Centra X +TP_LOCALLAB_CENTER_Y;Centra Y +TP_LOCALLAB_CH;CL - LC +TP_LOCALLAB_CHRO46LABEL;Livelli di crominanza 456: Medio=%1 Alto=%2 +TP_LOCALLAB_CHROLABEL;Livelli di crominanza 0123: Medio=%1 Alto=%2 +TP_LOCALLAB_CHROMA;Crominanza +TP_LOCALLAB_CHROMABLU_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. +TP_LOCALLAB_CHROMABLU;Livelli di crominanza +TP_LOCALLAB_CHROMACB_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. +TP_LOCALLAB_CHROMACBDL;Crominanza +TP_LOCALLAB_CHROMALEV;Livelli di crominanza +TP_LOCALLAB_CHROMASK_TOOLTIP;Cambia la crominanza della maschera se ne esiste una (cioè C(C) o LC(H) è attivato). +TP_LOCALLAB_CHROMASKCOL;Crominanza +TP_LOCALLAB_CHROML;Crominanza (C) +TP_LOCALLAB_CHRRT;Crominanza +TP_LOCALLAB_CIE_TOOLNAME;Aspetto del colore (Cam16 & JzCzHz) +TP_LOCALLAB_CIE;Aspetto del colore (Cam16 & JzCzHz) +TP_LOCALLAB_CIEC;Utilizza i parametri dell'ambiente CIECAM +TP_LOCALLAB_CIECAMLOG_TOOLTIP;Questo modulo si basa sul modello di aspetto del colore CIECAM che è stato progettato per simulare meglio il modo in cui la visione umana percepisce i colori in diverse condizioni di illuminazione.\nIl primo processo Ciecam 'Condizioni di scena' viene eseguito mediante codifica Log, utilizza anche 'Luminanza assoluta' a l'ora dello scatto.\nIl secondo processo Ciecam 'Regolazioni immagine' è semplificato e utilizza solo 3 variabili (contrasto locale, contrasto J, saturazione s).\nIl terzo processo Ciecam 'Condizioni di visualizzazione' adatta l'output alle condizioni di visualizzazione previste ( monitor, TV, proiettore, stampante, ecc.) in modo che l'aspetto cromatico e di contrasto venga preservato in tutto l'ambiente di visualizzazione. +TP_LOCALLAB_CIECOLORFRA;Colore +TP_LOCALLAB_CIECONTFRA;Contrasto +TP_LOCALLAB_CIELIGHTCONTFRA;Illuminazione e contrasto +TP_LOCALLAB_CIELIGHTFRA;Illuminazione +TP_LOCALLAB_CIEMODE_COM;Default +TP_LOCALLAB_CIEMODE_DR;Gamma dinamica +TP_LOCALLAB_CIEMODE_TM;Mappatura dei toni +TP_LOCALLAB_CIEMODE_TOOLTIP;Nella modalità predefinita, Ciecam viene aggiunto alla fine del processo. 'Maschera e modifiche' e 'Recupero basato sulla maschera di luminanza' sono disponibili per'Cam16 e JzCzHz' a tua disposizione.\nPuoi anche integrare Ciecam in altri strumenti se lo desideri (TM, Wavelet, Dynamic Range, Log Encoding). I risultati per questi strumenti saranno diversi rispetto a quelli senza Ciecam. In questa modalità è anche possibile utilizzare 'Maschera e modifiche' e 'Ripristino basato sulla maschera di luminanza'. +TP_LOCALLAB_CIEMODE_WAV;Wavelet +TP_LOCALLAB_CIEMODE;Modificare la posizione dello strumento +TP_LOCALLAB_CIETOOLEXP;Curve +TP_LOCALLAB_CIRCRAD_TOOLTIP;Contiene i riferimenti della macchia, utili per il rilevamento della forma (tonalità, luminanza, crominanza, Sobel).\bValori bassi possono essere utili per l'elaborazione del fogliame.\Valori alti possono essere utili per l'elaborazione della pelle. +TP_LOCALLAB_CIRCRADIUS;Dimensione del punto +TP_LOCALLAB_CLARI_TOOLTIP;Livelli da 0 a 4 (inclusi): 'Maschera nitida' è abilitata\nLivelli 5 e superiori: 'Chiarezza' è abilitata.\nUtile se si utilizza la 'Mappatura toni livello Wavelet'. +TP_LOCALLAB_CLARICRES;Unisci crominanza +TP_LOCALLAB_CLARIFRA;Maschera Chiarezza e Nitidezza/Unisci e ammorbidisci le immagini +TP_LOCALLAB_CLARIJZ_TOOLTIP;Livelli da 0 a 4 (inclusi): 'Maschera nitida' è abilitata\nLivelli 5 e superiori: 'Chiarezza' è abilitata. +TP_LOCALLAB_CLARILRES;Unisci luminanza +TP_LOCALLAB_CLARISOFT_TOOLTIP;Il cursore 'Raggio morbido' (algoritmo di filtro guidato) riduce gli aloni e le irregolarità per Chiarezza, Maschera nitida e tutti i processi piramidali wavelet. Per disattivare, impostare il cursore su zero. +TP_LOCALLAB_CLARISOFT;Raggio morbido +TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;Il dispositivo di scorrimento "Raggio morbido" (algoritmo di filtro guidato) riduce gli aloni e le irregolarità per Chiarezza, Maschera nitida e Wavelet di contrasto locale Jz. +TP_LOCALLAB_CLARITYML;Clarity +TP_LOCALLAB_CLIPTM;Clip dei dati ripristinati (guadagno) +TP_LOCALLAB_COFR;Colore e luce +TP_LOCALLAB_COL_NAME;Nome +TP_LOCALLAB_COL_VIS;Stato +TP_LOCALLAB_COLOR_CIE;Curva colore +TP_LOCALLAB_COLOR_TOOLNAME;Colore e luce +TP_LOCALLAB_COLORDE_TOOLTIP;Mostra un'anteprima di colore blu per la selezione ΔE se negativa e verde se positiva.\n\nMaschera e modifiche (mostra aree modificate senza maschera): mostra le modifiche effettive se positive, mostra le modifiche migliorate (solo luminanza) con blu e giallo se negative. +TP_LOCALLAB_COLORDE;ΔE anteprima colore - intensità +TP_LOCALLAB_COLORDEPREV_TOOLTIP;Il pulsante Anteprima ΔE funzionerà solo se hai attivato uno (e solo uno) degli strumenti nel menu 'Aggiungi strumento al punto corrente'.\nPer poter visualizzare l'anteprima ΔE con diversi strumenti abilitati, usa Maschera e modifiche - Anteprima ΔE. +TP_LOCALLAB_COLORSCOPE_TOOLTIP;Cursore di ambito comune per Colore e luce, Ombre/Alte luci, Vividezza.\nAltri strumenti hanno i propri controlli di ambito. +TP_LOCALLAB_COLORSCOPE;Ambito (strumenti colore) +TP_LOCALLAB_COMPFRA;Contrasto direzionale +TP_LOCALLAB_COMPREFRA;Mappatura dei toni del livello wavelet +TP_LOCALLAB_CONTCOL;Soglia di contrasto +TP_LOCALLAB_CONTFRA;Livello di contrasto +TP_LOCALLAB_CONTRAST;Contrasto +TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Ti permette di cambiare liberamente il contrasto della maschera.\n Ha una funzione simile ai cursori Gamma e Pendenza.\n Ti permette di individuare alcune parti dell'immagine (solitamente le parti più chiare della maschera utilizzando la curva per escludere le parti più scure). Può creare artefatti. +TP_LOCALLAB_CONTRESID;Contrasto +TP_LOCALLAB_CONTTHMASK_TOOLTIP;Consente di determinare quali parti dell'immagine verranno interessate in base alla texture. +TP_LOCALLAB_CONTTHR;Soglia di contrasto +TP_LOCALLAB_CONTWFRA;Contrasto locale +TP_LOCALLAB_CSTHRESHOLD;Livelli di Wavelet +TP_LOCALLAB_CSTHRESHOLDBLUR;Selezione del livello wavelet +TP_LOCALLAB_CURV;LighQualità - Contrasto - Crominanza 'Super' +TP_LOCALLAB_CURVCURR;Normale +TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;Se le curve sono in alto, la maschera è completamente nera e non viene apportata alcuna modifica all'immagine.\nMan mano che si abbassa la curva, la maschera diventa gradualmente più colorata e luminosa, cambiando progressivamente l'immagine.\n\nÈ consigliato (ma (non obbligatorio) posizionare la parte superiore delle curve sulla linea di confine grigia che rappresenta i valori di riferimento di crominanza, luminanza, tonalità per lo spot. +TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;Per attivare le curve, impostare la casella combinata 'Tipo di curva' su 'Normale'. +TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Curva del tono +TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), può essere utilizzato con L(H) in Colore e Luce. +TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;Se le curve sono in alto, la maschera è completamente nera e non viene apportata alcuna modifica all'immagine.\nMan mano che si abbassa la curva, la maschera diventa gradualmente più colorata e luminosa, modificando progressivamente l'immagine.\n\nSi consiglia ( ma non obbligatorio) posizionare la parte superiore delle curve sulla linea di confine grigia che rappresenta i valori di riferimento di crominanza, luminanza, tonalità per lo spot. +TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normale', la curva L=f(L) utilizza lo stesso algoritmo del cursore della luminosità. +TP_LOCALLAB_CURVES_CIE;Curva del tono +TP_LOCALLAB_CURVNONE;Disabilita curve +TP_LOCALLAB_DARKRETI;Durezza +TP_LOCALLAB_DEHAFRA;Rimouovi foschia +TP_LOCALLAB_DEHAZ_TOOLTIP;I valori negativi aggiungono foschia. +TP_LOCALLAB_DEHAZ;Intensità +TP_LOCALLAB_DEHAZE_BLACK;Nero +TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Rimuove la foschia atmosferica. Aumenta la saturazione e il dettaglio complessivi.\nPuò rimuovere dominanti di colore, ma può anche introdurre una dominante blu che può essere corretta con altri strumenti. +TP_LOCALLAB_DELTAD;Equilibrio delta +TP_LOCALLAB_DELTAEC;ΔE Maschera immagine +TP_LOCALLAB_DENOI_EXP;Riduzione rumore +TP_LOCALLAB_DENOI_TOOLTIP;Questo modulo può essere utilizzato per la riduzione del rumore da solo (alla fine della pipeline di elaborazione) o in aggiunta al modulo Riduzione del rumore nella scheda Dettagli (che funziona all'inizio della pipeline).\n L'ambito ti consente di differenziare l'azione in base al colore (ΔE).\nDimensione minima dello spot: 128x128. +TP_LOCALLAB_DENOI1_EXP;Riduzione rumore basato sulla maschera di luminanza +TP_LOCALLAB_DENOI2_EXP;Recupero basato sulla maschera di luminanza +TP_LOCALLAB_DENOIBILAT_TOOLTIP;Consente di ridurre il rumore impulsivo o "sale e pepe". +TP_LOCALLAB_DENOICHROC_TOOLTIP;Ti consente di gestire macchie e pacchetti di rumore. +TP_LOCALLAB_DENOICHRODET_TOOLTIP;Permette di recuperare il dettaglio della crominanza applicando progressivamente una trasformata di Fourier (DCT). +TP_LOCALLAB_DENOICHROF_TOOLTIP;Consente di regolare il rumore della crominanza nei minimi dettagli. +TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Consente di effettuare una riduzione maggiore o minore del rumore sia nelle ombre che nelle luci. +TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Consente di indirizzare la riduzione del rumore cromatico verso i colori blu-giallo o rosso-verde. +TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Permette di recuperare il dettaglio della luminanza applicando progressivamente una trasformata di Fourier (DCT). +TP_LOCALLAB_DENOIMASK_TOOLTIP;Per tutti gli strumenti, consente di controllare il livello di rumore cromatico della maschera.\nUtile per un migliore controllo della crominanza e per evitare artefatti quando si utilizza la curva LC(h). +TP_LOCALLAB_DENOIMASK;Ruzione rumore maschera di crominanza +TP_LOCALLAB_DENOIQUA_TOOLTIP;La modalità conservativa preserva i dettagli a bassa frequenza. La modalità aggressiva rimuove i dettagli a bassa frequenza.\nLe modalità conservativa e aggressiva utilizzano wavelet e DCT e possono essere utilizzate insieme a "Mezzi non locali – Luminanza". +TP_LOCALLAB_DENOITHR_TOOLTIP;Regola il rilevamento dei bordi per ridurre il rumore nelle aree uniformi e a basso contrasto. +TP_LOCALLAB_DENOIWAVCH;Wavelets: Crominanza +TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminanza +TP_LOCALLAB_DEPTH;Profondità +TP_LOCALLAB_DETAIL;Contrasto locale +TP_LOCALLAB_DETAILFRA;Rilevamento dei bordi - DCT +TP_LOCALLAB_DETAILSH;Dettagli +TP_LOCALLAB_DETAILTHR;Soglia dettaglio Luminanza/Crominanza +TP_LOCALLAB_DIVGR;Gamma +TP_LOCALLAB_DUPLSPOTNAME;Copia +TP_LOCALLAB_EDGFRA;Nitidezza dei bordi +TP_LOCALLAB_EDGSHOW;Mostra tutti gli strumenti +TP_LOCALLAB_ELI;Ellisse +TP_LOCALLAB_ENABLE_AFTER_MASK;Utilizza la mappatura dei toni +TP_LOCALLAB_ENABLE_MASK;Abilita maschera +TP_LOCALLAB_ENABLE_MASKAFT;Utilizza tutti gli algoritmi di esposizione +TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;Se abilitata, la maschera utilizza i dati ripristinati dopo la mappa di trasmissione invece dei dati originali. +TP_LOCALLAB_ENH;Migliorato +TP_LOCALLAB_ENHDEN;Migliorato + riduzione rumore cromatico +TP_LOCALLAB_EPSBL;Dettagli +TP_LOCALLAB_EQUIL;Normalizza la luminanza +TP_LOCALLAB_EQUILTM_TOOLTIP;Ricostruire la luminanza in modo che la media e la varianza dell'immagine di output siano identiche a quelle dell'originale. +TP_LOCALLAB_ESTOP;Arresto sul bordo +TP_LOCALLAB_EV_DUPL;Copia di +TP_LOCALLAB_EV_NVIS_ALL;Nascondi tutto +TP_LOCALLAB_EV_NVIS;Nascondi +TP_LOCALLAB_EV_VIS_ALL;Mostra tutto +TP_LOCALLAB_EV_VIS;Mostra +TP_LOCALLAB_EXCLUF_TOOLTIP;La modalità 'Esclusione' impedisce ai punti adiacenti di influenzare alcune parti dell'immagine. La regolazione di 'Ambito' estenderà la gamma di colori.\n Puoi anche aggiungere strumenti a un punto di esclusione e utilizzarli come per un punto normale. +TP_LOCALLAB_EXCLUF;Escluso +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +TP_LOCALLAB_EXCLUTYPE;Metodo Spot +TP_LOCALLAB_EXECLU;Escluso spot +TP_LOCALLAB_EXFULL;Immagine piena +TP_LOCALLAB_EXNORM;Spot normale +TP_LOCALLAB_EXP_TOOLNAME;Gamma dinamica ed esposizione +TP_LOCALLAB_EXPCBDL_TOOLTIP;Può essere utilizzato per rimuovere segni sul sensore o sull'obiettivo riducendo il contrasto ai livelli di dettaglio appropriati. +TP_LOCALLAB_EXPCHROMA_TOOLTIP;Utilizzare insieme a 'Compensazione dell'esposizione f' e 'Attenuatore contrasto f' per evitare la desaturazione dei colori. +TP_LOCALLAB_EXPCHROMA;Compensazione cromatica +TP_LOCALLAB_EXPCOLOR_TOOLTIP;Regola colore, luminosità, contrasto e correggi piccoli difetti come occhi rossi, polvere del sensore, ecc. +TP_LOCALLAB_EXPCOMP_TOOLTIP;Per ritratti o immagini con una bassa sfumatura di colore. Puoi modificare il "Rilevamento della forma" in "Impostazioni":\n\nAumenta la "Soglia ambito ΔE"\nRiduci il "Decadimento ΔE"\nAumenta il "Bilanciamento ab-L (ΔE)" +TP_LOCALLAB_EXPCOMP;Compensazione dell'esposizione Æ’ +TP_LOCALLAB_EXPCOMPINV;Compensazione dell'esposizione +TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Evita punti troppo piccoli (< 32x32 pixel).\nUtilizza un 'Valore di transizione' basso e un 'Decadimento della transizione' e un''Ambito' alti per simulare piccoli punti e gestire i difetti.\nUtilizza la maschera Chiarezza e Nitidezza e Fondi e ammorbidisci immagini ' se necessario regolando 'Raggio morbido' per ridurre gli artefatti. +TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Consulta la documentazione per i Livelli Wavelet.\nCi sono alcune differenze nella versione Regolazioni Locali, che ha più strumenti e più possibilità per lavorare su livelli di dettaglio individuali.\nEs. mappatura dei toni a livello wavelet. +TP_LOCALLAB_EXPCURV;Curve +TP_LOCALLAB_EXPGRAD;Filtro graduato +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Un filtro graduato è disponibile in Colore e Luce (luminanza, crominanza e gradienti di tonalità e "Unisci file"), Esposizione (grado di luminanza), Maschera esposizione (grado di luminanza), Ombre/Alte luci (grado di luminanza), Vividezza ( luminanza, crominanza e gradienti di tonalità), contrasto locale e piramide wavelet (gradazione di contrasto locale).\nPiuma si trova in Impostazioni. +TP_LOCALLAB_EXPLAP_TOOLTIP;Spostando il cursore verso destra si riduce progressivamente il contrasto. +TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Modifica la fusione dell'immagine trasformata/originale. +TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Modifica il comportamento delle immagini con contrasto eccessivo o insufficiente aggiungendo una curva gamma prima e dopo la trasformata di Laplace. +TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. +TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Consente di utilizzare le modalità di fusione dei livelli di GIMP o Photoshop (differenza, moltiplicazione, luce soffusa, sovrapposizione, ecc.) con controllo dell'opacità.\nImmagine originale: unisci il punto corrente con l'originale.\nPunto precedente: unisci il punto corrente con quello precedente (se presente solo uno spot, precedente = originale).\nSfondo: unisce lo spot corrente con uno sfondo di colore e luminanza (meno possibilità). +TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applica un filtro mediano prima della trasformazione di Laplace per prevenire artefatti (rumore).\nPuoi anche utilizzare lo strumento "Rimuovi rumore". +TP_LOCALLAB_EXPOSE;Gamma dinamica ed esposizione +TP_LOCALLAB_EXPOSURE_TOOLTIP;Modificare l'esposizione nello spazio L*a*b utilizzando gli algoritmi PDE laplaciani per tenere conto dE e ridurre al minimo gli artefatti. +TP_LOCALLAB_EXPRETITOOLS;Strumenti Retinex avanzati +TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimo 39*39.\nUtilizza valori di transizione bassi e valori alti di "Decadimento transizione" e "Ambito" per simulare spot più piccoli. +TP_LOCALLAB_EXPTOOL;Strumenti di esposizione +TP_LOCALLAB_FATAMOUNT;Quantità +TP_LOCALLAB_FATANCHOR;Ancora +TP_LOCALLAB_FATDETAIL;Dettaglio +TP_LOCALLAB_FATFRA;Compressione della gamma dinamica Æ’ +TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattali - utilizza l'algoritmo di mappatura dei toni fattali. +TP_LOCALLAB_FATLEVEL;Sigma +TP_LOCALLAB_FATSAT;Controllo della Saturazione +TP_LOCALLAB_FATSHFRA;Maschera di compressione della gamma dinamica Æ’ +TP_LOCALLAB_FEATH_TOOLTIP;Ampiezza del gradiente come percentuale della diagonale del punto\Utilizzato da tutti i filtri graduati in tutti gli strumenti.\nessuna azione se non è stato attivato un filtro graduato. +TP_LOCALLAB_FEATVALUE;Gradiente di sfumatura (filtri graduati) +TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ +TP_LOCALLAB_FFTMASK_TOOLTIP;Utilizzare una trasformata di Fourier per una migliore qualità (maggiore tempo di elaborazione e requisiti di memoria). +TP_LOCALLAB_FFTW;Æ’ - Utilizza la trasformata veloce di Fourier +TP_LOCALLAB_FFTWBLUR;Æ’ - Utilizza sempre la trasformata veloce di Fourier +TP_LOCALLAB_FULLIMAGE;Compensazione dell'esposizione dei neri e compensazione dell'esposizione dei bianchi per l'intera immagine +TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calcola i livelli Ev per l'intera immagine. +TP_LOCALLAB_GAM;Gamma +TP_LOCALLAB_GAMC_TOOLTIP;Applicare una gamma sui dati di luminanza L*a*b* prima e dopo il trattamento Piramide 1 e Piramide 2.\nSe gamma = 3.0 Viene utilizzata la luminanza 'lineare'. +TP_LOCALLAB_GAMC;Gamma +TP_LOCALLAB_GAMCOL_TOOLTIP;Applica una gamma sui dati di luminanza L*a*b*.\nSe gamma = 3.0 viene utilizzata la luminanza 'lineare'. +TP_LOCALLAB_GAMFRA;Curva di risposta tonale (CRT) +TP_LOCALLAB_GAMM;Gamma +TP_LOCALLAB_GAMMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente "L" per evitare eventuali discontinuità. +TP_LOCALLAB_GAMMASKCOL;Gamma +TP_LOCALLAB_GAMSH;Gamma +TP_LOCALLAB_GAMUTLABRELA;Lab +TP_LOCALLAB_GAMUTMUNSELL;Solo Munsell +TP_LOCALLAB_GAMUTNON;Nessuno +TP_LOCALLAB_GAMUTXYZABSO;XYZ Assoluto +TP_LOCALLAB_GAMUTXYZRELA;XYZ Relativo +TP_LOCALLAB_GAMW;Gamma (piramide di wavelet) +TP_LOCALLAB_GRADANG_TOOLTIP;Angolo di rotazione in gradi: -180 o +180. +TP_LOCALLAB_GRADANG;Angolo gradiente +TP_LOCALLAB_GRADFRA;Maschera con filtro graduato +TP_LOCALLAB_GRADGEN_TOOLTIP;Regola l'intensità del gradiente di luminanza. +TP_LOCALLAB_GRADLOGFRA;Luminanza del filtro graduato +TP_LOCALLAB_GRADSTR;Intensità del gradiente +TP_LOCALLAB_GRADSTRAB_TOOLTIP;Regola l'intensità del gradiente cromatico. +TP_LOCALLAB_GRADSTRCHRO;Intensità del gradiente cromatico +TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Regola l'intensità del gradiente di tonalità. +TP_LOCALLAB_GRADSTRHUE;Intensità del gradiente di tonalità +TP_LOCALLAB_GRADSTRHUE2;Intensità del gradiente di tonalità +TP_LOCALLAB_GRADSTRLUM;Intensità del gradiente luminanza +TP_LOCALLAB_GRAIN_TOOLTIP;Aggiunge una grana simile a una pellicola all'immagine. +TP_LOCALLAB_GRAINFRA;Grana della pellicola 1:1 +TP_LOCALLAB_GRAINFRA2;Ruvidezza +TP_LOCALLAB_GRALWFRA;Filtro graduato (contrasto locale) +TP_LOCALLAB_GRIDFRAME_TOOLTIP;Puoi usare questo strumento come un pennello. Usa un piccolo punto e adatta il 'Valore di transizione' e il 'Decadimento della transizione'\nSolo la modalità 'Normale' ed eventualmente Tonalità, Saturazione, Colore e Luminosità sono interessate da Unisci sfondo (ΔE). +TP_LOCALLAB_GRIDMETH_TOOLTIP;Tonalità del colore: la luminanza viene presa in considerazione quando si varia la crominanza. Equivalente a H=f(H) se il 'punto bianco' sulla griglia rimane a zero e si varia solo il 'punto nero'. Equivalente a 'Viraggio colore' se si variano i 2 punti.\n\nDiretto: agisce direttamente sulla crominanza. +TP_LOCALLAB_GRIDONE;Tonificazione del colore +TP_LOCALLAB_GRIDTWO;Diretto +TP_LOCALLAB_GUIDBL_TOOLTIP;Applica un filtro guidato con raggio regolabile. Consente di ridurre gli artefatti o sfocare l'immagine. +TP_LOCALLAB_GUIDBL;Raggio morbido +TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Modifica la funzione di distribuzione del filtro guidato. I valori negativi simulano una sfocatura gaussiana. +TP_LOCALLAB_GUIDFILTER_TOOLTIP;Può ridurre o aumentare gli artefatti. +TP_LOCALLAB_GUIDFILTER;Raggio del filtro guidato +TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensità del filtro guidato. +TP_LOCALLAB_HHMASK_TOOLTIP;Regolazioni fini della tonalità, ad esempio per la pelle. +TP_LOCALLAB_HIGHMASKCOL;Alteluci +TP_LOCALLAB_HLH;H +TP_LOCALLAB_HUECIE;Tonalità +TP_LOCALLAB_IND;Independente (mouse) +TP_LOCALLAB_INDSL;Independento (mouse + scorrimento) +TP_LOCALLAB_INVBL_TOOLTIP;Alternativa alla modalità 'Inversa': usa due spot\Primo spot:\nell'immagine intera\in\Secondo spot: escluso lo spot. +TP_LOCALLAB_INVBL;Inverso +TP_LOCALLAB_INVERS_TOOLTIP;Meno possibilità se selezionato (Inverso).\n\nAlternativa: usa due spot\nPrimo spot:\n Immagine intera\n \nSecondo spot: escluso spot\n\n Inverso abiliterà questo strumento per l'area esterna allo spot, mentre il l'area all'interno dello spot non verrà influenzata dallo strumento. +TP_LOCALLAB_INVERS;Inverso +TP_LOCALLAB_INVMASK;Algoritmo inverso +TP_LOCALLAB_ISOGR;Distribuzione (ISO) +TP_LOCALLAB_JAB;Usa la compensazione dell'esposizione dei neri e la compensazione dell'esposizione dei bianchi +TP_LOCALLAB_JABADAP_TOOLTIP;Adattamento uniforme percettivo.\nRegola automaticamente il rapporto tra Jz e saturazione tenendo conto della 'Luminanza assoluta'. +TP_LOCALLAB_JZ100_TOOLTIP;Regola automaticamente il livello di riferimento Jz 100 cd/m2 (segnale immagine).\nModifica il livello di saturazione e l'azione dell''adattamento PU' (adattamento uniforme percettivo). +TP_LOCALLAB_JZ100;Riferimento Jz 100cd/m2 +TP_LOCALLAB_JZADAP; Adattamento PU +TP_LOCALLAB_JZCH;Crominanza +TP_LOCALLAB_JZCHROM;Crominanza +TP_LOCALLAB_JZCLARICRES;Unisci crominanza Cz +TP_LOCALLAB_JZCLARILRES;Unisci Jz +TP_LOCALLAB_JZCONT;Contrasto +TP_LOCALLAB_JZFORCE_TOOLTIP;Consente di forzare il valore Jz massimo su 1 per una migliore risposta dello slider e della curva. +TP_LOCALLAB_JZFORCE;Forza il massimo Jz di 1 +TP_LOCALLAB_JZFRA;Jz Cz Hz Regolazioni dell'immagine +TP_LOCALLAB_JZHFRA;Curve Hz +TP_LOCALLAB_JZHJZFRA;Curva Jz(Hz) +TP_LOCALLAB_JZHUECIE;Rotazione della tonalità +TP_LOCALLAB_JZLIGHT;Luminosità +TP_LOCALLAB_JZLOG;Codifica del registro Jz +TP_LOCALLAB_JZLOGWB_TOOLTIP;Se Auto è abilitato, calcolerà e regolerà i livelli Ev e la 'Luminanza media Yb%' per l'area spot. I valori risultanti verranno utilizzati da tutte le operazioni Jz inclusa 'Log Encoding Jz'.\nCalcola anche la luminanza assoluta al momento dello scatto. +TP_LOCALLAB_JZLOGWBS_TOOLTIP;Le regolazioni Ev nero e Ev bianco possono essere diverse a seconda che venga utilizzata la codifica Log o Sigmoid.\nPer Sigmoid, potrebbe essere necessario un cambiamento (aumento nella maggior parte dei casi) di Ev bianco per ottenere una migliore resa delle luci, del contrasto e della saturazione. +TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb è la luminanza relativa dello sfondo, espressa come percentuale di grigio. Il 18% di grigio corrisponde a una luminanza di sfondo del 50% quando espressa in CIE L.\nI dati si basano sulla luminanza media dell'immagine.\nSe utilizzata con Log Encoding, la luminanza media viene utilizzata per determinare la quantità di guadagno necessaria da applicare al segnale prima della codifica del log. Valori più bassi di luminanza media si tradurranno in un aumento del guadagno. +TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (solo in modalità 'Avanzata'). Funziona solo se il dispositivo di output (monitor) è HDR (luminanza di picco superiore a 100 cd/m2 - idealmente tra 4000 e 10000 cd/m2. Luminanza del punto nero inferiore a 0,005 cd/m2). Ciò presuppone che a) l'ICC-PCS per lo schermo utilizzi Jzazbz (o XYZ), b) funzioni con precisione reale, c) che il monitor sia calibrato (se possibile con una gamma DCI-P3 o Rec-2020), d) che la solita gamma (sRGB o BT709) è sostituita da una funzione Perceptual Quantiser (PQ). +TP_LOCALLAB_JZPQFRA_TOOLTIP;Permette di adattare l'algoritmo Jz ad un ambiente SDR o alle caratteristiche (prestazioni) di un ambiente HDR come segue:\n a) per valori di luminanza compresi tra 0 e 100 cd/m2, il sistema si comporta come se fosse in un ambiente SDR .\n b) per valori di luminanza compresi tra 100 e 10000 cd/m2 è possibile adattare l'algoritmo alle caratteristiche HDR dell'immagine e del monitor.\n\nSe 'PQ - Luminanza di picco' è impostato su 10000, 'Rimappatura Jz' si comporta allo stesso modo dell'algoritmo Jzazbz originale. +TP_LOCALLAB_JZPQFRA;Rimappatura Jz +TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Quantizzatore percettivo): consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 120 cd/m2).\nPuò essere utilizzato per adattarsi a diverse immagini, processi e dispositivi. +TP_LOCALLAB_JZPQREMAP;PQ - Luminanza di picco +TP_LOCALLAB_JZQTOJ_TOOLTIP;Ti permette di utilizzare 'Luminanza relativa' invece di 'Luminanza assoluta' - La luminosità diventa Luminosità.\nLe modifiche influiscono: sul cursore Luminosità, sul cursore Contrasto e sulla curva Jz(Jz). +TP_LOCALLAB_JZQTOJ;Luminanza relativa +TP_LOCALLAB_JZSAT;Saturatione +TP_LOCALLAB_JZSHFRA;Ombre/Alteluci Jz +TP_LOCALLAB_JZSOFTCIE;Raggio morbido (Filtro guidato) +TP_LOCALLAB_JZSTRSOFTCIE;Filtro guidato dell'intensità +TP_LOCALLAB_JZTARGET_EV;Visualizzazione della luminanza media (Yb%) +TP_LOCALLAB_JZTHRHCIE;Soglia cromatica per Jz(Hz) +TP_LOCALLAB_JZWAVEXP;Wavelet Jz +TP_LOCALLAB_LABBLURM;Maschera di sfocatura +TP_LOCALLAB_LABEL;Aggiustamenti locali +TP_LOCALLAB_LABGRID_VALUES;Alto(a)=%1 Alto(b)=%2\nBasso(a)=%3 Basso(b)=%4 +TP_LOCALLAB_LABGRID;Griglia di correzione del colore +TP_LOCALLAB_LABGRIDMERG;Sfondo +TP_LOCALLAB_LABSTRUM;Maschera di struttura +TP_LOCALLAB_LAP_MASK_TOOLTIP;Risolve i PDE per tutte le maschere laplaciane.\nSe abilitata, la maschera della soglia laplaciana riduce gli artefatti e uniforma il risultato.\nSe disabilitata, la risposta è lineare. +TP_LOCALLAB_LAPLACC;ΔØ La maschera laplaciana risolve la PDE +TP_LOCALLAB_LAPLACE;Soglia laplaciana ΔE +TP_LOCALLAB_LAPLACEXP;Soglia laplaciana +TP_LOCALLAB_LAPMASKCOL;Soglia laplaciana +TP_LOCALLAB_LAPRAD_TOOLTIP;Il raggio uniforme utilizza un filtro guidato per ridurre gli artefatti e uniformare la transizione. +TP_LOCALLAB_LAPRAD1_TOOLTIP;Aumenta il contrasto della maschera aumentando i valori di luminanza delle aree più chiare. Può essere utilizzato insieme alle curve L(L) e LC(H). +TP_LOCALLAB_LAPRAD2_TOOLTIP;Il raggio uniforme utilizza un filtro guidato per ridurre gli artefatti e uniformare la transizione. +TP_LOCALLAB_LC_FFTW_TOOLTIP;La FFT migliora la qualità e consente l'utilizzo di raggi ampi, ma aumenta i tempi di lavorazione (dipende dall'area da trattare). Preferibile l'utilizzo solo per raggi ampi. La dimensione dell'area può essere ridotta di alcuni pixel per ottimizzare la FFTW. Ciò può ridurre il tempo di elaborazione di un fattore da 1,5 a 10. +TP_LOCALLAB_LC_TOOLNAME;Contrasto locale e wavelet +TP_LOCALLAB_LCLABELS_TOOLTIP;Visualizza i valori di rumore medio e alto per l'area mostrata nel pannello di anteprima (con zoom al 100%). I valori del rumore sono raggruppati per livelli wavelet 0,1,2,3 e 4,5,6.\nI valori visualizzati sono solo indicativi e sono progettati per assistere nelle regolazioni del rumore. Non devono essere interpretati come livelli di rumore assoluti.\n\n 300: Molto rumoroso\n 100-300: Rumoroso\n 50-100: Moderatamente rumoroso\n < 50: Basso rumore\n\nPermettono di vedere:\ n*L'impatto della riduzione del rumore nella scheda Dettagli del menu principale.\n*L'influenza delle medie non locali, delle wavelet e del DCT sul rumore della luminanza.\n*L'influenza delle wavelet e del DCT sul rumore della crominanza.\n *L'influenza di cattura nitidezza e demosaicizzazione. +TP_LOCALLAB_LCLABELS;Livelli di rumore residuo +TP_LOCALLAB_LEVELBLUR;Livelli massimi di sfocatura +TP_LOCALLAB_LEVELWAV_TOOLTIP;Il Livello si adatta automaticamente alla dimensione dello spot e dell'anteprima.\Dal livello 9 dimensione max 512 al livello 1 dimensione max = 4. +TP_LOCALLAB_LEVELWAV;Livelli di Wavelet +TP_LOCALLAB_LEVFRA;Livelli +TP_LOCALLAB_LIGHTN_TOOLTIP;In modalità inversa: la selezione = -100 forza la luminanza a zero. +TP_LOCALLAB_LIGHTNESS;Luminosità +TP_LOCALLAB_LIGHTRETI;Luminosità +TP_LOCALLAB_LINEAR;Linearità +TP_LOCALLAB_LIST_NAME;Aggiungi strumento al punto corrente... +TP_LOCALLAB_LIST_TOOLTIP;Puoi selezionare 3 livelli di complessità per ciascuno strumento: Base, Standard e Avanzato.\nL'impostazione predefinita per tutti gli strumenti è Base ma può essere modificata nella finestra Preferenze.\nPuoi anche modificare il livello di complessità per strumento base durante la modifica. +TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Permette di diminuire o aumentare l'effetto su particolari livelli di dettaglio della maschera puntando su determinate zone di luminanza (in genere le più chiare). +TP_LOCALLAB_LMASK_LL_TOOLTIP;Ti permette di cambiare liberamente il contrasto della maschera.\n Ha una funzione simile ai cursori Gamma e Pendenza.\n Ti permette di individuare alcune parti dell'immagine (solitamente le parti più chiare della maschera utilizzando la curva per escludere le parti più scure). Può creare artefatti. +TP_LOCALLAB_LOC_CONTRAST;Contrasto locale e wavelet +TP_LOCALLAB_LOC_CONTRASTPYR;Piramide 1: +TP_LOCALLAB_LOC_CONTRASTPYR2;Piramide 2: +TP_LOCALLAB_LOC_CONTRASTPYR2LAB; Contrasto per livello/TM/Contrasto direzionale +TP_LOCALLAB_LOC_CONTRASTPYRLAB; Filtro graduato/Nitidezza bordi/Sfocatura +TP_LOCALLAB_LOC_RESIDPYR;Immagine residua (principale) +TP_LOCALLAB_LOCCONT;Maschera di contrasto +TP_LOCALLAB_LOG_TOOLNAME;Codifica del registro +TP_LOCALLAB_LOG;Codifica del registro +TP_LOCALLAB_LOG1FRA;CAM16 Regolazioni dell'immagine +TP_LOCALLAB_LOG2FRA;Condizioni di visualizzazione +TP_LOCALLAB_LOGAUTO_TOOLTIP;Premendo questo pulsante si calcolerà la gamma dinamica e la 'Luminanza media' per le condizioni della scena se è selezionata la 'Luminanza media automatica (Yb%)).\nCalcola anche la luminanza assoluta al momento dello scatto.\nPremere nuovamente il pulsante per regolare i valori calcolati automaticamente. +TP_LOCALLAB_LOGAUTO;Automatico +TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Calcola automaticamente la "luminanza media" per le condizioni della scena quando viene premuto il pulsante "Automatico" in Livelli di esposizione relativa. +TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Calcola automaticamente la "luminanza media" per le condizioni della scena. +TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValori inferiori a 2 riducono l'azione dell'algoritmo rendendo le ombre più scure e le luci più luminose.\nCon valori maggiori di 2, le ombre sono più grigie e le luci diventano più sbiadite. +TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. +TP_LOCALLAB_LOGCIE_TOOLTIP;Consente di utilizzare Nero Ev, Bianco Ev, Luminanza media scena (Yb%) e Luminanza media visualizzazione (Yb%) per la mappatura dei toni utilizzando la codifica Log Q. +TP_LOCALLAB_LOGCIE;Codifica del registro anziché Sigmoid +TP_LOCALLAB_LOGCOLORF_TOOLTIP;Quantità di tonalità percepita in relazione al grigio.\nIndicatore che uno stimolo appare più o meno colorato. +TP_LOCALLAB_LOGCOLORFL;Colorazione (M) +TP_LOCALLAB_LOGCONQL;Contrasto (Q) +TP_LOCALLAB_LOGCONTHRES;Soglia di Contrasto (J & Q) +TP_LOCALLAB_LOGCONTL_TOOLTIP;Il contrasto (J) in CIECAM16 tiene conto dell'aumento della colorazione percepita con la luminanza. +TP_LOCALLAB_LOGCONTL;Contrasto (J) +TP_LOCALLAB_LOGCONTQ_TOOLTIP;Il contrasto (Q) in CIECAM16 tiene conto dell'aumento della colorazione percepita con la luminosità. +TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Regola la gamma di contrasto dei toni medi (J e Q).\nI valori positivi riducono progressivamente l'effetto dei cursori Contrasto (J e Q). I valori negativi aumentano progressivamente l'effetto dei cursori Contrasto. +TP_LOCALLAB_LOGDETAIL_TOOLTIP;Agisce principalmente sulle alte frequenze. +TP_LOCALLAB_LOGENCOD_TOOLTIP;Mappatura dei toni con codifica logaritmica (ACES).\nUtile per immagini sottoesposte o immagini con elevata gamma dinamica.\n\nProcesso in due fasi: 1) Calcolo della gamma dinamica 2) Regolazione manuale. +TP_LOCALLAB_LOGEXP;Tutti gli strumenti +TP_LOCALLAB_LOGFRA;Condizioni della scena +TP_LOCALLAB_LOGFRAME_TOOLTIP;Consente di calcolare e regolare i livelli Ev e la "luminanza media Yb%" (punto grigio sorgente) per l'area spot. I valori risultanti verranno utilizzati da tutte le operazioni di laboratorio e dalla maggior parte delle operazioni RGB in corso.\nCalcola inoltre la luminanza assoluta al momento dello scatto. +TP_LOCALLAB_LOGIMAGE_TOOLTIP;Tiene conto delle variabili Ciecam corrispondenti: ovvero Contrasto (J) e Saturazione (s), nonché Contrasto (Q), Luminosità (Q), Luminosità (J) e Colorazione (M) (in modalità Avanzata). +TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Vicino alla Luminosità (L*a*b*). Tiene conto dell'aumento della colorazione percepita. +TP_LOCALLAB_LOGLIGHTL;Luminosità (J) +TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Quantità percepita di luce emanata da uno stimolo.\nIndicatore che uno stimolo sembra essere più o meno luminoso, chiaro. +TP_LOCALLAB_LOGLIGHTQ;Luminosità (Q) +TP_LOCALLAB_LOGLIN;Modalità logaritmo +TP_LOCALLAB_LOGPFRA;Livelli di esposizione relativa +TP_LOCALLAB_LOGREPART_TOOLTIP;Consente di regolare la forza relativa dell'immagine con codifica log rispetto all'immagine originale.\nNon influisce sul componente Ciecam. +TP_LOCALLAB_LOGREPART;Overall strength +TP_LOCALLAB_LOGSATURL_TOOLTIP;La saturazione (s) in CIECAM16 corrisponde al colore di uno stimolo in relazione alla propria luminosità.\nAgisce principalmente sui toni medi e sulle alte luci. +TP_LOCALLAB_LOGSCENE_TOOLTIP;Corrisponde alle condizioni di ripresa. +TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Modifica toni e colori per tenere conto delle condizioni della scena.\n\nMedia: condizioni di luce medie (standard). L'immagine non cambierà.\n\nDim: condizioni di luminosità. L'immagine diventerà leggermente più luminosa.\n\nScuro: condizioni di oscurità. L'immagine diventerà più luminosa. +TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corrisponde al supporto su cui verrà visualizzata l'immagine finale (monitor, TV, proiettore, stampante, ecc.), nonché alle condizioni circostanti. +TP_LOCALLAB_LUM;LL - CC +TP_LOCALLAB_LUM46LABEL;Livelli luminanza 456: Media=%1 Alta=%2 +TP_LOCALLAB_LUMADARKEST;Più oscuro +TP_LOCALLAB_LUMASK_TOOLTIP;Regola la tonalità di grigio o il colore dello sfondo della maschera in Mostra maschera (Maschera e modifiche). +TP_LOCALLAB_LUMASK;Maschera colore/luminosità dello sfondo +TP_LOCALLAB_LUMAWHITESEST;Il più leggero +TP_LOCALLAB_LUMFRA;Norma L*a*b* +TP_LOCALLAB_LUMLABEL;Livelli luminanza 0123: Media=%1 Alta=%2 +TP_LOCALLAB_MASFRAME_TOOLTIP;Per tutte le maschere.\nPrende in considerazione l'immagine ΔE per evitare di modificare l'area di selezione quando vengono utilizzati i seguenti strumenti maschera: Gamma, Pendenza, Crominanza, Curva di contrasto, Contrasto locale (per livello wavelet), Maschera di sfocatura e Maschera di struttura (se abilitata ).\nDisabilitato quando viene utilizzata la modalità Inversa. +TP_LOCALLAB_MASFRAME;Maschera e Unisci +TP_LOCALLAB_MASK_TOOLTIP;Puoi abilitare più maschere per uno strumento attivando un altro strumento e utilizzando solo la maschera (imposta i cursori dello strumento su 0 ).\n\nPuoi anche duplicare il punto e posizionarlo vicino al primo punto. Le piccole variazioni nei riferimenti spot consentono di effettuare regolazioni fini. +TP_LOCALLAB_MASK;Curve +TP_LOCALLAB_MASK2;Curva di contrasto +TP_LOCALLAB_MASKCOM_TOOLNAME;Maschera di colore comune +TP_LOCALLAB_MASKCOM_TOOLTIP;Uno strumento a sé stante.\Può essere utilizzato per regolare l'aspetto dell'immagine (crominanza, luminanza, contrasto) e la trama in funzione di Scope. +TP_LOCALLAB_MASKCOM;Maschera di colore comune +TP_LOCALLAB_MASKCURVE_TOOLTIP;Le 3 curve sono impostate su 1 (massimo) per impostazione predefinita:\nC=f(C) la crominanza varia in base alla crominanza. È possibile diminuire la crominanza per migliorare la selezione. Impostando questa curva vicino allo zero (con un valore basso di C per attivare la curva) è possibile desaturare lo sfondo in modalità Inversa.\nL=f(L) la luminanza varia in base alla luminanza, quindi è possibile diminuire la luminosità a migliorare la selezione.\nL e C = f(H) la luminanza e la crominanza variano con la tonalità, quindi è possibile diminuire la luminanza e la crominanza per migliorare la selezione. +TP_LOCALLAB_MASKDDECAY;Intensità di decadimento +TP_LOCALLAB_MASKDE_TOOLTIP;Utilizzato per indirizzare l'eliminazione del rumore in funzione delle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitata per utilizzare questa funzione.\n Se la maschera è al di sotto della soglia 'scura', la riduzione del rumore verrà applicata progressivamente.\n iSe la maschera è al di sopra della soglia 'chiara', la riduzione del rumore verrà applicata progressivamente.\n Tra In entrambi i casi, le impostazioni dell'immagine senza Denoise verranno mantenute, a meno che non si regoli i cursori 'Rimozione rumore luminanza area grigia' o 'Rimozione rumore crominanza area grigia'. +TP_LOCALLAB_MASKDECAY_TOOLTIP;Gestisce il tasso di decadimento per i livelli di grigio nella maschera.\n Decay = 1 lineare, Decay > 1 transizioni paraboliche più nette, Decay < 1 transizioni più graduali. +TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. +TP_LOCALLAB_MASKGF_TOOLTIP;Utilizzato per indirizzare il filtro guidato in funzione delle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitato a utilizzare questa funzione.\n Se la maschera è al di sotto della soglia 'scura', il GF verrà applicato progressivamente.\n Se la maschera è al di sopra della soglia 'chiara', il GF verrà applicato progressivamente.\n Tra i due, verranno mantenute le impostazioni dell'immagine senza GF. +TP_LOCALLAB_MASKH;Curva tonalità +TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; Il filtro guidato viene progressivamente ridotto dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (come determinato dalla maschera).\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'struttura maschera', 'Raggio uniforme', 'Gamma e pendenza', 'Curva di contrasto', 'Wavelet di contrasto locale'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura' , 'Maschera di sfocatura', 'Raggio attenuato', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Limite del tono più chiaro oltre il quale i parametri CBDL (solo luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni CBDL.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio :'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\nUtilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; Il rumore viene progressivamente ridotto dal 100% dell'impostazione della soglia allo 0% al valore massimo del bianco (come determinato dalla maschera).\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura ', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai valori originali prima di essere modificati dalle impostazioni "Gamma dinamica ed esposizione".\n Puoi utilizzare alcuni strumenti in "Maschera e modifiche" per modificare i livelli di grigio: " Raggio uniforme", Gamma e Pendenza, "Curva di contrasto".\n Utilizza un "selettore colori bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di codifica del registro.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Raggio uniforme', 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Limite di tono più chiaro al di sopra del quale i parametri Retinex (solo Luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Retinex.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Smussato raggio', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Ombre E Luci.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Mappatura tono.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Limite del tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Vividezza e Caldo Freddo.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Raggio uniforme ', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Contrasto locale e Wavelet.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme ', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLC_TOOLTIP;Utilizzato dalla luminanza wavelet.\nCiò consente di indirizzare la riduzione del rumore in base alle informazioni sulla luminanza dell'immagine contenute nella maschera L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n 'Soglia luminanza area scura'. Se 'Rafforza il denoise nelle aree scure e chiare' > 1 il denoise viene progressivamente aumentato dallo 0% all'impostazione della soglia al 100% al valore massimo del nero (determinato dalla maschera).\n 'Soglia luminanza dell'area chiara'. La riduzione del rumore viene progressivamente ridotta dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (determinato dalla maschera).\n Nell'area tra le due soglie, le impostazioni della riduzione del rumore non sono influenzate dalla maschera. +TP_LOCALLAB_MASKLCTHR;Soglia di luminanza dell'area chiara +TP_LOCALLAB_MASKLCTHR2;Soglia luminanza dell'area chiara +TP_LOCALLAB_MASKLCTHRLOW;Soglia di luminanza dell'area scura +TP_LOCALLAB_MASKLCTHRLOW2;Soglia luminanza dell'area scura +TP_LOCALLAB_MASKLCTHRMID;Rimuovi rumore luminanza dell'area grigia +TP_LOCALLAB_MASKLCTHRMIDCH;Rimuovi rumore crominanza area grigia +TP_LOCALLAB_MASKLNOISELOW;Rinforza le aree scure/chiare +TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;Il filtro guidato viene progressivamente aumentato dallo 0% dell'impostazione della soglia al 100% del valore massimo del nero (come determinato dalla maschera).\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio : 'Maschera struttura', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: ' Maschera struttura", "Maschera di sfocatura", "Raggio uniforme", Gamma e pendenza, "Curva di contrasto", "Contrasto locale" (wavelet).\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate . Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri CBDL (solo Luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni CBDL.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare il grigio livelli: "Raggio uniforme", Gamma e pendenza, "Curva di contrasto".\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;Il rumore viene progressivamente aumentato dallo 0% dell'impostazione della soglia al 100% del valore massimo del nero (come determinato dalla maschera).\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni 'Gamma dinamica ed esposizione'.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare il grigio livelli: "Raggio uniforme", Gamma e pendenza, "Curva di contrasto".\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di codifica del registro.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Smussato raggio', 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri Retinex (solo Luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Retinex.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare il grigio livelli: "Raggio uniforme", Gamma e pendenza, "Curva di contrasto".\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Ombre Evidenziazioni.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Smussato raggio', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Mappatura toni.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Smussato raggio', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Vividezza e Caldo Freddo.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Contrasto locale e Wavelet.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKRECOL_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni Colore e Luce in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC La maschera (H) deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia scura e sopra la soglia chiara verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni Colore e Luce \n Tra queste due aree, verrà applicato l'intero valore delle impostazioni Colore e Luce. +TP_LOCALLAB_MASKRECOTHRES;Soglia di ripristino +TP_LOCALLAB_MASKREEXP_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni 'Gamma dinamica ed esposizione' in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) oppure per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree 'scure' e 'chiare' sotto la soglia di buio e sopra la soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dal ' Impostazioni di "Gamma dinamica ed esposizione" \n Tra queste due aree, verrà applicato il valore completo delle impostazioni di "Gamma dinamica ed esposizione". +TP_LOCALLAB_MASKRELOG_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni di codifica Log in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia scura e sopra la soglia chiara verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni di codifica del registro - può essere utilizzato per ripristinare le luci ricostruite dalla propagazione del colore \n Tra queste due aree, verrà applicato l'intero valore delle impostazioni di codifica del registro. +TP_LOCALLAB_MASKRESCB_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni CBDL (solo luminanza) in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia scura e sopra la soglia chiara verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni CBDL \n Tra queste due aree, verrà applicato l'intero valore delle impostazioni CBDL. +TP_LOCALLAB_MASKRESH_TOOLTIP;Utilizza l'effetto delle impostazioni Ombre Evidenziazioni in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia di buio e sopra la soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni Ombre Alte luci\n Tra queste due aree, verrà applicato l'intero valore delle impostazioni Ombre Evidenziazioni. +TP_LOCALLAB_MASKRESRETI_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni di Retinex (solo luminanza) in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree 'scure' e 'chiare' sotto la soglia di buio e sopra la soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni di Retinex \n Tra queste due aree, verrà applicato l'intero valore delle impostazioni Retinex. +TP_LOCALLAB_MASKRESTM_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni di Mappatura dei toni in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia scura e sopra la soglia chiara verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni di mappatura dei toni\n Tra queste due aree verrà applicato l'intero valore delle impostazioni di mappatura dei toni. +TP_LOCALLAB_MASKRESVIB_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni Vividezza e Caldo Freddo in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o Per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree "scure" e "chiare" al di sotto della soglia del buio e al di sopra della soglia della luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate da Vividezza e Caldo Impostazioni Freddo \n Tra queste due aree, verrà applicato il valore completo delle impostazioni Vividezza e Caldo Freddo. +TP_LOCALLAB_MASKRESWAV_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni Contrasto locale e Wavelet in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o Per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree "scure" e "chiare" al di sotto della soglia di buio e al di sopra della soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dal Contrasto locale e Impostazioni Wavelet \n Tra queste due aree, verrà applicato il valore completo delle impostazioni Contrasto locale e Wavelet. +TP_LOCALLAB_MASKUNUSABLE;Maschera disabilitata (Maschera e modifiche) +TP_LOCALLAB_MASKUSABLE;Maschera abilitata (Maschera e modifiche) +TP_LOCALLAB_MEDIAN_TOOLTIP;Puoi scegliere un valore medio compreso tra 3x3 e 9x9 pixel. Valori più alti aumentano la riduzione del rumore e la sfocatura. +TP_LOCALLAB_MEDIAN;Mediana bassa +TP_LOCALLAB_MEDIANITER_TOOLTIP;Il numero di iterazioni successive eseguite dal filtro mediano. +TP_LOCALLAB_MEDNONE;Nessuno +TP_LOCALLAB_MERCOL;Colore +TP_LOCALLAB_MERDCOL;Unisci sfondo (ΔE) +TP_LOCALLAB_MERELE;Schiarisci solo +TP_LOCALLAB_MERFIV;Somma +TP_LOCALLAB_MERFOR;Colore scherma +TP_LOCALLAB_MERFOU;Moltiplica +TP_LOCALLAB_MERGE1COLFRA;Unisci con Originale/Precedente/Sfondo +TP_LOCALLAB_MERGECOLFRA;Maschera: LCh & Struttura +TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Permette di creare maschere basate sulle 3 curve LCh e/o un algoritmo di rilevamento della struttura. +TP_LOCALLAB_MERGEMER_TOOLTIP;Prende in considerazione ΔE quando si uniscono i file (equivalente dell'ambito in questo caso). +TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacità = % del punto corrente da unire con il punto originale o precedente.\nSoglia contrasto: regola il risultato in funzione del contrasto nell'immagine originale. +TP_LOCALLAB_MERHEI;Sovrapposizione +TP_LOCALLAB_MERHUE;Tonalità +TP_LOCALLAB_MERLUCOL;Luminanza +TP_LOCALLAB_MERLUM;Luminosità +TP_LOCALLAB_MERNIN;Schermo +TP_LOCALLAB_MERONE;Normale +TP_LOCALLAB_MERSAT;Saturazione +TP_LOCALLAB_MERSEV;Luce soffusa (legacy) +TP_LOCALLAB_MERSEV0;Illusione di luce soffusa +TP_LOCALLAB_MERSEV1;Luce soffusa W3C +TP_LOCALLAB_MERSEV2;Luce forte +TP_LOCALLAB_MERSIX;Dividi +TP_LOCALLAB_MERTEN;Scurisci solo +TP_LOCALLAB_MERTHI;Colore brucia +TP_LOCALLAB_MERTHR;Differenza +TP_LOCALLAB_MERTWE;Esclusione +TP_LOCALLAB_MERTWO;Sottrai +TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' aumenta significativamente i tempi di elaborazione.\nMa riduce gli artefatti. +TP_LOCALLAB_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Ritaglia dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. +TP_LOCALLAB_MLABEL;Dati ripristinati Min=%1 Max=%2 +TP_LOCALLAB_MODE_EXPERT;Avanzato +TP_LOCALLAB_MODE_NORMAL;Standard +TP_LOCALLAB_MODE_SIMPLE;Base +TP_LOCALLAB_MRFIV;Sfondo +TP_LOCALLAB_MRFOU;Spot precedente +TP_LOCALLAB_MRONE;Nessuno +TP_LOCALLAB_MRTHR;Immagine originale +TP_LOCALLAB_MULTIPL_TOOLTIP;Ampia gamma di regolazione del tono: da -18EV a +4EV. Il primo cursore agisce su toni molto scuri compresi tra -18EV e -6EV. L'ultimo cursore agisce sui toni chiari fino a 4EV. +TP_LOCALLAB_NEIGH;Raggio +TP_LOCALLAB_NLDENOISE_TOOLTIP;'Recupero dettagli' agisce su una trasformazione laplaciana per individuare aree uniformi anziché aree con dettagli. +TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Valori più bassi preservano dettagli e texture, valori più alti aumentano il denoise.\nSe gamma = 3.0 Viene utilizzata la luminanza 'lineare'. +TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Utilizza questo cursore per adattare la quantità di riduzione rumore alla dimensione degli oggetti da elaborare. +TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Valori più alti aumentano il rumore a scapito del tempo di elaborazione. +TP_LOCALLAB_NLDET;Recupero dettagli +TP_LOCALLAB_NLFRA;Mezzi non locali: Luminanza +TP_LOCALLAB_NLFRAME_TOOLTIP;Il denoising delle medie non locali prende una media di tutti i pixel dell'immagine, ponderata in base alla loro somiglianza con il pixel di destinazione.\nRiduce la perdita di dettaglio rispetto agli algoritmi della media locale.\nViene preso in considerazione solo il rumore della luminanza. Il rumore della crominanza viene elaborato al meglio utilizzando wavelet e trasformate di Fourier (DCT).\nPuò essere utilizzato insieme a "Rimozione rumore luminanza per livello" o da solo. +TP_LOCALLAB_NLGAM;Gamma +TP_LOCALLAB_NLLUM;Forza +TP_LOCALLAB_NLPAT;Dimensione massima della patch +TP_LOCALLAB_NLRAD;Dimensione massima del raggio +TP_LOCALLAB_NOISE_TOOLTIP;Aggiunge rumore di luminanza. +TP_LOCALLAB_NOISECHROC_TOOLTIP;Se superiore a zero, l'algoritmo di alta qualità è abilitato.\nCoarse è per slider >=0.02. +TP_LOCALLAB_NOISECHROCOARSE;Crominanza grossolana (Wav) +TP_LOCALLAB_NOISECHRODETAIL;Recupero dettagli crominanza +TP_LOCALLAB_NOISECHROFINE;Crominanza fine (Wav) +TP_LOCALLAB_NOISEGAM_TOOLTIP;Se gamma = 1 Luminanza viene utilizzato 'Lab'. Se gamma = 3.0 Viene utilizzata la luminanza 'lineare'.\nValori più bassi preservano dettagli e texture, valori più alti aumentano il rumore. +TP_LOCALLAB_NOISEGAM;Gamma +TP_LOCALLAB_NOISELEQUAL;Equalizzatore bianco-nero +TP_LOCALLAB_NOISELUMCOARSE;Luminanza grossolana (Wav) +TP_LOCALLAB_NOISELUMDETAIL;Recupero dettaglio luminanza +TP_LOCALLAB_NOISELUMFINE;Luminanza fine 1 (Wav) +TP_LOCALLAB_NOISELUMFINETWO;Luminanza fine 2 (Wav) +TP_LOCALLAB_NOISELUMFINEZERO;Luminanza fine 0 (Wav) +TP_LOCALLAB_NOISEMETH;Rimuovi rumore +TP_LOCALLAB_NONENOISE;Nessuno +TP_LOCALLAB_NUL_TOOLTIP;. +TP_LOCALLAB_OFFS;Spostamento +TP_LOCALLAB_OFFSETWAV;Spostamento +TP_LOCALLAB_OPACOL;Opacità +TP_LOCALLAB_ORIGLC;Unisci solo con l'immagine originale +TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifica ΔE prima di qualsiasi modifica apportata da 'Scope'. Ciò consente di differenziare l'azione per diverse parti dell'immagine (rispetto ad esempio allo sfondo). +TP_LOCALLAB_ORRETISTREN_TOOLTIP;Agisce sulla soglia laplaciana, maggiore è l'azione, più si ridurranno le differenze di contrasto. +TP_LOCALLAB_PASTELS2;Vivace +TP_LOCALLAB_PDE;Attenuatore contrasto - Compressione della gamma dinamica +TP_LOCALLAB_PDEFRA;Attenuatore contrasto Æ’ +TP_LOCALLAB_PDEFRAME_TOOLTIP;Algoritmo PDE IPOL adattato per Rawtherapee: fornisce risultati diversi e richiede impostazioni diverse rispetto al menu principale 'Esposizione'.\nPuò essere utile per immagini sottoesposte o con elevata gamma dinamica. +TP_LOCALLAB_PREVHIDE;Nascondi impostazioni aggiuntive +TP_LOCALLAB_PREVIEW;Anteprima ΔE +TP_LOCALLAB_PREVSHOW;Mostra impostazioni aggiuntive +TP_LOCALLAB_PROXI;Decadimento ΔE +TP_LOCALLAB_QUAAGRES;Aggressivo +TP_LOCALLAB_QUACONSER;Conservatore +TP_LOCALLAB_QUAL_METHOD;Qualità globale +TP_LOCALLAB_QUALCURV_METHOD;Tipo di curva +TP_LOCALLAB_QUANONEALL;Disattivato +TP_LOCALLAB_QUANONEWAV;Significa solo non-locale +TP_LOCALLAB_RADIUS_TOOLTIP;Utilizza una trasformata veloce di Fourier per raggio > 30. +TP_LOCALLAB_RADIUS;Raggio +TP_LOCALLAB_RADMASKCOL;Raggio uniforme +TP_LOCALLAB_RECOTHRES02_TOOLTIP;Se il valore della 'Soglia di ripristino' è maggiore di 1, la maschera in Maschera e Modifiche tiene conto di eventuali modifiche precedenti apportate all'immagine ma non di quelle apportate con lo strumento corrente (es. Colore e Luce, Wavelet, Cam16, ecc.) .)\nSe il valore della 'Soglia di ripristino' è inferiore a 1, la maschera in Maschera e Modifiche non tiene conto di eventuali modifiche precedenti all'immagine.\n\nIn entrambi i casi, la 'Soglia di ripristino' agisce sulla immagine mascherata modificata dallo strumento corrente (Colore e Luce, Wavelet, Cam16, ecc.). +TP_LOCALLAB_RECT;Rettangolo +TP_LOCALLAB_RECURS_TOOLTIP;Forza l'algoritmo a ricalcolare i riferimenti dopo l'applicazione di ogni strumento.\nUtile anche per lavorare con le maschere. +TP_LOCALLAB_RECURS;Riferimenti ricorsivi +TP_LOCALLAB_REN_DIALOG_LAB;Inserisci il nome del nuovo punto di controllo +TP_LOCALLAB_REN_DIALOG_NAME;Rinominare punto di controllo +TP_LOCALLAB_REPARCOL_TOOLTIP;Permette di regolare l'intensità relativa dell'immagine Colore e Luce rispetto all'immagine originale. +TP_LOCALLAB_REPARDEN_TOOLTIP;Permette di regolare l'intensità relativa dell'immagine Rimuovi rumore rispetto all'immagine originale. +TP_LOCALLAB_REPAREXP_TOOLTIP;Consente di regolare la forza relativa dell'immagine Gamma dinamica ed Esposizione rispetto all'immagine originale. +TP_LOCALLAB_REPARSH_TOOLTIP;Consente di regolare l'intensità relativa dell'immagine Ombre/Alte luci e dell'equalizzatore toni rispetto all'immagine originale. +TP_LOCALLAB_REPARTM_TOOLTIP;Permette di regolare la forza relativa dell'immagine di mappatura tono rispetto all'immagine originale. +TP_LOCALLAB_REPARW_TOOLTIP;Permette di regolare l'intensità relativa del contrasto locale e dell'immagine wavelet rispetto all'immagine originale. +TP_LOCALLAB_RESID;Immagine residua +TP_LOCALLAB_RESIDBLUR;Sfoca immagine residua +TP_LOCALLAB_RESIDCHRO;Croma immagine residua +TP_LOCALLAB_RESIDCOMP;Comprimi l'immagine residua +TP_LOCALLAB_RESIDCONT;Contrasto immagine residua +TP_LOCALLAB_RESIDHI;Alteluci +TP_LOCALLAB_RESIDHITHR;Soglia evidenziazioni +TP_LOCALLAB_RESIDSHA;Ombre +TP_LOCALLAB_RESIDSHATHR;Soglia ombre +TP_LOCALLAB_RET_TOOLNAME;Rimozione foschia e Retinex +TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Non ha effetto quando il valore di 'Chiarezza = 1' o 'Scurità =2'.\nPer altri valori, viene applicato l'ultimo passaggio di un algoritmo 'Retinex a scala multipla' (simile a 'contrasto locale'). Questi 2 cursori, associati a 'Intensità', consentono di effettuare regolazioni a monte del contrasto locale. +TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Regola i parametri interni per ottimizzare la risposta.\nPreferibile mantenere i valori 'Dati ripristinati' vicini a Min=0 e Max=32768 (modalità registro), ma sono possibili altri valori. +TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;La modalità logaritmo introduce più contrasto ma genererà anche più aloni. +TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;I cursori del raggio e della varianza ti consentono di regolare la foschia e puntare al primo piano o allo sfondo. +TP_LOCALLAB_RETI_SCALE_TOOLTIP;Se Scala=1, Retinex si comporta come contrasto locale con possibilità aggiuntive.\nAumentando il valore di Scala aumenta l'intensità dell'azione ricorsiva a scapito del tempo di elaborazione. +TP_LOCALLAB_RETI;Rimozione foschia e Retinex +TP_LOCALLAB_RETIFRA;Retinex +TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex può essere utile per elaborare immagini:\nche sono sfocate, nebbiose o confuse (oltre a Dehaze).\nche contengono grandi differenze di luminanza.\nPuò essere utilizzato anche per effetti speciali (mappatura dei toni). +TP_LOCALLAB_RETIM;Retinex originale +TP_LOCALLAB_RETITOOLFRA;Strumenti Retinex +TP_LOCALLAB_REWEI;La riponderazione itera +TP_LOCALLAB_RGB;Curva toni RGB +TP_LOCALLAB_RGBCURVE_TOOLTIP;In modalità RGB hai 4 scelte: Standard, Standard ponderato, Luminanza e Simil-pellicola. +TP_LOCALLAB_ROW_NVIS;Non visibile +TP_LOCALLAB_ROW_VIS;Visibile +TP_LOCALLAB_RSTPROTECT_TOOLTIP;La protezione del rosso e della tonalità della pelle influisce sui cursori Saturazione, Crominanza e Colore. +TP_LOCALLAB_SATUR;Saturazione +TP_LOCALLAB_SATURV;Saturazione (s) +TP_LOCALLAB_SCALEGR;Scala +TP_LOCALLAB_SCALERETI;Scala +TP_LOCALLAB_SCALTM;Scala +TP_LOCALLAB_SCOPEMASK_TOOLTIP;Abilitato se la maschera immagine ΔE è abilitata.\nValori bassi evitano il ritocco dell'area selezionata. +TP_LOCALLAB_SCOPEMASK;Ambito (maschera immagine ΔE) +TP_LOCALLAB_SENSI_TOOLTIP;Regola l'ambito dell'azione:\nValori piccoli limitano l'azione a colori simili a quelli al centro del punto.\nValori alti consentono allo strumento di agire su una gamma più ampia di colori. +TP_LOCALLAB_SENSI;Ambito +TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Regola i colori da escludere. +TP_LOCALLAB_SENSIEXCLU;Ambito +TP_LOCALLAB_SENSIMASK_TOOLTIP;Regolazione dell'ambito specifica per il comune strumento maschera.\nAgisce sulla differenza tra l'immagine originale e la maschera.\nUtilizza i riferimenti luminanza, crominanza e tonalità dal centro dello spot\n\nPuoi anche regolare il ΔE del mascherarsi utilizzando 'Ambito (maschera immagine ΔE)' in 'Impostazioni' > 'Maschera e unisci'. +TP_LOCALLAB_SETTINGS;Impostazioni +TP_LOCALLAB_SH_TOOLNAME;Ombre/luci ed equalizzatore toni +TP_LOCALLAB_SH1;Evidenzia ombre +TP_LOCALLAB_SH2;Equalizzatore +TP_LOCALLAB_SHADEX;Ombre +TP_LOCALLAB_SHADEXCOMP;Compressione delle ombre +TP_LOCALLAB_SHADHIGH;Ombre/luci ed equalizzatore toni +TP_LOCALLAB_SHADHMASK_TOOLTIP;Abbassa le luci della maschera allo stesso modo dell'algoritmo ombre/luci. +TP_LOCALLAB_SHADMASK_TOOLTIP;Alza le ombre della maschera allo stesso modo dell'algoritmo ombre/luci. +TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Regola ombre e luci con i cursori ombre e luci o con un equalizzatore di toni.\nPuò essere utilizzato al posto o insieme al modulo Esposizione.\nPuò anche essere utilizzato come filtro graduato. +TP_LOCALLAB_SHAMASKCOL;Ombre +TP_LOCALLAB_SHAPE_TOOLTIP;'Ellisse' è la modalità normale.\n 'Rettangolo' può essere utilizzato in alcuni casi, ad esempio per lavorare in modalità immagine intera posizionando i delimitatori all'esterno dell'area di anteprima. In questo caso, imposta transizione = 100.\n\nGli sviluppi futuri includeranno forme poligonali e curve di Bezier. +TP_LOCALLAB_SHAPETYPE;Forma del punto +TP_LOCALLAB_SHARAMOUNT;Quantità +TP_LOCALLAB_SHARBLUR;Raggio di sfocatura +TP_LOCALLAB_SHARDAMPING;Smorzamento +TP_LOCALLAB_SHARFRAME;Modifiche +TP_LOCALLAB_SHARITER;Iterazioni +TP_LOCALLAB_SHARP_TOOLNAME;Nitidezza +TP_LOCALLAB_SHARP;Nitidezza +TP_LOCALLAB_SHARRADIUS;Raggio +TP_LOCALLAB_SHORTC;Maschera curve corte 'L' +TP_LOCALLAB_SHORTCMASK_TOOLTIP;Cortocircuita le 2 curve L(L) e L(H).\nPermette di mixare l'immagine corrente con l'immagine originale modificata dal lavoro della maschera.\nUtilizzabile con le maschere 2, 3, 4, 6, 7. +TP_LOCALLAB_SHOWC;Maschera e modifiche +TP_LOCALLAB_SHOWC1;Unisci file +TP_LOCALLAB_SHOWCB;Maschera e modifiche +TP_LOCALLAB_SHOWDCT;Mostra processo Fourier (Æ’). +TP_LOCALLAB_SHOWE;Maschera e modifiche +TP_LOCALLAB_SHOWFOURIER;Fourier Æ’(dct) +TP_LOCALLAB_SHOWLAPLACE;∆ Laplaciano (primo) +TP_LOCALLAB_SHOWLC;Maschera e modifiche +TP_LOCALLAB_SHOWMASK;Mostra maschera +TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Visualizza maschere e modifiche.\nAttenzione, puoi visualizzare solo una maschera strumento alla volta.\nMostra immagine modificata: mostra l'immagine modificata compreso l'effetto di eventuali regolazioni e maschere.\nMostra aree modificate senza maschera: mostra le modifiche prima dell'applicazione di qualsiasi maschera.\nMostra aree modificate con maschera: mostra le modifiche dopo l'applicazione di una maschera.\nMostra maschera: mostra l'aspetto della maschera compreso l'effetto di eventuali curve e filtri.\nMostra struttura spot: consente di vedere la maschera di rilevamento della struttura quando il cursore 'Spot struttura' è attivato (se disponibile).\nNota: la maschera viene applicata prima dell'algoritmo di rilevamento della forma. +TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Permette di visualizzare le diverse fasi del processo di Fourier.\n Laplace - calcola la derivata seconda della trasformata di Laplace in funzione della soglia.\nFourier - mostra la trasformata laplaciana con DCT.\nPoisson - mostra la soluzione del Poisson DCE.\nNessuna normalizzazione della luminanza: mostra il risultato senza alcuna normalizzazione della luminanza. +TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Può essere utilizzato con 'Maschera e modifiche'.\nSe è selezionato 'Sfocatura e rumore', la maschera non può essere utilizzata per Rimuovi rumore.\nSe è selezionato Riduci rumore, la maschera non può essere utilizzata per 'Sfocatura e rumore'.\ nSe è selezionato 'Sfocatura e rumore + Riduzione rumore', la maschera viene condivisa. Tieni presente che in questo caso, i cursori dell'ambito sia per "Sfocatura e rumore" che per Riduci rumore saranno attivi, quindi è consigliabile utilizzare l'opzione "Mostra modifiche con maschera" quando si apportano eventuali modifiche. +TP_LOCALLAB_SHOWMASKTYP1;Sfocatura e rumore +TP_LOCALLAB_SHOWMASKTYP2;Rimuovi rumore +TP_LOCALLAB_SHOWMASKTYP3;Sfocatura e rumore + Rimuovi rumore +TP_LOCALLAB_SHOWMNONE;Mostra immagine modificata +TP_LOCALLAB_SHOWMODIF;Mostra le aree modificate senza maschera +TP_LOCALLAB_SHOWMODIF2;Mostra aree modificate +TP_LOCALLAB_SHOWMODIFMASK;Mostra aree modificate con maschera +TP_LOCALLAB_SHOWNORMAL;Nessuna normalizzazione della luminanza +TP_LOCALLAB_SHOWPLUS;Maschera e modifiche (Sfocatura e Riduzione rumore) +TP_LOCALLAB_SHOWPOISSON;Poisson (pde Æ’) +TP_LOCALLAB_SHOWR;Maschera e modifiche +TP_LOCALLAB_SHOWREF;Anteprima ΔE +TP_LOCALLAB_SHOWS;Maschera e modifiche +TP_LOCALLAB_SHOWSTRUC;Mostra struttura spot(Avanzato) +TP_LOCALLAB_SHOWSTRUCEX;Mostra struttura spot(Avanzato) +TP_LOCALLAB_SHOWT;Maschera e modifiche +TP_LOCALLAB_SHOWVI;Maschera e modifiche +TP_LOCALLAB_SHRESFRA;Ombre/Alte luci e TRC +TP_LOCALLAB_SHTRC_TOOLTIP;In base al 'profilo di lavoro' (solo quelli forniti), modifica i toni dell'immagine agendo su una TRC (Curva di risposta del tono).\nGamma agisce principalmente sui toni chiari.\nSlope agisce principalmente sui toni scuri.\n si consiglia che il TRC di entrambi i dispositivi (monitor e profilo di output) sia sRGB (predefinito). +TP_LOCALLAB_SIGFRA;Sigmoide Q e codifica registro Q +TP_LOCALLAB_SIGJZFRA;Sigmoide Jz +TP_LOCALLAB_SIGMAWAV;Risposta di attenuazione +TP_LOCALLAB_SIGMOID_TOOLTIP;Permette di simulare un aspetto di Tone-mapping utilizzando sia la funzione 'Ciecam' (o 'Jz') che 'Sigmoid'.\nTre slider: a) Il contrasto agisce sulla forma della curva sigmoidea e di conseguenza sull'intensità ; b) Soglia (punto grigio) distribuisce l'azione in base alla luminanza; c)Blend agisce sull'aspetto finale dell'immagine, contrasto e luminanza. +TP_LOCALLAB_SIGMOIDBL;Miscela +TP_LOCALLAB_SIGMOIDLAMBDA;Contrasto +TP_LOCALLAB_SIGMOIDQJ;Utilizza Ev nero e Ev bianco +TP_LOCALLAB_SIGMOIDTH;Soglia (punto grigio) +TP_LOCALLAB_SLOMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente 'L' per evitare eventuali discontinuità. +TP_LOCALLAB_SLOMASKCOL;Pendenza +TP_LOCALLAB_SLOSH;Pendenza +TP_LOCALLAB_SOFT_TOOLNAME;Luce soffusa e Retinex originale +TP_LOCALLAB_SOFT;Luce soffusa e Retinex originale +TP_LOCALLAB_SOFTM;Luce soffusa +TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Applica una miscela di luce soffusa (identica alla regolazione globale). Esegui scherma e brucia utilizzando l'algoritmo Retinex originale. +TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applica un filtro guidato all'immagine di output per ridurre possibili artefatti. +TP_LOCALLAB_SOFTRADIUSCOL;Raggio morbido +TP_LOCALLAB_SOFTRETI;Riduci gli artefatti ΔE +TP_LOCALLAB_SOURCE_ABS;Luminanza assoluta +TP_LOCALLAB_SOURCE_GRAY;Luminanza media (Yb%) +TP_LOCALLAB_SPECCASE;Casi specifici +TP_LOCALLAB_SPECIAL_TOOLTIP;La casella di controllo ti consente di rimuovere tutte le altre azioni, ad esempio 'Ambito', maschere, cursori ecc., (eccetto le transizioni) e utilizzare solo l'effetto della curva di tono RGB. +TP_LOCALLAB_SPECIAL;Utilizzo speciale delle curve RGB +TP_LOCALLAB_SPOTNAME;Nuovo punto +TP_LOCALLAB_STD;Standard +TP_LOCALLAB_STR;Intensità +TP_LOCALLAB_STRBL;Intensità +TP_LOCALLAB_STREN;Resistenza alla compressione +TP_LOCALLAB_STRENG;Intensità +TP_LOCALLAB_STRENGR;Intensità +TP_LOCALLAB_STRENGRID_TOOLTIP;Puoi regolare l'effetto desiderato con 'forza', ma puoi anche utilizzare la funzione 'ambito' che ti permette di delimitare l'azione (ad esempio per isolare un colore particolare). +TP_LOCALLAB_STRENGTH;Rumore +TP_LOCALLAB_STRGRID;Intento +TP_LOCALLAB_STRUC;Struttura +TP_LOCALLAB_STRUCCOL;Struttura del punto +TP_LOCALLAB_STRUCCOL1;Struttura del punto +TP_LOCALLAB_STRUCT_TOOLTIP;Utilizza l'algoritmo Sobel per prendere in considerazione la struttura per il rilevamento della forma.\nAttiva 'Maschera e modifiche' > 'Mostra struttura spot' (Modalità avanzata) per vedere un'anteprima della maschera (senza modifiche).\n\nPuò essere utilizzato insieme alla maschera di struttura, alla maschera di sfocatura e al "Contrasto locale" (per livello wavelet) per migliorare il rilevamento dei bordi.\n\nEffetti delle regolazioni utilizzando Luminosità, Contrasto, Crominanza, Esposizione o altri strumenti non correlati alla maschera visibili utilizzando 'Mostra immagine modificata' o 'Mostra aree modificate con maschera'. +TP_LOCALLAB_STRUMASK_TOOLTIP;Maschera struttura (slider) con la casella di controllo 'Maschera struttura come strumento' deselezionata: In questo caso verrà generata una maschera che mostra la struttura anche se nessuna delle 3 curve è attivata. Le maschere di struttura sono disponibili per maschera (Sfocatura e riduzione disturbo) e maschera (Colore e luce). +TP_LOCALLAB_STRUMASKCOL;Intensità maschera struttura +TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Si consiglia un uso moderato di questo cursore! +TP_LOCALLAB_STYPE_TOOLTIP;Puoi scegliere tra:\nSimmetrico - maniglia sinistra collegata a destra, maniglia superiore collegata a quella inferiore.\nIndipendente - tutte le maniglie sono indipendenti. +TP_LOCALLAB_STYPE;Metodo forma +TP_LOCALLAB_SYM;Simmetrico (mouse) +TP_LOCALLAB_SYMSL;Simmetrico (mouse + cursori) +TP_LOCALLAB_TARGET_GRAY;Luminanza media (Yb%) +TP_LOCALLAB_TE_PIVOT;Pivot (Ev) +TP_LOCALLAB_THRES;Struttura della soglia +TP_LOCALLAB_THRESDELTAE;Soglia ambito ΔE +TP_LOCALLAB_THRESRETI;Soglia +TP_LOCALLAB_THRESWAV;Soglia di bilanciamento +TP_LOCALLAB_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max sono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nPuoi normalizzare i risultati con il cursore della soglia. +TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Media=%3 Sig=%4 +TP_LOCALLAB_TM_MASK;Utilizza mappa di trasmissione +TP_LOCALLAB_TM;Mappatura toni +TP_LOCALLAB_TONE_TOOLNAME;Mappatura toni +TP_LOCALLAB_TONEMAP_TOOLTIP;Uguale allo strumento di mappatura dei toni nel menu principale.\nLo strumento del menu principale deve essere disattivato se si utilizza questo strumento. +TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;Questo cursore influisce sulla sensibilità dei bordi.\n Maggiore è il valore, più è probabile che un cambiamento di contrasto venga interpretato come un 'bordo'.\n Se impostato su zero, la mappatura dei toni avrà un effetto simile alla maschera di contrasto. +TP_LOCALLAB_TONEMAPGAM_TOOLTIP;Il cursore Gamma sposta l'effetto di mappatura dei toni verso le ombre o le luci. +TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In alcuni casi la mappatura dei toni può risultare in un aspetto da cartone animato, e in alcuni rari casi possono apparire aloni morbidi ma ampi.\n Aumentare il numero di iterazioni di riponderazione aiuterà a combattere alcuni di questi problemi. +TP_LOCALLAB_TONEMASCALE_TOOLTIP;Questo cursore ti consente di regolare la transizione tra il contrasto 'locale' e 'globale'.\nMaggiore è il valore, maggiore deve essere il dettaglio per essere potenziato. +TP_LOCALLAB_TOOLCOL;Maschera struttura come strumento +TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Permette di modificare la maschera, se ne esiste una. +TP_LOCALLAB_TOOLMASK_2;Wavelets +TP_LOCALLAB_TOOLMASK_TOOLTIP;Maschera struttura (slider) con la casella di controllo 'Maschera struttura come strumento' selezionata: in questo caso una maschera che mostra la struttura verrà generata dopo che una o più delle 2 curve L(L) o LC(H) sono state modificate .\n Qui, la 'Maschera Struttura' si comporta come gli altri strumenti Maschera: Gamma, Pendenza, ecc.\n Permette di variare l'azione sulla maschera in base alla struttura dell'immagine. +TP_LOCALLAB_TOOLMASK;Strumenti maschera +TP_LOCALLAB_TRANSIT_TOOLTIP;Regola la morbidezza della transizione tra le aree interessate e quelle non interessate come percentuale del 'raggio'. +TP_LOCALLAB_TRANSIT;Gradiente di transizione +TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Permette di variare la transizione dell'asse y. +TP_LOCALLAB_TRANSITGRAD;Differenziazione transizione XY +TP_LOCALLAB_TRANSITVALUE;Valore di transizione +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Regola la funzione di decadimento della transizione: 1 lineare, 2 parabolica, 3 cubica fino a ^25.\nPuò essere utilizzato insieme a valori di transizione molto bassi per ridurre i difetti (CBDL, Wavelets, Colore e Luce). +TP_LOCALLAB_TRANSITWEAK;Decadimento della transizione (log lineare) +TP_LOCALLAB_TRANSMISSION_TOOLTIP;Trasmissione secondo la trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione.\nÈ possibile regolare questa curva per modificare la trasmissione e ridurre gli artefatti. +TP_LOCALLAB_TRANSMISSIONGAIN;Guadagno di trasmissione +TP_LOCALLAB_TRANSMISSIONMAP;Mappa di trasmissione +TP_LOCALLAB_USEMASK;Laplaciano +TP_LOCALLAB_VART;Varianza (contrasto) +TP_LOCALLAB_VIB_TOOLNAME;Vibranza e caldo/freddo +TP_LOCALLAB_VIBRA_TOOLTIP;Regola la vivacità (essenzialmente uguale alla regolazione globale).\nEsegue l'equivalente di una regolazione del bilanciamento del bianco utilizzando un algoritmo CIECAM. +TP_LOCALLAB_VIBRANCE;Vivace e caldo/freddo +TP_LOCALLAB_VIS_TOOLTIP;Fai clic per mostrare/nascondere tutti i punti di controllo selezionati.\nCtrl+clic per mostrare/nascondere tutti i punti di controllo. +TP_LOCALLAB_WARM_TOOLTIP;Questo cursore utilizza l'algoritmo CIECAM e agisce come controllo del bilanciamento del bianco per rendere la temperatura del colore dell'area selezionata più calda o più fredda.\nIn alcuni casi può anche ridurre gli artefatti di colore. +TP_LOCALLAB_WARM;Artefatti caldo/freddo e colore +TP_LOCALLAB_WASDEN_TOOLTIP;Riduzione del rumore di luminanza: il lato sinistro della curva compreso il confine grigio scuro/grigio chiaro corrisponde ai primi 3 livelli 0, 1, 2 (dettaglio fine). Il lato destro della curva corrisponde ai dettagli più grossolani (livello 3, 4, 5, 6). +TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Bilancia l'azione all'interno di ogni livello. +TP_LOCALLAB_WAT_BLURLC_TOOLTIP;L'impostazione di sfocatura predefinita influisce su tutti e 3 i componenti L*a* b* (luminanza e colore).\nSe selezionata, solo la luminanza viene sfocata. +TP_LOCALLAB_WAT_CLARIC_TOOLTIP;'Unisci crominanza' viene utilizzato per selezionare l'intensità dell'effetto desiderato sulla crominanza. +TP_LOCALLAB_WAT_CLARIL_TOOLTIP;'Unisci luminanza' viene utilizzato per selezionare l'intensità dell'effetto desiderato sulla luminanza. +TP_LOCALLAB_WAT_CONTCHROMALEV_TOOLTIP;'Livelli di crominanza': regola i componenti 'a' e 'b' di Lab* come proporzione del valore di luminanza. +TP_LOCALLAB_WAT_CONTOFFSET_TOOLTIP;L'offset modifica l'equilibrio tra i dettagli a basso e ad alto contrasto.\nValori elevati amplificheranno le modifiche del contrasto ai dettagli a contrasto più elevato, mentre valori bassi amplificheranno le modifiche del contrasto ai dettagli a basso contrasto.\nUtilizzando un ' basso Dal valore della risposta di attenuazione è possibile selezionare quali valori di contrasto verranno migliorati. +TP_LOCALLAB_WAT_DELTABAL_TOOLTIP;Spostando il cursore verso sinistra, i livelli inferiori vengono accentuati. A destra i livelli inferiori vengono ridotti e quelli superiori accentuati. +TP_LOCALLAB_WAT_EXPRESID_TOOLTIP;L'immagine residua si comporta allo stesso modo dell'immagine principale quando si apportano modifiche al contrasto, alla crominanza, ecc. +TP_LOCALLAB_WAT_GRADW_TOOLTIP;Più si sposta il cursore verso destra, più efficace sarà l'algoritmo di rilevamento e meno evidenti saranno gli effetti del contrasto locale. +TP_LOCALLAB_WAT_LEVELLOCCONTRAST_TOOLTIP;Contrasto locale da basso ad alto da sinistra a destra sull'asse x.\nAumenta o diminuisce il contrasto locale sull'asse y. +TP_LOCALLAB_WAT_LOCCONTRASTEDG_TOOLTIP;Puoi regolare la distribuzione del contrasto locale in base al livello wavelet in base all'intensità iniziale del contrasto. Ciò modificherà gli effetti della prospettiva e del rilievo nell'immagine e/o ridurrà i valori di contrasto per livelli di contrasto iniziali molto bassi. +TP_LOCALLAB_WAT_ORIGLC_TOOLTIP;'Unisci solo con immagine originale', impedisce alle impostazioni della 'Piramide Wavelet' di interferire con 'Chiarezza' e 'Maschera di nitidezza'. +TP_LOCALLAB_WAT_RESIDBLUR_TOOLTIP;Sfoca l'immagine residua, indipendentemente dai livelli. +TP_LOCALLAB_WAT_RESIDCOMP_TOOLTIP;Comprime l'immagine residua per aumentare o ridurre il contrasto. +TP_LOCALLAB_WAT_SIGMALC_TOOLTIP;L'effetto della regolazione del contrasto locale è più forte per i dettagli a contrasto medio e più debole per i dettagli ad alto e basso contrasto.\n Questo cursore controlla quanto velocemente l'effetto si attenua verso i contrasti estremi.\nPiù alto è il valore del cursore , più ampia è la gamma di contrasti che riceverà il pieno effetto della regolazione del contrasto locale e maggiore è il rischio di generare artefatti.\nPiù basso è il valore, più l'effetto sarà localizzato verso una gamma ristretta di valori di contrasto. +TP_LOCALLAB_WAT_STRENGTHW_TOOLTIP;Intensità del rilevamento dell'effetto bordo. +TP_LOCALLAB_WAT_STRWAV_TOOLTIP;Permette di variare il contrasto locale in base al gradiente e all'angolo scelti. Viene presa in considerazione la variazione del segnale di luminanza e non la luminanza. +TP_LOCALLAB_WAT_THRESHOLDWAV_TOOLTIP;Gamma di livelli wavelet utilizzati nel modulo Wavelet. +TP_LOCALLAB_WAT_WAVBLURCURV_TOOLTIP;Ti permette di sfocare ogni livello di scomposizione.\nI livelli di scomposizione dal più piccolo al più grossolano vanno da sinistra a destra. +TP_LOCALLAB_WAT_WAVCBDL_TOOLTIP;Simile a Contrasto per livelli di dettaglio. Livelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. +TP_LOCALLAB_WAT_WAVDELTABAL_TOOLTIP;Agisce sull'equilibrio delle tre direzioni (orizzontale, verticale e diagonale) in base alla luminanza dell'immagine.\nPer impostazione predefinita le ombre o le luci vengono ridotte per evitare artefatti. +TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Mostra tutti gli strumenti 'Nitidezza bordi'. Si consiglia di leggere la documentazione sui Livelli Wavelet. +TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Permette di regolare l'effetto massimo della sfocatura sui livelli. +TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Contrasto locale da basso ad alto da sinistra a destra sull'asse x\nAumenta o diminuisce il contrasto locale sull'asse y. +TP_LOCALLAB_WAT_WAVTM_TOOLTIP;La parte inferiore (negativa) comprime ciascun livello di scomposizione creando un effetto di mappatura dei toni.\nLa parte superiore (positiva) attenua il contrasto per livello.\nI livelli di scomposizione da più piccoli a più grossolani sono da sinistra a destra sulla x- asse. +TP_LOCALLAB_WAV;Contrasto locale +TP_LOCALLAB_WAVBLUR_TOOLTIP;Permette di sfocare ogni livello della scomposizione, così come l'immagine residua. +TP_LOCALLAB_WAVCOMP_TOOLTIP;Permette di applicare il contrasto locale in base alla direzione della scomposizione wavelet: orizzontale, verticale, diagonale. +TP_LOCALLAB_WAVCOMP;Compressione per livello +TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Consente di applicare la mappatura dei toni o ridurre il contrasto locale su livelli individuali.\nLivelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. +TP_LOCALLAB_WAVCOMPRE;Compressione per livello +TP_LOCALLAB_WAVCON;Contrasto per livello +TP_LOCALLAB_WAVCONTF_TOOLTIP;Simile a Contrasto per livelli di dettaglio. Livelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. +TP_LOCALLAB_WAVDEN;Rimozione rumore luminanza +TP_LOCALLAB_WAVE;Wavelet +TP_LOCALLAB_WAVEDG;Contrasto locale +TP_LOCALLAB_WAVEEDG_TOOLTIP;Migliora la nitidezza mirando all'azione del contrasto locale sui bordi. Ha le stesse funzioni del modulo corrispondente in Livelli Wavelet e utilizza le stesse impostazioni. +TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Gamma di livelli wavelet utilizzati in 'Contrasto locale' (per livello wavelet). +TP_LOCALLAB_WAVGRAD_TOOLTIP;Permette di variare il contrasto locale in base al gradiente e all'angolo scelti. Viene presa in considerazione la variazione del segnale di luminanza e non la luminanza. +TP_LOCALLAB_WAVHUE_TOOLTIP;Permette di ridurre o aumentare la riduzione del rumore in base alla tonalità. +TP_LOCALLAB_WAVLEV;Sfocatura per livello +TP_LOCALLAB_WAVMASK_TOOLTIP;Utilizza wavelet per modificare il contrasto locale della maschera e rinforzare o ridurre la struttura (pelle, edifici, ecc.). +TP_LOCALLAB_WAVMASK;Contrasto locale +TP_LOCALLAB_WEDIANHI;Medio alto +TP_LOCALLAB_WHITE_EV;Compensazione dell'esposizione del bianco +TP_LOCALLAB_ZCAMFRA;Regolazioni immagine ZCAM +TP_LOCALLAB_ZCAMTHRES;Recupera alti dati +TP_LOCRETI_METHOD_TOOLTIP;Basso = Rinforza la luce scarsa.\Uniformemente = Distribuito uniformemente.\Alto = Rinforza la luce forte. +TP_METADATA_EDIT;Apply modifications +TP_METADATA_MODE;Modalità di copia dei metadati +TP_METADATA_STRIP;Elimina tutti i metadati +TP_METADATA_TUNNEL;Copia invariata TP_NEUTRAL_TOOLTIP;Riporta i controlli dell'esposizione ai valori neutrali.\nVale per gli stessi controlli cui è applicato Livelli Automatici, indipendentemente dal fatto che Livelli Automatici sia abilitato. -TP_PCVIGNETTE_FEATHER;Scia +TP_NEUTRAL;Ripristina TP_PCVIGNETTE_FEATHER_TOOLTIP;Scia:\n0 = solo i bordi,\n50 = a metà strada con il centro,\n100 = al centro. +TP_PCVIGNETTE_FEATHER;Scia TP_PCVIGNETTE_LABEL;Filtro Vignettatura -TP_PCVIGNETTE_ROUNDNESS;Rotondità TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rotondità:\n0 = rettangolo,\n50 = ellisse riempito,\n100 = cerchio. -TP_PCVIGNETTE_STRENGTH;Forza -TP_PCVIGNETTE_STRENGTH_TOOLTIP;Forza del filtro in stop (raggiunta agli angoli). +TP_PCVIGNETTE_ROUNDNESS;Rotondità +TP_PCVIGNETTE_STRENGTH_TOOLTIP;intensità del filtro in stop (raggiunta agli angoli). +TP_PCVIGNETTE_STRENGTH;intensità +TP_PDSHARPENING_LABEL;Acquisisci nitidezza +TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Fattore di ritaglio +TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Lunghezza focale +TP_PERSPECTIVE_CAMERA_FRAME;Correzione +TP_PERSPECTIVE_CAMERA_PITCH;Verticale +TP_PERSPECTIVE_CAMERA_ROLL;Rotazione +TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Spostamento orizzontale +TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Spostamento verticale +TP_PERSPECTIVE_CAMERA_YAW;Orizzontale +TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;Sono necessarie almeno due linee di controllo orizzontali o due verticali. +TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+trascina: traccia una nuova riga\nclic destro: elimina la riga +TP_PERSPECTIVE_CONTROL_LINES;Linee di controllo TP_PERSPECTIVE_HORIZONTAL;Orizzontale TP_PERSPECTIVE_LABEL;Prospettiva +TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-base +TP_PERSPECTIVE_METHOD_SIMPLE;Semplice +TP_PERSPECTIVE_METHOD;Metodo +TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Aggiustamento post-correzione +TP_PERSPECTIVE_PROJECTION_PITCH;Verticale +TP_PERSPECTIVE_PROJECTION_ROTATE;Rotatione +TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Spostamento orizzontale +TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Spostamento verticale +TP_PERSPECTIVE_PROJECTION_YAW;Orizzontale +TP_PERSPECTIVE_RECOVERY_FRAME;Recupera TP_PERSPECTIVE_VERTICAL;Verticale -TP_PFCURVE_CURVEEDITOR_CH;Tonalità TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controlla la forza di defringe dal colore.\nPiù alto = di più,\nPiù basso = di meno. +TP_PFCURVE_CURVEEDITOR_CH;Tonalità +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tenta di sopprimere i pixel morti. +TP_PREPROCESS_DEADPIXFILT;Filtro pixel morti TP_PREPROCESS_GREENEQUIL;Bilanciamento del verde +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tenta di sopprimere i pixel bruciati. +TP_PREPROCESS_HOTPIXFILT;Filtro pixel bruciati TP_PREPROCESS_LABEL;Pre-elaborazione +TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Entrambi +TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Orizzontale +TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Orizzontale solo su righe PDAF +TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Verticale +TP_PREPROCESS_LINEDENOISE_DIRECTION;Direzione TP_PREPROCESS_LINEDENOISE;Filtro per rumore a bande TP_PREPROCESS_NO_FOUND;Nessuno presente +TP_PREPROCESS_PDAFLINESFILTER;Filtro linee PDAF +TP_PREPROCWB_LABEL;Preelaborare il bilanciamento del bianco +TP_PREPROCWB_MODE_AUTO;Auto +TP_PREPROCWB_MODE_CAMERA;Camera +TP_PREPROCWB_MODE;Modo +TP_PRSHARPENING_LABEL;Nitidezza post-ridimensionamento +TP_PRSHARPENING_TOOLTIP;Rende più nitida l'immagine dopo il ridimensionamento. Funziona solo quando viene utilizzato il metodo di ridimensionamento 'Lanczos'. È impossibile prevedere in anteprima gli effetti di questo strumento. Vedi RawPedia per le istruzioni d'uso. +TP_RAW_1PASSMEDIUM;1-passaggio (Markesteijn) +TP_RAW_2PASS;1-passaggio+veloce +TP_RAW_3PASSBEST;3-passaggi (Markesteijn) +TP_RAW_4PASS;3-passaggi+veloce +TP_RAW_AHD;AHD +TP_RAW_AMAZE;AMaZE +TP_RAW_AMAZEBILINEAR;AMaZE+Bilineare +TP_RAW_AMAZEVNG4;AMaZE+VNG4 +TP_RAW_BORDER;Bordo +TP_RAW_DCB;DCB +TP_RAW_DCBBILINEAR;DCB+Bilineare +TP_RAW_DCBENHANCE;Miglioramento DCB +TP_RAW_DCBITERATIONS;Numero di iterazioni DCB +TP_RAW_DCBVNG4;DCB+VNG4 +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione %1... +TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO per aiutare nella riduzione rumore senza comportare posterizzazione o colori lavati. +TP_RAW_DMETHOD;Metodo +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Se la casella è selezionata (consigliato), RawTherapee calcola un valore ottimale in base alle regioni piatte nell'immagine.\nSe non c'è alcuna regione piatta nell'immagine o se l'immagine è troppo rumorosa, il valore verrà impostato su 0.\nPer impostare il valore manualmente, deselezionare prima la casella di controllo (valori ragionevoli dipendono dall'immagine). +TP_RAW_DUALDEMOSAICAUTOCONTRAST;Soglia Automatica +TP_RAW_DUALDEMOSAICCONTRAST;Soglia di contrasto +TP_RAW_EAHD;EAHD +TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori +TP_RAW_FAST;Veloce +TP_RAW_HD_TOOLTIP;Valori più bassi rendono il rilevamento dei pixel caldi/morti più aggressivo, ma i falsi positivi possono causare artefatti. Se noti artefatti quando abiliti i filtri pixel caldi/morti, aumenta gradualmente il valore di soglia finché non scompaiono. +TP_RAW_HD;Soglia +TP_RAW_HPHD;HPHD +TP_RAW_IGV;IGV +TP_RAW_IMAGENUM_SN;Modo SN +TP_RAW_IMAGENUM_TOOLTIP;Alcuni file RAW sono costituiti da diverse immagini secondarie (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nQuando si utilizza qualsiasi metodo di demosaicizzazione diverso da Pixel Shift, questo seleziona quali sotto-immagini viene utilizzata l'immagine.\n\nQuando si utilizza il metodo di demosaicizzazione Pixel Shift su un Pixel Shift raw, vengono utilizzate tutte le immagini secondarie e viene selezionato quale immagine secondaria deve essere utilizzata per lo spostamento delle parti. +TP_RAW_IMAGENUM;Immagine secondaria +TP_RAW_LABEL;Demosaicizzazione +TP_RAW_LMMSE_TOOLTIP;Aggiunge gamma (passo 1) - Aggiunge mediana (passi 2-4), poi perfeziona (passi 5-6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore. +TP_RAW_LMMSE;LMMSE +TP_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE +TP_RAW_MONO;Mono +TP_RAW_NONE;Nessuno (mostra il modello del sensore) +TP_RAW_PIXELSHIFT;Pixel Shift (spostamento dei pixel) +TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Utilizza la media di tutti i fotogrammi invece del fotogramma selezionato per le regioni con movimento.\nFornisce effetti di movimento su oggetti che si muovono lentamente (sovrapposti). +TP_RAW_PIXELSHIFTAVERAGE;Utilizzare la media per le parti in movimento +TP_RAW_PIXELSHIFTBLUR;Maschera di movimento sfocato +TP_RAW_PIXELSHIFTDMETHOD;Metodo di demosaicizzazione per il movimento +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;Il valore predefinito di 0 dovrebbe funzionare correttamente per l'ISO di base.\nValori più alti aumentano la sensibilità del rilevamento del movimento.\nCambia a piccoli passi e osserva la maschera di movimento mentre cambia.\nAumenta la sensibilità per immagini sottoesposte o con ISO elevati. +TP_RAW_PIXELSHIFTEPERISO;Sensibilità +TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalizza la luminosità dei fotogrammi alla luminosità del fotogramma selezionato.\nSe ci sono aree sovraesposte nei fotogrammi, seleziona il fotogramma più luminoso per evitare la dominante di colore magenta nelle aree sovraesposte o abilitare la correzione del movimento. +TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalizza la luminosità dei fotogrammi +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Abilitato: equalizza i canali RGB individualmente.\nDisabilitato: utilizza lo stesso fattore di equalizzazione per tutti i canali. +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalizza per canale +TP_RAW_PIXELSHIFTGREEN;Controllare il movimento nel canale verde +TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Riempi i buchi nella maschera di movimento. +TP_RAW_PIXELSHIFTHOLEFILL;Riempi i buchi nella maschera di movimento +TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Utilizza la mediana di tutti i fotogrammi anziché il fotogramma selezionato per le regioni con movimento.\nRimuove gli oggetti che si trovano in posizioni diverse in tutti i fotogrammi.\nConferisce un effetto di movimento agli oggetti che si muovono lentamente (sovrapposti). +TP_RAW_PIXELSHIFTMEDIAN;Utilizzare la mediana per le parti in movimento +TP_RAW_PIXELSHIFTMM_AUTO;Automatico +TP_RAW_PIXELSHIFTMM_CUSTOM;Personalizzato +TP_RAW_PIXELSHIFTMM_OFF;Chiuso +TP_RAW_PIXELSHIFTMOTIONMETHOD;Correzione del movimento +TP_RAW_PIXELSHIFTNONGREENCROSS;Controllare i canali rosso/blu per il movimento +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Sovrappone l'immagine con una maschera verde che mostra le regioni in movimento. +TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Mostra la maschera di movimento senza l'immagine. +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Mostra solo la maschera di movimento +TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Il raggio predefinito di 1,0 di solito si adatta bene agli ISO di base.\nAumenta il valore per gli scatti con ISO elevati, 5,0 è un buon punto di partenza.\nGuarda la maschera di movimento mentre modifichi il valore. +TP_RAW_PIXELSHIFTSIGMA;Raggio di sfocatura +TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Transizioni uniformi tra aree con movimento e aree senza.\nImposta su 0 per disattivare l'arrotondamento della transizione.\nImposta su 1 per ottenere il risultato AMaZE/LMMSE del fotogramma selezionato (a seconda che sia selezionato "Utilizza LMMSE") o la mediana di tutti e quattro i fotogrammi se è selezionato 'Usa mediana'. +TP_RAW_PIXELSHIFTSMOOTH;Transizioni fluide +TP_RAW_RCD;RCD +TP_RAW_RCDBILINEAR;RCD+Bilineare +TP_RAW_RCDVNG4;RCD+VNG4 +TP_RAW_SENSOR_BAYER_LABEL;Sensore con Matrice di Bayer +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;La modalità a 3 passaggi offre i migliori risultati (consigliata per immagini a ISO bassi).\nLa modalità a 1 passaggio è quasi indistinguibile dalla modalità a 3 passaggi per immagini a ISO elevati ed è più veloce.\n+la modalità veloce fornisce meno artefatti nelle aree piatte. +TP_RAW_SENSOR_XTRANS_LABEL;Sensore con Matrice X-Trans +TP_RAW_VNG4;VNG4 +TP_RAW_XTRANS;X-Trans +TP_RAW_XTRANSFAST;Fast X-Trans TP_RAWCACORR_AUTO;Autocorrezione +TP_RAWCACORR_AUTOIT_TOOLTIP;Questa impostazione è disponibile se è selezionata l'opzione "Correzione automatica".\nLa correzione automatica è conservativa, ovvero spesso non corregge tutta l'aberrazione cromatica.\nPer correggere l'aberrazione cromatica rimanente, puoi utilizzare fino a cinque iterazioni dell'aberrazione cromatica automatica. correzione.\nOgni iterazione ridurrà l'aberrazione cromatica rimanente dall'ultima iterazione al costo di ulteriore tempo di elaborazione. +TP_RAWCACORR_AUTOIT;Iterazioni +TP_RAWCACORR_AVOIDCOLORSHIFT;Evita il cambiamento di colore TP_RAWCACORR_CABLUE;Blu TP_RAWCACORR_CARED;Rosso TP_RAWCACORR_LABEL;Correzione AC +TP_RAWEXPOS_BLACK_0;Verde 1 (guida) +TP_RAWEXPOS_BLACK_1;Rosso +TP_RAWEXPOS_BLACK_2;Blu +TP_RAWEXPOS_BLACK_3;Verde 2 +TP_RAWEXPOS_BLACK_BLUE;Blu +TP_RAWEXPOS_BLACK_GREEN;Verde +TP_RAWEXPOS_BLACK_RED;Rosso TP_RAWEXPOS_LINEAR;Punto del Bianco - Correzione +TP_RAWEXPOS_RGB;Rosso, Verde, Blu TP_RAWEXPOS_TWOGREEN;Valori del verde uniti -TP_RAW_DCBENHANCE;Miglioramento DCB -TP_RAW_DCBITERATIONS;Numero di iterazioni DCB -TP_RAW_DMETHOD;Metodo -TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione %1... -TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... -TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO per aiutare nella riduzione rumore senza comportare posterizzazione o colori lavati. -TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori -TP_RAW_LABEL;Demosaicizzazione -TP_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE -TP_RAW_LMMSE_TOOLTIP;Aggiunge gamma (passo 1) - Aggiunge mediana (passi 2-4), poi perfeziona (passi 5-6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore. +TP_RESIZE_ALLOW_UPSCALING;Consenti l'upscaling TP_RESIZE_APPLIESTO;Applica a: TP_RESIZE_CROPPEDAREA;Zona ritagliata TP_RESIZE_FITBOX;Riquadro delimitato @@ -1088,18 +3707,101 @@ TP_RESIZE_H;A: TP_RESIZE_HEIGHT;Altezza TP_RESIZE_LABEL;Ridimensiona TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_LE;Bordo lungo: +TP_RESIZE_LONG;Bordo lungo TP_RESIZE_METHOD;Metodo: TP_RESIZE_NEAREST;Più prossimo (Nearest) TP_RESIZE_SCALE;Scala +TP_RESIZE_SE;Bordo corto: +TP_RESIZE_SHORT;Bordo corto TP_RESIZE_SPECIFY;Specifica: TP_RESIZE_W;L: TP_RESIZE_WIDTH;Larghezza +TP_RETINEX_CONTEDIT_HSL;HSL istogramma +TP_RETINEX_CONTEDIT_LAB;L*a*b* istogramma +TP_RETINEX_CONTEDIT_LH;Tonalità +TP_RETINEX_CONTEDIT_MAP;Equalizzatore +TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminanza in base alla luminanza L=f(L)\nCorreggere i dati grezzi per ridurre aloni e artefatti. +TP_RETINEX_CURVEEDITOR_CD;L=f(L) +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensità in base alla tonalità Intensità=f(H)\nQuesta curva agisce anche sulla crominanza quando si utilizza il metodo Retinex 'Alteluci'. +TP_RETINEX_CURVEEDITOR_LH;Intensità=f(H) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Questa curva può essere applicata da sola o con una maschera gaussiana o una maschera wavelet.\nAttenzione agli artefatti! +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_EQUAL;Equalizzatore +TP_RETINEX_FREEGAMMA;Gamma libera +TP_RETINEX_GAIN;Guadagno +TP_RETINEX_GAINOFFS;Guadagno e compensazione (luminosità) +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Aumentare o ridurre la mappa di trasmissione per ottenere la luminanza desiderata. L'asse x è la trasmissione. L'asse y è il guadagno. +TP_RETINEX_GAINTRANSMISSION;Transmissione guadagno +TP_RETINEX_GAMMA_FREE;Libero +TP_RETINEX_GAMMA_HIGH;Alto +TP_RETINEX_GAMMA_LOW;Basso +TP_RETINEX_GAMMA_MID;Medio +TP_RETINEX_GAMMA_NONE;Nessuno +TP_RETINEX_GAMMA_TOOLTIP;Ripristina i toni applicando gamma prima e dopo Retinex. Differenti dalle curve Retinex o da altre curve (Lab, Exposure, ecc.). +TP_RETINEX_GAMMA;Gamma +TP_RETINEX_GRAD_TOOLTIP;Se il dispositivo di scorrimento è impostato su 0, tutte le iterazioni sono identiche.\nSe > 0 Varianza e Soglia vengono ridotte quando le iterazioni aumentano e viceversa. +TP_RETINEX_GRAD;Gradiente di trasmissione +TP_RETINEX_GRADS_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 La forza viene ridotta quando le iterazioni aumentano e viceversa. +TP_RETINEX_GRADS;Gradiente di forza +TP_RETINEX_HIGH;Alto +TP_RETINEX_HIGHLIG;Alteluci +TP_RETINEX_HIGHLIGHT_TOOLTIP;Aumenta l'azione dell'algoritmo Alto.\nPotrebbe essere necessario regolare nuovamente i "Pixel vicini" e aumentare la "Correzione del punto bianco" nella scheda Raw -> strumento Punti bianchi grezzi. +TP_RETINEX_HIGHLIGHT;Soglia alteluci +TP_RETINEX_HSLSPACE_LIN;HSL-Lineare +TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmica +TP_RETINEX_ITER_TOOLTIP;Simula un operatore di mappatura dei toni.\nValori elevati aumentano il tempo di elaborazione. +TP_RETINEX_ITER;Iterazioni (mappatura dei toni) +TP_RETINEX_ITERF;Mappatura dei toni +TP_RETINEX_LABEL_MASK;Maschera +TP_RETINEX_LABEL;Retinex +TP_RETINEX_LABSPACE;L*a*b* +TP_RETINEX_LOW;Basso +TP_RETINEX_MAP_GAUS;Maschera Gaussiana +TP_RETINEX_MAP_MAPP;Maschera nitida (wavelet parziale) +TP_RETINEX_MAP_MAPT;Maschera nitida (wavelet totale) +TP_RETINEX_MAP_METHOD_TOOLTIP;Usa la maschera generata dalla funzione gaussiana sopra (Raggio, Metodo) per ridurre aloni e artefatti.\n\nSolo curva: applica una curva di contrasto diagonale sulla maschera.\nAttenzione agli artefatti!\n\nMaschera gaussiana: genera e usa una Sfocatura gaussiana della maschera originale.\nVeloce.\n\nMaschera nitida: genera e utilizza un'onda sulla maschera originale.\nLento. +TP_RETINEX_MAP_NONE;Nessuno +TP_RETINEX_MAP;Metodo +TP_RETINEX_MEDIAN;Filtro mediano di trasmissione +TP_RETINEX_METHOD_TOOLTIP;Basso = Rinforza la luce scarsa.\Uniforme = Equalizza l'azione.\Alto = Rinforza la luce alta.\Alte luci = Rimuove il magenta nelle alte luci. +TP_RETINEX_METHOD;Metodo +TP_RETINEX_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Clip dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. +TP_RETINEX_MLABEL;Ripristino dati Min=%1 Max=%2 +TP_RETINEX_NEIGHBOR;Raggio +TP_RETINEX_NEUTRAL_TOOLTIP;Ripristina tutti i cursori e le curve ai valori predefiniti. +TP_RETINEX_NEUTRAL;Ripristina +TP_RETINEX_OFFSET;Compensazione (luminosità) +TP_RETINEX_SCALES_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 Scala e raggio vengono ridotti quando le iterazioni aumentano e viceversa. +TP_RETINEX_SCALES;Gradiente Gaussiano +TP_RETINEX_SETTINGS;Impostazioni +TP_RETINEX_SKAL;Scala +TP_RETINEX_SLOPE;Pendenza gamma libera +TP_RETINEX_STRENGTH;Intensità +TP_RETINEX_THRESHOLD_TOOLTIP;Limiti in/out.\nIn = sorgente immagine,\nOut = gauss immagine. +TP_RETINEX_THRESHOLD;Soglia +TP_RETINEX_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max vengono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nÈ possibile normalizzare i risultati con il cursore della soglia. +TP_RETINEX_TLABEL;Dati TM Min=%1 Max=%2 Media=%3 Sigma=%4 +TP_RETINEX_TLABEL2;TM Effettivo Tm=%1 TM=%2 +TP_RETINEX_TRANF;Transmissione +TP_RETINEX_TRANSMISSION_TOOLTIP;Trasmissione secondo trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione. +TP_RETINEX_TRANSMISSION;Mappa di transmissione +TP_RETINEX_UNIFORM;Uniforme +TP_RETINEX_VARIANCE_TOOLTIP;Una varianza bassa aumenta il contrasto e la saturazione locali, ma può causare artefatti. +TP_RETINEX_VARIANCE;Contrasto +TP_RETINEX_VIEW_MASK;Maschera +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Visualizzazione normale.\nMaschera - Visualizza la maschera.\nMaschera di contrasto - Visualizza l'immagine con una maschera di contrasto ad alto raggio.\nTrasmissione - Automatica/Fissa - Visualizza la mappa di trasmissione del file, prima di qualsiasi azione su contrasto e luminosità.\n \nAttenzione: la maschera non corrisponde alla realtà, ma viene amplificata per renderla più visibile. +TP_RETINEX_VIEW_NONE;Standard +TP_RETINEX_VIEW_TRAN;Trasmissione - Automatica +TP_RETINEX_VIEW_TRAN2;Trasmissione - Risolto +TP_RETINEX_VIEW_UNSHARP;Maschera di contrasto +TP_RETINEX_VIEW;Processo TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Canale TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;Curve RGB -TP_RGBCURVES_LUMAMODE;Modalità Luminosità TP_RGBCURVES_LUMAMODE_TOOLTIP;La Modalità Luminosità consente di variare il contributo dei canali R, G e B alla luminosità dell'immagine, senza alterarne il colore. +TP_RGBCURVES_LUMAMODE;Modalità Luminosità TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;Angolo TP_ROTATE_LABEL;Ruota @@ -1116,60 +3818,342 @@ TP_SHARPENEDGE_LABEL;Bordi TP_SHARPENEDGE_PASSES;Iterazioni TP_SHARPENEDGE_THREE;Solo per luminanza TP_SHARPENING_AMOUNT;Quantità +TP_SHARPENING_BLUR;Raggio di sfocatura +TP_SHARPENING_CONTRAST;Soglia di contrasto TP_SHARPENING_EDRADIUS;Raggio TP_SHARPENING_EDTOLERANCE;Tolleranza bordi TP_SHARPENING_HALOCONTROL;Controllo dell'alone TP_SHARPENING_HCAMOUNT;Quantità +TP_SHARPENING_ITERCHECK;Limite di iterazione automatica TP_SHARPENING_LABEL;Nitidezza TP_SHARPENING_METHOD;Metodo TP_SHARPENING_ONLYEDGES;Definisci solo i bordi +TP_SHARPENING_RADIUS_BOOST;Aumento del raggio d'angolo TP_SHARPENING_RADIUS;Raggio -TP_SHARPENING_RLD;Deconvoluzione RL TP_SHARPENING_RLD_AMOUNT;Quantità -TP_SHARPENING_RLD_DAMPING;Smorzamento +TP_SHARPENING_RLD_DAMPING;Attenuazione TP_SHARPENING_RLD_ITERATIONS;Iterazioni +TP_SHARPENING_RLD;Deconvoluzione RL TP_SHARPENING_THRESHOLD;Soglia TP_SHARPENING_USM;Maschera di contrasto TP_SHARPENMICRO_AMOUNT;Quantità +TP_SHARPENMICRO_CONTRAST;Soglia di contrasto TP_SHARPENMICRO_LABEL;Microcontrasto TP_SHARPENMICRO_MATRIX;Matrice 3×3 invece di 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformità +TP_SOFTLIGHT_LABEL;Luce soffusa +TP_SOFTLIGHT_STRENGTH;Intensità +TP_SPOT_COUNTLABEL;%1 punto(i) +TP_SPOT_DEFAULT_SIZE;Dimensione spot predefinita +TP_SPOT_ENTRYCHANGED;Il punto è cambiato +TP_SPOT_HINT;Fare clic su questo pulsante per poter operare sull'area di anteprima.\n\nPer modificare un punto, posizionare il mouse sul segno bianco che individua un'area modificata, facendo apparire la geometria di modifica.\n\nPer aggiungere un punto, premere Ctrl e il tasto sinistro del mouse pulsante , trascina il cerchio (è possibile rilasciare il tasto Ctrl) in una posizione di origine, quindi rilascia il pulsante del mouse.\n\nPer spostare il punto di origine o di destinazione, passa con il mouse al centro, quindi trascinalo.\n\nIl cerchio interno (massimo effetto area) e il cerchio "piuma" può essere ridimensionato passandovi sopra con il mouse (il cerchio diventa arancione) e trascinandolo (il cerchio diventa rosso).\n\nUna volta completate le modifiche, fare clic con il pulsante destro del mouse all'esterno di qualsiasi punto per terminare la modalità di modifica Spot oppure fare nuovamente clic su questo pulsante. +TP_SPOT_LABEL;Rimozione delle macchie +TP_TM_FATTAL_AMOUNT;Quantità +TP_TM_FATTAL_ANCHOR;Ancora +TP_TM_FATTAL_LABEL;Compressione della gamma dinamica +TP_TM_FATTAL_THRESHOLD;Dettagli +TP_TONE_EQUALIZER_BAND_0;Neri +TP_TONE_EQUALIZER_BAND_1;Ombre +TP_TONE_EQUALIZER_BAND_2;Mezzitoni +TP_TONE_EQUALIZER_BAND_3;Alteluci +TP_TONE_EQUALIZER_BAND_4;Bianchi +TP_TONE_EQUALIZER_BANDS;Bande +TP_TONE_EQUALIZER_DETAIL;Regolarizzazione +TP_TONE_EQUALIZER_LABEL;Equalizzatore di toni +TP_TONE_EQUALIZER_PIVOT;Perno (Ev) +TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map TP_VIBRANCE_AVOIDCOLORSHIFT;Evita il color shift -TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Incarnato TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rosso/Viola TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rosso TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rosso/Giallo TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Giallo TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tonalità a seconda della Tinta H=f(H) +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_LABEL;Vividezza TP_VIBRANCE_PASTELS;Toni Pastello TP_VIBRANCE_PASTSATTOG;Lega i toni pastello e saturi TP_VIBRANCE_PROTECTSKINS;Proteggi l'incarnato -TP_VIBRANCE_PSTHRESHOLD;Soglia toni pastello/saturi TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Soglia Saturazione TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;L'asse verticale rappresenta i toni pastello alla base e i toni saturi in cima.\nL'asse orizzontale rappresenta l'intervallo di saturazione. TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Peso della transizione pastello/saturi +TP_VIBRANCE_PSTHRESHOLD;Soglia toni pastello/saturi TP_VIBRANCE_SATURATED;Toni Saturi TP_VIGNETTING_AMOUNT;Quantità -TP_VIGNETTING_CENTER;Centro TP_VIGNETTING_CENTER_X;Centra X TP_VIGNETTING_CENTER_Y;Centra Y +TP_VIGNETTING_CENTER;Centro TP_VIGNETTING_LABEL;Correzione Vignettatura TP_VIGNETTING_RADIUS;Raggio -TP_VIGNETTING_STRENGTH;Forza +TP_VIGNETTING_STRENGTH;intensità +TP_WAVELET_1;Livello 1 +TP_WAVELET_2;Livello 2 +TP_WAVELET_3;Livello 3 +TP_WAVELET_4;Livello 4 +TP_WAVELET_5;Livello 5 +TP_WAVELET_6;Livello 6 +TP_WAVELET_7;Livello 7 +TP_WAVELET_8;Livello 8 +TP_WAVELET_9;Livello 9 +TP_WAVELET_APPLYTO;Applica a +TP_WAVELET_AVOID;Evita cambiamento colore +TP_WAVELET_B0;Nero +TP_WAVELET_B1;Grigio +TP_WAVELET_B2;Residuale +TP_WAVELET_BACKGROUND;Sfondo +TP_WAVELET_BACUR;Curva +TP_WAVELET_BALANCE_TOOLTIP;Altera il bilanciamento tra le direzioni delle wavelet: verticale-orizzontale e diagonale.\nSe sono attivati contrasto, crominanza o mappatura del tono residuo, l'effetto dovuto al bilanciamento viene amplificato. +TP_WAVELET_BALANCE;Bilanciamento di contrasto d/v-h +TP_WAVELET_BALCHRO_TOOLTIP;Se abilitata, la curva o il cursore "Bilanciamento del contrasto" modifica anche il bilanciamento della crominanza. +TP_WAVELET_BALCHRO;Bilanciamento cromatico +TP_WAVELET_BALCHROM;Equalizzazione colore +TP_WAVELET_BALLUM;Equalizzatore antirumore Bianco-Nero +TP_WAVELET_BANONE;Nessuno +TP_WAVELET_BASLI;Dispositivo di scorrimento +TP_WAVELET_BATYPE;Metodo del bilanciamento del contrasto +TP_WAVELET_BL;Livelli di sfocatura +TP_WAVELET_BLCURVE;Sfocatura per livelli +TP_WAVELET_BLURFRAME;Sfoca +TP_WAVELET_BLUWAV;Risposta di attenuazione +TP_WAVELET_CB_TOOLTIP;Con valori elevati puoi creare effetti speciali, simili a quelli ottenuti con il Modulo Chroma, ma focalizzati sull'immagine residua.\nCon valori moderati puoi correggere manualmente il bilanciamento del bianco. +TP_WAVELET_CBENAB;Tonalità e bilanciamento del colore +TP_WAVELET_CCURVE;Contrasto locale +TP_WAVELET_CH1;Intera gamma cromatica +TP_WAVELET_CH2;Saturato/pastello +TP_WAVELET_CH3;Collega i livelli di contrasto +TP_WAVELET_CHCU;Curva +TP_WAVELET_CHR_TOOLTIP;Regola la crominanza in funzione dei "livelli di contrasto" e della "forza del collegamento crominanza-contrasto". +TP_WAVELET_CHR;Intensità coll.to contrasto cromatico +TP_WAVELET_CHRO_TOOLTIP;Imposta il livello wavelet che sarà la soglia tra i colori saturi e pastello.\n1-x: saturi\nx-9: pastello\n\nSe il valore supera la quantità di livelli wavelet che stai utilizzando, verrà ignorato. +TP_WAVELET_CHRO;Soglia saturata/pastello +TP_WAVELET_CHROFRAME;Riduce il rumore di crominanza +TP_WAVELET_CHROMAFRAME;Crominanza +TP_WAVELET_CHROMCO;Crominanza grossolana +TP_WAVELET_CHROMFI;Crominanza fine +TP_WAVELET_CHRWAV;Sfocatura cromatica +TP_WAVELET_CHSL;Cursori +TP_WAVELET_CHTYPE;Metodo della crominanza +TP_WAVELET_CLA;Chiarezza +TP_WAVELET_CLARI;Maschera di nitidezza e chiarezza +TP_WAVELET_COLORT;Opacità rosso-verde +TP_WAVELET_COMPCONT;Contrasto +TP_WAVELET_COMPEXPERT;Avanzate +TP_WAVELET_COMPGAMMA_TOOLTIP;La regolazione della gamma dell'immagine residua consente di equilibrare i dati e l'istogramma. +TP_WAVELET_COMPGAMMA;Compressione di gamma +TP_WAVELET_COMPLEX_TOOLTIP;Standard: mostra un set ridotto di strumenti adatti alla maggior parte delle operazioni di elaborazione.\nAvanzato: mostra il set completo di strumenti per operazioni di elaborazione avanzate. +TP_WAVELET_COMPLEXLAB;Complessità +TP_WAVELET_COMPNORMAL;Standard +TP_WAVELET_COMPTM;Mappatura dei toni +TP_WAVELET_CONTEDIT;Curva di contrasto 'dopo' +TP_WAVELET_CONTFRAME;Contrasto - Compressione +TP_WAVELET_CONTR;Gamma +TP_WAVELET_CONTRA_TOOLTIP;Modifica il contrasto residuo dell'immagine. +TP_WAVELET_CONTRA;Contrasto +TP_WAVELET_CONTRAST_MINUS;Contrasto - +TP_WAVELET_CONTRAST_PLUS;Contrasto + +TP_WAVELET_CTYPE;Controllo della crominanza +TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabilitato se lo zoom > circa 300%. +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifica il contrasto locale in funzione del contrasto locale originale (ascissa).\nI valori bassi dell'ascissa rappresentano un contrasto locale piccolo (valori reali circa 10..20).\nIl 50% dell'ascissa rappresenta il contrasto locale medio (valore reale circa 100..300) .\nIl 66% dell'ascissa rappresenta la deviazione standard del contrasto locale (valore reale circa 300..800).\nIl 100% dell'ascissa rappresenta il contrasto locale massimo (valore reale circa 3000..8000). +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifica il contrasto di ciascun livello in funzione della tonalità.\nFare attenzione a non sovrascrivere le modifiche apportate con i controlli della tonalità dello strumento secondario Gamut.\nLa curva avrà effetto solo quando i cursori del livello di contrasto wavelet sono diversi da zero. +TP_WAVELET_CURVEEDITOR_CH;Livelli di contrasto=f(Tonalità) +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applica una curva finale di contrasto-luminanza al termine dell'elaborazione wavelet. +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifica la tonalità residua dell'immagine in funzione della tonalità. +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_DALL;Tutte le direzioni +TP_WAVELET_DAUB_TOOLTIP;Modifiche ai coefficienti Daubechies:\nD4 = Standard,\nD14 = Spesso la migliore prestazione, il 10% in più in termini di tempo.\n\nInfluisce sul rilevamento dei bordi e sulla qualità generale dei primi livelli. Tuttavia la qualità non è strettamente legata a questo coefficiente e può variare a seconda dell'immagine e dell'utilizzo. +TP_WAVELET_DAUB;Prestazioni ai bordi +TP_WAVELET_DAUB10;D10 - medio +TP_WAVELET_DAUB14;D14 - alto +TP_WAVELET_DAUB2;D2 - basso +TP_WAVELET_DAUB4;D4 - standard +TP_WAVELET_DAUB6;D6 - standard + +TP_WAVELET_DAUBLOCAL;Prestazioni ai bordi Wavelet +TP_WAVELET_DEN5THR;Soglia guidata +TP_WAVELET_DENCURV;Curva +TP_WAVELET_DENL;Correctione struttura +TP_WAVELET_DENLH;Soglia guidata livelli 1-4 +TP_WAVELET_DENLOCAL_TOOLTIP;Utilizzare una curva per guidare il denoising in base al contrasto locale.\nLe aree vengono denoisate, le strutture vengono mantenute. +TP_WAVELET_DENMIX_TOOLTIP;Il valore di riferimento del contrasto locale utilizzato dal filtro guidato.\nA seconda dell'immagine, i risultati possono variare a seconda che il rumore venga misurato prima o dopo la riduzione del rumore. Queste quattro scelte consentono di prendere in considerazione varie combinazioni delle immagini originali e modificate (denoizzate) per trovare il miglior compromesso. +TP_WAVELET_DENOISE;Curva guida basata sul contrasto locale +TP_WAVELET_DENOISEGUID;Soglia guidata in base alla tonalità +TP_WAVELET_DENOISEH;Livelli alti Curva Contrasto locale +TP_WAVELET_DENOISEHUE;Equalizzatore tonalità rimozione rumore +TP_WAVELET_DENQUA;Modo +TP_WAVELET_DENSIGMA_TOOLTIP;Adatta la forma della guida. +TP_WAVELET_DENSLI;Dispositivo di scorrimento +TP_WAVELET_DENSLILAB;Metodo +TP_WAVELET_DENWAVGUID_TOOLTIP;Utilizza la tonalità per ridurre o aumentare l'azione del filtro guidato. +TP_WAVELET_DENWAVHUE_TOOLTIP;Amplifica o riduci il denoising a seconda del colore. +TP_WAVELET_DETEND;Dettagli +TP_WAVELET_DIRFRAME;Contrasto direzionale +TP_WAVELET_DONE;Verticale +TP_WAVELET_DTHR;Diagonale +TP_WAVELET_DTWO;Orizzontale +TP_WAVELET_EDCU;Curva +TP_WAVELET_EDEFFECT_TOOLTIP;Questo cursore seleziona l'intervallo di valori di contrasto che riceveranno il pieno effetto di qualsiasi regolazione. +TP_WAVELET_EDEFFECT;Risposta di attenuazione +TP_WAVELET_EDGCONT_TOOLTIP;Regolando i punti a sinistra si diminuisce il contrasto, mentre a destra lo si aumenta.\nIn basso a sinistra, in alto a sinistra, in alto a destra e in basso a destra rappresentano rispettivamente il contrasto locale per valori bassi, media, media+std. dev. e massimi. +TP_WAVELET_EDGCONT;Contrasto locale +TP_WAVELET_EDGE;Nitidezza dei bordi +TP_WAVELET_EDGEAMPLI;Amplificazione di base +TP_WAVELET_EDGEDETECT_TOOLTIP;Spostando il cursore verso destra si aumenta la sensibilità dei bordi. Ciò influisce sul contrasto locale, sulle impostazioni dei bordi e sul rumore. +TP_WAVELET_EDGEDETECT;Sensibilità gradiente +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Questo cursore imposta una soglia al di sotto della quale i dettagli più fini non verranno considerati un vantaggio. +TP_WAVELET_EDGEDETECTTHR;Soglia bassa (rumore) +TP_WAVELET_EDGEDETECTTHR2;Miglioramento dei bordi +TP_WAVELET_EDGESENSI;Sensibilità dei bordi +TP_WAVELET_EDGREINF_TOOLTIP;Rafforzare o ridurre l'azione del primo livello, fare il contrario del secondo livello e lasciare invariato il resto. +TP_WAVELET_EDGTHRESH_TOOLTIP;Cambia la ripartizione tra i primi livelli e gli altri. Più alta è la soglia più l'azione è centrata sui primi livelli. Fare attenzione ai valori negativi, aumentano l'azione a livelli elevati e possono introdurre artefatti. +TP_WAVELET_EDGTHRESH;Dettagli +TP_WAVELET_EDRAD_TOOLTIP;Questa regolazione controlla il miglioramento locale. Un valore pari a zero ha comunque effetto. +TP_WAVELET_EDRAD;Raggio +TP_WAVELET_EDSL;Cursori di soglia +TP_WAVELET_EDTYPE;Metodo di contrasto locale +TP_WAVELET_EDVAL;Intensità +TP_WAVELET_FINAL;Ritocco finale +TP_WAVELET_FINCFRAME;Contrasto locale finale +TP_WAVELET_FINEST;Più bello +TP_WAVELET_FINTHR_TOOLTIP;Utilizza il contrasto locale per ridurre o aumentare l'azione del filtro guidato. +TP_WAVELET_GUIDFRAME;Smoothing finale (filtro guidato) +TP_WAVELET_HIGHLIGHT;Gamma di luminanza a livelli più fini +TP_WAVELET_HS1;Intero intervallo di luminanza +TP_WAVELET_HS2;Gamma di luminanza selettiva +TP_WAVELET_HUESKIN_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. +TP_WAVELET_HUESKIN;Tonalità della pelle +TP_WAVELET_HUESKY_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. +TP_WAVELET_HUESKY;Gamma di tonalità +TP_WAVELET_ITER_TOOLTIP;Sinistra: aumenta i livelli bassi e riduci i livelli alti,\nDestra: riduci i livelli bassi e aumenta i livelli alti. +TP_WAVELET_ITER;Livelli di equilibrio delta +TP_WAVELET_LABEL;Livelli wavelet +TP_WAVELET_LABGRID_VALUES;Alto(a)=%1 Alto(b)=%2\nBasso(a)=%3 Basso(b)=%4 +TP_WAVELET_LARGEST;Grossolano +TP_WAVELET_LEVCH;Crominanza +TP_WAVELET_LEVDEN;Riduzione rumore livello 5-6 +TP_WAVELET_LEVDIR_ALL;Tutti i livelli, in tutte le direzioni +TP_WAVELET_LEVDIR_INF;Livelli di dettaglio più fini, incluso il livello selezionato +TP_WAVELET_LEVDIR_ONE;Un livello +TP_WAVELET_LEVDIR_SUP;Livelli di dettaglio più grossolani, escluso il livello selezionato +TP_WAVELET_LEVELHIGH;Raggio 5-6 +TP_WAVELET_LEVELLOW;Raggio 1-4 +TP_WAVELET_LEVELS_TOOLTIP;Scegli il numero di livelli di decomposizione wavelet per l'immagine.\nPiù livelli richiedono più RAM e un tempo di elaborazione più lungo. +TP_WAVELET_LEVELS;Livelli di Wavelet +TP_WAVELET_LEVELSIGM;Raggio +TP_WAVELET_LEVF;Contrasto +TP_WAVELET_LEVFOUR;Riduzione rumore e soglia guidata livello 5-6 +TP_WAVELET_LEVLABEL;Anteprima dei livelli massimi possibili = %1 +TP_WAVELET_LEVONE;Livello 2 +TP_WAVELET_LEVTHRE;Livello 4 +TP_WAVELET_LEVTWO;Livello 3 +TP_WAVELET_LEVZERO;Livello 1 +TP_WAVELET_LIMDEN;Iterazione livello 5-6 di livelli 1-4 +TP_WAVELET_LINKEDG;Collegamento all'intensità della nitidezza del bordo +TP_WAVELET_LIPST;Algoritmo migliorato +TP_WAVELET_LOWLIGHT;Gamma di luminanza a livelli più grossolani +TP_WAVELET_LOWTHR_TOOLTIP;Previene l'amplificazione delle texture fini e del rumore. +TP_WAVELET_MEDGREINF;Primo livello +TP_WAVELET_MEDI;Riduci gli artefatti nel cielo blu +TP_WAVELET_MEDILEV_TOOLTIP;Quando abiliti il rilevamento dei bordi, si consiglia di:\n- disattivare i livelli di contrasto bassi per evitare artefatti,\n- utilizzare valori elevati di sensibilità del gradiente.\n\nPuoi modulare l'intensità con 'perfeziona' da Riduci rumore e Affina. +TP_WAVELET_MEDILEV;Rilevamento dei bordi +TP_WAVELET_MERGEC;Unisci crominanza +TP_WAVELET_MERGEL;Unisci luminanza +TP_WAVELET_MIXCONTRAST;Riferimento +TP_WAVELET_MIXDENOISE;Riduzione del rumore +TP_WAVELET_MIXMIX;Misto 50% rumore - 50% riduzione rumore +TP_WAVELET_MIXMIX70;Misto 30% rumore - 30% riduzione rumore +TP_WAVELET_MIXNOISE;Rumore +TP_WAVELET_NEUTRAL;Neutro +TP_WAVELET_NOIS;Riduzione rumore +TP_WAVELET_NOISE;Elimina rumore e perfeziona +TP_WAVELET_NPHIGH;Alto +TP_WAVELET_NPLOW;Basso +TP_WAVELET_NPNONE;Nessuno +TP_WAVELET_NPTYPE_TOOLTIP;Questo algoritmo utilizza la vicinanza di un pixel e otto dei suoi vicini. Se la differenza è inferiore, i bordi sono rinforzati. +TP_WAVELET_NPTYPE;Pixel vicini +TP_WAVELET_OFFSET_TOOLTIP;L'offset modifica il bilanciamento tra i dettagli a basso contrasto e quelli ad alto contrasto.\nValori elevati amplificheranno le modifiche del contrasto ai dettagli a contrasto più elevato, mentre valori bassi amplificheranno le modifiche del contrasto ai dettagli a basso contrasto.\nUtilizzando un valore di risposta dell'attenuazione basso è possibile selezionare quale contrasto i valori verranno valorizzati. +TP_WAVELET_OLDSH;Algoritmo che utilizza valori negativi +TP_WAVELET_OPACITY;Opacità blu-giallo +TP_WAVELET_OPACITYW;Curva d/v-h del bilanciamento del contrasto +TP_WAVELET_OPACITYWL_TOOLTIP;Modificare il contrasto locale finale al termine del trattamento wavelet.\n\nIl lato sinistro rappresenta il contrasto locale più piccolo, procedendo fino al contrasto locale più grande sulla destra. +TP_WAVELET_OPACITYWL;Contrasto locale +TP_WAVELET_PASTEL;Cromia pastello +TP_WAVELET_PROC;Processo +TP_WAVELET_PROTAB;Protezione +TP_WAVELET_QUAAGRES;Aggressività +TP_WAVELET_QUACONSER;Conservativo +TP_WAVELET_RADIUS;Raggio Ombre - Alteluci +TP_WAVELET_RANGEAB;Allineare a e b % +TP_WAVELET_RE1;Rinforzata +TP_WAVELET_RE2;Invariato +TP_WAVELET_RE3;Ridotto +TP_WAVELET_RESBLUR_TOOLTIP;Disabilitato se lo zoom > circa 500%. +TP_WAVELET_RESBLUR;Luminanza sfocata +TP_WAVELET_RESBLURC;Blur chromaSfocatura cromatica +TP_WAVELET_RESCHRO;Intensità +TP_WAVELET_RESCON;Ombre +TP_WAVELET_RESCONH;Alteluci +TP_WAVELET_RESID;Immagine residuale +TP_WAVELET_SAT;Cromia saturata +TP_WAVELET_SETTINGS;Impostazioni Wavelet +TP_WAVELET_SHA;Maschera definita +TP_WAVELET_SHFRAME;Ombre/Alteluci +TP_WAVELET_SHOWMASK;Mostra la 'maschera' wavelet +TP_WAVELET_SIGM;Raggio +TP_WAVELET_SIGMA_TOOLTIP;L'effetto dei cursori del contrasto è più forte nei dettagli a contrasto medio e più debole nei dettagli ad alto e basso contrasto.\n Con questo cursore puoi controllare quanto velocemente l'effetto si attenua verso i contrasti estremi.\n Più alto è impostato il cursore, più ampia è la gamma di contrasti che otterrà un forte cambiamento e maggiore è il rischio di generare artefatti.\n .Più basso è, più l'effetto sarà localizzato verso una gamma ristretta di valori di contrasto. +TP_WAVELET_SIGMA;Risposta di attenuazione +TP_WAVELET_SIGMAFIN;Risposta di attenuazione +TP_WAVELET_SKIN_TOOLTIP;A -100 le tonalità della pelle vengono prese di mira.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità della pelle vengono protette mentre tutte le altre tonalità vengono influenzate. +TP_WAVELET_SKIN;Mira/protezione della pelle +TP_WAVELET_SKY_TOOLTIP;Consente di scegliere o proteggere una gamma di tonalità.\nA -100 vengono prese di mira le tonalità selezionate.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità selezionate vengono protette mentre tutte le altre tonalità vengono prese di mira. +TP_WAVELET_SKY;Mira/protezione della tonalità +TP_WAVELET_SOFTRAD;Raggio morbido +TP_WAVELET_STREN;Perfeziona +TP_WAVELET_STREND;Intensità +TP_WAVELET_STRENGTH;Intensità +TP_WAVELET_SUPE;Extra +TP_WAVELET_THR;Soglia delle ombre +TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. +TP_WAVELET_THREND;Soglia di contrasto locale +TP_WAVELET_THRESHOLD_TOOLTIP;Solo i livelli inferiori e compresi nel valore scelto saranno influenzati dall'intervallo di luminanza delle alte luci. +TP_WAVELET_THRESHOLD;Livelli più fini +TP_WAVELET_THRESHOLD2_TOOLTIP;Solo i livelli dal valore scelto al numero selezionato di 'livelli wavelet' saranno influenzati dall'intervallo di luminanza dell'ombra. +TP_WAVELET_THRESHOLD2;Livelli più grossolani +TP_WAVELET_THRH;Soglia delle Alteluci +TP_WAVELET_TILES_TOOLTIP;L'elaborazione dell'immagine completa porta a una migliore qualità ed è l'opzione consigliata, mentre l'utilizzo dei riquadri è una soluzione di ripiego per gli utenti con poca RAM. Fare riferimento a RawPedia per i requisiti di memoria. +TP_WAVELET_TILESBIG;Riquadri +TP_WAVELET_TILESFULL;Immagine completa +TP_WAVELET_TILESIZE;Metodo di quadrettatura +TP_WAVELET_TMEDGS;Arresto del bordo +TP_WAVELET_TMSCALE;Scala +TP_WAVELET_TMSTRENGTH_TOOLTIP;Controlla l'intensità della mappatura dei toni o della compressione del contrasto dell'immagine residua. +TP_WAVELET_TMSTRENGTH;Intensità della compressione +TP_WAVELET_TMTYPE;Metodo di compressione +TP_WAVELET_TON;Tonificante +TP_WAVELET_TONFRAME;Colori esclusi +TP_WAVELET_USH_TOOLTIP;Se selezioni Maschera nitida, puoi scegliere qualsiasi livello (in Impostazioni) da 1 a 4 per l'elaborazione.\nSe selezioni Chiarezza, puoi scegliere qualsiasi livello (in Impostazioni) tra 5 ed Extra. +TP_WAVELET_USH;Nessuno +TP_WAVELET_USHARP;Metodo di chiarezza +TP_WAVELET_WAVLOWTHR;Soglia di contrasto basso +TP_WAVELET_WAVOFFSET;Compensa +TP_WBALANCE_AUTO_HEADER;Automatico e perfezionamento TP_WBALANCE_AUTO;Automatico +TP_WBALANCE_AUTOITCGREEN;Correlazione della temperatura +TP_WBALANCE_AUTOOLD;Grigio RGB TP_WBALANCE_CAMERA;Fotocamera TP_WBALANCE_CLOUDY;Nuvoloso TP_WBALANCE_CUSTOM;Personalizzato TP_WBALANCE_DAYLIGHT;Luce Diurna (soleggiato) -TP_WBALANCE_EQBLUERED;Equalizzatore Blu/Rosso TP_WBALANCE_EQBLUERED_TOOLTIP;Consente di deviare dal comportamento normale del "bilanciamento del bianco" modulando il bilanciamento blu/rosso.\nPuò essere utile quando le condizioni di ripresa:\na) sono molto diverse dalle illuminazioni normali (ad esempio, sott'acqua),\nb) sono molto diverse dalle condizioni alle quali sono state effettuate le calibrazioni,\nc) quando le matrici o i profili ICC non sono disponibili. +TP_WBALANCE_EQBLUERED;Equalizzatore Blu/Rosso +TP_WBALANCE_FLASH_HEADER;Flash 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_FLUO_HEADER;Fluorescente TP_WBALANCE_FLUO1;F1 - Luce Diurna +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 TP_WBALANCE_FLUO2;F2 - Bianco Freddo TP_WBALANCE_FLUO3;F3 - Bianco TP_WBALANCE_FLUO4;F4 - Bianco Caldo @@ -1178,13 +4162,48 @@ TP_WBALANCE_FLUO6;F6 - Bianco Chiaro TP_WBALANCE_FLUO7;F7 - D65 Simulatore di Luce Diurna TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design TP_WBALANCE_FLUO9;F9 - Bianco Freddo Deluxe -TP_WBALANCE_FLUO10;F10 - Philips TL85 -TP_WBALANCE_FLUO11;F11 - Philips TL84 -TP_WBALANCE_FLUO12;F12 - Philips TL83 -TP_WBALANCE_FLUO_HEADER;Fluorescente TP_WBALANCE_GREEN;Tinta TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI +TP_WBALANCE_ITCWALG_TOOLTIP;Permette di passare all'altra temperatura Alternativa (Alt_temp), quando possibile.\nNon attivo nel caso "scelta singola". +TP_WBALANCE_ITCWB_ALG;Rimuovi l'algoritmo a 2 passaggi +TP_WBALANCE_ITCWB_CUSTOM;Utilizza temperatura e tinta personalizzate +TP_WBALANCE_ITCWB_DELTA;Delta temperatura nel circuito verde +TP_WBALANCE_ITCWB_FGREEN;Trova uno alunno verde +TP_WBALANCE_ITCWB_FORCED;Vicino al diagramma CIE completo +TP_WBALANCE_ITCWB_FRA_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di raw, colorimetria, ecc.), un adattamento dell'algoritmo di 'Correlazione della temperatura'. Non esiste una regola assoluta che lega questi parametri ai risultati ottenuti. +TP_WBALANCE_ITCWB_FRA;Impostazioni correlazione temperatura auto +TP_WBALANCE_ITCWB_MINSIZEPATCH;Dimensione minima della patch +TP_WBALANCE_ITCWB_NOPURPLE;Filtra sul colore viola +TP_WBALANCE_ITCWB_PRECIS;Algoritmo di precisione: scala utilizzata +TP_WBALANCE_ITCWB_PRIM_ACE;Forza l'uso dell'intero diagramma CIE +TP_WBALANCE_ITCWB_PRIM_ADOB;Campionamento medio +TP_WBALANCE_ITCWB_PRIM_BETA;Campionamento medio: vicino alla gamma di Pointer +TP_WBALANCE_ITCWB_PRIM_JDCMAX;Vicino al diagramma CIE completo +TP_WBALANCE_ITCWB_PRIM_REC;Campionamento elevato +TP_WBALANCE_ITCWB_PRIM_SRGB;Campionamento basso e nessun utilizzo Impostazioni della fotocamera +TP_WBALANCE_ITCWB_PRIM_XYZCAM;Matrice XYZ della fotocamera +TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax dopo la matrice XYZ della fotocamera +TP_WBALANCE_ITCWB_RGREEN;Gamma del verde +TP_WBALANCE_ITCWB_SAMPLING;Campionamento basso 5.9 +TP_WBALANCE_ITCWB_SIZE;Dimensioni di riferimento il colore viene confrontato con l'istogramma +TP_WBALANCE_ITCWB_SIZEPATCH;Dimensioni della toppa colorata +TP_WBALANCE_ITCWB_THRES;Colori utilizzati nell'immagine (preimpostati) +TP_WBALANCE_ITCWBDELTA_TOOLTIP;Risolto il problema per ogni iterazione "verde" tentata, della differenza di temperatura da prendere in considerazione. +TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Trova il miglior compromesso tra Student e green. +TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Consente di impostare il valore patch minimo. valori troppo bassi possono portare ad una mancanza di correlazione. +TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Consente di filtrare i dati magenta/viola dall'immagine. Se la casella è selezionata, viene applicato un filtro che limita il valore di Y. Per impostazione predefinita questo valore è 0,4. Puoi cambiarlo nelle 'opzioni' Itcwb_Yporpora (Massimo 1) +TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Più basso è il valore, più rilevanti sono i dati, ma aumenta il tempo di elaborazione. Poiché il tempo di elaborazione è basso, questo parametro dovrebbe generalmente poter rimanere al valore predefinito +TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Imposta l'ampiezza di revisione del valore verde in iterazioni, dall'ampiezza bassa da 0,82 a 1,25 all'ampiezza massima da 0,4 a 4. +TP_WBALANCE_ITCWBSIZE_TOOLTIP;Questa impostazione imposta il numero di iterazioni per trovare la migliore corrispondenza tra i colori spettrali di riferimento e quelli nel valore xyY dell'immagine. Un valore pari a 3 sembra un buon compromesso. +TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Questa impostazione imposta la dimensione dei dati di colore utilizzati dall'algoritmo. +TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limita il campionamento comparativo tra i dati spettrali e i dati dell'immagine. +TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Ti consente di utilizzare le impostazioni personalizzate Temperatura e Verde (tinta).\n\nSuggerimenti per l'uso:\n1) avvia Itcwb, attiva 'Utilizza temperatura e tinta personalizzate'.\n2) Imposta 'Temperatura e tinta' a tuo piacimento: gratis, scegli ,...(Personalizzato)\n3) torna a 'Correlazione temperatura'.\n\nNon è possibile utilizzare: 2 passaggi, bias temperatura AWB, perfezionamento verde. +TP_WBALANCE_ITCWFORCED_TOOLTIP;Per impostazione predefinita (casella non selezionata) i dati scansionati durante il campionamento vengono riportati al profilo sRGB, che è il più diffuso, sia per la calibrazione dei profili DCP o ICC con il Colorchecker24, sia utilizzato sul web.\n Se avete valori molto alti immagini della gamma (alcuni fiori, colori artificiali), potrebbe essere necessario utilizzare l'intero diagramma CIExy, il profilo utilizzato sarà ACESP0. In questo secondo caso sarà più importante il numero di colori che potranno essere utilizzati all’interno dell’algoritmo. +TP_WBALANCE_ITCWGREEN_TOOLTIP;Permette di cambiare la "tinta" (verde) che servirà da riferimento all'avvio dell'algoritmo. Ha sostanzialmente lo stesso ruolo per i verdi del "bias temperatura AWB" per la temperatura.\nL'intero algoritmo viene ricalcolato. +TP_WBALANCE_ITCWGREEN;Raffinatezza del verde +TP_WBALANCE_ITCWPRIM_TOOLTIP;Permette di selezionare il campionamento dell'immagine.\n'Vicino al diagramma CIE completo' utilizza quasi i dati presenti sul sensore, eventualmente includendo i colori immaginari.\n'Matrice XYZ della fotocamera' - utilizza la matrice derivata direttamente da Color Matrix.\ n'Campionamento medio' (predefinito) - vicino alla gamma del puntatore: corrisponde sostanzialmente ai casi più comuni di visione umana.\nL'altra scelta 'Campionamento basso e Impostazioni fotocamera inutilizzata' consentono di isolare parti ad alta gamma dell'immagine e forzare il algoritmo in alcuni casi (tinta > 0,8,...) per non utilizzare le impostazioni della fotocamera. Ciò ovviamente avrà un impatto sul risultato.\n\nQuesto campionamento influisce solo sui moltiplicatori di canale, non ha nulla a che vedere con il "profilo di lavoro" e non modifica il gamut dell'immagine. +TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Consente di utilizzare il vecchio algoritmo di campionamento per garantire una migliore compatibilità con 5.9. È necessario abilitare Observer 10° (impostazione predefinita). TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;Bilanciamento del bianco TP_WBALANCE_LAMP_HEADER;Lamp @@ -1192,3058 +4211,39 @@ TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 TP_WBALANCE_LED_HEADER;LED TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Metodo +TP_WBALANCE_MULLABEL_TOOLTIP;Valori forniti a scopo informativo. Non puoi cambiarli. +TP_WBALANCE_MULLABEL;Multi: r=%1 g=%2 b=%3 +TP_WBALANCE_OBSERVER10_TOOLTIP;La gestione del colore in Rawtherapee (bilanciamento del bianco, moltiplicatori di canali, recupero delle luci,...) utilizza i dati spettrali degli illuminanti e dei colori. L'osservatore è un parametro importante di questa gestione che tiene conto dell'angolo di percezione dell'occhio. Nel 1931 fu fissata a 2° (privilegia l'uso dei coni). Nel 1964 è stato fissato a 10° (privilegia l'uso dei coni, ma tiene parzialmente conto dei bastoncelli).\nPer evitare una (rara) deriva dei colori dovuta alla scelta dell'Osservatore 10° - probabilmente dovuta alla matrice di conversione - È necessario selezionare l'Osservatore 2°.\nNella maggior parte dei casi l'Osservatore 10° (predefinito) sarà una scelta più rilevante. +TP_WBALANCE_OBSERVER10;Osservatore 10° invece di 2° +TP_WBALANCE_PATCHLABEL_TOOLTIP;Visualizza il numero di colori letti (max=237).\nVisualizza la crominanza patch calcolata.\nBias di temperatura AWB, proviamo a ridurre questo valore, un minimo potrebbe sembrare per ottimizzare l'algoritmo.\n\nOttimizzazione della crominanza corrispondente alla dimensione della patch. +TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 +TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Visualizza patch ΔE (questo presuppone che ci siano abbastanza dati spettrali), tra l'immagine e i dati spettrali.\n Visualizza i dati letti trovati. I 2 valori corrispondono ai valori dei dati minimo e massimo presi in considerazione. È necessario tenere conto del coefficiente x9 per ottenere il numero di pixel interessati nell'immagine. +TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 +TP_WBALANCE_PICKER;Scegli TP_WBALANCE_SHADE;Ombra -TP_WBALANCE_SIZE;Dimensione: +TP_WBALANCE_SIZE;Dim.: 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_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SPOTWB;Punto BB +TP_WBALANCE_STUDLABEL_TOOLTIP;Visualizza la correlazione Student calcolata.\nValori più bassi sono migliori, dove <0,005 è eccellente,\n<0,01 è buono e >0,5 è scarso.\nValori bassi non significano che il bilanciamento del bianco è buono:\nse l'illuminante non è standard i risultati possono essere irregolari.\nUn valore di 1000 significa che vengono utilizzati i calcoli precedenti e\ni risultati sono probabilmente buoni.\n\nPassaggi: numero di passaggi effettuati.\nAlt_temp: temperatura alternativa. +TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 +TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 +TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 +TP_WBALANCE_TEMPBIAS_TOOLTIP;Permette di alterare il calcolo del 'bilanciamento automatico del bianco'\nspostandolo verso temperature più calde o più fredde. Il bias\nè espresso come percentuale della temperatura calcolata,\nin modo che il risultato sia dato da 'computedTemp + computedTemp * bias'.\n\nÈ possibile utilizzare il "bias temperatura Awb" per regolare i risultati della "correlazione della temperatura". Ogni movimento di questo comando comporta un nuovo calcolo di temperatura, tinta e correlazione. +TP_WBALANCE_TEMPBIAS;Distorsione temperatura AWB TP_WBALANCE_TEMPERATURE;Temperatura TP_WBALANCE_TUNGSTEN;Tungsteno +TP_WBALANCE_WATER_HEADER;Subacqueo TP_WBALANCE_WATER1;Subacqueo 1 TP_WBALANCE_WATER2;Subacqueo 2 -TP_WBALANCE_WATER_HEADER;Subacqueo ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;Apri (nuova) finestra di dettaglio ZOOMPANEL_ZOOM100;Ingrandimento al 100%.\nScorciatoia: z +ZOOMPANEL_ZOOMFITCROPSCREEN;Adatta il ritaglio allo schermo\nScorciatoia: f ZOOMPANEL_ZOOMFITSCREEN;Adatta allo schermo.\nScorciatoia: Alt-f ZOOMPANEL_ZOOMIN;Ingrandisci.\nScorciatoia: + ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!ADJUSTER_RESET_TO_DEFAULT;Click - reset to default value.\nCtrl+click - reset to initial value. -!CURVEEDITOR_AXIS_IN;I: -!CURVEEDITOR_AXIS_LEFT_TAN;LT: -!CURVEEDITOR_AXIS_OUT;O: -!CURVEEDITOR_AXIS_RIGHT_TAN;RT: -!CURVEEDITOR_CATMULLROM;Flexible -!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. -!DONT_SHOW_AGAIN;Don't show this message again. -!DYNPROFILEEDITOR_DELETE;Delete -!DYNPROFILEEDITOR_EDIT;Edit -!DYNPROFILEEDITOR_EDIT_RULE;Edit Dynamic Profile Rule -!DYNPROFILEEDITOR_ENTRY_TOOLTIP;The matching is case insensitive.\nUse the 're:' prefix to enter\na regular expression. -!DYNPROFILEEDITOR_IMGTYPE_ANY;Any -!DYNPROFILEEDITOR_IMGTYPE_HDR;HDR -!DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift -!DYNPROFILEEDITOR_IMGTYPE_STD;Standard -!DYNPROFILEEDITOR_MOVE_DOWN;Move Down -!DYNPROFILEEDITOR_MOVE_UP;Move Up -!DYNPROFILEEDITOR_NEW;New -!DYNPROFILEEDITOR_NEW_RULE;New Dynamic Profile Rule -!DYNPROFILEEDITOR_PROFILE;Processing Profile -!ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!EXIFFILTER_IMAGETYPE;Image type -!EXIFFILTER_PATH;File path -!EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags -!EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags -!EXIFPANEL_BASIC_GROUP;Basic -!EXIFPANEL_VALUE_NOT_SHOWN;Not shown -!EXPORT_BYPASS;Processing steps to bypass -!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels -!EXPORT_PIPELINE;Processing pipeline -!EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) -!EXPORT_USE_FAST_PIPELINE_TOOLTIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality. -!EXPORT_USE_NORMAL_PIPELINE;Standard (bypass some steps, resize at the end) -!FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. -!FILEBROWSER_CACHECLEARFROMFULL;Clear all including cached profiles -!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear all except cached profiles -!FILEBROWSER_DELETEDIALOG_ALL;Are you sure you want to permanently delete all %1 files in trash? -!FILEBROWSER_DELETEDIALOG_SELECTED;Are you sure you want to permanently delete the selected %1 files? -!FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? -!FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. -!FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPREMOVE;Delete permanently -!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILEBROWSER_RESETDEFAULTPROFILE;Reset to default -!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. -!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!FILECHOOSER_FILTER_ANY;All files -!FILECHOOSER_FILTER_COLPROF;Color profiles (*.icc) -!FILECHOOSER_FILTER_CURVE;Curve files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!FILECHOOSER_FILTER_LCP;Lens correction profiles -!FILECHOOSER_FILTER_PP;Processing profiles -!FILECHOOSER_FILTER_SAME;Same format as current photo -!FILECHOOSER_FILTER_TIFF;TIFF files -!GENERAL_APPLY;Apply -!GENERAL_ASIMAGE;As Image -!GENERAL_CURRENT;Current -!GENERAL_DELETE_ALL;Delete all -!GENERAL_EDIT;Edit -!GENERAL_HELP;Help -!GENERAL_OPEN;Open -!GENERAL_OTHER;Other -!GENERAL_RESET;Reset -!GENERAL_SAVE_AS;Save as... -!GENERAL_SLIDER;Slider -!GIMP_PLUGIN_INFO;Welcome to the RawTherapee GIMP plugin!\nOnce you are done editing, simply close the main RawTherapee window and the image will be automatically imported in GIMP. -!HISTOGRAM_TOOLTIP_CROSSHAIR;Show/Hide indicator crosshair. -!HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram. -!HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toggle visibility of the scope option buttons. -!HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Adjust scope brightness. -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw Histogram -!HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB Parade -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Hue-Chroma Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Hue-Saturation Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Waveform -!HISTORY_MSG_166;Exposure - Reset -!HISTORY_MSG_173;NR - Detail recovery -!HISTORY_MSG_203;NR - Color space -!HISTORY_MSG_235;B&W - CM - Auto -!HISTORY_MSG_237;B&W - CM -!HISTORY_MSG_256;NR - Median - Type -!HISTORY_MSG_257;Color Toning -!HISTORY_MSG_258;CT - Color curve -!HISTORY_MSG_259;CT - Opacity curve -!HISTORY_MSG_260;CT - a*[b*] opacity -!HISTORY_MSG_261;CT - Method -!HISTORY_MSG_262;CT - b* opacity -!HISTORY_MSG_263;CT - Shadows - Red -!HISTORY_MSG_264;CT - Shadows - Green -!HISTORY_MSG_265;CT - Shadows - Blue -!HISTORY_MSG_266;CT - Mid - Red -!HISTORY_MSG_267;CT - Mid - Green -!HISTORY_MSG_268;CT - Mid - Blue -!HISTORY_MSG_269;CT - High - Red -!HISTORY_MSG_270;CT - High - Green -!HISTORY_MSG_271;CT - High - Blue -!HISTORY_MSG_272;CT - Balance -!HISTORY_MSG_273;CT - Color Balance SMH -!HISTORY_MSG_276;CT - Opacity -!HISTORY_MSG_277;--unused-- -!HISTORY_MSG_278;CT - Preserve luminance -!HISTORY_MSG_279;CT - Shadows -!HISTORY_MSG_280;CT - Highlights -!HISTORY_MSG_281;CT - Sat. strength -!HISTORY_MSG_282;CT - Sat. threshold -!HISTORY_MSG_283;CT - Strength -!HISTORY_MSG_284;CT - Auto sat. protection -!HISTORY_MSG_285;NR - Median - Method -!HISTORY_MSG_286;NR - Median - Type -!HISTORY_MSG_287;NR - Median - Iterations -!HISTORY_MSG_288;Flat-Field - Clip control -!HISTORY_MSG_289;Flat-Field - Clip control - Auto -!HISTORY_MSG_290;Black Level - Red -!HISTORY_MSG_291;Black Level - Green -!HISTORY_MSG_292;Black Level - Blue -!HISTORY_MSG_293;Film Simulation -!HISTORY_MSG_294;Film Simulation - Strength -!HISTORY_MSG_295;Film Simulation - Film -!HISTORY_MSG_296;NR - Luminance curve -!HISTORY_MSG_297;NR - Mode -!HISTORY_MSG_298;Dead pixel filter -!HISTORY_MSG_299;NR - Chrominance curve -!HISTORY_MSG_301;NR - Luma control -!HISTORY_MSG_302;NR - Chroma method -!HISTORY_MSG_303;NR - Chroma method -!HISTORY_MSG_304;W - Contrast levels -!HISTORY_MSG_305;Wavelet Levels -!HISTORY_MSG_306;W - Process -!HISTORY_MSG_307;W - Process -!HISTORY_MSG_308;W - Process direction -!HISTORY_MSG_309;W - ES - Detail -!HISTORY_MSG_310;W - Residual - Sky tar/prot -!HISTORY_MSG_311;W - Wavelet levels -!HISTORY_MSG_312;W - Residual - Shadows threshold -!HISTORY_MSG_313;W - Chroma - Sat/past -!HISTORY_MSG_314;W - Gamut - Reduce artifacts -!HISTORY_MSG_315;W - Residual - Contrast -!HISTORY_MSG_316;W - Gamut - Skin tar/prot -!HISTORY_MSG_317;W - Gamut - Skin hue -!HISTORY_MSG_318;W - Contrast - Finer levels -!HISTORY_MSG_319;W - Contrast - Finer range -!HISTORY_MSG_320;W - Contrast - Coarser range -!HISTORY_MSG_321;W - Contrast - Coarser levels -!HISTORY_MSG_322;W - Gamut - Avoid color shift -!HISTORY_MSG_323;W - ES - Local contrast -!HISTORY_MSG_324;W - Chroma - Pastel -!HISTORY_MSG_325;W - Chroma - Saturated -!HISTORY_MSG_326;W - Chroma - Method -!HISTORY_MSG_327;W - Contrast - Apply to -!HISTORY_MSG_328;W - Chroma - Link strength -!HISTORY_MSG_329;W - Toning - Opacity RG -!HISTORY_MSG_330;W - Toning - Opacity BY -!HISTORY_MSG_331;W - Contrast levels - Extra -!HISTORY_MSG_332;W - Tiling method -!HISTORY_MSG_333;W - Residual - Shadows -!HISTORY_MSG_334;W - Residual - Chroma -!HISTORY_MSG_335;W - Residual - Highlights -!HISTORY_MSG_336;W - Residual - Highlights threshold -!HISTORY_MSG_337;W - Residual - Sky hue -!HISTORY_MSG_338;W - ES - Radius -!HISTORY_MSG_339;W - ES - Strength -!HISTORY_MSG_340;W - Strength -!HISTORY_MSG_341;W - Edge performance -!HISTORY_MSG_342;W - ES - First level -!HISTORY_MSG_343;W - Chroma levels -!HISTORY_MSG_344;W - Meth chroma sl/cur -!HISTORY_MSG_345;W - ES - Local contrast -!HISTORY_MSG_346;W - ES - Local contrast method -!HISTORY_MSG_347;W - Denoise - Level 1 -!HISTORY_MSG_348;W - Denoise - Level 2 -!HISTORY_MSG_349;W - Denoise - Level 3 -!HISTORY_MSG_350;W - ES - Edge detection -!HISTORY_MSG_351;W - Residual - HH curve -!HISTORY_MSG_352;W - Background -!HISTORY_MSG_353;W - ES - Gradient sensitivity -!HISTORY_MSG_354;W - ES - Enhanced -!HISTORY_MSG_355;W - ES - Threshold low -!HISTORY_MSG_356;W - ES - Threshold high -!HISTORY_MSG_357;W - Denoise - Link with ES -!HISTORY_MSG_358;W - Gamut - CH -!HISTORY_MSG_359;Hot/Dead - Threshold -!HISTORY_MSG_360;TM - Gamma -!HISTORY_MSG_361;W - Final - Chroma balance -!HISTORY_MSG_362;W - Residual - Compression method -!HISTORY_MSG_363;W - Residual - Compression strength -!HISTORY_MSG_364;W - Final - Contrast balance -!HISTORY_MSG_365;W - Final - Delta balance -!HISTORY_MSG_366;W - Residual - Compression gamma -!HISTORY_MSG_367;W - Final - 'After' contrast curve -!HISTORY_MSG_368;W - Final - Contrast balance -!HISTORY_MSG_369;W - Final - Balance method -!HISTORY_MSG_370;W - Final - Local contrast curve -!HISTORY_MSG_371;Post-Resize Sharpening -!HISTORY_MSG_372;PRS USM - Radius -!HISTORY_MSG_373;PRS USM - Amount -!HISTORY_MSG_374;PRS USM - Threshold -!HISTORY_MSG_375;PRS USM - Sharpen only edges -!HISTORY_MSG_376;PRS USM - Edge detection radius -!HISTORY_MSG_377;PRS USM - Edge tolerance -!HISTORY_MSG_378;PRS USM - Halo control -!HISTORY_MSG_379;PRS USM - Halo control amount -!HISTORY_MSG_380;PRS - Method -!HISTORY_MSG_381;PRS RLD - Radius -!HISTORY_MSG_382;PRS RLD - Amount -!HISTORY_MSG_383;PRS RLD - Damping -!HISTORY_MSG_384;PRS RLD - Iterations -!HISTORY_MSG_385;W - Residual - Color balance -!HISTORY_MSG_386;W - Residual - CB green high -!HISTORY_MSG_387;W - Residual - CB blue high -!HISTORY_MSG_388;W - Residual - CB green mid -!HISTORY_MSG_389;W - Residual - CB blue mid -!HISTORY_MSG_390;W - Residual - CB green low -!HISTORY_MSG_391;W - Residual - CB blue low -!HISTORY_MSG_392;W - Residual - Color balance -!HISTORY_MSG_393;DCP - Look table -!HISTORY_MSG_394;DCP - Baseline exposure -!HISTORY_MSG_395;DCP - Base table -!HISTORY_MSG_396;W - Contrast sub-tool -!HISTORY_MSG_397;W - Chroma sub-tool -!HISTORY_MSG_398;W - ES sub-tool -!HISTORY_MSG_399;W - Residual sub-tool -!HISTORY_MSG_400;W - Final sub-tool -!HISTORY_MSG_401;W - Toning sub-tool -!HISTORY_MSG_402;W - Denoise sub-tool -!HISTORY_MSG_403;W - ES - Edge sensitivity -!HISTORY_MSG_404;W - ES - Base amplification -!HISTORY_MSG_405;W - Denoise - Level 4 -!HISTORY_MSG_406;W - ES - Neighboring pixels -!HISTORY_MSG_407;Retinex - Method -!HISTORY_MSG_408;Retinex - Radius -!HISTORY_MSG_410;Retinex - Offset -!HISTORY_MSG_411;Retinex - Strength -!HISTORY_MSG_412;Retinex - Gaussian gradient -!HISTORY_MSG_413;Retinex - Contrast -!HISTORY_MSG_414;Retinex - Histogram - Lab -!HISTORY_MSG_415;Retinex - Transmission -!HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median -!HISTORY_MSG_418;Retinex - Threshold -!HISTORY_MSG_419;Retinex - Color space -!HISTORY_MSG_420;Retinex - Histogram - HSL -!HISTORY_MSG_421;Retinex - Gamma -!HISTORY_MSG_422;Retinex - Gamma -!HISTORY_MSG_423;Retinex - Gamma slope -!HISTORY_MSG_424;Retinex - HL threshold -!HISTORY_MSG_425;--unused-- -!HISTORY_MSG_426;Retinex - Hue equalizer -!HISTORY_MSG_427;Output rendering intent -!HISTORY_MSG_428;Monitor rendering intent -!HISTORY_MSG_429;Retinex - Iterations -!HISTORY_MSG_430;Retinex - Transmission gradient -!HISTORY_MSG_431;Retinex - Strength gradient -!HISTORY_MSG_432;Retinex - M - Highlights -!HISTORY_MSG_433;Retinex - M - Highlights TW -!HISTORY_MSG_434;Retinex - M - Shadows -!HISTORY_MSG_435;Retinex - M - Shadows TW -!HISTORY_MSG_436;Retinex - M - Radius -!HISTORY_MSG_437;Retinex - M - Method -!HISTORY_MSG_438;Retinex - M - Equalizer -!HISTORY_MSG_439;Retinex - Process -!HISTORY_MSG_440;CbDL - Method -!HISTORY_MSG_441;Retinex - Gain transmission -!HISTORY_MSG_442;Retinex - Scale -!HISTORY_MSG_443;Output black point compensation -!HISTORY_MSG_444;WB - Temp bias -!HISTORY_MSG_445;Raw Sub-Image -!HISTORY_MSG_446;--unused-- -!HISTORY_MSG_447;--unused-- -!HISTORY_MSG_448;--unused-- -!HISTORY_MSG_449;PS ISO adaption -!HISTORY_MSG_450;--unused-- -!HISTORY_MSG_451;--unused-- -!HISTORY_MSG_452;PS Show motion -!HISTORY_MSG_453;PS Show mask only -!HISTORY_MSG_454;--unused-- -!HISTORY_MSG_455;--unused-- -!HISTORY_MSG_456;--unused-- -!HISTORY_MSG_457;PS Check red/blue -!HISTORY_MSG_458;--unused-- -!HISTORY_MSG_459;--unused-- -!HISTORY_MSG_460;--unused-- -!HISTORY_MSG_461;--unused-- -!HISTORY_MSG_462;PS Check green -!HISTORY_MSG_463;--unused-- -!HISTORY_MSG_464;PS Blur motion mask -!HISTORY_MSG_465;PS Blur radius -!HISTORY_MSG_466;--unused-- -!HISTORY_MSG_467;--unused-- -!HISTORY_MSG_468;PS Fill holes -!HISTORY_MSG_469;PS Median -!HISTORY_MSG_470;--unused-- -!HISTORY_MSG_471;PS Motion correction -!HISTORY_MSG_472;PS Smooth transitions -!HISTORY_MSG_474;PS Equalize -!HISTORY_MSG_475;PS Equalize channel -!HISTORY_MSG_476;CAL - VC - Temperature -!HISTORY_MSG_477;CAL - VC - Tint -!HISTORY_MSG_478;CAL - VC - Mean luminance -!HISTORY_MSG_479;CAL - VC - Adaptation -!HISTORY_MSG_480;CAL - VC - Auto adaptation -!HISTORY_MSG_481;CAL - SC - Temperature -!HISTORY_MSG_482;CAL - SC - Tint -!HISTORY_MSG_483;CAL - SC - Mean luminance -!HISTORY_MSG_484;CAL - SC - Auto mean luminance -!HISTORY_MSG_485;Lens Correction -!HISTORY_MSG_486;Lens Correction - Camera -!HISTORY_MSG_487;Lens Correction - Lens -!HISTORY_MSG_488;Dynamic Range Compression -!HISTORY_MSG_489;DRC - Detail -!HISTORY_MSG_490;DRC - Amount -!HISTORY_MSG_491;White Balance -!HISTORY_MSG_492;RGB Curves -!HISTORY_MSG_493;L*a*b* Adjustments -!HISTORY_MSG_494;Capture Sharpening -!HISTORY_MSG_496;Local Spot deleted -!HISTORY_MSG_497;Local Spot selected -!HISTORY_MSG_498;Local - Spot name -!HISTORY_MSG_499;Local - Spot visibility -!HISTORY_MSG_500;Local - Spot shape -!HISTORY_MSG_501;Local - Spot method -!HISTORY_MSG_502;Local - SC - Shape method -!HISTORY_MSG_503;Local - Spot - Right -!HISTORY_MSG_504;Local - Spot - Left -!HISTORY_MSG_505;Local - Spot - Bottom -!HISTORY_MSG_506;Local - Spot - Top -!HISTORY_MSG_507;Local - Spot - Center -!HISTORY_MSG_508;Local - Spot - Size -!HISTORY_MSG_509;Local - Spot quality method -!HISTORY_MSG_510;Local - TG - Transition value -!HISTORY_MSG_511;Local - SD - ΔE scope threshold -!HISTORY_MSG_512;Local - SD - ΔE decay -!HISTORY_MSG_513;Local - Spot - Excluding - Scope -!HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments -!HISTORY_MSG_516;Local - Color and light -!HISTORY_MSG_517;Local - Enable super -!HISTORY_MSG_518;Local - Lightness -!HISTORY_MSG_519;Local - Contrast -!HISTORY_MSG_520;Local - Chrominance -!HISTORY_MSG_521;Local - Scope -!HISTORY_MSG_522;Local - Curve method -!HISTORY_MSG_523;Local - LL Curve -!HISTORY_MSG_524;Local - CC curve -!HISTORY_MSG_525;Local - LH Curve -!HISTORY_MSG_526;Local - H curve -!HISTORY_MSG_527;Local - Color Inverse -!HISTORY_MSG_528;Local - Exposure -!HISTORY_MSG_529;Local - Exp Compensation -!HISTORY_MSG_530;Local - Exp Hlcompr -!HISTORY_MSG_531;Local - Exp hlcomprthresh -!HISTORY_MSG_532;Local - Exp black -!HISTORY_MSG_533;Local - Exp Shcompr -!HISTORY_MSG_534;Local - Warm Cool -!HISTORY_MSG_535;Local - Exp Scope -!HISTORY_MSG_536;Local - Exp Contrast curve -!HISTORY_MSG_537;Local - Vibrance -!HISTORY_MSG_538;Local - Vib Saturated -!HISTORY_MSG_539;Local - Vib Pastel -!HISTORY_MSG_540;Local - Vib Threshold -!HISTORY_MSG_541;Local - Vib Protect skin tones -!HISTORY_MSG_542;Local - Vib avoid colorshift -!HISTORY_MSG_543;Local - Vib link -!HISTORY_MSG_544;Local - Vib Scope -!HISTORY_MSG_545;Local - Vib H curve -!HISTORY_MSG_546;Local - Blur and noise -!HISTORY_MSG_547;Local - Radius -!HISTORY_MSG_548;Local - Noise -!HISTORY_MSG_549;Local - Blur scope -!HISTORY_MSG_550;Local - Blur method -!HISTORY_MSG_551;Local - Blur Luminance only -!HISTORY_MSG_552;Local - Tone mapping -!HISTORY_MSG_553;Local - TM compression strength -!HISTORY_MSG_554;Local - TM gamma -!HISTORY_MSG_555;Local - TM edge stopping -!HISTORY_MSG_556;Local - TM scale -!HISTORY_MSG_557;Local - TM Reweighting -!HISTORY_MSG_558;Local - TM scope -!HISTORY_MSG_559;Local - Retinex -!HISTORY_MSG_560;Local - Retinex method -!HISTORY_MSG_561;Local - Retinex strength -!HISTORY_MSG_562;Local - Retinex chroma -!HISTORY_MSG_563;Local - Retinex radius -!HISTORY_MSG_564;Local - Retinex contrast -!HISTORY_MSG_565;Local - scope -!HISTORY_MSG_566;Local - Retinex Gain curve -!HISTORY_MSG_567;Local - Retinex Inverse -!HISTORY_MSG_568;Local - Sharpening -!HISTORY_MSG_569;Local - Sh Radius -!HISTORY_MSG_570;Local - Sh Amount -!HISTORY_MSG_571;Local - Sh Damping -!HISTORY_MSG_572;Local - Sh Iterations -!HISTORY_MSG_573;Local - Sh Scope -!HISTORY_MSG_574;Local - Sh Inverse -!HISTORY_MSG_575;Local - CBDL -!HISTORY_MSG_576;Local - cbdl mult -!HISTORY_MSG_577;Local - cbdl chroma -!HISTORY_MSG_578;Local - cbdl threshold -!HISTORY_MSG_579;Local - cbdl scope -!HISTORY_MSG_580;--unused-- -!HISTORY_MSG_581;Local - Denoise lum f 1 -!HISTORY_MSG_582;Local - Denoise lum c -!HISTORY_MSG_583;Local - Denoise lum detail -!HISTORY_MSG_584;Local - Denoise equalizer White-Black -!HISTORY_MSG_585;Local - Denoise chro f -!HISTORY_MSG_586;Local - Denoise chro c -!HISTORY_MSG_587;Local - Denoise chro detail -!HISTORY_MSG_588;Local - Denoise equalizer Blue-Red -!HISTORY_MSG_589;Local - Denoise bilateral -!HISTORY_MSG_590;Local - Denoise Scope -!HISTORY_MSG_591;Local - Avoid color shift -!HISTORY_MSG_592;Local - Sh Contrast -!HISTORY_MSG_593;Local - Local contrast -!HISTORY_MSG_594;Local - Local contrast radius -!HISTORY_MSG_595;Local - Local contrast amount -!HISTORY_MSG_596;Local - Local contrast darkness -!HISTORY_MSG_597;Local - Local contrast lightness -!HISTORY_MSG_598;Local - Local contrast scope -!HISTORY_MSG_599;Local - Retinex dehaze -!HISTORY_MSG_600;Local - Soft Light enable -!HISTORY_MSG_601;Local - Soft Light strength -!HISTORY_MSG_602;Local - Soft Light scope -!HISTORY_MSG_603;Local - Sh Blur radius -!HISTORY_MSG_605;Local - Mask preview choice -!HISTORY_MSG_606;Local Spot selected -!HISTORY_MSG_607;Local - Color Mask C -!HISTORY_MSG_608;Local - Color Mask L -!HISTORY_MSG_609;Local - Exp Mask C -!HISTORY_MSG_610;Local - Exp Mask L -!HISTORY_MSG_611;Local - Color Mask H -!HISTORY_MSG_612;Local - Color Structure -!HISTORY_MSG_613;Local - Exp Structure -!HISTORY_MSG_614;Local - Exp Mask H -!HISTORY_MSG_615;Local - Blend color -!HISTORY_MSG_616;Local - Blend Exp -!HISTORY_MSG_617;Local - Blur Exp -!HISTORY_MSG_618;Local - Use Color Mask -!HISTORY_MSG_619;Local - Use Exp Mask -!HISTORY_MSG_620;Local - Blur col -!HISTORY_MSG_621;Local - Exp inverse -!HISTORY_MSG_622;Local - Spot - Excluding - Spot structure -!HISTORY_MSG_623;Local - Exp Chroma compensation -!HISTORY_MSG_624;Local - Color correction grid -!HISTORY_MSG_625;Local - Color correction strength -!HISTORY_MSG_626;Local - Color correction Method -!HISTORY_MSG_627;Local - Shadow Highlight -!HISTORY_MSG_628;Local - SH Highlight -!HISTORY_MSG_629;Local - SH H tonalwidth -!HISTORY_MSG_630;Local - SH Shadows -!HISTORY_MSG_631;Local - SH S tonalwidth -!HISTORY_MSG_632;Local - SH radius -!HISTORY_MSG_633;Local - SH Scope -!HISTORY_MSG_634;Local - radius color -!HISTORY_MSG_635;Local - radius Exp -!HISTORY_MSG_636;Local - Tool added -!HISTORY_MSG_637;Local - SH Mask C -!HISTORY_MSG_638;Local - SH Mask L -!HISTORY_MSG_639;Local - SH Mask H -!HISTORY_MSG_640;Local - SH blend -!HISTORY_MSG_641;Local - Use SH mask -!HISTORY_MSG_642;Local - radius SH -!HISTORY_MSG_643;Local - Blur SH -!HISTORY_MSG_644;Local - inverse SH -!HISTORY_MSG_645;Local - SD - ab-L balance -!HISTORY_MSG_646;Local - Exp mask chroma -!HISTORY_MSG_647;Local - Exp mask gamma -!HISTORY_MSG_648;Local - Exp mask slope -!HISTORY_MSG_649;Local - Exp soft radius -!HISTORY_MSG_650;Local - Color mask chroma -!HISTORY_MSG_651;Local - Color mask gamma -!HISTORY_MSG_652;Local - Color mask slope -!HISTORY_MSG_653;Local - SH mask chroma -!HISTORY_MSG_654;Local - SH mask gamma -!HISTORY_MSG_655;Local - SH mask slope -!HISTORY_MSG_656;Local - Color soft radius -!HISTORY_MSG_657;Local - Retinex Reduce artifacts -!HISTORY_MSG_658;Local - CBDL soft radius -!HISTORY_MSG_659;Local - TG - Transition decay -!HISTORY_MSG_660;Local - cbdl clarity -!HISTORY_MSG_661;Local - cbdl contrast residual -!HISTORY_MSG_662;Local - Denoise lum f 0 -!HISTORY_MSG_663;Local - Denoise lum f 2 -!HISTORY_MSG_664;--unused-- -!HISTORY_MSG_665;Local - cbdl mask Blend -!HISTORY_MSG_666;Local - cbdl mask radius -!HISTORY_MSG_667;Local - cbdl mask chroma -!HISTORY_MSG_668;Local - cbdl mask gamma -!HISTORY_MSG_669;Local - cbdl mask slope -!HISTORY_MSG_670;Local - cbdl mask C -!HISTORY_MSG_671;Local - cbdl mask L -!HISTORY_MSG_672;Local - cbdl mask CL -!HISTORY_MSG_673;Local - Use cbdl mask -!HISTORY_MSG_674;Local - Tool removed -!HISTORY_MSG_675;Local - TM soft radius -!HISTORY_MSG_676;Local - TG - Transition differentiation -!HISTORY_MSG_677;Local - TM amount -!HISTORY_MSG_678;Local - TM saturation -!HISTORY_MSG_679;Local - Retinex mask C -!HISTORY_MSG_680;Local - Retinex mask L -!HISTORY_MSG_681;Local - Retinex mask CL -!HISTORY_MSG_682;Local - Retinex mask -!HISTORY_MSG_683;Local - Retinex mask Blend -!HISTORY_MSG_684;Local - Retinex mask radius -!HISTORY_MSG_685;Local - Retinex mask chroma -!HISTORY_MSG_686;Local - Retinex mask gamma -!HISTORY_MSG_687;Local - Retinex mask slope -!HISTORY_MSG_688;Local - Tool removed -!HISTORY_MSG_689;Local - Retinex mask transmission map -!HISTORY_MSG_690;Local - Retinex scale -!HISTORY_MSG_691;Local - Retinex darkness -!HISTORY_MSG_692;Local - Retinex lightness -!HISTORY_MSG_693;Local - Retinex threshold -!HISTORY_MSG_694;Local - Retinex Laplacian threshold -!HISTORY_MSG_695;Local - Soft method -!HISTORY_MSG_696;Local - Retinex Normalize -!HISTORY_MSG_697;Local - TM Normalize -!HISTORY_MSG_698;Local - Local contrast Fast Fourier -!HISTORY_MSG_699;Local - Retinex Fast Fourier -!HISTORY_MSG_701;Local - Exp Shadows -!HISTORY_MSG_702;Local - Exp Method -!HISTORY_MSG_703;Local - Exp Laplacian threshold -!HISTORY_MSG_704;Local - Exp PDE balance -!HISTORY_MSG_705;Local - Exp linearity -!HISTORY_MSG_706;Local - TM mask C -!HISTORY_MSG_707;Local - TM mask L -!HISTORY_MSG_708;Local - TM mask CL -!HISTORY_MSG_709;Local - use TM mask -!HISTORY_MSG_710;Local - TM mask Blend -!HISTORY_MSG_711;Local - TM mask radius -!HISTORY_MSG_712;Local - TM mask chroma -!HISTORY_MSG_713;Local - TM mask gamma -!HISTORY_MSG_714;Local - TM mask slope -!HISTORY_MSG_716;Local - Local method -!HISTORY_MSG_717;Local - Local contrast -!HISTORY_MSG_718;Local - Local contrast levels -!HISTORY_MSG_719;Local - Local contrast residual L -!HISTORY_MSG_720;Local - Blur mask C -!HISTORY_MSG_721;Local - Blur mask L -!HISTORY_MSG_722;Local - Blur mask CL -!HISTORY_MSG_723;Local - use Blur mask -!HISTORY_MSG_725;Local - Blur mask Blend -!HISTORY_MSG_726;Local - Blur mask radius -!HISTORY_MSG_727;Local - Blur mask chroma -!HISTORY_MSG_728;Local - Blur mask gamma -!HISTORY_MSG_729;Local - Blur mask slope -!HISTORY_MSG_730;Local - Blur method -!HISTORY_MSG_731;Local - median method -!HISTORY_MSG_732;Local - median iterations -!HISTORY_MSG_733;Local - soft radius -!HISTORY_MSG_734;Local - detail -!HISTORY_MSG_738;Local - Local contrast Merge L -!HISTORY_MSG_739;Local - Local contrast Soft radius -!HISTORY_MSG_740;Local - Local contrast Merge C -!HISTORY_MSG_741;Local - Local contrast Residual C -!HISTORY_MSG_742;Local - Exp Laplacian gamma -!HISTORY_MSG_743;Local - Exp Fattal Amount -!HISTORY_MSG_744;Local - Exp Fattal Detail -!HISTORY_MSG_745;Local - Exp Fattal Offset -!HISTORY_MSG_746;Local - Exp Fattal Sigma -!HISTORY_MSG_747;Local Spot created -!HISTORY_MSG_748;Local - Exp Denoise -!HISTORY_MSG_749;Local - Reti Depth -!HISTORY_MSG_750;Local - Reti Mode log - lin -!HISTORY_MSG_751;Local - Reti Dehaze saturation -!HISTORY_MSG_752;Local - Reti Offset -!HISTORY_MSG_753;Local - Reti Transmission map -!HISTORY_MSG_754;Local - Reti Clip -!HISTORY_MSG_755;Local - TM use tm mask -!HISTORY_MSG_756;Local - Exp use algo exposure mask -!HISTORY_MSG_757;Local - Exp Laplacian mask -!HISTORY_MSG_758;Local - Reti Laplacian mask -!HISTORY_MSG_759;Local - Exp Laplacian mask -!HISTORY_MSG_760;Local - Color Laplacian mask -!HISTORY_MSG_761;Local - SH Laplacian mask -!HISTORY_MSG_762;Local - cbdl Laplacian mask -!HISTORY_MSG_763;Local - Blur Laplacian mask -!HISTORY_MSG_764;Local - Solve PDE Laplacian mask -!HISTORY_MSG_765;Local - Denoise Detail threshold -!HISTORY_MSG_766;Local - Blur Fast Fourier -!HISTORY_MSG_767;Local - Grain Iso -!HISTORY_MSG_768;Local - Grain Strength -!HISTORY_MSG_769;Local - Grain Scale -!HISTORY_MSG_770;Local - Color Mask contrast curve -!HISTORY_MSG_771;Local - Exp Mask contrast curve -!HISTORY_MSG_772;Local - SH Mask contrast curve -!HISTORY_MSG_773;Local - TM Mask contrast curve -!HISTORY_MSG_774;Local - Reti Mask contrast curve -!HISTORY_MSG_775;Local - CBDL Mask contrast curve -!HISTORY_MSG_776;Local - Blur Denoise Mask contrast curve -!HISTORY_MSG_777;Local - Blur Mask local contrast curve -!HISTORY_MSG_778;Local - Mask highlights -!HISTORY_MSG_779;Local - Color Mask local contrast curve -!HISTORY_MSG_780;Local - Color Mask shadows -!HISTORY_MSG_781;Local - Contrast Mask Wavelet level -!HISTORY_MSG_782;Local - Blur Denoise Mask Wavelet levels -!HISTORY_MSG_783;Local - Color Wavelet levels -!HISTORY_MSG_784;Local - Mask - ΔE Image Mask -!HISTORY_MSG_785;Local - Mask - Scope -!HISTORY_MSG_786;Local - SH method -!HISTORY_MSG_787;Local - Equalizer multiplier -!HISTORY_MSG_788;Local - Equalizer detail -!HISTORY_MSG_789;Local - SH mask amount -!HISTORY_MSG_790;Local - SH mask anchor -!HISTORY_MSG_791;Local - Mask Short L curves -!HISTORY_MSG_792;Local - Mask - Background -!HISTORY_MSG_793;Local - SH TRC gamma -!HISTORY_MSG_794;Local - SH TRC slope -!HISTORY_MSG_795;Local - Mask save restore image -!HISTORY_MSG_796;Local - SC - Recursive references -!HISTORY_MSG_797;Local - Merge Original method -!HISTORY_MSG_798;Local - Opacity -!HISTORY_MSG_799;Local - Color RGB ToneCurve -!HISTORY_MSG_800;Local - Color ToneCurve Method -!HISTORY_MSG_801;Local - Color ToneCurve Special -!HISTORY_MSG_802;Local - Contrast threshold -!HISTORY_MSG_803;Local - Color Merge -!HISTORY_MSG_804;Local - Color mask Structure -!HISTORY_MSG_805;Local - Blur Noise mask Structure -!HISTORY_MSG_806;Local - Color mask Structure as tool -!HISTORY_MSG_807;Local - Blur Noise mask Structure as tool -!HISTORY_MSG_808;Local - Color mask curve H(H) -!HISTORY_MSG_809;Local - Vib mask curve C(C) -!HISTORY_MSG_810;Local - Vib mask curve L(L) -!HISTORY_MSG_811;Local - Vib mask curve LC(H) -!HISTORY_MSG_813;Local - Use Vib mask -!HISTORY_MSG_814;Local - Vib mask Blend -!HISTORY_MSG_815;Local - Vib mask radius -!HISTORY_MSG_816;Local - Vib mask chroma -!HISTORY_MSG_817;Local - Vib mask gamma -!HISTORY_MSG_818;Local - Vib mask slope -!HISTORY_MSG_819;Local - Vib mask laplacian -!HISTORY_MSG_820;Local - Vib mask contrast curve -!HISTORY_MSG_821;Local - color grid background -!HISTORY_MSG_822;Local - color background merge -!HISTORY_MSG_823;Local - color background luminance -!HISTORY_MSG_824;Local - Exp gradient mask strength -!HISTORY_MSG_825;Local - Exp gradient mask angle -!HISTORY_MSG_826;Local - Exp gradient strength -!HISTORY_MSG_827;Local - Exp gradient angle -!HISTORY_MSG_828;Local - SH gradient strength -!HISTORY_MSG_829;Local - SH gradient angle -!HISTORY_MSG_830;Local - Color gradient strength L -!HISTORY_MSG_831;Local - Color gradient angle -!HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient -!HISTORY_MSG_834;Local - Color gradient strength H -!HISTORY_MSG_835;Local - Vib gradient strength L -!HISTORY_MSG_836;Local - Vib gradient angle -!HISTORY_MSG_837;Local - Vib gradient strength C -!HISTORY_MSG_838;Local - Vib gradient strength H -!HISTORY_MSG_839;Local - Software complexity -!HISTORY_MSG_840;Local - CL Curve -!HISTORY_MSG_841;Local - LC curve -!HISTORY_MSG_842;Local - Blur mask Radius -!HISTORY_MSG_843;Local - Blur mask Contrast Threshold -!HISTORY_MSG_844;Local - Blur mask FFTW -!HISTORY_MSG_845;Local - Log encoding -!HISTORY_MSG_846;Local - Log encoding auto -!HISTORY_MSG_847;Local - Log encoding Source -!HISTORY_MSG_849;Local - Log encoding Source auto -!HISTORY_MSG_850;Local - Log encoding B_Ev -!HISTORY_MSG_851;Local - Log encoding W_Ev -!HISTORY_MSG_852;Local - Log encoding Target -!HISTORY_MSG_853;Local - Log encodind loc contrast -!HISTORY_MSG_854;Local - Log encodind Scope -!HISTORY_MSG_855;Local - Log encoding Whole image -!HISTORY_MSG_856;Local - Log encoding Shadows range -!HISTORY_MSG_857;Local - Wavelet blur residual -!HISTORY_MSG_858;Local - Wavelet blur luminance only -!HISTORY_MSG_859;Local - Wavelet max blur -!HISTORY_MSG_860;Local - Wavelet blur levels -!HISTORY_MSG_861;Local - Wavelet contrast levels -!HISTORY_MSG_862;Local - Wavelet contrast attenuation -!HISTORY_MSG_863;Local - Wavelet merge original image -!HISTORY_MSG_864;Local - Wavelet dir contrast attenuation -!HISTORY_MSG_865;Local - Wavelet dir contrast delta -!HISTORY_MSG_866;Local - Wavelet dir compression -!HISTORY_MSG_868;Local - SD - C-H balance -!HISTORY_MSG_869;Local - Denoise by level -!HISTORY_MSG_870;Local - Wavelet mask curve H -!HISTORY_MSG_871;Local - Wavelet mask curve C -!HISTORY_MSG_872;Local - Wavelet mask curve L -!HISTORY_MSG_873;Local - Wavelet mask -!HISTORY_MSG_875;Local - Wavelet mask blend -!HISTORY_MSG_876;Local - Wavelet mask smooth -!HISTORY_MSG_877;Local - Wavelet mask chroma -!HISTORY_MSG_878;Local - Wavelet mask contrast curve -!HISTORY_MSG_879;Local - Wavelet contrast chroma -!HISTORY_MSG_880;Local - Wavelet blur chroma -!HISTORY_MSG_881;Local - Wavelet contrast offset -!HISTORY_MSG_882;Local - Wavelet blur -!HISTORY_MSG_883;Local - Wavelet contrast by level -!HISTORY_MSG_884;Local - Wavelet dir contrast -!HISTORY_MSG_885;Local - Wavelet tone mapping -!HISTORY_MSG_886;Local - Wavelet tone mapping compress -!HISTORY_MSG_887;Local - Wavelet tone mapping compress residual -!HISTORY_MSG_888;Local - Contrast Wavelet Balance Threshold -!HISTORY_MSG_889;Local - Contrast Wavelet Graduated Strength -!HISTORY_MSG_890;Local - Contrast Wavelet Graduated angle -!HISTORY_MSG_891;Local - Contrast Wavelet Graduated -!HISTORY_MSG_892;Local - Log Encoding Graduated Strength -!HISTORY_MSG_893;Local - Log Encoding Graduated angle -!HISTORY_MSG_894;Local - SD - ΔE preview color intensity -!HISTORY_MSG_897;Local - Contrast Wavelet ES strength -!HISTORY_MSG_898;Local - Contrast Wavelet ES radius -!HISTORY_MSG_899;Local - Contrast Wavelet ES detail -!HISTORY_MSG_900;Local - Contrast Wavelet ES gradient -!HISTORY_MSG_901;Local - Contrast Wavelet ES threshold low -!HISTORY_MSG_902;Local - Contrast Wavelet ES threshold high -!HISTORY_MSG_903;Local - Contrast Wavelet ES local contrast -!HISTORY_MSG_904;Local - Contrast Wavelet ES first level -!HISTORY_MSG_905;Local - Contrast Wavelet Edge Sharpness -!HISTORY_MSG_906;Local - Contrast Wavelet ES sensitivity -!HISTORY_MSG_907;Local - Contrast Wavelet ES amplification -!HISTORY_MSG_908;Local - Contrast Wavelet ES neighboring -!HISTORY_MSG_909;Local - Contrast Wavelet ES show -!HISTORY_MSG_910;Local - SC - Wavelet Edge performance -!HISTORY_MSG_911;Local - Blur Chroma Luma -!HISTORY_MSG_912;Local - Blur Guide filter strength -!HISTORY_MSG_913;Local - Contrast Wavelet Sigma DR -!HISTORY_MSG_914;Local - Blur Wavelet Sigma BL -!HISTORY_MSG_915;Local - Edge Wavelet Sigma ED -!HISTORY_MSG_916;Local - Residual wavelet shadows -!HISTORY_MSG_917;Local - Residual wavelet shadows threshold -!HISTORY_MSG_918;Local - Residual wavelet highlights -!HISTORY_MSG_919;Local - Residual wavelet highlights threshold -!HISTORY_MSG_920;Local - Wavelet sigma LC -!HISTORY_MSG_921;Local - Wavelet Graduated sigma LC2 -!HISTORY_MSG_922;Local - SC - Changes in B/W -!HISTORY_MSG_923;Local - Tool complexity mode -!HISTORY_MSG_924;--unused-- -!HISTORY_MSG_925;Local - Scope (color tools) -!HISTORY_MSG_926;Local - Show mask type -!HISTORY_MSG_927;Local - Shadow -!HISTORY_MSG_928;Local - Common color mask -!HISTORY_MSG_929;Local - Mask common scope -!HISTORY_MSG_930;Local - Mask Common blend luma -!HISTORY_MSG_931;Local - Mask Common enable -!HISTORY_MSG_932;Local - Mask Common radius soft -!HISTORY_MSG_933;Local - Mask Common laplacian -!HISTORY_MSG_934;Local - Mask Common chroma -!HISTORY_MSG_935;Local - Mask Common gamma -!HISTORY_MSG_936;Local - Mask Common slope -!HISTORY_MSG_937;Local - Mask Common curve C(C) -!HISTORY_MSG_938;Local - Mask Common curve L(L) -!HISTORY_MSG_939;Local - Mask Common curve LC(H) -!HISTORY_MSG_940;Local - Mask Common structure as tool -!HISTORY_MSG_941;Local - Mask Common structure strength -!HISTORY_MSG_942;Local - Mask Common H(H) curve -!HISTORY_MSG_943;Local - Mask Common FFT -!HISTORY_MSG_944;Local - Mask Common Blur radius -!HISTORY_MSG_945;Local - Mask Common contrast threshold -!HISTORY_MSG_946;Local - Mask Common shadows -!HISTORY_MSG_947;Local - Mask Common Contrast curve -!HISTORY_MSG_948;Local - Mask Common Wavelet curve -!HISTORY_MSG_949;Local - Mask Common Threshold levels -!HISTORY_MSG_950;Local - Mask Common GF strength -!HISTORY_MSG_951;Local - Mask Common GF angle -!HISTORY_MSG_952;Local - Mask Common soft radius -!HISTORY_MSG_953;Local - Mask Common blend chroma -!HISTORY_MSG_954;Local - Show-hide tools -!HISTORY_MSG_955;Local - Enable Spot -!HISTORY_MSG_956;Local - CH Curve -!HISTORY_MSG_957;Local - Denoise mode -!HISTORY_MSG_958;Local - Show/hide settings -!HISTORY_MSG_959;Local - Inverse blur -!HISTORY_MSG_960;Local - Log encoding - cat16 -!HISTORY_MSG_961;Local - Log encoding Ciecam -!HISTORY_MSG_962;Local - Log encoding Absolute luminance source -!HISTORY_MSG_963;Local - Log encoding Absolute luminance target -!HISTORY_MSG_964;Local - Log encoding Surround -!HISTORY_MSG_965;Local - Log encoding Saturation s -!HISTORY_MSG_966;Local - Log encoding Contrast J -!HISTORY_MSG_967;Local - Log encoding Mask curve C -!HISTORY_MSG_968;Local - Log encoding Mask curve L -!HISTORY_MSG_969;Local - Log encoding Mask curve H -!HISTORY_MSG_970;Local - Log encoding Mask enable -!HISTORY_MSG_971;Local - Log encoding Mask blend -!HISTORY_MSG_972;Local - Log encoding Mask radius -!HISTORY_MSG_973;Local - Log encoding Mask chroma -!HISTORY_MSG_974;Local - Log encoding Mask contrast -!HISTORY_MSG_975;Local - Log encoding Lightness J -!HISTORY_MSG_977;Local - Log encoding Contrast Q -!HISTORY_MSG_978;Local - Log encoding Sursource -!HISTORY_MSG_979;Local - Log encoding Brightness Q -!HISTORY_MSG_980;Local - Log encoding Colorfulness M -!HISTORY_MSG_981;Local - Log encoding Strength -!HISTORY_MSG_982;Local - Equalizer hue -!HISTORY_MSG_983;Local - denoise threshold mask high -!HISTORY_MSG_984;Local - denoise threshold mask low -!HISTORY_MSG_985;Local - denoise Laplacian -!HISTORY_MSG_986;Local - denoise reinforce -!HISTORY_MSG_987;Local - GF recovery threshold -!HISTORY_MSG_988;Local - GF threshold mask low -!HISTORY_MSG_989;Local - GF threshold mask high -!HISTORY_MSG_990;Local - Denoise recovery threshold -!HISTORY_MSG_991;Local - Denoise threshold mask low -!HISTORY_MSG_992;Local - Denoise threshold mask high -!HISTORY_MSG_993;Local - Denoise Inverse algo -!HISTORY_MSG_994;Local - GF Inverse algo -!HISTORY_MSG_995;Local - Denoise decay -!HISTORY_MSG_996;Local - Color recovery threshold -!HISTORY_MSG_997;Local - Color threshold mask low -!HISTORY_MSG_998;Local - Color threshold mask high -!HISTORY_MSG_999;Local - Color decay -!HISTORY_MSG_1000;Local - Denoise luminance gray -!HISTORY_MSG_1001;Local - Log recovery threshold -!HISTORY_MSG_1002;Local - Log threshold mask low -!HISTORY_MSG_1003;Local - Log threshold mask high -!HISTORY_MSG_1004;Local - Log decay -!HISTORY_MSG_1005;Local - Exp recovery threshold -!HISTORY_MSG_1006;Local - Exp threshold mask low -!HISTORY_MSG_1007;Local - Exp threshold mask high -!HISTORY_MSG_1008;Local - Exp decay -!HISTORY_MSG_1009;Local - SH recovery threshold -!HISTORY_MSG_1010;Local - SH threshold mask low -!HISTORY_MSG_1011;Local - SH threshold mask high -!HISTORY_MSG_1012;Local - SH decay -!HISTORY_MSG_1013;Local - vib recovery threshold -!HISTORY_MSG_1014;Local - vib threshold mask low -!HISTORY_MSG_1015;Local - vib threshold mask high -!HISTORY_MSG_1016;Local - vib decay -!HISTORY_MSG_1017;Local - lc recovery threshold -!HISTORY_MSG_1018;Local - lc threshold mask low -!HISTORY_MSG_1019;Local - lc threshold mask high -!HISTORY_MSG_1020;Local - lc decay -!HISTORY_MSG_1021;Local - Denoise chrominance gray -!HISTORY_MSG_1022;Local - TM recovery threshold -!HISTORY_MSG_1023;Local - TM threshold mask low -!HISTORY_MSG_1024;Local - TM threshold mask high -!HISTORY_MSG_1025;Local - TM decay -!HISTORY_MSG_1026;Local - cbdl recovery threshold -!HISTORY_MSG_1027;Local - cbdl threshold mask low -!HISTORY_MSG_1028;Local - cbdl threshold mask high -!HISTORY_MSG_1029;Local - cbdl decay -!HISTORY_MSG_1030;Local - reti recovery threshold -!HISTORY_MSG_1031;Local - reti threshold mask low -!HISTORY_MSG_1032;Local - reti threshold mask high -!HISTORY_MSG_1033;Local - reti decay -!HISTORY_MSG_1034;Local - Nlmeans - strength -!HISTORY_MSG_1035;Local - Nlmeans - detail -!HISTORY_MSG_1036;Local - Nlmeans - patch -!HISTORY_MSG_1037;Local - Nlmeans - radius -!HISTORY_MSG_1038;Local - Nlmeans - gamma -!HISTORY_MSG_1039;Local - Grain - gamma -!HISTORY_MSG_1040;Local - SC - Soft radius -!HISTORY_MSG_1041;Local - Spot - Munsell -!HISTORY_MSG_1042;Local - Log encoding - threshold -!HISTORY_MSG_1043;Local - Exp - normalize -!HISTORY_MSG_1044;Local - Local contrast strength -!HISTORY_MSG_1045;Local - Color and Light strength -!HISTORY_MSG_1046;Local - Denoise strength -!HISTORY_MSG_1047;Local - SH and Tone Equalizer strength -!HISTORY_MSG_1048;Local - DR and Exposure strength -!HISTORY_MSG_1049;Local - TM strength -!HISTORY_MSG_1050;Local - Log encoding chroma -!HISTORY_MSG_1051;Local - Residual wavelet gamma -!HISTORY_MSG_1052;Local - Residual wavelet slope -!HISTORY_MSG_1053;Local - Denoise gamma -!HISTORY_MSG_1054;Local - Wavelet gamma -!HISTORY_MSG_1055;Local - Color and Light gamma -!HISTORY_MSG_1056;Local - DR and Exposure gamma -!HISTORY_MSG_1057;Local - CIECAM Enabled -!HISTORY_MSG_1058;Local - CIECAM Overall strength -!HISTORY_MSG_1059;Local - CIECAM Autogray -!HISTORY_MSG_1060;Local - CIECAM Mean luminance source -!HISTORY_MSG_1061;Local - CIECAM Source absolute -!HISTORY_MSG_1062;Local - CIECAM Surround Source -!HISTORY_MSG_1063;Local - CIECAM Saturation -!HISTORY_MSG_1064;Local - CIECAM Chroma -!HISTORY_MSG_1065;Local - CIECAM lightness J -!HISTORY_MSG_1066;Local - CIECAM brightness -!HISTORY_MSG_1067;Local - CIECAM Contrast J -!HISTORY_MSG_1068;Local - CIECAM threshold -!HISTORY_MSG_1069;Local - CIECAM contrast Q -!HISTORY_MSG_1070;Local - CIECAM colorfullness -!HISTORY_MSG_1071;Local - CIECAM Absolute luminance -!HISTORY_MSG_1072;Local - CIECAM Mean luminance -!HISTORY_MSG_1073;Local - CIECAM Cat16 -!HISTORY_MSG_1074;Local - CIECAM Local contrast -!HISTORY_MSG_1075;Local - CIECAM Surround viewing -!HISTORY_MSG_1076;Local - CIECAM Scope -!HISTORY_MSG_1077;Local - CIECAM Mode -!HISTORY_MSG_1078;Local - Red and skin protection -!HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J -!HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold -!HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv -!HISTORY_MSG_1083;Local - CIECAM Hue -!HISTORY_MSG_1084;Local - Uses Black Ev - White Ev -!HISTORY_MSG_1085;Local - Jz lightness -!HISTORY_MSG_1086;Local - Jz contrast -!HISTORY_MSG_1087;Local - Jz chroma -!HISTORY_MSG_1088;Local - Jz hue -!HISTORY_MSG_1089;Local - Jz Sigmoid strength -!HISTORY_MSG_1090;Local - Jz Sigmoid threshold -!HISTORY_MSG_1091;Local - Jz Sigmoid blend -!HISTORY_MSG_1092;Local - Jz adaptation -!HISTORY_MSG_1093;Local - CAM model -!HISTORY_MSG_1094;Local - Jz highligths -!HISTORY_MSG_1095;Local - Jz highligths thr -!HISTORY_MSG_1096;Local - Jz shadows -!HISTORY_MSG_1097;Local - Jz shadows thr -!HISTORY_MSG_1098;Local - Jz radius SH -!HISTORY_MSG_1099;Local - Cz(Hz) Curve -!HISTORY_MSG_1100;Local - Jz reference 100 -!HISTORY_MSG_1101;Local - Jz PQ remap -!HISTORY_MSG_1102;Local - Jz(Hz) Curve -!HISTORY_MSG_1103;Local - Vibrance gamma -!HISTORY_MSG_1104;Local - Sharp gamma -!HISTORY_MSG_1105;Local - CIECAM Tone method -!HISTORY_MSG_1106;Local - CIECAM Tone curve -!HISTORY_MSG_1107;Local - CIECAM Color method -!HISTORY_MSG_1108;Local - CIECAM Color curve -!HISTORY_MSG_1109;Local - Jz(Jz) curve -!HISTORY_MSG_1110;Local - Cz(Cz) curve -!HISTORY_MSG_1111;Local - Cz(Jz) curve -!HISTORY_MSG_1112;Local - forcejz -!HISTORY_MSG_1113;Local - HDR PQ -!HISTORY_MSG_1114;Local - Cie mask enable -!HISTORY_MSG_1115;Local - Cie mask curve C -!HISTORY_MSG_1116;Local - Cie mask curve L -!HISTORY_MSG_1117;Local - Cie mask curve H -!HISTORY_MSG_1118;Local - Cie mask blend -!HISTORY_MSG_1119;Local - Cie mask radius -!HISTORY_MSG_1120;Local - Cie mask chroma -!HISTORY_MSG_1121;Local - Cie mask contrast curve -!HISTORY_MSG_1122;Local - Cie mask recovery threshold -!HISTORY_MSG_1123;Local - Cie mask recovery dark -!HISTORY_MSG_1124;Local - Cie mask recovery light -!HISTORY_MSG_1125;Local - Cie mask recovery decay -!HISTORY_MSG_1126;Local - Cie mask laplacian -!HISTORY_MSG_1127;Local - Cie mask gamma -!HISTORY_MSG_1128;Local - Cie mask slope -!HISTORY_MSG_1129;Local - Cie Relative luminance -!HISTORY_MSG_1130;Local - Cie Saturation Jz -!HISTORY_MSG_1131;Local - Mask - Denoise -!HISTORY_MSG_1132;Local - Cie Wav sigma Jz -!HISTORY_MSG_1133;Local - Cie Wav level Jz -!HISTORY_MSG_1134;Local - Cie Wav local contrast Jz -!HISTORY_MSG_1135;Local - Cie Wav clarity Jz -!HISTORY_MSG_1136;Local - Cie Wav clarity Cz -!HISTORY_MSG_1137;Local - Cie Wav clarity Soft -!HISTORY_MSG_1138;Local - Local - Hz(Hz) Curve -!HISTORY_MSG_1139;Local - Jz soft Curves H -!HISTORY_MSG_1140;Local - Jz Threshold chroma -!HISTORY_MSG_1141;Local - chroma curve Jz(Hz) -!HISTORY_MSG_1142;Local - strength soft -!HISTORY_MSG_1143;Local - Jz blackev -!HISTORY_MSG_1144;Local - Jz whiteev -!HISTORY_MSG_1145;Local - Jz Log encoding -!HISTORY_MSG_1146;Local - Jz Log encoding target gray -!HISTORY_MSG_1147;Local - Jz BlackEv WhiteEv -!HISTORY_MSG_1148;Local - Jz Sigmoid -!HISTORY_MSG_1149;Local - Q Sigmoid -!HISTORY_MSG_1150;Local - Log encoding Q instead Sigmoid Q -!HISTORY_MSG_BLSHAPE;Blur by level -!HISTORY_MSG_BLURCWAV;Blur chroma -!HISTORY_MSG_BLURWAV;Blur luminance -!HISTORY_MSG_BLUWAV;Attenuation response -!HISTORY_MSG_CATCAT;CAL - Settings - Mode -!HISTORY_MSG_CATCOMPLEX;CAL - Settings - Complexity -!HISTORY_MSG_CATMODEL;CAL - Settings - CAM -!HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors -!HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction -!HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction -!HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Channel -!HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - region C mask -!HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H mask -!HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Lightness -!HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L mask -!HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - List -!HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - region mask blur -!HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - region offset -!HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - region power -!HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Saturation -!HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - region show mask -!HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - region slope -!HISTORY_MSG_COMPLEX;Wavelet complexity -!HISTORY_MSG_COMPLEXRETI;Retinex complexity -!HISTORY_MSG_DEHAZE_DEPTH;Dehaze - Depth -!HISTORY_MSG_DEHAZE_ENABLED;Haze Removal -!HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation -!HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map -!HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength -!HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness -!HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold -!HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold -!HISTORY_MSG_EDGEFFECT;Edge Attenuation response -!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata -!HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Reference output -!HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Film negative color space -!HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative -!HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Reference input -!HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values -!HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell -!HISTORY_MSG_HISTMATCHING;Auto-matched tone curve -!HISTORY_MSG_HLBL;Color propagation - blur -!HISTORY_MSG_HLTH;Inpaint opposed - gain threshold -!HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy -!HISTORY_MSG_ICM_AINTENT;Abstract profile intent -!HISTORY_MSG_ICM_BLUX;Primaries Blue X -!HISTORY_MSG_ICM_BLUY;Primaries Blue Y -!HISTORY_MSG_ICM_FBW;Black and White -!HISTORY_MSG_ICM_GAMUT;Gamut control -!HISTORY_MSG_ICM_GREX;Primaries Green X -!HISTORY_MSG_ICM_GREY;Primaries Green Y -!HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries -!HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D -!HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type -!HISTORY_MSG_ICM_PRESER;Preserve neutral -!HISTORY_MSG_ICM_REDX;Primaries Red X -!HISTORY_MSG_ICM_REDY;Primaries Red Y -!HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma -!HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method -!HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method -!HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope -!HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method -!HISTORY_MSG_ILLUM;CAL - SC - Illuminant -!HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount -!HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness -!HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast -!HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness -!HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius -!HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -!HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift -!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!HISTORY_MSG_METADATA_MODE;Metadata copy mode -!HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold -!HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold -!HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius -!HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations -!HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrast threshold -!HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterations -!HISTORY_MSG_PDSHARPEN_RADIUS;CS - Radius -!HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost -!HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera -!HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera -!HISTORY_MSG_PERSP_CAM_SHIFT;Perspective - Camera -!HISTORY_MSG_PERSP_CTRL_LINE;Perspective - Control lines -!HISTORY_MSG_PERSP_METHOD;Perspective - Method -!HISTORY_MSG_PERSP_PROJ_ANGLE;Perspective - Recovery -!HISTORY_MSG_PERSP_PROJ_ROTATE;Perspective - PCA rotation -!HISTORY_MSG_PERSP_PROJ_SHIFT;Perspective - PCA -!HISTORY_MSG_PIXELSHIFT_AVERAGE;PS - Average -!HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demosaic method for motion -!HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Line noise filter direction -!HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -!HISTORY_MSG_PREPROCWB_MODE;Preprocess WB Mode -!HISTORY_MSG_PROTAB;Protection -!HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrast threshold -!HISTORY_MSG_RANGEAB;Range ab -!HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations -!HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift -!HISTORY_MSG_RAW_BORDER;Raw border -!HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling -!HISTORY_MSG_RESIZE_LONGEDGE;Resize - Long Edge -!HISTORY_MSG_RESIZE_SHORTEDGE;Resize - Short Edge -!HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius -!HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold -!HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace -!HISTORY_MSG_SIGMACOL;Chroma Attenuation response -!HISTORY_MSG_SIGMADIR;Dir Attenuation response -!HISTORY_MSG_SIGMAFIN;Final contrast Attenuation response -!HISTORY_MSG_SIGMATON;Toning Attenuation response -!HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light -!HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength -!HISTORY_MSG_SPOT;Spot removal -!HISTORY_MSG_SPOT_ENTRY;Spot removal - Point modif. -!HISTORY_MSG_TEMPOUT;CAM02 automatic temperature -!HISTORY_MSG_THRESWAV;Balance threshold -!HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor -!HISTORY_MSG_TONE_EQUALIZER_BANDS;Tone equalizer - Bands -!HISTORY_MSG_TONE_EQUALIZER_ENABLED;Tone equalizer -!HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot -!HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization -!HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map -!HISTORY_MSG_TRANS_METHOD;Geometry - Method -!HISTORY_MSG_WAVBALCHROM;Equalizer chrominance -!HISTORY_MSG_WAVBALLUM;Equalizer luminance -!HISTORY_MSG_WAVBL;Blur levels -!HISTORY_MSG_WAVCHR;Blur levels - blur chroma -!HISTORY_MSG_WAVCHROMCO;Chroma coarse -!HISTORY_MSG_WAVCHROMFI;Chroma fine -!HISTORY_MSG_WAVCLARI;Clarity -!HISTORY_MSG_WAVDENLH;Level 5 -!HISTORY_MSG_WAVDENOISE;Local contrast -!HISTORY_MSG_WAVDENOISEH;High levels Local contrast -!HISTORY_MSG_WAVDETEND;Details soft -!HISTORY_MSG_WAVEDGS;Edge stopping -!HISTORY_MSG_WAVGUIDH;Local contrast-Hue equalizer -!HISTORY_MSG_WAVHUE;Equalizer hue -!HISTORY_MSG_WAVLABGRID_VALUE;Toning - exclude colors -!HISTORY_MSG_WAVLEVDEN;High level local contrast -!HISTORY_MSG_WAVLEVELSIGM;Denoise - radius -!HISTORY_MSG_WAVLEVSIGM;Radius -!HISTORY_MSG_WAVLIMDEN;Interaction 56 14 -!HISTORY_MSG_WAVLOWTHR;Threshold low contrast -!HISTORY_MSG_WAVMERGEC;Merge C -!HISTORY_MSG_WAVMERGEL;Merge L -!HISTORY_MSG_WAVMIXMET;Reference local contrast -!HISTORY_MSG_WAVOFFSET;Offset -!HISTORY_MSG_WAVOLDSH;Old algorithm -!HISTORY_MSG_WAVQUAMET;Denoise mode -!HISTORY_MSG_WAVRADIUS;Radius shadows-highlights -!HISTORY_MSG_WAVSCALE;Scale -!HISTORY_MSG_WAVSHOWMASK;Show wavelet mask -!HISTORY_MSG_WAVSIGM;Sigma -!HISTORY_MSG_WAVSIGMA;Attenuation response -!HISTORY_MSG_WAVSLIMET;Method -!HISTORY_MSG_WAVSOFTRAD;Soft radius clarity -!HISTORY_MSG_WAVSOFTRADEND;Soft radius final -!HISTORY_MSG_WAVSTREND;Strength soft -!HISTORY_MSG_WAVTHRDEN;Threshold local contrast -!HISTORY_MSG_WAVTHREND;Threshold local contrast -!HISTORY_MSG_WAVUSHAMET;Clarity method -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° -!HISTORY_MSG_WBITC_CUSTOM;Itcwb Custom -!HISTORY_MSG_WBITC_DELTA;Itcwb Delta green -!HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student -!HISTORY_MSG_WBITC_FORCE;Itcwb Force -!HISTORY_MSG_WBITC_GREEN;Green refinement -!HISTORY_MSG_WBITC_MINSIZE;Patch min size -!HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple -!HISTORY_MSG_WBITC_OBS;Remove algo 2 passes -!HISTORY_MSG_WBITC_PONDER;Itcwb ponderated -!HISTORY_MSG_WBITC_PRECIS;Itcwb Precision -!HISTORY_MSG_WBITC_PRIM;Primaries -!HISTORY_MSG_WBITC_RGREEN;Itcwb Green range -!HISTORY_MSG_WBITC_SAMPLING;Low sampling -!HISTORY_MSG_WBITC_SIZE;Itcwb Size -!HISTORY_MSG_WBITC_SORTED;Itcwb ponderated -!HISTORY_MSG_WBITC_THRES;Itcwb Threshold -!ICCPROFCREATOR_COPYRIGHT;Copyright: -!ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Reset to the default copyright, granted to 'RawTherapee, CC0'. -!ICCPROFCREATOR_CUSTOM;Custom -!ICCPROFCREATOR_DESCRIPTION;Description: -!ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Append gamma and slope values to the description -!ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Leave empty to set the default description. -!ICCPROFCREATOR_GAMMA;Gamma -!ICCPROFCREATOR_ICCVERSION;ICC version: -!ICCPROFCREATOR_ILL;Illuminant: -!ICCPROFCREATOR_ILL_41;D41 -!ICCPROFCREATOR_ILL_50;D50 -!ICCPROFCREATOR_ILL_55;D55 -!ICCPROFCREATOR_ILL_60;D60 -!ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater -!ICCPROFCREATOR_ILL_65;D65 -!ICCPROFCREATOR_ILL_80;D80 -!ICCPROFCREATOR_ILL_DEF;Default -!ICCPROFCREATOR_ILL_INC;StdA 2856K -!ICCPROFCREATOR_ILL_TOOLTIP;You can set the illuminant for ICC v4 profiles and also for ICC v2 profiles. -!ICCPROFCREATOR_PRIMARIES;Primaries: -!ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 -!ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 -!ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) -!ICCPROFCREATOR_PRIM_BEST;BestRGB -!ICCPROFCREATOR_PRIM_BETA;BetaRGB -!ICCPROFCREATOR_PRIM_BLUX;Blue X -!ICCPROFCREATOR_PRIM_BLUY;Blue Y -!ICCPROFCREATOR_PRIM_BRUCE;BruceRGB -!ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 -!ICCPROFCREATOR_PRIM_GREX;Green X -!ICCPROFCREATOR_PRIM_GREY;Green Y -!ICCPROFCREATOR_PRIM_PROPH;Prophoto -!ICCPROFCREATOR_PRIM_REC2020;Rec2020 -!ICCPROFCREATOR_PRIM_REDX;Red X -!ICCPROFCREATOR_PRIM_REDY;Red Y -!ICCPROFCREATOR_PRIM_SRGB;sRGB -!ICCPROFCREATOR_PRIM_TOOLTIP;You can set custom primaries for ICC v4 profiles and also for ICC v2 profiles. -!ICCPROFCREATOR_PRIM_WIDEG;Widegamut -!ICCPROFCREATOR_PROF_V2;ICC v2 -!ICCPROFCREATOR_PROF_V4;ICC v4 -!ICCPROFCREATOR_SAVEDIALOG_TITLE;Save ICC profile as... -!ICCPROFCREATOR_SLOPE;Slope -!ICCPROFCREATOR_TRC_PRESET;Tone response curve -!INSPECTOR_WINDOW_TITLE;Inspector -!IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. -!IPTCPANEL_CITYHINT;Enter the name of the city pictured in this image. -!IPTCPANEL_COPYRIGHT;Copyright notice -!IPTCPANEL_COPYRIGHTHINT;Enter a Notice on the current owner of the Copyright for this image, such as ©2008 Jane Doe. -!IPTCPANEL_COUNTRYHINT;Enter the name of the country pictured in this image. -!IPTCPANEL_CREATOR;Creator -!IPTCPANEL_CREATORHINT;Enter the name of the person that created this image. -!IPTCPANEL_CREATORJOBTITLE;Creator's job title -!IPTCPANEL_CREATORJOBTITLEHINT;Enter the Job Title of the person listed in the Creator field. -!IPTCPANEL_DATECREATEDHINT;Enter the Date the image was taken. -!IPTCPANEL_DESCRIPTION;Description -!IPTCPANEL_DESCRIPTIONHINT;Enter a 'caption' describing the who, what, and why of what is happening in this image, this might include names of people, and/or their role in the action that is taking place within the image. -!IPTCPANEL_DESCRIPTIONWRITER;Description writer -!IPTCPANEL_DESCRIPTIONWRITERHINT;Enter the name of the person involved in writing, editing or correcting the description of the image. -!IPTCPANEL_HEADLINEHINT;Enter a brief publishable synopsis or summary of the contents of the image. -!IPTCPANEL_INSTRUCTIONSHINT;Enter information about embargoes, or other restrictions not covered by the Copyright field. -!IPTCPANEL_KEYWORDSHINT;Enter any number of keywords, terms or phrases used to express the subject matter in the image. -!IPTCPANEL_PROVINCE;Province or state -!IPTCPANEL_PROVINCEHINT;Enter the name of the province or state pictured in this image. -!IPTCPANEL_SOURCEHINT;Enter or edit the name of a person or party who has a role in the content supply chain, such as a person or entity from whom you received this image from. -!IPTCPANEL_SUPPCATEGORIES;Supplemental categories -!IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image. -!IPTCPANEL_TITLEHINT;Enter a short verbal and human readable name for the image, this may be the file name. -!IPTCPANEL_TRANSREFERENCE;Job ID -!IPTCPANEL_TRANSREFERENCEHINT;Enter a number or identifier needed for workflow control or tracking. -!MAIN_BUTTON_ICCPROFCREATOR;ICC Profile Creator -!MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor -!MAIN_FRAME_PLACES_DEL;Remove -!MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. -!MAIN_TAB_ADVANCED;Advanced -!MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a -!MAIN_TAB_FAVORITES;Favorites -!MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u -!MAIN_TAB_INSPECT; Inspect -!MAIN_TAB_LOCALLAB;Local -!MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o -!MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. -!MONITOR_PROFILE_SYSTEM;System default -!OPTIONS_BUNDLED_MISSING;The bundled profile '%1' could not be found!\n\nYour installation could be damaged.\n\nDefault internal values will be used instead. -!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\n'%1' will be used instead. -!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\n'%1' will be used instead. -!PARTIALPASTE_ADVANCEDGROUP;Advanced Settings -!PARTIALPASTE_COLORTONING;Color toning -!PARTIALPASTE_DEHAZE;Haze removal -!PARTIALPASTE_EQUALIZER;Wavelet levels -!PARTIALPASTE_FILMNEGATIVE;Film negative -!PARTIALPASTE_FILMSIMULATION;Film simulation -!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings -!PARTIALPASTE_METADATA;Metadata mode -!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter -!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter -!PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -!PARTIALPASTE_PREPROCWB;Preprocess White Balance -!PARTIALPASTE_PRSHARPENING;Post-resize sharpening -!PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA avoid color shift -!PARTIALPASTE_RAWCACORR_CAREDBLUE;CA red & blue -!PARTIALPASTE_RAW_BORDER;Raw border -!PARTIALPASTE_RAW_IMAGENUM;Sub-image -!PARTIALPASTE_RAW_PIXELSHIFT;Pixel Shift -!PARTIALPASTE_RETINEX;Retinex -!PARTIALPASTE_SOFTLIGHT;Soft light -!PARTIALPASTE_SPOT;Spot removal -!PARTIALPASTE_TM_FATTAL;Dynamic range compression -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_APPEARANCE;Appearance -!PREFERENCES_APPEARANCE_COLORPICKERFONT;Color picker font -!PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color -!PREFERENCES_APPEARANCE_MAINFONT;Main font -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode -!PREFERENCES_APPEARANCE_THEME;Theme -!PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit -!PREFERENCES_CACHECLEAR;Clear -!PREFERENCES_CACHECLEAR_ALL;Clear all cached files: -!PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: -!PREFERENCES_CACHECLEAR_ONLYPROFILES;Clear only cached processing profiles: -!PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory -!PREFERENCES_CHUNKSIZES;Tiles per thread -!PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic -!PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA correction -!PREFERENCES_CHUNKSIZE_RAW_RCD;RCD demosaic -!PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic -!PREFERENCES_CHUNKSIZE_RGB;RGB processing -!PREFERENCES_CIE;Ciecam -!PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_CLUTSCACHE;HaldCLUT Cache -!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs -!PREFERENCES_CLUTSDIR;HaldCLUT directory -!PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments -!PREFERENCES_COMPLEXITY_EXP;Advanced -!PREFERENCES_COMPLEXITY_NORM;Standard -!PREFERENCES_COMPLEXITY_SIMP;Basic -!PREFERENCES_CROP;Crop Editing -!PREFERENCES_CROP_AUTO_FIT;Automatically zoom to fit the crop -!PREFERENCES_CROP_GUIDES;Guides shown when not editing the crop -!PREFERENCES_CROP_GUIDES_FRAME;Frame -!PREFERENCES_CROP_GUIDES_FULL;Original -!PREFERENCES_CROP_GUIDES_NONE;None -!PREFERENCES_CURVEBBOXPOS;Position of curve copy & paste buttons -!PREFERENCES_CURVEBBOXPOS_ABOVE;Above -!PREFERENCES_CURVEBBOXPOS_BELOW;Below -!PREFERENCES_CURVEBBOXPOS_LEFT;Left -!PREFERENCES_CURVEBBOXPOS_RIGHT;Right -!PREFERENCES_DIRECTORIES;Directories -!PREFERENCES_EDITORCMDLINE;Custom command line -!PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Bypass output profile -!PREFERENCES_EXTEDITOR_DIR;Output directory -!PREFERENCES_EXTEDITOR_DIR_CURRENT;Same as input image -!PREFERENCES_EXTEDITOR_DIR_CUSTOM;Custom -!PREFERENCES_EXTEDITOR_DIR_TEMP;OS temp dir -!PREFERENCES_EXTEDITOR_FLOAT32;32-bit float TIFF output -!PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application -!PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable -!PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command -!PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name -!PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Native command -!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compact toolbars in File Browser -!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Filmstrip and the File Browser -!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Having separate thumbnail size will require more processing time each time you'll switch between the single Editor tab and the File Browser. -!PREFERENCES_INSPECTORWINDOW;Open inspector in own window or fullscreen -!PREFERENCES_INSPECT_LABEL;Inspect -!PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum number of cached images -!PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Set the maximum number of images stored in cache when hovering over them in the File Browser; systems with little RAM (2GB) should keep this value set to 1 or 2. -!PREFERENCES_LANG;Language -!PREFERENCES_LENSFUNDBDIR;Lensfun database directory -!PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. -!PREFERENCES_LENSPROFILESDIR;Lens profiles directory -!PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) -!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders -!PREFERENCES_METADATA;Metadata -!PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars -!PREFERENCES_METADATA_SYNC_NONE;Off -!PREFERENCES_METADATA_SYNC_READ;Read only -!PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_MONINTENT;Default rendering intent -!PREFERENCES_MONITOR;Monitor -!PREFERENCES_MONPROFILE;Default color profile -!PREFERENCES_MONPROFILE_WARNOSX;Due to MacOS limitations, only sRGB is supported. -!PREFERENCES_NAVIGATIONFRAME;Navigation -!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel -!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. -!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. -!PREFERENCES_PERFORMANCE_MEASURE;Measure -!PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console -!PREFERENCES_PERFORMANCE_THREADS;Threads -!PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximum number of threads for Noise Reduction and Wavelet Levels (0 = Automatic) -!PREFERENCES_PREVDEMO;Preview Demosaic Method -!PREFERENCES_PREVDEMO_FAST;Fast -!PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: -!PREFERENCES_PREVDEMO_SIDECAR;As in PP3 -!PREFERENCES_PRINTER;Printer (Soft-Proofing) -!PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file -!PREFERENCES_PROFILESAVELOCATION;Processing profile saving location -!PREFERENCES_PROFILE_NONE;None -!PREFERENCES_PRTINTENT;Rendering intent -!PREFERENCES_PRTPROFILE;Color profile -!PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset -!PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. -!PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now -!PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings -!PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files -!PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. -!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips -!PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules -!PREFERENCES_TAB_FAVORITES;Favorites -!PREFERENCES_TAB_PERFORMANCE;Performance -!PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Embedded JPEG preview -!PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show -!PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering -!PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise -!PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. -!PREFERENCES_TOOLPANEL_FAVORITE;Favorite -!PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel -!PREFERENCES_TOOLPANEL_TOOL;Tool -!PREFERENCES_WBA;White Balance -!PREFERENCES_WBACORR;White Balance - Automatic temperature correlation -!PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -!PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings -!PREFERENCES_WBAENACUSTOM;Use Custom temperature & tint -!PREFERENCES_WBAFORC;Forces Extra algoritm -!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) -!PREFERENCES_WBANOPURP;No purple color used -!PREFERENCES_WBAPATCH;Number maximum of colors used in picture -!PREFERENCES_WBAPRECIS;Precision algorithm - scale used -!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color -!PREFERENCES_WBASORT;Sort in chroma order instead of histogram -!PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style -!PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) -!PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) -!PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling -!PROFILEPANEL_PDYNAMIC;Dynamic -!PROGRESSBAR_DECODING;Decoding... -!PROGRESSBAR_GREENEQUIL;Green equilibration... -!PROGRESSBAR_HLREC;Highlight reconstruction... -!PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... -!PROGRESSBAR_LINEDENOISE;Line noise filter... -!PROGRESSBAR_RAWCACORR;Raw CA correction... -!QINFO_FRAMECOUNT;%2 frames -!QINFO_HDR;HDR / %2 frame(s) -!QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) -!QUEUE_LOCATION_TITLE;Output Location -!QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s -!SAMPLEFORMAT_0;Unknown data format -!SAMPLEFORMAT_1;8-bit unsigned -!SAMPLEFORMAT_2;16-bit unsigned -!SAMPLEFORMAT_4;24-bit LogLuv -!SAMPLEFORMAT_8;32-bit LogLuv -!SAMPLEFORMAT_16;16-bit floating-point -!SAMPLEFORMAT_32;24-bit floating-point -!SAMPLEFORMAT_64;32-bit floating-point -!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) -!SAVEDLG_FILEFORMAT_FLOAT; floating-point -!SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. -!SOFTPROOF_GAMUTCHECK_TOOLTIP;Highlight pixels with out-of-gamut colors with respect to:\n- the printer profile, if one is set and soft-proofing is enabled,\n- the output profile, if a printer profile is not set and soft-proofing is enabled,\n- the monitor profile, if soft-proofing is disabled. -!SOFTPROOF_TOOLTIP;Soft-proofing simulates the appearance of the image:\n- when printed, if a printer profile is set in Preferences > Color Management,\n- when viewed on a display that uses the current output profile, if a printer profile is not set. -!SORT_ASCENDING;Ascending -!SORT_BY_DATE;By Date -!SORT_BY_EXIF;By EXIF -!SORT_BY_LABEL;By Color Label -!SORT_BY_NAME;By Name -!SORT_BY_RANK;By Rank -!SORT_DESCENDING;Descending -!TC_PRIM_BLUX;Bx -!TC_PRIM_BLUY;By -!TC_PRIM_GREX;Gx -!TC_PRIM_GREY;Gy -!TC_PRIM_REDX;Rx -!TC_PRIM_REDY;Ry -!TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. -!TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. -!TP_BWMIX_MIXC;Channel Mixer -!TP_BWMIX_NEUTRAL;Reset -!TP_CBDL_AFT;After Black-and-White -!TP_CBDL_BEF;Before Black-and-White -!TP_CBDL_METHOD;Process located -!TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. -!TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminance -!TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. -!TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;When setting manually, values above 65 are recommended. -!TP_COLORAPP_CATCLASSIC;Classic -!TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. -!TP_COLORAPP_CATMOD;Mode -!TP_COLORAPP_CATSYMGEN;Automatic Symmetric -!TP_COLORAPP_CATSYMSPE;Mixed -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing -!TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). -!TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D50) into new values whose white point is that of the new illuminant - see WP model (for example D75). -!TP_COLORAPP_FREE;Free temp + tint + CAT02/16 +[output] -!TP_COLORAPP_GEN;Settings -!TP_COLORAPP_GEN_TOOLTIP;This module is based on the CIECAM color appearance models, which were designed to better simulate how human vision perceives colors under different lighting conditions, e.g. against different backgrounds. It takes into account the environment of each color and modifies its appearance to get as close as possible to human perception. It also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic appearance is preserved across the scene and display environments. -!TP_COLORAPP_IL41;D41 -!TP_COLORAPP_IL50;D50 -!TP_COLORAPP_IL55;D55 -!TP_COLORAPP_IL60;D60 -!TP_COLORAPP_IL65;D65 -!TP_COLORAPP_IL75;D75 -!TP_COLORAPP_ILA;Incandescent StdA 2856K -!TP_COLORAPP_ILFREE;Free -!TP_COLORAPP_ILLUM;Illuminant -!TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and latitude. -!TP_COLORAPP_MEANLUMINANCE;Mean luminance (Yb%) -!TP_COLORAPP_MOD02;CAM02 -!TP_COLORAPP_MOD16;CAM16 -!TP_COLORAPP_MODELCAT;CAM -!TP_COLORAPP_MODELCAT_TOOLTIP;Allows you to choose between CAM02 or CAM16.\nCAM02 will sometimes be more accurate.\nCAM16 should generate fewer artifacts. -!TP_COLORAPP_NEUTRAL;Reset -!TP_COLORAPP_NEUTRAL_TOOLTIP;Reset all sliders checkbox and curves to their default values. -!TP_COLORAPP_SOURCEF_TOOLTIP;Corresponds to the shooting conditions and how to bring the conditions and data back to a 'normal' area. Normal means average or standard conditions and data, i.e. without taking into account CIECAM corrections. -!TP_COLORAPP_SURROUNDSRC;Surround -!TP_COLORAPP_SURSOURCE_TOOLTIP;Changes tones and colors to take into account the surround conditions of the scene lighting. The darker the surround conditions, the brighter the image will become. Image brightness will not be changed when the surround is set to average. -!TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 -!TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. -!TP_COLORAPP_TEMP_TOOLTIP;To select an illuminant, always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 -!TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. -!TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_COLORTONING_AB;o C/L -!TP_COLORTONING_AUTOSAT;Automatic -!TP_COLORTONING_BALANCE;Balance -!TP_COLORTONING_BY;o C/L -!TP_COLORTONING_CHROMAC;Opacity -!TP_COLORTONING_COLOR;Color: -!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L). -!TP_COLORTONING_HIGHLIGHT;Highlights -!TP_COLORTONING_HUE;Hue -!TP_COLORTONING_LAB;L*a*b* blending -!TP_COLORTONING_LABEL;Color Toning -!TP_COLORTONING_LABGRID;L*a*b* color correction grid -!TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 -!TP_COLORTONING_LABREGIONS;Color correction regions -!TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 -!TP_COLORTONING_LABREGION_CHANNEL;Channel -!TP_COLORTONING_LABREGION_CHANNEL_ALL;All -!TP_COLORTONING_LABREGION_CHANNEL_B;Blue -!TP_COLORTONING_LABREGION_CHANNEL_G;Green -!TP_COLORTONING_LABREGION_CHANNEL_R;Red -!TP_COLORTONING_LABREGION_CHROMATICITYMASK;C -!TP_COLORTONING_LABREGION_HUEMASK;H -!TP_COLORTONING_LABREGION_LIGHTNESS;Lightness -!TP_COLORTONING_LABREGION_LIGHTNESSMASK;L -!TP_COLORTONING_LABREGION_LIST_TITLE;Correction -!TP_COLORTONING_LABREGION_MASK;Mask -!TP_COLORTONING_LABREGION_MASKBLUR;Mask Blur -!TP_COLORTONING_LABREGION_OFFSET;Offset -!TP_COLORTONING_LABREGION_POWER;Power -!TP_COLORTONING_LABREGION_SATURATION;Saturation -!TP_COLORTONING_LABREGION_SHOWMASK;Show mask -!TP_COLORTONING_LABREGION_SLOPE;Slope -!TP_COLORTONING_LUMA;Luminance -!TP_COLORTONING_LUMAMODE;Preserve luminance -!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. -!TP_COLORTONING_METHOD;Method -!TP_COLORTONING_METHOD_TOOLTIP;'L*a*b* blending', 'RGB sliders' and 'RGB curves' use interpolated color blending.\n'Color balance (Shadows/Midtones/Highlights)' and 'Saturation 2 colors' use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. -!TP_COLORTONING_MIDTONES;Midtones -!TP_COLORTONING_NEUTRAL;Reset sliders -!TP_COLORTONING_NEUTRAL_TOOLTIP;Reset all values (Shadows, Midtones, Highlights) to default. -!TP_COLORTONING_OPACITY;Opacity: -!TP_COLORTONING_RGBCURVES;RGB - Curves -!TP_COLORTONING_RGBSLIDERS;RGB - Sliders -!TP_COLORTONING_SA;Saturation Protection -!TP_COLORTONING_SATURATEDOPACITY;Strength -!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold -!TP_COLORTONING_SHADOWS;Shadows -!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights -!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights -!TP_COLORTONING_SPLITLR;Saturation 2 colors -!TP_COLORTONING_STR;Strength -!TP_COLORTONING_STRENGTH;Strength -!TP_COLORTONING_TWO2;Special chroma '2 colors' -!TP_COLORTONING_TWOALL;Special chroma -!TP_COLORTONING_TWOBY;Special a* and b* -!TP_COLORTONING_TWOCOLOR_TOOLTIP;Standard chroma:\nLinear response, a* = b*.\n\nSpecial chroma:\nLinear response, a* = b*, but unbound - try under the diagonal.\n\nSpecial a* and b*:\nLinear response unbound with separate curves for a* and b*. Intended for special effects.\n\nSpecial chroma 2 colors:\nMore predictable. -!TP_COLORTONING_TWOSTD;Standard chroma -!TP_CROP_GTCENTEREDSQUARE;Centered square -!TP_CROP_GTHARMMEANS;Harmonic Means -!TP_CROP_GTTRIANGLE1;Golden Triangles 1 -!TP_CROP_GTTRIANGLE2;Golden Triangles 2 -!TP_CROP_PPI;PPI -!TP_CROP_RESETCROP;Reset -!TP_CROP_SELECTCROP;Select -!TP_DEHAZE_DEPTH;Depth -!TP_DEHAZE_LABEL;Haze Removal -!TP_DEHAZE_SATURATION;Saturation -!TP_DEHAZE_SHOW_DEPTH_MAP;Show depth map -!TP_DEHAZE_STRENGTH;Strength -!TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zones -!TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatic global -!TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Chrominance curve -!TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. -!TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominance -!TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Manual -!TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Method -!TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. -!TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the 'Preview' method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. -!TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Preview multi-zones -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Preview -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Preview size=%1, Center: Px=%2 Py=%3 -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Preview noise: Mean=%1 High=%2 -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Preview noise: Mean= - High= - -!TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Tile size=%1, Center: Tx=%2 Ty=%3 -!TP_DIRPYRDENOISE_LABEL;Noise Reduction -!TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Luminance control -!TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminance curve -!TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminance -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images. -!TP_DIRPYRDENOISE_MAIN_MODE;Mode -!TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Aggressive -!TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Conservative -!TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;Conservative preserves low frequency chroma patterns, while aggressive obliterates them. -!TP_DIRPYRDENOISE_MEDIAN_METHOD;Median method -!TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Chroma only -!TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* -!TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Median Filter -!TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Luminance only -!TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB -!TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;When using the 'Luminance only' and 'L*a*b*' methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the 'RGB' mode, it will be performed at the very end of the noise reduction pipeline. -!TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Weighted L* (little) + a*b* (normal) -!TP_DIRPYRDENOISE_MEDIAN_PASSES;Median iterations -!TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Applying three median filter iterations with a 3×3 window size often leads to better results than using one median filter iteration with a 7×7 window size. -!TP_DIRPYRDENOISE_MEDIAN_TYPE;Median type -!TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Apply a median filter of the desired window size. The larger the window's size, the longer it takes.\n\n3×3 soft: treats 5 pixels in a 3×3 pixel window.\n3×3: treats 9 pixels in a 3×3 pixel window.\n5×5 soft: treats 13 pixels in a 5×5 pixel window.\n5×5: treats 25 pixels in a 5×5 pixel window.\n7×7: treats 49 pixels in a 7×7 pixel window.\n9×9: treats 81 pixels in a 9×9 pixel window.\n\nSometimes it is possible to achieve higher quality running several iterations with a smaller window size than one iteration with a larger one. -!TP_DIRPYRDENOISE_TYPE_3X3;3×3 -!TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 soft -!TP_DIRPYRDENOISE_TYPE_5X5;5×5 -!TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 soft -!TP_DIRPYRDENOISE_TYPE_7X7;7×7 -!TP_DIRPYRDENOISE_TYPE_9X9;9×9 -!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts -!TP_DISTORTION_AUTO_TOOLTIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. -!TP_EPD_GAMMA;Gamma -!TP_EXPOSURE_CLAMPOOG;Clip out-of-gamut colors -!TP_EXPOSURE_HISTMATCHING;Auto-Matched Tone Curve -!TP_EXPOSURE_HISTMATCHING_TOOLTIP;Automatically adjust sliders and curves (except exposure compensation) to match the look of the embedded JPEG thumbnail. -!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance -!TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptual -!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points -!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points -!TP_FILMNEGATIVE_BLUE;Blue ratio -!TP_FILMNEGATIVE_BLUEBALANCE;Cool/Warm -!TP_FILMNEGATIVE_COLORSPACE;Inversion color space: -!TP_FILMNEGATIVE_COLORSPACE_INPUT;Input color space -!TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Select the color space used to perform the negative inversion:\nInput color space : perform inversion before the input profile is applied, as in the previous versions of RT.\nWorking color space : perform inversion after input profile, using the currently selected working profile. -!TP_FILMNEGATIVE_COLORSPACE_WORKING;Working color space -!TP_FILMNEGATIVE_GREEN;Reference exponent -!TP_FILMNEGATIVE_GREENBALANCE;Magenta/Green -!TP_FILMNEGATIVE_GUESS_TOOLTIP;Automatically set the red and blue ratios by picking two patches which had a neutral hue (no color) in the original scene. The patches should differ in brightness. -!TP_FILMNEGATIVE_LABEL;Film Negative -!TP_FILMNEGATIVE_OUT_LEVEL;Output level -!TP_FILMNEGATIVE_PICK;Pick neutral spots -!TP_FILMNEGATIVE_PICK_SIZE;Size: -!TP_FILMNEGATIVE_RED;Red ratio -!TP_FILMNEGATIVE_REF_LABEL;Input RGB: %1 -!TP_FILMNEGATIVE_REF_PICK;Pick white balance spot -!TP_FILMNEGATIVE_REF_SIZE;Size: -!TP_FILMNEGATIVE_REF_TOOLTIP;Pick a gray patch for white-balancing the output, positive image. -!TP_FILMSIMULATION_LABEL;Film Simulation -!TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee is configured to look for Hald CLUT images, which are used for the Film Simulation tool, in a folder which is taking too long to load.\nGo to Preferences > Image Processing > Film Simulation\nto see which folder is being used. You should either point RawTherapee to a folder which contains only Hald CLUT images and nothing more, or to an empty folder if you don't want to use the Film Simulation tool.\n\nRead the Film Simulation article in RawPedia for more information.\n\nDo you want to cancel the scan now? -!TP_FILMSIMULATION_STRENGTH;Strength -!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences -!TP_FLATFIELD_CLIPCONTROL;Clip control -!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, value 0 is used. -!TP_FLATFIELD_FROMMETADATA;From Metadata -!TP_HLREC_COLOROPP;Inpaint Opposed -!TP_HLREC_HLBLUR;Blur -!TP_HLREC_HLTH;Gain threshold -!TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Baseline exposure -!TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. -!TP_ICM_APPLYHUESATMAP;Base table -!TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only available if the selected DCP has one. -!TP_ICM_APPLYLOOKTABLE;Look table -!TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. -!TP_ICM_BPC;Black Point Compensation -!TP_ICM_FBW;Black-and-White -!TP_ICM_GAMUT;Gamut control -!TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. -!TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 -!TP_ICM_NEUTRAL;Reset -!TP_ICM_OUTPUTPROFILE_TOOLTIP;By default all RTv4 or RTv2 profiles are with TRC - sRGB: g=2.4 s=12.92\n\nWith 'ICC Profile Creator' you can generate v4 or v2 profiles with the following choices;\n-Primaries: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Custom\n-TRC: BT709, sRGB, linear, standard g=2.2, standard g=1.8, Custom\n-Illuminant: D41, D50, D55, D60, D65, D80, stdA 2856K -!TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 -!TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 -!TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different color mode for an image, you permanently change the color values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic color adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). -!TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 -!TP_ICM_PROFILEINTENT;Rendering Intent -!TP_ICM_REDFRAME;Custom Primaries -!TP_ICM_SAVEREFERENCE;Save Reference Image -!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance -!TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. -!TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. -!TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. -!TP_ICM_WORKING_CIEDIAG;CIE xy diagram -!TP_ICM_WORKING_ILLU;Illuminant -!TP_ICM_WORKING_ILLU_1500;Tungsten 1500K -!TP_ICM_WORKING_ILLU_2000;Tungsten 2000K -!TP_ICM_WORKING_ILLU_D41;D41 -!TP_ICM_WORKING_ILLU_D50;D50 -!TP_ICM_WORKING_ILLU_D55;D55 -!TP_ICM_WORKING_ILLU_D60;D60 -!TP_ICM_WORKING_ILLU_D65;D65 -!TP_ICM_WORKING_ILLU_D80;D80 -!TP_ICM_WORKING_ILLU_D120;D120 -!TP_ICM_WORKING_ILLU_NONE;Default -!TP_ICM_WORKING_ILLU_STDA;stdA 2875K -!TP_ICM_WORKING_PRESER;Preserves Pastel tones -!TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. -!TP_ICM_WORKING_PRIM_AC0;ACESp0 -!TP_ICM_WORKING_PRIM_ACE;ACESp1 -!TP_ICM_WORKING_PRIM_ADOB;Adobe RGB -!TP_ICM_WORKING_PRIM_BET;Beta RGB -!TP_ICM_WORKING_PRIM_BRU;BruceRGB -!TP_ICM_WORKING_PRIM_BST;BestRGB -!TP_ICM_WORKING_PRIM_CUS;Custom (sliders) -!TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) -!TP_ICM_WORKING_PRIM_JDCMAX;JDC Max -!TP_ICM_WORKING_PRIM_NONE;Default -!TP_ICM_WORKING_PRIM_PROP;ProPhoto -!TP_ICM_WORKING_PRIM_REC;Rec2020 -!TP_ICM_WORKING_PRIM_SRGB;sRGB -!TP_ICM_WORKING_PRIM_WID;WideGamut -!TP_ICM_WORKING_TRC;Tone response curve: -!TP_ICM_WORKING_TRC_18;Prophoto g=1.8 -!TP_ICM_WORKING_TRC_22;Adobe g=2.2 -!TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 -!TP_ICM_WORKING_TRC_CUSTOM;Custom -!TP_ICM_WORKING_TRC_GAMMA;Gamma -!TP_ICM_WORKING_TRC_LIN;Linear g=1 -!TP_ICM_WORKING_TRC_NONE;None -!TP_ICM_WORKING_TRC_SLOPE;Slope -!TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 -!TP_ICM_WORKING_TRC_TOOLTIP;Only for built-in profiles. -!TP_LENSGEOM_LIN;Linear -!TP_LENSGEOM_LOG;Logarithmic -!TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected -!TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file -!TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected -!TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. -!TP_LENSPROFILE_MODE_HEADER;Lens Profile -!TP_LENSPROFILE_USE_CA;Chromatic aberration -!TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion -!TP_LENSPROFILE_USE_HEADER;Correct -!TP_LENSPROFILE_USE_VIGNETTING;Vignetting -!TP_LOCALCONTRAST_AMOUNT;Amount -!TP_LOCALCONTRAST_DARKNESS;Darkness level -!TP_LOCALCONTRAST_LABEL;Local Contrast -!TP_LOCALCONTRAST_LIGHTNESS;Lightness level -!TP_LOCALCONTRAST_RADIUS;Radius -!TP_LOCALLAB_ACTIV;Luminance only -!TP_LOCALLAB_ACTIVSPOT;Enable Spot -!TP_LOCALLAB_ADJ;Equalizer Color -!TP_LOCALLAB_AMOUNT;Amount -!TP_LOCALLAB_ARTIF;Shape detection -!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. -!TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto -!TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. -!TP_LOCALLAB_AVOIDMUN;Munsell correction only -!TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. -!TP_LOCALLAB_AVOIDRAD;Soft radius -!TP_LOCALLAB_BALAN;ab-L balance (ΔE) -!TP_LOCALLAB_BALANEXP;Laplacian balance -!TP_LOCALLAB_BALANH;C-H balance (ΔE) -!TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. -!TP_LOCALLAB_BASELOG;Shadows range (logarithm base) -!TP_LOCALLAB_BILATERAL;Bilateral filter -!TP_LOCALLAB_BLACK_EV;Black Ev -!TP_LOCALLAB_BLCO;Chrominance only -!TP_LOCALLAB_BLENDMASKCOL;Blend -!TP_LOCALLAB_BLENDMASKMASK;Add/subtract luma mask -!TP_LOCALLAB_BLENDMASKMASKAB;Add/subtract chroma mask -!TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;If this slider = 0 no action.\nAdd or subtract the mask from the original image. -!TP_LOCALLAB_BLENDMASK_TOOLTIP;If blend = 0 only shape detection is improved.\nIf blend > 0 the mask is added to the image. If blend < 0 the mask is subtracted from the image. -!TP_LOCALLAB_BLGUID;Guided Filter -!TP_LOCALLAB_BLINV;Inverse -!TP_LOCALLAB_BLLC;Luminance & Chrominance -!TP_LOCALLAB_BLLO;Luminance only -!TP_LOCALLAB_BLMED;Median -!TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal: direct blur and noise with all settings.\nInverse: blur and noise with all settings. Warning, some settings may give curious results. -!TP_LOCALLAB_BLNOI_EXP;Blur & Noise -!TP_LOCALLAB_BLNORM;Normal -!TP_LOCALLAB_BLUFR;Blur/Grain & Denoise -!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for scope and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the scope.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. -!TP_LOCALLAB_BLUR;Gaussian Blur - Noise - Grain -!TP_LOCALLAB_BLURCOL;Radius -!TP_LOCALLAB_BLURCOLDE_TOOLTIP;The image used to calculate dE is blurred slightly to avoid taking isolated pixels into account. -!TP_LOCALLAB_BLURDE;Blur shape detection -!TP_LOCALLAB_BLURLC;Luminance only -!TP_LOCALLAB_BLURLEVELFRA;Blur levels -!TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. -!TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). -!TP_LOCALLAB_BLUR_TOOLNAME;Blur/Grain & Denoise -!TP_LOCALLAB_BLWH;All changes forced in Black-and-White -!TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. -!TP_LOCALLAB_BUTTON_ADD;Add -!TP_LOCALLAB_BUTTON_DEL;Delete -!TP_LOCALLAB_BUTTON_DUPL;Duplicate -!TP_LOCALLAB_BUTTON_REN;Rename -!TP_LOCALLAB_BUTTON_VIS;Show/Hide -!TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev -!TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. -!TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments -!TP_LOCALLAB_CAMMODE;CAM model -!TP_LOCALLAB_CAMMODE_CAM16;CAM 16 -!TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz -!TP_LOCALLAB_CATAD;Chromatic adaptation/Cat16 -!TP_LOCALLAB_CBDL;Contrast by Detail Levels -!TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. -!TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. -!TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. -!TP_LOCALLAB_CBDL_TOOLNAME;Contrast by Detail Levels -!TP_LOCALLAB_CENTER_X;Center X -!TP_LOCALLAB_CENTER_Y;Center Y -!TP_LOCALLAB_CH;CL - LC -!TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_CHROMA;Chrominance -!TP_LOCALLAB_CHROMABLU;Chroma levels -!TP_LOCALLAB_CHROMABLU_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMACBDL;Chroma -!TP_LOCALLAB_CHROMACB_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMALEV;Chroma levels -!TP_LOCALLAB_CHROMASKCOL;Chroma -!TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). -!TP_LOCALLAB_CHROML;Chroma (C) -!TP_LOCALLAB_CHRRT;Chroma -!TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) -!TP_LOCALLAB_CIEC;Use Ciecam environment parameters -!TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. -!TP_LOCALLAB_CIECOLORFRA;Color -!TP_LOCALLAB_CIECONTFRA;Contrast -!TP_LOCALLAB_CIELIGHTCONTFRA;Lighting & Contrast -!TP_LOCALLAB_CIELIGHTFRA;Lighting -!TP_LOCALLAB_CIEMODE;Change tool position -!TP_LOCALLAB_CIEMODE_COM;Default -!TP_LOCALLAB_CIEMODE_DR;Dynamic Range -!TP_LOCALLAB_CIEMODE_TM;Tone-Mapping -!TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. -!TP_LOCALLAB_CIEMODE_WAV;Wavelet -!TP_LOCALLAB_CIETOOLEXP;Curves -!TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) -!TP_LOCALLAB_CIRCRADIUS;Spot size -!TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. -!TP_LOCALLAB_CLARICRES;Merge chroma -!TP_LOCALLAB_CLARIFRA;Clarity & Sharp mask/Blend & Soften Images -!TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. -!TP_LOCALLAB_CLARILRES;Merge luma -!TP_LOCALLAB_CLARISOFT;Soft radius -!TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. -!TP_LOCALLAB_CLARISOFT_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and all wavelet pyramid processes. To deactivate, set slider to zero. -!TP_LOCALLAB_CLARITYML;Clarity -!TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. -!TP_LOCALLAB_CLIPTM;Clip restored data (gain) -!TP_LOCALLAB_COFR;Color & Light -!TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. -!TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. -!TP_LOCALLAB_COLORSCOPE;Scope (color tools) -!TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. -!TP_LOCALLAB_COLOR_CIE;Color curve -!TP_LOCALLAB_COLOR_TOOLNAME;Color & Light -!TP_LOCALLAB_COL_NAME;Name -!TP_LOCALLAB_COL_VIS;Status -!TP_LOCALLAB_COMPFRA;Directional contrast -!TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping -!TP_LOCALLAB_CONTCOL;Contrast threshold -!TP_LOCALLAB_CONTFRA;Contrast by level -!TP_LOCALLAB_CONTRAST;Contrast -!TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. -!TP_LOCALLAB_CONTRESID;Contrast -!TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. -!TP_LOCALLAB_CONTTHR;Contrast Threshold -!TP_LOCALLAB_CONTWFRA;Local contrast -!TP_LOCALLAB_CSTHRESHOLD;Wavelet levels -!TP_LOCALLAB_CSTHRESHOLDBLUR;Wavelet level selection -!TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance 'Super' -!TP_LOCALLAB_CURVCURR;Normal -!TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. -!TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve -!TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. -!TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. -!TP_LOCALLAB_CURVES_CIE;Tone curve -!TP_LOCALLAB_CURVNONE;Disable curves -!TP_LOCALLAB_DARKRETI;Darkness -!TP_LOCALLAB_DEHAFRA;Dehaze -!TP_LOCALLAB_DEHAZ;Strength -!TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. -!TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. -!TP_LOCALLAB_DELTAD;Delta balance -!TP_LOCALLAB_DELTAEC;ΔE Image mask -!TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask -!TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. -!TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. -!TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. -!TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Allows you to direct the chroma noise reduction towards either the blue-yellow or red-green colors. -!TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Allows you to carry out more or less noise reduction in either the shadows or the highlights. -!TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOIMASK;Denoise chroma mask -!TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. -!TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. -!TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. -!TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance -!TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance -!TP_LOCALLAB_DENOI_EXP;Denoise -!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. -!TP_LOCALLAB_DEPTH;Depth -!TP_LOCALLAB_DETAIL;Local contrast -!TP_LOCALLAB_DETAILFRA;Edge detection - DCT -!TP_LOCALLAB_DETAILSH;Details -!TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold -!TP_LOCALLAB_DIVGR;Gamma -!TP_LOCALLAB_DUPLSPOTNAME;Copy -!TP_LOCALLAB_EDGFRA;Edge sharpness -!TP_LOCALLAB_EDGSHOW;Show all tools -!TP_LOCALLAB_ELI;Ellipse -!TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping -!TP_LOCALLAB_ENABLE_MASK;Enable mask -!TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure -!TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. -!TP_LOCALLAB_ENH;Enhanced -!TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise -!TP_LOCALLAB_EPSBL;Detail -!TP_LOCALLAB_EQUIL;Normalize luminance -!TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. -!TP_LOCALLAB_ESTOP;Edge stopping -!TP_LOCALLAB_EV_DUPL;Copy of -!TP_LOCALLAB_EV_NVIS;Hide -!TP_LOCALLAB_EV_NVIS_ALL;Hide all -!TP_LOCALLAB_EV_VIS;Show -!TP_LOCALLAB_EV_VIS_ALL;Show all -!TP_LOCALLAB_EXCLUF;Excluding -!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. -!TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. -!TP_LOCALLAB_EXECLU;Excluding spot -!TP_LOCALLAB_EXFULL;Full image -!TP_LOCALLAB_EXNORM;Normal spot -!TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). -!TP_LOCALLAB_EXPCHROMA;Chroma compensation -!TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. -!TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. -!TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ -!TP_LOCALLAB_EXPCOMPINV;Exposure compensation -!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. -!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. -!TP_LOCALLAB_EXPCURV;Curves -!TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. -!TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. -!TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. -!TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. -!TP_LOCALLAB_EXPLAP_TOOLTIP;Moving the slider to the right progressively reduces the contrast. -!TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a color and luminance background (fewer possibilties). -!TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applies a median filter before the Laplace transform to prevent artifacts (noise).\nYou can also use the 'Denoise' tool. -!TP_LOCALLAB_EXPOSE;Dynamic Range & Exposure -!TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. -!TP_LOCALLAB_EXPRETITOOLS;Advanced Retinex Tools -!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'Scope' values to simulate smaller spots. -!TP_LOCALLAB_EXPTOOL;Exposure Tools -!TP_LOCALLAB_EXP_TOOLNAME;Dynamic Range & Exposure -!TP_LOCALLAB_FATAMOUNT;Amount -!TP_LOCALLAB_FATANCHOR;Anchor -!TP_LOCALLAB_FATDETAIL;Detail -!TP_LOCALLAB_FATFRA;Dynamic Range Compression Æ’ -!TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. -!TP_LOCALLAB_FATLEVEL;Sigma -!TP_LOCALLAB_FATSAT;Saturation control -!TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ -!TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) -!TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ -!TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). -!TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform -!TP_LOCALLAB_FFTWBLUR;Æ’ - Always Use Fast Fourier Transform -!TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image -!TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. -!TP_LOCALLAB_GAM;Gamma -!TP_LOCALLAB_GAMC;Gamma -!TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMFRA;Tone response curve (TRC) -!TP_LOCALLAB_GAMM;Gamma -!TP_LOCALLAB_GAMMASKCOL;Gamma -!TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_GAMSH;Gamma -!TP_LOCALLAB_GAMUTLABRELA;Lab -!TP_LOCALLAB_GAMUTMUNSELL;Munsell only -!TP_LOCALLAB_GAMUTNON;None -!TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute -!TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative -!TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) -!TP_LOCALLAB_GRADANG;Gradient angle -!TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. -!TP_LOCALLAB_GRADFRA;Graduated Filter Mask -!TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. -!TP_LOCALLAB_GRADLOGFRA;Graduated Filter Luminance -!TP_LOCALLAB_GRADSTR;Gradient strength -!TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. -!TP_LOCALLAB_GRADSTRCHRO;Chroma gradient strength -!TP_LOCALLAB_GRADSTRHUE;Hue gradient strength -!TP_LOCALLAB_GRADSTRHUE2;Hue gradient strength -!TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength. -!TP_LOCALLAB_GRADSTRLUM;Luma gradient strength -!TP_LOCALLAB_GRAINFRA;Film Grain 1:1 -!TP_LOCALLAB_GRAINFRA2;Coarseness -!TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. -!TP_LOCALLAB_GRALWFRA;Graduated filter (local contrast) -!TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). -!TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. -!TP_LOCALLAB_GRIDONE;Color Toning -!TP_LOCALLAB_GRIDTWO;Direct -!TP_LOCALLAB_GUIDBL;Soft radius -!TP_LOCALLAB_GUIDBL_TOOLTIP;Applies a guided filter with adjustable radius. Allows you to reduce artifacts or blur the image. -!TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Changes the distribution function of the guided filter. Negative values simulate a Gaussian blur. -!TP_LOCALLAB_GUIDFILTER;Guided filter radius -!TP_LOCALLAB_GUIDFILTER_TOOLTIP;Can reduce or increase artifacts. -!TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensity of the guided filter. -!TP_LOCALLAB_HHMASK_TOOLTIP;Fine hue adjustments for example for the skin. -!TP_LOCALLAB_HIGHMASKCOL;Highlights -!TP_LOCALLAB_HLH;H -!TP_LOCALLAB_HUECIE;Hue -!TP_LOCALLAB_IND;Independent (mouse) -!TP_LOCALLAB_INDSL;Independent (mouse + sliders) -!TP_LOCALLAB_INVBL;Inverse -!TP_LOCALLAB_INVBL_TOOLTIP;Alternative to 'Inverse' mode: use two spots\nFirst Spot:\n Full Image\n\nSecond spot: Excluding spot. -!TP_LOCALLAB_INVERS;Inverse -!TP_LOCALLAB_INVERS_TOOLTIP;Fewer possibilities if selected (Inverse).\n\nAlternative: use two spots\nFirst Spot:\n Full Image\n \nSecond spot: Excluding spot\n\n Inverse will enable this tool for the area outside the spot, while the area within the spot will remain unaffected by the tool. -!TP_LOCALLAB_INVMASK;Inverse algorithm -!TP_LOCALLAB_ISOGR;Distribution (ISO) -!TP_LOCALLAB_JAB;Uses Black Ev & White Ev -!TP_LOCALLAB_JABADAP_TOOLTIP;Perceptual Uniform adaptation.\nAutomatically adjusts the relationship between Jz and saturation taking into account 'Absolute luminance'. -!TP_LOCALLAB_JZ100;Jz reference 100cd/m2 -!TP_LOCALLAB_JZ100_TOOLTIP;Automatically adjusts the reference Jz 100 cd/m2 level (image signal).\nChanges the saturation level and action of 'PU adaptation' (Perceptual Uniform adaptation). -!TP_LOCALLAB_JZADAP;PU adaptation -!TP_LOCALLAB_JZCH;Chroma -!TP_LOCALLAB_JZCHROM;Chroma -!TP_LOCALLAB_JZCLARICRES;Merge chroma Cz -!TP_LOCALLAB_JZCLARILRES;Merge Jz -!TP_LOCALLAB_JZCONT;Contrast -!TP_LOCALLAB_JZFORCE;Force max Jz to 1 -!TP_LOCALLAB_JZFORCE_TOOLTIP;Allows you to force the maximum Jz value to 1 for better slider and curve response. -!TP_LOCALLAB_JZFRA;Jz Cz Hz Image Adjustments -!TP_LOCALLAB_JZHFRA;Curves Hz -!TP_LOCALLAB_JZHJZFRA;Curve Jz(Hz) -!TP_LOCALLAB_JZHUECIE;Hue Rotation -!TP_LOCALLAB_JZLIGHT;Brightness -!TP_LOCALLAB_JZLOG;Log encoding Jz -!TP_LOCALLAB_JZLOGWBS_TOOLTIP;Black Ev and White Ev adjustments can be different depending on whether Log encoding or Sigmoid is used.\nFor Sigmoid, a change (increase in most cases) of White Ev may be necessary to obtain a better rendering of highlights, contrast and saturation. -!TP_LOCALLAB_JZLOGWB_TOOLTIP;If Auto is enabled, it will calculate and adjust the Ev levels and the 'Mean luminance Yb%' for the spot area. The resulting values will be used by all Jz operations including 'Log Encoding Jz'.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed as a percentage of gray. 18% gray corresponds to a background luminance of 50% when expressed in CIE L.\nThe data is based on the mean luminance of the image.\nWhen used with Log Encoding, the mean luminance is used to determine the amount of gain that needs to be applied to the signal prior to the log encoding. Lower values of mean luminance will result in increased gain. -!TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (only in 'Advanced' mode). Only operational if the output device (monitor) is HDR (peak luminance higher than 100 cd/m2 - ideally between 4000 and 10000 cd/m2. Black point luminance inferior to 0.005 cd/m2). This supposes a) the ICC-PCS for the screen uses Jzazbz (or XYZ), b) works in real precision, c) that the monitor is calibrated (if possible with a DCI-P3 or Rec-2020 gamut), d) that the usual gamma (sRGB or BT709) is replaced by a Perceptual Quantiser (PQ) function. -!TP_LOCALLAB_JZPQFRA;Jz remapping -!TP_LOCALLAB_JZPQFRA_TOOLTIP;Allows you to adapt the Jz algorithm to an SDR environment or to the characteristics (performance) of an HDR environment as follows:\n a) for luminance values between 0 and 100 cd/m2, the system behaves as if it were in an SDR environment.\n b) for luminance values between 100 and 10000 cd/m2, you can adapt the algorithm to the HDR characteristics of the image and the monitor.\n\nIf 'PQ - Peak luminance' is set to 10000, 'Jz remappping' behaves in the same way as the original Jzazbz algorithm. -!TP_LOCALLAB_JZPQREMAP;PQ - Peak luminance -!TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - allows you to change the internal PQ function (usually 10000 cd/m2 - default 120 cd/m2).\nCan be used to adapt to different images, processes and devices. -!TP_LOCALLAB_JZQTOJ;Relative luminance -!TP_LOCALLAB_JZQTOJ_TOOLTIP;Allows you to use 'Relative luminance' instead of 'Absolute luminance' - Brightness becomes Lightness.\nThe changes affect: the Brightness slider, the Contrast slider and the Jz(Jz) curve. -!TP_LOCALLAB_JZSAT;Saturation -!TP_LOCALLAB_JZSHFRA;Shadows/Highlights Jz -!TP_LOCALLAB_JZSOFTCIE;Soft radius (GuidedFilter) -!TP_LOCALLAB_JZSTRSOFTCIE;Strength GuidedFilter -!TP_LOCALLAB_JZTARGET_EV;Viewing Mean luminance (Yb%) -!TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) -!TP_LOCALLAB_JZWAVEXP;Wavelet Jz -!TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments -!TP_LOCALLAB_LABGRID;Color correction grid -!TP_LOCALLAB_LABGRIDMERG;Background -!TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 -!TP_LOCALLAB_LABSTRUM;Structure Mask -!TP_LOCALLAB_LAPLACC;ΔØ Mask Laplacian solve PDE -!TP_LOCALLAB_LAPLACE;Laplacian threshold ΔE -!TP_LOCALLAB_LAPLACEXP;Laplacian threshold -!TP_LOCALLAB_LAPMASKCOL;Laplacian threshold -!TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the luminance values of the lighter areas. Can be used in conjunction with the L(L) and LC(H) curves. -!TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAPRAD_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAP_MASK_TOOLTIP;Solves PDEs for all Laplacian masks.\nIf enabled the Laplacian threshold mask reduces artifacts and smooths the result.\nIf disabled the response is linear. -!TP_LOCALLAB_LCLABELS;Residual noise levels -!TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. -!TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improves quality and allows the use of large radii, but increases processing time (depends on the area to be processed). Preferable to use only for large radii. The size of the area can be reduced by a few pixels to optimize the FFTW. This can reduce the processing time by a factor of 1.5 to 10. -!TP_LOCALLAB_LC_TOOLNAME;Local Contrast & Wavelets -!TP_LOCALLAB_LEVELBLUR;Maximum blur levels -!TP_LOCALLAB_LEVELWAV;Wavelet levels -!TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4. -!TP_LOCALLAB_LEVFRA;Levels -!TP_LOCALLAB_LIGHTNESS;Lightness -!TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse mode: selection = -100 forces luminance to zero. -!TP_LOCALLAB_LIGHTRETI;Lightness -!TP_LOCALLAB_LINEAR;Linearity -!TP_LOCALLAB_LIST_NAME;Add tool to current spot... -!TP_LOCALLAB_LIST_TOOLTIP;You can select 3 levels of complexity for each tool: Basic, Standard and Advanced.\nThe default setting for all tools is Basic but this can be changed in the Preferences window.\nYou can also change the level of complexity on a per-tool basis while you are editing. -!TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Allows you to decrease or increase the effect on particular levels of detail in the mask by targeting certain luminance zones (in general the lightest). -!TP_LOCALLAB_LMASK_LL_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts). May create artifacts. -!TP_LOCALLAB_LOCCONT;Unsharp Mask -!TP_LOCALLAB_LOC_CONTRAST;Local Contrast & Wavelets -!TP_LOCALLAB_LOC_CONTRASTPYR;Pyramid 1: -!TP_LOCALLAB_LOC_CONTRASTPYR2;Pyramid 2: -!TP_LOCALLAB_LOC_CONTRASTPYR2LAB; Contrast by level/TM/Directional contrast -!TP_LOCALLAB_LOC_CONTRASTPYRLAB; Graduated Filter/Edge Sharpness/Blur -!TP_LOCALLAB_LOC_RESIDPYR;Residual image (Main) -!TP_LOCALLAB_LOG;Log Encoding -!TP_LOCALLAB_LOG1FRA;CAM16 Image Adjustments -!TP_LOCALLAB_LOG2FRA;Viewing Conditions -!TP_LOCALLAB_LOGAUTO;Automatic -!TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions. -!TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. -!TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. -!TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. -!TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. -!TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) -!TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. -!TP_LOCALLAB_LOGCONQL;Contrast (Q) -!TP_LOCALLAB_LOGCONTHRES;Contrast threshold (J & Q) -!TP_LOCALLAB_LOGCONTL;Contrast (J) -!TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. -!TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. -!TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. -!TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. -!TP_LOCALLAB_LOGEXP;All tools -!TP_LOCALLAB_LOGFRA;Scene Conditions -!TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). -!TP_LOCALLAB_LOGLIGHTL;Lightness (J) -!TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. -!TP_LOCALLAB_LOGLIGHTQ;Brightness (Q) -!TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. -!TP_LOCALLAB_LOGLIN;Logarithm mode -!TP_LOCALLAB_LOGPFRA;Relative Exposure Levels -!TP_LOCALLAB_LOGREPART;Overall strength -!TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. -!TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. -!TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. -!TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the Scene conditions.\n\nAverage: Average light conditions (standard). The image will not change.\n\nDim: Dim conditions. The image will become slightly brighter.\n\nDark: Dark conditions. The image will become more bright. -!TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. -!TP_LOCALLAB_LOG_TOOLNAME;Log Encoding -!TP_LOCALLAB_LUM;LL - CC -!TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_LUMADARKEST;Darkest -!TP_LOCALLAB_LUMASK;Background color/luma mask -!TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). -!TP_LOCALLAB_LUMAWHITESEST;Lightest -!TP_LOCALLAB_LUMFRA;L*a*b* standard -!TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_MASFRAME;Mask and Merge -!TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. -!TP_LOCALLAB_MASK;Curves -!TP_LOCALLAB_MASK2;Contrast curve -!TP_LOCALLAB_MASKCOM;Common Color Mask -!TP_LOCALLAB_MASKCOM_TOOLNAME;Common Color Mask -!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of Scope. -!TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. -!TP_LOCALLAB_MASKDDECAY;Decay strength -!TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. -!TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. -!TP_LOCALLAB_MASKDE_TOOLTIP;Used to target the denoise as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the Denoise will be applied progressively.\n iIf the mask is above the 'light' threshold, then the Denoise will be applied progressively.\n Between the two, the image settings without the Denoise will be maintained, unless you adjust the sliders 'Gray area luminance denoise' or 'Gray area chrominance denoise'. -!TP_LOCALLAB_MASKGF_TOOLTIP;Used to target the Guided Filter as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the GF will be applied progressively.\n If the mask is above the 'light' threshold, then the GF will be applied progressively.\n Between the two, the image settings without the GF will be maintained. -!TP_LOCALLAB_MASKH;Hue curve -!TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lighter-tone limit above which CBDL (Luminance only) parameters will be restored progressively to their original values prior to being modified by the CBDL settings .\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\nUse a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable colorpicker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Lighter-tone limit above which Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLCTHR;Light area luminance threshold -!TP_LOCALLAB_MASKLCTHR2;Light area luma threshold -!TP_LOCALLAB_MASKLCTHRLOW;Dark area luminance threshold -!TP_LOCALLAB_MASKLCTHRLOW2;Dark area luma threshold -!TP_LOCALLAB_MASKLCTHRMID;Gray area luma denoise -!TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise -!TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. -!TP_LOCALLAB_MASKLNOISELOW;Reinforce dark/light areas -!TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;The denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Dark-tone limit below which the Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;The Guided Filter is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKRECOL_TOOLTIP;Used to modulate the effect of the Color and Light settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Color and Light settings \n In between these two areas, the full value of the Color and Light settings will be applied. -!TP_LOCALLAB_MASKRECOTHRES;Recovery threshold -!TP_LOCALLAB_MASKREEXP_TOOLTIP;Used to modulate the effect of the 'Dynamic range and Exposure' settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings \n In between these two areas, the full value of the 'Dynamic range and Exposure' settings will be applied. -!TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Log encoding settings - can be used to restore highlights reconstructed by Color propagation \n In between these two areas, the full value of the Log encoding settings will be applied. -!TP_LOCALLAB_MASKRESCB_TOOLTIP;Used to modulate the effect of the CBDL (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the CBDL settings \n In between these two areas, the full value of the CBDL settings will be applied. -!TP_LOCALLAB_MASKRESH_TOOLTIP;Used to modulate the effect of the Shadows Highlights settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Shadows Highlights settings \n In between these two areas, the full value of the Shadows Highlights settings will be applied. -!TP_LOCALLAB_MASKRESRETI_TOOLTIP;Used to modulate the effect of the Retinex (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Retinex settings \n In between these two areas, the full value of the Retinex settings will be applied. -!TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. -!TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. -!TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) -!TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) -!TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. -!TP_LOCALLAB_MEDIAN;Median Low -!TP_LOCALLAB_MEDIANITER_TOOLTIP;The number of successive iterations carried out by the median filter. -!TP_LOCALLAB_MEDIAN_TOOLTIP;You can choose a median value in the range 3x3 to 9x9 pixels. Higher values increase noise reduction and blur. -!TP_LOCALLAB_MEDNONE;None -!TP_LOCALLAB_MERCOL;Color -!TP_LOCALLAB_MERDCOL;Merge background (ΔE) -!TP_LOCALLAB_MERELE;Lighten only -!TP_LOCALLAB_MERFIV;Addition -!TP_LOCALLAB_MERFOR;Color Dodge -!TP_LOCALLAB_MERFOU;Multiply -!TP_LOCALLAB_MERGE1COLFRA;Merge with Original/Previous/Background -!TP_LOCALLAB_MERGECOLFRA;Mask: LCh & Structure -!TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Allows you to create masks based on the 3 LCh curves and/or a structure-detection algorithm. -!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of scope in this case). -!TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. -!TP_LOCALLAB_MERHEI;Overlay -!TP_LOCALLAB_MERHUE;Hue -!TP_LOCALLAB_MERLUCOL;Luminance -!TP_LOCALLAB_MERLUM;Luminosity -!TP_LOCALLAB_MERNIN;Screen -!TP_LOCALLAB_MERONE;Normal -!TP_LOCALLAB_MERSAT;Saturation -!TP_LOCALLAB_MERSEV;Soft Light (legacy) -!TP_LOCALLAB_MERSEV0;Soft Light Illusion -!TP_LOCALLAB_MERSEV1;Soft Light W3C -!TP_LOCALLAB_MERSEV2;Hard Light -!TP_LOCALLAB_MERSIX;Divide -!TP_LOCALLAB_MERTEN;Darken only -!TP_LOCALLAB_MERTHI;Color Burn -!TP_LOCALLAB_MERTHR;Difference -!TP_LOCALLAB_MERTWE;Exclusion -!TP_LOCALLAB_MERTWO;Subtract -!TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. -!TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 -!TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. -!TP_LOCALLAB_MODE_EXPERT;Advanced -!TP_LOCALLAB_MODE_NORMAL;Standard -!TP_LOCALLAB_MODE_SIMPLE;Basic -!TP_LOCALLAB_MRFIV;Background -!TP_LOCALLAB_MRFOU;Previous Spot -!TP_LOCALLAB_MRONE;None -!TP_LOCALLAB_MRTHR;Original Image -!TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. -!TP_LOCALLAB_NEIGH;Radius -!TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. -!TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. -!TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. -!TP_LOCALLAB_NLDET;Detail recovery -!TP_LOCALLAB_NLFRA;Non-local Means: Luminance -!TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. -!TP_LOCALLAB_NLGAM;Gamma -!TP_LOCALLAB_NLLUM;Strength -!TP_LOCALLAB_NLPAT;Maximum patch size -!TP_LOCALLAB_NLRAD;Maximum radius size -!TP_LOCALLAB_NOISECHROCOARSE;Coarse chroma (Wav) -!TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=0.02. -!TP_LOCALLAB_NOISECHRODETAIL;Chroma detail recovery -!TP_LOCALLAB_NOISECHROFINE;Fine chroma (Wav) -!TP_LOCALLAB_NOISEGAM;Gamma -!TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. -!TP_LOCALLAB_NOISELEQUAL;Equalizer white-black -!TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) -!TP_LOCALLAB_NOISELUMDETAIL;Luma detail recovery -!TP_LOCALLAB_NOISELUMFINE;Luminance fine 1 (Wav) -!TP_LOCALLAB_NOISELUMFINETWO;Luminance fine 2 (Wav) -!TP_LOCALLAB_NOISELUMFINEZERO;Luminance fine 0 (Wav) -!TP_LOCALLAB_NOISEMETH;Denoise -!TP_LOCALLAB_NOISE_TOOLTIP;Adds luminance noise. -!TP_LOCALLAB_NONENOISE;None -!TP_LOCALLAB_NUL_TOOLTIP;. -!TP_LOCALLAB_OFFS;Offset -!TP_LOCALLAB_OFFSETWAV;Offset -!TP_LOCALLAB_OPACOL;Opacity -!TP_LOCALLAB_ORIGLC;Merge only with original image -!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). -!TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. -!TP_LOCALLAB_PASTELS2;Vibrance -!TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression -!TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. -!TP_LOCALLAB_PREVHIDE;Hide additional settings -!TP_LOCALLAB_PREVIEW;Preview ΔE -!TP_LOCALLAB_PREVSHOW;Show additional settings -!TP_LOCALLAB_PROXI;ΔE decay -!TP_LOCALLAB_QUAAGRES;Aggressive -!TP_LOCALLAB_QUACONSER;Conservative -!TP_LOCALLAB_QUALCURV_METHOD;Curve type -!TP_LOCALLAB_QUAL_METHOD;Global quality -!TP_LOCALLAB_QUANONEALL;Off -!TP_LOCALLAB_QUANONEWAV;Non-local means only -!TP_LOCALLAB_RADIUS;Radius -!TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. -!TP_LOCALLAB_RADMASKCOL;Smooth radius -!TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). -!TP_LOCALLAB_RECT;Rectangle -!TP_LOCALLAB_RECURS;Recursive references -!TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. -!TP_LOCALLAB_REN_DIALOG_LAB;Enter the new Control Spot name -!TP_LOCALLAB_REN_DIALOG_NAME;Renaming Control Spot -!TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Color and Light image with respect to the original image. -!TP_LOCALLAB_REPARDEN_TOOLTIP;Allows you to adjust the relative strength of the Denoise image with respect to the original image. -!TP_LOCALLAB_REPAREXP_TOOLTIP;Allows you to adjust the relative strength of the Dynamic Range and Exposure image with respect to the original image. -!TP_LOCALLAB_REPARSH_TOOLTIP;Allows you to adjust the relative strength of the Shadows/Highlights and Tone Equalizer image with respect to the original image. -!TP_LOCALLAB_REPARTM_TOOLTIP;Allows you to adjust the relative strength of the Tone mapping image with respect to the original image. -!TP_LOCALLAB_REPARW_TOOLTIP;Allows you to adjust the relative strength of the local contrast and wavelet image with respect to the original image. -!TP_LOCALLAB_RESID;Residual Image -!TP_LOCALLAB_RESIDBLUR;Blur residual image -!TP_LOCALLAB_RESIDCHRO;Residual image Chroma -!TP_LOCALLAB_RESIDCOMP;Compress residual image -!TP_LOCALLAB_RESIDCONT;Residual image Contrast -!TP_LOCALLAB_RESIDHI;Highlights -!TP_LOCALLAB_RESIDHITHR;Highlights threshold -!TP_LOCALLAB_RESIDSHA;Shadows -!TP_LOCALLAB_RESIDSHATHR;Shadows threshold -!TP_LOCALLAB_RETI;Dehaze & Retinex -!TP_LOCALLAB_RETIFRA;Retinex -!TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex can be useful for processing images: \nthat are blurred, foggy or hazy (in addition to Dehaze).\nthat contain large differences in luminance.\nIt can also be used for special effects (tone mapping). -!TP_LOCALLAB_RETIM;Original Retinex -!TP_LOCALLAB_RETITOOLFRA;Retinex Tools -!TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Has no effect when the value of 'Lightness = 1' or 'Darkness =2'.\nFor other values, the last step of a 'Multiple scale Retinex' algorithm (similar to 'local contrast') is applied. These 2 cursors, associated with 'Strength' allow you to make adjustments upstream of local contrast. -!TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Adjusts the internal parameters to optimize the response.\nPreferable to keep the 'Restored data' values close to Min=0 and Max=32768 (log mode), but other values are possible. -!TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logarithm mode introduces more contrast but will also generate more halos. -!TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. -!TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. -!TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex -!TP_LOCALLAB_REWEI;Reweighting iterates -!TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. -!TP_LOCALLAB_ROW_NVIS;Not visible -!TP_LOCALLAB_ROW_VIS;Visible -!TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. -!TP_LOCALLAB_SATUR;Saturation -!TP_LOCALLAB_SATURV;Saturation (s) -!TP_LOCALLAB_SCALEGR;Scale -!TP_LOCALLAB_SCALERETI;Scale -!TP_LOCALLAB_SCALTM;Scale -!TP_LOCALLAB_SCOPEMASK;Scope (ΔE image mask) -!TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. -!TP_LOCALLAB_SENSI;Scope -!TP_LOCALLAB_SENSIEXCLU;Scope -!TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. -!TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. -!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. -!TP_LOCALLAB_SETTINGS;Settings -!TP_LOCALLAB_SH1;Shadows Highlights -!TP_LOCALLAB_SH2;Equalizer -!TP_LOCALLAB_SHADEX;Shadows -!TP_LOCALLAB_SHADEXCOMP;Shadow compression -!TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. -!TP_LOCALLAB_SHAMASKCOL;Shadows -!TP_LOCALLAB_SHAPETYPE;Spot shape -!TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. -!TP_LOCALLAB_SHARAMOUNT;Amount -!TP_LOCALLAB_SHARBLUR;Blur radius -!TP_LOCALLAB_SHARDAMPING;Damping -!TP_LOCALLAB_SHARFRAME;Modifications -!TP_LOCALLAB_SHARITER;Iterations -!TP_LOCALLAB_SHARP;Sharpening -!TP_LOCALLAB_SHARP_TOOLNAME;Sharpening -!TP_LOCALLAB_SHARRADIUS;Radius -!TP_LOCALLAB_SHORTC;Short Curves 'L' Mask -!TP_LOCALLAB_SHORTCMASK_TOOLTIP;Short circuit the 2 curves L(L) and L(H).\nAllows you to mix the current image with the original image modified by the mask job.\nUsable with masks 2, 3, 4, 6, 7. -!TP_LOCALLAB_SHOWC;Mask and modifications -!TP_LOCALLAB_SHOWC1;Merge file -!TP_LOCALLAB_SHOWCB;Mask and modifications -!TP_LOCALLAB_SHOWDCT;Show Fourier (Æ’) process -!TP_LOCALLAB_SHOWE;Mask and modifications -!TP_LOCALLAB_SHOWFOURIER;Fourier Æ’(dct) -!TP_LOCALLAB_SHOWLAPLACE;∆ Laplacian (first) -!TP_LOCALLAB_SHOWLC;Mask and modifications -!TP_LOCALLAB_SHOWMASK;Show mask -!TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Displays masks and modifications.\nBeware, you can only view one tool mask at a time.\nShow modified image: shows the modified image including the effect of any adjustments and masks.\nShow modified areas without mask: shows the modifications before any masks are applied.\nShow modified areas with mask: shows the modifications after a mask has been applied.\nShow mask: shows the aspect of the mask including the effect of any curves and filters.\nShow spot structure: allows you to see the structure-detection mask when the 'Spot structure' cursor is activated (when available).\nNote: The mask is applied before the shape detection algorithm. -!TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. -!TP_LOCALLAB_SHOWMASKTYP1;Blur & Noise -!TP_LOCALLAB_SHOWMASKTYP2;Denoise -!TP_LOCALLAB_SHOWMASKTYP3;Blur & Noise + Denoise -!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the Scope sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. -!TP_LOCALLAB_SHOWMNONE;Show modified image -!TP_LOCALLAB_SHOWMODIF;Show modified areas without mask -!TP_LOCALLAB_SHOWMODIF2;Show modified areas -!TP_LOCALLAB_SHOWMODIFMASK;Show modified areas with mask -!TP_LOCALLAB_SHOWNORMAL;No luminance normalization -!TP_LOCALLAB_SHOWPLUS;Mask and modifications (Blur & Denoise) -!TP_LOCALLAB_SHOWPOISSON;Poisson (pde Æ’) -!TP_LOCALLAB_SHOWR;Mask and modifications -!TP_LOCALLAB_SHOWREF;Preview ΔE -!TP_LOCALLAB_SHOWS;Mask and modifications -!TP_LOCALLAB_SHOWSTRUC;Show spot structure(Advanced) -!TP_LOCALLAB_SHOWSTRUCEX;Show spot structure(Advanced) -!TP_LOCALLAB_SHOWT;Mask and modifications -!TP_LOCALLAB_SHOWVI;Mask and modifications -!TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC -!TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -!TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q -!TP_LOCALLAB_SIGJZFRA;Sigmoid Jz -!TP_LOCALLAB_SIGMAWAV;Attenuation response -!TP_LOCALLAB_SIGMOIDBL;Blend -!TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev -!TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. -!TP_LOCALLAB_SLOMASKCOL;Slope -!TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_SLOSH;Slope -!TP_LOCALLAB_SOFT;Soft Light & Original Retinex -!TP_LOCALLAB_SOFTM;Soft Light -!TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. -!TP_LOCALLAB_SOFTRADIUSCOL;Soft radius -!TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. -!TP_LOCALLAB_SOFTRETI;Reduce ΔE artifacts -!TP_LOCALLAB_SOFT_TOOLNAME;Soft Light & Original Retinex -!TP_LOCALLAB_SOURCE_ABS;Absolute luminance -!TP_LOCALLAB_SOURCE_GRAY;Mean luminance (Yb%) -!TP_LOCALLAB_SPECCASE;Specific cases -!TP_LOCALLAB_SPECIAL;Special use of RGB curves -!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. -!TP_LOCALLAB_SPOTNAME;New Spot -!TP_LOCALLAB_STD;Standard -!TP_LOCALLAB_STR;Strength -!TP_LOCALLAB_STRBL;Strength -!TP_LOCALLAB_STREN;Compression strength -!TP_LOCALLAB_STRENG;Strength -!TP_LOCALLAB_STRENGR;Strength -!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). -!TP_LOCALLAB_STRENGTH;Noise -!TP_LOCALLAB_STRGRID;Strength -!TP_LOCALLAB_STRUC;Structure -!TP_LOCALLAB_STRUCCOL;Spot structure -!TP_LOCALLAB_STRUCCOL1;Spot structure -!TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. -!TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). -!TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! -!TP_LOCALLAB_STYPE;Shape method -!TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. -!TP_LOCALLAB_SYM;Symmetrical (mouse) -!TP_LOCALLAB_SYMSL;Symmetrical (mouse + sliders) -!TP_LOCALLAB_TARGET_GRAY;Mean luminance (Yb%) -!TP_LOCALLAB_TE_PIVOT;Pivot (Ev) -!TP_LOCALLAB_THRES;Threshold structure -!TP_LOCALLAB_THRESDELTAE;ΔE scope threshold -!TP_LOCALLAB_THRESRETI;Threshold -!TP_LOCALLAB_THRESWAV;Balance threshold -!TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Mean=%3 Sig=%4 -!TP_LOCALLAB_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. -!TP_LOCALLAB_TM;Tone Mapping -!TP_LOCALLAB_TM_MASK;Use transmission map -!TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;This slider affects edge sensitivity.\n The greater the value, the more likely a change in contrast will be interpreted as an 'edge'.\n If set to zero the tone mapping will have an effect similar to unsharp masking. -!TP_LOCALLAB_TONEMAPGAM_TOOLTIP;The Gamma slider shifts the tone-mapping effect towards either the shadows or the highlights. -!TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In some cases tone mapping may result in a cartoonish appearance, and in some rare cases soft but wide halos may appear.\n Increasing the number of reweighting iterates will help fight some of these problems. -!TP_LOCALLAB_TONEMAP_TOOLTIP;Same as the tone mapping tool in the main menu.\nThe main-menu tool must be deactivated if this tool is used. -!TP_LOCALLAB_TONEMASCALE_TOOLTIP;This slider allows you to adjust the transition between 'local' and 'global' contrast.\nThe greater the value, the larger a detail needs to be for it to be boosted. -!TP_LOCALLAB_TONE_TOOLNAME;Tone Mapping -!TP_LOCALLAB_TOOLCOL;Structure mask as tool -!TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Allows you to modify the mask, if one exists. -!TP_LOCALLAB_TOOLMASK;Mask Tools -!TP_LOCALLAB_TOOLMASK_2;Wavelets -!TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. -!TP_LOCALLAB_TRANSIT;Transition Gradient -!TP_LOCALLAB_TRANSITGRAD;Transition differentiation XY -!TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. -!TP_LOCALLAB_TRANSITVALUE;Transition value -!TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). -!TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. -!TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain -!TP_LOCALLAB_TRANSMISSIONMAP;Transmission map -!TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. -!TP_LOCALLAB_USEMASK;Laplacian -!TP_LOCALLAB_VART;Variance (contrast) -!TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool -!TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. -!TP_LOCALLAB_VIB_TOOLNAME;Vibrance & Warm/Cool -!TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtrl+click to show/hide all Control Spot. -!TP_LOCALLAB_WARM;Warm/Cool & Color artifacts -!TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases. -!TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve including the dark-gray/light-gray boundary corresponds to the first 3 levels 0, 1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3, 4, 5, 6). -!TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balances the action within each level. -!TP_LOCALLAB_WAT_BLURLC_TOOLTIP;The default blur setting affects all 3 L*a* b* components (luminance and colour).\nWhen checked, only luminance is blurred. -!TP_LOCALLAB_WAT_CLARIC_TOOLTIP;'Merge chroma' is used to select the intensity of the desired effect on chrominance. -!TP_LOCALLAB_WAT_CLARIL_TOOLTIP;'Merge luma' is used to select the intensity of the desired effect on luminance. -!TP_LOCALLAB_WAT_CONTCHROMALEV_TOOLTIP;'Chroma levels': adjusts the 'a' and 'b' components of Lab* as a proportion of the luminance value. -!TP_LOCALLAB_WAT_CONTOFFSET_TOOLTIP;Offset modifies the balance between low-contrast and high-contrast details.\nHigh values will amplify contrast changes to the higher-contrast details, whereas low values will amplify contrast changes to low-contrast details.\nBy using a low 'Attenuation response' value you can select which contrast values will be enhanced. -!TP_LOCALLAB_WAT_DELTABAL_TOOLTIP;By moving the slider to the left, the lower levels are accentuated. To the right, the lower levels are reduced and the higher levels accentuated. -!TP_LOCALLAB_WAT_EXPRESID_TOOLTIP;The residual image behaves in the same way as the main image when making adjustments to contrast, chroma etc. -!TP_LOCALLAB_WAT_GRADW_TOOLTIP;The more you move the slider to the right, the more effective the detection algorithm will be and the less noticeable the effects of local contrast. -!TP_LOCALLAB_WAT_LEVELLOCCONTRAST_TOOLTIP;Low to high local contrast from left to right on the x-axis.\nIncreases or decreases local contrast on the y-axis. -!TP_LOCALLAB_WAT_LOCCONTRASTEDG_TOOLTIP;You can adjust the distribution of local contrast by wavelet level based on the initial intensity of the contrast. This will modify the effects of perspective and relief in the image, and/or reduce the contrast values for very low initial contrast levels. -!TP_LOCALLAB_WAT_ORIGLC_TOOLTIP;'Merge only with original image', prevents the 'Wavelet Pyramid' settings from interfering with 'Clarity' and 'Sharp mask'. -!TP_LOCALLAB_WAT_RESIDBLUR_TOOLTIP;Blurs the residual image, independent of the levels. -!TP_LOCALLAB_WAT_RESIDCOMP_TOOLTIP;Compresses the residual image to increase or reduce contrast. -!TP_LOCALLAB_WAT_SIGMALC_TOOLTIP;The effect of the local contrast adjustment is stronger for medium-contrast details and weaker for high and low-contrast details.\n This slider controls how quickly the effect dampens towards the extreme contrasts.\nThe higher the value of the slider, the wider the range of contrasts that will receive the full effect of the local contrast adjustment and the higher the risk of generating artifacts.\nThe lower the value, the more the effect will be pinpointed towards a narrow range of contrast values. -!TP_LOCALLAB_WAT_STRENGTHW_TOOLTIP;Intensity of edge-effect detection. -!TP_LOCALLAB_WAT_STRWAV_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. -!TP_LOCALLAB_WAT_THRESHOLDWAV_TOOLTIP;Range of wavelet levels used throughout the Wavelets module. -!TP_LOCALLAB_WAT_WAVBLURCURV_TOOLTIP;Allows you to blur each level of decomposition.\nThe finest to coarsest levels of decomposition are from left to right. -!TP_LOCALLAB_WAT_WAVCBDL_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAT_WAVDELTABAL_TOOLTIP;Acts on the balance of the three directions (horizontal, vertical and diagonal) based on the luminance of the image.\nBy default the shadows or highlights are reduced to avoid artifacts. -!TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Shows all of the 'Edge sharpness' tools. It is advisable to read the Wavelet Levels documentation. -!TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Allows you to adjust the maximum effect of blurring on the levels. -!TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Low to high local contrast from left to right on the x-axis\nIncrease or decrease local contrast on the y-axis. -!TP_LOCALLAB_WAT_WAVTM_TOOLTIP;The lower (negative) part compresses each level of decomposition creating a tone mapping effect.\nThe upper (positive) part attenuates the contrast by level.\nThe finest to coarsest levels of decomposition are from left to right on the x-axis. -!TP_LOCALLAB_WAV;Local contrast -!TP_LOCALLAB_WAVBLUR_TOOLTIP;Allows you to blur each level of the decomposition, as well as the residual image. -!TP_LOCALLAB_WAVCOMP;Compression by level -!TP_LOCALLAB_WAVCOMPRE;Compression by level -!TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Allows you to apply tone mapping or reduce local contrast on individual levels.\nFine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAVCOMP_TOOLTIP;Allows you to apply local contrast based on the direction of the wavelet decomposition : horizontal, vertical, diagonal. -!TP_LOCALLAB_WAVCON;Contrast by level -!TP_LOCALLAB_WAVCONTF_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAVDEN;Luminance denoise -!TP_LOCALLAB_WAVE;Wavelets -!TP_LOCALLAB_WAVEDG;Local contrast -!TP_LOCALLAB_WAVEEDG_TOOLTIP;Improves sharpness by targeting the action of local contrast on the edges. It has the same functions as the corresponding module in Wavelet Levels and uses the same settings. -!TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Range of wavelet levels used in 'Local contrast' (by wavelet level). -!TP_LOCALLAB_WAVGRAD_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. -!TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. -!TP_LOCALLAB_WAVLEV;Blur by level -!TP_LOCALLAB_WAVMASK;Local contrast -!TP_LOCALLAB_WAVMASK_TOOLTIP;Uses wavelets to modify the local contrast of the mask and reinforce or reduce the structure (skin, buildings, etc.). -!TP_LOCALLAB_WEDIANHI;Median Hi -!TP_LOCALLAB_WHITE_EV;White Ev -!TP_LOCALLAB_ZCAMFRA;ZCAM Image Adjustments -!TP_LOCALLAB_ZCAMTHRES;Retrieve high datas -!TP_LOCAL_HEIGHT;Bottom -!TP_LOCAL_HEIGHT_T;Top -!TP_LOCAL_WIDTH;Right -!TP_LOCAL_WIDTH_L;Left -!TP_LOCRETI_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Evenly distributed.\nHigh = Reinforce strong light. -!TP_METADATA_EDIT;Apply modifications -!TP_METADATA_MODE;Metadata copy mode -!TP_METADATA_STRIP;Strip all metadata -!TP_METADATA_TUNNEL;Copy unchanged -!TP_NEUTRAL;Reset -!TP_PDSHARPENING_LABEL;Capture Sharpening -!TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor -!TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length -!TP_PERSPECTIVE_CAMERA_FRAME;Correction -!TP_PERSPECTIVE_CAMERA_PITCH;Vertical -!TP_PERSPECTIVE_CAMERA_ROLL;Rotation -!TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift -!TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Vertical shift -!TP_PERSPECTIVE_CAMERA_YAW;Horizontal -!TP_PERSPECTIVE_CONTROL_LINES;Control lines -!TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+drag: Draw new line\nRight-click: Delete line -!TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;At least two horizontal or two vertical control lines required. -!TP_PERSPECTIVE_METHOD;Method -!TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-based -!TP_PERSPECTIVE_METHOD_SIMPLE;Simple -!TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment -!TP_PERSPECTIVE_PROJECTION_PITCH;Vertical -!TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation -!TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontal shift -!TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Vertical shift -!TP_PERSPECTIVE_PROJECTION_YAW;Horizontal -!TP_PERSPECTIVE_RECOVERY_FRAME;Recovery -!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter -!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. -!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter -!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. -!TP_PREPROCESS_LINEDENOISE_DIRECTION;Direction -!TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Both -!TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontal -!TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontal only on PDAF rows -!TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Vertical -!TP_PREPROCESS_PDAFLINESFILTER;PDAF lines filter -!TP_PREPROCWB_LABEL;Preprocess White Balance -!TP_PREPROCWB_MODE;Mode -!TP_PREPROCWB_MODE_AUTO;Auto -!TP_PREPROCWB_MODE_CAMERA;Camera -!TP_PRSHARPENING_LABEL;Post-Resize Sharpening -!TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the 'Lanczos' resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. -!TP_RAWCACORR_AUTOIT;Iterations -!TP_RAWCACORR_AUTOIT_TOOLTIP;This setting is available if 'Auto-correction' is checked.\nAuto-correction is conservative, meaning that it often does not correct all chromatic aberration.\nTo correct the remaining chromatic aberration, you can use up to five iterations of automatic chromatic aberration correction.\nEach iteration will reduce the remaining chromatic aberration from the last iteration at the cost of additional processing time. -!TP_RAWCACORR_AVOIDCOLORSHIFT;Avoid color shift -!TP_RAWEXPOS_BLACK_0;Green 1 (lead) -!TP_RAWEXPOS_BLACK_1;Red -!TP_RAWEXPOS_BLACK_2;Blue -!TP_RAWEXPOS_BLACK_3;Green 2 -!TP_RAWEXPOS_BLACK_BLUE;Blue -!TP_RAWEXPOS_BLACK_GREEN;Green -!TP_RAWEXPOS_BLACK_RED;Red -!TP_RAWEXPOS_RGB;Red, Green, Blue -!TP_RAW_1PASSMEDIUM;1-pass (Markesteijn) -!TP_RAW_2PASS;1-pass+fast -!TP_RAW_3PASSBEST;3-pass (Markesteijn) -!TP_RAW_4PASS;3-pass+fast -!TP_RAW_AHD;AHD -!TP_RAW_AMAZE;AMaZE -!TP_RAW_AMAZEBILINEAR;AMaZE+Bilinear -!TP_RAW_AMAZEVNG4;AMaZE+VNG4 -!TP_RAW_BORDER;Border -!TP_RAW_DCB;DCB -!TP_RAW_DCBBILINEAR;DCB+Bilinear -!TP_RAW_DCBVNG4;DCB+VNG4 -!TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto threshold -!TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;If the checkbox is checked (recommended), RawTherapee calculates an optimum value based on flat regions in the image.\nIf there is no flat region in the image or the image is too noisy, the value will be set to 0.\nTo set the value manually, uncheck the checkbox first (reasonable values depend on the image). -!TP_RAW_DUALDEMOSAICCONTRAST;Contrast threshold -!TP_RAW_EAHD;EAHD -!TP_RAW_FAST;Fast -!TP_RAW_HD;Threshold -!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. -!TP_RAW_HPHD;HPHD -!TP_RAW_IGV;IGV -!TP_RAW_IMAGENUM;Sub-image -!TP_RAW_IMAGENUM_SN;SN mode -!TP_RAW_IMAGENUM_TOOLTIP;Some raw files consist of several sub-images (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nWhen using any demosaicing method other than Pixel Shift, this selects which sub-image is used.\n\nWhen using the Pixel Shift demosaicing method on a Pixel Shift raw, all sub-images are used, and this selects which sub-image should be used for moving parts. -!TP_RAW_LMMSE;LMMSE -!TP_RAW_MONO;Mono -!TP_RAW_NONE;None (Shows sensor pattern) -!TP_RAW_PIXELSHIFT;Pixel Shift -!TP_RAW_PIXELSHIFTAVERAGE;Use average for moving parts -!TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Use average of all frames instead of selected frame for regions with motion.\nGives motion effect on slow moving (overlapping) objects. -!TP_RAW_PIXELSHIFTBLUR;Blur motion mask -!TP_RAW_PIXELSHIFTDMETHOD;Demosaic method for motion -!TP_RAW_PIXELSHIFTEPERISO;Sensitivity -!TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;The default value of 0 should work fine for base ISO.\nHigher values increase sensitivity of motion detection.\nChange in small steps and watch the motion mask while changing.\nIncrease sensitivity for underexposed or high ISO images. -!TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalize brightness of frames -!TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalize per channel -!TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Enabled: Equalize the RGB channels individually.\nDisabled: Use same equalization factor for all channels. -!TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalize the brightness of the frames to the brightness of the selected frame.\nIf there are overexposed areas in the frames select the brightest frame to avoid magenta color cast in overexposed areas or enable motion correction. -!TP_RAW_PIXELSHIFTGREEN;Check green channel for motion -!TP_RAW_PIXELSHIFTHOLEFILL;Fill holes in motion mask -!TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Fill holes in motion mask. -!TP_RAW_PIXELSHIFTMEDIAN;Use median for moving parts -!TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use median of all frames instead of selected frame for regions with motion.\nRemoves objects which are at different places in all frames.\nGives motion effect on slow moving (overlapping) objects. -!TP_RAW_PIXELSHIFTMM_AUTO;Automatic -!TP_RAW_PIXELSHIFTMM_CUSTOM;Custom -!TP_RAW_PIXELSHIFTMM_OFF;Off -!TP_RAW_PIXELSHIFTMOTIONMETHOD;Motion Correction -!TP_RAW_PIXELSHIFTNONGREENCROSS;Check red/blue channels for motion -!TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask -!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Show only motion mask -!TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Shows the motion mask without the image. -!TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Overlays the image with a green mask showing the regions with motion. -!TP_RAW_PIXELSHIFTSIGMA;Blur radius -!TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;The default radius of 1.0 usually fits well for base ISO.\nIncrease the value for high ISO shots, 5.0 is a good starting point.\nWatch the motion mask while changing the value. -!TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions -!TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with motion and areas without.\nSet to 0 to disable transition smoothing.\nSet to 1 to either get the AMaZE/LMMSE result of the selected frame (depending on whether 'Use LMMSE' is selected), or the median of all four frames if 'Use median' is selected. -!TP_RAW_RCD;RCD -!TP_RAW_RCDBILINEAR;RCD+Bilinear -!TP_RAW_RCDVNG4;RCD+VNG4 -!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix -!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster.\n+fast gives less artifacts in flat areas. -!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix -!TP_RAW_VNG4;VNG4 -!TP_RAW_XTRANS;X-Trans -!TP_RAW_XTRANSFAST;Fast X-Trans -!TP_RESIZE_ALLOW_UPSCALING;Allow Upscaling -!TP_RESIZE_LE;Long Edge: -!TP_RESIZE_LONG;Long Edge -!TP_RESIZE_SE;Short Edge: -!TP_RESIZE_SHORT;Short Edge -!TP_RETINEX_CONTEDIT_HSL;HSL histogram -!TP_RETINEX_CONTEDIT_LAB;L*a*b* histogram -!TP_RETINEX_CONTEDIT_LH;Hue -!TP_RETINEX_CONTEDIT_MAP;Equalizer -!TP_RETINEX_CURVEEDITOR_CD;L=f(L) -!TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorrect raw data to reduce halos and artifacts. -!TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) -!TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the 'Highlight' retinex method. -!TP_RETINEX_CURVEEDITOR_MAP;L=f(L) -!TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! -!TP_RETINEX_EQUAL;Equalizer -!TP_RETINEX_FREEGAMMA;Free gamma -!TP_RETINEX_GAIN;Gain -!TP_RETINEX_GAINOFFS;Gain and Offset (brightness) -!TP_RETINEX_GAINTRANSMISSION;Gain transmission -!TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Increase or reduce the transmission map to achieve the desired luminance. The x-axis is the transmission. The y-axis is the gain. -!TP_RETINEX_GAMMA;Gamma -!TP_RETINEX_GAMMA_FREE;Free -!TP_RETINEX_GAMMA_HIGH;High -!TP_RETINEX_GAMMA_LOW;Low -!TP_RETINEX_GAMMA_MID;Middle -!TP_RETINEX_GAMMA_NONE;None -!TP_RETINEX_GAMMA_TOOLTIP;Restore tones by applying gamma before and after Retinex. Different from Retinex curves or others curves (Lab, Exposure, etc.). -!TP_RETINEX_GRAD;Transmission gradient -!TP_RETINEX_GRADS;Strength gradient -!TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Strength is reduced when iterations increase, and conversely. -!TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Variance and Threshold are reduced when iterations increase, and conversely. -!TP_RETINEX_HIGH;High -!TP_RETINEX_HIGHLIG;Highlight -!TP_RETINEX_HIGHLIGHT;Highlight threshold -!TP_RETINEX_HIGHLIGHT_TOOLTIP;Increase action of High algorithm.\nMay require you to re-adjust 'Neighboring pixels' and to increase the 'White-point correction' in the Raw tab -> Raw White Points tool. -!TP_RETINEX_HSLSPACE_LIN;HSL-Linear -!TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic -!TP_RETINEX_ITER;Iterations (Tone-mapping) -!TP_RETINEX_ITERF;Tone mapping -!TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. -!TP_RETINEX_LABEL;Retinex -!TP_RETINEX_LABEL_MASK;Mask -!TP_RETINEX_LABSPACE;L*a*b* -!TP_RETINEX_LOW;Low -!TP_RETINEX_MAP;Method -!TP_RETINEX_MAP_GAUS;Gaussian mask -!TP_RETINEX_MAP_MAPP;Sharp mask (wavelet partial) -!TP_RETINEX_MAP_MAPT;Sharp mask (wavelet total) -!TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generated by the Gaussian function above (Radius, Method) to reduce halos and artifacts.\n\nCurve only: apply a diagonal contrast curve on the mask.\nBeware of artifacts!\n\nGaussian mask: generate and use a Gaussian blur of the original mask.\nQuick.\n\nSharp mask: generate and use a wavelet on the original mask.\nSlow. -!TP_RETINEX_MAP_NONE;None -!TP_RETINEX_MEDIAN;Transmission median filter -!TP_RETINEX_METHOD;Method -!TP_RETINEX_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Equalize action.\nHigh = Reinforce high light.\nHighlights = Remove magenta in highlights. -!TP_RETINEX_MLABEL;Restored data Min=%1 Max=%2 -!TP_RETINEX_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. -!TP_RETINEX_NEIGHBOR;Radius -!TP_RETINEX_NEUTRAL;Reset -!TP_RETINEX_NEUTRAL_TOOLTIP;Reset all sliders and curves to their default values. -!TP_RETINEX_OFFSET;Offset (brightness) -!TP_RETINEX_SCALES;Gaussian gradient -!TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and radius are reduced when iterations increase, and conversely. -!TP_RETINEX_SETTINGS;Settings -!TP_RETINEX_SKAL;Scale -!TP_RETINEX_SLOPE;Free gamma slope -!TP_RETINEX_STRENGTH;Strength -!TP_RETINEX_THRESHOLD;Threshold -!TP_RETINEX_THRESHOLD_TOOLTIP;Limits in/out.\nIn = image source,\nOut = image gauss. -!TP_RETINEX_TLABEL;TM Datas Min=%1 Max=%2 Mean=%3 Sigma=%4 -!TP_RETINEX_TLABEL2;TM Effective Tm=%1 TM=%2 -!TP_RETINEX_TLABEL_TOOLTIP;ransmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. -!TP_RETINEX_TRANF;Transmission -!TP_RETINEX_TRANSMISSION;Transmission map -!TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. -!TP_RETINEX_UNIFORM;Uniform -!TP_RETINEX_VARIANCE;Contrast -!TP_RETINEX_VARIANCE_TOOLTIP;Low variance increase local contrast and saturation, but can lead to artifacts. -!TP_RETINEX_VIEW;Process -!TP_RETINEX_VIEW_MASK;Mask -!TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Normal display.\nMask - Displays the mask.\nUnsharp mask - Displays the image with a high radius unsharp mask.\nTransmission - Auto/Fixed - Displays the file transmission-map, before any action on contrast and brightness.\n\nAttention: the mask does not correspond to reality, but is amplified to make it more visible. -!TP_RETINEX_VIEW_NONE;Standard -!TP_RETINEX_VIEW_TRAN;Transmission - Auto -!TP_RETINEX_VIEW_TRAN2;Transmission - Fixed -!TP_RETINEX_VIEW_UNSHARP;Unsharp mask -!TP_SHARPENING_BLUR;Blur radius -!TP_SHARPENING_CONTRAST;Contrast threshold -!TP_SHARPENING_ITERCHECK;Auto limit iterations -!TP_SHARPENING_RADIUS_BOOST;Corner radius boost -!TP_SHARPENMICRO_CONTRAST;Contrast threshold -!TP_SOFTLIGHT_LABEL;Soft Light -!TP_SOFTLIGHT_STRENGTH;Strength -!TP_SPOT_COUNTLABEL;%1 point(s) -!TP_SPOT_DEFAULT_SIZE;Default spot size -!TP_SPOT_ENTRYCHANGED;Point changed -!TP_SPOT_HINT;Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. -!TP_SPOT_LABEL;Spot Removal -!TP_TM_FATTAL_AMOUNT;Amount -!TP_TM_FATTAL_ANCHOR;Anchor -!TP_TM_FATTAL_LABEL;Dynamic Range Compression -!TP_TM_FATTAL_THRESHOLD;Detail -!TP_TONE_EQUALIZER_BANDS;Bands -!TP_TONE_EQUALIZER_BAND_0;Blacks -!TP_TONE_EQUALIZER_BAND_1;Shadows -!TP_TONE_EQUALIZER_BAND_2;Midtones -!TP_TONE_EQUALIZER_BAND_3;Highlights -!TP_TONE_EQUALIZER_BAND_4;Whites -!TP_TONE_EQUALIZER_DETAIL;Regularization -!TP_TONE_EQUALIZER_LABEL;Tone Equalizer -!TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) -!TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map -!TP_WAVELET_1;Level 1 -!TP_WAVELET_2;Level 2 -!TP_WAVELET_3;Level 3 -!TP_WAVELET_4;Level 4 -!TP_WAVELET_5;Level 5 -!TP_WAVELET_6;Level 6 -!TP_WAVELET_7;Level 7 -!TP_WAVELET_8;Level 8 -!TP_WAVELET_9;Level 9 -!TP_WAVELET_APPLYTO;Apply to -!TP_WAVELET_AVOID;Avoid color shift -!TP_WAVELET_B0;Black -!TP_WAVELET_B1;Gray -!TP_WAVELET_B2;Residual -!TP_WAVELET_BACKGROUND;Background -!TP_WAVELET_BACUR;Curve -!TP_WAVELET_BALANCE;Contrast balance d/v-h -!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. -!TP_WAVELET_BALCHRO;Chroma balance -!TP_WAVELET_BALCHROM;Equalizer Color -!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. -!TP_WAVELET_BALLUM;Denoise equalizer White-Black -!TP_WAVELET_BANONE;None -!TP_WAVELET_BASLI;Slider -!TP_WAVELET_BATYPE;Contrast balance method -!TP_WAVELET_BL;Blur levels -!TP_WAVELET_BLCURVE;Blur by levels -!TP_WAVELET_BLURFRAME;Blur -!TP_WAVELET_BLUWAV;Attenuation response -!TP_WAVELET_CBENAB;Toning and Color balance -!TP_WAVELET_CB_TOOLTIP;With high values you can create special effects, similar to those achieved with the Chroma Module, but focused on the residual image\nWith moderate values you can manually correct the white balance. -!TP_WAVELET_CCURVE;Local contrast -!TP_WAVELET_CH1;Whole chroma range -!TP_WAVELET_CH2;Saturated/pastel -!TP_WAVELET_CH3;Link contrast levels -!TP_WAVELET_CHCU;Curve -!TP_WAVELET_CHR;Chroma-contrast link strength -!TP_WAVELET_CHRO;Saturated/pastel threshold -!TP_WAVELET_CHROFRAME;Denoise chrominance -!TP_WAVELET_CHROMAFRAME;Chroma -!TP_WAVELET_CHROMCO;Chrominance Coarse -!TP_WAVELET_CHROMFI;Chrominance Fine -!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. -!TP_WAVELET_CHRWAV;Blur chroma -!TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of 'contrast levels' and 'chroma-contrast link strength'. -!TP_WAVELET_CHSL;Sliders -!TP_WAVELET_CHTYPE;Chrominance method -!TP_WAVELET_CLA;Clarity -!TP_WAVELET_CLARI;Sharp-mask and Clarity -!TP_WAVELET_COLORT;Opacity red-green -!TP_WAVELET_COMPCONT;Contrast -!TP_WAVELET_COMPEXPERT;Advanced -!TP_WAVELET_COMPGAMMA;Compression gamma -!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allows you to equilibrate the data and histogram. -!TP_WAVELET_COMPLEXLAB;Complexity -!TP_WAVELET_COMPLEX_TOOLTIP;Standard: shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. -!TP_WAVELET_COMPNORMAL;Standard -!TP_WAVELET_COMPTM;Tone mapping -!TP_WAVELET_CONTEDIT;'After' contrast curve -!TP_WAVELET_CONTFRAME;Contrast - Compression -!TP_WAVELET_CONTR;Gamut -!TP_WAVELET_CONTRA;Contrast -!TP_WAVELET_CONTRAST_MINUS;Contrast - -!TP_WAVELET_CONTRAST_PLUS;Contrast + -!TP_WAVELET_CONTRA_TOOLTIP;Changes the residual image contrast. -!TP_WAVELET_CTYPE;Chrominance control -!TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabled if zoom > about 300%. -!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (abscissa).\nLow abscissa values represent small local contrast (real values about 10..20).\n50% abscissa represents average local contrast (real value about 100..300).\n66% abscissa represents standard deviation of local contrast (real value about 300..800).\n100% abscissa represents maximum local contrast (real value about 3000..8000). -!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) -!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function of hue.\nTake care not to overwrite changes made with the Gamut sub-tool's hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. -!TP_WAVELET_CURVEEDITOR_CL;L -!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast-luminance curve at the end of the wavelet processing. -!TP_WAVELET_CURVEEDITOR_HH;HH -!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image hue as a function of hue. -!TP_WAVELET_DALL;All directions -!TP_WAVELET_DAUB;Edge performance -!TP_WAVELET_DAUB2;D2 - low -!TP_WAVELET_DAUB4;D4 - standard -!TP_WAVELET_DAUB6;D6 - standard plus -!TP_WAVELET_DAUB10;D10 - medium -!TP_WAVELET_DAUB14;D14 - high -!TP_WAVELET_DAUBLOCAL;Wavelet Edge performance -!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the first levels. However the quality is not strictly related to this coefficient and can vary depending on image and use. -!TP_WAVELET_DEN5THR;Guided threshold -!TP_WAVELET_DENCURV;Curve -!TP_WAVELET_DENL;Correction structure -!TP_WAVELET_DENLH;Guided threshold levels 1-4 -!TP_WAVELET_DENLOCAL_TOOLTIP;Use a curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained. -!TP_WAVELET_DENMIX_TOOLTIP;The local-contrast reference value used by the guided filter.\nDepending on the image, results can vary depending on whether the noise is measured before or after the noise reduction. These four choices allow you to take into account various combinations of the original and modified (denoised) images to find the best compromise. -!TP_WAVELET_DENOISE;Guide curve based on Local contrast -!TP_WAVELET_DENOISEGUID;Guided threshold based on hue -!TP_WAVELET_DENOISEH;High levels Curve Local contrast -!TP_WAVELET_DENOISEHUE;Denoise hue equalizer -!TP_WAVELET_DENQUA;Mode -!TP_WAVELET_DENSIGMA_TOOLTIP;Adapts the shape of the guide. -!TP_WAVELET_DENSLI;Slider -!TP_WAVELET_DENSLILAB;Method -!TP_WAVELET_DENWAVGUID_TOOLTIP;Uses hue to reduce or increase the action of the guided filter. -!TP_WAVELET_DENWAVHUE_TOOLTIP;Amplify or reduce denoising depending on the color. -!TP_WAVELET_DETEND;Details -!TP_WAVELET_DIRFRAME;Directional contrast -!TP_WAVELET_DONE;Vertical -!TP_WAVELET_DTHR;Diagonal -!TP_WAVELET_DTWO;Horizontal -!TP_WAVELET_EDCU;Curve -!TP_WAVELET_EDEFFECT;Attenuation response -!TP_WAVELET_EDEFFECT_TOOLTIP;This slider selects the range of contrast values that will receive the full effect of any adjustment. -!TP_WAVELET_EDGCONT;Local contrast -!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, top-left, top-right and bottom-right represent respectively local contrast for low values, mean, mean+std. dev. and maxima. -!TP_WAVELET_EDGE;Edge sharpness -!TP_WAVELET_EDGEAMPLI;Base amplification -!TP_WAVELET_EDGEDETECT;Gradient sensitivity -!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) -!TP_WAVELET_EDGEDETECTTHR2;Edge enhancement -!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This slider sets a threshold below which finer details won't be considered as an edge. -!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. -!TP_WAVELET_EDGESENSI;Edge sensitivity -!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. -!TP_WAVELET_EDGTHRESH;Detail -!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centered on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. -!TP_WAVELET_EDRAD;Radius -!TP_WAVELET_EDRAD_TOOLTIP;This adjustment controls the local enhancement. A value of zero still has an effect. -!TP_WAVELET_EDSL;Threshold sliders -!TP_WAVELET_EDTYPE;Local contrast method -!TP_WAVELET_EDVAL;Strength -!TP_WAVELET_FINAL;Final Touchup -!TP_WAVELET_FINCFRAME;Final local contrast -!TP_WAVELET_FINEST;Finest -!TP_WAVELET_FINTHR_TOOLTIP;Uses local contrast to reduce or increase the action of the guided filter. -!TP_WAVELET_GUIDFRAME;Final smoothing (guided filter) -!TP_WAVELET_HIGHLIGHT;Finer levels luminance range -!TP_WAVELET_HS1;Whole luminance range -!TP_WAVELET_HS2;Selective luminance range -!TP_WAVELET_HUESKIN;Skin hue -!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. -!TP_WAVELET_HUESKY;Hue range -!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. -!TP_WAVELET_ITER;Delta balance levels -!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. -!TP_WAVELET_LABEL;Wavelet levels -!TP_WAVELET_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 -!TP_WAVELET_LARGEST;Coarsest -!TP_WAVELET_LEVCH;Chroma -!TP_WAVELET_LEVDEN;Level 5-6 denoise -!TP_WAVELET_LEVDIR_ALL;All levels, in all directions -!TP_WAVELET_LEVDIR_INF;Finer detail levels, including selected level -!TP_WAVELET_LEVDIR_ONE;One level -!TP_WAVELET_LEVDIR_SUP;Coarser detail levels, excluding selected level -!TP_WAVELET_LEVELHIGH;Radius 5-6 -!TP_WAVELET_LEVELLOW;Radius 1-4 -!TP_WAVELET_LEVELS;Wavelet levels -!TP_WAVELET_LEVELSIGM;Radius -!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of wavelet decomposition levels for the image.\nMore levels require more RAM and require a longer processing time. -!TP_WAVELET_LEVF;Contrast -!TP_WAVELET_LEVFOUR;Level 5-6 denoise and guided threshold -!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 -!TP_WAVELET_LEVONE;Level 2 -!TP_WAVELET_LEVTHRE;Level 4 -!TP_WAVELET_LEVTWO;Level 3 -!TP_WAVELET_LEVZERO;Level 1 -!TP_WAVELET_LIMDEN;Interaction levels 5-6 on levels 1-4 -!TP_WAVELET_LINKEDG;Link to Edge Sharpness Strength -!TP_WAVELET_LIPST;Enhanced algoritm -!TP_WAVELET_LOWLIGHT;Coarser levels luminance range -!TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise. -!TP_WAVELET_MEDGREINF;First level -!TP_WAVELET_MEDI;Reduce artifacts in blue sky -!TP_WAVELET_MEDILEV;Edge detection -!TP_WAVELET_MEDILEV_TOOLTIP;When you enable Edge Detection, it is recommanded:\n- to disabled low contrast levels to avoid artifacts,\n- to use high values of gradient sensitivity.\n\nYou can modulate the strength with 'refine' from Denoise and Refine. -!TP_WAVELET_MERGEC;Merge chroma -!TP_WAVELET_MERGEL;Merge luma -!TP_WAVELET_MIXCONTRAST;Reference -!TP_WAVELET_MIXDENOISE;Denoise -!TP_WAVELET_MIXMIX;Mixed 50% noise - 50% denoise -!TP_WAVELET_MIXMIX70;Mixed 30% noise - 70% denoise -!TP_WAVELET_MIXNOISE;Noise -!TP_WAVELET_NEUTRAL;Neutral -!TP_WAVELET_NOIS;Denoise -!TP_WAVELET_NOISE;Denoise and Refine -!TP_WAVELET_NPHIGH;High -!TP_WAVELET_NPLOW;Low -!TP_WAVELET_NPNONE;None -!TP_WAVELET_NPTYPE;Neighboring pixels -!TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. -!TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between low contrast and high contrast details.\nHigh values will amplify contrast changes to the higher contrast details, whereas low values will amplify contrast changes to low contrast details.\nBy using a low Attenuation response value you can select which contrast values will be enhanced. -!TP_WAVELET_OLDSH;Algorithm using negatives values -!TP_WAVELET_OPACITY;Opacity blue-yellow -!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve -!TP_WAVELET_OPACITYWL;Local contrast -!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. -!TP_WAVELET_PASTEL;Pastel chroma -!TP_WAVELET_PROC;Process -!TP_WAVELET_PROTAB;Protection -!TP_WAVELET_QUAAGRES;Aggressive -!TP_WAVELET_QUACONSER;Conservative -!TP_WAVELET_RADIUS;Radius shadows - highlight -!TP_WAVELET_RANGEAB;Range a and b % -!TP_WAVELET_RE1;Reinforced -!TP_WAVELET_RE2;Unchanged -!TP_WAVELET_RE3;Reduced -!TP_WAVELET_RESBLUR;Blur luminance -!TP_WAVELET_RESBLURC;Blur chroma -!TP_WAVELET_RESBLUR_TOOLTIP;Disabled if zoom > about 500%. -!TP_WAVELET_RESCHRO;Strength -!TP_WAVELET_RESCON;Shadows -!TP_WAVELET_RESCONH;Highlights -!TP_WAVELET_RESID;Residual Image -!TP_WAVELET_SAT;Saturated chroma -!TP_WAVELET_SETTINGS;Wavelet Settings -!TP_WAVELET_SHA;Sharp mask -!TP_WAVELET_SHFRAME;Shadows/Highlights -!TP_WAVELET_SHOWMASK;Show wavelet 'mask' -!TP_WAVELET_SIGM;Radius -!TP_WAVELET_SIGMA;Attenuation response -!TP_WAVELET_SIGMAFIN;Attenuation response -!TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values. -!TP_WAVELET_SKIN;Skin targetting/protection -!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. -!TP_WAVELET_SKY;Hue targetting/protection -!TP_WAVELET_SKY_TOOLTIP;Allows you to target or protect a range of hues.\nAt -100 selected hues are targetted.\nAt 0 all hues are treated equally.\nAt +100 selected hues are protected while all other hues are targetted. -!TP_WAVELET_SOFTRAD;Soft radius -!TP_WAVELET_STREN;Refine -!TP_WAVELET_STREND;Strength -!TP_WAVELET_STRENGTH;Strength -!TP_WAVELET_SUPE;Extra -!TP_WAVELET_THR;Shadows threshold -!TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. -!TP_WAVELET_THREND;Local contrast threshold -!TP_WAVELET_THRESHOLD;Finer levels -!TP_WAVELET_THRESHOLD2;Coarser levels -!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels from the chosen value to the selected number of 'wavelet levels' will be affected by the Shadow luminance range. -!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels below and including the chosen value will be affected by the Highlight luminance range. -!TP_WAVELET_THRH;Highlights threshold -!TP_WAVELET_TILESBIG;Tiles -!TP_WAVELET_TILESFULL;Full image -!TP_WAVELET_TILESIZE;Tiling method -!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. -!TP_WAVELET_TMEDGS;Edge stopping -!TP_WAVELET_TMSCALE;Scale -!TP_WAVELET_TMSTRENGTH;Compression strength -!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. -!TP_WAVELET_TMTYPE;Compression method -!TP_WAVELET_TON;Toning -!TP_WAVELET_TONFRAME;Excluded colors -!TP_WAVELET_USH;None -!TP_WAVELET_USHARP;Clarity method -!TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, you can choose any level (in Settings) from 1 to 4 for processing.\nIf you select Clarity, you can choose any level (in Settings) between 5 and Extra. -!TP_WAVELET_WAVLOWTHR;Low contrast threshold -!TP_WAVELET_WAVOFFSET;Offset -!TP_WBALANCE_AUTOITCGREEN;Temperature correlation -!TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement -!TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. -!TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. -!TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. -!TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Allows you to set the minimum patch value. values that are too low can lead to a lack of correlation. -!TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Allows you to filter magenta/purple data from the image. If the box is checked a filter limiting the value of Y is applied. By default this value is 0.4. You can change it in 'options' Itcwb_Ypurple (Maximum 1) -!TP_WBALANCE_ITCWBPRECIS_TOOLTIP;The lower the value, the more relevant the data, but increases the processing time. Since the processing time is low, this parameter should generally be able to remain at the default value -!TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Sets the green value review amplitude in iterations, from low amplitude 0.82 to 1.25 to maximum amplitude 0.4 to 4. -!TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;This setting sets the size of color datas used by algorithm. -!TP_WBALANCE_ITCWBSIZE_TOOLTIP;This setting sets the number of iterations to find the best correspondence between the reference spectral colors and those in xyY value of the image. A value of 3 seams a good compromise. -!TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. -!TP_WBALANCE_ITCWB_ALG;Remove 2 pass algorithm -!TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint -!TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop -!TP_WBALANCE_ITCWB_FGREEN;Find green student -!TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram -!TP_WBALANCE_ITCWB_FRA;Auto temperature correlation settings -!TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. -!TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimum size -!TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple color -!TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used -!TP_WBALANCE_ITCWB_PRIM_ACE;Forces use of the entire CIE diagram -!TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling -!TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - near Pointer's gamut -!TP_WBALANCE_ITCWB_PRIM_JDCMAX;Close to full CIE diagram -!TP_WBALANCE_ITCWB_PRIM_REC;High sampling -!TP_WBALANCE_ITCWB_PRIM_SRGB;Low sampling & Ignore Camera settings -!TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ matrix -!TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax after Camera XYZ matrix -!TP_WBALANCE_ITCWB_RGREEN;Green range -!TP_WBALANCE_ITCWB_SAMPLING;Low sampling 5.9 -!TP_WBALANCE_ITCWB_SIZE;Size of ref. color compare to histogram -!TP_WBALANCE_ITCWB_SIZEPATCH;Size of color patch -!TP_WBALANCE_ITCWB_THRES;Colors used in picture (preset) -!TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and Green (tint).\n\nUsage tips:\n1) start Itcwb , enable 'Use Custom temperature and tint'.\n2) Set 'Temperature and tint' to your liking :free, Pick,...(Custom)\n3) go back to 'Temperature correlation'.\n\nYou cannot use : 2 passes, AWB temperature bias, Green refinement. -!TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. -!TP_WBALANCE_ITCWGREEN;Green refinement -!TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. -!TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). -!TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 -!TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. -!TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. -!TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 -!TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. -!TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 -!TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Display ΔE patch (this assumes there is enough spectral data), between image and spectral datas.\n Display read datas found. The 2 values correspond to the minimum and maximum data values taken into account. The coefficient x9 must be taken into account to obtain the number of pixels concerned in the image. -!TP_WBALANCE_PICKER;Pick -!TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 -!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 -!TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 -!TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. -!TP_WBALANCE_TEMPBIAS;AWB temperature bias -!TP_WBALANCE_TEMPBIAS_TOOLTIP;Allows to alter the computation of the 'auto white balance'\nby biasing it towards warmer or cooler temperatures. The bias\nis expressed as a percentage of the computed temperature,\nso that the result is given by 'computedTemp + computedTemp * bias'.\n\nYou can use "Awb temperature bias" to adjust the "Temperature correlation" results. Each movement of this command brings a new calculation of temperature, tint and correlation. -!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: f -!//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. -!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram +//TP_WBALANCE_ITCWB_FORCED;Forza l'uso dell'intero diagramma CIE +//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Per impostazione predefinita, quando è attivato "Inpaint opposto", i colori viola non vengono presi in considerazione. Tuttavia, se l'immagine non necessita di ricostruzione delle alte luci o se l'immagine contiene naturalmente tinte viola (fiori, ecc.), potrebbe essere necessario disattivarla per tenere conto di tutti i colori. From a5df36c56966808e0d13195336c179ce082850c3 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 7 Mar 2024 08:23:50 +0100 Subject: [PATCH 135/291] Change Tooltip Observer (#6975) * Change Tooltip Observer * Change observer tooltip 2 --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index db08f0586..07b5f18c9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -4226,7 +4226,7 @@ TP_WBALANCE_METHOD;Method TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) “Observer 10°†must be selected. TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 From 3e269764031e09db701456c8645f3da85c632ed7 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 26 Feb 2024 11:32:01 +0100 Subject: [PATCH 136/291] Read embedded dcp profile from raw files raw files, usually dng files, can provide a dcp profile by providing the related tags. This patch will make the "Use embedded" options in the color management panel selectable if the source raw file embeds a dcp profile. In this case the DCP panel will be enabled like when reading an external dcp profile. Additional changes: * Rename "Use embedded, if possible" to just "Use embedded" since the option is already disabled when no embedded profile is found. * Update the "Use embedded" options tooltip as it's now not related to only non raw images. --- rtdata/languages/default | 4 ++-- rtengine/rawimagesource.cc | 39 +++++++++++++++++++++++++------------- rtengine/rawimagesource.h | 9 +++------ rtengine/rtthumbnail.cc | 4 ++-- rtgui/icmpanel.cc | 11 +++++++---- rtgui/icmpanel.h | 1 + 6 files changed, 41 insertions(+), 27 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 07b5f18c9..4e76b7b00 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2634,8 +2634,8 @@ TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced Raw 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_INPUTEMBEDDED;Use embedded +TP_ICM_INPUTEMBEDDED_TOOLTIP;Use the color profile embedded in the file.\nIf unavailable, fall back to Camera standard TP_ICM_INPUTNONE;No profile TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. TP_ICM_INPUTPROFILE;Input Profile diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 8149c0464..c027cd7d4 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1078,7 +1078,7 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA DCPProfile *dcpProf = nullptr; cmsHPROFILE dummy; - findInputProfile(cmp.inputProfile, nullptr, (static_cast(getMetaData()))->getCamera(), &dcpProf, dummy); + findInputProfile(cmp.inputProfile, nullptr, (static_cast(getMetaData()))->getCamera(), fileName, &dcpProf, dummy); if (dcpProf == nullptr) { if (settings->verbose) { @@ -1094,8 +1094,24 @@ DCPProfile *RawImageSource::getDCP(const ColorManagementParams &cmp, DCPProfileA void RawImageSource::convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb) { + cmsHPROFILE in; + DCPProfile *dcpProf; + + if (!findInputProfile(cmp.inputProfile, embProfile, (static_cast(getMetaData()))->getCamera(), fileName, &dcpProf, in)) { + return; + } + double pre_mul[3] = { ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2) }; - colorSpaceConversion(image, cmp, wb, pre_mul, embProfile, camProfile, imatrices.xyz_cam, (static_cast(getMetaData()))->getCamera()); + colorSpaceConversion_(image, cmp, wb, pre_mul, camProfile, imatrices.xyz_cam, in, dcpProf); +} + +void RawImageSource::colorSpaceConversion(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName, const Glib::ustring &fileName) +{ + cmsHPROFILE in; + DCPProfile *dcpProf; + if (findInputProfile(cmp.inputProfile, embedded, camName, fileName, &dcpProf, in)) { + colorSpaceConversion_(im, cmp, wb, pre_mul, camprofile, cam, in, dcpProf); + } } void RawImageSource::getFullSize(int& w, int& h, int tr) @@ -3156,18 +3172,11 @@ lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b) } // Converts raw image including ICC input profile to working space - floating point version -void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) +void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE camprofile, double camMatrix[3][3], cmsHPROFILE in, DCPProfile *dcpProf) { // MyTime t1, t2, t3; // t1.set (); - cmsHPROFILE in; - DCPProfile *dcpProf; - - if (!findInputProfile(cmp.inputProfile, embedded, camName, &dcpProf, in)) { - return; - } - if (dcpProf != nullptr) { // DCP processing const DCPProfile::Triple pre_mul_row = { @@ -3557,7 +3566,7 @@ void RawImageSource::colorSpaceConversion_(Imagefloat* im, const ColorManagement // 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) +bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, const Glib::ustring &fileName, DCPProfile **dcpProf, cmsHPROFILE& in) { in = nullptr; // cam will be taken on NULL *dcpProf = nullptr; @@ -3566,8 +3575,12 @@ bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embed return false; } - if (embedded && inProfile == "(embedded)") { - in = embedded; + if (inProfile == "(embedded)") { + if (embedded) { + in = embedded; + } else { + *dcpProf = DCPStore::getInstance()->getProfile(fileName); + } } else if (inProfile == "(cameraICC)") { // DCPs have higher quality, so use them first *dcpProf = DCPStore::getInstance()->getStdProfile(camName); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e65cadaa3..739a6371f 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -46,7 +46,7 @@ private: static DiagonalCurve *phaseOneIccCurveInv; static LUTf invGrad; // for fast_demosaic static LUTf initInvGrad (); - static void colorSpaceConversion_ (Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName); + static void colorSpaceConversion_ (Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE camprofile, double cam[3][3], cmsHPROFILE in, DCPProfile *dcpProf); static int defTransform (const RawImage *ri, int tran); protected: @@ -190,11 +190,8 @@ public: DCPProfile *getDCP(const procparams::ColorManagementParams &cmp, DCPProfileApplyState &as) override; void convertColorSpace(Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) override; - static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in); - static void colorSpaceConversion(Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName) - { - colorSpaceConversion_(im, cmp, wb, pre_mul, embedded, camprofile, cam, camName); - } + static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, const Glib::ustring &filename, DCPProfile **dcpProf, cmsHPROFILE& in); + static void colorSpaceConversion(Imagefloat* im, const procparams::ColorManagementParams& cmp, const ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], const std::string &camName, const Glib::ustring &fileName); static void inverse33(const double (*coeff)[3], double (*icoeff)[3]); void MSR(float** luminance, float **originalLuminance, float **exLuminance, const LUTf& mapcurve, bool mapcontlutili, int width, int height, const procparams::RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 65c03ac96..1ae5d30a7 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1328,7 +1328,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT if (isRaw) { double pre_mul[3] = { redMultiplier, greenMultiplier, blueMultiplier }; - RawImageSource::colorSpaceConversion (baseImg, params.icm, currWB, pre_mul, embProfile, camProfile, cam2xyz, camName ); + RawImageSource::colorSpaceConversion (baseImg, params.icm, currWB, pre_mul, embProfile, camProfile, cam2xyz, camName, metadata->getFileName()); } else { StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, thumbImg->getSampleFormat()); } @@ -1467,7 +1467,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT if (isRaw) { cmsHPROFILE dummy; - RawImageSource::findInputProfile (params.icm.inputProfile, nullptr, camName, &dcpProf, dummy); + RawImageSource::findInputProfile (params.icm.inputProfile, nullptr, camName, metadata->getFileName(), &dcpProf, dummy); if (dcpProf) { dcpProf->setStep2ApplyState (params.icm.workingProfile, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset, as); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index b18afe5aa..772f8e38e 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -705,6 +705,8 @@ void ICMPanel::updateDCP(int dcpIlluminant, Glib::ustring dcp_name) if (dcp_name == "(cameraICC)") { dcp = DCPStore::getInstance()->getStdProfile(camName); + } else if (dcp_name == "(embedded)") { + dcp = DCPStore::getInstance()->getProfile(filename); } else if (ifromfile->get_active() && DCPStore::getInstance()->isValidDCPFileName(dcp_name)) { dcp = DCPStore::getInstance()->getProfile(dcp_name); } @@ -806,8 +808,8 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker wprimconn_(wprimconn); trcExp->set_expanded(false); - if (pp->icm.inputProfile.substr(0, 5) != "file:") { - ipDialog->set_filename(" "); + if (pp->icm.inputProfile.substr(0, 5) != "file:" && !ipDialog->get_filename().empty()) { + ipDialog->set_filename(pp->icm.inputProfile); } if (pp->icm.inputProfile == "(none)") { @@ -815,7 +817,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) updateDCP(pp->icm.dcpIlluminant, ""); } else if (pp->icm.inputProfile == "(embedded)" || ((pp->icm.inputProfile == "(camera)" || pp->icm.inputProfile.empty()) && icamera->get_state() == Gtk::STATE_INSENSITIVE)) { iembedded->set_active(true); - updateDCP(pp->icm.dcpIlluminant, ""); + updateDCP(pp->icm.dcpIlluminant, "(embedded)"); } else if ((pp->icm.inputProfile == "(cameraICC)") && icameraICC->get_state() != Gtk::STATE_INSENSITIVE) { icameraICC->set_active(true); updateDCP(pp->icm.dcpIlluminant, "(cameraICC)"); @@ -2126,8 +2128,9 @@ void ICMPanel::setRawMeta(bool raw, const rtengine::FramesData* pMeta) iembedded->set_active(!raw); icamera->set_sensitive(raw); camName = pMeta->getCamera(); + filename = pMeta->getFileName(); icameraICC->set_sensitive(raw && (ICCStore::getInstance()->getStdProfile(pMeta->getCamera()) != nullptr || DCPStore::getInstance()->getStdProfile(pMeta->getCamera()) != nullptr)); - iembedded->set_sensitive(!raw); + iembedded->set_sensitive(!raw || DCPStore::getInstance()->getProfile(filename)); enableListener(); } diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index f41e17b7b..b11b9478c 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -167,6 +167,7 @@ private: double dcpTemperatures[2]; Glib::ustring lastRefFilename; Glib::ustring camName; + Glib::ustring filename; void updateDCP(int dcpIlluminant, Glib::ustring dcp_name); void updateRenderingIntent(const Glib::ustring &profile); void foldAllButMe (GdkEventButton* event, MyExpander *expander); From 3b2732d64188695356370fd9acc36c5fe8769407 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Thu, 7 Mar 2024 14:12:02 -0800 Subject: [PATCH 137/291] windows innosetup: comment out font bf988ad2744865f151611a2761a91c9d90f7ba83 removes the default font in favor of the OS default. `tools/win/InnoSetup/WindowsInnoSetup.iss.in` Line 122 causes the win build fail trying to load the deleted font. --- tools/win/InnoSetup/WindowsInnoSetup.iss.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/win/InnoSetup/WindowsInnoSetup.iss.in b/tools/win/InnoSetup/WindowsInnoSetup.iss.in index 954d39991..a80925d72 100644 --- a/tools/win/InnoSetup/WindowsInnoSetup.iss.in +++ b/tools/win/InnoSetup/WindowsInnoSetup.iss.in @@ -119,7 +119,7 @@ Source: "{#MyBuildBasePath}\*.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gdb.exe"; DestDir: "{app}"; Flags: skipifsourcedoesntexist ignoreversion -Source: "{#MyBuildBasePath}\fonts\DroidSansMonoSlashed.ttf"; DestDir: "{fonts}"; FontInstall: "Droid Sans Mono Slashed"; Flags: onlyifdoesntexist uninsneveruninstall +;Source: "{#MyBuildBasePath}\fonts\DroidSansMonoSlashed.ttf"; DestDir: "{fonts}"; FontInstall: "Droid Sans Mono Slashed"; Flags: onlyifdoesntexist uninsneveruninstall ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] From 8de0519204e87a743e60802349676b1358a29987 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Fri, 8 Mar 2024 10:41:33 +0100 Subject: [PATCH 138/291] denoise gui: set luminance detail adjuster default as procparams default The rtgui denoise luminance detail adjuster widget default value is set to 50, but the procparams default is 0 causing some confusing behavior: when enabling the denoise tool in the gui the luminance detail value is set to the proc params default value (0), when resetting the adjuster the values is set to 50. This patch sets the adjuster default value to the procparams default value like the other adjusters. --- rtgui/dirpyrdenoise.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index 4e487b184..e1200ac20 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -69,7 +69,7 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPY Lmethodconn = Lmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::LmethodChanged) ); luma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING"), 0, 100, 0.01, 0)); - Ldetail = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LUMINANCE_DETAIL"), 0, 100, 0.01, 50)); + Ldetail = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LUMINANCE_DETAIL"), 0, 100, 0.01, 0)); NoiscurveEditorG = new CurveEditorGroup (options.lastDenoiseCurvesDir, M("TP_DIRPYRDENOISE_LUMINANCE_CURVE")); //curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); NoiscurveEditorG->setCurveListener (this); From 96a48c633482782a6bd58e31a0d64d468b773e04 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 9 Mar 2024 07:36:46 +0100 Subject: [PATCH 139/291] Local adjustments - set method Avoid Gamut to Munsell - better processing of highlights and gamut (#6965) * Avoidgamumethod set to Munsell-only * Set appimage.yml and windows.yml to la_gamutmunsell * Remove procparams conversion XYZ absolute tu Munsell only * Neutralize appimage.yml and windows.yml --- rtengine/iplocallab.cc | 7 ++++--- rtengine/procparams.cc | 2 +- rtgui/controlspotpanel.cc | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 4e9072f7e..a3e9dee22 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -76,7 +76,8 @@ constexpr double czlim = rtengine::RT_SQRT1_2;// 0.70710678118654752440; constexpr float clipLoc(float x) { - return rtengine::LIM(x, 0.f, 32767.f); + //return rtengine::LIM(x, 0.f, 32767.f);//remove leads to bad behavior + return x; } constexpr float clipDE(float x) @@ -86,12 +87,12 @@ constexpr float clipDE(float x) constexpr float clipC(float x) { - return rtengine::LIM(x, -42000.f, 42000.f); + return rtengine::LIM(x, -100000.f, 100000.f);//increase LIM from 42000 to 1000000 to avoid clip and also imaginaries colors } constexpr float clipChro(float x) { - return rtengine::LIM(x, 0.f, 140.f); + return rtengine::LIM(x, 0.f, 300.f);//increase LIM from 140 to 300 to avoid clip and also imaginaries colors } constexpr double clipazbz(double x) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 43b8bb3ec..1b8269a2f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2972,7 +2972,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : structexclu(0), struc(4.0), shapeMethod("IND"), - avoidgamutMethod("XYZ"), + avoidgamutMethod("MUNS"), loc{150, 150, 150, 150}, centerX(0), centerY(0), diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index dd9c20d01..12eea86cc 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -407,7 +407,7 @@ ControlSpotPanel::ControlSpotPanel(): avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZABSO")); avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTXYZRELA")); avoidgamutMethod_->append(M("TP_LOCALLAB_GAMUTMUNSELL")); - avoidgamutMethod_->set_active(2); + avoidgamutMethod_->set_active(4); avoidgamutconn_ = avoidgamutMethod_->signal_changed().connect( sigc::mem_fun( *this, &ControlSpotPanel::avoidgamutMethodChanged)); From 5ecdaa2b0035856abc84eb1f027c02686098474c Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 9 Mar 2024 11:14:10 -0800 Subject: [PATCH 140/291] Update Dutch translation Supplied by paulmatthijsse (https://github.com/Beep6581/RawTherapee/issues/6979). --- rtdata/languages/Nederlands | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 76e9befdd..a0418e70c 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -16,6 +16,7 @@ #016 2017-04-21 update by wim ter meer #017 2020-06-05 update by dheijl #018 2024-02-18 update to RawTherapee 5.10 by Paul Matthijsse +#019 2024-03-08 update by Paul Matthijsse #100 #101 @LANGUAGE_DISPLAY_NAME=Nederlands @@ -1558,7 +1559,9 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminantie-curve TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminantie-detail TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminantie TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminantie -TP_DIRPYRDENOISE_MAIN_COLORSPACE;Methode +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compenseer lichtheid +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Wijzig de kracht van de ruisvermindering gebaseerd op de lichtheid van de afbeelding. De kracht wordt minder bij donkere beelden en meer bij heldere beelden. +TP_DIRPYRDENOISE_MAIN_COLORSPACE;Kleurruimte TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Voor RAW-afbeeldingen kan de RGB- of Lab-methode worden gebruikt.\n\nVoor niet-RAW-afbeeldingen zal altijd de Lab-methode worden gebruikt, ongeacht de geselecteerde methode. @@ -1779,9 +1782,9 @@ TP_LENSPROFILE_USE_GEOMETRIC;Geometrische vervorming TP_LENSPROFILE_USE_HEADER;Lenscorrecties TP_LENSPROFILE_USE_VIGNETTING;Vignettering TP_LOCALCONTRAST_AMOUNT;Hoeveelheid -TP_LOCALCONTRAST_DARKNESS;Donker niveau +TP_LOCALCONTRAST_DARKNESS;Donkere delen TP_LOCALCONTRAST_LABEL;Lokaal contrast -TP_LOCALCONTRAST_LIGHTNESS;helderheidsniveau +TP_LOCALCONTRAST_LIGHTNESS;Lichte delen TP_LOCALCONTRAST_RADIUS;Straal TP_METADATA_EDIT;Pas wijzigingen toe TP_METADATA_MODE;Metadata kopieermodus @@ -2982,13 +2985,14 @@ HISTORY_MSG_1150;LA - Log-codering Q in plaats van Sigmoid Q HISTORY_MSG_BLSHAPE;Vervaag per niveau HISTORY_MSG_BLURCWAV;Vervaging chroma HISTORY_MSG_BLURWAV;Vervaging luminantie -HISTORY_MSG_BLUWAV;Versterkinsrespons +HISTORY_MSG_BLUWAV;Versterkingsrespons HISTORY_MSG_CATCAT;CAL - Instellingen - Modus HISTORY_MSG_CATCOMPLEX;CAL - Instellingen - Complexiteit HISTORY_MSG_CATMODEL;CAL - Instellingen - CAM -HISTORY_MSG_COMPLEX;Wavelet complexiteit -HISTORY_MSG_COMPLEXRETI;Retinex complexiteit -HISTORY_MSG_DEHAZE_SATURATION;Ontnevel - Verzadiging +HISTORY_MSG_COMPLEX;Waveletcomplexiteit +HISTORY_MSG_COMPLEXRETI;Retinexcomplexiteit +HISTORY_MSG_DEHAZE_SATURATION;Nevelvermindering - Verzadiging +HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compenseer lichtheid HISTORY_MSG_EDGEFFECT;Randversterking respons HISTORY_MSG_FF_FROMMETADATA;Flat-Field - Uit metadata HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Referentie-uitvoer From 82dce5fd47960324eca6a1367dd37c7d1b753b54 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 9 Mar 2024 12:47:52 -0800 Subject: [PATCH 141/291] Adapt to real hi-DPI update Change recursive folder browsing button icon color and size. --- .../icons/rawtherapee/scalable/apps/folder-subfolder.svg | 8 ++++---- rtgui/filecatalog.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rtdata/icons/rawtherapee/scalable/apps/folder-subfolder.svg b/rtdata/icons/rawtherapee/scalable/apps/folder-subfolder.svg index f22d0da0f..eb858b543 100644 --- a/rtdata/icons/rawtherapee/scalable/apps/folder-subfolder.svg +++ b/rtdata/icons/rawtherapee/scalable/apps/folder-subfolder.svg @@ -71,13 +71,13 @@ inkscape:groupmode="layer" inkscape:label="Layer 1"> diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 2bd16edf5..69b9e6dc9 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -350,7 +350,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bOriginal->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); bRecursive = Gtk::manage(new Gtk::ToggleButton()); - bRecursive->set_image(*Gtk::manage(new RTImage("folder-subfolder.png"))); + bRecursive->set_image(*Gtk::manage(new RTImage("folder-subfolder", Gtk::ICON_SIZE_LARGE_TOOLBAR))); bRecursive->set_tooltip_text(M("FILEBROWSER_SHOWRECURSIVE")); bRecursive->set_relief(Gtk::RELIEF_NONE); bRecursive->set_active(options.browseRecursive); From c3a1656ac088b3b04ac7336496905b099130858d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 9 Mar 2024 22:17:55 -0800 Subject: [PATCH 142/291] Fix WB multipliers for some Canon cameras Read the correct tag for the as-shot multipliers (index 0x69). The port from LibRaw incorrectly used the tag at index 0x69 + 0x64, which is the daylight WB multipliers. This fix affects Canon cameras with color data versions 34 (EOS R3) and 48 (EOS R6m2, EOS R7, and EOS R10). --- rtengine/dcraw.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 236414c31..65343e906 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6124,7 +6124,7 @@ get2_256: // imCanon.ColorDataVer = 11; imCanon.ColorDataSubVer = get2(); - fseek(ifp, save1 + ((0x0069+0x0064) << 1), SEEK_SET); + fseek(ifp, save1 + (0x0069 << 1), SEEK_SET); FORC4 cam_mul[c ^ (c >> 1)] = (float)get2(); offsetChannelBlackLevel2 = save1 + ((0x0069+0x0102) << 1); From 026e9e2a388b7d58302f56d96bc4743cac194a94 Mon Sep 17 00:00:00 2001 From: Pandagrapher Date: Sat, 16 Mar 2024 16:13:47 +0100 Subject: [PATCH 143/291] Do not install 'index.theme' file for linux build with 'BUILD_BUNDLE=OFF' --- rtdata/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt index e14862d7f..7ed0d95c7 100644 --- a/rtdata/CMakeLists.txt +++ b/rtdata/CMakeLists.txt @@ -24,7 +24,13 @@ endif() if(UNIX) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rawtherapee.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR}) - install(DIRECTORY "${ICONTHEMEDIR}/hicolor" DESTINATION "${ICONSDIR}") + if(BUILD_BUNDLE) + install(DIRECTORY "${ICONTHEMEDIR}/hicolor" DESTINATION "${ICONSDIR}") + else() + # For theme 'hicolor' (containing app icon), 'index.theme' shall not be installed for Linux build with 'BUILD_BUNDLE=OFF' option + # (to avoid conflict with existing 'index.theme' distro file) + install(DIRECTORY "${ICONTHEMEDIR}/hicolor" DESTINATION "${ICONSDIR}" PATTERN "index.theme" EXCLUDE) + endif() endif() install(FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") From 2aea26b5f35709f3a27a55bce061802f0ba4f7e1 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 14 Mar 2024 10:50:03 +0100 Subject: [PATCH 144/291] Handle flat field images with different black levels than raw image For bayer images handle flat field images with different black levels than the raw image. --- rtengine/ffmanager.cc | 3 +++ rtengine/rawflatfield.cc | 35 ++++++++++++++++++++++++++--------- rtengine/rawimagesource.h | 2 +- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index bd6428127..8a7d6a524 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -145,6 +145,7 @@ void ffInfo::updateRawImage() int H = ri->get_height(); int W = ri->get_width(); ri->compress_image(0); + ri->set_prefilters(); int rSize = W * ((ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1) ? 1 : 3); acc_t **acc = new acc_t*[H]; @@ -165,6 +166,7 @@ void ffInfo::updateRawImage() if( !temp->loadRaw(true)) { temp->compress_image(0); //\ TODO would be better working on original, because is temporary + temp->set_prefilters(); nFiles++; if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS || ri->get_colors() == 1 ) { @@ -204,6 +206,7 @@ void ffInfo::updateRawImage() ri = nullptr; } else { ri->compress_image(0); + ri->set_prefilters(); } } diff --git a/rtengine/rawflatfield.cc b/rtengine/rawflatfield.cc index 22dbca852..0a6b3917e 100644 --- a/rtengine/rawflatfield.cc +++ b/rtengine/rawflatfield.cc @@ -263,13 +263,21 @@ void cfaboxblur(const float* const * riFlatFile, float* cfablur, int boxH, int b namespace rtengine { -void RawImageSource::processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D &rawData, const float black[4]) +void RawImageSource::processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D &rawData, const float black[4]) { // BENCHFUN std::unique_ptr cfablur(new float[H * W]); const int BS = raw.ff_BlurRadius + (raw.ff_BlurRadius & 1); + std::array ffblack; + { + const auto tmpfilters = riFlatFile->get_filters(); + riFlatFile->set_filters(riFlatFile->prefilters); // we need 4 blacks for bayer processing + riFlatFile->get_colorsCoeff(nullptr, nullptr, ffblack.data(), false); + riFlatFile->set_filters(tmpfilters); + } + if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::V)) { cfaboxblur(riFlatFile->data, cfablur.get(), 2 * BS, 0, H, W); } else if (raw.ff_BlurType == procparams::RAWParams::getFlatFieldBlurTypeString(procparams::RAWParams::FlatFieldBlurType::H)) { @@ -291,7 +299,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const int col = 2 * (W >> 2) + n; const int c = ri->get_colors() != 1 ? FC(row, col) : 0; const int c4 = ri->get_colors() != 1 ? ((c == 1 && !(row & 1)) ? 3 : c) : 0; - refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - black[c4]); + refcolor[m][n] = std::max(0.0f, cfablur[row * W + col] - ffblack[c4]); } float limitFactor = 1.f; @@ -314,7 +322,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra clippedBefore = true; break; } - const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - black[c4])); + const float tempval = (rawVal - black[c4]) * (refcolor[m][n] / std::max(1e-5f, cfablur[(row + m) * W + col + n] - ffblack[c4])); maxval = std::max(maxval, tempval); } } @@ -363,6 +371,9 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]), _mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]]) }; + const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]), + _mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]]) + }; const vfloat onev = F2V(1.f); const vfloat minValuev = F2V(minValue); @@ -375,10 +386,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra int col = 0; #ifdef __SSE2__ const vfloat rowBlackv = blackv[row & 1]; + const vfloat ffrowBlackv = ffblackv[row & 1]; const vfloat rowRefcolorv = refcolorv[row & 1]; for (; col < W - 3; col += 4) { - const vfloat blurv = LVFU(cfablur[row * W + col]) - rowBlackv; + const vfloat blurv = LVFU(cfablur[row * W + col]) - ffrowBlackv; vfloat vignettecorrv = rowRefcolorv / blurv; vignettecorrv = vself(vmaskf_le(blurv, minValuev), onev, vignettecorrv); const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; @@ -388,7 +400,7 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra #endif for (; col < W; ++col) { - const float blur = cfablur[row * W + col] - black[c4[row & 1][col & 1]]; + const float blur = cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]]; const float vignettecorr = blur <= minValue ? 1.f : refcolor[row & 1][col & 1] / blur; rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * vignettecorr + black[c4[row & 1][col & 1]]; } @@ -490,6 +502,10 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra const vfloat blackv[2] = {_mm_set_ps(black[c4[0][1]], black[c4[0][0]], black[c4[0][1]], black[c4[0][0]]), _mm_set_ps(black[c4[1][1]], black[c4[1][0]], black[c4[1][1]], black[c4[1][0]]) }; + const vfloat ffblackv[2] = {_mm_set_ps(ffblack[c4[0][1]], ffblack[c4[0][0]], ffblack[c4[0][1]], ffblack[c4[0][0]]), + _mm_set_ps(ffblack[c4[1][1]], ffblack[c4[1][0]], ffblack[c4[1][1]], ffblack[c4[1][0]]) + }; + const vfloat epsv = F2V(1e-5f); #endif @@ -501,10 +517,11 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra int col = 0; #ifdef __SSE2__ const vfloat rowBlackv = blackv[row & 1]; + const vfloat ffrowBlackv = ffblackv[row & 1]; for (; col < W - 3; col += 4) { - const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - rowBlackv, epsv)) / - (vmaxf(LVFU(cfablur1[row * W + col]) - rowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - rowBlackv, epsv)); + const vfloat linecorrv = SQRV(vmaxf(LVFU(cfablur[row * W + col]) - ffrowBlackv, epsv)) / + (vmaxf(LVFU(cfablur1[row * W + col]) - ffrowBlackv, epsv) * vmaxf(LVFU(cfablur2[row * W + col]) - ffrowBlackv, epsv)); const vfloat valv = LVFU(rawData[row][col]) - rowBlackv; STVFU(rawData[row][col], valv * linecorrv + rowBlackv); } @@ -512,8 +529,8 @@ void RawImageSource::processFlatField(const procparams::RAWParams &raw, const Ra #endif for (; col < W; ++col) { - const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - black[c4[row & 1][col & 1]])) / - (std::max(1e-5f, cfablur1[row * W + col] - black[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - black[c4[row & 1][col & 1]])); + const float linecorr = SQR(std::max(1e-5f, cfablur[row * W + col] - ffblack[c4[row & 1][col & 1]])) / + (std::max(1e-5f, cfablur1[row * W + col] - ffblack[c4[row & 1][col & 1]]) * std::max(1e-5f, cfablur2[row * W + col] - ffblack[c4[row & 1][col & 1]])); rawData[row][col] = (rawData[row][col] - black[c4[row & 1][col & 1]]) * linecorr + black[c4[row & 1][col & 1]]; } } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e65cadaa3..20658c04b 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -138,7 +138,7 @@ public: return rgbSourceModified; // tracks whether cached rgb output of demosaic has been modified } - void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D &rawData, const float black[4]); + void processFlatField(const procparams::RAWParams &raw, RawImage *riFlatFile, array2D &rawData, const float black[4]); void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D &rawData ); void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D &rawData); // raw for cblack void WBauto(bool extra, double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) override; From 91dc97eafb929ab3b658b854847dbe553feaae29 Mon Sep 17 00:00:00 2001 From: Andy Dodd Date: Sun, 17 Mar 2024 09:49:42 -0400 Subject: [PATCH 145/291] Fix regression with demosaiced DNGs caused by 831a9bbd Uses a new function checkRawDataDimensions as suggested/written by @Lawrence37 to verify that image dimensions are correct. Fixes #6996 --- rtengine/rawimagesource.cc | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 8149c0464..03823644b 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -742,9 +742,19 @@ void RawImageSource::getWBMults(const ColorTemp &ctemp, const RAWParams &raw, st autoGainComp = camInitialGain / initialGain; } +bool checkRawDataDimensions(const array2D &rawData, const RawImage &rawImage, int width, int height) +{ + const int colors = (rawImage.getSensorType() == rtengine::ST_BAYER || + rawImage.getSensorType() == rtengine::ST_FUJI_XTRANS || + rawImage.get_colors() == 1) + ? 1 + : 3; + return rawData.getHeight() == height && rawData.getWidth() == colors * width; +} + void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); MyMutex::MyLock lock(getImageMutex); @@ -1747,7 +1757,7 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); MyTime t1, t2; t1.set(); @@ -3842,7 +3852,7 @@ void RawImageSource::hlRecovery(const std::string &method, float* red, float* gr void RawImageSource::getAutoExpHistogram(LUTu & histogram, int& histcompr) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); // BENCHFUN histcompr = 3; @@ -7487,7 +7497,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, double & greenref, double & tempitc, double & greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double & rm, double & gm, double & bm, const WBParams & wbpar, const ColorManagementParams & cmp, const RAWParams & raw, const ToneCurveParams &hrp) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); // BENCHFUN constexpr double clipHigh = 64000.0; @@ -7713,7 +7723,7 @@ void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, doubl void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); // BENCHFUN constexpr double clipHigh = 64000.0; @@ -7931,7 +7941,7 @@ void RawImageSource::getAutoWBMultipliers(double &rm, double &gm, double &bm) ColorTemp RawImageSource::getSpotWB(std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); int x; int y; @@ -8271,7 +8281,7 @@ void RawImageSource::init() void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int &B) { - if (rawData.getWidth() != W || rawData.getHeight() != H || d1x) { // Nikon D1x has special sensor. We just skip it + if (!checkRawDataDimensions(rawData, *ri, W, H) || d1x) { // Nikon D1x has special sensor. We just skip it R = G = B = 0; return; } @@ -8319,7 +8329,7 @@ bool RawImageSource::isGainMapSupported() const void RawImageSource::applyDngGainMap(const float black[4], const std::vector &gainMaps) { - assert(rawData.getHeight() == H && rawData.getWidth() == W); + assert(checkRawDataDimensions(rawData, *ri, W, H)); // now we can apply each gain map to raw_data array2D mvals[2][2]; From c5967cb4e40c50ef480ca64cc40911510c2349ee Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:45:35 -0700 Subject: [PATCH 146/291] Add initial support for OM TG-7 Read CFA pattern for OM Digital Solutions cameras. Use Olympus TG-6 camconst for the TG-7, since the dcraw matrix and raw crop are the same. --- rtengine/camconst.json | 2 +- rtengine/dcraw.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index f834acdbd..ce7eabe71 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2206,7 +2206,7 @@ Camera constants: }, { // Quality B - "make_model": "OLYMPUS TG-6", + "make_model": [ "OLYMPUS TG-6", "OM Digital Solutions TG-7" ], "dcraw_matrix" : [10899, -3833, -1082, -2112, 10736, 1575, -267, 1452, 5269], // DNG v13.2 "raw_crop": [ 0, 0, -24, 0 ] // 24 pixels at right are garbage }, diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 65343e906..621473589 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -10434,7 +10434,7 @@ konica_400z: filters = 0x16161616; load_raw = &CLASS packed_load_raw; load_flags = 30; - } else if (!strcmp(make,"Olympus")) { + } else if (!strcmp(make,"Olympus") || !strncmp(make, "OM Digi", 7)) { height += height & 1; if (exif_cfa) filters = exif_cfa; if (width == 4100) width -= 4; From b46c22dee644e938f3ccfae0a0fddb542780da04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Fri, 16 Feb 2024 22:05:51 -0500 Subject: [PATCH 147/291] iplab2rgb: Fix memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Hubert Figuière --- rtengine/iplab2rgb.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 7620068a4..ffa6ea8c0 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -351,6 +351,7 @@ Imagefloat* ImProcFunctions::lab2rgbOut(LabImage* lab, int cx, int cy, int cw, i image->ExecCMSTransform(hTransform, *lab, cx, cy); cmsDeleteTransform(hTransform); + cmsCloseProfile(iprof); image->normalizeFloatTo65535(); } else { From 6b1afe07cd142c60a35b6f2b2d53206663bfce12 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 23 Mar 2024 17:37:11 -0700 Subject: [PATCH 148/291] Remove Adwaita cursors from Windows build --- .github/workflows/windows.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 875dce60e..6963df7c9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -129,14 +129,6 @@ jobs: "symbolic/ui" \ "$BUILD_DIR/share/icons/Adwaita/symbolic" cp 'index.theme' "$BUILD_DIR/share/icons/Adwaita" - mkdir -p "$BUILD_DIR/share/icons/Adwaita/cursors" - cp -r \ - "cursors/plus.cur" \ - "cursors/sb_h_double_arrow.cur" \ - "cursors/sb_left_arrow.cur" \ - "cursors/sb_right_arrow.cur" \ - "cursors/sb_v_double_arrow.cur" \ - "$BUILD_DIR/share/icons/Adwaita/cursors" cd - echo "Copying GDK pixbuf." From c2a57359fe4b397a202ff2fc643c968c5b023287 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 25 Mar 2024 11:02:03 +0100 Subject: [PATCH 149/291] options: fix BrowseRecursiveFollowLinks reading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #6769 added the boolean BrowseRecursiveFollowLinks options, but while it's saved as a boolean, it's read as an integer causing this error: ``` Options::readFromFile / Error code 5 while reading values from "/home/sgotti/.config/RawTherapee/options": Key file contains key “BrowseRecursiveFollowLinks†in group “File Browser†which has a value that cannot be interpreted. ``` --- rtgui/options.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 81271acde..c8750809b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -1364,7 +1364,7 @@ void Options::readFromFile(Glib::ustring fname) } if (keyFile.has_key("File Browser", "BrowseRecursiveFollowLinks")) { - browseRecursiveFollowLinks = keyFile.get_integer("File Browser", "BrowseRecursiveFollowLinks"); + browseRecursiveFollowLinks = keyFile.get_boolean("File Browser", "BrowseRecursiveFollowLinks"); } } From 13eddbdd94f1e220ca818ded02341d341e28dbdc Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Fri, 22 Mar 2024 13:49:31 +0100 Subject: [PATCH 150/291] dcraw: handle fujifilm lossy compression port from libraw handling of fujifilm lossy compression. --- rtengine/dcraw.h | 43 +++- rtengine/fujicompressed.cc | 491 ++++++++++++++++++++++++------------- 2 files changed, 354 insertions(+), 180 deletions(-) diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index f932e2472..eaf87d618 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -109,16 +109,24 @@ protected: unsigned black, cblack[4102], maximum, mix_green, raw_color, zero_is_bad; unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; unsigned tile_width, tile_length, gpsdata[32], load_flags, row_padding; - bool xtransCompressed = false; + + struct fuji_q_table + { + int8_t *q_table; /* quantization table */ + int raw_bits; + int total_values; + int max_grad; // sdp val + int q_grad_mult; // quant_gradient multiplier + int q_base; + }; + struct fuji_compressed_params { - char *q_table; /* quantization table */ - int q_point[5]; /* quantization points */ + struct fuji_q_table qt[4]; + void *buf; int max_bits; int min_value; - int raw_bits; - int total_values; - int maxDiff; + int max_value; ushort line_width; }; @@ -135,6 +143,13 @@ protected: _ltotal }; + // tables of gradients for single sample level + struct fuji_grads + { + int_pair grads[41]; + int_pair lossy_grads[3][5]; + }; + struct fuji_compressed_block { int cur_bit; // current bit being read (from left to right) int cur_pos; // current position in a buffer @@ -144,13 +159,13 @@ protected: uchar *cur_buf; // currently read block int fillbytes; // Counter to add extra byte for block size N*16 rtengine::IMFILE *input; - struct int_pair grad_even[3][41]; // tables of gradients - struct int_pair grad_odd[3][41]; + fuji_grads even[3]; // tables of even gradients + fuji_grads odd[3]; // tables of odd gradients ushort *linealloc; ushort *linebuf[_ltotal]; }; - int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, fuji_raw_type; + int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, fuji_raw_type, fuji_lossless; ushort raw_height, raw_width, height, width, top_margin, left_margin; ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; @@ -374,6 +389,8 @@ void adobe_copy_pixel (unsigned row, unsigned col, ushort **rp); void lossless_dng_load_raw(); void packed_dng_load_raw(); void deflate_dng_load_raw(); +void init_fuji_main_qtable(fuji_compressed_params *params, uchar q_base); +void init_fuji_main_grads(const fuji_compressed_params *params, fuji_compressed_block *info); void init_fuji_compr(struct fuji_compressed_params* info); void fuji_fill_buffer(struct fuji_compressed_block *info); void init_fuji_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params, INT64 raw_offset, unsigned dsize); @@ -381,8 +398,8 @@ void copy_line_to_xtrans(struct fuji_compressed_block* info, int cur_line, int c void copy_line_to_bayer(struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width); void fuji_zerobits(struct fuji_compressed_block* info, int *count); void fuji_read_code(struct fuji_compressed_block* info, int *data, int bits_to_read); -int fuji_decode_sample_even(struct fuji_compressed_block* info, const struct fuji_compressed_params * params, ushort* line_buf, int pos, struct int_pair* grads); -int fuji_decode_sample_odd(struct fuji_compressed_block* info, const struct fuji_compressed_params * params, ushort* line_buf, int pos, struct int_pair* grads); +int fuji_decode_sample_even(struct fuji_compressed_block* info, const struct fuji_compressed_params* params, ushort* line_buf, int pos, struct fuji_grads* grad_params); +int fuji_decode_sample_odd(struct fuji_compressed_block* info, const struct fuji_compressed_params* params, ushort* line_buf, int pos, struct fuji_grads* grad_params); void fuji_decode_interpolation_even(int line_width, ushort* line_buf, int pos); void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, int end); void fuji_extend_red(ushort *linebuf[_ltotal], int line_width); @@ -390,9 +407,9 @@ void fuji_extend_green(ushort *linebuf[_ltotal], int line_width); void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width); void xtrans_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params); void fuji_bayer_decode_block(struct fuji_compressed_block* info, const struct fuji_compressed_params *params); -void fuji_decode_strip(const struct fuji_compressed_params* info_common, int cur_block, INT64 raw_offset, unsigned dsize); +void fuji_decode_strip (fuji_compressed_params* params, int cur_block, INT64 raw_offset, unsigned dsize, uchar *q_bases); void fuji_compressed_load_raw(); -void fuji_decode_loop(const struct fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes); +void fuji_decode_loop(fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes, uchar *q_bases); void parse_fuji_compressed_header(); void fuji_14bit_load_raw(); void pentax_load_raw(); diff --git a/rtengine/fujicompressed.cc b/rtengine/fujicompressed.cc index c1c620657..0bae92356 100644 --- a/rtengine/fujicompressed.cc +++ b/rtengine/fujicompressed.cc @@ -31,75 +31,164 @@ int bitDiff (int value1, int value2) return decBits; } +static inline int log2ceil(int val) +{ + int result = 0; + if (val--) + do + ++result; + while (val >>= 1); + + return result; } -void CLASS init_fuji_compr (struct fuji_compressed_params* info) +void setup_qlut(int8_t *qt, int *q_point) { - int cur_val; - char *qt; + for (int curVal = -q_point[4]; curVal <= q_point[4]; ++qt, ++curVal) + { + if (curVal <= -q_point[3]) + *qt = -4; + else if (curVal <= -q_point[2]) + *qt = -3; + else if (curVal <= -q_point[1]) + *qt = -2; + else if (curVal < -q_point[0]) + *qt = -1; + else if (curVal <= q_point[0]) + *qt = 0; + else if (curVal < q_point[1]) + *qt = 1; + else if (curVal < q_point[2]) + *qt = 2; + else if (curVal < q_point[3]) + *qt = 3; + else + *qt = 4; + } +} +} // namespace + +void CLASS init_fuji_main_qtable(fuji_compressed_params *params, uchar q_base) +{ + fuji_q_table *qt = params->qt; + int qp[5]; + int maxVal = params->max_value + 1; + qp[0] = q_base; + qp[1] = 3 * q_base + 0x12; + qp[2] = 5 * q_base + 0x43; + qp[3] = 7 * q_base + 0x114; + qp[4] = params->max_value; + if (qp[1] >= maxVal || qp[1] < q_base + 1) + qp[1] = q_base + 1; + if (qp[2] < qp[1] || qp[2] >= maxVal) + qp[2] = qp[1]; + if (qp[3] < qp[2] || qp[3] >= maxVal) + qp[3] = qp[2]; + setup_qlut(qt->q_table, qp); + qt->q_base = q_base; + qt->max_grad = 0; + qt->total_values = (qp[4] + 2 * q_base) / (2 * q_base + 1) + 1; + qt->raw_bits = log2ceil(qt->total_values); + qt->q_grad_mult = 9; + params->max_bits = 4 * log2ceil(qp[4] + 1); +} + +void CLASS init_fuji_main_grads(const fuji_compressed_params *params, fuji_compressed_block *info) +{ + int max_diff = std::max(2, (params->qt->total_values + 0x20) >> 6); + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 41; i++) { + info->even[j].grads[i].value1 = max_diff; + info->even[j].grads[i].value2 = 1; + info->odd[j].grads[i].value1 = max_diff; + info->odd[j].grads[i].value2 = 1; + } + } +} + +void CLASS init_fuji_compr (struct fuji_compressed_params* params) +{ if ((fuji_block_width % 3 && fuji_raw_type == 16) || (fuji_block_width & 1 && fuji_raw_type == 0)) { derror(); } - info->q_table = (char *) malloc (2 << fuji_bits); - merror (info->q_table, "init_fuji_compr()"); + size_t q_table_size = 2 << fuji_bits; + if (fuji_lossless) { + params->buf = malloc(q_table_size); + } else { + params->buf = malloc(3 * q_table_size); + } + merror (params->buf, "init_fuji_compr()"); if (fuji_raw_type == 16) { - info->line_width = (fuji_block_width * 2) / 3; + params->line_width = (fuji_block_width * 2) / 3; } else { - info->line_width = fuji_block_width >> 1; + params->line_width = fuji_block_width >> 1; } - info->q_point[0] = 0; - info->q_point[1] = 0x12; - info->q_point[2] = 0x43; - info->q_point[3] = 0x114; - info->q_point[4] = (1 << fuji_bits) - 1; - info->min_value = 0x40; + params->min_value = 0x40; + params->max_value = (1 << fuji_bits) - 1; - cur_val = -info->q_point[4]; - - for (qt = info->q_table; cur_val <= info->q_point[4]; ++qt, ++cur_val) { - if (cur_val <= -info->q_point[3]) { - *qt = -4; - } else if (cur_val <= -info->q_point[2]) { - *qt = -3; - } else if (cur_val <= -info->q_point[1]) { - *qt = -2; - } else if (cur_val < 0) { - *qt = -1; - } else if (cur_val == 0) { - *qt = 0; - } else if (cur_val < info->q_point[1]) { - *qt = 1; - } else if (cur_val < info->q_point[2]) { - *qt = 2; - } else if (cur_val < info->q_point[3]) { - *qt = 3; - } else { - *qt = 4; - } + // setup qtables + if (fuji_lossless) + { + // setup main qtable only, zero the rest + memset(params->qt + 1, 0, 3 * sizeof(fuji_q_table)); + params->qt[0].q_table = (int8_t *)params->buf; + params->qt[0].q_base = -1; + init_fuji_main_qtable(params, 0); } + else + { + // setup 3 extra qtables - main one will be set for each block + memset(params->qt, 0, sizeof(fuji_q_table)); + int qp[5]; - // populting gradients - //if (info->q_point[4] == 0x3FFF) { - // info->total_values = 0x4000; - // info->raw_bits = 14; - // info->max_bits = 56; - // info->maxDiff = 256; - //} else if (info->q_point[4] == 0xFFF) { - // info->total_values = 4096; - // info->raw_bits = 12; - // info->max_bits = 48; - // info->maxDiff = 64; - //} else { - // derror(); - //} - info->total_values = (1 << fuji_bits); - info->raw_bits = fuji_bits; - info->max_bits = 4 * info->raw_bits; - info->maxDiff = info->total_values >> 6; + qp[0] = 0; + qp[4] = params->max_value; + + // table 0 + params->qt[1].q_table = (int8_t *)params->buf; + params->qt[1].q_base = 0; + params->qt[1].max_grad = 5; + params->qt[1].q_grad_mult = 3; + params->qt[1].total_values = qp[4] + 1; + params->qt[1].raw_bits = log2ceil(params->qt[1].total_values); + + qp[1] = qp[4] >= 0x12 ? 0x12 : qp[0] + 1; + qp[2] = qp[4] >= 0x43 ? 0x43 : qp[1]; + qp[3] = qp[4] >= 0x114 ? 0x114 : qp[2]; + setup_qlut(params->qt[1].q_table, qp); + + // table 1 + params->qt[2].q_table = params->qt[1].q_table + q_table_size; + params->qt[2].q_base = 1; + params->qt[2].max_grad = 6; + params->qt[2].q_grad_mult = 3; + params->qt[2].total_values = (qp[4] + 2) / 3 + 1; + params->qt[2].raw_bits = log2ceil(params->qt[2].total_values); + + qp[0] = params->qt[2].q_base; + qp[1] = qp[4] >= 0x15 ? 0x15 : qp[0] + 1; + qp[2] = qp[4] >= 0x48 ? 0x48 : qp[1]; + qp[3] = qp[4] >= 0x11B ? 0x11B : qp[2]; + setup_qlut(params->qt[2].q_table, qp); + + // table 2 + params->qt[3].q_table = params->qt[2].q_table + q_table_size; + params->qt[3].q_base = 2; + params->qt[3].max_grad = 7; + params->qt[3].q_grad_mult = 3; + params->qt[3].total_values = (qp[4] + 4) / 5 + 1; + params->qt[3].raw_bits = log2ceil(params->qt[3].total_values); + + qp[0] = params->qt[3].q_base; + qp[1] = qp[4] >= 0x18 ? 0x18 : qp[0] + 1; + qp[2] = qp[4] >= 0x4D ? 0x4D : qp[1]; + qp[3] = qp[4] >= 0x122 ? 0x122 : qp[2]; + setup_qlut(params->qt[3].q_table, qp); + } } #define FUJI_BUF_SIZE 0x10000u @@ -157,17 +246,26 @@ void CLASS init_fuji_block (struct fuji_compressed_block* info, const struct fuj info->cur_bit = 0; info->cur_pos = 0; info->cur_buf_offset = raw_offset; - - for (int j = 0; j < 3; j++) - for (int i = 0; i < 41; i++) { - info->grad_even[j][i].value1 = params->maxDiff; - info->grad_even[j][i].value2 = 1; - info->grad_odd[j][i].value1 = params->maxDiff; - info->grad_odd[j][i].value2 = 1; - } - info->cur_buf_size = 0; fuji_fill_buffer (info); + + // init grads for lossy and lossless + if (fuji_lossless) { + init_fuji_main_grads(params, info); + } else { + // init static grads for lossy only - main ones are done per line + for (int k = 0; k < 3; ++k) { + int max_diff = std::max(2, ((params->qt[k + 1].total_values + 0x20) >> 6)); + for (int j = 0; j < 3; ++j) { + for (int i = 0; i < 5; ++i) { + info->even[j].lossy_grads[k][i].value1 = max_diff; + info->even[j].lossy_grads[k][i].value2 = 1; + info->odd[j].lossy_grads[k][i].value1 = max_diff; + info->odd[j].lossy_grads[k][i].value2 = 1; + } + } + } + } } void CLASS copy_line_to_xtrans (struct fuji_compressed_block* info, int cur_line, int cur_block, int cur_block_width) @@ -278,7 +376,7 @@ void CLASS copy_line_to_bayer (struct fuji_compressed_block *info, int cur_line, } -#define fuji_quant_gradient(i,v1,v2) (9*i->q_table[i->q_point[4]+(v1)] + i->q_table[i->q_point[4]+(v2)]) +#define fuji_quant_gradient(max, q, v1, v2) (q->q_grad_mult * q->q_table[(max) + (v1)] + q->q_table[(max) + (v2)]) inline void CLASS fuji_zerobits (struct fuji_compressed_block* info, int *count) { @@ -340,7 +438,7 @@ inline void CLASS fuji_read_code (struct fuji_compressed_block* info, int *data, info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; } -int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const struct fuji_compressed_params * params, ushort* line_buf, int pos, struct int_pair* grads) +int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const struct fuji_compressed_params* params, ushort* line_buf, int pos, struct fuji_grads* grad_params) { int interp_val = 0; int errcnt = 0; @@ -354,11 +452,22 @@ int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const str int grad, gradient, diffRcRb, diffRfRb, diffRdRb; - grad = fuji_quant_gradient (params, Rb - Rf, Rc - Rb); - gradient = std::abs (grad); - diffRcRb = std::abs (Rc - Rb); - diffRfRb = std::abs (Rf - Rb); - diffRdRb = std::abs (Rd - Rb); + diffRcRb = std::abs(Rc - Rb); + diffRfRb = std::abs(Rf - Rb); + diffRdRb = std::abs(Rd - Rb); + + const fuji_q_table *qt = params->qt; + int_pair *grads = grad_params->grads; + for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) { + if (diffRfRb + diffRcRb <= params->qt[i].max_grad) { + qt = params->qt + i; + grads = grad_params->lossy_grads[i - 1]; + break; + } + } + + grad = fuji_quant_gradient(params->max_value, qt, Rb - Rf, Rc - Rb); + gradient = std::abs(grad); if ( diffRcRb > diffRfRb && diffRcRb > diffRdRb ) { interp_val = Rf + Rd + 2 * Rb; @@ -371,16 +480,16 @@ int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const str fuji_zerobits (info, &sample); - if (sample < params->max_bits - params->raw_bits - 1) { + if (sample < params->max_bits - qt->raw_bits - 1) { int decBits = bitDiff (grads[gradient].value1, grads[gradient].value2); fuji_read_code (info, &code, decBits); code += sample << decBits; } else { - fuji_read_code (info, &code, params->raw_bits); + fuji_read_code (info, &code, qt->raw_bits); code++; } - if (code < 0 || code >= params->total_values) { + if (code < 0 || code >= qt->total_values) { errcnt++; } @@ -400,19 +509,19 @@ int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const str grads[gradient].value2++; if (grad < 0) { - interp_val = (interp_val >> 2) - code; + interp_val = (interp_val >> 2) - code * (2 * qt->q_base + 1); } else { - interp_val = (interp_val >> 2) + code; + interp_val = (interp_val >> 2) + code * (2 * qt->q_base + 1); } - if ( interp_val < 0 ) { - interp_val += params->total_values; - } else if (interp_val > params->q_point[4]) { - interp_val -= params->total_values; + if (interp_val < -qt->q_base) { + interp_val += qt->total_values * (2 * qt->q_base + 1); + } else if (interp_val > qt->q_base + params->max_value) { + interp_val -= qt->total_values * (2 * qt->q_base + 1); } - if ( interp_val >= 0 ) { - line_buf_cur[0] = std::min (interp_val, params->q_point[4]); + if (interp_val >= 0) { + line_buf_cur[0] = std::min(interp_val, params->max_value); } else { line_buf_cur[0] = 0; } @@ -420,7 +529,7 @@ int CLASS fuji_decode_sample_even (struct fuji_compressed_block* info, const str return errcnt; } -int CLASS fuji_decode_sample_odd (struct fuji_compressed_block* info, const struct fuji_compressed_params * params, ushort* line_buf, int pos, struct int_pair* grads) +int CLASS fuji_decode_sample_odd (struct fuji_compressed_block* info, const struct fuji_compressed_params* params, ushort* line_buf, int pos, struct fuji_grads* grad_params) { int interp_val = 0; int errcnt = 0; @@ -435,7 +544,20 @@ int CLASS fuji_decode_sample_odd (struct fuji_compressed_block* info, const stru int grad, gradient; - grad = fuji_quant_gradient (params, Rb - Rc, Rc - Ra); + int diffRcRa = std::abs(Rc - Ra); + int diffRbRc = std::abs(Rb - Rc); + + const fuji_q_table *qt = params->qt; + int_pair *grads = grad_params->grads; + for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) + if (diffRbRc + diffRcRa <= params->qt[i].max_grad) + { + qt = params->qt + i; + grads = grad_params->lossy_grads[i - 1]; + break; + } + + grad = fuji_quant_gradient(params->max_value, qt, Rb - Rc, Rc - Ra); gradient = std::abs (grad); if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd)) { @@ -446,16 +568,16 @@ int CLASS fuji_decode_sample_odd (struct fuji_compressed_block* info, const stru fuji_zerobits (info, &sample); - if (sample < params->max_bits - params->raw_bits - 1) { + if (sample < params->max_bits - qt->raw_bits - 1) { int decBits = bitDiff (grads[gradient].value1, grads[gradient].value2); fuji_read_code (info, &code, decBits); code += sample << decBits; } else { - fuji_read_code (info, &code, params->raw_bits); + fuji_read_code (info, &code, qt->raw_bits); code++; } - if (code < 0 || code >= params->total_values) { + if (code < 0 || code >= qt->total_values) { errcnt++; } @@ -475,19 +597,19 @@ int CLASS fuji_decode_sample_odd (struct fuji_compressed_block* info, const stru grads[gradient].value2++; if (grad < 0) { - interp_val -= code; + interp_val -= code * (2 * qt->q_base + 1); } else { - interp_val += code; + interp_val += code * (2 * qt->q_base + 1); } - if ( interp_val < 0 ) { - interp_val += params->total_values; - } else if (interp_val > params->q_point[4]) { - interp_val -= params->total_values; + if (interp_val < -qt->q_base) { + interp_val += qt->total_values * (2 * qt->q_base + 1); + } else if (interp_val > qt->q_base + params->max_value) { + interp_val -= qt->total_values * (2 * qt->q_base + 1); } - if ( interp_val >= 0 ) { - line_buf_cur[0] = std::min (interp_val, params->q_point[4]); + if (interp_val >= 0) { + line_buf_cur[0] = std::min(interp_val, params->max_value); } else { line_buf_cur[0] = 0; } @@ -552,14 +674,14 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct if (g_even_pos < line_width) { fuji_decode_interpolation_even (line_width, info->linebuf[_R2] + 1, r_even_pos); r_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G2] + 1, g_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R2] + 1, r_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G2] + 1, g_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; } } @@ -571,16 +693,16 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G3] + 1, g_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; fuji_decode_interpolation_even (line_width, info->linebuf[_B2] + 1, b_even_pos); b_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G3] + 1, g_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B2] + 1, b_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); b_odd_pos += 2; } } @@ -594,7 +716,7 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { if (r_even_pos & 3) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R3] + 1, r_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); } else { fuji_decode_interpolation_even (line_width, info->linebuf[_R3] + 1, r_even_pos); } @@ -605,9 +727,9 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R3] + 1, r_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G4] + 1, g_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; } } @@ -620,22 +742,22 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G5] + 1, g_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; if ((b_even_pos & 3) == 2) { fuji_decode_interpolation_even (line_width, info->linebuf[_B3] + 1, b_even_pos); } else { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B3] + 1, b_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); } b_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G5] + 1, g_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B3] + 1, b_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); b_odd_pos += 2; } } @@ -651,18 +773,18 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct if ((r_even_pos & 3) == 2) { fuji_decode_interpolation_even (line_width, info->linebuf[_R4] + 1, r_even_pos); } else { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R4] + 1, r_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); } r_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G6] + 1, g_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R4] + 1, r_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G6] + 1, g_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; } } @@ -679,7 +801,7 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct g_even_pos += 2; if (b_even_pos & 3) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B4] + 1, b_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); } else { fuji_decode_interpolation_even (line_width, info->linebuf[_B4] + 1, b_even_pos); } @@ -688,9 +810,9 @@ void CLASS xtrans_decode_block (struct fuji_compressed_block* info, const struct } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G7] + 1, g_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B4] + 1, b_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); b_odd_pos += 2; } } @@ -715,16 +837,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R2] + 1, r_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R2] + 1, r_even_pos, &info->even[0]); r_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G2] + 1, g_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R2] + 1, r_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G2] + 1, g_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; } } @@ -736,16 +858,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G3] + 1, g_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B2] + 1, b_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B2] + 1, b_even_pos, &info->even[1]); b_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G3] + 1, g_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B2] + 1, b_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); b_odd_pos += 2; } } @@ -758,16 +880,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R3] + 1, r_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); r_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G4] + 1, g_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G4] + 1, g_even_pos, &info->even[2]); g_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R3] + 1, r_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G4] + 1, g_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; } } @@ -780,16 +902,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G5] + 1, g_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); g_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B3] + 1, b_even_pos, info->grad_even[0]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); b_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G5] + 1, g_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B3] + 1, b_odd_pos, info->grad_odd[0]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); b_odd_pos += 2; } } @@ -802,16 +924,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R4] + 1, r_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); r_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G6] + 1, g_even_pos, info->grad_even[1]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); g_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R4] + 1, r_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); r_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G6] + 1, g_odd_pos, info->grad_odd[1]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); g_odd_pos += 2; } } @@ -824,16 +946,16 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st while (g_even_pos < line_width || g_odd_pos < line_width) { if (g_even_pos < line_width) { - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G7] + 1, g_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_G7] + 1, g_even_pos, &info->even[2]); g_even_pos += 2; - errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B4] + 1, b_even_pos, info->grad_even[2]); + errcnt += fuji_decode_sample_even (info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); b_even_pos += 2; } if (g_even_pos > 8) { - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G7] + 1, g_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); g_odd_pos += 2; - errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B4] + 1, b_odd_pos, info->grad_odd[2]); + errcnt += fuji_decode_sample_odd (info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); b_odd_pos += 2; } } @@ -846,11 +968,21 @@ void CLASS fuji_bayer_decode_block (struct fuji_compressed_block *info, const st } } -void CLASS fuji_decode_strip (const struct fuji_compressed_params* info_common, int cur_block, INT64 raw_offset, unsigned dsize) +void CLASS fuji_decode_strip (fuji_compressed_params* params, int cur_block, INT64 raw_offset, unsigned dsize, uchar *q_bases) { int cur_block_width, cur_line; unsigned line_size; - struct fuji_compressed_block info; + fuji_compressed_block info; + fuji_compressed_params *info_common = params; + + if (!fuji_lossless) { + int buf_size = sizeof(fuji_compressed_params) + (2 << fuji_bits); + + info_common = (fuji_compressed_params *)malloc(buf_size); + memcpy(info_common, params, sizeof(fuji_compressed_params)); + info_common->qt[0].q_table = (int8_t *)(info_common + 1); + info_common->qt[0].q_base = -1; + } init_fuji_block (&info, info_common, raw_offset, dsize); line_size = sizeof (ushort) * (info_common->line_width + 2); @@ -869,6 +1001,17 @@ void CLASS fuji_decode_strip (const struct fuji_compressed_params* info_common, ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}}; for (cur_line = 0; cur_line < fuji_total_lines; cur_line++) { + // init grads and main qtable + if (!fuji_lossless) + { + int q_base = q_bases ? q_bases[cur_line] : 0; + if (!cur_line || q_base != info_common->qt[0].q_base) + { + init_fuji_main_qtable(info_common, q_bases[cur_line]); + init_fuji_main_grads(info_common, &info); + } + } + if (fuji_raw_type == 16) { xtrans_decode_block (&info, info_common); } else { @@ -894,6 +1037,8 @@ void CLASS fuji_decode_strip (const struct fuji_compressed_params* info_common, } // release data + if (!fuji_lossless) + free (info_common); free (info.linealloc); #ifndef MYFILE_MMAP free (info.cur_buf); @@ -916,8 +1061,8 @@ void CLASS fuji_compressed_load_raw() struct fuji_compressed_params common_info; int cur_block; unsigned *block_sizes; + uchar *q_bases = 0; INT64 raw_offset, *raw_block_offsets; - //struct fuji_compressed_block info; init_fuji_compr (&common_info); @@ -927,17 +1072,30 @@ void CLASS fuji_compressed_load_raw() raw_block_offsets = (INT64*) malloc (sizeof (INT64) * fuji_total_blocks); merror (raw_block_offsets, "fuji_compressed_load_raw()"); - raw_offset = sizeof (unsigned) * fuji_total_blocks; + fseek(ifp, data_offset, SEEK_SET); + int sizesToRead = sizeof(unsigned) * fuji_total_blocks; + if (fread(block_sizes, 1, sizesToRead, ifp) != sizesToRead) + { + free(block_sizes); + free(raw_block_offsets); + derror(); + return; + } - if (raw_offset & 0xC) { - raw_offset += 0x10 - (raw_offset & 0xC); + raw_offset = ((sizeof(unsigned) * fuji_total_blocks) + 0xF) & ~0xF; + + // read q bases for lossy + if (!fuji_lossless) { + int total_q_bases = fuji_total_blocks * ((fuji_total_lines + 0xF) & ~0xF); + q_bases = (uchar *)malloc(total_q_bases); + merror (q_bases, "fuji_compressed_load_raw()"); + fseek(ifp, raw_offset + data_offset, SEEK_SET); + fread(q_bases, 1, total_q_bases, ifp); + raw_offset += total_q_bases; } raw_offset += data_offset; - fseek (ifp, data_offset, SEEK_SET); - fread (block_sizes, 1, sizeof (unsigned)*fuji_total_blocks, ifp); - raw_block_offsets[0] = raw_offset; // calculating raw block offsets @@ -950,33 +1108,34 @@ void CLASS fuji_compressed_load_raw() raw_block_offsets[cur_block] = raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1] ; } - fuji_decode_loop (&common_info, fuji_total_blocks, raw_block_offsets, block_sizes); + fuji_decode_loop (&common_info, fuji_total_blocks, raw_block_offsets, block_sizes, q_bases); - free (block_sizes); - free (raw_block_offsets); - free (common_info.q_table); + free(q_bases); + free(block_sizes); + free(raw_block_offsets); + free(common_info.buf); } -void CLASS fuji_decode_loop (const struct fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes) +void CLASS fuji_decode_loop (fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes, uchar *q_bases) { + const int lineStep = (fuji_total_lines + 0xF) & ~0xF; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,1) // dynamic scheduling is faster if count > number of cores (e.g. count for GFX 50S is 12) #endif for (int cur_block = 0; cur_block < count ; cur_block++) { - fuji_decode_strip (common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block]); + fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block], q_bases ? q_bases + cur_block * lineStep : 0); } } - void CLASS parse_fuji_compressed_header() { uchar header[16]; ushort signature; - uchar version; + uchar lossless; uchar h_raw_type; uchar h_raw_bits; ushort h_raw_height; @@ -987,10 +1146,10 @@ void CLASS parse_fuji_compressed_header() ushort h_total_lines; fseek (ifp, data_offset, SEEK_SET); - fread (header, 1, sizeof (header), ifp); + if (fread(header, 1, sizeof (header), ifp) != sizeof(header)) return; signature = sgetn (2, header); - version = header[2]; + lossless = header[2]; h_raw_type = header[3]; h_raw_bits = header[4]; h_raw_height = sgetn (2, header + 5); @@ -1000,32 +1159,29 @@ void CLASS parse_fuji_compressed_header() h_blocks_in_row = header[13]; h_total_lines = sgetn (2, header + 14); - // general validation if (signature != 0x4953 - || version != 1 - || h_raw_height > 0x3000 + || lossless > 1 + || h_raw_height > 0x4002 || h_raw_height < 6 || h_raw_height % 6 - || h_raw_width > 0x3000 + || h_raw_width > 0x4200 || h_raw_width < 0x300 || h_raw_width % 24 - || h_raw_rounded_width > 0x3000 - || h_block_size != 0x300 + || h_raw_rounded_width > 0x4200 || h_raw_rounded_width < h_block_size || h_raw_rounded_width % h_block_size || h_raw_rounded_width - h_raw_width >= h_block_size + || h_block_size != 0x300 || h_blocks_in_row > 0x10 || h_blocks_in_row == 0 || h_blocks_in_row != h_raw_rounded_width / h_block_size - || h_total_lines > 0x800 + || h_total_lines > 0xAAB || h_total_lines == 0 || h_total_lines != h_raw_height / 6 || (h_raw_bits != 12 && h_raw_bits != 14 && h_raw_bits != 16) - || (h_raw_type != 16 && h_raw_type != 0)) { - xtransCompressed = false; - return; - } + || (h_raw_type != 16 && h_raw_type != 0)) + return; // modify data fuji_total_lines = h_total_lines; @@ -1033,6 +1189,7 @@ void CLASS parse_fuji_compressed_header() fuji_block_width = h_block_size; fuji_bits = h_raw_bits; fuji_raw_type = h_raw_type; + fuji_lossless = lossless; raw_width = h_raw_width; raw_height = h_raw_height; data_offset += 16; From 65c68364a942df9aefb120cd5ec9d6767222e756 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Wed, 20 Mar 2024 17:24:30 +0100 Subject: [PATCH 151/291] dcraw: add support for Fujifilm GFX 100 II --- rtengine/camconst.json | 11 +++++++++++ rtengine/dcraw.cc | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index ce7eabe71..06c23afae 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1456,6 +1456,17 @@ Camera constants: ] }, + { // Quality C + "make_model": [ "FUJIFILM GFX100 II" ], + "dcraw_matrix" : [ 12806, -5779, -1110, -3546, 11507, 2318, -177, 996, 5715 ], // adobe dcp d65 + "raw_crop": [ + // multi-aspect crop to account for 16-shot pixel shift images + { "frame" : [11808, 8754], "crop" : [ 0, 0, 11664, 8750 ] }, + // this crop has been copied from the GFX 100 one, no sample pixel shift images are available + { "frame" : [23616, 17508], "crop" : [ 0, 4, 23328, 17468 ] } + ] + }, + { // Quality B "make_model": [ "FUJIFILM GFX 50R", "FUJIFILM GFX 50S", "FUJIFILM GFX50S II" ], "dcraw_matrix": [ 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 ], // DNGv9.9 D65 diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 621473589..56d400d3d 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -9676,7 +9676,7 @@ void CLASS identify() apply_tiff(); if (!strcmp(model, "X-T3")) { height = raw_height - 2; - } else if (!strcmp(model, "GFX 100") || !strcmp(model, "GFX100S")) { + } else if (!strcmp(model, "GFX 100") || !strcmp(model, "GFX100S") || !strcmp(model, "GFX100 II")) { load_flags = 0; } if (!load_raw) { From 52e88e89542cfd3e6e87ca10ebc70ae1048b2890 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Fri, 29 Mar 2024 15:16:55 +0100 Subject: [PATCH 152/291] imageio: fix issues/crash on png with transparency If a png has a transparency chunk (tRNS), after converting the transparency to alpha we should also strip alpha (color_type is not updated with PNG_COLOR_MASK_ALPHA flag set) or the row parsing will return also the alpha channel causing a memory overflow. --- rtengine/imageio.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index e2c6c1310..f096213dc 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -285,6 +285,7 @@ int ImageIO::loadPNG (const Glib::ustring &fname) if (png_get_valid(png, info, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png); + png_set_strip_alpha(png); } if (color_type & PNG_COLOR_MASK_ALPHA) { From dcc983331dca43c660aceb231704fdeeddbf4be8 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Tue, 12 Mar 2024 08:50:44 +0100 Subject: [PATCH 153/291] thumbnail: rename get/setStage to get/setTrashed Also return a bool in getTrashed since it's already used as a bool in setTrash and in all the checks. --- rtgui/filebrowser.cc | 24 ++++++++++++------------ rtgui/filecatalog.cc | 4 ++-- rtgui/thumbnail.cc | 18 +++++++++--------- rtgui/thumbnail.h | 4 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 26f0d5cd6..661b6051a 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -547,13 +547,13 @@ void FileBrowser::rightClicked () untrash->set_sensitive (false); for (size_t i = 0; i < selected.size(); i++) - if ((static_cast(selected[i]))->thumbnail->getStage()) { + if ((static_cast(selected[i]))->thumbnail->getTrashed()) { untrash->set_sensitive (true); break; } for (size_t i = 0; i < selected.size(); i++) - if (!(static_cast(selected[i]))->thumbnail->getStage()) { + if (!(static_cast(selected[i]))->thumbnail->getTrashed()) { trash->set_sensitive (true); break; } @@ -649,7 +649,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) entry->addButtonSet(new FileThumbnailButtonSet(entry)); entry->getThumbButtonSet()->setRank(entry->thumbnail->getRank()); entry->getThumbButtonSet()->setColorLabel(entry->thumbnail->getColorLabel()); - entry->getThumbButtonSet()->setInTrash(entry->thumbnail->getStage()); + entry->getThumbButtonSet()->setInTrash(entry->thumbnail->getTrashed()); entry->getThumbButtonSet()->setButtonListener(this); entry->resize(getThumbnailHeight()); entry->filtered = !checkFilter(entry); @@ -1023,12 +1023,12 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) const auto thumbnail = mselected[i]->thumbnail; const auto rank = thumbnail->getRank(); const auto colorLabel = thumbnail->getColorLabel(); - const auto stage = thumbnail->getStage(); + const auto stage = thumbnail->getTrashed(); thumbnail->createProcParamsForUpdate (false, true); thumbnail->setRank(rank); thumbnail->setColorLabel(colorLabel); - thumbnail->setStage(stage); + thumbnail->setTrashed(stage); // Empty run to update the thumb rtengine::procparams::ProcParams params = thumbnail->getProcParams (); @@ -1558,8 +1558,8 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> ((entry->thumbnail->isRecentlySaved() && filter.showRecentlySaved[0]) && !filter.showRecentlySaved[1]) || ((!entry->thumbnail->isRecentlySaved() && filter.showRecentlySaved[1]) && !filter.showRecentlySaved[0]) || - (entry->thumbnail->getStage() && !filter.showTrash) || - (!entry->thumbnail->getStage() && !filter.showNotTrash)) { + (entry->thumbnail->getTrashed() && !filter.showTrash) || + (!entry->thumbnail->getTrashed() && !filter.showNotTrash)) { return false; } @@ -1625,11 +1625,11 @@ void FileBrowser::toTrashRequested (std::vector tbe) // no need to notify listeners as item goes to trash, likely to be deleted - if (tbe[i]->thumbnail->getStage()) { + if (tbe[i]->thumbnail->getTrashed()) { continue; } - tbe[i]->thumbnail->setStage (true); + tbe[i]->thumbnail->setTrashed (true); if (tbe[i]->getThumbButtonSet()) { tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); @@ -1649,11 +1649,11 @@ void FileBrowser::fromTrashRequested (std::vector tbe) for (size_t i = 0; i < tbe.size(); i++) { // if thumbnail was marked inTrash=true then param file must be there, no need to run customprofilebuilder - if (!tbe[i]->thumbnail->getStage()) { + if (!tbe[i]->thumbnail->getTrashed()) { continue; } - tbe[i]->thumbnail->setStage (false); + tbe[i]->thumbnail->setTrashed (false); if (tbe[i]->getThumbButtonSet()) { tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); @@ -1784,7 +1784,7 @@ void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionD FileBrowserEntry* entry = static_cast(actionData); tbe.push_back (entry); - if (!entry->thumbnail->getStage()) { + if (!entry->thumbnail->getTrashed()) { toTrashRequested (tbe); } else { fromTrashRequested (tbe); diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 69b9e6dc9..8c5a70628 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1910,7 +1910,7 @@ void FileCatalog::emptyTrash () std::vector toDel; for (const auto entry : t) { - if ((static_cast(entry))->thumbnail->getStage() == 1) { + if ((static_cast(entry))->thumbnail->getTrashed()) { toDel.push_back(static_cast(entry)); } } @@ -1926,7 +1926,7 @@ bool FileCatalog::trashIsEmpty () const auto& t = fileBrowser->getEntries(); for (const auto entry : t) { - if ((static_cast(entry))->thumbnail->getStage() == 1) { + if ((static_cast(entry))->thumbnail->getTrashed()) { return false; } } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 266dbacd3..0d413e6a4 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -141,7 +141,7 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageDat // TODO? should we call notifylisterners_procParamsChanged here? setRank(cfs.rankOld); - setStage(cfs.inTrashOld); + setTrashed(cfs.inTrashOld); } delete tpp; @@ -444,7 +444,7 @@ void Thumbnail::clearProcParams (int whoClearedIt) // preserve rank, colorlabel and inTrash across clear int rank = getRank(); int colorlabel = getColorLabel(); - int inTrash = getStage(); + int inTrash = getTrashed(); cfs.recentlySaved = false; @@ -460,7 +460,7 @@ void Thumbnail::clearProcParams (int whoClearedIt) setRank(rank); pparamsValid = cfs.rating != rank; setColorLabel(colorlabel); - setStage(inTrash); + setTrashed(inTrash); // params could get validated by rank/inTrash values restored above if (pparamsValid) { @@ -563,7 +563,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh // do not update rank, colorlabel and inTrash const int rank = getRank(); const int colorlabel = getColorLabel(); - const int inTrash = getStage(); + const int inTrash = getTrashed(); if (pe) { pe->combine(*pparams, pp, true); @@ -575,7 +575,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh setRank(rank); setColorLabel(colorlabel); - setStage(inTrash); + setTrashed(inTrash); if (updateCacheNow) { updateCache(); @@ -1115,15 +1115,15 @@ void Thumbnail::setColorLabel (int colorlabel) } } -int Thumbnail::getStage () const +bool Thumbnail::getTrashed () const { return pparams->inTrash; } -void Thumbnail::setStage (bool stage) +void Thumbnail::setTrashed (bool trashed) { - if (pparams->inTrash != stage) { - pparams->inTrash = stage; + if (pparams->inTrash != trashed) { + pparams->inTrash = trashed; pparamsValid = true; } } diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 82c4f4738..64014b0e8 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -155,8 +155,8 @@ public: int getColorLabel () const; void setColorLabel (int colorlabel); - int getStage () const; - void setStage (bool stage); + bool getTrashed () const; + void setTrashed (bool trashed); void addThumbnailListener (ThumbnailListener* tnl); void removeThumbnailListener (ThumbnailListener* tnl); From 68fd35d881fd1368e435bb95ccf44fc32fbc7d13 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Tue, 12 Mar 2024 13:55:51 +0100 Subject: [PATCH 154/291] thumbnail: decouple proc params rank/color/trash Add a Properties type that contains values for rank, color and trashed Each value will also contain an edited flag. The properties variable is used to store rank, color and trashed. They are fetched from the proc params and will update the proc params when needed. This is the base for future implementations where some properties (like rank) will be also retrieved from other sources like xmp sidecar files. --- rtgui/thumbnail.cc | 118 ++++++++++++++++++++++++++------------------- rtgui/thumbnail.h | 26 ++++++++++ 2 files changed, 95 insertions(+), 49 deletions(-) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 0d413e6a4..763735e13 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -133,7 +133,7 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageDat generateExifDateTimeStrings (); if (cfs.rankOld >= 0) { - // rank and inTrash were found in cache (old style), move them over to pparams + // rank and inTrash were found in cache (old style), move them over to pparams or xmp sidecar // 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 @@ -144,6 +144,8 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, CacheImageDat setTrashed(cfs.inTrashOld); } + loadProperties(); + delete tpp; tpp = nullptr; } @@ -173,6 +175,8 @@ Thumbnail::Thumbnail(CacheManager* cm, const Glib::ustring& fname, const std::st initial_ = false; + loadProperties(); + delete tpp; tpp = nullptr; } @@ -306,7 +310,7 @@ const ProcParams& Thumbnail::getProcParamsU () * @param returnParams Ask to return a pointer to a ProcParams object if true * @param force True if the profile has to be re-generated even if it already exists * @param flaggingMode True if the ProcParams will be created because the file browser is being flagging an image - * (rang, to trash, color labels). This parameter is passed to the CPB. + * (rank, to trash, color labels). This parameter is passed to the CPB. * * @return Return a pointer to a ProcPamas structure to be updated if returnParams is true and if everything went fine, NULL otherwise. */ @@ -441,12 +445,6 @@ void Thumbnail::clearProcParams (int whoClearedIt) { MyMutex::MyLock lock(mutex); - // preserve rank, colorlabel and inTrash across clear - int rank = getRank(); - int colorlabel = getColorLabel(); - int inTrash = getTrashed(); - - cfs.recentlySaved = false; pparamsValid = false; @@ -456,13 +454,10 @@ void Thumbnail::clearProcParams (int whoClearedIt) // reset the params to defaults pparams->setDefaults(); - // and restore rank and inTrash - setRank(rank); - pparamsValid = cfs.rating != rank; - setColorLabel(colorlabel); - setTrashed(inTrash); + // preserve rank, colorlabel and inTrash across clear + updateProcParamsProperties(); - // params could get validated by rank/inTrash values restored above + // params could get validated by updateProcParamsProperties if (pparamsValid) { updateCache(); } else { @@ -560,11 +555,6 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh return; } - // do not update rank, colorlabel and inTrash - const int rank = getRank(); - const int colorlabel = getColorLabel(); - const int inTrash = getTrashed(); - if (pe) { pe->combine(*pparams, pp, true); } else { @@ -573,9 +563,8 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh pparamsValid = true; - setRank(rank); - setColorLabel(colorlabel); - setTrashed(inTrash); + // do not update rank, colorlabel and inTrash + updateProcParamsProperties(); if (updateCacheNow) { updateCache(); @@ -1045,7 +1034,6 @@ void Thumbnail::saveThumbnail () */ void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) { - if (updatePParams && pparamsValid) { pparams->save ( options.saveParamsFile ? fname + paramFileExtension : "", @@ -1084,48 +1072,34 @@ void Thumbnail::setFileName (const Glib::ustring &fn) cfs.md5 = ::getMD5 (fname); } -int Thumbnail::getRank () const +int Thumbnail::getRank() const { - // prefer the user-set rank over the embedded Rating - // pparams->rank == -1 means that there is no saved rank yet, so we should - // next look for the embedded Rating metadata. - if (pparams->rank != -1) { - return pparams->rank; - } else { - return cfs.rating; - } + return properties.rank; } -void Thumbnail::setRank (int rank) +void Thumbnail::setRank(int rank) { - pparams->rank = rank; - pparamsValid = true; + properties.rank = rank; } -int Thumbnail::getColorLabel () const +int Thumbnail::getColorLabel() const { - return pparams->colorlabel; + return properties.color; } -void Thumbnail::setColorLabel (int colorlabel) +void Thumbnail::setColorLabel(int colorlabel) { - if (pparams->colorlabel != colorlabel) { - pparams->colorlabel = colorlabel; - pparamsValid = true; - } + properties.color = colorlabel; } -bool Thumbnail::getTrashed () const +bool Thumbnail::getTrashed() const { - return pparams->inTrash; + return properties.trashed; } -void Thumbnail::setTrashed (bool trashed) +void Thumbnail::setTrashed(bool trashed) { - if (pparams->inTrash != trashed) { - pparams->inTrash = trashed; - pparamsValid = true; - } + properties.trashed = trashed; } void Thumbnail::addThumbnailListener (ThumbnailListener* tnl) @@ -1239,6 +1213,52 @@ void Thumbnail::getCamWB(double& temp, double& green, rtengine::StandardObserver } } +void Thumbnail::loadProperties() +{ + properties = Properties(); + + // get initial rank from cache or image metadata + if (cfs.exifValid) { + properties.rank.value = rtengine::LIM(cfs.getRating(), 0, 5); + } else { + const std::unique_ptr md(rtengine::FramesMetaData::fromFile(fname)); + if (md && md->hasExif()) { + properties.rank.value = rtengine::LIM(md->getRating(), 0, 5); + } + } + + // update rank and load color, trash from procparams + if (pparamsValid) { + if (pparams->rank >= 0) { + properties.rank.value = pparams->rank; + } + properties.color.value = pparams->colorlabel; + properties.trashed.value = pparams->inTrash; + } +} + +void Thumbnail::updateProcParamsProperties() +{ + if (!properties.edited()) { + return; + } + + if (properties.trashed.edited && properties.trashed != pparams->inTrash) { + pparams->inTrash = properties.trashed; + pparamsValid = true; + } + + if (properties.rank.edited && properties.rank != pparams->rank) { + pparams->rank = properties.rank; + pparamsValid = true; + } + + if (properties.color.edited && properties.color != pparams->colorlabel) { + pparams->colorlabel = properties.color; + pparamsValid = true; + } +} + void Thumbnail::saveMetadata() { if (options.rtSettings.metadata_xmp_sync != rtengine::Settings::MetadataXmpSync::READ_WRITE) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index 64014b0e8..e24be18f5 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -78,6 +78,30 @@ class Thumbnail bool initial_; + // Properties holds values and edited states for rank, color and trashed + struct Properties { + template struct Property { + T value; + bool edited; + Property(T v): value(v), edited(false) {} + Property& operator=(T v) + { + value = v; + edited = true; + return *this; + } + operator T() const { return value; } + }; + Property rank; + Property color; + Property trashed; + + explicit Properties(int r=0, int c=0, bool t=false): + rank(r), color(c), trashed(t) {} + bool edited() const { return rank.edited || color.edited || trashed.edited; } + }; + Properties properties; + // vector of listeners std::vector listeners; @@ -90,6 +114,8 @@ class Thumbnail Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fext) const; void saveMetadata(); + void loadProperties(); + void updateProcParamsProperties(); public: Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); From 4e57202bf6c909b12f5765869b208cdcb9616cb9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 31 Mar 2024 17:43:04 -0700 Subject: [PATCH 155/291] Improve Lensfun auto lens matching Handle lens names with spaces surrounding dashes. --- rtengine/rtlensfun.cc | 46 ++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index fc5bb0017..8bdda29ec 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -19,6 +19,7 @@ */ #include +#include #include "imagedata.h" #include "procparams.h" @@ -475,23 +476,36 @@ LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) c } } } - auto found = data_->FindLenses(camera.data_, nullptr, name.c_str()); - for (size_t pos = 0; !found && pos < name.size(); ) { - // try to split the maker from the model of the lens -- we have to - // guess a bit here, since there are makers with a multi-word name - // (e.g. "Leica Camera AG") - if (name.find("f/", pos) == 0) { - break; // no need to search further + const auto find_lens_from_name = [](const lfDatabase *database, const lfCamera *cam, const Glib::ustring &lens_name) { + auto found = database->FindLenses(cam, nullptr, lens_name.c_str()); + for (size_t pos = 0; !found && pos < lens_name.size(); ) { + // try to split the maker from the model of the lens -- we have to + // guess a bit here, since there are makers with a multi-word name + // (e.g. "Leica Camera AG") + if (lens_name.find("f/", pos) == 0) { + break; // no need to search further + } + Glib::ustring make, model; + auto i = lens_name.find(' ', pos); + if (i != Glib::ustring::npos) { + make = lens_name.substr(0, i); + model = lens_name.substr(i+1); + found = database->FindLenses(cam, make.c_str(), model.c_str()); + pos = i+1; + } else { + break; + } } - Glib::ustring make, model; - auto i = name.find(' ', pos); - if (i != Glib::ustring::npos) { - make = name.substr(0, i); - model = name.substr(i+1); - found = data_->FindLenses(camera.data_, make.c_str(), model.c_str()); - pos = i+1; - } else { - break; + return found; + }; + auto found = find_lens_from_name(data_, camera.data_, name); + if (!found) { + // Some names have white-space around the dash(s) while Lensfun does + // not have any. + const std::regex pattern("\\s*-\\s*"); + const auto formatted_name = std::regex_replace(name.raw(), pattern, "-"); + if (name != formatted_name) { + found = find_lens_from_name(data_, camera.data_, formatted_name); } } if (!found && camera && camera.isFixedLens()) { From 1098966a8bbe92e390c4b688eeae23491530832b Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Tue, 12 Mar 2024 18:12:49 +0100 Subject: [PATCH 156/291] Add optional image rank/color load/save from/to xmp sidecar Add optional ability to load/save image rank property from/to xmp sidecar "xmp.Rating" and color property from xmp "xmp.Label" ignoring the ones provided in the processing params file. This behavior is disabled by default and an option under settings -> file browser has been added to enable it. When enabled: * On load: * rank and color are not read from processing params. * rank is mapped from xmp sidecar file rating entry. * color is mapped from xmp sidecar file label entry. * On save: * rank and color are saved to the xmp sidecar * rank and color are also saved to the processing param (pp3) files to keep them in sync Rating mapping: Since rating can be also -1 but rank only goes from 0 to 5, the -1 value is ignored like already done when importing from embedded xmp data. Color mapping: XMP has no color concept, usually programs like digikam uses the label field to write a color name ("Red", "Orange"). The problem is that this isn't standardized and label can be any string. Additionally Rawtherapee has 5 specific colors while other programs can have different colors with different name so they won't be shown if they don't map to the 5 color names supported by rawtherapee. On save only the 5 color supported by rawtherapee wil be saved. Trash is kept only in the profile files for multiple reasons: * There's no trash concept in xmp, there's the rejected concept assigned to a rating == -1. * We could map rejected to trash but in rawtherapee rank and trash are two different values and an image can have both rank >= 0 and trashed set to true. Using an unique value like rating for rank and trash (when -1) will require changing the current rawtherapee logic. * Also digikam only handles ratings from 0 to 5 (no -1) and handles trash in its own internal way without reflecting it in the xmp sidecar. --- rtdata/languages/default | 1 + rtengine/metadata.cc | 13 ----- rtengine/metadata.h | 14 +++++ rtgui/options.cc | 18 +++++++ rtgui/options.h | 6 +++ rtgui/preferences.cc | 7 +++ rtgui/preferences.h | 2 + rtgui/thumbnail.cc | 107 +++++++++++++++++++++++++++++++++++++-- rtgui/thumbnail.h | 1 + 9 files changed, 152 insertions(+), 17 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index a6a8cdc5c..a6897f316 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2033,6 +2033,7 @@ PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Embedded JPEG preview PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 0a55c1424..df8988f5a 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -106,19 +106,6 @@ void clear_metadata_key(Data &data, const Key &key) } } -template -auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( -#if EXIV2_TEST_VERSION(0,28,0) - iter->toInt64() -) { - return iter->toInt64(n); -#else - iter->toLong() -) { - return iter->toLong(n); -#endif -} - } // namespace diff --git a/rtengine/metadata.h b/rtengine/metadata.h index 7424b2720..75d37d46c 100644 --- a/rtengine/metadata.h +++ b/rtengine/metadata.h @@ -97,4 +97,18 @@ private: static std::unique_ptr cache_; }; +template +auto to_long(const Iterator &iter, Integer n = Integer{0}) -> decltype( +#if EXIV2_TEST_VERSION(0,28,0) + iter->toInt64() +) { + return iter->toInt64(n); +#else + iter->toLong() +) { + return iter->toLong(n); +#endif +} + + } // namespace rtengine diff --git a/rtgui/options.cc b/rtgui/options.cc index c8750809b..522bcc26a 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -694,6 +694,7 @@ void Options::setDefaults() lastICCProfCreatorDir = ""; gimpPluginShowInfoDialog = true; maxRecentFolders = 15; + thumbnailRankColorMode = Options::ThumbnailPropertyMode::PROCPARAMS; sortMethod = SORT_BY_NAME; sortDescending = false; rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc @@ -1366,6 +1367,15 @@ void Options::readFromFile(Glib::ustring fname) if (keyFile.has_key("File Browser", "BrowseRecursiveFollowLinks")) { browseRecursiveFollowLinks = keyFile.get_boolean("File Browser", "BrowseRecursiveFollowLinks"); } + + if (keyFile.has_key("File Browser", "ThumbnailRankColorMode")) { + std::string val = keyFile.get_string("File Browser", "ThumbnailRankColorMode"); + if (val == "xmp") { + thumbnailRankColorMode = ThumbnailPropertyMode::XMP; + } else { + thumbnailRankColorMode = ThumbnailPropertyMode::PROCPARAMS; + } + } } if (keyFile.has_group("Clipping Indication")) { @@ -2462,6 +2472,14 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string_list("File Browser", "RecentFolders", temp); } + switch (thumbnailRankColorMode) { + case ThumbnailPropertyMode::XMP: + keyFile.set_string("File Browser", "ThumbnailRankColorMode", "xmp"); + break; + default: // ThumbnailPropertyMode::PROCPARAMS + keyFile.set_string("File Browser", "ThumbnailRankColorMode", "procparams"); + break; + } keyFile.set_integer("File Browser", "SortMethod", sortMethod); keyFile.set_boolean("File Browser", "SortDescending", sortDescending); keyFile.set_boolean("File Browser", "BrowseRecursive", browseRecursive); diff --git a/rtgui/options.h b/rtgui/options.h index 2b5df3aa6..d65013dac 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -492,6 +492,12 @@ public: size_t maxRecentFolders; // max. number of recent folders stored in options file std::vector recentFolders; // List containing all recent folders + enum class ThumbnailPropertyMode { + PROCPARAMS, // store rank and color in procparams sidecars + XMP // store rank and color xmp sidecar + }; + ThumbnailPropertyMode thumbnailRankColorMode; + enum SortMethod { SORT_BY_NAME, SORT_BY_DATE, diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 527800cb6..eddfc561e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1470,6 +1470,9 @@ Gtk::Widget* Preferences::getFileBrowserPanel() vbro->pack_start(*sameThumbSize, Gtk::PACK_SHRINK, 0); vbro->pack_start(*ckbInternalThumbIfUntouched, Gtk::PACK_SHRINK, 0); + thumbnailRankColorMode = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_THUMBNAIL_RANK_COLOR_MODE"))); + vbro->pack_start(*thumbnailRankColorMode, Gtk::PACK_SHRINK, 0); + Gtk::Box* hbrecent = Gtk::manage(new Gtk::Box()); Gtk::Label* labrecent = Gtk::manage (new Gtk::Label (M("PREFERENCES_MAXRECENTFOLDERS") + ":", Gtk::ALIGN_START)); maxRecentFolders = Gtk::manage(new Gtk::SpinButton()); @@ -2029,6 +2032,8 @@ void Preferences::storePreferences() moptions.rtSettings.metadata_xmp_sync = rtengine::Settings::MetadataXmpSync(metadataSyncCombo->get_active_row_number()); moptions.rtSettings.xmp_sidecar_style = rtengine::Settings::XmpSidecarStyle(xmpSidecarCombo->get_active_row_number()); + + moptions.thumbnailRankColorMode = thumbnailRankColorMode->get_active() ? Options::ThumbnailPropertyMode::XMP : Options::ThumbnailPropertyMode::PROCPARAMS; } void Preferences::fillPreferences() @@ -2287,6 +2292,8 @@ void Preferences::fillPreferences() metadataSyncCombo->set_active(int(moptions.rtSettings.metadata_xmp_sync)); xmpSidecarCombo->set_active(int(moptions.rtSettings.xmp_sidecar_style)); + + thumbnailRankColorMode->set_active(moptions.thumbnailRankColorMode == Options::ThumbnailPropertyMode::XMP); } /* diff --git a/rtgui/preferences.h b/rtgui/preferences.h index b34a8348f..191f122f5 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -224,6 +224,8 @@ class Preferences final : Gtk::CheckButton* ckbInternalThumbIfUntouched; + Gtk::CheckButton *thumbnailRankColorMode; + Gtk::Entry* txtCustProfBuilderPath; Gtk::ComboBoxText* custProfBuilderLabelType; diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 763735e13..7ee4d3da1 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -105,6 +105,46 @@ bool CPBDump( return true; } +struct ColorMapper { + std::map indexLabelMap; + std::map labelIndexMap; + + ColorMapper(std::map colors) { + for (const auto& color: colors) { + indexLabelMap.insert({color.first, color.second}); + labelIndexMap.insert({color.second, color.first}); + } + } + + int index(const std::string &label) const + { + auto it = labelIndexMap.find(label); + if (it != labelIndexMap.end()) { + return it->second; + } + return 0; + } + + std::string label(int index) const + { + auto it = indexLabelMap.find(index); + if (it != indexLabelMap.end()) { + return it->second; + } + return ""; + } +}; + +const std::map defaultColors = { + {1, "Red"}, + {2, "Yellow"}, + {3, "Green"}, + {4, "Blue"}, + {5, "Purple"} +}; + +auto defaultColorMapper = ColorMapper(defaultColors); + } // namespace using namespace rtengine::procparams; @@ -1034,6 +1074,8 @@ void Thumbnail::saveThumbnail () */ void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) { + updateProcParamsProperties(); + if (updatePParams && pparamsValid) { pparams->save ( options.saveParamsFile ? fname + paramFileExtension : "", @@ -1049,6 +1091,8 @@ void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) if (updatePParams && pparamsValid) { saveMetadata(); } + + saveXMPSidecarProperties(); } Thumbnail::~Thumbnail () @@ -1227,13 +1271,37 @@ void Thumbnail::loadProperties() } } - // update rank and load color, trash from procparams + // update rank and color from procparams or xmp sidecar + // load trash from procparams if (pparamsValid) { - if (pparams->rank >= 0) { - properties.rank.value = pparams->rank; + if (options.thumbnailRankColorMode == Options::ThumbnailPropertyMode::PROCPARAMS) { + if (pparams->rank >= 0) { + properties.rank.value = pparams->rank; + } } - properties.color.value = pparams->colorlabel; + properties.trashed.value = pparams->inTrash; + properties.color.value = pparams->colorlabel; + } + + if (options.thumbnailRankColorMode == Options::ThumbnailPropertyMode::XMP) { + try { + auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname); + auto pos = xmp.findKey(Exiv2::XmpKey("Xmp.xmp.Rating")); + if (pos != xmp.end()) { + int r = rtengine::to_long(pos); + properties.rank.value = rtengine::LIM(r, 0, 5); + } + + pos = xmp.findKey(Exiv2::XmpKey("Xmp.xmp.Label")); + if (pos != xmp.end()) { + properties.color.value = defaultColorMapper.index(pos->toString()); + } + } catch (std::exception &exc) { + std::cerr << "ERROR loading thumbnail properties data from " + << rtengine::Exiv2Metadata::xmpSidecarPath(fname) + << ": " << exc.what() << std::endl; + } } } @@ -1248,6 +1316,8 @@ void Thumbnail::updateProcParamsProperties() pparamsValid = true; } + // save procparams rank and color also when options.thumbnailRankColorMode == Options::ThumbnailPropertyMode::XMP + // so they'll be kept in sync if (properties.rank.edited && properties.rank != pparams->rank) { pparams->rank = properties.rank; pparamsValid = true; @@ -1259,6 +1329,35 @@ void Thumbnail::updateProcParamsProperties() } } +void Thumbnail::saveXMPSidecarProperties() +{ + if (!properties.edited()) { + return; + } + + if (options.thumbnailRankColorMode != Options::ThumbnailPropertyMode::XMP) { + return; + } + + auto fn = rtengine::Exiv2Metadata::xmpSidecarPath(fname); + try { + auto xmp = rtengine::Exiv2Metadata::getXmpSidecar(fname); + if (properties.rank.edited) { + xmp["Xmp.xmp.Rating"] = std::to_string(properties.rank); + } + if (properties.color.edited) { + xmp["Xmp.xmp.Label"] = defaultColorMapper.label(properties.color); + } + + rtengine::Exiv2Metadata meta; + meta.xmpData() = std::move(xmp); + meta.saveToXmp(fn); + } catch (std::exception &exc) { + std::cerr << "ERROR saving thumbnail properties data to " << fn + << ": " << exc.what() << std::endl; + } +} + void Thumbnail::saveMetadata() { if (options.rtSettings.metadata_xmp_sync != rtengine::Settings::MetadataXmpSync::READ_WRITE) { diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h index e24be18f5..c1e52760c 100644 --- a/rtgui/thumbnail.h +++ b/rtgui/thumbnail.h @@ -116,6 +116,7 @@ class Thumbnail void saveMetadata(); void loadProperties(); void updateProcParamsProperties(); + void saveXMPSidecarProperties(); public: Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); From dfc82c403c382e0ec95949edb91beb5946cf11b2 Mon Sep 17 00:00:00 2001 From: xiota Date: Tue, 21 Sep 2021 22:19:27 -0700 Subject: [PATCH 157/291] Add ability to import JXL images --- CMakeLists.txt | 5 ++ rtdata/options/options.lin | 4 +- rtdata/options/options.osx | 4 +- rtdata/options/options.win | 4 +- rtengine/CMakeLists.txt | 1 + rtengine/imageio.cc | 168 ++++++++++++++++++++++++++++++++++++- rtengine/imageio.h | 4 + rtengine/stdimagesource.cc | 6 ++ rtengine/utils.cc | 8 ++ rtengine/utils.h | 5 ++ rtgui/main-cli.cc | 2 +- rtgui/thumbnail.cc | 15 ++++ 12 files changed, 218 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 051d215e2..5ed90ca61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -552,6 +552,11 @@ if(WITH_SYSTEM_KLT) find_package(KLT REQUIRED) endif() +pkg_check_modules(JXL IMPORTED_TARGET libjxl libjxl_threads) +if(JXL) + set(JXL_LIBRARIES jxl jxl_threads) +endif() + # Check for libcanberra-gtk3 (sound events on Linux): if(UNIX AND (NOT APPLE)) option(USE_LIBCANBERRA "Build with libcanberra" ON) diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index fbd8bc6cb..0f31df6ee 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index ef68d7144..273b189e5 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -13,8 +13,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index 00b74d07f..9f72a1a72 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 6f329f7be..b92917ef5 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -246,6 +246,7 @@ target_link_libraries(rtengine ${RSVG_LIBRARIES} ${KLT_LIBRARIES} ${EXIV2_LIBRARIES} + ${JXL_LIBRARIES} ) if(OpenMP_FOUND) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index e2c6c1310..ece182821 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -24,13 +24,20 @@ #include #include #include - #include #include #include #include #include +#ifdef JXL +#include +#include "jxl/decode.h" +#include "jxl/decode_cxx.h" +#include "jxl/resizable_parallel_runner.h" +#include "jxl/resizable_parallel_runner_cxx.h" +#endif + #ifdef _WIN32 #include #else @@ -822,6 +829,161 @@ int ImageIO::loadTIFF (const Glib::ustring &fname) return IMIO_SUCCESS; } +#ifdef JXL +#define _PROFILE_ JXL_COLOR_PROFILE_TARGET_ORIGINAL + +// adapted from libjxl +int ImageIO::loadJxl(const Glib::ustring &fname) +{ + if (pl) { + pl->setProgressStr("PROGRESSBAR_LOADJXL"); + pl->setProgress(0.0); + } + + std::vector icc_profile; + + gpointer buffer = nullptr; + size_t buffer_size = 0; + + JxlBasicInfo info = {}; + JxlPixelFormat format = {}; + + format.num_channels = 3; + format.data_type = JXL_TYPE_FLOAT; + format.endianness = JXL_NATIVE_ENDIAN; + format.align = 0; + + // get file contents + std::ifstream instream(fname.c_str(), std::ios::in | std::ios::binary); + std::vector compressed( + (std::istreambuf_iterator(instream)), + std::istreambuf_iterator()); + instream.close(); + + + // multi-threaded parallel runner. + auto runner = JxlResizableParallelRunnerMake(nullptr); + + auto dec = JxlDecoderMake(nullptr); + if (JXL_DEC_SUCCESS != + JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | + JXL_DEC_COLOR_ENCODING | + JXL_DEC_FULL_IMAGE)) { + g_printerr("Error: JxlDecoderSubscribeEvents failed\n"); + return false; + } + + if (JXL_DEC_SUCCESS != + JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, + runner.get())) { + g_printerr("Error: JxlDecoderSetParallelRunner failed\n"); + return false; + } + + // grand decode loop... + JxlDecoderSetInput(dec.get(), compressed.data(), compressed.size()); + + while (true) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec.get()); + + if (status == JXL_DEC_BASIC_INFO) { + if (JXL_DEC_SUCCESS != + JxlDecoderGetBasicInfo(dec.get(), &info)) { + g_printerr("Error: JxlDecoderGetBasicInfo failed\n"); + return false; + } + + JxlResizableParallelRunnerSetThreads( + runner.get(), JxlResizableParallelRunnerSuggestThreads( + info.xsize, info.ysize)); + } else if (status == JXL_DEC_COLOR_ENCODING) { + // check for ICC profile + deleteLoadedProfileData(); + embProfile = nullptr; + size_t icc_size = 0; + + if (JXL_DEC_SUCCESS != + JxlDecoderGetICCProfileSize(dec.get(), &format, + _PROFILE_, &icc_size)) { + g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); + } + + if (icc_size > 0) { + icc_profile.resize(icc_size); + if (JXL_DEC_SUCCESS != + JxlDecoderGetColorAsICCProfile( + dec.get(), &format, _PROFILE_, + icc_profile.data(), icc_profile.size())) { + g_printerr( + "Warning: JxlDecoderGetColorAsICCProfile failed\n"); + } else { + embProfile = cmsOpenProfileFromMem(icc_profile.data(), + icc_profile.size()); + } + } else { + g_printerr("Warning: Empty ICC data.\n"); + } + } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { + format.data_type = JXL_TYPE_FLOAT; + if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize( + dec.get(), &format, &buffer_size)) { + g_printerr("Error: JxlDecoderImageOutBufferSize failed\n"); + return false; + } + buffer = g_malloc(buffer_size); + if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, + buffer, buffer_size)) { + g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); + g_free(buffer); + return false; + } + } else if (status == JXL_DEC_FULL_IMAGE || + status == JXL_DEC_FRAME) { + // Nothing to do. If the image is an animation, more full frames + // may be decoded. This example only keeps the first one. + } else if (status == JXL_DEC_SUCCESS) { + // All decoding successfully finished. + // It's not required to call JxlDecoderReleaseInput(dec.get()) + // since the decoder will be destroyed. + break; + } else if (status == JXL_DEC_NEED_MORE_INPUT) { + g_printerr("Error: Already provided all input\n"); + return false; + } else if (status == JXL_DEC_ERROR) { + g_printerr("Error: Decoder error\n"); + return false; + } else { + g_printerr("Error: Unknown decoder status\n"); + return false; + } + } // end grand decode loop + + unsigned int width = info.xsize; + unsigned int height = info.ysize; + + allocate(width, height); + + int line_length = width * 3 * 4; + + for (size_t row = 0; row < height; ++row) { + setScanline (row, ((const unsigned char*)buffer) + (row * line_length), 32); + + if (pl && !(row % 100)) { + pl->setProgress ((double)(row) / height); + } + } + + g_free(buffer); + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} +#endif + int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool swap, int bps) { allocate (width, height); @@ -1310,6 +1472,10 @@ int ImageIO::load (const Glib::ustring &fname) return loadPNG (fname); } else if (hasJpegExtension(fname)) { return loadJPEG (fname); +#ifdef JXL + } else if (hasJxlExtension(fname)) { + return loadJxl(fname); +#endif } else if (hasTiffExtension(fname)) { return loadTIFF (fname); } else { diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 813bfcc61..e7fa23b20 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -90,6 +90,10 @@ public: int load (const Glib::ustring &fname); int save (const Glib::ustring &fname) const; +#ifdef JXL + int loadJxl (const Glib::ustring &fname); +#endif + int loadPNG (const Glib::ustring &fname); int loadJPEG (const Glib::ustring &fname); int loadTIFF (const Glib::ustring &fname); diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 435f2f9a0..33d02e5b1 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -90,6 +90,12 @@ void StdImageSource::getSampleFormat (const Glib::ustring &fname, IIOSampleForma if (result == IMIO_SUCCESS) { return; } +#ifdef JXL + } else if (hasJxlExtension(fname)) { + sFormat = IIOSF_FLOAT32; + sArrangement = IIOSA_CHUNKY; + return; +#endif } else if (hasTiffExtension(fname)) { int result = ImageIO::getTIFFSampleFormat (fname, sFormat, sArrangement); diff --git a/rtengine/utils.cc b/rtengine/utils.cc index 0674c9806..0a53f0a83 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -237,6 +237,14 @@ bool hasJpegExtension(const Glib::ustring& filename) return extension == "jpg" || extension == "jpeg"; } +#ifdef JXL +bool hasJxlExtension(const Glib::ustring& filename) +{ + const Glib::ustring extension = getFileExtension(filename); + return extension == "jxl"; +} +#endif + bool hasTiffExtension(const Glib::ustring& filename) { const Glib::ustring extension = getFileExtension(filename); diff --git a/rtengine/utils.h b/rtengine/utils.h index e0097d76e..06f42237c 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -52,6 +52,11 @@ bool hasTiffExtension(const Glib::ustring& filename); // Return true if file has .png extension (ignoring case) bool hasPngExtension(const Glib::ustring& filename); +#ifdef JXL +// Return true if file has .jxl extension (ignoring case) +bool hasJxlExtension(const Glib::ustring& filename); +#endif + void swab(const void* from, void* to, ssize_t n); } diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 6d63d194a..6a3c34694 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -707,7 +707,7 @@ int processLineParams ( int argc, char **argv ) isRaw = true; Glib::ustring ext = getExtension (inputFile); - if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg" || ext.lowercase() == "tif" || ext.lowercase() == "tiff" || ext.lowercase() == "png") { + if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg" || ext.lowercase() == "tif" || ext.lowercase() == "tiff" || ext.lowercase() == "png" || ext.lowercase() == "jxl") { isRaw = false; } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 266dbacd3..a0164bc7d 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -212,6 +212,12 @@ void Thumbnail::_generateThumbnailImage () if (tpp) { cfs.format = FT_Jpeg; } + } else if (ext == "jxl") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); + + if (tpp) { + cfs.format = FT_Png; + } } else if (ext == "png") { tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); @@ -255,6 +261,15 @@ void Thumbnail::_generateThumbnailImage () } } + if (!tpp) { + // try a custom loader + tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, true); + if (tpp) { + cfs.format = FT_Custom; + infoFromImage(fname); + } + } + if (tpp) { tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul); _saveThumbnail (); From dd01cc110bc438507a22bc86c4728319caebc11b Mon Sep 17 00:00:00 2001 From: xiota Date: Thu, 23 Sep 2021 13:34:48 -0700 Subject: [PATCH 158/291] Add error code to returns Fix conditional libjxl compilation --- CMakeLists.txt | 4 ++-- rtengine/CMakeLists.txt | 3 +++ rtengine/imageio.cc | 26 +++++++++++++------------- rtengine/imageio.h | 2 +- rtengine/stdimagesource.cc | 2 +- rtengine/utils.cc | 2 +- rtengine/utils.h | 2 +- rtgui/main-cli.cc | 2 +- rtgui/thumbnail.cc | 14 ++++++++------ 9 files changed, 31 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ed90ca61..23a3dbc0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -553,8 +553,8 @@ if(WITH_SYSTEM_KLT) endif() pkg_check_modules(JXL IMPORTED_TARGET libjxl libjxl_threads) -if(JXL) - set(JXL_LIBRARIES jxl jxl_threads) +if(JXL_FOUND) + add_definitions(-DLIBJXL) endif() # Check for libcanberra-gtk3 (sound events on Linux): diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index b92917ef5..5d87310b9 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -45,6 +45,9 @@ endif() if(EXIV2_INCLUDE_DIRS) include_directories("${EXIV2_INCLUDE_DIRS}") endif() +if(JXL_INCLUDE_DIRS) + include_directories("${JXL_INCLUDE_DIRS}") +endif() link_directories( "${EXPAT_LIBRARY_DIRS}" diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index ece182821..675e75f65 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -30,7 +30,7 @@ #include #include -#ifdef JXL +#ifdef LIBJXL #include #include "jxl/decode.h" #include "jxl/decode_cxx.h" @@ -829,9 +829,8 @@ int ImageIO::loadTIFF (const Glib::ustring &fname) return IMIO_SUCCESS; } -#ifdef JXL +#ifdef LIBJXL #define _PROFILE_ JXL_COLOR_PROFILE_TARGET_ORIGINAL - // adapted from libjxl int ImageIO::loadJxl(const Glib::ustring &fname) { @@ -870,14 +869,14 @@ int ImageIO::loadJxl(const Glib::ustring &fname) JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE)) { g_printerr("Error: JxlDecoderSubscribeEvents failed\n"); - return false; + return IMIO_HEADERERROR; } if (JXL_DEC_SUCCESS != JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, runner.get())) { g_printerr("Error: JxlDecoderSetParallelRunner failed\n"); - return false; + return IMIO_HEADERERROR; } // grand decode loop... @@ -890,7 +889,7 @@ int ImageIO::loadJxl(const Glib::ustring &fname) if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec.get(), &info)) { g_printerr("Error: JxlDecoderGetBasicInfo failed\n"); - return false; + return IMIO_HEADERERROR; } JxlResizableParallelRunnerSetThreads( @@ -928,14 +927,14 @@ int ImageIO::loadJxl(const Glib::ustring &fname) if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize( dec.get(), &format, &buffer_size)) { g_printerr("Error: JxlDecoderImageOutBufferSize failed\n"); - return false; + return IMIO_READERROR; } buffer = g_malloc(buffer_size); if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer, buffer_size)) { g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); g_free(buffer); - return false; + return IMIO_READERROR; } } else if (status == JXL_DEC_FULL_IMAGE || status == JXL_DEC_FRAME) { @@ -948,13 +947,13 @@ int ImageIO::loadJxl(const Glib::ustring &fname) break; } else if (status == JXL_DEC_NEED_MORE_INPUT) { g_printerr("Error: Already provided all input\n"); - return false; + return IMIO_READERROR; } else if (status == JXL_DEC_ERROR) { g_printerr("Error: Decoder error\n"); - return false; + return IMIO_READERROR; } else { g_printerr("Error: Unknown decoder status\n"); - return false; + return IMIO_READERROR; } } // end grand decode loop @@ -982,7 +981,8 @@ int ImageIO::loadJxl(const Glib::ustring &fname) return IMIO_SUCCESS; } -#endif +#undef _PROFILE_ +#endif // LIBJXL int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool swap, int bps) { @@ -1472,7 +1472,7 @@ int ImageIO::load (const Glib::ustring &fname) return loadPNG (fname); } else if (hasJpegExtension(fname)) { return loadJPEG (fname); -#ifdef JXL +#ifdef LIBJXL } else if (hasJxlExtension(fname)) { return loadJxl(fname); #endif diff --git a/rtengine/imageio.h b/rtengine/imageio.h index e7fa23b20..cfc54e629 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -90,7 +90,7 @@ public: int load (const Glib::ustring &fname); int save (const Glib::ustring &fname) const; -#ifdef JXL +#ifdef LIBJXL int loadJxl (const Glib::ustring &fname); #endif diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 33d02e5b1..32961f975 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -90,7 +90,7 @@ void StdImageSource::getSampleFormat (const Glib::ustring &fname, IIOSampleForma if (result == IMIO_SUCCESS) { return; } -#ifdef JXL +#ifdef LIBJXL } else if (hasJxlExtension(fname)) { sFormat = IIOSF_FLOAT32; sArrangement = IIOSA_CHUNKY; diff --git a/rtengine/utils.cc b/rtengine/utils.cc index 0a53f0a83..4c4f18691 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -237,7 +237,7 @@ bool hasJpegExtension(const Glib::ustring& filename) return extension == "jpg" || extension == "jpeg"; } -#ifdef JXL +#ifdef LIBJXL bool hasJxlExtension(const Glib::ustring& filename) { const Glib::ustring extension = getFileExtension(filename); diff --git a/rtengine/utils.h b/rtengine/utils.h index 06f42237c..7ff16c79b 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -52,7 +52,7 @@ bool hasTiffExtension(const Glib::ustring& filename); // Return true if file has .png extension (ignoring case) bool hasPngExtension(const Glib::ustring& filename); -#ifdef JXL +#ifdef LIBJXL // Return true if file has .jxl extension (ignoring case) bool hasJxlExtension(const Glib::ustring& filename); #endif diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index 6a3c34694..6d63d194a 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -707,7 +707,7 @@ int processLineParams ( int argc, char **argv ) isRaw = true; Glib::ustring ext = getExtension (inputFile); - if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg" || ext.lowercase() == "tif" || ext.lowercase() == "tiff" || ext.lowercase() == "png" || ext.lowercase() == "jxl") { + if (ext.lowercase() == "jpg" || ext.lowercase() == "jpeg" || ext.lowercase() == "tif" || ext.lowercase() == "tiff" || ext.lowercase() == "png") { isRaw = false; } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index a0164bc7d..ba4c223ca 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -212,18 +212,20 @@ void Thumbnail::_generateThumbnailImage () if (tpp) { cfs.format = FT_Jpeg; } - } else if (ext == "jxl") { - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); - - if (tpp) { - cfs.format = FT_Png; - } } else if (ext == "png") { tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); if (tpp) { cfs.format = FT_Png; } +#ifdef LIBJXL + } else if (ext == "jxl") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); + + if (tpp) { + cfs.format = FT_Custom; + } +#endif } else if (ext == "tif" || ext == "tiff") { infoFromImage (fname); tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); From 320859bf922baa359203c34b921e65867a687fcf Mon Sep 17 00:00:00 2001 From: xiota Date: Thu, 23 Sep 2021 14:02:54 -0700 Subject: [PATCH 159/291] Remove unnecessary thumbnail loading code --- rtgui/thumbnail.cc | 83 +++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 57 deletions(-) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index ba4c223ca..18829d9e1 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -184,7 +184,6 @@ Glib::ustring Thumbnail::xmpSidecarPath(const Glib::ustring &imagePath) void Thumbnail::_generateThumbnailImage () { - // delete everything loaded into memory delete tpp; tpp = nullptr; @@ -205,67 +204,37 @@ void Thumbnail::_generateThumbnailImage () cfs.exifValid = false; cfs.timeValid = false; - if (ext == "jpg" || ext == "jpeg") { + // 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::eSensorType sensorType = rtengine::ST_NONE; + if ( initial_ && options.internalThumbIfUntouched) { + quick = true; + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, tw, th, 1, TRUE); + } + + if ( tpp == nullptr ) { + quick = false; + tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); + } + + cfs.sensortype = sensorType; + if (tpp) { + cfs.format = FT_Raw; + cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); - - if (tpp) { - cfs.format = FT_Jpeg; - } - } else if (ext == "png") { - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); - - if (tpp) { - cfs.format = FT_Png; - } -#ifdef LIBJXL - } else if (ext == "jxl") { - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal); - - if (tpp) { - cfs.format = FT_Custom; - } -#endif - } else if (ext == "tif" || ext == "tiff") { - infoFromImage (fname); - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); - - 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::eSensorType sensorType = rtengine::ST_NONE; - if ( initial_ && options.internalThumbIfUntouched) { - quick = true; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, tw, th, 1, TRUE); - } - - if ( tpp == nullptr ) { - quick = false; - tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); - } - - cfs.sensortype = sensorType; - if (tpp) { - cfs.format = FT_Raw; - cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; - infoFromImage (fname); - if (!quick) { - cfs.width = tpp->full_width; - cfs.height = tpp->full_height; - } + if (!quick) { + cfs.width = tpp->full_width; + cfs.height = tpp->full_height; } } if (!tpp) { - // try a custom loader - tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, true); + // this will load formats supported by imagio (jpg, png, jxl, and tiff) + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); if (tpp) { cfs.format = FT_Custom; infoFromImage(fname); From 135bb7d2e9b38ec4fec3575053cdb99bb5b64cbd Mon Sep 17 00:00:00 2001 From: xiota Date: Sat, 23 Oct 2021 17:17:16 -0700 Subject: [PATCH 160/291] alphabetize extensions in rtdata/options/options.* --- rtdata/options/options.lin | 4 ++-- rtdata/options/options.osx | 4 ++-- rtdata/options/options.win | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index 0f31df6ee..c30ff61c7 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f +ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index 273b189e5..aec627ae8 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -13,8 +13,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f +ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index 9f72a1a72..a583b9046 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f;jxl; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f +ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 [Output] PathTemplate=%p1/converted/%f From 8c4ab0277ab9d6091fcc436bff7dca820af5c2fe Mon Sep 17 00:00:00 2001 From: xiota Date: Sat, 23 Oct 2021 17:19:16 -0700 Subject: [PATCH 161/291] change , to ; in rtdata/options/options.* --- rtdata/options/options.lin | 4 ++-- rtdata/options/options.osx | 4 ++-- rtdata/options/options.win | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index c30ff61c7..2a96c6997 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f -ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index aec627ae8..eff9cd8d9 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -13,8 +13,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f -ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index a583b9046..e3f43343e 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr,arw,arq,cr2,cr3,crf,crw,dcr,dng,fff,iiq,jpg,jpeg,jxl,kdc,mef,mos,mrw,nef,nrw,orf,ori,pef,png,raf,raw,rw2,rwl,rwz,sr2,srf,srw,tif,tiff,x3f -ParseExtensionsEnabled=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1 +ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; [Output] PathTemplate=%p1/converted/%f From 7715d156159abc10d7fbb43a75f63cacc31b12a4 Mon Sep 17 00:00:00 2001 From: xiota Date: Wed, 10 Apr 2024 12:32:49 +0000 Subject: [PATCH 162/291] Update to current libjxl API --- rtengine/imageio.cc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 675e75f65..e5a3683dc 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -859,7 +859,6 @@ int ImageIO::loadJxl(const Glib::ustring &fname) std::istreambuf_iterator()); instream.close(); - // multi-threaded parallel runner. auto runner = JxlResizableParallelRunnerMake(nullptr); @@ -886,15 +885,14 @@ int ImageIO::loadJxl(const Glib::ustring &fname) JxlDecoderStatus status = JxlDecoderProcessInput(dec.get()); if (status == JXL_DEC_BASIC_INFO) { - if (JXL_DEC_SUCCESS != - JxlDecoderGetBasicInfo(dec.get(), &info)) { + if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec.get(), &info)) { g_printerr("Error: JxlDecoderGetBasicInfo failed\n"); return IMIO_HEADERERROR; } JxlResizableParallelRunnerSetThreads( - runner.get(), JxlResizableParallelRunnerSuggestThreads( - info.xsize, info.ysize)); + runner.get(), + JxlResizableParallelRunnerSuggestThreads(info.xsize, info.ysize)); } else if (status == JXL_DEC_COLOR_ENCODING) { // check for ICC profile deleteLoadedProfileData(); @@ -902,8 +900,7 @@ int ImageIO::loadJxl(const Glib::ustring &fname) size_t icc_size = 0; if (JXL_DEC_SUCCESS != - JxlDecoderGetICCProfileSize(dec.get(), &format, - _PROFILE_, &icc_size)) { + JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size)) { g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); } @@ -911,7 +908,7 @@ int ImageIO::loadJxl(const Glib::ustring &fname) icc_profile.resize(icc_size); if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsICCProfile( - dec.get(), &format, _PROFILE_, + dec.get(), _PROFILE_, icc_profile.data(), icc_profile.size())) { g_printerr( "Warning: JxlDecoderGetColorAsICCProfile failed\n"); @@ -924,14 +921,15 @@ int ImageIO::loadJxl(const Glib::ustring &fname) } } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { format.data_type = JXL_TYPE_FLOAT; - if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize( - dec.get(), &format, &buffer_size)) { + + if (JXL_DEC_SUCCESS != + JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { g_printerr("Error: JxlDecoderImageOutBufferSize failed\n"); return IMIO_READERROR; } + buffer = g_malloc(buffer_size); - if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, - buffer, buffer_size)) { + if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer, buffer_size)) { g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); g_free(buffer); return IMIO_READERROR; From b2550abd83f598030a7dc3dc49f0e321658c9aa8 Mon Sep 17 00:00:00 2001 From: xiota Date: Wed, 10 Apr 2024 13:44:09 +0000 Subject: [PATCH 163/291] Add cmake option WITH_JXL ON = Force required OFF = Optional --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23a3dbc0c..f26112cd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,6 +222,7 @@ option(USE_EXPERIMENTAL_LANG_VERSIONS "Build with -std=c++0x" OFF) option(BUILD_SHARED "Build with shared libraries" OFF) option(WITH_BENCHMARK "Build with benchmark code" OFF) option(WITH_MYFILE_MMAP "Build using memory mapped file" ON) +option(WITH_JXL "Build with JPEG XL import support" OFF) option(WITH_LTO "Build with link-time optimizations" OFF) option(WITH_SAN "Build with run-time sanitizer" OFF) option(WITH_PROF "Build with profiling instrumentation" OFF) @@ -552,7 +553,12 @@ if(WITH_SYSTEM_KLT) find_package(KLT REQUIRED) endif() -pkg_check_modules(JXL IMPORTED_TARGET libjxl libjxl_threads) +set(JXL_LIBS "libjxl libjxl_threads") +if(WITH_JXL) + pkg_check_modules(JXL REQUIRED IMPORTED_TARGET ${JXL_LIBS}) +else() + pkg_check_modules(JXL IMPORTED_TARGET ${JXL_LIBS}) +endif() if(JXL_FOUND) add_definitions(-DLIBJXL) endif() From 4a16bdd624ffbce579359a9acc425c6efec4949d Mon Sep 17 00:00:00 2001 From: xiota Date: Wed, 10 Apr 2024 18:18:55 +0000 Subject: [PATCH 164/291] Change WITH_JXL option to tristate (AUTO/ON/OFF) --- CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f26112cd2..4fd1221c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,7 +222,6 @@ option(USE_EXPERIMENTAL_LANG_VERSIONS "Build with -std=c++0x" OFF) option(BUILD_SHARED "Build with shared libraries" OFF) option(WITH_BENCHMARK "Build with benchmark code" OFF) option(WITH_MYFILE_MMAP "Build using memory mapped file" ON) -option(WITH_JXL "Build with JPEG XL import support" OFF) option(WITH_LTO "Build with link-time optimizations" OFF) option(WITH_SAN "Build with run-time sanitizer" OFF) option(WITH_PROF "Build with profiling instrumentation" OFF) @@ -248,6 +247,9 @@ set(TCMALLOC_LIB_DIR "" CACHE PATH "Custom path for the tcmalloc library") +set(WITH_JXL AUTO CACHE STRING "Build with JPEG XL support") +set_property(CACHE WITH_JXL PROPERTY STRINGS AUTO ON OFF) + # Set installation directories: if(WIN32 OR APPLE) if(BUILD_BUNDLE) @@ -560,7 +562,13 @@ else() pkg_check_modules(JXL IMPORTED_TARGET ${JXL_LIBS}) endif() if(JXL_FOUND) - add_definitions(-DLIBJXL) + if(WITH_JXL OR WITH_JXL STREQUAL AUTO) + add_definitions(-DLIBJXL) + else() + message(STATUS " JXL support disabled by WITH_JXL = ${WITH_JXL}") + set(JXL_INCLUDE_DIRS "") + set(JXL_LIBRARIES "") + endif() endif() # Check for libcanberra-gtk3 (sound events on Linux): From c514fbb939662aa0df0e5015f9a7560f1c97aeee Mon Sep 17 00:00:00 2001 From: xiota Date: Wed, 10 Apr 2024 18:51:06 +0000 Subject: [PATCH 165/291] Fix tristate auto behavior --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fd1221c0..141783f23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,7 +247,7 @@ set(TCMALLOC_LIB_DIR "" CACHE PATH "Custom path for the tcmalloc library") -set(WITH_JXL AUTO CACHE STRING "Build with JPEG XL support") +set(WITH_JXL "AUTO" CACHE STRING "Build with JPEG XL support") set_property(CACHE WITH_JXL PROPERTY STRINGS AUTO ON OFF) # Set installation directories: @@ -556,13 +556,13 @@ if(WITH_SYSTEM_KLT) endif() set(JXL_LIBS "libjxl libjxl_threads") -if(WITH_JXL) +if(WITH_JXL AND NOT WITH_JXL STREQUAL "AUTO") pkg_check_modules(JXL REQUIRED IMPORTED_TARGET ${JXL_LIBS}) else() pkg_check_modules(JXL IMPORTED_TARGET ${JXL_LIBS}) endif() if(JXL_FOUND) - if(WITH_JXL OR WITH_JXL STREQUAL AUTO) + if(WITH_JXL OR WITH_JXL STREQUAL "AUTO") add_definitions(-DLIBJXL) else() message(STATUS " JXL support disabled by WITH_JXL = ${WITH_JXL}") From 01f925d8d7f295be0efcdb6f744a1e57a0fdb4d9 Mon Sep 17 00:00:00 2001 From: xiota Date: Thu, 11 Apr 2024 05:31:03 +0000 Subject: [PATCH 166/291] Revise cmake tristate option --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 141783f23..fe7884ee9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -555,12 +555,12 @@ if(WITH_SYSTEM_KLT) find_package(KLT REQUIRED) endif() -set(JXL_LIBS "libjxl libjxl_threads") if(WITH_JXL AND NOT WITH_JXL STREQUAL "AUTO") - pkg_check_modules(JXL REQUIRED IMPORTED_TARGET ${JXL_LIBS}) + set(JXL_REQUIRED "REQUIRED") else() - pkg_check_modules(JXL IMPORTED_TARGET ${JXL_LIBS}) + set(JXL_REQUIRED "") endif() +pkg_check_modules(JXL ${JXL_REQUIRED} IMPORTED_TARGET libjxl libjxl_threads) if(JXL_FOUND) if(WITH_JXL OR WITH_JXL STREQUAL "AUTO") add_definitions(-DLIBJXL) From fe68e913be19fe5b8ae8af9bf8c0defaf4fdba4e Mon Sep 17 00:00:00 2001 From: xiota Date: Thu, 11 Apr 2024 15:44:55 +0000 Subject: [PATCH 167/291] Conditional compilation for old/new API Debian/Ubuntu package libjxl 0.7.0, but Arch/MSYS2 package 0.10.2 --- rtengine/imageio.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index e5a3683dc..c6576b3c8 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -900,16 +900,28 @@ int ImageIO::loadJxl(const Glib::ustring &fname) size_t icc_size = 0; if (JXL_DEC_SUCCESS != - JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size)) { +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) + JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) +#else + JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) +#endif + ) { g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); } if (icc_size > 0) { icc_profile.resize(icc_size); if (JXL_DEC_SUCCESS != +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) + JxlDecoderGetColorAsICCProfile( + dec.get(), &format, _PROFILE_, + icc_profile.data(), icc_profile.size()) +#else JxlDecoderGetColorAsICCProfile( dec.get(), _PROFILE_, - icc_profile.data(), icc_profile.size())) { + icc_profile.data(), icc_profile.size()) +#endif + ) { g_printerr( "Warning: JxlDecoderGetColorAsICCProfile failed\n"); } else { From 84134e9aa2a2a7c2acfb08075b3407c38e08e793 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 12 Apr 2024 07:52:20 +0200 Subject: [PATCH 168/291] Change tweakParams spot.cc - hand-open-hicontrast toolbar.cc (#7029) --- rtgui/spot.cc | 3 +++ rtgui/toolbar.cc | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rtgui/spot.cc b/rtgui/spot.cc index 43fdb632d..ad5fab63e 100644 --- a/rtgui/spot.cc +++ b/rtgui/spot.cc @@ -893,4 +893,7 @@ void Spot::tweakParams(procparams::ProcParams& pparams) pparams.gradient.enabled = false; pparams.pcvignette.enabled = false; pparams.colorappearance.enabled = false; + pparams.locallab.enabled = false; + // pparams.toneCurve.hrenabled = false; // not sure for this one, it could be useful for ExpComp w/o performance penalty + pparams.toneCurve.histmatching = false; } diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index 56237197c..1b59b8b24 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -27,8 +27,8 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n { editingMode = false; - - handimg.reset(new RTImage("hand-open", Gtk::ICON_SIZE_LARGE_TOOLBAR)); + //handimg.reset(new RTImage("hand-open", Gtk::ICON_SIZE_LARGE_TOOLBAR)); + handimg.reset(new RTImage("hand-open-hicontrast", Gtk::ICON_SIZE_LARGE_TOOLBAR)); editinghandimg.reset(new RTImage("crosshair-adjust", Gtk::ICON_SIZE_LARGE_TOOLBAR)); handTool = Gtk::manage (new Gtk::ToggleButton ()); From 79450113b4cff12af787e209b1fbbd9b57d3a6ec Mon Sep 17 00:00:00 2001 From: xiota Date: Fri, 12 Apr 2024 22:02:37 +0000 Subject: [PATCH 169/291] Add libjxl to workflow depends lists --- .github/workflows/appimage.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cf82dafb8..b44ce89c6 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -35,7 +35,7 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libjxl-dev libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full - name: Install Exiv2 run: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f57786098..868bccf42 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -41,7 +41,7 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev libjxl-dev - name: Configure build run: | diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8755f7c66..ad16f96d5 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -25,7 +25,7 @@ jobs: mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 | tee -a depslog + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6963df7c9..56a6320e6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -52,6 +52,7 @@ jobs: fftw:p lensfun:p libiptcdata:p + libjxl:p exiv2:p - name: Configure build From eaabf66e9c4e65471d2f97f3eb4a89b6eb3271c0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 12 Apr 2024 22:36:08 -0700 Subject: [PATCH 170/291] Register icons folder for Windows installer --- tools/win/InnoSetup/WindowsInnoSetup.iss.in | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/win/InnoSetup/WindowsInnoSetup.iss.in b/tools/win/InnoSetup/WindowsInnoSetup.iss.in index a80925d72..f95657bd7 100644 --- a/tools/win/InnoSetup/WindowsInnoSetup.iss.in +++ b/tools/win/InnoSetup/WindowsInnoSetup.iss.in @@ -102,6 +102,7 @@ Source: "{#MyBuildBasePath}\camconst.json"; DestDir: "{app}"; Flags: ignoreversi Source: "{#MyBuildBasePath}\dcpprofiles\*"; DestDir: "{app}\dcpprofiles\"; Flags: ignoreversion recursesubdirs createallsubdirs ;Source: "{#MyBuildBasePath}\etc\*"; DestDir: "{app}\etc\"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyBuildBasePath}\iccprofiles\*"; DestDir: "{app}\iccprofiles\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\icons\*"; DestDir: "{app}\icons\"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyBuildBasePath}\images\*"; DestDir: "{app}\images\"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyBuildBasePath}\languages\*"; DestDir: "{app}\languages\"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "{#MyBuildBasePath}\licenses\*"; DestDir: "{app}\licenses\"; Flags: ignoreversion recursesubdirs createallsubdirs From 9cd5ebbf3795711fd52fc0eb321b413ec5099a9f Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 14 Apr 2024 02:08:02 +0000 Subject: [PATCH 171/291] Add libjxl to appimage workflow --- .github/workflows/appimage.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index b44ce89c6..cc0f6b025 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -35,7 +35,21 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libjxl-dev libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full libtcmalloc-minimal4 + + - name: Install libjxl + run: | + echo "Downloading and installing libhwy and libjxl..." + VERSION_UBUNTU=20.04 + VERSION_JXL=0.10.2 + DEB_URL_HWYDEV="https://launchpad.net/~ubuntuhandbook1/+archive/ubuntu/apps/+files/libhwy-dev_0.16.0-0focal1_amd64.deb" + DEB_URL_HWY="https://launchpad.net/~ubuntuhandbook1/+archive/ubuntu/apps/+files/libhwy0_0.16.0-0focal1_amd64.deb" + curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libhwy-dev.deb "$DEB_URL_HWYDEV" + curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libhwy.deb "$DEB_URL_HWY" + curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libjxl-debs.tar.gz \ + "https://github.com/libjxl/libjxl/releases/download/v${VERSION_JXL}/jxl-debs-amd64-ubuntu-${VERSION_UBUNTU}-v${VERSION_JXL}.tar.gz" + tar xf libjxl-debs.tar.gz + DEBIAN_FRONTEND=noninteractive sudo dpkg -i libhwy-dev.deb libhwy.deb jxl_${VERSION_JXL}_amd64.deb libjxl-dev_${VERSION_JXL}_amd64.deb libjxl_${VERSION_JXL}_amd64.deb - name: Install Exiv2 run: | From aff8de59ea1efcadb7bbcdaad120e4215508a2f0 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 14 Apr 2024 02:10:17 +0000 Subject: [PATCH 172/291] Add libjxl to codeql workflow --- .github/workflows/codeql.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 868bccf42..9452c0587 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -41,7 +41,17 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev libjxl-dev + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev libhwy0 libhwy-dev + + - name: Install libjxl + run: | + echo "Downloading and installing libjxl..." + VERSION_UBUNTU=22.04 + VERSION_JXL=0.10.2 + curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libjxl-debs.tar.gz \ + "https://github.com/libjxl/libjxl/releases/download/v${VERSION_JXL}/jxl-debs-amd64-ubuntu-${VERSION_UBUNTU}-v${VERSION_JXL}.tar.gz" + tar xf libjxl-debs.tar.gz + DEBIAN_FRONTEND=noninteractive sudo dpkg -i jxl_${VERSION_JXL}_amd64.deb libjxl-dev_${VERSION_JXL}_amd64.deb libjxl_${VERSION_JXL}_amd64.deb - name: Configure build run: | From 775f7cbd036c394dcce2aff926460739d6d4245c Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 14 Apr 2024 05:22:24 +0000 Subject: [PATCH 173/291] Add missing dep to codeql workflow --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9452c0587..049b1d184 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -41,7 +41,7 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev libhwy0 libhwy-dev + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexiv2-dev libtcmalloc-minimal4 libhwy0 libhwy-dev - name: Install libjxl run: | From 4c61b7d3c3eb8d474ab54a2221eeb1a059dcd67d Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 Apr 2024 22:44:59 -0700 Subject: [PATCH 174/291] Squashed 'rtengine/libraw/' changes from 1ef70158d..12b0e5d60 12b0e5d60 Snapshot 202403 a4c9b1981 loop parameters in remove_trailing_spaces e231b01a4 CR3-Qstep table: avoid wrong 64-bit code generation 21368133a 0.21.2 release a6f212a4a tag type => tag size mapping fixed 41506ef73 cubic_spline: better handling of non-integer data 17294b5fd extra metadata check in arq_load_raw 47d9dd8e2 Better incorrect data handling in cubic_spline 3baa51068 skip invalid pattern in xtrans_interpolate eaf63bf5f Check HL recovery coeffs before processing a14574080 limit wavelet denoise minimum size 4e597e4e9 Merge pull request #594 from pinotree/path_max 086dcb9a6 raw-identify: use fallback if PATH_MAX not available 0e105f9f8 additional check against corrupted ljpeg layout 0c8b68e9f Disable color conversion for Canon 16-bit thumbnails cd1abd695 docs/changelog: explained the case when no thumbnail is found in specific file 6fffd414b rename swapXX to libraw_swapXX to avoid name conflict af78ae48a Check against corrupted LJPEG header in Canon sRAW decoder ba780e600 Limit embedded color profile allocation/read size 122bf7c5b Wrong alloc result check for 16-bit bitmap thumbnail e6dd2709e check pana_data/buffer offset before use ae2dc5884 Check P1 quadrant linearization coeff[15] against zero f2998bacc avoid integer overflow in buffer space check 443b7fb51 prevent buffer overrun in buffer_datastream::scanf_one 35a6d3615 ensure correct T.tlength for 16b bitmap thumbnails(2) b69ea8be5 ensure correct T.tlength for 16b bitmap thumbnails 2b6eca897 Do not run sraw decoder on (crafted) bayer files 68808b57f better striped thumbnails handling 9ab70f6dc do not set shrink flag for 3/4 component images 32425dd96 allow more decoders for fuji-rotated RAWs REVERT: 1ef70158d 0.21.2 release REVERT: 62f042366 tag type => tag size mapping fixed REVERT: ee087e3fe cubic_spline: better handling of non-integer data REVERT: af755b991 extra metadata check in arq_load_raw REVERT: 0fadd8819 Better incorrect data handling in cubic_spline REVERT: d7fb66053 skip invalid pattern in xtrans_interpolate REVERT: d059ed280 Check HL recovery coeffs before processing REVERT: 104730519 limit wavelet denoise minimum size REVERT: cae09838e raw-identify: use fallback if PATH_MAX not available REVERT: d6c677608 additional check against corrupted ljpeg layout REVERT: 1001a6ac1 Disable color conversion for Canon 16-bit thumbnails REVERT: a5130b01b docs/changelog: explained the case when no thumbnail is found in specific file REVERT: 600c0c63d rename swapXX to libraw_swapXX to avoid name conflict REVERT: 299c8a11b Check against corrupted LJPEG header in Canon sRAW decoder REVERT: ec8671ad9 Limit embedded color profile allocation/read size REVERT: 5229d5942 Wrong alloc result check for 16-bit bitmap thumbnail REVERT: b278b775f check pana_data/buffer offset before use REVERT: 7f4b8d3af Check P1 quadrant linearization coeff[15] against zero REVERT: e942a7db6 avoid integer overflow in buffer space check REVERT: f6a57cfb8 prevent buffer overrun in buffer_datastream::scanf_one REVERT: 3e62ed304 ensure correct T.tlength for 16b bitmap thumbnails(2) REVERT: 8e52d81cd ensure correct T.tlength for 16b bitmap thumbnails REVERT: 8e1af15e2 Do not run sraw decoder on (crafted) bayer files REVERT: 0ace959c2 better striped thumbnails handling REVERT: 477e0719f do not set shrink flag for 3/4 component images REVERT: c8efae6c5 allow more decoders for fuji-rotated RAWs git-subtree-dir: rtengine/libraw git-subtree-split: 12b0e5d60c57bb795382fda8494fc45f683550b8 --- COPYRIGHT | 2 +- Changelog.txt | 120 +- ...ng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff | 13 + GoPro/gpr_read_image.cpp-dng16.diff | 29 + GoPro/gpr_read_image.cpp-dng17.diff | 17 + GoPro/gpr_read_image.h-dng16.diff | 12 + GoPro/gpr_read_image.h-dng17.diff | 17 + Makefile.am | 3 +- Makefile.devel | 23 +- Makefile.devel.nopp | 12 +- Makefile.devel.noppr2i | 13 +- Makefile.dist | 24 +- Makefile.mingw | 13 +- Makefile.msvc | 24 +- README.DNGSDK.txt | 10 +- README.GoPro.txt | 24 +- README.md | 18 +- RawSpeed3/README.md | 1 + .../patches/05.no-phase-one-correction.patch | 16 + buildfiles/libraw.pro | 3 +- buildfiles/libraw.vcxproj | 3 + configure.ac | 22 - doc/API-C.html | 1 + doc/API-CXX.html | 4 - doc/API-datastruct.html | 52 +- doc/Install-LibRaw.html | 3 +- doc/index.html | 2 +- internal/dcraw_defs.h | 2 +- internal/dcraw_fileio_defs.h | 2 +- internal/defines.h | 10 +- internal/dmp_include.h | 2 +- internal/libraw_cameraids.h | 16 +- internal/libraw_checked_buffer.h | 28 + internal/libraw_cxx_defs.h | 34 +- internal/libraw_internal_funcs.h | 24 +- internal/losslessjpeg.h | 292 +++++ internal/var_defines.h | 3 +- internal/x3f_tools.h | 2 +- libraw/libraw.h | 16 +- libraw/libraw_alloc.h | 2 +- libraw/libraw_const.h | 23 +- libraw/libraw_datastream.h | 19 +- libraw/libraw_internal.h | 19 +- libraw/libraw_types.h | 13 +- libraw/libraw_version.h | 6 +- samples/4channels.cpp | 4 +- samples/dcraw_emu.cpp | 2 +- samples/dcraw_half.c | 2 +- samples/half_mt.c | 2 +- samples/half_mt_win32.c | 2 +- samples/mem_image_sample.cpp | 2 +- samples/multirender_test.cpp | 2 +- samples/openbayer_sample.cpp | 2 +- samples/postprocessing_benchmark.cpp | 2 +- samples/raw-identify.cpp | 2 +- samples/rawtextdump.cpp | 2 +- samples/simple_dcraw.cpp | 2 +- samples/unprocessed_raw.cpp | 2 +- src/decoders/canon_600.cpp | 2 +- src/decoders/crx.cpp | 6 +- src/decoders/decoders_dcraw.cpp | 114 +- src/decoders/decoders_libraw_dcrdefs.cpp | 3 +- src/decoders/dng.cpp | 7 +- src/decoders/fp_dng.cpp | 2 +- src/decoders/generic.cpp | 2 +- src/decoders/kodak_decoders.cpp | 2 +- src/decoders/load_mfbacks.cpp | 2 +- src/decoders/pana8.cpp | 529 ++++++++ src/decoders/smal.cpp | 2 +- src/decoders/sonycc.cpp | 318 +++++ src/decoders/unpack.cpp | 18 +- src/decoders/unpack_thumb.cpp | 111 +- src/decompressors/losslessjpeg.cpp | 391 ++++++ src/demosaic/ahd_demosaic.cpp | 2 +- src/demosaic/misc_demosaic.cpp | 2 +- src/demosaic/xtrans_demosaic.cpp | 2 +- src/integration/dngsdk_glue.cpp | 98 +- src/integration/rawspeed_glue.cpp | 84 +- src/libraw_c_api.cpp | 2 +- src/libraw_datastream.cpp | 68 +- src/metadata/adobepano.cpp | 2 +- src/metadata/canon.cpp | 33 +- src/metadata/ciff.cpp | 2 +- src/metadata/cr3_parser.cpp | 22 +- src/metadata/epson.cpp | 2 +- src/metadata/exif_gps.cpp | 2 +- src/metadata/fuji.cpp | 553 ++++---- src/metadata/hasselblad_model.cpp | 31 +- src/metadata/identify.cpp | 586 +++++---- src/metadata/identify_tools.cpp | 2 +- src/metadata/kodak.cpp | 2 +- src/metadata/leica.cpp | 15 +- src/metadata/makernotes.cpp | 2 +- src/metadata/mediumformat.cpp | 2 +- src/metadata/minolta.cpp | 2 +- src/metadata/misc_parsers.cpp | 36 +- src/metadata/nikon.cpp | 39 +- src/metadata/normalize_model.cpp | 82 +- src/metadata/olympus.cpp | 9 +- src/metadata/p1.cpp | 2 +- src/metadata/pentax.cpp | 2 +- src/metadata/samsung.cpp | 2 +- src/metadata/sony.cpp | 269 ++-- src/metadata/tiff.cpp | 257 +++- src/postprocessing/aspect_ratio.cpp | 2 +- src/postprocessing/dcraw_process.cpp | 2 +- src/postprocessing/mem_image.cpp | 2 +- src/postprocessing/postprocessing_aux.cpp | 2 +- src/postprocessing/postprocessing_ph.cpp | 2 +- src/postprocessing/postprocessing_utils.cpp | 2 +- .../postprocessing_utils_dcrdefs.cpp | 2 +- src/preprocessing/ext_preprocess.cpp | 2 +- src/preprocessing/preprocessing_ph.cpp | 2 +- src/preprocessing/raw2image.cpp | 18 +- src/preprocessing/subtract_black.cpp | 2 +- src/tables/cameralist.cpp | 72 +- src/tables/colorconst.cpp | 2 +- src/tables/colordata.cpp | 1115 +++++++++-------- src/tables/wblists.cpp | 2 +- src/utils/curves.cpp | 4 +- src/utils/decoder_info.cpp | 35 +- src/utils/init_close_utils.cpp | 17 +- src/utils/open.cpp | 64 +- src/utils/phaseone_processing.cpp | 16 +- src/utils/read_utils.cpp | 2 +- src/utils/thumb_utils.cpp | 13 +- src/utils/utils_dcraw.cpp | 2 +- src/utils/utils_libraw.cpp | 73 +- src/write/apply_profile.cpp | 2 +- src/write/file_write.cpp | 2 +- src/write/tiff_writer.cpp | 2 +- src/write/write_ph.cpp | 2 +- src/x3f/x3f_parse_process.cpp | 38 +- 133 files changed, 4307 insertions(+), 1939 deletions(-) create mode 100644 GoPro/dng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff create mode 100644 GoPro/gpr_read_image.cpp-dng16.diff create mode 100644 GoPro/gpr_read_image.cpp-dng17.diff create mode 100644 GoPro/gpr_read_image.h-dng16.diff create mode 100644 GoPro/gpr_read_image.h-dng17.diff create mode 100644 RawSpeed3/patches/05.no-phase-one-correction.patch create mode 100644 internal/libraw_checked_buffer.h create mode 100644 internal/losslessjpeg.h create mode 100644 src/decoders/pana8.cpp create mode 100644 src/decoders/sonycc.cpp create mode 100644 src/decompressors/losslessjpeg.cpp diff --git a/COPYRIGHT b/COPYRIGHT index 89e8bc528..3c6f41246 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,6 +1,6 @@ ** LibRaw: Raw images processing library ** -Copyright (C) 2008-2021 LibRaw LLC (http://www.libraw.org, info@libraw.org) +Copyright (C) 2008-2024 LibRaw LLC (http://www.libraw.org, info@libraw.org) LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/Changelog.txt b/Changelog.txt index 42c2bb2b5..50fb003b5 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,37 +1,115 @@ -2023-12-19 Alex Tutubalin +2024-03-30 Alex Tutubalin - LibRaw 0.21.2-Release + LibRaw-snapshot-202403 + + * Raw format support + 1) Panasonic encoding 8 + + 2) Sony YCC (Medium/Small compression) pseudo-RAW support: + -- normal processing (3-channel RGB output) + -- or YCbCr output if LIBRAW_RAWSPECIAL_SRAW_NO_RGB bit is set + in imgdata.rawparams.specials (one may specify the + LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE flag too avoid Cb/Cr interpolation) + Note: if YCbCr is selected, Cb/Cr neutral points are adjusted to 8192 + (to fit histogram/range area of the Y channel) + -- RAW (pseudo-RAW) data is already white balanced, so + imgdata.color.as_shot_wb_applied is set to + LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_SONY + + 3) DNG 1.7 (including JPEG-XL compression) support via Adobe DNG SDK 1.7.x integration + + 4) Canon CRN files: embedded RAW extracted + + * Camera support + - Canon EOS R6 Mark II, EOS R8, EOS R50, EOS R100, EOS Ra + - Fujifilm GFX100-II, X-T5, X-S20, X-H2, X-H2S: support of files with wrong metadata (pre 1.03 fw) + - GoPro HERO11, HERO12 (via GoPro SDK) + - Hasselblad X2D-100c + - Leica Q3, M11 Monochrom + - Nikon Z30, Z8 (HE/HE* formats are not supported) + - OM Digital OM-5 + - Panasonic DC-G9 II, DC-ZS200D / ZS220D, DC-TZ200D / TZ202D / TZ220D, DC-S5-II, DC-GH6 + - Sony A7C-II, A7CR, ILCE-6700, ZV-1M2, ZV-E1, ILCE-7RM5 (A7R-V), ILME-FX30, + A1: support for files damaged by exiftool + - Multiple DJI and Skydio drones + - tested with multiple smartphones with DNG format recorded. + + * Sony DSC-HX95: improved metadata parsing + + * Better support for cropped images from latest Fujifilm cameras + (X-H2, X-H2S, X-T5) + + * As planned in LibRaw snapshot 202101 release notes, OLD_VIDEOCAMS + support is dropped. + These cameras are no longer supported: + - old RED Cine cameras + - Canon C500 + - ARRI video/digital cinema cameras + + * JPEG-XL previews (DNG 1.7) support: + - new bit for imgdata.rawparams.options: LIBRAW_RAWOPTIONS_ALLOW_JPEGXL_PREVIEWS (not set by default) + - if the bit is set, LibRaw will perceive such previews in the same way as JPEG ones + (largest preview is selected by default, etc). + - tformat field for such preview is set to LIBRAW_THUMBNAIL_JPEGXL + - image metadata (width/height/channels count) is not parsed for JPEG-XL previews + + * New patch for RawSpeed3: 05.no-phase-one-correction.patch + this patch disables RawSpeed's PhaseOne flat field correction (not needed because + LibRaw uses own P1-metadata based correction) + + * RawSpeed3/PhaseOne compressed files: scale unpacked data to match camer black level data. + + * New imgdata.params.use_p1_correction parameter + If set to non-zero (default): PhaseOne compressed files will be corrected (linearization; defect mapping) + based on metadata contained in file. + + * New possible bit in imgdata.process_warnings: LIBRAW_WARN_VENDOR_CROP_SUGGESTED + If set: unknown/untested RAW image frame size passed to LibRaw, cropping may be incorrect. + It is suggested to use LibRaw::adjust_to_raw_inset_crop(1) for vendor specified crop. + + * Better handling of DNG RAW Previews with Stage2 opcodes + + * Added imgdata.makernotes.sony.AspectRatio field + - if parsed: contains aspect ratio (width to height) + - if not parsed: initialized to -999.f + + * Nikon Z8/HLG mode: do not add 10 bit/unknown format thumbnails to the thumb_list + + * Canon CR2 16-bit bitmap previes: do not convert from Kodak colorspace * New compile-defined limit LIBRAW_MAX_PROFILE_SIZE_MB: limits allocation/read size for embedded color profile (default: 256Mb) * Embedded color profile allocation/read size: limited by input file size. - * Multiple fixes (mostly inspired by oss-fuzz) to improve library stability and/or input checks. - - * raw-identify: use fallback if PATH_MAX not available - - * Disabled color conversion for Canon 16-bit thumbnails - - * docs/changelog: explained the case when no thumbnail is found in specific file - - * swapXX renamed to libraw_swapXX to avoid name conflict - - * better striped thumbnails handling - + * Check against corrupted LJPEG header in Canon sRAW decoder -2023-01-05 Alex Tutubalin - LibRaw 0.21.1-Release - * fixed typo in panasonic metadata parser + * Better support for Sony metadata -2022-12-18 Alex Tutubalin - LibRaw 0.21-Release + * Better handling of memory allocation errors in unpack_thumb() - * Multiple fixes inspired by oss-fuzz project + * Support for 8bit/Monochrome DNG Previews + + * LibRaw::thumbOK(): return 0 for YCbCr thumbnails (because + unpack_thumb() will always return error: no correct thumbnails + with this format found in the image samples yet) + + * Improved Sigma X3F files model recognition + + * Placeholder for DNG/YCC preview decoding: such previews are recorded + by Samsung S21 Ultra smartfone, while all present samples contains + broken data; Right now 'no preview' returned for such files. + + * Support for BW bitmap previews in LibRaw::dcraw_thumb_writer + + * Phase One: explicitly switch to monochrome mode if firmware string + contains 'Achromatic' word + + * tiff parser: check for IFD offset before parsing it 2022-07-01 Alex Tutubalin - LibRaw 0.21-Beta1 + LibRaw 0.21 == Camera format support == * Phase One/Leaf IIQ-S v2 support diff --git a/GoPro/dng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff b/GoPro/dng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff new file mode 100644 index 000000000..1b356d0eb --- /dev/null +++ b/GoPro/dng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff @@ -0,0 +1,13 @@ +--- a/gpr_sdk/private/gpr_read_image.cpp ++++ b/gpr_sdk/private/gpr_read_image.cpp +@@ -68,8 +68,10 @@ gpr_read_image::gpr_read_image( gpr_buffer_auto* vc5_buffer ) : _vc5_buffer(vc5_ + } + + #if GPR_WRITING || GPR_READING ++#if !defined(qDNG_1_6) && !defined(qDNGSupportJXL) + const int ccVc5 = 9; // Vc5 compression type + #endif ++#endif + + void gpr_read_image::ReadTile (dng_host &host, + const dng_ifd &ifd, diff --git a/GoPro/gpr_read_image.cpp-dng16.diff b/GoPro/gpr_read_image.cpp-dng16.diff new file mode 100644 index 000000000..1761abc01 --- /dev/null +++ b/GoPro/gpr_read_image.cpp-dng16.diff @@ -0,0 +1,29 @@ +--- gpr_read_image.cpp.orig 2019-08-30 12:20:00.326653300 +0300 ++++ gpr_read_image.cpp 2019-08-31 10:43:26.568184100 +0300 +@@ -67,6 +67,10 @@ + fDecodeVC5 = true; + } + + void gpr_read_image::ReadTile (dng_host &host, + const dng_ifd &ifd, + dng_stream &stream, +@@ -77,7 +81,8 @@ + uint32 tileByteCount, + AutoPtr &compressedBuffer, + AutoPtr &uncompressedBuffer, +- AutoPtr &subTileBlockBuffer) ++ AutoPtr &subTileBlockBuffer, ++ bool usingMultipleThreads) + { + + if( ifd.fCompression == ccVc5 ) +@@ -122,7 +127,8 @@ + tileByteCount, + compressedBuffer, + uncompressedBuffer, +- subTileBlockBuffer); ++ subTileBlockBuffer, ++ usingMultipleThreads); + } + } + diff --git a/GoPro/gpr_read_image.cpp-dng17.diff b/GoPro/gpr_read_image.cpp-dng17.diff new file mode 100644 index 000000000..86f4e67b7 --- /dev/null +++ b/GoPro/gpr_read_image.cpp-dng17.diff @@ -0,0 +1,17 @@ +diff --git a/gpr_sdk/private/gpr_read_image.cpp b/gpr_sdk/private/gpr_read_image.cpp +index c611b3f..4f8fe88 100644 +--- a/gpr_sdk/private/gpr_read_image.cpp ++++ b/gpr_sdk/private/gpr_read_image.cpp +@@ -79,7 +81,12 @@ void gpr_read_image::ReadTile (dng_host &host, + uint32 plane, + uint32 planes, + uint32 tileByteCount, ++// DNG 1.7 detection ++#ifdef qDNGSupportJXL ++ std::shared_ptr &compressedBuffer, ++#else + AutoPtr &compressedBuffer, ++#endif + AutoPtr &uncompressedBuffer, + AutoPtr &subTileBlockBuffer, + bool usingMultipleThreads) diff --git a/GoPro/gpr_read_image.h-dng16.diff b/GoPro/gpr_read_image.h-dng16.diff new file mode 100644 index 000000000..413b55a51 --- /dev/null +++ b/GoPro/gpr_read_image.h-dng16.diff @@ -0,0 +1,12 @@ +--- gpr_read_image.h.orig 2019-08-30 12:20:00.326653300 +0300 ++++ gpr_read_image.h 2019-08-30 20:56:11.138246800 +0300 +@@ -56,7 +56,8 @@ + uint32 tileByteCount, + AutoPtr &compressedBuffer, + AutoPtr &uncompressedBuffer, +- AutoPtr &subTileBlockBuffer); ++ AutoPtr &subTileBlockBuffer, ++ bool usingMultipleThreads ); + }; + + #endif // GPR_READING diff --git a/GoPro/gpr_read_image.h-dng17.diff b/GoPro/gpr_read_image.h-dng17.diff new file mode 100644 index 000000000..a18db1652 --- /dev/null +++ b/GoPro/gpr_read_image.h-dng17.diff @@ -0,0 +1,17 @@ +diff --git a/gpr_sdk/private/gpr_read_image.h b/gpr_sdk/private/gpr_read_image.h +index 159310b..f7d3ce1 100644 +--- a/gpr_sdk/private/gpr_read_image.h ++++ b/gpr_sdk/private/gpr_read_image.h +@@ -54,7 +54,12 @@ public: + uint32 plane, + uint32 planes, + uint32 tileByteCount, ++// DNG 1.7 detection ++#ifdef qDNGSupportJXL ++ std::shared_ptr &compressedBuffer, ++#else + AutoPtr &compressedBuffer, ++#endif + AutoPtr &uncompressedBuffer, + AutoPtr &subTileBlockBuffer, + bool usingMultipleThreads ); diff --git a/Makefile.am b/Makefile.am index 19166b75e..c5bd647da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,7 +30,8 @@ lib_LTLIBRARIES = lib/libraw.la lib/libraw_r.la lib_libraw_a_CPPFLAGS = -DLIBRAW_NOTHREADS -w lib_libraw_a_SOURCES = src/libraw_c_api.cpp \ src/libraw_datastream.cpp src/decoders/canon_600.cpp \ - src/decoders/crx.cpp src/decoders/decoders_dcraw.cpp \ + src/decoders/crx.cpp src/decoders/pana8.cpp src/decoders/decoders_dcraw.cpp \ + src/decoders/sonycc.cpp src/decompressors/losslessjpeg.cpp \ src/decoders/decoders_libraw_dcrdefs.cpp \ src/decoders/decoders_libraw.cpp src/decoders/dng.cpp \ src/decoders/fp_dng.cpp src/decoders/fuji_compressed.cpp \ diff --git a/Makefile.devel b/Makefile.devel index f82c007e5..73da195e3 100644 --- a/Makefile.devel +++ b/Makefile.devel @@ -33,10 +33,6 @@ CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms -# Jasper support for RedCine -#CFLAGS+=-DUSE_JASPER -I/opt/local/include -#LDADD+=-L/opt/local/lib -ljasper - # ZLIB support (FP dng) CFLAGS+=-DUSE_ZLIB LDADD+=-lz @@ -58,7 +54,8 @@ HEADERS=libraw/libraw.h libraw/libraw_alloc.h libraw/libraw_const.h \ LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ - object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/crx.o object/pana8.o object/fp_dng.o object/decoders_libraw.o \ + object/sonycc.o object/losslessjpeg.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ @@ -91,7 +88,9 @@ LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ object/cameralist.mt.o object/fuji_compressed.mt.o \ - object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ + object/crx.mt.o object/pana8.mt.o object/fp_dng.mt.o \ + object/sonycc.mt.o object/losslessjpeg.mt.o \ + object/decoders_libraw.mt.o \ object/unpack.mt.o object/unpack_thumb.mt.o \ object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ object/colorconst.mt.o object/utils_libraw.mt.o \ @@ -210,6 +209,18 @@ object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/crx.mt.o: src/decoders/crx.cpp $(HEADERS) ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp +object/pana8.o: src/decoders/pana8.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pana8.o src/decoders/pana8.cpp +object/pana8.mt.o: src/decoders/pana8.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/pana8.mt.o src/decoders/pana8.cpp +object/sonycc.o: src/decoders/sonycc.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sonycc.o src/decoders/sonycc.cpp +object/sonycc.mt.o: src/decoders/sonycc.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/sonycc.mt.o src/decoders/sonycc.cpp +object/losslessjpeg.o: src/decompressors/losslessjpeg.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/losslessjpeg.o src/decompressors/losslessjpeg.cpp +object/losslessjpeg.mt.o: src/decompressors/losslessjpeg.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/losslessjpeg.mt.o src/decompressors/losslessjpeg.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp $(HEADERS) diff --git a/Makefile.devel.nopp b/Makefile.devel.nopp index 6ece7e9e8..e84d1e9d4 100644 --- a/Makefile.devel.nopp +++ b/Makefile.devel.nopp @@ -25,9 +25,6 @@ CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms -# Jasper support for RedCine -#CFLAGS+=-DUSE_JASPER -I/opt/local/include -#LDADD+=-L/opt/local/lib -ljasper # JPEG support for DNG and Kodak CFLAGS+=-DUSE_JPEG -I/usr/local/include @@ -40,7 +37,8 @@ CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o \ object/cameralist.o object/fuji_compressed.o \ - object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/crx.o object/pana8.o object/fp_dng.o object/decoders_libraw.o \ + object/sonycc.o object/losslessjpeg.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ @@ -108,6 +106,12 @@ object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/pana8.o: src/decoders/pana8.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pana8.o src/decoders/pana8.cpp +object/sonycc.o: src/decoders/sonycc.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sonycc.o src/decoders/sonycc.cpp +object/losslessjpeg.o: src/decompressors/losslessjpeg.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/losslessjpeg.o src/decompressors/losslessjpeg.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp diff --git a/Makefile.devel.noppr2i b/Makefile.devel.noppr2i index 69372877f..7fb9bc71d 100644 --- a/Makefile.devel.noppr2i +++ b/Makefile.devel.noppr2i @@ -25,10 +25,6 @@ CFLAGS+= -g -I. -pedantic -Wno-long-long -Wno-overflow -O3 #CFLAGS+=-DUSE_LCMS2 -I/opt/local/include #LDADD+=-L/opt/local/lib -llcms -# Jasper support for RedCine -#CFLAGS+=-DUSE_JASPER -I/opt/local/include -#LDADD+=-L/opt/local/lib -ljasper - # JPEG support for DNG and Kodak CFLAGS+=-DUSE_JPEG -I/usr/local/include LDADD+=-L/usr/local/lib -ljpeg @@ -40,7 +36,8 @@ CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o \ object/cameralist.o object/fuji_compressed.o \ - object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/crx.o object/pana8.o object/fp_dng.o object/decoders_libraw.o \ + object/sonycc.o object/losslessjpeg.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ @@ -100,6 +97,12 @@ object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/pana8.o: src/decoders/pana8.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pana8.o src/decoders/pana8.cpp +object/sonycc.o: src/decoders/sonycc.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sonycc.o src/decoders/sonycc.cpp +object/losslessjpeg.o: src/decompressors/losslessjpeg.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/losslessjpeg.o src/decompressors/losslessjpeg.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp diff --git a/Makefile.dist b/Makefile.dist index 9c3e3f1c1..4fd4ba989 100644 --- a/Makefile.dist +++ b/Makefile.dist @@ -21,10 +21,6 @@ CXX=g++ # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz -# Jasper support for RedCine -#CFLAGS+=-DUSE_JASPER -I/usr/local/include -#LDADD+=-L/usr/local/lib -ljasper - # ZLIB support (FP dng) CFLAGS+=-DUSE_ZLIB LDADD+=-lz @@ -47,7 +43,8 @@ CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ - object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/crx.o object/pana8.o object/fp_dng.o object/decoders_libraw.o \ + object/sonycc.o object/losslessjpeg.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ @@ -80,7 +77,8 @@ LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ object/cameralist.mt.o object/fuji_compressed.mt.o \ - object/crx.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ + object/crx.mt.o object/pana8.mt.o object/fp_dng.mt.o object/decoders_libraw.mt.o \ + object/sonycc.mt.o object/losslessjpeg.mt.o \ object/unpack.mt.o object/unpack_thumb.mt.o \ object/rawspeed_glue.mt.o object/dngsdk_glue.mt.o \ object/colorconst.mt.o object/utils_libraw.mt.o \ @@ -105,7 +103,7 @@ LIB_MT_OBJECTS= object/libraw_datastream.mt.o object/libraw_c_api.mt.o \ object/tiff.mt.o object/ciff.mt.o object/mediumformat.mt.o \ object/minolta.mt.o \ object/identify_tools.mt.o \ - object/hasselblad_model.o object/normalize_model.mt.o object/identify.mt.o \ + object/hasselblad_model.mt.o object/normalize_model.mt.o object/identify.mt.o \ object/misc_parsers.mt.o object/wblists.mt.o \ object/postprocessing_aux.mt.o object/postprocessing_utils_dcrdefs.mt.o \ object/aspect_ratio.mt.o \ @@ -215,6 +213,18 @@ object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp object/crx.mt.o: src/decoders/crx.cpp ${CXX} -c ${CFLAGS} -o object/crx.mt.o src/decoders/crx.cpp +object/pana8.o: src/decoders/pana8.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pana8.o src/decoders/pana8.cpp +object/pana8.mt.o: src/decoders/pana8.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/pana8.mt.o src/decoders/pana8.cpp +object/sonycc.o: src/decoders/sonycc.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sonycc.o src/decoders/sonycc.cpp +object/sonycc.mt.o: src/decoders/sonycc.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/sonycc.mt.o src/decoders/sonycc.cpp +object/losslessjpeg.o: src/decompressors/losslessjpeg.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/losslessjpeg.o src/decompressors/losslessjpeg.cpp +object/losslessjpeg.mt.o: src/decompressors/losslessjpeg.cpp $(HEADERS) + ${CXX} -c ${CFLAGS} -o object/losslessjpeg.mt.o src/decompressors/losslessjpeg.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_dcraw.mt.o: src/decoders/decoders_dcraw.cpp diff --git a/Makefile.mingw b/Makefile.mingw index f2c291e21..e9172e10f 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -16,10 +16,6 @@ CXX=g++ # CFLAGS+=-DUSE_DNGSDK -I../dng_sdk/source # LDADDD+=-L../dng_sdk/release -ldng -lXMPCore -ljpeg -lz -# Jasper support for RedCine -#CFLAGS+=-DUSE_JASPER -I/usr/local/include -#LDADD+=-L/usr/local/lib -ljasper - # JPEG support for lossy DNG #CFLAGS+=-DUSE_JPEG -I/usr/local/include #LDADD+=-L/usr/local/lib -ljpeg @@ -38,7 +34,8 @@ CSTFLAGS=$(CFLAGS) -DLIBRAW_NOTHREADS LIB_OBJECTS= object/libraw_datastream.o object/libraw_c_api.o \ object/cameralist.o object/fuji_compressed.o \ - object/crx.o object/fp_dng.o object/decoders_libraw.o \ + object/crx.o object/pana8.o object/fp_dng.o object/decoders_libraw.o \ + object/losslessjpeg.o object/sonycc.o \ object/unpack.o object/unpack_thumb.o \ object/rawspeed_glue.o object/dngsdk_glue.o \ object/colorconst.o object/utils_libraw.o object/init_close_utils.o \ @@ -153,6 +150,12 @@ object/canon_600.o: src/decoders/canon_600.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/canon_600.o src/decoders/canon_600.cpp object/crx.o: src/decoders/crx.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/crx.o src/decoders/crx.cpp +object/pana8.o: src/decoders/pana8.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/pana8.o src/decoders/pana8.cpp +object/sonycc.o: src/decoders/sonycc.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/sonycc.o src/decoders/sonycc.cpp +object/losslessjpeg.o: src/decompressors/losslessjpeg.cpp + ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/losslessjpeg.o src/decompressors/losslessjpeg.cpp object/decoders_dcraw.o: src/decoders/decoders_dcraw.cpp ${CXX} -c -DLIBRAW_NOTHREADS ${CFLAGS} -o object/decoders_dcraw.o src/decoders/decoders_dcraw.cpp object/decoders_libraw_dcrdefs.o: src/decoders/decoders_libraw_dcrdefs.cpp diff --git a/Makefile.msvc b/Makefile.msvc index c06b35f05..80bfcad05 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -41,7 +41,8 @@ $(LIBDLL): $(DLL) LIB_OBJECTS= object\libraw_datastream_st.obj object\libraw_c_api_st.obj \ object\cameralist_st.obj object\fuji_compressed_st.obj \ - object\crx_st.obj object\fp_dng_st.obj object\decoders_libraw_st.obj \ + object\crx_st.obj object\pana8_st.obj object\fp_dng_st.obj object\decoders_libraw_st.obj \ + object\sonycc_st.obj object\losslessjpeg_st.obj \ object\unpack_st.obj object\unpack_thumb_st.obj \ object\rawspeed_glue_st.obj object\dngsdk_glue_st.obj \ object\colorconst_st.obj object\utils_libraw_st.obj object\init_close_utils_st.obj \ @@ -74,7 +75,8 @@ LIB_OBJECTS= object\libraw_datastream_st.obj object\libraw_c_api_st.obj \ DLL_OBJECTS= object\libraw_datastream.obj object\libraw_c_api.obj \ object\cameralist.obj object\fuji_compressed.obj \ - object\crx.obj object\fp_dng.obj object\decoders_libraw.obj \ + object\crx.obj object\pana8.obj object\fp_dng.obj object\decoders_libraw.obj \ + object\sonycc.obj object\losslessjpeg.obj \ object\unpack.obj object\unpack_thumb.obj \ object\rawspeed_glue.obj object\dngsdk_glue.obj \ object\colorconst.obj object\utils_libraw.obj \ @@ -188,6 +190,24 @@ object\crx_st.obj: src\decoders\crx.cpp object\crx.obj: src\decoders\crx.cpp $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\crx.obj" /c src\decoders\crx.cpp +object\pana8_st.obj: src\decoders\pana8.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\pana8_st.obj" /c src\decoders\pana8.cpp + +object\pana8.obj: src\decoders\pana8.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\pana8.obj" /c src\decoders\pana8.cpp + +object\sonycc_st.obj: src\decoders\sonycc.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\sonycc_st.obj" /c src\decoders\sonycc.cpp + +object\sonycc.obj: src\decoders\sonycc.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\sonycc.obj" /c src\decoders\sonycc.cpp + +object\losslessjpeg_st.obj: src\decompressors\losslessjpeg.cpp + $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\losslessjpeg_st.obj" /c src\decompressors\losslessjpeg.cpp + +object\losslessjpeg.obj: src\decompressors\losslessjpeg.cpp + $(CC) $(COPT) /DLIBRAW_BUILDLIB /Fo"object\\losslessjpeg.obj" /c src\decompressors\losslessjpeg.cpp + object\decoders_dcraw_st.obj: src\decoders\decoders_dcraw.cpp $(CC) $(COPT) /DLIBRAW_NODLL /DLIBRAW_BUILDLIB /Fo"object\\decoders_dcraw_st.obj" /c src\decoders\decoders_dcraw.cpp diff --git a/README.DNGSDK.txt b/README.DNGSDK.txt index 1eeabcac9..00f6ce497 100644 --- a/README.DNGSDK.txt +++ b/README.DNGSDK.txt @@ -15,8 +15,14 @@ To build LibRaw with DNG SDK specify USE_DNGSDK in defines and adjust include/linker path settings to point to DNG SDK's include and library folders. DNG SDK Version compatibility: - - Since LibRaw 0.20, DNG SDK 1.4 is required (DNG SDK 1.5 may work too, but - have not tested w/ LibRaw). + + - DNG SDK 1.6 and 1.7 are tested with LibRaw newer then 0.21 + If you want to use LibRaw with Modern DNG files please use: + -- DNG SDK 1.7 for JpegXL compressed files + -- DNG SDK 1.6+ to access Enhanced DNG frames + + - DNG SDK 1.5 may work too, but have not tested w/ LibRaw. + - Since LibRaw 0.20, DNG SDK 1.4 or newer is required - There are several DNG SDK 1.4 versions circulated, the oldest known is dated May 2012, you'll need the last one (dated June 2015). - This version is available from Adobe site: diff --git a/README.GoPro.txt b/README.GoPro.txt index 77ae15aed..5ce7c67c2 100644 --- a/README.GoPro.txt +++ b/README.GoPro.txt @@ -19,7 +19,7 @@ I. GPR SDK comes with (patched) Adobe DNG SDK source (v1.4 but outdated). II. So, you need to patch latest Adobe DNG SDK v1.4 (dated 2015), this version is available from Adobe: http://download.adobe.com/pub/adobe/dng/dng_sdk_1_4.zip - or use Adobe DNG SDK v1.6 + or use Adobe DNG SDK v1.6 or v1.7 (most likely, this apply for v1.5 too, but not tested/checked): @@ -29,17 +29,27 @@ II. So, you need to patch latest Adobe DNG SDK v1.4 (dated 2015), this version (it may not apply to any Adobe DNG SDK version, if so apply it by hands). This compression type is already handled (passed via validation) - in Adobe DNG SDK v1.6 + in Adobe DNG SDK v1.6/1.7 - b) Adobe DNG SDK v1.6 defines the ccVc5 constant in dng_tag_values.h + b) Adobe DNG SDK v1.6/1.7 defines the ccVc5 constant in dng_tag_values.h so GPR SDK's gpr_read_image.cpp will not compile due to constant redefinition - so use provided patch: LibRaw/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff + so use provided patch: + + For Adobe DNG SDK 1.6 (only): LibRaw/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff + For Adobe DNG SDK 1.6 or 1.7: LibRaw/GoPro/dng-sdk-1_6-1_7-hide-ccVc5-definitiion.diff + to use Adobe's definitiion c) Newer (than supplied w/ GPR SDK) Adobe SDK versions changes dng_read_image::ReadTile interface, please apply patches - LibRaw/GoPro/gpr_read_image.cpp.diff - and LibRaw/GoPro/gpr_read_image.h.diff to your GPR SDK code + * For all versions of Adobe DNG SDK: + + LibRaw/GoPro/gpr_read_image.cpp-dng16.diff + and LibRaw/GoPro/gpr_read_image.h-dng16.diff to your GPR SDK code + + * For Adone DNG SDK 1.7 (in addition to two -dng16.diff patches listed in previous section): + LibRaw/GoPro/gpr_read_image.h-dng16.diff + LibRaw/GoPro/gpr_read_image.h-dng17.diff d) GPR SDK's gpr_sdk/private/gpr.cpp uses own (added) dng_host method GetGPMFPayload so it will not compile with Adobes (not patched) @@ -50,6 +60,8 @@ II. So, you need to patch latest Adobe DNG SDK v1.4 (dated 2015), this version - or provide GPR's dng_host.h while building GPR SDK. (in our software we use 1st method). + + See Note VII below for detailed GPR SDK build instructions w/ Cmake III. LibRaw uses private gpr_read_image() interface diff --git a/README.md b/README.md index d7cedbe57..8f00255f7 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,13 @@ The library is intended for use with programs that work with RAW files, such as: Using the LibRaw library allows one to focus on the substantive part of processing the data contained in RAW files, without getting distracted by the wide variety of RAW file and metadata formats, compression algorithms, etc. -The library’s development is focused on: +The library�s development is focused on: * Support for new cameras and formats * Improving extraction of metadata necessary for RAW processing * Providing an interface for reading other types of metadata. -Additionally, the LibRaw library offers some basic RAW conversion, intended for cases when such conversion is not the main function of the LibRaw-using application _(for example: a viewer for 500+ graphic file formats, including RAW)._ These methods are inherited from the Dave Coffin’s dcraw.c utility _(see below the “Project history” section);_ their further development is not currently planned, because we do not consider production-quality rendering to be in the scope of LibRaw’s functionality _(the methods are retained for compatibility with prior versions and for rapid-fire testing of RAW support and other aspects)._ +Additionally, the LibRaw library offers some basic RAW conversion, intended for cases when such conversion is not the main function of the LibRaw-using application _(for example: a viewer for 500+ graphic file formats, including RAW)._ These methods are inherited from the Dave Coffin�s dcraw.c utility _(see below the �Project history� section);_ their further development is not currently planned, because we do not consider production-quality rendering to be in the scope of LibRaw�s functionality _(the methods are retained for compatibility with prior versions and for rapid-fire testing of RAW support and other aspects)._ ## Licensing @@ -35,7 +35,7 @@ The LibRaw library is distributed free of charge and with open-source code subje To use the LibRaw library in an application, you can choose the license that better suits your needs. -If you modify/add/improve the LibRaw source code, then your patches can only be included into the library’s official source code if you agree to it being distributed under both of the above licenses. +If you modify/add/improve the LibRaw source code, then your patches can only be included into the library�s official source code if you agree to it being distributed under both of the above licenses. We do not guarantee that the licensing will not change in future versions of LibRaw. @@ -47,7 +47,7 @@ We do not guarantee that the licensing will not change in future versions of Lib * Major releases _(for example, 0.20)_ are published once every year and a half to two years. * When the first public beta version of a major release is published, the list of supported cameras and formats is frozen; we try (but do not guarantee) to freeze the API/ABI as well. * The public major release contains only that code which has been sufficiently tested on a wide user base (including in our commercial products). Something very new may not be included in it (but it will probably be included in a public snapshot, see below). -* Minor updates _(0.20.1, 0.20.2…)_ do not change the API/ABI and new cameras are not added; generally they are just bugfixes. +* Minor updates _(0.20.1, 0.20.2�)_ do not change the API/ABI and new cameras are not added; generally they are just bugfixes. * Bugfixes are published as soon as possible in the [public GitHub repository](https://github.com/LibRaw/LibRaw). * Minor version increments: these are generally published if a serious error has been fixed, one that potentially affects many library users (for example, a possible stack overflow). @@ -55,7 +55,7 @@ We do not guarantee that the licensing will not change in future versions of Lib * Public snapshots are published every 7-9 months in the [public GitHub repository](https://github.com/LibRaw/LibRaw). * These versions contain support for new cameras that was added after the previous major release. The API/ABI of public snapshots is not frozen, and may change. -* Public snapshots are always tested on a fairly large user base, and may be considered suitable for use in programs that work with files with known origins (that is, recorded directly by users’ digital cameras). However, public snapshots should not be considered sufficiently reliable for processing files that are specially constructed for vulnerability testing; that is, they should not be used in public services that allow for anonymous processing of files of unknown provenance +* Public snapshots are always tested on a fairly large user base, and may be considered suitable for use in programs that work with files with known origins (that is, recorded directly by users� digital cameras). However, public snapshots should not be considered sufficiently reliable for processing files that are specially constructed for vulnerability testing; that is, they should not be used in public services that allow for anonymous processing of files of unknown provenance ## Support and feedback @@ -85,15 +85,15 @@ The code that implements rendering of RAW to RGB is inherited from dcraw.c, with In the early-to-mid 2010s, we gladly expanded post-processing implemented in LibRaw, and readily accepted the input of outside developers (new/improved methods for debayerization/demosaicing, systematic noise reduction etc.). -Experience has shown that the LibRaw team cannot support this added code on their own, while contributors do not provide support and development of the code they suggest and it ends up abandoned. As such, the majority of the modifications that are implemented by people outside the LibRaw team was moved to the [LibRaw-demosaic-pack-….](https://github.com/LibRaw?tab=repositories), where they remain in their original form (but these projects are still present in our GitHub). +Experience has shown that the LibRaw team cannot support this added code on their own, while contributors do not provide support and development of the code they suggest and it ends up abandoned. As such, the majority of the modifications that are implemented by people outside the LibRaw team was moved to the [LibRaw-demosaic-pack-�.](https://github.com/LibRaw?tab=repositories), where they remain in their original form (but these projects are still present in our GitHub). Thus, we arrive at our current status, described in the first part of this text. ## Copyrights and Acknowledgements -Copyright (C) 2008-2021 LibRaw LLC +Copyright (C) 2008-2024 LibRaw LLC -LibRaw uses code from Dave Coffin’s dcraw.c utility (without RESTRICTED/GPL2 code): +LibRaw uses code from Dave Coffin�s dcraw.c utility (without RESTRICTED/GPL2 code): Copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net @@ -101,6 +101,6 @@ LibRaw uses DCB demosaic code by Jaceck Gozdz distributed under BSD license: Copyright (C) 2010, Jacek Gozdz (mailto:cuniek@kft.umcs.lublin.pl) -LibRaw uses Roland Karlsson’s X3F tools source code, licensed under BSD license: +LibRaw uses Roland Karlsson�s X3F tools source code, licensed under BSD license: Copyright (c) 2010, Roland Karlsson (roland@proxel.se) \ No newline at end of file diff --git a/RawSpeed3/README.md b/RawSpeed3/README.md index 6dd21146c..9b4b80ca5 100644 --- a/RawSpeed3/README.md +++ b/RawSpeed3/README.md @@ -19,6 +19,7 @@ They are extremely reluctant to accept 3rd-party patches to this library, theref * **02.Makernotes-processing.patch** - fixes an error in processing the Makernotes tag. * **03.remove-limits-and-logging.patch** - removes debug printing and file size limits. This patch is optional, but if you are going to decode files from cameras that were not available at the time a particular version of RawSpeed was created, then this patch can be useful. * **04.clang-cl-compatibility.patch -** fixes for compatibility with Microsoft C++ library. + * **05.no-phase-one-correction.patch -** disables RawSpeed's PhaseOne flat field correction because LibRaw implements own ## Building the RawSpeed-v3 library diff --git a/RawSpeed3/patches/05.no-phase-one-correction.patch b/RawSpeed3/patches/05.no-phase-one-correction.patch new file mode 100644 index 000000000..28fdd3bed --- /dev/null +++ b/RawSpeed3/patches/05.no-phase-one-correction.patch @@ -0,0 +1,16 @@ +diff --git a/src/librawspeed/decoders/IiqDecoder.cpp b/src/librawspeed/decoders/IiqDecoder.cpp +index 61b04e1a..b6113679 100644 +--- a/src/librawspeed/decoders/IiqDecoder.cpp ++++ b/src/librawspeed/decoders/IiqDecoder.cpp +@@ -212,9 +212,10 @@ RawImage IiqDecoder::decodeRawInternal() { + PhaseOneDecompressor p(mRaw, std::move(strips)); + mRaw->createData(); + p.decompress(); +- ++#if 0 + if (correction_meta_data.getSize() != 0 && iiq) + CorrectPhaseOneC(correction_meta_data, split_row, split_col); ++#endif + + for (int i = 0; i < 3; i++) + mRaw->metadata.wbCoeffs[i] = wb.getFloat(); diff --git a/buildfiles/libraw.pro b/buildfiles/libraw.pro index 1a5c56cee..786123f13 100644 --- a/buildfiles/libraw.pro +++ b/buildfiles/libraw.pro @@ -28,7 +28,8 @@ DEFINES+=LIBRAW_BUILDLIB SOURCES+= ../src/libraw_datastream.cpp ../src/decoders/canon_600.cpp \ ../src/decoders/crx.cpp ../src/decoders/decoders_dcraw.cpp \ - ../src/decoders/decoders_libraw_dcrdefs.cpp \ + ../src/decoders/decoders_libraw_dcrdefs.cpp ../src/decoders/pana8.cpp \ + ../src/decompressors/losslessjpeg.cpp ../src/decoders/sonycc.cpp \ ../src/decoders/decoders_libraw.cpp ../src/decoders/dng.cpp \ ../src/decoders/fp_dng.cpp ../src/decoders/fuji_compressed.cpp \ ../src/decoders/generic.cpp ../src/decoders/kodak_decoders.cpp \ diff --git a/buildfiles/libraw.vcxproj b/buildfiles/libraw.vcxproj index 574f710bc..9d3277818 100644 --- a/buildfiles/libraw.vcxproj +++ b/buildfiles/libraw.vcxproj @@ -149,6 +149,9 @@ + + + diff --git a/configure.ac b/configure.ac index 7bf5fdfd7..092182727 100644 --- a/configure.ac +++ b/configure.ac @@ -64,28 +64,6 @@ if test x$jpeg = xtrue; then ) fi -# check for Jasper (JPEG2000) support -AC_ARG_ENABLE([jasper], - [ --enable-jasper Enable Jasper (JPEG2000) support for RedCine files], - [case "${enableval}" in - yes) jasper=true ;; - no) jasper=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-jasper]) ;; - esac],[jasper=true]) - -if test x$jasper = xtrue; then - AC_CHECK_LIB([jasper], [jas_init], - [ - AC_CHECK_HEADERS([jasper/jasper.h], [ - CPPFLAGS="$CPPFLAGS -DUSE_JASPER" - LIBS="$LIBS -ljasper" - AC_SUBST([PACKAGE_LIBS_PRIVATE],"-ljasper $PACKAGE_LIBS_PRIVATE") - ], AC_MSG_WARN([no jasper headers found])) - ], - AC_MSG_WARN([libjasper not found]) - ) -fi - # check if we want zlib support AC_ARG_ENABLE([zlib], [ --enable-zlib Enable zlib support for deflate compressed DNG files], diff --git a/doc/API-C.html b/doc/API-C.html index 952e54d9b..0421bed08 100644 --- a/doc/API-C.html +++ b/doc/API-C.html @@ -95,6 +95,7 @@

  • void libraw_set_bright(libraw_data_t *lr,float value);
  • void libraw_set_highlight(libraw_data_t *lr,int value);
  • void libraw_set_fbdd_noiserd(libraw_data_t *lr,int value);
  • +
  • int libraw_adjust_to_raw_inset_crop(libraw_data_t *lr, unsigned mask, float maxcrop);
  • Auxiliary Functions

    diff --git a/doc/API-CXX.html b/doc/API-CXX.html index b58ecbd3d..cf78531b2 100644 --- a/doc/API-CXX.html +++ b/doc/API-CXX.html @@ -751,10 +751,6 @@ This object is used by libjpeg for JPEG data reading from datastream.

    Returns -1 on error and 0 on success.

    -
    virtual void * make_jas_stream();
    -
    Creates LibJasper input stream (for JPEG2000 decoding). -

    returns NULL on error or data pointer on success.

    -

    Other methods
    diff --git a/doc/API-datastruct.html b/doc/API-datastruct.html index 5c2ddb3bf..1907b36b5 100644 --- a/doc/API-datastruct.html +++ b/doc/API-datastruct.html @@ -127,7 +127,8 @@ when raw2image() or dcraw_process() is called.
    libraw_output_params_t params;
    Data structure intended for management of image postprocessing (using - the dcraw emulator). Fields of this structure are described in detail below .
    libraw_callbacks_t callbacks;
    user-settable callbacks
    @@ -427,12 +428,12 @@ -

    - Note: even if no thumbnails were found in TIFF/CR3 structure, the - thumbcount field will be initialized to 1 and thumblist[0] will be - initialized to thumbnail data from the thumbnail data, so - LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb(). -

    +

    + Note: even if no thumbnails were found in TIFF/CR3 structure, the + thumbcount field will be initialized to 1 and thumblist[0] will be + initialized to thumbnail data from the thumbnail data, so + LibRaw::unpack_thumb_ex(0) will do the same as LibRaw::unpack_thumb(). +

    Structure libraw_lensinfo_t: parsed lens data

    The following parameters are extracted from Makernotes and EXIF, to help @@ -794,15 +795,19 @@ interpolation callback call.

    int no_interpolation;
    Disables call to demosaic code in LibRaw::dcraw_process()
    +
    int use_p1_correction;
    +
    If set to non-zero (default): PhaseOne compressed files will be corrected (linearization; defect mapping) + based on metadata contained in file.

    Structure libraw_callbacks_t: user-settable callbacks

    data_callback data_cb
    -
    Called on data error, settable via set_dataerror_handler. See C++ +
    Called on data error, settable via set_dataerror_handler. See C++ API for details.
    progress_callback progress_cb
    -
    Called on process callback, settable via set_progress_handler. See Called on process callback, settable via set_progress_handler. See C++ API for details.
    exif_parser_callback exif_cb, params: (void *context, int tag, int type, int len, unsigned int ord, void *ifp)
    @@ -978,7 +983,8 @@
    LIBRAW_BAD_CROP
    The incorrect cropping coordinates are set via params.cropbox[]: the left-top corner of cropping rectangle is outside the image. The - processing will be cancelled, all allocated resources will be freed, LIBRAW_TOO_BIG
    Raw data size exceeds data limit.
    @@ -1000,10 +1006,12 @@ file (only for formats supporting storage of several images in a file).
    LIBRAW_OUT_OF_ORDER_CALL
    -
    API functions have been called in wrong order (e.g.,
    API functions have been called in wrong order (e.g., unpack() before open_file() ) or the previous stage has ended with an error - (e.g., unpack() is called after unpack() is called after open_file() has returned an error).
    LIBRAW_NO_THUMBNAIL
    @@ -1145,7 +1153,7 @@ triplet.
    LIBRAW_THUMBNAIL_BITMAP16
    The thumbnail buffer contains the gamma-adjusted 16-bit RGB bitmap. To - get this format instead of LIBRAW_THUMBNAIL_BITMAP you + get this format instead of LIBRAW_THUMBNAIL_BITMAP you need to set LIBRAW_PROCESSING_USE_PPM16_THUMBS in processing options.
    LIBRAW_THUMBNAIL_LAYER
    @@ -1157,7 +1165,10 @@
    LIBRAW_THUMBNAIL_H265
    The thumbnail buffer contains a H.265 data frame (read from RAW file as is, no manipulations performed on it).
    -
    +
    LIBRAW_THUMBNAIL_JPEGXL
    +
    The thumbnail buffer contains a JPEG-XL data frame (read from RAW file + as is, no manipulations performed on it).
    +

    Nonstandard Situations (Warnings) during RAW Data Processing

    Some suspicious situations emerging during image processing are not fatal @@ -1210,6 +1221,10 @@

    DNG Stage2 conversion was performed
    LIBRAW_DNG_STAGE3_APPLIED
    DNG Stage3 conversion was performed
    +
    LIBRAW_WARN_VENDOR_CROP_SUGGESTED
    +
    If set: unknown/untested RAW image frame size passed to LibRaw, cropping may be incorrect. +

    It is suggested to use LibRaw::adjust_to_raw_inset_crop(1) for vendor specified crop. +
    @@ -1301,9 +1316,14 @@ plus data size is beyond filecontents. This flag enforces size+offset checks for files from known vendors (this will result into correct but smaller thumbnail selected). -
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS - same +
  • LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS - same is above, but check is performed regardless of vendor (Make tag).
  • - +
  • LIBRAW_RAWOPTIONS_ALLOW_JPEGXL_PREVIEWS - + if set, LibRaw will perceive such previews in the same way as JPEG onesgest preview is + selected by default, etc).

    + tformat field for such preview is set to LIBRAW_THUMBNAIL_JPEGXL. Image metadata (width/height/channels count) is not parsed for JPEG-XL previews +

  • +

    diff --git a/doc/Install-LibRaw.html b/doc/Install-LibRaw.html index a65e812be..3fb1aea0e 100644 --- a/doc/Install-LibRaw.html +++ b/doc/Install-LibRaw.html @@ -16,7 +16,6 @@

    Additional libraries (optional):

    • zlib (used to decode deflated DNGs)
    • -
    • libjasper (used to decode RED files)
    • libjpeg8 (used to decode lossy DNGs and several old Kodak cameras)

    LibRaw has been tested on 32- and 64-bit Unix systems working on x86- @@ -92,7 +91,7 @@ make nmake -f Makefile.msvc
    -

    You may need to edit Makefile.msvc to provide libjpeg/zlib/libjasper +

    You may need to edit Makefile.msvc to provide libjpeg/zlib paths to INCLUDE/LIB.

    If all paths are set correctly and the include-files/libraries have been found, then the following will be compiled:

    diff --git a/doc/index.html b/doc/index.html index f58e89c03..3401fe62b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -22,7 +22,7 @@

    Copyright

    -

    LibRaw library, Copyright (C) 2008-2021 LibRaw LLC (info@libraw.org)
    +

    LibRaw library, Copyright (C) 2008-2024 LibRaw LLC (info@libraw.org)
    The library includes source code from
    dcraw.c, Dave Coffin's raw photo decoder
    Copyright 1997-2016 by Dave Coffin, dcoffin a cybercom o net
    diff --git a/internal/dcraw_defs.h b/internal/dcraw_defs.h index 574f3a8bd..b53752511 100644 --- a/internal/dcraw_defs.h +++ b/internal/dcraw_defs.h @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/internal/dcraw_fileio_defs.h b/internal/dcraw_fileio_defs.h index 3d12edca5..68bd8581f 100644 --- a/internal/dcraw_fileio_defs.h +++ b/internal/dcraw_fileio_defs.h @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/internal/defines.h b/internal/defines.h index 674ad671b..a24666a8d 100644 --- a/internal/defines.h +++ b/internal/defines.h @@ -1,5 +1,5 @@ /* - Copyright 2008-2021 LibRaw LLC (info@libraw.org) + Copyright 2008-2024 LibRaw LLC (info@libraw.org) LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -23,9 +23,7 @@ it under the terms of the one of two licenses as you choose: #ifndef USE_JPEG #define NO_JPEG #endif -#ifndef USE_JASPER -#define NO_JASPER -#endif + #define DCRAW_VERSION "9.26" #ifndef _GNU_SOURCE @@ -65,13 +63,9 @@ typedef unsigned long long UINT64; #endif #ifdef NODEPS -#define NO_JASPER #define NO_JPEG #define NO_LCMS #endif -#ifndef NO_JASPER -#include /* Decode Red camera movies */ -#endif #ifndef NO_JPEG #include /* Decode compressed Kodak DC120 photos */ #endif /* and Adobe Lossy DNGs */ diff --git a/internal/dmp_include.h b/internal/dmp_include.h index 6b6b5a6c7..ab85279c2 100644 --- a/internal/dmp_include.h +++ b/internal/dmp_include.h @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/internal/libraw_cameraids.h b/internal/libraw_cameraids.h index 4d03006b6..419bdeaad 100644 --- a/internal/libraw_cameraids.h +++ b/internal/libraw_cameraids.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: internal/libraw_cameraids.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Aug 17, 2020 LibRaw is free software; you can redistribute it and/or modify @@ -91,6 +91,10 @@ it under the terms of the one of two licenses as you choose: #define CanonID_EOS_R7 (0x80000000ULL + 0x464ULL) #define CanonID_EOS_R10 (0x80000000ULL + 0x465ULL) #define CanonID_EOS_M50_Mark_II (0x80000000ULL + 0x468ULL) +#define CanonID_EOS_R50 (0x80000000ULL + 0x480ULL) +#define CanonID_EOS_R6m2 (0x80000000ULL + 0x481ULL) +#define CanonID_EOS_R8 (0x80000000ULL + 0x487ULL) +#define CanonID_EOS_R100 (0x80000000ULL + 0x498ULL) // CanonID_EOS_D2000C after Canon's TIFF2CR2 convertor: #define CanonID_EOS_D2000C (0x80000000ULL + 0x520ULL) @@ -160,6 +164,7 @@ it under the terms of the one of two licenses as you choose: #define OlyID_E_M1_Mark_III OlyID_str2hex("S0092") #define OlyID_E_P7 OlyID_str2hex("S0093") #define OlyID_OM_1 OlyID_str2hex("S0095") +#define OlyID_OM_5 OlyID_str2hex("S0101") #define OlyID_C_3030Z OlyID_str2hex("SX351") #define OlyID_C_5050Z OlyID_str2hex("SX558") #define OlyID_C_350Z OlyID_str2hex("SX751") @@ -303,6 +308,7 @@ it under the terms of the one of two licenses as you choose: #define SonyID_DSC_RX100M5A 0x171ULL #define SonyID_ILCE_6400 0x173ULL #define SonyID_DSC_RX0M2 0x174ULL +#define SonyID_DSC_HX95 0x175ULL #define SonyID_DSC_RX100M7 0x176ULL #define SonyID_ILCE_7RM4 0x177ULL #define SonyID_ILCE_9M2 0x178ULL @@ -317,4 +323,12 @@ it under the terms of the one of two licenses as you choose: #define SonyID_ILCE_7RM3A 0x182ULL #define SonyID_ILCE_7RM4A 0x183ULL #define SonyID_ILCE_7M4 0x184ULL +// #define SonyID_ZV_1F 0x185ULL // Sony ZV-1F doesn't save raw +#define SonyID_ILCE_7RM5 0x186ULL +#define SonyID_ILME_FX30 0x187ULL +#define SonyID_ZV_E1 0x189ULL +#define SonyID_ILCE_6700 0x18aULL +#define SonyID_ZV_1M2 0x18bULL +#define SonyID_ILCE_7CR 0x18cULL +#define SonyID_ILCE_7CM2 0x18dULL #endif diff --git a/internal/libraw_checked_buffer.h b/internal/libraw_checked_buffer.h new file mode 100644 index 000000000..a5de6fd99 --- /dev/null +++ b/internal/libraw_checked_buffer.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include "../libraw/libraw_types.h" + +class checked_buffer_t +{ +public: + // create with internal storage + checked_buffer_t(short ord, int size); + checked_buffer_t(short ord, unsigned char *dd, int ss); + ushort sget2(int offset); + void checkoffset(int off); + unsigned char operator[](int idx); + unsigned sget4(int offset); + double sgetreal(int type, int offset); + unsigned char *data() { return _data; } + + int tiff_sget(unsigned save, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, + unsigned *tag_datalen, int *tag_dataunitlen); +protected: + short _order; + + private: + unsigned char *_data; + int _len; + std::vector storage; +}; diff --git a/internal/libraw_cxx_defs.h b/internal/libraw_cxx_defs.h index 164849335..d249414c0 100644 --- a/internal/libraw_cxx_defs.h +++ b/internal/libraw_cxx_defs.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: internal/libraw_cxx_defs.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Aug 17, 2020 LibRaw is free software; you can redistribute it and/or modify @@ -39,43 +39,25 @@ it under the terms of the one of two licenses as you choose: #endif #include #endif - #ifdef USE_RAWSPEED -#include -#include -#include -#include -#include -#include -extern const char *_rawspeed_data_xml[]; -extern const int RAWSPEED_DATA_COUNT; -class CameraMetaDataLR : public RawSpeed::CameraMetaData -{ -public: - CameraMetaDataLR() : CameraMetaData() {} - CameraMetaDataLR(char *filename) : RawSpeed::CameraMetaData(filename) {} - CameraMetaDataLR(char *data, int sz); -}; - -CameraMetaDataLR *make_camera_metadata(); - +void *make_camera_metadata(); +void clear_camera_metadata(void*); +void clear_rawspeed_decoder(void*); #endif -#ifdef USE_DNGSDK -#include "dng_host.h" -#include "dng_negative.h" -#include "dng_simple_image.h" -#include "dng_info.h" -#endif #define P1 imgdata.idata #define S imgdata.sizes +#ifndef LIBRAW_DNGSDK_CONFLICT #define O imgdata.params #define C imgdata.color #define T imgdata.thumbnail #define MN imgdata.makernotes +#ifndef LIBRAW_EXPAT_CONFLICT #define IO libraw_internal_data.internal_output_params #define ID libraw_internal_data.internal_data +#endif +#endif #define makeIs(idx) (imgdata.idata.maker_index == idx) #define mnCamID imgdata.lens.makernotes.CamID diff --git a/internal/libraw_internal_funcs.h b/internal/libraw_internal_funcs.h index 6abdb6bde..83337a9b9 100644 --- a/internal/libraw_internal_funcs.h +++ b/internal/libraw_internal_funcs.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_internal_funcs.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 14, 2008 LibRaw is free software; you can redistribute it and/or modify @@ -88,9 +88,6 @@ it under the terms of the one of two licenses as you choose: void parsePentaxMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseRicohMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); void parseSamsungMakernotes(int base, unsigned tag, unsigned type, unsigned len, unsigned dng_writer); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - void fixupArri(); -#endif void setSonyBodyFeatures (unsigned long long id); void parseSonyLensType2 (uchar a, uchar b); void parseSonyLensFeatures (uchar a, uchar b); @@ -204,11 +201,6 @@ it under the terms of the one of two licenses as you choose: int guess_RAFDataGeneration (uchar *RAFData_start); void parse_fuji (int offset); void parse_fuji_thumbnail(int offset); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -// RedCine - void parse_redcine(); - void redcine_load_raw(); -#endif // Rollei void rollei_load_raw(); @@ -248,9 +240,6 @@ it under the terms of the one of two licenses as you choose: void nokia_load_raw(); void android_loose_load_raw(); void android_tight_load_raw(); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - void canon_rmf_load_raw(); -#endif unsigned pana_data (int nb, unsigned *bytes); void panasonic_load_raw(); // void panasonic_16x10_load_raw(); @@ -286,6 +275,7 @@ it under the terms of the one of two licenses as you choose: void kodak_rgb_load_thumb(); void kodak_ycbcr_load_thumb(); void vc5_dng_load_raw_placeholder(); + void jxl_dng_load_raw_placeholder(); // It's a Sony (and K&M) void sony_decrypt (unsigned *data, int len, int start, int key); void sony_load_raw(); @@ -293,6 +283,7 @@ it under the terms of the one of two licenses as you choose: void sony_arw2_load_raw(); void sony_arq_load_raw(); void sony_ljpeg_load_raw(); + void sony_ycbcr_load_raw(); void samsung_load_raw(); void samsung2_load_raw(); void samsung3_load_raw(); @@ -318,6 +309,14 @@ it under the terms of the one of two licenses as you choose: void parse_raspberrypi(); #endif + void kodak_thumb_loader(); + void dng_ycbcr_thumb_loader(); +#ifdef USE_X3FTOOLS + void x3f_thumb_loader(); + INT64 x3f_thumb_size(); +#endif + + // CAM/RGB void pseudoinverse (double (*in)[3], double (*out)[3], int size); void simple_coeff (int index); @@ -383,6 +382,7 @@ it under the terms of the one of two licenses as you choose: int crxParseImageHeader(uchar *cmp1TagData, int nTrack, int size); void panasonicC6_load_raw(); void panasonicC7_load_raw(); + void panasonicC8_load_raw(); void nikon_14bit_load_raw(); diff --git a/internal/losslessjpeg.h b/internal/losslessjpeg.h new file mode 100644 index 000000000..382746be0 --- /dev/null +++ b/internal/losslessjpeg.h @@ -0,0 +1,292 @@ +/* -*- C++ -*- + * File: huffmandec.h + * Copyright (C) 2023-2024 Alex Tutubalin, LibRaw LLC + * + Lossless JPEG decoder + + Code partially backported from DNGLab's rust code + DNGLab was originally created in 2021 by Daniel Vogelbacher. + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ +#pragma once +#include +#include + +struct BitPump // generic bit source +{ + virtual uint32_t peek(uint32_t num) = 0; + virtual void consume(uint32_t num) = 0; + + uint32_t get(uint32_t num) + { + if(num == 0) { return 0u; } + uint32_t val = peek(num); + consume(num); + return val; + } +}; + +struct ByteStreamBE // Jpeg is always big endian +{ + enum Exceptions + { + OK = 0, + EndOfBuffer = 1 + }; + + uint8_t *buffer; + unsigned size, pos; + ByteStreamBE(uint8_t *b, unsigned s) : buffer(b), size(s), pos(0) {} + ByteStreamBE() : buffer(0),size(0),pos(0){} + bool skip_to_marker(); + + uint8_t get_u8() + { + if (pos >= size) + throw EndOfBuffer; + uint8_t ret = buffer[pos]; + pos++; + return ret; + } + uint16_t get_u16() + { + if (pos + 2 > size) + throw EndOfBuffer; + uint8_t r1 = buffer[pos]; + uint8_t r2 = buffer[pos + 1]; + pos += 2; + return (r1 << 8) | r2; + } +}; + +struct BitPumpJpeg : public BitPump +{ + uint8_t *buffer; + unsigned size, pos; + uint64_t bits; + uint32_t nbits; + bool finished; + + void consume(uint32_t num) + { + if (num <= nbits) + { + nbits -= num; + bits &= (uint64_t(1) << nbits) - 1UL; + } + } + uint32_t peek(uint32_t num) + { + if (num > nbits && !finished) + { + if ((size >= 4) && pos < size && buffer[pos] != 0xff && buffer[pos + 1] != 0xff && buffer[pos + 2] != 0xff && + buffer[pos + 3] != 0xff) + { + uint64_t inbits = (uint32_t(buffer[pos]) << 24) | (uint32_t(buffer[pos + 1]) << 16) | + (uint32_t(buffer[pos + 2]) << 8) | (uint32_t(buffer[pos + 3])); + bits = (bits << 32) | inbits; + pos += 4; + nbits += 32; + } + else + { + int read_bytes = 0; + while (read_bytes < 4 && !finished) + { + uint8_t byte = 0; + if (pos >= size) + finished = true; + else + { + uint8_t nextbyte = buffer[pos]; + if (nextbyte != 0xff) + byte = nextbyte; + else if (buffer[pos + 1] == 0x00) + { + pos += 1; + byte = nextbyte; + } + else + finished = true; + }; + bits = (bits << 8) | uint64_t(byte); + pos += 1; + nbits += 8; + read_bytes += 1; + } + } + } + if(num > nbits && finished) + { + bits <<= 32; + nbits += 32; + } + return uint32_t(bits >> (nbits - num)); + } + + BitPumpJpeg(ByteStreamBE& s): buffer(s.buffer+s.pos),size(s.size-s.pos),pos(0),bits(0),nbits(0),finished(false){} +}; + + +const uint32_t LIBRAW_DECODE_CACHE_BITS = 13; +const uint64_t LIBRAW_CACHE_PRESENT_FLAG = 0x100000000L; + +struct HuffTable +{ + uint32_t bits[17]; + uint32_t huffval[256]; + uint32_t shiftval[256]; + bool dng_bug; + bool disable_cache; + uint32_t nbits; + std::vector hufftable; // len:8 << 16| huffval:8 << 8 | shift:8 + std::vector decodecache; + bool initialized; + HuffTable(); + void initval(uint32_t bits[17], uint32_t huffval[256], bool dng_bug); + + int32_t decode(BitPump& pump) + { + uint64_t cached = disable_cache ? 0 : decodecache[pump.peek(LIBRAW_DECODE_CACHE_BITS)]; + if (cached & LIBRAW_CACHE_PRESENT_FLAG) + { + uint32_t bits = (cached >> 16) & 0xff; + int16_t val = int16_t(cached & 0xffff); + if (val == -32768 && dng_bug) + { + if (bits > 16) + pump.consume(bits - 16); + } + else + pump.consume(bits); + return val; + } + else + return decode_slow1(pump); + } + + int32_t decode_slow1(BitPump &pump) + { + int32_t _diff = diff(pump, len(pump)); + return _diff; + } + + int32_t decode_slow2(BitPump & pump, uint32_t& outlen) // output: (len+shift):8, code:16 + { + uint32_t _len = len(pump); + int32_t _diff = diff(pump, _len); + uint8_t bits8 = (_len >> 16) & 0xff; + uint8_t len8 = (_len >> 8) & 0xff; + outlen = bits8 + len8; + return _diff; + } + + uint32_t len(BitPump & pump) //bits:8, len:8, shift:8 + { + uint32_t code = pump.peek(nbits); + uint32_t huffdata = hufftable[code]; + uint32_t bits = (huffdata >> 16) & 0xff; + pump.consume(bits); + return huffdata; + } + + int32_t diff(BitPump & pump, uint32_t hentry) // input: bits:8, len:8, shift:8; output: diff:i32 + { + uint32_t len = (hentry >> 8) & 0xff; + if (len == 0) + return 0; + if (len == 16) + { + if (dng_bug) + pump.get(16); + return -32768; + } + uint32_t shift = hentry & 0xff; + uint32_t fulllen = len + shift; + uint32_t bits = pump.get(len); + int32_t diff = ((bits << 1) + 1) << shift >> 1; + if ((diff & (1 << (fulllen - 1))) == 0) + { + diff -= int32_t((1 << fulllen) - ((shift == 0))); + } + return diff; + } +}; + +struct LibRaw_JpegComponentInfo +{ + unsigned id; + unsigned index; + unsigned dc_tbl; + unsigned subsample_h, subsample_v; + LibRaw_JpegComponentInfo() : id(0), index(0), dc_tbl(0), subsample_h(0), subsample_v(0) {}; + LibRaw_JpegComponentInfo(unsigned _id, unsigned _index, unsigned _dcn, unsigned _sh, unsigned _sv) + : id(_id), index(_index), dc_tbl(_dcn), subsample_h(_sh), subsample_v(_sv){}; + LibRaw_JpegComponentInfo(const LibRaw_JpegComponentInfo& q): id(q.id), index(q.index), dc_tbl(q.dc_tbl), + subsample_h(q.subsample_h),subsample_v(q.subsample_v){} +}; + +struct LibRaw_SOFInfo +{ + unsigned width, height; + unsigned cps, precision; + std::vector components; + bool csfix; + LibRaw_SOFInfo(): width(0),height(0),cps(0),precision(0),csfix(false){} + bool parse_sof(ByteStreamBE&); // true => OK, false => not OK + uint32_t parse_sos(ByteStreamBE&); // returns (predictor << 8 | point transform); if above 0xffff => error +}; + +struct LibRaw_LjpegDecompressor +{ + ByteStreamBE buffer; + LibRaw_SOFInfo sof; + uint32_t predictor, point_transform; + uint32_t datastart; + std::vector dhts; + LibRaw_LjpegDecompressor(uint8_t *b, unsigned s); + LibRaw_LjpegDecompressor(uint8_t *b, unsigned bs, bool dngbug, bool csfix); + void initialize(bool dngbug, bool csfix); + uint8_t next_marker(bool allowskip); + bool parse_dht(bool init[4], uint32_t dht_bits[4][17], uint32_t dht_huffval[4][256]); // return true on OK; + bool decode_ljpeg_422(std::vector &dest, int width, int height); + + struct State { + enum States + { + OK = 0, + NotInited = 1, + NoSOI = 2, + IncorrectPrecision = 3, + EOIReached = 4, + InvalidDHT = 5, + InvalidSOF = 6, + InvalidSOS = 7, + DQTPresent = 8 + }; + + }; + struct Marker { + enum Markers { + Stuff = 0x00, + SOF3 = 0xc3, // lossless + DHT = 0xc4, // huffman tables + SOI = 0xd8, // start of image + EOI = 0xd9, // end of image + SOS = 0xda, // start of scan + DQT = 0xdb, // quantization tables + Fill = 0xff, + }; + }; + enum State::States state; +}; + diff --git a/internal/var_defines.h b/internal/var_defines.h index 71db9c3bd..d6d5ea299 100644 --- a/internal/var_defines.h +++ b/internal/var_defines.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: var_defines.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw redefinitions of dcraw internal variables @@ -184,6 +184,7 @@ it under the terms of the one of two licenses as you choose: #define tile_length (libraw_internal_data.unpacker_data.tile_length) #define load_flags (libraw_internal_data.unpacker_data.load_flags) #define pana_encoding (libraw_internal_data.unpacker_data.pana_encoding) +#define pana8 (libraw_internal_data.unpacker_data.pana8) #define pana_bpp (libraw_internal_data.unpacker_data.pana_bpp) #define CM_found (libraw_internal_data.unpacker_data.CM_found) diff --git a/internal/x3f_tools.h b/internal/x3f_tools.h index 84bb00c00..df2c6f796 100644 --- a/internal/x3f_tools.h +++ b/internal/x3f_tools.h @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/libraw/libraw.h b/libraw/libraw.h index 50d4276d4..897f63f1a 100644 --- a/libraw/libraw.h +++ b/libraw/libraw.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C++ interface @@ -24,11 +24,6 @@ it under the terms of the one of two licenses as you choose: #define _FILE_OFFSET_BITS 64 #endif -// Enable use old cinema cameras if USE_OLD_VIDEOCAMS defined -#ifdef USE_OLD_VIDEOCAMS -#define LIBRAW_OLD_VIDEO_SUPPORT -#endif - #ifndef LIBRAW_USE_DEPRECATED_IOSTREAMS_DATASTREAM #define LIBRAW_NO_IOSTREAMS_DATASTREAM #endif @@ -378,7 +373,9 @@ protected: int crxDecodePlane(void *, uint32_t planeNumber); virtual void crxLoadFinalizeLoopE3(void *, int); void crxConvertPlaneLineDf(void *, int); - + /* Panasonic Compression 8 parallel decoder stubs*/ + virtual void pana8_decode_loop(void*); + int pana8_decode_strip(void*, int); // return: 0 if OK, non-zero on error int FCF(int row, int col) { int rr, cc; @@ -417,12 +414,7 @@ protected: //void (LibRaw::*thumb_load_raw)(); void (LibRaw::*pentax_component_load_raw)(); - void kodak_thumb_loader(); void write_thumb_ppm_tiff(FILE *); -#ifdef USE_X3FTOOLS - void x3f_thumb_loader(); - INT64 x3f_thumb_size(); -#endif int own_filtering_supported() { return 0; } void identify(); diff --git a/libraw/libraw_alloc.h b/libraw/libraw_alloc.h index c22d99586..2a6461e42 100644 --- a/libraw/libraw_alloc.h +++ b/libraw/libraw_alloc.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_alloc.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 22, 2008 * * LibRaw C++ interface diff --git a/libraw/libraw_const.h b/libraw/libraw_const.h index 61f8028b2..0d84029eb 100644 --- a/libraw/libraw_const.h +++ b/libraw/libraw_const.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_const.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * LibRaw error codes LibRaw is free software; you can redistribute it and/or modify @@ -119,7 +119,8 @@ enum LibRaw_As_Shot_WB_Applied_codes LIBRAW_ASWB_CANON = 2, LIBRAW_ASWB_NIKON = 4, LIBRAW_ASWB_NIKON_SRAW = 8, - LIBRAW_ASWB_PENTAX = 16 + LIBRAW_ASWB_PENTAX = 16, + LIBRAW_ASWB_SONY = 32 }; #define tagtypeIs(typex) (type == typex) @@ -288,6 +289,7 @@ enum LibRaw_colorspace { LIBRAW_COLORSPACE_CameraGamma, LIBRAW_COLORSPACE_MonochromeLinear, LIBRAW_COLORSPACE_MonochromeGamma, + LIBRAW_COLORSPACE_Rec2020, LIBRAW_COLORSPACE_Unknown = 255 }; @@ -540,7 +542,8 @@ enum LibRaw_Sony_0x9050_Type { LIBRAW_SONY_Tag9050None = 0, LIBRAW_SONY_Tag9050a, LIBRAW_SONY_Tag9050b, - LIBRAW_SONY_Tag9050c + LIBRAW_SONY_Tag9050c, + LIBRAW_SONY_Tag9050d }; enum LIBRAW_SONY_FOCUSMODEmodes @@ -639,7 +642,8 @@ enum LibRaw_processing_options LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT = 1 << 20, LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT = 1 << 21, LIBRAW_RAWOPTIONS_DNG_ADD_MASKS = 1 << 22, - LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION = 1 << 23 + LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION = 1 << 23, + LIBRAW_RAWOPTIONS_ALLOW_JPEGXL_PREVIEWS = 1 << 24 }; enum LibRaw_decoder_flags @@ -682,9 +686,6 @@ enum LibRaw_warnings LIBRAW_WARN_NO_BADPIXELMAP = 1 << 8, LIBRAW_WARN_BAD_DARKFRAME_FILE = 1 << 9, LIBRAW_WARN_BAD_DARKFRAME_DIM = 1 << 10, -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - LIBRAW_WARN_NO_JASPER = 1 << 11, -#endif LIBRAW_WARN_RAWSPEED_PROBLEM = 1 << 12, LIBRAW_WARN_RAWSPEED_UNSUPPORTED = 1 << 13, LIBRAW_WARN_RAWSPEED_PROCESSED = 1 << 14, @@ -697,7 +698,8 @@ enum LibRaw_warnings LIBRAW_WARN_RAWSPEED3_PROBLEM = 1 << 21, LIBRAW_WARN_RAWSPEED3_UNSUPPORTED = 1 << 22, LIBRAW_WARN_RAWSPEED3_PROCESSED = 1 << 23, - LIBRAW_WARN_RAWSPEED3_NOTLISTED = 1 << 24 + LIBRAW_WARN_RAWSPEED3_NOTLISTED = 1 << 24, + LIBRAW_WARN_VENDOR_CROP_SUGGESTED = 1 << 25 }; enum LibRaw_exceptions @@ -791,6 +793,8 @@ enum LibRaw_internal_thumbnail_formats LIBRAW_INTERNAL_THUMBNAIL_PPM, LIBRAW_INTERNAL_THUMBNAIL_PPM16, LIBRAW_INTERNAL_THUMBNAIL_X3F, + LIBRAW_INTERNAL_THUMBNAIL_DNG_YCBCR, + LIBRAW_INTERNAL_THUMBNAIL_JPEGXL }; @@ -802,7 +806,8 @@ enum LibRaw_thumbnail_formats LIBRAW_THUMBNAIL_BITMAP16 = 3, LIBRAW_THUMBNAIL_LAYER = 4, LIBRAW_THUMBNAIL_ROLLEI = 5, - LIBRAW_THUMBNAIL_H265 = 6 + LIBRAW_THUMBNAIL_H265 = 6, + LIBRAW_THUMBNAIL_JPEGXL = 7 }; enum LibRaw_image_formats diff --git a/libraw/libraw_datastream.h b/libraw/libraw_datastream.h index 0596e83a5..a978ae602 100644 --- a/libraw/libraw_datastream.h +++ b/libraw/libraw_datastream.h @@ -1,6 +1,6 @@ /* -*- C -*- * File: libraw_datastream.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sun Jan 18 13:07:35 2009 * * LibRaw Data stream interface @@ -95,9 +95,6 @@ public: virtual char *gets(char *, int) = 0; virtual int scanf_one(const char *, void *) = 0; virtual int eof() = 0; -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - virtual void *make_jas_stream() = 0; -#endif virtual int jpeg_src(void *); virtual void buffering_off() {} /* reimplement in subclass to use parallel access in xtrans_load_raw() if @@ -133,16 +130,12 @@ protected: #ifdef LIBRAW_WIN32_UNICODEPATHS std::wstring wfilename; #endif - FILE *jas_file; public: virtual ~LibRaw_file_datastream(); LibRaw_file_datastream(const char *fname); #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_file_datastream(const wchar_t *fname); -#endif -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - virtual void *make_jas_stream(); #endif virtual int valid(); virtual int read(void *ptr, size_t size, size_t nmemb); @@ -215,9 +208,6 @@ public: #endif virtual ~LibRaw_bigfile_buffered_datastream(); virtual int valid(); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - virtual void *make_jas_stream(); -#endif virtual void buffering_off() { buffered = 0; } virtual int read(void *ptr, size_t size, size_t nmemb); virtual int eof(); @@ -266,9 +256,6 @@ public: LibRaw_buffer_datastream(const void *buffer, size_t bsize); virtual ~LibRaw_buffer_datastream(); virtual int valid(); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - virtual void *make_jas_stream(); -#endif virtual int jpeg_src(void *jpegdata); virtual int read(void *ptr, size_t sz, size_t nmemb); virtual int eof(); @@ -297,10 +284,6 @@ public: #endif virtual ~LibRaw_bigfile_datastream(); virtual int valid(); -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - virtual void *make_jas_stream(); -#endif - virtual int read(void *ptr, size_t size, size_t nmemb); virtual int eof(); virtual int seek(INT64 o, int whence); diff --git a/libraw/libraw_internal.h b/libraw/libraw_internal.h index 9ed3a1790..5af31d3ab 100644 --- a/libraw/libraw_internal.h +++ b/libraw/libraw_internal.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_internal.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw internal data structures (not visible outside) @@ -150,6 +150,22 @@ typedef struct INT64 *chunk_offsets; } crx_data_header_t; +typedef struct +{ + uint32_t tag39[6]; + uint16_t tag3A[6]; + uint16_t tag3B; + uint16_t initial[4]; + uint16_t tag40a[17], tag40b[17], tag41[17]; + uint16_t stripe_count; // 0x42 + uint16_t tag43; + INT64 stripe_offsets[5]; //0x44 + uint16_t stripe_left[5]; // 0x45 + uint32_t stripe_compressed_size[5]; //0x46 + uint16_t stripe_width[5]; //0x47 + uint16_t stripe_height[5]; +} pana8_tags_t; + typedef struct { short order; @@ -177,6 +193,7 @@ typedef struct int fuji_total_lines, fuji_total_blocks, fuji_block_width, fuji_bits, fuji_raw_type, fuji_lossless; int pana_encoding, pana_bpp; + pana8_tags_t pana8; crx_data_header_t crx_header[LIBRAW_CRXTRACKS_MAXCOUNT]; int crx_track_selected; int crx_track_count; diff --git a/libraw/libraw_types.h b/libraw/libraw_types.h index ec413b68b..57ba2097d 100644 --- a/libraw/libraw_types.h +++ b/libraw/libraw_types.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_types.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C data structures @@ -370,6 +370,8 @@ typedef unsigned long long UINT64; ushort DRangePriority; ushort DRangePriorityAuto; ushort DRangePriorityFixed; + char FujiModel[32 + 1]; + char FujiModel2[32 + 1]; /* tag 0x9200, converted to BrightnessCompensation @@ -509,6 +511,9 @@ typedef unsigned long long UINT64; ushort SensorWidth; ushort SensorHeight; ushort Active_D_Lighting; + unsigned PictureControlVersion; + char PictureControlName [20]; + char PictureControlBase [20]; unsigned ShotInfoVersion; short MakernotesFlip; double RollAngle; // positive is clockwise, CW @@ -675,6 +680,9 @@ typedef unsigned long long UINT64; ushort HDR[2]; ushort group2010; ushort group9050; + + ushort len_group9050; // currently, for debugging only + ushort real_iso_offset; // init in 0xffff ushort MeteringMode_offset; ushort ExposureProgram_offset; @@ -731,8 +739,10 @@ typedef unsigned long long UINT64; 3330 ARW 2.3.3 3350 ARW 2.3.5 4000 ARW 4.0 + 4010 ARW 4.0.1 */ char MetaVersion [16]; + float AspectRatio; } libraw_sony_info_t; typedef struct @@ -915,6 +925,7 @@ typedef unsigned long long UINT64; float adjust_maximum_thr; int no_auto_bright; /* -W */ int use_fuji_rotate; /* -j */ + int use_p1_correction; int green_matching; /* DCB parameters */ int dcb_iterations; diff --git a/libraw/libraw_version.h b/libraw/libraw_version.h index c6f5c72a3..143a769ad 100644 --- a/libraw/libraw_version.h +++ b/libraw/libraw_version.h @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_version.h - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Mon Sept 8, 2008 * * LibRaw C++ interface @@ -22,8 +22,8 @@ it under the terms of the one of two licenses as you choose: #define LIBRAW_MAJOR_VERSION 0 #define LIBRAW_MINOR_VERSION 21 -#define LIBRAW_PATCH_VERSION 2 -#define LIBRAW_VERSION_TAIL Release +#define LIBRAW_PATCH_VERSION 0 +#define LIBRAW_VERSION_TAIL Beta1 #define LIBRAW_SHLIB_CURRENT 23 #define LIBRAW_SHLIB_REVISION 0 diff --git a/samples/4channels.cpp b/samples/4channels.cpp index 82d40f4e0..57293a2fe 100644 --- a/samples/4channels.cpp +++ b/samples/4channels.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: 4channels.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Mon Feb 09, 2009 * * LibRaw sample @@ -44,7 +44,7 @@ int main(int ac, char *av[]) { usage: printf("4channels - LibRaw %s sample. %d cameras supported\n" - "Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n" + "Usage: %s [-s N] [-g] [-A] [-B] raw-files....\n" "\t-s N - select Nth image in file (default=0)\n" "\t-g - use gamma correction with gamma 2.2 (not precise,use for " "visual inspection only)\n" diff --git a/samples/dcraw_emu.cpp b/samples/dcraw_emu.cpp index 1af82ff04..afa341558 100644 --- a/samples/dcraw_emu.cpp +++ b/samples/dcraw_emu.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: dcraw_emu.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sun Mar 23, 2008 * * LibRaw simple C++ API sample: almost complete dcraw emulator diff --git a/samples/dcraw_half.c b/samples/dcraw_half.c index 5fe56a573..233cbe0c7 100644 --- a/samples/dcraw_half.c +++ b/samples/dcraw_half.c @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: dcraw_half.c - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C API sample: emulates "dcraw -h" diff --git a/samples/half_mt.c b/samples/half_mt.c index f46c83ea8..c8cda4c7d 100644 --- a/samples/half_mt.c +++ b/samples/half_mt.c @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: halt_mt.c - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] diff --git a/samples/half_mt_win32.c b/samples/half_mt_win32.c index b8d3943d3..85713370b 100644 --- a/samples/half_mt_win32.c +++ b/samples/half_mt_win32.c @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: halt_mt_win32.c - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a] diff --git a/samples/mem_image_sample.cpp b/samples/mem_image_sample.cpp index 1ce5b8c60..3ea315b2f 100644 --- a/samples/mem_image_sample.cpp +++ b/samples/mem_image_sample.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: mem_image.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * * LibRaw mem_image/mem_thumb API test. Results should be same (bitwise) to dcraw [-4] [-6] [-e] diff --git a/samples/multirender_test.cpp b/samples/multirender_test.cpp index 06dcec58a..a77db76db 100644 --- a/samples/multirender_test.cpp +++ b/samples/multirender_test.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: multirender_test.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Jul 10, 2011 * * LibRaw simple C++ API: creates 8 different renderings from 1 source file. diff --git a/samples/openbayer_sample.cpp b/samples/openbayer_sample.cpp index c1e46595b..a700535e1 100644 --- a/samples/openbayer_sample.cpp +++ b/samples/openbayer_sample.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: openvayer_sample.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Feb 11, 2020 * * LibRaw simple C++ API: opens bayer data (Kodak KAI-0340 sensor) from buffer, diff --git a/samples/postprocessing_benchmark.cpp b/samples/postprocessing_benchmark.cpp index 703a7a373..778c68a79 100644 --- a/samples/postprocessing_benchmark.cpp +++ b/samples/postprocessing_benchmark.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: postprocessing_benchmark.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Jul 13, 2011 * * LibRaw simple C++ API: creates 8 different renderings from 1 source file. diff --git a/samples/raw-identify.cpp b/samples/raw-identify.cpp index 31c770d34..5c5b29a8c 100644 --- a/samples/raw-identify.cpp +++ b/samples/raw-identify.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: identify.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw C++ demo: emulates dcraw -i [-v] diff --git a/samples/rawtextdump.cpp b/samples/rawtextdump.cpp index 62c4c6ffe..e72f59176 100644 --- a/samples/rawtextdump.cpp +++ b/samples/rawtextdump.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: raw2text.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sun Sept 01, 2020 * * LibRaw sample diff --git a/samples/simple_dcraw.cpp b/samples/simple_dcraw.cpp index f96b23cff..710252ecf 100644 --- a/samples/simple_dcraw.cpp +++ b/samples/simple_dcraw.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: simple_dcraw.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8, 2008 * * LibRaw simple C++ API: emulates call to "dcraw [-D] [-T] [-v] [-e] [-4]" diff --git a/samples/unprocessed_raw.cpp b/samples/unprocessed_raw.cpp index 2f30ce4cb..3060d4d5f 100644 --- a/samples/unprocessed_raw.cpp +++ b/samples/unprocessed_raw.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: unprocessed_raw.cpp - * Copyright 2009-2021 LibRaw LLC (info@libraw.org) + * Copyright 2009-2024 LibRaw LLC (info@libraw.org) * Created: Fri Jan 02, 2009 * * LibRaw sample diff --git a/src/decoders/canon_600.cpp b/src/decoders/canon_600.cpp index 59576f1ff..b6960393c 100644 --- a/src/decoders/canon_600.cpp +++ b/src/decoders/canon_600.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/decoders/crx.cpp b/src/decoders/crx.cpp index 30a702054..495c2f4e4 100644 --- a/src/decoders/crx.cpp +++ b/src/decoders/crx.cpp @@ -2032,7 +2032,7 @@ int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*tota // not sure about this nonsense - why is it not just avg like with 2 levels? quantVal = ((quantVal < 0) * 3 + quantVal) >> 2; if (quantVal / 6 >= 6) - *qStepTbl = q_step_tbl[quantVal % 6] * (1 << (quantVal / 6 + 26)); + *qStepTbl = q_step_tbl[quantVal % 6] * (1 << ((quantVal / 6 - 6 ) & 0x1f)); else *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); } @@ -2052,7 +2052,7 @@ int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*tota { int32_t quantVal = (qpTable[row0Idx++] + qpTable[row1Idx++]) / 2; if (quantVal / 6 >= 6) - *qStepTbl = q_step_tbl[quantVal % 6] * (1 << (quantVal / 6 + 26)); + *qStepTbl = q_step_tbl[quantVal % 6] * (1 << ((quantVal / 6 - 6) & 0x1f)); else *qStepTbl = q_step_tbl[quantVal % 6] >> (6 - quantVal / 6); } @@ -2066,7 +2066,7 @@ int crxMakeQStep(CrxImage *img, CrxTile *tile, int32_t *qpTable, uint32_t /*tota for (int qpRow = 0; qpRow < qpHeight; ++qpRow) for (int qpCol = 0; qpCol < qpWidth; ++qpCol, ++qStepTbl, ++qpTable) if (*qpTable / 6 >= 6) - *qStepTbl = q_step_tbl[*qpTable % 6] * (1 << (*qpTable / 6 + 26)); + *qStepTbl = q_step_tbl[*qpTable % 6] * (1 << ((*qpTable / 6 - 6) & 0x1f)); else *qStepTbl = q_step_tbl[*qpTable % 6] >> (6 - *qpTable / 6); diff --git a/src/decoders/decoders_dcraw.cpp b/src/decoders/decoders_dcraw.cpp index 090a6b726..a6cb6b7aa 100644 --- a/src/decoders/decoders_dcraw.cpp +++ b/src/decoders/decoders_dcraw.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -1051,38 +1051,6 @@ void LibRaw::nokia_load_raw() filters = 0x4b4b4b4b; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - -void LibRaw::canon_rmf_load_raw() -{ - int row, col, bits, orow, ocol, c; - - int *words = (int *)malloc(sizeof(int) * (raw_width / 3 + 1)); - for (row = 0; row < raw_height; row++) - { - checkCancel(); - fread(words, sizeof(int), raw_width / 3, ifp); - for (col = 0; col < raw_width - 2; col += 3) - { - bits = words[col / 3]; - FORC3 - { - orow = row; - if ((ocol = col + c - 4) < 0) - { - ocol += raw_width; - if ((orow -= 2) < 0) - orow += raw_height; - } - RAW(orow, ocol) = curve[bits >> (10 * c + 2) & 0x3ff]; - } - } - } - free(words); - maximum = curve[0x3ff]; -} -#endif - unsigned LibRaw::pana_data(int nb, unsigned *bytes) { #ifndef LIBRAW_NOTHREADS @@ -1728,83 +1696,3 @@ void LibRaw::samsung3_load_raw() } } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void LibRaw::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_t *)ifp->make_jas_stream(); - if (!in) - throw LIBRAW_EXCEPTION_DECODE_JPEG2000; - jas_stream_seek(in, data_offset + 20, SEEK_SET); - jimg = jas_image_decode(in, -1, 0); - if (!jimg) - { - jas_stream_close(in); - throw LIBRAW_EXCEPTION_DECODE_JPEG2000; - } - jmat = jas_matrix_create(height / 2, width / 2); - img = (ushort *)calloc((height + 2), (width + 2) * 2); - bool fastexitflag = false; - try - { - FORC4 - { - checkCancel(); - 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++) - { - checkCancel(); - 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++) - { - checkCancel(); - for (col = 0; col < width; col++) - RAW(row, col) = curve[img[(row + 1) * (width + 2) + col + 1]]; - } - } - catch (...) - { - fastexitflag = true; - } - free(img); - jas_matrix_destroy(jmat); - jas_image_destroy(jimg); - jas_stream_close(in); - if (fastexitflag) - throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; -#endif -} -#endif diff --git a/src/decoders/decoders_libraw_dcrdefs.cpp b/src/decoders/decoders_libraw_dcrdefs.cpp index 89d82595b..9ce9dd467 100644 --- a/src/decoders/decoders_libraw_dcrdefs.cpp +++ b/src/decoders/decoders_libraw_dcrdefs.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -71,7 +71,6 @@ void LibRaw::packed_tiled_dng_load_raw() } - void LibRaw::sony_ljpeg_load_raw() { unsigned trow = 0, tcol = 0, jrow, jcol, row, col; diff --git a/src/decoders/dng.cpp b/src/decoders/dng.cpp index 89537a540..4245e52f9 100644 --- a/src/decoders/dng.cpp +++ b/src/decoders/dng.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -23,6 +23,11 @@ void LibRaw::vc5_dng_load_raw_placeholder() // placeholder only, real decoding implemented in GPR SDK throw LIBRAW_EXCEPTION_DECODE_RAW; } +void LibRaw::jxl_dng_load_raw_placeholder() +{ + // placeholder only, real decoding implemented in DNG SDK + throw LIBRAW_EXCEPTION_DECODE_RAW; +} void LibRaw::adobe_copy_pixel(unsigned row, unsigned col, ushort **rp) { diff --git a/src/decoders/fp_dng.cpp b/src/decoders/fp_dng.cpp index 72631dbbd..f54a79ef3 100644 --- a/src/decoders/fp_dng.cpp +++ b/src/decoders/fp_dng.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/decoders/generic.cpp b/src/decoders/generic.cpp index 6c521d849..b286ed790 100644 --- a/src/decoders/generic.cpp +++ b/src/decoders/generic.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/decoders/kodak_decoders.cpp b/src/decoders/kodak_decoders.cpp index e4b1b3957..0706e4911 100644 --- a/src/decoders/kodak_decoders.cpp +++ b/src/decoders/kodak_decoders.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/decoders/load_mfbacks.cpp b/src/decoders/load_mfbacks.cpp index cddc33ebc..bc60e87cd 100644 --- a/src/decoders/load_mfbacks.cpp +++ b/src/decoders/load_mfbacks.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/decoders/pana8.cpp b/src/decoders/pana8.cpp new file mode 100644 index 000000000..909c9bd8b --- /dev/null +++ b/src/decoders/pana8.cpp @@ -0,0 +1,529 @@ +/* -*- C++ -*- + * File: pana8.cpp + * Copyright (C) 2022-2024 Alex Tutubalin, LibRaw LLC + * + Panasonic RawFormat=8 file decoder + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#include + + // in 8-byte words, 800kb +#define PANA8_BUFSIZE 102400 + +class pana8_bufio_t +{ +public: + pana8_bufio_t(LibRaw_abstract_datastream *stream, INT64 start, uint32_t len) + : data(PANA8_BUFSIZE), input(stream), baseoffset(start), begin(0), end(0), _size(len) + { + } + uint32_t size() { return ((_size+7)/8)*8; } + uint64_t getQWord(uint32_t offset) + { + if (offset >= begin && offset < end) + return data[offset - begin]; + if (!input) return 0; + refill(offset); + if (offset >= begin && offset < end) + return data[offset - begin]; + return 0; + } + void refill(uint32_t newoffset); + + std::vector data; + LibRaw_abstract_datastream *input; + INT64 baseoffset; + INT64 begin, end; + uint32_t _size; +}; + +struct pana8_param_t +{ + uint32_t range_shift, gamma_base; + uint32_t tag3A[6]; + uint32_t tag39[6]; + uint32_t tag3B; + uint32_t initial[4]; + uint32_t huff_coeff[17]; + uint32_t tag3B_2; + uint32_t noGammaFlag; + uint64_t hufftable1[17]; + uint64_t hufftable2[17]; + std::vector gammaTable; + std::vector extrahuff; + pana8_param_t(const pana8_tags_t& init); + int32_t gammaCurve(uint32_t i); + bool DecodeC8( + pana8_bufio_t& bufio, + unsigned int width, unsigned int height, + LibRaw *libraw, uint16_t left_margin); + uint32_t GetDBit(uint64_t a2); +}; + +void invertBits(void *buf, size_t size); + +void pana8_bufio_t::refill(uint32_t newoffset) +{ + if (newoffset >= begin && newoffset < end) + return; + uint32_t readwords, remainwords,toread; +#ifdef LIBRAW_USE_OPENMP +#pragma omp critical + { +#endif + input->lock(); + input->seek(baseoffset + newoffset*sizeof(int64_t), SEEK_SET); + remainwords = (_size - newoffset*sizeof(int64_t) + 7) >> 3; + toread = MIN(PANA8_BUFSIZE, remainwords); + uint32_t readbytes = input->read(data.data(), 1, toread*sizeof(uint64_t)); + readwords = (readbytes + 7) >> 3; + input->unlock(); +#ifdef LIBRAW_USE_OPENMP + } +#endif + + if (INT64(readwords) < INT64(toread) - 1LL) + throw LIBRAW_EXCEPTION_IO_EOF; + + if(readwords>0) + invertBits(data.data(), readwords * sizeof(uint64_t)); + begin = newoffset; + end = newoffset + readwords; +} + +void LibRaw::panasonicC8_load_raw() +{ + int errs = 0; + unsigned totalw = 0; + INT64 fsz = libraw_internal_data.internal_data.input->size(); + if (libraw_internal_data.unpacker_data.pana8.stripe_count > 5) errs++; + for (int i = 0; i < libraw_internal_data.unpacker_data.pana8.stripe_count && i < 5; i++) + { + if (libraw_internal_data.unpacker_data.pana8.stripe_height[i] != imgdata.sizes.raw_height) + errs++; + if (libraw_internal_data.unpacker_data.pana8.stripe_offsets[i] < 0 + || (libraw_internal_data.unpacker_data.pana8.stripe_offsets[i] + INT64((libraw_internal_data.unpacker_data.pana8.stripe_compressed_size[i] + 7u) / 8u)) > fsz) + errs++; + totalw += libraw_internal_data.unpacker_data.pana8.stripe_width[i]; + } + if (totalw != imgdata.sizes.raw_width) errs++; + if (errs) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + pana8_param_t pana8_param(libraw_internal_data.unpacker_data.pana8); + pana8_decode_loop(&pana8_param); +} + +void LibRaw::pana8_decode_loop(void *data) +{ +#ifdef LIBRAW_USE_OPENMP + int errs = 0, scount = MIN(5,libraw_internal_data.unpacker_data.pana8.stripe_count); +#pragma omp parallel for + for (int stream = 0; stream < scount; stream++) + { + if (pana8_decode_strip(data, stream)) + errs++; + } + if(errs) + throw LIBRAW_EXCEPTION_IO_CORRUPT; +#else + for (int stream = 0; stream < libraw_internal_data.unpacker_data.pana8.stripe_count && stream < 5; stream++) + if (pana8_decode_strip(data, stream)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; +#endif +} + +int LibRaw::pana8_decode_strip(void* data, int stream) +{ + pana8_param_t *pana8_param = (pana8_param_t*)data; + if (!data || stream < 0 || stream > 4 || stream > libraw_internal_data.unpacker_data.pana8.stripe_count) return 1; // error + + unsigned exactbytes = (libraw_internal_data.unpacker_data.pana8.stripe_compressed_size[stream] + 7u) / 8u; + pana8_bufio_t bufio(libraw_internal_data.internal_data.input, + libraw_internal_data.unpacker_data.pana8.stripe_offsets[stream], exactbytes); + return !pana8_param->DecodeC8(bufio, libraw_internal_data.unpacker_data.pana8.stripe_width[stream], + libraw_internal_data.unpacker_data.pana8.stripe_height[stream], this, + libraw_internal_data.unpacker_data.pana8.stripe_left[stream]); +} + +struct pana8_base_t +{ + pana8_base_t() { coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0; } + pana8_base_t(const pana8_base_t &s) { clone(s.coeff); } + void clone(const uint32_t *scoeff) + { // TODO: implement SSE load for SSE-enabled code + coeff[0] = scoeff[0]; + coeff[1] = scoeff[1]; + coeff[2] = scoeff[2]; + coeff[3] = scoeff[3]; + } + uint32_t coeff[4]; +}; + +bool pana8_param_t::DecodeC8(pana8_bufio_t &bufio, unsigned int width, unsigned int height, LibRaw *libraw, + uint16_t left_margin) +{ + unsigned halfwidth = width >> 1; + unsigned halfheight = height >> 1; + if (!halfwidth || !halfheight || bufio.size() < 9) + return false; // invalid input + + uint32_t datamax = tag3B_2 >> range_shift; + + pana8_base_t start_coeff; + for(int i = 0; i < 4; i++) + start_coeff.coeff[i] = initial[i] & 0xffffu; + + bool _extrahuff = (extrahuff.size() >= 0x10000); + + uint8_t *big_huff_table = 0; + if (_extrahuff) + big_huff_table = extrahuff.data(); + + uint16_t *gammatable = (gammaTable.size() >= 0x10000) && !noGammaFlag ? (uint16_t *)gammaTable.data() : 0; + +#ifdef PANA8_FULLY_BUFFERED + const uint8_t *inputbyteptr = source.data(); + uint32_t jobsz_in_qwords = source.size() >> 3; +#else + uint32_t jobsz_in_qwords = bufio.size() >> 3; +#endif + int32_t doublewidth = 4 * halfwidth; + std::vector outline(4 * doublewidth); + pana8_base_t line_base(start_coeff); + int64_t bittail = 0LL; + int32_t bitportion = 0; + uint32_t inqword = 0u; + + try + { + for (uint32_t current_row = 0; current_row < halfheight; current_row++) + { + uint8_t *outrowp = outline.data(); + pana8_base_t current_base(line_base); + + for (int32_t col = 0; col < doublewidth; col++) + { + uint64_t pixbits; + if (bitportion < 0) + { + uint32_t inqword_next = inqword + 1; + if ((int)inqword + 1 >= int(jobsz_in_qwords)) + return false; + bitportion += 64; + uint64_t inputqword = bufio.getQWord(inqword); + uint64_t inputqword_next = bufio.getQWord(inqword_next); + pixbits = (inputqword_next >> bitportion) | (inputqword << (64 - (uint8_t)(bitportion & 0xffu))); + if ((unsigned int)inqword < jobsz_in_qwords) + inqword = inqword_next; + } + else + { + if ((unsigned int)inqword >= jobsz_in_qwords) + return false; + uint64_t inputqword = bufio.getQWord(inqword); + pixbits = (inputqword >> bitportion) | bittail; + uint32_t step = (bitportion == 0); + if (!bitportion) + bitportion = 64; + inqword += step; + } + int huff_index = 0; + if (_extrahuff) + huff_index = *(uint8_t *)(big_huff_table + ((pixbits >> 48) & 0xffffu)); + else + { + huff_index = int(GetDBit(pixbits)); + datamax = tag3B_2; + } + int32_t v37 = (huff_coeff[huff_index] >> 24) & 0x1F; + uint32_t hc = huff_coeff[huff_index]; + int64_t v38 = pixbits << (((hc >> 16) & 0xffffu) & 0x1F); + uint64_t v90 = (uint32_t)(huff_index - v37); + int32_t v39 = (uint16_t)((uint64_t)v38 >> ((uint8_t)v37 - (uint8_t)huff_index)) << ((huff_coeff[huff_index] >> 24) & 0xffu); + + if (huff_index - v37 <= 0) + v39 &= 0xffff0000u; + + int32_t delta1; + if (v38 < 0) + delta1 = (uint16_t)v39; + else if (huff_index) + { + int32_t v40 = -1 << huff_index; + if ((uint8_t)v37) + delta1 = (uint16_t)v39 + v40; + else + delta1 = (uint16_t)v39 + v40 + 1; + } + else + delta1 = 0; + + uint32_t v42 = bitportion - ((huff_coeff[huff_index] >> 16) & 0x1F); + int32_t delta2 = uint8_t(v37) ? 1 << (v37 - 1) : 0; + uint32_t *destpixel = (uint32_t *)(outrowp + 16LL * (col >> 2)); + + int32_t delta = delta1 + delta2; + int32_t col_amp_3 = col & 3; +#define _LIM(a, _max_) (a < 0) ? 0 : ((a > _max_) ? _max_ : a) + if (col_amp_3 == 2) + { + int32_t val = current_base.coeff[1] + delta; + destpixel[1] = uint32_t(_LIM(val, int(datamax))); + } + else if (col_amp_3 == 1) + { + int32_t val = current_base.coeff[2] + delta; + destpixel[2] = uint32_t(_LIM(val, int(datamax))); + } + else if ((col & 3) != 0) // == 3 + { + int32_t val = current_base.coeff[3] + delta; + destpixel[3] = uint32_t(_LIM(val, int(datamax))); + } + else // 0 + { + int32_t val = current_base.coeff[0] + delta; + destpixel[0] = uint32_t(_LIM(val, int(datamax))); + } +#undef _LIM + if (huff_index <= v37) + v90 = 0LL; + bittail = v38 << v90; + bitportion = int32_t(v42 - v90); + + if (col_amp_3 == 3) + current_base.clone((uint32_t *)(outrowp + 16LL * (col >> 2))); + if (col == 3) + line_base.clone((uint32_t *)(outrowp)); + } + + int destrow = current_row * 2; + uint16_t *destrow0 = libraw->imgdata.rawdata.raw_image + (destrow * libraw->imgdata.sizes.raw_width) + left_margin; + uint16_t *destrow1 = + libraw->imgdata.rawdata.raw_image + (destrow + 1) * libraw->imgdata.sizes.raw_width + left_margin; + uint16_t *srcrow = (uint16_t *)(outrowp); + if (gammatable) + { + for (unsigned col = 0; col < width - 1; col += 2) + { + const int c6 = col * 4; + destrow0[col] = gammatable[srcrow[c6]]; + destrow0[col + 1] = gammatable[srcrow[c6 + 2]]; + destrow1[col] = gammatable[srcrow[c6 + 4]]; + destrow1[col + 1] = gammatable[srcrow[c6 + 6]]; + } + } + else + { + for (unsigned col = 0; col < width - 1; col += 2) + { + const int c6 = col * 4; + destrow0[col] = srcrow[c6]; + destrow0[col + 1] = srcrow[c6 + 2]; + destrow1[col] = srcrow[c6 + 4]; + destrow1[col + 1] = srcrow[c6 + 6]; + } + } + } + } + catch (...) // buffer read may throw an exception + { + return false; + } + return true; +} + + +uint32_t pana8_param_t::GetDBit(uint64_t a2) +{ + for (int i = 0; i < 16; i++) + { + if ((a2 & hufftable2[i]) == hufftable1[i]) + return i; + } + return uint32_t((hufftable2[16] & a2) == hufftable1[16]) ^ 0x11u; +} + +pana8_param_t::pana8_param_t(const pana8_tags_t &meta) : gammaTable(0) +{ + range_shift = gamma_base = tag3B = 0; +#ifndef ZERO +#define ZERO(a) memset(a, 0, sizeof(a)) +#endif + ZERO(tag3A); + ZERO(tag39); + ZERO(tag3A); + ZERO(initial); + ZERO(huff_coeff); + ZERO(hufftable1); + ZERO(hufftable2); +#undef ZERO + noGammaFlag = 1; + + for (int i = 0; i < 6; i++) + { + tag3A[i] = meta.tag3A[i]; + tag39[i] = meta.tag39[i]; + } + tag3B_2 = tag3B = meta.tag3B; + for(int i = 0; i < 4; i++) + initial[i] = meta.initial[i]; + + for (int i = 0; i < 17; i++) + huff_coeff[i] = (uint32_t(meta.tag41[i]) << 24) | (uint32_t(meta.tag40a[i]) << 16) | meta.tag40b[i]; + + std::vector tempGamma(0x10000); + for (unsigned i = 0; i < 0x10000; i++) + { + uint64_t val = gammaCurve(i); + tempGamma[i] = uint16_t(val & 0xffffu); + if (i != val) + noGammaFlag = 0; + } + if (!noGammaFlag) + gammaTable = tempGamma; + + int v7 = 0; + + for (unsigned hindex = 0; hindex < 17; hindex++) + { + uint32_t hc = huff_coeff[hindex]; + uint32_t hlow = (hc >> 16) & 0x1F; + int16_t v8 = 0; + if ((hc & 0x1F0000) != 0) + { + int h7 = ((hc >> 16) & 0xffffu) & 7; + if (hlow - 1 >= 7) + { + uint32_t hdiff = h7 - hlow; + v8 = 0; + do + { + v8 = (v8 << 8) | 0xFFu; + hdiff += 8; + } while (hdiff); + } + else + v8 = 0; + for (; h7; --h7) + v8 = 2 * v8 + 1; + } + + uint16_t v9 = hc & v8; + if (uint32_t(v7) < hlow) + v7 = ((huff_coeff[hindex] >> 16) & 0xFFFFu) & 0x1F; + hufftable2[hindex] = 0xFFFFULL << (64-hlow); + hufftable1[hindex] = (uint64_t)v9 << (64-hlow); + } + + if (v7 < 17) + { + if (extrahuff.size() < 0x10000) + extrahuff.resize(0x10000); + uint64_t v17 = 0LL; + + for (int j = 0LL; j != 0x10000; ++j) + { + extrahuff[j] = uint8_t(GetDBit(v17) & 0xffu); + v17 += 0x1000000000000ULL; + } + } +} + +int32_t pana8_param_t::gammaCurve(uint32_t idx) +{ + unsigned int v2 = idx | 0xFFFF0000; + if ((idx & 0x10000) == 0) + v2 = idx & 0x1FFFF; + + int v3 = gamma_base + v2; + unsigned int v4 = MIN(v3, 0xFFFF); + + int v5 = 0; + if ((v4 & 0x80000000) != 0) + v4 = 0; + + if (v4 >= (0xFFFF & tag3A[1])) + { + v5 = 1; + if (v4 >= (0xFFFF & tag3A[2])) + { + v5 = 2; + if (v4 >= (0xFFFF & tag3A[3])) + { + v5 = 3; + if (v4 >= (0xFFFF & tag3A[4])) + v5 = ((v4 | 0x500000000LL) - (uint64_t)(0xFFFF & tag3A[5])) >> 32; + } + } + } + unsigned int v6 = tag3A[v5]; + int v7 = tag39[v5]; + unsigned int v8 = v4 - (uint16_t)v6; + char v9 = v7 & 0x1F; + int64_t result = 0; + + if (v9 == 31) + { + result = v5 == 5 ? 0xFFFFLL : ((tag3A[v5 + 1] >> 16) & 0xFFFF); + return MIN( uint32_t(result), tag3B); + } + if ((v7 & 0x10) == 0) + { + if (v9 == 15) + { + result = ((v6 >> 16) & 0xFFFF); + return MIN( uint32_t(result), tag3B); + } + else if(v9!=0) + v8 = (v8 + (1 << (v9 - 1))) >> v9; + } + else + v8 <<= v7 & 0xF; + + result = v8 + ((v6 >> 16) & 0xFFFF); + return MIN( uint32_t(result), tag3B); +} + +const static uint8_t _bitRevTable[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, + 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, + 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, + 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, + 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, + 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, + 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, + 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, + 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, + 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, + 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, + 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, + 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF}; + +void invertBits(void *buf, size_t size) +{ + unsigned sz = unsigned(size / 8); + uint64_t *ptr = (uint64_t *)buf; + for (unsigned i = 0; i < sz; i++) + { + uint8_t *b = (uint8_t *)&ptr[i]; + uint64_t r = ((uint64_t)_bitRevTable[b[0]] << 56) | ((uint64_t)_bitRevTable[b[1]] << 48) | + ((uint64_t)_bitRevTable[b[2]] << 40) | ((uint64_t)_bitRevTable[b[3]] << 32) | + ((uint64_t)_bitRevTable[b[4]] << 24) | ((uint64_t)_bitRevTable[b[5]] << 16) | + ((uint64_t)_bitRevTable[b[6]] << 8) | _bitRevTable[b[7]]; + ptr[i] = r; + } +} diff --git a/src/decoders/smal.cpp b/src/decoders/smal.cpp index 2e549906e..eeab2f006 100644 --- a/src/decoders/smal.cpp +++ b/src/decoders/smal.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/decoders/sonycc.cpp b/src/decoders/sonycc.cpp new file mode 100644 index 000000000..7d3cd4174 --- /dev/null +++ b/src/decoders/sonycc.cpp @@ -0,0 +1,318 @@ +/* -*- C++ -*- + * File: sonycc.cpp + * Copyright (C) 2023-2024 Alex Tutubalin, LibRaw LLC + * + Sony YCC (small/medium lossy compressed) decoder + + Code partially backported from DNGLab's rust code + DNGLab was originally created in 2021 by Daniel Vogelbacher. + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/libraw_cxx_defs.h" +#include "../../internal/losslessjpeg.h" +#include +#include + +#define ifp libraw_internal_data.internal_data.input +#define UD libraw_internal_data.unpacker_data +#define S imgdata.sizes + +struct LibRaw_SonyYCC_Decompressor : public LibRaw_LjpegDecompressor +{ + LibRaw_SonyYCC_Decompressor(uint8_t *b, unsigned s): LibRaw_LjpegDecompressor(b,s){} + bool decode_sony(std::vector &dest, int width, int height); + bool decode_sony_ljpeg_420(std::vector &dest, int width, int height); + +}; + +static +#ifdef _MSC_VER + __forceinline +#else + inline +#endif +void copy_yuv_420(uint16_t *out, uint32_t row, uint32_t col, uint32_t width, + int32_t y1, int32_t y2, int32_t y3, int32_t y4, int32_t cb, int32_t cr) +{ + uint32_t pix1 = row * width + col; + uint32_t pix2 = pix1 + 3; + uint32_t pix3 = (row + 1) * width + col; + uint32_t pix4 = pix3 + 3; + + out[pix1 + 0] = uint16_t(y1); + out[pix1 + 1] = uint16_t(cb); + out[pix1 + 2] = uint16_t(cr); + out[pix2 + 0] = uint16_t(y2); + out[pix2 + 1] = uint16_t(cb); + out[pix2 + 2] = uint16_t(cr); + out[pix3 + 0] = uint16_t(y3); + out[pix3 + 1] = uint16_t(cb); + out[pix3 + 2] = uint16_t(cr); + out[pix4 + 0] = uint16_t(y4); + out[pix4 + 1] = uint16_t(cb); + out[pix4 + 2] = uint16_t(cr); +} + + +bool LibRaw_SonyYCC_Decompressor::decode_sony_ljpeg_420(std::vector &_dest, int width, int height) +{ + if (sof.width * 3 != width || sof.height != height) + return false; + if (width % 2 || width % 6 || height % 2) + return false; + if (_dest.size() < width*height) + return false; + + HuffTable &huff1 = dhts[sof.components[0].dc_tbl]; + HuffTable &huff2 = dhts[sof.components[1].dc_tbl]; + HuffTable &huff3 = dhts[sof.components[2].dc_tbl]; + + if (!huff1.initialized || !huff2.initialized || !huff3.initialized) + return false; + + BitPumpJpeg pump(buffer); + + int32_t base = 1 << (sof.precision - point_transform - 1); + int32_t y1 = base + huff1.decode(pump); + int32_t y2 = y1 + huff1.decode(pump); + int32_t y3 = y1 + huff1.decode(pump); + int32_t y4 = y3 + huff1.decode(pump); + + int32_t cb = base + huff2.decode(pump); + int32_t cr = base + huff3.decode(pump); + + uint16_t *dest = _dest.data(); + copy_yuv_420(dest, 0, 0, width, y1, y2, y3, y4, cb, cr); + + for (uint32_t row = 0; row < height; row += 2) + { + uint32_t startcol = row == 0 ? 6 : 0; + for (uint32_t col = startcol; col < width; col += 6) + { + int32_t py1, py3, pcb, pcr; + if (col == 0) + { + uint32_t pos = (row - 2) * width; + py1 = dest[pos]; + py3 = 0; + pcb = dest[pos + 1]; + pcr = dest[pos + 2]; + } + else + { + uint32_t pos1 = row * width + col - 3; + uint32_t pos3 = (row + 1) * width + col - 3; + py1 = dest[pos1]; + py3 = dest[pos3]; + pcb = dest[pos1 + 1]; + pcr = dest[pos1 + 2]; + }; + y1 = py1 + huff1.decode(pump); + y2 = y1 + huff1.decode(pump); + y3 = ((col == 0) ? y1 : py3) + huff1.decode(pump); + y4 = y3 + huff1.decode(pump); + cb = pcb + huff2.decode(pump); + cr = pcr + huff3.decode(pump); + copy_yuv_420(dest, row, col, width, y1, y2, y3, y4, cb, cr); + } + } + return true; +} + +bool LibRaw_SonyYCC_Decompressor::decode_sony(std::vector &dest, int width, int height) +{ + if (sof.components[0].subsample_h == 2 && sof.components[0].subsample_v == 2) + { + return decode_sony_ljpeg_420(dest, width, height); + } + else if (sof.components[0].subsample_h == 2 && sof.components[0].subsample_v == 1) + return decode_ljpeg_422(dest, width, height); + else + return false; +} + +static +#ifdef _MSC_VER + __forceinline +#else + inline +#endif +void copy_ycc(ushort dst[][4], int rawwidth, int rawheight, int destrow0, int destcol0, ushort *src, + int srcwidth, // full array width is 3x + int srcheight, int steph, int stepv) +{ + if (steph < 2 && stepv < 2) + { + for (int tilerow = 0; tilerow < srcheight && destrow0 + tilerow < rawheight; tilerow++) + { + ushort(*destrow)[4] = &dst[(destrow0 + tilerow) * rawwidth + destcol0]; + for (int tilecol = 0; tilecol < srcwidth && tilecol + destcol0 < rawwidth; tilecol++) + { + int pix = (tilerow * srcwidth + tilecol) * 3; + destrow[tilecol][0] = src[pix]; + destrow[tilecol][1] = src[pix + 1] > 8192 ? src[pix + 1] - 8192 : 0; + destrow[tilecol][2] = src[pix + 2] > 8192 ? src[pix + 2] - 8192 : 0; + } + } + } + else + { + for (int tilerow = 0; tilerow < srcheight && destrow0 + tilerow < rawheight; tilerow++) + { + int destrow = destrow0 + tilerow; + ushort(*dest)[4] = &dst[destrow * rawwidth + destcol0]; + for (int tilecol = 0; tilecol < srcwidth && tilecol + destcol0 < rawwidth; tilecol++) + { + int pix = (tilerow * srcwidth + tilecol) * 3; + int destcol = destcol0 + tilecol; + dest[tilecol][0] = src[pix]; + if((destrow%stepv) == 0 && (destcol%steph)==0) + { + dest[tilecol][1] = src[pix + 1] > 8192 ? src[pix + 1] - 8192 : 0; + dest[tilecol][2] = src[pix + 2] > 8192 ? src[pix + 2] - 8192 : 0; + } + } + } + + } +} + +static +#ifdef _MSC_VER + __forceinline +#else + inline +#endif +uint16_t _lim16bit(float q) +{ + if (q < 0.f) + q = 0.f; + else if (q > 65535.f) + q = 65535.f; + return uint16_t(uint32_t(q)); +} + +static +#ifdef _MSC_VER + __forceinline +#else + inline +#endif +void ycc2rgb(uint16_t dst[][4], int rawwidth, int rawheight, int destrow0, int destcol0, ushort *src, + int srcwidth, // full array width is 3x + int srcheight) +{ + const ushort cdelta = 16383; + for (int tilerow = 0; tilerow < srcheight && destrow0 + tilerow < rawheight; tilerow++) + { + ushort(*destrow)[4] = &dst[(destrow0 + tilerow) * rawwidth + destcol0]; + for (int tilecol = 0; tilecol < srcwidth && tilecol + destcol0 < rawwidth; tilecol++) + { + int pix = (tilerow * srcwidth + tilecol) * 3; + float Y = float(src[pix]); + float Cb = float(src[pix + 1] - cdelta); + float Cr = float(src[pix + 2] - cdelta); + float R = Y + 1.40200f * Cr; + float G = Y - 0.34414f * Cb - 0.71414f * Cr; + float B = Y + 1.77200f * Cb; + destrow[tilecol][0] = _lim16bit(R); + destrow[tilecol][1] = _lim16bit(G); + destrow[tilecol][2] = _lim16bit(B); + } + } +} + +void LibRaw::sony_ycbcr_load_raw() +{ + if (!imgdata.image) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + // Sony YCC RAWs are always tiled + if (UD.tile_width < 1 || UD.tile_width > S.raw_width) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if (UD.tile_length < 1 || UD.tile_length > S.raw_height) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + // calculate tile count + int tile_w = (S.raw_width + UD.tile_width - 1) / UD.tile_width; + int tile_h = (S.raw_height + UD.tile_length - 1) / UD.tile_length; + int tiles = tile_w * tile_h; + if (tiles < 1 || tiles > 1024) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + INT64 fsize = ifp->size(); + std::vector toffsets(tiles); + ifp->seek(UD.data_offset, SEEK_SET); // We're already here, but to make sure + for (int i = 0; i < tiles; i++) + toffsets[i] = get4(); + + std::vector tlengths(tiles); + ifp->seek(UD.data_size, SEEK_SET); + for (int i = 0; i < tiles; i++) + { + tlengths[i] = get4(); + if(toffsets[i]+tlengths[i] > fsize) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + } + unsigned maxcomprlen = *std::max_element(tlengths.begin(), tlengths.end()); + + std::vector iobuffer(maxcomprlen+1); // Extra byte to ensure LJPEG byte stream marker search is ok + std::vector tilebuffer; + for (int tile = 0; tile < tiles; tile++) + { + ifp->seek(toffsets[tile],SEEK_SET); + int readed = ifp->read(iobuffer.data(), 1, tlengths[tile]); + if(readed != tlengths[tile]) + throw LIBRAW_EXCEPTION_IO_EOF; + LibRaw_SonyYCC_Decompressor dec(iobuffer.data(), readed); + if(dec.sof.cps != 3) // !YUV + throw LIBRAW_EXCEPTION_IO_CORRUPT; + if(dec.state != LibRaw_LjpegDecompressor::State::OK) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + unsigned tiledatatsize = UD.tile_width * UD.tile_length * 3; + if (tilebuffer.size() < tiledatatsize) + tilebuffer.resize(tiledatatsize); + + if(!dec.decode_sony(tilebuffer, UD.tile_width * 3, UD.tile_length)) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + + int tilerow = tile / tile_w; + int tilecol = tile % tile_w; + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) + { + if(imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE) + copy_ycc(imgdata.image, S.raw_width, S.raw_height, tilerow * UD.tile_length, tilecol * UD.tile_width, + tilebuffer.data(), UD.tile_width, UD.tile_length, dec.sof.components[0].subsample_h, dec.sof.components[0].subsample_v); + else + copy_ycc(imgdata.image, S.raw_width, S.raw_height, tilerow * UD.tile_length, tilecol * UD.tile_width, + tilebuffer.data(), UD.tile_width, UD.tile_length, 1, 1); + } + else + ycc2rgb(imgdata.image, S.raw_width, S.raw_height, tilerow * UD.tile_length, tilecol * UD.tile_width, + tilebuffer.data(), UD.tile_width, UD.tile_length); + } + + for (int i = 0; i < 6; i++) + imgdata.color.cblack[i] = 0; + + if (imgdata.rawparams.specials & LIBRAW_RAWSPECIAL_SRAW_NO_RGB) + { + imgdata.color.maximum = 18091; // estimated on over-exposed ISO100 frame + imgdata.color.black = 0; + } + else + { + imgdata.color.maximum = 17536; // estimated on over-exposed ISO100 frame + imgdata.color.black = 1024; + } +} diff --git a/src/decoders/unpack.cpp b/src/decoders/unpack.cpp index 38adba453..c4f3359e7 100644 --- a/src/decoders/unpack.cpp +++ b/src/decoders/unpack.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -167,8 +167,10 @@ int LibRaw::unpack(void) throw "Size mismatch"; // DECODED w/ success - if (rs3ret.filters>1) // Fuji or bayer - imgdata.rawdata.raw_image = (ushort*)rs3ret.pixeldata; + if (rs3ret.filters > 1) // Fuji or bayer + { + imgdata.rawdata.raw_image = (ushort*)rs3ret.pixeldata; + } else if (rs3ret.cpp == 4) { imgdata.rawdata.color4_image = (ushort(*)[4])rs3ret.pixeldata; @@ -189,6 +191,16 @@ int LibRaw::unpack(void) S.raw_width = rs3ret.width; S.raw_height = rs3ret.height; imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROCESSED; + + if (imgdata.rawdata.raw_image && + load_raw == &LibRaw::phase_one_load_raw_c && imgdata.color.phase_one_data.format != 8) + { + // Scale data to match libraw own decoder + for (int row = 0; row < rs3ret.height; row++) + for (int col = 0; col < rs3ret.pitch / 2; col++) + imgdata.rawdata.raw_image[row * rs3ret.pitch / 2 + col] <<= 2; + } + // if (r->whitePoint > 0 && r->whitePoint < 65536) // C.maximum = r->whitePoint; } diff --git a/src/decoders/unpack_thumb.cpp b/src/decoders/unpack_thumb.cpp index 4298c3750..1082b9326 100644 --- a/src/decoders/unpack_thumb.cpp +++ b/src/decoders/unpack_thumb.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -92,12 +92,34 @@ int LibRaw::unpack_thumb(void) { return LIBRAW_NO_THUMBNAIL; } + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_DNG_YCBCR) + { + try + { + dng_ycbcr_thumb_loader(); + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + T.tcolors = 3; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + } + catch (...) + { + return LIBRAW_NO_THUMBNAIL; + } + return 0; + + } else if ((Tformat >= LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB) && ((Tformat <= LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB))) { - kodak_thumb_loader(); - T.tformat = LIBRAW_THUMBNAIL_BITMAP; - SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + try { + kodak_thumb_loader(); + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + } + catch (...) + { + return LIBRAW_NO_THUMBNAIL; + } return 0; } else @@ -107,10 +129,11 @@ int LibRaw::unpack_thumb(void) { INT64 tsize = x3f_thumb_size(); if (tsize < 2048 || INT64(ID.toffset) + tsize < 1) - throw LIBRAW_EXCEPTION_IO_CORRUPT; + return LIBRAW_NO_THUMBNAIL; if (INT64(ID.toffset) + tsize > ID.input->size() + THUMB_READ_BEYOND) - throw LIBRAW_EXCEPTION_IO_EOF; + return LIBRAW_NO_THUMBNAIL; + THUMB_SIZE_CHECKT(tsize); } #else @@ -119,22 +142,30 @@ int LibRaw::unpack_thumb(void) else { if (INT64(ID.toffset) + INT64(T.tlength) < 1) - throw LIBRAW_EXCEPTION_IO_CORRUPT; + return LIBRAW_NO_THUMBNAIL; if (INT64(ID.toffset) + INT64(T.tlength) > ID.input->size() + THUMB_READ_BEYOND) - throw LIBRAW_EXCEPTION_IO_EOF; + return LIBRAW_NO_THUMBNAIL; } ID.input->seek(ID.toffset, SEEK_SET); - if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG || Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEGXL) { THUMB_SIZE_CHECKTNZ(T.tlength); if (T.thumb) free(T.thumb); T.thumb = (char *)malloc(T.tlength); + if(!T.thumb) + return LIBRAW_NO_THUMBNAIL; ID.input->read(T.thumb, 1, T.tlength); unsigned char *tthumb = (unsigned char *)T.thumb; + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEGXL) + { + T.tformat = LIBRAW_THUMBNAIL_JPEGXL; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + return 0; + } if (load_raw == &LibRaw::crxLoadRaw && T.tlength > 0xE0) { // Check if it is canon H.265 preview: CISZ at bytes 4-6, CISZ prefix is 000n @@ -195,7 +226,15 @@ int LibRaw::unpack_thumb(void) if (T.thumb) free(T.thumb); T.thumb = (char *)calloc(colors, tlength); + if(!T.thumb) + return LIBRAW_NO_THUMBNAIL; unsigned char *tbuf = (unsigned char *)calloc(colors, tlength); + if (!tbuf) + { + free(T.thumb); + T.thumb = 0; + return LIBRAW_NO_THUMBNAIL; + } // Avoid OOB of tbuf, should use tlength ID.input->read(tbuf, colors, tlength); if (libraw_internal_data.unpacker_data.thumb_misc >> 8 && @@ -236,24 +275,39 @@ int LibRaw::unpack_thumb(void) free(T.thumb); T.tcolors = 3; T.thumb = (char *)calloc(T.tcolors, tlength); + if (!T.thumb) + return LIBRAW_NO_THUMBNAIL; unsigned short *tbuf = (unsigned short *)calloc(2, tlength); - read_shorts(tbuf, tlength); - for (i = 0; i < tlength; i++) + if (!tbuf) { - T.thumb[i * 3] = (tbuf[i] << 3) & 0xff; - T.thumb[i * 3 + 1] = (tbuf[i] >> 5 << 2) & 0xff; - T.thumb[i * 3 + 2] = (tbuf[i] >> 11 << 3) & 0xff; + free(T.thumb); + T.thumb = 0; + return LIBRAW_NO_THUMBNAIL; } - free(tbuf); - T.tlength = T.tcolors * tlength; - T.tformat = LIBRAW_THUMBNAIL_BITMAP; - SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + try { + read_shorts(tbuf, tlength); + for (i = 0; i < tlength; i++) + { + T.thumb[i * 3] = (tbuf[i] << 3) & 0xff; + T.thumb[i * 3 + 1] = (tbuf[i] >> 5 << 2) & 0xff; + T.thumb[i * 3 + 2] = (tbuf[i] >> 11 << 3) & 0xff; + } + free(tbuf); + T.tlength = T.tcolors * tlength; + T.tformat = LIBRAW_THUMBNAIL_BITMAP; + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); + } + catch (...) + { + free(tbuf); + return LIBRAW_NO_THUMBNAIL; + } return 0; } else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) { if (t_bytesps > 1) - throw LIBRAW_EXCEPTION_IO_CORRUPT; // 8-bit thumb, but parsed for more + return LIBRAW_NO_THUMBNAIL; // 8-bit thumb, but parsed for more // bits THUMB_SIZE_CHECKWH(T.twidth, T.theight); int t_length = T.twidth * T.theight * t_colors; @@ -282,6 +336,8 @@ int LibRaw::unpack_thumb(void) if (T.thumb) free(T.thumb); T.thumb = (char *)malloc(T.tlength); + if (!T.thumb) + return LIBRAW_NO_THUMBNAIL; char *dest = T.thumb; INT64 pos = ID.input->tell(); @@ -316,6 +372,8 @@ int LibRaw::unpack_thumb(void) THUMB_SIZE_CHECKTNZ(T.tlength); T.thumb = (char *)malloc(T.tlength); + if (!T.thumb) + return LIBRAW_NO_THUMBNAIL; if (!T.tcolors) T.tcolors = t_colors; @@ -328,7 +386,7 @@ int LibRaw::unpack_thumb(void) else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM16) { if (t_bytesps > 2) - throw LIBRAW_EXCEPTION_IO_CORRUPT; // 16-bit thumb, but parsed for + return LIBRAW_NO_THUMBNAIL; // 16-bit thumb, but parsed for // more bits int o_bps = (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_USE_PPM16_THUMBS) ? 2 : 1; int o_length = T.twidth * T.theight * t_colors * o_bps; @@ -338,8 +396,8 @@ int LibRaw::unpack_thumb(void) THUMB_SIZE_CHECKTNZ(i_length); ushort *t_thumb = (ushort *)calloc(i_length, 1); - if (!t_thumb) - throw LIBRAW_EXCEPTION_ALLOC; + if (!t_thumb) + return LIBRAW_NO_THUMBNAIL;; ID.input->read(t_thumb, 1, i_length); if ((libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234)) @@ -356,8 +414,11 @@ int LibRaw::unpack_thumb(void) else { T.thumb = (char *)malloc(o_length); - if (!T.thumb) - throw LIBRAW_EXCEPTION_ALLOC; + if (!T.thumb) + { + free(t_thumb); + return LIBRAW_NO_THUMBNAIL; + } for (int i = 0; i < o_length; i++) T.thumb[i] = t_thumb[i] >> 8; free(t_thumb); @@ -370,7 +431,7 @@ int LibRaw::unpack_thumb(void) #ifdef USE_X3FTOOLS else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_X3F) { - x3f_thumb_loader(); + x3f_thumb_loader(); // errors already catched in this call SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); return 0; } diff --git a/src/decompressors/losslessjpeg.cpp b/src/decompressors/losslessjpeg.cpp new file mode 100644 index 000000000..538c2cb23 --- /dev/null +++ b/src/decompressors/losslessjpeg.cpp @@ -0,0 +1,391 @@ +/* -*- C++ -*- + * File: huffmandec.cpp + * Copyright (C) 2023-2024 Alex Tutubalin, LibRaw LLC + * + Lossless JPEG decoder + + Code partially backported from DNGLab's rust code + DNGLab was originally created in 2021 by Daniel Vogelbacher. + +LibRaw is free software; you can redistribute it and/or modify +it under the terms of the one of two licenses as you choose: + +1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 + (See file LICENSE.LGPL provided in LibRaw distribution archive for details). + +2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 + (See file LICENSE.CDDL provided in LibRaw distribution archive for details). + + */ + +#include "../../internal/losslessjpeg.h" +#include + +#define ZERO(a) do { memset(a,0,sizeof(a));} while(0) + +bool ByteStreamBE::skip_to_marker() // true: success, false - no marker +{ + if (pos + 2 > size) return false; + while (!(buffer[pos] == 0xff && buffer[pos + 1] != 0 && buffer[pos + 1] != 0xff)) + { + pos++; + if (pos + 2 > size) + return false; + } + pos++; + return true; +} + +LibRaw_LjpegDecompressor::LibRaw_LjpegDecompressor(uint8_t *b, unsigned bs, bool dngbug, bool csfix): buffer(b,bs), + state(State::NotInited) +{ + initialize(dngbug,csfix); +} + +LibRaw_LjpegDecompressor::LibRaw_LjpegDecompressor(uint8_t *b, unsigned bs): buffer(b,bs), + state(State::NotInited) +{ + initialize(false,false); +} + + +void LibRaw_LjpegDecompressor::initialize(bool dngbug, bool csfix) +{ + sof.csfix = csfix; + bool dht_init[4] = { false,false,false,false }; + uint32_t dht_bits[4][17]; + uint32_t dht_huffval[4][256]; + ZERO(dht_bits); + ZERO(dht_huffval); + if (next_marker(false) != Marker::SOI) + { + state = State::NoSOI; + return; + } + while (1) + { + uint8_t marker = next_marker(true); + if (marker == Marker::SOF3) + { + if (!sof.parse_sof(buffer)) + { + state = State::InvalidSOF; + return; + } + if (sof.precision > 16 || sof.precision < 12) + { + state = State::IncorrectPrecision; + return; + } + } + else if (marker == Marker::DHT) + { + bool hres = parse_dht(dht_init, dht_bits, dht_huffval); + if(!hres) + { + state = State::InvalidDHT; + return; + } + } + else if ( marker == Marker::SOS) + { + uint32_t val = sof.parse_sos(buffer); + if (val < 0x10000) + { + predictor = (val >> 8) & 0xff; + point_transform = val & 0xff; + } + else + { + state = State::InvalidSOS; + return; + } + break; + } + else if (marker == Marker::EOI) + { + state = State::EOIReached; + return; + } + else if (marker == Marker::DQT) + { + state = State::DQTPresent; + return; + } + else if(marker == Marker::Fill) + { + state = State::EOIReached; + return; + } + } + + dhts.resize(4); + for (int i = 0; i < 4; i++) + if (dht_init[i]) + dhts[i].initval(dht_bits[i], dht_huffval[i], dngbug); + datastart = buffer.pos; + state = State::OK; +} + +uint8_t LibRaw_LjpegDecompressor::next_marker(bool allowskip) +{ + if (!allowskip) + { + if (buffer.get_u8() != 0xff) + return Marker::Fill; // Error; + uint8_t mark = buffer.get_u8(); + return mark; + } + if (buffer.skip_to_marker()) + return buffer.get_u8(); + else + return Marker::Fill; +} + +bool LibRaw_LjpegDecompressor::parse_dht(bool init[4], uint32_t bits[4][17], uint32_t huffval[4][256]) +{ + uint16_t length = buffer.get_u16() - 2u; + + while (length > 0) + { + uint8_t b = buffer.get_u8(); + uint8_t tc = b >> 4; + uint8_t th = b & 0xf; + + if (tc != 0) + return false; + + if (th > 3) + return false; + + uint32_t acc = 0; + for (int i = 0; i < 16; i++) + { + bits[th][i + 1] = buffer.get_u8(); + acc += bits[th][i + 1]; + } + bits[th][0] = 0; + + if (acc > 256) + return false; + + if (length < 1 + 16 + acc) + return 0xff; + for (int i = 0; i < acc; i++) + huffval[th][i] = buffer.get_u8(); + + init[th] = true; + length -= 1 + 16 + acc; + } + return true; +} + +static +#ifdef _MSC_VER +__forceinline +#else +inline +#endif +void copy_yuv_422(uint16_t *out, uint32_t row, uint32_t col, uint32_t width, int32_t y1, int32_t y2, + int32_t cb, int32_t cr) +{ + uint32_t pix1 = row * width + col; + uint32_t pix2 = pix1 + 3; + out[pix1 + 0] = uint16_t(y1); + out[pix1 + 1] = uint16_t(cb); + out[pix1 + 2] = uint16_t(cr); + out[pix2 + 0] = uint16_t(y2); + out[pix2 + 1] = uint16_t(cb); + out[pix2 + 2] = uint16_t(cr); +} + + +bool LibRaw_LjpegDecompressor::decode_ljpeg_422(std::vector &_dest, int width, int height) +{ + if (sof.width * 3 != width || sof.height != height) + return false; + if (width % 2 || width % 6 || height % 2) + return false; + + if (_dest.size() < width * height) + return false; + + uint16_t *dest = _dest.data(); + + HuffTable &h1 = dhts[sof.components[0].dc_tbl]; + HuffTable &h2 = dhts[sof.components[1].dc_tbl]; + HuffTable &h3 = dhts[sof.components[2].dc_tbl]; + + if (!h1.initialized || !h2.initialized || !h3.initialized) + return false; + + BitPumpJpeg pump(buffer); + + int32_t base = 1 << (sof.precision - point_transform - 1); + int32_t y1 = base + h1.decode(pump); + int32_t y2 = y1 + h1.decode(pump); + int32_t cb = base + h2.decode(pump); + int32_t cr = base + h3.decode(pump); + copy_yuv_422(dest, 0, 0, width, y1, y2, cb, cr); + + for (uint32_t row = 0; row < height; row++) + { + uint32_t startcol = row == 0 ? 6 : 0; + for (uint32_t col = startcol; col < width; col += 6) + { + uint32_t pos = (col == 0) ? (row - 1) * width : row * width + col - 3; + int32_t py = dest[pos], + pcb = dest[pos + 1], + pcr = dest[pos + 2]; + int32_t y1 = py + h1.decode(pump); + int32_t y2 = y1 + h1.decode(pump); + int32_t cb = pcb + h2.decode(pump); + int32_t cr = pcr + h3.decode(pump); + copy_yuv_422(dest, row, col, width, y1, y2, cb, cr); + } + } + return true; +} + +bool LibRaw_SOFInfo::parse_sof(ByteStreamBE& input) +{ + uint32_t header_length = input.get_u16(); + precision = input.get_u8(); + height = input.get_u16(); + width = input.get_u16(); + cps = input.get_u8(); + + if (precision > 16) + return false; + if (cps > 4 || cps < 1) + return false; + if (header_length != 8 + cps * 3) + return false; + + components.clear(); + for (int i = 0; i < cps; i++) + { + unsigned id = input.get_u8(); + unsigned subs = input.get_u8(); + components.push_back(LibRaw_JpegComponentInfo(id, i, 0, (subs >> 4), (subs & 0xf) )); + input.get_u8(); + } + return true; +} + +uint32_t LibRaw_SOFInfo::parse_sos(ByteStreamBE& input) +{ + if (width == 0) + return 0x10000; + + input.get_u16(); + + uint32_t soscps = input.get_u8(); + if (cps != soscps) + return 0x10000; + for (uint32_t csi = 0; csi < cps; csi++) + { + uint32_t readcs = input.get_u8(); + uint32_t cs = csfix ? csi : readcs; // csfix might be used in MOS decoder + int cid = -1; + for(int c = 0; c < components.size(); c++) + if (components[c].id == cs) + { + cid = c; + break; + } + if (cid < 0) + return 0x10000; + + uint8_t td = input.get_u8() >> 4; + if (td > 3) + return 0x10000; + components[cid].dc_tbl = td; + } + uint8_t pred = input.get_u8(); + input.get_u8(); + uint8_t pt = input.get_u8() & 0xf; + return (pred << 8 | pt); +} + +HuffTable::HuffTable() +{ + ZERO(bits); + ZERO(huffval); + ZERO(shiftval); + dng_bug = false; + disable_cache = false; + nbits = 0; + initialized = false; +} + +struct PseudoPump : public BitPump +{ + uint64_t bits; + int32_t nbits; + PseudoPump() : bits(0), nbits(0) {} + + void set(uint32_t _bits, uint32_t nb) + { + bits = uint64_t(_bits) << 32; + nbits = nb + 32; + } + int32_t valid() { return nbits - 32; } + + uint32_t peek(uint32_t num) + { + return uint32_t((bits >> (nbits - num)) & 0xffffffffUL); + } + + void consume(uint32_t num) + { + nbits -= num; + bits &= (uint64_t(1) << nbits) - 1UL; + } +}; + +void HuffTable::initval(uint32_t _bits[17], uint32_t _huffval[256], bool _dng_bug) +{ + memmove(bits, _bits, sizeof(bits)); + memmove(huffval, _huffval, sizeof(huffval)); + dng_bug = _dng_bug; + + nbits = 16; + for(int i = 0; i < 16; i++) + { + if(bits[16 - i] != 0) + break; + nbits--; + } + hufftable.resize(1 << nbits); + for (int i = 0; i < hufftable.size(); i++) hufftable[i] = 0; + + int h = 0; + int pos = 0; + for (uint8_t len = 0; len < nbits; len++) + { + for (int i = 0; i < bits[len + 1]; i++) + { + for (int j = 0; j < (1 << (nbits - len - 1)); j++) + { + hufftable[h] = ((len+1) << 16) | (uint8_t(huffval[pos] & 0xff) << 8) | uint8_t(shiftval[pos] & 0xff); + h++; + } + pos++; + } + } + if (!disable_cache) + { + PseudoPump pump; + decodecache = std::vector(1 << LIBRAW_DECODE_CACHE_BITS,0); + for(uint32_t i = 0; i < 1 << LIBRAW_DECODE_CACHE_BITS; i++) + { + pump.set(i, LIBRAW_DECODE_CACHE_BITS); + uint32_t len; + int16_t val16 = int16_t(decode_slow2(pump,len)); + if (pump.valid() >= 0) + decodecache[i] = LIBRAW_CACHE_PRESENT_FLAG | uint64_t(((len & 0xff) << 16) | uint16_t(val16)); + } + } + initialized = true; +} diff --git a/src/demosaic/ahd_demosaic.cpp b/src/demosaic/ahd_demosaic.cpp index e743c96af..8d32d6cd1 100644 --- a/src/demosaic/ahd_demosaic.cpp +++ b/src/demosaic/ahd_demosaic.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/demosaic/misc_demosaic.cpp b/src/demosaic/misc_demosaic.cpp index d23e494d0..76b837860 100644 --- a/src/demosaic/misc_demosaic.cpp +++ b/src/demosaic/misc_demosaic.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/demosaic/xtrans_demosaic.cpp b/src/demosaic/xtrans_demosaic.cpp index 2d96c62ef..8bd1842c4 100644 --- a/src/demosaic/xtrans_demosaic.cpp +++ b/src/demosaic/xtrans_demosaic.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/integration/dngsdk_glue.cpp b/src/integration/dngsdk_glue.cpp index 494383676..0d0a9e8e3 100644 --- a/src/integration/dngsdk_glue.cpp +++ b/src/integration/dngsdk_glue.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -12,8 +12,18 @@ */ +#define LIBRAW_DNGSDK_CONFLICT 1 + #include "../../internal/libraw_cxx_defs.h" +#ifdef USE_DNGSDK +#include "dng_host.h" +#include "dng_negative.h" +#include "dng_simple_image.h" +#include "dng_info.h" +#endif + + #if defined (USE_GPRSDK) && !defined(USE_DNGSDK) #error GPR (GoPro) SDK should be used with Adobe DNG SDK #endif @@ -83,6 +93,19 @@ int LibRaw::valid_for_dngsdk() if (!imgdata.idata.dng_version) return 0; +#ifdef qDNGSupportJXL + if (libraw_internal_data.unpacker_data.tiff_compress == 52546) // regardless of flags or use_dngsdk value! + { +#ifdef qDNGSupportJXL + if (dngVersion_Current >= dngVersion_1_7_0_0) + return 1; + else +#endif + return 0; // Old DNG SDK + } +#endif + + // All DNG larger than 2GB - to DNG SDK if (libraw_internal_data.internal_data.input->size() > 2147483647ULL) return 1; @@ -95,7 +118,7 @@ int LibRaw::valid_for_dngsdk() if (libraw_internal_data.unpacker_data.tiff_compress == 34892 && libraw_internal_data.unpacker_data.tiff_bps == 8 - && libraw_internal_data.unpacker_data.tiff_samples == 3 + && (libraw_internal_data.unpacker_data.tiff_samples == 3 || libraw_internal_data.unpacker_data.tiff_samples == 1) && load_raw == &LibRaw::lossy_dng_load_raw ) { @@ -116,11 +139,13 @@ int LibRaw::valid_for_dngsdk() dng_ifd *rawIFD = search_for_ifd(info, libraw_internal_data.unpacker_data.data_offset, imgdata.sizes.raw_width, imgdata.sizes.raw_height, ifdindex,stream); if (rawIFD && ifdindex >= 0 && ifdindex == info.fMainIndex) return 1; + if (rawIFD && ifdindex >= 0 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS)) + return 1; return 0; } #ifdef USE_GPRSDK - if (load_raw == &LibRaw::vc5_dng_load_raw_placeholder) // regardless of flags or use_dngsdk value! + if (libraw_internal_data.unpacker_data.tiff_compress == 9) // regardless of flags or use_dngsdk value! return 1; #endif if (!imgdata.rawparams.use_dngsdk) @@ -184,39 +209,64 @@ int LibRaw::try_dngsdk() return LIBRAW_DATA_ERROR; AutoPtr stage2; - bool stage23used = false; + unsigned stageBits = 0; // 1=> release Stage2, 2=> change Black/Max bool zerocopy = false; - //(new dng_simple_image(rawIFD->Bounds(), rawIFD->fSamplesPerPixel, rawIFD->PixelType(), host->Allocator())); - - if (((libraw_internal_data.unpacker_data.tiff_compress == 34892 + if ( +#ifdef USE_GPRSDK + libraw_internal_data.unpacker_data.tiff_compress != 9 && +#endif + ( + ((libraw_internal_data.unpacker_data.tiff_compress == 34892 && libraw_internal_data.unpacker_data.tiff_bps == 8 && libraw_internal_data.unpacker_data.tiff_samples == 3 - && load_raw == &LibRaw::lossy_dng_load_raw) + && load_raw == &LibRaw::lossy_dng_load_raw) // JPEG DNG or JPEG DNG RAW Preview || (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2| LIBRAW_RAWOPTIONS_DNG_STAGE3)) || ((tiff_ifd[ifdindex].dng_levels.parsedfields & (LIBRAW_DNGFM_OPCODE2| LIBRAW_DNGFM_OPCODE3)) && (imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT | LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT))) ) && ifdindex >= 0) + ) { if (info.fMainIndex != ifdindex) info.fMainIndex = ifdindex; - negative->ReadStage1Image(*host, stream, info); - negative->BuildStage2Image(*host); - imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE2_APPLIED; - if ( (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3) || - ((tiff_ifd[ifdindex].dng_levels.parsedfields & LIBRAW_DNGFM_OPCODE3) && - (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT)) - ) + if (rawIFD->fNewSubFileType == 1) // Preview { - negative->BuildStage3Image(*host); - stage2.Reset((dng_simple_image*)negative->Stage3Image()); - imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE3_APPLIED; + dng_read_image reader; + AutoPtr copy2; + negative->ReadStage1Image(*host, stream, info); // Read image AND opcodes lists + copy2.Reset((dng_simple_image*) negative->Stage1Image()); + host->ApplyOpcodeList(negative->OpcodeList1(), *negative,copy2); + stageBits = 1; + if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE2) + || ((tiff_ifd[ifdindex].dng_levels.parsedfields & LIBRAW_DNGFM_OPCODE2) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE2_IFPRESENT)) + ) + { + host->ApplyOpcodeList(negative->OpcodeList2(), *negative, copy2); + stageBits |= 2; + } + stage2.Reset((dng_simple_image *)copy2.Get()); + copy2.Release(); } else - stage2.Reset((dng_simple_image*)negative->Stage2Image()); - stage23used = true; + { + negative->ReadStage1Image(*host, stream, info); + negative->BuildStage2Image(*host); + imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE2_APPLIED; + if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3) || + ((tiff_ifd[ifdindex].dng_levels.parsedfields & LIBRAW_DNGFM_OPCODE3) && + (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_STAGE3_IFPRESENT)) + ) + { + negative->BuildStage3Image(*host); + stage2.Reset((dng_simple_image*)negative->Stage3Image()); + imgdata.process_warnings |= LIBRAW_WARN_DNG_STAGE3_APPLIED; + } + else + stage2.Reset((dng_simple_image*)negative->Stage2Image()); + stageBits = 3; + } } else { @@ -256,7 +306,7 @@ int LibRaw::try_dngsdk() return LIBRAW_DATA_ERROR; } } - if (stage23used) + if (stageBits & 2) { if (stage2->Planes() > 1) { @@ -277,7 +327,7 @@ int LibRaw::try_dngsdk() int pixels = stage2->Bounds().H() * stage2->Bounds().W() * pplanes; - if (ptype == ttShort && !stage23used && !is_curve_linear()) + if (ptype == ttShort && !(stageBits & 1) && !is_curve_linear()) { imgdata.rawdata.raw_alloc = malloc(pixels * TagTypeSize(ptype)); ushort *src = (ushort *)buffer.fData; @@ -307,7 +357,7 @@ int LibRaw::try_dngsdk() else { // Alloc - if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY) && !stage23used) + if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNGSDK_ZEROCOPY) && !(stageBits & 1)) { zerocopy = true; } @@ -320,7 +370,7 @@ int LibRaw::try_dngsdk() S.raw_pitch = S.raw_width * pplanes * TagTypeSize(ptype); } - if (stage23used) + if (stageBits & 1) stage2.Release(); if ((ptype == ttFloat) && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)) diff --git a/src/integration/rawspeed_glue.cpp b/src/integration/rawspeed_glue.cpp index 42561e7b8..90d461190 100644 --- a/src/integration/rawspeed_glue.cpp +++ b/src/integration/rawspeed_glue.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -12,17 +12,47 @@ */ +#define LIBRAW_EXPAT_CONFLICT #include "../../internal/libraw_cxx_defs.h" -#ifdef USE_RAWSPEED -using namespace RawSpeed; -CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() +#ifdef USE_RAWSPEED +#include +#include +#include +#include +#include +#include + +#include "../../RawSpeed/rawspeed_xmldata.cpp" +const int RAWSPEED_DATA_COUNT = (sizeof(_rawspeed_data_xml) / sizeof(_rawspeed_data_xml[0])); + + +class CameraMetaDataLR : public RawSpeed::CameraMetaData +{ +public: + CameraMetaDataLR() : CameraMetaData() {} + CameraMetaDataLR(char *filename) : RawSpeed::CameraMetaData(filename) {} + CameraMetaDataLR(char *data, int sz); +}; + + +#define P1 imgdata.idata +#define S imgdata.sizes +#define O imgdata.params +#define C imgdata.color +#define T imgdata.thumbnail +#define MN imgdata.makernotes +#define IO libraw_internal_data.internal_output_params +#define ID libraw_internal_data.internal_data + + +CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : RawSpeed::CameraMetaData() { ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { - ThrowCME("CameraMetaData:Could not initialize context."); + RawSpeed::ThrowCME("CameraMetaData:Could not initialize context."); } xmlResetLastError(); @@ -30,7 +60,7 @@ CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() if (doc == NULL) { - ThrowCME("CameraMetaData: XML Document could not be parsed successfully. " + RawSpeed::ThrowCME("CameraMetaData: XML Document could not be parsed successfully. " "Error was: %s", ctxt->lastError.message); } @@ -43,7 +73,7 @@ CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() } else { - ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", + RawSpeed::ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s", ctxt->lastError.message); } } @@ -52,7 +82,7 @@ CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() cur = xmlDocGetRootElement(doc); if (xmlStrcmp(cur->name, (const xmlChar *)"Cameras")) { - ThrowCME("CameraMetaData: XML document of the wrong type, root node is not " + RawSpeed::ThrowCME("CameraMetaData: XML document of the wrong type, root node is not " "cameras."); return; } @@ -62,13 +92,13 @@ CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera"))) { - Camera *camera = new Camera(doc, cur); + RawSpeed::Camera *camera = new RawSpeed::Camera(doc, cur); addCamera(camera); // Create cameras for aliases. for (unsigned int i = 0; i < camera->aliases.size(); i++) { - addCamera(new Camera(camera, i)); + addCamera(new RawSpeed::Camera(camera, i)); } } cur = cur->next; @@ -81,7 +111,7 @@ CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData() ctxt = 0; } -CameraMetaDataLR *make_camera_metadata() +void *make_camera_metadata() { int len = 0, i; for (i = 0; i < RAWSPEED_DATA_COUNT; i++) @@ -117,7 +147,22 @@ CameraMetaDataLR *make_camera_metadata() return ret; } -#endif +void clear_rawspeed_decoder(void* _rawspeed_decoder) +{ + RawSpeed::RawDecoder *d = + static_cast(_rawspeed_decoder); + if(d) + delete d; +} + +void clear_camera_metadata(void* _rawspeed_camerameta) +{ + CameraMetaDataLR *cmeta = + static_cast(_rawspeed_camerameta); + if(cmeta) + delete cmeta; +} + int LibRaw::set_rawspeed_camerafile(char * filename) { @@ -181,9 +226,9 @@ int LibRaw::try_rawspeed() if (!_rawspeed_buffer) throw LIBRAW_EXCEPTION_ALLOC; ID.input->read(_rawspeed_buffer, _rawspeed_buffer_sz, 1); - FileMap map((uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz); - RawParser t(&map); - RawDecoder *d = 0; + RawSpeed::FileMap map((RawSpeed::uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz); + RawSpeed::RawParser t(&map); + RawSpeed::RawDecoder *d = 0; CameraMetaDataLR *meta = static_cast(_rawspeed_camerameta); d = t.getDecoder(); @@ -203,7 +248,7 @@ int LibRaw::try_rawspeed() { d->checkSupport(meta); } - catch (const RawDecoderException &e) + catch (const RawSpeed::RawDecoderException &e) { imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; throw e; @@ -211,7 +256,7 @@ int LibRaw::try_rawspeed() _rawspeed_decoder = static_cast(d); d->decodeRaw(); d->decodeMetaData(meta); - RawImage r = d->mRaw; + RawSpeed::RawImage r = d->mRaw; if (r->errors.size() > 0 && !rawspeed_ignore_errors) { delete d; @@ -243,7 +288,7 @@ int LibRaw::try_rawspeed() if (_rawspeed_decoder) { // set sizes - iPoint2D rsdim = r->getUncroppedDim(); + RawSpeed::iPoint2D rsdim = r->getUncroppedDim(); S.raw_pitch = r->pitch; S.raw_width = rsdim.x; S.raw_height = rsdim.y; @@ -254,7 +299,7 @@ int LibRaw::try_rawspeed() _rawspeed_buffer = 0; imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED; } - catch (const RawDecoderException &RDE) + catch (const RawSpeed::RawDecoderException &RDE) { imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM; if (_rawspeed_buffer) @@ -284,3 +329,4 @@ int LibRaw::try_rawspeed() return LIBRAW_NOT_IMPLEMENTED; #endif } +#endif diff --git a/src/libraw_c_api.cpp b/src/libraw_c_api.cpp index 4e85ec293..2609fef70 100644 --- a/src/libraw_c_api.cpp +++ b/src/libraw_c_api.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_c_api.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * Created: Sat Mar 8 , 2008 * * LibRaw C interface diff --git a/src/libraw_datastream.cpp b/src/libraw_datastream.cpp index 60593b42f..33182253d 100644 --- a/src/libraw_datastream.cpp +++ b/src/libraw_datastream.cpp @@ -1,6 +1,6 @@ /* -*- C++ -*- * File: libraw_datastream.cpp - * Copyright 2008-2021 LibRaw LLC (info@libraw.org) + * Copyright 2008-2024 LibRaw LLC (info@libraw.org) * * LibRaw C++ interface (implementation) @@ -27,11 +27,6 @@ #include "libraw/libraw_types.h" #include "libraw/libraw_datastream.h" #include -#ifdef USE_JASPER -#include /* Decode RED camera movies */ -#else -#define NO_JASPER -#endif #ifdef USE_JPEG #include #include @@ -156,20 +151,12 @@ int LibRaw_abstract_datastream::jpeg_src(void *jpegdata) #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM // == LibRaw_file_datastream == -LibRaw_file_datastream::~LibRaw_file_datastream() -{ - if (jas_file) - fclose(jas_file); -} - LibRaw_file_datastream::LibRaw_file_datastream(const char *fname) : filename(fname), _fsize(0) #ifdef LIBRAW_WIN32_UNICODEPATHS , wfilename() #endif - , - jas_file(NULL) { if (filename.size() > 0) { @@ -200,7 +187,7 @@ LibRaw_file_datastream::LibRaw_file_datastream(const char *fname) } #ifdef LIBRAW_WIN32_UNICODEPATHS LibRaw_file_datastream::LibRaw_file_datastream(const wchar_t *fname) - : filename(), wfilename(fname), jas_file(NULL), _fsize(0) + : filename(), wfilename(fname), _fsize(0) { if (wfilename.size() > 0) { @@ -330,26 +317,6 @@ const char *LibRaw_file_datastream::fname() #undef LR_STREAM_CHK -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void *LibRaw_file_datastream::make_jas_stream() -{ -#ifdef NO_JASPER - return NULL; -#else -#ifdef LIBRAW_WIN32_UNICODEPATHS - if (wfname()) - { - jas_file = _wfopen(wfname(), L"rb"); - return jas_stream_fdopen(fileno(jas_file), "rb"); - } - else -#endif - { - return jas_stream_fopen(fname(), "rb"); - } -#endif -} -#endif #endif // == LibRaw_buffer_datastream @@ -478,16 +445,6 @@ int LibRaw_buffer_datastream::eof() } int LibRaw_buffer_datastream::valid() { return buf ? 1 : 0; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void *LibRaw_buffer_datastream::make_jas_stream() -{ -#ifdef NO_JASPER - return NULL; -#else - return jas_stream_memopen((char *)buf + streampos, streamsize - streampos); -#endif -} -#endif int LibRaw_buffer_datastream::jpeg_src(void *jpegdata) { @@ -642,17 +599,6 @@ const char *LibRaw_bigfile_datastream::fname() return filename.size() > 0 ? filename.c_str() : NULL; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void *LibRaw_bigfile_datastream::make_jas_stream() -{ -#ifdef NO_JASPER - return NULL; -#else - return jas_stream_fdopen(fileno(f), "rb"); -#endif -} -#endif - // == LibRaw_windows_datastream #ifdef LIBRAW_WIN32_CALLS @@ -820,16 +766,6 @@ const char *LibRaw_bigfile_buffered_datastream::fname() return filename.size() > 0 ? filename.c_str() : NULL; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void *LibRaw_bigfile_buffered_datastream::make_jas_stream() -{ -#ifdef NO_JASPER - return NULL; -#else - return NULL; -#endif -} -#endif INT64 LibRaw_bigfile_buffered_datastream::readAt(void *ptr, size_t size, INT64 off) { diff --git a/src/metadata/adobepano.cpp b/src/metadata/adobepano.cpp index 689c24a4e..ee1d2c8a1 100644 --- a/src/metadata/adobepano.cpp +++ b/src/metadata/adobepano.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/src/metadata/canon.cpp b/src/metadata/canon.cpp index 012ecb09a..eab35e0e8 100644 --- a/src/metadata/canon.cpp +++ b/src/metadata/canon.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -108,11 +108,15 @@ void LibRaw::setCanonBodyFeatures(unsigned long long id) ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Canon_EF_M; } - else if ((id == CanonID_EOS_R) || - (id == CanonID_EOS_RP) || - (id == CanonID_EOS_R3) || - (id == CanonID_EOS_R5) || - (id == CanonID_EOS_R6)) + else if ( + (id == CanonID_EOS_R) + || (id == CanonID_EOS_RP) + || (id == CanonID_EOS_R3) + || (id == CanonID_EOS_R5) + || (id == CanonID_EOS_R6) + || (id == CanonID_EOS_R6m2) + || (id == CanonID_EOS_R8) + ) { ilm.CameraFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; @@ -120,8 +124,12 @@ void LibRaw::setCanonBodyFeatures(unsigned long long id) ilm.LensMount = LIBRAW_MOUNT_Canon_EF; } - else if ((id == CanonID_EOS_R7) || - (id == CanonID_EOS_R10)) + else if ( + (id == CanonID_EOS_R7) + || (id == CanonID_EOS_R10) + || (id == CanonID_EOS_R50) + || (id == CanonID_EOS_R100) + ) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Canon_RF; @@ -955,6 +963,7 @@ void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_1to1; break; case 2: + case 0x102: imgdata.sizes.raw_aspect = LIBRAW_IMAGE_ASPECT_4to3; break; case 7: @@ -1234,9 +1243,9 @@ void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, break; case 1820: // M50; ColorDataSubVer: 16 - case 1824: // R; ColorDataSubVer: 17 + case 1824: // R, Ra; ColorDataSubVer: 17 case 1816: // RP, 250D, SX70 HS; ColorDataSubVer: 18 - // M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19 + // R100, M6 Mark II, M200, 90D, G5 X Mark II, G7 X Mark III, 850D; ColorDataSubVer: 19 imCanon.ColorDataVer = 9; AsShot_Auto_MeasuredWB(0x0047); CR3_ColorData(0x0047); @@ -1244,14 +1253,14 @@ void LibRaw::parseCanonMakernotes(unsigned tag, unsigned /*type*/, unsigned len, case 1770: // R5 CRM case 2024: // -1D X Mark III; ColorDataSubVer: 32 - case 3656: // R5, R6; ColorDataSubVer: 33 + case 3656: // R5, R6; ColorDataSubVer: 33 imCanon.ColorDataVer = 10; AsShot_Auto_MeasuredWB(0x0055); CR3_ColorData(0x0055); break; case 3973: // R3; ColorDataSubVer: 34 - case 3778: // R7, R10; ColorDataSubVer: 48 + case 3778: // R6 Mark II, R7, R8, R10, R50; ColorDataSubVer: 48 imCanon.ColorDataVer = 11; AsShot_Auto_MeasuredWB(0x0069); diff --git a/src/metadata/ciff.cpp b/src/metadata/ciff.cpp index 2c59b11e7..b3c43066d 100644 --- a/src/metadata/ciff.cpp +++ b/src/metadata/ciff.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/cr3_parser.cpp b/src/metadata/cr3_parser.cpp index 52061e9c7..4b0d1d195 100644 --- a/src/metadata/cr3_parser.cpp +++ b/src/metadata/cr3_parser.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -138,6 +138,7 @@ void LibRaw::selectCRXTrack() else return; // No RAW track index + int ctmdcount = 0; // Frame selected: parse CTMD metadata for (int i = 0, trackcnt = 0; i <= maxTrack && i < LIBRAW_CRXTRACKS_MAXCOUNT; i++) { @@ -149,6 +150,7 @@ void LibRaw::selectCRXTrack() if (fsel) selectCRXFrame(i, fsel); parseCR3_CTMD(i); + ctmdcount++; } else if (d->MediaType == 2) // JPEG { @@ -228,6 +230,10 @@ void LibRaw::selectCRXTrack() } if (tiff_idx >= 0) flip = tiff_ifd[tiff_idx].t_flip; + + if (ctmdcount == 1 && imgdata.makernotes.canon.multishot[0] && imgdata.makernotes.canon.multishot[1]) + for (int c = 0; c < 4; c++) + cam_mul[c] = 1024; } } @@ -443,6 +449,7 @@ int LibRaw::parseCR3(INT64 oAtomList, char UIID[16]; uchar CMP1[85]; + uchar thdr[4]; uchar CDI1[60]; char HandlerType[5], MediaFormatID[5]; uint32_t relpos_inDir, relpos_inBox; @@ -463,6 +470,11 @@ int LibRaw::parseCR3(INT64 oAtomList, err = 0; order = 0x4d4d; fseek(ifp, oAtom, SEEK_SET); + if (nesting == 0) + { + fread(thdr, 1, 4, ifp); + fseek(ifp, oAtom, SEEK_SET); + } szAtom = get4(); FORC4 nmAtom[c] = AtomNameStack[nesting * 4 + c] = fgetc(ifp); AtomNameStack[(nesting + 1) * 4] = '\0'; @@ -478,6 +490,14 @@ int LibRaw::parseCR3(INT64 oAtomList, if (!AtomType) { + if (nesting == 0) + { + if(!memcmp(thdr,"II*\0",4) || !memcmp(thdr,"MM*\0",4)) + { + err = 0; + goto fin; + } + } err = 1; } diff --git a/src/metadata/epson.cpp b/src/metadata/epson.cpp index 427d98e9c..5537c9752 100644 --- a/src/metadata/epson.cpp +++ b/src/metadata/epson.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/metadata/exif_gps.cpp b/src/metadata/exif_gps.cpp index 7fb3b53ff..bc59371e5 100644 --- a/src/metadata/exif_gps.cpp +++ b/src/metadata/exif_gps.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/fuji.cpp b/src/metadata/fuji.cpp index feb394ef6..30e64c2ea 100644 --- a/src/metadata/fuji.cpp +++ b/src/metadata/fuji.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -17,6 +17,8 @@ */ #include "../../internal/dcraw_defs.h" +#include "../../internal/libraw_checked_buffer.h" + int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to first valid width/height pair { @@ -53,8 +55,9 @@ int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to - same conditions as for RAFData gen. 3, but also adds WRTS in bytes 4..7 - contains a table of 3+2*13 values; first 3 values look like WHW - H in WHW group has a different meaning if the shot is taken in crop 2 mode - GFX 100, GFX 100S, GFX 50R, GFX 50S, GFX 50S II - X-E2S, X-E3, X-H1, X-S10 + GFX 100, GFX 100S, GFX 100 II + GFX 50R, GFX 50S, GFX 50S II + X-E2S, X-E3, X-H1, X-S10, X-H2 X-T2, X-T3, X-T4, X-T20, X-T30 X-Pro2, X-Pro3 X100F, X100V @@ -96,16 +99,51 @@ int LibRaw::guess_RAFDataGeneration (uchar *RAFData_start) // returns offset to imFuji.RAFDataVersion = b23; } -// printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", -// imFuji.RAFDataVersion, imFuji.RAFDataGeneration); +//printf ("ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", +//ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration); return offsetWH_inRAFData; } +class fuji_wb_checked_buffer_t : public checked_buffer_t +{ +public: + bool isWB(unsigned offset) + { + return sget2(offset) != 0 && sget2(offset + 2) != 0 && sget2(offset + 4) != 0 && sget2(offset + 6) != 0 && + sget2(offset + 8) != 0 && sget2(offset + 10) != 0 && sget2(offset) != 0xff && sget2(offset + 2) != 0xff && + sget2(offset + 4) != 0xff && sget2(offset + 6) != 0xff && sget2(offset + 8) != 0xff && + sget2(offset + 10) != 0xff && sget2(offset) == sget2(offset + 6) && sget2(offset) < sget2(offset + 2) && + sget2(offset) < sget2(offset + 4) && sget2(offset) < sget2(offset + 8) && sget2(offset) < sget2(offset + 10) + ; + } + fuji_wb_checked_buffer_t(short ord, int size) : checked_buffer_t(ord, size) {} + void set_order(short o) { _order = o; } +}; + +struct tag2wb_t +{ + unsigned tag; + int wb; +} tag2wbtable[] = +{ + {0x2000, LIBRAW_WBI_Auto }, + {0x2100, LIBRAW_WBI_FineWeather }, + {0x2200, LIBRAW_WBI_Shade}, + {0x2300, LIBRAW_WBI_FL_D }, + {0x2301, LIBRAW_WBI_FL_N}, + {0x2302, LIBRAW_WBI_FL_W }, + {0x2310, LIBRAW_WBI_FL_WW}, + {0x2311, LIBRAW_WBI_FL_L}, + {0x2400, LIBRAW_WBI_Tungsten}, + {0x2410, LIBRAW_WBI_Flash} +}; +const int tag2wbtable_size = sizeof(tag2wbtable) / sizeof(tag2wbtable[0]); + + void LibRaw::parseAdobeRAFMakernote() { - uchar *PrivateMknBuf; unsigned posPrivateMknBuf=0; /* clang warns about not inited value */ unsigned PrivateMknLength; unsigned PrivateOrder; @@ -117,27 +155,7 @@ void LibRaw::parseAdobeRAFMakernote() int posWB; int c; -#define CHECKSPACE_ABS3(s1, s2, s3) \ - if (INT64(s1) + INT64(s2) + INT64(s3) > INT64(PrivateMknLength)) \ - { \ - free(PrivateMknBuf); \ - return; \ - } - -#define CHECKSPACE_ABS2(s1,s2) \ - if (INT64(s1) + INT64(s2) > INT64(PrivateMknLength)) \ - { \ - free(PrivateMknBuf); \ - return; \ - } - -#define CHECKSPACE(s) \ - if (INT64(posPrivateMknBuf) + INT64(s) > INT64(PrivateMknLength)) \ - { \ - free(PrivateMknBuf); \ - return; \ - } - +#if 0 #define isWB(posWB) \ sget2(posWB) != 0 && sget2(posWB + 2) != 0 && sget2(posWB + 4) != 0 && \ sget2(posWB + 6) != 0 && sget2(posWB + 8) != 0 && \ @@ -147,16 +165,15 @@ void LibRaw::parseAdobeRAFMakernote() sget2(posWB + 10) != 0xff && sget2(posWB) == sget2(posWB + 6) && \ sget2(posWB) < sget2(posWB + 2) && sget2(posWB) < sget2(posWB + 4) && \ sget2(posWB) < sget2(posWB + 8) && sget2(posWB) < sget2(posWB + 10) +#endif #define get_average_WB(wb_index) \ - CHECKSPACE(8); \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ - sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); \ + PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)); \ if ((PrivateTagBytes == 16) && average_WBData) { \ - CHECKSPACE(16); \ FORC4 icWBC[wb_index][GRGB_2_RGBG(c)] = \ (icWBC[wb_index][GRGB_2_RGBG(c)] + \ - sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)+8)) /2; \ + PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)+8)) /2; \ } \ if (use_WBcorr_coeffs) { \ icWBC[wb_index][0] *= wbR_corr; \ @@ -189,11 +206,11 @@ void LibRaw::parseAdobeRAFMakernote() PrivateMknLength = get4(); // At least 0x36 bytes because of memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); - if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000) && - (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024))) // 1024b for safety + if ((PrivateMknLength >= 0x36) && (PrivateMknLength < 10240000)) // 1024b for safety { - fread(PrivateMknBuf, PrivateMknLength, 1, ifp); - memcpy(imFuji.SerialSignature, PrivateMknBuf + 6, 0x0c); + fuji_wb_checked_buffer_t PrivateMknBuf(order, PrivateMknLength+1024); + fread(PrivateMknBuf.data(), PrivateMknLength, 1, ifp); + memcpy(imFuji.SerialSignature, PrivateMknBuf.data() + 6, 0x0c); imFuji.SerialSignature[0x0c] = 0; memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04); imFuji.SensorID[0x04] = 0; @@ -201,25 +218,22 @@ void LibRaw::parseAdobeRAFMakernote() while (isdigit(imFuji.SerialSignature[c]) && (c>0)) c--; ilm.CamID = unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1); - memcpy(model, PrivateMknBuf + 0x12, 0x20); + memcpy(model, PrivateMknBuf.data() + 0x12, 0x20); model[0x20] = 0; - memcpy(imFuji.RAFVersion, PrivateMknBuf + 0x32, 4); + memcpy(imFuji.RAFVersion, PrivateMknBuf.data() + 0x32, 4); imFuji.RAFVersion[4] = 0; - PrivateOrder = sget2(PrivateMknBuf); + PrivateOrder = PrivateMknBuf.sget2(0); unsigned s, l; - s = ifd_start = sget4(PrivateMknBuf +2)+6; - CHECKSPACE(INT64(ifd_start)+4LL); - l = ifd_len = sget4(PrivateMknBuf +ifd_start); - CHECKSPACE_ABS3(ifd_start, ifd_len, 4); + s = ifd_start = PrivateMknBuf.sget4(2)+6; + l = ifd_len = PrivateMknBuf.sget4(ifd_start); - if (!sget4(PrivateMknBuf+ifd_start+ifd_len+4)) + if (!PrivateMknBuf.sget4(ifd_start+ifd_len+4)) FujiShotSelect = 0; if ((FujiShotSelect == 1) && (PrivateMknLength > ifd_len*2)) { ifd_start += (ifd_len+4); - CHECKSPACE_ABS2(ifd_start, 4); - ifd_len = sget4(PrivateMknBuf +ifd_start); + ifd_len = PrivateMknBuf.sget4(ifd_start); if ((ifd_start+ifd_len) > PrivateMknLength) { ifd_start = s; ifd_len = l; @@ -227,12 +241,10 @@ void LibRaw::parseAdobeRAFMakernote() } } else FujiShotSelect = 0; - CHECKSPACE_ABS3(ifd_start, 4, 4); - PrivateEntries = sget4(PrivateMknBuf + ifd_start + 4); + PrivateEntries = PrivateMknBuf.sget4(ifd_start + 4); if ((PrivateEntries > 1000) || ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) { - free(PrivateMknBuf); return; } posPrivateMknBuf = (ifd_start+8); @@ -246,68 +258,35 @@ void LibRaw::parseAdobeRAFMakernote() **/ while (PrivateEntries--) { - order = 0x4d4d; - CHECKSPACE(4); - PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); - PrivateTagBytes = sget2(PrivateMknBuf + posPrivateMknBuf + 2); + PrivateMknBuf.set_order(0x4d4d); + order = 0x4d4d; + PrivateTagID = PrivateMknBuf.sget2(posPrivateMknBuf); + PrivateTagBytes = PrivateMknBuf.sget2(posPrivateMknBuf + 2); posPrivateMknBuf += 4; - order = PrivateOrder; + PrivateMknBuf.set_order(PrivateOrder); + order = PrivateOrder; - if (PrivateTagID == 0x2000) - { - get_average_WB(LIBRAW_WBI_Auto); - } - else if (PrivateTagID == 0x2100) - { - get_average_WB(LIBRAW_WBI_FineWeather); - } - else if (PrivateTagID == 0x2200) - { - get_average_WB(LIBRAW_WBI_Shade); - } - else if (PrivateTagID == 0x2300) - { - get_average_WB(LIBRAW_WBI_FL_D); - } - else if (PrivateTagID == 0x2301) - { - get_average_WB(LIBRAW_WBI_FL_N); - } - else if (PrivateTagID == 0x2302) - { - get_average_WB(LIBRAW_WBI_FL_W); - } - else if (PrivateTagID == 0x2310) - { - get_average_WB(LIBRAW_WBI_FL_WW); - } - else if (PrivateTagID == 0x2311) - { - get_average_WB(LIBRAW_WBI_FL_L); - } - else if (PrivateTagID == 0x2400) - { - get_average_WB(LIBRAW_WBI_Tungsten); - } - else if (PrivateTagID == 0x2410) - { - get_average_WB(LIBRAW_WBI_Flash); - } + if (PrivateTagID >= 0x2000 && PrivateTagID <= 0x2410) + { + for(int q = 0; q < tag2wbtable_size; q++) + if (tag2wbtable[q].tag == PrivateTagID) + { + get_average_WB(tag2wbtable[q].wb); + break; + } + } else if (PrivateTagID == 0x2f00) { - CHECKSPACE(4); - int nWBs = MIN(sget4(PrivateMknBuf + posPrivateMknBuf), 6); + int nWBs = MIN(PrivateMknBuf.sget4(posPrivateMknBuf), 6); posWB = posPrivateMknBuf + 4; for (int wb_ind = LIBRAW_WBI_Custom1; wb_ind < LIBRAW_WBI_Custom1+nWBs; wb_ind++) { - CHECKSPACE_ABS2(posWB, 8); FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = - sget2(PrivateMknBuf + posWB + (c << 1)); + PrivateMknBuf.sget2(posWB + (c << 1)); if ((PrivateTagBytes >= unsigned(4+16*nWBs)) && average_WBData) { posWB += 8; - CHECKSPACE_ABS2(posWB, 8); FORC4 icWBC[wb_ind][GRGB_2_RGBG(c)] = (icWBC[wb_ind][GRGB_2_RGBG(c)] + - sget2(PrivateMknBuf + posWB + (c << 1))) /2; + PrivateMknBuf.sget2(posWB + (c << 1))) /2; } if (use_WBcorr_coeffs) { icWBC[wb_ind][0] *= wbR_corr; @@ -325,49 +304,48 @@ void LibRaw::parseAdobeRAFMakernote() ((PrivateTagBytes == 8) || (PrivateTagBytes == 16))) { imFuji.BlackLevel[0] = PrivateTagBytes / 2; - CHECKSPACE(10); FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c)+1] = - sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1)); + PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1)); if (imFuji.BlackLevel[0] == 8) { - CHECKSPACE(18); FORC4 imFuji.BlackLevel[GRGB_2_RGBG(c) + 5] = - sget2(PrivateMknBuf + posPrivateMknBuf + (c << 1) + 8); + PrivateMknBuf.sget2(posPrivateMknBuf + (c << 1) + 8); } } else if (PrivateTagID == 0x9650) { - CHECKSPACE(4); - short a = (short)sget2(PrivateMknBuf + posPrivateMknBuf); - float b = fMAX(1.0f, sget2(PrivateMknBuf + posPrivateMknBuf + 2)); + short a = (short)PrivateMknBuf.sget2(posPrivateMknBuf); + float b = fMAX(1.0f, PrivateMknBuf.sget2(posPrivateMknBuf + 2)); imFuji.ExpoMidPointShift = a / b; imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; } else if ((PrivateTagID == 0xc000) && (PrivateTagBytes > 3) && (PrivateTagBytes < 10240000)) { - order = 0x4949; + PrivateMknBuf.set_order(0x4949); + order = 0x4949; if (PrivateTagBytes != 4096) // not one of Fuji X-A3, X-A5, X-A7, X-A10, X-A20, X-T100, X-T200, XF10 { int is34 = 0; - CHECKSPACE(8); - guess_RAFDataGeneration (PrivateMknBuf + posPrivateMknBuf); -// printf ("RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", -// imFuji.RAFDataVersion, imFuji.RAFDataGeneration); + PrivateMknBuf.checkoffset(posPrivateMknBuf + 8); // will raise exception if no space + guess_RAFDataGeneration (PrivateMknBuf.data() + posPrivateMknBuf); + +//printf ("ID: 0x%llx, RAFDataVersion: 0x%04x, RAFDataGeneration: %d\n", +//ilm.CamID, imFuji.RAFDataVersion, imFuji.RAFDataGeneration); for (posWB = 0; posWB < (int)PrivateTagBytes - 16; posWB++) { - CHECKSPACE_ABS2(posWB, 12); - if ((!memcmp(PrivateMknBuf + posWB, "TSNERDTS", 8) && - (sget2(PrivateMknBuf + posWB + 10) > 125))) + PrivateMknBuf.checkoffset(posWB + 12); // will raise exception if no space + if ((!memcmp(PrivateMknBuf.data() + posWB, "TSNERDTS", 8) && + (PrivateMknBuf.sget2( posWB + 10) > 125))) { posWB += 10; icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = - sget2(PrivateMknBuf + posWB); + PrivateMknBuf.sget2(posWB); icWBC[LIBRAW_WBI_Auto][0] = - sget2(PrivateMknBuf + posWB + 2); + PrivateMknBuf.sget2(posWB + 2); icWBC[LIBRAW_WBI_Auto][2] = - sget2(PrivateMknBuf + posWB + 4); + PrivateMknBuf.sget2(posWB + 4); break; } } @@ -375,16 +353,20 @@ void LibRaw::parseAdobeRAFMakernote() if ((imFuji.RAFDataVersion == 0x0260) || // X-Pro3, GFX 100S (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II (imFuji.RAFDataVersion == 0x0262) || // X-T4 - (imFuji.RAFDataVersion == 0x0264) || // X-S10 - (imFuji.RAFDataVersion == 0x0265) || // X-E4 + (imFuji.RAFDataVersion == 0x0263) || // X-H2s + (imFuji.RAFDataVersion == 0x0264) || // X-S10, X-H2 + (imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5 (imFuji.RAFDataVersion == 0x0266) || // X-T30 II + (imFuji.RAFDataVersion == 0x0267) || // GFX 100 II !strcmp(model, "X-Pro3") || - !strcmp(model, "GFX 100S") || - !strcmp(model, "GFX100S") || - !strcmp(model, "GFX 50S II") || - !strcmp(model, "GFX50S II") || + !strcmp(model, "GFX 100 II") || !strcmp(model, "GFX100 II") || + !strcmp(model, "GFX 100S") || !strcmp(model, "GFX100S") || + !strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II") || !strcmp(model, "X100V") || + !strcmp(model, "X-H2") || + !strcmp(model, "X-H2S") || !strcmp(model, "X-T4") || + !strcmp(model, "X-T5") || !strcmp(model, "X-E4") || !strcmp(model, "X-T30 II") || !strcmp(model, "X-S10")) @@ -464,16 +446,11 @@ void LibRaw::parseAdobeRAFMakernote() } else if (imFuji.RAFDataVersion == 0x025f) // X-T30, GFX 50R, GFX 100 (? RAFDataVersion 0x045f) { - if (!strcmp(model, "X-T30")) { - CHECKSPACE(0x20b8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) + if (!strcmp(model, "X-T30")) { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8)) wb_section_offset = 0x20b8; - else - { - CHECKSPACE(0x20c8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8)) wb_section_offset = 0x20c8; - } } else if (!strcmp(model, "GFX 50R")) wb_section_offset = 0x1424; @@ -496,16 +473,34 @@ void LibRaw::parseAdobeRAFMakernote() } else if (imFuji.RAFDataVersion == 0x0262) // X-T4 { - wb_section_offset = 0x21c8; + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8)) + wb_section_offset = 0x21c8; + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) + wb_section_offset = 0x21cc; } - else if (imFuji.RAFDataVersion == 0x0264) // X-S10 + else if (imFuji.RAFDataVersion == 0x0263) // X-H2S { - wb_section_offset = 0x21de; + wb_section_offset = 0x0b40; } - else if ((imFuji.RAFDataVersion == 0x0265) || // X-E4 - (imFuji.RAFDataVersion == 0x0266)) // X-T30 II + else if (imFuji.RAFDataVersion == 0x0264) // X-S10, X-H2 { - wb_section_offset = 0x21cc; + if (!strcmp(model, "X-S10")) + wb_section_offset = 0x21de; + else if (!strcmp(model, "X-H2")) + wb_section_offset = 0x0b3e; + } + else if ((imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5 + (imFuji.RAFDataVersion == 0x0266)) // X-T30 II, X-S20 + { + if (!strcmp(model, "X-T5") || + !strcmp(model, "X-S20")) + wb_section_offset = 0x0c72; + else + wb_section_offset = 0x21cc; + } + else if (imFuji.RAFDataVersion == 0x0267) // GFX 100 II + { + wb_section_offset = 0x0cae; } else if (imFuji.RAFDataVersion == 0x0355) // X-E2S { @@ -515,168 +510,166 @@ void LibRaw::parseAdobeRAFMakernote() /* try for unknown RAF Data versions */ else if (!strcmp(model, "X-Pro2")) { - CHECKSPACE(0x135c + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x135c)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x135c)) wb_section_offset = 0x135c; } else if (!strcmp(model, "X100F")) { - CHECKSPACE(0x1370 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1370)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1370)) wb_section_offset = 0x1370; } else if (!strcmp(model, "X-E1")) { - CHECKSPACE(0x13ac + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13ac)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13ac)) wb_section_offset = 0x13ac; } else if (!strcmp(model, "X-T2") || !strcmp(model, "X-T20")) { - CHECKSPACE(0x13dc + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13dc)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13dc)) wb_section_offset = 0x13dc; } else if (!strcmp(model, "X20") || !strcmp(model, "X100S")) { - CHECKSPACE(0x1410 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1410)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1410)) wb_section_offset = 0x1410; } else if (!strcmp(model, "XQ1") || !strcmp(model, "XQ2")) { - CHECKSPACE(0x1414+ 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1414)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1414)) wb_section_offset = 0x1414; } else if (!strcmp(model, "X-E3")) { - CHECKSPACE(0x141c + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x141c)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x141c)) wb_section_offset = 0x141c; } else if (!strcmp(model, "GFX 50S") || !strcmp(model, "GFX 50R")) { - CHECKSPACE(0x1424 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1424)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1424)) wb_section_offset = 0x1424; } - else if (!strcmp(model, "GFX 50S II") || !strcmp(model, "GFX50S II")) { - CHECKSPACE(0x214c + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x214c)) + else if (!strcmp(model, "GFX 50S II") || + !strcmp(model, "GFX50S II")) { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x214c)) wb_section_offset = 0x214c; } else if (!strcmp(model, "X30") || !strcmp(model, "X100T")) { - CHECKSPACE(0x1444 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1444)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1444)) wb_section_offset = 0x1444; } else if (!strcmp(model, "X-M1") || !strcmp(model, "X-A1") || !strcmp(model, "X-A2")) { - CHECKSPACE(0x1474 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1474)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1474)) wb_section_offset = 0x1474; } else if (!strcmp(model, "X-E2") || !strcmp(model, "X-H1")) { - CHECKSPACE(0x1480 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1480)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1480)) wb_section_offset = 0x1480; } else if (!strcmp(model, "X-T1")) { - CHECKSPACE(0x14b0 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x14b0)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x14b0)) wb_section_offset = 0x14b0; } else if (!strcmp(model, "X70")) { - CHECKSPACE(0x17b4 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x17b4)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x17b4)) wb_section_offset = 0x17b4; } else if (!strcmp(model, "X-T10")) { - CHECKSPACE(0x1824 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1824)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1824)) wb_section_offset = 0x1824; } else if (!strcmp(model, "X-E2S")) { - CHECKSPACE(0x1840 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1840)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1840)) wb_section_offset = 0x1840; } else if (!strcmp(model, "X-T3")) { - CHECKSPACE(0x2014 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2014)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2014)) wb_section_offset = 0x2014; } else if (!strcmp(model, "X100V")) { - CHECKSPACE(0x2078 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2078)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2078)) wb_section_offset = 0x2078; } else if (!strcmp(model, "X-T30")) { - CHECKSPACE(0x20b8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20b8)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20b8)) wb_section_offset = 0x20b8; - else - { - CHECKSPACE(0x20c8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20c8)) - wb_section_offset = 0x20c8; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20c8)) + wb_section_offset = 0x20c8; } else if (!strcmp(model, "GFX 100")) { - CHECKSPACE(0x20e4 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e4)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e4)) wb_section_offset = 0x20e4; } else if (!strcmp(model, "X-Pro3")) { - CHECKSPACE(0x20e8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x20e8)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x20e8)) wb_section_offset = 0x20e8; } - else if (!strcmp(model, "GFX100S") || !strcmp(model, "GFX 100S")) + else if (!strcmp(model, "GFX100S") || + !strcmp(model, "GFX 100S")) { - CHECKSPACE(0x2108 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x2108)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x2108)) wb_section_offset = 0x2108; } else if (!strcmp(model, "X-T4")) { - CHECKSPACE(0x21c8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21c8)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21c8)) wb_section_offset = 0x21c8; + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) + wb_section_offset = 0x21cc; } else if ((!strcmp(model, "X-E4")) || (!strcmp(model, "X-T30 II"))) { - CHECKSPACE(0x21cc + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21cc)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21cc)) wb_section_offset = 0x21cc; } else if (!strcmp(model, "X-S10")) { - CHECKSPACE(0x21de + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x21de)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x21de)) wb_section_offset = 0x21de; } + else if (!strcmp(model, "X-H2")) + { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b3e)) + wb_section_offset = 0x0b3e; + } + else if (!strcmp(model, "X-H2S")) + { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0b40)) + wb_section_offset = 0x0b40; + } + else if (!strcmp(model, "X-T5") || + !strcmp(model, "X-S20")) + { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0c72)) + wb_section_offset = 0x0c72; + } + else if (!strcmp(model, "GFX 100 II") || + !strcmp(model, "GFX100 II")) + { + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x0cae)) + wb_section_offset = 0x0cae; + } + /* no RAF Data version for the models below */ else if (!strcmp(model, "FinePix X100")) // X100 0 0x19f0 0x19e8 { @@ -687,15 +680,10 @@ void LibRaw::parseAdobeRAFMakernote() wb_section_offset = 0x19f0; else { - CHECKSPACE(0x19e8 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19e8)) + if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19e8)) wb_section_offset = 0x19e8; - else - { - CHECKSPACE(0x19f0 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x19f0)) - wb_section_offset = 0x19f0; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x19f0)) + wb_section_offset = 0x19f0; } } else if (!strcmp(model, "X-Pro1")) // X-Pro1 0 0x13a4 @@ -704,34 +692,22 @@ void LibRaw::parseAdobeRAFMakernote() !strcmp(imFuji.RAFVersion, "0101") || !strcmp(imFuji.RAFVersion, "0204")) wb_section_offset = 0x13a4; - else - { - CHECKSPACE(0x13a4 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x13a4)) - wb_section_offset = 0x13a4; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x13a4)) + wb_section_offset = 0x13a4; } else if (!strcmp(model, "XF1")) // XF1 0 0x138c { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x138c; - else - { - CHECKSPACE(0x138c + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) - wb_section_offset = 0x138c; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c)) + wb_section_offset = 0x138c; } else if (!strcmp(model, "X-S1")) // X-S1 0 0x1284 { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x1284; - else - { - CHECKSPACE(0x1284 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1284)) - wb_section_offset = 0x1284; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1284)) + wb_section_offset = 0x1284; } else if (!strcmp(model, "X10")) // X10 0 0x1280 0x12d4 { @@ -740,76 +716,46 @@ void LibRaw::parseAdobeRAFMakernote() wb_section_offset = 0x1280; else if (!strcmp(imFuji.RAFVersion, "0103")) wb_section_offset = 0x12d4; - else - { - CHECKSPACE(0x1280 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x1280)) + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x1280)) wb_section_offset = 0x1280; - else - { - CHECKSPACE(0x12d4 + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x12d4)) - wb_section_offset = 0x12d4; - } - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x12d4)) + wb_section_offset = 0x12d4; } else if (!strcmp(model, "XF1")) // XF1 0 0x138c { if (!strcmp(imFuji.RAFVersion, "0100")) wb_section_offset = 0x138c; - else - { - CHECKSPACE(0x138c + 12); - if (isWB(PrivateMknBuf + posPrivateMknBuf + 0x138c)) - wb_section_offset = 0x138c; - } + else if (PrivateMknBuf.isWB(posPrivateMknBuf + 0x138c)) + wb_section_offset = 0x138c; } - if (wb_section_offset) - { - CHECKSPACE(INT64(wb_section_offset) + 12LL); - } - - if (wb_section_offset && - isWB(PrivateMknBuf + posPrivateMknBuf + wb_section_offset)) + if (wb_section_offset && PrivateMknBuf.isWB(posPrivateMknBuf + wb_section_offset)) { if (!imFuji.RAFDataVersion) { posWB = posPrivateMknBuf + wb_section_offset - 6; - CHECKSPACE_ABS2(posWB, 6); - icWBC[LIBRAW_WBI_Auto][1] = - icWBC[LIBRAW_WBI_Auto][3] = - sget2(PrivateMknBuf + posWB); - icWBC[LIBRAW_WBI_Auto][0] = - sget2(PrivateMknBuf + posWB + 2); - icWBC[LIBRAW_WBI_Auto][2] = - sget2(PrivateMknBuf + posWB + 4); + icWBC[LIBRAW_WBI_Auto][1] = icWBC[LIBRAW_WBI_Auto][3] = PrivateMknBuf.sget2(posWB); + icWBC[LIBRAW_WBI_Auto][0] = PrivateMknBuf.sget2(posWB + 2); + icWBC[LIBRAW_WBI_Auto][2] = PrivateMknBuf.sget2(posWB + 4); } posWB = posPrivateMknBuf + wb_section_offset; for (int wb_ind = 0; wb_ind < (int)Fuji_wb_list1.size(); posWB += 6, wb_ind++) { - CHECKSPACE_ABS2(posWB, 6); - icWBC[Fuji_wb_list1[wb_ind]][1] = - icWBC[Fuji_wb_list1[wb_ind]][3] = - sget2(PrivateMknBuf + posWB); - icWBC[Fuji_wb_list1[wb_ind]][0] = - sget2(PrivateMknBuf + posWB + 2); - icWBC[Fuji_wb_list1[wb_ind]][2] = - sget2(PrivateMknBuf + posWB + 4); + icWBC[Fuji_wb_list1[wb_ind]][1] = icWBC[Fuji_wb_list1[wb_ind]][3] = PrivateMknBuf.sget2(posWB); + icWBC[Fuji_wb_list1[wb_ind]][0] = PrivateMknBuf.sget2(posWB + 2); + icWBC[Fuji_wb_list1[wb_ind]][2] = PrivateMknBuf.sget2(posWB + 4); } int found = 0; if (is34) posWB += 0x30; posWB += 0xc0; - CHECKSPACE_ABS2(posWB, 2); - ushort Gval = sget2(PrivateMknBuf + posWB); + ushort Gval = PrivateMknBuf.sget2(posWB); for (int posEndCCTsection = posWB; posEndCCTsection < (posWB + 30); posEndCCTsection += 6) { - CHECKSPACE_ABS2(posEndCCTsection, 2); - if (sget2(PrivateMknBuf + posEndCCTsection) != Gval) + if (PrivateMknBuf.sget2(posEndCCTsection) != Gval) { if (is34) wb_section_offset = posEndCCTsection - 34*3*2; // 34 records, 3 2-byte values in a record @@ -824,11 +770,10 @@ void LibRaw::parseAdobeRAFMakernote() { for (int iCCT = 0; iCCT < 31; iCCT++) { - CHECKSPACE_ABS2(wb_section_offset, iCCT*6+6); icWBCCTC[iCCT][0] = FujiCCT_K[iCCT]; - icWBCCTC[iCCT][1] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 2); - icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6); - icWBCCTC[iCCT][3] = sget2(PrivateMknBuf + wb_section_offset + iCCT * 6 + 4); + icWBCCTC[iCCT][1] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 2); + icWBCCTC[iCCT][2] = icWBCCTC[iCCT][4] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6); + icWBCCTC[iCCT][3] = PrivateMknBuf.sget2(wb_section_offset + iCCT * 6 + 4); } } } @@ -842,18 +787,17 @@ void LibRaw::parseAdobeRAFMakernote() posWB = posPrivateMknBuf + 0x200; for (int wb_ind = 0; wb_ind < 42; wb_ind++) { - CHECKSPACE_ABS2(posWB, 24); - nWB = sget4(PrivateMknBuf + posWB); + nWB = PrivateMknBuf.sget4(posWB); posWB += 4; - tWB = sget4(PrivateMknBuf + posWB); + tWB = PrivateMknBuf.sget4(posWB); posWB += 4; - wb[0] = sget4(PrivateMknBuf + posWB) << 1; + wb[0] = PrivateMknBuf.sget4(posWB) << 1; posWB += 4; - wb[1] = sget4(PrivateMknBuf + posWB); + wb[1] = PrivateMknBuf.sget4(posWB); posWB += 4; - wb[3] = sget4(PrivateMknBuf + posWB); + wb[3] = PrivateMknBuf.sget4(posWB); posWB += 4; - wb[2] = sget4(PrivateMknBuf + posWB) << 1; + wb[2] = PrivateMknBuf.sget4(posWB) << 1; posWB += 4; if (tWB && (iCCT < 255)) @@ -878,12 +822,8 @@ void LibRaw::parseAdobeRAFMakernote() } posPrivateMknBuf += PrivateTagBytes; } - free(PrivateMknBuf); } #undef get_average_WB -#undef CHECKSPACE -#undef CHECKSPACE_ABS2 -#undef CHECKSPACE_ABS3 } void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, @@ -1046,7 +986,7 @@ void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, imFuji.ShutterType = get2(); break; case 0x1100: - imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode + imFuji.AutoBracketing = get2(); // AutoBracketing = 6 for pixel shift mode break; case 0x1101: imFuji.SequenceNumber = get2(); @@ -1114,6 +1054,12 @@ void LibRaw::parseFujiMakernotes(unsigned tag, unsigned type, unsigned len, case 0x1445: imFuji.DRangePriorityFixed = get2(); break; + case 0x1447: + stmread(imFuji.FujiModel, len, ifp); + break; + case 0x1448: + stmread(imFuji.FujiModel2, len, ifp); + break; } return; } @@ -1292,45 +1238,14 @@ void LibRaw::parse_fuji(int offset) imFuji.ExpoMidPointShift = a / b; imCommon.ExposureCalibrationShift += imFuji.ExpoMidPointShift; } - else if (tag == 0x2000) // WB_GRGBLevelsAuto + if (tag >= 0x2000 && tag <= 0x2410) { - get_average_WB(LIBRAW_WBI_Auto); - } - else if (tag == 0x2100) // WB_GRGBLevelsDaylight - { - get_average_WB(LIBRAW_WBI_FineWeather); - } - else if (tag == 0x2200) // WB_GRGBLevelsCloudy - { - get_average_WB(LIBRAW_WBI_Shade); - } - else if (tag == 0x2300) // WB_GRGBLevelsDaylightFluor - { - get_average_WB(LIBRAW_WBI_FL_D); - } - else if (tag == 0x2301) // WB_GRGBLevelsDayWhiteFluor - { - get_average_WB(LIBRAW_WBI_FL_N); - } - else if (tag == 0x2302) // WB_GRGBLevelsWhiteFluorescent - { - get_average_WB(LIBRAW_WBI_FL_W); - } - else if (tag == 0x2310) // WB_GRGBLevelsWarmWhiteFluor - { - get_average_WB(LIBRAW_WBI_FL_WW); - } - else if (tag == 0x2311) // WB_GRGBLevelsLivingRoomWarmWhiteFluor - { - get_average_WB(LIBRAW_WBI_FL_L); - } - else if (tag == 0x2400) // WB_GRGBLevelsTungsten - { - get_average_WB(LIBRAW_WBI_Tungsten); - } - else if (tag == 0x2410) - { - get_average_WB(LIBRAW_WBI_Flash); + for (int q = 0; q < tag2wbtable_size; q++) + if (tag2wbtable[q].tag == tag) + { + get_average_WB(tag2wbtable[q].wb); + break; + } } else if (tag == 0x2f00) // WB_GRGBLevels { diff --git a/src/metadata/hasselblad_model.cpp b/src/metadata/hasselblad_model.cpp index b20da5efa..042a63fbe 100644 --- a/src/metadata/hasselblad_model.cpp +++ b/src/metadata/hasselblad_model.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -43,9 +43,10 @@ void LibRaw::process_Hassy_Lens (int LensMount) { // focal1*10000ULL + focal2*10 + version; char *ps; int c; - char *q = strchr(imgdata.lens.Lens, ' '); - if(!q) return ; - c = atoi(q+1); + char *q = strchr(imgdata.lens.Lens, ' '); + if (!q) + return; + c = atoi(q +1); if (!c) return; @@ -315,6 +316,11 @@ static const char *Hasselblad_SensorEnclosures[] = { strcpy(imHassy.Sensor, "-100c"); cpynorm("100-17-Coated5"); + } else if ((imHassy.SensorCode == 20) && + (imHassy.CoatingCode == 6)) { + strcpy(imHassy.Sensor, "-100c"); + cpynorm("100-20-Coated6"); + } else if ((raw_width == 4090) || // V96C ((raw_width == 4096) && (raw_height == 4096)) || ((raw_width == 4088) && (raw_height == 4088)) || // Adobe crop @@ -446,12 +452,20 @@ static const char *Hasselblad_SensorEnclosures[] = { } else if (((raw_width == 12000) && (raw_height == 8816)) || ((raw_width == 11608) && (raw_height == 8708)) || // Adobe crop - ((raw_width == 11600) && (raw_height == 8700))) { // Phocus crop + ((raw_width == 11600) && (raw_height == 8700))) { // Phocus crop strcpy(imHassy.Sensor, "-100c"); cpynorm("100-17-Coated5"); if (!imHassy.SensorCode) imHassy.SensorCode = 17; if (!imHassy.CoatingCode) imHassy.CoatingCode = 5; + } else if (((raw_width == 11904) && (raw_height == 8842)) || // X2D 100C + ((raw_width == 11664) && (raw_height == 8750)) || // Adobe crop + ((raw_width == 11656) && (raw_height == 8742))) { // Phocus crop + strcpy(imHassy.Sensor, "-100c"); + cpynorm("100-20-Coated6"); + if (!imHassy.SensorCode) imHassy.SensorCode = 20; + if (!imHassy.CoatingCode) imHassy.CoatingCode = 6; + } if (raw_width == 4090) @@ -470,7 +484,8 @@ static const char *Hasselblad_SensorEnclosures[] = { ((raw_width == 8384) && (raw_height == 6304)) || ((raw_width == 9044) && (raw_height == 6732)) || ((raw_width == 10320) && (raw_height == 7752)) || - ((raw_width == 12000) && (raw_height == 8816)) + ((raw_width == 12000) && (raw_height == 8816)) || + ((raw_width == 11904) && (raw_height == 8842)) ) imHassy.uncropped = 1; @@ -533,6 +548,10 @@ static const char *Hasselblad_SensorEnclosures[] = { } } } + +// printf (">> SensorCode: %d, CoatingCode: %d, Sensor: %s\n", imHassy.SensorCode, imHassy.CoatingCode, imHassy.Sensor); +// printf (">> raw_width: %d, raw_height: %d\n", raw_width, raw_height); + if (normalized_model[0] && !CM_found) CM_found = adobe_coeff(maker_index, normalized_model); } diff --git a/src/metadata/identify.cpp b/src/metadata/identify.cpp index aabbf85c1..bb43081bc 100644 --- a/src/metadata/identify.cpp +++ b/src/metadata/identify.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -42,8 +42,8 @@ static const struct {LIBRAW_CAMERAMAKER_Nikon, "Nikon"}, {LIBRAW_CAMERAMAKER_Nokia, "Nokia"}, {LIBRAW_CAMERAMAKER_Olympus, "Olympus"}, - {LIBRAW_CAMERAMAKER_OmDigital, "OM Digital"}, - {LIBRAW_CAMERAMAKER_Ricoh, "Ricoh"}, + {LIBRAW_CAMERAMAKER_OmDigital, "OM Digital"}, + {LIBRAW_CAMERAMAKER_Ricoh, "Ricoh"}, {LIBRAW_CAMERAMAKER_Pentax, "Pentax"}, {LIBRAW_CAMERAMAKER_PhaseOne, "Phase One"}, {LIBRAW_CAMERAMAKER_PhaseOne, "PhaseOne"}, @@ -130,50 +130,6 @@ const char *LibRaw::cameramakeridx2maker(unsigned maker) } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void LibRaw::fixupArri() -{ - struct alist_t - { - const char *a_model; - const char *a_software; - ushort a_width,a_height; - int a_black; - unsigned a_filters; - float a_aspect; - } - alist[] = - { - {"ALEXA65", "Alexa65 XT", 6560 ,3100, 256,0x49494949,1.f}, - - {"ALEXALF", "Alexa LF Plus W", 3840 ,2160, 256,0x49494949,1.0f }, - {"ALEXALF", "Alexa LF Plus W", 4448 ,1856, 256,0x49494949,0.75f }, - {"ALEXALF", "Alexa LF Plus W", 4448 ,3096, 256,0x49494949,1.f }, - - {"ALEXA", "Alexa Plus 4:3 SXT", 2880 ,1620, 256,0x61616161,.75f}, - {"ALEXA", "Alexa Plus 4:3 SXT", 3168 ,1782, 256,0x61616161,0.75f}, - {"ALEXA", "Alexa Plus 4:3 SXT", 3424 ,2202, 256,0x61616161,1.f}, - {"ALEXA", "Alexa Plus 4:3 SXT", 2592 ,2160, 256,0x61616161,1.12f}, - - {"ALEXA", "Alexa Plus 4:3 XT", 2592 ,2160, 256,0x61616161,1.12f}, - {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,2160, 256,0x61616161,1.f}, - {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,1620, 256,0x61616161,0.75f}, - {"ALEXA", "Alexa Plus 4:3 XT", 3424 ,2202, 256,0x61616161,1.f}, - }; - for(int i = 0; i < int(sizeof(alist)/sizeof(alist[0])); i++) - if(!strncasecmp(model,alist[i].a_model,strlen(alist[i].a_model)) && software - && !strncasecmp(software,alist[i].a_software,strlen(alist[i].a_software)) - && width == alist[i].a_width && height == alist[i].a_height) - { - filters = alist[i].a_filters; - black = alist[i].a_black; - pixel_aspect = alist[i].a_aspect; - strcpy(model,software); - software[0]=0; - return; - } -} -#endif /* Identify which camera created this file, and set global variables accordingly. @@ -208,7 +164,7 @@ void LibRaw::identify() { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, // 19 "PowerShot SX50 HS" { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, // 20 "PowerShot G16", "PowerShot S120" { 4312, 2876, 22, 18, 0, 2 }, // 21 "EOS 450D" - { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R" + { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R", "EOS Ra" { 4352, 2874, 62, 18, 0, 0 }, // 23 "EOS 1100D" { 4476, 2954, 90, 34, 0, 0 }, // 24 "EOS 5D" { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, // 25 "PowerShot G10" @@ -231,174 +187,175 @@ void LibRaw::identify() { 5920, 3950, 122, 80, 2, 0 }, // 42 "EOS 5D Mark III" { 6096, 4051, 76, 35, 0, 0 }, // 43 "EOS 1500D" { 6096, 4056, 72, 34, 0, 0 }, // 44 "EOS M3", "EOS 760D", "EOS 750D" - { 6288, 4056, 264, 36, 0, 0 }, // 45 "EOS M5", "EOS M100", "EOS M6", "PowerShot G1 X Mark III", "EOS 80D", "EOS 800D", "EOS 77D", "EOS 200D", "EOS 250D", "EOS M50" + { 6288, 4056, 264, 36, 0, 0 }, // 45 "EOS M5", "EOS M100", "EOS M6", "PowerShot G1 X Mark III", "EOS 80D", "EOS 800D", "EOS 77D", "EOS 200D", "EOS 250D", "EOS M50", "EOS R100" { 6384, 4224, 120, 44, 0, 0 }, // 46 "EOS 6D Mark II", "EOS RP" { 6880, 4544, 136, 42, 0, 0 }, // 47 "EOS 5D Mark IV" - { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R" + { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R", "EOS Ra" { 7128, 4732, 144, 72, 0, 0 }, // 49 "EOS M6 II", "EOS 90D" { 8896, 5920, 160, 64, 0, 0 }, // 50 "EOS 5DS", "EOS 5DS R" - { 6192, 4152, 160, 120, 0, 0}, // EOS R3 - { 6192, 4060, 168, 52, 24, 8, 16,48,32,0,} // EOS R10 + { 6192, 4152, 160, 120, 0, 0}, // EOS R3 + { 6192, 4060, 168, 52, 24, 8, 16,48,32,0}, // EOS R10 + { 6188, 4120, 154, 96, 12, 0, 16, 48, 32, 0}, // EOS R6mk2 }; static const libraw_custom_camera_t const_table[] = { - { 786432, 1024, 768, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-080C" }, - { 1447680, 1392, 1040, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-145C" }, - { 1920000, 1600, 1200, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-201C" }, - { 5067304, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C" }, - { 5067316, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C", 12 }, - { 10134608, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C" }, - { 10134620, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C", 12 }, - { 16157136, 3272, 2469, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-810C" }, - { 3995136, 1632, 1224, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, - { 15980544, 3264, 2448, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, - { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" }, - { 31850496, 4608, 3456, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 4:3" }, - { 23887872, 4608, 2592, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 16:9" }, - { 32257024, 4624, 3488, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" }, - { 24192768, 4624, 2616, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" }, - { 18016000, 4000, 2252, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" }, + { 786432, 1024, 768, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-080C" }, + { 1447680, 1392, 1040, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-145C" }, + { 1920000, 1600, 1200, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-201C" }, + { 5067304, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C" }, + { 5067316, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C", 12 }, + { 10134608, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C" }, + { 10134620, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C", 12 }, + { 16157136, 3272, 2469, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-810C" }, + { 3995136, 1632, 1224, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, + { 15980544, 3264, 2448, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" }, + { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" }, + { 31850496, 4608, 3456, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 4:3" }, + { 23887872, 4608, 2592, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 16:9" }, + { 32257024, 4624, 3488, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" }, + { 24192768, 4624, 2616, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" }, + { 18016000, 4000, 2252, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" }, // {24000000, 4000, 3000, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", // "G3DUO 4:3"}, // Conflict w/ Samsung WB550 // Android Raw dumps id start // File Size in bytes Horizontal Res Vertical Flag then bayer order eg // 0x16 bbgr 0x94 rggb - { 1540857, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "Samsung", "S3" }, - { 2658304, 1212, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontMipi" }, - { 2842624, 1296, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontQCOM" }, - { 2969600, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" }, - { 3170304, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" }, - { 3763584, 1584, 1184, 0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" }, - { 5107712, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" }, - { 5382640, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" }, - { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, - { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, - { 5364240, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, - { 6299648, 2592, 1944, 0, 0, 0, 0, 1, 0x16, 0, 0, "OmniVisi", "OV5648" }, - { 6721536, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "OmniVisi", "OV56482" }, - { 6746112, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "OneSV" }, - { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" }, - { 9830400, 2560, 1920, 0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" }, - { 10186752, 3264, 2448, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" }, - { 10223360, 2608, 1944, 0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" }, - { 10782464, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" }, - { 10788864, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "Xperia", "L" }, - { 15967488, 3264, 2446, 0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" }, - { 16224256, 4208, 3082, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3MipiL" }, - { 16424960, 4208, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "IMX135", "MipiL" }, - { 17326080, 4164, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3LQCom" }, - { 17522688, 4212, 3120, 0, 0, 0, 0, 0, 0x16, 0, 0, "Sony", "IMX135-QCOM" }, - { 19906560, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7mipi" }, - { 19976192, 5312, 2988, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G4" }, - { 20389888, 4632, 3480, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" }, - { 20500480, 4656, 3496, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" }, - { 21233664, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7qcom" }, - { 26023936, 4192, 3104, 0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" }, - { 26257920, 4208, 3120, 0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" }, - { 26357760, 4224, 3120, 0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" }, - { 41312256, 5248, 3936, 0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" }, - { 42923008, 5344, 4016, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" }, + { 1540857, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "Samsung", "S3" }, + { 2658304, 1212, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontMipi" }, + { 2842624, 1296, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontQCOM" }, + { 2969600, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" }, + { 3170304, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" }, + { 3763584, 1584, 1184, 0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" }, + { 5107712, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" }, + { 5382640, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" }, + { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 5364240, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" }, + { 6299648, 2592, 1944, 0, 0, 0, 0, 1, 0x16, 0, 0, "OmniVisi", "OV5648" }, + { 6721536, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "OmniVisi", "OV56482" }, + { 6746112, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "OneSV" }, + { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" }, + { 9830400, 2560, 1920, 0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" }, + { 10186752, 3264, 2448, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" }, + { 10223360, 2608, 1944, 0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" }, + { 10782464, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" }, + { 10788864, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "Xperia", "L" }, + { 15967488, 3264, 2446, 0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" }, + { 16224256, 4208, 3082, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3MipiL" }, + { 16424960, 4208, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "IMX135", "MipiL" }, + { 17326080, 4164, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3LQCom" }, + { 17522688, 4212, 3120, 0, 0, 0, 0, 0, 0x16, 0, 0, "Sony", "IMX135-QCOM" }, + { 19906560, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7mipi" }, + { 19976192, 5312, 2988, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G4" }, + { 20389888, 4632, 3480, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" }, + { 20500480, 4656, 3496, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" }, + { 21233664, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7qcom" }, + { 26023936, 4192, 3104, 0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" }, + { 26257920, 4208, 3120, 0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" }, + { 26357760, 4224, 3120, 0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" }, + { 41312256, 5248, 3936, 0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" }, + { 42923008, 5344, 4016, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" }, // Android Raw dumps id end - { 20137344, 3664, 2748, 0, 0, 0, 0, 0x40, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff }, - { 2868726, 1384, 1036, 0, 0, 0, 0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 }, - { 6553440, 2664, 1968, 4, 4, 44, 4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack - { 9243240, 3152, 2346, 12, 7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack - { 6653280, 2672, 1992, 10, 6, 42, 2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack - { 6573120, 2672, 1968, 12, 8, 44, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack - { 9219600, 3152, 2340, 36, 12, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack - { 10383120, 3344, 2484, 12, 6, 44, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack - { 12945240, 3736, 2772, 12, 6, 52, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack - { 15636240, 4104, 3048, 48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack - { 10341600, 3336, 2480, 6, 5, 32, 3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack - { 24724224, 4704, 3504, 8, 16, 56, 8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack - { 18763488, 4104, 3048, 10, 22, 82, 22, 8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ? - { 19493760, 4160, 3124, 104, 12, 8, 66, 40, 0x49, 0, 2, "Canon", "PowerShot S100" }, // chdk hack CRW - { 7710960, 2888, 2136, 44, 8, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack - { 5298000, 2400, 1766, 12, 12, 44, 2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack - { 18653760, 4080, 3048, 24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack - { 21936096, 4464, 3276, 25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack - { 19167840, 4176, 3060, 96, 16, 8, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2 - { 15467760, 3720, 2772, 6, 12, 30, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack - { 15534576, 3728, 2778, 12, 9, 44, 9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack - { 19131120, 4168, 3060, 92, 16, 4, 1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack - { 31663200, 5344, 3950, 96, 18, 0, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack - { 30858240, 5248, 3920, 8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack - { 1976352, 1632, 1211, 0, 2, 0, 1, 0, 0x94, 0, 1, "Casio", "QV-2000UX" }, - { 3217760, 2080, 1547, 0, 0, 10, 1, 0, 0x94, 0, 1, "Casio", "QV-3*00EX" }, - { 6218368, 2585, 1924, 0, 0, 9, 0, 0, 0x94, 0, 1, "Casio", "QV-5700" }, - { 7816704, 2867, 2181, 0, 0, 34, 36, 0, 0x16, 0, 1, "Casio", "EX-Z60" }, - { 2937856, 1621, 1208, 0, 0, 1, 0, 0, 0x94, 7, 13, "Casio", "EX-S20" }, - { 4948608, 2090, 1578, 0, 0, 32, 34, 0, 0x94, 7, 1, "Casio", "EX-S100" }, - { 6054400, 2346, 1720, 2, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "QV-R41" }, - { 7426656, 2568, 1928, 0, 0, 0, 0, 0, 0x94, 0, 1, "Casio", "EX-P505" }, - { 7530816, 2602, 1929, 0, 0, 22, 0, 0, 0x94, 7, 1, "Casio", "QV-R51" }, - { 7542528, 2602, 1932, 0, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "EX-Z50" }, - { 7562048, 2602, 1937, 0, 0, 25, 0, 0, 0x16, 7, 1, "Casio", "EX-Z500" }, - { 7753344, 2602, 1986, 0, 0, 32, 26, 0, 0x94, 7, 1, "Casio", "EX-Z55" }, - { 9313536, 2858, 2172, 0, 0, 14, 30, 0, 0x94, 7, 1, "Casio", "EX-P600" }, - { 10834368, 3114, 2319, 0, 0, 27, 0, 0, 0x94, 0, 1, "Casio", "EX-Z750" }, - { 10843712, 3114, 2321, 0, 0, 25, 0, 0, 0x94, 0, 1, "Casio", "EX-Z75" }, - { 10979200, 3114, 2350, 0, 0, 32, 32, 0, 0x94, 7, 1, "Casio", "EX-P700" }, - { 12310144, 3285, 2498, 0, 0, 6, 30, 0, 0x94, 0, 1, "Casio", "EX-Z850" }, - { 12489984, 3328, 2502, 0, 0, 47, 35, 0, 0x94, 0, 1, "Casio", "EX-Z8" }, - { 15499264, 3754, 2752, 0, 0, 82, 0, 0, 0x94, 0, 1, "Casio", "EX-Z1050" }, - { 18702336, 4096, 3044, 0, 0, 24, 0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" }, - { 7684000, 2260, 1700, 0, 0, 0, 0, 13, 0x94, 0, 1, "Casio", "QV-4000" }, - { 787456, 1024, 769, 0, 1, 0, 0, 0, 0x49, 0, 0, "Creative", "PC-CAM 600" }, - { 28829184, 4384, 3288, 0, 0, 0, 0, 36, 0x61, 0, 0, "DJI" }, - { 15151104, 4608, 3288, 0, 0, 0, 0, 0, 0x94, 0, 0, "Matrix" }, - { 3840000, 1600, 1200, 0, 0, 0, 0, 65, 0x49, 0, 0, "Foculus", "531C" }, - { 307200, 640, 480, 0, 0, 0, 0, 0, 0x94, 0, 0, "Generic" }, - { 62464, 256, 244, 1, 1, 6, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, - { 124928, 512, 244, 1, 1, 10, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, - { 1652736, 1536, 1076, 0, 52, 0, 0, 0, 0x61, 0, 0, "Kodak", "DCS200" }, - { 4159302, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330" }, - { 4162462, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330", 3160 }, - { 2247168, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, - { 3370752, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, - { 6163328, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603" }, - { 6166488, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603", 3160 }, - { 460800, 640, 480, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, - { 9116448, 2848, 2134, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, - { 12241200, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP" }, - { 12272756, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP", 31556 }, - { 18000000, 4000, 3000, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "12MP" }, - { 614400, 640, 480, 0, 3, 0, 0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" }, - { 15360000, 3200, 2400, 0, 0, 0, 0, 96, 0x16, 0, 0, "Lenovo", "A820" }, - { 3884928, 1608, 1207, 0, 0, 0, 0, 96, 0x16, 0, 0, "Micron", "2010", 3212 }, - { 1138688, 1534, 986, 0, 0, 0, 0, 0, 0x61, 0, 0, "Minolta", "RD175", 513 }, - { 1581060, 1305, 969, 0, 0, 18, 6, 6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack - { 2465792, 1638, 1204, 0, 0, 22, 1, 6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775; + { 20137344, 3664, 2748, 0, 0, 0, 0, 64, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff }, + { 2868726, 1384, 1036, 0, 0, 0, 0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 }, + { 6553440, 2664, 1968, 4, 4, 44, 4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack + { 9243240, 3152, 2346, 12, 7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack + { 6653280, 2672, 1992, 10, 6, 42, 2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack + { 6573120, 2672, 1968, 12, 8, 44, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack + { 9219600, 3152, 2340, 36, 12, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack + { 10383120, 3344, 2484, 12, 6, 44, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack + { 12945240, 3736, 2772, 12, 6, 52, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack + { 15636240, 4104, 3048, 48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack + { 10341600, 3336, 2480, 6, 5, 32, 3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack + { 24724224, 4704, 3504, 8, 16, 56, 8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack + { 18763488, 4104, 3048, 10, 22, 82, 22, 8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ? + { 19493760, 4160, 3124, 104, 12, 8, 66, 40, 0x49, 0, 2, "Canon", "PowerShot S100" }, // chdk hack CRW + { 7710960, 2888, 2136, 44, 8, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack + { 5298000, 2400, 1766, 12, 12, 44, 2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack + { 18653760, 4080, 3048, 24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack + { 21936096, 4464, 3276, 25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack + { 19167840, 4176, 3060, 96, 16, 8, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2 + { 15467760, 3720, 2772, 6, 12, 30, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack + { 15534576, 3728, 2778, 12, 9, 44, 9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack + { 19131120, 4168, 3060, 92, 16, 4, 1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack + { 31663200, 5344, 3950, 96, 18, 0, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack + { 30858240, 5248, 3920, 8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack + { 1976352, 1632, 1211, 0, 2, 0, 1, 0, 0x94, 0, 1, "Casio", "QV-2000UX" }, + { 3217760, 2080, 1547, 0, 0, 10, 1, 0, 0x94, 0, 1, "Casio", "QV-3*00EX" }, + { 6218368, 2585, 1924, 0, 0, 9, 0, 0, 0x94, 0, 1, "Casio", "QV-5700" }, + { 7816704, 2867, 2181, 0, 0, 34, 36, 0, 0x16, 0, 1, "Casio", "EX-Z60" }, + { 2937856, 1621, 1208, 0, 0, 1, 0, 0, 0x94, 7, 13, "Casio", "EX-S20" }, + { 4948608, 2090, 1578, 0, 0, 32, 34, 0, 0x94, 7, 1, "Casio", "EX-S100" }, + { 6054400, 2346, 1720, 2, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "QV-R41" }, + { 7426656, 2568, 1928, 0, 0, 0, 0, 0, 0x94, 0, 1, "Casio", "EX-P505" }, + { 7530816, 2602, 1929, 0, 0, 22, 0, 0, 0x94, 7, 1, "Casio", "QV-R51" }, + { 7542528, 2602, 1932, 0, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "EX-Z50" }, + { 7562048, 2602, 1937, 0, 0, 25, 0, 0, 0x16, 7, 1, "Casio", "EX-Z500" }, + { 7753344, 2602, 1986, 0, 0, 32, 26, 0, 0x94, 7, 1, "Casio", "EX-Z55" }, + { 9313536, 2858, 2172, 0, 0, 14, 30, 0, 0x94, 7, 1, "Casio", "EX-P600" }, + { 10834368, 3114, 2319, 0, 0, 27, 0, 0, 0x94, 0, 1, "Casio", "EX-Z750" }, + { 10843712, 3114, 2321, 0, 0, 25, 0, 0, 0x94, 0, 1, "Casio", "EX-Z75" }, + { 10979200, 3114, 2350, 0, 0, 32, 32, 0, 0x94, 7, 1, "Casio", "EX-P700" }, + { 12310144, 3285, 2498, 0, 0, 6, 30, 0, 0x94, 0, 1, "Casio", "EX-Z850" }, + { 12489984, 3328, 2502, 0, 0, 47, 35, 0, 0x94, 0, 1, "Casio", "EX-Z8" }, + { 15499264, 3754, 2752, 0, 0, 82, 0, 0, 0x94, 0, 1, "Casio", "EX-Z1050" }, + { 18702336, 4096, 3044, 0, 0, 24, 0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" }, + { 7684000, 2260, 1700, 0, 0, 0, 0, 13, 0x94, 0, 1, "Casio", "QV-4000" }, + { 787456, 1024, 769, 0, 1, 0, 0, 0, 0x49, 0, 0, "Creative", "PC-CAM 600" }, + { 28829184, 4384, 3288, 0, 0, 0, 0, 36, 0x61, 0, 0, "DJI" }, + { 15151104, 4608, 3288, 0, 0, 0, 0, 0, 0x94, 0, 0, "Matrix" }, + { 3840000, 1600, 1200, 0, 0, 0, 0, 65, 0x49, 0, 0, "Foculus", "531C" }, + { 307200, 640, 480, 0, 0, 0, 0, 0, 0x94, 0, 0, "Generic" }, + { 62464, 256, 244, 1, 1, 6, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, + { 124928, 512, 244, 1, 1, 10, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" }, + { 1652736, 1536, 1076, 0, 52, 0, 0, 0, 0x61, 0, 0, "Kodak", "DCS200" }, + { 4159302, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330" }, + { 4162462, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330", 3160 }, + { 2247168, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, + { 3370752, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" }, + { 6163328, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603" }, + { 6166488, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603", 3160 }, + { 460800, 640, 480, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, + { 9116448, 2848, 2134, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" }, + { 12241200, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP" }, + { 12272756, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP", 31556 }, + { 18000000, 4000, 3000, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "12MP" }, + { 614400, 640, 480, 0, 3, 0, 0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" }, + { 15360000, 3200, 2400, 0, 0, 0, 0, 96, 0x16, 0, 0, "Lenovo", "A820" }, + { 3884928, 1608, 1207, 0, 0, 0, 0, 96, 0x16, 0, 0, "Micron", "2010", 3212 }, + { 1138688, 1534, 986, 0, 0, 0, 0, 0, 0x61, 0, 0, "Minolta", "RD175", 513 }, + { 1581060, 1305, 969, 0, 0, 18, 6, 6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack + { 2465792, 1638, 1204, 0, 0, 22, 1, 6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775; // Olympus C-2020Z - { 2940928, 1616, 1213, 0, 0, 0, 7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500 - { 4771840, 2064, 1541, 0, 0, 0, 1, 6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995; + { 2940928, 1616, 1213, 0, 0, 0, 7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500 + { 4771840, 2064, 1541, 0, 0, 0, 1, 6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995; // Olympus C-3030Z - { 4775936, 2064, 1542, 0, 0, 0, 0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500; + { 4775936, 2064, 1542, 0, 0, 0, 0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500; // Pentax "Optio 33WR"; possibly also Olympus C-740UZ - { 5865472, 2288, 1709, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z - { 5869568, 2288, 1710, 0, 0, 0, 0, 6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2" - { 7438336, 2576, 1925, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700 - { 8998912, 2832, 2118, 0, 0, 0, 0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack - { 5939200, 2304, 1718, 0, 0, 0, 0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ - { 3178560, 2064, 1540, 0, 0, 0, 0, 0, 0x94, 0, 1, "Pentax", "Optio S V1.01" }, - { 4841984, 2090, 1544, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S" }, - { 6114240, 2346, 1737, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S4" }, - { 10702848, 3072, 2322, 0, 0, 0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" }, - { 4147200, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD" }, - { 4151666, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD", 8 }, - { 13248000, 2208, 3000, 0, 0, 0, 0, 13, 0x61, 0, 0, "Pixelink", "A782" }, - { 6291456, 2048, 1536, 0, 0, 0, 0, 96, 0x61, 0, 0, "RoverShot", "3320AF" }, - { 311696, 644, 484, 0, 0, 0, 0, 0, 0x16, 0, 8, "ST Micro", "STV680 VGA" }, - { 16098048, 3288, 2448, 0, 0, 24, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack - { 16215552, 3312, 2448, 0, 0, 48, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack - { 20487168, 3648, 2808, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, - { 24000000, 4000, 3000, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, - { 12582980, 3072, 2048, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare - { 33292868, 4080, 4080, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44 - { 44390468, 4080, 5440, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54 - { 1409024, 1376, 1024, 0, 0, 1, 0, 0, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, - { 2818048, 1376, 1024, 0, 0, 1, 0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, + { 5865472, 2288, 1709, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z + { 5869568, 2288, 1710, 0, 0, 0, 0, 6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2" + { 7438336, 2576, 1925, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700 + { 8998912, 2832, 2118, 0, 0, 0, 0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack + { 5939200, 2304, 1718, 0, 0, 0, 0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ + { 3178560, 2064, 1540, 0, 0, 0, 0, 0, 0x94, 0, 1, "Pentax", "Optio S V1.01" }, + { 4841984, 2090, 1544, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S" }, + { 6114240, 2346, 1737, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S4" }, + { 10702848, 3072, 2322, 0, 0, 0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" }, + { 4147200, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD" }, + { 4151666, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD", 8 }, + { 13248000, 2208, 3000, 0, 0, 0, 0, 13, 0x61, 0, 0, "Pixelink", "A782" }, + { 6291456, 2048, 1536, 0, 0, 0, 0, 96, 0x61, 0, 0, "RoverShot", "3320AF" }, + { 311696, 644, 484, 0, 0, 0, 0, 0, 0x16, 0, 8, "ST Micro", "STV680 VGA" }, + { 16098048, 3288, 2448, 0, 0, 24, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack + { 16215552, 3312, 2448, 0, 0, 48, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack + { 20487168, 3648, 2808, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, + { 24000000, 4000, 3000, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" }, + { 12582980, 3072, 2048, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare + { 33292868, 4080, 4080, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44 + { 44390468, 4080, 5440, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54 + { 1409024, 1376, 1024, 0, 0, 1, 0, 0, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, + { 2818048, 1376, 1024, 0, 0, 1, 0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" }, }; libraw_custom_camera_t @@ -638,50 +595,6 @@ void LibRaw::identify() mask[0][3] = 1; filters = 0x61616161; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - 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); - model[63] = 0; - fseek(ifp, 760, SEEK_SET); - fread(software, 1, 64, ifp); - if((unsigned char)software[0] == 0xff) software[0] = 0; - software[63] = 0; - data_offset = 4096; - load_raw = &LibRaw::packed_load_raw; - load_flags = 88; - filters = 0x61616161; - fixupArri(); - } - else if (!memcmp(head, "XPDS", 4)) - { - order = 0x4949; - fseek(ifp, 0x800, SEEK_SET); - fread(make, 1, 41, ifp); - raw_height = get2(); - raw_width = get2(); - fseek(ifp, 56, SEEK_CUR); - fread(model, 1, 30, ifp); - data_offset = 0x10000; - load_raw = &LibRaw::canon_rmf_load_raw; - gamma_curve(0, 12.25, 1, 1023); - } - else if (!memcmp(head + 4, "RED1", 4)) - { - strcpy(make, "Red"); - strcpy(model, "One"); - parse_redcine(); - load_raw = &LibRaw::redcine_load_raw; - gamma_curve(1 / 2.4, 12.92, 1, 4095); - filters = 0x49494949; - } -#endif else if (!memcmp(head, "DSC-Image", 9)) parse_rollei(); else if (!memcmp(head, "PWAD", 4)) @@ -1008,6 +921,11 @@ void LibRaw::identify() case 9: load_raw = &LibRaw::vc5_dng_load_raw_placeholder; break; +#endif +#ifdef USE_DNGSDK + case 52546: + load_raw = &LibRaw::jxl_dng_load_raw_placeholder; + break; #endif case 34892: load_raw = &LibRaw::lossy_dng_load_raw; @@ -1250,15 +1168,6 @@ dng_skip: if (dng_version && (tiff_samples < 1 || tiff_samples > 4)) is_raw = 0; // we do not handle DNGs with more than 4 values per pixel -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -#ifdef NO_JASPER - if (load_raw == &LibRaw::redcine_load_raw) - { - is_raw = 0; - imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER; - } -#endif -#endif #ifdef NO_JPEG if (load_raw == &LibRaw::kodak_jpeg_load_raw || load_raw == &LibRaw::lossy_dng_load_raw) @@ -2342,11 +2251,59 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) case 4992: // X-E2S, X-E2, X-T10, X-T1, X100S, X100T, X70 left_margin = 4; break; + case 7872: // X-H2, full image + switch (FujiCropMode) + { + case 0: // no crop + top_margin = 6; + left_margin = 0; + width = 7752; + height = 5178; + break; + default: + /* try to guess from crop inset*/ + if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width && + imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height) + { + top_margin = imgdata.sizes.raw_inset_crops[0].ctop; + left_margin = imgdata.sizes.raw_inset_crops[0].cleft; + width = imgdata.sizes.raw_inset_crops[0].cwidth; + height = imgdata.sizes.raw_inset_crops[0].cheight; + } + break; + } + break; case 6336: // X-H2S - top_margin = 6; - left_margin = 0; - width = 6264; - height = 4176; + switch (FujiCropMode) + { + case 0: // no crop + top_margin = 6; + left_margin = 0; + if(!strcasecmp(model,"X-S20")) + width = 6252; + else + width = 6264; + height = 4176; + break; + case 2: /* sports finder*/ + case 4: /* Electronic shutter crop */ + left_margin = 630; + top_margin = 0; + height = 3348; + width = 5004; + break; + default: + /* try to guess from crop inset*/ + if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width + && imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height) + { + top_margin = imgdata.sizes.raw_inset_crops[0].ctop; + left_margin = imgdata.sizes.raw_inset_crops[0].cleft; + width = imgdata.sizes.raw_inset_crops[0].cwidth; + height = imgdata.sizes.raw_inset_crops[0].cheight; + } + break; + } break; case 6384: // X-T3, X-T4, X100V, X-S10, X-T30, X-Pro3 top_margin = 0; @@ -2363,7 +2320,7 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) height = raw_height; break; case 4: // electronic shutter, high speed mode (1.25x crop) - left_margin = 624; + left_margin = 624; width = 5004; break; } @@ -2382,7 +2339,8 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) case 11808: // GFX 100; no crop left_margin = 0; width = raw_width - 146; - height = raw_height - (top_margin = 2); + height = raw_height - 8; + top_margin = 2; if (tiff_bps == 16) maximum = 0xffff; default: @@ -2429,7 +2387,17 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) flip = 6; break; default: - /* insert model name-based width/height/margins/etc. assignments */ + /* insert model name-based width/height/margins/etc. assignments */ + + /* raw_inset_crops default*/ + if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width && + imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height) + { + top_margin = imgdata.sizes.raw_inset_crops[0].ctop; + left_margin = imgdata.sizes.raw_inset_crops[0].cleft; + width = imgdata.sizes.raw_inset_crops[0].cwidth; + height = imgdata.sizes.raw_inset_crops[0].cheight; + } break; } } @@ -2690,6 +2658,13 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) top_margin = 108; height = raw_height - top_margin; } + else if ((imHassy.SensorCode == 20) && imHassy.uncropped) + { // Hasselblad X2D-100c + left_margin = 124; + width = 11664; + top_margin = 92; + height = raw_height - top_margin; + } if (tiff_samples > 1) { @@ -2855,7 +2830,40 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) load_raw = &LibRaw::sony_load_raw; } - else if (raw_width == 3984) { // Sony DSC-R1; + else if ((unique_id == SonyID_ILCE_7RM5) || (unique_id == SonyID_ILCE_7CR)) + { + if (raw_width == 6304) + { + /* nothing: APS-C Uncompressed, handled in open_datastream*/ + } + else if (raw_width == 6656) /* 7RM5 Lossy compressed, medium */ + { + width = 6272; + height = 4180; + } + else if (raw_width == 9728) // FF, Lossless compresssed + { + width = 9566; + height = 6374; + } + else if (raw_width == 5120) // APS-C??/Lossy-Small? + { + width = 4776; + height = 3180; + } + else if (raw_width == 9600) + { + width = raw_width - 36; + } + else + { + width = raw_width - 32; // fallback + imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED; + + } + } + else if (raw_width == 3984) + { // Sony DSC-R1; width = 3925; order = 0x4d4d; @@ -2870,7 +2878,7 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) } else if (raw_width == 4928) { - // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, SLT-A55, + // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, DSC-HX95, SLT-A55, // NEX-5N, SLT-A37, SLT-A57, NEX-F3, NEX-6, NEX-5R, NEX-3N, NEX-5T; if (height < 3280) width -= 8; @@ -2904,10 +2912,18 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) width -= 32; } - else if (raw_width == 9600) { // Sony ILCE-7RM4 + else if (raw_width == 9600) { // Sony ILCE-7RM4 && 7RM5 width -= 32; } + else if (unique_id == SonyID_ZV_E1) + { + if (raw_width == 4608 && raw_height == 3072) // SonyID_ZV_E1 + { + width = 4256; + height = 2846; + } + } else if(unique_id == SonyID_ILCE_1) { if (raw_width == 8704 && raw_height == 6144) // ILCE-1 FF@Compressed @@ -2928,20 +2944,62 @@ void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen) { width -= 28; } + else if (raw_width == 5632) // Lossy/Medium + { + width -= 4; + height = 3756; + } + else if (raw_width == 4608) // Lossy/small + { + width = 4332; + height = 2892; + } + else + imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED; + + /* need samples for lossy small/medium w/ APC crop*/ } - else if (unique_id == SonyID_ILCE_7M4) + else if ((unique_id == SonyID_ILCE_7M4)|| (unique_id == SonyID_ILCE_7CM2)) { - if (raw_width == 7168 && raw_height == 5120) // ILCE-1 FF@Compressed + if (raw_width == 7168 && raw_height == 5120) { width = 7028; height = 4688; } + else if (raw_width == 5120) // Lossy/Medium + { + width = 4624; + height = 3080; + } + else if (raw_width == 3584) // Lossy/Small + { + width = 3516; + height = 2344; + } else if (raw_width == 7040) // FF uncompressed/lossy { width -= 12; } + else + imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED; /* FIXME: need APS-C samples, both losslesscompressed and uncompressed or lossy */ } + else if (unique_id == SonyID_ILCE_6700) + { + if (raw_width == 6656) + { + width = 6272; + height = 4168; + } + else if (raw_width == 6272) // APS-C uncompressed + { + width = raw_width - 32; + } + else // fallback + { + width = raw_width - 32; + } + } else if (!strcmp(model, "DSLR-A100")) { if (width == 3880) { diff --git a/src/metadata/identify_tools.cpp b/src/metadata/identify_tools.cpp index 28a1d69c8..caf1cddf0 100644 --- a/src/metadata/identify_tools.cpp +++ b/src/metadata/identify_tools.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/kodak.cpp b/src/metadata/kodak.cpp index 1193eac32..2c4419778 100644 --- a/src/metadata/kodak.cpp +++ b/src/metadata/kodak.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/metadata/leica.cpp b/src/metadata/leica.cpp index cda4b0c63..182537485 100644 --- a/src/metadata/leica.cpp +++ b/src/metadata/leica.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -48,7 +48,7 @@ void LibRaw::setLeicaBodyFeatures(int LeicaMakernoteSignature) ilm.FocalType = LIBRAW_FT_ZOOM_LENS; } else if ((LeicaMakernoteSignature == - 0x0200) || // M10, M10-D, M10-R, "S (Typ 007)", M11 + 0x0200) || // M10, M10-D, M10-R, "S (Typ 007)", M11, "M11 Monochrom" (LeicaMakernoteSignature == 0x02ff) || // "M (Typ 240)", "M (Typ 262)", "M-D (Typ 262)", // "M Monochrom (Typ 246)", "S (Typ 006)", "S-E (Typ 006)", S2, S3 @@ -68,6 +68,7 @@ void LibRaw::setLeicaBodyFeatures(int LeicaMakernoteSignature) } else if ((LeicaMakernoteSignature == 0x0600) || // "T (Typ 701)", TL (LeicaMakernoteSignature == 0x0900) || // SL2, "SL2-S", "SL (Typ 601)", CL, Q2, "Q2 MONO" + (LeicaMakernoteSignature == 0x0a00) || // Q3 (LeicaMakernoteSignature == 0x1a00)) // TL2 { if ((model[0] == 'S') || (model[6] == 'S')) @@ -82,7 +83,8 @@ void LibRaw::setLeicaBodyFeatures(int LeicaMakernoteSignature) ilm.CameraMount = LIBRAW_MOUNT_LPS_L; } else if (((model[0] == 'Q') || (model[6] == 'Q')) && - ((model[1] == '2') || (model[7] == '2'))) + (((model[1] == '2') || (model[7] == '2')) || + ((model[1] == '3') || (model[7] == '3')))) { ilm.CameraFormat = ilm.LensFormat = LIBRAW_FORMAT_FF; ilm.CameraMount = ilm.LensMount = LIBRAW_MOUNT_FixedLens; @@ -206,6 +208,7 @@ void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) (LeicaMakernoteSignature != 0x0200) && (LeicaMakernoteSignature != 0x0800) && (LeicaMakernoteSignature != 0x0900) && + (LeicaMakernoteSignature != 0x0a00) && (LeicaMakernoteSignature != 0x02ff)) base = ftell(ifp) - 8; } @@ -297,7 +300,7 @@ void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) parseLeicaLensName(len); } } - else if (LeicaMakernoteSignature == 0x0200) // M10, M10-D, M10-R, "S (Typ 007)", M11 + else if (LeicaMakernoteSignature == 0x0200) // M10, M10-D, M10-R, "S (Typ 007)", M11, "M11 Monochrom" { if ((tag == 0x035a) && (fabs(ilm.CurAp) < 0.17f)) { @@ -331,8 +334,10 @@ void LibRaw::parseLeicaMakernote(int base, int uptag, unsigned MakernoteTagType) } } else if ((LeicaMakernoteSignature == 0x0800) || // "Q (Typ 116)" - (LeicaMakernoteSignature == 0x0900)) // SL2, "SL2-S", "SL (Typ 601)", + (LeicaMakernoteSignature == 0x0900) || // SL2, "SL2-S", "SL (Typ 601)", // CL, Q2, "Q2 MONO" + (LeicaMakernoteSignature == 0x0a00) // Q3 + ) { if ((tag == 0x0304) && (len == 1) && ((c = fgetc(ifp)) != 0) && (ilm.CameraMount == LIBRAW_MOUNT_LPS_L)) diff --git a/src/metadata/makernotes.cpp b/src/metadata/makernotes.cpp index b8ed4d3c7..728acd7d5 100644 --- a/src/metadata/makernotes.cpp +++ b/src/metadata/makernotes.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/mediumformat.cpp b/src/metadata/mediumformat.cpp index 6bb8705d9..c3d3dbeca 100644 --- a/src/metadata/mediumformat.cpp +++ b/src/metadata/mediumformat.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/minolta.cpp b/src/metadata/minolta.cpp index c8224332c..aa40a9b03 100644 --- a/src/metadata/minolta.cpp +++ b/src/metadata/minolta.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/metadata/misc_parsers.cpp b/src/metadata/misc_parsers.cpp index 7d6e2f447..1aea57e6f 100644 --- a/src/metadata/misc_parsers.cpp +++ b/src/metadata/misc_parsers.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -92,40 +92,6 @@ int LibRaw::canon_s2is() return 0; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -void LibRaw::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) - { - fseek(ifp, 0, SEEK_SET); - while ((len = get4()) != (unsigned)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(); - } -} -#endif - void LibRaw::parse_cine() { unsigned off_head, off_setup, off_image, i, temp; diff --git a/src/metadata/nikon.cpp b/src/metadata/nikon.cpp index c0c90f81c..f0fb655d9 100644 --- a/src/metadata/nikon.cpp +++ b/src/metadata/nikon.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -128,7 +128,7 @@ void LibRaw::processNikonLensData(uchar *LensData, unsigned len) i = 8; break; case 58: // "Z 6", "Z 6 II", "Z 7", "Z 7 II", "Z 50", D780, "Z 5", "Z fc" - case 108: // "Z 9" + case 108: // "Z 9", "Z 30", "Z 8" if (model[6] == 'Z') ilm.CameraMount = LIBRAW_MOUNT_Nikon_Z; if (imNikon.HighSpeedCropFormat != 12) @@ -144,6 +144,8 @@ void LibRaw::processNikonLensData(uchar *LensData, unsigned len) (ilm.LensID == 11) || (ilm.LensID == 12) || (ilm.LensID == 26) + || (ilm.LensID == 41) + || (ilm.LensID == 43) ) ilm.LensFormat = LIBRAW_FORMAT_APSC; else ilm.LensFormat = LIBRAW_FORMAT_FF; if (ilm.MaxAp4CurFocal < 0.7f) @@ -519,6 +521,9 @@ uchar *cj_block, *ck_block; case 2: imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB; break; + case 4: + imCommon.ColorSpace = LIBRAW_COLORSPACE_Rec2020; + break; default: imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown; break; @@ -535,6 +540,22 @@ uchar *cj_block, *ck_block; { imNikon.Active_D_Lighting = get2(); } + else if (tag == 0x0023) + { + FORC4 imNikon.PictureControlVersion = + imNikon.PictureControlVersion * 10 + fgetc(ifp) - '0'; + if ((imNikon.PictureControlVersion >= 300) && + (imNikon.PictureControlVersion <= 399)) + { + fseek(ifp, 4, SEEK_CUR); + } + stmread (imNikon.PictureControlName, 20, ifp); + stmread (imNikon.PictureControlBase, 20, ifp); + if (!strncmp(imNikon.PictureControlBase, "STANDARD(HLG)", 13)) + { + imCommon.ExposureCalibrationShift -= 2; + } + } else if (tag == 0x003b) { // WB for multi-exposure (ME); all 1s for regular exposures imNikon.ME_WB[0] = getreal(type); @@ -849,17 +870,19 @@ free(ck_block); OrientationOffset = sget4_order(morder, ShotInfo_buf+0x9c); break; - case 800: // Z 6, Z 7, ShotInfoZ7II, Roll/Pitch/Yaw - case 801: // Z 50, ShotInfoZ7II, Roll/Pitch/Yaw - case 802: // Z 5, ShotInfoZ7II, Roll/Pitch/Yaw - case 803: // Z 6_2, Z 7_2, ShotInfoZ7II, Roll/Pitch/Yaw - case 804: // Z fc ShotInfoZ7II, Roll/Pitch/Yaw + case 800: // "Z 6", "Z 7", ShotInfoZ7II, Roll/Pitch/Yaw + case 801: // "Z 50", ShotInfoZ7II, Roll/Pitch/Yaw + case 802: // "Z 5", ShotInfoZ7II, Roll/Pitch/Yaw + case 803: // "Z 6_2", "Z 7_2", ShotInfoZ7II, Roll/Pitch/Yaw + case 804: // "Z fc" ShotInfoZ7II, Roll/Pitch/Yaw OrientationOffset = sget4_order(morder, ShotInfo_buf+0x98); break; - case 805: // Z 9, ShotInfoZ9, Roll/Pitch/Yaw + case 805: // "Z 9", ShotInfoZ9, Roll/Pitch/Yaw OrientationOffset = sget4_order(morder, ShotInfo_buf+0x84); break; + case 807: // "Z 30" + break; } if (OrientationOffset && ((OrientationOffset+12) 6) && strncmp(imgdata.color.UniqueCameraModel+6, "PowerShot", 9)) { - for (i = 0; i < int(sizeof unique / sizeof *unique); i++) - { - if (!strcmp(unique[i].t_model, imgdata.color.UniqueCameraModel+6)) + if (!strcmp(model, "EOS Ra")) { + ilm.CamID = unique_id = CanonID_EOS_R; + strcpy(normalized_model, model); + // try_xml = 1; // ?? + } else { + for (i = 0; i < int(sizeof unique / sizeof *unique); i++) { - ilm.CamID = unique_id = unique[i].id; - strcpy(normalized_model, unique[i].t_model); - try_xml = 1; - break; + if (!strcmp(unique[i].t_model, imgdata.color.UniqueCameraModel+6)) + { + ilm.CamID = unique_id = unique[i].id; + strcpy(normalized_model, unique[i].t_model); + try_xml = 1; + break; + } } } } @@ -1017,6 +1044,35 @@ void LibRaw::GetNormalizedModel() } } +/* +char pgroup9050 = '-'; +char cameratype[16] = "unknown"; +switch (imSony.CameraType) { + case LIBRAW_SONY_DSC: strcpy(cameratype, "DSC"); break; + case LIBRAW_SONY_DSLR: strcpy(cameratype, "DSLR"); break; + case LIBRAW_SONY_NEX: strcpy(cameratype, "NEX"); break; + case LIBRAW_SONY_SLT: strcpy(cameratype, "SLT"); break; + case LIBRAW_SONY_ILCE: strcpy(cameratype, "ILCE"); break; + case LIBRAW_SONY_ILCA: strcpy(cameratype, "ILCA"); break; +} +switch (imSony.group9050) { + case LIBRAW_SONY_Tag9050a: + pgroup9050 = 'a'; + break; + case LIBRAW_SONY_Tag9050b: + pgroup9050 = 'b'; + break; + case LIBRAW_SONY_Tag9050c: + pgroup9050 = 'c'; + break; + case LIBRAW_SONY_Tag9050d: + pgroup9050 = 'd'; + break; +} +printf("catchme\t%s\t%s\t%s\t9050%c\t%d\t%d\n", + model, normalized_model, cameratype, pgroup9050, imSony.len_group9050, imSony.FileFormat); +*/ + } else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) { remove_caseSubstr (normalized_model, (char *)"EasyShare"); remove_caseSubstr (normalized_model, (char *)"ZOOM"); @@ -1191,7 +1247,9 @@ void LibRaw::GetNormalizedModel() ilm.CameraMount = LIBRAW_MOUNT_Fuji_GF; } else if (!strncmp(normalized_model, "X-", 2) && - (strncmp(normalized_model, "X-S1", 4) || !strncmp(normalized_model, "X-S10", 5))) + (strncmp(normalized_model, "X-S1", 4) || + !strncmp(normalized_model, "X-S10", 5) || + !strncmp(normalized_model, "X-S20", 5))) { ilm.CameraFormat = LIBRAW_FORMAT_APSC; ilm.CameraMount = LIBRAW_MOUNT_Fuji_X; diff --git a/src/metadata/olympus.cpp b/src/metadata/olympus.cpp index 6c427137b..1a49a66d1 100644 --- a/src/metadata/olympus.cpp +++ b/src/metadata/olympus.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -19,9 +19,10 @@ void LibRaw::setOlympusBodyFeatures(unsigned long long id) { ilm.CamID = id; - if ((id == OlyID_E_1) || - (id == OlyID_E_300) || - ((id & 0x00ffff0000ULL) == 0x0030300000ULL)) + if ((id == OlyID_E_1) || + (id == OlyID_E_300) || + (id == OlyID_AIR_A01) || + ((id & 0xffff000000ULL) == 0x5330000000ULL)) { ilm.CameraFormat = LIBRAW_FORMAT_FT; diff --git a/src/metadata/p1.cpp b/src/metadata/p1.cpp index a3867b8c9..7382e108d 100644 --- a/src/metadata/p1.cpp +++ b/src/metadata/p1.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/src/metadata/pentax.cpp b/src/metadata/pentax.cpp index 705fd84c9..ae238d0aa 100644 --- a/src/metadata/pentax.cpp +++ b/src/metadata/pentax.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/src/metadata/samsung.cpp b/src/metadata/samsung.cpp index 5c595e8ba..26fd58f4d 100644 --- a/src/metadata/samsung.cpp +++ b/src/metadata/samsung.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/src/metadata/sony.cpp b/src/metadata/sony.cpp index ea568b5ff..b63d0495d 100644 --- a/src/metadata/sony.cpp +++ b/src/metadata/sony.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -14,6 +14,7 @@ #include "../../internal/dcraw_defs.h" #include "../../internal/libraw_cameraids.h" +#include "../../internal/libraw_checked_buffer.h" static ushort saneSonyCameraInfo(uchar a, uchar b, uchar c, uchar d, uchar e, uchar f) @@ -295,6 +296,8 @@ void LibRaw::setSonyBodyFeatures(unsigned long long id) LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX0M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, + {SonyID_DSC_HX95, LIBRAW_FORMAT_1div2p3INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_DSC_RX100M7, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_Tag2010i, 0x0320, 0xffff, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7RM4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, @@ -326,8 +329,25 @@ void LibRaw::setSonyBodyFeatures(unsigned long long id) LIBRAW_SONY_Tag2010i, 0x0320, 0x019f, 0x024b, 0x024c, 0x0208}, {SonyID_ILCE_7M4, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILCE_7RM5, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILME_FX30, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ZV_E1, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILCE_6700, LIBRAW_FORMAT_APSC, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ZV_1M2, LIBRAW_FORMAT_1INCH, LIBRAW_MOUNT_FixedLens, LIBRAW_SONY_DSC, LIBRAW_MOUNT_FixedLens, + LIBRAW_SONY_Tag2010i, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + + {SonyID_ILCE_7CR, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, + {SonyID_ILCE_7CM2, LIBRAW_FORMAT_FF, LIBRAW_MOUNT_Sony_E, LIBRAW_SONY_ILCE, LIBRAW_MOUNT_Unknown, + LIBRAW_SONY_Tag2010None, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}, }; ilm.CamID = id; + int isPreProductionFW = 0; + if (!strcmp(model, "MODEL-NAME")) isPreProductionFW = 1; if (id == SonyID_DSC_R1) { @@ -364,8 +384,8 @@ void LibRaw::setSonyBodyFeatures(unsigned long long id) case SonyID_ILCE_7C: case SonyID_ILCE_7M3: case SonyID_ILCE_7RM2: - case SonyID_ILCE_7RM3A: case SonyID_ILCE_7RM3: + case SonyID_ILCE_7RM3A: case SonyID_ILCE_7RM4: case SonyID_ILCE_7RM4A: case SonyID_ILCE_7SM2: @@ -373,23 +393,50 @@ void LibRaw::setSonyBodyFeatures(unsigned long long id) case SonyID_ILCE_9M2: case SonyID_ILCA_99M2: case SonyID_ZV_E10: - imSony.group9050 = LIBRAW_SONY_Tag9050b; - break; - case SonyID_ILCE_7SM3: - case SonyID_ILCE_1: - case SonyID_ILME_FX3: - case SonyID_ILCE_7M4: - imSony.group9050 = LIBRAW_SONY_Tag9050c; - break; - default: - if ((imSony.CameraType != LIBRAW_SONY_DSC) && - (imSony.CameraType != LIBRAW_SONY_DSLR)) + if (!isPreProductionFW) + { + imSony.group9050 = LIBRAW_SONY_Tag9050b; // length: 944 bytes + } + else + { imSony.group9050 = LIBRAW_SONY_Tag9050a; + imSony.ImageCount3_offset = 0xffff; // not valid + } + break; + case SonyID_ILCE_1: + case SonyID_ILCE_7M4: + case SonyID_ILCE_7RM5: + case SonyID_ILCE_7SM3: + case SonyID_ILME_FX3: + if (!isPreProductionFW) + { + imSony.group9050 = LIBRAW_SONY_Tag9050c; // length: 256 bytes + } + else + { + imSony.group9050 = LIBRAW_SONY_Tag9050a; + imSony.ImageCount3_offset = 0xffff; // not valid + } + break; + case SonyID_ZV_E1: + case SonyID_ILCE_6700: + case SonyID_ILCE_7CR: + case SonyID_ILCE_7CM2: + imSony.group9050 = LIBRAW_SONY_Tag9050d; + break; + default: // see also process_Sony_0x9050 + if ( + (imSony.CameraType != LIBRAW_SONY_DSC) && + (imSony.CameraType != LIBRAW_SONY_DSLR) + ) + imSony.group9050 = LIBRAW_SONY_Tag9050a; // length: 3072 or 944 bytes else imSony.group9050 = LIBRAW_SONY_Tag9050None; break; } + if (isPreProductionFW) return; + char *sbstr = strstr(software, " v"); if (sbstr != NULL) { @@ -421,12 +468,6 @@ void LibRaw::setSonyBodyFeatures(unsigned long long id) imSony.ImageCount3_offset = 0x01b6; } } - - if ((id == SonyID_ILCE_7SM3) && - !strcmp(model, "MODEL-NAME")) { - imSony.group9050 = LIBRAW_SONY_Tag9050a; - } - } void LibRaw::parseSonyLensType2(uchar a, uchar b) @@ -575,9 +616,39 @@ void LibRaw::process_Sony_0x0116(uchar *buf, ushort len, unsigned long long id) void LibRaw::process_Sony_0x2010(uchar *buf, ushort len) { - if (imSony.group2010 == LIBRAW_SONY_Tag2010None) return; + ushort ar_offset = 0; + if (imSony.group2010 == LIBRAW_SONY_Tag2010e) { + if (ilm.CamID == SonyID_DSC_RX100) { + ar_offset = 0x1a88; + } else { + ar_offset = 0x192c; + } + } else if (imSony.group2010 == LIBRAW_SONY_Tag2010f) { + ar_offset = 0x192c; + } else if (imSony.group2010 == LIBRAW_SONY_Tag2010g) { + ar_offset = 0x1958; + } else if (imSony.group2010 == LIBRAW_SONY_Tag2010h) { + ar_offset = 0x192c; + } else if (imSony.group2010 == LIBRAW_SONY_Tag2010i) { + ar_offset = 0x188c; + } + if (ar_offset != 0) { + int s = (int)SonySubstitution[buf[ar_offset]]; + if (s == 0) { + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9; + } else if (s == 1) { + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_4to3; + } else if (s == 2) { + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2; + } else if (s == 3) { + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_1to1; + } else { + imSony.AspectRatio = (float)s; + } + } + if ((imSony.real_iso_offset != 0xffff) && (len >= (imSony.real_iso_offset + 2)) && (imCommon.real_ISO < 0.1f)) { @@ -612,10 +683,23 @@ void LibRaw::process_Sony_0x9050(uchar *buf, ushort len, unsigned long long id) uchar s[4]; int c; - if ((imSony.group9050 == LIBRAW_SONY_Tag9050None) && + + if ( + (imSony.group9050 == LIBRAW_SONY_Tag9050None) && (imSony.CameraType != LIBRAW_SONY_DSC) && - (imSony.CameraType != LIBRAW_SONY_DSLR)) + (imSony.CameraType != LIBRAW_SONY_DSLR) + ) { imSony.group9050 = LIBRAW_SONY_Tag9050a; + } + +/* +printf ("==>> Tag9050, len: 0x%04x, type: %s\n", len, + imSony.group9050==LIBRAW_SONY_Tag9050None?"None": + imSony.group9050==LIBRAW_SONY_Tag9050a?"9050a": + imSony.group9050==LIBRAW_SONY_Tag9050b?"9050b": + imSony.group9050==LIBRAW_SONY_Tag9050c?"9050c": + imSony.group9050==LIBRAW_SONY_Tag9050d?"9050d":"---"); +*/ if (imSony.group9050 == LIBRAW_SONY_Tag9050None) return; @@ -639,16 +723,30 @@ void LibRaw::process_Sony_0x9050(uchar *buf, ushort len, unsigned long long id) if ((imSony.group9050 == LIBRAW_SONY_Tag9050b) || (imSony.group9050 == LIBRAW_SONY_Tag9050c)) { - if (len <= 0x8d) return; - unsigned long long b88 = SonySubstitution[buf[0x88]]; - unsigned long long b89 = SonySubstitution[buf[0x89]]; - unsigned long long b8a = SonySubstitution[buf[0x8a]]; - unsigned long long b8b = SonySubstitution[buf[0x8b]]; - unsigned long long b8c = SonySubstitution[buf[0x8c]]; - unsigned long long b8d = SonySubstitution[buf[0x8d]]; + unsigned start_InternalBodySerial = 0x88; + if (id == SonyID_ILCE_1) start_InternalBodySerial += 2; + if (len <= start_InternalBodySerial+5) return; + unsigned long long b88 = SonySubstitution[buf[start_InternalBodySerial]]; + unsigned long long b89 = SonySubstitution[buf[start_InternalBodySerial+1]]; + unsigned long long b8a = SonySubstitution[buf[start_InternalBodySerial+2]]; + unsigned long long b8b = SonySubstitution[buf[start_InternalBodySerial+3]]; + unsigned long long b8c = SonySubstitution[buf[start_InternalBodySerial+4]]; + unsigned long long b8d = SonySubstitution[buf[start_InternalBodySerial+5]]; sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx", (b88 << 40) + (b89 << 32) + (b8a << 24) + (b8b << 16) + (b8c << 8) + b8d); + } else if (imSony.group9050 == LIBRAW_SONY_Tag9050d) { + unsigned start_InternalBodySerial = 0x38; + if (len <= start_InternalBodySerial+5) return; + unsigned long long b38 = SonySubstitution[buf[start_InternalBodySerial]]; + unsigned long long b39 = SonySubstitution[buf[start_InternalBodySerial+1]]; + unsigned long long b4a = SonySubstitution[buf[start_InternalBodySerial+2]]; + unsigned long long b4b = SonySubstitution[buf[start_InternalBodySerial+3]]; + unsigned long long b4c = SonySubstitution[buf[start_InternalBodySerial+4]]; + unsigned long long b4d = SonySubstitution[buf[start_InternalBodySerial+5]]; + sprintf(imgdata.shootinginfo.InternalBodySerial, "%06llx", + (b38 << 40) + (b39 << 32) + (b4a << 24) + (b4b << 16) + (b4c << 8) + b4d); + } else if (imSony.group9050 == LIBRAW_SONY_Tag9050a) { if ((ilm.CameraMount == LIBRAW_MOUNT_Sony_E) && (id != SonyID_NEX_5N) && @@ -780,7 +878,10 @@ void LibRaw::process_Sony_0x9400(uchar *buf, ushort len, unsigned long long /*id (bufx == 0x24) || (bufx == 0x26) || (bufx == 0x28) || - (bufx == 0x31)) && + (bufx == 0x31) || + (bufx == 0x32) || + (bufx == 0x33)) + && (len >= 0x1f)) // 0x9400 'c' version { imSony.Sony0x9400_version = 0xc; @@ -1009,13 +1110,13 @@ void LibRaw::parseSonyMakernotes( uchar *&table_buf_0x940c, ushort &table_buf_0x940c_len, uchar *&table_buf_0x940e, ushort &table_buf_0x940e_len) { - ushort lid, a, c, d; uchar *table_buf; uchar uc; uchar s[2]; int LensDataValid = 0; unsigned uitemp; + ushort u16temp; // printf ("==>> tag 0x%x, len %d, type %d, model =%s=, cam.id 0x%llx, cam.type %d, =%s=\n", // tag, len, type, model, ilm.CamID, imSony.CameraType, imSony.MetaVersion); @@ -1041,6 +1142,7 @@ void LibRaw::parseSonyMakernotes( if (table_buf_0x9050_len) { + imSony.len_group9050 = table_buf_0x9050_len; process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, unique_id); free(table_buf_0x9050); table_buf_0x9050_len = 0; @@ -1498,6 +1600,19 @@ void LibRaw::parseSonyMakernotes( case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; case 4: imgdata.shootinginfo.FocusMode +=2; break; } + lid = 0x55 << 1; + u16temp = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + switch (u16temp) { + case 1: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 2: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9; + break; + default: + imSony.AspectRatio = (float)u16temp; + break; + } if (!imCommon.ColorSpace || (imCommon.ColorSpace == LIBRAW_COLORSPACE_Unknown)) { lid = 0x83 << 1; @@ -1530,12 +1645,36 @@ void LibRaw::parseSonyMakernotes( case 1: case 2: case 3: imgdata.shootinginfo.FocusMode++; break; case 4: imgdata.shootinginfo.FocusMode +=2; break; } + lid = 0x55 << 1; + u16temp = ((ushort)table_buf[lid]) << 8 | ((ushort)table_buf[lid + 1]); + switch (u16temp) { + case 1: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 2: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9; + break; + default: + imSony.AspectRatio = (float)u16temp; + break; + } lid = 0x7e << 1; imgdata.shootinginfo.DriveMode = table_buf[lid + 1]; break; case 1536: // a560 a580 a33 a35 a55 NEX-3 NEX-5 NEX-5C NEX-C3 NEX-VG10E case 2048: // a450 a500 a550 // CameraSettings3 are little endian + switch (table_buf[0x0a]) { + case 4: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_3to2; + break; + case 8: + imSony.AspectRatio = LIBRAW_IMAGE_ASPECT_16to9; + break; + default: + imSony.AspectRatio = (float)table_buf[0x0a]; + break; + } switch (table_buf[0x0e]) { case 1: imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB; @@ -1751,6 +1890,7 @@ void LibRaw::parseSonyMakernotes( if (ilm.CamID) { + imSony.len_group9050 = table_buf_0x9050_len; process_Sony_0x9050(table_buf_0x9050, table_buf_0x9050_len, ilm.CamID); free(table_buf_0x9050); table_buf_0x9050_len = 0; @@ -1968,73 +2108,6 @@ void LibRaw::parseSonyMakernotes( } } -class checked_buffer_t -{ -public: - // create with internal storage - checked_buffer_t(short ord, int size) : _order(ord), storage(size+64) { - _data = storage.data(); - _len = size; - } - checked_buffer_t(short ord, unsigned char *dd, int ss): _order(ord), _data(dd),_len(ss){} - - ushort sget2(int offset) - { - checkoffset(offset + 2); - return libraw_sget2_static(_order, _data + offset); - } - void checkoffset(int off) - { - if (off >= _len) throw LIBRAW_EXCEPTION_IO_EOF; - } - unsigned char operator [] (int idx) - { - checkoffset(idx); - return _data[idx]; - } - unsigned sget4(int offset) - { - checkoffset(offset+4); - return libraw_sget4_static(_order, _data + offset); - } - double sgetreal(int type, int offset) - { - int sz = libraw_tagtype_dataunit_bytes(type); - checkoffset(offset + sz); - return libraw_sgetreal_static(_order, type, _data + offset); - } - - unsigned char *data() { return _data; } - - int tiff_sget(unsigned save, INT64 *tag_offset, - unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, - unsigned *tag_datalen, int *tag_dataunitlen) - { - if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun - return -1; - } - int pos = *tag_offset; - *tag_id = sget2(pos); pos += 2; - *tag_type = sget2(pos); pos += 2; - *tag_datalen = sget4(pos); pos += 4; - *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type); - if ((*tag_datalen * (*tag_dataunitlen)) > 4) { - *tag_dataoffset = sget4(pos) - save; - if ((*tag_dataoffset + *tag_datalen) > _len) { // abnormal, tag data buffer overrun - return -2; - } - } - else *tag_dataoffset = *tag_offset + 8; - *tag_offset += 12; - return 0; - } - -private: - short _order; - unsigned char *_data; - int _len; - std::vector storage; -}; void LibRaw::parseSonySR2(uchar *_cbuf_SR2, unsigned SR2SubIFDOffset, unsigned SR2SubIFDLength, unsigned dng_writer) diff --git a/src/metadata/tiff.cpp b/src/metadata/tiff.cpp index c34b86470..9c1650c1a 100644 --- a/src/metadata/tiff.cpp +++ b/src/metadata/tiff.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -65,7 +65,6 @@ int LibRaw::parse_tiff_ifd(int base) len, order, ifp, base); fseek(ifp, savepos, SEEK_SET); } - if (!is_pana_raw) { /* processing of EXIF tags that collide w/ PanasonicRaw tags */ switch (tag) @@ -114,6 +113,13 @@ int LibRaw::parse_tiff_ifd(int base) tiff_ifd[ifd].bps = jh.bits; tiff_ifd[ifd].samples = 1; } + else if (!dng_version && !strcasecmp(make, "SONY") && tiff_ifd[ifd].phint == 6 && + tiff_ifd[ifd].comp == 7 && tiff_ifd[ifd].samples == 3) // Sony/lossless YCbCr + { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].bps = jh.bits; + // tiff_ifd[ifd].samples = 3; // no change + } else { tiff_ifd[ifd].comp = 6; @@ -189,16 +195,15 @@ int LibRaw::parse_tiff_ifd(int base) pana_black[tag - 0x001c] = get2(); break; case 0x002d: /* 45, RawFormat */ - /* pana_encoding: tag 0x002d (45dec) - not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 + /* pana_encoding: tag 0x002d (45dec) not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 2 - RAW DMC-FZ8/FZ18 3 - RAW DMC-L10 - 4 - RW2 for most other models, including G9 in "pixel shift off" - mode and YUNEEC CGO4 (must add 15 to black levels for - RawFormat == 4) 5 - RW2 DC-GH5s; G9 in "pixel shift on" - mode 6 - RW2 DC-S1, DC-S1R in "pixel shift off" - mode 7 - RW2 DC-S1R (probably DC-S1 too) in - "pixel shift on" mode + 4 - RW2 for most other models, including G9 in "pixel shift off" mode and YUNEEC CGO4 + (must add 15 to black levels for RawFormat == 4) + 5 - RW2 DC-GH5s; G9 in "pixel shift on" mode + 6 - RW2 DC-S1, DC-S1R in "pixel shift off" mode + 7 - RW2 DC-S1R (probably DC-S1 too) in "pixel shift on" mode + 8 - RW2 DC-GH6, DC-S5M2 */ pana_encoding = get2(); break; @@ -220,7 +225,140 @@ int LibRaw::parse_tiff_ifd(int base) if (iso_speed == 65535) iso_speed = get4(); break; - case 0x011c: /* 284, Gamma */ + case 0x0039: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 26) + { + ushort cnt = get2(); + if (cnt > 6) + cnt = 6; + for (i = 0; i < cnt; i++) + pana8.tag39[i] = get4(); + } + break; + case 0x003A: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 26) + { + ushort cnt = get2(); + if (cnt > 6) + cnt = 6; + for (i = 0; i < cnt; i++) + { + get2(); + pana8.tag3A[i] = get2(); + } + } + break; + case 0x003B: + if (type == LIBRAW_EXIFTAG_TYPE_SHORT && len == 1) + pana8.tag3B = get2(); + break; + case 0x003C: + case 0x003D: + case 0x003E: + case 0x003F: + if (type == LIBRAW_EXIFTAG_TYPE_SHORT && len == 1) + pana8.initial[tag - 0x3c] = get2(); + break; + case 0x0040: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 70) + { + ushort count = get2(); + if (count > 17) count = 17; + for (i = 0; i < count; i++) + { + ushort v1 = get2(); + if (v1 > 16u) v1 = 16u; + pana8.tag40a[i] = v1; + ushort v2 = get2(); + if (v2 > 0xfffu) + v2 = 0xfffu; + pana8.tag40b[i] = v2; + } + } + break; + case 0x0041: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 36) + { + ushort count = get2(); + if (count > 17) + count = 17; + for (i = 0; i < count; i++) + { + ushort v1 = get2(); + if (v1 > 0x40u) v1 = 64; + pana8.tag41[i] = v1; + } + } + break; + case 0x0042: + if (type == LIBRAW_EXIFTAG_TYPE_SHORT && len == 1) + { + ushort val = get2(); + if (val > 5) + val = 5; + pana8.stripe_count = val; + } + break; + case 0x0043: + if (type == LIBRAW_EXIFTAG_TYPE_SHORT && len == 1) + { + ushort val = get2(); + if (val > 5) + val = 5; + pana8.tag43 = val; + } + break; + case 0x0044: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 50) + { + ushort count = get2(); + if (count > 5) + count = 5; + for (i = 0; i < count; i++) + pana8.stripe_offsets[i] = get4(); + } + break; + case 0x0045: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 50) + { + ushort count = get2(); + if (count > 5) + count = 5; + for (i = 0; i < count; i++) + pana8.stripe_left[i] = get4(); + } + break; + case 0x0046: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 50) + { + ushort count = get2(); + if (count > 5) + count = 5; + for (i = 0; i < count; i++) + pana8.stripe_compressed_size[i] = get4(); + } + break; + case 0x0047: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 26) + { + ushort count = get2(); + if (count > 5) + count = 5; + for (i = 0; i < count; i++) + pana8.stripe_width[i] = get2(); + } + break; + case 0x0048: + if (type == LIBRAW_EXIFTAG_TYPE_UNDEFINED && len == 26) + { + ushort count = get2(); + if (count > 5) + count = 5; + for (i = 0; i < count; i++) + pana8.stripe_height[i] = get2(); + } + break; + case 0x011c: /* 284, Gamma */ { int n = get2(); if (n >= 1024) @@ -1008,20 +1146,23 @@ int LibRaw::parse_tiff_ifd(int base) (imFuji.RAFDataVersion == 0x0261) || // X100V, GFX 50S II (imFuji.RAFDataVersion == 0x0262) || // X-T4 (imFuji.RAFDataVersion == 0x0263) || // X-H2S - (imFuji.RAFDataVersion == 0x0264) || // X-S10 - (imFuji.RAFDataVersion == 0x0265) || // X-E4 - (imFuji.RAFDataVersion == 0x0266) || // X-T30 II + (imFuji.RAFDataVersion == 0x0264) || // X-S10, X-H2 + (imFuji.RAFDataVersion == 0x0265) || // X-E4, X-T5 + (imFuji.RAFDataVersion == 0x0266) || // X-T30 II, X-S20 + (imFuji.RAFDataVersion == 0x0267) || // GFX 100 II !strcmp(model, "X-Pro3") || - !strcmp(model, "GFX 100S") || - !strcmp(model, "GFX100S") || - !strcmp(model, "GFX 50S II") || - !strcmp(model, "GFX50S II") || + !strcmp(model, "GFX100 II") || !strcmp(model, "GFX 100 II") || + !strcmp(model, "GFX100S") || !strcmp(model, "GFX 100S") || + !strcmp(model, "GFX50S II") || !strcmp(model, "GFX 50S II") || !strcmp(model, "X100V") || !strcmp(model, "X-T4") || !strcmp(model, "X-H2S") || + !strcmp(model, "X-H2") || !strcmp(model, "X-E4") || + !strcmp(model, "X-T5") || !strcmp(model, "X-T30 II") || - !strcmp(model, "X-S10")) + !strcmp(model, "X-S10") || + !strcmp(model, "X-S20")) // is34 cameras have 34 CCT values instead of 31, manual still claims 2500 to 10000 K // aligned 3000 K to Incandescent, as it is usual w/ other Fujifilm cameras is34 = 1; @@ -1055,7 +1196,7 @@ int LibRaw::parse_tiff_ifd(int base) fj -= 93; if (is34) fj -= 9; -// printf ("wb start in DNG: 0x%04x\n", fj*2-0x4e); +//printf ("wb start in DNG: 0x%04x\n", fj*2-0x4e); for (int iCCT = 0, ofst = fj; iCCT < 31; iCCT++, ofst += 3) { @@ -1386,7 +1527,13 @@ int LibRaw::parse_tiff_ifd(int base) if (!strncmp(mbuf, "RAF ", 4)) { // Fujifilm Raw, AdobeRAF - parseAdobeRAFMakernote(); + try { + parseAdobeRAFMakernote(); // May raise exception for out-of buffer reads + } + catch (...) + { + // just ignore it + } } if (!strncmp(mbuf, "SR2 ", 4)) @@ -1579,7 +1726,7 @@ int ifd_size_t_cmp(const void *a, const void *b) : (bi->databits < ai->databits ? -1 : 0); } -static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make); +static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make, bool isDNG); void LibRaw::apply_tiff() { @@ -1640,7 +1787,7 @@ void LibRaw::apply_tiff() // Preview: 0x1 or 0x10001 || ((tiff_ifd[i].newsubfiletype & 0xffff) == 1 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_PREVIEWS)) - // Transparency mask: 0x4 + // Transparency mask: 0x4 || ((tiff_ifd[i].newsubfiletype & 0xffff) == 4 && (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DNG_ADD_MASKS))) { @@ -1676,7 +1823,7 @@ void LibRaw::apply_tiff() (arr[q].ifdi & 0xff)); // add inverted frame # to ensure same // sort order for similar sized frames. if (tiff_ifd[ifdidx].phint == 4) - arr[q].databits /= 4; // Force lower bit count for Transp. mask images + arr[q].databits /= 4; // Force lower bit count for Transp. mask images } qsort(arr, MIN(ifdc, LIBRAW_IFD_MAXCOUNT * 2), sizeof(arr[0]), ifd_size_t_cmp); @@ -1773,7 +1920,13 @@ void LibRaw::apply_tiff() if (tiff_ifd[i].phint == 2 && tiff_ifd[i].extrasamples > 0 && tiff_ifd[i].samples > 3) continue; // SKIP RGB+Alpha IFDs - if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + if (!strncasecmp(make, "Sony", 4) && tiff_ifd[i].bps == 8 && tiff_ifd[i].phint == 6 && tiff_ifd[i].comp == 7 && + tiff_ifd[i].samples == 3 && tiff_ifd[i].newsubfiletype == 1) + continue; // Sony RGB preview + + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3 || + (tiff_ifd[i].comp == 6 && tiff_ifd[i].samples == 3 && !strncasecmp(make, "Sony", 4) && tiff_ifd[i].bps >=12) + ) && unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && (unsigned)tiff_ifd[i].bps < 33 && (unsigned)tiff_ifd[i].samples < 13 && ns && @@ -1952,9 +2105,25 @@ void LibRaw::apply_tiff() case 6: case 7: case 99: - if (!dng_version && tiff_compress == 6 && !strcasecmp(make, "SONY")) - load_raw = &LibRaw::sony_ljpeg_load_raw; - else + if (!dng_version && tiff_compress == 6 && !strcasecmp(make, "SONY")) + { + if (tiff_ifd[raw].phint == 6 && tiff_ifd[raw].bps >= 12 && tiff_ifd[raw].samples == 3) + { + load_raw = &LibRaw::sony_ycbcr_load_raw; + filters = 0; + colors = 3; + } + else + load_raw = &LibRaw::sony_ljpeg_load_raw; + } + // Allow A1/Compression=7 + else if(!dng_version && tiff_compress == 7 && !strcasecmp(make, "SONY") && + (!strcasecmp(model,"ILCE-1") || !strncasecmp(model, "ILCE-7",6) + || !strncasecmp(model, "ILCE-9", 6) // Most likely ILCE-9 will use tiff_compr=7 this w/ updated FW + ) && + tiff_bps == 14 && tiff_samples == 1) + load_raw = &LibRaw::sony_ljpeg_load_raw; + else load_raw = &LibRaw::lossless_jpeg_load_raw; break; case 262: @@ -2024,7 +2193,7 @@ void LibRaw::apply_tiff() load_flags = (((INT64(raw_width) * 3ULL / 2ULL) + 15ULL) / 16ULL) * 16ULL; // bytes per row } - else if (!strncmp(model, "NIKON Z 9", 9) && tiff_ifd[raw].offset) + else if ((!strncmp(model, "NIKON Z 9", 9) || !strncmp(model, "NIKON Z 8", 9)) && tiff_ifd[raw].offset) { INT64 pos = ftell(ifp); unsigned char cmp[] = "CONTACT_INTOPIX"; // 15 @@ -2062,6 +2231,12 @@ void LibRaw::apply_tiff() break; case 8: break; +#ifdef USE_DNGSDK + case 52546: + if (dng_version) + break; /* Compression=9 supported for dng if we compiled with GPR SDK */ + /* Else: fallthrough */ +#endif #ifdef USE_GPRSDK case 9: if (dng_version) @@ -2076,6 +2251,7 @@ void LibRaw::apply_tiff() if (((tiff_samples == 3 && tiff_ifd[raw].bytes && !(tiff_bps == 16 && !strncmp(make, "Leaf", 4)) && // Allow Leaf/16bit/3color files + !(tiff_ifd[raw].comp == 6 && tiff_ifd[raw].phint == 6 && tiff_bps >= 12 && !strncasecmp(make,"Sony",4)) && // Sony YCbCr tiff_bps != 14 && (tiff_compress & -16) != 32768) || (tiff_bps == 8 && strncmp(make, "Phase", 5) && @@ -2093,8 +2269,8 @@ void LibRaw::apply_tiff() if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_ALL_VENDORS) fsizecheck = ifp->size(); - else if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS) - && !strncasecmp(make,"Ricoh",5)) + else if ((imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CHECK_THUMBNAILS_KNOWN_VENDORS) && + (!strncasecmp(make, "Ricoh", 5) || (dng_version && !strncasecmp(make, "Samsung", 7)))) fsizecheck = ifp->size(); for (i = 0; i < (int)tiff_nifds; i++) @@ -2104,6 +2280,7 @@ void LibRaw::apply_tiff() tiff_ifd[i].samples == 1)) /* Allow 1-bps JPEGs */ && tiff_ifd[i].bps > 0 && tiff_ifd[i].bps < 33 && tiff_ifd[i].phint != 32803 && tiff_ifd[i].phint != 34892 && + (tiff_ifd[i].comp != 52546 || (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ALLOW_JPEGXL_PREVIEWS)) && unsigned(tiff_ifd[i].t_width | tiff_ifd[i].t_height) < 0x10000 && tiff_ifd[i].comp != 34892) { @@ -2150,7 +2327,7 @@ void LibRaw::apply_tiff() { int idx = imgdata.thumbs_list.thumbcount; imgdata.thumbs_list.thumblist[idx].tformat = tiff2thumbformat(tiff_ifd[i].comp, tiff_ifd[i].phint, - tiff_ifd[i].bps, make); + tiff_ifd[i].bps, make, dng_version); imgdata.thumbs_list.thumblist[idx].twidth = tiff_ifd[i].t_width; imgdata.thumbs_list.thumblist[idx].theight = tiff_ifd[i].t_height; imgdata.thumbs_list.thumblist[idx].tflip = tiff_ifd[i].t_flip; @@ -2164,23 +2341,27 @@ void LibRaw::apply_tiff() if (thm >= 0) { thumb_misc |= tiff_ifd[thm].samples << 5; - thumb_format = tiff2thumbformat(tiff_ifd[thm].comp, tiff_ifd[thm].phint, tiff_ifd[thm].bps, make); + thumb_format = tiff2thumbformat(tiff_ifd[thm].comp, tiff_ifd[thm].phint, tiff_ifd[thm].bps, make, dng_version); } } -static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make) +static LibRaw_internal_thumbnail_formats tiff2thumbformat(int _comp, int _phint, int _bps, const char *_make, bool isDNG) { switch (_comp) { case 0: return LIBRAW_INTERNAL_THUMBNAIL_LAYER; case 1: - if (_bps <= 8) - return LIBRAW_INTERNAL_THUMBNAIL_PPM; - else if (!strncmp(_make, "Imacon", 6)) - return LIBRAW_INTERNAL_THUMBNAIL_PPM16; + if (_bps <= 8) + return LIBRAW_INTERNAL_THUMBNAIL_PPM; + else if (!strncmp(_make, "Imacon", 6)) + return LIBRAW_INTERNAL_THUMBNAIL_PPM16; + else if (isDNG && _phint == 6 && _bps == 12) + return LIBRAW_INTERNAL_THUMBNAIL_DNG_YCBCR; else return LIBRAW_INTERNAL_THUMBNAIL_KODAK_THUMB; + case 52546: + return LIBRAW_INTERNAL_THUMBNAIL_JPEGXL; case 65000: return _phint == 6 ? LIBRAW_INTERNAL_THUMBNAIL_KODAK_YCBCR : LIBRAW_INTERNAL_THUMBNAIL_KODAK_RGB; } diff --git a/src/postprocessing/aspect_ratio.cpp b/src/postprocessing/aspect_ratio.cpp index 7e0dfd098..e5165e9bf 100644 --- a/src/postprocessing/aspect_ratio.cpp +++ b/src/postprocessing/aspect_ratio.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/postprocessing/dcraw_process.cpp b/src/postprocessing/dcraw_process.cpp index e8eff1317..8b3d77cf6 100644 --- a/src/postprocessing/dcraw_process.cpp +++ b/src/postprocessing/dcraw_process.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/postprocessing/mem_image.cpp b/src/postprocessing/mem_image.cpp index 9f70d671b..4c17994df 100644 --- a/src/postprocessing/mem_image.cpp +++ b/src/postprocessing/mem_image.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/postprocessing/postprocessing_aux.cpp b/src/postprocessing/postprocessing_aux.cpp index c8c53fa66..e0fd33521 100644 --- a/src/postprocessing/postprocessing_aux.cpp +++ b/src/postprocessing/postprocessing_aux.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/postprocessing/postprocessing_ph.cpp b/src/postprocessing/postprocessing_ph.cpp index 3af0939dd..4e2947402 100644 --- a/src/postprocessing/postprocessing_ph.cpp +++ b/src/postprocessing/postprocessing_ph.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing tools diff --git a/src/postprocessing/postprocessing_utils.cpp b/src/postprocessing/postprocessing_utils.cpp index 986b5bbfa..f944adb4c 100644 --- a/src/postprocessing/postprocessing_utils.cpp +++ b/src/postprocessing/postprocessing_utils.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/postprocessing/postprocessing_utils_dcrdefs.cpp b/src/postprocessing/postprocessing_utils_dcrdefs.cpp index 98ea0618e..cddc292ab 100644 --- a/src/postprocessing/postprocessing_utils_dcrdefs.cpp +++ b/src/postprocessing/postprocessing_utils_dcrdefs.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/preprocessing/ext_preprocess.cpp b/src/preprocessing/ext_preprocess.cpp index 8f2ec4957..e9020751c 100644 --- a/src/preprocessing/ext_preprocess.cpp +++ b/src/preprocessing/ext_preprocess.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/preprocessing/preprocessing_ph.cpp b/src/preprocessing/preprocessing_ph.cpp index 44868ed55..f296feecb 100644 --- a/src/preprocessing/preprocessing_ph.cpp +++ b/src/preprocessing/preprocessing_ph.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing and preprocessing calls diff --git a/src/preprocessing/raw2image.cpp b/src/preprocessing/raw2image.cpp index 702cf2902..703d02c17 100644 --- a/src/preprocessing/raw2image.cpp +++ b/src/preprocessing/raw2image.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -61,12 +61,14 @@ int LibRaw::raw2image(void) { raw2image_start(); - if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) + bool free_p1_buffer = false; + if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED))) { phase_one_allocate_tempbuffer(); + free_p1_buffer = true; int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, imgdata.rawdata.raw_image); - if (rc == 0) + if (rc == 0 && imgdata.params.use_p1_correction) rc = phase_one_correct(); if (rc != 0) { @@ -180,7 +182,7 @@ int LibRaw::raw2image(void) } // Free PhaseOne separate copy allocated at function start - if (is_phaseone_compressed()) + if (free_p1_buffer) { phase_one_free_tempbuffer(); } @@ -306,14 +308,16 @@ int LibRaw::raw2image_ex(int do_subtract_black) try { raw2image_start(); + bool free_p1_buffer = false; // Compressed P1 files with bl data! - if (is_phaseone_compressed() && imgdata.rawdata.raw_alloc) + if (is_phaseone_compressed() && (imgdata.rawdata.raw_alloc || (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED))) { phase_one_allocate_tempbuffer(); + free_p1_buffer = true; int rc = phase_one_subtract_black((ushort *)imgdata.rawdata.raw_alloc, imgdata.rawdata.raw_image); - if (rc == 0) + if (rc == 0 && imgdata.params.use_p1_correction) rc = phase_one_correct(); if (rc != 0) { @@ -528,7 +532,7 @@ int LibRaw::raw2image_ex(int do_subtract_black) } // Free PhaseOne separate copy allocated at function start - if (is_phaseone_compressed()) + if (free_p1_buffer) { phase_one_free_tempbuffer(); } diff --git a/src/preprocessing/subtract_black.cpp b/src/preprocessing/subtract_black.cpp index 42bbe4fac..5539d9643 100644 --- a/src/preprocessing/subtract_black.cpp +++ b/src/preprocessing/subtract_black.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify diff --git a/src/tables/cameralist.cpp b/src/tables/cameralist.cpp index da7f48164..86c88894a 100644 --- a/src/tables/cameralist.cpp +++ b/src/tables/cameralist.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -13,12 +13,6 @@ */ #include "../../internal/libraw_cxx_defs.h" -#ifdef USE_RAWSPEED -/* we need separate file for that */ -#include "../../RawSpeed/rawspeed_xmldata.cpp" -const int RAWSPEED_DATA_COUNT = - (sizeof(_rawspeed_data_xml) / sizeof(_rawspeed_data_xml[0])); -#endif // clang-format off // Supported cameras: static const char *static_camera_list[] = { @@ -36,21 +30,16 @@ static const char *static_camera_list[] = { "Apple iPhone X", "Apple iPhone 12 Pro", "Apple iPhone 12 Pro Max", - "Apple iPhone 13 Pro", + "Apple iPhone 13", + "Apple iPhone 14", "Apple QuickTake 100", "Apple QuickTake 150", "Apple QuickTake 200", -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - "ARRI ALEXA", - "ARRI ALEXA65", - "ARRI ALEXA LF", - "ARRI ALEXA XT", - "ARRI ALEXA SXT", -#endif "ASUS ZenPhone4", "ASUS ZenPhone6", "AutelRobotics XB015", "AutelRobotics XT705 (EVO II)", + "AutelRobotics XL720 (EVO Lite+)", "AVT F-080C", "AVT F-145C", "AVT F-201C", @@ -153,12 +142,17 @@ static const char *static_camera_list[] = { "Canon PowerShot SX20 IS (CHDK hack)", "Canon PowerShot SX30 IS (CHDK hack)", "Canon EOS R", + "Canon EOS Ra", "Canon EOS RP", "Canon EOS R3", "Canon EOS R5", "Canon EOS R6", + "Canon EOS R6 Mark II", "Canon EOS R7", + "Canon EOS R8", "Canon EOS R10", + "Canon EOS R50", + "Canon EOS R100", "Canon EOS D30", "Canon EOS D60", "Canon EOS 5DS", @@ -205,9 +199,6 @@ static const char *static_camera_list[] = { "Canon EOS 1300D / Rebel T6 / Kiss X80", "Canon EOS 1500D / 2000D / Rebel T7 / Kiss X90", "Canon EOS 3000D / 4000D / Rebel T100", -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - "Canon EOS C500", -#endif "Canon EOS D2000", "Canon EOS M", "Canon EOS M2", @@ -291,11 +282,18 @@ static const char *static_camera_list[] = { "Digital Bolex D16", "Digital Bolex D16M", "DJI 4384x3288", + "DJI Inspire 3", "DJI Mavic Air", - "DJI Mavic Air2", + "DJI Mavic Air 2", "DJI Mavic Air 2S", - "DJI Mavic Mini2", + "DJI Mavic Air 3", + "DJI Mavic Mini 2", + "DJI Mavic Mini 3", + "DJI Mavic Mini 3 Pro", + "DJI Mavic 2 Pro", "DJI Mavic 3", + "DJI Mavic 3 Classic", + "DJI Mavic 3 Pro", "DJI Osmo Action", "DJI Pocket", "DJI Phantom4 Pro/Pro+", @@ -342,11 +340,13 @@ static const char *static_camera_list[] = { "FujiFilm GFX 50S II", "FujiFilm GFX 50R", "FujiFilm GFX 100", + "FujiFilm GFX 100 II", "FujiFilm GFX 100S", "FujiFilm X-Pro1", "FujiFilm X-Pro2", "FujiFilm X-Pro3", "FujiFilm X-S1", + "FujiFilm X-S20", "FujiFilm XQ1", "FujiFilm XQ2", "FujiFilm X100", @@ -374,6 +374,7 @@ static const char *static_camera_list[] = { "FujiFilm XF1", "FujiFilm XF10", "FujiFilm X-H1", + "FujiFilm X-H2", "FujiFilm X-H2S", "FujiFilm X-T1", "FujiFilm X-S10", @@ -381,6 +382,7 @@ static const char *static_camera_list[] = { "FujiFilm X-T2", "FujiFilm X-T3", "FujiFilm X-T4", + "FujiFilm X-T5", "FujiFilm X-T10", "FujiFilm X-T20", "FujiFilm X-T30", @@ -398,6 +400,7 @@ static const char *static_camera_list[] = { "Google Pixel 4 XL", "Google Pixel 4a (5G)", "Google Pixel 5", + "Google Pixel 7a", #ifdef USE_GPRSDK "GoPro Fusion", "GoPro HERO5", @@ -406,6 +409,8 @@ static const char *static_camera_list[] = { "GoPro HERO8", "GoPro HERO9", "GoPro HERO10", + "GoPro HERO11", + "GoPro HERO12", #endif "Hasselblad H2D-22", "Hasselblad H2D-39", @@ -443,6 +448,7 @@ static const char *static_camera_list[] = { "Hasselblad HV", "Hasselblad X1D", "Hasselblad X1D II 50C", + "Hasselblad X2D 100C", "HTC UltraPixel", "HTC MyTouch 4G", "HTC One (A9)", @@ -587,6 +593,7 @@ static const char *static_camera_list[] = { "Leica M10-R", "Leica M10 Monochrom", "Leica M11", + "Leica M11 Monochrom", "Leica M (Typ 240)", "Leica M (Typ 262)", "Leica Monochrom (Typ 240)", @@ -599,6 +606,7 @@ static const char *static_camera_list[] = { "Leica Q-P", "Leica Q2", "Leica Q2 Monochrom", + "Leica Q3", "Leica S", "Leica S2", "Leica S3", @@ -710,7 +718,9 @@ static const char *static_camera_list[] = { "Nikon Z 6 II", "Nikon Z 7", "Nikon Z 7 II", + "Nikon Z 8 (HE/HE* formats are not supported yet)", "Nikon Z 9 (HE/HE* formats are not supported yet)", + "Nikon Z 30", "Nikon Z 50", "Nikon Z fc", "Nikon 1 AW1", @@ -843,6 +853,7 @@ static const char *static_camera_list[] = { "Olympus XZ-2", "Olympus XZ-10", "OM Digital Solutions OM-1", + "OM Digital Solutions OM-5", "OmniVision 4688", "OmniVision OV5647", "OmniVision OV5648", @@ -882,6 +893,7 @@ static const char *static_camera_list[] = { "Panasonic DMC-G7 / G70", "Panasonic DMC-G8 / G80 / G81 / G85", "Panasonic DC-G9", + "Panasonic DC-G9 Mark II", "Panasonic DC-G90 / G95 / G91 / G99", "Panasonic DC-G100 / G110", "Panasonic DMC-GF1", @@ -899,6 +911,7 @@ static const char *static_camera_list[] = { "Panasonic DC-GH5", "Panasonic DC-GH5S", "Panasonic DC-GH5 Mark II", + "Panasonic DC-GH6", "Panasonic DMC-GM1", "Panasonic DMC-GM1s", "Panasonic DMC-GM5", @@ -924,6 +937,7 @@ static const char *static_camera_list[] = { "Panasonic DC-S1H", "Panasonic DC-S1R", "Panasonic DC-S5", + "Panasonic DC-S5 MkII", "Panasonic DMC-ZS40, DMC-TZ60 / TZ61", "Panasonic DMC-ZS50, DMC-TZ70 / TZ71", "Panasonic DMC-ZS60, DMC-TZ80 / TZ81 / TZ82 / TZ85", @@ -931,6 +945,7 @@ static const char *static_camera_list[] = { "Panasonic DC-ZS80, DC-TZ95 / TZ96 / TZ97", "Panasonic DMC-ZS100 / ZS110, DMC-TZ100 / TZ101 / TZ110, DMC-TX1", "Panasonic DC-ZS200 / ZS220, DC-TZ200 / TZ202 / TZ220, DC-TX2", + "Panasonic DC-ZS200D / ZS220D, DC-TZ200D / TZ202D / TZ220D", "PARROT Anafi", "PARROT Bebop 2", "PARROT Bebop Drone", @@ -955,6 +970,7 @@ static const char *static_camera_list[] = { "Pentax K-3", "Pentax K-3 Mark II", "Pentax K-3 Mark III", +// "Pentax K-3 Mark III Monochrome", "Pentax K-30", "Pentax K-5", "Pentax K-5 II", @@ -1035,11 +1051,6 @@ static const char *static_camera_list[] = { "Ricoh GXR Ricoh Lens A16 24-85mm F3.5-5.5", "Ricoh GXR Ricoh Lens S10 24-72mm F2.5-4.4 VC", "Ricoh GXR Ricoh Lens P10 28-300 mm F3.5-5.6 VC", -#ifdef LIBRAW_OLD_VIDEO_SUPPORT -#ifndef NO_JASPER - "Redcode R3D format", -#endif -#endif "Rollei d530flex", "RoverShot 3320af", "Samsung EX1 / TL500", @@ -1060,6 +1071,7 @@ static const char *static_camera_list[] = { "Samsung Galaxy S9+ (SM-G965U / 965F)", "Samsung Galaxy S10 (SM-G973F)", "Samsung Galaxy S10+ (SM-G975U)", + "Samsung Galaxy S22 Ultra (SM-S908B)", "Samsung NX1", "Samsung NX5", "Samsung NX10", @@ -1088,6 +1100,7 @@ static const char *static_camera_list[] = { "Seitz Roundshot D3", "Seitz Roundshot D2X", "Seitz Roundshot D2Xs", + "Skydio 2+", "Sigma fp", #ifdef USE_X3FTOOLS "Sigma SD9 (raw decode only)", @@ -1138,12 +1151,15 @@ static const char *static_camera_list[] = { "Sony ILCE-7M3 (A7 III)", "Sony ILCE-7M4 (A7 IV)", "Sony ILCE-7C (A7C)", + "Sony ILCE-7CR (A7CR)", + "Sony ILCE-7CM2 (A7C II)", "Sony ILCE-7R (A7R)", "Sony ILCE-7RM2 (A7R II)", "Sony ILCE-7RM3 (A7R III)", "Sony ILCE-7RM3A (A7R IIIA)", "Sony ILCE-7RM4 (A7R IV)", "Sony ILCE-7RM4A (A7R IVA)", + "Sony ILCE-7RM5 (A7R V)", "Sony ILCE-7S (A7S)", "Sony ILCE-7SM2 (A7S II)", "Sony ILCE-7SM3 (A7S III)", @@ -1161,6 +1177,7 @@ static const char *static_camera_list[] = { "Sony ILCE-6400", "Sony ILCE-6500", "Sony ILCE-6600", + "Sony ILCE-6700", "Sony ILCE-QX1", "Sony DSC-F828", "Sony DSC-HX95", @@ -1234,7 +1251,10 @@ static const char *static_camera_list[] = { "Sony Xperia 5 II (XQ-AS52)", "Sony Xperia L", "Sony Xperia 1 III", + "Sony Xperia 1 IV (XQ-CT54)", "Sony ZV-1 (DCZV1/B)", + "Sony ZV-1M2", + "Sony ZV-E1", "Sony ZV-E10", "STV680 VGA", "PtGrey GRAS-50S5C", @@ -1246,6 +1266,8 @@ static const char *static_camera_list[] = { "YUNEEC CGO3", "YUNEEC CGO3P", "YUNEEC CGO4", + "Xiaomi 12S Ultra (2203121C)", + "Xiaomi 13 Pro (2210132G)", "Xiaomi MI3", "Xiaomi MI 8", "Xiaomi MI 9 Lite", diff --git a/src/tables/colorconst.cpp b/src/tables/colorconst.cpp index ad5a649cf..5e178e2d6 100644 --- a/src/tables/colorconst.cpp +++ b/src/tables/colorconst.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/tables/colordata.cpp b/src/tables/colordata.cpp index fc9f100f7..25d27a3a4 100644 --- a/src/tables/colordata.cpp +++ b/src/tables/colordata.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -31,601 +31,622 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, const char *prefix; int t_black, t_maximum, trans[12]; } table[] = { - { LIBRAW_CAMERAMAKER_Agfa, "DC-833m", 0, 0, - { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Agfa, "DC-833m", 0, 0, + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Apple, "QuickTake", 0, 0, - { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Apple, "QuickTake", 0, 0, + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Broadcom, "RPi IMX219", 66, 0x3ff, - { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ - { LIBRAW_CAMERAMAKER_Broadcom, "RPi OV5647", 16, 0x3ff, - { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Broadcom, "RPi IMX219", 66, 0x3ff, + { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_Broadcom, "RPi OV5647", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ { LIBRAW_CAMERAMAKER_Broadcom, "Pi", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ #ifdef USE_6BY9RPI // this code normalizes model to LIBRAW_CAMERAMAKER_RaspberryPi - { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx477", 0, 0, // Do not set black, it is set at parser to 256 or 64 - { 5603, -1351, -600, -2872, 11180, 2132, 600, 453, 5821 } }, /* PyDNG */ - { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx", 66, 0x3ff, - { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ - { LIBRAW_CAMERAMAKER_RaspberryPi, "ov5647", 16, 0x3ff, - { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx477", 0, 0, // Do not set black, it is set at parser to 256 or 64 + { 5603, -1351, -600, -2872, 11180, 2132, 600, 453, 5821 } }, /* PyDNG */ + { LIBRAW_CAMERAMAKER_RaspberryPi, "RP_imx", 66, 0x3ff, + { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ + { LIBRAW_CAMERAMAKER_RaspberryPi, "ov5647", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ #endif - { LIBRAW_CAMERAMAKER_Canon, "EOS D30", 0, 0, - { 9900,-2771,-1324,-7072,14229,3140,-2790,3344,8861 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS D60", 0, 0xfa0, - { 6211,-1358,-896,-8557,15766,3012,-3001,3507,8567 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 5DS", 0, 0x3c96, // same CMs: 5DS, "5DS R" */ - { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, // v.2 - { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark IV", 0, 0, - { 6446,-366,-864,-4436,12204,2513,-952,2496,6348 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark III", 0, 0x3c80, - { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark II", 0, 0x3cf0, - { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 5D", 0, 0xe6c, - { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 6D Mark II", 0, 0x38de, - { 6875,-970,-932,-4691,12459,2501,-874,1953,5809 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 6D", 0, 0x3c82, - { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 77D", 0, 0, - { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 7D Mark II", 0, 0x3510, - { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 7D", 0, 0x3510, - { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 850D", 0, 0, - { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, - { LIBRAW_CAMERAMAKER_Canon, "EOS 800D", 0, 0, - { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 80D", 0, 0, - { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 10D", 0, 0xfa0, - { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 250D", 0, 0, - { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 200D", 0, 0, - { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 20Da", 0, 0, - { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 20D", 0, 0xfff, - { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 30D", 0, 0, - { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 40D", 0, 0x3f60, - { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 50D", 0, 0x3d93, - { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 60Da", 0, 0x2ff7, - { 17492,-7240,-2023,-1791,10323,1701,-186,1329,5406 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 60D", 0, 0x2ff7, - { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 70D", 0, 0x3bc7, - { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 100D", 0, 0x350f, - { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 300D", 0, 0xfa0, - { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 350D", 0, 0xfff, - { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 3000D", 0, 0, - { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 400D", 0, 0xe8e, - { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 450D", 0, 0x390d, - { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 500D", 0, 0x3479, - { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 550D", 0, 0x3dd7, - { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 600D", 0, 0x3510, - { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 650D", 0, 0x354d, - { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 750D", 0, 0x3c00, - { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 760D", 0, 0x3c00, - { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 700D", 0, 0x3c00, - { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 90D", 0, 0, - { 11498, -3759, -1516, -5073, 12954, 2349, -892, 1867, 6118}}, - { LIBRAW_CAMERAMAKER_Canon, "EOS 1000D", 0, 0xe43, - { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 1100D", 0, 0x3510, - { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 1200D", 0, 0x37c2, - { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 1300D", 0, 0x37c2, - { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS 1500D", 0, 0, - { 8300,-2110,-1120,-4917,12694,2482,-938,2141,5666 } }, // v.2 + { LIBRAW_CAMERAMAKER_Canon, "EOS D30", 0, 0, + { 9900,-2771,-1324,-7072,14229,3140,-2790,3344,8861 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS D60", 0, 0xfa0, + { 6211,-1358,-896,-8557,15766,3012,-3001,3507,8567 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5DS", 0, 0x3c96, // same CMs: 5DS, "5DS R" */ + { 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 } }, // v.2 + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark IV", 0, 0, + { 6446,-366,-864,-4436,12204,2513,-952,2496,6348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark III", 0, 0x3c80, + { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 6D Mark II", 0, 0x38de, + { 6875,-970,-932,-4691,12459,2501,-874,1953,5809 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 6D", 0, 0x3c82, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 77D", 0, 0, + { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 850D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS 800D", 0, 0, + { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 80D", 0, 0, + { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 10D", 0, 0xfa0, + { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 250D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 200D", 0, 0, + { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 60Da", 0, 0x2ff7, + { 17492,-7240,-2023,-1791,10323,1701,-186,1329,5406 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 60D", 0, 0x2ff7, + { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 100D", 0, 0x350f, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 300D", 0, 0xfa0, + { 8250,-2044,-1127,-8092,15606,2664,-2893,3453,8348 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 3000D", 0, 0, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 550D", 0, 0x3dd7, + { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 600D", 0, 0x3510, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 650D", 0, 0x354d, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 750D", 0, 0x3c00, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 760D", 0, 0x3c00, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 700D", 0, 0x3c00, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 90D", 0, 0, + { 11498, -3759, -1516, -5073, 12954, 2349, -892, 1867, 6118}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1100D", 0, 0x3510, + { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1200D", 0, 0x37c2, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1300D", 0, 0x37c2, + { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS 1500D", 0, 0, + { 8300,-2110,-1120,-4917,12694,2482,-938,2141,5666 } }, // v.2 - { LIBRAW_CAMERAMAKER_Canon, "EOS RP", 0, 0, - { 8608,-2097,-1178,-5425,13265,2383,-1149,2238,5680 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS R3", 0, 0, - { 9423,-2839,-1195,-4532,12377,2415,-483,1374,5276 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS R5", 0, 0, - { 9766,-2953,-1254,-4276,12116,2433,-437,1336,5131 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS R6", 0, 0, - { 8293,-1611,-1132,-4759,12711,2275,-1013,2415,5509 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS RP", 0, 0, + { 8608,-2097,-1178,-5425,13265,2383,-1149,2238,5680 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R3", 0, 0, + { 9423,-2839,-1195,-4532,12377,2415,-483,1374,5276 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R50", 0, 0, + { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R100", 0, 0, + { 8230, -1515, -1032, -4179, 12005, 2454, -649, 2076, 4711 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R5", 0, 0, + { 9766,-2953,-1254,-4276,12116,2433,-437,1336,5131 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R6 Mark II", 0, 0, + { 9539, -2795, -1224, -4175, 11998, 2458, -465, 1755,6048 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R6", 0, 0, + { 8293,-1611,-1132,-4759,12711,2275,-1013,2415,5509 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R7", 0, 0, { 10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS R8", 0, 0, + { 9539, -2795, -1224, -4175, 11998, 2458, -465, 1755, 6048 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R10", 0, 0, { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS Ra", 0, 0, + { 22880,-11531,-2223,-2034,10469,1809, 316,1401,5769 } }, { LIBRAW_CAMERAMAKER_Canon, "EOS R", 0, 0, - { 8293,-1789,-1094,-5025,12925,2327,-1199,2769,6108 } }, // v.2 + { 8293,-1789,-1094,-5025,12925,2327,-1199,2769,6108 } }, // v.2 - { LIBRAW_CAMERAMAKER_Canon, "EOS M6 Mark II", 0, 0, - { 11498,-3759,-1516,-5073,12954,2349,-892,1867,6118 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M6", 0, 0, - { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M50 Mark II", 0, 0, - { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M50", 0, 0, - { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M5", 0, 0, - { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M3", 0, 0, - { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M200", 0, 0, - { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M2", 0, 0, - { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M100", 0, 0, - { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M10", 0, 0, - { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS M", 0, 0, - { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M6 Mark II", 0, 0, + { 11498,-3759,-1516,-5073,12954,2349,-892,1867,6118 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M6", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M50 Mark II", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M50", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M5", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M3", 0, 0, + { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M200", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M2", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M100", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M10", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS M", 0, 0, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark III", 0, 0x3bb0, - { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark II", 0, 0xe80, - { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark IV", 0, 0x3bb0, - { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark III", 0, 0x3bb0, - { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II N", 0, 0xe80, - { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II", 0, 0xe80, - { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds", 0, 0xe20, - { 3925,4060,-1739,-8973,16552,2545,-3287,3945,8243 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D C", 0, 0x3c4e, - { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark III", 0, 0, - { 8971, -2022, -1242, -5405, 13249, 2380, -1280, 2483, 6072}}, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark II", 0, 0x3c4e, - { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X", 0, 0x3c4e, - { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS-1D", 0, 0xe20, - { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, - { LIBRAW_CAMERAMAKER_Canon, "EOS C500", 853, 0, - { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1Ds", 0, 0xe20, + { 3925,4060,-1739,-8973,16552,2545,-3287,3945,8243 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D C", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark III", 0, 0, + { 8971, -2022, -1242, -5405, 13249, 2380, -1280, 2483, 6072}}, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X Mark II", 0, 0x3c4e, + { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { LIBRAW_CAMERAMAKER_Canon, "EOS C500", 853, 0, + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "IXUS 160", 0, 0, - { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, /* DJC */ - {LIBRAW_CAMERAMAKER_Canon, "PowerShot 600", 0, 0, - { -3822,10019,1311,4085,-157,3386,-5341,10829,4812,-1969,10969,1126 } }, + { LIBRAW_CAMERAMAKER_Canon, "IXUS 160", 0, 0, + { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, /* DJC */ + {LIBRAW_CAMERAMAKER_Canon, "PowerShot 600", 0, 0, + { -3822,10019,1311,4085,-157,3386,-5341,10829,4812,-1969,10969,1126 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A3300 IS", 0, 0, - { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A460", 0, 0, - { 6493,-2338,-885,-1589,5934,697,-445,1368,2543 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A470", 0, 0, - { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A530", 0, 0, - { 7252,-2405,-1223,-2102,6560,523,-112,704,3007 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A50", 0, 0, - { -6233,10706,1825,3260,821,3980,-6512,10745,6287,-2539,12232,262 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A5", 0, 0, - { -5707,10308,2002,2662,1829,4139,-6265,11063,6033,-2659,11911,593 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A610", 0, 0, - { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A620", 0, 0, - { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A630", 0, 0, - { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A640", 0, 0, - { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A650 IS", 0, 0, - { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot A720 IS", 0, 0, - { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A3300 IS", 0, 0, + { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A460", 0, 0, + { 6493,-2338,-885,-1589,5934,697,-445,1368,2543 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A470", 0, 0, + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A530", 0, 0, + { 7252,-2405,-1223,-2102,6560,523,-112,704,3007 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A50", 0, 0, + { -6233,10706,1825,3260,821,3980,-6512,10745,6287,-2539,12232,262 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A5", 0, 0, + { -5707,10308,2002,2662,1829,4139,-6265,11063,6033,-2659,11911,593 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A610", 0, 0, + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A620", 0, 0, + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A630", 0, 0, + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A640", 0, 0, + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A650 IS", 0, 0, + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot A720 IS", 0, 0, + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot D10", 127, 0, - { 14052,-5229,-1156,-1325,9420,2252,-498,1957,4116 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot D10", 127, 0, + { 14052,-5229,-1156,-1325,9420,2252,-498,1957,4116 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G10", 0, 0, - { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G11", 0, 0, - { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G12", 0, 0, - { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G15", 0, 0, - { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G16", 0, 0, - { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark III", 0, 0, - { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark II", 0, 0, - { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X", 0, 0, - { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1", 0, 0, - { -5686,10300,2223,4725,-1157,4383,-6128,10783,6163,-2688,12093,604 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G2", 0, 0, - { 9194,-2787,-1059,-8098,15657,2608,-2610,3064,7867 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3 X", 0, 0, - { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3", 0, 0, - { 9326,-2882,-1084,-7940,15447,2677,-2620,3090,7740 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X Mark II",0, 0, - { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X",0, 0, - { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5", 0, 0, - { 9869,-2972,-942,-7314,15098,2369,-1898,2536,7282 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G6", 0, 0, - { 9876,-3774,-871,-7613,14807,3071,-1448,1305,7485 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark III", 0, 0, - { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark II", 0, 0, - { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X", 0, 0, - { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X Mark II", 0, 0, - { 10056,-4131,-944,-2576,11143,1625,-238,1294,5179 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X",0, 0, - { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9", 0, 0, - { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G12", 0, 0, + { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G15", 0, 0, + { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark III", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X Mark II", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1 X", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G1", 0, 0, + { -5686,10300,2223,4725,-1157,4383,-6128,10783,6163,-2688,12093,604 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G2", 0, 0, + { 9194,-2787,-1059,-8098,15657,2608,-2610,3064,7867 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3 X", 0, 0, + { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G3", 0, 0, + { 9326,-2882,-1084,-7940,15447,2677,-2620,3090,7740 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X Mark II",0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5 X",0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G5", 0, 0, + { 9869,-2972,-942,-7314,15098,2369,-1898,2536,7282 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G6", 0, 0, + { 9876,-3774,-871,-7613,14807,3071,-1448,1305,7485 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark III", 0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X Mark II", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X Mark II", 0, 0, + { 10056,-4131,-944,-2576,11143,1625,-238,1294,5179 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9 X",0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S2 IS", 0, 0, - { 5477,-1435,-992,-1868,6639,510,-58,792,2670 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S3 IS", 0, 0, - { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S30", 0, 0, - { 10744,-3813,-1142,-7962,15966,2075,-2492,2805,7744 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S40", 0, 0, - { 8606,-2573,-949,-8237,15489,2974,-2649,3076,9100 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S45", 0, 0, // + - { 8251,-2410,-964,-8047,15430,2823,-2380,2824,8119 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S50", 0, 0, - { 8979,-2658,-871,-7721,15500,2357,-1773,2366,6634 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S60", 0, 0, - { 8794,-2482,-797,-7804,15403,2572,-1422,1996,7083 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S70", 0, 0, - { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S90", 0, 0, - { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S95", 0, 0, - { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S120", 0, 0, - { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S110", 0, 0, - { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot S100", 0, 0, - { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S2 IS", 0, 0, + { 5477,-1435,-992,-1868,6639,510,-58,792,2670 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S3 IS", 0, 0, + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S30", 0, 0, + { 10744,-3813,-1142,-7962,15966,2075,-2492,2805,7744 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S40", 0, 0, + { 8606,-2573,-949,-8237,15489,2974,-2649,3076,9100 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S45", 0, 0, // + + { 8251,-2410,-964,-8047,15430,2823,-2380,2824,8119 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S50", 0, 0, + { 8979,-2658,-871,-7721,15500,2357,-1773,2366,6634 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S60", 0, 0, + { 8794,-2482,-797,-7804,15403,2572,-1422,1996,7083 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S95", 0, 0, + { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S110", 0, 0, + { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot S100", 0, 0, + { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SD300", 0, 0, - { 6526,-1720,-1075,-1390,5945,602,-90,820,2380 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SD300", 0, 0, + { 6526,-1720,-1075,-1390,5945,602,-90,820,2380 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX1 IS", 0, 0, - { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX20 IS", 0, 0, - { 8275,-2904,-1260,-128,5305,505,51,481,2450 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX30 IS", 0, 0, - { 13014,-4698,-1026,-2001,9615,2386,-164,1423,3759 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX40 HS", 0, 0, - { 54480,-17404,-8039,-7505,44044,1136,-580,7158,11891 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX50 HS", 0, 0, - { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX60 HS", 0, 0, - { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX70 HS", 0, 0, - { 18285,-8907,-1951,-1845,10688,1323,364,1101,5139 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX110 IS", 0, 0, - { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX120 IS", 0, 0, - { 7286,-2242,-1047,41,4401,457,269,684,1864 } }, // CHDK - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX220 HS", 0, 0, - { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX710 HS", 0, 0, - { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX20 IS", 0, 0, + { 8275,-2904,-1260,-128,5305,505,51,481,2450 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX30 IS", 0, 0, + { 13014,-4698,-1026,-2001,9615,2386,-164,1423,3759 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX40 HS", 0, 0, + { 54480,-17404,-8039,-7505,44044,1136,-580,7158,11891 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX50 HS", 0, 0, + { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX70 HS", 0, 0, + { 18285,-8907,-1951,-1845,10688,1323,364,1101,5139 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX110 IS", 0, 0, + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX120 IS", 0, 0, + { 7286,-2242,-1047,41,4401,457,269,684,1864 } }, // CHDK + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX220 HS", 0, 0, + { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Canon, "PowerShot SX710 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro1", 0, 0, - { 10062,-3522,-1000,-7643,15117,2730,-765,817,7322 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro70", 34, 0, - { -5106,10695,1576,3820,53,4566,-6497,10736,6701,-3336,11887,1394 } }, - { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro90", 0, 0, - { -5912,10768,2288,4612,-989,4333,-6153,10897,5944,-2907,12288,624 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro1", 0, 0, + { 10062,-3522,-1000,-7643,15117,2730,-765,817,7322 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro70", 34, 0, + { -5106,10695,1576,3820,53,4566,-6497,10736,6701,-3336,11887,1394 } }, + { LIBRAW_CAMERAMAKER_Canon, "PowerShot Pro90", 0, 0, + { -5912,10768,2288,4612,-989,4333,-6153,10897,5944,-2907,12288,624 } }, - { LIBRAW_CAMERAMAKER_Casio, "EX-F1", 0, 0, - { 9084,-2016,-848,-6711,14351,2570,-1059,1725,6135 } }, - { LIBRAW_CAMERAMAKER_Casio, "EX-FH100", 0, 0, - { 12771,-4179,-1558,-2149,10938,1375,-453,1751,4494 } }, - { LIBRAW_CAMERAMAKER_Casio, "EX-S20", 0, 0, - { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Casio, "EX-Z750", 0, 0, - { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_Casio, "EX-Z10", 128, 0xfff, - { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Casio, "EX-F1", 0, 0, + { 9084,-2016,-848,-6711,14351,2570,-1059,1725,6135 } }, + { LIBRAW_CAMERAMAKER_Casio, "EX-FH100", 0, 0, + { 12771,-4179,-1558,-2149,10938,1375,-453,1751,4494 } }, + { LIBRAW_CAMERAMAKER_Casio, "EX-S20", 0, 0, + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Casio, "EX-Z750", 0, 0, + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, /* DJC */ + { LIBRAW_CAMERAMAKER_Casio, "EX-Z10", 128, 0xfff, + { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, /* DJC */ - { LIBRAW_CAMERAMAKER_CINE, "650", 0, 0, - { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, - { LIBRAW_CAMERAMAKER_CINE, "660", 0, 0, - { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { LIBRAW_CAMERAMAKER_CINE, "650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { LIBRAW_CAMERAMAKER_CINE, "660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, { LIBRAW_CAMERAMAKER_CINE, "", 0, 0, /* empty camera name*/ - { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, - { LIBRAW_CAMERAMAKER_Contax, "N Digital", 0, 0xf1e, - { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { LIBRAW_CAMERAMAKER_Contax, "N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, - { LIBRAW_CAMERAMAKER_DXO, "ONE", 0, 0, - { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + { LIBRAW_CAMERAMAKER_DXO, "ONE", 0, 0, + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, - { LIBRAW_CAMERAMAKER_Epson, "R-D1", 0, 0, // same CMs: R-D1, R-D1s, R-D1x - { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { LIBRAW_CAMERAMAKER_Epson, "R-D1", 0, 0, // same CMs: R-D1, R-D1s, R-D1x + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "DBP for GX680", -128, 0x0fff, - { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, /* temp, copy from S2Pro */ + { LIBRAW_CAMERAMAKER_Fujifilm, "DBP for GX680", -128, 0x0fff, + { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, /* temp, copy from S2Pro */ - { LIBRAW_CAMERAMAKER_Fujifilm, "E550", 0, 0, - { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "E900", 0, 0, - { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F5", 0, 0, // F500EXR/F505EXR; F550EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F6", 0, 0, // F600EXR/F605EXR; F660EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F77", 0, 0xfe9, // F770EXR/F775EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F7", 0, 0, // same CMs: F700, F710EXR - { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F810", 0, 0, - { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F8", 0, 0, // F800EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "F900EXR", 0, 0, - { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "E550", 0, 0, + { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F5", 0, 0, // F500EXR/F505EXR; F550EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F6", 0, 0, // F600EXR/F605EXR; F660EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F77", 0, 0xfe9, // F770EXR/F775EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F7", 0, 0, // same CMs: F700, F710EXR + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F810", 0, 0, + { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F8", 0, 0, // F800EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 100", 0, 0, // same CMs: "GFX 100", "GFX 100S"/"GFX100S", "GFX 100 IR" - { 16212,-8423,-1583,-4336,12583,1937,-195,726,6199 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 50", 0, 0, // same CMs: "GFX 50S", "GFX 50R", "GFX 50S II" - { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 100 II", 0, 0, + { 12806,-5779,-1110,-3546,11507,2318,-177,996,5715 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 100", 0, 0, // same CMs: "GFX 100", "GFX 100S"/"GFX100S", "GFX 100 IR" + { 16212,-8423,-1583,-4336,12583,1937,-195,726,6199 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "GFX 50", 0, 0, // same CMs: "GFX 50S", "GFX 50R", "GFX 50S II" + { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "HS10", 0, 0xf68, - { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0, // HS20EXR/HS22EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "HS3", 0, 0, // HS30EXR/HS33EXR/HS35EXR - { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "HS50EXR", 0, 0, - { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS10", 0, 0xf68, + { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS2", 0, 0, // HS20EXR/HS22EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS3", 0, 0, // HS30EXR/HS33EXR/HS35EXR + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "HS50EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "IS-1", 0, 0, - { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "IS Pro", 0, 0, - { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S5000", 0, 0, - { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S5100", 0, 0, - { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S5200", 0, 0, // S5200/S5600 - { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S6", 0, 0, // S6000fd/S6500fd - { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S7000", 0, 0, - { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S9000", 0, 0, // S9000/S9500 - { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S9100", 0, 0, // S9100/S9600 - { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5100", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5200", 0, 0, // S5200/S5600 + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S6", 0, 0, // S6000fd/S6500fd + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S9000", 0, 0, // S9000/S9500 + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S9100", 0, 0, // S9100/S9600 + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S100FS", -514, 0, - { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S100FS", -514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S20Pro", 0, 0, - { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S20", -512, 0x3fff, // S200EXR/S205EXR - { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S20", -512, 0x3fff, // S200EXR/S205EXR + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "SL1000", 0, 0, - { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "SL1000", 0, 0, + { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S1", 0, 0, - { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S2Pro", -128, 0, - { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S3Pro", 0, 0, - { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "S5Pro", 0, 0, - { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S2Pro", -128, 0, + { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X100F", 0, 0, - { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X100S", 0, 0, - { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X100T", 0, 0, - { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X100V", 0, 0, - { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X100", 0, 0, - { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100F", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100S", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100T", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100V", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X100", 0, 0, + { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X10", 0, 0, - { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X20", 0, 0, - { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X30", 0, 0, - { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X70", 0, 0, - { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X20", 0, 0, + { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X70", 0, 0, + { 10450,-4329,-878,-3217,11105,2421,-752,1758,6519 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "XF10", 0, 0, - { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "XF1", 0, 0, - { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "XF10", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "XQ", 0, 0, // same CMs: XQ1, XQ2 - { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "XQ", 0, 0, // same CMs: XQ1, XQ2 + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro1", 0, 0, - { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro2", 0, 0, - { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro3", 0, 0, - { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro2", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-Pro3", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A10", 0, 0, - { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A20", 0, 0, - { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A1", 0, 0, - { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A2", 0, 0, - { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A3", 0, 0, - { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A5", 0, 0, - { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-A7", 0, 0, - { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-E1", 0, 0, - { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2S", 0, 0, - { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2", 0, 0, - { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-E3", 0, 0, - { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-E4", 0, 0, - { 13426, -6334, -1177, -4244, 12136, 2371, -580, 1303, 5980 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-H1", 0, 0, - { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A10", 0, 0, + { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A20", 0, 0, + { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605} }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A3", 0, 0, + { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A5", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-A7", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2S", 0, 0, + { 11562,-5118,-961,-3022,11007,2311,-525,1569,6097 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E3", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-E4", 0, 0, + { 13426, -6334, -1177, -4244, 12136, 2371, -580, 1303, 5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-H1", 0, 0, + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { LIBRAW_CAMERAMAKER_Fujifilm, "X-H2S", 0, 0, + { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-H2", 0, 0, + { 11809, -5358, -1141, -4248, 12164, 2343, -514, 1097, 5848 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-S20", 0, 0, { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-M1", 0, 0, - { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-S10", 0, 0, - { 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-S1", 0, 0, - { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-S10", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T100", 0, 0, - { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T1", 0, 0, /* same CMs: X-T1, "X-T1IR", "X-T1 IR", X-T10 */ - { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T200", 0, 0, - { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T2", 0, 0, // same CMs: X-T2, X-T20 - { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T3", 0, 0, // same CMs: X-T3, X-T30, "X-T30 II" - { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // v.2 - { LIBRAW_CAMERAMAKER_Fujifilm, "X-T4", 0, 0, - { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T100", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T1", 0, 0, /* same CMs: X-T1, "X-T1IR", "X-T1 IR", X-T10 */ + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T200", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T2", 0, 0, // same CMs: X-T2, X-T20 + { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T3", 0, 0, // same CMs: X-T3, X-T30, "X-T30 II" + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // v.2 + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T4", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, + { LIBRAW_CAMERAMAKER_Fujifilm, "X-T5", 0, 0, + { 11809, -5358, -1141, -4248, 12164, 2343, -514, 1097, 5848 } }, - { LIBRAW_CAMERAMAKER_GITUP, "G3DUO", 130, 62000, - { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { LIBRAW_CAMERAMAKER_GITUP, "G3DUO", 130, 62000, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, - { LIBRAW_CAMERAMAKER_GITUP, "GIT2P", 4160, 0, - { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, - { LIBRAW_CAMERAMAKER_GITUP, "GIT2", 3200, 0, - { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { LIBRAW_CAMERAMAKER_GITUP, "GIT2P", 4160, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { LIBRAW_CAMERAMAKER_GITUP, "GIT2", 3200, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, - { LIBRAW_CAMERAMAKER_GoPro, "HERO5 Black", 0, 0, - { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } }, + { LIBRAW_CAMERAMAKER_GoPro, "HERO5 Black", 0, 0, + { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } }, - {LIBRAW_CAMERAMAKER_Hasselblad, "L1D-20c", 0, 0, - { 7310, -2746, -646, -2991, 10847, 2469, 163, 585, 6324}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "L1D-20c", 0, 0, + { 7310, -2746, -646, -2991, 10847, 2469, 163, 585, 6324}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-3FR", 0, 0, - { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-FFF", 0, 0, - { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated", 0, 0, - { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-3FR", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated-FFF", 0, 0, + { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "16-Uncoated", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-3FR", 0, 0, - { 8523, -3257, -280, -5078, 13458, 1743, -1449, 2961, 7809}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-FFF", 0, 0, - { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated", 0, 0, - { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-3FR", 0, 0, + { 8523, -3257, -280, -5078, 13458, 1743, -1449, 2961, 7809}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated-FFF", 0, 0, + { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "22-Uncoated", 0, 0, + { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated-FFF", 0, 0, - { 5155, -1201, 200, -5841, 13197, 2950, -1101, 2317, 6988}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated", 0, 0, - { 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated-FFF", 0, 0, + { 5155, -1201, 200, -5841, 13197, 2950, -1101, 2317, 6988}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "31-Uncoated", 0, 0, + { 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-3FR", 0, 0, - { 3904, -100, 262, -4318, 12407, 2128, -1598, 3594, 6233}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-FFF", 0, 0, - { 4739, -932, 295, -4829, 12220, 2952, -1027, 2341, 7083}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated", 0, 0, - { 3894, -110, 287, -4672, 12610, 2295, -2092, 4100, 6196}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-3FR", 0, 0, + { 3904, -100, 262, -4318, 12407, 2128, -1598, 3594, 6233}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated-FFF", 0, 0, + { 4739, -932, 295, -4829, 12220, 2952, -1027, 2341, 7083}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "39-Uncoated", 0, 0, + { 3894, -110, 287, -4672, 12610, 2295, -2092, 4100, 6196}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-3FR", 0, 0, - { 5427, -1147, 173, -3834, 12073, 1969, -1444, 3320, 5621}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-FFF", 0, 0, - { 5323, -1233, 399, -4926, 12362, 2894, -856, 2471, 5961}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated", 0, 0, - { 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-3FR", 0, 0, + { 5427, -1147, 173, -3834, 12073, 1969, -1444, 3320, 5621}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated-FFF", 0, 0, + { 5323, -1233, 399, -4926, 12362, 2894, -856, 2471, 5961}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "39-Coated", 0, 0, + { 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-3FR", 0, 0, - { 7014, -2067, -540, -4821, 13016, 1980, -1663, 3089, 6940}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-FFF", 0, 0, - { 5963, -1357, -172, -5439, 12762, 3007, -964, 2222, 7172}}, - {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5", 0, 0, - { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-3FR", 0, 0, + { 7014, -2067, -540, -4821, 13016, 1980, -1663, 3089, 6940}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5-FFF", 0, 0, + { 5963, -1357, -172, -5439, 12762, 3007, -964, 2222, 7172}}, + {LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated5", 0, 0, + { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-3FR", 0, 0, - { 6550, -1681, -399, -4626, 12598, 2257, -1807, 3354, 6486}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-FFF", 0, 0, - { 6041, -1375, -174, -5439, 10000, 3007, -930, 2145, 6923}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated", 0, 0, - { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-3FR", 0, 0, + { 6550, -1681, -399, -4626, 12598, 2257, -1807, 3354, 6486}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated-FFF", 0, 0, + { 6041, -1375, -174, -5439, 10000, 3007, -930, 2145, 6923}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "40-Coated", 0, 0, + { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-3FR", 0, 0, - { 5707, -693, -382, -4285, 12669, 1773, -1615, 3519, 5410}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-FFF", 0, 0, - { 5263, -612, 39, -4950, 12426, 2843, -935, 2423, 5941}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5", 0, 0, - { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-3FR", 0, 0, + { 5707, -693, -382, -4285, 12669, 1773, -1615, 3519, 5410}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5-FFF", 0, 0, + { 5263, -612, 39, -4950, 12426, 2843, -935, 2423, 5941}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated5", 0, 0, + { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-3FR", 0, 0, - { 5656, -659, -346, -3923, 12305, 1790, -1602, 3509, 5442}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-FFF", 0, 0, - { 5280, -614, 39, -4950, 12426, 2843, -939, 2434, 5968}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated", 0, 0, - { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-3FR", 0, 0, + { 5656, -659, -346, -3923, 12305, 1790, -1602, 3509, 5442}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated-FFF", 0, 0, + { 5280, -614, 39, -4950, 12426, 2843, -939, 2434, 5968}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-Coated", 0, 0, + { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-3FR", 0, 0, - { 10887, -6152, 1034, -3564, 12412, 4224, 63, 626, 10123}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-FFF", 0, 0, - { 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II", 0, 0, - { 8737, -4937, 830, -2860, 9961, 3390, 51, 502, 8124}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-3FR", 0, 0, + { 10887, -6152, 1034, -3564, 12412, 4224, 63, 626, 10123}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II-FFF", 0, 0, + { 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5-II", 0, 0, + { 8737, -4937, 830, -2860, 9961, 3390, 51, 502, 8124}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5", 0, 0, - { 4932,-835,141,-4878,11868,3437,-1138,1961,7067 } }, + { LIBRAW_CAMERAMAKER_Hasselblad, "50-15-Coated5", 0, 0, + { 4932,-835,141,-4878,11868,3437,-1138,1961,7067 } }, - { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated-3FR", 0, 0, - { 9296, 336, -1088, -6442, 14323, 2289, -1433, 2942, 5756}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated", 0, 0, - { 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated-3FR", 0, 0, + { 9296, 336, -1088, -6442, 14323, 2289, -1433, 2942, 5756}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "60-Coated", 0, 0, + { 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}}, - { LIBRAW_CAMERAMAKER_Hasselblad, "100-17-Coated5", 0, 0, - { 5110, -1357, -308, -5573, 12835, 3077, -1279, 2025, 7010}}, + { LIBRAW_CAMERAMAKER_Hasselblad, "100-17-Coated5", 0, 0, + { 5110, -1357, -308, -5573, 12835, 3077, -1279, 2025, 7010}}, - { LIBRAW_CAMERAMAKER_HTC, "One A9", 64, 1023, + { LIBRAW_CAMERAMAKER_Hasselblad, "100-20-Coated6", 0, 0, + { 6468,-1899,-545,-4526,12267,2542,-388,1276,6096 } }, + + { LIBRAW_CAMERAMAKER_HTC, "One A9", 64, 1023, { 101,-20,-2,-11,145,41,-24,1,56 } }, /* this is FM1 transposed */ { LIBRAW_CAMERAMAKER_Imacon, "Ixpress", 0, 0, @@ -994,6 +1015,8 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Nikon, "Df", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Z 30", 0, 0, + { 10339,-3822,-890,-4183,12023,2436,-671,1638,7049 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z 50", 0, 0, { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z 5", 0, 0, @@ -1002,7 +1025,9 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, // 'Z 6'(v.2), 'Z 6_2' { LIBRAW_CAMERAMAKER_Nikon, "Z 7", 0, 0, { 13705,-6004,-1400,-5464,13568,2062,-940,1706,7618 } }, // 'Z 7'(v.2), 'Z 7_2' - { LIBRAW_CAMERAMAKER_Nikon, "Z 9", 0, 0, + { LIBRAW_CAMERAMAKER_Nikon, "Z 8", 0, 0, + {11423,-4564,-1123,-4816,12895,2119,-210,1061,7282 } }, + { LIBRAW_CAMERAMAKER_Nikon, "Z 9", 0, 0, { 13389,-6049,-1441,-4544,12757,1969,229,498,7390 } }, { LIBRAW_CAMERAMAKER_Nikon, "Z fc", 0, 0, { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, @@ -1156,6 +1181,9 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Olympus, "OM-1", 0, 0, { 9488, -3984, -714, -2887, 10945, 2229, -137, 960, 5786 } }, + { LIBRAW_CAMERAMAKER_Olympus, "OM-5", 0, 0, + { 11896, -5110, -1076, -3181, 11378, 2048, -519, 1224, 5166 } }, + { LIBRAW_CAMERAMAKER_OmniVison, "", 16, 0x3ff, { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ @@ -1240,6 +1268,8 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { 9397,-3719,-805,-5425,13326,2309,-972,1715,6034 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S1", 0, 0, { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-S5M2", 0, 0, + { 10308, -4206, -783, -4088, 12102, 2229, -125, 1051, 5912 } }, {LIBRAW_CAMERAMAKER_Panasonic, "DC-S5", 0, 0, { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, @@ -1335,6 +1365,10 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-G8", -15, 0xfff, { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + + {LIBRAW_CAMERAMAKER_Panasonic, "DC-G9M2", 0, 0, + {8325,-3456,-623,-4330,12089,2528,-860,2646,5984}}, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-G9", -15, 0, { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } }, @@ -1352,6 +1386,8 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { 9300, -3659, -755, -2981, 10988, 2287, -190, 1077, 5016 } }, { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH5", -15, 0, { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } }, + { LIBRAW_CAMERAMAKER_Panasonic, "DC-GH6", -2048, 0, + { 7949,-3491,-710,-3435,11681,1977,-503,1622,5065} }, { LIBRAW_CAMERAMAKER_Panasonic, "DMC-GM1", -15, 0, { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, @@ -1612,10 +1648,12 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Sony, "DSC-HX9", -800, 0, // same CMs: DSC-HX95, DSC-HX99 { 13076,-5686,-1481,-4027,12851,1251,-167,725,4937 } }, - { LIBRAW_CAMERAMAKER_Sony, "ZV-1", -800, 0, + { LIBRAW_CAMERAMAKER_Sony, "ZV-1", -800, 0, // same CMs: ZV-1, ZV-1B, ZV-1M2 { 8280,-2987,-703,-3531,11645,2133,-550,1542,5312 } }, { LIBRAW_CAMERAMAKER_Sony, "ZV-E10", 0, 0, { 6355,-2067,-490,-3653,11542,2400,-406,1258,5506 } }, + { LIBRAW_CAMERAMAKER_Sony, "ZV-E1", 0, 0, + { 6912,-2127,-469,-4470,12175,2587,-398,1478,6492 } }, { LIBRAW_CAMERAMAKER_Sony, "DSC-RX100M7", -800, 0, {10315, -4390, -937, -4859, 12734, 2365, -734, 1537, 5997 } }, @@ -1677,6 +1715,9 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Sony, "ILCE-1", 0, 0, { 8161, -2947, -739, -4811, 12668, 2389, -437, 1229, 6524}}, + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM5", 0, 0, + { 8200, -2976, -719, -4296, 12053, 2532, -429, 1282, 5774 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM4", 0, 0, // same CMs: ILCE-7RM4, ILCE-7RM4A { 7662, -2686,-660,-5240, 12965,2530, -796, 1508, 6167 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7RM3", 0, 0, // same CMs: ILCE-7RM3, ILCE-7RM3A @@ -1691,6 +1732,11 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { LIBRAW_CAMERAMAKER_Sony, "ILCE-7S", 0, 0, // same CMs: ILCE-7S, ILCE-7SM2 { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7CR", 0, 0, + { 8200,-2976,-719,-4296,12053,2532,-429,1282,5774 } }, // temp + + { LIBRAW_CAMERAMAKER_Sony, "ILCE-7CM2", 0, 0, + { 7460,-2365,-588,-5687,13442,2474,-624,1156,6584 } }, // temp { LIBRAW_CAMERAMAKER_Sony, "ILCE-7C", 0, 0, { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, @@ -1714,9 +1760,14 @@ int LibRaw::adobe_coeff(unsigned make_idx, const char *t_model, { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, { LIBRAW_CAMERAMAKER_Sony, "ILCE-6600", 0, 0, { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE-6700", 0, 0, + { 6972,-2408,-600,-4330,12101,2515,-388,1277,5847 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILCE", 0, 0, // same CMs: ILCE-3000, ILCE-5000, ILCE-5100, ILCE-6000, ILCE-QX1 { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { LIBRAW_CAMERAMAKER_Sony, "ILME-FX30", 0, 0, + { 6972, -2408, -600, -4330, 12101, 2515, -388, 1277, 5847 } }, { LIBRAW_CAMERAMAKER_Sony, "ILME-FX3", 0, 0, { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } }, diff --git a/src/tables/wblists.cpp b/src/tables/wblists.cpp index 1f8ae172b..53206047f 100644 --- a/src/tables/wblists.cpp +++ b/src/tables/wblists.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: diff --git a/src/utils/curves.cpp b/src/utils/curves.cpp index b14f19b79..58a1436f4 100644 --- a/src/utils/curves.cpp +++ b/src/utils/curves.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -38,7 +38,7 @@ void LibRaw::cubic_spline(const int *x_, const int *y_, const int len) for (i = len - 1; i > 0; i--) { float _div = x[i] - x[i - 1]; - if (fabs(_div) < 1.0e-15) + if (fabsf(_div) < 1.0e-15f) _div = 1; b[i] = (y[i] - y[i - 1]) / _div; d[i - 1] = _div; diff --git a/src/utils/decoder_info.cpp b/src/utils/decoder_info.cpp index cc440db4d..3abc35e9b 100644 --- a/src/utils/decoder_info.cpp +++ b/src/utils/decoder_info.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -46,6 +46,13 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) d_info->decoder_name = "vc5_dng_load_raw_placeholder()"; #ifndef USE_GPRSDK d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; +#endif + } + else if (load_raw == &LibRaw::jxl_dng_load_raw_placeholder) + { + d_info->decoder_name = "jxl_dng_load_raw_placeholder()"; +#ifndef USE_DNGSDK + d_info->decoder_flags = LIBRAW_DECODER_UNSUPPORTED_FORMAT; #endif } else if (load_raw == &LibRaw::canon_600_load_raw) @@ -138,7 +145,7 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) else if (load_raw == &LibRaw::phase_one_load_raw_c) { d_info->decoder_name = "phase_one_load_raw_c()"; - d_info->decoder_flags = LIBRAW_DECODER_TRYRAWSPEED3; /* FIXME: need to make sure correction not applied*/ + d_info->decoder_flags = imgdata.color.phase_one_data.format == 5 ? 0: LIBRAW_DECODER_TRYRAWSPEED3; /* Use only with patched RawSpeed3; */ } else if (load_raw == &LibRaw::phase_one_load_raw_s) { @@ -194,13 +201,6 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) d_info->decoder_name = "nokia_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - else if (load_raw == &LibRaw::canon_rmf_load_raw) - { - // UNTESTED - d_info->decoder_name = "canon_rmf_load_raw()"; - } -#endif else if (load_raw == &LibRaw::panasonic_load_raw) { d_info->decoder_name = "panasonic_load_raw()"; @@ -215,6 +215,10 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) { d_info->decoder_name = "panasonicC7_load_raw()"; } + else if (load_raw == &LibRaw::panasonicC8_load_raw) + { + d_info->decoder_name = "panasonicC8_load_raw()"; + } else if (load_raw == &LibRaw::olympus_load_raw) { d_info->decoder_name = "olympus_load_raw()"; @@ -295,6 +299,12 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) { d_info->decoder_name = "sony_ljpeg_load_raw()"; } + else if (load_raw == &LibRaw::sony_ycbcr_load_raw) + { + d_info->decoder_name = "sony_ycbcr_load_raw()"; + d_info->decoder_flags = LIBRAW_DECODER_LEGACY_WITH_MARGINS; + + } else if (load_raw == &LibRaw::sony_arw_load_raw) { d_info->decoder_name = "sony_arw_load_raw()"; @@ -337,13 +347,6 @@ int LibRaw::get_decoder_info(libraw_decoder_info_t *d_info) d_info->decoder_name = "smal_v9_load_raw()"; d_info->decoder_flags = LIBRAW_DECODER_FIXEDMAXC; } -#ifdef LIBRAW_OLD_VIDEO_SUPPORT - else if (load_raw == &LibRaw::redcine_load_raw) - { - d_info->decoder_name = "redcine_load_raw()"; - d_info->decoder_flags = LIBRAW_DECODER_HASCURVE; - } -#endif else if (load_raw == &LibRaw::x3f_load_raw) { d_info->decoder_name = "x3f_load_raw()"; diff --git a/src/utils/init_close_utils.cpp b/src/utils/init_close_utils.cpp index 26478d88c..fffab4de6 100644 --- a/src/utils/init_close_utils.cpp +++ b/src/utils/init_close_utils.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -46,10 +46,7 @@ LibRaw::LibRaw(unsigned int flags) : memmgr(1024) _x3f_data = NULL; #ifdef USE_RAWSPEED - CameraMetaDataLR *camerameta = - make_camera_metadata(); // May be NULL in case of exception in - // make_camera_metadata() - _rawspeed_camerameta = static_cast(camerameta); + _rawspeed_camerameta = make_camera_metadata(); #endif callbacks.data_cb = (flags & LIBRAW_OPTIONS_NO_DATAERR_CALLBACK) ? NULL @@ -79,6 +76,7 @@ LibRaw::LibRaw(unsigned int flags) : memmgr(1024) imgdata.params.output_color = 1; imgdata.params.output_bps = 8; imgdata.params.use_fuji_rotate = 1; + imgdata.params.use_p1_correction = 1; imgdata.params.exp_shift = 1.0; imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD; imgdata.params.adjust_maximum_thr = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; @@ -118,9 +116,7 @@ LibRaw::~LibRaw() #ifdef USE_RAWSPEED if (_rawspeed_camerameta) { - CameraMetaDataLR *cmeta = - static_cast(_rawspeed_camerameta); - delete cmeta; + clear_camera_metadata(_rawspeed_camerameta); _rawspeed_camerameta = NULL; } #endif @@ -292,14 +288,13 @@ void LibRaw::recycle() MN.sony.AFMicroAdjValue = 0x7f; MN.sony.AFMicroAdjOn = -1; MN.sony.AFMicroAdjRegisteredLenses = 0xff; + MN.sony.AspectRatio = -999.f; _exitflag = 0; #ifdef USE_RAWSPEED if (_rawspeed_decoder) { - RawSpeed::RawDecoder *d = - static_cast(_rawspeed_decoder); - delete d; + clear_rawspeed_decoder(_rawspeed_decoder); } _rawspeed_decoder = 0; #endif diff --git a/src/utils/open.cpp b/src/utils/open.cpp index 12b0cb878..a1c1917cf 100644 --- a/src/utils/open.cpp +++ b/src/utils/open.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -488,6 +488,56 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) ) return LIBRAW_FILE_UNSUPPORTED; } + // Remove unsupported Nikon thumbnails + if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && !strncasecmp(imgdata.idata.model, "Z 8",3) && + imgdata.thumbs_list.thumbcount > 1) + { + int tgtidx = 0; + for (int idx = 0; idx < imgdata.thumbs_list.thumbcount && idx < LIBRAW_THUMBNAIL_MAXCOUNT; idx++) + { + int bps = imgdata.thumbs_list.thumblist[idx].tmisc & 0x1f; + if (bps > 8) // remove high-bit thumbs + { + // nothing: just skip this item + } + else + { + if (tgtidx < idx) + { + memmove(&imgdata.thumbs_list.thumblist[tgtidx], &imgdata.thumbs_list.thumblist[idx], + sizeof(imgdata.thumbs_list.thumblist[idx])); + tgtidx++; + } + else // same index, just assign next tgtidx + tgtidx = idx + 1; + } + } + if (tgtidx > 0 && tgtidx < imgdata.thumbs_list.thumbcount) + { + int selidx = 0; + INT64 maximgbits = INT64(imgdata.thumbs_list.thumblist[0].twidth) * + INT64(imgdata.thumbs_list.thumblist[0].theight) * INT64(imgdata.thumbs_list.thumblist[0].tmisc & 0x1f); + for (int i = 1; i < tgtidx; i++) + { + INT64 imgbits = INT64(imgdata.thumbs_list.thumblist[i].twidth) * + INT64(imgdata.thumbs_list.thumblist[i].theight) * + INT64(imgdata.thumbs_list.thumblist[i].tmisc & 0x1f); + if (imgbits > maximgbits) + { + selidx = i; + maximgbits = imgbits; + } + } + libraw_internal_data.internal_data.toffset = imgdata.thumbs_list.thumblist[selidx].toffset; + imgdata.thumbnail.tlength = imgdata.thumbs_list.thumblist[selidx].tlength; + libraw_internal_data.unpacker_data.thumb_format = imgdata.thumbs_list.thumblist[selidx].tformat; + imgdata.thumbnail.twidth = imgdata.thumbs_list.thumblist[selidx].twidth; + imgdata.thumbnail.theight = imgdata.thumbs_list.thumblist[selidx].theight; + libraw_internal_data.unpacker_data.thumb_misc = imgdata.thumbs_list.thumblist[selidx].tmisc; + // find another largest thumb and copy it to single thumbnail data + } + imgdata.thumbs_list.thumbcount = tgtidx > 0 ? tgtidx : 1; + } // promote the old single thumbnail to the thumbs_list if not present already if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) @@ -571,7 +621,8 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) if (load_raw == &LibRaw::panasonic_load_raw) { if (libraw_internal_data.unpacker_data.pana_encoding == 6 || - libraw_internal_data.unpacker_data.pana_encoding == 7) + libraw_internal_data.unpacker_data.pana_encoding == 7 || + libraw_internal_data.unpacker_data.pana_encoding == 8) { for (int i = 0; i < 3; i++) imgdata.color.cblack[i] = @@ -612,6 +663,13 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) else imgdata.idata.raw_count = 0; // incorrect size } + else if (libraw_internal_data.unpacker_data.pana_encoding == 8) + { + if (libraw_internal_data.unpacker_data.pana8.stripe_count > 0) + load_raw = &LibRaw::panasonicC8_load_raw; + else + imgdata.idata.raw_count = 0; // incorrect stripes count + } } #define NIKON_14BIT_SIZE(rw, rh) \ @@ -1087,6 +1145,8 @@ int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) ((MN.pentax.MultiExposure & 0x01) == 1)) imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX; + else if (makeIs(LIBRAW_CAMERAMAKER_Sony) && load_raw == &LibRaw::sony_ycbcr_load_raw) + imgdata.color.as_shot_wb_applied = LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_SONY; else imgdata.color.as_shot_wb_applied = 0; diff --git a/src/utils/phaseone_processing.cpp b/src/utils/phaseone_processing.cpp index b82988b69..6c7339223 100644 --- a/src/utils/phaseone_processing.cpp +++ b/src/utils/phaseone_processing.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. @@ -18,15 +18,23 @@ #include "../../internal/libraw_cxx_defs.h" + void LibRaw::phase_one_allocate_tempbuffer() { // Allocate temp raw_image buffer - imgdata.rawdata.raw_image = (ushort *)malloc(S.raw_pitch * S.raw_height); + if (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED) + { + // Processed by RawSpeed, raw_image contains ptr to rawspeed internals + imgdata.rawdata.raw_alloc = imgdata.rawdata.raw_image; // save for data processing and future reuse + } + imgdata.rawdata.raw_image = (ushort *)malloc(S.raw_pitch * S.raw_height); } void LibRaw::phase_one_free_tempbuffer() { - free(imgdata.rawdata.raw_image); - imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; + free(imgdata.rawdata.raw_image); + imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; + if (imgdata.process_warnings & LIBRAW_WARN_RAWSPEED3_PROCESSED) + imgdata.rawdata.raw_alloc = 0; } int LibRaw::phase_one_subtract_black(ushort *src, ushort *dest) diff --git a/src/utils/read_utils.cpp b/src/utils/read_utils.cpp index 974ffc07b..c934344c1 100644 --- a/src/utils/read_utils.cpp +++ b/src/utils/read_utils.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/utils/thumb_utils.cpp b/src/utils/thumb_utils.cpp index b468b0b06..98184e759 100644 --- a/src/utils/thumb_utils.cpp +++ b/src/utils/thumb_utils.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -14,6 +14,13 @@ */ #include "../../internal/libraw_cxx_defs.h" +#include + +void LibRaw::dng_ycbcr_thumb_loader() +{ + // Placeholder: the only known camera w/ YCC previews in DNG provides broken files + throw LIBRAW_EXCEPTION_UNSUPPORTED_FORMAT; +} void LibRaw::kodak_thumb_loader() { @@ -267,7 +274,9 @@ int LibRaw::thumbOK(INT64 maxsz) return 0; // No thumb for raw > 4Gb-1 int tsize = 0; int tcol = (T.tcolors > 0 && T.tcolors < 4) ? T.tcolors : 3; - if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) + if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_DNG_YCBCR) + return 0; // Temp: unless we get correct DNG w/ YCBCR preview + else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_JPEG) tsize = T.tlength; else if (Tformat == LIBRAW_INTERNAL_THUMBNAIL_PPM) tsize = tcol * T.twidth * T.theight; diff --git a/src/utils/utils_dcraw.cpp b/src/utils/utils_dcraw.cpp index 97d14552e..fd3085cc1 100644 --- a/src/utils/utils_dcraw.cpp +++ b/src/utils/utils_dcraw.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/utils/utils_libraw.cpp b/src/utils/utils_libraw.cpp index 15a7b6551..dc81d0dd3 100644 --- a/src/utils/utils_libraw.cpp +++ b/src/utils/utils_libraw.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -14,6 +14,7 @@ */ #include "../../internal/libraw_cxx_defs.h" +#include "../../internal/libraw_checked_buffer.h" #ifdef __cplusplus extern "C" @@ -229,7 +230,8 @@ unsigned LibRaw::capabilities() int LibRaw::is_sraw() { return load_raw == &LibRaw::canon_sraw_load_raw || - load_raw == &LibRaw::nikon_load_sraw; + load_raw == &LibRaw::nikon_load_sraw || + load_raw == &LibRaw::sony_ycbcr_load_raw; } int LibRaw::is_coolscan_nef() { @@ -245,6 +247,8 @@ int LibRaw::sraw_midpoint() { if (load_raw == &LibRaw::canon_sraw_load_raw) return 8192; + else if (load_raw == &LibRaw::sony_ycbcr_load_raw) + return 8192; // adjusted as in canon sRAW else if (load_raw == &LibRaw::nikon_load_sraw) return 2048; else @@ -671,3 +675,68 @@ void LibRaw::libraw_swab(void *arr, size_t len) #endif } + +checked_buffer_t::checked_buffer_t(short ord, int size) : _order(ord), storage(size + 64) +{ + _data = storage.data(); + _len = size; +} +checked_buffer_t::checked_buffer_t(short ord, unsigned char *dd, int ss) : _order(ord), _data(dd), _len(ss) {} + +ushort checked_buffer_t::sget2(int offset) +{ + checkoffset(offset + 2); + return libraw_sget2_static(_order, _data + offset); +} +void checked_buffer_t::checkoffset(int off) +{ + if (off >= _len) + throw LIBRAW_EXCEPTION_IO_EOF; +} +unsigned char checked_buffer_t::operator[](int idx) +{ + checkoffset(idx); + return _data[idx]; +} +unsigned checked_buffer_t::sget4(int offset) +{ + checkoffset(offset + 4); + return libraw_sget4_static(_order, _data + offset); +} + +double checked_buffer_t::sgetreal(int type, int offset) +{ + int sz = libraw_tagtype_dataunit_bytes(type); + checkoffset(offset + sz); + return libraw_sgetreal_static(_order, type, _data + offset); +} + +int checked_buffer_t::tiff_sget(unsigned save, INT64 *tag_offset, unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, + unsigned *tag_datalen, int *tag_dataunitlen) +{ + if ((((*tag_offset) + 12) > _len) || (*tag_offset < 0)) + { // abnormal, tag buffer overrun + return -1; + } + int pos = *tag_offset; + *tag_id = sget2(pos); + pos += 2; + *tag_type = sget2(pos); + pos += 2; + *tag_datalen = sget4(pos); + pos += 4; + *tag_dataunitlen = libraw_tagtype_dataunit_bytes(*tag_type); + if ((*tag_datalen * (*tag_dataunitlen)) > 4) + { + *tag_dataoffset = sget4(pos) - save; + if ((*tag_dataoffset + *tag_datalen) > _len) + { // abnormal, tag data buffer overrun + return -2; + } + } + else + *tag_dataoffset = *tag_offset + 8; + *tag_offset += 12; + return 0; +} + diff --git a/src/write/apply_profile.cpp b/src/write/apply_profile.cpp index 0bcb16dca..9c8a9fd98 100644 --- a/src/write/apply_profile.cpp +++ b/src/write/apply_profile.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/write/file_write.cpp b/src/write/file_write.cpp index bf17ea2b4..ce9073d13 100644 --- a/src/write/file_write.cpp +++ b/src/write/file_write.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/write/tiff_writer.cpp b/src/write/tiff_writer.cpp index 895b18e52..f8a126af2 100644 --- a/src/write/tiff_writer.cpp +++ b/src/write/tiff_writer.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. diff --git a/src/write/write_ph.cpp b/src/write/write_ph.cpp index 8151f108f..1c77470f8 100644 --- a/src/write/write_ph.cpp +++ b/src/write/write_ph.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * Placeholder functions to build LibRaw w/o postprocessing and preprocessing calls diff --git a/src/x3f/x3f_parse_process.cpp b/src/x3f/x3f_parse_process.cpp index 354e46737..e704d069f 100644 --- a/src/x3f/x3f_parse_process.cpp +++ b/src/x3f/x3f_parse_process.cpp @@ -1,5 +1,5 @@ /* -*- C++ -*- - * Copyright 2019-2021 LibRaw LLC (info@libraw.org) + * Copyright 2019-2024 LibRaw LLC (info@libraw.org) * LibRaw is free software; you can redistribute it and/or modify @@ -223,10 +223,15 @@ void LibRaw::parse_x3f() else { // No property list - if (imgdata.sizes.raw_width == 5888 || imgdata.sizes.raw_width == 2944 || - imgdata.sizes.raw_width == 6656 || imgdata.sizes.raw_width == 3328 || - imgdata.sizes.raw_width == 5504 || - imgdata.sizes.raw_width == 2752) // Quattro + // sd Quattro H: 6656x4480, 3328x2240, 5504x3680, 2752x1840 + // dpN Quattro: 5888x3672, 2944x1836 + // sd Quattro: 5888x3776, 2944x1888 + if ((imgdata.sizes.raw_width == 5888) || // Quattro: dp0, dp1, dp2, sd + (imgdata.sizes.raw_width == 2944) || // Quattro: dp0, dp1, dp2, sd + (imgdata.sizes.raw_width == 6656) || // sd Quattro H + (imgdata.sizes.raw_width == 3328) || // sd Quattro H + (imgdata.sizes.raw_width == 5504) || // sd Quattro H APS-C + (imgdata.sizes.raw_width == 2752)) // sd Quattro H APS-C { imgdata.idata.raw_count = 1; load_raw = &LibRaw::x3f_load_raw; @@ -254,15 +259,24 @@ void LibRaw::parse_x3f() } else if (fndsd) { - snprintf(imgdata.idata.model, 64, "%s", fndsd); - } + unsigned char *fndsdQH = (unsigned char *)lr_memmem(fndsd, 20, "sd Quattro H", 12); + if (fndsdQH) + snprintf(imgdata.idata.model, 64, "%s", fndsdQH); + else + snprintf(imgdata.idata.model, 64, "%s", fndsd); + } else #endif - if (imgdata.sizes.raw_width == 6656 || - imgdata.sizes.raw_width == 3328) - strcpy(imgdata.idata.model, "sd Quattro H"); - else - strcpy(imgdata.idata.model, "dp2 Quattro"); + if ((imgdata.sizes.raw_width == 6656) || + (imgdata.sizes.raw_width == 3328) || + (imgdata.sizes.raw_width == 5504) || + (imgdata.sizes.raw_width == 2752)) + strcpy(imgdata.idata.model, "sd Quattro H"); + else if ((imgdata.sizes.raw_height == 3776) || + (imgdata.sizes.raw_height == 1888)) + strcpy(imgdata.idata.model, "sd Quattro"); + else // defaulting to dp2 Quattro + strcpy(imgdata.idata.model, "dp2 Quattro"); } // else } From fe2247cca516d7c08534856fc01b14eb4cf000db Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:23:06 -0700 Subject: [PATCH 175/291] Add README for upgrading the internal LibRaw --- rtengine/libraw.README | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rtengine/libraw.README diff --git a/rtengine/libraw.README b/rtengine/libraw.README new file mode 100644 index 000000000..1070cd2cd --- /dev/null +++ b/rtengine/libraw.README @@ -0,0 +1,7 @@ +To upgrade the internal copy of LibRaw, + +1. Find the commit hash of the version you are upgrading to. LibRaw tags releases. For snapshots, search the commits in the master branch. +2. cd into the root of this repository. +3. Run 'git subtree --squash -P rtengine/libraw/ pull https://github.com/LibRaw/LibRaw.git '. This will use the git subtree pull command to merge all commits up to from the LibRaw GitHub repository. The --squash option squashes the commits to make the commit history cleaner. The '-P rtengine/libraw/' tells git subtree where the LibRaw project is located in this repository. +4. Fix any merge conflicts. Remember to commit the merge. +5. git subtree will create two commits. The first is the squashed commit. The second is a merge commit. Edit the merge commit message and add the message 'Upgrade LibRaw to .', where is the LibRaw version ('0.21.2' or 'snapshot 202403', for example). If there are merge conflicts, you can add the message before committing. If there are no merge conflicts or if you forgot to add the message, use 'git commit --amend' to edit the message. From bde73f5ce1206e0a1b822c4eaea3cdab64a8dde2 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 14 Apr 2024 06:14:20 +0000 Subject: [PATCH 176/291] Use makedeb to build libjxl from source --- .github/workflows/appimage.yml | 23 +++--- tools/makedeb/PKGBUILD.libjxl | 41 ++++++++++ tools/makedeb/install.sh | 135 +++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 tools/makedeb/PKGBUILD.libjxl create mode 100644 tools/makedeb/install.sh diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cc0f6b025..cecd43ad3 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -35,21 +35,20 @@ jobs: echo "Running apt update." sudo apt update echo "Installing dependencies with apt." - DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full libtcmalloc-minimal4 + DEBIAN_FRONTEND=noninteractive sudo apt install -y cmake libgtk-3-dev libgtkmm-3.0-dev liblensfun-dev librsvg2-dev liblcms2-dev libfftw3-dev libiptcdata0-dev libtiff5-dev libcanberra-gtk3-dev liblensfun-bin libexpat1-dev libbrotli-dev zlib1g-dev libinih-dev adwaita-icon-theme-full gettext libarchive-tools zstd libgif-dev libwebp-dev libwebpdemux2 + + - name: Install makedeb + run: | + echo "Installing makedeb..." + curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o makedeb.deb \ + "https://github.com/makedeb/makedeb/releases/download/v16.1.0-beta1/makedeb-beta_16.1.0-beta1_amd64_focal.deb" + DEBIAN_FRONTEND=noninteractive sudo dpkg -i makedeb.deb - name: Install libjxl + working-directory: tools/makedeb run: | - echo "Downloading and installing libhwy and libjxl..." - VERSION_UBUNTU=20.04 - VERSION_JXL=0.10.2 - DEB_URL_HWYDEV="https://launchpad.net/~ubuntuhandbook1/+archive/ubuntu/apps/+files/libhwy-dev_0.16.0-0focal1_amd64.deb" - DEB_URL_HWY="https://launchpad.net/~ubuntuhandbook1/+archive/ubuntu/apps/+files/libhwy0_0.16.0-0focal1_amd64.deb" - curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libhwy-dev.deb "$DEB_URL_HWYDEV" - curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libhwy.deb "$DEB_URL_HWY" - curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libjxl-debs.tar.gz \ - "https://github.com/libjxl/libjxl/releases/download/v${VERSION_JXL}/jxl-debs-amd64-ubuntu-${VERSION_UBUNTU}-v${VERSION_JXL}.tar.gz" - tar xf libjxl-debs.tar.gz - DEBIAN_FRONTEND=noninteractive sudo dpkg -i libhwy-dev.deb libhwy.deb jxl_${VERSION_JXL}_amd64.deb libjxl-dev_${VERSION_JXL}_amd64.deb libjxl_${VERSION_JXL}_amd64.deb + echo "Building and installing libjxl..." + makedeb -si --no-confirm -p PKGBUILD.libjxl - name: Install Exiv2 run: | diff --git a/tools/makedeb/PKGBUILD.libjxl b/tools/makedeb/PKGBUILD.libjxl new file mode 100644 index 000000000..b63801812 --- /dev/null +++ b/tools/makedeb/PKGBUILD.libjxl @@ -0,0 +1,41 @@ +# Maintainer: RawTherapee Developers + +_pkgname="libjxl" +pkgname="$_pkgname" +pkgver='0.10.2' +pkgrel='1' +pkgdesc='JPEG XL image format reference implementation' +url='https://github.com/libjxl/libjxl' +license=('BSD') +arch=('amd64') + +depends=('libgif-dev' 'libjpeg-dev' 'libopenexr-dev' 'libpng-dev' 'libwebp-dev') +makedepends=('cmake' 'pkg-config' 'libbrotli-dev' 'libgflags-dev') + +_pkgsrc="$_pkgname" +source=("git+$url.git#tag=v$pkgver") +sha256sums=('SKIP') + +prepare() { + cd "$_pkgsrc" + git submodule update --init --recursive --depth 1 --recommend-shallow +} + +build() { + local _cmake_options=( + -B build + -S "$_pkgsrc" + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX='/usr' + -DJPEGXL_FORCE_SYSTEM_BROTLI=ON + -DBUILD_TESTING=OFF + -Wno-dev + ) + + cmake "${_cmake_options[@]}" + cmake --build build --parallel +} + +package() { + DESTDIR="$pkgdir" cmake --install build +} diff --git a/tools/makedeb/install.sh b/tools/makedeb/install.sh new file mode 100644 index 000000000..409c0f5a1 --- /dev/null +++ b/tools/makedeb/install.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# The installation script for makedeb. This is the script that's shown and gets ran from https://makedeb.org. +set -e + +# Handy env vars. +MAKEDEB_RELEASE="${MAKEDEB_RELEASE:-}" +makedeb_url='makedeb.org' +color_normal="$(tput sgr0)" +color_bold="$(tput bold)" +color_green="$(tput setaf 77)" +color_orange="$(tput setaf 214)" +color_blue="$(tput setaf 14)" +color_red="$(tput setaf 202)" +color_purple="$(tput setaf 135)" +noninteractive_mode=0 +apt_args=() + +# Handy functions. +msg() { + echo "${color_blue}[>]${color_normal} ${1}" +} + +error() { + echo "${color_red}[!]${color_normal} ${1}" +} + +question() { + echo "${color_purple}[?]${color_normal} ${1}" +} + +die_cmd() { + error "${1}" + exit 1 +} + +answered_yes() { + if [[ "${1}" == "" || "${1,,}" == "y" ]]; then + return 0 + else + return 1 + fi +} + +# Pre-checks. +if [[ "${UID}" == "0" ]]; then + die_cmd "This script is not allowed to be run under the root user. Please run as a normal user and try again." +fi + +# Program start. +echo "-------------------------" +echo "${color_green}[#]${color_normal} ${color_orange}makedeb Installer${color_normal} ${color_green}[#]${color_normal}" +echo "-------------------------" +echo + +if ! echo "${-}" | grep -q i; then + msg "Running in noninteractive mode." + noninteractive_mode=1 + export DEBIAN_FRONTEND=noninteractive + apt_args+=('-y') +fi + +msg "Ensuring needed packages are installed..." +if ! sudo apt-get update "${apt_args[@]}"; then + die_cmd "Failed to update APT cache." +fi + +missing_dependencies=() +dpkg-query -W 'wget' > /dev/null 2>&1 || missing_dependencies+=('wget') +dpkg-query -W 'gpg' > /dev/null 2>&1 || missing_dependencies+=('gpg') + +if ! ( test -z "${missing_dependencies[*]}" || sudo apt-get install "${apt_args[@]}" --mark-auto "${missing_dependencies[@]}" ); then + die_cmd "Failed to install needed packages." +fi + +echo + +if (( "${noninteractive_mode}" )) && [[ "${MAKEDEB_RELEASE:+x}" == '' ]]; then + error "The script was ran in noninteractive mode, but no makedeb package was specified to install." + error "Please specify a package to install via the 'MAKEDEB_RELEASE' environment variable." + die_cmd "Available packages are 'makedeb', 'makedeb-beta', and 'makedeb-alpha'." +elif [[ "${MAKEDEB_RELEASE:+x}" == '' ]]; then + msg "Multiple releases of makedeb are available for installation." + msg "Currently, you can install one of 'makedeb', 'makedeb-beta', or" + msg "'makedeb-alpha'." + + while true; do + read -p "$(question "Which release would you like? ")" MAKEDEB_RELEASE + + if ! echo "${MAKEDEB_RELEASE}" | grep -qE '^makedeb$|^makedeb-beta$|^makedeb-alpha$'; then + error "Invalid response: ${MAKEDEB_RELEASE}" + continue + fi + + break + done + + echo +fi + +case "${MAKEDEB_RELEASE}" in + makedeb|makedeb-alpha|makedeb-beta) + ;; + *) + echo + error "Invalid \$MAKEDEB_RELEASE: '${MAKEDEB_RELEASE}'" + exit 1 ;; +esac + +msg "Setting up makedeb APT repository..." +if ! wget -qO - "https://proget.${makedeb_url}/debian-feeds/makedeb.pub" | gpg --dearmor | sudo tee /usr/share/keyrings/makedeb-archive-keyring.gpg 1> /dev/null; then + die_cmd "Failed to set up makedeb APT repository." +fi +echo "deb [signed-by=/usr/share/keyrings/makedeb-archive-keyring.gpg arch=all] https://proget.${makedeb_url} makedeb main" | sudo tee /etc/apt/sources.list.d/makedeb.list 1> /dev/null + +msg "Updating APT cache..." +if ! sudo apt-get update "${apt_args[@]}"; then + die_cmd "Failed to update APT cache." +fi + +echo +msg "Installing '${MAKEDEB_RELEASE}'..." +if ! sudo apt-get install "${apt_args[@]}" -- "${MAKEDEB_RELEASE}"; then + die_cmd "Failed to install package." +fi + +msg "Finished! If you need help of any kind, feel free to reach out:" +echo +msg "${color_bold}makedeb Homepage:${color_normal} https://${makedeb_url}" +msg "${color_bold}makedeb Package Repository:${color_normal} https://mpr.${makedeb_url}" +msg "${color_bold}makedeb Documentation:${color_normal} https://docs.${makedeb_url}" +msg "${color_bold}makedeb Support:${color_normal} https://docs.${makedeb_url}/support/obtaining-support" +echo +msg "Enjoy makedeb!" + +# vim: set sw=4 expandtab: From 1ad5ec3e9ef779d52614e38f6ea4252817109e1d Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 14 Apr 2024 08:02:20 +0000 Subject: [PATCH 177/291] Remove makedeb installer script --- tools/makedeb/install.sh | 135 --------------------------------------- 1 file changed, 135 deletions(-) delete mode 100644 tools/makedeb/install.sh diff --git a/tools/makedeb/install.sh b/tools/makedeb/install.sh deleted file mode 100644 index 409c0f5a1..000000000 --- a/tools/makedeb/install.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -# The installation script for makedeb. This is the script that's shown and gets ran from https://makedeb.org. -set -e - -# Handy env vars. -MAKEDEB_RELEASE="${MAKEDEB_RELEASE:-}" -makedeb_url='makedeb.org' -color_normal="$(tput sgr0)" -color_bold="$(tput bold)" -color_green="$(tput setaf 77)" -color_orange="$(tput setaf 214)" -color_blue="$(tput setaf 14)" -color_red="$(tput setaf 202)" -color_purple="$(tput setaf 135)" -noninteractive_mode=0 -apt_args=() - -# Handy functions. -msg() { - echo "${color_blue}[>]${color_normal} ${1}" -} - -error() { - echo "${color_red}[!]${color_normal} ${1}" -} - -question() { - echo "${color_purple}[?]${color_normal} ${1}" -} - -die_cmd() { - error "${1}" - exit 1 -} - -answered_yes() { - if [[ "${1}" == "" || "${1,,}" == "y" ]]; then - return 0 - else - return 1 - fi -} - -# Pre-checks. -if [[ "${UID}" == "0" ]]; then - die_cmd "This script is not allowed to be run under the root user. Please run as a normal user and try again." -fi - -# Program start. -echo "-------------------------" -echo "${color_green}[#]${color_normal} ${color_orange}makedeb Installer${color_normal} ${color_green}[#]${color_normal}" -echo "-------------------------" -echo - -if ! echo "${-}" | grep -q i; then - msg "Running in noninteractive mode." - noninteractive_mode=1 - export DEBIAN_FRONTEND=noninteractive - apt_args+=('-y') -fi - -msg "Ensuring needed packages are installed..." -if ! sudo apt-get update "${apt_args[@]}"; then - die_cmd "Failed to update APT cache." -fi - -missing_dependencies=() -dpkg-query -W 'wget' > /dev/null 2>&1 || missing_dependencies+=('wget') -dpkg-query -W 'gpg' > /dev/null 2>&1 || missing_dependencies+=('gpg') - -if ! ( test -z "${missing_dependencies[*]}" || sudo apt-get install "${apt_args[@]}" --mark-auto "${missing_dependencies[@]}" ); then - die_cmd "Failed to install needed packages." -fi - -echo - -if (( "${noninteractive_mode}" )) && [[ "${MAKEDEB_RELEASE:+x}" == '' ]]; then - error "The script was ran in noninteractive mode, but no makedeb package was specified to install." - error "Please specify a package to install via the 'MAKEDEB_RELEASE' environment variable." - die_cmd "Available packages are 'makedeb', 'makedeb-beta', and 'makedeb-alpha'." -elif [[ "${MAKEDEB_RELEASE:+x}" == '' ]]; then - msg "Multiple releases of makedeb are available for installation." - msg "Currently, you can install one of 'makedeb', 'makedeb-beta', or" - msg "'makedeb-alpha'." - - while true; do - read -p "$(question "Which release would you like? ")" MAKEDEB_RELEASE - - if ! echo "${MAKEDEB_RELEASE}" | grep -qE '^makedeb$|^makedeb-beta$|^makedeb-alpha$'; then - error "Invalid response: ${MAKEDEB_RELEASE}" - continue - fi - - break - done - - echo -fi - -case "${MAKEDEB_RELEASE}" in - makedeb|makedeb-alpha|makedeb-beta) - ;; - *) - echo - error "Invalid \$MAKEDEB_RELEASE: '${MAKEDEB_RELEASE}'" - exit 1 ;; -esac - -msg "Setting up makedeb APT repository..." -if ! wget -qO - "https://proget.${makedeb_url}/debian-feeds/makedeb.pub" | gpg --dearmor | sudo tee /usr/share/keyrings/makedeb-archive-keyring.gpg 1> /dev/null; then - die_cmd "Failed to set up makedeb APT repository." -fi -echo "deb [signed-by=/usr/share/keyrings/makedeb-archive-keyring.gpg arch=all] https://proget.${makedeb_url} makedeb main" | sudo tee /etc/apt/sources.list.d/makedeb.list 1> /dev/null - -msg "Updating APT cache..." -if ! sudo apt-get update "${apt_args[@]}"; then - die_cmd "Failed to update APT cache." -fi - -echo -msg "Installing '${MAKEDEB_RELEASE}'..." -if ! sudo apt-get install "${apt_args[@]}" -- "${MAKEDEB_RELEASE}"; then - die_cmd "Failed to install package." -fi - -msg "Finished! If you need help of any kind, feel free to reach out:" -echo -msg "${color_bold}makedeb Homepage:${color_normal} https://${makedeb_url}" -msg "${color_bold}makedeb Package Repository:${color_normal} https://mpr.${makedeb_url}" -msg "${color_bold}makedeb Documentation:${color_normal} https://docs.${makedeb_url}" -msg "${color_bold}makedeb Support:${color_normal} https://docs.${makedeb_url}/support/obtaining-support" -echo -msg "Enjoy makedeb!" - -# vim: set sw=4 expandtab: From 8d4c12b00d3726a1861d4f06024ec0916645399a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 Apr 2024 12:03:50 -0700 Subject: [PATCH 178/291] Publish LibRaw pre-dev builds --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5d36fc444..318a90c28 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Lawrence37:libraw-copylib"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 198098f29..cdd1f9f31 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Lawrence37:libraw-copylib"]' jobs: build: From 8e312d9c02241031fa091db50546d16d147b17be Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 15 Apr 2024 07:47:19 +0200 Subject: [PATCH 179/291] Local Adjustments - Cam16 - lacam16n2 (new) (#7010) * Restore settings and options * Clean code and windows.yml * Gui improvment * Fixed wrong value maxicam * Change GUI TRC and Log encoding and sigmoid * Clean code locallabtools2 * Fomat locallabtools2 * New calcualtion gray when using Q * Improve sigmoid Q with meanQ * Change labels and tooltip * Change DR with log * Change location GUI TRC * Change GUI sigmoid hide - show * Fixed bug with trc * Added whites to TRC & whites * Small modification whites - comment code * Change GUI and selection for sigmoid and log encoding Q * Change yml worksflow * Added cat to workingtrc rtthumbnail * Delete entries in defualt languages * Blacks and whites distribution * Change tooltips * Fixed some issues * Change GUI hide to set_sensitive * first step white and black log encoding * GUI Labels - tooltips * Compress brightness log encoding * Change compression threshold * Clean procparams * Improve GUI and threshold compression * Improvment GUI and tooltips * First step primaries cam16 * Primaries loc step 2 * Primaries loc step 3 * jdcmax primaries - format iplab2rgb * Improve GUI * Beta RGB primaries and message * Change tooltips * Change order prim * CIExy diagram step 1 * CIExy step 2 * CIExy step 2 * CIExy diagram step 4 * CIExy diagram step 5 * Change improccordinator and locallabtool2s listener * Forgoten delete in improccordinator * Disable setListener * Improve GUI and behavior TRC and Primaries * TRC primaries - illuminant step 1 * TRC primaries - illuminant step 2 * TRC primaries - illuminant step 3 * TRC primaries - illuminant step 4 * Gamut control - remove old listener and added listener locallabcieLC * publish pre dev labels windows appimage * publish pre dev labels windows appimage [] * Move log encoding cie - step 1 * Step 2 * Move Log encoding CIE and improve GUI step 3 * Pre Ciecam midtones step 1 * Mid tones step 2 and tooltips * Forgoten label and tooltips * Improve tooltips - and change yml files * Include repository in appimage and windows.yml - change labels * Forgotten surroundcie in procparams.cc * Improve GUI with expander - clean code * Change tooltip * Clean locallabtools2 - improve Jpro * Bypass Ciecam step 1 * step 2 * Step 3 * Change settings - improve GUI * Clean code * Improve sigmoid cam16 * Improve sigmoid cam16 * Added illuminant E to illmethod * Change iccmatrices * Working profile JDCmax stdA and Abstract Profile * Pre-ciecam JDCmax stdA * Abstract profile - cat method step 1 * Step 3 * Step 4 and various changes * Enable default gamutcontrol - improve GUI * Refine color pre-ciecam * Step 2 * step 3 * Step - 4 * Refine colors Abstract profiles * Expander true Abstract Profile * Clean and comment code * Tooltip pre-ciecam * Change tooltips * Improve GUI free primaries * Labgrid dominant color * Shift dominant color step 1 * Shift xy dominant color * History msg shift * Fixed various bad behavior - change scalrefi * Improve behavior DR vs deltaE - log encoding and pre-ciecam * Limited reduce deltaE to 1 - comment code * Improve behavior TIF/JPG * Forgotten code * Various small changes to refinement color pre-ciecam * Foramt iplab2rgb and simpleprocees - small change meanx meany * Bad behavior with simpleprocess abstract profile and pre-ciecam * Re-enable code for simpleprocess * Iprove iplab2rgb * Improve GUI if selection Jz * provis with precision * Chnage GUI log encoding basic - improve shiftxl shiftyl pre-ciecam * Improve GUI with expanders * Change location pre-ciecam expander * Change label tooltip pre-ciecam * Improve white distribution and equalizer * Bad behavior Source data adjustments * Comment code * Improve Dynamic Range Compression - for some images with very high DR * Clean code * Improve TM fattal with saturation control in LA * saturation control fattal LA * RE-order paramsedit * Change local contrast in LA - log encoding and Cam16 * LA settings avoidcolorshift XYZabsolute * Change GUI precision blackEv WhiteEv BlackEvjz WhiteEvjz * Check button smoothcie - smooth highlights * Change order midtones - log encoding - other method smooth * Change maximum gamma in TRC cam16 * Change maximum slope in TRC cam16 * refine smooth highlights * Small improvment - comment code * Bad behavior - black screen - in Cam16 * setLogscale for slopjcie * Change source data GUI - PQ and other DR functions * PQ mode advanced - adjustments and tooltip * Comment and clean code * Simplified GUI in Basic mode - Source Data Adjustments * Added primaries to source date adjustements - fix basic problem * GUI graduaded filter cie cam16 * Graduated filter - LA Color appearance * More illuminant cam16 - D120 - Tungsten 2000K - Tungsten 1500K * Abstract profile ICM - shift x - shift y * Frame color dominant Abstract profile * Frame color dominant Abstract profile * Illuminant E - abstract profile * Abstact profile - midtones * Abstrcat profile - smooth highlights checkbutton * Abstract Profile - Smooth highligts rtengine * Bad behavior LA gamut - re-enabled Munsell in settings * adapts Abstract profile and auto-match tone curve * Change chromaticity curve c(h) - ppversion 351 and procparams * icmpanel fixed bad wmidtcie * Change in procparams assignfromkeyfile color Management * Remove message in console * Missing code procparams.cc wcat * Clean message in console * Disable ppversion 351 - surround extremely dark * Choice surround scene Disable ciecam * Improve GUI for surround Disable Ciecam * Small change gamutcontrol - message g0..g5 verbose * Remove gautcontrol on limits * Strength log encoding - Source data adjustments * Fixed genral bug in lacam16n - bad behavior color * Checkbutton saturation control - Cam16 log encoding * Change default saturation controle log encoding - false * GUI LA Log encoding - Strength - saturation control - part 1 * Checkbox saturation control LA Log encoding * Change repartition GUI brightnees - hue - chroma * Hide primaries and illuminant in standard mode * Merge with dev 2 * reduces sigmoid Q contrast * Provisory disable Sigmoid Q * Re-enable sigmoid function complexity mode * Re-enable log encoding Q - with Ciecam * GUI improvments - small code improvments * Change tooltip * Simplify GUI mode Basic - Standard - added tooltip * Change tooltip - LA settings - Avoid color shift * hope to fix the bug between Jz and Cam16 * Another change for Jz - format astyle locallabtool2.cc * Clean code GUI - remove Zcam * Change label in Recovery based on luminance mask * Reduces minimum spot size from 2 to 1.5 * Improve behavior GUI with Jzczhz * Clean code iplocallab.cc * Small improvement ciecam02.cc * Fixed bad behvior GUI and code between Cam16 and Jzczhz * Improve Jz and surround effects * Improve Jz and Local contrast Cam16 & Jz taking account surround * Disable local contrast if cam16 and not ciecam surround * Restore epsil 0.001 loccont * Improve local contrast when surround low and Jz * Clean code locallabtool2 - weakened a little Local Contrast in connection with surround * Remove Laplacian threshold in Cam16 and JzCzHz mask * Simplify Mask for JzCzHz * Enable choice complexity mask in mode advanced * Solved bad behavior GUI masks * Optimize GUI mask Jz and cam16 * Change 3 icon .png without png * Remove wrong message in console without problem * Remove warning with & in some tooltips and TP_WBALANCE_AUTO_HEADER * Smoothcie Method GUI * Replace checkbutton smooth highlight bya combobox * Improve behavior GUI - CIECAM - advanced - tempout and greenout * Fixed - I hope - crash when delete spot and cam16 * Clean code with maxcam and dependencies * Added Smooth highlight rolloff or not * Improve smooth lights - gamma mode only - standard and advanced - gray balance * Improve Smoothing lights - take into account the 2 Yb * Change tooltip * Chnage wrong lable scope => slope * Clean and comment code * Reduces the effect of - Smoothing light -Ev mode - Small change range Slope * Scale Yb scene white whiteEv * Hide Scale in some GUI cases * Clean comment code Smotth and TM function * Change GUI - Smooth highlights and tone mapping - allows also Basic * Change labels * Change tooltip * Remove arrow.cur in windows.yml as suggested by Lawrence37 * Reverse last changes * Change limits slope based in SDA * Clean locallabtools2.cc * Set minimum slope based to 0.6 * Change label highlight * Change listener scene parameters to GUI * Clean code sine changes listener * Limits Blackev Whiteev values in slope base to avoid crash * Change a little limits BlackEv WhiteEv * Small changes in console - remove warnings * Change XYZ relative - avoid color shift * Improve gamutmap * re build gamutmap --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 157 +- rtengine/ciecam02.cc | 2 +- rtengine/color.cc | 347 ++- rtengine/color.h | 47 +- rtengine/dcrop.cc | 71 +- rtengine/iccmatrices.h | 38 + rtengine/iccstore.cc | 6 +- rtengine/improccoordinator.cc | 266 +- rtengine/improccoordinator.h | 2 + rtengine/improcfun.h | 26 +- rtengine/iplab2rgb.cc | 1226 +++++--- rtengine/iplocallab.cc | 5331 ++++++++++++++++++++------------ rtengine/iptoneequalizer.cc | 35 +- rtengine/procevents.h | 3 +- rtengine/procparams.cc | 474 ++- rtengine/procparams.h | 102 +- rtengine/rawimagesource.cc | 2 +- rtengine/refreshmap.cc | 2 +- rtengine/rtengine.h | 38 +- rtengine/rtthumbnail.cc | 47 +- rtengine/settings.h | 2 +- rtengine/simpleprocess.cc | 297 +- rtgui/colorappearance.cc | 9 +- rtgui/colortoning.cc | 10 +- rtgui/controlspotpanel.cc | 9 +- rtgui/iccprofilecreator.cc | 23 +- rtgui/icmpanel.cc | 330 +- rtgui/icmpanel.h | 33 +- rtgui/labgrid.cc | 71 +- rtgui/labgrid.h | 27 +- rtgui/locallab.cc | 65 +- rtgui/locallab.h | 17 +- rtgui/locallabtools.cc | 33 +- rtgui/locallabtools.h | 209 +- rtgui/locallabtools2.cc | 3314 +++++++++++++++----- rtgui/options.cc | 6 + rtgui/paramsedited.cc | 579 +++- rtgui/paramsedited.h | 89 +- rtgui/wavelet.cc | 6 +- 41 files changed, 9618 insertions(+), 3737 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cf82dafb8..fd2652345 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:lacam16n2"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6963df7c9..2f752f978 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:lacam16n2"]' jobs: build: diff --git a/rtdata/languages/default b/rtdata/languages/default index a6a8cdc5c..88e2f68f2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1311,7 +1311,7 @@ HISTORY_MSG_1078;Local - Red and skin protection HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +HISTORY_MSG_1082;Local - CIECAM Auto threshold HISTORY_MSG_1083;Local - CIECAM Hue HISTORY_MSG_1084;Local - Uses Black Ev - White Ev HISTORY_MSG_1085;Local - Jz lightness @@ -1427,22 +1427,79 @@ HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy HISTORY_MSG_ICM_AINTENT;Abstract profile intent HISTORY_MSG_ICM_BLUX;Primaries Blue X HISTORY_MSG_ICM_BLUY;Primaries Blue Y +HISTORY_MSG_ICM_CAT;Matrix adaptation HISTORY_MSG_ICM_FBW;Black and White HISTORY_MSG_ICM_GAMUT;Gamut control HISTORY_MSG_ICM_GREX;Primaries Green X HISTORY_MSG_ICM_GREY;Primaries Green Y +HISTORY_MSG_ICM_MIDTCIE;Midtones HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type HISTORY_MSG_ICM_PRESER;Preserve neutral HISTORY_MSG_ICM_REDX;Primaries Red X HISTORY_MSG_ICM_REDY;Primaries Red Y +HISTORY_MSG_ICM_REFI;Refinement Colors +HISTORY_MSG_ICM_SHIFTX;Refinement Colors - shift x +HISTORY_MSG_ICM_SHIFTY;Refinement Colors - shift y +HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +HISTORY_MSG_ICM_TRCEXP;Abstract Profile HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method HISTORY_MSG_ILLUM;CAL - SC - Illuminant +HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local CIECAM - gradient angle +HISTORY_MSG_LOCAL_CIE_BRICOMP;Local CIECAM Brightness compression +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local CIECAM Brightness compression threshold +HISTORY_MSG_LOCAL_CIE_CAT;Matrix adaptation +HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local JzCzHz Local contrast +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local CIECAM All mask tools +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local CIECAM Pre-Cam +HISTORY_MSG_LOCAL_CIE_GAM;Local CIECAM Gamma +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local CIECAM Gamut +HISTORY_MSG_LOCAL_CIE_ILL;Local CIECAM TRC Illuminant +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local CIECAM Log encoding Q +HISTORY_MSG_LOCAL_CIE_MIDT;Local CIECAM Mid Tones +HISTORY_MSG_LOCAL_CIE_NORM;Local CIECAM Normalize L +HISTORY_MSG_LOCAL_CIE_PRIM;Local CIECAM TRC Primaries +HISTORY_MSG_LOCAL_CIE_REFI;Local CIECAM Refinement Colors +HISTORY_MSG_LOCAL_CIE_SIG;Sigmoid +HISTORY_MSG_LOCAL_CIE_SIGADAP;Local CIECAM Sigmoid adaptability +HISTORY_MSG_LOCAL_CIE_SIGMET;Local CIECAM - Sigmoid method +HISTORY_MSG_LOCAL_CIE_SLOP;Local CIECAM - Slope +HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local CIECAM - Gray balance +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local CIECAM - Smooth lights method +HISTORY_MSG_LOCAL_CIE_STRGRAD;Local CIECAM - gradient strength L +HISTORY_MSG_LOCAL_CIE_TRC;Local CIECAM - TRC +HISTORY_MSG_LOCAL_CIE_REDXL;Local CIECAM - Red X +HISTORY_MSG_LOCAL_CIE_REDYL;Local CIECAM - Red Y +HISTORY_MSG_LOCAL_CIE_GREXL;Local CIECAM - Green X +HISTORY_MSG_LOCAL_CIE_GREYL;Local CIECAM - Green Y +HISTORY_MSG_LOCAL_CIE_BLACKS;Local CIECAM - Blacks distribution +HISTORY_MSG_LOCAL_CIE_BLUXL;Local CIECAM - Blue X +HISTORY_MSG_LOCAL_CIE_BLUYL;Local CIECAM - Blue Y +HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local CIECAM - Shift x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local CIECAM - Shift y +HISTORY_MSG_LOCAL_CIE_SMOOTH;Local CIECAM - Scale Yb Scene +HISTORY_MSG_LOCAL_CIE_SATCIE;Local CIECAM - Saturation control +HISTORY_MSG_LOCAL_CIE_STRLOG;Local CIECAM - Log encoding strength +HISTORY_MSG_LOCAL_CIE_WHITES;Local CIECAM - Whites distribution +HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local Cie mask blur contrast +HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local Cie mask blur fftw +HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local Cie mask blur radius +HISTORY_MSG_LOCAL_CIEMASK_CHH;Local Cie mask curve hh +HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local Cie mask highlights +HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local Cie mask shadows +HISTORY_MSG_LOCAL_CIEMASK_STRU;Local Cie mask structure +HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local Cie mask structure as tool +HISTORY_MSG_LOCAL_CIEMASK_WLC;Local CIECAM mask wavelet Lc +HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local CIECAM mask wavelet levels +HISTORY_MSG_LOCAL_LOG_BLACKS;Local Log - Blacks distribution +HISTORY_MSG_LOCAL_LOG_COMPR;Local Log - Compress brightness +HISTORY_MSG_LOCAL_LOG_SAT;Local Log - Saturation control +HISTORY_MSG_LOCAL_LOG_WHITES;Local Log - Whites distribution HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast @@ -2175,6 +2232,7 @@ TC_PRIM_GREX;Gx TC_PRIM_GREY;Gy TC_PRIM_REDX;Rx TC_PRIM_REDY;Ry +TC_PRIM_REFI;Refine colors (white-point) THRESHOLDSELECTOR_B;Bottom THRESHOLDSELECTOR_BL;Bottom-left THRESHOLDSELECTOR_BR;Bottom-right @@ -2662,9 +2720,16 @@ TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile TP_ICM_TONECURVE;Tone curve TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. TP_ICM_TRCFRAME;Abstract Profile -TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. TP_ICM_WORKINGPROFILE;Working Profile +TP_ICM_WORKING_CAT;Matrix adaptation +TP_ICM_WORKING_CAT_BRAD;Bradford +TP_ICM_WORKING_CAT_CAT16;Cat16 +TP_ICM_WORKING_CAT_CAT02;Cat02 +TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default Bradford +TP_ICM_WORKING_CAT_VK;Von Kries +TP_ICM_WORKING_CAT_XYZ;XYZ scale TP_ICM_WORKING_CIEDIAG;CIE xy diagram TP_ICM_WORKING_ILLU;Illuminant TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2676,10 +2741,13 @@ TP_ICM_WORKING_ILLU_D60;D60 TP_ICM_WORKING_ILLU_D65;D65 TP_ICM_WORKING_ILLU_D80;D80 TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_E;E TP_ICM_WORKING_ILLU_NONE;Default TP_ICM_WORKING_ILLU_STDA;stdA 2875K +TP_ICM_WORKING_NON;None TP_ICM_WORKING_PRESER;Preserves Pastel tones TP_ICM_WORKING_PRIM;Destination primaries +TP_ICM_WORKING_PRIM_TOOLTIP;Destination primaries (Advanced): which allows you to change the destination primaries to restore or change image color (saturation), the color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are not too different, 'Working Profiles' are not modified. Perform a gamut control.\nWhen 'Custom LA (sliders)' is selected you can modify the values of the 3 primaries Red, Green, Blue for X and Y. TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 @@ -2689,7 +2757,9 @@ TP_ICM_WORKING_PRIM_BRU;BruceRGB TP_ICM_WORKING_PRIM_BST;BestRGB TP_ICM_WORKING_PRIM_CUS;Custom (sliders) TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA TP_ICM_WORKING_PRIM_NONE;Default TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 @@ -2770,9 +2840,9 @@ TP_LOCALLAB_AMOUNT;Amount TP_LOCALLAB_ARTIF;Shape detection TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -TP_LOCALLAB_AUTOGRAYCIE;Auto +TP_LOCALLAB_AUTOGRAYCIE;Automatic TP_LOCALLAB_AVOID;Avoid color shift -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. TP_LOCALLAB_AVOIDMUN;Munsell correction only TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2815,9 +2885,12 @@ TP_LOCALLAB_BUTTON_DEL;Delete TP_LOCALLAB_BUTTON_DUPL;Duplicate TP_LOCALLAB_BUTTON_REN;Rename TP_LOCALLAB_BUTTON_VIS;Show/Hide +TP_LOCALLAB_BWEVNONE;None +TP_LOCALLAB_BWEVSIG;Activated +TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. For example to match Cam16 processing with the maximum monitor brightness of 400cd/m2. TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments TP_LOCALLAB_CAMMODE;CAM model TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2844,6 +2917,11 @@ TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) +TP_LOCALLAB_CIE_SMOOTH_NONE;None +TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation +TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based TP_LOCALLAB_CIEC;Use Ciecam environment parameters TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIECOLORFRA;Color @@ -2878,10 +2956,14 @@ TP_LOCALLAB_COLORSCOPE;Scope (color tools) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. TP_LOCALLAB_COLOR_CIE;Color curve TP_LOCALLAB_COLOR_TOOLNAME;Color & Light +TP_LOCALLAB_COLORFRAME;Dominant color TP_LOCALLAB_COL_NAME;Name TP_LOCALLAB_COL_VIS;Status TP_LOCALLAB_COMPFRA;Directional contrast TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +TP_LOCALLAB_COMPRCIE;Brightness compression +TP_LOCALLAB_COMPRCIETH;Compression threshold +TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the theshold slider value. To use in conjunction with Whites distribution. TP_LOCALLAB_CONTCOL;Contrast threshold TP_LOCALLAB_CONTFRA;Contrast by level TP_LOCALLAB_CONTRAST;Contrast @@ -2912,7 +2994,7 @@ TP_LOCALLAB_DELTAD;Delta balance TP_LOCALLAB_DELTAEC;ΔE Image mask TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -2932,6 +3014,7 @@ TP_LOCALLAB_DETAIL;Local contrast TP_LOCALLAB_DETAILFRA;Edge detection - DCT TP_LOCALLAB_DETAILSH;Details TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround TP_LOCALLAB_DIVGR;Gamma TP_LOCALLAB_DUPLSPOTNAME;Copy TP_LOCALLAB_EDGFRA;Edge sharpness @@ -2939,6 +3022,7 @@ TP_LOCALLAB_EDGSHOW;Show all tools TP_LOCALLAB_ELI;Ellipse TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping TP_LOCALLAB_ENABLE_MASK;Enable mask +TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. TP_LOCALLAB_ENH;Enhanced @@ -2970,7 +3054,7 @@ TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nTh TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_EXPCURV;Curves TP_LOCALLAB_EXPGRAD;Graduated Filter -TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3134,8 +3218,11 @@ TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' fo TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +TP_LOCALLAB_LOGCIE;Log encoding +TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. +TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast etc.:\nThe user may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. + TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3143,7 +3230,7 @@ TP_LOCALLAB_LOGCONTHRES;Contrast threshold (J & Q) TP_LOCALLAB_LOGCONTL;Contrast (J) TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. TP_LOCALLAB_LOGEXP;All tools @@ -3156,6 +3243,7 @@ TP_LOCALLAB_LOGLIGHTQ;Brightness (Q) TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. TP_LOCALLAB_LOGLIN;Logarithm mode TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +TP_LOCALLAB_LOGPFRA2;Log Encoding settings TP_LOCALLAB_LOGREPART;Overall strength TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3225,7 +3313,7 @@ TP_LOCALLAB_MASKRESRETI_TOOLTIP;Used to modulate the effect of the Retinex (Lumi TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. TP_LOCALLAB_MEDIAN;Median Low @@ -3261,6 +3349,7 @@ TP_LOCALLAB_MERTHR;Difference TP_LOCALLAB_MERTWE;Exclusion TP_LOCALLAB_MERTWO;Subtract TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +TP_LOCALLAB_MIDTCIE;Midtones TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3307,11 +3396,19 @@ TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. TP_LOCALLAB_PASTELS2;Vibrance TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression +TP_LOCALLAB_PRECAM_TOOLTIP;This 'Source Data Adjustments' modifies: a)the Dynamic Range using Log encoding; b) the tones of the image and primaries(simplified Abstract Profile) and also midtones, just before the Ciecam process. The values are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\n\n\n-Destination primaries: which allows you to change the destination primaries to restore or change image color (saturation), the color balance is 'significantly' preserved when the 'Working Profile' and the 'Destination primaries' are not too different (be careful), 'Working Profiles' are not modified.\nYou can also finely adapt the primaries and the illuminant (white-point).\nMoving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked ensures a gamut control just after primary conversion to XYZ matrix. +TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y" allows you to carry out moderate Color Toning. TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. TP_LOCALLAB_PREVHIDE;Hide additional settings TP_LOCALLAB_PREVIEW;Preview ΔE TP_LOCALLAB_PREVSHOW;Show additional settings +TC_LOCALLAB_PRIM_SHIFTX;Shift x +TC_LOCALLAB_PRIM_SHIFTY;Shift y +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors" allows you:\n 1) for low values adjust the image purity.\n 2) for higher values, carry out moderate Color Toning.\n 3) Be careful not to go outside the CIE xy diagram. +TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant TP_LOCALLAB_PROXI;ΔE decay TP_LOCALLAB_QUAAGRES;Aggressive TP_LOCALLAB_QUACONSER;Conservative @@ -3356,10 +3453,11 @@ TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast w TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex TP_LOCALLAB_REWEI;Reweighting iterates TP_LOCALLAB_RGB;RGB Tone Curve -TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. TP_LOCALLAB_ROW_NVIS;Not visible TP_LOCALLAB_ROW_VIS;Visible TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +TP_LOCALLAB_SATCIE;Saturation control TP_LOCALLAB_SATUR;Saturation TP_LOCALLAB_SATURV;Saturation (s) TP_LOCALLAB_SCALEGR;Scale @@ -3380,7 +3478,7 @@ TP_LOCALLAB_SHADEXCOMP;Shadow compression TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. TP_LOCALLAB_SHAMASKCOL;Shadows TP_LOCALLAB_SHAPETYPE;Spot shape TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3426,17 +3524,36 @@ TP_LOCALLAB_SHOWVI;Mask and modifications TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +TP_LOCALLAB_SIGCIE;Sigmoid +TP_LOCALLAB_SIGFRA;Sigmoid Q +TP_LOCALLAB_SIGGAMJCIE;Gamma TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Attenuation response TP_LOCALLAB_SIGMOIDBL;Blend TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +TP_LOCALLAB_SIGMOIDSENSI;Adaptability TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the 'Jz' and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' and 'Sigmoid Q'.\nSigmoid Q: three sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Adaptability weights the action of the sigmoid by action on the internal exponential function. +TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the comboxbox selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance : ratio between original and output image. +TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the comboxbox selection'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. This last value stands for brightness (Q) should be a near the possible value 'Compression treshold' (calculate when 'Auto threshold" checked, often > 1). +TP_LOCALLAB_SIGSLOPJCIE;Slope +TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +TP_LOCALLAB_SIGWHITESCIE;Whites distribution +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic, when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. TP_LOCALLAB_SLOMASKCOL;Slope TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) TP_LOCALLAB_SLOSH;Slope +TP_LOCALLAB_SMOOTHCIE;Smooth & Tone-Mapping +TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma - Slope - based: choice (Standard and Advanced) allows you to simulate a "Tone mapping" using: a) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%); b) Viewing conditions: Mean luminance (Yb%).\nScale Yb Scene is function of White-Ev. TP_LOCALLAB_SOFT;Soft Light & Original Retinex TP_LOCALLAB_SOFTM;Soft Light TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3458,13 +3575,14 @@ TP_LOCALLAB_STRENG;Strength TP_LOCALLAB_STRENGR;Strength TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). TP_LOCALLAB_STRENGTH;Noise +TP_LOCALLAB_STRENGTHCIELOG;Strength TP_LOCALLAB_STRGRID;Strength TP_LOCALLAB_STRUC;Structure TP_LOCALLAB_STRUCCOL;Spot structure TP_LOCALLAB_STRUCCOL1;Spot structure TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. TP_LOCALLAB_STRUMASKCOL;Structure mask strength -TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! TP_LOCALLAB_STYPE;Shape method TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3496,11 +3614,12 @@ TP_LOCALLAB_TRANSITGRAD;Transition differentiation XY TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. TP_LOCALLAB_TRANSITVALUE;Transition value TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain TP_LOCALLAB_TRANSMISSIONMAP;Transmission map TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones TP_LOCALLAB_USEMASK;Laplacian TP_LOCALLAB_VART;Variance (contrast) TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4154,7 +4273,7 @@ TP_WAVELET_WAVOFFSET;Offset TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Temperature correlation TP_WBALANCE_AUTOOLD;RGB grey -TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +TP_WBALANCE_AUTO_HEADER;Automatic & Refinement TP_WBALANCE_CAMERA;Camera TP_WBALANCE_CLOUDY;Cloudy TP_WBALANCE_CUSTOM;Custom diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc index 25f0c852d..264fd5ab7 100644 --- a/rtengine/ciecam02.cc +++ b/rtengine/ciecam02.cc @@ -229,7 +229,7 @@ float Ciecam02::achromatic_response_to_whitefloat ( float x, float y, float z, f gpa = nonlinear_adaptationfloat ( gp, fl ); bpa = nonlinear_adaptationfloat ( bp, fl ); - return ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb; + return ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb; } void Ciecam02::xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int c16, float plum) diff --git a/rtengine/color.cc b/rtengine/color.cc index 4e139a868..16104ae86 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -25,11 +25,67 @@ #include "opthelper.h" #include "iccstore.h" #include +#include "linalgebra.h" using namespace std; -namespace rtengine +namespace rtengine { +namespace { + +typedef Vec3f A3; + +// D50 <-> D65 adapted from darktable, thanks to Alberto Griggio + +void XYZ_D50_to_D65(float &X, float &Y, float &Z) { + // Bradford adaptation matrix from http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html + constexpr float M[3][3] = { + { 0.9555766f, -0.0230393f, 0.0631636f }, + { -0.0282895f, 1.0099416f, 0.0210077f }, + { 0.0122982f, -0.0204830f, 1.3299098f } + }; + A3 res = dot_product(M, A3(X, Y, Z)); + X = res[0]; + Y = res[1]; + Z = res[2]; +} + + +void XYZ_D65_to_D50(float &X, float &Y, float &Z) +{ + // Bradford adaptation matrix from http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html + constexpr float M[3][3] = { + { 1.0478112f, 0.0228866f, -0.0501270f }, + { 0.0295424f, 0.9904844f, -0.0170491f }, + { -0.0092345f, 0.0150436f, 0.7521316f } + }; + A3 res = dot_product(M, A3(X, Y, Z)); + X = res[0]; + Y = res[1]; + Z = res[2]; +} + +/* +float PQ(float X) +{ + X = std::max(X, 1e-10f); + const float XX = std::pow(X*1e-4f, 0.1593017578125f); + return std::pow( + (0.8359375f + 18.8515625f*XX) / (1 + 18.6875f*XX), + 134.034375f); +} + + +float PQ_inv(float X) +{ + X = std::max(X, 1e-10f); + const auto XX = std::pow(X, 7.460772656268214e-03f); + return 1e4f * std::pow( + (0.8359375f - XX) / (18.6875f*XX - 18.8515625f), + 6.277394636015326f); +} +*/ +} // namespace cmsToneCurve* Color::linearGammaTRC; LUTf Color::cachef; @@ -1911,7 +1967,146 @@ void Color::Lch2Luv(float c, float h, float &u, float &v) v = c * sincosval.y; } -void Color::primaries_to_xyz(double p[6], double Wx, double Wz, double *pxyz) +// code take in ART thanks to Alberto Griggio +//----------------------------------------------------------------------------- +// oklab color space from https://bottosson.github.io/posts/oklab/ +//----------------------------------------------------------------------------- + +void Color::xyz2oklab(float X, float Y, float Z, float &L, float &a, float &b) +{ + XYZ_D50_to_D65(X, Y, Z); + + constexpr float M1[3][3] = { + {0.8189330101f, 0.3618667424f, -0.1288597137f}, + {0.0329845436f, 0.9293118715f, 0.0361456387f}, + {0.0482003018f, 0.2643662691f, 0.6338517070f} + }; + + A3 lms = dot_product(M1, A3(X, Y, Z)); + for (int i = 0; i < 3; ++i) { + lms[i] = xcbrtf(lms[i]); + } + + constexpr float M2[3][3] = { + {0.2104542553f, 0.7936177850f, -0.0040720468f}, + {1.9779984951f, -2.4285922050f, 0.4505937099f}, + {0.0259040371f, 0.7827717662f, -0.8086757660f} + }; + + lms = dot_product(M2, lms); + + L = lms[0]; + a = lms[1]; + b = lms[2]; +} + + +void Color::oklab2xyz(float L, float a, float b, float &X, float &Y, float &Z) +{ + constexpr float M2_inv[3][3] = { + {1.f, 0.39633779f, 0.21580376f}, + {1.00000001f, -0.10556134f, -0.06385417f}, + {1.00000005f, -0.08948418f, -1.29148554f} + }; + + A3 lms = dot_product(M2_inv, A3(L, a, b)); + for (int i = 0; i < 3; ++i) { + lms[i] = SQR(lms[i])*lms[i]; + } + + constexpr float M1_inv[3][3] = { + {1.22701385f, -0.55779998f, 0.28125615f}, + {-0.04058018f, 1.11225687f, -0.07167668f}, + {-0.07638128f, -0.42148198f, 1.58616322} + }; + + lms = dot_product(M1_inv, lms); + X = lms[0]; + Y = lms[1]; + Z = lms[2]; + + XYZ_D65_to_D50(X, Y, Z); +} + + +// https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-F.pdf +// Perceptual Quantization / SMPTE standard ST.2084 +float Color::eval_PQ_curve(float x, bool oetf) +{ + constexpr float M1 = 2610.0 / 16384.0; + constexpr float M2 = (2523.0 / 4096.0) * 128.0; + constexpr float C1 = 3424.0 / 4096.0; + constexpr float C2 = (2413.0 / 4096.0) * 32.0; + constexpr float C3 = (2392.0 / 4096.0) * 32.0; + + if (x == 0.f) { + return 0.f; + } + + float res = 0.f; + if (oetf) { + // assume 1.0 is 100 nits, normalise so that 1.0 is 10000 nits + float p = std::pow(std::max(x, 0.f) / 100.f, M1); + float num = C1 + C2 * p; + float den = 1.f + C3 * p; + res = std::pow(num / den, M2); + } else { + float p = std::pow(x, 1.f / M2); + float num = std::max(p - C1, 0.f); + float den = C2 - C3 * p; + res = std::pow(num / den, 1.f / M1) * 100.f; + } + return res; +} + + +// https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-F.pdf +// Hybrid Log-Gamma +float Color::eval_HLG_curve(float x, bool oetf) +{ + constexpr float A = 0.17883277f; + constexpr float B = 0.28466892f; // 1.f - 4.f * A + constexpr float C = 0.55991072953f; // 0.5f - A * std::log(4.f * A) + + if (x == 0.f) { + return 0.f; + } + + float res = 0.f; + if (oetf) { + // assume 1.0 is 100 nits, normalise so that 1.0 is 1000 nits + float e = LIM01(x / 10.f); + res = (e <= 1.f/12.f) ? std::sqrt(3.f * e) : A * std::log(12.f * e - B) + C; + } else { + res = (x <= 0.5f) ? SQR(x) / 3.f : (std::exp((x - C) / A) + B) / 12.f; + res *= 10.f; + } + + return res; +} + + +float Color::eval_ACEScct_curve(float x, bool forward) +{ + if (forward) { + if (x <= 0.078125f) { + return 10.5402377416545f * x + 0.0729055341958355f; + } else { + return (std::log2(x) + 9.72f) / 17.52f; + } + } else { + if (x <= 0.155251141552511f) { + return (x - 0.0729055341958355f) / 10.5402377416545f; + } else { + return std::exp2(x * 17.52f - 9.72f); + } + } +} + +// end code take in ART thanks to Alberto Griggio + + +void Color::primaries_to_xyz(double p[6], double Wx, double Wz, double *pxyz, int cat) { //calculate Xr, Xg, Xb, Yr, Yb, Tg, Zr,Zg Zb double Wy = 1.0; @@ -1967,29 +2162,112 @@ void Color::primaries_to_xyz(double p[6], double Wx, double Wz, double *pxyz) mat_xyz[2][1] = Sb * Yb; mat_xyz[2][2] = Sb * Zb; - //chromatic adaptation Bradford + //chromatic adaptation Matrix MaBradford = {}; - MaBradford[0][0] = 0.8951; - MaBradford[0][1] = -0.7502; - MaBradford[0][2] = 0.0389; - MaBradford[1][0] = 0.2664; - MaBradford[1][1] = 1.7135; - MaBradford[1][2] = -0.0685; - MaBradford[2][0] = -0.1614; - MaBradford[2][1] = 0.0367; - MaBradford[2][2] = 1.0296; + if( cat == 0 ) {//i bradford + MaBradford[0][0] = 0.8951; + MaBradford[0][1] = -0.7502; + MaBradford[0][2] = 0.0389; + MaBradford[1][0] = 0.2664; + MaBradford[1][1] = 1.7135; + MaBradford[1][2] = -0.0685; + MaBradford[2][0] = -0.1614; + MaBradford[2][1] = 0.0367; + MaBradford[2][2] = 1.0296; + } else if ( cat == 1 ) {// icat16 + MaBradford[0][0] = 1.86206786; + MaBradford[0][1] = -1.01125463; + MaBradford[0][2] = 0.14918677; + MaBradford[1][0] = 0.38752654; + MaBradford[1][1] = 0.62144744; + MaBradford[1][2] = -0.00897398; + MaBradford[2][0] = -0.0158415; + MaBradford[2][1] = -0.03412294; + MaBradford[2][2] = 1.04996444; + } else if ( cat == 2 ) {// icat02 + MaBradford[0][0] = 0.99015849; + MaBradford[0][1] = -0.00838772; + MaBradford[0][2] = 0.018229217; + MaBradford[1][0] = 0.239565979; + MaBradford[1][1] = 0.758664642; + MaBradford[1][2] = 0.001770137; + MaBradford[2][0] = 0.0; + MaBradford[2][1] = 0.0; + MaBradford[2][2] = 1.0; + } else if ( cat == 3 ) {//Von Kries + MaBradford[0][0] = 0.40024; + MaBradford[0][1] = -0.2263; + MaBradford[0][2] = 0.0; + MaBradford[1][0] = 0.7076; + MaBradford[1][1] = 1.16532; + MaBradford[1][2] = 0.0; + MaBradford[2][0] = -0.08081; + MaBradford[2][1] = 0.0457; + MaBradford[2][2] = 0.91822; + } else if ( cat == 4 ) {//None XYZ + MaBradford[0][0] = 1.0; + MaBradford[0][1] = 0.0; + MaBradford[0][2] = 0.0; + MaBradford[1][0] = 0.0; + MaBradford[1][1] = 1.0; + MaBradford[1][2] = 0.0; + MaBradford[2][0] = 0.0; + MaBradford[2][1] = 0.0; + MaBradford[2][2] = 1.0; + } Matrix Ma_oneBradford = {}; - Ma_oneBradford[0][0] = 0.9869929; - Ma_oneBradford[0][1] = 0.4323053; - Ma_oneBradford[0][2] = -0.0085287; - Ma_oneBradford[1][0] = -0.1470543; - Ma_oneBradford[1][1] = 0.5183603; - Ma_oneBradford[1][2] = 0.0400428; - Ma_oneBradford[2][0] = 0.1599627; - Ma_oneBradford[2][1] = 0.0492912; - Ma_oneBradford[2][2] = 0.9684867; - + if( cat == 0 ) {//Bradford + Ma_oneBradford[0][0] = 0.9869929; + Ma_oneBradford[0][1] = 0.4323053; + Ma_oneBradford[0][2] = -0.0085287; + Ma_oneBradford[1][0] = -0.1470543; + Ma_oneBradford[1][1] = 0.5183603; + Ma_oneBradford[1][2] = 0.0400428; + Ma_oneBradford[2][0] = 0.1599627; + Ma_oneBradford[2][1] = 0.0492912; + Ma_oneBradford[2][2] = 0.9684867; + } else if ( cat == 1 ) { //cat16 + Ma_oneBradford[0][0] = 0.401288; + Ma_oneBradford[0][1] = 0.650173; + Ma_oneBradford[0][2] = -0.051461; + Ma_oneBradford[1][0] = -0.250268; + Ma_oneBradford[1][1] = 1.204414; + Ma_oneBradford[1][2] = 0.045854; + Ma_oneBradford[2][0] = -0.002079; + Ma_oneBradford[2][1] = 0.048952; + Ma_oneBradford[2][2] = 0.953127; + } else if ( cat == 2 ) { //cat02 + Ma_oneBradford[0][0] = 1.007245; + Ma_oneBradford[0][1] = 0.011136; + Ma_oneBradford[0][2] = -0.018381; + Ma_oneBradford[1][0] = -0.318061; + Ma_oneBradford[1][1] = 1.314589; + Ma_oneBradford[1][2] = 0.003471; + Ma_oneBradford[2][0] = 0.0; + Ma_oneBradford[2][1] = 0.0; + Ma_oneBradford[2][2] = 1.0; + } else if ( cat == 3 ) { //Von Kries + Ma_oneBradford[0][0] = 1.8599364; + Ma_oneBradford[0][1] = 0.3611914; + Ma_oneBradford[0][2] = 0.0; + Ma_oneBradford[1][0] = -1.1293816; + Ma_oneBradford[1][1] = 0.6388125; + Ma_oneBradford[1][2] = 0.0; + Ma_oneBradford[2][0] = 0.2198974; + Ma_oneBradford[2][1] = -0.0000064; + Ma_oneBradford[2][2] = 1.0890636; + } else if ( cat == 4 ) { //none XYZ + Ma_oneBradford[0][0] = 1.0; + Ma_oneBradford[0][1] = 0.0; + Ma_oneBradford[0][2] = 0.0; + Ma_oneBradford[1][0] = 0.0; + Ma_oneBradford[1][1] = 1.0; + Ma_oneBradford[1][2] = 0.0; + Ma_oneBradford[2][0] = 0.0; + Ma_oneBradford[2][1] = 0.0; + Ma_oneBradford[2][2] = 1.0; + } //R G B source double Rs = Wx * MaBradford[0][0] + Wy * MaBradford[1][0] + Wz * MaBradford[2][0]; double Gs = Wx * MaBradford[0][1] + Wy * MaBradford[1][1] + Wz * MaBradford[2][1]; @@ -2078,16 +2356,15 @@ void Color::primaries_to_xyz(double p[6], double Wx, double Wz, double *pxyz) * 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 epsil = 0.0001f; - float intermXYZ = X + 15 * Y + 3 * Z; - if(intermXYZ <= 0.f) { - intermXYZ = epsil; - } - - float u = 4 * X / (intermXYZ) - u0; + float epsil = 0.0001f; + float intermXYZ = X + 15 * Y + 3 * Z; + if(intermXYZ <= 0.f) { + intermXYZ = epsil; + } + + float u = 4 * X / (intermXYZ) - u0; float v = 9 * Y / (intermXYZ) - v0; float lam[3][2]; float lam_min = 1.0f; @@ -2118,14 +2395,12 @@ void Color::gamutmap(float &X, float Y, float &Z, const double p[3][3]) v = v * (double) lam_min + v0; X = (9 * u * Y) / (4 * v); - float intermuv = 12 - 3 * u - 20 * v; - if(intermuv < 0.f) { - intermuv = 0.f; - } + float intermuv = 12 - 3 * u - 20 * v; + if(intermuv < 0.f) { + intermuv = 0.f; + } Z = (intermuv) * Y / (4 * v); - - } void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s) diff --git a/rtengine/color.h b/rtengine/color.h index 3622a9e36..c20ac97ee 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -127,8 +127,8 @@ public: constexpr static float D50x = 0.9642f; //0.96422; constexpr static float D50z = 0.8249f; //0.82521; - constexpr static double u0 = 4.0 * static_cast(D50x) / (static_cast(D50x) + 15 + 3 * static_cast(D50z)); - constexpr static double v0 = 9.0 / (static_cast(D50x) + 15 + 3 * static_cast(D50z)); + constexpr static double u0 = 4.0 * static_cast(D50x) / (static_cast(D50x) + 15.0 + 3.0 * static_cast(D50z)); + constexpr static double v0 = 9.0 / (static_cast(D50x) + 15.0 + 3.0 * static_cast(D50z)); constexpr static double epskap = 8.0; constexpr static float epskapf = epskap; @@ -1399,7 +1399,36 @@ static inline void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, v //static inline float gamma (double x) { return gammatab[x]; } //static inline float igamma_srgb (double x) { return igammatab_srgb[x]; } + // code take in ART thanks to Alberto Griggio + // Rec.2100 PQ curve + // https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-F.pdf + // Perceptual Quantization / SMPTE standard ST.2084 + static float eval_PQ_curve(float x, bool oetf); + // Hybrid-log gamma curve + // https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-2-201807-I!!PDF-F.pdf + static float eval_HLG_curve(float x, bool oetf); + + static float eval_ACEScct_curve(float x, bool inverse); + + static void xyz2oklab(float X, float Y, float Z, float &L, float &a, float &b); + static void oklab2xyz(float L, float a, float b, float &X, float &Y, float &Z); + + template + static void rgb2oklab(float R, float G, float B, float &L, float &a, float &b, const T ws[3][3]) + { + float X, Y, Z; + rgbxyz(R, G, B, X, Y, Z, ws); + xyz2oklab(X, Y, Z, L, a, b); + } + + template + static void oklab2rgb(float L, float a, float b, float &R, float &G, float &B, const T iws[3][3]) + { + float X, Y, Z; + oklab2xyz(L, a, b, X, Y, Z); + xyz2rgb(X, Y, Z, R, G, B, iws); + } // -------------------------------- Jacques's Munsell correction @@ -1847,13 +1876,13 @@ static inline void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, v */ static void gamutmap(float &X, float Y, float &Z, const double p[3][3]); - /** - * @brief Convert primaries in XYZ values in function of illuminant - * @param p primaries red, gree, blue - * @param Wx Wy white for illuminant - * @param pxyz return matrix XYZ - */ - static void primaries_to_xyz (double p[6], double Wx, double Wz, double *pxyz); + /** + * @brief Convert primaries in XYZ values in function of illuminant + * @param p primaries red, gree, blue + * @param Wx Wy white for illuminant + * @param pxyz return matrix XYZ + */ + static void primaries_to_xyz (double p[6], double Wx, double Wz, double *pxyz, int cat); /** * @brief Get HSV's hue from the Lab's hue diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 85661edd3..a489bd681 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -896,6 +896,7 @@ void Crop::update(int todo) auto& locllmasCurve = parent->locllmasCurve; auto& lochhmasCurve = parent->lochhmasCurve; auto& lochhhmasCurve = parent->lochhhmasCurve; + auto& lochhhmascieCurve = parent->lochhhmascieCurve; auto& locccmasexpCurve = parent->locccmasexpCurve; auto& locllmasexpCurve = parent->locllmasexpCurve; auto& lochhmasexpCurve = parent->lochhmasexpCurve; @@ -935,6 +936,7 @@ void Crop::update(int todo) auto& locwavCurvejz = parent->locwavCurvejz; auto& loclmasCurveblwav = parent->loclmasCurveblwav; auto& loclmasCurvecolwav = parent->loclmasCurvecolwav; + auto& loclmasCurveciewav = parent->loclmasCurveciewav; auto& loclevwavCurve = parent->loclevwavCurve; auto& locconwavCurve = parent->locconwavCurve; auto& loccompwavCurve = parent->loccompwavCurve; @@ -958,6 +960,7 @@ void Crop::update(int todo) const bool llmasutili = locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve); const bool lhmasutili = lochhmasCurve.Set(params.locallab.spots.at(sp).HHmaskcurve); const bool lhhmasutili = lochhhmasCurve.Set(params.locallab.spots.at(sp).HHhmaskcurve); + const bool lhhmascieutili = lochhhmascieCurve.Set(params.locallab.spots.at(sp).HHhmaskciecurve); const bool lcmasexputili = locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); const bool llmasexputili = locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); const bool lhmasexputili = lochhmasexpCurve.Set(params.locallab.spots.at(sp).HHmaskexpcurve); @@ -993,6 +996,7 @@ void Crop::update(int todo) const bool lmasutili_wav = loclmasCurve_wav.Set(params.locallab.spots.at(sp).LLmask_curvewav); const bool lmasutiliblwav = loclmasCurveblwav.Set(params.locallab.spots.at(sp).LLmaskblcurvewav); const bool lmasutilicolwav = loclmasCurvecolwav.Set(params.locallab.spots.at(sp).LLmaskcolcurvewav); + const bool lmasutiliciewav = loclmasCurveciewav.Set(params.locallab.spots.at(sp).LLmaskciecurvewav); const bool lcmaslcutili = locccmaslcCurve.Set(params.locallab.spots.at(sp).CCmasklccurve); const bool llmaslcutili = locllmaslcCurve.Set(params.locallab.spots.at(sp).LLmasklccurve); const bool lhmaslcutili = lochhmaslcCurve.Set(params.locallab.spots.at(sp).HHmasklccurve); @@ -1056,6 +1060,10 @@ void Crop::update(int todo) float stdretie = parent->stdretis[sp]; float fab = 1.f; + float maxicam = -1000.f; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + int ill = 2; float minCD; float maxCD; float mini; @@ -1073,6 +1081,9 @@ void Crop::update(int todo) float Lnresi = 0.f; float Lhighresi46 = 0.f; float Lnresi46 = 0.f; + float contsig = params.locallab.spots.at(sp).contsigqcie; + + float lightsig = params.locallab.spots.at(sp).lightsigqcie; /* huerefp[sp] = huere; chromarefp[sp] = chromare; lumarefp[sp] = lumare; @@ -1111,7 +1122,7 @@ void Crop::update(int todo) czlocalcurve2,localczutili, czjzlocalcurve2,localczjzutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, lochhhmascieCurve, lhhmascieutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, @@ -1127,6 +1138,7 @@ void Crop::update(int todo) lochhhmas_Curve, lhhmas_utili, loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, + loclmasCurveciewav,lmasutiliciewav, locwavCurve, locwavutili, locwavCurvejz, locwavutilijz, loclevwavCurve, loclevwavutili, @@ -1141,7 +1153,7 @@ void Crop::update(int todo) huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, parent->previewDeltaE, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallvibMask, parent->localllcMask, parent->locallsharMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, parent->localllogMask, parent->locall_Mask, parent->locallcieMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, + meantme, stdtme, meanretie, stdretie, fab, maxicam,rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye,ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); LocallabListener::locallabDenoiseLC denoiselc; @@ -1224,7 +1236,7 @@ void Crop::update(int todo) czlocalcurve2,localczutili, czjzlocalcurve2,localczjzutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili,lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili,lochhhmasCurve, lhhmasutili, lochhhmascieCurve, lhhmascieutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, @@ -1240,6 +1252,7 @@ void Crop::update(int todo) loclmasCurveblwav,lmasutiliblwav, loclmasCurvecolwav,lmasutilicolwav, + loclmasCurveciewav,lmasutiliciewav, locwavCurve, locwavutili, locwavCurvejz, locwavutilijz, loclevwavCurve, loclevwavutili, @@ -1253,7 +1266,7 @@ void Crop::update(int todo) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, + meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); } @@ -1599,7 +1612,7 @@ void Crop::update(int todo) parent->ipf.softLight(labnCrop, params.softlight); - if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE) { + if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params.icm.trcExp) { const int GW = labnCrop->W; const int GH = labnCrop->H; std::unique_ptr provis; @@ -1623,8 +1636,52 @@ void Crop::update(int todo) cmsHTRANSFORM cmsDummy = nullptr; int ill = 0; - parent->ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, cmsDummy, true, false, false); - parent->ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, cmsDummy, false, true, true); + int locprim = 0; + bool gamutcontrol = params.icm.gamut; + int catc = rtengine::toUnderlying(params.icm.wcat); + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + parent->ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly,meanx, meany, meanxe, meanye, cmsDummy, true, false, false, false); + parent->ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, catc, illum, prim, locprim, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, cmsDummy, false, true, true, gamutcontrol); + const int midton = params.icm.wmidtcie; + + if(midton != 0) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[2] = midton; + params.bands[4] = 0; + params.bands[5] = 0; + int mid = abs(midton); + int threshmid = 50; + if(mid > threshmid) { + params.bands[1] = sign(midton) * (mid - threshmid); + params.bands[3] = sign(midton) * (mid - threshmid); + } + parent->ipf.toneEqualizer(tmpImage1.get(), params, prof, skip, false); + } + + const bool smoothi = params.icm.wsmoothcie; + if(smoothi) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[1] = 0; + params.bands[2] = 0; + params.bands[3] = 0; + params.bands[4] = -40;//arbitrary value to adapt with WhiteEvjz - here White Ev # 10 + params.bands[5] = -80;//8 Ev and above + bool Evsix = true; + if(Evsix) {//EV = 6 majority of images + params.bands[4] = -15; + } + + parent->ipf.toneEqualizer(tmpImage1.get(), params, prof, skip, false); + } parent->ipf.rgb2lab(*tmpImage1, *labnCrop, params.icm.workingProfile); //labnCrop and provis diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h index be685b676..6c5203744 100644 --- a/rtengine/iccmatrices.h +++ b/rtengine/iccmatrices.h @@ -94,12 +94,50 @@ constexpr double xyz_jdcmax[3][3] = {//prim red 0.734702 0.265302 gr 0.021908 0. {0.8394088, 0.0163780, 0.1084133}, {0.3031122, 0.6954651, 0.0014227}, {-0.000048, 0.0357376, 0.7891671} + +/* + {0.878152, -0.035991, 0.122039},//stdA + {0.293869, 0.682893, 0.023238}, + {0.020725, 0.025411, 0.778763} +*/ +/* + {0.831816, 0.041363, 0.091021},//D80 + {0.307370, 0.714525, -0.021895}, + {-0.004335, 0.039442, 0.789793} + */ +}; + +constexpr double xyz_jdcmaxstdA[3][3] = {//prim red 0.734702 0.265302 gr 0.021908 0.930288 bl 0.120593 0.001583 + + {0.878152, -0.035991, 0.122039},//stdA + {0.293869, 0.682893, 0.023238}, + {0.020725, 0.025411, 0.778763} +}; + +constexpr double jdcmaxstdA_xyz[3][3] = { + + {1.1209647, 0.06568858, -0.177625},//stdA + {-0.481904, 1.437746, 0.03261678}, + {-0.0141074, -0.0486617, 1.28775} + }; constexpr double jdcmax_xyz[3][3] = { {1.1984508, -0.0197646, -0.1646037}, {-0.5223824, 1.4466349, 0.0691553}, {0.0236634, -0.0655113, 1.2640260} + + /* + {1.1209647, 0.06568858, -0.177625},//stdA + {-0.481904, 1.437746, 0.03261678}, + {-0.0141074, -0.0486617, 1.28775} + */ + /* + {1.2247276, -0.0630103, -0.142892},//D80 + {-0.525835, 1.424446, 0.100089}, + {0.032982, -0.0714782, 1.260371} + */ + }; diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index af1b94fbe..86a9c214b 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -197,9 +197,9 @@ cmsHPROFILE createXYZProfile() return rtengine::ICCStore::createFromMatrix(mat, false, "XYZ"); } -const double(*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_jdcmax, xyz_beta, xyz_best, xyz_rec2020, xyz_ACESp0, xyz_ACESp1, xyz_bruce};// -const double(*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, jdcmax_xyz, beta_xyz, best_xyz, rec2020_xyz, ACESp0_xyz, ACESp1_xyz, bruce_xyz};// -const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "JDCmax", "Beta RGB", "BestRGB", "Rec2020", "ACESp0", "ACESp1", "BruceRGB"};// +const double(*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_jdcmax, xyz_jdcmaxstdA, xyz_beta, xyz_best, xyz_rec2020, xyz_ACESp0, xyz_ACESp1, xyz_bruce};// +const double(*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, jdcmax_xyz, jdcmaxstdA_xyz, beta_xyz, best_xyz, rec2020_xyz, ACESp0_xyz, ACESp1_xyz, bruce_xyz};// +const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "JDCmax", "JDCmax stdA", "Beta RGB", "BestRGB", "Rec2020", "ACESp0", "ACESp1", "BruceRGB"};// //default = gamma inside profile //BT709 g=2.22 s=4.5 sRGB g=2.4 s=12.92310 //linear g=1.0 diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5358f2880..604d353c4 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -875,8 +875,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } for (int sp = 0; sp < (int)params->locallab.spots.size(); sp++) { - if (params->locallab.spots.at(sp).expsharp && params->dirpyrequalizer.cbdlMethod == "bef") { - if (params->locallab.spots.at(sp).shardamping < 1) { + if(params->locallab.spots.at(sp).expsharp && params->dirpyrequalizer.cbdlMethod == "bef") { + if(params->locallab.spots.at(sp).shardamping < 1) { params->locallab.spots.at(sp).shardamping = 1; } } @@ -904,9 +904,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->toneCurve.black, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, params->toneCurve.hrenabled); } - if (params->toneCurve.histmatching) { + if (params->toneCurve.histmatching ) { + bool exectrcexp = false;//store if Abstract profile enabled + exectrcexp = params->icm.trcExp; if (!params->toneCurve.fromHistMatching) { + if(params->icm.trcExp) { + params->icm.trcExp = false;//disabled Abstract profile, if hismatching + } imgsrc->getAutoMatchedToneCurve(params->icm, params->raw, params->wb.observer, params->toneCurve.curve); + params->icm.trcExp = exectrcexp;//restore Abstract profile } if (params->toneCurve.autoexp) { @@ -930,6 +936,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->locallab.enabled && !params->locallab.spots.empty()) { const int sizespot = (int)params->locallab.spots.size(); const LocallabParams::LocallabSpot defSpot; + std::vector locallciebef; float *sourceg = nullptr; sourceg = new float[sizespot]; @@ -951,6 +958,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) Autogr = new bool[sizespot]; bool *autocie = nullptr; autocie = new bool[sizespot]; + int *whits = nullptr; + whits = new int[sizespot]; + int *blacks = nullptr; + blacks = new int[sizespot]; + int *whitslog = nullptr; + whitslog = new int[sizespot]; + int *blackslog = nullptr; + blackslog = new int[sizespot]; float *locx = nullptr; @@ -975,6 +990,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) whiteev[sp] = params->locallab.spots.at(sp).whiteEv; sourceg[sp] = params->locallab.spots.at(sp).sourceGray; sourceab[sp] = params->locallab.spots.at(sp).sourceabs; + whits[sp] = params->locallab.spots.at(sp).whitescie; + blacks[sp] = params->locallab.spots.at(sp).blackscie; + whitslog[sp] = params->locallab.spots.at(sp).whiteslog; + blackslog[sp] = params->locallab.spots.at(sp).blackslog; Autogr[sp] = params->locallab.spots.at(sp).Autogray; targetg[sp] = params->locallab.spots.at(sp).targetGray; locx[sp] = params->locallab.spots.at(sp).loc.at(0) / 2000.0; @@ -1011,9 +1030,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) xsta = 0.f; xend = 1.f; } - - ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, sourceab, fw, fh, xsta, xend, ysta, yend, SCALE); - // printf("sp=%i sg=%f sab=%f\n", sp, sourceg[sp], sourceab[sp]); + ipf.getAutoLogloc(sp, imgsrc, sourceg, blackev, whiteev, Autogr, sourceab, whits, blacks, whitslog, blackslog, fw, fh, xsta, xend, ysta, yend, SCALE); params->locallab.spots.at(sp).blackEv = blackev[sp]; params->locallab.spots.at(sp).whiteEv = whiteev[sp]; params->locallab.spots.at(sp).blackEvjz = blackev[sp]; @@ -1022,10 +1039,25 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) params->locallab.spots.at(sp).sourceabs = sourceab[sp]; params->locallab.spots.at(sp).sourceGraycie = sourceg[sp]; params->locallab.spots.at(sp).sourceabscie = sourceab[sp]; + params->locallab.spots.at(sp).whitescie = whits[sp]; + params->locallab.spots.at(sp).blackscie = blacks[sp]; + params->locallab.spots.at(sp).whiteslog = whitslog[sp]; + params->locallab.spots.at(sp).blackslog = blackslog[sp]; float jz1 = defSpot.jz100; + + LocallabListener::locallabcieBEF locciebef; + locciebef.blackevbef = blackev[sp]; + locciebef.whiteevbef = whiteev[sp]; + locciebef.sourcegbef = sourceg[sp]; + locciebef.sourceabbef = sourceab[sp]; + locciebef.targetgbef = targetg[sp]; + locciebef.autocomputbef = autocomput[sp]; + locciebef.autociebef = autocie[sp]; + locciebef.jz1bef = jz1; + locallciebef.push_back(locciebef); if (locallListener) { - locallListener->logencodChanged(blackev[sp], whiteev[sp], sourceg[sp], sourceab[sp], targetg[sp], autocomput[sp], autocie[sp], jz1); + locallListener->ciebefChanged(locallciebef,params->locallab.selspot); } } } @@ -1043,6 +1075,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete [] blackev; delete [] targetg; delete [] sourceab; + delete [] whits; + delete [] blacks; + delete [] whitslog; + delete [] blackslog; delete [] sourceg; delete [] cie; delete [] log; @@ -1092,6 +1128,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float avge, meantme, stdtme, meanretie, stdretie; //std::vector locallref; std::vector locallretiminmax; + std::vector locallcielc; + std::vector locallciesig; huerefs.resize(params->locallab.spots.size()); huerefblurs.resize(params->locallab.spots.size()); chromarefblurs.resize(params->locallab.spots.size()); @@ -1124,7 +1162,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti) { savenormreti.reset(new LabImage(*oprevl, true)); } - + // Set local curves of current spot to LUT locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); @@ -1138,6 +1176,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const bool llmasutili = locllmasCurve.Set(params->locallab.spots.at(sp).LLmaskcurve); const bool lhmasutili = lochhmasCurve.Set(params->locallab.spots.at(sp).HHmaskcurve); const bool lhhmasutili = lochhhmasCurve.Set(params->locallab.spots.at(sp).HHhmaskcurve); + const bool lhhmascieutili = lochhhmascieCurve.Set(params->locallab.spots.at(sp).HHhmaskciecurve); const bool llmasexputili = locllmasexpCurve.Set(params->locallab.spots.at(sp).LLmaskexpcurve); const bool lcmasexputili = locccmasexpCurve.Set(params->locallab.spots.at(sp).CCmaskexpcurve); const bool lhmasexputili = lochhmasexpCurve.Set(params->locallab.spots.at(sp).HHmaskexpcurve); @@ -1168,13 +1207,13 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const bool llmascieutili = locllmascieCurve.Set(params->locallab.spots.at(sp).LLmaskciecurve); const bool lcmascieutili = locccmascieCurve.Set(params->locallab.spots.at(sp).CCmaskciecurve); const bool lhmascieutili = lochhmascieCurve.Set(params->locallab.spots.at(sp).HHmaskciecurve); - const bool lcmas_utili = locccmas_Curve.Set(params->locallab.spots.at(sp).CCmask_curve); const bool llmas_utili = locllmas_Curve.Set(params->locallab.spots.at(sp).LLmask_curve); const bool lhmas_utili = lochhmas_Curve.Set(params->locallab.spots.at(sp).HHmask_curve); const bool lhhmas_utili = lochhhmas_Curve.Set(params->locallab.spots.at(sp).HHhmask_curve); const bool lmasutiliblwav = loclmasCurveblwav.Set(params->locallab.spots.at(sp).LLmaskblcurvewav); const bool lmasutilicolwav = loclmasCurvecolwav.Set(params->locallab.spots.at(sp).LLmaskcolcurvewav); + const bool lmasutiliciewav = loclmasCurveciewav.Set(params->locallab.spots.at(sp).LLmaskciecurvewav); const bool locwavutili = locwavCurve.Set(params->locallab.spots.at(sp).locwavcurve); const bool locwavutilijz = locwavCurvejz.Set(params->locallab.spots.at(sp).locwavcurvejz); const bool loclevwavutili = loclevwavCurve.Set(params->locallab.spots.at(sp).loclevwavcurve); @@ -1215,7 +1254,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) double shcompr = params->locallab.spots.at(sp).shcompr; double br = params->locallab.spots.at(sp).lightness; double cont = params->locallab.spots.at(sp).contrast; - + float contsig = params->locallab.spots.at(sp).contsigqcie; + + float lightsig = params->locallab.spots.at(sp).lightsigqcie; + if (black < 0. && params->locallab.spots.at(sp).expMethod == "pde") { black *= 1.5; } @@ -1232,6 +1274,10 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) meanretie = 0.f; stdretie = 0.f; float fab = 1.f; + float maxicam = -1000.f; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + int ill = 2; bool istm = params->locallab.spots.at(sp).equiltm && params->locallab.spots.at(sp).exptonemap; bool isreti = params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti; //preparation for mean and sigma on current RT-spot @@ -1257,7 +1303,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) yend = std::min(static_cast(centy + locy), 1.f); xsta = std::max(static_cast(centx - locxl), 0.f); xend = std::min(static_cast(centx + locx), 1.f); - // printf("xsta=%f xend=%f ysta=%f yend=%f \n", xsta, xend, ysta, yend); } int ww = nprevl->W; @@ -1296,14 +1341,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) sca); // Save Locallab mask curve references for current spot - /* - LocallabListener::locallabRef spotref; - spotref.huer = huer; - spotref.lumar = lumar; - spotref.chromar = chromar; - spotref.fab = 1.f; - locallref.push_back(spotref); - */ // Locallab tools computation /* Notes: * - shbuffer is used as nullptr @@ -1328,7 +1365,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float Lnresi = 0.f; float Lhighresi46 = 0.f; float Lnresi46 = 0.f; - + Glib::ustring prof = params->icm.workingProfile; + if(params->locallab.spots.at(sp).complexcie == 2) { + params->locallab.spots.at(sp).primMethod = prof;//in Basic mode set to Working profile + } + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv.get(), savenormtm.get(), savenormreti.get(), lastorigimp.get(), fw, fh, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, cllocalcurve, localclutili, @@ -1353,7 +1394,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, lochhhmascieCurve, lhhmascieutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, @@ -1369,6 +1410,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lochhhmas_Curve, lhhmas_utili, loclmasCurveblwav, lmasutiliblwav, loclmasCurvecolwav, lmasutilicolwav, + loclmasCurveciewav, lmasutiliciewav, locwavCurve, locwavutili, locwavCurvejz, locwavutilijz, loclevwavCurve, loclevwavutili, @@ -1382,12 +1424,59 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantm, stdtm, meanreti, stdreti, fab, + meantm, stdtm, meanreti, stdreti, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); fabrefp[sp] = fab; + //Illuminant + float w_x = 0.3f; + float w_y = 0.3f; + if(ill == 2) { + w_x = 0.3457f; + w_y = 0.3585f; + } else if(ill == 4) { + w_x = 0.3217f; + w_y = 0.3377f; + } else if(ill == 5) { + w_x = 0.3127f; + w_y = 0.3290f; + } else if(ill == 1) { + w_x = 0.376137f; + w_y = 0.374021f; + } else if(ill == 3) { + w_x = 0.332424f; + w_y = 0.347426f; + } else if(ill == 6) { + w_x = 0.293756f; + w_y = 0.309185f; + } else if(ill == 7) {//D120 + w_x = 0.269669f; + w_y = 0.28078f; + } else if(ill == 8) {//stdA + w_x = 0.447573f; + w_y = 0.407440f; + } else if(ill == 9) {//2000K + w_x = 0.526591f; + w_y = 0.41331f; + } else if(ill == 10) {//1500K + w_x = 0.585703f; + w_y = 0.393157f; + } else if(ill == 20) { + w_x = 0.333333f; + w_y = 0.333333f; + } + //move white-point in GUI + double refin = params->locallab.spots.at(sp).refi; + double arefi = (w_y - meany) / (w_x - meanx); + double brefi = w_y - arefi * w_x; + double scalrefi = meanx - w_x; + w_x = w_x + scalrefi * refin; + w_y = w_x * arefi + brefi; + + + if (istm) { //calculate mean and sigma on full image for use by normalize_mean_dt float meanf = 0.f; float stdf = 0.f; @@ -1425,6 +1514,27 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) retiMinMax.Tmax = Tmax; locallretiminmax.push_back(retiMinMax); + //save Locallab CIE primaries and white for current spot + LocallabListener::locallabcieLC loccielc; + loccielc.redxlc = rdx; + loccielc.redylc = rdy; + loccielc.grexlc = grx; + loccielc.greylc = gry; + loccielc.bluxlc = blx; + loccielc.bluylc = bly; + loccielc.wxlc = w_x; + loccielc.wylc = w_y; + loccielc.meanxlc = meanx; + loccielc.meanylc = meany; + loccielc.meanxelc = meanxe; + loccielc.meanyelc = meanye; + locallcielc.push_back(loccielc); + + LocallabListener::locallabcieSIG locciesig; + locciesig.contsigq = contsig; + locciesig.lightsigq = lightsig; + locallciesig.push_back(locciesig); + // Recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reserv.get(), reserv.get(), 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg, locwavCurveden, locwavdenutili); @@ -1434,46 +1544,30 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) // Update Locallab reference values according to recurs parameter if (params->locallab.spots.at(sp).recurs) { - /* - spotref.huer = huer; - spotref.lumar = lumar; - spotref.chromar = chromar; - spotref.fab = fab; - locallref.at(sp).chromar = chromar; - locallref.at(sp).lumar = lumar; - locallref.at(sp).huer = huer; - locallref.at(sp).fab = fab; - */ huerefp[sp] = huer; chromarefp[sp] = chromar; lumarefp[sp] = lumar; fabrefp[sp] = fab; } + - // spotref.fab = fab; - // locallref.at(sp).fab = fab; - - // locallref.push_back(spotref); if (locallListener) { - // locallListener->refChanged(locallref, params->locallab.selspot); locallListener->refChanged2(huerefp, chromarefp, lumarefp, fabrefp, params->locallab.selspot); locallListener->minmaxChanged(locallretiminmax, params->locallab.selspot); + if (params->locallab.spots.at(sp).expprecam) { + locallListener->cieChanged(locallcielc,params->locallab.selspot); + } + locallListener->sigChanged(locallciesig,params->locallab.selspot); } - + } delete [] huerefp; delete [] chromarefp; delete [] lumarefp; delete [] fabrefp; - // Transmit Locallab reference values and Locallab Retinex min/max to LocallabListener - /* - if (locallListener) { - locallListener->refChanged(locallref, params->locallab.selspot); - locallListener->minmaxChanged(locallretiminmax, params->locallab.selspot); - } - */ + ipf.lab2rgb(*nprevl, *oprevi, params->icm.workingProfile); //************************************************************* // end locallab @@ -1886,7 +1980,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.softLight(nprevl, params->softlight); - if (params->icm.workingTRC != ColorManagementParams::WorkingTrc::NONE) { + if (params->icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params->icm.trcExp) { const int GW = nprevl->W; const int GH = nprevl->H; std::unique_ptr provis; @@ -1903,15 +1997,58 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) const float gamtone = params->icm.workingTRCGamma; const float slotone = params->icm.workingTRCSlope; - int illum = toUnderlying(params->icm.will); const int prim = toUnderlying(params->icm.wprim); Glib::ustring prof = params->icm.workingProfile; + cmsHTRANSFORM dummy = nullptr; int ill = 0; - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, dummy, false, true, true); + bool gamutcontrol = params->icm.gamut; + int catc = toUnderlying(params->icm.wcat); + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, true, false, false, false); + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, catc, illum, prim, locprim, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, false, true, true, gamutcontrol); + const int midton = params->icm.wmidtcie; + if(midton != 0) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[2] = midton; + params.bands[4] = 0; + params.bands[5] = 0; + int mid = abs(midton); + int threshmid = 50; + if(mid > threshmid) { + params.bands[1] = sign(midton) * (mid - threshmid); + params.bands[3] = sign(midton) * (mid - threshmid); + } + ipf.toneEqualizer(tmpImage1.get(), params, prof, scale, false); + } + const bool smoothi = params->icm.wsmoothcie; + if(smoothi) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[1] = 0; + params.bands[2] = 0; + params.bands[3] = 0; + params.bands[4] = -40;//arbitrary value to adapt with WhiteEvjz - here White Ev # 10 + params.bands[5] = -80;//8 Ev and above + bool Evsix = true; + if(Evsix) {//EV = 6 majority of images + params.bands[4] = -15; + } + + ipf.toneEqualizer(tmpImage1.get(), params, prof, scale, false); + } ipf.rgb2lab(*tmpImage1, *nprevl, params->icm.workingProfile); @@ -1934,7 +2071,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) tmpImage1.reset(); - if (prim == 13) {//pass red gre blue xy in function of area dats Ciexy + if (prim == 14) {//pass red gre blue xy in function of area dats Ciexy float redgraphx = params->icm.labgridcieALow; float redgraphy = params->icm.labgridcieBLow; float blugraphx = params->icm.labgridcieAHigh; @@ -2020,9 +2157,18 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) wy = 0.3932f; break; } + + + //move white point in GUI + double refin = params->icm.refi; + double arefi = (wy - meany) / (wx - meanx); + double brefi = wy - arefi * wx; + double scalrefi = meanx - wx; + wx = wx + scalrefi * refin; + wy = wx * arefi + brefi; if (primListener) { - primListener->iprimChanged(r_x, r_y, b_x, b_y, g_x, g_y, wx, wy); + primListener->iprimChanged(r_x, r_y, b_x, b_y, g_x, g_y, wx, wy, meanx, meany); } } } @@ -2116,6 +2262,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } double tempsym = 5003.; + double greensym = 1.; int wmodel = 0;//wmodel allows - arbitrary - choice of illuminant and temp with choice if (params->colorappearance.wbmodel == "RawT") { @@ -2128,28 +2275,37 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->colorappearance.catmethod == "symg" && wmodel == 2) { tempsym = params->wb.temperature;//force white balance in symmetric - } else { + } else if(params->colorappearance.autotempout) { if (params->colorappearance.illum == "iA") {//otherwise force illuminant source tempsym = 2856.; + greensym = 1.; } else if (params->colorappearance.illum == "i41") { tempsym = 4100.; + greensym = 1.; } else if (params->colorappearance.illum == "i50") { tempsym = 5003.; + greensym = 1.; } else if (params->colorappearance.illum == "i55") { tempsym = 5503.; } else if (params->colorappearance.illum == "i60") { tempsym = 6000. ; + greensym = 1.; } else if (params->colorappearance.illum == "i65") { tempsym = 6504.; + greensym = 1.; } else if (params->colorappearance.illum == "i75") { tempsym = 7504.; + greensym = 1.; } else if (params->colorappearance.illum == "ifree") { tempsym = params->wb.temperature;//force white balance in symmetric + greensym = 1.; } + } else { + tempsym = params->colorappearance.tempout; + greensym = params->colorappearance.greenout; } - - if (params->colorappearance.enabled && params->colorappearance.autotempout) { - acListener->wbCamChanged(tempsym, 1.f); //real temp and tint = 1. + if (params->colorappearance.enabled) { + acListener->wbCamChanged(tempsym, greensym); //real temp and tint. } } else { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index e236aed17..f276bc30a 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -305,6 +305,7 @@ protected: LocLLmaskCurve locllmasCurve; LocHHmaskCurve lochhmasCurve; LocHHmaskCurve lochhhmasCurve; + LocHHmaskCurve lochhhmascieCurve; LocCCmaskCurve locccmasexpCurve; LocLLmaskCurve locllmasexpCurve; LocHHmaskCurve lochhmasexpCurve; @@ -343,6 +344,7 @@ protected: LocwavCurve locwavCurve; LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; + LocwavCurve loclmasCurveciewav; LocwavCurve loclevwavCurve; LocwavCurve locconwavCurve; LocwavCurve loccompwavCurve; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 58e597dce..3283c8b64 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -193,7 +193,8 @@ enum class BlurType { void moyeqt(Imagefloat* working, float &moyS, float &eqty); void luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf &curve); - void ciecamloc_02float(const struct local_params& lp, int sp, LabImage* lab, int bfw, int bfh, int call, int sk, const LUTf& cielocalcurve, bool localcieutili, const LUTf& cielocalcurve2, bool localcieutili2, const LUTf& jzlocalcurve, bool localjzutili, const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, const LocCHCurve& locchCurvejz, const LocHHCurve& lochhCurve, const LocLHCurve& loclhCurve, bool HHcurvejz, bool CHcurvejz, bool LHcurvejz, const LocwavCurve& locwavCurvejz, bool locwavutilijz); + void ciecamloc_02float(struct local_params& lp, int sp, LabImage* lab, int bfw, int bfh, int call, int sk, const LUTf& cielocalcurve, bool localcieutili, const LUTf& cielocalcurve2, bool localcieutili2, const LUTf& jzlocalcurve, bool localjzutili, const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, const LocCHCurve& locchCurvejz, const LocHHCurve& lochhCurve, const LocLHCurve& loclhCurve, bool HHcurvejz, bool CHcurvejz, bool LHcurvejz, + const LocwavCurve& locwavCurvejz, bool locwavutilijz, float &maxicam, float &comtsig, float &lightsig); void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const procparams::ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, @@ -252,7 +253,7 @@ enum class BlurType { float strumask, bool astool, const LocCCmaskCurve & locccmasCurve, bool lcmasutili, const LocLLmaskCurve & locllmasCurve, bool llmasutili, - const LocHHmaskCurve & lochhmasCurve, bool lhmasutili, const LocHHmaskCurve & lochhhmasCurve, bool lhhmasutili, + const LocHHmaskCurve & lochhmasCurve, bool lhmasutili, const LocHHmaskCurve & lochhhmasCurve, bool lhhmasutili, bool multiThread, bool enaMask, bool showmaske, bool deltaE, bool modmask, bool zero, bool modif, float chrom, float rad, float lap, float gamma, float slope, float blendm, float blendmab, int shado, int highl, float amountcd, float anchorcd, const LUTf& lmasklocalcurve, bool localmaskutili, const LocwavCurve & loclmasCurvecolwav, bool lmasutilicolwav, int level_bl, int level_hl, int level_br, int level_hr, @@ -270,10 +271,10 @@ enum class BlurType { void loccont(int bfw, int bfh, LabImage* tmp1, float rad, float stren, int sk); void rex_poisson_dct(float * data, size_t nx, size_t ny, double m); - void mean_dt(const float * data, size_t size, double& mean_p, double& dt_p); + void mean_dt(const float * data, int size, double& mean_p, double& dt_p, double nbstd); float *cos_table(size_t size); - void normalize_mean_dt(float *data, const float *ref, size_t size, float mod, float sigm, float mdef, float sdef, float mdef2, float sdef2); + void normalize_mean_dt(float *data, const float *ref, int size, float mod, float sigm, float mdef, float sdef, float mdef2, float sdef2, double nbstd); void retinex_pde(const float *datain, float * dataout, int bfw, int bfh, float thresh, float multy, float *dE, int show, int dEenable, int normalize); void exposure_pde(float *dataor, float *datain, float * dataout, int bfw, int bfh, float thresh, float mod); void fftw_convol_blur(float *input, float *output, int bfw, int bfh, float radius, int fftkern, int algo); @@ -291,7 +292,7 @@ enum class BlurType { //3 functions from Alberto Griggio, adapted J.Desmis 2019 void filmGrain(Imagefloat *rgb, int isogr, int strengr, int scalegr,float divgr, int bfw, int bfh, int call, int fw, int fh); void log_encode(Imagefloat *rgb, struct local_params & lp, bool multiThread, int bfw, int bfh); - void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); + void getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int *whits, int *blacks, int *whitslog, int *blackslog, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE); void MSRLocal(int call, int sp, bool fftw, int lum, float** reducDE, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, LabImage * bufmaskorigreti, float** luminance, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, @@ -331,7 +332,7 @@ enum class BlurType { const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, - const LocCCmaskCurve& locccmasCurve, bool lcmasutili, const LocLLmaskCurve& locllmasCurve, bool llmasutili, const LocHHmaskCurve& lochhmasCurve, bool lhmasutili, const LocHHmaskCurve& llochhhmasCurve, bool lhhmasutili, + const LocCCmaskCurve& locccmasCurve, bool lcmasutili, const LocLLmaskCurve& locllmasCurve, bool llmasutili, const LocHHmaskCurve& lochhmasCurve, bool lhmasutili, const LocHHmaskCurve& llochhhmasCurve, bool lhhmasutili, const LocHHmaskCurve& llochhhmascieCurve, bool lhhmascieutili, const LocCCmaskCurve& locccmasexpCurve, bool lcmasexputili, const LocLLmaskCurve& locllmasexpCurve, bool llmasexputili, const LocHHmaskCurve& lochhmasexpCurve, bool lhmasexputili, const LocCCmaskCurve& locccmasSHCurve, bool lcmasSHutili, const LocLLmaskCurve& locllmasSHCurve, bool llmasSHutili, const LocHHmaskCurve& lochhmasSHCurve, bool lhmasSHutili, const LocCCmaskCurve& locccmasvibCurve, bool lcmasvibutili, const LocLLmaskCurve& locllmasvibCurve, bool llmasvibutili, const LocHHmaskCurve& lochhmasvibCurve, bool lhmasvibutili, @@ -348,6 +349,7 @@ enum class BlurType { const LocwavCurve& loclmasCurveblwav, bool lmasutiliblwav, const LocwavCurve& loclmasCurvecolwav, bool lmasutilicolwav, + const LocwavCurve& loclmasCurveciewav, bool lmasutiliciewav, const LocwavCurve& locwavCurve, bool locwavutili, const LocwavCurve& locwavCurvejz, bool locwavutilijz, const LocwavCurve& loclevwavCurve, bool loclevwavutili, @@ -362,10 +364,12 @@ enum class BlurType { double& huerefblur, double &chromarefblur, double& lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int &lastsav, bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &ill, float &contsig, float &lightsig, float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46); - - void tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); + + void tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); + void tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); + void tone_eqcam(ImProcFunctions *ipf, Imagefloat *rgb, int midtone, const Glib::ustring &workingProfile, double scale, bool multithread); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -507,7 +511,9 @@ enum class BlurType { static void rgb2lab(std::uint8_t red, std::uint8_t green, std::uint8_t blue, float &L, float &a, float &b, const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true); Imagefloat* lab2rgbOut(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); // CieImage *ciec; - void workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring &profile, double gampos, double slpos, int &illum, int prim, cmsHTRANSFORM &transform, bool normalizeIn = true, bool normalizeOut = true, bool keepTransForm = false) const; + void workingtrc(int sp, Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring &profile, double gampos, double slpos, int cat, int &illum, int prim, int locprim, + float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, + cmsHTRANSFORM &transform, bool normalizeIn = true, bool normalizeOut = true, bool keepTransForm = false, bool gamutcontrol = false) const; void preserv(LabImage *nprevl, LabImage *provis, int cw, int ch); bool transCoord(int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr) const; diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index ffa6ea8c0..d2b2c9f2c 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -34,7 +34,8 @@ namespace rtengine { -namespace { +namespace +{ inline void copyAndClampLine(const float *src, unsigned char *dst, const int W) { @@ -65,10 +66,12 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r rgb_xyzv[i][j] = F2V(rgb_xyzf[i][j]); } } + #endif #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int i = 0; i < H; ++i) { float* rL = src->L[i]; float* ra = src->a[i]; @@ -80,19 +83,21 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r float gbuffer[W] ALIGNED16; float bbuffer[W] ALIGNED16; int j = 0; + for (; j < W - 3; j += 4) { vfloat R, G, B; vfloat x_, y_, z_; - Color::Lab2XYZ(LVFU(rL[j]), LVFU(ra[j]), LVFU(rb[j]), x_, y_, z_ ); + Color::Lab2XYZ(LVFU(rL[j]), LVFU(ra[j]), LVFU(rb[j]), x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzv); STVF(rbuffer[j], Color::gamma2curve[R]); STVF(gbuffer[j], Color::gamma2curve[G]); STVF(bbuffer[j], Color::gamma2curve[B]); } + for (; j < W; ++j) { float R, G, B; float x_, y_, z_; - Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_ ); + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzf); rbuffer[j] = Color::gamma2curve[R]; gbuffer[j] = Color::gamma2curve[G]; @@ -106,16 +111,18 @@ inline void copyAndClamp(const LabImage *src, unsigned char *dst, const double r } #else + for (int j = 0; j < W; ++j) { float R, G, B; float x_, y_, z_; - Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_ ); + Color::Lab2XYZ(rL[j], ra[j], rb[j], x_, y_, z_); Color::xyz2rgb(x_, y_, z_, R, G, B, rgb_xyzf); dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[R]); dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[G]); dst[ix++] = uint16ToUint8Rounded(Color::gamma2curve[B]); } + #endif } } @@ -250,7 +257,7 @@ Image8* ImProcFunctions::lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, lcmsMutex->lock(); cmsHPROFILE LabIProf = cmsCreateLab4Profile(nullptr); - cmsHTRANSFORM hTransform = cmsCreateTransform (LabIProf, TYPE_Lab_DBL, oprof, TYPE_RGB_FLT, icm.outputIntent, flags); + cmsHTRANSFORM hTransform = cmsCreateTransform(LabIProf, TYPE_Lab_DBL, oprof, TYPE_RGB_FLT, icm.outputIntent, flags); cmsCloseProfile(LabIProf); lcmsMutex->unlock(); @@ -284,7 +291,7 @@ Image8* ImProcFunctions::lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, buffer[iy++] = rb[j] / 327.68f; } - cmsDoTransform (hTransform, buffer, outbuffer, cw); + cmsDoTransform(hTransform, buffer, outbuffer, cw); copyAndClampLine(outbuffer, data + ix, cw); } } // End of parallelization @@ -354,7 +361,7 @@ Imagefloat* ImProcFunctions::lab2rgbOut(LabImage* lab, int cx, int cy, int cw, i cmsCloseProfile(iprof); image->normalizeFloatTo65535(); } else { - + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif @@ -390,35 +397,133 @@ Imagefloat* ImProcFunctions::lab2rgbOut(LabImage* lab, int cx, int cy, int cw, i } void ImProcFunctions::preserv(LabImage *nprevl, LabImage *provis, int cw, int ch) -{//avoid too strong in middle values chroma when changing primaries - float pres = 0.01f * params->icm.preser; - float neutral = 2000000000.f;//if a2 + b2 < 200000000 scale 0..100 a and b about : 140 > a & b > -140 decrease effect - float medneutral = 10000000.f;//plein effect 10 > a & b > -10 - float aaneu = 1.f / (medneutral - neutral); - float bbneu = - aaneu * neutral; +{ + //avoid too strong in middle values chroma when changing primaries + float pres = 0.01f * params->icm.preser; + float neutral = 2000000000.f;//if a2 + b2 < 200000000 scale 0..100 a and b about : 140 > a & b > -140 decrease effect + float medneutral = 10000000.f;//plein effect 10 > a & b > -10 + float aaneu = 1.f / (medneutral - neutral); + float bbneu = - aaneu * neutral; #ifdef _OPENMP - #pragma omp for schedule(dynamic, 16) nowait + #pragma omp for schedule(dynamic, 16) nowait #endif - for (int i = 0; i < ch; ++i) + + for (int i = 0; i < ch; ++i) for (int j = 0; j < cw; ++j) { float neu = SQR(provis->a[i][j]) + SQR(provis->b[i][j]); + if (neu < medneutral) {//plein effect - nprevl->a[i][j] = intp(pres, provis->a[i][j], nprevl->a[i][j]); - nprevl->b[i][j] = intp(pres, provis->b[i][j], nprevl->b[i][j]); + nprevl->a[i][j] = intp(pres, provis->a[i][j], nprevl->a[i][j]); + nprevl->b[i][j] = intp(pres, provis->b[i][j], nprevl->b[i][j]); } else if (neu < neutral) {//decrease effect float presred = aaneu * neu + bbneu; - nprevl->a[i][j] = intp(pres * presred, provis->a[i][j], nprevl->a[i][j]); - nprevl->b[i][j] = intp(pres * presred, provis->b[i][j], nprevl->b[i][j]); - } + nprevl->a[i][j] = intp(pres * presred, provis->a[i][j], nprevl->a[i][j]); + nprevl->b[i][j] = intp(pres * presred, provis->b[i][j], nprevl->b[i][j]); + } } } -void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring &profile, double gampos, double slpos, int &illum, int prim, cmsHTRANSFORM &transform, bool normalizeIn, bool normalizeOut, bool keepTransForm) const +void ImProcFunctions::workingtrc(int sp, Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, Glib::ustring &profile, double gampos, double slpos, int cat, int &illum, int prim, int locprim, + float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, + cmsHTRANSFORM &transform, bool normalizeIn, bool normalizeOut, bool keepTransForm, bool gamutcontrol) const { const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + double wb2[3][3]; + float epsilon = 0.000001f; + + // if(gamutcontrol) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < ch; ++i) + for (int j = 0; j < cw; ++j) { + src->r(i, j) = (float) rtengine::max(src->r(i, j), epsilon); + src->g(i, j) = (float) rtengine::max(src->g(i, j), epsilon); + src->b(i, j) = (float) rtengine::max(src->b(i, j), epsilon); + } + // } + + + + if (mul == 5) {//only second pass workingtrc - avoid this code first pass + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + wb2[r][c] = wprof[r][c]; + } + } + + //provis - samme approach as in WB itcwb + //we can add others function on colors ...others than mean (actually) + int precision = 3; + const int bfw = cw / precision + ((cw % precision) > 0 ? 1 : 0); + const int bfh = ch / precision + ((ch % precision) > 0 ? 1 : 0); + + Imagefloat *provis = nullptr; + provis = new Imagefloat(bfw, bfh);//cw, ch + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < bfh ; ++i) { + const int ii = i * precision; + + if (ii < ch) { + for (int j = 0, jj = 0; j < bfw ; ++j, jj += precision) { + provis->r(i, j) = src->r(ii, jj); + provis->g(i, j) = src->g(ii, jj); + provis->b(i, j) = src->b(ii, jj); + } + } + } + + +// I try to find the dominant color by a simple way (average of x and y) +// It is probably intellectually more relevant to place this algorithm at the end, but it is complex at the GUI level (at least for me). +// The errors made are relatively minimal and result seems good enough + meanx = 0.f; + meany = 0.f; + +#ifdef _OPENMP + #pragma omp parallel for reduction(+:meanx, meany) if(multiThread) +#endif + + for (int y = 0; y < bfh ; ++y) { + for (int x = 0; x < bfw ; ++x) { + const float RR = provis->r(y, x); + const float GG = provis->g(y, x); + const float BB = provis->b(y, x); + float xcb, ycb, zcb; + Color::rgbxyz(RR, GG, BB, xcb, ycb, zcb, wb2); + float X_r = xcb; + float Y_r = ycb; + float Z_r = zcb; + if(gamutcontrol) { + Color::gamutmap(X_r, Y_r, Z_r, wb2);//gamut control + } + const float som = X_r + Y_r + Z_r; + X_r = X_r / som; + Y_r = Y_r / som; + meanx += X_r; + meany += Y_r; + } + } + + meanx /= (bfh * bfw); + meany /= (bfh * bfw); + meanx += 0.005f; + meany += 0.005f; //ampirical mean delta with value end in process + + if (settings->verbose) { + printf("Estimation dominant color : x=%f y=%f\n", (double) meanx, (double) meany); + } + + delete provis; + } + double wprofprim[3][3];//store primaries to XYZ - bool gamutcontrol = params->icm.gamut; + const float toxyz[3][3] = { { static_cast(wprof[0][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x @@ -435,7 +540,7 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } }; - if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1" || profile == "JDCmax") { + if (profile == "sRGB" || profile == "Adobe RGB" || profile == "ProPhoto" || profile == "WideGamut" || profile == "BruceRGB" || profile == "Beta RGB" || profile == "BestRGB" || profile == "Rec2020" || profile == "ACESp0" || profile == "ACESp1" || profile == "JDCmax" || profile == "JDCmax stdA") { if (settings->verbose) { printf("Profile=%s\n", profile.c_str()); } @@ -455,22 +560,22 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, for (int i = 0; i < ch; ++i) for (int j = 0; j < cw; ++j) { - float r = src->r(i, j); - float g = src->g(i, j); - float b = src->b(i, j); - r = (Color::igammatab_srgb[r]) / 65535.f; - g = (Color::igammatab_srgb[g]) / 65535.f; - b = (Color::igammatab_srgb[b]) / 65535.f; - dst->r(i, j) = r; - dst->g(i, j) = g; - dst->b(i, j) = b; + double r = (double) src->r(i, j); + double g = (double) src->g(i, j); + double b = (double) src->b(i, j); + r = (Color::igammatab_srgb[r]) / 65535.; + g = (Color::igammatab_srgb[g]) / 65535.; + b = (Color::igammatab_srgb[b]) / 65535.; + dst->r(i, j) = r; + dst->g(i, j) = g; + dst->b(i, j) = b; } return; } - if (mul == 1 || (params->icm.wprim == ColorManagementParams::Primaries::DEFAULT && params->icm.will == ColorManagementParams::Illuminant::DEFAULT)) { //shortcut and speedup when no call primaries and illuminant - no gamut control...in this case be careful + if (mul == 1) { // || (params->icm.wprim == ColorManagementParams::Primaries::DEFAULT && params->icm.will == ColorManagementParams::Illuminant::DEFAULT)) { //shortcut and speedup when no call primaries and illuminant - no gamut control...in this case be careful GammaValues g_a; //gamma parameters double pwr = 1.0 / static_cast(gampos); Color::calcGamma(pwr, slpos, g_a); // call to calcGamma with selected gamma and slope @@ -510,7 +615,78 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, float greyy = params->icm.grey; float epsil = 0.0001f; - if (prim == 13) {//convert datas area to xy + double Wx = 1.0; + double Wz = 1.0; + cmsCIExyY xyD; + + if (locprim == 1 && mul == 5) { + rdx = params->locallab.spots.at(sp).redxl; + rdy = params->locallab.spots.at(sp).redyl; + grx = params->locallab.spots.at(sp).grexl; + gry = params->locallab.spots.at(sp).greyl; + blx = params->locallab.spots.at(sp).bluxl; + bly = params->locallab.spots.at(sp).bluyl; + + if (params->locallab.spots.at(sp).illMethod == "d50") { + illum = 2; + xyD = {0.3457, 0.3585, 1.0}; // near LCMS values but not perfect... it's a compromise!! + Wx = 0.964295676; + Wz = 0.825104603; + } else if (params->locallab.spots.at(sp).illMethod == "d60") { + illum = 4; + Wx = 0.952646075; + Wz = 1.008825184; + xyD = {0.32168, 0.33767, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "d65") { + illum = 5; + Wx = 0.95045471; + Wz = 1.08905029; + xyD = {0.312700492, 0.329000939, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "d41") { + illum = 1; + Wx = 0.991488263; + Wz = 0.631604625; + xyD = {0.376137, 0.374021, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "d55") { + illum = 3; + Wx = 0.956565934; + Wz = 0.920253249; + xyD = {0.332424, 0.347426, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "d80") { + illum = 6; + Wx = 0.950095542; + Wz = 1.284213976; + xyD = {0.293756, 0.309185, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "d120") { + illum = 7; + Wx = 0.979182; + Wz = 1.623623; + xyD = {0.269669, 0.28078, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "stda") { + illum = 8; + Wx = 1.098500393; + Wz = 0.355848714; + xyD = {0.447573, 0.407440, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "T2000") { + illum = 9; + Wx = 1.274335; + Wz = 0.145233; + xyD = {0.526591, 0.41331, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "T1500") { + illum = 10; + Wx = 1.489921; + Wz = 0.053826; + xyD = {0.585703, 0.393157, 1.0}; + } else if (params->locallab.spots.at(sp).illMethod == "iE") { + illum = 20; + Wx = 1.; + Wz = 1.; + xyD = {0.333333, 0.333333, 1.0}; + } + + } + + if (prim == 14 && locprim == 0 && mul == 5) {//convert datas area to xy float redgraphx = params->icm.labgridcieALow; float redgraphy = params->icm.labgridcieBLow; float blugraphx = params->icm.labgridcieAHigh; @@ -561,76 +737,307 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, return; } + enum class ColorTemp { + D50 = 5003, // for Widegamut, ProPhoto Best, Beta -> D50 + D65 = 6504, // for sRGB, AdobeRGB, Bruce Rec2020 -> D65 + D60 = 6005 // for ACES AP0 and AP1 + }; + double tempv4 = 5003.; + double p[6]; //primaries - switch (ColorManagementParams::Primaries(prim)) { - case ColorManagementParams::Primaries::DEFAULT: { - break; + if (locprim == 0 && mul == 5) { + switch (ColorManagementParams::Primaries(prim)) { + case ColorManagementParams::Primaries::DEFAULT: { + break; + } + + case ColorManagementParams::Primaries::SRGB: { + profile = "sRGB"; + break; + } + + case ColorManagementParams::Primaries::ADOBE_RGB: { + profile = "Adobe RGB"; + break; + } + + case ColorManagementParams::Primaries::PRO_PHOTO: { + profile = "ProPhoto"; + break; + } + + case ColorManagementParams::Primaries::REC2020: { + profile = "Rec2020"; + break; + } + + case ColorManagementParams::Primaries::ACES_P1: { + profile = "ACESp1"; + break; + } + + case ColorManagementParams::Primaries::WIDE_GAMUT: { + profile = "WideGamut"; + break; + } + + case ColorManagementParams::Primaries::ACES_P0: { + profile = "ACESp0"; + break; + } + + case ColorManagementParams::Primaries::JDC_MAX: { + profile = "JDCmax"; + break; + } + + case ColorManagementParams::Primaries::JDC_MAXSTDA: { + profile = "JDCmax stdA"; + break; + } + + case ColorManagementParams::Primaries::BRUCE_RGB: { + profile = "BruceRGB"; + break; + } + + case ColorManagementParams::Primaries::BETA_RGB: { + profile = "Beta RGB"; + break; + } + + case ColorManagementParams::Primaries::BEST_RGB: { + profile = "BestRGB"; + break; + } + + case ColorManagementParams::Primaries::CUSTOM: { + profile = "Custom"; + break; + } + + case ColorManagementParams::Primaries::CUSTOM_GRID: { + profile = "Custom"; + break; + } + } + } else if (locprim == 1 && mul == 5) { + //local primaries + if (prim == 1) { + p[0] = 0.6400; // sRGB primaries + p[1] = 0.3300; + p[2] = 0.3000; + p[3] = 0.6000; + p[4] = 0.1500; + p[5] = 0.0600; + tempv4 = 6504.; + Wx = 0.95045471; + Wz = 1.08905029; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + + } else if (prim == 2) { + p[0] = 0.6400; //Adobe primaries + p[1] = 0.3300; + p[2] = 0.2100; + p[3] = 0.7100; + p[4] = 0.1500; + p[5] = 0.0600; + tempv4 = 6504.; + Wx = 0.95045471; + Wz = 1.08905029; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + + } else if (prim == 3) { + p[0] = 0.7347; //ProPhoto and default primaries + p[1] = 0.2653; + p[2] = 0.1596; + p[3] = 0.8404; + p[4] = 0.0366; + p[5] = 0.0001; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + + } else if (prim == 4) { + p[0] = 0.7080; // Rec2020 primaries + p[1] = 0.2920; + p[2] = 0.1700; + p[3] = 0.7970; + p[4] = 0.1310; + p[5] = 0.0460; + tempv4 = 6504.; + Wx = 0.95045471; + Wz = 1.08905029; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + + } else if (prim == 5) { + p[0] = 0.713; // ACES P1 primaries + p[1] = 0.293; + p[2] = 0.165; + p[3] = 0.830; + p[4] = 0.128; + p[5] = 0.044; + tempv4 = 6004.; + Wx = 0.952646075; + Wz = 1.008825184; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + + } else if (prim == 6) { + p[0] = 0.7350; //Widegamut primaries + p[1] = 0.2650; + p[2] = 0.1150; + p[3] = 0.8260; + p[4] = 0.1570; + p[5] = 0.0180; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 7) { + p[0] = 0.7347; //ACESp0 primaries + p[1] = 0.2653; + p[2] = 0.; + p[3] = 1.0; + p[4] = 0.0001; + p[5] = -0.0770; + tempv4 = 6004.; + Wx = 0.952646075; + Wz = 1.008825184; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 8) { + p[0] = 0.734702; // JDC max primaries + p[1] = 0.265302; + p[2] = 0.021908; + p[3] = 0.930288; + p[4] = 0.120593; + p[5] = 0.001583; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 9) { + p[0] = 0.734702; // JDC max primaries + p[1] = 0.265302; + p[2] = 0.021908; + p[3] = 0.930288; + p[4] = 0.120593; + p[5] = 0.001583; + Wx = 1.098500393; + Wz = 0.355848714; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 10) { + p[0] = 0.64; // Bruce primaries + p[1] = 0.33; + p[2] = 0.28; + p[3] = 0.65; + p[4] = 0.15; + p[5] = 0.06; + Wx = 0.95045471; + Wz = 1.08905029; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 11) { + p[0] = 0.6888; // Beta primaries + p[1] = 0.3112; + p[2] = 0.1986; + p[3] = 0.7551; + p[4] = 0.1265; + p[5] = 0.0352; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 12) { + p[0] = 0.7347; // Best primaries + p[1] = 0.2653; + p[2] = 0.2150; + p[3] = 0.7750; + p[4] = 0.13; + p[5] = 0.0350; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; + } else if (prim == 15) { + p[0] = rdx; + p[1] = rdy; + p[2] = grx; + p[3] = gry; + p[4] = blx; + p[5] = bly; + } else { + p[0] = 0.7347; //ProPhoto and default primaries + p[1] = 0.2653; + p[2] = 0.1596; + p[3] = 0.8404; + p[4] = 0.0366; + p[5] = 0.0001; + Wx = 0.964295676; + Wz = 0.825104603; + rdx = p[0]; + rdy = p[1]; + grx = p[2]; + gry = p[3]; + blx = p[4]; + bly = p[5]; } - case ColorManagementParams::Primaries::SRGB: { - profile = "sRGB"; - break; - } - case ColorManagementParams::Primaries::ADOBE_RGB: { - profile = "Adobe RGB"; - break; - } - - case ColorManagementParams::Primaries::PRO_PHOTO: { - profile = "ProPhoto"; - break; - } - - case ColorManagementParams::Primaries::REC2020: { - profile = "Rec2020"; - break; - } - - case ColorManagementParams::Primaries::ACES_P1: { - profile = "ACESp1"; - break; - } - - case ColorManagementParams::Primaries::WIDE_GAMUT: { - profile = "WideGamut"; - break; - } - - case ColorManagementParams::Primaries::ACES_P0: { - profile = "ACESp0"; - break; - } - - case ColorManagementParams::Primaries::JDC_MAX: { - profile = "JDCmax"; - break; - } - - case ColorManagementParams::Primaries::BRUCE_RGB: { - profile = "BruceRGB"; - break; - } - - case ColorManagementParams::Primaries::BETA_RGB: { - profile = "Beta RGB"; - break; - } - - case ColorManagementParams::Primaries::BEST_RGB: { - profile = "BestRGB"; - break; - } - - case ColorManagementParams::Primaries::CUSTOM: { - profile = "Custom"; - break; - } - - case ColorManagementParams::Primaries::CUSTOM_GRID: { - profile = "Custom"; - break; - } } if (settings->verbose && prim != 0) { @@ -656,161 +1063,165 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, // int select_temp = 1; //5003K constexpr double eps = 0.000000001; // not divide by zero - enum class ColorTemp { - D50 = 5003, // for Widegamut, ProPhoto Best, Beta -> D50 - D65 = 6504, // for sRGB, AdobeRGB, Bruce Rec2020 -> D65 - D60 = 6005 // for ACES AP0 and AP1 - - }; - double tempv4 = 5003.; - double p[6]; //primaries - double Wx = 1.0; - double Wz = 1.0; - //primaries for 10 working profiles ==> output profiles - if (profile == "WideGamut") { - p[0] = 0.7350; //Widegamut primaries - p[1] = 0.2650; - p[2] = 0.1150; - p[3] = 0.8260; - p[4] = 0.1570; - p[5] = 0.0180; - illum = toUnderlying(ColorManagementParams::Illuminant::D50); - Wx = 0.964295676; - Wz = 0.825104603; + if (locprim == 0 && mul ==5) { + if (profile == "WideGamut") { + p[0] = 0.7350; //Widegamut primaries + p[1] = 0.2650; + p[2] = 0.1150; + p[3] = 0.8260; + p[4] = 0.1570; + p[5] = 0.0180; + illum = toUnderlying(ColorManagementParams::Illuminant::D50); + Wx = 0.964295676; + Wz = 0.825104603; - } else if (profile == "Adobe RGB") { - p[0] = 0.6400; //Adobe primaries - p[1] = 0.3300; - p[2] = 0.2100; - p[3] = 0.7100; - p[4] = 0.1500; - p[5] = 0.0600; - tempv4 = 6504.; - illum = toUnderlying(ColorManagementParams::Illuminant::D65); - Wx = 0.95045471; - Wz = 1.08905029; + } else if (profile == "Adobe RGB") { + p[0] = 0.6400; //Adobe primaries + p[1] = 0.3300; + p[2] = 0.2100; + p[3] = 0.7100; + p[4] = 0.1500; + p[5] = 0.0600; + tempv4 = 6504.; + illum = toUnderlying(ColorManagementParams::Illuminant::D65); + Wx = 0.95045471; + Wz = 1.08905029; - } else if (profile == "sRGB") { - p[0] = 0.6400; // sRGB primaries - p[1] = 0.3300; - p[2] = 0.3000; - p[3] = 0.6000; - p[4] = 0.1500; - p[5] = 0.0600; - tempv4 = 6504.; - illum = toUnderlying(ColorManagementParams::Illuminant::D65); - Wx = 0.95045471; - Wz = 1.08905029; + } else if (profile == "sRGB") { + p[0] = 0.6400; // sRGB primaries + p[1] = 0.3300; + p[2] = 0.3000; + p[3] = 0.6000; + p[4] = 0.1500; + p[5] = 0.0600; + tempv4 = 6504.; + illum = toUnderlying(ColorManagementParams::Illuminant::D65); + Wx = 0.95045471; + Wz = 1.08905029; - } else if (profile == "BruceRGB") { - p[0] = 0.6400; // Bruce primaries - p[1] = 0.3300; - p[2] = 0.2800; - p[3] = 0.6500; - p[4] = 0.1500; - p[5] = 0.0600; - tempv4 = 6504.; - illum = toUnderlying(ColorManagementParams::Illuminant::D65); - Wx = 0.95045471; - Wz = 1.08905029; + } else if (profile == "BruceRGB") { + p[0] = 0.6400; // Bruce primaries + p[1] = 0.3300; + p[2] = 0.2800; + p[3] = 0.6500; + p[4] = 0.1500; + p[5] = 0.0600; + tempv4 = 6504.; + illum = toUnderlying(ColorManagementParams::Illuminant::D65); + Wx = 0.95045471; + Wz = 1.08905029; - } else if (profile == "Beta RGB") { - p[0] = 0.6888; // Beta primaries - p[1] = 0.3112; - p[2] = 0.1986; - p[3] = 0.7551; - p[4] = 0.1265; - p[5] = 0.0352; - illum = toUnderlying(ColorManagementParams::Illuminant::D50); - Wx = 0.964295676; - Wz = 0.825104603; + } else if (profile == "Beta RGB") { + p[0] = 0.6888; // Beta primaries + p[1] = 0.3112; + p[2] = 0.1986; + p[3] = 0.7551; + p[4] = 0.1265; + p[5] = 0.0352; + illum = toUnderlying(ColorManagementParams::Illuminant::D50); + Wx = 0.964295676; + Wz = 0.825104603; - } else if (profile == "BestRGB") { - p[0] = 0.7347; // Best primaries - p[1] = 0.2653; - p[2] = 0.2150; - p[3] = 0.7750; - p[4] = 0.1300; - p[5] = 0.0350; - illum = toUnderlying(ColorManagementParams::Illuminant::D50); - Wx = 0.964295676; - Wz = 0.825104603; + } else if (profile == "BestRGB") { + p[0] = 0.7347; // Best primaries + p[1] = 0.2653; + p[2] = 0.2150; + p[3] = 0.7750; + p[4] = 0.1300; + p[5] = 0.0350; + illum = toUnderlying(ColorManagementParams::Illuminant::D50); + Wx = 0.964295676; + Wz = 0.825104603; - } else if (profile == "Rec2020") { - p[0] = 0.7080; // Rec2020 primaries - p[1] = 0.2920; - p[2] = 0.1700; - p[3] = 0.7970; - p[4] = 0.1310; - p[5] = 0.0460; - tempv4 = 6504.; - illum = toUnderlying(ColorManagementParams::Illuminant::D65); - Wx = 0.95045471; - Wz = 1.08905029; + } else if (profile == "Rec2020") { + p[0] = 0.7080; // Rec2020 primaries + p[1] = 0.2920; + p[2] = 0.1700; + p[3] = 0.7970; + p[4] = 0.1310; + p[5] = 0.0460; + tempv4 = 6504.; + illum = toUnderlying(ColorManagementParams::Illuminant::D65); + Wx = 0.95045471; + Wz = 1.08905029; - } else if (profile == "ACESp0") { - p[0] = 0.7347; // ACES P0 primaries - p[1] = 0.2653; - p[2] = 0.0000; - p[3] = 1.0; - p[4] = 0.0001; - p[5] = -0.0770; - tempv4 = 6004.; - illum = toUnderlying(ColorManagementParams::Illuminant::D60); - Wx = 0.952646075; - Wz = 1.008825184; + } else if (profile == "ACESp0") { + p[0] = 0.7347; // ACES P0 primaries + p[1] = 0.2653; + p[2] = 0.0000; + p[3] = 1.0; + p[4] = 0.0001; + p[5] = -0.0770; + tempv4 = 6004.; + illum = toUnderlying(ColorManagementParams::Illuminant::D60); + Wx = 0.952646075; + Wz = 1.008825184; - } else if (profile == "JDCmax") { - p[0] = 0.734702; // JDC max primaries - p[1] = 0.265302; - p[2] = 0.021908; - p[3] = 0.930288; - p[4] = 0.120593; - p[5] = 0.001583; - illum = toUnderlying(ColorManagementParams::Illuminant::D50); - Wx = 0.964295676; - Wz = 0.825104603; + } else if (profile == "JDCmax") { + p[0] = 0.734702; // JDC max primaries + p[1] = 0.265302; + p[2] = 0.021908; + p[3] = 0.930288; + p[4] = 0.120593; + p[5] = 0.001583; + illum = toUnderlying(ColorManagementParams::Illuminant::D50); + Wx = 0.964295676; + Wz = 0.825104603; - } else if (profile == "ACESp1") { - p[0] = 0.713; // ACES P1 primaries - p[1] = 0.293; - p[2] = 0.165; - p[3] = 0.830; - p[4] = 0.128; - p[5] = 0.044; - tempv4 = 6004.; - illum = toUnderlying(ColorManagementParams::Illuminant::D60); - Wx = 0.952646075; - Wz = 1.008825184; + } else if (profile == "JDCmax stdA") { + p[0] = 0.734702; // JDC max primaries and stdA + p[1] = 0.265302; + p[2] = 0.021908; + p[3] = 0.930288; + p[4] = 0.120593; + p[5] = 0.001583; + illum = toUnderlying(ColorManagementParams::Illuminant::STDA); + Wx = 1.098500393; + Wz = 0.355848714; - } else if (profile == "ProPhoto") { - p[0] = 0.7347; //ProPhoto and default primaries - p[1] = 0.2653; - p[2] = 0.1596; - p[3] = 0.8404; - p[4] = 0.0366; - p[5] = 0.0001; - illum = toUnderlying(ColorManagementParams::Illuminant::D50); - Wx = 0.964295676; - Wz = 0.825104603; + } else if (profile == "ACESp1") { + p[0] = 0.713; // ACES P1 primaries + p[1] = 0.293; + p[2] = 0.165; + p[3] = 0.830; + p[4] = 0.128; + p[5] = 0.044; + tempv4 = 6004.; + illum = toUnderlying(ColorManagementParams::Illuminant::D60); + Wx = 0.952646075; + Wz = 1.008825184; - } else if (profile == "Custom") { - p[0] = redxx; - p[1] = redyy; - p[2] = grexx; - p[3] = greyy; - p[4] = bluxx; - p[5] = bluyy; - } else { - p[0] = 0.7347; //default primaries always unused - p[1] = 0.2653; - p[2] = 0.1596; - p[3] = 0.8404; - p[4] = 0.0366; - p[5] = 0.0001; + } else if (profile == "ProPhoto") { + p[0] = 0.7347; //ProPhoto and default primaries + p[1] = 0.2653; + p[2] = 0.1596; + p[3] = 0.8404; + p[4] = 0.0366; + p[5] = 0.0001; + illum = toUnderlying(ColorManagementParams::Illuminant::D50); + Wx = 0.964295676; + Wz = 0.825104603; + + } else if (profile == "Custom") { + p[0] = redxx; + p[1] = redyy; + p[2] = grexx; + p[3] = greyy; + p[4] = bluxx; + p[5] = bluyy; + + } else { + p[0] = 0.7347; //default primaries always unused + p[1] = 0.2653; + p[2] = 0.1596; + p[3] = 0.8404; + p[4] = 0.0366; + p[5] = 0.0001; + } } + if (slpos == 0) { slpos = eps; } @@ -827,153 +1238,192 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, gammaParams[3] = 1. / slpos; gammaParams[5] = 0.0; gammaParams[6] = 0.0; - // printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0, ga1, ga2, ga3, ga4); + if(rtengine::settings->verbose) { + printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", gammaParams[0], gammaParams[1], gammaParams[2], gammaParams[3], gammaParams[4]); + } // 7 parameters for smoother curves - cmsCIExyY xyD; +// cmsCIExyY xyD; Glib::ustring ills = "D50"; - switch (ColorManagementParams::Illuminant(illum)) { - case ColorManagementParams::Illuminant::DEFAULT: - case ColorManagementParams::Illuminant::STDA: - case ColorManagementParams::Illuminant::TUNGSTEN_2000K: - case ColorManagementParams::Illuminant::TUNGSTEN_1500K: { - break; + if (locprim == 0 && mul == 5) { + + switch (ColorManagementParams::Illuminant(illum)) { + case ColorManagementParams::Illuminant::DEFAULT: + case ColorManagementParams::Illuminant::STDA: + case ColorManagementParams::Illuminant::TUNGSTEN_2000K: + case ColorManagementParams::Illuminant::TUNGSTEN_1500K: + case ColorManagementParams::Illuminant::E:{ + break; + } + + case ColorManagementParams::Illuminant::D41: { + tempv4 = 4100.; + ills = "D41"; + break; + } + + case ColorManagementParams::Illuminant::D50: { + tempv4 = 5003.; + ills = "D50"; + break; + } + + case ColorManagementParams::Illuminant::D55: { + tempv4 = 5500.; + ills = "D55"; + break; + } + + case ColorManagementParams::Illuminant::D60: { + tempv4 = 6004.; + ills = "D60"; + break; + } + + case ColorManagementParams::Illuminant::D65: { + tempv4 = 6504.; + ills = "D65"; + break; + } + + case ColorManagementParams::Illuminant::D80: { + tempv4 = 8000.; + ills = "D80"; + break; + } + + case ColorManagementParams::Illuminant::D120: { + tempv4 = 12000.; + ills = "D120"; + break; + } } - case ColorManagementParams::Illuminant::D41: { - tempv4 = 4100.; - ills = "D41"; - break; - } + cmsWhitePointFromTemp(&xyD, tempv4); - case ColorManagementParams::Illuminant::D50: { - tempv4 = 5003.; - ills = "D50"; - break; - } + switch (ColorManagementParams::Illuminant(illum)) { + case ColorManagementParams::Illuminant::DEFAULT: { + break; + } - case ColorManagementParams::Illuminant::D55: { - tempv4 = 5500.; - ills = "D55"; - break; - } + case ColorManagementParams::Illuminant::D55: { + Wx = 0.956565934; + Wz = 0.920253249; + break; + } - case ColorManagementParams::Illuminant::D60: { - tempv4 = 6004.; - ills = "D60"; - break; - } + case ColorManagementParams::Illuminant::D80: { + Wx = 0.950095542; + Wz = 1.284213976; + break; + } - case ColorManagementParams::Illuminant::D65: { - tempv4 = 6504.; - ills = "D65"; - break; - } + case ColorManagementParams::Illuminant::D41: { + Wx = 0.991488263; + Wz = 0.631604625; + break; + } - case ColorManagementParams::Illuminant::D80: { - tempv4 = 8000.; - ills = "D80"; - break; - } + case ColorManagementParams::Illuminant::D50: { + xyD = {0.3457, 0.3585, 1.0}; // near LCMS values but not perfect... it's a compromise!! + Wx = 0.964295676; + Wz = 0.825104603; + break; + } - case ColorManagementParams::Illuminant::D120: { - tempv4 = 12000.; - ills = "D120"; - break; + case ColorManagementParams::Illuminant::D60: { + Wx = 0.952646075; + Wz = 1.008825184; + xyD = {0.32168, 0.33767, 1.0}; + break; + } + + case ColorManagementParams::Illuminant::D65: { + Wx = 0.95045471; + Wz = 1.08905029; + xyD = {0.312700492, 0.329000939, 1.0}; + break; + } + + case ColorManagementParams::Illuminant::D120: { + Wx = 0.979182; + Wz = 1.623623; + xyD = {0.269669, 0.28078, 1.0}; + break; + } + + case ColorManagementParams::Illuminant::STDA: { + Wx = 1.098500393; + Wz = 0.355848714; + xyD = {0.447573, 0.407440, 1.0}; + ills = "stdA 2875K"; + break; + } + + case ColorManagementParams::Illuminant::TUNGSTEN_2000K: { + Wx = 1.274335; + Wz = 0.145233; + xyD = {0.526591, 0.41331, 1.0}; + ills = "Tungsten 2000K"; + break; + } + + case ColorManagementParams::Illuminant::TUNGSTEN_1500K: { + Wx = 1.489921; + Wz = 0.053826; + xyD = {0.585703, 0.393157, 1.0}; + ills = "Tungsten 1500K"; + break; + } + + case ColorManagementParams::Illuminant::E: { + Wx = 1.; + Wz = 1.; + xyD = {0.33333, 0.33333, 1.0}; + ills = "E"; + break; + } + } } - cmsWhitePointFromTemp(&xyD, tempv4); + //xyD + //meanx, meany + // adjust refinement (purity) with a simple algorithm + if (mul == 5) { + double refin = 0.; - switch (ColorManagementParams::Illuminant(illum)) { - case ColorManagementParams::Illuminant::DEFAULT: { - break; + if (locprim == 1) { + refin = params->locallab.spots.at(sp).refi; + meanx += params->locallab.spots.at(sp).shiftxl; + meany += params->locallab.spots.at(sp).shiftyl; + } else if (locprim == 0) { + refin = params->icm.refi; + meanx += params->icm.shiftx; + meany += params->icm.shifty; } - case ColorManagementParams::Illuminant::D55: { - Wx = 0.956565934; - Wz = 0.920253249; - break; - } - - case ColorManagementParams::Illuminant::D80: { - Wx = 0.950095542; - Wz = 1.284213976; - break; - } - - case ColorManagementParams::Illuminant::D41: { - Wx = 0.991488263; - Wz = 0.631604625; - break; - } - - case ColorManagementParams::Illuminant::D50: { - xyD = {0.3457, 0.3585, 1.0}; // near LCMS values but not perfect... it's a compromise!! - Wx = 0.964295676; - Wz = 0.825104603; - break; - } - - case ColorManagementParams::Illuminant::D60: { - Wx = 0.952646075; - Wz = 1.008825184; - xyD = {0.32168, 0.33767, 1.0}; - break; - } - - case ColorManagementParams::Illuminant::D65: { - Wx = 0.95045471; - Wz = 1.08905029; - xyD = {0.312700492, 0.329000939, 1.0}; - break; - } - - case ColorManagementParams::Illuminant::D120: { - Wx = 0.979182; - Wz = 1.623623; - xyD = {0.269669, 0.28078, 1.0}; - break; - } - - case ColorManagementParams::Illuminant::STDA: { - Wx = 1.098500393; - Wz = 0.355848714; - xyD = {0.447573, 0.407440, 1.0}; - ills = "stdA 2875K"; - break; - } - - case ColorManagementParams::Illuminant::TUNGSTEN_2000K: { - Wx = 1.274335; - Wz = 0.145233; - xyD = {0.526591, 0.41331, 1.0}; - ills = "Tungsten 2000K"; - break; - } - - case ColorManagementParams::Illuminant::TUNGSTEN_1500K: { - Wx = 1.489921; - Wz = 0.053826; - xyD = {0.585703, 0.393157, 1.0}; - ills = "Tungsten 1500K"; - break; - } + double arefi = (xyD.y - meany) / (xyD.x - meanx); + double brefi = xyD.y - arefi * xyD.x; + double scalrefi = 0.98 * (meanx - xyD.x); + xyD.x = xyD.x + scalrefi * refin; + xyD.y = xyD.x * arefi + brefi; + // recalculate Wx Wy + Wx = xyD.x / xyD.y; + Wz = (1. - xyD.x - xyD.y) / xyD.y; } double wprofpri[9]; - if (gamutcontrol) { - //xyz in functiuon primaries and illuminant - Color::primaries_to_xyz(p, Wx, Wz, wprofpri); + //xyz in function primaries and illuminant + Color::primaries_to_xyz(p, Wx, Wz, wprofpri, cat); - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - wprofprim[i][j] = (double) wprofpri[j * 3 + i]; - //xyz in TMatrix format - } + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + wprofprim[i][j] = (double) wprofpri[j * 3 + i]; + //xyz in TMatrix format } } @@ -996,11 +1446,17 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, cmsWriteTag(oprofdef, cmsSigBlueTRCTag, GammaTRC[2]); //to read XYZ values and illuminant - if (rtengine::settings->verbose) { + if (rtengine::settings->verbose && mul == 5) { cmsCIEXYZ *redT = static_cast(cmsReadTag(oprofdef, cmsSigRedMatrixColumnTag)); cmsCIEXYZ *greenT = static_cast(cmsReadTag(oprofdef, cmsSigGreenMatrixColumnTag)); cmsCIEXYZ *blueT = static_cast(cmsReadTag(oprofdef, cmsSigBlueMatrixColumnTag)); - printf("Illuminant=%s\n", ills.c_str()); + + if (locprim == 0) { + printf("Illuminant=%s\n", ills.c_str()); + } else { + printf("Illuminant=%s\n", params->locallab.spots.at(sp).illMethod.c_str()); + } + printf("rX=%f gX=%f bX=%f\n", redT->X, greenT->X, blueT->X); printf("rY=%f gY=%f bY=%f\n", redT->Y, greenT->Y, blueT->Y); printf("rZ=%f gZ=%f bZ=%f\n", redT->Z, greenT->Z, blueT->Z); @@ -1063,6 +1519,42 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, } } +// alternative to find dominant color xy +// Not use : +// 1) GUI complex at least for mean +// 2) small difference for meanxe, meanye with meanx , meany above in most cases + /* + if (locprim == 1) { + meanxe = 0.f; + meanye = 0.f; + + #ifdef _OPENMP + #pragma omp parallel for reduction(+:meanxe, meanye) if(multiThread) + #endif + for (int y = 0; y < ch ; ++y) { + for (int x = 0; x < cw ; ++x) { + const float RR = dst->r(y,x); + const float GG = dst->g(y,x); + const float BB = dst->b(y,x); + float xcb, ycb, zcb; + Color::rgbxyz(RR, GG, BB, xcb, ycb, zcb, wb2);//use sRGB Adobe Rec2020 ACESp0 + + float X_r = xcb; + float Y_r = ycb; + float Z_r = zcb; + Color::gamutmap(X_r, Y_r, Z_r, wb2);//gamut control + const float som = X_r + Y_r + Z_r; + X_r = X_r / som; + Y_r = Y_r / som; + meanxe += X_r; + meanye += Y_r; + } + } + meanxe /= (ch*cw); + meanye /= (ch*cw); + printf("DiffmeanxE=%f DiffmeanyE=%f \n", (double) (meanxe - meanx), (double) (meanye - meany)); + } + */ if (!keepTransForm) { cmsDeleteTransform(hTransform); hTransform = nullptr; diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index a3e9dee22..37ef276df 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . - * 2016 - 2020 Jacques Desmis + * 2016 - 2024 Jacques Desmis * 2016 - 2020 Ingo Weyrich */ @@ -173,7 +173,8 @@ constexpr float exclusion(float a, float b) } void calcdif(float lmr, float &lmrc) -{ //approximative change between gamma sRGB g=2.4 s=12.92 and gamma LAB g=3.0 s=9.03 +{ + //approximative change between gamma sRGB g=2.4 s=12.92 and gamma LAB g=3.0 s=9.03 //useful to calculate action with dark and light area mask //differences in 3 parts linear...very small differences with real... float a0 = 7.6f / 11.6f;//11.6 sRGB - 7.6 Lab...11.6 max difference @@ -183,8 +184,9 @@ void calcdif(float lmr, float &lmrc) float b1 = 62.f - a1 * 60.f; float a2 = (100.f - 62.f) / (100.f - 60.f); float b2 = 100.f - a2 * 100.f; - if(lmr < 11.6f) { - lmrc = a0 * lmr; + + if (lmr < 11.6f) { + lmrc = a0 * lmr; } else if (lmr < 60.f) { lmrc = a1 * lmr + b1; } else { @@ -213,6 +215,7 @@ void calcGammaLut(double gamma, double ts, LUTf &gammaLut) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1024) #endif + for (int i = 0; i < 65536; i++) { const double x = rtengine::Color::igammareti(i / 65535.0, gamm, start, ts, mul, add); gammaLut[i] = 0.5 * rtengine::CLIP(x * 65535.0); // CLIP avoid in some case extra values @@ -221,6 +224,7 @@ void calcGammaLut(double gamma, double ts, LUTf &gammaLut) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 1024) #endif + for (int i = 0; i < 65536; i++) { const double x = rtengine::Color::gammareti(i / 65535.0, gamm, start, ts, mul, add); gammaLut[i] = 0.5 * rtengine::CLIP(x * 65535.0); // CLIP avoid in some case extra values @@ -253,6 +257,7 @@ float calcLocalFactorrect(const float lox, const float loy, const float lcx, con const float ky = loy - lcy; float ref; + //gradient allows differentiation between transition x and y if (std::fabs(kx / (ky + eps)) < krap) { ref = std::sqrt(rtengine::SQR(dy) * (1.f + rtengine::SQR(kx / (ky + eps)))); @@ -307,6 +312,7 @@ void deltaEforLaplace(float *dE, const float lap, int bfw, int bfh, rtengine::La #ifdef _OPENMP #pragma omp parallel for reduction(max:maxC) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { const float val = std::sqrt((rtengine::SQR(refa - bufexporig->a[y][x]) + rtengine::SQR(refb - bufexporig->b[y][x])) + rtengine::SQR(refL - bufexporig->L[y][x])) / 327.68f; @@ -320,14 +326,15 @@ void deltaEforLaplace(float *dE, const float lap, int bfw, int bfh, rtengine::La } const float ade = 1.f / (maxdE - maxC); - // const float bde = -ade * maxC; + // const float bde = -ade * maxC; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { - // dE[y * bfw + x] = dE[y * bfw + x] >= maxdE ? ade * dE[y * bfw + x] + bde : 1.f; + // dE[y * bfw + x] = dE[y * bfw + x] >= maxdE ? ade * dE[y * bfw + x] + bde : 1.f; dE[y * bfw + x] = dE[y * bfw + x] >= maxdE ? ade * (dE[y * bfw + x] - maxC) : 1.f; } @@ -391,23 +398,29 @@ void SobelCannyLuma(float **sobelL, float **luma, int bfw, int bfh, float radius for (int x = 0; x < bfw; x++) { sobelL[0][x] = 0.f; } + for (int y = 1; y < bfh - 1; y++) { sobelL[y][0] = 0.f; + for (int x = 1; x < bfw - 1; x++) { float sumXL = 0.f; float sumYL = 0.f; + for (int i = -1; i < 2; i += 2) { for (int j = -1; j < 2; j += 1) { sumXL += GX[j + 1][i + 1] * tmL[y + i][x + j]; sumYL += GY[j + 1][i + 1] * tmL[y + i][x + j]; } } + //Edge strength //we can add if need teta = atan2 (sumYr, sumXr) sobelL[y][x] = rtengine::min(std::sqrt(rtengine::SQR(sumXL) + rtengine::SQR(sumYL)), 32767.f); } + sobelL[y][bfw - 1] = 0.f; } + for (int x = 0; x < bfw; x++) { sobelL[bfh - 1][x] = 0.f; } @@ -422,7 +435,7 @@ float igammalog(float x, float p, float s, float g2, float g4) #ifdef __SSE2__ vfloat igammalog(vfloat x, vfloat p, vfloat s, vfloat g2, vfloat g4) { - // return x <= g2 ? x / s : pow_F((x + g4) / (1.f + g4), p);//continuous + // return x <= g2 ? x / s : pow_F((x + g4) / (1.f + g4), p);//continuous return vself(vmaskf_le(x, g2), x / s, pow_F((x + g4) / (F2V(1.f) + g4), p)); } #endif @@ -435,9 +448,9 @@ float gammalog(float x, float p, float s, float g3, float g4) #ifdef __SSE2__ vfloat gammalog(vfloat x, vfloat p, vfloat s, vfloat g3, vfloat g4) { - // return x <= g3 ? x * s : (1.f + g4) * xexpf(xlogf(x) / p) - g4;//continuous + // return x <= g3 ? x * s : (1.f + g4) * xexpf(xlogf(x) / p) - g4;//continuous return vself(vmaskf_le(x, g3), x * s, (F2V(1.f) + g4) * xexpf(xlogf(x) / p) - g4);//improve by Ingo - used by Nlmeans - + } #endif } @@ -459,7 +472,7 @@ struct local_params { float balance; float balanceh; int colorde; - int cir; + float cir; bool recur; float thr; float stru; @@ -685,7 +698,10 @@ struct local_params { float lowthrcie; float higthrcie; float decaycie; - + float blurciemask; + float contciemask; + bool islogcie; + bool issmoothcie; int noiselequal; float noisechrodetail; float bilat; @@ -702,8 +718,10 @@ struct local_params { float noisecf; float noisecc; float mulloc[6]; - int mullocsh[5]; + int mullocsh[6]; int detailsh; + int whitescie; + int midtcie; double tePivot; float threshol; float chromacb; @@ -778,7 +796,16 @@ struct local_params { float targetgray; float blackev; float whiteev; + float sourcegraycie; + float targetgraycie; + float blackevjz; + float whiteevjz; float detail; + float detailcie; + float strgradcie; + float anggradcie; + bool satcie; + bool satlog; int sensilog; int sensicie; int sensimas; @@ -816,6 +843,12 @@ struct local_params { float mLjz; float mCjz; float softrjz; + bool fftcieMask; + float comprlo; + float comprlocie; + int moka; + int sursouci; + int smoothciem; }; @@ -823,7 +856,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall { int w = oW; int h = oH; - int circr = locallab.spots.at(sp).circrad; + float circr = locallab.spots.at(sp).circrad; bool recur = locallab.spots.at(sp).recurs; float streng = ((float)locallab.spots.at(sp).stren); float gam = ((float)locallab.spots.at(sp).gamma); @@ -839,7 +872,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall // if (thre > 8.f || thre < 0.f) {//to avoid artifacts if user does not clear cache with new settings. Can be suppressed after // thre = 2.f; // } - thre = LIM(thre, 0.f, 10.0f); + thre = LIM(thre, 0.f, 15.0f); double local_x = locallab.spots.at(sp).loc.at(0) / 2000.0; double local_y = locallab.spots.at(sp).loc.at(2) / 2000.0; @@ -880,13 +913,14 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall } else if (locallab.spots.at(sp).gridMethod == "two") { lp.gridmet = 1; } -/* - if (locallab.spots.at(sp).expMethod == "std") { - lp.expmet = 0; - } else if (locallab.spots.at(sp).expMethod == "pde") { - lp.expmet = 1; - } -*/ + + /* + if (locallab.spots.at(sp).expMethod == "std") { + lp.expmet = 0; + } else if (locallab.spots.at(sp).expMethod == "pde") { + lp.expmet = 1; + } + */ lp.expmet = 1; if (locallab.spots.at(sp).localcontMethod == "loc") { @@ -898,15 +932,25 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.laplacexp = locallab.spots.at(sp).laplacexp; lp.balanexp = locallab.spots.at(sp).balanexp; lp.linear = locallab.spots.at(sp).linear; - if (locallab.spots.at(sp).spotMethod == "norm") { + + if (locallab.spots.at(sp).smoothciemet == "norm") { + lp.smoothciem = 1; + } else if (locallab.spots.at(sp).smoothciemet == "Ev") { + lp.smoothciem = 1; + } else if (locallab.spots.at(sp).smoothciemet == "gam") { + lp.smoothciem = 2; + } else if (locallab.spots.at(sp).smoothciemet == "gamnorol") { + lp.smoothciem = 3; + } + + if (locallab.spots.at(sp).smoothciemet == "none") { lp.fullim = 0; - } else if(locallab.spots.at(sp).spotMethod == "exc"){ + } else if (locallab.spots.at(sp).spotMethod == "exc") { lp.fullim = 1; - } else if (locallab.spots.at(sp).spotMethod == "full"){ + } else if (locallab.spots.at(sp).spotMethod == "full") { lp.fullim = 2; } - // printf("Lpfullim=%i\n", lp.fullim); - + lp.fftColorMask = locallab.spots.at(sp).fftColorMask; lp.prevdE = prevDeltaE; lp.showmaskcolmet = llColorMask; @@ -921,13 +965,15 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.showmaskcbmet = llcbMask; lp.showmaskretimet = llretiMask; lp.showmasksoftmet = llsoftMask; - + lp.showmasktmmet = lltmMask; lp.showmaskblmet = llblMask; lp.showmasklogmet = lllogMask; lp.showmask_met = ll_Mask; lp.showmaskciemet = llcieMask; -//printf("CIEmask=%i\n", lp.showmaskciemet); + lp.fftcieMask = locallab.spots.at(sp).fftcieMask; + lp.islogcie = locallab.spots.at(sp).logcie && locallab.spots.at(sp).expprecam; + lp.issmoothcie = locallab.spots.at(sp).smoothcie; lp.enaColorMask = locallab.spots.at(sp).enaColorMask && llsoftMask == 0 && llColorMaskinv == 0 && llSHMaskinv == 0 && llColorMask == 0 && llExpMaskinv == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaColorMaskinv = locallab.spots.at(sp).enaColorMask && llColorMaskinv == 0 && llSHMaskinv == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible lp.enaExpMask = locallab.spots.at(sp).enaExpMask && llExpMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && llColorMask == 0 && llColorMaskinv == 0 && llsoftMask == 0 && lllcMask == 0 && llsharMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0;// Exposure mask is deactivated if Color & Light mask is visible @@ -936,7 +982,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.enaSHMaskinv = locallab.spots.at(sp).enaSHMask && llColorMaskinv == 0 && llSHMaskinv == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; lp.enacbMask = locallab.spots.at(sp).enacbMask && llColorMaskinv == 0 && llcbMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; lp.enaretiMask = locallab.spots.at(sp).enaretiMask && llColorMaskinv == 0 && lllcMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && llsharMask == 0 && llsoftMask == 0 && llretiMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; - lp.enatmMask = locallab.spots.at(sp).enatmMask && llColorMaskinv == 0 && lltmMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && llblMask == 0 && llvibMask == 0&& lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; + lp.enatmMask = locallab.spots.at(sp).enatmMask && llColorMaskinv == 0 && lltmMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; lp.enablMask = locallab.spots.at(sp).enablMask && llColorMaskinv == 0 && llblMask == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; lp.enavibMask = locallab.spots.at(sp).enavibMask && llvibMask == 0 && llColorMaskinv == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && lllcMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llcbMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llSHMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; lp.enalcMask = locallab.spots.at(sp).enalcMask && lllcMask == 0 && llColorMaskinv == 0 && llExpMaskinv == 0 && llSHMaskinv == 0 && llcbMask == 0 && llsoftMask == 0 && llsharMask == 0 && llColorMask == 0 && llExpMask == 0 && llSHMask == 0 && llretiMask == 0 && lltmMask == 0 && llblMask == 0 && llvibMask == 0 && lllogMask == 0 && ll_Mask == 0 && llcieMask == 0; @@ -986,7 +1032,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall } else if (locallab.spots.at(sp).quamethod == "none") { lp.quamet = 3; } -// printf("lpqualmet=%i\n", lp.quamet); + if (locallab.spots.at(sp).shMethod == "std") { lp.shmeth = 0; @@ -1006,13 +1052,14 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall } else if (locallab.spots.at(sp).medMethod == "99") { lp.medmet = 3; } -/* - if (locallab.spots.at(sp).blurMethod == "norm") { - lp.blurmet = 0; - } else if (locallab.spots.at(sp).blurMethod == "inv") { - lp.blurmet = 1; - } -*/ + + /* + if (locallab.spots.at(sp).blurMethod == "norm") { + lp.blurmet = 0; + } else if (locallab.spots.at(sp).blurMethod == "inv") { + lp.blurmet = 1; + } + */ if (locallab.spots.at(sp).invbl == false) { lp.blurmet = 0; } else if (locallab.spots.at(sp).invbl == true) { @@ -1144,7 +1191,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall if (locallab.spots.at(sp).shape == "ELI") { lp.shapmet = 0; - } else /*if (locallab.spots.at(sp).shape == "RECT")*/ { + } else { /*if (locallab.spots.at(sp).shape == "RECT")*/ lp.shapmet = 1; } @@ -1178,8 +1225,9 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lnoiselc4 = 250.f * locwavCurveden[333]; lnoiselc5 = 250.f * locwavCurveden[416]; lnoiselc6 = 250.f * locwavCurveden[500]; - } + } } + lp.wavcurvedenoi = wavcurveden; float local_noiseldetail = (float)locallab.spots.at(sp).noiselumdetail; int local_noiselequal = locallab.spots.at(sp).noiselequal; @@ -1255,9 +1303,9 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall multi[y] = ((float) locallab.spots.at(sp).mult[y]); } - float multish[5]; + float multish[6]; - for (int y = 0; y < 5; y++) { + for (int y = 0; y < 6; y++) { multish[y] = ((float) locallab.spots.at(sp).multsh[y]); } @@ -1420,7 +1468,33 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.targetgray = (float) locallab.spots.at(sp).targetGray; lp.blackev = (float) locallab.spots.at(sp).blackEv; lp.whiteev = (float) locallab.spots.at(sp).whiteEv; + lp.sourcegraycie = (float) locallab.spots.at(sp).sourceGraycie; + lp.targetgraycie = (float) locallab.spots.at(sp).targetGraycie; + + if (locallab.spots.at(sp).modecam == "cam16") { + lp.moka = 1; + } else if (locallab.spots.at(sp).modecam == "jz") { + lp.moka = 2; + } + + if (locallab.spots.at(sp).sursourcie == "Average") { + lp.sursouci = 0; + } else if (locallab.spots.at(sp).sursourcie == "Dim") { + lp.sursouci = 1; + } else if (locallab.spots.at(sp).sursourcie == "Dark") { + lp.sursouci = 2; + } else if (locallab.spots.at(sp).sursourcie == "exDark") { + lp.sursouci = 3; + } else if (locallab.spots.at(sp).sursourcie == "disacie") { + lp.sursouci = 4; + } + + lp.satcie = (float) locallab.spots.at(sp).satcie; + lp.satlog = (float) locallab.spots.at(sp).satlog; + lp.blackevjz = (float) locallab.spots.at(sp).blackEvjz; + lp.whiteevjz = (float) locallab.spots.at(sp).whiteEvjz; lp.detail = locallab.spots.at(sp).detail; + lp.detailcie = 0.01 * locallab.spots.at(sp).detailcie; lp.sensilog = locallab.spots.at(sp).sensilog; lp.Autogray = locallab.spots.at(sp).Autogray; lp.autocompute = locallab.spots.at(sp).autocompute; @@ -1430,6 +1504,15 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float blendmaskcie = ((float) locallab.spots.at(sp).blendmaskcie) / 100.f ; float radmaskcie = ((float) locallab.spots.at(sp).radmaskcie); float chromaskcie = ((float) locallab.spots.at(sp).chromaskcie); + float blurciemask = (float) locallab.spots.at(sp).blurcie; + float contciemask = (float) locallab.spots.at(sp).contcie; + float strgradcie = ((float) locallab.spots.at(sp).strgradcie); + float anggradcie = ((float) locallab.spots.at(sp).anggradcie); + + lp.comprlo = locallab.spots.at(sp).comprlog; + lp.comprlocie = locallab.spots.at(sp).comprcie; + + lp.deltaem = locallab.spots.at(sp).deltae; lp.scalereti = scaleret; lp.cir = circr; @@ -1460,7 +1543,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.angmaexp = angmaskexpo; lp.str_mas = strmask; lp.ang_mas = angmask; - + lp.strexp = strexpo; lp.angexp = angexpo; lp.strSH = strSH; @@ -1650,7 +1733,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.lowthrr = local_lowthrr; lp.higthrr = local_higthrr; lp.decayr = local_decayr; - + lp.recothrl = local_recothrl; lp.lowthrl = local_lowthrl; lp.higthrl = local_higthrl; @@ -1661,7 +1744,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.noiselc4 = lnoiselc4; lp.noiselc5 = lnoiselc5; lp.noiselc6 = lnoiselc6; - + lp.noisecf = local_noisecf; lp.noisecc = local_noisecc; lp.sensden = local_sensiden; @@ -1685,6 +1768,10 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.blurma = (float) locallab.spots.at(sp).blurmask; lp.fftma = locallab.spots.at(sp).fftmask; lp.contma = (float) locallab.spots.at(sp).contmask; + lp.blurciemask = blurciemask; + lp.contciemask = 0.01f * contciemask; + lp.strgradcie = strgradcie; + lp.anggradcie = anggradcie; lp.blendmacie = blendmaskcie; lp.radmacie = radmaskcie; @@ -1695,14 +1782,16 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.mulloc[y] = LIM(multi[y], 0.f, 4.f);//to prevent crash with old pp3 integer } - for (int y = 0; y < 5; y++) { + for (int y = 0; y < 6; y++) { lp.mullocsh[y] = multish[y]; } - lp.activspot = locallab.spots.at(sp).activ; - + lp.activspot = locallab.spots.at(sp).activ; lp.detailsh = locallab.spots.at(sp).detailSH; lp.tePivot = locallab.spots.at(sp).tePivot; + lp.whitescie = locallab.spots.at(sp).whitescie; + lp.midtcie = locallab.spots.at(sp).midtcie; + lp.threshol = thresho; lp.chromacb = chromcbdl; lp.expvib = locallab.spots.at(sp).expvibrance && lp.activspot ; @@ -1823,6 +1912,7 @@ static void calcTransition(const float lox, const float loy, const float ach, co if (!zone) { zone = (zoneVal > 1.f && ((SQR((lox - lp.xc) / (lp.lx)) + SQR((loy - lp.yc) / (lp.ly))) < 1.f)) ? 1 : 0; + if (zone == 1) { localFactor = pow_F(calcLocalFactor(lox, loy, lp.xc, lp.lx, lp.yc, lp.ly, ach, lp.transgrad), lp.transweak); } @@ -1833,6 +1923,7 @@ static void calcTransition(const float lox, const float loy, const float ach, co if (!zone) { zone = (zoneVal > 1.f && ((SQR((lox - lp.xc) / (lp.lx)) + SQR((loy - lp.yc) / (lp.lyT))) < 1.f)) ? 1 : 0; + if (zone == 1) { localFactor = pow_F(calcLocalFactor(lox, loy, lp.xc, lp.lx, lp.yc, lp.lyT, ach, lp.transgrad), lp.transweak); } @@ -1845,6 +1936,7 @@ static void calcTransition(const float lox, const float loy, const float ach, co if (!zone) { zone = (zoneVal > 1.f && ((SQR((lox - lp.xc) / (lp.lxL)) + SQR((loy - lp.yc) / (lp.lyT))) < 1.f)) ? 1 : 0; + if (zone == 1) { localFactor = pow_F(calcLocalFactor(lox, loy, lp.xc, lp.lxL, lp.yc, lp.lyT, ach, lp.transgrad), lp.transweak); } @@ -1855,6 +1947,7 @@ static void calcTransition(const float lox, const float loy, const float ach, co if (!zone) { zone = (zoneVal > 1.f && ((SQR((lox - lp.xc) / (lp.lxL)) + SQR((loy - lp.yc) / (lp.ly))) < 1.f)) ? 1 : 0; + if (zone == 1) { localFactor = pow_F(calcLocalFactor(lox, loy, lp.xc, lp.lxL, lp.yc, lp.ly, ach, lp.transgrad), lp.transweak); } @@ -1922,7 +2015,8 @@ float find_gray(float source_gray, float target_gray) return 0.f; // not found } -void ImProcFunctions::mean_sig (const float* const * const savenormL, float &meanf, float &stdf, int xStart, int xEnd, int yStart, int yEnd) const { +void ImProcFunctions::mean_sig(const float* const * const savenormL, float &meanf, float &stdf, int xStart, int xEnd, int yStart, int yEnd) const +{ const int size = (yEnd - yStart) * (xEnd - xStart); // use double precision for large accumulations double meand = 0.0; @@ -1930,18 +2024,21 @@ void ImProcFunctions::mean_sig (const float* const * const savenormL, float &mea #ifdef _OPENMP #pragma omp parallel for reduction(+:meand, stdd) if(multiThread) #endif + for (int y = yStart; y < yEnd; ++y) { for (int x = xStart; x < xEnd; ++x) { meand += static_cast(savenormL[y][x]); stdd += SQR(static_cast(savenormL[y][x])); } } + meand /= size; stdd /= size; stdd -= SQR(meand); stdf = std::sqrt(stdd); meanf = meand; } + // taken from darktable inline float power_norm(float r, float g, float b) { @@ -1953,7 +2050,7 @@ inline float power_norm(float r, float g, float b) float g2 = SQR(g); float b2 = SQR(b); float d = r2 + g2 + b2; - float n = r*r2 + g*g2 + b*b2; + float n = r * r2 + g * g2 + b * b2; return n / std::max(d, 1e-12f); } @@ -1969,12 +2066,15 @@ inline float gray2ev(float gray) return std::log2(0.18f / gray); } +// copyright 2018 Alberto Griggio inline float norm2(float r, float g, float b, TMatrix ws) { - return (power_norm(r, g, b) + Color::rgbLuminance(r, g, b, ws)) / 2.f; + constexpr float hi = std::numeric_limits::max() / 100.f; + return std::min(hi, power_norm(r, g, b) / 2.f + Color::rgbLuminance(r, g, b, ws) / 2.f); } + inline float norm(float r, float g, float b, TMatrix ws) { return (Color::rgbLuminance(r, g, b, ws)); @@ -1984,18 +2084,52 @@ inline float norm(float r, float g, float b, TMatrix ws) // basic log encoding taken from ACESutil.Lin_to_Log2, from // https://github.com/ampas/aces-dev // (as seen on pixls.us) +// copyright 2018 Alberto Griggio void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool multiThread, int bfw, int bfh) { - // BENCHFUN - const float gray = 0.01f * lp.sourcegray; - const float shadows_range = lp.blackev; + // BENCHFUN + float gray = 0.1f; + float shadows_range = 0.f; + bool comprlog = 0.f; + float comprfactorlog = 0.f; + float dynamic_range = 1.f; + float targray = 0.1f; + + bool satcontrol = false; + + if(lp.logena) { + gray = 0.01f * lp.sourcegray; + shadows_range = lp.blackev; + comprlog = lp.comprlo > 0.f; + comprfactorlog = lp.comprlo; + dynamic_range = max(lp.whiteev - lp.blackev, 0.5f); + targray = lp.targetgray; + satcontrol = lp.satlog; + + } else if (lp.cieena) { + gray = 0.01f * lp.sourcegraycie; + shadows_range = lp.blackevjz; + comprlog = lp.comprlocie > 0.f; + comprfactorlog = lp.comprlocie; + dynamic_range = max(lp.whiteevjz - lp.blackevjz, 0.5f); + targray = lp.targetgraycie; + satcontrol = lp.satcie; + } + float comprthlog = 1.f; - float dynamic_range = max(lp.whiteev - lp.blackev, 0.5f); const float noise = pow_F(2.f, -16.f); const float log2 = xlogf(2.f); - const float base = lp.targetgray > 1 && lp.targetgray < 100 && dynamic_range > 0 ? find_gray(std::abs(lp.blackev) / dynamic_range, 0.01f * lp.targetgray) : 0.f; + const float base = targray > 1 && targray < 100 && dynamic_range > 0 ? find_gray(std::abs(shadows_range) / dynamic_range, 0.01f * targray) : 0.f; const float linbase = rtengine::max(base, 2.f);//2 to avoid bad behavior TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + float ac = -5.f;//max 4 + float bc = 4.f; + if(comprlog < 0.6f) { + comprthlog = ac * comprlog + bc; + } else { + comprthlog = 1.f; + } + if (settings->verbose) { printf("Base Log encoding std=%5.1f\n", (double) linbase); } @@ -2009,9 +2143,16 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool x = rtengine::max(x, noise); x = rtengine::max(x / gray, noise); + if (comprlog && x >= comprthlog) + { + x = intp(comprfactorlog, (std::tanh((x - comprthlog) / comprthlog) + 1.f) * comprthlog, x); + } + + x = rtengine::max((xlogf(x) / log2 - shadows_range) / dynamic_range, noise); assert(x == x); + if (linbase > 0.f) { x = xlog2lin(x, linbase); @@ -2020,18 +2161,47 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool if (scale) { return x * 65535.f; - } else { + } else + { return x; } }; - const float detail = lp.detail; + const auto sf = + [=](float s, float c) -> float + { + if (c > noise) { + return 1.f - min(std::abs(s) / c, 1.f); + } else { + return 0.f; + } + }; +//added 2024 02 + const auto apply_sat = + [&](float &r, float &g, float &b, float f) -> void + { + float ll = Color::rgbLuminance(r, g, b, ws); + float rl = r - ll; + float gl = g - ll; + float bl = b - ll; + float s = intp(max(sf(rl, r), sf(gl, g), sf(bl, b)), pow_F(f, 0.3f) * 0.6f + 0.4f, 1.f); + r = ll + s * rl; + g = ll + s * gl; + b = ll + s * bl; + }; + + + float detail = lp.detail;//Log encoding + if(lp.cieena) {//Cam16 + detail = lp.detailcie; + } const int W = rgb->getWidth(), H = rgb->getHeight(); if (detail == 0.f) {//no local contrast #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { float r = rgb->r(y, x); @@ -2043,10 +2213,15 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool float mm = apply(m); float f = mm / m; f = min(f, 1000000.f); - + r *= f; b *= f; g *= f; + + if (satcontrol && f < 1.f) { + apply_sat(r, g, b, f); + } + r = CLIP(r); g = CLIP(g); b = CLIP(b); @@ -2071,6 +2246,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { Y2[y][x] = norm2(rgb->r(y, x), rgb->g(y, x), rgb->b(y, x), ws) / 65535.f; @@ -2080,6 +2256,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool assert(std::isfinite(Y[y][x])); } } + const float radius = rtengine::max(rtengine::max(bfw, W), rtengine::max(bfh, H)) / 30.f; const float epsilon = 0.005f; rtengine::guidedFilter(Y2, Y, Y, radius, epsilon, multiThread); @@ -2089,6 +2266,7 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { float &r = rgb->r(y, x); @@ -2104,28 +2282,36 @@ void ImProcFunctions::log_encode(Imagefloat *rgb, struct local_params & lp, bool float f2 = apply(t2) / t2; f = intp(blend, f, f2); f = min(f, 1000000.f); - - // assert(std::isfinite(f)); + + // assert(std::isfinite(f)); r *= f; g *= f; b *= f; r = CLIP(r); g = CLIP(g); b = CLIP(b); - // assert(std::isfinite(r)); - // assert(std::isfinite(g)); - // assert(std::isfinite(b)); + assert(std::isfinite(r)); + assert(std::isfinite(g)); + assert(std::isfinite(b)); + + if (satcontrol && f < 1.f) { + apply_sat(r, g, b, f); + } + + } } } } } - -void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) + +// Copyright 2018 Alberto Griggio +void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, float *blackev, float *whiteev, bool *Autogr, float *sourceab, int *whits, int *blacks, int *whitslog, int *blackslog, int fw, int fh, float xsta, float xend, float ysta, float yend, int SCALE) { //BENCHFUN //adpatation to local adjustments Jacques Desmis 12 2019 and 11 2021 (from ART) +// improvment white aand black toen_eqcam 9 2023 const PreviewProps pp(0, 0, fw, fh, SCALE); Imagefloat img(int(fw / SCALE + 0.5), int(fh / SCALE + 0.5)); @@ -2149,13 +2335,27 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, int www = int(fw / SCALE + 0.5); int hhh = int(fh / SCALE + 0.5); array2D YY(www, hhh); - double mean = 0.0; - int nc = 0; + int nc = 0; + + int whit = -whits[sp]; + int blac = -blacks[sp]; + + if(params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).Autograycie) { + ImProcFunctions::tone_eqcam2(this, &img, whit, blac, params->icm.workingProfile, SCALE, multiThread); + } + + int whitlog = -whitslog[sp]; + int blaclog = -blackslog[sp]; + + if(params->locallab.spots.at(sp).explog && params->locallab.spots.at(sp).autocompute) { + ImProcFunctions::tone_eqcam2(this, &img, whitlog, blaclog, params->icm.workingProfile, SCALE, multiThread); + } + for (int y = hsta; y < hend; ++y) { for (int x = wsta; x < wend; ++x) { const float r = img.r(y, x), g = img.g(y, x), b = img.b(y, x); - YY[y][x] = norm2(r, g, b, ws) / 65535.f;//norm2 to find a best color luminance response in RGB + YY[y][x] = norm2(r, g, b, ws) / 65535.f;//norm2 to find a best color luminance response in RGB mean += static_cast((float) ws[1][0] * Color::gamma_srgb(r) + (float) ws[1][1] * Color::gamma_srgb(g) + (float) ws[1][2] * Color::gamma_srgb(b)); //alternative to fing gray in case of above process does not works nc++; @@ -2165,15 +2365,18 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, for (int y = hsta; y < hend; ++y) { for (int x = wsta; x < wend; ++x) { float l = YY[y][x]; + if (l > noise) { minVal = min(minVal, l); maxVal = max(maxVal, l); } } } - - maxVal *= 1.45f; //(or 1.5f...) slightly increase max to take into account illuminance incident light - minVal *= 0.55f; //(or 0.5f...) slightly decrease min to take into account illuminance incident light + + + maxVal *= 1.5f; + minVal *= 0.5f; + //E = 2.5*2^EV => e=2.5 depends on the sensor type C=250 e=2.5 to C=330 e=3.3 //repartition with 2.5 between 1.45 Light and shadows 0.58 => a little more 0.55... // https://www.pixelsham.com/2020/12/26/exposure-value-measurements/ @@ -2200,7 +2403,7 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, for (int y = hsta; y < hend; ++y) { for (int x = wsta; x < wend; ++x) { - const float l = img.g(y, x) / 65535.f; + const float l = YY[y][x]; if (l >= gmin && l <= gmax) { tot += static_cast(l); @@ -2221,12 +2424,13 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, yb = 1.5f + 100.f * pow_F(mean, 1.8f);//empirical formula for Jz and log encode for low exposure images sourceg[sp] = yb; + if (settings->verbose) { std::cout << " no samples found in range, resorting to Yb gray point value " << sourceg[sp] << std::endl; } } } - + constexpr float MIN_WHITE = 2.f; constexpr float MAX_BLACK = -3.5f; @@ -2238,7 +2442,6 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, //calculate La - Absolute luminance shooting const FramesMetaData* metaData = imgsrc->getMetaData(); - float fnum = metaData->getFNumber(); // F number float fiso = metaData->getISOSpeed() ; // ISO float fspeed = metaData->getShutterSpeed() ; // Speed @@ -2252,17 +2455,19 @@ void ImProcFunctions::getAutoLogloc(int sp, ImageSource *imgsrc, float *sourceg, double kexp = 0.; E_V += kexp * params->toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV E_V += 0.5 * std::log2(params->raw.expos); // exposure raw white point ; log2 ==> linear to EV - adap = pow(2.0, E_V - 3.0); // cd / m2 ==> 3.0 = log2(8) =>fnum*fnum/speed = Luminance (average scene) * fiso / K (K is the reflected-light meter calibration constant according to the sensors about 12.5 or 14 + adap = pow(2.0, E_V - 3.0); // cd / m2 ==> 3.0 = log2(8) =>fnum*fnum/speed = Luminance (average scene) * fiso / K (K is the reflected-light meter calibration constant according to the sensors about 12.5 or 14 // end calculation adaptation scene luminosity } - + sourceab[sp] = adap; } } + void tone_eq(ImProcFunctions *ipf, Imagefloat *rgb, const struct local_params &lp, const Glib::ustring &workingProfile, double scale, bool multithread) { + ToneEqualizerParams params; params.enabled = true; params.regularization = lp.detailsh; @@ -2270,6 +2475,181 @@ void tone_eq(ImProcFunctions *ipf, Imagefloat *rgb, const struct local_params &l std::copy(lp.mullocsh, lp.mullocsh + params.bands.size(), params.bands.begin()); ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); } + +void ImProcFunctions::tone_eqcam(ImProcFunctions *ipf, Imagefloat *rgb, int midtone, const Glib::ustring &workingProfile, double scale, bool multithread) +{ + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[2] = midtone; + params.bands[4] = 0; + params.bands[5] = 0; + int mid = abs(midtone); + int threshmid = 50; + if(mid > threshmid) { + params.bands[1] = sign(midtone) * (mid - threshmid); + params.bands[3] = sign(midtone) * (mid - threshmid); + } + + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); +} + +void tone_eqsmooth(ImProcFunctions *ipf, Imagefloat *rgb, const struct local_params &lp, const Glib::ustring &workingProfile, double scale, bool multithread) +{ + //smooth highlights after TRC + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[1] = 0; + params.bands[2] = 0; + params.bands[3] = 0; + params.bands[4] = -30;//arbitrary value to adapt with WhiteEvjz - here White Ev # 10 + params.bands[5] = -100;//8 Ev and above + if(lp.whiteevjz < 6) {//EV = 6 majority of images + params.bands[4] = -15; + } + if(lp.islogcie) {//with log encoding Cie + params.bands[4] = -15; + params.bands[5] = -50; + if(lp.whiteevjz < 6) { + params.bands[4] = -10; + } + } + + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); +} + +void ImProcFunctions::tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread) +{ + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = blacks; + int bla = abs(blacks); + int threshblawhi = 50; + int threshblawhi2 = 70; + int threshblawhi3 = 40; + if(bla > threshblawhi) { + params.bands[1] = sign(blacks) * (bla - threshblawhi); + } + if(bla > threshblawhi2) { + params.bands[2] = sign(blacks) * (bla - threshblawhi2); + } + + params.bands[4] = whits; + int whi = abs(whits); + if(whi > threshblawhi) { + params.bands[3] = sign(whits) * (whi - threshblawhi); + } + if(whi > threshblawhi3) { + params.bands[5] = sign(whits) * (whi - threshblawhi3); + } + + ipf->toneEqualizer(rgb, params, workingProfile, scale, multithread); +} + + +// tone mapping from +// https://github.com/thatcherfreeman/utility-dctls/ +// Copyright of the original code +/* +MIT License + +Copyright (c) 2023 Thatcher Freeman + +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. +*/ + +/* +// I also took some code from Alberto Grigio +*/ +//Copyright (c) 2023 Thatcher Freeman +// Adapted to Rawtherapee Jacques Desmis mars 2024 jdesmis@gmail.com + +float rolloff_function(float x, float dr, float b, float c, float kmid) +{ + return (dr * (x / (x + b)) + c) * kmid;//Simple sigmoid (rather a polynomial asymptotic power function) ponderate with kmid - take into account if need Mean Yb scene and Mean Yb viewing and slope value +} +//Copyright (c) 2023 Thatcher Freeman +// Adapted to Rawtherapee Jacques Desmis mars 2024 jdesmis@gmail.com +float scene_contrast(float x, float mid_gray_scene, float gamma) +{ + return mid_gray_scene * std::pow(x / mid_gray_scene, gamma);//apply gamma +} +//Copyright (c) 2023 Thatcher Freeman +// Adapted to Rawtherapee Jacques Desmis mars 2024 jdesmis@gmail.com +float do_get(float x, bool rolloff_, float mid_gray_scene, float gamma, float dr, float b, float c, float kmid) +{ + if (rolloff_ && x <= mid_gray_scene) {//general smooth - till Yb scene + return x; + } else { + return rolloff_function(scene_contrast(x, mid_gray_scene, gamma), dr, b, c, kmid);//simulate polynomial power function with a slope to begin + } +} + +//Copyright (c) 2023 Thatcher Freeman +// Adapted to Rawtherapee Jacques Desmis 25 mars 2024 +void tonemapFreeman(float target_slope, float white_point, float black_point, float mid_gray_scene, float mid_gray_view, bool rolloff, LUTf& lut, int mode, bool scale) +{ + float dr;//Dynamic Range + float b; + float c;//black point + float gamma; + float mid_gray_scene_;//Mean luminance - Scene conditions + // mid_gray_view //Mean luminance - Viewing conditions + + c = black_point; + dr = white_point - c; + + if(scale) {//scale Yb mean luminance scene with white : dr and black + mid_gray_scene_ = mid_gray_scene * dr + c; + } else { + mid_gray_scene_ = mid_gray_scene; + } + + b = (dr / (mid_gray_scene_ - c)) * (1.f - ((mid_gray_scene_ - c) / dr)) * mid_gray_scene_;//b - ponderate mid_gray_scene taking into account the total DR, and the dark part below the mid_gray_scene + gamma = target_slope * (float) std::pow((mid_gray_scene_ + b), 2.0) / (dr * b);//Caculate gamma with slope and mid_gray_scene + float kmid = 1.f;//general case + if(mode == 3 && target_slope != 1.f) {//case tone-mapping + float midutil = mid_gray_view / mid_gray_scene;//take into account ratio between Yb source and Yb viewing + float midk = 1.f; + float k_slope = 2.2f; + if(target_slope >= 1.f) { + midk = pow_F(midutil, k_slope * (target_slope - 1.f));//ponderation in function target_slope when "slope user" < 1.f + } + kmid = midk; + } + if (settings->verbose) { + printf("b=%f gamma=%f slope=%f DynRange=%f kmid=%f black=%f Yb-scale=%f\n", (double) b, (double) gamma, (double) target_slope, (double) dr, (double) kmid, (double) c, (double) mid_gray_scene_); + } + //lut - take from Alberto Griggio + for (int i = 0; i < 65536; ++i) {// i - value image RGB + lut[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gamma, dr, b, c, kmid);//call main function + } +} + + void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float stren, int sk) { if (rad > 0.f) { @@ -2278,6 +2658,7 @@ void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { LL[y][x] = tmp1->L[y][x]; @@ -2285,19 +2666,21 @@ void ImProcFunctions::loccont(int bfw, int bfh, LabImage* tmp1, float rad, float guide[y][x] = xlin2log(rtengine::max(ll, 0.f), 10.f); } } + array2D iL(bfw, bfh, LL, 0); float gu = stren * rad; int r = rtengine::max(int(gu / sk), 1); const double epsil = 0.001 * std::pow(2.f, -10); float st = 0.01f * rad; rtengine::guidedFilterLog(guide, 10.f, LL, r, epsil, false); - + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { - LL[y][x] = intp(st, LL[y][x] , iL[y][x]); + LL[y][x] = intp(st, LL[y][x], iL[y][x]); tmp1->L[y][x] = LL[y][x]; } } @@ -2332,80 +2715,101 @@ void ImProcFunctions::tone_eqdehaz(ImProcFunctions *ipf, Imagefloat *rgb, int wh } -void sigmoidla (float &valj, float thresj, float lambda) +void sigmoidla(float &valj, float thresj, float lambda) { //thres : shifts the action of sigmoid to darker tones or lights //lambda : changes the "slope" of the sigmoid. Low values give a flat curve, high values a "rectangular / orthogonal" curve - valj = 1.f / (1.f + xexpf(lambda - (lambda / thresj) * valj)); + valj = 1.f / (1.f + xexpf(lambda - (lambda / thresj) * valj)); } -void gamutjz (double &Jz, double &az, double &bz, double pl, const double wip[3][3], const float higherCoef, const float lowerCoef) -{//Not used...bad results - constexpr float ClipLevel = 65535.0f; - bool inGamut; - // int nb = 0; - do { - inGamut = true; - double L_, M_, S_; - double xx, yy, zz; - bool zcam = false; - Ciecam02::jzczhzxyz (xx, yy, zz, Jz, az, bz, pl, L_, M_, S_, zcam); - double x, y, z; - x = 65535. * (d65_d50[0][0] * xx + d65_d50[0][1] * yy + d65_d50[0][2] * zz); - y = 65535. * (d65_d50[1][0] * xx + d65_d50[1][1] * yy + d65_d50[1][2] * zz); - z = 65535. * (d65_d50[2][0] * xx + d65_d50[2][1] * yy + d65_d50[2][2] * zz); - float R,G,B; - Color:: xyz2rgb(x, y, z, R, G, B, wip); - if (rtengine::min(R, G, B) < 0.f || rtengine::max(R, G, B) > ClipLevel) { +void gamutjz(double &Jz, double &az, double &bz, double pl, const double wip[3][3], const float higherCoef, const float lowerCoef) +{ + //Not used...bad results + constexpr float ClipLevel = 65535.0f; + bool inGamut; + + // int nb = 0; + do { + inGamut = true; + double L_, M_, S_; + double xx, yy, zz; + bool zcam = false; + Ciecam02::jzczhzxyz(xx, yy, zz, Jz, az, bz, pl, L_, M_, S_, zcam); + double x, y, z; + x = 65535. * (d65_d50[0][0] * xx + d65_d50[0][1] * yy + d65_d50[0][2] * zz); + y = 65535. * (d65_d50[1][0] * xx + d65_d50[1][1] * yy + d65_d50[1][2] * zz); + z = 65535. * (d65_d50[2][0] * xx + d65_d50[2][1] * yy + d65_d50[2][2] * zz); + float R, G, B; + Color:: xyz2rgb(x, y, z, R, G, B, wip); + + if (rtengine::min(R, G, B) < 0.f || rtengine::max(R, G, B) > ClipLevel) { // nb++; - double hz = xatan2f(bz, az); - float2 sincosval = xsincosf(hz); - double Cz = sqrt(az * az + bz * bz); - // printf("cz=%f jz=%f" , (double) Cz, (double) Jz); - Cz *= (double) higherCoef; - if(Cz < 0.01 && Jz > 0.05) {//empirical values - Jz -= (double) lowerCoef; - } - az = clipazbz(Cz * (double) sincosval.y); - bz = clipazbz(Cz * (double) sincosval.x); - - inGamut = false; + double hz = xatan2f(bz, az); + float2 sincosval = xsincosf(hz); + double Cz = sqrt(az * az + bz * bz); + // printf("cz=%f jz=%f" , (double) Cz, (double) Jz); + Cz *= (double) higherCoef; + + if (Cz < 0.01 && Jz > 0.05) { //empirical values + Jz -= (double) lowerCoef; } - } while (!inGamut); + + az = clipazbz(Cz * (double) sincosval.y); + bz = clipazbz(Cz * (double) sincosval.x); + + inGamut = false; + } + } while (!inGamut); } -void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, LabImage* lab, int bfw, int bfh, int call, int sk, const LUTf& cielocalcurve, bool localcieutili, const LUTf& cielocalcurve2, bool localcieutili2, const LUTf& jzlocalcurve, bool localjzutili, const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, const LocCHCurve& locchCurvejz, const LocHHCurve& lochhCurvejz, const LocLHCurve& loclhCurvejz, bool HHcurvejz, bool CHcurvejz, bool LHcurvejz, const LocwavCurve& locwavCurvejz, bool locwavutilijz -) +void ImProcFunctions::ciecamloc_02float(struct local_params& lp, int sp, LabImage* lab, int bfw, int bfh, int call, int sk, const LUTf& cielocalcurve, bool localcieutili, const LUTf& cielocalcurve2, bool localcieutili2, + const LUTf& jzlocalcurve, bool localjzutili, const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, const LocCHCurve& locchCurvejz, const LocHHCurve& lochhCurvejz, const LocLHCurve& loclhCurvejz, bool HHcurvejz, bool CHcurvejz, bool LHcurvejz, + const LocwavCurve& locwavCurvejz, bool locwavutilijz, float &maxicam, float &contsig, float &lightsig + ) { // BENCHFUN -//possibility to reenable Zcam - if(!params->locallab.spots.at(sp).activ) {//disable all ciecam functions + if (!params->locallab.spots.at(sp).activ) { //disable all ciecam functions return; } + bool ciec = false; bool iscie = false; + if (params->locallab.spots.at(sp).ciecam && params->locallab.spots.at(sp).explog && call == 1) { ciec = true; iscie = false; - } - else if (params->locallab.spots.at(sp).expcie && call == 0) { + } else if (params->locallab.spots.at(sp).expcie && call == 0) { ciec = true; iscie = true; } + bool z_cam = false; //params->locallab.spots.at(sp).jabcie; //alaways use normal algorithm, Zcam giev often bad results bool jabcie = false;//always disabled bool islogjz = params->locallab.spots.at(sp).forcebw; bool issigjz = params->locallab.spots.at(sp).sigjz; bool issigq = params->locallab.spots.at(sp).sigq; - bool islogq = params->locallab.spots.at(sp).logcie; + // bool islogq = params->locallab.spots.at(sp).logcie; + // bool istrc = params->locallab.spots.at(sp).trccie; + bool issig = true; //params->locallab.spots.at(sp).sigcie; //sigmoid J Q variables - const float sigmoidlambda = params->locallab.spots.at(sp).sigmoidldacie; - const float sigmoidth = params->locallab.spots.at(sp).sigmoidthcie; - const float sigmoidbl = params->locallab.spots.at(sp).sigmoidblcie; - const bool sigmoidqj = params->locallab.spots.at(sp).sigmoidqjcie; + const float sigmoidlambda = params->locallab.spots.at(sp).sigmoidldacie; + const float sigmoidth = params->locallab.spots.at(sp).sigmoidthcie; + const float sigmoidbl = params->locallab.spots.at(sp).sigmoidblcie; + const bool sigmoidnorm = params->locallab.spots.at(sp).normcie; + int mobwev = 0; + float sumcamq01 = 0.5f; + if (params->locallab.spots.at(sp).bwevMethod == "none") { + mobwev = 0; + } else if (params->locallab.spots.at(sp).bwevMethod == "sig") { + mobwev = 1; + } else if (params->locallab.spots.at(sp).bwevMethod == "logsig") { + mobwev = 2; + } + + float senssig = (float) params->locallab.spots.at(sp).sigmoidsenscie; TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); const double wip[3][3] = {//improve precision with double {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, @@ -2415,41 +2819,45 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L float plum = (float) params->locallab.spots.at(sp).pqremapcam16; int mocam = 1; - if(params->locallab.spots.at(sp).modecam == "all") { - mocam = 10;//à remettre à 0 si modecam = "all" - } else if(params->locallab.spots.at(sp).modecam == "cam16") { + + if(lp.moka == 1) { mocam = 1; - } else if(params->locallab.spots.at(sp).modecam == "jz") { + } else if (lp.moka == 2) { mocam = 2; -// } else if(params->locallab.spots.at(sp).modecam == "zcam") { -// mocam = 3; } int mecamcurve = 0; - if(params->locallab.spots.at(sp).toneMethodcie == "one") { + + if (params->locallab.spots.at(sp).toneMethodcie == "one") { mecamcurve = 0; - } else if(params->locallab.spots.at(sp).toneMethodcie == "two") { + } else if (params->locallab.spots.at(sp).toneMethodcie == "two") { mecamcurve = 1; } int mecamcurve2 = 0; - if(params->locallab.spots.at(sp).toneMethodcie2 == "onec") { + + if (params->locallab.spots.at(sp).toneMethodcie2 == "onec") { mecamcurve2 = 0; - } else if(params->locallab.spots.at(sp).toneMethodcie2 == "twoc") { + } else if (params->locallab.spots.at(sp).toneMethodcie2 == "twoc") { mecamcurve2 = 1; - } else if(params->locallab.spots.at(sp).toneMethodcie2 == "thrc") { + } else if (params->locallab.spots.at(sp).toneMethodcie2 == "thrc") { mecamcurve2 = 2; } float th = 1.f; - const float at = 1.f - sigmoidth; - const float bt = sigmoidth; +// const float at = 1.f - sigmoidth; +// const float bt = sigmoidth; - const float ath = sigmoidth - 1.f; - const float bth = 1; - float sila = pow_F(sigmoidlambda, 0.5f); - const float sigm = 3.3f + 7.1f *(1.f - sila);//e^10.4 = 32860 => sigm vary from 3.3 to 10.4 - const float bl = sigmoidbl; + // const float ath = sigmoidth - 1.f; + // const float bth = 1; + float sila = pow_F(sigmoidlambda, senssig); + sila = LIM01(sila); + const float sigm = 3.3f + 7.1f * (1.f - sila); //e^10.4 = 32860 => sigm vary from 3.3 to 10.4 + float bl = std::min(sigmoidbl, 1.f);//reused old slider + if(params->locallab.spots.at(sp).logcieq) { + bl = 0.01f * (float) params->locallab.spots.at(sp).strcielog; + bl = std::min(bl, 1.f); + } //end sigmoid int width = lab->W, height = lab->H; @@ -2468,63 +2876,63 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L //for J light and contrast LUTf CAMBrightCurveJ(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); LUTf CAMBrightCurveQ(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); - + LUTf CAMBrightCurveQsig(32768, LUT_CLIP_BELOW | LUT_CLIP_ABOVE); #ifdef _OPENMP const int numThreads = min(max(width * height / 65536, 1), omp_get_max_threads()); #pragma omp parallel num_threads(numThreads) if(numThreads>1) #endif { - LUTu hist16Jthr(hist16J.getSize(), LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); - LUTu hist16Qthr(hist16Q.getSize(), LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + LUTu hist16Jthr(hist16J.getSize(), LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); + LUTu hist16Qthr(hist16Q.getSize(), LUT_CLIP_BELOW | LUT_CLIP_ABOVE, true); #ifdef _OPENMP - #pragma omp for + #pragma omp for #endif - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { //rough correspondence between L and J - float currL = lab->L[i][j] / 327.68f; - float koef; //rough correspondence between L and J + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { //rough correspondence between L and J + float currL = lab->L[i][j] / 327.68f; + float koef; //rough correspondence between L and J - if (currL > 50.f) { - if (currL > 70.f) { - if (currL > 80.f) { - if (currL > 85.f) { - koef = 0.97f; + if (currL > 50.f) { + if (currL > 70.f) { + if (currL > 80.f) { + if (currL > 85.f) { + koef = 0.97f; + } else { + koef = 0.93f; + } } else { - koef = 0.93f; + koef = 0.87f; } } else { - koef = 0.87f; + if (currL > 60.f) { + koef = 0.85f; + } else { + koef = 0.8f; + } } } else { - if (currL > 60.f) { - koef = 0.85f; - } else { - koef = 0.8f; - } - } - } else { - if (currL > 10.f) { - if (currL > 20.f) { - if (currL > 40.f) { - koef = 0.75f; + if (currL > 10.f) { + if (currL > 20.f) { + if (currL > 40.f) { + koef = 0.75f; + } else { + koef = 0.7f; + } } else { - koef = 0.7f; + koef = 0.9f; } } else { - koef = 0.9f; + koef = 1.0; } - } else { - koef = 1.0; } + + hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J + hist16Qthr[CLIP((int)(32768.f * sqrt((koef * (lab->L[i][j])) / 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L } - - hist16Jthr[(int)((koef * lab->L[i][j]))]++; //evaluate histogram luminance L # J - hist16Qthr[CLIP((int)(32768.f * sqrt((koef * (lab->L[i][j])) / 32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L } - } #ifdef _OPENMP #pragma omp critical @@ -2545,7 +2953,8 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L float lightL = 0.f; float contQ = 0.f; float lightQ = 0.f; - if(iscie) { + + if (iscie) { contL = 0.6 * params->locallab.spots.at(sp).contlcie; //0.6 less effect, no need 1. lightL = 0.4 * params->locallab.spots.at(sp).lightlcie; //0.4 less effect, no need 1. contQ = 0.5 * params->locallab.spots.at(sp).contqcie; //0.5 less effect, no need 1. @@ -2555,55 +2964,86 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L lightL = 0.4 * params->locallab.spots.at(sp).lightl; //0.4 less effect, no need 1. contQ = 0.5 * params->locallab.spots.at(sp).contq; //0.5 less effect, no need 1. lightQ = 0.4 * params->locallab.spots.at(sp).lightq; //0.4 less effect, no need 1. - + } + float contthresL = 0.f; - - if(iscie) { + + if (iscie) { contthresL = params->locallab.spots.at(sp).contthrescie; } else { contthresL = params->locallab.spots.at(sp).contthres; } + float contthresQ = contthresL; - if(contL < 0.f) { + + if (contL < 0.f) { contthresL *= -1; - } + } + float thL = 0.6f; thL = 0.3f * contthresL + 0.6f; - - if(contQ < 0.f) { + + if (contQ < 0.f) { contthresQ *= -1; - } + } + float thQ = 0.6f; thQ = 0.3f * contthresQ + 0.6f; + float thQsig = 0.6f; Ciecam02::curveJfloat(lightL, contL, thL, hist16J, CAMBrightCurveJ); //lightness J and contrast J CAMBrightCurveJ /= 327.68f; + double podcont = 40.;//50 + double podcont0 = 40.;//50 + double podcont1 = 30.;//35. + double ka = -(podcont0 - podcont1) / 0.5; + double kb = podcont1 - ka; + + double podlight = 35.; + double podlight0 = 35.; + double podlight1 = 40.;//45 + double kal = -(podlight0 - podlight1) / 0.5; + double kbl = podlight1 - kal; + double contbase = params->locallab.spots.at(sp).sigmoidldacie; + + if(contbase <= 0.5) { + podcont = podcont0; + podlight = podlight0; + + } else { + podcont = ka * contbase + kb; + podlight = kal * contbase + kbl; + } Ciecam02::curveJfloat(lightQ, contQ, thQ, hist16Q, CAMBrightCurveQ); //brightness Q and contrast Q + lightsig = -podlight * contbase; + contsig = podcont * contbase; + Ciecam02::curveJfloat(lightsig, contsig, thQsig, hist16Q, CAMBrightCurveQsig); //brightness Q and contrast Q bypass. } - - + + int tempo = 5000; - if(params->locallab.spots.at(sp).expvibrance && call == 2) { + + if (params->locallab.spots.at(sp).expvibrance && call == 2) { if (params->locallab.spots.at(sp).warm > 0) { tempo = 5000 - 30 * params->locallab.spots.at(sp).warm; - } else if (params->locallab.spots.at(sp).warm < 0){ + } else if (params->locallab.spots.at(sp).warm < 0) { tempo = 5000 - 70 * params->locallab.spots.at(sp).warm; } } - if(ciec) { - if(iscie) { + if (ciec) { + if (iscie) { if (params->locallab.spots.at(sp).catadcie > 0) { tempo = 5000 - 30 * params->locallab.spots.at(sp).catadcie; - } else if (params->locallab.spots.at(sp).catadcie < 0){ + } else if (params->locallab.spots.at(sp).catadcie < 0) { tempo = 5000 - 70 * params->locallab.spots.at(sp).catadcie; } } else { if (params->locallab.spots.at(sp).catad > 0) { tempo = 5000 - 30 * params->locallab.spots.at(sp).catad; - } else if (params->locallab.spots.at(sp).catad < 0){ + } else if (params->locallab.spots.at(sp).catad < 0) { tempo = 5000 - 70 * params->locallab.spots.at(sp).catad; } } @@ -2619,19 +3059,26 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L nc = 1.00f; //viewing condition for surround f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; - if(ciec) { - if(iscie) { - //surround source with only 2 choices (because Log encoding before) - if (params->locallab.spots.at(sp).sursourcie == "Average") { + + if (ciec) { + if (iscie) { + //surround source with only 2 choices (because Log encoding before) + if(lp.sursouci == 0) { f = 1.0f, c = 0.69f, nc = 1.0f; - } else if (params->locallab.spots.at(sp).sursourcie == "Dim") { + } else if (lp.sursouci == 1){ f = 0.9f; c = 0.59f; nc = 0.9f; - } else if (params->locallab.spots.at(sp).sursourcie == "Dark") { + } else if (lp.sursouci == 2) { f = 0.8f; c = 0.525f; nc = 0.8f; + } else if (lp.sursouci == 3) { + f = 0.8f; + c = 0.41f; + nc = 0.8f; + } else if (lp.sursouci == 4) { + f = 1.0f, c = 0.702f, nc = 1.0f;//very small surround effect for Jz - Also disable Ciecam further } } else { if (params->locallab.spots.at(sp).sursour == "Average") { @@ -2644,11 +3091,15 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L f = 0.8f; c = 0.525f; nc = 0.8f; + } else if (params->locallab.spots.at(sp).sursour == "exDark") { + f = 0.8f; + c = 0.41f; + nc = 0.8f; } } //viewing condition for surround - if(iscie) { + if (iscie) { if (params->locallab.spots.at(sp).surroundcie == "Average") { f2 = 1.0f, c2 = 0.69f, nc2 = 1.0f; } else if (params->locallab.spots.at(sp).surroundcie == "Dim") { @@ -2680,7 +3131,7 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L c2 = 0.41f; nc2 = 0.8f; } - + } } @@ -2696,8 +3147,9 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L //La and la2 = ambiant luminosity scene and viewing la = 400.f; float la2 = 400.f; - if(ciec) { - if(iscie) { + + if (ciec) { + if (iscie) { la = params->locallab.spots.at(sp).sourceabscie; la2 = params->locallab.spots.at(sp).targabscie; } else { @@ -2712,8 +3164,9 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L //algoritm's params float yb = 18.f; yb2 = 18; - if(ciec) { - if(iscie) { + + if (ciec) { + if (iscie) { yb = params->locallab.spots.at(sp).sourceGraycie;// avgm = (double) pow_F(0.01f * (yb - 1.f), 0.45f);; yb2 = params->locallab.spots.at(sp).targetGraycie; @@ -2722,47 +3175,51 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L yb2 = params->locallab.spots.at(sp).targetGray; } } - if(params->locallab.spots.at(sp).expcie && call == 10 && params->locallab.spots.at(sp).modecam == "jz") { - yb = params->locallab.spots.at(sp).sourceGraycie;//for Jz calculate Yb and surround in Lab and cam16 before process Jz - la = params->locallab.spots.at(sp).sourceabscie; - if (params->locallab.spots.at(sp).sursourcie == "Average") { + if (params->locallab.spots.at(sp).expcie && call == 10 && params->locallab.spots.at(sp).modecam == "jz") { + yb = params->locallab.spots.at(sp).sourceGraycie;//for Jz calculate Yb and surround in Lab and cam16 before process Jz + la = params->locallab.spots.at(sp).sourceabscie; + if(lp.sursouci == 0) { f = 1.0f, c = 0.69f, nc = 1.0f; - } else if (params->locallab.spots.at(sp).sursourcie == "Dim") { + } else if (lp.sursouci == 1){ f = 0.9f; c = 0.59f; nc = 0.9f; - } else if (params->locallab.spots.at(sp).sursourcie == "Dark") { + } else if (lp.sursouci == 2) { f = 0.8f; c = 0.525f; nc = 0.8f; + } else if (lp.sursouci == 3) { + f = 0.8f; + c = 0.41f; + nc = 0.8f; + } else if (lp.sursouci == 4) { + f = 1.0f, c = 0.702f, nc = 1.0f;//very small surround effect for Jz } + } - + float schr = 0.f; float mchr = 0.f; float cchr = 0.f; float rstprotection = 0.f; float hue = 0.f; -/* - float mchrz = 0.f; - float schrz = 0.f; - float cchrz = 0.f; -*/ + if (ciec) { - if(iscie) { + if (iscie) { rstprotection = params->locallab.spots.at(sp).rstprotectcie; hue = params->locallab.spots.at(sp).huecie; cchr = params->locallab.spots.at(sp).chromlcie; + if (cchr == -100.0f) { - cchr = -99.8f; + cchr = -99.8f; } schr = params->locallab.spots.at(sp).saturlcie; if (schr > 0.f) { - schr = schr / 2.f; //divide sensibility for saturation + schr = schr / 2.f; //divide sensibility for saturation } if (schr == -100.f) { @@ -2774,24 +3231,22 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L if (mchr == -100.0f) { mchr = -99.8f ; } + if (mchr == 100.0f) { mchr = 99.9f; } -/* - mchrz = 0.5f * (float) params->locallab.spots.at(sp).colorflzcam; - schrz = 0.5f * (float) params->locallab.spots.at(sp).saturzcam; - cchrz = 0.5f * (float) params->locallab.spots.at(sp).chromzcam; -*/ + } else { cchr = params->locallab.spots.at(sp).chroml; + if (cchr == -100.0f) { - cchr = -99.8f; + cchr = -99.8f; } schr = params->locallab.spots.at(sp).saturl; if (schr > 0.f) { - schr = schr / 2.f; //divide sensibility for saturation + schr = schr / 2.f; //divide sensibility for saturation } if (schr == -100.f) { @@ -2803,6 +3258,7 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L if (mchr == -100.0f) { mchr = -99.8f ; } + if (mchr == 100.0f) { mchr = 99.9f; } @@ -2819,9 +3275,11 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L float cz, wh, pfl; int c16 = 16;//always cat16 bool c20 = true; - if(c20 && plum > 100.f) { + + if (c20 && plum > 100.f) { c16 = 21;//I define 21...for 2021 :) } + int level_bljz = params->locallab.spots.at(sp).csthresholdjz.getBottomLeft(); int level_hljz = params->locallab.spots.at(sp).csthresholdjz.getTopLeft(); int level_brjz = params->locallab.spots.at(sp).csthresholdjz.getBottomRight(); @@ -2842,17 +3300,20 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L ahighjz = 1.f / (level_hrjz - level_brjz); bhighjz = -ahighjz * level_brjz; } + float sigmalcjz = params->locallab.spots.at(sp).sigmalcjz; float jzamountchr = 0.01 * params->locallab.spots.at(sp).thrhjzcie; bool jzch = params->locallab.spots.at(sp).chjzcie; double jzamountchroma = 0.01 * settings->amchromajz; - if(jzamountchroma < 0.05) { + + if (jzamountchroma < 0.05) { jzamountchroma = 0.05; } - if(jzamountchroma > 2.) { + + if (jzamountchroma > 2.) { jzamountchroma = 2.; } - + Ciecam02::initcam1float(yb, pilot, f, la, xw, yw, zw, n, d, nbb, ncb, cz, aw, wh, pfl, fl, c, c16, plum); const float pow1 = pow_F(1.64f - pow_F(0.29f, n), 0.73f); float nj, nbbj, ncbj, czj, awj, flj; @@ -2862,7 +3323,8 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L #endif const float epsil = 0.0001f; const float coefQ = 32767.f / wh; - const float coefq = 1 / wh; + const float coefq = 1.f / wh; + const float pow1n = pow_F(1.64f - pow_F(0.29f, nj), 0.73f); const float coe = pow_F(fl, 0.25f); const float QproFactor = (0.4f / c) * (aw + 4.0f) ; @@ -2874,7 +3336,7 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L const double log2 = xlog(2.); const float log2f = xlogf(2.f); - if((mocam == 0 || mocam ==2) && call == 0) {//Jz az bz ==> Jz Cz Hz before Ciecam16 + if ((mocam == 2) && call == 0) { //Jz az bz ==> Jz Cz Hz before Ciecam16 double mini = 1000.; double maxi = -1000.; double sum = 0.; @@ -2890,13 +3352,13 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L bool Qtoj = params->locallab.spots.at(sp).qtoj;//betwwen lightness to brightness const bool logjz = params->locallab.spots.at(sp).logjz;//log encoding - //calculate min, max, mean for Jz #ifdef _OPENMP - #pragma omp parallel for reduction(min:mini) reduction(max:maxi) reduction(+:sum) if(multiThread) + #pragma omp parallel for reduction(min:mini) reduction(max:maxi) reduction(+:sum) if(multiThread) #endif - for (int i = 0; i < height; i+=1) { - for (int k = 0; k < width; k+=1) { + + for (int i = 0; i < height; i += 1) { + for (int k = 0; k < width; k += 1) { float L = lab->L[i][k]; float a = lab->a[i][k]; float b = lab->b[i][k]; @@ -2916,51 +3378,59 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L double L_p, M_p, S_p; bool zcam = z_cam; - Ciecam02::xyz2jzczhz (Jz, az, bz, xx, yy, zz, pl, L_p, M_p, S_p, zcam); - if(Jz > maxi) { + Ciecam02::xyz2jzczhz(Jz, az, bz, xx, yy, zz, pl, L_p, M_p, S_p, zcam); + + if (Jz > maxi) { maxi = Jz; } - if(Jz < mini) { + + if (Jz < mini) { mini = Jz; } + sum += Jz; - // I read bz, az values and Hz ==> with low chroma values Hz are very different from lab always around 1.4 radians ???? for blue... + // I read bz, az values and Hz ==> with low chroma values Hz are very different from lab always around 1.4 radians ???? for blue... } } + nc = height * width; sum = sum / nc; maxi += epsiljz; sum += epsiljz; - //remapping Jz - double ijz100 = 1./jz100; - double ajz = (ijz100 - 1.)/9.;//9 = sqrt(100) - 1 with a parabolic curve after jz100 - we can change for others curve ..log...(you must change also in locallabtool2) + //remapping Jz + double ijz100 = 1. / jz100; + double ajz = (ijz100 - 1.) / 9.; //9 = sqrt(100) - 1 with a parabolic curve after jz100 - we can change for others curve ..log...(you must change also in locallabtool2) double bjz = 1. - ajz; - //relation between adapjz and Absolute luminance source (La), adapjz =sqrt(La) - see locallabtool2 adapjzcie + //relation between adapjz and Absolute luminance source (La), adapjz =sqrt(La) - see locallabtool2 adapjzcie double interm = jz100 * (adapjz * ajz + bjz); double bj = (10. - maxi) / 9.; - double aj = maxi -bj; + double aj = maxi - bj; double to_screen = (aj * interm + bj) / maxi; //to screen - remapping of Jz in function real scene absolute luminance -// if (settings->verbose) { +// if (settings->verbose) { // printf("ajz=%f bjz=%f adapjz=%f jz100=%f interm=%f to-scrp=%f to_screen=%f\n", ajz, bjz, adapjz, jz100, interm ,to_screenp, to_screen); // } double to_one = 1.;//only for calculation in range 0..1 or 0..32768 to_one = 1 / (maxi * to_screen); - if(adapjz == 10.) {//force original algorithm if La > 10000 + + if (adapjz == 10.) { //force original algorithm if La > 10000 to_screen = 1.; } - if(Qtoj) { - double xxw = (d50_d65[0][0] * (double) Xw + d50_d65[0][1] * (double) Yw + d50_d65[0][2] * (double) Zw); - double yyw = (d50_d65[1][0] * (double) Xw + d50_d65[1][1] * (double) Yw + d50_d65[1][2] * (double) Zw); - double zzw = (d50_d65[2][0] * (double) Xw + d50_d65[2][1] * (double) Yw + d50_d65[2][2] * (double) Zw); - double L_pa, M_pa, S_pa; - Ciecam02::xyz2jzczhz (jzw, azw, bzw, xxw, yyw, zzw, pl, L_pa, M_pa, S_pa, z_cam); - if (settings->verbose) { //calculate Jz white for use of lightness instead brightness - printf("Jzwhite=%f \n", jzw); - } + + if (Qtoj) { + double xxw = (d50_d65[0][0] * (double) Xw + d50_d65[0][1] * (double) Yw + d50_d65[0][2] * (double) Zw); + double yyw = (d50_d65[1][0] * (double) Xw + d50_d65[1][1] * (double) Yw + d50_d65[1][2] * (double) Zw); + double zzw = (d50_d65[2][0] * (double) Xw + d50_d65[2][1] * (double) Yw + d50_d65[2][2] * (double) Zw); + double L_pa, M_pa, S_pa; + Ciecam02::xyz2jzczhz(jzw, azw, bzw, xxw, yyw, zzw, pl, L_pa, M_pa, S_pa, z_cam); + + if (settings->verbose) { //calculate Jz white for use of lightness instead brightness + printf("Jzwhite=%f \n", jzw); + } } + const std::unique_ptr temp(new LabImage(width, height)); const std::unique_ptr tempresid(new LabImage(width, height)); const std::unique_ptr tempres(new LabImage(width, height)); @@ -2973,20 +3443,21 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L int shtonals = params->locallab.spots.at(sp).shthjzcie; int radhs = params->locallab.spots.at(sp).radjzcie; float softjz = (float) params->locallab.spots.at(sp).softjzcie; - + avgm = 0.5 * (sum * to_screen * to_one + avgm);//empirical formula double miny = 0.1; double delta = 0.015 * (double) sqrt(std::max(100.f, la) / 100.f);//small adaptation in function La scene double maxy = 0.65;//empirical value - double maxreal = maxi*to_screen; - double maxjzw = jzw*to_screen; - if (settings->verbose) { + double maxreal = maxi * to_screen; + double maxjzw = jzw * to_screen; + + if (settings->verbose) { printf("La=%4.1f PU_adap=%2.1f maxi=%f mini=%f mean=%f, avgm=%f to_screen=%f Max_real=%f to_one=%f\n", (double) la, adapjz, maxi, mini, sum, avgm, to_screen, maxreal, to_one); } - const float sigmoidlambdajz = params->locallab.spots.at(sp).sigmoidldajzcie; - const float sigmoidthjz = params->locallab.spots.at(sp).sigmoidthjzcie; - const float sigmoidbljz = params->locallab.spots.at(sp).sigmoidbljzcie; + const float sigmoidlambdajz = params->locallab.spots.at(sp).sigmoidldajzcie; + const float sigmoidthjz = params->locallab.spots.at(sp).sigmoidthjzcie; + const float sigmoidbljz = params->locallab.spots.at(sp).sigmoidbljzcie; float thjz = 1.f; const float atjz = 1.f - sigmoidthjz; @@ -2995,9 +3466,9 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L const float athjz = sigmoidthjz - 1.f; const float bthjz = 1.f; float powsig = pow_F(sigmoidlambdajz, 0.5f); - const float sigmjz = 3.3f + 7.1f *(1.f - powsig);// e^10.4 = 32860 + const float sigmjz = 3.3f + 7.1f * (1.f - powsig); // e^10.4 = 32860 const float bljz = sigmoidbljz; - + double contreal = 0.2 * params->locallab.spots.at(sp).contjzcie; DiagonalCurve jz_contrast({ DCT_NURBS, @@ -3015,17 +3486,18 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L DCT_NURBS, 0, 0, miny, miny + lightreal / 150., - maxy, min (1.0, maxy + delta + lightreal / 300.0), + maxy, min(1.0, maxy + delta + lightreal / 300.0), 1, 1 }); DiagonalCurve jz_lightn({ DCT_NURBS, 0, 0, - max(0.0, miny - lightreal / 150.), miny , + max(0.0, miny - lightreal / 150.), miny, maxy + delta - lightreal / 300.0, maxy + delta, 1, 1 }); bool wavcurvejz = false; + if (locwavCurvejz && locwavutilijz) { for (int i = 0; i < 500; i++) { if (locwavCurvejz[i] != 0.5f) { @@ -3034,52 +3506,58 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } } + float mjjz = lp.mLjz; - if(wavcurvejz && lp.mLjz == 0.f) { + + if (wavcurvejz && lp.mLjz == 0.f) { mjjz = 0.0f;//to enable clarity if need in some cases mjjz = 0.0001f } - //log encoding Jz - double gray = 0.15; - /* - const double shadows_range = params->locallab.spots.at(sp).blackEvjz; - const double targetgray = params->locallab.spots.at(sp).targetjz; - double targetgraycor = 0.15; - double dynamic_range = std::max(params->locallab.spots.at(sp).whiteEvjz - shadows_range, 0.5); - const double noise = pow(2., -16.6);//16.6 instead of 16 a little less than others, but we work in double - const double log2 = xlog(2.); - */ - double base = 10.; - double linbase = 10.; - if(logjz) {//with brightness Jz - gray = 0.01 * params->locallab.spots.at(sp).sourceGraycie;//acts as amplifier (gain) : needs same type of modifications than targetgraycor with pow - gray = pow(gray, 1.2);//or 1.15 => modification to increase sensitivity gain, only on defaults, of course we can change this value manually...take into account suuround and Yb Cam16 - targetgraycor = pow(0.01 * targetgray, 1.15);//or 1.2 small reduce effect -> take into account a part of surround (before it was at 1.2) - base = targetgray > 1. && targetgray < 100. && dynamic_range > 0. ? (double) find_gray(std::abs((float) shadows_range) / (float) dynamic_range, (float) (targetgraycor)) : 0.; - linbase = std::max(base, 2.);//2. minimal base log to avoid very bad results - if (settings->verbose) { - printf("Base logarithm encoding Jz=%5.1f\n", linbase); + //log encoding Jz + double gray = 0.15; + /* + const double shadows_range = params->locallab.spots.at(sp).blackEvjz; + const double targetgray = params->locallab.spots.at(sp).targetjz; + double targetgraycor = 0.15; + double dynamic_range = std::max(params->locallab.spots.at(sp).whiteEvjz - shadows_range, 0.5); + const double noise = pow(2., -16.6);//16.6 instead of 16 a little less than others, but we work in double + const double log2 = xlog(2.); + */ + double base = 10.; + double linbase = 10.; + + if (logjz) { //with brightness Jz + gray = 0.01 * params->locallab.spots.at(sp).sourceGraycie;//acts as amplifier (gain) : needs same type of modifications than targetgraycor with pow + gray = pow(gray, 1.2);//or 1.15 => modification to increase sensitivity gain, only on defaults, of course we can change this value manually...take into account suuround and Yb Cam16 + targetgraycor = pow(0.01 * targetgray, 1.15);//or 1.2 small reduce effect -> take into account a part of surround (before it was at 1.2) + base = targetgray > 1. && targetgray < 100. && dynamic_range > 0. ? (double) find_gray(std::abs((float) shadows_range) / (float) dynamic_range, (float)(targetgraycor)) : 0.; + linbase = std::max(base, 2.);//2. minimal base log to avoid very bad results + + if (settings->verbose) { + printf("Base logarithm encoding Jz=%5.1f\n", linbase); + } } - } - const auto applytojz = - [ = ](double x) -> double { + const auto applytojz = + [ = ](double x) -> double { - x = std::max(x, noise); - x = std::max(x / gray, noise);//gray = gain - before log conversion - x = std::max((xlog(x) / log2 - shadows_range) / dynamic_range, noise);//x in range EV - assert(x == x); + x = std::max(x, noise); + x = std::max(x / gray, noise);//gray = gain - before log conversion + x = std::max((xlog(x) / log2 - shadows_range) / dynamic_range, noise);//x in range EV + assert(x == x); - if (linbase > 0.)//apply log base in function of targetgray blackEvjz and Dynamic Range - { - x = xlog2lin(x, linbase); - } - return x; - }; + if (linbase > 0.)//apply log base in function of targetgray blackEvjz and Dynamic Range + { + x = xlog2lin(x, linbase); + } + + return x; + }; #ifdef _OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for if(multiThread) #endif + for (int i = 0; i < height; i++) { for (int k = 0; k < width; k++) { float L = lab->L[i][k]; @@ -3100,7 +3578,7 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L double L_p, M_p, S_p; bool zcam = z_cam; - Ciecam02::xyz2jzczhz (Jz, az, bz, xx, yy, zz, pl, L_p, M_p, S_p, zcam); + Ciecam02::xyz2jzczhz(Jz, az, bz, xx, yy, zz, pl, L_p, M_p, S_p, zcam); //remapping Jz Jz = Jz * to_screen; az = az * to_screen; @@ -3108,7 +3586,8 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L JJz[i][k] = Jz; Aaz[i][k] = az; Bbz[i][k] = bz; - if(highhs > 0 || shadhs > 0 || wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f || LHcurvejz || HHcurvejz || CHcurvejz) { + + if (highhs > 0 || shadhs > 0 || wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f || LHcurvejz || HHcurvejz || CHcurvejz) { //here we work in float with usual functions SH / wavelets / curves H temp->L[i][k] = tempresid->L[i][k] = tempres->L[i][k] = (float) to_one * 32768.f * (float) JJz[i][k]; temp->a[i][k] = tempresid->a[i][k] = tempres->a[i][k] = (float) to_one * 32768.f * (float) Aaz[i][k]; @@ -3117,11 +3596,12 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } - if(highhs > 0 || shadhs > 0) { + if (highhs > 0 || shadhs > 0) { ImProcFunctions::shadowsHighlights(temp.get(), true, 1, highhs, shadhs, radhs, sk, hltonahs * maxi * to_screen * to_one, shtonals * maxi * to_screen * to_one); #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int i = 0; i < height; i++) { for (int k = 0; k < width; k++) {//reinitialize datas after SH...: guide, etc. tempresid->L[i][k] = tempres->L[i][k] = temp->L[i][k]; @@ -3130,21 +3610,22 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } } + //others "Lab" treatment...to adapt - - if(wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f) {//local contrast wavelet and clarity + + if (wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f) { //local contrast wavelet and clarity #ifdef _OPENMP const int numThreads = omp_get_max_threads(); #else const int numThreads = 1; #endif - // adap maximum level wavelet to size of RT-spot + // adap maximum level wavelet to size of RT-spot int wavelet_level = 1 + params->locallab.spots.at(sp).csthresholdjz.getBottomRight();//retrieve with +1 maximum wavelet_level int minwin = rtengine::min(width, height); int maxlevelspot = 10;//maximum possible - // adapt maximum level wavelet to size of crop + // adapt maximum level wavelet to size of crop while ((1 << maxlevelspot) >= (minwin * sk) && maxlevelspot > 1) { --maxlevelspot ; } @@ -3152,23 +3633,27 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L wavelet_level = rtengine::min(wavelet_level, maxlevelspot); int maxlvl = wavelet_level; + //simple local contrast in function luminance if (locwavCurvejz && locwavutilijz && wavcurvejz) { float strengthjz = 1.2; std::unique_ptr wdspot(new wavelet_decomposition(temp->L[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen));//lp.daubLen + if (wdspot->memory_allocation_failed()) { return; } + maxlvl = wdspot->maxlevel(); wavlc(*wdspot, level_bljz, level_hljz, maxlvl, level_hrjz, level_brjz, ahighjz, bhighjz, alowjz, blowjz, sigmalcjz, strengthjz, locwavCurvejz, numThreads); wdspot->reconstruct(temp->L[0], 1.f); } + float thr = 0.001f; int flag = 2; - + // begin clarity wavelet jz - if(mjjz != 0.f || lp.mCjz != 0.f) { + if (mjjz != 0.f || lp.mCjz != 0.f) { float mL0 = 0.f; float mC0 = 0.f; bool exec = false; @@ -3190,18 +3675,20 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L thr = 1.f; flag = 2; } + LabImage *mergfile = temp.get(); #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int x = 0; x < height; x++) for (int y = 0; y < width; y++) { temp->L[x][y] = clipLoc((1.f + mL0) * mergfile->L[x][y] - mL * tempresid->L[x][y]); temp->a[x][y] = clipC((1.f + mC0) * mergfile->a[x][y] - mC * tempresid->a[x][y]); temp->b[x][y] = clipC((1.f + mC0) * mergfile->b[x][y] - mC * tempresid->b[x][y]); - } + } } - + if (lp.softrjz >= 0.5f && (wavcurvejz || std::fabs(mjjz) > 0.001f)) {//guidedfilter softproc(tempres.get(), temp.get(), lp.softrjz, height, width, 0.001, 0.00001, thr, sk, multiThread, flag); } @@ -3209,55 +3696,62 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L //new curves Hz #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < height; i++) { for (int k = 0; k < width; k++) { float j_z = temp->L[i][k]; float C_z = sqrt(SQR(temp->a[i][k]) + SQR(temp->b[i][k])); float c_z = C_z / 32768.f; + if (loclhCurvejz && LHcurvejz) {//Jz=f(Hz) curve float kcz = (float) jzamountchr; - float Hz = xatan2f (temp->b[i][k], temp->a[i][k]); + float Hz = xatan2f(temp->b[i][k], temp->a[i][k]); float l_r = j_z / 32768.f; float kcc = SQR(c_z / kcz); jzch = true; - if(jzch == false) { + + if (jzch == false) { kcc = 1.f; - } else if(kcc > 1.f) { + } else if (kcc > 1.f) { kcc = 1.f; //cbrt(kcc); } - float valparam = loclhCurvejz[500.f *static_cast(Color::huejz_to_huehsv2((float) Hz))] - 0.5f; + + float valparam = loclhCurvejz[500.f * static_cast(Color::huejz_to_huehsv2((float) Hz))] - 0.5f; float valparamneg; valparamneg = valparam; valparam *= 2.f * kcc; valparamneg *= kcc; - if (valparam > 0.f) { - l_r = (1.f - valparam) * l_r + valparam * (1.f - SQR(((SQR(1.f - min(l_r, 1.0f)))))); - } else - //for negative - { - float khue = 1.9f; //in reserve in case of! - l_r *= (1.f + khue * valparamneg); - } + + if (valparam > 0.f) { + l_r = (1.f - valparam) * l_r + valparam * (1.f - SQR(((SQR(1.f - min(l_r, 1.0f)))))); + } else + //for negative + { + float khue = 1.9f; //in reserve in case of! + l_r *= (1.f + khue * valparamneg); + } + temp->L[i][k] = l_r * 32768.f; } - + if (locchCurvejz && CHcurvejz) {//Cz=f(Hz) curve - float Hz = xatan2f (temp->b[i][k], temp->a[i][k]); - const float valparam = 1.5f * (locchCurvejz[500.f * static_cast(Color::huejz_to_huehsv2((float)Hz))] - 0.5f); //get valp=f(H) - float chromaCzfactor = 1.0f + valparam; - temp->a[i][k] *= chromaCzfactor; - temp->b[i][k] *= chromaCzfactor; + float Hz = xatan2f(temp->b[i][k], temp->a[i][k]); + const float valparam = 1.5f * (locchCurvejz[500.f * static_cast(Color::huejz_to_huehsv2((float)Hz))] - 0.5f); //get valp=f(H) + float chromaCzfactor = 1.0f + valparam; + temp->a[i][k] *= chromaCzfactor; + temp->b[i][k] *= chromaCzfactor; } - - - if (lochhCurvejz && HHcurvejz) { // Hz=f(Hz) - float Hz = xatan2f (temp->b[i][k], temp->a[i][k]); + + + if (lochhCurvejz && HHcurvejz) { // Hz=f(Hz) + float Hz = xatan2f(temp->b[i][k], temp->a[i][k]); const float valparam = 1.4f * (lochhCurvejz[500.f * static_cast(Color::huejz_to_huehsv2((float)Hz))] - 0.5f) + static_cast(Hz); Hz = valparam; - if ( Hz < 0.0f ) { + + if (Hz < 0.0f) { Hz += (2.f * rtengine::RT_PI_F); } @@ -3268,80 +3762,88 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } - if (loclhCurvejz && LHcurvejz && softjz > 0.f) {//Guidedilter for artifacts curve J(H) - float thr = 0.00001f; - int flag = 2; - float softjzr = 0.05f * softjz; - softproc(tempres.get(), temp.get(), softjzr, height, width, 0.000001, 0.00000001, thr, sk, multiThread, flag); - } + if (loclhCurvejz && LHcurvejz && softjz > 0.f) {//Guidedilter for artifacts curve J(H) + float thr = 0.00001f; + int flag = 2; + float softjzr = 0.05f * softjz; + softproc(tempres.get(), temp.get(), softjzr, height, width, 0.000001, 0.00000001, thr, sk, multiThread, flag); + } - if ((lochhCurvejz && HHcurvejz) || (locchCurvejz && CHcurvejz)) { //for artifacts curve H(H) - if(softjz > 0.f) { - array2D chro(width, height); - array2D hue(width, height); - array2D guid(width, height); - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - hue[y][x] = xatan2f(temp->b[y][x], temp->a[y][x]); - chro[y][x] = sqrt(SQR(temp->b[y][x]) + SQR(temp->a[y][x]))/32768.f; - if ( hue[y][x] < 0.0f ) { - hue[y][x] += (2.f * rtengine::RT_PI_F); - } - hue[y][x] /= (2.f * rtengine::RT_PI_F); - guid[y][x] = tempres->L[y][x] / 32768.f; - } - } - float softr = softjz; - const float tmpblur = softr < 0.f ? -1.f / softr : 1.f + softr; - const int r2 = rtengine::max(10 / sk * tmpblur + 0.2f, 1); - const int r1 = rtengine::max(4 / sk * tmpblur + 0.5f, 1); - constexpr float epsilmax = 0.0005f; - constexpr float epsilmin = 0.0000001f; - constexpr float aepsil = (epsilmax - epsilmin) / 100.f; - constexpr float bepsil = epsilmin; - const float epsil = softr < 0.f ? 0.001f : aepsil * softr + bepsil; - if (lochhCurvejz && HHcurvejz) { - rtengine::guidedFilter(guid, hue, hue, r2, 0.5f * epsil, multiThread); - } - if (locchCurvejz && CHcurvejz) { - rtengine::guidedFilter(guid, chro, chro, r1, 0.4f * epsil, multiThread); - } + if ((lochhCurvejz && HHcurvejz) || (locchCurvejz && CHcurvejz)) { //for artifacts curve H(H) + if (softjz > 0.f) { + array2D chro(width, height); + array2D hue(width, height); + array2D guid(width, height); #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - hue[y][x] *= (2.f * rtengine::RT_PI_F); - chro[y][x] *= 32768.f; - float2 sincosval = xsincosf(hue[y][x]); - temp->a[y][x] = chro[y][x] * sincosval.y; - temp->b[y][x] = chro[y][x] * sincosval.x; - } + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + hue[y][x] = xatan2f(temp->b[y][x], temp->a[y][x]); + chro[y][x] = sqrt(SQR(temp->b[y][x]) + SQR(temp->a[y][x])) / 32768.f; + + if (hue[y][x] < 0.0f) { + hue[y][x] += (2.f * rtengine::RT_PI_F); } + + hue[y][x] /= (2.f * rtengine::RT_PI_F); + guid[y][x] = tempres->L[y][x] / 32768.f; } - } + } + + float softr = softjz; + const float tmpblur = softr < 0.f ? -1.f / softr : 1.f + softr; + const int r2 = rtengine::max(10 / sk * tmpblur + 0.2f, 1); + const int r1 = rtengine::max(4 / sk * tmpblur + 0.5f, 1); + constexpr float epsilmax = 0.0005f; + constexpr float epsilmin = 0.0000001f; + constexpr float aepsil = (epsilmax - epsilmin) / 100.f; + constexpr float bepsil = epsilmin; + const float epsil = softr < 0.f ? 0.001f : aepsil * softr + bepsil; + + if (lochhCurvejz && HHcurvejz) { + rtengine::guidedFilter(guid, hue, hue, r2, 0.5f * epsil, multiThread); + } + + if (locchCurvejz && CHcurvejz) { + rtengine::guidedFilter(guid, chro, chro, r1, 0.4f * epsil, multiThread); + } + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + hue[y][x] *= (2.f * rtengine::RT_PI_F); + chro[y][x] *= 32768.f; + float2 sincosval = xsincosf(hue[y][x]); + temp->a[y][x] = chro[y][x] * sincosval.y; + temp->b[y][x] = chro[y][x] * sincosval.x; + } + } + } + } /////////////////// - + #ifdef _OPENMP - #pragma omp parallel for if(multiThread) -#endif + #pragma omp parallel for if(multiThread) +#endif + for (int i = 0; i < height; i++) { for (int k = 0; k < width; k++) { //reconvert to double - if(highhs > 0 || shadhs > 0 || wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f || LHcurvejz || HHcurvejz || CHcurvejz) { + if (highhs > 0 || shadhs > 0 || wavcurvejz || mjjz != 0.f || lp.mCjz != 0.f || LHcurvejz || HHcurvejz || CHcurvejz) { //now we work in double necessary for matrix conversion and when in range 0..1 with use of PQ - JJz[i][k] = (double) (temp->L[i][k] / (32768.f * (float) to_one)); - Aaz[i][k] = (double) (temp->a[i][k] / (32768.f * (float) to_one)); - Bbz[i][k] = (double) (temp->b[i][k] / (32768.f * (float) to_one)); + JJz[i][k] = (double)(temp->L[i][k] / (32768.f * (float) to_one)); + Aaz[i][k] = (double)(temp->a[i][k] / (32768.f * (float) to_one)); + Bbz[i][k] = (double)(temp->b[i][k] / (32768.f * (float) to_one)); } double az = Aaz[i][k]; @@ -3349,57 +3851,67 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L double Jz = LIM01(JJz[i][k]); Jz *= to_one; double Cz = sqrt(az * az + bz * bz); + //log encoding - if(logjz) { + if (logjz) { double jmz = Jz; + if (jmz > noise) { double mm = applytojz(jmz); double f = mm / jmz; Jz *= f; - //Cz *= f; Jz = LIM01(Jz);//clip values - //Cz = clipcz(Cz); } } + //sigmoid - if(issigjz && iscie) {//sigmoid Jz + if (issigjz && iscie) { //sigmoid Jz float val = Jz; - if(islogjz) { + + if (islogjz) { val = std::max((xlog(Jz) / log2 - shadows_range) / (dynamic_range + 1.5), noise);//in range EV } - if(sigmoidthjz >= 1.f) { + + if (sigmoidthjz >= 1.f) { thjz = athjz * val + bthjz;//threshold } else { thjz = atjz * val + btjz; } - sigmoidla (val, thjz, sigmjz);//sigmz "slope" of sigmoid - + + sigmoidla(val, thjz, sigmjz); //sigmz "slope" of sigmoid + Jz = LIM01((double) bljz * Jz + (double) val); } - if(Qtoj == true) {//lightness instead of brightness + if (Qtoj == true) { //lightness instead of brightness Jz /= to_one; Jz /= maxjzw;//Jz white Jz = SQR(Jz); } - //contrast - Jz= LIM01(jz_contrast.getVal(LIM01(Jz))); + + //contrast + Jz = LIM01(jz_contrast.getVal(LIM01(Jz))); + //brightness and lightness - if(lightreal > 0) { + if (lightreal > 0) { Jz = LIM01(jz_light.getVal(Jz)); } - if(lightreal < 0) { + + if (lightreal < 0) { Jz = LIM01(jz_lightn.getVal(Jz)); } + //Jz (Jz) curve double Jzold = Jz; - if(jzlocalcurve && localjzutili) { - Jz = (double) (jzlocalcurve[(float) Jz * 65535.f] / 65535.f); + + if (jzlocalcurve && localjzutili) { + Jz = (double)(jzlocalcurve[(float) Jz * 65535.f] / 65535.f); Jz = 0.3 * (Jz - Jzold) + Jzold; } + //reconvert from lightness or Brightness - if(Qtoj == false) { + if (Qtoj == false) { Jz /= to_one; } else { Jz = sqrt(Jz); @@ -3407,54 +3919,65 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } double Hz; - //remapping Cz - Hz = xatan2 ( bz, az ); + //remapping Cz + Hz = xatan2(bz, az); double Czold = Cz; + //Cz(Cz) curve - if(czlocalcurve && localczutili) { - Cz = (double) (czlocalcurve[(float) Cz * 92666.f * (float) to_one] / (92666.f * (float) to_one)); + if (czlocalcurve && localczutili) { + Cz = (double)(czlocalcurve[(float) Cz * 92666.f * (float) to_one] / (92666.f * (float) to_one)); Cz = 0.5 * (Cz - Czold) + Czold; } + //Cz(Jz) curve - if(czjzlocalcurve && localczjzutili) { - double chromaCfactor = (double) (czjzlocalcurve[(float) Jz * 65535.f * (float) to_one]) / (Jz * 65535. * to_one); + if (czjzlocalcurve && localczjzutili) { + double chromaCfactor = (double)(czjzlocalcurve[(float) Jz * 65535.f * (float) to_one]) / (Jz * 65535. * to_one); Cz *= chromaCfactor; } + //Hz in 0 2*PI - if ( Hz < 0.0 ) { - Hz += (2. * rtengine::RT_PI); + if (Hz < 0.0) { + Hz += (2. * rtengine::RT_PI); } + //Chroma slider - if(chromz < 0.) { + if (chromz < 0.) { Cz = Cz * (1. + 0.01 * chromz); } else { double maxcz = czlim / to_one; double fcz = Cz / maxcz; - double pocz = pow(fcz , 1. - 0.0024 * chromz);//increase value - before 0.0017 + double pocz = pow(fcz, 1. - 0.0024 * chromz); //increase value - before 0.0017 Cz = maxcz * pocz; - // Cz = Cz * (1. + 0.005 * chromz);//linear + // Cz = Cz * (1. + 0.005 * chromz);//linear } + //saturation slider - if(saturz != 0.) { - double js = Jz/ maxjzw;//divide by Jz white + if (saturz != 0.) { + double js = Jz / maxjzw; //divide by Jz white js = SQR(js); - if(js <= 0.) { + + if (js <= 0.) { js = 0.0000001; } + double Sz = Cz / (js); - if(saturz < 0.) { + + if (saturz < 0.) { Sz = Sz * (1. + 0.01 * saturz); } else { Sz = Sz * (1. + 0.003 * saturz);//not pow function because Sz is "open" - 0.003 empirical value to have results comparable to Cz } + Cz = Sz * js; } - + //rotation hue Hz += dhue; - if ( Hz < 0.0 ) { - Hz += (2. * rtengine::RT_PI); + + if (Hz < 0.0) { + Hz += (2. * rtengine::RT_PI); } + Cz = clipcz(Cz); double2 sincosval = xsincos(Hz); az = clipazbz(Cz * sincosval.y); @@ -3466,16 +3989,17 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L az = az / (to_screen); Jz = LIM01(Jz / (to_screen)); - if(jabcie) {//Not used does not work at all + + if (jabcie) { //Not used does not work at all Jz = clipjz05(Jz); - gamutjz (Jz, az, bz, pl, wip, 0.94, 0.004); + gamutjz(Jz, az, bz, pl, wip, 0.94, 0.004); } double L_, M_, S_; double xx, yy, zz; bool zcam = z_cam; //reconvert to XYZ in double - Ciecam02::jzczhzxyz (xx, yy, zz, Jz, az, bz, pl, L_, M_, S_, zcam); + Ciecam02::jzczhzxyz(xx, yy, zz, Jz, az, bz, pl, L_, M_, S_, zcam); //re enable D50 double x, y, z; x = 65535. * (d65_d50[0][0] * xx + d65_d50[0][1] * yy + d65_d50[0][2] * zz); @@ -3490,35 +4014,36 @@ void ImProcFunctions::ciecamloc_02float(const struct local_params& lp, int sp, L } } } - -if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 vibrance warm-cool - call = 10 take into account "mean luminance Yb for Jz + //lp.sursouci==4 disable ciecam + if ((mocam == 1 && lp.sursouci!= 4)|| mocam ==2 || call == 1 || call == 2 || call == 10) { //CAM16 call=2 vibrance warm-cool - call = 10 take into account "mean luminance Yb for Jz //begin ciecam - if (settings->verbose && (mocam == 0 || mocam == 1 || call == 1)) {//display only if choice cam16 - //information on Cam16 scene conditions - allows user to see choices's incidences - float maxicam = -1000.f; - float maxicamq = -1000.f; - float maxisat = -1000.f; - float maxiM = -1000.f; - float minicam = 1000000.f; - float minicamq = 1000000.f; - float minisat = 1000000.f; - float miniM = 1000000.f; - int nccam = 0; - float sumcam = 0.f; - float sumcamq = 0.f; - float sumsat = 0.f; - float sumM = 0.f; - if(lp.logena && !(params->locallab.spots.at(sp).expcie && mocam == 1)) {//Log encoding only, but enable for log encoding if we use Cam16 module both with log encoding - plum = 100.f; - } + if (settings->verbose && (mocam == 1 || call == 1)) {//display only if choice cam16 + //information on Cam16 scene conditions - allows user to see choices's incidences + float maxicamq = -1000.f; + float maxicamj = -1000.f; + float maxisat = -1000.f; + float maxiM = -1000.f; + float minicam = 1000000.f; + float minicamq = 1000000.f; + float minisat = 1000000.f; + float miniM = 1000000.f; + int nccam = 0; + float sumcam = 0.f; + float sumcamq = 0.f; + float sumsat = 0.f; + float sumM = 0.f; + if (lp.logena && !(params->locallab.spots.at(sp).expcie && mocam == 1)) { //Log encoding only, but enable for log encoding if we use Cam16 module both with log encoding + plum = 100.f; + } - + //find main values Cam16 #ifdef _OPENMP - #pragma omp parallel for reduction(min:minicam) reduction(max:maxicam) reduction(min:minicamq) reduction(max:maxicamq) reduction(min:minisat) reduction(max:maxisat) reduction(min:miniM) reduction(max:maxiM) reduction(+:sumcam) reduction(+:sumcamq) reduction(+:sumsat) reduction(+:sumM)if(multiThread) + #pragma omp parallel for reduction(min:minicam) reduction(max:maxicamj) reduction(min:minicamq) reduction(max:maxicamq) reduction(min:minisat) reduction(max:maxisat) reduction(min:miniM) reduction(max:maxiM) reduction(+:sumcam) reduction(+:sumcamq) reduction(+:sumsat) reduction(+:sumM)if(multiThread) #endif - for (int i = 0; i < height; i+=1) { - for (int k = 0; k < width; k+=1) { + + for (int i = 0; i < height; i += 1) { + for (int k = 0; k < width; k += 1) { float L = lab->L[i][k]; float a = lab->a[i][k]; float b = lab->b[i][k]; @@ -3530,87 +4055,156 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 z = z / 655.35f; float J, C, h, Q, M, s; Ciecam02::xyz2jchqms_ciecam02float(J, C, h, - Q, M, s, aw, fl, wh, - x, y, z, - xw1, yw1, zw1, - c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); - if(J > maxicam) { - maxicam = J; + Q, M, s, aw, fl, wh, + x, y, z, + xw1, yw1, zw1, + c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); + + if (J > maxicamj) { + maxicamj = J; } - if(J < minicam) { + + if (J < minicam) { minicam = J; } + sumcam += J; - if(Q > maxicamq) { + if (Q > maxicamq) { maxicamq = Q; } - if(Q < minicamq) { + + if (Q < minicamq) { minicamq = Q; } + sumcamq += Q; - if(s > maxisat) { + if (s > maxisat) { maxisat = s; } - if(s < minisat) { + + if (s < minisat) { minisat = s; } + sumsat += s; - if(M > maxiM) { + if (M > maxiM) { maxiM = M; } - if(M < miniM) { + + if (M < miniM) { miniM = M; } - sumM += M; + sumM += M; + } + } + + nccam = height * width; + sumcam = sumcam / nccam; + sumcamq /= nccam; + sumsat /= nccam; + sumM /= nccam; + + if (settings->verbose) { + printf("Cam16 Scene Lighness_J Brightness_Q- HDR-PQ=%5.1f minJ=%3.1f maxJ=%3.1f meanJ=%3.1f minQ=%3.1f maxQ=%4.1f meanQ=%4.1f meanQ1=%2.3f\n", (double) plum, (double) minicam, (double) maxicamj, (double) sumcam, (double) minicamq, (double) maxicamq, (double) sumcamq, (double) (sumcamq * coefq)); + printf("Cam16 Scene Saturati-s Colorfulln_M- minSat=%3.1f maxSat=%3.1f meanSat=%3.1f minM=%3.1f maxM=%3.1f meanM=%3.1f\n", (double) minisat, (double) maxisat, (double) sumsat, (double) miniM, (double) maxiM, (double) sumM); + } + // maxicam = maxicamq;//maximum Brightness + if(sumcamq < maxicamq) { + // maxicam = sumcamq + 0.2f * minicamq;//maximum Brightness take into account + maxicam = sumcamq;//maximum Brightness take into account + //ponderate maxicam with mean and mini + } else { + maxicam = 0.4f * sumcamq + 0.6f * maxicamq; + } + sumcamq01 = sumcamq * coefq; + + } + + float base = 10.f; + float linbaseor = 10.f; + float linbase = 10.f; + float gray = 15.f; + + const bool compr = params->locallab.spots.at(sp).comprcie > 0.; + float comprfactor = params->locallab.spots.at(sp).comprcie; + float comprth = 1.f; //0.1 + params->locallab.spots.at(sp).comprcieth; + + double drref = 8.5; //Dynamic Range standard + + double drd = ((double) dynamic_range - drref) / drref; + + double dratt = (double) dynamic_range / drref; + comprfactor = 0.4f * comprfactor * (float) dratt;//adapt comprfactor to Dynamic Range + float newgray = 0.18f; + + if ((params->locallab.spots.at(sp).logcie && params->locallab.spots.at(sp).logcieq) || mobwev != 0) {//increase Dyn Range when log encoding + dynamic_range += 0.2;//empirical value + gray = 0.01f * (float) params->locallab.spots.at(sp).sourceGraycie; + const float targetgraycie = params->locallab.spots.at(sp).targetGraycie; + float targetgraycor = 0.01f * targetgraycie; + base = targetgraycie > 1.f && targetgraycie < 100.f && (float) dynamic_range > 0.f ? find_gray(std::abs((float) shadows_range) / (float) dynamic_range, (targetgraycor)) : 0.f; + linbaseor = std::max(base, 2.f);//2. minimal base log to avoid very bad results + + float maxQgray = coefq * maxicam / gray; + maxicam = maxQgray;//setting threshold comprcieth + const float log2 = xlogf(2.f); + + float corlog = xlogf(maxicam)/log2;//correction base logarithme + linbase = linbaseor / corlog; + newgray = gray; //gray - 0.022f * (6.f - maxicam);//empirical formula to take into account Q in DR. 6.f =>approach to mean overall images + + if (settings->verbose) { + printf("Gray=%1.3f newgray=%1.3f MaxicamQ=%3.2f Base log encode corrected Q=%5.1f Base log encode origig Q=%5.1f\n", (double) gray, (double) newgray, (double) maxicam, (double) linbase, (double) linbaseor); + } + + } + + const auto applytoq = + [ = ](float x) -> float { + + x = rtengine::max(x, (float) noise); + x = rtengine::max(x / newgray, (float) noise);//gray = gain - before log conversion + + if (compr && x >= comprth)//comprth = maxicam + { + x = intp(comprfactor, (std::tanh((x - comprth) / comprth) + 1.f) * comprth, x); //as sigmoid... but tanh (tg hyperbolic), inspired by the work of alberto Grigio + } + + x = rtengine::max((xlogf(x) / log2f - (float) shadows_range) / (float) dynamic_range, (float) noise);//x in range EV + assert(x == x); + + if (linbase > 0.f)//apply log base in function of targetgray blackEvjz and Dynamic Range + { + x = xlog2lin(x, linbase); + } + + return x; + }; + + //prepare Normalize luminance + float *datain = nullptr; + float *data = nullptr; + float *datanorm = nullptr; + + if ((sigmoidnorm && issigq) || params->locallab.spots.at(sp).logcieq) { + datain = new float[width* height]; + data = new float[width * height]; + datanorm = new float[width * height]; +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + datain[(y) * width + (x)] = lab->L[y][x]; + } } } - nccam = height * width; - sumcam = sumcam / nccam; - sumcamq /= nccam; - sumsat /= nccam; - sumM /= nccam; - printf("Cam16 Scene Lighness_J Brightness_Q- HDR-PQ=%5.1f minJ=%3.1f maxJ=%3.1f meanJ=%3.1f minQ=%3.1f maxQ=%4.1f meanQ=%4.1f\n", (double) plum, (double) minicam, (double) maxicam, (double) sumcam, (double) minicamq, (double) maxicamq, (double) sumcamq); - printf("Cam16 Scene Saturati-s Colorfulln_M- minSat=%3.1f maxSat=%3.1f meanSat=%3.1f minM=%3.1f maxM=%3.1f meanM=%3.1f\n", (double) minisat, (double) maxisat, (double) sumsat, (double) miniM, (double) maxiM, (double) sumM); -} - - float base = 10.; - float linbase = 10.; - float gray = 15.; - if(islogq) {//with brightness Jz - gray = 0.01f * (float) params->locallab.spots.at(sp).sourceGraycie; - gray = pow_F(gray, 1.2f);//or 1.15 => modification to increase sensitivity gain, only on defaults, of course we can change this value manually...take into account suuround and Yb Cam16 - const float targetgraycie = params->locallab.spots.at(sp).targetGraycie; - float targetgraycor = pow_F(0.01f * targetgraycie, 1.15f); - base = targetgraycie > 1.f && targetgraycie < 100.f && (float) dynamic_range > 0.f ? find_gray(std::abs((float) shadows_range) / (float) dynamic_range,(targetgraycor)) : 0.f; - linbase = std::max(base, 2.f);//2. minimal base log to avoid very bad results - if (settings->verbose) { - printf("Base logarithm encoding Q=%5.1f\n", (double) linbase); - } - } - - const auto applytoq = - [ = ](float x) -> float { - - x = rtengine::max(x, (float) noise); - x = rtengine::max(x / gray, (float) noise);//gray = gain - before log conversion - x = rtengine::max((xlogf(x) / log2f - (float) shadows_range) / (float) dynamic_range, (float) noise);//x in range EV - assert(x == x); - - if (linbase > 0.f)//apply log base in function of targetgray blackEvjz and Dynamic Range - { - x = xlog2lin(x, linbase); - } - return x; - }; - - - -//Ciecam "old" code not change except sigmoid added #ifdef __SSE2__ int bufferLength = ((width + 3) / 4) * 4; // bufferLength has to be a multiple of 4 #endif @@ -3628,11 +4222,12 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 float sbuffer[bufferLength] ALIGNED16; #endif #ifdef _OPENMP - #pragma omp for schedule(dynamic, 16) + #pragma omp for schedule(dynamic, 16) #endif + for (int i = 0; i < height; i++) { #ifdef __SSE2__ - // vectorized conversion from Lab to jchqms + // vectorized conversion from Lab to jchqms int k; vfloat c655d35 = F2V(655.35f); @@ -3644,10 +4239,10 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 z = z / c655d35; vfloat J, C, h, Q, M, s; Ciecam02::xyz2jchqms_ciecam02float(J, C, h, - Q, M, s, F2V(aw), F2V(fl), F2V(wh), - x, y, z, - F2V(xw1), F2V(yw1), F2V(zw1), - F2V(c), F2V(nc), F2V(pow1), F2V(nbb), F2V(ncb), F2V(pfl), F2V(cz), F2V(d), c16, F2V(plum)); + Q, M, s, F2V(aw), F2V(fl), F2V(wh), + x, y, z, + F2V(xw1), F2V(yw1), F2V(zw1), + F2V(c), F2V(nc), F2V(pow1), F2V(nbb), F2V(ncb), F2V(pfl), F2V(cz), F2V(d), c16, F2V(plum)); STVF(Jbuffer[k], J); STVF(Cbuffer[k], C); STVF(hbuffer[k], h); @@ -3668,10 +4263,10 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 z = z / 655.35f; float J, C, h, Q, M, s; Ciecam02::xyz2jchqms_ciecam02float(J, C, h, - Q, M, s, aw, fl, wh, - x, y, z, - xw1, yw1, zw1, - c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); + Q, M, s, aw, fl, wh, + x, y, z, + xw1, yw1, zw1, + c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); Jbuffer[k] = J; Cbuffer[k] = C; hbuffer[k] = h; @@ -3686,7 +4281,7 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 float J, C, h, Q, M, s; #ifdef __SSE2__ - // use precomputed values from above + // use precomputed values from above J = Jbuffer[j]; C = Cbuffer[j]; h = hbuffer[j]; @@ -3706,10 +4301,10 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 z = z1 / 655.35f; //process source==> normal Ciecam02::xyz2jchqms_ciecam02float(J, C, h, - Q, M, s, aw, fl, wh, - x, y, z, - xw1, yw1, zw1, - c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); + Q, M, s, aw, fl, wh, + x, y, z, + xw1, yw1, zw1, + c, nc, pow1, nbb, ncb, pfl, cz, d, c16, plum); #endif float Jpro, Cpro, hpro, Qpro, Mpro, spro; Jpro = J; @@ -3718,50 +4313,58 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 Qpro = Q; Mpro = M; spro = s; - /* - */ - if(ciec) { + + if (ciec && mocam == 1) {//only Cam16 bool jp = false; - if ((cielocalcurve && localcieutili) && mecamcurve == 1) { + + if (params->locallab.spots.at(sp).logcie && params->locallab.spots.at(sp).logcieq && iscie) {//log encoding Q + float val = Qpro * coefq; + + if (val > (float) noise) { + float mm = applytoq(val); + float f = mm / val; + Qpro *= f; + } + } + // if (issig && issigq && iscie && !islogq && mobwev != 2) { //sigmoid Q only and black Ev & white Ev + if (issig && issigq && iscie && mobwev != 2) { //sigmoid Q only and black Ev & white Ev + float val = Qpro * coefq; + + if (mobwev == 1) { + val = std::max((xlog(val) / log2 - shadows_range) / (dynamic_range + 1.5), noise);//in range EV + } + + float sigreal = sigmoidth * sumcamq01;//correction for sigmoid Q take into account mean Q + + if (sigreal >= 1.f) { + th = (sigreal - 1.f) * val + 1.f; + } else { + th = (1.f - sigreal) * val + sigreal; + } + + sigmoidla(val, th, sigm); + Qpro = std::max(Qpro + val / coefq, 0.f); + Qpro = CAMBrightCurveQsig[(float)(Qpro * coefQ)] / coefQ; //brightness and contrast + + Jpro = SQR((10.f * Qpro) / wh); + + } + + if ((cielocalcurve && localcieutili) && mecamcurve == 1) {//curve Q jp = true; float Qq = Qpro * coefQ; float Qold = Qpro; Qq = 0.5f * cielocalcurve[Qq * 2.f]; Qq = Qq / coefQ; Qpro = 0.2f * (Qq - Qold) + Qold; - if(jp) { + + if (jp) { Jpro = SQR((10.f * Qpro) / wh); } } Qpro = CAMBrightCurveQ[(float)(Qpro * coefQ)] / coefQ; //brightness and contrast - if(islogq && issigq) { - float val = Qpro * coefq;; - if (val > (float) noise) { - float mm = applytoq(val); - float f = mm / val; - Qpro *= f; - } - } - - - if(issigq && iscie && !islogq) {//sigmoid Q only with ciecam module - float val = Qpro * coefq; - if(sigmoidqj == true) { - val = std::max((xlog(val) / log2 - shadows_range) / (dynamic_range + 1.5), noise);//in range EV - } - if(sigmoidth >= 1.f) { - th = ath * val + bth; - } else { - th = at * val + bt; - } - sigmoidla (val, th, sigm); - float bl2 = 1.f; - Qpro = std::max(bl * Qpro + bl2 * val / coefq, 0.f); - } - - float Mp, sres; Mp = Mpro / 100.0f; Ciecam02::curvecolorfloat(mchr, Mp, sres, 2.5f); @@ -3775,7 +4378,7 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 spro = 100.0f * sqrtf(Mpro / Qpro); if (Jpro > 99.9f) { - Jpro = 99.9f; + Jpro = 99.9f; } Jpro = CAMBrightCurveJ[(float)(Jpro * 327.68f)]; //lightness CIECAM02 + contrast @@ -3791,14 +4394,14 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 Cpro = Cp * 100.f; Ciecam02::curvecolorfloat(cchr, Cp, sres, 1.8f); Color::skinredfloat(Jpro, hpro, sres, Cp, 55.f, 30.f, 1, rstprotection, 100.f, Cpro); - + hpro = hpro + hue; if (hpro < 0.0f) { hpro += 360.0f; //hue } - - if ((cielocalcurve && localcieutili) && mecamcurve == 0) { + + if ((cielocalcurve && localcieutili) && mecamcurve == 0) {//curve J float Jj = (float) Jpro * 327.68f; float Jold = Jj; Jj = 0.5f * cielocalcurve[Jj * 2.f]; @@ -3809,8 +4412,9 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 Jpro = 1.f; } } - if (cielocalcurve2 && localcieutili2) { - if(mecamcurve2 == 0) { + + if (cielocalcurve2 && localcieutili2) {//chroma saturation colorfullness + if (mecamcurve2 == 0) {//chroma float parsat = 0.8f; //0.68; float coef = 327.68f / parsat; float Cc = (float) Cpro * coef; @@ -3821,7 +4425,7 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 int sk1 = 1; float ko = 1.f / coef; Color::skinredfloat(Jpro, hpro, Cc, Ccold, dred, protect_red, sk1, rstprotection, ko, Cpro); - } else if (mecamcurve2 == 1) { + } else if (mecamcurve2 == 1) {//saturation float parsat = 0.8f; //0.6 float coef = 327.68f / parsat; float Ss = (float) spro * coef; @@ -3836,7 +4440,7 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 Color::skinredfloat(Jpro, hpro, Ss, Sold, dred, protect_red, 0, rstprotection, ko, spro); Qpro = (4.0f / c) * sqrtf(Jpro / 100.0f) * (aw + 4.0f) ; Cpro = (spro * spro * Qpro) / (10000.0f); - } else if (mecamcurve2 == 2) { + } else if (mecamcurve2 == 2) {//colorfullness float parsat = 0.8f; //0.68; float coef = 327.68f / parsat; float Mm = (float) Mpro * coef; @@ -3851,7 +4455,6 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 Cpro = Mpro / coe; } } - } //retrieve values C,J...s @@ -3872,9 +4475,9 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 //process normal==> viewing Ciecam02::jch2xyz_ciecam02float(xx, yy, zz, - J, C, h, - xw2, yw2, zw2, - c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); + J, C, h, + xw2, yw2, zw2, + c2, nc2, pow1n, nbbj, ncbj, flj, czj, dj, awj, c16, plum); x = CLIP(xx * 655.35f); y = CLIP(yy * 655.35f); z = CLIP(zz * 655.35f); @@ -3896,9 +4499,9 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 for (k = 0; k < bufferLength; k += 4) { vfloat x, y, z; Ciecam02::jch2xyz_ciecam02float(x, y, z, - LVF(Jbuffer[k]), LVF(Cbuffer[k]), LVF(hbuffer[k]), - F2V(xw2), F2V(yw2), F2V(zw2), - F2V(nc2), F2V(pow1n), F2V(nbbj), F2V(ncbj), F2V(flj), F2V(dj), F2V(awj), F2V(reccmcz), c16, F2V(plum)); + LVF(Jbuffer[k]), LVF(Cbuffer[k]), LVF(hbuffer[k]), + F2V(xw2), F2V(yw2), F2V(zw2), + F2V(nc2), F2V(pow1n), F2V(nbbj), F2V(ncbj), F2V(flj), F2V(dj), F2V(awj), F2V(reccmcz), c16, F2V(plum)); STVF(xbuffer[k], x * c655d35); STVF(ybuffer[k], y * c655d35); STVF(zbuffer[k], z * c655d35); @@ -3912,7 +4515,7 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 xbuffer[j] = CLIP(xbuffer[j]); ybuffer[j] = CLIP(ybuffer[j]); zbuffer[j] = CLIP(zbuffer[j]); - + Color::XYZ2Lab(xbuffer[j], ybuffer[j], zbuffer[j], Ll, aa, bb); lab->L[i][j] = Ll; @@ -3922,303 +4525,54 @@ if(mocam == 0 || mocam == 1 || call == 1 || call == 2 || call == 10) {//call=2 #endif } - } - } - -if(mocam == 3) {//Zcam not use but keep in case off -/* - double miniiz = 1000.; - double maxiiz = -1000.; - double sumiz = 0.; - int nciz = 0; - double epsilzcam = 0.0001; - double atten = 2700.; - double epsilzcam2 = 1.; - if(mocam == 3) {//Zcam - double pl = params->locallab.spots.at(sp).pqremap; -//calculate min, max, mean for Jz + + if ((mocam == 1 && (sigmoidnorm && issigq)) || params->locallab.spots.at(sp).logcieq) { //Normalize luminance + #ifdef _OPENMP - #pragma omp parallel for reduction(min:miniiz) reduction(max:maxiiz) reduction(+:sumiz) if(multiThread) + #pragma omp parallel for schedule(dynamic, 16) #endif - for (int i = 0; i < height; i+=1) { - for (int k = 0; k < width; k+=1) { - float L = lab->L[i][k]; - float a = lab->a[i][k]; - float b = lab->b[i][k]; - float x, y, z; - //convert Lab => XYZ - Color::Lab2XYZ(L, a, b, x, y, z); - x = x / 65535.f; - y = y / 65535.f; - z = z / 65535.f; - double Jz, az, bz; - double xx, yy, zz; - //D50 ==> D65 - xx = (d50_d65[0][0] * (double) x + d50_d65[0][1] * (double) y + d50_d65[0][2] * (double) z); - yy = (d50_d65[1][0] * (double) x + d50_d65[1][1] * (double) y + d50_d65[1][2] * (double) z); - zz = (d50_d65[2][0] * (double) x + d50_d65[2][1] * (double) y + d50_d65[2][2] * (double) z); - xx = LIM01(xx); - yy = LIM01(yy); - zz = LIM01(zz); - - double L_p, M_p, S_p; - bool zcam = true; - Ciecam02::xyz2jzczhz (Jz, az, bz, xx, yy, zz, pl, L_p, M_p, S_p, zcam); - if(Jz > maxiiz) { - maxiiz = Jz; - } - if(Jz < miniiz) { - miniiz = Jz; - } - sumiz += Jz; + for (int y = 0; y < height; y++) { //data after ciecam + for (int x = 0; x < width; x++) { + data[(y) * width + (x)] = lab->L[y][x]; + datanorm[(y) * width + (x)] = lab->L[y][x]; + } } - } - nciz = height * width; - sumiz = sumiz / nciz; - sumiz += epsilzcam; - maxiiz += epsilzcam; - if (settings->verbose) { - printf("Zcam miniiz=%f maxiiz=%f meaniz=%f\n", miniiz, maxiiz, sumiz); - } - } - double avgmz = sumiz; - //calculate various parameter for Zcam - those with ** come from documentation Zcam - // ZCAM, a colour appearance model based on a high dynamic range uniform colour space - //Muhammad Safdar, Jon Yngve Hardeberg, and Ming Ronnier Luo - // https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-29-4-6036&id=447640#e12 - double L_p, M_p, S_p; - double jzw, azw, bzw; - bool zcam = true; - double plz = params->locallab.spots.at(sp).pqremap;// to test or change to 10000 -// double po = 0.1 + params->locallab.spots.at(sp).contthreszcam; - float fb_source = sqrt(yb / 100.f); - float fb_dest = sqrt(yb2 / 100.f); - double flz = 0.171 * pow(la, 0.3333333)*(1. - exp(-(48. * (double) la / 9.))); - double fljz = 0.171 * pow(la2, 0.3333333)*(1. - exp(-(48. * (double) la2 / 9.))); - double cpow = 2.2;//empirical - double cpp = pow( (double) c, 0.5);//empirical - double cpp2 = pow( (double) c2, 0.5);//empirical - double pfl = pow(flz, 0.25); - double cmul_source = 1.26;//empirical - double cmul_source_ch = 1.1;//empirical - double achro_source = pow((double) c, cpow)*(pow((double) flz, - 0.004)* (double) sqrt(fb_source));//I think there is an error in formula documentation step 5 - all parameters are inversed or wrong - double achro_dest = pow((double) c2, cpow)*(pow((double) fljz, - 0.004) * (double) sqrt(fb_dest)); - double kk_source = (1.6 * (double) cpp) / pow((double) fb_source, 0.12); - double ikk_dest = pow((double) fb_dest, 0.12) /(1.6 * (double) cpp2); - Ciecam02::xyz2jzczhz (jzw, azw, bzw, Xw, Yw, Zw, plz, L_p, M_p, S_p, zcam); - double eff = 1.; - double kap = 2.7; - if(maxiiz > (kap * sumiz)) { - kap = 1.7; - } - double qzw = cmul_source * atten * pow(jzw, (double) kk_source) / achro_source;//I think there is an error in formula documentation step 5 - all parameters are inversed - double maxforq = kap * sumiz * eff + epsilzcam2; - if(maxforq > maxiiz) { - maxforq = maxiiz; - } else { - maxforq = 0.9 * maxforq + 0.1 * maxiiz; - } - double qzmax = cmul_source * atten * pow(maxforq, (double) kk_source) / achro_source; - double izw = jzw; - double coefm = pow(flz, 0.2) / (pow((double) fb_source, 0.1) * pow(izw, 0.78)); - if (settings->verbose) { - printf("qzw=%f PL=%f qzmax=%f\n", qzw, plz, qzmax);//huge change with PQ peak luminance - } - array2D Iiz(width, height); - array2D Aaz(width, height); - array2D Bbz(width, height); -//curve to replace LUT , LUT leads to crash... - double contqz = 0.5 * params->locallab.spots.at(sp).contqzcam; - DiagonalCurve qz_contrast({ - DCT_NURBS, - 0, 0, - avgmz - avgmz * (0.6 - contqz / 250.0), avgmz - avgmz * (0.6 + contqz / 250.0), - avgmz + (1. - avgmz) * (0.6 - contqz / 250.0), avgmz + (1. - avgmz) * (0.6 + contqz / 250.0), - 1, 1 - }); - double contlz = 0.6 * params->locallab.spots.at(sp).contlzcam; - DiagonalCurve ljz_contrast({ - DCT_NURBS, - 0, 0, - avgmz - avgmz * (0.6 - contlz / 250.0), avgmz - avgmz * (0.6 + contlz / 250.0), - avgmz + (1. - avgmz) * (0.6 - contlz / 250.0), avgmz + (1. - avgmz) * (0.6 + contlz / 250.0), - 1, 1 - }); - - //all calculations in double for best results...but slow - double lqz = 0.4 * params->locallab.spots.at(sp).lightqzcam; - if(params->locallab.spots.at(sp).lightqzcam < 0) { - lqz = 0.2 * params->locallab.spots.at(sp).lightqzcam; //0.4 less effect, no need 1. - } - DiagonalCurve qz_light({ - DCT_NURBS, - 0, 0, - 0.1, 0.1 + lqz / 150., - 0.7, min (1.0, 0.7 + lqz / 300.0), - 1, 1 - }); - DiagonalCurve qz_lightn({ - DCT_NURBS, - 0, 0, - max(0.0, 0.1 - lqz / 150.), 0.1 , - 0.7 - lqz / 300.0, 0.7, - 1, 1 - }); - double ljz = 0.4 * params->locallab.spots.at(sp).lightlzcam; - if(params->locallab.spots.at(sp).lightlzcam < 0) { - ljz = 0.2 * params->locallab.spots.at(sp).lightlzcam; - } - DiagonalCurve ljz_light({ - DCT_NURBS, - 0, 0, - 0.1, 0.1 + ljz / 150., - 0.7, min (1.0, 0.7 + ljz / 300.0), - 1, 1 - }); - DiagonalCurve ljz_lightn({ - DCT_NURBS, - 0, 0, - max(0.0, 0.1 - ljz / 150.), 0.1 , - 0.7 - ljz / 300.0, 0.7, - 1, 1 - }); + double nbs = 1.; + drd = std::max(drd, 1.); + if (bl > 0.5f) { + nbs = (1.7 * (double) bl * drd);//take into account DR to increase variance in image source + } + if(!params->locallab.spots.at(sp).logcieq) {// not with log encoding Q + normalize_mean_dt(datanorm, datain, height * width, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, nbs);//normalize luminance + } #ifdef _OPENMP - #pragma omp parallel for if(multiThread) + #pragma omp parallel for schedule(dynamic, 16) #endif - for (int i = 0; i < height; i++) { - for (int k = 0; k < width; k++) { - float L = lab->L[i][k]; - float a = lab->a[i][k]; - float b = lab->b[i][k]; - float x, y, z; - //convert Lab => XYZ - Color::Lab2XYZ(L, a, b, x, y, z); - x = x / 65535.f; - y = y / 65535.f; - z = z / 65535.f; - double iz, az, bz; - double xx, yy, zz; - //change WP to D65 - xx = (d50_d65[0][0] * (double) x + d50_d65[0][1] * (double) y + d50_d65[0][2] * (double) z); - yy = (d50_d65[1][0] * (double) x + d50_d65[1][1] * (double) y + d50_d65[1][2] * (double) z); - zz = (d50_d65[2][0] * (double) x + d50_d65[2][1] * (double) y + d50_d65[2][2] * (double) z); - double L_p, M_p, S_p; - bool zcam = true; - Ciecam02::xyz2jzczhz (iz, az, bz, xx, yy, zz, plz, L_p, M_p, S_p, zcam); - Iiz[i][k] = LIM01(iz); - Aaz[i][k] = clipazbz(az); - Bbz[i][k] = clipazbz(bz); + + for (int ir = 0; ir < height; ir++) { + for (int jr = 0; jr < width; jr++) { + if(!params->locallab.spots.at(sp).logcieq) {// if not Log encoding ciecam + data[ir * width + jr] = intp(bl, data[ir * width + jr], datanorm[ir * width + jr]);//blend with original + } else { + data[ir * width + jr] = intp(bl, data[ir * width + jr], datain[ir * width + jr]);//blend with original + } + lab->L[ir][jr] = data[ir * width + jr]; + } } } -#ifdef _OPENMP - #pragma omp parallel for if(multiThread) -#endif - for (int i = 0; i < height; i++) { - for (int k = 0; k < width; k++) { - double az = Aaz[i][k]; - double bz = Bbz[i][k]; - double iz = Iiz[i][k]; - if(iz > kap * sumiz) { - iz = kap * sumiz * eff; - } - float coefqz = (float) qzmax; - float coefjz = 100.f ; - double qz = cmul_source * atten * pow(iz, (double) kk_source) / achro_source;//partial - az *= cmul_source_ch; - bz *= cmul_source_ch; - - qz= (double) coefqz * LIM01(qz_contrast.getVal((float)qz / coefqz)); + delete [] datain; + delete [] data; + delete [] datanorm; + } - if(lqz > 0) { - qz = (double) coefqz * LIM01(qz_light.getVal((float)qz / coefqz)); - } - if(lqz < 0) { - qz = (double) coefqz * LIM01(qz_lightn.getVal((float)qz / coefqz)); - } - // double jz = 100. * (qz / qzw); - double jz = SQR((10. * qz) / qzw);//formula CAM16 - jz= (double) coefjz * LIM01(ljz_contrast.getVal((float)jz / coefjz)); - if(ljz > 0) { - jz = (double) coefjz * LIM01(ljz_light.getVal((float)jz / coefjz)); - } - if(ljz < 0) { - jz = (double) coefjz * LIM01(ljz_lightn.getVal((float)jz / coefjz)); - } - if(jz > 100.) jz = 99.; - - - //qzpro = 0.01 * jzpro * qzw; - double qzpro = 0.1 * sqrt(jz) * qzw; - iz = LIM01(pow(qzpro / (atten / achro_dest), ikk_dest)); - double h = atan2(bz, az); - if ( h < 0.0 ) { - h += (double) (2.f * rtengine::RT_PI_F); - } - double hp = h * (360 / (double) (2.f * rtengine::RT_PI_F)); - double ez = 1.015 + cos(89.038 + hp); - if(mchrz != 0.f || schrz != 0.f || cchrz != 0.f){ - //colorfullness - double Mpz = 100. * pow(az * az + bz * bz, 0.37)* pow(ez, 0.068) * coefm; - Mpz *= (double) (1.f + 0.01f * mchrz); - float ccz = sqrt(pow((float) (Mpz / (100. * pow(ez, 0.068) * coefm)), (1.f / 0.37f))); - float2 sincosval = xsincosf(h); - az = (double)(ccz * sincosval.y); - bz = (double)(ccz * sincosval.x); - if(schrz != 0.f){ - //saturation - double Spz = 100. * pow(flz, 0.6) * (Mpz / qz); - Spz *= (double) (1.f + 0.01f * schrz); - Mpz = (Spz * qz) / (100.* pow(flz, 0.6)); - ccz = sqrt(pow((float) (Mpz / (100. * pow(ez, 0.068) * coefm)), (1.f / 0.37f))); - az = (double)(ccz * sincosval.y); - bz = (double)(ccz * sincosval.x); - } - if(cchrz != 0.f){ - // double Cpz = 100. * (Mpz / qzw); - double Cpz = 100. * (Mpz / pfl);//Cam16 formula - Cpz *= (double) (1.f + 0.01f * cchrz); - Mpz = (Cpz * pfl) / 100.; - // double Vpz = sqrt(SQR(jz - 58.) + 3.4 * SQR(Cpz));//vividness not working - // Vpz *= (double) (1.f + 0.01f * cchrz); - //Mpz = (Cpz * qzw) / 100.; - // Mpz = 0.01 * qzw * sqrt((SQR(Vpz) - SQR(jz - 58.)) / 3.4); - ccz = sqrt(pow((float) (Mpz / (100. * pow(ez, 0.068) * coefm)), (1.f / 0.37f))); - az = (double)(ccz * sincosval.y); - bz = (double)(ccz * sincosval.x); - } - - } - double L_, M_, S_; - double xx, yy, zz; - bool zcam = true; - iz=LIM01(iz); - az=clipazbz(az); - bz=clipazbz(bz); - - Ciecam02::jzczhzxyz (xx, yy, zz, iz, az, bz, plz, L_, M_, S_, zcam); - //re enable D50 - double x, y, z; - x = 65535. * (d65_d50[0][0] * xx + d65_d50[0][1] * yy + d65_d50[0][2] * zz); - y = 65535. * (d65_d50[1][0] * xx + d65_d50[1][1] * yy + d65_d50[1][2] * zz); - z = 65535. * (d65_d50[2][0] * xx + d65_d50[2][1] * yy + d65_d50[2][2] * zz); - float Ll, aa, bb; - Color::XYZ2Lab(x, y, z, Ll, aa, bb); - lab->L[i][k] = Ll; - lab->a[i][k] = aa; - lab->b[i][k] = bb; - } - } -*/ -} - } void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, float epsilmax, float epsilmin, float thres, int sk, bool multiThread, int flag) @@ -4226,11 +4580,13 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco if (rad != 0.f) { array2D ble(bfw, bfh); array2D guid(bfw, bfh); + if (flag == 0) { #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { guid[ir][jr] = Color::L2Y(bufcolorig->L[ir][jr]) / 32768.f; @@ -4240,7 +4596,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco const float aepsil = (epsilmax - epsilmin) / 100.f; const float bepsil = epsilmin; //epsilmax - 100.f * aepsil; - // const float epsil = aepsil * 0.1f * rad + bepsil; + // const float epsil = aepsil * 0.1f * rad + bepsil; const float epsil = aepsil * rad + bepsil; const float blur = 10.f / sk * (thres + 0.f * rad); @@ -4249,6 +4605,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufcolfin->L[ir][jr] = Color::computeXYZ2LabY(32768.f * ble[ir][jr]); @@ -4259,6 +4616,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { ble[ir][jr] = bufcolfin->L[ir][jr] / 32768.f; @@ -4276,6 +4634,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufcolfin->L[ir][jr] = 32768.f * ble[ir][jr]; @@ -4286,6 +4645,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { ble[ir][jr] = bufcolfin->L[ir][jr] / 32768.f; @@ -4295,7 +4655,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco const float aepsil = (epsilmax - epsilmin) / 1000.f; const float bepsil = epsilmin; //epsilmax - 100.f * aepsil; const float epsil = rad < 0.f ? 0.0001f : aepsil * 10.f * rad + bepsil; - // const float epsil = bepsil; + // const float epsil = bepsil; const float blur = rad < 0.f ? -1.f / rad : 0.00001f + rad; const int r2 = rtengine::max(int(20.f / sk * blur + 0.000001f), 1); @@ -4304,6 +4664,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufcolfin->L[ir][jr] = 32768.f * ble[ir][jr]; @@ -4321,6 +4682,7 @@ void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &bu #ifdef _OPENMP #pragma omp parallel for reduction(min:minlig) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { minlig = rtengine::min(buflight[ir][jr], minlig); @@ -4332,6 +4694,7 @@ void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &bu #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { buflight[ir][jr] = LIM01((buflight[ir][jr] - minlig) / (100.f - minlig)); @@ -4349,6 +4712,7 @@ void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &bu #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { buflight[ir][jr] = (100.f - minlig) * buflight[ir][jr] + minlig; @@ -4362,26 +4726,30 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf //exposure local constexpr float maxran = 65536.f; - if(lp.laplacexp == 0.f) { + + if (lp.laplacexp == 0.f) { lp.linear = 0.f; } const float linear = lp.linear; int bw = bfw; int bh = bfh; + if (linear > 0.f && lp.expcomp == 0.f) { lp.expcomp = 0.001f; } + const bool exec = (lp.expmet == 1 && linear > 0.f && lp.laplacexp > 0.1f); - if(!exec) {//for standard exposure - + if (!exec) { //for standard exposure + const float cexp_scale = std::pow(2.f, lp.expcomp); const float ccomp = (rtengine::max(0.f, lp.expcomp) + 1.f) * lp.hlcomp / 100.f; const float cshoulder = ((maxran / rtengine::max(1.0f, cexp_scale)) * (lp.hlcompthr / 200.f)) + 0.1f; const float chlrange = maxran - cshoulder; const float diffde = 100.f - lp.sensex;//the more scope, the less take into account dE for Laplace - if(!lp.invex) {// Laplacian not in inverse + + if (!lp.invex) { // Laplacian not in inverse bw = bfwr; bh = bfhr; @@ -4398,6 +4766,7 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf float bb = blap - 30.f * aa; float lap; + if (diffde > 80.f) { lap = alap; } else if (diffde < 30.f) { @@ -4407,8 +4776,9 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf } #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { datain[y * bfwr + x] = bufexporig->L[y][x]; @@ -4418,20 +4788,22 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf MyMutex::MyLock lock(*fftwMutex); ImProcFunctions::retinex_pde(datain.get(), dataout.get(), bfwr, bfhr, lap, 1.f, dE.get(), 0, 1, 1);//350 arbitrary value about 45% strength Laplacian #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { bufexporig->L[y][x] = dataout[y * bfwr + x]; } } - + } - + #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif - for (int ir = 0; ir < bh; ir++) {//for standard with Laplacian in normal and without in inverse + + for (int ir = 0; ir < bh; ir++) {//for standard with Laplacian in normal and without in inverse for (int jr = 0; jr < bw; jr++) { float L = bufexporig->L[ir][jr]; //highlight @@ -4443,7 +4815,7 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf lab->L[ir][jr] = 0.5f * tonecurve[2 * L]; } } - } else if(!lp.invex) {//for PDE algorithms + } else if (!lp.invex) { //for PDE algorithms constexpr float kl = 1.f; const float hlcompthr = lp.hlcompthr / 200.f; const float hlcomp = lp.hlcomp / 100.f; @@ -4451,6 +4823,7 @@ void ImProcFunctions::exlabLocal(local_params& lp, float strlap, int bfh, int bf #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { float L = bufexporig->L[ir][jr]; @@ -4493,6 +4866,7 @@ void ImProcFunctions::addGaNoise(LabImage *lab, LabImage *dst, const float mean, #ifdef _OPENMP #pragma omp for schedule(static) // static scheduling is important to avoid artefacts #endif + for (int y = 0; y < lab->H; y++) { for (int x = 0; x < lab->W; x++) { generate = !generate; @@ -4605,6 +4979,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { const int loy = cy + y; const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing @@ -4619,7 +4994,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -4639,6 +5014,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab reducdEa = SQR(calcreducdE(dEa, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensden)); reducdEb = SQR(calcreducdE(dEb, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensden)); } + float difL, difa, difb; if (call == 2 /*|| call == 1 || call == 3 */) { //simpleprocess @@ -4697,8 +5073,8 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or const int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); const int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); const int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); - - + + lumaref *= 327.68f; const float ach = lp.trans / 100.f; @@ -4742,8 +5118,8 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or } } - // const int begx = lp.xc - lp.lxL; - // const int begy = lp.yc - lp.lyT; +// const int begx = lp.xc - lp.lxL; +// const int begy = lp.yc - lp.lyT; constexpr float r327d68 = 1.f / 327.68f; #ifdef _OPENMP @@ -4766,7 +5142,7 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or // if (isZone0) { // outside selection and outside transition zone => no effect, keep original values // continue; - // } +// } for (int x = xstart, lox = cx + x; x < xend; x++, lox++) { int zone; @@ -4798,13 +5174,13 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or float difL, difa, difb; const float repart = 1.0f - 0.01f * lp.reparden; - tmp1.L[y-ystart][x-xstart] = intp(repart, original->L[y][x], tmp1.L[y-ystart][x-xstart]); - tmp1.a[y-ystart][x-xstart] = intp(repart, original->a[y][x], tmp1.a[y-ystart][x-xstart]); - tmp1.b[y-ystart][x-xstart] = intp(repart, original->b[y][x], tmp1.b[y-ystart][x-xstart]); - - difL = tmp1.L[y-ystart][x-xstart] - original->L[y][x]; - difa = tmp1.a[y-ystart][x-xstart] - original->a[y][x]; - difb = tmp1.b[y-ystart][x-xstart] - original->b[y][x]; + tmp1.L[y - ystart][x - xstart] = intp(repart, original->L[y][x], tmp1.L[y - ystart][x - xstart]); + tmp1.a[y - ystart][x - xstart] = intp(repart, original->a[y][x], tmp1.a[y - ystart][x - xstart]); + tmp1.b[y - ystart][x - xstart] = intp(repart, original->b[y][x], tmp1.b[y - ystart][x - xstart]); + + difL = tmp1.L[y - ystart][x - xstart] - original->L[y][x]; + difa = tmp1.a[y - ystart][x - xstart] - original->a[y][x]; + difb = tmp1.b[y - ystart][x - xstart] - original->b[y][x]; difL *= localFactor * reducdEL; difa *= localFactor * reducdEa; @@ -4876,6 +5252,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { int loy = cy + y; @@ -4887,7 +5264,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -4909,6 +5286,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl transformed->a[y][x] = clipC(original->a[y][x] + difa * reducdE); transformed->b[y][x] = clipC(original->b[y][x] + difb * reducdE); } + break; } @@ -4931,6 +5309,7 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl transformed->a[y][x] = clipC(original->a[y][x] + difa * reducdE); transformed->b[y][x] = clipC(original->b[y][x] + difb * reducdE); } + break; } @@ -5016,6 +5395,7 @@ void ImProcFunctions::InverseBlurNoise_Local(LabImage * originalmask, const stru #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { int loy = cy + y; @@ -5030,7 +5410,9 @@ void ImProcFunctions::InverseBlurNoise_Local(LabImage * originalmask, const stru } else { calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } - float reducdE; + + float reducdE; + if (zone != 2) { float abdelta2 = SQR(refa - maskptr->a[y][x]) + SQR(refb - maskptr->b[y][x]); float chrodelta2 = SQR(std::sqrt(SQR(maskptr->a[y][x]) + SQR(maskptr->b[y][x])) - (chromaref * 327.68f)); @@ -5042,12 +5424,12 @@ void ImProcFunctions::InverseBlurNoise_Local(LabImage * originalmask, const stru switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition - const float diflc = (tmp1->L[y][x] - original->L[y][x]) * reducdE; - const float difa = (tmp1->a[y][x] - original->a[y][x]) * reducdE; - const float difb = (tmp1->b[y][x] - original->b[y][x]) * reducdE; - transformed->L[y][x] = CLIP(original->L[y][x] + diflc); - transformed->a[y][x] = clipC(original->a[y][x] + difa) ; - transformed->b[y][x] = clipC(original->b[y][x] + difb); + const float diflc = (tmp1->L[y][x] - original->L[y][x]) * reducdE; + const float difa = (tmp1->a[y][x] - original->a[y][x]) * reducdE; + const float difb = (tmp1->b[y][x] - original->b[y][x]) * reducdE; + transformed->L[y][x] = CLIP(original->L[y][x] + diflc); + transformed->a[y][x] = clipC(original->a[y][x] + difa) ; + transformed->b[y][x] = clipC(original->b[y][x] + difb); if (blshow) { transformed->L[y][x] = CLIP(12000.f + diflc); @@ -5105,24 +5487,26 @@ static void mean_fab(int xstart, int ystart, int bfw, int bfh, LabImage* bufexpo if (nbfab > 0) { double sumab = 0.0; -#ifdef _OPENMP +#ifdef _OPENMP #pragma omp parallel for reduction(+:sumab) if(multiThread) #else static_cast(multiThread); #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { - if(flag == 0) { + if (flag == 0) { bufexporig->a[y][x] = original->a[y + ystart][x + xstart]; bufexporig->b[y][x] = original->b[y + ystart][x + xstart]; } else { bufexporig->a[y][x] = original->a[y][x]; bufexporig->b[y][x] = original->b[y][x]; } + sumab += static_cast(SQR(std::fabs(bufexporig->a[y][x])) + SQR(std::fabs(bufexporig->b[y][x]))); - - // sumab += static_cast(std::fabs(bufexporig->a[y][x])); - // sumab += static_cast(std::fabs(bufexporig->b[y][x])); + + // sumab += static_cast(std::fabs(bufexporig->a[y][x])); + // sumab += static_cast(std::fabs(bufexporig->b[y][x])); } } @@ -5133,12 +5517,14 @@ static void mean_fab(int xstart, int ystart, int bfw, int bfh, LabImage* bufexpo #ifdef _OPENMP #pragma omp parallel for reduction(+:som) reduction(max:maxfab)if(multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { som += static_cast(SQR(std::fabs(bufexporig->a[y][x]) - meanfab) + SQR(std::fabs(bufexporig->b[y][x]) - meanfab)); maxm = static_cast(SQR(std::fabs(bufexporig->a[y][x])) + SQR(std::fabs(bufexporig->b[y][x]))); maxm = sqrt(maxm); - if(maxm > (double) maxfab) { + + if (maxm > (double) maxfab) { maxfab = (float) maxm; } @@ -5151,10 +5537,12 @@ static void mean_fab(int xstart, int ystart, int bfw, int bfh, LabImage* bufexpo const float stddv = std::sqrt(som / nbfab); float fabprov = meanfab + multsigma * stddv * multchrom;//with 3 sigma about 99% cases - if(fabprov > maxfab) { + + if (fabprov > maxfab) { fabprov = maxfab; } - fab = max(fabprov, 0.90f* maxfab);//Find maxi between mean + 3 sigma and 90% max (90 arbitrary empirical value) + + fab = max(fabprov, 0.90f * maxfab); //Find maxi between mean + 3 sigma and 90% max (90 arbitrary empirical value) if (fab <= 0.f) { fab = 50.f; @@ -5233,6 +5621,9 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& } else if (indic == 12) { stops = -lp.str_mas; angs = lp.ang_mas; + } else if (indic == 15) { + stops = lp.strgradcie; + angs = lp.anggradcie; } @@ -5331,6 +5722,7 @@ void ImProcFunctions::blendstruc(int bfw, int bfh, LabImage* bufcolorig, float r #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { float X, Y, Z; @@ -5352,6 +5744,7 @@ void ImProcFunctions::blendstruc(int bfw, int bfh, LabImage* bufcolorig, float r #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { blend2[ir][jr] = 32768.f * ble[ir][jr]; @@ -5366,6 +5759,7 @@ static void blendmask(const local_params& lp, int xstart, int ystart, int cx, in #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int y = 0; y < bfh ; y++) { const int loy = y + ystart + cy; @@ -5378,7 +5772,7 @@ static void blendmask(const local_params& lp, int xstart, int ystart, int cx, in if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -5463,6 +5857,7 @@ void ImProcFunctions::deltaEforMask(float **rdE, int bfw, int bfh, LabImage* buf #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { const float abdelta2 = SQR(refa - bufcolorig->a[y][x] / 327.68f) + SQR(refb - bufcolorig->b[y][x] / 327.68f); @@ -5471,6 +5866,7 @@ void ImProcFunctions::deltaEforMask(float **rdE, int bfw, int bfh, LabImage* buf const float tempdE = std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - bufcolorig->L[y][x] / 327.68f)); float reducdE; + if (tempdE > maxdE) { reducdE = 0.f; } else if (tempdE > mindE && tempdE <= maxdE) { @@ -5505,7 +5901,8 @@ static void showmask(int lumask, const local_params& lp, int xstart, int ystart, { float lum = fabs(lumask * 400.f); float colo = 0.f; - if(lumask < 0.f) { + + if (lumask < 0.f) { lum *= 1.4f; colo = 30000.f + 12.f * lum; } @@ -5513,6 +5910,7 @@ static void showmask(int lumask, const local_params& lp, int xstart, int ystart, #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int y = 0; y < bfh; y++) { const int loy = y + ystart + cy; @@ -5524,7 +5922,7 @@ static void showmask(int lumask, const local_params& lp, int xstart, int ystart, if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -5552,33 +5950,32 @@ void ImProcFunctions::laplacian(const array2D &src, array2D &dst, const int H = bfh; const auto X = - [W](int x) -> int - { - return x < 0 ? x+2 : (x >= W ? x-2 : x); - }; + [W](int x) -> int { + return x < 0 ? x + 2 : (x >= W ? x - 2 : x); + }; const auto Y = - [H](int y) -> int - { - return y < 0 ? y+2 : (y >= H ? y-2 : y); - }; + [H](int y) -> int { + return y < 0 ? y + 2 : (y >= H ? y - 2 : y); + }; const auto get = - [&src](int y, int x) -> float - { - return std::max(src[y][x], 0.f); - }; + [&src](int y, int x) -> float { + return std::max(src[y][x], 0.f); + }; dst(W, H); const float f = factor / ceiling; #ifdef _OPENMP -# pragma omp parallel for if (multiThread) + # pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H; ++y) { - int n = Y(y-1), s = Y(y+1); + int n = Y(y - 1), s = Y(y + 1); + for (int x = 0; x < W; ++x) { - int w = X(x-1), e = X(x+1); + int w = X(x - 1), e = X(x + 1); float v = -8.f * get(y, x) + get(n, x) + get(s, x) + get(y, w) + get(y, e) + get(n, w) + get(n, e) + get(s, w) + get(s, e); dst[y][x] = LIM(std::abs(v) - threshold, 0.f, ceiling) * f; } @@ -5590,7 +5987,7 @@ void ImProcFunctions::laplacian(const array2D &src, array2D &dst, void ImProcFunctions::discrete_laplacian_threshold(float * data_out, const float * data_in, size_t nx, size_t ny, float t) { - // BENCHFUN + // BENCHFUN if (!data_in || !data_out) { fprintf(stderr, "a pointer is NULL and should not be so\n"); @@ -5608,11 +6005,14 @@ void ImProcFunctions::discrete_laplacian_threshold(float * data_out, const float #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (size_t j = 0; j < ny; j++) { const float* ptr_in = &data_in[j * nx]; float* ptr_out = &data_out[j * nx]; + for (size_t i = 0; i < nx; i++) { float val = 0.f; + /* row differences */ if (0 < i) { const float diff = ptr_in[i] - ptr_in[i - 1]; @@ -5677,7 +6077,7 @@ void ImProcFunctions::rex_poisson_dct(float * data, size_t nx, size_t ny, double * @author Nicolas Limare * some adaptations for Rawtherapee */ - // BENCHFUN + // BENCHFUN /* * get the cosinus tables @@ -5702,11 +6102,13 @@ void ImProcFunctions::rex_poisson_dct(float * data, size_t nx, size_t ny, double #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (size_t i = 0; i < ny; ++i) { for (size_t j = 0; j < nx; ++j) { data[i * nx + j] *= m2 / (cosx[j] + cosy[i]); } } + // handle the first value, data[0, 0] = 0 data[0] = 0.f; @@ -5715,7 +6117,7 @@ void ImProcFunctions::rex_poisson_dct(float * data, size_t nx, size_t ny, double } -void ImProcFunctions::mean_dt(const float* data, size_t size, double& mean_p, double& dt_p) +void ImProcFunctions::mean_dt(const float* data, int size, double& mean_p, double& dt_p, double nbstd) { double mean = 0.; @@ -5724,7 +6126,8 @@ void ImProcFunctions::mean_dt(const float* data, size_t size, double& mean_p, do #ifdef _OPENMP #pragma omp parallel for reduction(+:mean,dt) if(multiThread) #endif - for (size_t i = 0; i < size; i++) { + + for (int i = 0; i < size; i++) { mean += static_cast(data[i]); dt += static_cast(SQR(data[i])); } @@ -5733,10 +6136,10 @@ void ImProcFunctions::mean_dt(const float* data, size_t size, double& mean_p, do dt /= size; dt -= SQR(mean); mean_p = mean; - dt_p = std::sqrt(dt); + dt_p = nbstd * std::sqrt(dt); } -void ImProcFunctions::normalize_mean_dt(float * data, const float * ref, size_t size, float mod, float sigm, float mdef, float sdef, float mdef2, float sdef2) +void ImProcFunctions::normalize_mean_dt(float * data, const float * ref, int size, float mod, float sigm, float mdef, float sdef, float mdef2, float sdef2, double nbstd) { /* * Copyright 2009-2011 IPOL Image Processing On Line http://www.ipol.im/ @@ -5757,18 +6160,18 @@ void ImProcFunctions::normalize_mean_dt(float * data, const float * ref, size_t double mean_ref, mean_data, dt_ref, dt_data; /* compute mean and variance of the two arrays */ - if(mdef!= 0.f && sdef != 0.f) { + if (mdef != 0.f && sdef != 0.f) { mean_ref = mdef; dt_ref = sdef; } else { - mean_dt(ref, size, mean_ref, dt_ref); + mean_dt(ref, size, mean_ref, dt_ref, nbstd); } - if(mdef2!= 0.f && sdef2 != 0.f) { - // printf("OK shortcut\n"); + + if (mdef2 != 0.f && sdef2 != 0.f) { mean_data = mdef2; dt_data = sdef2; } else { - mean_dt(data, size, mean_data, dt_data); + mean_dt(data, size, mean_data, dt_data, 1.0); } /* compute the normalization coefficients */ @@ -5783,7 +6186,8 @@ void ImProcFunctions::normalize_mean_dt(float * data, const float * ref, size_t #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif - for (size_t i = 0; i < size; i++) { + + for (int i = 0; i < size; i++) { data[i] = (modma * data[i] + sigmmmodmb) + onesmod * ref[i];//normalize mean and stdv and balance PDE } @@ -5802,18 +6206,21 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw * adapted for Rawtherapee by Jacques Desmis 6-2019 */ - // BENCHFUN - + // BENCHFUN + #ifdef RT_FFTW3F_OMP if (multiThread) { fftwf_init_threads(); fftwf_plan_with_nthreads(omp_get_max_threads()); } + #endif float *datashow = nullptr; + if (show != 0) { datashow = (float *) fftwf_malloc(sizeof(float) * bfw * bfh); + if (!datashow) { fprintf(stderr, "allocation error\n"); abort(); @@ -5821,6 +6228,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw } float *data_tmp = (float *) fftwf_malloc(sizeof(float) * bfw * bfh); + if (!data_tmp) { fprintf(stderr, "allocation error\n"); abort(); @@ -5830,6 +6238,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw discrete_laplacian_threshold(data_tmp, datain, bfw, bfh, thresh); float *data_fft = (float *) fftwf_malloc(sizeof(float) * bfw * bfh); + if (!data_fft) { fprintf(stderr, "allocation error\n"); abort(); @@ -5852,10 +6261,12 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw if (dEenable == 1) { float* data_fft04 = (float *)fftwf_malloc(sizeof(float) * bfw * bfh); float* data_tmp04 = (float *)fftwf_malloc(sizeof(float) * bfw * bfh); + if (!data_fft04 || !data_tmp04) { fprintf(stderr, "allocation error\n"); abort(); } + //second call to laplacian with 40% strength ==> reduce effect if we are far from ref (deltaE) discrete_laplacian_threshold(data_tmp04, datain, bfw, bfh, 0.4f * thresh); const auto dct_fw04 = fftwf_plan_r2r_2d(bfh, bfw, data_tmp04, data_fft04, FFTW_REDFT10, FFTW_REDFT10, FFTW_ESTIMATE | FFTW_DESTROY_INPUT); @@ -5873,13 +6284,17 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw #ifdef _OPENMP #pragma omp for #endif + for (int y = 0; y < bfh ; y++) {//mix two fftw Laplacian : plein if dE near ref int x = 0; #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(data_fft[y * bfw + x], intp(pow_F(LVFU(dE[y * bfw + x]), exponentv), LVFU(data_fft[y * bfw + x]), LVFU(data_fft04[y * bfw + x]))); } + #endif + for (; x < bfw; x++) { data_fft[y * bfw + x] = intp(pow_F(dE[y * bfw + x], exponent), data_fft[y * bfw + x], data_fft04[y * bfw + x]); } @@ -5888,6 +6303,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw fftwf_free(data_fft04); fftwf_free(data_tmp04); } + if (show == 2) { for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { @@ -5914,7 +6330,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw fftwf_free(data_fft); if (show != 4 && normalize == 1) { - normalize_mean_dt(data_tmp, datain, bfw * bfh, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f); + normalize_mean_dt(data_tmp, datain, bfw * bfh, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); } if (show == 0 || show == 4) { @@ -5922,6 +6338,7 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { dataout[y * bfw + x] = clipLoc(multy * data_tmp[y * bfw + x]); @@ -5936,15 +6353,19 @@ void ImProcFunctions::retinex_pde(const float * datain, float * dataout, int bfw } fftwf_free(data_tmp); + if (datashow) { fftwf_free(datashow); } + fftwf_cleanup(); #ifdef RT_FFTW3F_OMP + if (multiThread) { fftwf_cleanup_threads(); } + #endif } @@ -5974,14 +6395,16 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int mean_fab(xstart, ystart, bfw, bfh, bufcolorig, 0, original, fab, meanfab, maxfab, chrom, multiThread); corfab = 0.7f * (65535.f) / (fab + epsi);//empirical values 0.7 link to chromult - // printf("Fab=%f corfab=%f maxfab=%f\n", (double) fab, (double) corfab, (double) maxfab); + // printf("Fab=%f corfab=%f maxfab=%f\n", (double) fab, (double) corfab, (double) maxfab); float chromult = 1.f; - if(chrom > 0.f){ + + if (chrom > 0.f) { chromult = 1.f + 0.003f * chrom; } else { chromult = 1.f + 0.01f * chrom; } - // chromult * corfab * kmaskC + + // chromult * corfab * kmaskC float kinv = 1.f; float kneg = 1.f; @@ -5994,6 +6417,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufmaskblurcol->L[y][x] = original->L[y + ystart][x + xstart]; @@ -6050,7 +6474,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int if (rm > 0) { float **mb = blendblur; #ifdef _OPENMP - #pragma omp parallel if (multiThread) + #pragma omp parallel if (multiThread) #endif { gaussianBlur(mb, mb, bfw, bfh, rm); @@ -6060,7 +6484,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int if (blu_ma >= 0.25f) { if (!fftt) { // || (lp.fftColorMask && call != 2)) { #ifdef _OPENMP - #pragma omp parallel if (multiThread) + #pragma omp parallel if (multiThread) #endif { gaussianBlur(bufcolorig->L, blur, bfw, bfh, blu_ma / sk); @@ -6095,16 +6519,19 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int tmpab.clear(true); #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { tmpab.L[ir][jr] = bufcolorig->L[ir][jr]; tmpab.a[ir][jr] = bufcolorig->a[ir][jr]; tmpab.b[ir][jr] = bufcolorig->b[ir][jr]; - } + } + float noisevarab_r = SQR(lp.denoichmask / 10.f); - if(noisevarab_r > 0.f) { + + if (noisevarab_r > 0.f) { int wavelet_leve = 6; int minwin1 = rtengine::min(bfw, bfh); @@ -6123,11 +6550,11 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #endif - wavelet_decomposition Ldecomp(tmpab.L[0],tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); - wavelet_decomposition adecomp(tmpab.a[0],tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); - wavelet_decomposition bdecomp(tmpab.b[0],tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); + wavelet_decomposition Ldecomp(tmpab.L[0], tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); + wavelet_decomposition adecomp(tmpab.a[0], tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); + wavelet_decomposition bdecomp(tmpab.b[0], tmpab.W, tmpab.H, maxlvl1, 1, sk, numThreads, lp.daubLen); float* noisevarchrom; - noisevarchrom = new float[bfw*bfh]; + noisevarchrom = new float[bfw * bfh]; float nvch = 0.6f;//high value float nvcl = 0.1f;//low value float seuil = 4000.f;//low @@ -6136,10 +6563,11 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int float ac = (nvch - nvcl) / (seuil - seuil2); float bc = nvch - seuil * ac; int bfw2 = (bfw + 1) / 2; - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float cN = std::sqrt(SQR(tmpab.a[ir][jr]) + SQR(tmpab.b[ir][jr])); @@ -6152,13 +6580,15 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int noisevarchrom[(ir >> 1)*bfw2 + (jr >> 1)] = nvcl; } } - + float madL[8][3]; int levred = maxlvl1; + if (!Ldecomp.memory_allocation_failed()) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif + for (int lvl = 0; lvl < levred; lvl++) { for (int dir = 1; dir < 4; dir++) { int Wlvl_L = Ldecomp.level_W(lvl); @@ -6169,34 +6599,37 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int } } } - - if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { - WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, true, false, false, numThreads); - WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, true, false, false, numThreads); - WaveletDenoiseAll_BiShrinkAB(Ldecomp, bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, false, false, false, numThreads); - WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, false, false, false, numThreads); + if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { + WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, true, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, true, false, false, numThreads); + + WaveletDenoiseAll_BiShrinkAB(Ldecomp, bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, false, false, false, numThreads); + WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, false, false, false, numThreads); } - + delete[] noisevarchrom; if (!Ldecomp.memory_allocation_failed()) { Ldecomp.reconstruct(tmpab.L[0]); } + if (!adecomp.memory_allocation_failed()) { adecomp.reconstruct(tmpab.a[0]); } + if (!bdecomp.memory_allocation_failed()) { bdecomp.reconstruct(tmpab.b[0]); } - + float meanfab1, fab1, maxfab1; std::unique_ptr buforig; buforig.reset(new LabImage(bfw, bfh)); #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { buforig->L[ir][jr] = tmpab.L[ir][jr]; @@ -6204,12 +6637,13 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int buforig->b[ir][jr] = tmpab.b[ir][jr]; } - + mean_fab(xstart, ystart, bfw, bfh, buforig.get(), 1, buforig.get(), fab1, meanfab1, maxfab1, chrom, multiThread); - // printf("Fab den=%f \n", (double) fab1); + // printf("Fab den=%f \n", (double) fab1); fab = fab1;//fab denoise - + } + // end code denoise mask chroma @@ -6226,6 +6660,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp for schedule(dynamic, 16) #endif + for (int ir = 0; ir < bfh; ir++) { #ifdef __SSE2__ @@ -6233,12 +6668,12 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int int i = 0; for (; i < bfw - 3; i += 4) { - // STVF(atan2Buffer[i], xatan2f(LVFU(bufcolorig->b[ir][i]), LVFU(bufcolorig->a[ir][i]))); + // STVF(atan2Buffer[i], xatan2f(LVFU(bufcolorig->b[ir][i]), LVFU(bufcolorig->a[ir][i]))); STVF(atan2Buffer[i], xatan2f(LVFU(tmpab.b[ir][i]), LVFU(tmpab.a[ir][i]))); } for (; i < bfw; i++) { - // atan2Buffer[i] = xatan2f(bufcolorig->b[ir][i], bufcolorig->a[ir][i]); + // atan2Buffer[i] = xatan2f(bufcolorig->b[ir][i], bufcolorig->a[ir][i]); atan2Buffer[i] = xatan2f(tmpab.b[ir][i], tmpab.a[ir][i]); } } @@ -6268,13 +6703,13 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int } if (locllmasCurve && llmasutili) { - // printf("s"); + // printf("s"); kmaskL = 32768.f * LIM01(kinv - kneg * locllmasCurve[(500.f / 32768.f) * bufcolorig->L[ir][jr]]); } if (!deltaE && locccmasCurve && lcmasutili) { - // kmaskC = LIM01(kinv - kneg * locccmasCurve[500.f * (0.0001f + std::sqrt(SQR(bufcolorig->a[ir][jr]) + SQR(bufcolorig->b[ir][jr])) / (fab))]); + // kmaskC = LIM01(kinv - kneg * locccmasCurve[500.f * (0.0001f + std::sqrt(SQR(bufcolorig->a[ir][jr]) + SQR(bufcolorig->b[ir][jr])) / (fab))]); kmaskC = LIM01(kinv - kneg * locccmasCurve[500.f * (0.0001f + std::sqrt(SQR(tmpab.a[ir][jr]) + SQR(tmpab.b[ir][jr])) / fab)]); } @@ -6282,7 +6717,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef __SSE2__ const float huema = atan2Buffer[jr]; #else - // const float huema = xatan2f(bufcolorig->b[ir][jr], bufcolorig->a[ir][jr]); + // const float huema = xatan2f(bufcolorig->b[ir][jr], bufcolorig->a[ir][jr]); const float huema = xatan2f(tmpab.b[ir][jr], tmpab.a[ir][jr]); #endif float h = Color::huelab_to_huehsv2(huema); @@ -6319,27 +6754,31 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int } } } - + if (lap > 0.f && pde) { array2D mask; mask(bfw, bfh); - float amount = LIM01(float(lap)/100.f); + float amount = LIM01(float(lap) / 100.f); array2D LL(bfw, bfh, bufcolorig->L, ARRAY2D_BYREFERENCE); laplacian(LL, mask, bfw, bfh, 25.f, 20000.f, amount, false); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { mask[i][j] = LIM01(mask[i][j]); } } + for (int i = 0; i < 3; ++i) { boxblur(static_cast(mask), static_cast(mask), 5 / sk, bfw, bfh, false); } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { bufmaskblurcol->L[i][j] += clipLoc(100000.f * (mask[i][j]));//increase strongly result @@ -6348,6 +6787,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int } std::unique_ptr bufprov; + if (delt) { bufprov.reset(new LabImage(bfw, bfh)); bufprov->CopyFrom(bufmaskblurcol, multiThread); @@ -6375,6 +6815,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { float2 sincosval = xsincosf(hue[ir][jr]); @@ -6389,6 +6830,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufmaskblurcol->L[ir][jr] *= (1.f + blendstru[ir][jr]); @@ -6400,6 +6842,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { bufmaskblurcol->L[ir][jr] = 0.5f * lmasklocalcurve[2.f * bufmaskblurcol->L[ir][jr]]; @@ -6445,9 +6888,11 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #endif wavelet_decomposition *wdspot = new wavelet_decomposition(bufmaskblurcol->L[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen); + if (wdspot->memory_allocation_failed()) { return; } + float mean[10]; float meanN[10]; float sigma[10]; @@ -6457,6 +6902,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int Evaluate2(*wdspot, mean, meanN, sigma, sigmaN, MaxP, MaxN, numThreads); float alow = 1.f; float blow = 0.f; + if (level_hl != level_bl) { alow = 1.f / (level_hl - level_bl); blow = -alow * level_bl; @@ -6469,13 +6915,13 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int ahigh = 1.f / (level_hr - level_br); bhigh = -ahigh * level_br; } - + for (int dir = 1; dir < 4; dir++) { for (int level = level_bl; level < maxlvl; ++level) { int W_L = wdspot->level_W(level); int H_L = wdspot->level_H(level); float* const* wav_L = wdspot->level_coeffs(level); - + if (MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { float insigma = 0.666f; //SD float logmax = log(MaxP[level]); //log Max @@ -6486,12 +6932,13 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int float asig = 0.166f / (sigma[level]); float bsig = 0.5f - asig * mean[level]; float amean = 0.5f / mean[level]; - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < W_L * H_L; i++) { - if(loclmasCurvecolwav && lmasutilicolwav) { + if (loclmasCurvecolwav && lmasutilicolwav) { float absciss; float &val = wav_L[dir][i]; @@ -6507,6 +6954,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int } float klev = 1.f; + if (level >= level_hl && level <= level_hr) { klev = 1.f; } @@ -6522,7 +6970,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int klev = ahigh * level + bhigh; } } - + float kc = klev * (loclmasCurvecolwav[absciss * 500.f] - 0.5f); float amplieffect = kc <= 0.f ? 1.f : 4.f; @@ -6530,14 +6978,14 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int kinterm = kinterm <= 0.f ? 0.01f : kinterm; val *= kinterm; - + } } } - + } } - + wdspot->reconstruct(bufmaskblurcol->L[0], 1.f); delete wdspot; @@ -6547,6 +6995,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float huemah = xatan2f(bufmaskblurcol->b[ir][jr], bufmaskblurcol->a[ir][jr]); @@ -6604,6 +7053,7 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float rdEval = rdE[ir][jr]; @@ -6616,38 +7066,40 @@ void ImProcFunctions::maskcalccol(bool invmask, bool pde, int bfw, int bfh, int struct grad_params gp; - if ((indic == 0 && lp.strmaexp != 0.f) || (indic ==12 && lp.str_mas != 0.f)) { + if ((indic == 0 && lp.strmaexp != 0.f) || (indic == 12 && lp.str_mas != 0.f)) { calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, indic); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufmaskblurcol->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); } } } -/* - if (lap > 0.f) { - const float *datain = bufmaskblurcol->L[0]; - const std::unique_ptr data_tmp(new float[bfh * bfw]); - if (!pde) { - ImProcFunctions::discrete_laplacian_threshold(data_tmp.get(), datain, bfw, bfh, 200.f * lap); - } else { - ImProcFunctions::retinex_pde(datain, data_tmp.get(), bfw, bfh, 12.f * lap, 1.f, nullptr, 0, 0, 1); - } + /* + if (lap > 0.f) { + const float *datain = bufmaskblurcol->L[0]; + const std::unique_ptr data_tmp(new float[bfh * bfw]); -#ifdef _OPENMP - #pragma omp parallel for if (multiThread) -#endif - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - bufmaskblurcol->L[y][x] = data_tmp[y * bfw + x]; + if (!pde) { + ImProcFunctions::discrete_laplacian_threshold(data_tmp.get(), datain, bfw, bfh, 200.f * lap); + } else { + ImProcFunctions::retinex_pde(datain, data_tmp.get(), bfw, bfh, 12.f * lap, 1.f, nullptr, 0, 0, 1); + } + + #ifdef _OPENMP + #pragma omp parallel for if (multiThread) + #endif + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + bufmaskblurcol->L[y][x] = data_tmp[y * bfw + x]; + } + } } - } - } - */ + */ } const float radiusb = 1.f / sk; @@ -6721,6 +7173,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { int loy = cy + y; @@ -6731,7 +7184,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -6794,6 +7247,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co transformed->b[y][x] = 0.f; } } + break; } @@ -6862,6 +7316,7 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { const int loy = cy + y; const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing @@ -6877,7 +7332,7 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -6931,7 +7386,7 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromaref, float lumaref, float sobelref, float meansobel, const struct local_params & lp, const LabImage * original, LabImage * transformed, const LabImage * rsv, const LabImage * reserv, int cx, int cy, int sk) { - // BENCHFUN + // BENCHFUN { const float ach = lp.trans / 100.f; const float varsens = lp.sensexclu; @@ -6976,8 +7431,8 @@ void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromar #pragma omp barrier #pragma omp for schedule(dynamic,16) #endif - for (int y = 0; y < transformed->H; y++) - { + + for (int y = 0; y < transformed->H; y++) { const int loy = cy + y; const bool isZone0 = loy > (lp.yc + lp.ly - 1) || loy < lp.yc - lp.lyT; // // -1 fix issue 5554 @@ -7006,7 +7461,7 @@ void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromar if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -7067,13 +7522,13 @@ void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromar } - - + + void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabImage * bufexporig, LabImage * bufexpfin, LabImage * bufmask, LabImage * buforigmas, float **buflight, float **bufchro, const float hueref, const float chromaref, const float lumaref, struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { - //BENCHFUN + //BENCHFUN { const int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); const int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); @@ -7101,17 +7556,19 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma const float kab = balancedeltaE(lp.balance) / SQR(327.68f); const float kH = lp.balanceh; const float kch = balancedeltaE(kH); + if (lp.colorde == 0) { lp.colorde = -1;//to avoid black } -/* - float ampli = 1.f + std::fabs(lp.colorde); - ampli = 2.f + 0.5f * (ampli - 2.f); - float darklim = 5000.f; - float aadark = -1.f; - float bbdark = darklim; -*/ + /* + float ampli = 1.f + std::fabs(lp.colorde); + ampli = 2.f + 0.5f * (ampli - 2.f); + + float darklim = 5000.f; + float aadark = -1.f; + float bbdark = darklim; + */ const bool showmas = lp.showmaskretimet == 3 ; const std::unique_ptr origblur(new LabImage(GW, GH)); @@ -7146,8 +7603,8 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif - for (int y = ystart; y < yend; y++) - { + + for (int y = ystart; y < yend; y++) { const int loy = cy + y; for (int x = xstart; x < xend; x++) { @@ -7157,7 +7614,7 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -7201,8 +7658,8 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma clc = previewreti ? settings->previewselection * 100.f : bufchro[y - ystart][x - xstart]; } else { cli = buflight[y][x]; - // clc = previewreti ? settings->previewselection * 100.f : bufchro[y][x]; - clc = previewreti ? reducdE * 10000.f * lp.colorde: bufchro[y][x]; + // clc = previewreti ? settings->previewselection * 100.f : bufchro[y][x]; + clc = previewreti ? reducdE * 10000.f * lp.colorde : bufchro[y][x]; } @@ -7289,8 +7746,7 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma } } - if (showmas || retishow || previewreti) - { + if (showmas || retishow || previewreti) { return; } @@ -7301,7 +7757,7 @@ void ImProcFunctions::transit_shapedetect_retinex(int call, int senstype, LabIma void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexporig, LabImage * originalmask, float **bufchro, bool HHutili, const float hueref, const float chromaref, const float lumaref, float sobelref, float meansobel, float ** blend2, const struct local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { - // BENCHFUN + // BENCHFUN const int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); const int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); const int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); @@ -7313,14 +7769,11 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo const float ach = lp.trans / 100.f; float varsens = lp.sensex; - if (senstype == 6 || senstype == 7) //cbdl - { + if (senstype == 6 || senstype == 7) { //cbdl varsens = lp.senscb; - } else if (senstype == 8) //TM - { + } else if (senstype == 8) { //TM varsens = lp.senstm; - } else if (senstype == 10) //local contrast - { + } else if (senstype == 10) { //local contrast varsens = lp.senslc; } @@ -7355,8 +7808,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo const bool usemasktm = (lp.showmasktmmet == 2 || lp.enatmMask || lp.showmasktmmet == 4) && senstype == 8; const bool usemaskall = (usemaskcb || usemasktm); - if (usemaskall) - { + if (usemaskall) { origblurmask.reset(new LabImage(bfw, bfh)); #ifdef _OPENMP @@ -7368,24 +7820,26 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo gaussianBlur(originalmask->b, origblurmask->b, bfw, bfh, radius); } } - if (lp.equtm && senstype == 8) //normalize luminance for Tone mapping , at this place we can use for others senstype! - { + + if (lp.equtm && senstype == 8) { //normalize luminance for Tone mapping , at this place we can use for others senstype! float *datain = new float[bfh * bfw]; float *data = new float[bfh * bfw]; #ifdef _OPENMP #pragma omp parallel if (multiThread) #endif + for (int y = ystart; y < yend; y++) for (int x = xstart; x < xend; x++) { datain[(y - ystart) * bfw + (x - xstart)] = original->L[y][x]; data[(y - ystart)* bfw + (x - xstart)] = bufexporig->L[y - ystart][x - xstart]; } - normalize_mean_dt(data, datain, bfh * bfw, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f); + normalize_mean_dt(data, datain, bfh * bfw, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = ystart; y < yend; y++) for (int x = xstart; x < xend; x++) { bufexporig->L[y - ystart][x - xstart] = data[(y - ystart) * bfw + x - xstart]; @@ -7402,8 +7856,8 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif - for (int y = 0; y < bfh; y++) - { + + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { origblur->L[y][x] = original->L[y + ystart][x + xstart]; origblur->a[y][x] = original->a[y + ystart][x + xstart]; @@ -7434,8 +7888,8 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif - for (int y = ystart; y < yend; y++) - { + + for (int y = ystart; y < yend; y++) { const int loy = cy + y; #ifdef __SSE2__ @@ -7464,7 +7918,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -7593,6 +8047,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H; y++) { for (int x = 0; x < transformed->W; x++) { temp->L[y][x] = original->L[y][x]; @@ -7609,19 +8064,24 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp lab2rgb(*temp, *tmpImage, params->icm.workingProfile); Glib::ustring prof = params->icm.workingProfile; + if (tonecurv) { //Tone response curve : does nothing if gamma=2.4 and slope=12.92 ==> gamma sRGB const float gamtone = params->locallab.spots.at(sp).gamSH; const float slotone = params->locallab.spots.at(sp).sloSH; int ill = 0; cmsHTRANSFORM dummy = nullptr; - workingtrc(tmpImage.get(), tmpImage.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - // workingtrc(tmpImage.get(), tmpImage.get(), GW, GH, 5, prof, gamtone, slotone, illum, 0, dummy, false, true, true);//to keep if we want improve with illuminant and primaries - workingtrc(tmpImage.get(), tmpImage.get(), GW, GH, 1, prof, gamtone, slotone, ill, 0, dummy, false, true, true);//be careful no gamut control + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + workingtrc(0, tmpImage.get(), tmpImage.get(), GW, GH, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly , meanx, meany, meanxe, meanye, dummy, true, false, false, false); + // workingtrc(tmpImage.get(), tmpImage.get(), GW, GH, 5, prof, gamtone, slotone, illum, 0, dummy, false, true, true);//to keep if we want improve with illuminant and primaries + workingtrc(0, tmpImage.get(), tmpImage.get(), GW, GH, 1, prof, gamtone, slotone, 0, ill, 0, locprim, rdx, rdy, grx, gry, blx, bly , meanx, meany, meanxe, meanye, dummy, false, true, true, false);//be careful no gamut control } if (tonequ) { tone_eq(this, tmpImage.get(), lp, params->icm.workingProfile, sk, multiThread); + // tone_eq(tmpImage.get(), lp, params->icm.workingProfile, sk, multiThread); } rgb2lab(*tmpImage, *temp, params->icm.workingProfile); @@ -7634,6 +8094,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < temp->H; y++) { for (int x = 0; x < temp->W; x++) { const float lh = 0.5f * exlocalcurve[2.f * temp->L[y][x]]; // / ((lighn) / 1.9f) / 3.61f; //lh between 0 and 0 50 or more @@ -7662,6 +8123,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H; y++) { for (int x = 0; x < transformed->W; x++) { const float epsi = original->L[y][x] == 0.f ? 0.001f : 0.f; @@ -7676,6 +8138,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H; y++) { for (int x = 0; x < transformed->W; x++) { //same as in "normal" @@ -7694,6 +8157,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H; y++) { for (int x = 0; x < transformed->W; x++) { temp->L[y][x] = 0.5f * lllocalcurve[2.f * original->L[y][x]]; @@ -7760,6 +8224,7 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < transformed->H; y++) { const int loy = cy + y; @@ -7779,12 +8244,13 @@ void ImProcFunctions::InverseColorLight_Local(bool tonequ, bool tonecurv, int sp if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor);//rect not good } //deltaE float reducdE; + if (zone != 2) { const float abdelta2 = SQR(refa - maskptr->a[y][x]) + SQR(refb - maskptr->b[y][x]); const float chrodelta2 = SQR(std::sqrt(SQR(maskptr->a[y][x]) + SQR(maskptr->b[y][x])) - (chromaref * 327.68f)); @@ -7940,7 +8406,7 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform int nsb = 0; // single precision for the result float avA, avB, avL; - int spotSize = 0.88623f * rtengine::max(1, lp.cir / sk); //18 + int spotSize = 0.88623f * rtengine::max(1.f, lp.cir / sk); //18 //O.88623 = std::sqrt(PI / 4) ==> square equal to circle int spotSise2; // = 0.88623f * max (1, lp.cir / sk); //18 @@ -7951,7 +8417,7 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform LabImage *origblur = nullptr; LabImage *blurorig = nullptr; - int spotSi = 1 + 2 * rtengine::max(1, lp.cir / sk); + int spotSi = 1 + 2 * rtengine::max(1.f, lp.cir / sk); if (spotSi < 5) { spotSi = 5; @@ -7970,7 +8436,7 @@ void ImProcFunctions::calc_ref(int sp, LabImage * original, LabImage * transform isdenoise = true; } - if (isdenoise) { + if (isdenoise) { origblur = new LabImage(spotSi, spotSi); blurorig = new LabImage(spotSi, spotSi); @@ -8134,11 +8600,12 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc int ftsizeW = 1; int deltaw = 150; int deltah = 150; - - if(W < 4000) { + + if (W < 4000) { deltaw = 80; } - if(H < 4000) { + + if (H < 4000) { deltah = 80; } @@ -8156,14 +8623,15 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc break; } } - - if(fulima == 2) {// if full image, the ftsizeH and ftsizeW is a bit larger (about 10 to 200 pixels) than the image dimensions so that it is fully processed (consumes a bit more resources) + + if (fulima == 2) { // if full image, the ftsizeH and ftsizeW is a bit larger (about 10 to 200 pixels) than the image dimensions so that it is fully processed (consumes a bit more resources) for (int ftfu = 0; ftfu < N_fftwsize; ftfu++) { //find best values if (fftw_size[ftfu] <= (H + deltah)) { ftsizeH = fftw_size[ftfu]; break; } } + for (int ftfu = 0; ftfu < N_fftwsize; ftfu++) { //find best values if (fftw_size[ftfu] <= (W + deltaw)) { ftsizeW = fftw_size[ftfu]; @@ -8173,7 +8641,7 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc } if (settings->verbose) { - if(fulima == 2) { + if (fulima == 2) { printf("Full image: ftsizeWF=%i ftsizeH=%i\n", ftsizeW, ftsizeH); } else { @@ -8186,6 +8654,7 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc bool reduW = false; bool reduH = false; bool exec = true; + if (ystart == 0 && yend < H) { lp.ly -= (bfh - ftsizeH); } else if (ystart != 0 && yend == H) { @@ -8197,7 +8666,7 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc lp.ly -= (bfh - ftsizeH); } } else if (ystart == 0 && yend == H) { - // bfhr = ftsizeH; + // bfhr = ftsizeH; bfhr = bfh; reduH = true; exec = false; @@ -8214,11 +8683,12 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc lp.lx -= (bfw - ftsizeW); } } else if (xstart == 0 && xend == W) { - // bfwr = ftsizeW; + // bfwr = ftsizeW; bfwr = bfw; reduW = true; exec = false; } + //new values optimized ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, H); @@ -8316,6 +8786,7 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, LabImage * originalmask, c #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = ystart; y < yend; y++) { const int loy = cy + y; @@ -8325,7 +8796,7 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, LabImage * originalmask, c if (lp.shapmet == 0) { calcTransition(lox, loy, ach, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } @@ -8394,14 +8865,6 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in int bfw = xend - xstart; int bfh = yend - ystart; - int bfhr = bfh; - int bfwr = bfw; - if (lp.blurcolmask >= 0.25f && lp.fftColorMask && call == 2) { - optfft(N_fftwsize, bfh, bfw, bfhr, bfwr, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy, lp.fullim); - } - - bfh = bfhr; - bfw = bfwr; //initialize scope float varsens = lp.sensex;//exposure @@ -8424,9 +8887,24 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in varsens = lp.sensilog; } else if (senstype == 20) { //common mask varsens = lp.sensimas; - } else if (senstype == 31) { //ciecam + } else if (senstype == 31) { //ciecam varsens = lp.sensicie; - } + } + int bfhr = bfh; + int bfwr = bfw; + + if (lp.blurcolmask >= 0.25f && lp.fftColorMask && call == 2 && senstype == 0) { + optfft(N_fftwsize, bfh, bfw, bfhr, bfwr, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy, lp.fullim); + } + + if (lp.blurciemask >= 0.25f && lp.fftcieMask && call == 2 && senstype == 31) { + optfft(N_fftwsize, bfh, bfw, bfhr, bfwr, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy, lp.fullim); + } + + bfh = bfhr; + bfw = bfwr; + + bool delt = lp.deltaem; //sobel sobelref /= 100.f; @@ -8453,7 +8931,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const bool origshow = ((lp.showmasksoftmet == 5) && senstype == 3 && lp.softmet == 1); const bool logshow = ((lp.showmasklogmet == 1 || lp.showmasklogmet == 2) && senstype == 11); const bool cieshow = ((lp.showmaskciemet == 1 || lp.showmaskciemet == 2) && senstype == 31); - + const bool masshow = ((lp.showmask_met == 1) && senstype == 20); const bool previewvib = ((lp.showmaskvibmet == 4) && senstype == 2); @@ -8497,9 +8975,11 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in float aadark = -1.f; float bbdark = darklim; bool usemask = true; - if(originalmask == nullptr) { + + if (originalmask == nullptr) { usemask = false; } + const bool usemaskvib = (lp.showmaskvibmet == 2 || lp.enavibMask || lp.showmaskvibmet == 4) && senstype == 2; const bool usemaskexp = (lp.showmaskexpmet == 2 || lp.enaExpMask || lp.showmaskexpmet == 5) && senstype == 1; const bool usemaskcol = (lp.showmaskcolmet == 2 || lp.enaColorMask || lp.showmaskcolmet == 5) && senstype == 0; @@ -8510,6 +8990,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const bool usemasklog = (lp.showmasklogmet == 2 || lp.enaLMask || lp.showmasklogmet == 4) && senstype == 11; const bool usemaskcie = (lp.showmaskciemet == 2 || lp.enacieMask || lp.showmaskciemet == 4) && senstype == 31; const bool usemaskall = usemask && (usemaskexp || usemaskvib || usemaskcol || usemaskSH || usemasktm || usemasklc || usemasklog || usemaskcie || usemaskmas); + //blur a little mask if (usemaskall) { origblurmask.reset(new LabImage(bfw, bfh)); @@ -8533,29 +9014,32 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in #ifdef _OPENMP #pragma omp parallel for #endif + for (int y = ystart; y < yend; y++) for (int x = xstart; x < xend; x++) { datain[(y - ystart) * bfw + (x - xstart)] = original->L[y][x]; data[(y - ystart)* bfw + (x - xstart)] = bufexpfin->L[y - ystart][x - xstart]; } - if(call == 3 || call == 2) {//improccoordinator and simpleprocess - normalize_mean_dt(data, datain, bfw * bfh, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f); - } else if(call == 1) {//dcrop + + if (call == 3 || call == 2) { //improccoordinator and simpleprocess + normalize_mean_dt(data, datain, bfw * bfh, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); + } else if (call == 1) { //dcrop float ma = meantm; float sa = stdtm; - float ma2 = (float) params->locallab.spots.at(sp).noiselumc; + float ma2 = (float) params->locallab.spots.at(sp).noiselumc; float sa2 = (float) params->locallab.spots.at(sp).softradiustm; //printf("ma=%f sa=%f ma2=%f sa2=%f\n", (double) ma, (double) sa, (double) ma2, (double) sa2); //use normalize with mean and stdv - normalize_mean_dt(data, datain, bfw * bfh, 1.f, 1.f, ma, sa, ma2, sa2); + normalize_mean_dt(data, datain, bfw * bfh, 1.f, 1.f, ma, sa, ma2, sa2, 1.); } - - - - + + + + #ifdef _OPENMP #pragma omp parallel for #endif + for (int y = ystart; y < yend; y++) for (int x = xstart; x < xend; x++) { bufexpfin->L[y - ystart][x - xstart] = data[(y - ystart) * bfw + x - xstart]; @@ -8570,14 +9054,14 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const float repart = 1.0f - 0.01f * lp.repartm; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int y = ystart; y < yend; y++){ + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { - bufexpfin->L[y - ystart][x - xstart]= intp(repart, original->L[y][x], bufexpfin->L[y - ystart][x - xstart]); - bufexpfin->a[y - ystart][x - xstart]= intp(repart, original->a[y][x], bufexpfin->a[y - ystart][x - xstart]); - bufexpfin->b[y - ystart][x - xstart]= intp(repart, original->b[y][x], bufexpfin->b[y - ystart][x - xstart]); + bufexpfin->L[y - ystart][x - xstart] = intp(repart, original->L[y][x], bufexpfin->L[y - ystart][x - xstart]); + bufexpfin->a[y - ystart][x - xstart] = intp(repart, original->a[y][x], bufexpfin->a[y - ystart][x - xstart]); + bufexpfin->b[y - ystart][x - xstart] = intp(repart, original->b[y][x], bufexpfin->b[y - ystart][x - xstart]); } } } @@ -8590,6 +9074,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { origblur->L[y][x] = original->L[y + ystart][x + xstart]; @@ -8603,19 +9088,26 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in gaussianBlur(origblur->b, origblur->b, bfw, bfh, radius); } - - + + //choice between original and mask const LabImage *maskptr = usemaskall ? origblurmask.get() : origblur.get(); //parameters deltaE - //increase a bit lp.thr and lp.iterat and kL if HDR only with log encoding and CAM16 Jz - if(senstype == 11 || senstype == 31) { + int limvarsens = 50;//begin change calculation reduction deltaE + if ((senstype == 11 || (senstype == 31 && lp.islogcie)) && (varsens < limvarsens)) { + //increase a bit lp.thr and lp.iterat and kL if HDR only with log encoding and CAM16 Jz lp.thr *= 1.2f; lp.iterat *= 1.2f; - kL *= 1.2f; + kL /= 1.2f; + } else if ((senstype == 11 || (senstype == 31 && lp.islogcie)) && (varsens >= limvarsens)) {//for log encoding and cam16 is log encode used + lp.thr += 10.f;//increase threshold deltaE + lp.thr = LIM(lp.thr, 0.f, 15.0f); + lp.balance -= 2.3f; + lp.balance = LIM(lp.balance, 0.05f, 2.5f); // down balance ab-L + kL = lp.balance / SQR(327.68f); } - + const float mindE = 2.f + MINSCOPE * varsens * lp.thr; const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr); const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; @@ -8632,6 +9124,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < bfh; y++) { const int loy = y + ystart + cy; @@ -8660,7 +9153,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in //calculate transition if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -8701,6 +9194,13 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const float dE = rsob + std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - maskptr->L[y][x])); //reduction action with deltaE float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); + if ((senstype == 11 || ( senstype == 31 && lp.islogcie)) && (varsens >= limvarsens)) { + int maxvarsens = 90;//arbitrary value to get maximum incidence + float ared = (1.f - reducdE) / (maxvarsens - limvarsens); + float bred = 1.f - ared * maxvarsens; + reducdE = ared * varsens + bred; + reducdE = LIM(reducdE, 0.1f, 1.f); + } if(varsens == 100.f) { reducdE = 1.f; } @@ -8713,7 +9213,8 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in cla = bufexpfin->a[y][x] - original->a[y + ystart][x + xstart]; clb = bufexpfin->b[y][x] - original->b[y + ystart][x + xstart]; } - if(lp.blwh) { + + if (lp.blwh) { cla = 0.f; clb = 0.f; } @@ -8728,7 +9229,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in if (zone > 0) { //simplified transformed with deltaE and transition - transformed->L[y + ystart][x + xstart] = clipLoc(original->L[y + ystart][x + xstart] + factorx * realstrdE); + transformed->L[y + ystart][x + xstart] = clipLoc(original->L[y + ystart][x + xstart] + factorx * realstrdE);//clipLoc now do nothing...just keep in ace off float diflc = factorx * realstrdE; transformed->a[y + ystart][x + xstart] = clipC(original->a[y + ystart][x + xstart] + factorx * realstradE); const float difa = factorx * realstradE; @@ -8825,17 +9326,20 @@ void ImProcFunctions::exposure_pde(float * dataor, float * datain, float * datao fftwf_cleanup(); #ifdef RT_FFTW3F_OMP + if (multiThread) { fftwf_cleanup_threads(); } + #endif - normalize_mean_dt(data, dataor, bfw * bfh, mod, 1.f, 0.f, 0.f, 0.f, 0.f); + normalize_mean_dt(data, dataor, bfw * bfh, mod, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); { #ifdef _OPENMP #pragma omp parallel for #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { dataout[y * bfw + x] = clipLoc(data[y * bfw + x]); @@ -8873,6 +9377,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i fftwf_init_threads(); fftwf_plan_with_nthreads(omp_get_max_threads()); } + #endif @@ -8921,6 +9426,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int j = 0; j < bfh; j++) { int index = j * bfw; @@ -8940,6 +9446,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int j = 0; j < bfh; j++) { int index = j * bfw; @@ -8958,6 +9465,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int j = 0; j < bfh; j++) { int index = j * bfw; @@ -8969,6 +9477,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int j = 0; j < bfh; j++) { int index = j * bfw; @@ -8985,6 +9494,7 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int index = 0; index < image_size; index++) { //restore data output[index] /= image_sizechange; } @@ -8993,9 +9503,11 @@ void ImProcFunctions::fftw_convol_blur(float * input, float * output, int bfw, i fftwf_free(out); #ifdef RT_FFTW3F_OMP + if (multiThread) { fftwf_cleanup_threads(); } + #endif } @@ -9020,6 +9532,7 @@ void ImProcFunctions::fftw_convol_blur2(float **input2, float **output2, int bfw #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { input[y * bfw + x] = input2[y][x]; @@ -9031,6 +9544,7 @@ void ImProcFunctions::fftw_convol_blur2(float **input2, float **output2, int bfw #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { output2[y][x] = output[y * bfw + x]; @@ -9115,6 +9629,7 @@ void ImProcFunctions::fftw_tile_blur(int GW, int GH, int tilssize, int max_numbl #ifdef _OPENMP #pragma omp for #endif + for (int vblk = 0; vblk < numblox_H; ++vblk) { int top = (vblk - 1) * offset; @@ -9227,6 +9742,7 @@ void ImProcFunctions::fftw_tile_blur(int GW, int GH, int tilssize, int max_numbl #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { tmp1[i][j] = Lresult[i][j] / totwt[i][j]; @@ -9267,6 +9783,7 @@ void ImProcFunctions::wavcbd(wavelet_decomposition &wdspot, int level_bl, int ma #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif + for (int dir = 1; dir < 4; dir++) { for (int level = level_bl; level < maxlvl; ++level) { const int W_L = wdspot.level_W(level); @@ -9406,9 +9923,11 @@ void ImProcFunctions::Compresslevels(float **Source, int W_L, int H_L, float com #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif + for (int y = 0; y < H_L; y++) { int x = 0; #ifdef __SSE2__ + for (; x < W_L - 3; x += 4) { vfloat exponev = onev; vfloat valv = LVFU(Source[y][x]); @@ -9422,7 +9941,9 @@ void ImProcFunctions::Compresslevels(float **Source, int W_L, int H_L, float com const vfloat resultv = multv * xexpf(xlogf(valv + madLv) * exponev); STVFU(Source[y][x], resultv); } + #endif + for (; x < W_L; x++) { float expone = 1.f; @@ -9450,78 +9971,82 @@ void ImProcFunctions::Compresslevels(float **Source, int W_L, int H_L, float com void ImProcFunctions::wavlc(wavelet_decomposition& wdspot, int level_bl, int level_hl, int maxlvl, int level_hr, int level_br, float ahigh, float bhigh, float alow, float blow, float sigmalc, float strength, const LocwavCurve & locwavCurve, int numThreads) { - float mean[10]; - float meanN[10]; - float sigma[10]; - float sigmaN[10]; - float MaxP[10]; - float MaxN[10]; - - Evaluate2(wdspot, mean, meanN, sigma, sigmaN, MaxP, MaxN, numThreads); - for (int dir = 1; dir < 4; dir++) { - for (int level = level_bl; level < maxlvl; ++level) { - int W_L = wdspot.level_W(level); - int H_L = wdspot.level_H(level); - float klev = 1.f; + float mean[10]; + float meanN[10]; + float sigma[10]; + float sigmaN[10]; + float MaxP[10]; + float MaxN[10]; - if (level >= level_hl && level <= level_hr) { - klev = 1.f; + Evaluate2(wdspot, mean, meanN, sigma, sigmaN, MaxP, MaxN, numThreads); + + for (int dir = 1; dir < 4; dir++) { + for (int level = level_bl; level < maxlvl; ++level) { + int W_L = wdspot.level_W(level); + int H_L = wdspot.level_H(level); + float klev = 1.f; + + if (level >= level_hl && level <= level_hr) { + klev = 1.f; + } + + if (level_hl != level_bl) { + if (level >= level_bl && level < level_hl) { + klev = alow * level + blow; } + } - if (level_hl != level_bl) { - if (level >= level_bl && level < level_hl) { - klev = alow * level + blow; - } + if (level_hr != level_br) { + if (level > level_hr && level <= level_br) { + klev = ahigh * level + bhigh; } + } - if (level_hr != level_br) { - if (level > level_hr && level <= level_br) { - klev = ahigh * level + bhigh; - } - } - float* const* wav_L = wdspot.level_coeffs(level); + float* const* wav_L = wdspot.level_coeffs(level); - if (MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { - constexpr float insigma = 0.666f; //SD - const float logmax = log(MaxP[level]); //log Max - const float rapX = (mean[level] + sigmalc * sigma[level]) / MaxP[level]; //rapport between sD / max - const float inx = log(insigma); - const float iny = log(rapX); - const float rap = inx / iny; //koef - const float asig = 0.166f / (sigma[level] * sigmalc); - const float bsig = 0.5f - asig * mean[level]; - const float amean = 0.5f / mean[level]; - const float limit1 = mean[level] + sigmalc * sigma[level]; - const float limit2 = mean[level]; + if (MaxP[level] > 0.f && mean[level] != 0.f && sigma[level] != 0.f) { + constexpr float insigma = 0.666f; //SD + const float logmax = log(MaxP[level]); //log Max + const float rapX = (mean[level] + sigmalc * sigma[level]) / MaxP[level]; //rapport between sD / max + const float inx = log(insigma); + const float iny = log(rapX); + const float rap = inx / iny; //koef + const float asig = 0.166f / (sigma[level] * sigmalc); + const float bsig = 0.5f - asig * mean[level]; + const float amean = 0.5f / mean[level]; + const float limit1 = mean[level] + sigmalc * sigma[level]; + const float limit2 = mean[level]; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic, 16 * W_L) if (multiThread) + #pragma omp parallel for schedule(dynamic, 16 * W_L) if (multiThread) #endif - for (int i = 0; i < W_L * H_L; i++) { - const float val = std::fabs(wav_L[dir][i]); - float absciss; - if (val >= limit1) { //for max - const float valcour = xlogf(val); - absciss = xexpf((valcour - logmax) * rap); - } else if (val >= limit2) { - absciss = asig * val + bsig; - } else { - absciss = amean * val; - } + for (int i = 0; i < W_L * H_L; i++) { + const float val = std::fabs(wav_L[dir][i]); - const float kc = klev * (locwavCurve[absciss * 500.f] - 0.5f); - const float reduceeffect = kc <= 0.f ? 1.f : strength; + float absciss; - float kinterm = 1.f + reduceeffect * kc; - kinterm = kinterm <= 0.f ? 0.01f : kinterm; - - wav_L[dir][i] *= kinterm <= 0.f ? 0.01f : kinterm; + if (val >= limit1) { //for max + const float valcour = xlogf(val); + absciss = xexpf((valcour - logmax) * rap); + } else if (val >= limit2) { + absciss = asig * val + bsig; + } else { + absciss = amean * val; } + + const float kc = klev * (locwavCurve[absciss * 500.f] - 0.5f); + const float reduceeffect = kc <= 0.f ? 1.f : strength; + + float kinterm = 1.f + reduceeffect * kc; + kinterm = kinterm <= 0.f ? 0.01f : kinterm; + + wav_L[dir][i] *= kinterm <= 0.f ? 0.01f : kinterm; } } } - -} + } + +} void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavelet_decomposition& wdspot, int level_bl, int maxlvl, const LocwavCurve & loclevwavCurve, bool loclevwavutili, @@ -9548,6 +10073,7 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel if (process == 1 && loclevwavCurve && loclevwavutili) { //blur array2D templevel(W_L, H_L); + for (int dir = 1; dir < 4; ++dir) { for (int level = level_bl; level < maxlvl; ++level) { const auto WavL = wdspot.level_coeffs(level)[dir]; @@ -9561,9 +10087,11 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel const float klev = 0.25f * loclevwavCurve[level * 55.5f]; float* src[H_L]; + for (int i = 0; i < H_L; ++i) { src[i] = &wdspot.level_coeffs(level)[dir][i * W_L]; } + #ifdef _OPENMP #pragma omp parallel if (multiThread) #endif @@ -9580,15 +10108,19 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel #ifdef _OPENMP #pragma omp for #endif + for (int y = 0; y < H_L; y++) { int x = 0; int j = y * W_L; #ifdef __SSE2__ + for (; x < W_L - 3; x += 4, j += 4) { const vfloat valv = LVFU(WavL[j]); STVFU(WavL[j], intp((*meaLut)[vabsf(valv) * lutFactorv], LVFU(templevel[y][x]), valv)); } + #endif + for (; x < W_L; x++, j++) { WavL[j] = intp((*meaLut)[std::fabs(WavL[j]) * lutFactor], templevel[y][x], WavL[j]); } @@ -9639,16 +10171,20 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel #ifdef _OPENMP #pragma omp for #endif + for (int i = 0; i < H_L; ++i) { int j = 0; #ifdef __SSE2__ + for (; j < W_L - 3; j += 4) { const vfloat LL100v = LC2VFU(tmp[i * 2][j * 2]) / c327d68v; const vfloat kbav = factorv * (loccompwavCurve[sixv * LL100v] - zd5v); //k1 between 0 and 0.5 0.5==> 1/6=0.16 const vfloat valv = LVFU(WavL[i * W_L + j]); STVFU(WavL[i * W_L + j], valv * pow_F(onev + kbav * (*meaLut)[vabsf(valv) * lutFactorv], itfv)); } + #endif + for (; j < W_L; ++j) { const float LL100 = tmp[i * 2][j * 2] / 327.68f; const float kba = factor * (loccompwavCurve[6.f * LL100] - 0.5f); //k1 between 0 and 0.5 0.5==> 1/6=0.16 @@ -9664,6 +10200,7 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif + for (int dir = 1; dir < 4; dir++) { for (int level = level_bl; level < maxlvl; ++level) { madL[level][dir - 1] = Mad(wdspot.level_coeffs(level)[dir], wdspot.level_W(level) * wdspot.level_H(level)); //evaluate noise by level @@ -9684,6 +10221,7 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H_L; y++) { for (int x = 0; x < W_L; x++) { int j = y * W_L + x; @@ -9692,11 +10230,13 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel } float klev = (loccomprewavCurve[level * 55.5f] - 0.75f); + if (klev < 0.f) { klev *= 2.6666f;//compression increase contraste } else { klev *= 4.f;//dilatation reduce contraste - detailattenuator } + const float compression = expf(-klev); const float detailattenuator = std::max(klev, 0.f); @@ -9711,15 +10251,19 @@ void ImProcFunctions::wavcont(const struct local_params& lp, float ** tmp, wavel #ifdef _OPENMP #pragma omp for #endif + for (int y = 0; y < H_L; y++) { int x = 0; int j = y * W_L; #ifdef __SSE2__ + for (; x < W_L - 3; x += 4, j += 4) { const vfloat valv = LVFU(wav_L[j]); STVFU(wav_L[j], intp((*meaLut)[vabsf(valv) * lutFactorv], LVFU(templevel[y][x]), valv)); } + #endif + for (; x < W_L; x++, j++) { wav_L[j] = intp((*meaLut)[std::fabs(wav_L[j]) * lutFactor], templevel[y][x], wav_L[j]); } @@ -9762,11 +10306,13 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < H_Lm; y++) { for (int x = 0; x < W_Lm; x++) { factorwav[y][x] = mult * (1.f - ImProcFunctions::calcGradientFactor(gpwav, x, y)); } } + float mean[10]; float meanN[10]; float sigma[10]; @@ -9822,6 +10368,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float klev = ahighg * level + bhighg; } } + klev *= 0.8f; const float threshold = mean[level] + lp.sigmalc2 * sigma[level]; float lutFactor; @@ -9837,6 +10384,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float const float WavCL = std::fabs(wav_L[y * W_L + x]); float absciss; + if (WavCL >= threshold) { //for max absciss = pow_F(WavCL - logmax, rap); } else if (WavCL >= mean[level]) { @@ -9864,6 +10412,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float if (radblur > 0.f && blurena) { float* src[H_Level]; + for (int i = 0; i < H_Level; ++i) { src[i] = &wav_L0[i * W_Level]; } @@ -9889,6 +10438,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float if (lp.residshathr > (100.f - tran)) { tran = 100.f - lp.residshathr; } + constexpr float alp = 3.f; const float aalp = (1.f - alp) / lp.residshathr; const float ath = -lp.residsha / tran; @@ -9902,6 +10452,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < W_Level * H_Level; i++) { const float LL100 = wav_L0[i] / 327.68f; @@ -9932,7 +10483,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float } } - ImProcFunctions::shadowsHighlights(temp.get(), true, 1, lp.residhi, lp.residsha , 40, sk, lp.residhithr, lp.residshathr); + ImProcFunctions::shadowsHighlights(temp.get(), true, 1, lp.residhi, lp.residsha, 40, sk, lp.residhithr, lp.residshathr); #ifdef _OPENMP #pragma omp parallel for if (multiThread) @@ -9951,6 +10502,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for reduction(+:avedbl) if (multiThread) #endif + for (int i = 0; i < W_Level * H_Level; i++) { avedbl += static_cast(wav_L0[i]); } @@ -9967,6 +10519,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < W_Level * H_Level; i++) { wav_L0[i] = resid_contrast.getVal(LIM01(wav_L0[i] / 32768.f)) * 32768.0; } @@ -10033,6 +10586,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float float gradw = lp.gradw; float tloww = lp.tloww; + for (int lvl = 0; lvl < 4; lvl++) { for (int dir = 1; dir < 4; dir++) { const int W_L = wdspot->level_W(lvl); @@ -10042,7 +10596,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float // return convolution KoeLi and maxkoeLi of level 0 1 2 3 and Dir Horiz, Vert, Diag } } - + tmC.free(); float aamp = 1.f + lp.thigw / 100.f; @@ -10053,6 +10607,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif + for (int i = 1; i < H_Level - 1; i++) { for (int j = 1; j < W_Level - 1; j++) { //treatment of koeLi and maxkoeLi @@ -10064,12 +10619,13 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float for (int dir = 1; dir < 4; dir++) { //neighbors proxi koeLi[lvl * 3 + dir - 1][i * W_Level + j] = (kneigh * koeLi[lvl * 3 + dir - 1][i * W_Level + j] + - 2.f * koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j] + 2.f * koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_Level + j + 1] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_Level + j - 1] - + koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j - 1] + koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j + 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j - 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j + 1]) / somm; + 2.f * koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j] + 2.f * koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_Level + j + 1] + 2.f * koeLi[lvl * 3 + dir - 1][i * W_Level + j - 1] + + koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j - 1] + koeLi[lvl * 3 + dir - 1][(i - 1) * W_Level + j + 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j - 1] + koeLi[lvl * 3 + dir - 1][(i + 1) * W_Level + j + 1]) / somm; } } float interm = 0.f; + for (int dir = 1; dir < 4; dir++) { //here I evaluate combination of vert / diag / horiz...we are with multiplicators of the signal interm += SQR(koeLi[lvl * 3 + dir - 1][i * W_Level + j]); @@ -10108,6 +10664,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float } float kampli; + if (alph > eddlipinfl) { kampli = alipinfl * alph + blipinfl; //If beta low reduce kampli kampli = SQR(bet) * kampli * aamp; @@ -10150,11 +10707,13 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float if (lp.edgwmet != 1) { float brepart; + if (lp.edgwmet == 0) { brepart = 3.f; - } else /*if (lp.edgwmet == 2)*/ { + } else { /*if (lp.edgwmet == 2)*/ brepart = 0.5f; //arbitrary value to increase / decrease repart, between 1 and 0 } + if (rad < lim0 / 60.f) { const float arepart = - (brepart - 1.f) / (lim0 / 60.f); repart *= arepart * rad + brepart; //linear repartition of repart @@ -10172,6 +10731,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float float* const* wav_L = wdspot->level_coeffs(lvl); const float koef = ak * lvl + bk; //modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels float expkoef = -pow_F(std::fabs(rad - lvl), koef); //reduce effect for high levels + if (lp.edgwmet == 2) { if (rad < lim0 / 60.f && lvl == 0) { expkoef *= abs(repart); //reduce effect for low values of rad and level=0==> quasi only level 1 is effective @@ -10181,6 +10741,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float expkoef /= repart; //increase effect for low values of rad and level=1==> quasi only level 0 is effective } } + //take into account local contrast const float refin = value * xexpf(expkoef); const float edgePrecalc = 1.f + refin; //estimate edge "pseudo variance" @@ -10215,11 +10776,13 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 16) if(multiThread) #endif + for (int i = borderL; i < H_L - borderL; i++) { for (int j = borderL; j < W_L - borderL; j++) { const int k = i * W_L + j; float edge; + if (lvl < 4) { edge = 1.f + (edgePrecalc - 1.f) * (koeLi[lvl * 3][k]) / (1.f + 0.9f * maxkoeLi[lvl * 3 + dir - 1]); } else { @@ -10227,11 +10790,12 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float } float absciss = 0.f; + if (std::fabs(wav_L[dir][k]) >= mean[lvl] + sigma[lvl]) { //for max absciss = xexpf((xlogf(std::fabs(wav_L[dir][k])) - logmax) * rap); } else if (std::fabs(wav_L[dir][k]) >= mean[lvl]) { absciss = asig * std::fabs(wav_L[dir][k]) + bsig; - } else /*if (std::fabs(wav_L[dir][k]) < mean[lvl])*/ { + } else { /*if (std::fabs(wav_L[dir][k]) < mean[lvl])*/ absciss = amean * std::fabs(wav_L[dir][k]); } @@ -10255,6 +10819,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float const float kc = kmul * (locedgwavCurve[absciss * 500.f] - 0.5f); float kinterm; + if (kc >= 0.f) { constexpr float reduceeffect = 0.6f; kinterm = 1.f + reduceeffect * kc; //about 1 to 3 general and big amplification for max (under 0) @@ -10286,41 +10851,52 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float float strengthlc = 1.5f; wavlc(*wdspot, level_bl, level_hl, maxlvl, level_hr, level_br, ahigh, bhigh, alow, blow, lp.sigmalc, strengthlc, locwavCurve, numThreads); } + //reconstruct all for L wdspot->reconstruct(tmp[0], 1.f); bool reconstruct = false; + if (wavcurvecon && (chromalev != 1.f) && levelena) { // a if need ) {//contrast by levels for chroma a // a wdspot.reset(new wavelet_decomposition(tmpa[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspot->memory_allocation_failed()) { return; } + wavcbd(*wdspot, level_bl, maxlvl, locconwavCurve, locconwavutili, sigm, offs, chromalev, sk); reconstruct = true; } + if (wavcurvelev && radlevblur > 0.f && blurena && chromablu > 0.f && !blurlc) {//chroma blur if need // a if (!reconstruct) { wdspot.reset(new wavelet_decomposition(tmpa[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspot->memory_allocation_failed()) { return; } } + wavcont(lp, tmp, *wdspot, level_bl, maxlvl, loclevwavCurve, loclevwavutili, loccompwavCurve, loccompwavutili, loccomprewavCurve, loccomprewavutili, radlevblur, 1, chromablu, 0.f, 0.f, 0.f); reconstruct = true; } + if (reconstruct) { wdspot->reconstruct(tmpa[0], 1.f); } reconstruct = false; + if (wavcurvecon && (chromalev != 1.f) && levelena) { // b if need ) {//contrast by levels for chroma b //b wdspot.reset(new wavelet_decomposition(tmpb[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspot->memory_allocation_failed()) { return; } + //b wavcbd(*wdspot, level_bl, maxlvl, locconwavCurve, locconwavutili, sigm, offs, chromalev, sk); reconstruct = true; @@ -10330,18 +10906,21 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float //b if (!reconstruct) { wdspot.reset(new wavelet_decomposition(tmpb[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspot->memory_allocation_failed()) { return; } } + wavcont(lp, tmp, *wdspot, level_bl, maxlvl, loclevwavCurve, loclevwavutili, loccompwavCurve, loccompwavutili, loccomprewavCurve, loccomprewavutili, radlevblur, 1, chromablu, 0.f, 0.f, 0.f); reconstruct = true; } + if (reconstruct) { wdspot->reconstruct(tmpb[0], 1.f); } - - + + //gamma and slope residual image - be careful memory bool tonecur = false; const Glib::ustring profile = params->icm.workingProfile; @@ -10350,20 +10929,26 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float if (isworking && (lp.residgam != 2.4f || lp.residslop != 12.92f)) { tonecur = true; } - - if(tonecur) { + + if (tonecur) { std::unique_ptr wdspotL(new wavelet_decomposition(tmp[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspotL->memory_allocation_failed()) { return; } + std::unique_ptr wdspota(new wavelet_decomposition(tmpa[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspota->memory_allocation_failed()) { return; } + std::unique_ptr wdspotb(new wavelet_decomposition(tmpb[0], bfw, bfh, maxlvl, 1, sk, numThreads, lp.daubLen)); + if (wdspotb->memory_allocation_failed()) { return; } + int W_Level = wdspotL->level_W(0); int H_Level = wdspotL->level_H(0); float *wav_L0 = wdspotL->get_coeff0(); @@ -10374,6 +10959,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_Level; y++) { for (int x = 0; x < W_Level; x++) { labresid->L[y][x] = wav_L0[y * W_Level + x]; @@ -10387,15 +10973,19 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float lab2rgb(*labresid, *tmpImage, params->icm.workingProfile); Glib::ustring prof = params->icm.workingProfile; cmsHTRANSFORM dummy = nullptr; - int ill =0; - workingtrc(tmpImage, tmpImage, W_Level, H_Level, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - workingtrc(tmpImage, tmpImage, W_Level, H_Level, 1, prof, lp.residgam, lp.residslop, ill, 0, dummy, false, true, true);//be careful no gamut control + int ill = 0; + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + workingtrc(0, tmpImage, tmpImage, W_Level, H_Level, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly ,meanx, meany, meanxe, meanye, dummy, true, false, false, false); + workingtrc(0, tmpImage, tmpImage, W_Level, H_Level, 1, prof, lp.residgam, lp.residslop, 0, ill, 0, locprim, rdx, rdy, grx, gry, blx, bly , meanx, meany, meanxe, meanye, dummy, false, true, true, false);//be careful no gamut control rgb2lab(*tmpImage, *labresid, params->icm.workingProfile); delete tmpImage; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_Level; y++) { for (int x = 0; x < W_Level; x++) { wav_L0[y * W_Level + x] = labresid->L[y][x]; @@ -10413,7 +11003,7 @@ void ImProcFunctions::wavcontrast4(struct local_params& lp, float ** tmp, float void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom) { - // BENCHFUN + // BENCHFUN fftwf_plan plan_forward_blox[2]; fftwf_plan plan_backward_blox[2]; @@ -10491,6 +11081,7 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in #ifdef _OPENMP #pragma omp for #endif + for (int vblk = 0; vblk < numblox_H; ++vblk) { int top = (vblk - 1) * offset; @@ -10589,27 +11180,31 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in }//end of vertical block loop } - //Threshold DCT from Alberto Grigio, adapted to Rawtherapee + //Threshold DCT from Alberto Grigio, adapted to Rawtherapee const int detail_thresh = lp.detailthr; array2D mask; if (detail_thresh > 0) { mask(GW, GH); + if (lp.usemask) {//with Laplacian - float amount = LIM01(float(detail_thresh)/100.f); + float amount = LIM01(float(detail_thresh) / 100.f); float thr = (1.f - amount); float alph = params_Ldetail / 100.f; array2D LL(GW, GH, prov, ARRAY2D_BYREFERENCE); laplacian(LL, mask, GW, GH, 25.f, 20000.f, amount, false); + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { - mask[i][j] = LIM01(mask[i][j]+ thr); + mask[i][j] = LIM01(mask[i][j] + thr); } } + for (int i = 0; i < 3; ++i) { boxblur(static_cast(mask), static_cast(mask), 10 / sk, GW, GH, false); - + } + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { float k = 1.f - mask[i][j] * alph; @@ -10620,7 +11215,7 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in float thr = log2lin(float(detail_thresh) / 200.f, 100.f); buildBlendMask(prov, mask, GW, GH, thr); #ifdef _OPENMP - #pragma omp parallel if (multiThread) + #pragma omp parallel if (multiThread) #endif { gaussianBlur(mask, mask, GW, GH, 20.0 / sk); @@ -10629,18 +11224,20 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in constexpr float alfa = 0.856f; const float beta = 1.f + std::sqrt(log2lin(thr, 100.f)); buildGradientsMask(GW, GH, prov, m2, params_Ldetail / 100.f, 7, 3, alfa, beta, multiThread); + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { mask[i][j] *= m2[i][j]; } } - } + } } #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { float d = Ldetail[i][j] / totwt[i][j]; @@ -10678,7 +11275,7 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct local_params & lp, LabImage * originalmaskbl, LabImage * bufmaskblurbl, int levred, float huerefblur, float lumarefblur, float chromarefblur, LabImage * original, LabImage * transformed, int cx, int cy, int sk, const LocwavCurve& locwavCurvehue, bool locwavhueutili, float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46) { - BENCHFUN + // BENCHFUN //local denoise //all these variables are to prevent use of denoise when non necessary // but with qualmet = 2 (default for best quality) we must denoise chroma with little values to prevent artifacts due to variations of Hue @@ -10698,7 +11295,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct if (((lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.nlstr > 0 || lp.wavcurvedenoi || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f || execmaskden || aut == 1 || aut == 2) && lp.denoiena && lp.quamet != 3) || execdenoi) { // sk == 1 ?? - StopWatch Stop1("locallab Denoise called"); + //StopWatch Stop1("locallab Denoise called"); if (aut == 0) { MyMutex::MyLock lock(*fftwMutex); @@ -10731,21 +11328,24 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct const int numThreads = 1; #endif - int minwin = rtengine::min(GW, GH); - int maxlevelspot = 10;//maximum possible - bool isnois = true; - // adap maximum level wavelet to size of crop - while ((1 << maxlevelspot) >= (minwin * sk) && maxlevelspot > 1) { - --maxlevelspot ; - } + int minwin = rtengine::min(GW, GH); + int maxlevelspot = 10;//maximum possible + bool isnois = true; - levred = rtengine::min(levred, maxlevelspot); - if(levred < 7) {//If windows preview or detail window too small exit to avoid artifacts - isnois = false; - if(lp.quamet == 2) { - isnois = true; - } + // adap maximum level wavelet to size of crop + while ((1 << maxlevelspot) >= (minwin * sk) && maxlevelspot > 1) { + --maxlevelspot ; + } + + levred = rtengine::min(levred, maxlevelspot); + + if (levred < 7) { //If windows preview or detail window too small exit to avoid artifacts + isnois = false; + + if (lp.quamet == 2) { + isnois = true; } + } if (call == 1 && ((GW >= mDEN && GH >= mDEN && isnois) || lp.quamet == 2)) { @@ -10778,18 +11378,22 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - if(gamma > 1.f) { + if (gamma > 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < GH; ++y) { int x = 0; #ifdef __SSE2__ + for (; x < GW - 3; x += 4) { STVFU(tmp1.L[y][x], F2V(32768.f) * igammalog(LVFU(tmp1.L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < GW; ++x) { + + for (; x < GW; ++x) { tmp1.L[y][x] = 32768.f * igammalog(tmp1.L[y][x] / 32768.f, gamma, ts, g_a[2], g_a[4]); } } @@ -10811,6 +11415,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP // #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif + for (int lvl = 0; lvl < levred; lvl++) { for (int dir = 1; dir < 4; dir++) { int Wlvl_L = Ldecomp.level_W(lvl); @@ -10871,6 +11476,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < GH; ir++) for (int jr = 0; jr < GW; jr++) { float lN = tmp1.L[ir][jr]; @@ -10884,7 +11490,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } } - if(lp.enablMask && lp.lnoiselow !=1.f && lp.smasktyp != 0) { + if (lp.enablMask && lp.lnoiselow != 1.f && lp.smasktyp != 0) { //this code has been reviewed by Ingo in september 2020 PR5903 float higc; float hig = lp.thrhigh; @@ -10892,8 +11498,8 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct float low = lp.thrlow; float lowc; calcdif(low, lowc); - - if(higc < lowc) { + + if (higc < lowc) { higc = lowc + 0.01f; } @@ -10901,10 +11507,11 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct float blow = lp.lnoiselow; float ahigh = 0.9999f / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < GH; ir++) for (int jr = 0; jr < GW; jr++) { const float lM = bufmaskblurbl->L[ir][jr]; @@ -10917,22 +11524,23 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } else { noisevarlum[(ir >> 1) * GW2 + (jr >> 1)] *= ahigh * lmr + bhigh; } - } + } } - if(HHhuecurve) { - //same code as in wavelet levels - + if (HHhuecurve) { + //same code as in wavelet levels + #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif + for (int ir = 0; ir < GH; ir++) for (int jr = 0; jr < GW; jr++) { float hueG = xatan2f(tmp1.b[ir][jr], tmp1.a[ir][jr]); float valparam = 2.f * (locwavCurvehue[500.f * static_cast(Color::huelab_to_huehsv2(hueG))] - 0.5f); //get H=f(H) noisevarhue[(ir >> 1)*GW2 + (jr >> 1)] = 1.f + valparam; - noisevarlum[(ir >> 1)*GW2 + (jr >> 1)] *= noisevarhue[(ir >> 1)*GW2 + (jr >> 1)]; + noisevarlum[(ir >> 1)*GW2 + (jr >> 1)] *= noisevarhue[(ir >> 1) * GW2 + (jr >> 1)]; } } @@ -10940,7 +11548,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct if ((lp.quamet == 0 && aut == 0) || (mxsl < 1.f && (aut == 1 || aut == 2))) { WaveletDenoiseAllL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); - } else if (lp.quamet == 1){ + } else if (lp.quamet == 1) { WaveletDenoiseAll_BiShrinkL(Ldecomp, noisevarlum, madL, vari, edge, numThreads); @@ -11153,6 +11761,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < GH; ir++) for (int jr = 0; jr < GW; jr++) { float cN = std::sqrt(SQR(tmp1.a[ir][jr]) + SQR(tmp1.b[ir][jr])); @@ -11172,7 +11781,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct if ((lp.quamet == 0 && aut == 0) || (maxccoarse < 0.1f && (aut == 1 || aut == 2))) { WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); - } else if (lp.quamet == 1){ + } else if (lp.quamet == 1) { WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); @@ -11190,6 +11799,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { (*Lin)[i][j] = tmp1.L[i][j]; @@ -11210,6 +11820,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { (*Ain)[i][j] = tmp1.a[i][j]; @@ -11233,6 +11844,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { for (int j = 0; j < GW; ++j) { (*Bin)[i][j] = tmp1.b[i][j]; @@ -11251,26 +11863,38 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } if(gamma > 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < GH; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < GW - 3; x += 4) { STVFU(tmp1.L[y][x], F2V(32768.f) * gammalog(LVFU(tmp1.L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < GW; ++x) { tmp1.L[y][x] = 32768.f * gammalog(tmp1.L[y][x] / 32768.f, gamma, ts, g_a[3], g_a[4]); } } } +//<<<<<<< HEAD +// if (lp.nlstr > 0) { +// NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); +// } + +// if (lp.smasktyp != 0) { +// if (lp.enablMask && lp.recothrd != 1.f) { +//======= if(lp.smasktyp != 0) { if(lp.enablMask && lp.recothrd != 1.f) { LabImage tmp3(GW, GH); - for (int ir = 0; ir < GH; ir++){ + for (int ir = 0; ir < GH; ir++) { for (int jr = 0; jr < GW; jr++) { tmp3.L[ir][jr] = original->L[ir][jr]; tmp3.a[ir][jr] = original->a[ir][jr]; @@ -11290,23 +11914,26 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct float mid = 0.01f * lp.midthrd; float midch = 0.01f * lp.midthrdch; - if(higc < lowc) { + if (higc < lowc) { higc = lowc + 0.01f; } + float th = (lp.recothrd - 1.f); float ahigh = th / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - float alow = th / lowc; + float alow = th / lowc; float blow = 1.f - th; #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < GH; ir++) { for (int jr = 0; jr < GW; jr++) { const float lmr = bufmaskblurbl->L[ir][jr] / 327.68f; float k; float kch; + if (lmr < lowc) { k = alow * lmr + blow; kch = alow * lmr + blow; @@ -11317,7 +11944,8 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct k = ahigh * lmr + bhigh; kch = ahigh * lmr + bhigh; } - if(lp.invmaskd) { + + if (lp.invmaskd) { masklum[ir][jr] = 1.f - pow_F(k, lp.decayd); masklumch[ir][jr] = 1.f - pow_F(kch, lp.decayd); } else { @@ -11331,16 +11959,19 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct boxblur(static_cast(masklum), static_cast(masklum), 10 / sk, GW, GH, multiThread); boxblur(static_cast(masklumch), static_cast(masklumch), 10 / sk, GW, GH, multiThread); } + #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < GH; ++i) { - for (int j = 0; j < GW; ++j) { + for (int j = 0; j < GW; ++j) { tmp1.L[i][j] = (tmp3.L[i][j] - tmp1.L[i][j]) * LIM01(masklum[i][j]) + tmp1.L[i][j]; tmp1.a[i][j] = (tmp3.a[i][j] - tmp1.a[i][j]) * LIM01(masklumch[i][j]) + tmp1.a[i][j]; tmp1.b[i][j] = (tmp3.b[i][j] - tmp1.b[i][j]) * LIM01(masklumch[i][j]) + tmp1.b[i][j]; } } + masklum.free(); masklumch.free(); } @@ -11453,6 +12084,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H ; y++) //{ for (int x = 0; x < transformed->W; x++) { int lox = cx + x; @@ -11471,20 +12103,25 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct double pwr = 1.0 / (double) lp.noisegam;//default 3.0 - gamma Lab double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - if(gamma > 1.f) { + + if (gamma > 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; ++y) { int x = 0; - + #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(bufwv.L[y][x], F2V(32768.f) * igammalog(LVFU(bufwv.L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < bfw; ++x) { - bufwv.L[y][x] = 32768.f * igammalog(bufwv.L[y][x] / 32768.f, gamma, ts, g_a[2], g_a[4]); + + for (; x < bfw; ++x) { + bufwv.L[y][x] = 32768.f * igammalog(bufwv.L[y][x] / 32768.f, gamma, ts, g_a[2], g_a[4]); } } } @@ -11503,6 +12140,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif + for (int lvl = 0; lvl < levred; lvl++) { for (int dir = 1; dir < 4; dir++) { int Wlvl_L = Ldecomp.level_W(lvl); @@ -11568,6 +12206,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float lN = bufwv.L[ir][jr]; @@ -11580,56 +12219,59 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct noisevarlum[(ir >> 1)*bfw2 + (jr >> 1)] = nvll[i]; } } - - if(lp.enablMask && lp.lnoiselow != 1.f && lp.smasktyp != 0) { - //this code has been reviewed by Ingo in september 2020 PR5903 - //i just change parameters to better progressivity - float higc; - float hig = lp.thrhigh; - calcdif(hig, higc); - float low = lp.thrlow; - float lowc; - calcdif(low, lowc); - - if(higc < lowc) { - higc = lowc + 0.01f; - } - float alow = -(lp.lnoiselow - 1.f) / lowc; - float blow = lp.lnoiselow; - float ahigh = 0.9999f / (higc - 100.f); - float bhigh = 1.f - higc * ahigh; + if (lp.enablMask && lp.lnoiselow != 1.f && lp.smasktyp != 0) { + //this code has been reviewed by Ingo in september 2020 PR5903 + //i just change parameters to better progressivity + float higc; + float hig = lp.thrhigh; + calcdif(hig, higc); + float low = lp.thrlow; + float lowc; + calcdif(low, lowc); + + if (higc < lowc) { + higc = lowc + 0.01f; + } + + float alow = -(lp.lnoiselow - 1.f) / lowc; + float blow = lp.lnoiselow; + float ahigh = 0.9999f / (higc - 100.f); + float bhigh = 1.f - higc * ahigh; #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif - for (int ir = 0; ir < bfh; ir++) - for (int jr = 0; jr < bfw; jr++) { - const float lM = bufmaskblurbl->L[ir + ystart][jr + xstart]; - const float lmr = lM / 327.68f; - if (lM < 327.68f * lowc) { - noisevarlum[(ir >> 1) * bfw2 + (jr >> 1)] *= alow * lmr + blow; - } else if (lM < 327.68f * higc) { - // do nothing - } else { - noisevarlum[(ir >> 1) * bfw2 + (jr >> 1)] *= ahigh * lmr + bhigh; + + for (int ir = 0; ir < bfh; ir++) + for (int jr = 0; jr < bfw; jr++) { + const float lM = bufmaskblurbl->L[ir + ystart][jr + xstart]; + const float lmr = lM / 327.68f; + + if (lM < 327.68f * lowc) { + noisevarlum[(ir >> 1) * bfw2 + (jr >> 1)] *= alow * lmr + blow; + } else if (lM < 327.68f * higc) { + // do nothing + } else { + noisevarlum[(ir >> 1) * bfw2 + (jr >> 1)] *= ahigh * lmr + bhigh; + } } } - } - if(HHhuecurve) { + if (HHhuecurve) { //same code as in wavelet levels #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float hueG = xatan2f(bufwv.b[ir][jr], bufwv.a[ir][jr]); float valparam = 2.f * (locwavCurvehue[500.f * static_cast(Color::huelab_to_huehsv2(hueG))] - 0.5f); //get H=f(H) noisevarhue[(ir >> 1)* bfw2 + (jr >> 1)] = 1.f + valparam; - noisevarlum[(ir >> 1)* bfw2 + (jr >> 1)] *= noisevarhue[(ir >> 1)* bfw2 + (jr >> 1)]; + noisevarlum[(ir >> 1)* bfw2 + (jr >> 1)] *= noisevarhue[(ir >> 1) * bfw2 + (jr >> 1)]; } } @@ -11851,6 +12493,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float cN = std::sqrt(SQR(bufwv.a[ir][jr]) + SQR(bufwv.b[ir][jr])); @@ -11869,7 +12512,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct if ((lp.quamet == 0 && aut == 0) || (maxccoarse < 0.1f && (aut == 1 || aut == 2))) { WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); WaveletDenoiseAllAB(Ldecomp, bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, numThreads); - } else if (lp.quamet == 1){ + } else if (lp.quamet == 1) { WaveletDenoiseAll_BiShrinkAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, numThreads); @@ -11887,6 +12530,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { (*Lin)[i][j] = bufwv.L[i][j]; @@ -11911,6 +12555,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { (*Ain)[i][j] = bufwv.a[i][j]; @@ -11932,6 +12577,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { (*Bin)[i][j] = bufwv.b[i][j]; @@ -11947,19 +12593,23 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } } - if(gamma > 1.f) { + if (gamma > 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; - + #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(bufwv.L[y][x], F2V(32768.f) * gammalog(LVFU(bufwv.L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < bfw ; ++x) { bufwv.L[y][x] = 32768.f * gammalog(bufwv.L[y][x] / 32768.f, gamma, ts, g_a[3], g_a[4]); @@ -11967,17 +12617,18 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct } } - if(lp.nlstr > 0) { + if (lp.nlstr > 0) { NLMeans(bufwv.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, bfw, bfh, 1.f, multiThread); } if (lp.smasktyp != 0) { - if(lp.enablMask && lp.recothrd != 1.f) { + if (lp.enablMask && lp.recothrd != 1.f) { LabImage tmp3(bfw, bfh); #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H ; y++) { for (int x = 0; x < transformed->W; x++) { int lox = cx + x; @@ -11987,7 +12638,7 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct tmp3.L[loy - begy][lox - begx] = original->L[y][x]; tmp3.a[loy - begy][lox - begx] = original->a[y][x]; tmp3.b[loy - begy][lox - begx] = original->b[y][x]; - } + } } } @@ -11996,7 +12647,8 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct array2D masklumch; masklum(bfw, bfh); masklumch(bfw, bfh); - for (int ir = 0; ir < bfh; ir++){ + + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { masklum[ir][jr] = 1.f; masklumch[ir][jr] = 1.f; @@ -12012,54 +12664,61 @@ void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct float mid = 0.01f * lp.midthrd; float midch = 0.01f * lp.midthrdch; - if(higc < lowc) { + if (higc < lowc) { higc = lowc + 0.01f; } + float th = (lp.recothrd - 1.f); float ahigh = th / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - float alow = th / lowc; + float alow = th / lowc; float blow = 1.f - th; #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart, lox = cx + x; x < xend; x++, lox++) { - const float lM = bufmaskblurbl->L[y][x]; + const float lM = bufmaskblurbl->L[y][x]; const float lmr = lM / 327.68f; + if (lM < 327.68f * lowc) { - masklum[y-ystart][x-xstart] = alow * lmr + blow; - masklumch[y-ystart][x-xstart] = alow * lmr + blow; + masklum[y - ystart][x - xstart] = alow * lmr + blow; + masklumch[y - ystart][x - xstart] = alow * lmr + blow; } else if (lM < 327.68f * higc) { - masklum[y-ystart][x-xstart] = 1.f - mid; - masklumch[y-ystart][x-xstart] = 1.f - midch; + masklum[y - ystart][x - xstart] = 1.f - mid; + masklumch[y - ystart][x - xstart] = 1.f - midch; } else { - masklum[y-ystart][x-xstart] = ahigh * lmr + bhigh; - masklumch[y-ystart][x-xstart] = ahigh * lmr + bhigh; + masklum[y - ystart][x - xstart] = ahigh * lmr + bhigh; + masklumch[y - ystart][x - xstart] = ahigh * lmr + bhigh; } - float k = masklum[y-ystart][x-xstart]; - float kch = masklumch[y-ystart][x-xstart]; - if(lp.invmaskd == true) { - masklum[y-ystart][x-xstart] = 1.f - pow(k, lp.decayd); - masklumch[y-ystart][x-xstart] = 1.f - pow(kch, lp.decayd); + + float k = masklum[y - ystart][x - xstart]; + float kch = masklumch[y - ystart][x - xstart]; + + if (lp.invmaskd == true) { + masklum[y - ystart][x - xstart] = 1.f - pow(k, lp.decayd); + masklumch[y - ystart][x - xstart] = 1.f - pow(kch, lp.decayd); } else { - masklum[y-ystart][x-xstart] = pow(k, lp.decayd); - masklumch[y-ystart][x-xstart] = pow(kch, lp.decayd); + masklum[y - ystart][x - xstart] = pow(k, lp.decayd); + masklumch[y - ystart][x - xstart] = pow(kch, lp.decayd); } } } + for (int i = 0; i < 3; ++i) { boxblur(static_cast(masklum), static_cast(masklum), 10 / sk, bfw, bfh, false); boxblur(static_cast(masklumch), static_cast(masklumch), 10 / sk, bfw, bfh, false); } - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufwv.L[y][x] = (tmp3.L[y][x] - bufwv.L[y][x]) * LIM01(masklum[y][x]) + bufwv.L[y][x]; @@ -12140,6 +12799,7 @@ void ImProcFunctions::clarimerge(const struct local_params& lp, float &mL, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) #endif + for (int dir = 1; dir < 4; dir++) { for (int level = 0; level < maxlvlresid; ++level) { int W_L = wdspotresid->level_W(level); @@ -12180,6 +12840,7 @@ void ImProcFunctions::clarimerge(const struct local_params& lp, float &mL, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) #endif + for (int dir = 1; dir < 4; dir++) { for (int level = 0; level < maxlvlresid; ++level) { int W_L = wdspotresida->level_W(level); @@ -12216,6 +12877,7 @@ void ImProcFunctions::clarimerge(const struct local_params& lp, float &mL, float #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) #endif + for (int dir = 1; dir < 4; dir++) { for (int level = 0; level < maxlvlresid; ++level) { int W_L = wdspotresidb->level_W(level); @@ -12266,7 +12928,7 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag const float ach = lp.trans / 100.f; bool execmunsell = true; - if (params->locallab.spots.at(sp).expcie && (params->locallab.spots.at(sp).modecam == "all" || params->locallab.spots.at(sp).modecam == "jz" || params->locallab.spots.at(sp).modecam == "cam16")) { + if (params->locallab.spots.at(sp).expcie && (params->locallab.spots.at(sp).modecam == "jz" || params->locallab.spots.at(sp).modecam == "cam16")) { execmunsell = false; } @@ -12439,12 +13101,13 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag Color::gamutmap(xg, yg, zg, wp); - if (avoidgamut == 3) {//0.5f arbitrary coeff - xg = xg + 0.5f * (x0 - xg); - yg = yg + 0.5f * (y0 - yg); - zg = zg + 0.5f * (z0 - zg); + if (avoidgamut == 3) {//-0.3f arbitrary coeff, 04-2024 change mistake where 0.5f => -0.3f + xg = rtengine::LIM(xg - 0.3f * (x0 - xg), 0.f, 65535.f); + yg = rtengine::LIM(yg - 0.3f * (y0 - yg), 0.f, 65535.f); + zg = rtengine::LIM(zg - 0.3f * (z0 - zg), 0.f, 65535.f); } + //Color::gamutmap(xg, yg, zg, wp);//Put XYZ in gamut wp float aag2, bbg2; Color::XYZ2Lab(xg, yg, zg, Lag, aag2, bbg2); @@ -12477,6 +13140,7 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag float correctlum = 0.f; const float memChprov = std::sqrt(SQR(reserved->a[y][x]) + SQR(reserved->b[y][x])) / 327.68f; + if (execmunsell) { Color::AllMunsellLch(true, Lprov1, Lprov2, HH, Chprov, memChprov, correctionHue, correctlum); } @@ -12580,15 +13244,18 @@ void ImProcFunctions::avoidcolshi(const struct local_params& lp, int sp, LabImag void maskrecov(const LabImage * bufcolfin, LabImage * original, LabImage * bufmaskblurcol, int bfh, int bfw, int ystart, int xstart, float hig, float low, float recoth, float decay, bool invmask, int sk, bool multiThread) { LabImage tmp3(bfw, bfh); - for (int y = 0; y < bfh; y++){ + + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { tmp3.L[y][x] = original->L[y + ystart][x + xstart]; tmp3.a[y][x] = original->a[y + ystart][x + xstart]; tmp3.b[y][x] = original->b[y + ystart][x + xstart]; } } + array2D masklum; masklum(bfw, bfh); + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { masklum[ir][jr] = 1.f; @@ -12599,22 +13266,25 @@ void maskrecov(const LabImage * bufcolfin, LabImage * original, LabImage * bufma float lowc; calcdif(low, lowc); - if(higc < lowc) { + if (higc < lowc) { higc = lowc + 0.01f; } + float th = (recoth - 1.f); float ahigh = th / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - float alow = th / lowc; + float alow = th / lowc; float blow = 1.f - th; #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float lM = bufmaskblurcol->L[ir][jr]; const float lmr = lM / 327.68f; + if (lM < 327.68f * lowc) { masklum[ir][jr] = alow * lmr + blow; } else if (lM < 327.68f * higc) { @@ -12622,8 +13292,10 @@ void maskrecov(const LabImage * bufcolfin, LabImage * original, LabImage * bufma } else { masklum[ir][jr] = ahigh * lmr + bhigh; } + float k = masklum[ir][jr]; - if(invmask == false) { + + if (invmask == false) { masklum[ir][jr] = 1 - pow(k, decay); } else { masklum[ir][jr] = pow(k, decay); @@ -12632,21 +13304,23 @@ void maskrecov(const LabImage * bufcolfin, LabImage * original, LabImage * bufma } } - for (int i = 0; i < 3; ++i) { - boxblur(static_cast(masklum), static_cast(masklum), 10 / sk, bfw, bfh, false); - } + for (int i = 0; i < 3; ++i) { + boxblur(static_cast(masklum), static_cast(masklum), 10 / sk, bfw, bfh, false); + } #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif - for (int i = 0; i < bfh; ++i) { - for (int j = 0; j < bfw; ++j) { - bufcolfin->L[i][j] = (tmp3.L[i][j] - bufcolfin->L[i][j]) * LIM01(masklum[i][j]) + bufcolfin->L[i][j]; - bufcolfin->a[i][j] = (tmp3.a[i][j] - bufcolfin->a[i][j]) * LIM01(masklum[i][j]) + bufcolfin->a[i][j]; - bufcolfin->b[i][j] = (tmp3.b[i][j] - bufcolfin->b[i][j]) * LIM01(masklum[i][j]) + bufcolfin->b[i][j]; - } + + for (int i = 0; i < bfh; ++i) { + for (int j = 0; j < bfw; ++j) { + bufcolfin->L[i][j] = (tmp3.L[i][j] - bufcolfin->L[i][j]) * LIM01(masklum[i][j]) + bufcolfin->L[i][j]; + bufcolfin->a[i][j] = (tmp3.a[i][j] - bufcolfin->a[i][j]) * LIM01(masklum[i][j]) + bufcolfin->a[i][j]; + bufcolfin->b[i][j] = (tmp3.b[i][j] - bufcolfin->b[i][j]) * LIM01(masklum[i][j]) + bufcolfin->b[i][j]; } - masklum.free(); + } + + masklum.free(); } //thanks to Alberto Griggio @@ -12656,33 +13330,33 @@ void ImProcFunctions::detail_mask(const array2D &src, array2D &mas const int H = bfh; mask(W, H); - array2D L2(W/4, H/4);//ARRAY2D_ALIGNED); - array2D m2(W/4, H/4);//ARRAY2D_ALIGNED) + array2D L2(W / 4, H / 4); //ARRAY2D_ALIGNED); + array2D m2(W / 4, H / 4); //ARRAY2D_ALIGNED) rescaleBilinear(src, L2, multithread); #ifdef _OPENMP -# pragma omp parallel for if (multithread) + # pragma omp parallel for if (multithread) #endif - for (int y = 0; y < H/4; ++y) { - for (int x = 0; x < W/4; ++x) { - L2[y][x] = xlin2log(L2[y][x]/scaling, 50.f); + + for (int y = 0; y < H / 4; ++y) { + for (int x = 0; x < W / 4; ++x) { + L2[y][x] = xlin2log(L2[y][x] / scaling, 50.f); } } - - laplacian(L2, m2, W / 4, H / 4, threshold/scaling, ceiling/scaling, factor, multithread); + + laplacian(L2, m2, W / 4, H / 4, threshold / scaling, ceiling / scaling, factor, multithread); rescaleBilinear(m2, mask, multithread); const auto scurve = - [](float x) -> float - { - constexpr float b = 101.f; - constexpr float a = 2.23f; - return xlin2log(pow_F(x, a), b); - }; + [](float x) -> float { + constexpr float b = 101.f; + constexpr float a = 2.23f; + return xlin2log(pow_F(x, a), b); + }; const float thr = 1.f - factor; #ifdef _OPENMP -# pragma omp parallel for if (multithread) + # pragma omp parallel for if (multithread) #endif for (int y = 0; y < H; ++y) { @@ -12692,9 +13366,9 @@ void ImProcFunctions::detail_mask(const array2D &src, array2D &mas } if (blur_type == BlurType::GAUSS) { - + #ifdef _OPENMP -# pragma omp parallel if (multithread) + # pragma omp parallel if (multithread) #endif { gaussianBlur(mask, mask, W, H, blur); @@ -12706,7 +13380,7 @@ void ImProcFunctions::detail_mask(const array2D &src, array2D &mas } } } - + } // basic idea taken from Algorithm 3 in the paper: @@ -12723,11 +13397,12 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int if (!strength) { return; } - // printf("Scale=%f\n", scale); - if(scale > 5.f) {//avoid to small values - leads to crash - but enough to evaluate noise + + // printf("Scale=%f\n", scale); + if (scale > 5.f) { //avoid to small values - leads to crash - but enough to evaluate noise return; } - BENCHFUN + // BENCHFUN const int W = bfw; const int H = bfh; // printf("W=%i H=%i\n", W, H); @@ -12740,19 +13415,24 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int //first change Lab L to pseudo linear with gamma = 3.f slope 9.032...and in range 0...65536, or with gamma slope Lab #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multithread) + # pragma omp parallel for schedule(dynamic,16) if (multithread) #endif + for (int y = 0; y < H; ++y) { int x = 0; #ifdef __SSE2__ + for (; x < W - 3; x += 4) { STVFU(img[y][x], F2V(65536.f) * igammalog(LVFU(img[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < W; ++x) { + + for (; x < W; ++x) { img[y][x] = 65536.f * igammalog(img[y][x] / 32768.f, gamma, ts, g_a[2], g_a[4]); } } + // these two can be changed if needed. increasing max_patch_radius doesn't // affect performance, whereas max_search_radius *really* does // (the complexity is O(max_search_radius^2 * W * H)) @@ -12780,44 +13460,49 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int // modified by compression and offsetting depending on the detail_thresh // parameter, i.e. mask[y][x] = mask[y][x] * (1 - f) + f, // where f = detail_thresh / 100 - float amount = LIM(float(detail_thresh)/100.f, 0.f, 0.99f); + float amount = LIM(float(detail_thresh) / 100.f, 0.f, 0.99f); array2D mask(W, H);// ARRAY2D_ALIGNED); - + { array2D LL(W, H, img, ARRAY2D_BYREFERENCE); ImProcFunctions::detail_mask(LL, mask, W, H, 1.f, 1e-3f, 1.f, amount, BlurType::GAUSS, 2.f / scale, multithread); } - + //allocate dst - same type of datas as img float** dst; int wid = W; int hei = H; dst = new float*[hei]; + for (int i = 0; i < hei; ++i) { - dst[i] = new float[wid]; + dst[i] = new float[wid]; } + const int border = search_radius + patch_radius; const int WW = W + border * 2; const int HH = H + border * 2; array2D src(WW, HH);//, ARRAY2D_ALIGNED); - + #ifdef _OPENMP -# pragma omp parallel for if (multithread) + # pragma omp parallel for if (multithread) #endif + for (int y = 0; y < HH; ++y) { - int yy = y <= border ? 0 : y - border >= H ? H-1 : y - border; + int yy = y <= border ? 0 : y - border >= H ? H - 1 : y - border; + for (int x = 0; x < WW; ++x) { - int xx = x <= border ? 0 : x - border >= W ? W-1 : x - border; + int xx = x <= border ? 0 : x - border >= W ? W - 1 : x - border; float Y = img[yy][xx] / 65536.f; src[y][x] = Y; } } #ifdef _OPENMP -# pragma omp parallel for if (multithread) + # pragma omp parallel for if (multithread) #endif + for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { dst[y][x] = 0.f; @@ -12825,27 +13510,29 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int } constexpr int lutsz = 8192; - constexpr float lutfactor = 100.f / float(lutsz-1); + constexpr float lutfactor = 100.f / float(lutsz - 1); LUTf explut(lutsz); + for (int i = 0; i < lutsz; ++i) { float x = float(i) * lutfactor; explut[i] = xexpf(-x); } #ifdef _OPENMP -# pragma omp parallel for if (multithread) + # pragma omp parallel for if (multithread) #endif + for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { mask[y][x] = (1.f / (mask[y][x] * h2)) / lutfactor; } } - + // process by tiles to avoid numerical accuracy errors in the computation // of the integral image const int tile_size = 150; - const int ntiles_x = int(std::ceil(float(WW) / (tile_size-2*border))); - const int ntiles_y = int(std::ceil(float(HH) / (tile_size-2*border))); + const int ntiles_x = int(std::ceil(float(WW) / (tile_size - 2 * border))); + const int ntiles_y = int(std::ceil(float(HH) / (tile_size - 2 * border))); const int ntiles = ntiles_x * ntiles_y; #ifdef __SSE2__ @@ -12855,147 +13542,162 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int #endif #ifdef _OPENMP - #pragma omp parallel if (multithread) + #pragma omp parallel if (multithread) #endif { #ifdef __SSE2__ - // flush denormals to zero to avoid performance penalty - const auto oldMode = _MM_GET_FLUSH_ZERO_MODE(); - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + // flush denormals to zero to avoid performance penalty + const auto oldMode = _MM_GET_FLUSH_ZERO_MODE(); + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); #endif - + #ifdef _OPENMP - #pragma omp for schedule(dynamic, 2) + #pragma omp for schedule(dynamic, 2) #endif - for (int tile = 0; tile < ntiles; ++tile) { - const int tile_y = tile / ntiles_x; - const int tile_x = tile % ntiles_x; - const int start_y = tile_y * (tile_size - 2*border); - const int end_y = std::min(start_y + tile_size, HH); - const int TH = end_y - start_y; + for (int tile = 0; tile < ntiles; ++tile) { + const int tile_y = tile / ntiles_x; + const int tile_x = tile % ntiles_x; - const int start_x = tile_x * (tile_size - 2*border); - const int end_x = std::min(start_x + tile_size, WW); - const int TW = end_x - start_x; + const int start_y = tile_y * (tile_size - 2 * border); + const int end_y = std::min(start_y + tile_size, HH); + const int TH = end_y - start_y; - const auto Yf = [=](int y) -> int { return LIM(y+start_y, 0, HH-1); }; - const auto Xf = [=](int x) -> int { return LIM(x+start_x, 0, WW-1); }; + const int start_x = tile_x * (tile_size - 2 * border); + const int end_x = std::min(start_x + tile_size, WW); + const int TW = end_x - start_x; - const auto score = - [&](int tx, int ty, int zx, int zy) -> float - { + const auto Yf = [ = ](int y) -> int { return LIM(y + start_y, 0, HH - 1); }; + const auto Xf = [ = ](int x) -> int { return LIM(x + start_x, 0, WW - 1); }; + + const auto score = + [&](int tx, int ty, int zx, int zy) -> float { return SQR(src[Yf(zy)][Xf(zx)] - src[Yf(zy + ty)][Xf(zx + tx)]); }; - array2D St(TW, TH);//, ARRAY2D_ALIGNED); - array2D SW(TW, TH, ARRAY2D_CLEAR_DATA);//, ARRAY2D_ALIGNED|ARRAY2D_CLEAR_DATA); + array2D St(TW, TH);//, ARRAY2D_ALIGNED); + array2D SW(TW, TH, ARRAY2D_CLEAR_DATA);//, ARRAY2D_ALIGNED|ARRAY2D_CLEAR_DATA); + + for (int ty = -search_radius; ty <= search_radius; ++ty) { + for (int tx = -search_radius; tx <= search_radius; ++tx) { + // Step 1 — Compute the integral image St + St[0][0] = 0.f; - for (int ty = -search_radius; ty <= search_radius; ++ty) { - for (int tx = -search_radius; tx <= search_radius; ++tx) { - // Step 1 — Compute the integral image St - St[0][0] = 0.f; - for (int xx = 1; xx < TW; ++xx) { - St[0][xx] = St[0][xx-1] + score(tx, ty, xx, 0); - } - for (int yy = 1; yy < TH; ++yy) { - St[yy][0] = St[yy-1][0] + score(tx, ty, 0, yy); - } - for (int yy = 1; yy < TH; ++yy) { for (int xx = 1; xx < TW; ++xx) { - // operation grouping tuned for performance (empirically) - St[yy][xx] = (St[yy][xx-1] + St[yy-1][xx]) - (St[yy-1][xx-1] - score(tx, ty, xx, yy)); + St[0][xx] = St[0][xx - 1] + score(tx, ty, xx, 0); } - } - // Step 2 — Compute weight and estimate for patches - // V(x), V(y) with y = x + t - for (int yy = start_y+border; yy < end_y-border; ++yy) { - int y = yy - border; - int xx = start_x+border; + + for (int yy = 1; yy < TH; ++yy) { + St[yy][0] = St[yy - 1][0] + score(tx, ty, 0, yy); + } + + for (int yy = 1; yy < TH; ++yy) { + for (int xx = 1; xx < TW; ++xx) { + // operation grouping tuned for performance (empirically) + St[yy][xx] = (St[yy][xx - 1] + St[yy - 1][xx]) - (St[yy - 1][xx - 1] - score(tx, ty, xx, yy)); + } + } + + // Step 2 — Compute weight and estimate for patches + // V(x), V(y) with y = x + t + for (int yy = start_y + border; yy < end_y - border; ++yy) { + int y = yy - border; + int xx = start_x + border; #ifdef __SSE2__ - for (; xx < end_x-border-3; xx += 4) { - int x = xx - border; - int sx = xx + tx; - int sy = yy + ty; - int sty = yy - start_y; - int stx = xx - start_x; - - vfloat dist2 = LVFU(St[sty + patch_radius][stx + patch_radius]) + LVFU(St[sty - patch_radius][stx - patch_radius]) - LVFU(St[sty + patch_radius][stx - patch_radius]) - LVFU(St[sty - patch_radius][stx + patch_radius]); - dist2 = vmaxf(dist2, zerov); - vfloat d = dist2 * LVFU(mask[y][x]); - vfloat weight = explut[d]; - STVFU(SW[y-start_y][x-start_x], LVFU(SW[y-start_y][x-start_x]) + weight); - vfloat Y = weight * LVFU(src[sy][sx]); - STVFU(dst[y][x], LVFU(dst[y][x]) + Y); - } + for (; xx < end_x - border - 3; xx += 4) { + int x = xx - border; + int sx = xx + tx; + int sy = yy + ty; + + int sty = yy - start_y; + int stx = xx - start_x; + + vfloat dist2 = LVFU(St[sty + patch_radius][stx + patch_radius]) + LVFU(St[sty - patch_radius][stx - patch_radius]) - LVFU(St[sty + patch_radius][stx - patch_radius]) - LVFU(St[sty - patch_radius][stx + patch_radius]); + dist2 = vmaxf(dist2, zerov); + vfloat d = dist2 * LVFU(mask[y][x]); + vfloat weight = explut[d]; + STVFU(SW[y - start_y][x - start_x], LVFU(SW[y - start_y][x - start_x]) + weight); + vfloat Y = weight * LVFU(src[sy][sx]); + STVFU(dst[y][x], LVFU(dst[y][x]) + Y); + } + #endif - for (; xx < end_x-border; ++xx) { - int x = xx - border; - int sx = xx + tx; - int sy = yy + ty; - int sty = yy - start_y; - int stx = xx - start_x; - - float dist2 = St[sty + patch_radius][stx + patch_radius] + St[sty - patch_radius][stx - patch_radius] - St[sty + patch_radius][stx - patch_radius] - St[sty - patch_radius][stx + patch_radius]; - dist2 = std::max(dist2, 0.f); - float d = dist2 * mask[y][x]; - float weight = explut[d]; - SW[y-start_y][x-start_x] += weight; - float Y = weight * src[sy][sx]; - dst[y][x] += Y; + for (; xx < end_x - border; ++xx) { + int x = xx - border; + int sx = xx + tx; + int sy = yy + ty; - assert(!xisinff(dst[y][x])); - assert(!xisnanf(dst[y][x])); + int sty = yy - start_y; + int stx = xx - start_x; + + float dist2 = St[sty + patch_radius][stx + patch_radius] + St[sty - patch_radius][stx - patch_radius] - St[sty + patch_radius][stx - patch_radius] - St[sty - patch_radius][stx + patch_radius]; + dist2 = std::max(dist2, 0.f); + float d = dist2 * mask[y][x]; + float weight = explut[d]; + SW[y - start_y][x - start_x] += weight; + float Y = weight * src[sy][sx]; + dst[y][x] += Y; + + assert(!xisinff(dst[y][x])); + assert(!xisnanf(dst[y][x])); + } } } } - } + // printf("E\n"); - - // Compute final estimate at pixel x = (x1, x2) - for (int yy = start_y+border; yy < end_y-border; ++yy) { - int y = yy - border; - int xx = start_x+border; -#ifdef __SSE2__ - for (; xx < end_x-border-3; xx += 4) { - int x = xx - border; - - const vfloat Y = LVFU(dst[y][x]); - const vfloat f = (v1e_5f + LVFU(SW[y-start_y][x-start_x])); - STVFU(dst[y][x], (Y / f) * v65536f); - } -#endif - for (; xx < end_x-border; ++xx) { - int x = xx - border; - - const float Y = dst[y][x]; - const float f = (1e-5f + SW[y-start_y][x-start_x]); - dst[y][x] = (Y / f) * 65536.f; - assert(!xisnanf(dst[y][x])); + // Compute final estimate at pixel x = (x1, x2) + for (int yy = start_y + border; yy < end_y - border; ++yy) { + int y = yy - border; + int xx = start_x + border; +#ifdef __SSE2__ + + for (; xx < end_x - border - 3; xx += 4) { + int x = xx - border; + + const vfloat Y = LVFU(dst[y][x]); + const vfloat f = (v1e_5f + LVFU(SW[y - start_y][x - start_x])); + STVFU(dst[y][x], (Y / f) * v65536f); + } + +#endif + + for (; xx < end_x - border; ++xx) { + int x = xx - border; + + const float Y = dst[y][x]; + const float f = (1e-5f + SW[y - start_y][x - start_x]); + dst[y][x] = (Y / f) * 65536.f; + + assert(!xisnanf(dst[y][x])); + } } } - } #ifdef __SSE2__ - _MM_SET_FLUSH_ZERO_MODE(oldMode); + _MM_SET_FLUSH_ZERO_MODE(oldMode); #endif } // omp parallel #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multithread) + # pragma omp parallel for schedule(dynamic,16) if (multithread) #endif + for (int y = 0; y < H; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < W - 3; x += 4) { STVFU(img[y][x], F2V(32768.f) * gammalog(LVFU(dst[y][x]) / F2V(65536.f), F2V(gamma), F2V(ts), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < W; ++x) { img[y][x] = 32768.f * gammalog(dst[y][x] / 65536.f, gamma, ts, g_a[3], g_a[4]); } @@ -13004,8 +13706,9 @@ void ImProcFunctions::NLMeans(float **img, int strength, int detail_thresh, int for (int i = 0; i < hei; ++i) { delete[] dst[i]; } + delete[] dst; - + } void ImProcFunctions::Lab_Local( @@ -13034,7 +13737,7 @@ void ImProcFunctions::Lab_Local( const LUTf& czlocalcurve, bool localczutili, const LUTf& czjzlocalcurve, bool localczjzutili, - const LocCCmaskCurve& locccmasCurve, bool lcmasutili, const LocLLmaskCurve& locllmasCurve, bool llmasutili, const LocHHmaskCurve& lochhmasCurve, bool lhmasutili, const LocHHmaskCurve& llochhhmasCurve, bool lhhmasutili, + const LocCCmaskCurve& locccmasCurve, bool lcmasutili, const LocLLmaskCurve& locllmasCurve, bool llmasutili, const LocHHmaskCurve& lochhmasCurve, bool lhmasutili, const LocHHmaskCurve& llochhhmasCurve, bool lhhmasutili, const LocHHmaskCurve& llochhhmascieCurve, bool lhhmascieutili, const LocCCmaskCurve& locccmasexpCurve, bool lcmasexputili, const LocLLmaskCurve& locllmasexpCurve, bool llmasexputili, const LocHHmaskCurve& lochhmasexpCurve, bool lhmasexputili, const LocCCmaskCurve& locccmasSHCurve, bool lcmasSHutili, const LocLLmaskCurve& locllmasSHCurve, bool llmasSHutili, const LocHHmaskCurve& lochhmasSHCurve, bool lhmasSHutili, const LocCCmaskCurve& locccmasvibCurve, bool lcmasvibutili, const LocLLmaskCurve& locllmasvibCurve, bool llmasvibutili, const LocHHmaskCurve& lochhmasvibCurve, bool lhmasvibutili, @@ -13050,6 +13753,7 @@ void ImProcFunctions::Lab_Local( const LocHHmaskCurve& lochhhmas_Curve, bool lhhmas_utili, const LocwavCurve& loclmasCurveblwav, bool lmasutiliblwav, const LocwavCurve& loclmasCurvecolwav, bool lmasutilicolwav, + const LocwavCurve& loclmasCurveciewav, bool lmasutiliciewav, const LocwavCurve& locwavCurve, bool locwavutili, const LocwavCurve& locwavCurvejz, bool locwavutilijz, const LocwavCurve& loclevwavCurve, bool loclevwavutili, @@ -13060,12 +13764,12 @@ void ImProcFunctions::Lab_Local( const LocwavCurve& locwavCurveden, bool locwavdenutili, const LocwavCurve& locedgwavCurve, bool locedgwavutili, const LocwavCurve& loclmasCurve_wav, bool lmasutili_wav, - + bool LHutili, bool HHutili, bool CHutili, bool HHutilijz, bool CHutilijz, bool LHutilijz, const LUTf& cclocalcurve, bool localcutili, const LUTf& rgblocalcurve, bool localrgbutili, bool localexutili, const LUTf& exlocalcurve, const LUTf& hltonecurveloc, const LUTf& shtonecurveloc, const LUTf& tonecurveloc, const LUTf& lightCurveloc, double& huerefblur, double& chromarefblur, double& lumarefblur, double& hueref, double& chromaref, double& lumaref, double& sobelref, int &lastsav, - bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, + bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float& minCD, float& maxCD, float& mini, float& maxi, float& Tmean, float& Tsigma, float& Tmin, float& Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab,float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &ill, float &contsig, float &lightsig, float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46 ) @@ -13111,6 +13815,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif + for (int y = rtengine::max(begy - cy, 0); y < rtengine::min(yEn - cy, original->H); y++) { const int loy = cy + y; @@ -13131,6 +13836,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { ble[ir][jr] /= 32768.f; @@ -13154,6 +13860,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(+:sombel) if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float val = ble[ir][jr] * 32768.f; @@ -13167,8 +13874,8 @@ void ImProcFunctions::Lab_Local( } //encoding lab at the beginning - if (lp.logena && (call <=3 || lp.prevdE || lp.showmasklogmet == 2 || lp.enaLMask || lp.showmasklogmet == 3 || lp.showmasklogmet == 4)) { - + if (lp.logena && (call <= 3 || lp.prevdE || lp.showmasklogmet == 2 || lp.enaLMask || lp.showmasklogmet == 3 || lp.showmasklogmet == 4)) { + const int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); const int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); const int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); @@ -13193,6 +13900,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufexporig->L[y - ystart][x - xstart] = original->L[y][x]; @@ -13232,6 +13940,7 @@ void ImProcFunctions::Lab_Local( if (lp.showmasklogmet == 0) { zero = true; } + float chrom = lp.chromaL; float rad = lp.radmaL; float blendm = lp.blendmaL; @@ -13266,6 +13975,7 @@ void ImProcFunctions::Lab_Local( return; } + if (lp.showmasklogmet == 0 || lp.showmasklogmet == 1 || lp.showmasklogmet == 2 || lp.showmasklogmet == 4 || lp.enaLMask) { bufexpfin->CopyFrom(bufexporig.get(), multiThread); @@ -13275,35 +13985,40 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - tmpImageorig->r(y, x) = tmpImage->r(y, x); - tmpImageorig->g(y, x) = tmpImage->g(y, x); - tmpImageorig->b(y, x) = tmpImage->b(y, x); - } + + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + tmpImageorig->r(y, x) = tmpImage->r(y, x); + tmpImageorig->g(y, x) = tmpImage->g(y, x); + tmpImageorig->b(y, x) = tmpImage->b(y, x); } - + } + log_encode(tmpImage.get(), lp, multiThread, bfw, bfh); + + const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).repar; - + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - tmpImage->r(y, x) = intp(repart, tmpImageorig->r(y, x), tmpImage->r(y, x)); - tmpImage->g(y, x) = intp(repart, tmpImageorig->g(y, x), tmpImage->g(y, x)); - tmpImage->b(y, x) = intp(repart, tmpImageorig->b(y, x), tmpImage->b(y, x)); - } + + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + tmpImage->r(y, x) = intp(repart, tmpImageorig->r(y, x), tmpImage->r(y, x)); + tmpImage->g(y, x) = intp(repart, tmpImageorig->g(y, x), tmpImage->g(y, x)); + tmpImage->b(y, x) = intp(repart, tmpImageorig->b(y, x), tmpImage->b(y, x)); } - + } + rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); - + tmpImageorig.reset(); tmpImage.reset(); + if (params->locallab.spots.at(sp).ciecam) { - bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false;; - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 1, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 1, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); } @@ -13311,11 +14026,12 @@ void ImProcFunctions::Lab_Local( bool HHcurvejz = false; bool CHcurvejz = false; bool LHcurvejz = false; + if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); } - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(),bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); float rad = params->locallab.spots.at(sp).detailcie; loccont(bfw, bfh, bufexpfin.get(), rad, 15.f, sk); @@ -13327,37 +14043,40 @@ void ImProcFunctions::Lab_Local( struct grad_params gplog; calclocalGradientParams(lp, gplog, ystart, xstart, bfw, bfh, 11); #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gplog, jr, ir); } } } - //end graduated - float recoth = lp.recothrl; + //end graduated - if(lp.recothrl < 1.f) { - recoth = -1.f * recoth + 2.f; - } + float recoth = lp.recothrl; - if(lp.enaLMask && lp.recothrl != 1.f) { - float hig = lp.higthrl; - float low = lp.lowthrl; - // float recoth = lp.recothrl; - float decay = lp.decayl; - bool invmask = false; - maskrecov(bufexpfin.get(), original, bufmaskoriglog.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); - } - if(lp.recothrl >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), originalmasklog.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); - } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); - } + if (lp.recothrl < 1.f) { + recoth = -1.f * recoth + 2.f; + } + + if (lp.enaLMask && lp.recothrl != 1.f) { + float hig = lp.higthrl; + float low = lp.lowthrl; + // float recoth = lp.recothrl; + float decay = lp.decayl; + bool invmask = false; + maskrecov(bufexpfin.get(), original, bufmaskoriglog.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); + } + + if (lp.recothrl >= 1.f) { + transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), originalmasklog.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + } else { + transit_shapedetect2(sp, 0.f, 0.f, call, 11, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + } } - + if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; @@ -13393,12 +14112,13 @@ void ImProcFunctions::Lab_Local( if (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) { bufmaskorigbl.reset(new LabImage(TW, TH)); bufmaskblurbl.reset(new LabImage(TW, TH, true)); - originalmaskbl.reset (new LabImage(TW, TH)); + originalmaskbl.reset(new LabImage(TW, TH)); } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH; y++) { for (int x = 0; x < TW; x++) { bufblorig->L[y][x] = original->L[y][x]; @@ -13516,6 +14236,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { tmp1->L[y - ystart][x - xstart] = original->L[y][x]; @@ -13566,12 +14287,15 @@ void ImProcFunctions::Lab_Local( #pragma omp parallel if (multiThread) #endif { - if (lp.chromet == 0) { + if (lp.chromet == 0) + { gaussianBlur(tmp1->L, tmp1->L, bfw, bfh, radius); - } else if (lp.chromet == 1) { + } else if (lp.chromet == 1) + { gaussianBlur(tmp1->a, tmp1->a, bfw, bfh, radius); gaussianBlur(tmp1->b, tmp1->b, bfw, bfh, radius); - } else if (lp.chromet == 2) { + } else if (lp.chromet == 2) + { gaussianBlur(tmp1->L, tmp1->L, bfw, bfh, radius); gaussianBlur(tmp1->a, tmp1->a, bfw, bfh, radius); gaussianBlur(tmp1->b, tmp1->b, bfw, bfh, radius); @@ -13596,12 +14320,15 @@ void ImProcFunctions::Lab_Local( #pragma omp parallel if (multiThread) #endif { - if (lp.chromet == 0) { + if (lp.chromet == 0) + { gaussianBlur(original->L, tmp1->L, TW, TH, radius); - } else if (lp.chromet == 1) { + } else if (lp.chromet == 1) + { gaussianBlur(original->a, tmp1->a, TW, TH, radius); gaussianBlur(original->b, tmp1->b, TW, TH, radius); - } else if (lp.chromet == 2) { + } else if (lp.chromet == 2) + { gaussianBlur(original->L, tmp1->L, TW, TH, radius); gaussianBlur(original->a, tmp1->a, TW, TH, radius); gaussianBlur(original->b, tmp1->b, TW, TH, radius); @@ -13730,6 +14457,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { tmp1->L[y - ystart][x - xstart] = original->L[y][x]; @@ -13749,11 +14477,12 @@ void ImProcFunctions::Lab_Local( array2D gg(bfw, bfh); array2D bb(bfw, bfh); array2D guide(bfw, bfh); - - + + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { LL[y][x] = tmp1->L[y][x]; @@ -13765,6 +14494,7 @@ void ImProcFunctions::Lab_Local( } } + array2D iR(bfw, bfh, rr, 0); array2D iG(bfw, bfh, gg, 0); array2D iB(bfw, bfh, bb, 0); @@ -13788,11 +14518,12 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { - rr[y][x] = intp(lp.strbl, rr[y][x] , iR[y][x]); - gg[y][x] = intp(lp.strbl, gg[y][x] , iG[y][x]); - bb[y][x] = intp(lp.strbl, bb[y][x] , iB[y][x]); + rr[y][x] = intp(lp.strbl, rr[y][x], iR[y][x]); + gg[y][x] = intp(lp.strbl, gg[y][x], iG[y][x]); + bb[y][x] = intp(lp.strbl, bb[y][x], iB[y][x]); tmpImage->r(y, x) = rr[y][x]; tmpImage->g(y, x) = gg[y][x]; tmpImage->b(y, x) = bb[y][x]; @@ -13806,16 +14537,19 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { - LL[y][x] = intp(lp.strbl, LL[y][x] , iL[y][x]); + LL[y][x] = intp(lp.strbl, LL[y][x], iL[y][x]); tmp1->L[y][x] = LL[y][x]; } } } - if(lp.enablMask && lp.recothr != 1.f && lp.smasktyp != 1) { + + if (lp.enablMask && lp.recothr != 1.f && lp.smasktyp != 1) { array2D masklum; masklum(bfw, bfh); + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { masklum[ir][jr] = 1.f; @@ -13828,33 +14562,37 @@ void ImProcFunctions::Lab_Local( float lowc; calcdif(low, lowc); - if(higc < lowc) { + if (higc < lowc) { higc = lowc + 0.01f; } + float th = (lp.recothr - 1.f); float ahigh = th / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - float alow = th / lowc; + float alow = th / lowc; float blow = 1.f - th; - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { const float lM = bufmaskblurbl->L[ir + ystart][jr + xstart]; const float lmr = lM / 327.68f; + if (lM < 327.68f * lowc) { masklum[ir][jr] = alow * lmr + blow; } else if (lM < 327.68f * higc) { - + } else { masklum[ir][jr] = ahigh * lmr + bhigh; } - if(lp.invmask == true) { + + if (lp.invmask == true) { float k = masklum[ir][jr]; - masklum[ir][jr] = 1 - k*k; + masklum[ir][jr] = 1 - k * k; } } @@ -13863,8 +14601,9 @@ void ImProcFunctions::Lab_Local( } #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < bfh; ++i) { for (int j = 0; j < bfw; ++j) { tmp1->L[i][j] = (tmp3->L[i][j] - tmp1->L[i][j]) * LIM01(masklum[i][j]) + tmp1->L[i][j]; @@ -13872,6 +14611,7 @@ void ImProcFunctions::Lab_Local( tmp1->b[i][j] = (tmp3->b[i][j] - tmp1->b[i][j]) * LIM01(masklum[i][j]) + tmp1->b[i][j]; } } + masklum.free(); } @@ -13884,6 +14624,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { tmp1->L[y][x] = original->L[y][x]; @@ -13908,6 +14649,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { LL[y][x] = tmp1->L[y][x]; @@ -13943,11 +14685,12 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { - rr[y][x] = intp(lp.strbl, rr[y][x] , iR[y][x]); - gg[y][x] = intp(lp.strbl, gg[y][x] , iG[y][x]); - bb[y][x] = intp(lp.strbl, bb[y][x] , iB[y][x]); + rr[y][x] = intp(lp.strbl, rr[y][x], iR[y][x]); + gg[y][x] = intp(lp.strbl, gg[y][x], iG[y][x]); + bb[y][x] = intp(lp.strbl, bb[y][x], iB[y][x]); tmpImage->r(y, x) = rr[y][x]; tmpImage->g(y, x) = gg[y][x]; tmpImage->b(y, x) = bb[y][x]; @@ -13961,16 +14704,19 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { - LL[y][x] = intp(lp.strbl, LL[y][x] , iL[y][x]); + LL[y][x] = intp(lp.strbl, LL[y][x], iL[y][x]); tmp1->L[y][x] = LL[y][x]; } } } - if(lp.enablMask && lp.recothr != 1.f && lp.smasktyp != 1) { + + if (lp.enablMask && lp.recothr != 1.f && lp.smasktyp != 1) { array2D masklum; masklum(TW, TH); + for (int ir = 0; ir < TH; ir++) for (int jr = 0; jr < TW; jr++) { masklum[ir][jr] = 1.f; @@ -13983,27 +14729,30 @@ void ImProcFunctions::Lab_Local( float lowc; calcdif(low, lowc); - if(higc < lowc) { + if (higc < lowc) { higc = lowc + 0.01f; } + float th = (lp.recothr - 1.f); float ahigh = th / (higc - 100.f); float bhigh = 1.f - higc * ahigh; - float alow = th / lowc; + float alow = th / lowc; float blow = 1.f - th; - + #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < TH; ir++) for (int jr = 0; jr < TW; jr++) { const float lM = bufmaskblurbl->L[ir][jr]; const float lmr = lM / 327.68f; + if (lM < 327.68f * lowc) { masklum[ir][jr] = alow * lmr + blow; } else if (lM < 327.68f * higc) { - + } else { masklum[ir][jr] = (ahigh * lmr + bhigh); } @@ -14014,8 +14763,9 @@ void ImProcFunctions::Lab_Local( } #ifdef _OPENMP - #pragma omp parallel for if (multiThread) + #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < TH; ++i) { for (int j = 0; j < TW; ++j) { tmp1->L[i][j] = (tmp3->L[i][j] - tmp1->L[i][j]) * LIM01(masklum[i][j]) + tmp1->L[i][j]; @@ -14023,6 +14773,7 @@ void ImProcFunctions::Lab_Local( tmp1->b[i][j] = (tmp3->b[i][j] - tmp1->b[i][j]) * LIM01(masklum[i][j]) + tmp1->b[i][j]; } } + masklum.free(); } @@ -14033,8 +14784,8 @@ void ImProcFunctions::Lab_Local( if (tmp1.get()) { if (lp.blurmet == 0) { //blur and noise (center) - - if(lp.smasktyp != 1) { + + if (lp.smasktyp != 1) { BlurNoise_Local(tmp1.get(), originalmaskbl.get(), hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } else { BlurNoise_Local(tmp1.get(), original, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); @@ -14046,8 +14797,8 @@ void ImProcFunctions::Lab_Local( calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); } } else if (lp.blurmet == 1) { - // InverseBlurNoise_Local(originalmaskbl, bufchro, lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); - if(lp.smasktyp != 1) { +// InverseBlurNoise_Local(originalmaskbl, bufchro, lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); + if (lp.smasktyp != 1) { InverseBlurNoise_Local(originalmaskbl.get(), lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); } else { InverseBlurNoise_Local(original, lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); @@ -14082,6 +14833,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = rtengine::max(0, begy - cy); y < rtengine::min(transformed->H, yEn - cy); y++) { const int loy = cy + y; @@ -14136,7 +14888,7 @@ void ImProcFunctions::Lab_Local( const int bfw = xend - xstart; if (bfw >= mDEN && bfh >= mDEN) { - // printf("OK TM\n"); + // printf("OK TM\n"); array2D buflight(bfw, bfh); JaggedArray bufchro(bfw, bfh); std::unique_ptr bufgb(new LabImage(bfw, bfh)); @@ -14158,31 +14910,35 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel if (multiThread) { - #pragma omp for schedule(dynamic,16) nowait + #pragma omp for schedule(dynamic,16) nowait #endif - for (int y = ystart; y < yend; y++) { - for (int x = xstart; x < xend; x++) { - bufgbm->L[y - ystart][x - xstart] = bufgb->L[y - ystart][x - xstart] = original->L[y][x]; + + for (int y = ystart; y < yend; y++) { + for (int x = xstart; x < xend; x++) { + bufgbm->L[y - ystart][x - xstart] = bufgb->L[y - ystart][x - xstart] = original->L[y][x]; + } } - } #ifdef _OPENMP - #pragma omp for schedule(dynamic,16) nowait + #pragma omp for schedule(dynamic,16) nowait #endif - for (int y = ystart; y < yend; y++) { - for (int x = xstart; x < xend; x++) { - bufgbm->a[y - ystart][x - xstart] = bufgb->a[y - ystart][x - xstart] = original->a[y][x]; + + for (int y = ystart; y < yend; y++) { + for (int x = xstart; x < xend; x++) { + bufgbm->a[y - ystart][x - xstart] = bufgb->a[y - ystart][x - xstart] = original->a[y][x]; + } } - } #ifdef _OPENMP - #pragma omp for schedule(dynamic,16) + #pragma omp for schedule(dynamic,16) #endif - for (int y = ystart; y < yend; y++) { - for (int x = xstart; x < xend; x++) { - bufgbm->b[y - ystart][x - xstart] = bufgb->b[y - ystart][x - xstart] = original->b[y][x]; + + for (int y = ystart; y < yend; y++) { + for (int x = xstart; x < xend; x++) { + bufgbm->b[y - ystart][x - xstart] = bufgb->b[y - ystart][x - xstart] = original->b[y][x]; + } } - } + #ifdef _OPENMP } #endif @@ -14261,29 +15017,32 @@ void ImProcFunctions::Lab_Local( constexpr int itera = 0; ImProcFunctions::EPDToneMaplocal(sp, bufgb.get(), tmp1.get(), itera, sk);//iterate to 0 calculate with edgstopping, improve result, call=1 dcrop we can put iterate to 5 - if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "tm") { - bool HHcurvejz = false; - bool CHcurvejz = false; - bool LHcurvejz = false; - if (params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz - ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "tm") { + bool HHcurvejz = false; + bool CHcurvejz = false; + bool LHcurvejz = false; + + if (params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz + ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); + } + + ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); + + float rad = params->locallab.spots.at(sp).detailcie; + loccont(bfw, bfh, tmp1.get(), rad, 15.f, sk); } - ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); - - float rad = params->locallab.spots.at(sp).detailcie; - loccont(bfw, bfh, tmp1.get(), rad, 15.f, sk); - } - tmp1m->CopyFrom(tmp1.get(), multiThread); //save current result7 - if(params->locallab.spots.at(sp).equiltm && params->locallab.spots.at(sp).exptonemap) { - if(call == 3) { + + if (params->locallab.spots.at(sp).equiltm && params->locallab.spots.at(sp).exptonemap) { + if (call == 3) { #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { savenormtm->L[y][x] = tmp1->L[y - ystart][x - xstart]; @@ -14293,6 +15052,7 @@ void ImProcFunctions::Lab_Local( } } } + bool enatmMasktmap = params->locallab.spots.at(sp).enatmMaskaft; if (enatmMasktmap) { @@ -14336,6 +15096,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(max:maxL) reduction(min:minL) reduction(max:maxC) reduction(min:minC) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { buflight[ir][jr] = tmp1->L[ir][jr] - bufgb->L[ir][jr]; @@ -14365,6 +15126,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { buflight[y][x] *= coef; @@ -14372,15 +15134,16 @@ void ImProcFunctions::Lab_Local( } } - if(lp.enatmMask && lp.recothrt != 1.f) { + if (lp.enatmMask && lp.recothrt != 1.f) { float recoth = lp.recothrt; - if(lp.recothrt < 1.f) { + if (lp.recothrt < 1.f) { recoth = -1.f * recoth + 2.f; } + float hig = lp.higthrt; float low = lp.lowthrt; - // float recoth = lp.recothrt; + // float recoth = lp.recothrt; float decay = lp.decayt; bool invmask = false; maskrecov(tmp1.get(), original, bufmaskorigtm.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); @@ -14388,11 +15151,12 @@ void ImProcFunctions::Lab_Local( // transit_shapedetect_retinex(call, 4, bufgb.get(),bufmaskorigtm.get(), originalmasktm.get(), buflight, bufchro, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); - if(lp.recothrt >= 1.f) { + if (lp.recothrt >= 1.f) { transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), originalmasktm.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, meantm, stdtm, call, 8, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } + // transit_shapedetect(8, tmp1.get(), originalmasktm.get(), bufchro, false, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); bufgb.reset(); @@ -14409,7 +15173,7 @@ void ImProcFunctions::Lab_Local( //end TM - if ((lp.dehaze != 0 || lp.prevdE) && lp.retiena ) { + if ((lp.dehaze != 0 || lp.prevdE) && lp.retiena) { int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); @@ -14424,6 +15188,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufexporig->L[y - ystart][x - xstart] = original->L[y][x]; @@ -14476,17 +15241,18 @@ void ImProcFunctions::Lab_Local( bufreti = new LabImage(TW, TH); bufmask = new LabImage(TW, TH); - bufmaskorigreti = new LabImage(TW, TH); + bufmaskorigreti = new LabImage(TW, TH); if (!lp.enaretiMasktmap && lp.enaretiMask) { buforig = new LabImage(TW, TH); buforigmas = new LabImage(TW, TH); - // bufmaskorigreti = new LabImage(GW, GH); + // bufmaskorigreti = new LabImage(GW, GH); } #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < TH; ir++) //fill with 0 for (int jr = 0; jr < TW; jr++) { bufreti->L[ir][jr] = 0.f; @@ -14499,6 +15265,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H ; y++) //{ for (int x = 0; x < transformed->W; x++) { bufreti->L[y][x] = original->L[y][x]; @@ -14508,21 +15275,22 @@ void ImProcFunctions::Lab_Local( bufmask->a[y][x] = original->a[y][x]; bufmask->b[y][x] = original->b[y][x]; - + if (!lp.enaretiMasktmap && lp.enaretiMask) { buforig->L[y][x] = original->L[y][x]; buforig->a[y][x] = original->a[y][x]; buforig->b[y][x] = original->b[y][x]; - // bufmaskorigreti->L[y][x] = original->L[y][x]; - // bufmaskorigreti->a[y][x] = original->a[y][x]; - // bufmaskorigreti->b[y][x] = original->b[y][x]; - - + // bufmaskorigreti->L[y][x] = original->L[y][x]; + // bufmaskorigreti->a[y][x] = original->a[y][x]; + // bufmaskorigreti->b[y][x] = original->b[y][x]; + + } } + float raddE = params->locallab.spots.at(sp).softradiusret; //calc dE and reduction to use in MSR to reduce artifacts @@ -14542,6 +15310,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H ; y++) for (int x = 0; x < transformed->W; x++) { float dE = std::sqrt(SQR(refa - bufreti->a[y][x] / 327.68f) + SQR(refb - bufreti->b[y][x] / 327.68f) + SQR(static_cast(lumaref) - bufreti->b[y][x] / 327.68f)); @@ -14558,6 +15327,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { orig[ir][jr] = bufreti->L[ir][jr]; @@ -14585,11 +15355,13 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { tmpl->L[ir][jr] = orig[ir][jr]; - if(params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti) { - if(call == 3) { + + if (params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti) { + if (call == 3) { savenormreti->L[ir][jr] = tmpl->L[ir][jr]; } } @@ -14602,23 +15374,24 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { datain[ir * Wd + jr] = orig1[ir][jr]; data[ir * Wd + jr] = orig[ir][jr]; } - if(params->locallab.spots.at(sp).equilret){ - if(call == 3) {//improccoordinator - normalize_mean_dt(data, datain, Hd * Wd, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f); - } else if(call == 1) {//dcrop + if (params->locallab.spots.at(sp).equilret) { + if (call == 3) { //improccoordinator + normalize_mean_dt(data, datain, Hd * Wd, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); + } else if (call == 1) { //dcrop float ma = meanreti; float sa = stdreti; - float ma2 = (float) params->locallab.spots.at(sp).sensihs; + float ma2 = (float) params->locallab.spots.at(sp).sensihs; float sa2 = (float) params->locallab.spots.at(sp).sensiv; //printf("ma=%f sa=%f ma2=%f sa2=%f\n", (double) ma, (double) sa, (double) ma2, (double) sa2); //use normalize with mean and stdv - normalize_mean_dt(data, datain, Hd * Wd, 1.f, 1.f, ma, sa, ma2, sa2); + normalize_mean_dt(data, datain, Hd * Wd, 1.f, 1.f, ma, sa, ma2, sa2, 1.); } } @@ -14626,6 +15399,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { tmpl->L[ir][jr] = data[ir * Wd + jr]; @@ -14635,7 +15409,7 @@ void ImProcFunctions::Lab_Local( delete [] data; } - if(lp.enaretiMask && lp.recothrr != 1.f) { + if (lp.enaretiMask && lp.recothrr != 1.f) { float hig = lp.higthrr; float low = lp.lowthrr; float recoth = lp.recothrr; @@ -14649,6 +15423,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(min:minL) reduction(max:maxL) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { buflight[ir][jr] = tmpl->L[ir][jr] - bufreti->L[ir][jr]; @@ -14680,6 +15455,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { @@ -14693,6 +15469,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(max:maxChro) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { maxChro = rtengine::max(maxChro, orig1[ir][jr]); @@ -14721,6 +15498,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { const float Chprov = orig1[ir][jr]; @@ -14744,6 +15522,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(min:minC) reduction(max:maxC) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { bufchro[ir][jr] = std::sqrt(SQR(tmpl->a[ir][jr]) + SQR(tmpl->b[ir][jr])) - orig1[ir][jr]; @@ -14759,6 +15538,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { bufchro[ir][jr] *= coefC; @@ -14789,6 +15569,7 @@ void ImProcFunctions::Lab_Local( delete buforigmas; } } + delete bufreti; } } @@ -14839,6 +15620,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) //fill with 0 for (int jr = 0; jr < bfw; jr++) { bufreti->L[ir][jr] = 0.f; @@ -14852,6 +15634,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufreti->L[y - ystart][x - xstart] = original->L[y][x]; @@ -14888,6 +15671,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { const float dE = std::sqrt(SQR(refa - bufreti->a[y - ystart][x - xstart] / 327.68f) + SQR(refb - bufreti->b[y - ystart][x - xstart] / 327.68f) + SQR(static_cast(lumaref) - bufreti->b[y - ystart][x - xstart] / 327.68f)); @@ -14908,6 +15692,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { orig[ir][jr] = bufreti->L[ir][jr]; @@ -14940,6 +15725,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) for (int jr = 0; jr < Wd; jr += 1) { tmpl->L[ir][jr] = orig[ir][jr]; @@ -14952,6 +15738,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { datain[ir * Wd + jr] = orig1[ir][jr]; @@ -14959,17 +15746,19 @@ void ImProcFunctions::Lab_Local( } } - normalize_mean_dt(data.get(), datain.get(), Hd * Wd, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f); + normalize_mean_dt(data.get(), datain.get(), Hd * Wd, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.); #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { tmpl->L[ir][jr] = data[ir * Wd + jr]; } } } - if(lp.enaretiMask && lp.recothrr != 1.f) { + + if (lp.enaretiMask && lp.recothrr != 1.f) { float hig = lp.higthrr; float low = lp.lowthrr; float recoth = lp.recothrr; @@ -14984,6 +15773,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(min:minL) reduction(max:maxL) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { buflight[ir][jr] = tmpl->L[ir][jr] - bufreti->L[ir][jr]; @@ -14999,6 +15789,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { buflight[ir][jr] *= coef; @@ -15020,6 +15811,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { orig[ir][jr] = std::sqrt(SQR(bufreti->a[ir][jr]) + SQR(bufreti->b[ir][jr])); @@ -15032,6 +15824,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(max:maxChro) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { maxChro = rtengine::max(maxChro, orig1[ir][jr]); @@ -15058,6 +15851,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir += 1) { for (int jr = 0; jr < Wd; jr += 1) { const float Chprov = orig1[ir][jr]; @@ -15079,6 +15873,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(min:minC) reduction(max:maxC) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { bufchro[ir][jr] = std::sqrt(SQR(tmpl->a[ir][jr]) + SQR(tmpl->b[ir][jr])) - orig1[ir][jr]; @@ -15094,6 +15889,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int ir = 0; ir < Hd; ir++) { for (int jr = 0; jr < Wd; jr++) { bufchro[ir][jr] *= coefC; @@ -15116,7 +15912,7 @@ void ImProcFunctions::Lab_Local( delete tmpl; delete bufmask; delete bufmaskorigreti; - + if (!lp.enaretiMasktmap && lp.enaretiMask) { if (buforig) { delete buforig; @@ -15126,6 +15922,7 @@ void ImProcFunctions::Lab_Local( delete buforigmas; } } + delete bufreti; } } @@ -15140,6 +15937,7 @@ void ImProcFunctions::Lab_Local( const int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); int bfh = yend - ystart; int bfw = xend - xstart; + if (bfw > 65 && bfh > 65) { array2D bufsh(bfw, bfh); JaggedArray bufchrom(bfw, bfh, true); @@ -15158,6 +15956,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { loctemp->L[y - ystart][x - xstart] = original->L[y][x]; @@ -15242,6 +16041,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufsh[y - ystart][x - xstart] = origcbdl->L[y - ystart][x - xstart] = original->L[y][x]; @@ -15261,12 +16061,12 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::cbdl_local_temp(bufsh, loctemp->L, bfw, bfh, lp.mulloc, 1.f, lp.threshol, lp.clarityml, lp.contresid, skinprot, false, b_l, t_l, t_r, b_r, choice, sk, multiThread); - + if (lp.softradiuscb > 0.f) { softproc(origcbdl.get(), loctemp.get(), lp.softradiuscb, bfh, bfw, 0.001, 0.00001, 0.5f, sk, multiThread, 1); } - - if(lp.enacbMask && lp.recothrcb != 1.f) { + + if (lp.enacbMask && lp.recothrcb != 1.f) { float hig = lp.higthrcb; float low = lp.lowthrcb; float recoth = lp.recothrcb; @@ -15274,7 +16074,7 @@ void ImProcFunctions::Lab_Local( bool invmask = false; maskrecov(loctemp.get(), original, bufmaskorigcb.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); } - + } transit_shapedetect(6, loctemp.get(), originalmaskcb.get(), bufchrom, false, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); @@ -15287,6 +16087,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufsh[ir][jr] = std::sqrt(SQR(loctemp->a[ir][jr]) + SQR(loctemp->b[ir][jr])); @@ -15316,6 +16117,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for reduction(max:maxC) reduction(min:minC) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufchrom[ir][jr] = (loctemp->L[ir][jr] - std::sqrt(SQR(loctemp->a[ir][jr]) + SQR(loctemp->b[ir][jr]))); @@ -15331,6 +16133,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufchrom[ir][jr] *= coefC; @@ -15340,14 +16143,15 @@ void ImProcFunctions::Lab_Local( transit_shapedetect(7, loctemp.get(), nullptr, bufchrom, false, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } + bufsh.free(); - + if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); } - + } } } @@ -15357,6 +16161,7 @@ void ImProcFunctions::Lab_Local( //vibrance float vibg = params->locallab.spots.at(sp).vibgam; + if (lp.expvib && (lp.past != 0.f || lp.satur != 0.f || lp.strvib != 0.f || vibg != 1.f || lp.war != 0 || lp.strvibab != 0.f || lp.strvibh != 0.f || lp.showmaskvibmet == 2 || lp.enavibMask || lp.showmaskvibmet == 3 || lp.showmaskvibmet == 4 || lp.prevdE) && lp.vibena) { //interior ellipse reinforced lightness and chroma //locallutili if (call <= 3) { //simpleprocess, dcrop, improccoordinator const int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); @@ -15382,6 +16187,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -15460,6 +16266,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + /* for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { @@ -15469,13 +16276,13 @@ void ImProcFunctions::Lab_Local( } } */ - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - // bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; - bufexporig->a[y][x] = original->a[y + ystart][x + xstart]; - bufexporig->b[y][x] = original->b[y + ystart][x + xstart]; + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + // bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; + bufexporig->a[y][x] = original->a[y + ystart][x + xstart]; + bufexporig->b[y][x] = original->b[y + ystart][x + xstart]; + } } - } VibranceParams vibranceParams; vibranceParams.enabled = params->locallab.spots.at(sp).expvibrance; @@ -15488,14 +16295,14 @@ void ImProcFunctions::Lab_Local( vibranceParams.skintonescurve = params->locallab.spots.at(sp).skintonescurve; - // bufexpfin->CopyFrom(bufexporig.get(), multiThread); - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - bufexpfin->L[y][x] = bufexporig->L[y][x]; - bufexpfin->a[y][x] = bufexporig->a[y][x]; - bufexpfin->b[y][x] = bufexporig->b[y][x]; - } - } + // bufexpfin->CopyFrom(bufexporig.get(), multiThread); + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + bufexpfin->L[y][x] = bufexporig->L[y][x]; + bufexpfin->a[y][x] = bufexporig->a[y][x]; + bufexpfin->b[y][x] = bufexporig->b[y][x]; + } + } if (lp.strvibh != 0.f) { printf("a\n"); @@ -15504,6 +16311,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { float factor = ImProcFunctions::calcGradientFactor(gph, jr, ir); @@ -15536,13 +16344,13 @@ void ImProcFunctions::Lab_Local( } if (lp.strvib != 0.f) { - printf("b\n"); - + struct grad_params gp; calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 7); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); @@ -15552,12 +16360,13 @@ void ImProcFunctions::Lab_Local( if (lp.strvibab != 0.f) { printf("c\n"); - + struct grad_params gpab; calclocalGradientParams(lp, gpab, ystart, xstart, bfw, bfh, 8); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { const float factor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); @@ -15565,23 +16374,29 @@ void ImProcFunctions::Lab_Local( bufexpfin->b[ir][jr] *= factor; } } + float gamma1 = params->locallab.spots.at(sp).vibgam; rtengine::GammaValues g_a; //gamma parameters double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; ++y) { - int x = 0; + int x = 0; #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(bufexpfin->L[y][x], F2V(32768.f) * igammalog(LVFU(bufexpfin->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < bfw; ++x) { + + for (; x < bfw; ++x) { bufexpfin->L[y][x] = 32768.f * igammalog(bufexpfin->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); } } @@ -15594,19 +16409,23 @@ void ImProcFunctions::Lab_Local( // rtengine::GammaValues g_a; //gamma parameters // double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab // double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - // rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope + // rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(bufexpfin->L[y][x], F2V(32768.f) * gammalog(LVFU(bufexpfin->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < bfw; ++x) { bufexpfin->L[y][x] = 32768.f * gammalog(bufexpfin->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); } @@ -15616,30 +16435,30 @@ void ImProcFunctions::Lab_Local( if (params->locallab.spots.at(sp).warm != 0) { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; - - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 2, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 2, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); } - if(lp.enavibMask && lp.recothrv != 1.f) { + if (lp.enavibMask && lp.recothrv != 1.f) { float recoth = lp.recothrv; - if(lp.recothrv < 1.f) { + if (lp.recothrv < 1.f) { recoth = -1.f * recoth + 2.f; } float hig = lp.higthrv; float low = lp.lowthrv; - // float recoth = lp.recothrv; + // float recoth = lp.recothrv; float decay = lp.decayv; bool invmask = false; maskrecov(bufexpfin.get(), original, bufmaskorigvib.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); } - if(lp.recothrv >= 1.f) { + if (lp.recothrv >= 1.f) { transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), originalmaskvib.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, 0.f, 0.f, call, 2, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); - + } } @@ -15658,7 +16477,7 @@ void ImProcFunctions::Lab_Local( //shadow highlight bool tonequ = false; - if (lp.mullocsh[0] != 0 || lp.mullocsh[1] != 0 || lp.mullocsh[2] != 0 || lp.mullocsh[3] != 0 || lp.mullocsh[4] != 0) { + if (lp.mullocsh[0] != 0 || lp.mullocsh[1] != 0 || lp.mullocsh[2] != 0 || lp.mullocsh[3] != 0 || lp.mullocsh[4] != 0 || lp.mullocsh[5] != 0) { tonequ = true; } @@ -15696,6 +16515,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -15774,6 +16594,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -15797,6 +16618,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); @@ -15815,10 +16637,12 @@ void ImProcFunctions::Lab_Local( float gamtone = params->locallab.spots.at(sp).gamSH; float slotone = params->locallab.spots.at(sp).sloSH; cmsHTRANSFORM dummy = nullptr; - int ill =0; - workingtrc(tmpImage, tmpImage, bfw, bfh, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - // workingtrc(tmpImage, tmpImage, bfw, bfh, 5, prof, gamtone, slotone, 0, 0, dummy, false, true, true); //to keep if we want improve with illuminant and primaries - workingtrc(tmpImage, tmpImage, bfw, bfh, 1, prof, gamtone, slotone, ill, 0, dummy, false, true, true);//be careful no gamut control + int ill = 0; + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + workingtrc(0, tmpImage, tmpImage, bfw, bfh, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly , meanx, meany, meanxe, meanye, dummy, true, false, false, false); + workingtrc(0, tmpImage, tmpImage, bfw, bfh, 1, prof, gamtone, slotone, 0, ill, 0, locprim, rdx, rdy, grx, gry, blx, bly , meanx, meany, meanxe, meanye, dummy, false, true, true, false);//be careful no gamut control } if (tonequ) { @@ -15831,16 +16655,16 @@ void ImProcFunctions::Lab_Local( } } - if(lp.enaSHMask && lp.recothrs != 1.f) { + if (lp.enaSHMask && lp.recothrs != 1.f) { float recoth = lp.recothrs; - if(lp.recothrs < 1.f) { + if (lp.recothrs < 1.f) { recoth = -1.f * recoth + 2.f; } float hig = lp.higthrs; float low = lp.lowthrs; - // float recoth = lp.recothrs; + // float recoth = lp.recothrs; float decay = lp.decays; bool invmask = false; maskrecov(bufexpfin.get(), original, bufmaskorigSH.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); @@ -15851,8 +16675,9 @@ void ImProcFunctions::Lab_Local( int bh = bufexporig->H; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif + for (int x = 0; x < bh; x++) { for (int y = 0; y < bw; y++) { bufexpfin->L[x][y] = intp(repart, bufexporig->L[x][y], bufexpfin->L[x][y]); @@ -15861,11 +16686,12 @@ void ImProcFunctions::Lab_Local( } } - if(lp.recothrs >= 1.f) { + if (lp.recothrs >= 1.f) { transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), originalmaskSH.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, 0.f, 0.f, call, 9, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } + if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; @@ -15885,6 +16711,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { bufcolorig->L[y][x] = original->L[y][x]; @@ -15981,6 +16808,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufexporig->L[y - ystart][x - xstart] = original->L[y][x]; @@ -16006,6 +16834,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { datain[y * bfwr + x] = bufexpfin->L[y][x]; @@ -16018,6 +16847,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { bufexpfin->L[y][x] = dataout[y * bfwr + x]; @@ -16051,6 +16881,7 @@ void ImProcFunctions::Lab_Local( } } } + if (loclevwavCurve && loclevwavutili) { for (int i = 0; i < 500; i++) { if (loclevwavCurve[i] != 0.f) { @@ -16059,6 +16890,7 @@ void ImProcFunctions::Lab_Local( } } } + if (locconwavCurve && locconwavutili) { for (int i = 0; i < 500; i++) { if (locconwavCurve[i] != 0.5f) { @@ -16067,6 +16899,7 @@ void ImProcFunctions::Lab_Local( } } } + if (loccompwavCurve && loccompwavutili) { for (int i = 0; i < 500; i++) { if (loccompwavCurve[i] != 0.f) { @@ -16075,6 +16908,7 @@ void ImProcFunctions::Lab_Local( } } } + if (loccomprewavCurve && loccomprewavutili) { for (int i = 0; i < 500; i++) { if (loccomprewavCurve[i] != 0.75f) { @@ -16121,6 +16955,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend; y++) { for (int x = xstart; x < xend; x++) { bufgb->L[y - ystart][x - xstart] = original->L[y][x]; @@ -16141,6 +16976,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufgb->L[y][x] = original->L[y + ystart][x + xstart]; @@ -16233,6 +17069,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { tmpfftw->L[y][x] = tmp1->L[y][x]; @@ -16246,6 +17083,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { tmp1->L[y][x] = tmpfftw->L[y][x]; @@ -16301,7 +17139,7 @@ void ImProcFunctions::Lab_Local( const float offs = params->locallab.spots.at(sp).offset; const float sigmadc = params->locallab.spots.at(sp).sigmadc; const float deltad = params->locallab.spots.at(sp).deltad; - // const float fatres = params->locallab.spots.at(sp).fatres; + // const float fatres = params->locallab.spots.at(sp).fatres; const float chrol = params->locallab.spots.at(sp).chromalev; const float chrobl = params->locallab.spots.at(sp).chromablu; const bool blurena = params->locallab.spots.at(sp).wavblur; @@ -16317,18 +17155,22 @@ void ImProcFunctions::Lab_Local( double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - if(gamma != 1.f) { + if (gamma != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < tmp1->H; ++y) { - int x = 0; + int x = 0; #ifdef __SSE2__ + for (; x < tmp1->W - 3; x += 4) { - STVFU(tmp1->L[y][x], F2V(32768.f) * igammalog(LVFU(tmp1->L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[2]), F2V(g_a[4]))); + STVFU(tmp1->L[y][x], F2V(32768.f) * igammalog(LVFU(tmp1->L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < tmp1->W; ++x) { + + for (; x < tmp1->W; ++x) { tmp1->L[y][x] = 32768.f * igammalog(tmp1->L[y][x] / 32768.f, gamma, ts, g_a[2], g_a[4]); } } @@ -16338,11 +17180,12 @@ void ImProcFunctions::Lab_Local( if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "wav") { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; + if (params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz - ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); } - ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, tmp1.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); float rad = params->locallab.spots.at(sp).detailcie; loccont(bfw, bfh, tmp1.get(), rad, 5.f, sk); @@ -16350,17 +17193,21 @@ void ImProcFunctions::Lab_Local( - if(gamma != 1.f) { + if (gamma != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < tmp1->H; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < tmp1->W - 3; x += 4) { STVFU(tmp1->L[y][x], F2V(32768.f) * gammalog(LVFU(tmp1->L[y][x]) / F2V(32768.f), F2V(gamma), F2V(ts), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < tmp1->W; ++x) { tmp1->L[y][x] = 32768.f * gammalog(tmp1->L[y][x] / 32768.f, gamma, ts, g_a[3], g_a[4]); } @@ -16388,6 +17235,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_La; y++) { for (int x = 0; x < W_La; x++) { bufa[y][x] = wav_ab0a [y * W_La + x]; @@ -16404,6 +17252,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_La; y++) { for (int x = 0; x < W_La; x++) { wav_ab0a[y * W_La + x] = bufa[y][x]; @@ -16416,6 +17265,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < W_La * H_La; i++) { wav_ab0a[i] *= (1.f + xsinf(rtengine::RT_PI_F * (satur / 200.f)));//more progressive than linear wav_ab0a[i] = clipC(wav_ab0a[i]); @@ -16440,6 +17290,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_Lb; y++) { for (int x = 0; x < W_Lb; x++) { bufb[y][x] = wav_ab0b [y * W_Lb + x]; @@ -16457,6 +17308,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < H_Lb; y++) { for (int x = 0; x < W_Lb; x++) { wav_ab0b[y * W_Lb + x] = bufb[y][x]; @@ -16470,6 +17322,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int i = 0; i < W_Lb * H_Lb; i++) { wav_ab0b[i] *= (1.f + xsinf(rtengine::RT_PI_F * (satur / 200.f))); wav_ab0b[i] = clipC(wav_ab0b[i]); @@ -16486,6 +17339,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { tmpresid->L[y][x] = tmp1->L[y][x]; @@ -16493,6 +17347,7 @@ void ImProcFunctions::Lab_Local( tmpresid->b[y][x] = tmp1->b[y][x]; } } + clarimerge(lp, mL, mC, exec, tmpresid.get(), wavelet_level, sk, numThreads); } @@ -16520,6 +17375,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for if (multiThread) #endif + for (int x = 0; x < bfh; x++) for (int y = 0; y < bfw; y++) { tmp1->L[x][y] = clipLoc((1.f + mL0) * mergfile->L[x][y] - mL * tmpresid->L[x][y]); @@ -16533,20 +17389,21 @@ void ImProcFunctions::Lab_Local( } } - if(lp.enalcMask && lp.recothrw != 1.f) { - float recoth = lp.recothrw; + if (lp.enalcMask && lp.recothrw != 1.f) { + float recoth = lp.recothrw; - if(lp.recothrw < 1.f) { - recoth = -1.f * recoth + 2.f; - } - - float hig = lp.higthrw; - float low = lp.lowthrw; - //float recoth = lp.recothrw; - float decay = lp.decayw; - bool invmask = false; - maskrecov(tmp1.get(), original, bufmaskoriglc.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); + if (lp.recothrw < 1.f) { + recoth = -1.f * recoth + 2.f; } + + float hig = lp.higthrw; + float low = lp.lowthrw; + //float recoth = lp.recothrw; + float decay = lp.decayw; + bool invmask = false; + maskrecov(tmp1.get(), original, bufmaskoriglc.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); + } + const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparw; int bw = bufgb->W; int bh = bufgb->H; @@ -16554,18 +17411,21 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int x = 0; x < bh; x++) { - for (int y = 0; y < bw; y++) { - tmp1->L[x][y] = intp(repart, bufgb->L[x][y], tmp1->L[x][y]); - tmp1->a[x][y] = intp(repart, bufgb->a[x][y], tmp1->a[x][y]); - tmp1->b[x][y] = intp(repart, bufgb->b[x][y], tmp1->b[x][y]); - } + + for (int x = 0; x < bh; x++) { + for (int y = 0; y < bw; y++) { + tmp1->L[x][y] = intp(repart, bufgb->L[x][y], tmp1->L[x][y]); + tmp1->a[x][y] = intp(repart, bufgb->a[x][y], tmp1->a[x][y]); + tmp1->b[x][y] = intp(repart, bufgb->b[x][y], tmp1->b[x][y]); } - if(lp.recothrw >= 1.f) { + } + + if (lp.recothrw >= 1.f) { transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), originalmasklc.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, 0.f, 0.f, call, 10, bufgb.get(), tmp1.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); } + tmp1.reset(); } @@ -16593,26 +17453,28 @@ void ImProcFunctions::Lab_Local( int yEn = lp.yc + lp.ly; int xEn = lp.xc + lp.lx; - if(lp.fullim == 2) {//limit sharpening to image dimension...no more...to avoid a long treatment - begy = 0; - begx = 0; - yEn = original->H; - xEn = original->W; - lp.lxL = lp.xc; - lp.lyT = lp.yc; - lp.ly = yEn - lp.yc; - lp.lx = xEn - lp.xc; - bfh= yEn; - bfw = xEn; - } + if (lp.fullim == 2) { //limit sharpening to image dimension...no more...to avoid a long treatment + begy = 0; + begx = 0; + yEn = original->H; + xEn = original->W; + lp.lxL = lp.xc; + lp.lyT = lp.yc; + lp.ly = yEn - lp.yc; + lp.lx = xEn - lp.xc; + bfh = yEn; + bfw = xEn; + } + //printf("begy=%i begx=%i yen=%i xen=%i\n", begy, begx, yEn, xEn); - JaggedArray bufsh(bfw, bfh, true); - JaggedArray hbuffer(bfw, bfh); - JaggedArray loctemp2(bfw, bfh); + JaggedArray bufsh(bfw, bfh, true); + JaggedArray hbuffer(bfw, bfh); + JaggedArray loctemp2(bfw, bfh); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < transformed->H ; y++) { for (int x = 0; x < transformed->W; x++) { int lox = cx + x; @@ -16623,113 +17485,136 @@ void ImProcFunctions::Lab_Local( } } } - float gamma1 = params->locallab.spots.at(sp).shargam; - rtengine::GammaValues g_a; //gamma parameters - double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab - double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + + float gamma1 = params->locallab.spots.at(sp).shargam; + rtengine::GammaValues g_a; //gamma parameters + double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab + double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope + + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < bfh; ++y) { - int x = 0; + + for (int y = 0; y < bfh; ++y) { + int x = 0; #ifdef __SSE2__ - for (; x < bfw - 3; x += 4) { - STVFU(bufsh[y][x], F2V(32768.f) * igammalog(LVFU(bufsh[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); - } -#endif - for (;x < bfw; ++x) { - bufsh[y][x] = 32768.f * igammalog(bufsh[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); - } - } + + for (; x < bfw - 3; x += 4) { + STVFU(bufsh[y][x], F2V(32768.f) * igammalog(LVFU(bufsh[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); } - - //sharpen only square area instead of all image, but limited to image dimensions (full image) - ImProcFunctions::deconvsharpeningloc(bufsh, hbuffer, bfw, bfh, loctemp2, params->locallab.spots.at(sp).shardamping, (double)params->locallab.spots.at(sp).sharradius, params->locallab.spots.at(sp).shariter, params->locallab.spots.at(sp).sharamount, params->locallab.spots.at(sp).sharcontrast, (double)params->locallab.spots.at(sp).sharblur, 1); - /* - float gamma = params->locallab.spots.at(sp).shargam; - double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab - double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - */ - if(gamma1 != 1.f) { -#ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif - for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f - int x = 0; -#ifdef __SSE2__ - for (; x < bfw - 3; x += 4) { - STVFU(bufsh[y][x], F2V(32768.f) * gammalog(LVFU(bufsh[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); - STVFU(loctemp2[y][x], F2V(32768.f) * gammalog(LVFU(loctemp2[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); - } #endif - for (; x < bfw; ++x) { - bufsh[y][x] = 32768.f * gammalog(bufsh[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); - loctemp2[y][x] = 32768.f * gammalog(loctemp2[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); - } - } + + for (; x < bfw; ++x) { + bufsh[y][x] = 32768.f * igammalog(bufsh[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); } - //sharpen simpleprocess - Sharp_Local(call, loctemp2, 0, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); + } + } + + + //sharpen only square area instead of all image, but limited to image dimensions (full image) + ImProcFunctions::deconvsharpeningloc(bufsh, hbuffer, bfw, bfh, loctemp2, params->locallab.spots.at(sp).shardamping, (double)params->locallab.spots.at(sp).sharradius, params->locallab.spots.at(sp).shariter, params->locallab.spots.at(sp).sharamount, params->locallab.spots.at(sp).sharcontrast, (double)params->locallab.spots.at(sp).sharblur, 1); + + /* + float gamma = params->locallab.spots.at(sp).shargam; + double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab + double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope + */ + if (gamma1 != 1.f) { +#ifdef _OPENMP + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + + for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f + int x = 0; +#ifdef __SSE2__ + + for (; x < bfw - 3; x += 4) { + STVFU(bufsh[y][x], F2V(32768.f) * gammalog(LVFU(bufsh[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); + STVFU(loctemp2[y][x], F2V(32768.f) * gammalog(LVFU(loctemp2[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); + } + +#endif + + for (; x < bfw; ++x) { + bufsh[y][x] = 32768.f * gammalog(bufsh[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); + loctemp2[y][x] = 32768.f * gammalog(loctemp2[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); + } + } + } + + //sharpen simpleprocess + Sharp_Local(call, loctemp2, 0, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } else { //call from dcrop.cc - JaggedArray loctemp(bfw, bfh); - - float gamma1 = params->locallab.spots.at(sp).shargam; - rtengine::GammaValues g_a; //gamma parameters - double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab - double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + JaggedArray loctemp(bfw, bfh); + + float gamma1 = params->locallab.spots.at(sp).shargam; + rtengine::GammaValues g_a; //gamma parameters + double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab + double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope + + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < bfh; ++y) { - int x = 0; + + for (int y = 0; y < bfh; ++y) { + int x = 0; #ifdef __SSE2__ - for (; x < bfw - 3; x += 4) { - STVFU(original->L[y][x], F2V(32768.f) * igammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); - } -#endif - for (;x < bfw; ++x) { - original->L[y][x] = 32768.f * igammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); - } - } + + for (; x < bfw - 3; x += 4) { + STVFU(original->L[y][x], F2V(32768.f) * igammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); } - - - ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, bfw, bfh, loctemp, params->locallab.spots.at(sp).shardamping, (double)params->locallab.spots.at(sp).sharradius, params->locallab.spots.at(sp).shariter, params->locallab.spots.at(sp).sharamount, params->locallab.spots.at(sp).sharcontrast, (double)params->locallab.spots.at(sp).sharblur, sk); - /* - float gamma = params->locallab.spots.at(sp).shargam; - double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab - double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope - */ - if(gamma1 != 1.f) { + +#endif + + for (; x < bfw; ++x) { + original->L[y][x] = 32768.f * igammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); + } + } + } + + + ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, bfw, bfh, loctemp, params->locallab.spots.at(sp).shardamping, (double)params->locallab.spots.at(sp).sharradius, params->locallab.spots.at(sp).shariter, params->locallab.spots.at(sp).sharamount, params->locallab.spots.at(sp).sharcontrast, (double)params->locallab.spots.at(sp).sharblur, sk); + + /* + float gamma = params->locallab.spots.at(sp).shargam; + double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab + double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope + */ + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif - for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f - int x = 0; -#ifdef __SSE2__ - for (; x < bfw - 3; x += 4) { - STVFU(original->L[y][x], F2V(32768.f) * gammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); - STVFU(loctemp[y][x], F2V(32768.f) * gammalog(LVFU(loctemp[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); - } + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (; x < bfw; ++x) { - original->L[y][x] = 32768.f * gammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); - loctemp[y][x] = 32768.f * gammalog(loctemp[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); - } - } + + for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f + int x = 0; +#ifdef __SSE2__ + + for (; x < bfw - 3; x += 4) { + STVFU(original->L[y][x], F2V(32768.f) * gammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); + STVFU(loctemp[y][x], F2V(32768.f) * gammalog(LVFU(loctemp[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); } - //sharpen dcrop - Sharp_Local(call, loctemp, 0, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); + +#endif + + for (; x < bfw; ++x) { + original->L[y][x] = 32768.f * gammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); + loctemp[y][x] = 32768.f * gammalog(loctemp[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); + } + } + } + + //sharpen dcrop + Sharp_Local(call, loctemp, 0, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } - + if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; @@ -16746,18 +17631,23 @@ void ImProcFunctions::Lab_Local( double pwr1 = 1.0 / (double) gamma1;//default 3.0 - gamma Lab double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < GH; ++y) { int x = 0; #ifdef __SSE2__ + for (; x < GW - 3; x += 4) { STVFU(original->L[y][x], F2V(32768.f) * igammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); } + #endif - for (;x < GW; ++x) { + + for (; x < GW; ++x) { original->L[y][x] = 32768.f * igammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); } } @@ -16765,24 +17655,29 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, GW, GH, loctemp, params->locallab.spots.at(sp).shardamping, (double)params->locallab.spots.at(sp).sharradius, params->locallab.spots.at(sp).shariter, params->locallab.spots.at(sp).sharamount, params->locallab.spots.at(sp).sharcontrast, (double)params->locallab.spots.at(sp).sharblur, sk); + /* float gamma = params->locallab.spots.at(sp).shargam; double pwr = 1.0 / (double) gamma;//default 3.0 - gamma Lab double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope */ - if(gamma1 != 1.f) { + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < GH; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < GW - 3; x += 4) { STVFU(original->L[y][x], F2V(32768.f) * gammalog(LVFU(original->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); STVFU(loctemp[y][x], F2V(32768.f) * igammalog(LVFU(loctemp[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < GW; ++x) { original->L[y][x] = 32768.f * gammalog(original->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); loctemp[y][x] = 32768.f * igammalog(loctemp[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); @@ -16844,6 +17739,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -16857,24 +17753,28 @@ void ImProcFunctions::Lab_Local( double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < bfh; ++y) { + + for (int y = 0; y < bfh; ++y) { int x = 0; #ifdef __SSE2__ - for (; x < bfw - 3; x += 4) { + + for (; x < bfw - 3; x += 4) { STVFU(bufexporig->L[y][x], F2V(32768.f) * igammalog(LVFU(bufexporig->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); - } + } + #endif - for (;x < bfw; ++x) { - bufexporig->L[y][x] = 32768.f * igammalog(bufexporig->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); - } + + for (; x < bfw; ++x) { + bufexporig->L[y][x] = 32768.f * igammalog(bufexporig->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); } } + } - const int spotSi = rtengine::max(1 + 2 * rtengine::max(1, lp.cir / sk), 5); + const int spotSi = rtengine::max(1 + 2 * rtengine::max(1.f, lp.cir / sk), 5.f); if (bfw > 2 * spotSi && bfh > 2 * spotSi && lp.struexp > 0.f) { blend2(bfw, bfh); @@ -16884,6 +17784,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { const int lox = cx + x; @@ -16894,7 +17795,7 @@ void ImProcFunctions::Lab_Local( if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -16973,6 +17874,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { bufexpfin->L[y][x] = original->L[y + ystart][x + xstart]; @@ -16988,11 +17890,12 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { bufexpfin->L[ir][jr] = 0.6f * bufexporig->L[ir][jr] + 0.2f * exlocalcurve[2.f * bufexporig->L[ir][jr]]; } - + if (lp.expcomp == 0.f) { lp.expcomp = 0.001f;// to enabled } @@ -17004,12 +17907,13 @@ void ImProcFunctions::Lab_Local( } else { if (lp.expcomp == 0.f && (lp.linear > 0.01f && lp.laplacexp > 0.1f)) { lp.expcomp = 0.001f;// to enabled - } + } - if (lp.expcomp != 0.f ) { // || lp.laplacexp > 0.1f - if(lp.laplacexp <= 0.1f) { + if (lp.expcomp != 0.f) { // || lp.laplacexp > 0.1f + if (lp.laplacexp <= 0.1f) { lp.laplacexp = 0.2f; //force to use Laplacian with very small values } + ImProcFunctions::exlabLocal(lp, 1.f, bfh, bfw, bfhr, bfwr, bufexporig.get(), bufexpfin.get(), hltonecurveloc, shtonecurveloc, tonecurveloc, hueref, lumaref, chromaref); } } @@ -17023,6 +17927,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); @@ -17039,11 +17944,13 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { datain[y * bfwr + x] = bufexpfin->L[y][x]; } } + FattalToneMappingParams fatParams; fatParams.enabled = true; fatParams.threshold = params->locallab.spots.at(sp).fatdetail; @@ -17054,7 +17961,8 @@ void ImProcFunctions::Lab_Local( const std::unique_ptr tmpImagefat(new Imagefloat(bfwr, bfhr)); lab2rgb(*bufexpfin, *tmpImagefat, params->icm.workingProfile); int alg = 0; - if(fatParams.anchor == 50.f) { + + if (fatParams.anchor == 50.f) { alg = 1; } bool satu = false; @@ -17063,13 +17971,15 @@ void ImProcFunctions::Lab_Local( } ToneMapFattal02(tmpImagefat.get(), fatParams, 3, 0, nullptr, 0, 0, alg, satu);//last parameter alg = 1 ==>ART algorithm rgb2lab(*tmpImagefat, *bufexpfin, params->icm.workingProfile); + if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "dr") { bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; + if (params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); } - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); float rad = params->locallab.spots.at(sp).detailcie; loccont(bfw, bfh, bufexpfin.get(), rad, 15.f, sk); @@ -17088,12 +17998,14 @@ void ImProcFunctions::Lab_Local( if (params->locallab.spots.at(sp).exnoiseMethod == "med" || params->locallab.spots.at(sp).exnoiseMethod == "medhi") { if (lp.blac < -100.f && lp.linear > 0.01f) { float evnoise = lp.blac - lp.linear * 2000.f; + if (params->locallab.spots.at(sp).exnoiseMethod == "med") { evnoise *= 0.4f; } //soft denoise, user must use Local Denoise for best result Median med; + if (evnoise < -18000.f) { med = Median::TYPE_5X5_STRONG; } else if (evnoise < -15000.f) { @@ -17113,6 +18025,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { float L = LIM01(bufexpfin->L[y][x] / 32768.f);//change gamma for Laplacian @@ -17125,6 +18038,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfhr; y++) { for (int x = 0; x < bfwr; x++) { const float Y = dataout[y * bfwr + x] / 32768.f;//inverse Laplacian gamma @@ -17133,6 +18047,7 @@ void ImProcFunctions::Lab_Local( } } } + if (lp.shadex > 0) { if (lp.expcomp == 0.f) { @@ -17146,7 +18061,7 @@ void ImProcFunctions::Lab_Local( lp.expcomp = 0.001f; // to enabled } } - + //shadows with ipshadowshighlight if ((lp.expcomp != 0.f) || (exlocalcurve && localexutili)) { if (lp.shadex > 0) { @@ -17164,6 +18079,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float epsi = bufexporig->L[ir][jr] == 0.f ? 0.001f : 0.f; @@ -17174,6 +18090,7 @@ void ImProcFunctions::Lab_Local( } } } + /* float gamma = lp.gamex; rtengine::GammaValues g_a; //gamma parameters @@ -17181,17 +18098,21 @@ void ImProcFunctions::Lab_Local( double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope */ - if(gamma1 != 1.f) { + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { STVFU(bufexpfin->L[y][x], F2V(32768.f) * gammalog(LVFU(bufexpfin->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < bfw; ++x) { bufexpfin->L[y][x] = 32768.f * gammalog(bufexpfin->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); } @@ -17201,22 +18122,22 @@ void ImProcFunctions::Lab_Local( if (lp.softradiusexp > 0.f && lp.expmet == 0) { softproc(buforig.get(), bufexpfin.get(), lp.softradiusexp, bfh, bfw, 0.1, 0.001, 0.5f, sk, multiThread, 1); } - - if(lp.enaExpMask && lp.recothre != 1.f) { + + if (lp.enaExpMask && lp.recothre != 1.f) { float recoth = lp.recothre; - if(lp.recothre < 1.f) { + if (lp.recothre < 1.f) { recoth = -1.f * recoth + 2.f; } float hig = lp.higthre; float low = lp.lowthre; - // float recoth = lp.recothre; + // float recoth = lp.recothre; float decay = lp.decaye; bool invmask = false; maskrecov(bufexpfin.get(), original, bufmaskblurexp.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); } - + float meansob = 0.f; const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparexp; @@ -17224,8 +18145,9 @@ void ImProcFunctions::Lab_Local( int bh = bufexporig->H; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif + for (int x = 0; x < bh; x++) { for (int y = 0; y < bw; y++) { bufexpfin->L[x][y] = intp(repart, bufexporig->L[x][y], bufexpfin->L[x][y]); @@ -17234,7 +18156,7 @@ void ImProcFunctions::Lab_Local( } } - if(lp.recothre >= 1.f) { + if (lp.recothre >= 1.f) { transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), originalmaskexp.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, 0.f, 0.f, call, 1, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); @@ -17265,6 +18187,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { bufexporig->L[y][x] = original->L[y][x]; @@ -17400,6 +18323,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolorig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -17414,30 +18338,34 @@ void ImProcFunctions::Lab_Local( } } - float gamma1 = lp.gamc; - rtengine::GammaValues g_a; //gamma parameters - double pwr1 = 1.0 / (double) lp.gamc;//default 3.0 - gamma Lab - double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope + float gamma1 = lp.gamc; + rtengine::GammaValues g_a; //gamma parameters + double pwr1 = 1.0 / (double) lp.gamc;//default 3.0 - gamma Lab + double ts1 = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr1, ts1, g_a); // call to calcGamma with selected gamma and slope - if(gamma1 != 1.f) { + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) + # pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < bufcolorig->H; ++y) { + + for (int y = 0; y < bufcolorig->H; ++y) { int x = 0; #ifdef __SSE2__ - for (; x < bufcolorig->W - 3; x += 4) { + + for (; x < bufcolorig->W - 3; x += 4) { STVFU(bufcolorig->L[y][x], F2V(32768.f) * igammalog(LVFU(bufcolorig->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[2]), F2V(g_a[4]))); - } + } + #endif - for (;x < bufcolorig->W; ++x) { - bufcolorig->L[y][x] = 32768.f * igammalog(bufcolorig->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); - } + + for (; x < bufcolorig->W; ++x) { + bufcolorig->L[y][x] = 32768.f * igammalog(bufcolorig->L[y][x] / 32768.f, gamma1, ts1, g_a[2], g_a[4]); } } + } - const int spotSi = rtengine::max(1 + 2 * rtengine::max(1, lp.cir / sk), 5); + const int spotSi = rtengine::max(1 + 2 * rtengine::max(1.f, lp.cir / sk), 5.f); const bool blends = bfw > 2 * spotSi && bfh > 2 * spotSi && lp.struco > 0.f; if (blends) { @@ -17448,6 +18376,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { const int lox = cx + x; @@ -17458,7 +18387,7 @@ void ImProcFunctions::Lab_Local( if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -17469,6 +18398,7 @@ void ImProcFunctions::Lab_Local( } } } + return; } } @@ -17501,6 +18431,7 @@ void ImProcFunctions::Lab_Local( const float merlucol = params->locallab.spots.at(sp).merlucol; int tonemod = 0; + if (params->locallab.spots.at(sp).toneMethod == "one") { tonemod = 0; } else if (params->locallab.spots.at(sp).toneMethod == "two") { @@ -17547,6 +18478,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) for (int x = 0; x < bfw; x++) { @@ -17620,6 +18552,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { const int loy = y + ystart + cy; @@ -17630,7 +18563,7 @@ void ImProcFunctions::Lab_Local( if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); - } else /*if (lp.shapmet == 1)*/ { + } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } @@ -17654,6 +18587,7 @@ void ImProcFunctions::Lab_Local( } bool HHcurve = false; + if (lochhCurve && HHutili) { for (int i = 0; i < 500; i++) { if (lochhCurve[i] != 0.5f) { @@ -17684,6 +18618,7 @@ void ImProcFunctions::Lab_Local( 1, 1 }); bool LHcurve = false; + if (loclhCurve && LHutili) { for (int i = 0; i < 500; i++) { if (loclhCurve[i] != 0.5f) { @@ -17692,7 +18627,9 @@ void ImProcFunctions::Lab_Local( } } } + bool CHcurve = false; + if (locchCurve && CHutili) { for (int i = 0; i < 500; i++) { if (locchCurve[i] != 0.5f) { @@ -17701,17 +18638,21 @@ void ImProcFunctions::Lab_Local( } } } + double amountchrom = 0.01 * settings->amchroma; - if(amountchrom < 0.05) { + + if (amountchrom < 0.05) { amountchrom = 0.05; } - if(amountchrom > 2.) { + + if (amountchrom > 2.) { amountchrom = 2.; } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { float bufcolcalca = origptr->a[ir][jr]; @@ -17786,16 +18727,16 @@ void ImProcFunctions::Lab_Local( if (loclhCurve && LHcurve && lp.qualcurvemet != 0) {//L=f(H) curve const float rhue = xatan2f(bufcolcalcb, bufcolcalca); //printf("rhu=%f", (double) rhue); - const float chromat = (std::sqrt(SQR(bufcolcalca) + SQR(bufcolcalcb)))/32768.f; + const float chromat = (std::sqrt(SQR(bufcolcalca) + SQR(bufcolcalcb))) / 32768.f; float l_r = LIM01(bufcolcalcL / 32768.f); //Luminance Lab in 0..1 - float valparam = loclhCurve[500.f *static_cast(Color::huelab_to_huehsv2(rhue))] - 0.5f; //get l_r=f(H) - // printf("rh=%f V=%f", (double) rhue, (double) valparam); - // float kc = 0.05f + 0.02f * params->locallab.spots.at(sp).lightjzcie; + float valparam = loclhCurve[500.f * static_cast(Color::huelab_to_huehsv2(rhue))] - 0.5f; //get l_r=f(H) + // printf("rh=%f V=%f", (double) rhue, (double) valparam); + // float kc = 0.05f + 0.02f * params->locallab.spots.at(sp).lightjzcie; float kc = amountchrom; float valparamneg; valparamneg = valparam; float kcc = SQR(chromat / kc); //take Chroma into account...40 "middle low" of chromaticity (arbitrary and simple), one can imagine other algorithme - // printf("KC=%f", (double) kcc); + // printf("KC=%f", (double) kcc); //reduce action for low chroma and increase action for high chroma valparam *= 2.f * kcc; valparamneg *= kcc; //slightly different for negative @@ -17803,7 +18744,7 @@ void ImProcFunctions::Lab_Local( if (valparam > 0.f) { l_r = (1.f - valparam) * l_r + valparam * (1.f - SQR(((SQR(1.f - min(l_r, 1.0f)))))); } else - //for negative + //for negative { float khue = 1.9f; //in reserve in case of! l_r *= (1.f + khue * valparamneg); @@ -17812,6 +18753,7 @@ void ImProcFunctions::Lab_Local( bufcolcalcL = l_r * 32768.f; } + if (locchCurve && CHcurve && lp.qualcurvemet != 0) {//C=f(H) curve const float rhue = xatan2f(bufcolcalcb, bufcolcalca); const float valparam = locchCurve[500.f * static_cast(Color::huelab_to_huehsv2(rhue))] - 0.5f; //get valp=f(H) @@ -17844,6 +18786,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { bufcolfin->L[ir][jr] = origptr->L[ir][jr]; @@ -17853,6 +18796,7 @@ void ImProcFunctions::Lab_Local( } bool nottransit = false; + if (lp.mergemet >= 2) { //merge result with original nottransit = true; bufcolreserv.reset(new LabImage(bfw, bfh)); @@ -17862,6 +18806,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { lumreserv[y][x] = 32768.f - reserved->L[y + ystart][x + xstart]; @@ -17878,9 +18823,9 @@ void ImProcFunctions::Lab_Local( bufcolreserv->a[y][x] = lastorig->a[y + ystart][x + xstart]; bufcolreserv->b[y][x] = lastorig->b[y + ystart][x + xstart]; } else if (lp.mergemet == 4) { - bufcolreserv->L[y][x] = merlucol * 327.68f; - bufcolreserv->a[y][x] = 9.f * scaledirect * a_scalemerg; - bufcolreserv->b[y][x] = 9.f * scaledirect * b_scalemerg; + bufcolreserv->L[y][x] = merlucol * 327.68f; + bufcolreserv->a[y][x] = 9.f * scaledirect * a_scalemerg; + bufcolreserv->b[y][x] = 9.f * scaledirect * b_scalemerg; } } } @@ -17891,6 +18836,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gp, jr, ir); @@ -17905,6 +18851,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); @@ -17920,6 +18867,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gph, jr, ir); @@ -17929,6 +18877,7 @@ void ImProcFunctions::Lab_Local( const float HH = xatan2f(bb, aa); float cor = 0.f; + if (corrFactor < 1.f) { cor = - 2.5f * (1.f - corrFactor); } else if (corrFactor > 1.f) { @@ -17936,6 +18885,7 @@ void ImProcFunctions::Lab_Local( } float newhr = HH + cor; + if (newhr > rtengine::RT_PI_F) { newhr -= 2 * rtengine::RT_PI_F; } else if (newhr < -rtengine::RT_PI_F) { @@ -17976,6 +18926,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { rdE[y][x] *= SQR(rdE[y][x]); @@ -17994,6 +18945,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufprov->L[y][x] = intp(rdE[y][x], bufcolfin->L[y][x], bufcolreserv->L[y][x]); @@ -18011,6 +18963,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolfin->L[y][x] = intp(blend[y][x], bufcolfin->L[y][x], bufreser->L[y][x]); @@ -18028,6 +18981,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { rdE[y][x] *= SQR(rdE[y][x]); @@ -18040,6 +18994,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufprov->L[y][x] = intp(rdE[y][x], bufcolfin->L[y][x], bufcolreserv->L[y][x]); @@ -18052,6 +19007,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { if (lp.mergecolMethod == 17) { @@ -18100,6 +19056,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolfin->L[y][x] = intp(blend[y][x], bufcolfin->L[y][x], bufcolreserv->L[y][x]); @@ -18116,6 +19073,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolfin->L[y][x] = intp(rdE[y][x], bufcolfin->L[y][x], bufcolreserv->L[y][x]); @@ -18139,10 +19097,12 @@ void ImProcFunctions::Lab_Local( float maxG = minG; float minB = tmpImagereserv->b(0, 0); float maxB = minB; + if (lp.mergecolMethod == 6 || lp.mergecolMethod == 9 || lp.mergecolMethod == 10 || lp.mergecolMethod == 11) { #ifdef _OPENMP #pragma omp parallel for reduction(max:maxR,maxG,maxB) reduction(min:minR,minG,minB) schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) { for (int jr = 0; jr < bfw; jr++) { minR = rtengine::min(minR, tmpImagereserv->r(ir, jr)); @@ -18160,6 +19120,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) {//LIM(x 0 2) 2 arbitrary value but limit... for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, tmpImageorig->r(y, x) - tmpImagereserv->r(y, x), tmpImageorig->r(y, x)); @@ -18171,6 +19132,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, std::fabs(tmpImageorig->r(y, x) - tmpImagereserv->r(y, x)), tmpImageorig->r(y, x)); @@ -18182,6 +19144,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, tmpImageorig->r(y, x) * tmpImagereserv->r(y, x), tmpImageorig->r(y, x)); @@ -18193,6 +19156,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, tmpImageorig->r(y, x) + tmpImagereserv->r(y, x), tmpImageorig->r(y, x)); @@ -18204,6 +19168,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, tmpImageorig->r(y, x) / (tmpImagereserv->r(y, x) + 0.00001f), tmpImageorig->r(y, x)); @@ -18215,6 +19180,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, softlig(tmpImageorig->r(y, x), tmpImagereserv->r(y, x), minR, maxR), tmpImageorig->r(y, x)); @@ -18226,6 +19192,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, softlig2(LIM01(tmpImageorig->r(y, x)), LIM01(tmpImageorig->r(y, x))), tmpImageorig->r(y, x)); @@ -18237,6 +19204,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, softlig3(LIM01(tmpImageorig->r(y, x)), tmpImagereserv->r(y, x)), tmpImageorig->r(y, x)); @@ -18248,6 +19216,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, overlay(tmpImagereserv->r(y, x), tmpImageorig->r(y, x), minR, maxR), tmpImageorig->r(y, x)); @@ -18259,6 +19228,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, overlay(tmpImageorig->r(y, x), tmpImagereserv->r(y, x), minR, maxR), tmpImageorig->r(y, x)); @@ -18270,6 +19240,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, screen(tmpImageorig->r(y, x), tmpImagereserv->r(y, x), 1.f), tmpImageorig->r(y, x)); @@ -18281,6 +19252,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, rtengine::min(tmpImageorig->r(y, x), tmpImagereserv->r(y, x)), tmpImageorig->r(y, x)); @@ -18292,6 +19264,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, rtengine::max(tmpImageorig->r(y, x), tmpImagereserv->r(y, x)), tmpImageorig->r(y, x)); @@ -18303,6 +19276,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, exclusion(tmpImageorig->r(y, x), tmpImagereserv->r(y, x)), tmpImageorig->r(y, x)); @@ -18315,6 +19289,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, colburn(LIM01(tmpImageorig->r(y, x)), LIM01(tmpImagereserv->r(y, x))), tmpImageorig->r(y, x)); @@ -18326,6 +19301,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { tmpImageorig->r(y, x) = intp(lp.opacol, coldodge(LIM01(tmpImageorig->r(y, x)), LIM01(tmpImagereserv->r(y, x))), tmpImageorig->r(y, x)); @@ -18342,6 +19318,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolfin->L[y][x] = intp(blend[y][x], bufcolfin->L[y][x], bufcolreserv->L[y][x]); @@ -18355,22 +19332,24 @@ void ImProcFunctions::Lab_Local( if (lp.softradiuscol > 0.f) { softproc(bufcolreserv.get(), bufcolfin.get(), lp.softradiuscol, bfh, bfw, 0.001, 0.00001, 0.5f, sk, multiThread, 1); } + float meansob = 0.f; const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcol; int bw = bufcolreserv->W; int bh = bufcolreserv->H; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int x = 0; x < bh; x++) { - for (int y = 0; y < bw; y++) { - bufcolfin->L[x][y] = intp(repart, bufcolreserv->L[x][y], bufcolfin->L[x][y]); - bufcolfin->a[x][y] = intp(repart, bufcolreserv->a[x][y], bufcolfin->a[x][y]); - bufcolfin->b[x][y] = intp(repart, bufcolreserv->b[x][y], bufcolfin->b[x][y]); + + for (int x = 0; x < bh; x++) { + for (int y = 0; y < bw; y++) { + bufcolfin->L[x][y] = intp(repart, bufcolreserv->L[x][y], bufcolfin->L[x][y]); + bufcolfin->a[x][y] = intp(repart, bufcolreserv->a[x][y], bufcolfin->a[x][y]); + bufcolfin->b[x][y] = intp(repart, bufcolreserv->b[x][y], bufcolfin->b[x][y]); + } } - } - + transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolreserv.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); } @@ -18382,6 +19361,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gp, jr, ir); @@ -18395,6 +19375,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gpab, jr, ir); @@ -18409,6 +19390,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int ir = 0; ir < bfh; ir++) for (int jr = 0; jr < bfw; jr++) { const float corrFactor = ImProcFunctions::calcGradientFactor(gph, jr, ir); @@ -18441,24 +19423,28 @@ void ImProcFunctions::Lab_Local( -/* - float gamma = lp.gamc; - rtengine::GammaValues g_a; //gamma parameters - double pwr = 1.0 / (double) lp.gamc;//default 3.0 - gamma Lab - double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab - rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope -*/ - if(gamma1 != 1.f) { + /* + float gamma = lp.gamc; + rtengine::GammaValues g_a; //gamma parameters + double pwr = 1.0 / (double) lp.gamc;//default 3.0 - gamma Lab + double ts = 9.03296;//always the same 'slope' in the extreme shadows - slope Lab + rtengine::Color::calcGamma(pwr, ts, g_a); // call to calcGamma with selected gamma and slope + */ + if (gamma1 != 1.f) { #ifdef _OPENMP -# pragma omp parallel for schedule(dynamic,16) if (multiThread) -#endif + # pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < bfh; ++y) {//apply inverse gamma 3.f and put result in range 32768.f int x = 0; #ifdef __SSE2__ + for (; x < bfw - 3; x += 4) { - STVFU(bufcolfin->L[y][x], F2V(32768.f) * gammalog(LVFU(bufcolfin->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); + STVFU(bufcolfin->L[y][x], F2V(32768.f) * gammalog(LVFU(bufcolfin->L[y][x]) / F2V(32768.f), F2V(gamma1), F2V(ts1), F2V(g_a[3]), F2V(g_a[4]))); } + #endif + for (; x < bfw; ++x) { bufcolfin->L[y][x] = 32768.f * gammalog(bufcolfin->L[y][x] / 32768.f, gamma1, ts1, g_a[3], g_a[4]); } @@ -18469,39 +19455,43 @@ void ImProcFunctions::Lab_Local( if (lp.softradiuscol > 0.f) { softproc(bufcolorig.get(), bufcolfin.get(), lp.softradiuscol, bfh, bfw, 0.001, 0.00001, 0.5f, sk, multiThread, 1); } - //mask recovery - if(lp.enaColorMask && lp.recothrc != 1.f) { - float recoth = lp.recothrc; + //mask recovery - if(lp.recothrc < 1.f) { - recoth = -1.f * recoth + 2.f; + if (lp.enaColorMask && lp.recothrc != 1.f) { + float recoth = lp.recothrc; + + if (lp.recothrc < 1.f) { + recoth = -1.f * recoth + 2.f; + } + + float hig = lp.higthrc; + float low = lp.lowthrc; + // float recoth = lp.recothrc; + float decay = lp.decayc; + bool invmask = false; + maskrecov(bufcolfin.get(), original, bufmaskblurcol.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); } - float hig = lp.higthrc; - float low = lp.lowthrc; - // float recoth = lp.recothrc; - float decay = lp.decayc; - bool invmask = false; - maskrecov(bufcolfin.get(), original, bufmaskblurcol.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); - } - const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcol; - int bw = bufcolorig->W; - int bh = bufcolorig->H; + const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcol; + int bw = bufcolorig->W; + int bh = bufcolorig->H; #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) + #pragma omp parallel for schedule(dynamic,16) if(multiThread) #endif - for (int x = 0; x < bh; x++) { - for (int y = 0; y < bw; y++) { - bufcolfin->L[x][y] = intp(repart, bufcolorig->L[x][y], bufcolfin->L[x][y]); - bufcolfin->a[x][y] = intp(repart, bufcolorig->a[x][y], bufcolfin->a[x][y]); - bufcolfin->b[x][y] = intp(repart, bufcolorig->b[x][y], bufcolfin->b[x][y]); + + for (int x = 0; x < bh; x++) { + for (int y = 0; y < bw; y++) { + bufcolfin->L[x][y] = intp(repart, bufcolorig->L[x][y], bufcolfin->L[x][y]); + bufcolfin->a[x][y] = intp(repart, bufcolorig->a[x][y], bufcolfin->a[x][y]); + bufcolfin->b[x][y] = intp(repart, bufcolorig->b[x][y], bufcolfin->b[x][y]); + } } - } - + float meansob = 0.f; - if(lp.recothrc >= 1.f) { + + if (lp.recothrc >= 1.f) { transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); } else { transit_shapedetect2(sp, 0.f, 0.f, call, 0, bufcolorig.get(), bufcolfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, meansob, blend2, lp, original, transformed, cx, cy, sk); @@ -18553,6 +19543,7 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < TH ; y++) { for (int x = 0; x < TW; x++) { bufcolorig->L[y][x] = original->L[y][x]; @@ -18615,20 +19606,22 @@ void ImProcFunctions::Lab_Local( } } } - + //begin common mask - if(lp.maskena) { + if (lp.maskena) { int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); int bfh = yend - ystart; int bfw = xend - xstart; + if (bfw >= mSP && bfh >= mSP) { if (lp.blurma >= 0.25f && lp.fftma && call == 2) { optfft(N_fftwsize, bfh, bfw, bfh, bfw, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy, lp.fullim); } + array2D blechro(bfw, bfh); array2D ble(bfw, bfh); array2D hue(bfw, bfh); @@ -18640,7 +19633,7 @@ void ImProcFunctions::Lab_Local( std::unique_ptr bufmaskblurcol; std::unique_ptr originalmaskcol; std::unique_ptr bufcolreserv; - + int wo = original->W; int ho = original->H; LabImage *origsav = nullptr; @@ -18656,9 +19649,11 @@ void ImProcFunctions::Lab_Local( bufmaskblurcol.reset(new LabImage(bfw, bfh, true)); originalmaskcol.reset(new LabImage(bfw, bfh)); } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolorig->L[y][x] = original->L[y + ystart][x + xstart]; @@ -18674,6 +19669,7 @@ void ImProcFunctions::Lab_Local( bufcolfin->b[y][x] = original->b[y + ystart][x + xstart]; } } + const int inv = 0; const bool showmaske = lp.showmask_met == 2; const bool enaMask = lp.ena_Mask; @@ -18682,15 +19678,17 @@ void ImProcFunctions::Lab_Local( const bool zero = lp.showmask_met == 0; const bool modif = lp.showmask_met == 1; const float chrom = params->locallab.spots.at(sp).chromask; - const float rad = params->locallab.spots.at(sp).radmask; - const float gamma = params->locallab.spots.at(sp).gammask; + const float rad = params->locallab.spots.at(sp).radmask; + const float gamma = params->locallab.spots.at(sp).gammask; const float slope = params->locallab.spots.at(sp).slopmask; float blendm = 0.1 * params->locallab.spots.at(sp).blendmask; float blendmab = params->locallab.spots.at(sp).blendmaskab; + if (lp.showmask_met == 2) { blendm = 0.f;//normalize behavior mask with others no action of blend blendmab = 0.f; } + const float lap = params->locallab.spots.at(sp).lapmask; const bool pde = params->locallab.spots.at(sp).laplac; const int shado = params->locallab.spots.at(sp).shadmask; @@ -18720,15 +19718,17 @@ void ImProcFunctions::Lab_Local( shortcu, delt, hueref, chromaref, lumaref, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftma, lp.blurma, lp.contma, 12, fab ); - - + + if (lp.showmask_met == 2) { showmask(lumask, lp, xstart, ystart, cx, cy, bfw, bfh, bufcolorig.get(), transformed, bufmaskblurcol.get(), 0); return; } + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh ; y++) { for (int x = 0; x < bfw; x++) { bufcolfin->L[y][x] = bufcolorig->L[y][x]; @@ -18741,6 +19741,7 @@ void ImProcFunctions::Lab_Local( guid[y][x] = bufcolorigsav->L[y][x] / 32768.f; } } + if (softr != 0.f) {//soft for L a b because we change color... const float tmpblur = softr < 0.f ? -1.f / softr : 1.f + softr; const int r1 = rtengine::max(4 / sk * tmpblur + 0.5f, 1); @@ -18757,8 +19758,9 @@ void ImProcFunctions::Lab_Local( rtengine::guidedFilter(guid, ble, ble, r2, 0.2f * epsil, multiThread); #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif + for (int y = 0; y < bfh; y++) { for (int x = 0; x < bfw; x++) { float2 sincosval = xsincosf(hue[y][x]); @@ -18768,39 +19770,52 @@ void ImProcFunctions::Lab_Local( } } } - + float meansob = 0.f; transit_shapedetect2(sp, 0.f, 0.f, call, 20, bufcolorigsav.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, nullptr, lp, origsav, transformed, cx, cy, sk); delete origsav; origsav = NULL; - + if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); } - + } } } -//end common mask - - if(params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "com" && lp.activspot) {//ciecam - int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); - int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); - int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); - int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); - int bfh = yend - ystart; - int bfw = xend - xstart; - if (bfh >= mSP && bfw >= mSP) { - const std::unique_ptr bufexporig(new LabImage(bfw, bfh)); //buffer for data in zone limit - const std::unique_ptr bufexpfin(new LabImage(bfw, bfh)); //buffer for data in zone limit - std::unique_ptr bufmaskorigcie; - std::unique_ptr bufmaskblurcie; - std::unique_ptr originalmaskcie; +//end common mask + //Cie + rdx = params->locallab.spots.at(sp).redxl; + rdy = params->locallab.spots.at(sp).redyl; + grx = params->locallab.spots.at(sp).grexl; + gry = params->locallab.spots.at(sp).greyl; + blx = params->locallab.spots.at(sp).bluxl; + bly = params->locallab.spots.at(sp).bluyl; + + if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecie == "com" && lp.activspot) { //ciecam + int ystart = rtengine::max(static_cast(lp.yc - lp.lyT) - cy, 0); + int yend = rtengine::min(static_cast(lp.yc + lp.ly) - cy, original->H); + int xstart = rtengine::max(static_cast(lp.xc - lp.lxL) - cx, 0); + int xend = rtengine::min(static_cast(lp.xc + lp.lx) - cx, original->W); + int bfh = yend - ystart; + int bfw = xend - xstart; + + if (bfh >= mSP && bfw >= mSP) { + + if (lp.blurciemask >= 0.25f && lp.fftcieMask && call == 2) { + optfft(N_fftwsize, bfh, bfw, bfh, bfw, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy, lp.fullim); + } + + const std::unique_ptr bufexporig(new LabImage(bfw, bfh)); //buffer for data in zone limit + const std::unique_ptr bufexpfin(new LabImage(bfw, bfh)); //buffer for data in zone limit + std::unique_ptr bufmaskorigcie; + std::unique_ptr bufmaskblurcie; + std::unique_ptr originalmaskcie; if (lp.showmaskciemet == 2 || lp.enacieMask || lp.showmaskciemet == 3 || lp.showmaskciemet == 4) { bufmaskorigcie.reset(new LabImage(bfw, bfh)); @@ -18811,172 +19826,430 @@ void ImProcFunctions::Lab_Local( #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + #pragma omp parallel for schedule(dynamic,16) if (multiThread) #endif - for (int y = 0; y < bfh; y++) { - for (int x = 0; x < bfw; x++) { - bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; - bufexporig->a[y][x] = original->a[y + ystart][x + xstart]; - bufexporig->b[y][x] = original->b[y + ystart][x + xstart]; - } - } - - bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; - if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elementsfor Jz - ImProcFunctions::ciecamloc_02float(lp, sp, bufexporig.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); - } - if (lochhCurvejz && HHutilijz) { - for (int i = 0; i < 500; i++) { - if (lochhCurvejz[i] != 0.5f) { - HHcurvejz = true; - break; - } - } - } - - if (locchCurvejz && CHutilijz) { - for (int i = 0; i < 500; i++) { - if (locchCurvejz[i] != 0.5f) { - CHcurvejz = true; - break; - } - } - } - - if (loclhCurvejz && LHutilijz) { - for (int i = 0; i < 500; i++) { - if (loclhCurvejz[i] != 0.5f) { - LHcurvejz = true; - break; - } - } - } - - int inv = 0; - bool showmaske = false; - bool enaMask = false; - bool deltaE = false; - bool modmask = false; - bool zero = false; - bool modif = false; - - if (lp.showmaskciemet == 3) { - showmaske = true; - } - - if (lp.enacieMask) { - enaMask = true; - } - - if (lp.showmaskciemet == 4) { - deltaE = true; - } - - if (lp.showmaskciemet == 2) { - modmask = true; - } - - if (lp.showmaskciemet == 1) { - modif = true; - } - - if (lp.showmaskciemet == 0) { - zero = true; - } - - float chrom = lp.chromacie; - float rad = lp.radmacie; - float gamma = params->locallab.spots.at(sp).gammaskcie; - float slope = params->locallab.spots.at(sp).slomaskcie; - float blendm = lp.blendmacie; - float lap = params->locallab.spots.at(sp).lapmaskcie; - bool pde = params->locallab.spots.at(sp).laplac; - LocwavCurve dummy; - bool delt = params->locallab.spots.at(sp).deltae; - int sco = params->locallab.spots.at(sp).scopemask; - int shortcu = 0;//lp.mergemet; //params->locallab.spots.at(sp).shortc; - int shado = 0; - const int highl = 0; - - const float mindE = 2.f + MINSCOPE * sco * lp.thr; - const float maxdE = 5.f + MAXSCOPE * sco * (1 + 0.1f * lp.thr); - const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; - const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); - int lumask = params->locallab.spots.at(sp).lumask; - float amountcd = 0.f; - float anchorcd = 50.f; - LocHHmaskCurve lochhhmasCurve; - maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskorigcie.get(), originalmaskcie.get(), original, reserved, inv, lp, - 0.f, false, - locccmascieCurve, lcmascieutili, locllmascieCurve, llmascieutili, lochhmascieCurve, lhmascieutili, lochhhmasCurve, false, multiThread, - enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskcielocalcurve, localmaskcieutili, dummy, false, 1, 1, 5, 5, - shortcu, delt, hueref, chromaref, lumaref, - maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, false, 0.f, 0.f, -1, fab - ); - - if (lp.showmaskciemet == 3) { - showmask(lumask, lp, xstart, ystart, cx, cy, bfw, bfh, bufexporig.get(), transformed, bufmaskorigcie.get(), 0); - - return; - } - - - - if (lp.showmaskciemet == 0 || lp.showmaskciemet == 1 || lp.showmaskciemet == 2 || lp.showmaskciemet == 4 || lp.enacieMask) { - - bufexpfin->CopyFrom(bufexporig.get(), multiThread); - if (params->locallab.spots.at(sp).expcie) { - ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz); - } - } - - if(lp.enacieMask && lp.recothrcie != 1.f) { - float recoth = lp.recothrcie; - - if(lp.recothrcie < 1.f) { - recoth = -1.f * recoth + 2.f; - } - float hig = lp.higthrcie; - float low = lp.lowthrcie; - //float recoth = lp.recothrcie; - float decay = lp.decaycie; - bool invmask = false; - maskrecov(bufexpfin.get(), original, bufmaskorigcie.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); - } - - - float radcie = params->locallab.spots.at(sp).detailcie; - loccont(bfw, bfh, bufexpfin.get(), radcie, 15.f, sk); - - const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcie; - int bw = bufexporig->W; - int bh = bufexporig->H; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) if(multiThread) -#endif - for (int x = 0; x < bh; x++) { - for (int y = 0; y < bw; y++) { - bufexpfin->L[x][y] = intp(repart, bufexporig->L[x][y], bufexpfin->L[x][y]); - bufexpfin->a[x][y] = intp(repart, bufexporig->a[x][y], bufexpfin->a[x][y]); - bufexpfin->b[x][y] = intp(repart, bufexporig->b[x][y], bufexpfin->b[x][y]); - } - } - - if(lp.recothrcie >= 1.f) { - transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), originalmaskcie.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); - } else { - transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); - } - if (lp.recur) { - original->CopyFrom(transformed, multiThread); - float avge; - calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + bufexporig->L[y][x] = original->L[y + ystart][x + xstart]; + bufexporig->a[y][x] = original->a[y + ystart][x + xstart]; + bufexporig->b[y][x] = original->b[y + ystart][x + xstart]; } } + bool HHcurvejz = false, CHcurvejz = false, LHcurvejz = false; + + if (params->locallab.spots.at(sp).expcie && params->locallab.spots.at(sp).modecam == "jz") {//some cam16 elements for Jz + ImProcFunctions::ciecamloc_02float(lp, sp, bufexporig.get(), bfw, bfh, 10, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); + } + + if (lochhCurvejz && HHutilijz) { + for (int i = 0; i < 500; i++) { + if (lochhCurvejz[i] != 0.5f) { + HHcurvejz = true; + break; + } + } + } + + if (locchCurvejz && CHutilijz) { + for (int i = 0; i < 500; i++) { + if (locchCurvejz[i] != 0.5f) { + CHcurvejz = true; + break; + } + } + } + + if (loclhCurvejz && LHutilijz) { + for (int i = 0; i < 500; i++) { + if (loclhCurvejz[i] != 0.5f) { + LHcurvejz = true; + break; + } + } + } + + int inv = 0; + bool showmaske = false; + bool enaMask = false; + bool deltaE = false; + bool modmask = false; + bool zero = false; + bool modif = false; + + if (lp.showmaskciemet == 3) { + showmaske = true; + } + + if (lp.enacieMask) { + enaMask = true; + } + + if (lp.showmaskciemet == 4) { + deltaE = true; + } + + if (lp.showmaskciemet == 2) { + modmask = true; + } + + if (lp.showmaskciemet == 1) { + modif = true; + } + + if (lp.showmaskciemet == 0) { + zero = true; + } + + float chrom = lp.chromacie; + float rad = lp.radmacie; + float gamma = params->locallab.spots.at(sp).gammaskcie; + float slope = params->locallab.spots.at(sp).slomaskcie; + float blendm = lp.blendmacie; + float lap = params->locallab.spots.at(sp).lapmaskcie; + bool pde = params->locallab.spots.at(sp).laplac; + LocwavCurve dummy; + bool delt = params->locallab.spots.at(sp).deltae; + int sco = params->locallab.spots.at(sp).scopemask; + int shortcu = 0;//lp.mergemet; //params->locallab.spots.at(sp).shortc; + const int level_bl = params->locallab.spots.at(sp).csthresholdcie.getBottomLeft(); + const int level_hl = params->locallab.spots.at(sp).csthresholdcie.getTopLeft(); + const int level_br = params->locallab.spots.at(sp).csthresholdcie.getBottomRight(); + const int level_hr = params->locallab.spots.at(sp).csthresholdcie.getTopRight(); + + const float mindE = 2.f + MINSCOPE * sco * lp.thr; + const float maxdE = 5.f + MAXSCOPE * sco * (1 + 0.1f * lp.thr); + const float mindElim = 2.f + MINSCOPE * limscope * lp.thr; + const float maxdElim = 5.f + MAXSCOPE * limscope * (1 + 0.1f * lp.thr); + int lumask = params->locallab.spots.at(sp).lumask; + float amountcd = 0.f; + float anchorcd = 50.f; + LocHHmaskCurve lochhhmasCurve; + bool astool = params->locallab.spots.at(sp).toolcie; + const float strumask = 0.02 * params->locallab.spots.at(sp).strumaskcie; + const int shado = params->locallab.spots.at(sp).shadmaskcie; + const int highl = params->locallab.spots.at(sp).highmaskcie; + + maskcalccol(false, pde, bfw, bfh, xstart, ystart, sk, cx, cy, bufexporig.get(), bufmaskorigcie.get(), originalmaskcie.get(), original, reserved, inv, lp, + strumask, astool, + locccmascieCurve, lcmascieutili, locllmascieCurve, llmascieutili, lochhmascieCurve, lhmascieutili, llochhhmascieCurve, lhhmascieutili, multiThread, + enaMask, showmaske, deltaE, modmask, zero, modif, chrom, rad, lap, gamma, slope, blendm, blendm, shado, highl, amountcd, anchorcd, lmaskcielocalcurve, localmaskcieutili, loclmasCurveciewav, lmasutiliciewav, + level_bl, level_hl, level_br, level_hr, + shortcu, delt, hueref, chromaref, lumaref, + maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sco, lp.fftcieMask, lp.blurciemask, lp.contciemask, -1, fab + ); + + if (lp.showmaskciemet == 3) { + showmask(lumask, lp, xstart, ystart, cx, cy, bfw, bfh, bufexporig.get(), transformed, bufmaskorigcie.get(), 0); + + return; + } + + + + if (lp.showmaskciemet == 0 || lp.showmaskciemet == 1 || lp.showmaskciemet == 2 || lp.showmaskciemet == 4 || lp.enacieMask) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < bfh ; y++) { + for (int x = 0; x < bfw; x++) { + bufexpfin->L[y][x] = original->L[y + ystart][x + xstart]; + bufexpfin->a[y][x] = original->a[y + ystart][x + xstart]; + bufexpfin->b[y][x] = original->b[y + ystart][x + xstart]; + } + } + + if (params->locallab.spots.at(sp).expprecam && params->locallab.spots.at(sp).modecam == "cam16") { + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + Imagefloat *tmpImagelog = nullptr; + tmpImagelog = new Imagefloat(bfw, bfh); + + lab2rgb(*bufexpfin, *tmpImage, params->icm.workingProfile); + Glib::ustring prof = params->icm.workingProfile; + + float gamtone = params->locallab.spots.at(sp).gamjcie; + float slotone = params->locallab.spots.at(sp).slopjcie; + cmsHTRANSFORM dummy = nullptr; + int prim = 3; + int typ = 1; + rdx = params->locallab.spots.at(sp).redxl; + rdy = params->locallab.spots.at(sp).redyl; + grx = params->locallab.spots.at(sp).grexl; + gry = params->locallab.spots.at(sp).greyl; + blx = params->locallab.spots.at(sp).bluxl; + bly = params->locallab.spots.at(sp).bluyl; + /* + if (params->locallab.spots.at(sp).complexcie == 2) { + printf("Mode complexity=%i Prov=%s\n", params->locallab.spots.at(sp).complexcie, prof.c_str()); + printf("prim=%s \n", params->locallab.spots.at(sp).primMethod.c_str()); + } + */ + if (params->locallab.spots.at(sp).primMethod == "beta") { + typ = 5; + ill = 2; + prim = 11; + } else if (params->locallab.spots.at(sp).primMethod == "srgb") { + prim = 1; + ill = 5; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "ado") { + prim = 2; + ill = 5; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "pro") { + prim = 3; + ill = 2; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "rec") { + prim = 4; + ill = 5; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "ac1") { + prim = 5; + ill = 4; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "wid") { + prim = 6; + ill = 2; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "jdcmax") { + prim = 8; + ill = 2; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "jdcmaxstdA") { + prim = 9; + ill = 8; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "ac0") { + prim = 7; + ill = 4; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "best") { + prim = 12; + ill = 2; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "bru") { + prim = 10; + ill = 5; + typ = 5; + } else if (params->locallab.spots.at(sp).primMethod == "free") { + prim = 15; + typ = 5; + + rdx = params->locallab.spots.at(sp).redxl; + rdy = params->locallab.spots.at(sp).redyl; + grx = params->locallab.spots.at(sp).grexl; + gry = params->locallab.spots.at(sp).greyl; + blx = params->locallab.spots.at(sp).bluxl; + bly = params->locallab.spots.at(sp).bluyl; + + } + int catx = 0; + if (params->locallab.spots.at(sp).catMethod == "brad") { + catx = 0; + } else if (params->locallab.spots.at(sp).catMethod == "cat16") { + catx = 1; + } else if (params->locallab.spots.at(sp).catMethod == "cat02") { + catx = 2; + } else if (params->locallab.spots.at(sp).catMethod == "vky") { + catx = 3; + } else if (params->locallab.spots.at(sp).catMethod == "xyz") { + catx = 4; + } + + params->locallab.spots.at(sp).catMethod; + int locprim = 1; + bool gamcie = params->locallab.spots.at(sp).gamutcie; + float rx, ry, gx, gy, bx, by = 0.f; + float mx, my, mxe, mye = 0.f; + + workingtrc(sp, tmpImage, tmpImage, bfw, bfh, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rx, ry, gx, gy, bx, by, mx, my, mxe, mye, dummy, true, false, false, false); + workingtrc(sp, tmpImage, tmpImage, bfw, bfh, typ, prof, gamtone, slotone, catx, ill, prim, locprim, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, false, true, true, gamcie);//with gamut control + + if(lp.midtcie != 0) { + ImProcFunctions::tone_eqcam(this, tmpImage, lp.midtcie, params->icm.workingProfile, sk, multiThread); + } + + tmpImage->copyData(tmpImagelog); + + if(params->locallab.spots.at(sp).logcie && !params->locallab.spots.at(sp).logcieq) { + log_encode(tmpImagelog, lp, multiThread, bfw, bfh); + float strlog = 0.01f * (float) params->locallab.spots.at(sp).strcielog; + + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic, 16) +#endif + + for (int y = 0; y < bfh; ++y) { + for (int x = 0; x < bfw; ++x) { + tmpImage->r(y, x) = intp(strlog, tmpImagelog->r(y, x), tmpImage->r(y, x)); + tmpImage->g(y, x) = intp(strlog, tmpImagelog->g(y, x), tmpImage->g(y, x)); + tmpImage->b(y, x) = intp(strlog, tmpImagelog->b(y, x), tmpImage->b(y, x)); + + } + } + } + + if(lp.smoothciem == 1) { + tone_eqsmooth(this, tmpImage, lp, params->icm.workingProfile, sk, multiThread);//reduce Ev > 0 < 12 + } else if(lp.smoothciem == 2 || lp.smoothciem == 3) {// 2 - only smmoth highlightd - 3 - Tone mapping with slope and mid_grey + + //TonemapFreeman - Copyright (c) 2023 Thatcher Freeman + float mid_gray = 0.01f * lp.sourcegraycie;//Mean luminance Yb Scene + float mid_gray_view = 0.01f * lp.targetgraycie;//Mean luminance Yb Viewing + lp.whiteevjz = LIM(lp.whiteevjz, 0.1f, 31.5f);//limit whiteEv to avoid crash + float white_point = xexpf(lp.whiteevjz * std::log(2.f) + xlogf(mid_gray));//lp.whiteevjz White_Ev + lp.blackevjz = LIM(lp.blackevjz, -15.5f, -0.2f);//limit BlackEv to avoid crash + float black_point = xexpf(lp.blackevjz * std::log(2.f) + xlogf(mid_gray));//lp.blackevjz Black_Ev + bool rolloff = true;//only soften highlights + float slopegray = 1.f;//slopegray between 0.8 and 1.6 - lineary light the shadows by the user - the gamma is calculated according to slope and the characteristics of the image DR, White, Black + int mode = 1; + float slopsmoot = 1.f - ((float) params->locallab.spots.at(sp).slopesmo - 1.f);//modify response so when increase slope the grays are becoming lighter + if(lp.smoothciem == 3) {//slope activ, only with choice gamma - slope - based + rolloff = false;//allows tone-mapping slope + slopegray = slopsmoot; + mode = 3; + } + LUTf lut(65536, LUT_CLIP_OFF);//take from Alberto Griggio + bool scale = lp.issmoothcie;//scale Yb mid_gray - WhiteEv and BlavkEv + tonemapFreeman(slopegray, white_point, black_point, mid_gray, mid_gray_view, rolloff, lut, mode, scale); + + #ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < bfh ; ++ y) {//apply Lut tone-mapping or smooth: thanks to Alberto - gain time. + for (int x = 0; x < bfw ; ++x) { + tmpImage->r(y, x) = 65535.f * lut[tmpImage->r(y, x)]; + tmpImage->g(y, x) = 65535.f * lut[tmpImage->g(y, x)]; + tmpImage->b(y, x) = 65535.f * lut[tmpImage->b(y, x)]; + } + } + + } + + + rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); + + delete tmpImage; + delete tmpImagelog; + } + + if (params->locallab.spots.at(sp).expcie) { + ImProcFunctions::ciecamloc_02float(lp, sp, bufexpfin.get(), bfw, bfh, 0, sk, cielocalcurve, localcieutili, cielocalcurve2, localcieutili2, jzlocalcurve, localjzutili, czlocalcurve, localczutili, czjzlocalcurve, localczjzutili, locchCurvejz, lochhCurvejz, loclhCurvejz, HHcurvejz, CHcurvejz, LHcurvejz, locwavCurvejz, locwavutilijz, maxicam, contsig, lightsig); + } + } + + if (lp.strgradcie != 0.f) { + + struct grad_params gp; + calclocalGradientParams(lp, gp, ystart, xstart, bfw, bfh, 15); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + + for (int ir = 0; ir < bfh; ir++) { + for (int jr = 0; jr < bfw; jr++) { + bufexpfin->L[ir][jr] *= ImProcFunctions::calcGradientFactor(gp, jr, ir); + } + } + } + + if (lp.enacieMask && lp.recothrcie != 1.f) { + float recoth = lp.recothrcie; + + if (lp.recothrcie < 1.f) { + recoth = -1.f * recoth + 2.f; + } + + float hig = lp.higthrcie; + float low = lp.lowthrcie; + float decay = lp.decaycie; + bool invmask = false; + maskrecov(bufexpfin.get(), original, bufmaskorigcie.get(), bfh, bfw, ystart, xstart, hig, low, recoth, decay, invmask, sk, multiThread); + } + + + float radcie = 0.30f; + bool exec_lc = true; + if(lp.moka == 1 && lp.sursouci == 4) {//disable local contrast if user do not want to use ciecam and Cam16 (I make this choice) + exec_lc = false; + } + if(lp.moka == 1) { //cam16 + radcie = 0.01 * params->locallab.spots.at(sp).detailcie; + } else if(lp.moka == 2) { //Jz + radcie = 0.01 * params->locallab.spots.at(sp).detailciejz; + } + if(radcie > 0.f && exec_lc) { + //local contrast + //ampirical ponderation, to verify + float surrsour_ampl_str = 1.f;//amount + float surrsour_ampl_dark = 1.f;//dark + float surrsour_ampl_radius = 1.f;//radius + if(lp.sursouci == 0) {//Average + surrsour_ampl_str = 0.9f; + surrsour_ampl_dark = 1.f; + surrsour_ampl_radius = 1.f; + } else if(lp.sursouci == 1) {//Dim + surrsour_ampl_str = 1.f; + surrsour_ampl_dark = 1.1f; + surrsour_ampl_radius = 1.05f; + } else if(lp.sursouci == 2) {//Dark + surrsour_ampl_str = 1.2f; + surrsour_ampl_dark = 1.2f; + surrsour_ampl_radius = 1.1f; + } else if(lp.sursouci == 3) {//Ex Dark + surrsour_ampl_str = 1.4f; + surrsour_ampl_radius = 1.2f; + surrsour_ampl_dark = 1.5f; + } else if(lp.sursouci == 4 && lp.moka == 2) {//less than average for Jz + surrsour_ampl_str = 0.9f; + surrsour_ampl_radius = 0.9f; + surrsour_ampl_dark = 1.f; + } + LocalContrastParams localContrastParams; + LocallabParams locallabparams; + localContrastParams.enabled = true; + localContrastParams.radius = rtengine::min((double) surrsour_ampl_radius * 80., 100.); + localContrastParams.amount = rtengine::min(radcie * surrsour_ampl_str, 1.f); + localContrastParams.darkness = rtengine::min((double) surrsour_ampl_dark * 1., 3.); + localContrastParams.lightness = 1.; + bool fftwlc = false; + + ImProcFunctions::localContrast(bufexpfin.get(), bufexpfin->L, localContrastParams, fftwlc, sk); + } + + const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcie; + int bw = bufexporig->W; + int bh = bufexporig->H; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if(multiThread) +#endif + + for (int x = 0; x < bh; x++) { + for (int y = 0; y < bw; y++) { + bufexpfin->L[x][y] = intp(repart, bufexporig->L[x][y], bufexpfin->L[x][y]); + bufexpfin->a[x][y] = intp(repart, bufexporig->a[x][y], bufexpfin->a[x][y]); + bufexpfin->b[x][y] = intp(repart, bufexporig->b[x][y], bufexpfin->b[x][y]); + } + } + + if (lp.recothrcie >= 1.f) { + transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), originalmaskcie.get(), hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + } else { + transit_shapedetect2(sp, 0.f, 0.f, call, 31, bufexporig.get(), bufexpfin.get(), nullptr, hueref, chromaref, lumaref, sobelref, 0.f, nullptr, lp, original, transformed, cx, cy, sk); + } + + if (lp.recur) { + original->CopyFrom(transformed, multiThread); + float avge; + calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); + } } + } // Gamut and Munsell control - very important do not deactivated to avoid crash diff --git a/rtengine/iptoneequalizer.cc b/rtengine/iptoneequalizer.cc index 7fb6c791f..350260a92 100644 --- a/rtengine/iptoneequalizer.cc +++ b/rtengine/iptoneequalizer.cc @@ -22,7 +22,11 @@ const std::vector> colormap = { {1.f, 0.f, 0.f}, // whites {1.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, + {1.f, 0.f, 0.f}, {1.f, 0.f, 0.f} + }; @@ -72,16 +76,16 @@ void toneEqualizer( }; // Build the luma channels: band-pass filters with gaussian windows of // std 2 EV, spaced by 2 EV - const float centers[12] = { + const float centers[15] = { -16.0f, -14.0f, -12.0f, -10.0f, -8.0f, -6.0f, - -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f + -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f, 12.0f }; const auto conv = [&](int v, float lo, float hi) -> float { const float f = v < 0 ? lo : hi; return exp2(float(v) / 100.f * f); }; - const float factors[12] = { + const float factors[15] = { conv(params.bands[0], 2.f, 3.f), // -16 EV conv(params.bands[0], 2.f, 3.f), // -14 EV conv(params.bands[0], 2.f, 3.f), // -12 EV @@ -93,7 +97,12 @@ void toneEqualizer( conv(params.bands[4], 3.f, 2.f), // 0 EV conv(params.bands[4], 3.f, 2.f), // 2 EV conv(params.bands[4], 3.f, 2.f), // 4 EV - conv(params.bands[4], 3.f, 2.f) // 6 EV + conv(params.bands[4], 3.f, 2.f), // 6 EV + // this settings under are very rarely used...images with very high DR - I add a slider, but it's not the goal: the goal is white distribution (in very rare case) + // I have not change "main" Tone Equalizer. + conv(params.bands[5], 3.f, 2.f), // 8 EV Added for white distribution (Cam16 and Log encode) and images with very high DR + conv(params.bands[5], 3.f, 2.f), // 10 EV Added for white distribution(Cam16 and Log encode) and images with very high DR + conv(params.bands[5], 3.f, 2.f) // 12 EV Added for white distribution(Cam16 and Log encode) and images with very high DR }; rtengine::TMatrix ws = rtengine::ICCStore::getInstance()->workingSpaceMatrix(workingProfile); @@ -125,7 +134,7 @@ void toneEqualizer( #endif for (int y = 0; y < H; ++y) { for (int x = 0; x < W; ++x) { - float l = rtengine::LIM(log2(rtengine::max(Y[y][x], 1e-9f)), centers[0], centers[11]); + float l = rtengine::LIM(log2(rtengine::max(Y[y][x], 1e-9f)), centers[0], centers[13]); float ll = round(l * base_posterization) / base_posterization; Y2[y][x] = Y[y][x]; Y[y][x] = exp2(ll); @@ -145,12 +154,12 @@ void toneEqualizer( // For every pixel luminance, the sum of the gaussian masks float w_sum = 0.f; - for (int i = 0; i < 12; ++i) { + for (int i = 0; i < 15; ++i) { w_sum += gauss(centers[i], 0.f); } constexpr float luma_lo = -14.f; - constexpr float luma_hi = 4.f; + constexpr float luma_hi = 6.f; const auto process_pixel = [&](float y) -> float { @@ -161,7 +170,7 @@ void toneEqualizer( // luminance channel to current pixel float correction = 0.0f; - for (int c = 0; c < 12; ++c) + for (int c = 0; c < 15; ++c) { correction += gauss(centers[c], luma) * factors[c]; } @@ -198,7 +207,7 @@ void toneEqualizer( // build the correction as the sum of the contribution of each // luminance channel to current pixel - for (int c = 0; c < 12; ++c) { + for (int c = 0; c < 15; ++c) { float w = gauss(centers[c], luma); for (int i = 0; i < 3; ++i) { ret[i] += w * cur_colormap[c][i]; @@ -213,10 +222,10 @@ void toneEqualizer( #ifdef __SSE2__ - vfloat vfactors[12]; - vfloat vcenters[12]; + vfloat vfactors[15]; + vfloat vcenters[15]; - for (int i = 0; i < 12; ++i) { + for (int i = 0; i < 15; ++i) { vfactors[i] = F2V(factors[i]); vcenters[i] = F2V(centers[i]); } @@ -240,7 +249,7 @@ void toneEqualizer( vfloat correction = zerov; - for (int c = 0; c < 12; ++c) + for (int c = 0; c < 15; ++c) { correction += vgauss(vcenters[c], luma) * vfactors[c]; } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 13df614dc..a1408e405 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -1108,7 +1108,7 @@ enum ProcEventCode { Evlocallabsigmoidldacie = 1078, Evlocallabsigmoidthcie = 1079, Evlocallabsigmoidblcie = 1080, - Evlocallabsigmoidqjcie = 1081, + Evlocallabcomprcieauto = 1081, Evlocallabhuecie = 1082, Evlocallabjabcie = 1083, Evlocallablightjzcie = 1084, @@ -1177,6 +1177,7 @@ enum ProcEventCode { Evlocallabsigjz = 1147, Evlocallabsigq = 1148, Evlocallablogcie = 1149, + NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1b8269a2f..cd80a8980 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1886,7 +1886,7 @@ bool SHParams::operator !=(const SHParams& other) const ToneEqualizerParams::ToneEqualizerParams() : enabled(false), - bands{0, 0, 0, 0, 0}, + bands{0, 0, 0, 0, 0, 0}, regularization(0), show_colormap(false), pivot(0) @@ -2390,17 +2390,24 @@ ColorManagementParams::ColorManagementParams() : workingTRC(WorkingTrc::NONE), will(Illuminant::DEFAULT), wprim(Primaries::DEFAULT), + wcat(Cat::BRAD), workingTRCGamma(2.4),//gamma sRGB workingTRCSlope(12.92), + wmidtcie(0.), + wsmoothcie(false), redx(0.7347), redy(0.2653), grex(0.1596), grey(0.8404), blux(0.0366), bluy(0.0001), + refi(0.), + shiftx(0.), + shifty(0.), preser(0.), fbw(false), - gamut(false), + trcExp(false), + gamut(true), labgridcieALow(0.51763),//Prophoto red = (0.7347+0.1) * 1.81818 - 1 labgridcieBLow(-0.33582), labgridcieAHigh(-0.75163),//Prophoto blue @@ -2409,6 +2416,8 @@ ColorManagementParams::ColorManagementParams() : labgridcieGy(-0.70909),//0.84 labgridcieWx(-0.18964),//D50 0.3457, 0.3585, labgridcieWy(-0.16636),// + labgridcieMx(0.),// + labgridcieMy(0.),// aRendIntent(RI_RELATIVE), outputProfile(options.rtSettings.srgb), outputIntent(RI_RELATIVE), @@ -2429,14 +2438,20 @@ bool ColorManagementParams::operator ==(const ColorManagementParams& other) cons && workingTRC == other.workingTRC && will == other.will && wprim == other.wprim + && wcat == other.wcat && workingTRCGamma == other.workingTRCGamma && workingTRCSlope == other.workingTRCSlope + && wmidtcie == other.wmidtcie + && wsmoothcie == other.wsmoothcie && redx == other.redx && redy == other.redy && grex == other.grex && grey == other.grey && blux == other.blux && bluy == other.bluy + && refi == other.refi + && shiftx == other.shiftx + && shifty == other.shifty && labgridcieALow == other.labgridcieALow && labgridcieBLow == other.labgridcieBLow && labgridcieAHigh == other.labgridcieAHigh @@ -2445,8 +2460,11 @@ bool ColorManagementParams::operator ==(const ColorManagementParams& other) cons && labgridcieGy == other.labgridcieGy && labgridcieWx == other.labgridcieWx && labgridcieWy == other.labgridcieWy + && labgridcieMx == other.labgridcieMx + && labgridcieMy == other.labgridcieMy && preser == other.preser && fbw == other.fbw + && trcExp == other.trcExp && gamut == other.gamut && aRendIntent == other.aRendIntent && outputProfile == other.outputProfile @@ -2976,7 +2994,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : loc{150, 150, 150, 150}, centerX(0), centerY(0), - circrad(18), + circrad(18.), qualityMethod("enh"), complexMethod("mod"), transit(60.), @@ -3360,7 +3378,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : expshadhigh(false), complexshadhigh(0), shMethod("tone"), - multsh{0, 0, 0, 0, 0}, + multsh{0, 0, 0, 0, 0, 0}, highlights(0), h_tonalwidth(70), shadows(0), @@ -4227,8 +4245,13 @@ LocallabParams::LocallabSpot::LocallabSpot() : fullimage(true), repar(100.0), ciecam(false), - blackEv(-5.0), - whiteEv(10.0), + satlog(false), + blackEv(-5.00), + whiteEv(10.00), + whiteslog(0), + blackslog(0), + comprlog(0.4), + strelog(100.), detail(0.6), sensilog(60), sursour("Average"), @@ -4400,6 +4423,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : // ciecam visicie(false), expcie(false), + expprecam(false), complexcie(0), reparcie(100.), sensicie(60), @@ -4408,8 +4432,14 @@ LocallabParams::LocallabSpot::LocallabSpot() : forcebw(true), qtoj(false), jabcie(true), - sigmoidqjcie(false), + comprcieauto(false), + normcie(true), + gamutcie(true), + sigcie(true), logcie(false), + satcie(true), + logcieq(false), + smoothcie(false), logjz(false), sigjz(false), sigq(false), @@ -4419,6 +4449,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : sursourcie("Average"), modecie("com"), modecam("cam16"), + bwevMethod("sig"), saturlcie(0.), rstprotectcie(0.), chromlcie(0.), @@ -4550,8 +4581,10 @@ LocallabParams::LocallabSpot::LocallabSpot() : lightlcie(0.), lightjzcie(0.), lightqcie(0.), + lightsigqcie(0.), contlcie(0.), contjzcie(0.), + detailciejz(30.), adapjzcie(4.0), jz100(0.25), pqremap(120.), @@ -4578,33 +4611,60 @@ LocallabParams::LocallabSpot::LocallabSpot() : }, csthresholdjz(0, 0, 7, 4, false), contthrescie(0.), - blackEvjz(-5.0), - whiteEvjz(10.0), + blackEvjz(-5.00), + whiteEvjz(10.00), targetjz(18.0), sigmoidldacie(0.5), - sigmoidthcie(1.), - sigmoidblcie(1.), + sigmoidthcie(1.2), + sigmoidsenscie(0.9), + sigmoidblcie(0.75), + comprcie(0.4), + strcielog(80.), + comprcieth(6.), + gamjcie(2.4), + slopjcie(12.923), + slopesmo(1.), + midtcie(0), + grexl(0.1596), + greyl(0.8404), + bluxl(0.0366), + bluyl(0.0001), + redxl(0.7347), + redyl(0.2653), + refi(0.), + shiftxl(0.), + shiftyl(0.), + labgridcieALow(0.51763),//Prophoto red = (0.7347+0.1) * 1.81818 - 1 + labgridcieBLow(-0.33582), + labgridcieAHigh(-0.75163),//Prophoto blue + labgridcieBHigh(-0.8180), + labgridcieGx(-0.528),//Prophoto green 0.1596 + labgridcieGy(0.7096),//0.84 + labgridcieWx(-0.18964),//D50 0.3457, 0.3585, + labgridcieWy(-0.16636),// + labgridcieMx(0.), + labgridcieMy(0.),// + whitescie(0), + blackscie(0), + illMethod("d50"), + smoothciemet("none"), + primMethod("pro"), + catMethod("brad"), sigmoidldajzcie(0.5), sigmoidthjzcie(1.), sigmoidbljzcie(1.), contqcie(0.), + contsigqcie(0.), colorflcie(0.), -/* - lightlzcam(0.), - lightqzcam(0.), - contlzcam(0.), - contqzcam(0.), - contthreszcam(0.), - colorflzcam(0.), - saturzcam(0.), - chromzcam(0.), -*/ targabscie(16.), targetGraycie(18.), catadcie(0.), - detailcie(0.), + detailcie(30.), surroundcie("Average"), + strgradcie(0.), + anggradcie(0.), enacieMask(false), + enacieMaskall(false), CCmaskciecurve{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -4650,6 +4710,22 @@ LocallabParams::LocallabSpot::LocallabSpot() : 0.35, 0.35 }, + HHhmaskciecurve{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 0.5, + 0.35, + 0.35, + 0.50, + 0.5, + 0.35, + 0.35, + 1.00, + 0.5, + 0.35, + 0.35 + }, + blendmaskcie(0), radmaskcie(0.0), chromaskcie(0.0), @@ -4666,8 +4742,27 @@ LocallabParams::LocallabSpot::LocallabSpot() : recothrescie(1.), lowthrescie(12.), higthrescie(85.), - decaycie(2.) - + decaycie(2.), + strumaskcie(0.), + toolcie(false), + fftcieMask(true), + contcie(0.), + blurcie(0.2), + highmaskcie(0.), + shadmaskcie(0.), + LLmaskciecurvewav{ + static_cast(FCT_MinMaxCPoints), + 0.0, + 0.5, + 0.35, + 0.35, + 1., + 0.5, + 0.35, + 0.35 + }, + csthresholdcie(0, 0, 6, 5, false) + { } @@ -4843,7 +4938,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && shMethod == other.shMethod && [this, &other]() -> bool { - for (int i = 0; i < 5; ++i) { + for (int i = 0; i < 6; ++i) { if (multsh[i] != other.multsh[i]) { return false; } @@ -5226,8 +5321,13 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && fullimage == other.fullimage && repar == other.repar && ciecam == other.ciecam + && satlog == other.satlog && blackEv == other.blackEv && whiteEv == other.whiteEv + && whiteslog == other.whiteslog + && blackslog == other.blackslog + && comprlog == other.comprlog + && strelog == other.strelog && detail == other.detail && sensilog == other.sensilog && baselog == other.baselog @@ -5280,6 +5380,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const //ciecam && visicie == other.visicie && expcie == other.expcie + && expprecam == other.expprecam && complexcie == other.complexcie && reparcie == other.reparcie && sensicie == other.sensicie @@ -5288,8 +5389,14 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && forcebw == other.forcebw && qtoj == other.qtoj && jabcie == other.jabcie - && sigmoidqjcie == other.sigmoidqjcie + && comprcieauto == other.comprcieauto + && normcie == other.normcie + && gamutcie == other.gamutcie + && sigcie == other.sigcie && logcie == other.logcie + && satcie == other.satcie + && logcieq == other.logcieq + && smoothcie == other.smoothcie && logjz == other.logjz && sigjz == other.sigjz && sigq == other.sigq @@ -5299,6 +5406,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && sursourcie == other.sursourcie && modecie == other.modecie && modecam == other.modecam + && bwevMethod == other.bwevMethod && saturlcie == other.saturlcie && rstprotectcie == other.rstprotectcie && chromlcie == other.chromlcie @@ -5322,8 +5430,10 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && lightlcie == other.lightlcie && lightjzcie == other.lightjzcie && lightqcie == other.lightqcie + && lightsigqcie == other.lightsigqcie && contlcie == other.contlcie && contjzcie == other.contjzcie + && detailciejz == other.detailciejz && adapjzcie == other.adapjzcie && jz100 == other.jz100 && pqremap == other.pqremap @@ -5345,30 +5455,59 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && targetjz == other.targetjz && sigmoidldacie == other.sigmoidldacie && sigmoidthcie == other.sigmoidthcie + && sigmoidsenscie == other.sigmoidsenscie && sigmoidblcie == other.sigmoidblcie + && comprcie == other.comprcie + && strcielog == other.strcielog + && comprcieth == other.comprcieth + && gamjcie == other.gamjcie + && slopjcie == other.slopjcie + && slopesmo == other.slopesmo + && midtcie == other.midtcie + && redxl == other.redxl + && redyl == other.redyl + && grexl == other.grexl + && greyl == other.greyl + && bluxl == other.bluxl + && bluyl == other.bluyl + && refi == other.refi + && shiftxl == other.shiftxl + && shiftyl == other.shiftyl + && labgridcieALow == other.labgridcieALow + && labgridcieBLow == other.labgridcieBLow + && labgridcieAHigh == other.labgridcieAHigh + && labgridcieBHigh == other.labgridcieBHigh + && labgridcieGx == other.labgridcieGx + && labgridcieGy == other.labgridcieGy + && labgridcieWx == other.labgridcieWx + && labgridcieWy == other.labgridcieWy + && labgridcieMx == other.labgridcieMx + && labgridcieMy == other.labgridcieMy + && whitescie == other.whitescie + && blackscie == other.blackscie + && illMethod == other.illMethod + && smoothciemet == other.smoothciemet + && primMethod == other.primMethod + && catMethod == other.catMethod && sigmoidldajzcie == other.sigmoidldajzcie && sigmoidthjzcie == other.sigmoidthjzcie && sigmoidbljzcie == other.sigmoidbljzcie && contqcie == other.contqcie + && contsigqcie == other.contsigqcie && colorflcie == other.colorflcie -/* && lightlzcam == other.lightlzcam - && lightqzcam == other.lightqzcam - && contlzcam == other.contlzcam - && contqzcam == other.contqzcam - && contthreszcam == other.contthreszcam - && colorflzcam == other.colorflzcam - && saturzcam == other.saturzcam - && chromzcam == other.chromzcam -*/ && targabscie == other.targabscie && targetGraycie == other.targetGraycie && catadcie == other.catadcie && detailcie == other.detailcie + && strgradcie == other.strgradcie + && anggradcie == other.anggradcie && surroundcie == other.surroundcie && enacieMask == other.enacieMask + && enacieMaskall == other.enacieMaskall && CCmaskciecurve == other.CCmaskciecurve && LLmaskciecurve == other.LLmaskciecurve && HHmaskciecurve == other.HHmaskciecurve + && HHhmaskciecurve == other.HHhmaskcurve && blendmaskcie == other.blendmaskcie && radmaskcie == other.radmaskcie && chromaskcie == other.chromaskcie @@ -5379,8 +5518,16 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && recothrescie == other.recothrescie && lowthrescie == other.lowthrescie && higthrescie == other.higthrescie - && decaycie == other.decaycie; - + && decaycie == other.decaycie + && strumaskcie == other.strumaskcie + && toolcie == other.toolcie + && blurcie == other.blurcie + && contcie == other.contcie + && highmaskcie == other.highmaskcie + && shadmaskcie == other.shadmaskcie + && fftcieMask == other.fftcieMask + && LLmaskciecurvewav == other.LLmaskciecurvewav + && csthresholdcie == other.csthresholdcie; } @@ -6730,7 +6877,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->complexshadhigh, "Locallab", "Complexshadhigh_" + index_str, spot.complexshadhigh, keyFile); saveToKeyfile(!pedited || spot_edited->shMethod, "Locallab", "ShMethod_" + index_str, spot.shMethod, keyFile); - for (int j = 0; j < 5; j++) { + for (int j = 0; j < 6; j++) { saveToKeyfile(!pedited || spot_edited->multsh[j], "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, spot.multsh[j], keyFile); } @@ -7114,8 +7261,13 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->fullimage, "Locallab", "Fullimage_" + index_str, spot.fullimage, keyFile); saveToKeyfile(!pedited || spot_edited->repar, "Locallab", "Repart_" + index_str, spot.repar, keyFile); saveToKeyfile(!pedited || spot_edited->ciecam, "Locallab", "Ciecam_" + index_str, spot.ciecam, keyFile); + saveToKeyfile(!pedited || spot_edited->satlog, "Locallab", "Satlog_" + index_str, spot.satlog, keyFile); saveToKeyfile(!pedited || spot_edited->blackEv, "Locallab", "BlackEv_" + index_str, spot.blackEv, keyFile); saveToKeyfile(!pedited || spot_edited->whiteEv, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, keyFile); + saveToKeyfile(!pedited || spot_edited->whiteslog, "Locallab", "Whiteslog_" + index_str, spot.whiteslog, keyFile); + saveToKeyfile(!pedited || spot_edited->blackslog, "Locallab", "Blackslog_" + index_str, spot.blackslog, keyFile); + saveToKeyfile(!pedited || spot_edited->comprlog, "Locallab", "Comprlog_" + index_str, spot.comprlog, keyFile); + saveToKeyfile(!pedited || spot_edited->strelog, "Locallab", "Strelog_" + index_str, spot.strelog, keyFile); saveToKeyfile(!pedited || spot_edited->detail, "Locallab", "Detail_" + index_str, spot.detail, keyFile); saveToKeyfile(!pedited || spot_edited->sensilog, "Locallab", "Sensilog_" + index_str, spot.sensilog, keyFile); saveToKeyfile(!pedited || spot_edited->baselog, "Locallab", "Baselog_" + index_str, spot.baselog, keyFile); @@ -7170,6 +7322,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo //ciecam if ((!pedited || spot_edited->visicie) && spot.visicie) { saveToKeyfile(!pedited || spot_edited->expcie, "Locallab", "Expcie_" + index_str, spot.expcie, keyFile); + saveToKeyfile(!pedited || spot_edited->expprecam, "Locallab", "Expprecam_" + index_str, spot.expprecam, keyFile); saveToKeyfile(!pedited || spot_edited->complexcie, "Locallab", "Complexcie_" + index_str, spot.complexcie, keyFile); saveToKeyfile(!pedited || spot_edited->reparcie, "Locallab", "Reparcie_" + index_str, spot.reparcie, keyFile); saveToKeyfile(!pedited || spot_edited->sensicie, "Locallab", "Sensicie_" + index_str, spot.sensicie, keyFile); @@ -7178,8 +7331,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->forcebw, "Locallab", "Forcebw_" + index_str, spot.forcebw, keyFile); saveToKeyfile(!pedited || spot_edited->qtoj, "Locallab", "Qtoj_" + index_str, spot.qtoj, keyFile); saveToKeyfile(!pedited || spot_edited->jabcie, "Locallab", "jabcie_" + index_str, spot.jabcie, keyFile); - saveToKeyfile(!pedited || spot_edited->sigmoidqjcie, "Locallab", "sigmoidqjcie_" + index_str, spot.sigmoidqjcie, keyFile); + saveToKeyfile(!pedited || spot_edited->comprcieauto, "Locallab", "comprcieauto_" + index_str, spot.comprcieauto, keyFile); + saveToKeyfile(!pedited || spot_edited->normcie, "Locallab", "normcie_" + index_str, spot.normcie, keyFile); + saveToKeyfile(!pedited || spot_edited->gamutcie, "Locallab", "gamutcie_" + index_str, spot.gamutcie, keyFile); + saveToKeyfile(!pedited || spot_edited->sigcie, "Locallab", "sigcie_" + index_str, spot.sigcie, keyFile); saveToKeyfile(!pedited || spot_edited->logcie, "Locallab", "logcie_" + index_str, spot.logcie, keyFile); + saveToKeyfile(!pedited || spot_edited->satcie, "Locallab", "satcie_" + index_str, spot.satcie, keyFile); + saveToKeyfile(!pedited || spot_edited->logcieq, "Locallab", "logcieq_" + index_str, spot.logcieq, keyFile); + saveToKeyfile(!pedited || spot_edited->smoothcie, "Locallab", "smoothcie_" + index_str, spot.smoothcie, keyFile); saveToKeyfile(!pedited || spot_edited->logjz, "Locallab", "Logjz_" + index_str, spot.logjz, keyFile); saveToKeyfile(!pedited || spot_edited->sigjz, "Locallab", "Sigjz_" + index_str, spot.sigjz, keyFile); saveToKeyfile(!pedited || spot_edited->sigq, "Locallab", "Sigq_" + index_str, spot.sigq, keyFile); @@ -7189,6 +7348,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->sursourcie, "Locallab", "Sursourcie_" + index_str, spot.sursourcie, keyFile); saveToKeyfile(!pedited || spot_edited->modecie, "Locallab", "Modecie_" + index_str, spot.modecie, keyFile); saveToKeyfile(!pedited || spot_edited->modecam, "Locallab", "Modecam_" + index_str, spot.modecam, keyFile); + saveToKeyfile(!pedited || spot_edited->bwevMethod, "Locallab", "bwevMethod_" + index_str, spot.bwevMethod, keyFile); saveToKeyfile(!pedited || spot_edited->saturlcie, "Locallab", "Saturlcie_" + index_str, spot.saturlcie, keyFile); saveToKeyfile(!pedited || spot_edited->rstprotectcie, "Locallab", "Rstprotectcie_" + index_str, spot.rstprotectcie, keyFile); saveToKeyfile(!pedited || spot_edited->chromlcie, "Locallab", "Chromlcie_" + index_str, spot.chromlcie, keyFile); @@ -7212,8 +7372,10 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->lightlcie, "Locallab", "Lightlcie_" + index_str, spot.lightlcie, keyFile); saveToKeyfile(!pedited || spot_edited->lightjzcie, "Locallab", "Lightjzcie_" + index_str, spot.lightjzcie, keyFile); saveToKeyfile(!pedited || spot_edited->lightqcie, "Locallab", "Brightqcie_" + index_str, spot.lightqcie, keyFile); + saveToKeyfile(!pedited || spot_edited->lightsigqcie, "Locallab", "Brightsigqcie_" + index_str, spot.lightsigqcie, keyFile); saveToKeyfile(!pedited || spot_edited->contlcie, "Locallab", "Contlcie_" + index_str, spot.contlcie, keyFile); saveToKeyfile(!pedited || spot_edited->contjzcie, "Locallab", "Contjzcie_" + index_str, spot.contjzcie, keyFile); + saveToKeyfile(!pedited || spot_edited->detailciejz, "Locallab", "Detailciejz_" + index_str, spot.detailciejz, keyFile); saveToKeyfile(!pedited || spot_edited->adapjzcie, "Locallab", "Adapjzcie_" + index_str, spot.adapjzcie, keyFile); saveToKeyfile(!pedited || spot_edited->jz100, "Locallab", "Jz100_" + index_str, spot.jz100, keyFile); saveToKeyfile(!pedited || spot_edited->pqremap, "Locallab", "PQremap_" + index_str, spot.pqremap, keyFile); @@ -7235,31 +7397,61 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->targetjz, "Locallab", "Targetjz_" + index_str, spot.targetjz, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidldacie, "Locallab", "Sigmoidldacie_" + index_str, spot.sigmoidldacie, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidthcie, "Locallab", "Sigmoidthcie_" + index_str, spot.sigmoidthcie, keyFile); + saveToKeyfile(!pedited || spot_edited->sigmoidsenscie, "Locallab", "Sigmoidsenscie_" + index_str, spot.sigmoidsenscie, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidblcie, "Locallab", "Sigmoidblcie_" + index_str, spot.sigmoidblcie, keyFile); + saveToKeyfile(!pedited || spot_edited->comprcie, "Locallab", "comprcie_" + index_str, spot.comprcie, keyFile); + saveToKeyfile(!pedited || spot_edited->strcielog, "Locallab", "strcielog_" + index_str, spot.strcielog, keyFile); + saveToKeyfile(!pedited || spot_edited->comprcieth, "Locallab", "comprcieth_" + index_str, spot.comprcieth, keyFile); + saveToKeyfile(!pedited || spot_edited->gamjcie, "Locallab", "gamjcie_" + index_str, spot.gamjcie, keyFile); + saveToKeyfile(!pedited || spot_edited->slopjcie, "Locallab", "slopjcie_" + index_str, spot.slopjcie, keyFile); + saveToKeyfile(!pedited || spot_edited->slopesmo, "Locallab", "slopesmo_" + index_str, spot.slopesmo, keyFile); + saveToKeyfile(!pedited || spot_edited->midtcie, "Locallab", "midtcie_" + index_str, spot.midtcie, keyFile); + saveToKeyfile(!pedited || spot_edited->redxl, "Locallab", "redxl_" + index_str, spot.redxl, keyFile); + saveToKeyfile(!pedited || spot_edited->redyl, "Locallab", "redyl_" + index_str, spot.redyl, keyFile); + saveToKeyfile(!pedited || spot_edited->grexl, "Locallab", "grexl_" + index_str, spot.grexl, keyFile); + saveToKeyfile(!pedited || spot_edited->greyl, "Locallab", "greyl_" + index_str, spot.greyl, keyFile); + saveToKeyfile(!pedited || spot_edited->bluxl, "Locallab", "bluxl_" + index_str, spot.bluxl, keyFile); + saveToKeyfile(!pedited || spot_edited->bluyl, "Locallab", "bluyl_" + index_str, spot.bluyl, keyFile); + saveToKeyfile(!pedited || spot_edited->refi, "Locallab", "refi_" + index_str, spot.refi, keyFile); + saveToKeyfile(!pedited || spot_edited->shiftxl, "Locallab", "shiftxl_" + index_str, spot.shiftxl, keyFile); + saveToKeyfile(!pedited || spot_edited->shiftyl, "Locallab", "shiftyl_" + index_str, spot.shiftyl, keyFile); + + saveToKeyfile(!pedited || spot_edited->labgridcieALow, "Locallab", "labgridcieALow_" + index_str, spot.labgridcieALow, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieBLow, "Locallab", "labgridcieBLow_" + index_str, spot.labgridcieBLow, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieAHigh, "Locallab", "labgridcieAHigh_" + index_str, spot.labgridcieAHigh, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieBHigh, "Locallab", "labgridcieBHigh_" + index_str, spot.labgridcieBHigh, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieGx, "Locallab", "labgridcieGx_" + index_str, spot.labgridcieGx, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieGy, "Locallab", "labgridcieGy_" + index_str, spot.labgridcieGy, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieWx, "Locallab", "labgridcieWx_" + index_str, spot.labgridcieWx, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieWy, "Locallab", "labgridcieWy_" + index_str, spot.labgridcieWy, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieMx, "Locallab", "labgridcieMx_" + index_str, spot.labgridcieMx, keyFile); + saveToKeyfile(!pedited || spot_edited->labgridcieMy, "Locallab", "labgridcieMy_" + index_str, spot.labgridcieMy, keyFile); + + saveToKeyfile(!pedited || spot_edited->whitescie, "Locallab", "whitescie_" + index_str, spot.whitescie, keyFile); + saveToKeyfile(!pedited || spot_edited->blackscie, "Locallab", "blackscie_" + index_str, spot.blackscie, keyFile); + saveToKeyfile(!pedited || spot_edited->illMethod, "Locallab", "illMethod_" + index_str, spot.illMethod, keyFile); + saveToKeyfile(!pedited || spot_edited->smoothciemet, "Locallab", "smoothciemet_" + index_str, spot.smoothciemet, keyFile); + saveToKeyfile(!pedited || spot_edited->primMethod, "Locallab", "primMethod_" + index_str, spot.primMethod, keyFile); + saveToKeyfile(!pedited || spot_edited->catMethod, "Locallab", "catMethod_" + index_str, spot.catMethod, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidldajzcie, "Locallab", "Sigmoidldajzcie_" + index_str, spot.sigmoidldajzcie, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidthjzcie, "Locallab", "Sigmoidthjzcie_" + index_str, spot.sigmoidthjzcie, keyFile); saveToKeyfile(!pedited || spot_edited->sigmoidbljzcie, "Locallab", "Sigmoidbljzcie_" + index_str, spot.sigmoidbljzcie, keyFile); saveToKeyfile(!pedited || spot_edited->contqcie, "Locallab", "Contqcie_" + index_str, spot.contqcie, keyFile); + saveToKeyfile(!pedited || spot_edited->contsigqcie, "Locallab", "Contsigqcie_" + index_str, spot.contsigqcie, keyFile); saveToKeyfile(!pedited || spot_edited->colorflcie, "Locallab", "Colorflcie_" + index_str, spot.colorflcie, keyFile); -/* - saveToKeyfile(!pedited || spot_edited->lightlzcam, "Locallab", "Lightlzcam_" + index_str, spot.lightlzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->lightqzcam, "Locallab", "Lightqzcam_" + index_str, spot.lightqzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->contlzcam, "Locallab", "Contlzcam_" + index_str, spot.contlzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->contqzcam, "Locallab", "Contqzcam_" + index_str, spot.contqzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->contthreszcam, "Locallab", "Contthreszcam_" + index_str, spot.contthreszcam, keyFile); - saveToKeyfile(!pedited || spot_edited->colorflzcam, "Locallab", "Colorflzcam_" + index_str, spot.colorflzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->saturzcam, "Locallab", "Saturzcam_" + index_str, spot.saturzcam, keyFile); - saveToKeyfile(!pedited || spot_edited->chromzcam, "Locallab", "Chromzcam_" + index_str, spot.chromzcam, keyFile); -*/ saveToKeyfile(!pedited || spot_edited->targabscie, "Locallab", "Targabscie_" + index_str, spot.targabscie, keyFile); saveToKeyfile(!pedited || spot_edited->targetGraycie, "Locallab", "TargetGraycie_" + index_str, spot.targetGraycie, keyFile); saveToKeyfile(!pedited || spot_edited->catadcie, "Locallab", "Catadcie_" + index_str, spot.catadcie, keyFile); saveToKeyfile(!pedited || spot_edited->detailcie, "Locallab", "Detailcie_" + index_str, spot.detailcie, keyFile); + saveToKeyfile(!pedited || spot_edited->strgradcie, "Locallab", "Strgradcie_" + index_str, spot.strgradcie, keyFile); + saveToKeyfile(!pedited || spot_edited->anggradcie, "Locallab", "Anggradcie_" + index_str, spot.anggradcie, keyFile); saveToKeyfile(!pedited || spot_edited->surroundcie, "Locallab", "Surroundcie_" + index_str, spot.surroundcie, keyFile); saveToKeyfile(!pedited || spot_edited->enacieMask, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, keyFile); + saveToKeyfile(!pedited || spot_edited->enacieMaskall, "Locallab", "EnacieMaskall_" + index_str, spot.enacieMaskall, keyFile); saveToKeyfile(!pedited || spot_edited->CCmaskciecurve, "Locallab", "CCmaskcieCurve_" + index_str, spot.CCmaskciecurve, keyFile); saveToKeyfile(!pedited || spot_edited->LLmaskciecurve, "Locallab", "LLmaskcieCurve_" + index_str, spot.LLmaskciecurve, keyFile); saveToKeyfile(!pedited || spot_edited->HHmaskciecurve, "Locallab", "HHmaskcieCurve_" + index_str, spot.HHmaskciecurve, keyFile); + saveToKeyfile(!pedited || spot_edited->HHhmaskciecurve, "Locallab", "HHhmaskcieCurve_" + index_str, spot.HHhmaskciecurve, keyFile); saveToKeyfile(!pedited || spot_edited->blendmaskcie, "Locallab", "Blendmaskcie_" + index_str, spot.blendmaskcie, keyFile); saveToKeyfile(!pedited || spot_edited->radmaskcie, "Locallab", "Radmaskcie_" + index_str, spot.radmaskcie, keyFile); saveToKeyfile(!pedited || spot_edited->chromaskcie, "Locallab", "Chromaskcie_" + index_str, spot.chromaskcie, keyFile); @@ -7271,11 +7463,19 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->lowthrescie, "Locallab", "Lowthrescie_" + index_str, spot.lowthrescie, keyFile); saveToKeyfile(!pedited || spot_edited->higthrescie, "Locallab", "Higthrescie_" + index_str, spot.higthrescie, keyFile); saveToKeyfile(!pedited || spot_edited->decaycie, "Locallab", "Decaycie_" + index_str, spot.decaycie, keyFile); + saveToKeyfile(!pedited || spot_edited->strumaskcie, "Locallab", "strumaskcie_" + index_str, spot.strumaskcie, keyFile); + saveToKeyfile(!pedited || spot_edited->toolcie, "Locallab", "toolcie_" + index_str, spot.toolcie, keyFile); + saveToKeyfile(!pedited || spot_edited->fftcieMask, "Locallab", "FftcieMask_" + index_str, spot.fftcieMask, keyFile); + saveToKeyfile(!pedited || spot_edited->contcie, "Locallab", "contcie_" + index_str, spot.contcie, keyFile); + saveToKeyfile(!pedited || spot_edited->blurcie, "Locallab", "blurcie_" + index_str, spot.blurcie, keyFile); + saveToKeyfile(!pedited || spot_edited->blurcie, "Locallab", "highmaskcie_" + index_str, spot.highmaskcie, keyFile); + saveToKeyfile(!pedited || spot_edited->blurcie, "Locallab", "shadmaskcie_" + index_str, spot.shadmaskcie, keyFile); + saveToKeyfile(!pedited || spot_edited->LLmaskciecurvewav, "Locallab", "LLmaskcieCurvewav_" + index_str, spot.LLmaskciecurvewav, keyFile); + saveToKeyfile(!pedited || spot_edited->csthresholdcie, "Locallab", "CSThresholdcie_" + index_str, spot.csthresholdcie.toVector(), keyFile); } - } } @@ -7374,7 +7574,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo {ColorManagementParams::Illuminant::D120, "D120"}, {ColorManagementParams::Illuminant::STDA, "stda"}, {ColorManagementParams::Illuminant::TUNGSTEN_2000K, "2000"}, - {ColorManagementParams::Illuminant::TUNGSTEN_1500K, "1500"} + {ColorManagementParams::Illuminant::TUNGSTEN_1500K, "1500"}, + {ColorManagementParams::Illuminant::E, "E"} }, icm.will, keyFile @@ -7393,6 +7594,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo {ColorManagementParams::Primaries::WIDE_GAMUT, "wid"}, {ColorManagementParams::Primaries::ACES_P0, "ac0"}, {ColorManagementParams::Primaries::JDC_MAX, "jdcmax"}, + {ColorManagementParams::Primaries::JDC_MAXSTDA, "jdcmaxstdA"}, {ColorManagementParams::Primaries::BRUCE_RGB, "bru"}, {ColorManagementParams::Primaries::BETA_RGB, "bet"}, {ColorManagementParams::Primaries::BEST_RGB, "bst"}, @@ -7402,14 +7604,34 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo icm.wprim, keyFile ); + saveToKeyfile( + !pedited || pedited->icm.wcat, + "Color Management", + "Wcat", + { + {ColorManagementParams::Cat::BRAD, "brad"}, + {ColorManagementParams::Cat::CAT16, "cat16"}, + {ColorManagementParams::Cat::CAT02, "cat02"}, + {ColorManagementParams::Cat::CAT_VK, "cat_vk"}, + {ColorManagementParams::Cat::CAT_XYZ, "cat_xyz"} + }, + icm.wcat, + keyFile + ); + saveToKeyfile(!pedited || pedited->icm.workingTRCGamma, "Color Management", "WorkingTRCGamma", icm.workingTRCGamma, keyFile); saveToKeyfile(!pedited || pedited->icm.workingTRCSlope, "Color Management", "WorkingTRCSlope", icm.workingTRCSlope, keyFile); + saveToKeyfile(!pedited || pedited->icm.wmidtcie, "Color Management", "Wmidtcie", icm.wmidtcie, keyFile); + saveToKeyfile(!pedited || pedited->icm.wsmoothcie, "Color Management", "Wsmoothcie", icm.wsmoothcie, keyFile); saveToKeyfile(!pedited || pedited->icm.redx, "Color Management", "Redx", icm.redx, keyFile); saveToKeyfile(!pedited || pedited->icm.redy, "Color Management", "Redy", icm.redy, keyFile); saveToKeyfile(!pedited || pedited->icm.grex, "Color Management", "Grex", icm.grex, keyFile); saveToKeyfile(!pedited || pedited->icm.grey, "Color Management", "Grey", icm.grey, keyFile); saveToKeyfile(!pedited || pedited->icm.blux, "Color Management", "Blux", icm.blux, keyFile); saveToKeyfile(!pedited || pedited->icm.bluy, "Color Management", "Bluy", icm.bluy, keyFile); + saveToKeyfile(!pedited || pedited->icm.refi, "Color Management", "Refi", icm.refi, keyFile); + saveToKeyfile(!pedited || pedited->icm.shiftx, "Color Management", "Shiftx", icm.shiftx, keyFile); + saveToKeyfile(!pedited || pedited->icm.shifty, "Color Management", "Shifty", icm.shifty, keyFile); saveToKeyfile(!pedited || pedited->icm.labgridcieALow, "Color Management", "LabGridcieALow", icm.labgridcieALow, keyFile); saveToKeyfile(!pedited || pedited->icm.labgridcieBLow, "Color Management", "LabGridcieBLow", icm.labgridcieBLow, keyFile); saveToKeyfile(!pedited || pedited->icm.labgridcieAHigh, "Color Management", "LabGridcieAHigh", icm.labgridcieAHigh, keyFile); @@ -7418,8 +7640,11 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->icm.labgridcieGy, "Color Management", "LabGridcieGy", icm.labgridcieGy, keyFile); saveToKeyfile(!pedited || pedited->icm.labgridcieWx, "Color Management", "LabGridcieWx", icm.labgridcieWx, keyFile); saveToKeyfile(!pedited || pedited->icm.labgridcieWy, "Color Management", "LabGridcieWy", icm.labgridcieWy, keyFile); + saveToKeyfile(!pedited || pedited->icm.labgridcieMx, "Color Management", "LabGridcieMx", icm.labgridcieMx, keyFile); + saveToKeyfile(!pedited || pedited->icm.labgridcieMy, "Color Management", "LabGridcieMy", icm.labgridcieMy, keyFile); saveToKeyfile(!pedited || pedited->icm.preser, "Color Management", "Preser", icm.preser, keyFile); saveToKeyfile(!pedited || pedited->icm.fbw, "Color Management", "Fbw", icm.fbw, keyFile); + saveToKeyfile(!pedited || pedited->icm.trcExp, "Color Management", "TrcExp", icm.trcExp, keyFile); saveToKeyfile(!pedited || pedited->icm.gamut, "Color Management", "Gamut", icm.gamut, keyFile); saveToKeyfile(!pedited || pedited->icm.outputProfile, "Color Management", "OutputProfile", icm.outputProfile, keyFile); saveToKeyfile( @@ -8742,6 +8967,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "ShapeMethod_" + index_str, spot.shapeMethod, spotEdited.shapeMethod); if (keyFile.has_key("Locallab", "AvoidgamutMethod_" + index_str)) { assignFromKeyfile(keyFile, "Locallab", "AvoidgamutMethod_" + index_str, spot.avoidgamutMethod, spotEdited.avoidgamutMethod); + /* if (ppVersion < 351) { + if(spot.avoidgamutMethod == "XYZ") {//5.10 default value + spot.avoidgamutMethod = "MUNS";//set to Munsell only + } + } */ } else if (keyFile.has_key("Locallab", "Avoid_" + index_str)) { const bool avoid = keyFile.get_boolean("Locallab", "Avoid_" + index_str); const bool munsell = keyFile.has_key("Locallab", "Avoidmun_" + index_str) && keyFile.get_boolean("Locallab", "Avoidmun_" + index_str); @@ -8927,7 +9157,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Complexshadhigh_" + index_str, spot.complexshadhigh, spotEdited.complexshadhigh); assignFromKeyfile(keyFile, "Locallab", "ShMethod_" + index_str, spot.shMethod, spotEdited.shMethod); - for (int j = 0; j < 5; j ++) { + for (int j = 0; j < 6; j ++) { assignFromKeyfile(keyFile, "Locallab", "Multsh" + std::to_string(j) + "_" + index_str, spot.multsh[j], spotEdited.multsh[j]); } @@ -9370,8 +9600,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, spot.fullimage, spotEdited.fullimage); assignFromKeyfile(keyFile, "Locallab", "Repart_" + index_str, spot.repar, spotEdited.repar); assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, spot.ciecam, spotEdited.ciecam); + assignFromKeyfile(keyFile, "Locallab", "Satlog_" + index_str, spot.satlog, spotEdited.satlog); assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, spot.blackEv, spotEdited.blackEv); assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, spotEdited.whiteEv); + assignFromKeyfile(keyFile, "Locallab", "Whiteslog_" + index_str, spot.whiteslog, spotEdited.whiteslog); + assignFromKeyfile(keyFile, "Locallab", "Blackslog_" + index_str, spot.blackslog, spotEdited.blackslog); + assignFromKeyfile(keyFile, "Locallab", "Comprlog_" + index_str, spot.comprlog, spotEdited.comprlog); + assignFromKeyfile(keyFile, "Locallab", "Strelog_" + index_str, spot.strelog, spotEdited.strelog); assignFromKeyfile(keyFile, "Locallab", "Detail_" + index_str, spot.detail, spotEdited.detail); assignFromKeyfile(keyFile, "Locallab", "Sensilog_" + index_str, spot.sensilog, spotEdited.sensilog); assignFromKeyfile(keyFile, "Locallab", "Baselog_" + index_str, spot.baselog, spotEdited.baselog); @@ -9440,6 +9675,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (spot.visicie) { spotEdited.visicie = true; } + assignFromKeyfile(keyFile, "Locallab", "Expprecam_" + index_str, spot.expprecam, spotEdited.expprecam); assignFromKeyfile(keyFile, "Locallab", "Complexcie_" + index_str, spot.complexcie, spotEdited.complexcie); assignFromKeyfile(keyFile, "Locallab", "Reparcie_" + index_str, spot.reparcie, spotEdited.reparcie); assignFromKeyfile(keyFile, "Locallab", "Sensicie_" + index_str, spot.sensicie, spotEdited.sensicie); @@ -9448,8 +9684,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Forcebw_" + index_str, spot.forcebw, spotEdited.forcebw); assignFromKeyfile(keyFile, "Locallab", "Qtoj_" + index_str, spot.qtoj, spotEdited.qtoj); assignFromKeyfile(keyFile, "Locallab", "jabcie_" + index_str, spot.jabcie, spotEdited.jabcie); - assignFromKeyfile(keyFile, "Locallab", "sigmoidqjcie_" + index_str, spot.sigmoidqjcie, spotEdited.sigmoidqjcie); + assignFromKeyfile(keyFile, "Locallab", "comprcieauto_" + index_str, spot.comprcieauto, spotEdited.comprcieauto); + assignFromKeyfile(keyFile, "Locallab", "normcie_" + index_str, spot.normcie, spotEdited.normcie); + assignFromKeyfile(keyFile, "Locallab", "gamutcie_" + index_str, spot.gamutcie, spotEdited.gamutcie); + assignFromKeyfile(keyFile, "Locallab", "sigcie_" + index_str, spot.sigcie, spotEdited.sigcie); assignFromKeyfile(keyFile, "Locallab", "logcie_" + index_str, spot.logcie, spotEdited.logcie); + assignFromKeyfile(keyFile, "Locallab", "satcie_" + index_str, spot.satcie, spotEdited.satcie); + assignFromKeyfile(keyFile, "Locallab", "logcieq_" + index_str, spot.logcieq, spotEdited.logcieq); + assignFromKeyfile(keyFile, "Locallab", "smoothcie_" + index_str, spot.smoothcie, spotEdited.smoothcie); assignFromKeyfile(keyFile, "Locallab", "Logjz_" + index_str, spot.logjz, spotEdited.logjz); assignFromKeyfile(keyFile, "Locallab", "Sigjz_" + index_str, spot.sigjz, spotEdited.sigjz); assignFromKeyfile(keyFile, "Locallab", "Sigq_" + index_str, spot.sigq, spotEdited.sigq); @@ -9459,8 +9701,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Sursourcie_" + index_str, spot.sursourcie, spotEdited.sursourcie); assignFromKeyfile(keyFile, "Locallab", "Modecie_" + index_str, spot.modecie, spotEdited.modecie); assignFromKeyfile(keyFile, "Locallab", "Modecam_" + index_str, spot.modecam, spotEdited.modecam); + assignFromKeyfile(keyFile, "Locallab", "bwevMethod_" + index_str, spot.bwevMethod, spotEdited.bwevMethod); assignFromKeyfile(keyFile, "Locallab", "Saturlcie_" + index_str, spot.saturlcie, spotEdited.saturlcie); - assignFromKeyfile(keyFile, "Locallab", "Rstprotectcie_" + index_str, spot.rstprotectcie, spotEdited.rstprotectcie); + assignFromKeyfile(keyFile, "Locallab", "Rstprotectcie_" + index_str, spot.rstprotectcie, spotEdited.rstprotectcie); assignFromKeyfile(keyFile, "Locallab", "Chromlcie_" + index_str, spot.chromlcie, spotEdited.chromlcie); assignFromKeyfile(keyFile, "Locallab", "Huecie_" + index_str, spot.huecie, spotEdited.huecie); assignFromKeyfile(keyFile, "Locallab", "ToneMethodcie_" + index_str, spot.toneMethodcie, spotEdited.toneMethodcie); @@ -9471,7 +9714,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Saturjzcie_" + index_str, spot.saturjzcie, spotEdited.saturjzcie); assignFromKeyfile(keyFile, "Locallab", "Huejzcie_" + index_str, spot.huejzcie, spotEdited.huejzcie); assignFromKeyfile(keyFile, "Locallab", "Softjzcie_" + index_str, spot.softjzcie, spotEdited.softjzcie); - assignFromKeyfile(keyFile, "Locallab", "strSoftjzcie_" + index_str, spot.strsoftjzcie, spotEdited.strsoftjzcie); + assignFromKeyfile(keyFile, "Locallab", "strSoftjzcie_" + index_str, spot.strsoftjzcie, spotEdited.strsoftjzcie); assignFromKeyfile(keyFile, "Locallab", "Thrhjzcie_" + index_str, spot.thrhjzcie, spotEdited.thrhjzcie); assignFromKeyfile(keyFile, "Locallab", "JzCurve_" + index_str, spot.jzcurve, spotEdited.jzcurve); assignFromKeyfile(keyFile, "Locallab", "CzCurve_" + index_str, spot.czcurve, spotEdited.czcurve); @@ -9482,14 +9725,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Lightlcie_" + index_str, spot.lightlcie, spotEdited.lightlcie); assignFromKeyfile(keyFile, "Locallab", "Lightjzcie_" + index_str, spot.lightjzcie, spotEdited.lightjzcie); assignFromKeyfile(keyFile, "Locallab", "Brightqcie_" + index_str, spot.lightqcie, spotEdited.lightqcie); + assignFromKeyfile(keyFile, "Locallab", "Brightsigqcie_" + index_str, spot.lightsigqcie, spotEdited.lightsigqcie); assignFromKeyfile(keyFile, "Locallab", "Contlcie_" + index_str, spot.contlcie, spotEdited.contlcie); assignFromKeyfile(keyFile, "Locallab", "Contjzcie_" + index_str, spot.contjzcie, spotEdited.contjzcie); - assignFromKeyfile(keyFile, "Locallab", "Adapjzcie_" + index_str, spot.adapjzcie, spotEdited.adapjzcie); + assignFromKeyfile(keyFile, "Locallab", "Detailciejz_" + index_str, spot.detailciejz, spotEdited.detailciejz); + assignFromKeyfile(keyFile, "Locallab", "Adapjzcie_" + index_str, spot.adapjzcie, spotEdited.adapjzcie); assignFromKeyfile(keyFile, "Locallab", "Jz100_" + index_str, spot.jz100, spotEdited.jz100); assignFromKeyfile(keyFile, "Locallab", "PQremap_" + index_str, spot.pqremap, spotEdited.pqremap); - assignFromKeyfile(keyFile, "Locallab", "PQremapcam16_" + index_str, spot.pqremapcam16, spotEdited.pqremapcam16); + assignFromKeyfile(keyFile, "Locallab", "PQremapcam16_" + index_str, spot.pqremapcam16, spotEdited.pqremapcam16); assignFromKeyfile(keyFile, "Locallab", "Hljzcie_" + index_str, spot.hljzcie, spotEdited.hljzcie); - assignFromKeyfile(keyFile, "Locallab", "Hlthjzcie_" + index_str, spot.hlthjzcie, spotEdited.hlthjzcie); + assignFromKeyfile(keyFile, "Locallab", "Hlthjzcie_" + index_str, spot.hlthjzcie, spotEdited.hlthjzcie); assignFromKeyfile(keyFile, "Locallab", "Shjzcie_" + index_str, spot.shjzcie, spotEdited.shjzcie); assignFromKeyfile(keyFile, "Locallab", "Shthjzcie_" + index_str, spot.shthjzcie, spotEdited.shthjzcie); assignFromKeyfile(keyFile, "Locallab", "Radjzcie_" + index_str, spot.radjzcie, spotEdited.radjzcie); @@ -9514,32 +9759,61 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "WhiteEvjz_" + index_str, spot.whiteEvjz, spotEdited.whiteEvjz); assignFromKeyfile(keyFile, "Locallab", "Targetjz_" + index_str, spot.targetjz, spotEdited.targetjz); assignFromKeyfile(keyFile, "Locallab", "Sigmoidthcie_" + index_str, spot.sigmoidthcie, spotEdited.sigmoidthcie); + assignFromKeyfile(keyFile, "Locallab", "Sigmoidsenscie_" + index_str, spot.sigmoidsenscie, spotEdited.sigmoidsenscie); assignFromKeyfile(keyFile, "Locallab", "Sigmoidblcie_" + index_str, spot.sigmoidblcie, spotEdited.sigmoidblcie); + assignFromKeyfile(keyFile, "Locallab", "comprcie_" + index_str, spot.comprcie, spotEdited.comprcie); + assignFromKeyfile(keyFile, "Locallab", "strcielog_" + index_str, spot.strcielog, spotEdited.strcielog); + assignFromKeyfile(keyFile, "Locallab", "comprcieth_" + index_str, spot.comprcieth, spotEdited.comprcieth); + assignFromKeyfile(keyFile, "Locallab", "gamjcie_" + index_str, spot.gamjcie, spotEdited.gamjcie); + assignFromKeyfile(keyFile, "Locallab", "slopjcie_" + index_str, spot.slopjcie, spotEdited.slopjcie); + assignFromKeyfile(keyFile, "Locallab", "slopesmo_" + index_str, spot.slopesmo, spotEdited.slopesmo); + assignFromKeyfile(keyFile, "Locallab", "midtcie_" + index_str, spot.midtcie, spotEdited.midtcie); + assignFromKeyfile(keyFile, "Locallab", "grexl_" + index_str, spot.grexl, spotEdited.grexl); + assignFromKeyfile(keyFile, "Locallab", "greyl_" + index_str, spot.greyl, spotEdited.greyl); + assignFromKeyfile(keyFile, "Locallab", "bluxl_" + index_str, spot.bluxl, spotEdited.bluxl); + assignFromKeyfile(keyFile, "Locallab", "bluyl_" + index_str, spot.bluyl, spotEdited.bluyl); + assignFromKeyfile(keyFile, "Locallab", "redxl_" + index_str, spot.redxl, spotEdited.redxl); + assignFromKeyfile(keyFile, "Locallab", "redyl_" + index_str, spot.redyl, spotEdited.redyl); + assignFromKeyfile(keyFile, "Locallab", "refi_" + index_str, spot.refi, spotEdited.refi); + assignFromKeyfile(keyFile, "Locallab", "shiftxl_" + index_str, spot.shiftxl, spotEdited.shiftxl); + assignFromKeyfile(keyFile, "Locallab", "shiftyl_" + index_str, spot.shiftyl, spotEdited.shiftyl); + assignFromKeyfile(keyFile, "Locallab", "labgridcieALow_" + index_str, spot.labgridcieALow, spotEdited.labgridcieALow); + assignFromKeyfile(keyFile, "Locallab", "labgridcieBLow_" + index_str, spot.labgridcieBLow, spotEdited.labgridcieBLow); + assignFromKeyfile(keyFile, "Locallab", "labgridcieAHigh_" + index_str, spot.labgridcieAHigh, spotEdited.labgridcieAHigh); + assignFromKeyfile(keyFile, "Locallab", "labgridcieBHigh_" + index_str, spot.labgridcieBHigh, spotEdited.labgridcieBHigh); + assignFromKeyfile(keyFile, "Locallab", "labgridcieGx_" + index_str, spot.labgridcieGx, spotEdited.labgridcieGx); + assignFromKeyfile(keyFile, "Locallab", "labgridcieGy_" + index_str, spot.labgridcieGy, spotEdited.labgridcieGy); + assignFromKeyfile(keyFile, "Locallab", "labgridcieWx_" + index_str, spot.labgridcieWx, spotEdited.labgridcieWx); + assignFromKeyfile(keyFile, "Locallab", "labgridcieWy_" + index_str, spot.labgridcieWy, spotEdited.labgridcieWy); + assignFromKeyfile(keyFile, "Locallab", "labgridcieMx_" + index_str, spot.labgridcieMx, spotEdited.labgridcieMx); + assignFromKeyfile(keyFile, "Locallab", "labgridcieMy_" + index_str, spot.labgridcieMy, spotEdited.labgridcieMy); + + assignFromKeyfile(keyFile, "Locallab", "whitescie_" + index_str, spot.whitescie, spotEdited.whitescie); + assignFromKeyfile(keyFile, "Locallab", "blackscie_" + index_str, spot.blackscie, spotEdited.blackscie); + assignFromKeyfile(keyFile, "Locallab", "illMethod_" + index_str, spot.illMethod, spotEdited.illMethod); + assignFromKeyfile(keyFile, "Locallab", "smoothciemet_" + index_str, spot.smoothciemet, spotEdited.smoothciemet); + assignFromKeyfile(keyFile, "Locallab", "primMethod_" + index_str, spot.primMethod, spotEdited.primMethod); + assignFromKeyfile(keyFile, "Locallab", "catMethod_" + index_str, spot.catMethod, spotEdited.catMethod); assignFromKeyfile(keyFile, "Locallab", "Sigmoidldajzcie_" + index_str, spot.sigmoidldajzcie, spotEdited.sigmoidldajzcie); assignFromKeyfile(keyFile, "Locallab", "Sigmoidthjzcie_" + index_str, spot.sigmoidthjzcie, spotEdited.sigmoidthjzcie); assignFromKeyfile(keyFile, "Locallab", "Sigmoidbljzcie_" + index_str, spot.sigmoidbljzcie, spotEdited.sigmoidbljzcie); assignFromKeyfile(keyFile, "Locallab", "Contqcie_" + index_str, spot.contqcie, spotEdited.contqcie); + assignFromKeyfile(keyFile, "Locallab", "Contsigqcie_" + index_str, spot.contsigqcie, spotEdited.contsigqcie); assignFromKeyfile(keyFile, "Locallab", "Colorflcie_" + index_str, spot.colorflcie, spotEdited.colorflcie); -/* - assignFromKeyfile(keyFile, "Locallab", "Lightlzcam_" + index_str, spot.lightlzcam, spotEdited.lightlzcam); - assignFromKeyfile(keyFile, "Locallab", "Lightqzcam_" + index_str, spot.lightqzcam, spotEdited.lightqzcam); - assignFromKeyfile(keyFile, "Locallab", "Contlzcam_" + index_str, spot.contlzcam, spotEdited.contlzcam); - assignFromKeyfile(keyFile, "Locallab", "Contqzcam_" + index_str, spot.contqzcam, spotEdited.contqzcam); - assignFromKeyfile(keyFile, "Locallab", "Contthreszcam_" + index_str, spot.contthreszcam, spotEdited.contthreszcam); -*/ assignFromKeyfile(keyFile, "Locallab", "Targabscie_" + index_str, spot.targabscie, spotEdited.targabscie); assignFromKeyfile(keyFile, "Locallab", "TargetGraycie_" + index_str, spot.targetGraycie, spotEdited.targetGraycie); assignFromKeyfile(keyFile, "Locallab", "Catadcie_" + index_str, spot.catadcie, spotEdited.catadcie); assignFromKeyfile(keyFile, "Locallab", "Detailcie_" + index_str, spot.detailcie, spotEdited.detailcie); -/* - assignFromKeyfile(keyFile, "Locallab", "Colorflzcam_" + index_str, spot.colorflzcam, spotEdited.colorflzcam); - assignFromKeyfile(keyFile, "Locallab", "Saturzcam_" + index_str, spot.saturzcam, spotEdited.saturzcam); - assignFromKeyfile(keyFile, "Locallab", "Chromzcam_" + index_str, spot.chromzcam, spotEdited.chromzcam); -*/ - assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, spotEdited.enacieMask); + assignFromKeyfile(keyFile, "Locallab", "Surroundcie_" + index_str, spot.surroundcie, spotEdited.surroundcie); + assignFromKeyfile(keyFile, "Locallab", "Strgradcie_" + index_str, spot.strgradcie, spotEdited.strgradcie); + assignFromKeyfile(keyFile, "Locallab", "Anggradcie_" + index_str, spot.anggradcie, spotEdited.anggradcie); + + assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, spotEdited.enacieMask); + assignFromKeyfile(keyFile, "Locallab", "EnacieMaskall_" + index_str, spot.enacieMaskall, spotEdited.enacieMaskall); assignFromKeyfile(keyFile, "Locallab", "CCmaskcieCurve_" + index_str, spot.CCmaskciecurve, spotEdited.CCmaskciecurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurve_" + index_str, spot.LLmaskciecurve, spotEdited.LLmaskciecurve); - assignFromKeyfile(keyFile, "Locallab", "HHmaskcieCurve_" + index_str, spot.HHmaskciecurve, spotEdited.HHmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "HHmaskcieCurve_" + index_str, spot.HHmaskciecurve, spotEdited.HHmaskciecurve); + assignFromKeyfile(keyFile, "Locallab", "HHhmaskcieCurve_" + index_str, spot.HHhmaskciecurve, spotEdited.HHhmaskciecurve); assignFromKeyfile(keyFile, "Locallab", "Blendmaskcie_" + index_str, spot.blendmaskcie, spotEdited.blendmaskcie); assignFromKeyfile(keyFile, "Locallab", "Radmaskcie_" + index_str, spot.radmaskcie, spotEdited.radmaskcie); assignFromKeyfile(keyFile, "Locallab", "Chromaskcie_" + index_str, spot.chromaskcie, spotEdited.chromaskcie); @@ -9551,6 +9825,24 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Lowthrescie_" + index_str, spot.lowthrescie, spotEdited.lowthrescie); assignFromKeyfile(keyFile, "Locallab", "Higthrescie_" + index_str, spot.higthrescie, spotEdited.higthrescie); assignFromKeyfile(keyFile, "Locallab", "Decaycie_" + index_str, spot.decaycie, spotEdited.decaycie); + assignFromKeyfile(keyFile, "Locallab", "strumaskcie_" + index_str, spot.strumaskcie, spotEdited.strumaskcie); + assignFromKeyfile(keyFile, "Locallab", "toolcie_" + index_str, spot.toolcie, spotEdited.toolcie); + assignFromKeyfile(keyFile, "Locallab", "FftcieMask_" + index_str, spot.fftcieMask, spotEdited.fftcieMask); + assignFromKeyfile(keyFile, "Locallab", "contcie_" + index_str, spot.contcie, spotEdited.contcie); + assignFromKeyfile(keyFile, "Locallab", "blurcie_" + index_str, spot.blurcie, spotEdited.blurcie); + assignFromKeyfile(keyFile, "Locallab", "highmaskcie_" + index_str, spot.highmaskcie, spotEdited.highmaskcie); + assignFromKeyfile(keyFile, "Locallab", "shadmaskcie_" + index_str, spot.shadmaskcie, spotEdited.shadmaskcie); + assignFromKeyfile(keyFile, "Locallab", "LLmaskcieCurvewav_" + index_str, spot.LLmaskciecurvewav, spotEdited.LLmaskciecurvewav); + + if (keyFile.has_key("Locallab", "CSThresholdcie_" + index_str)) { + const std::vector thresh = keyFile.get_integer_list("Locallab", "CSThresholdcie_" + index_str); + + if (thresh.size() >= 4) { + spot.csthresholdcie.setValues(thresh[0], thresh[1], min(thresh[2], 10), min(thresh[3], 10)); + } + + spotEdited.csthresholdcie = true; + } // Append LocallabSpot and LocallabParamsEdited locallab.spots.push_back(spot); @@ -9731,7 +10023,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) {"D120", ColorManagementParams::Illuminant::D120}, {"stda", ColorManagementParams::Illuminant::STDA}, {"2000", ColorManagementParams::Illuminant::TUNGSTEN_2000K}, - {"1500", ColorManagementParams::Illuminant::TUNGSTEN_1500K} + {"1500", ColorManagementParams::Illuminant::TUNGSTEN_1500K}, + {"E", ColorManagementParams::Illuminant::E} }, icm.will, pedited->icm.will @@ -9757,6 +10050,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) {"wid", ColorManagementParams::Primaries::WIDE_GAMUT}, {"ac0", ColorManagementParams::Primaries::ACES_P0}, {"jdcmax", ColorManagementParams::Primaries::JDC_MAX}, + {"jdcmaxstdA", ColorManagementParams::Primaries::JDC_MAXSTDA}, {"bru", ColorManagementParams::Primaries::BRUCE_RGB}, {"bet", ColorManagementParams::Primaries::BETA_RGB}, {"bst", ColorManagementParams::Primaries::BEST_RGB}, @@ -9772,8 +10066,33 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) pedited->icm.wprim = true; } } - assignFromKeyfile(keyFile, "Color Management", "WorkingTRCGamma", icm.workingTRCGamma, pedited->icm.workingTRCGamma); + if ( + !assignFromKeyfile( + keyFile, + "Color Management", + "Wcat", + { + {"brad", ColorManagementParams::Cat::BRAD}, + {"cat16", ColorManagementParams::Cat::CAT16}, + {"cat02", ColorManagementParams::Cat::CAT02}, + {"cat_vk", ColorManagementParams::Cat::CAT_VK}, + {"cat_xyz", ColorManagementParams::Cat::CAT_XYZ} + }, + icm.wcat, + pedited->icm.wcat + ) + ){ + icm.wcat = ColorManagementParams::Cat::BRAD; + if (pedited) { + pedited->icm.wcat = true; + } + } + + assignFromKeyfile(keyFile, "Color Management", "Gamut", icm.gamut, pedited->icm.gamut); assignFromKeyfile(keyFile, "Color Management", "WorkingTRCSlope", icm.workingTRCSlope, pedited->icm.workingTRCSlope); + assignFromKeyfile(keyFile, "Color Management", "WorkingTRCGamma", icm.workingTRCGamma, pedited->icm.workingTRCGamma); + assignFromKeyfile(keyFile, "Color Management", "Wmidtcie", icm.wmidtcie, pedited->icm.wmidtcie); + assignFromKeyfile(keyFile, "Color Management", "Wsmoothcie", icm.wsmoothcie, pedited->icm.wsmoothcie); assignFromKeyfile(keyFile, "Color Management", "Redx", icm.redx, pedited->icm.redx); assignFromKeyfile(keyFile, "Color Management", "Redy", icm.redy, pedited->icm.redy); @@ -9781,9 +10100,12 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Color Management", "Grey", icm.grey, pedited->icm.grey); assignFromKeyfile(keyFile, "Color Management", "Blux", icm.blux, pedited->icm.blux); assignFromKeyfile(keyFile, "Color Management", "Bluy", icm.bluy, pedited->icm.bluy); + assignFromKeyfile(keyFile, "Color Management", "Refi", icm.refi, pedited->icm.refi); + assignFromKeyfile(keyFile, "Color Management", "Shiftx", icm.shiftx, pedited->icm.shiftx); + assignFromKeyfile(keyFile, "Color Management", "Shifty", icm.shifty, pedited->icm.shifty); assignFromKeyfile(keyFile, "Color Management", "Preser", icm.preser, pedited->icm.preser); assignFromKeyfile(keyFile, "Color Management", "Fbw", icm.fbw, pedited->icm.fbw); - assignFromKeyfile(keyFile, "Color Management", "Gamut", icm.gamut, pedited->icm.gamut); + assignFromKeyfile(keyFile, "Color Management", "TrcExp", icm.trcExp, pedited->icm.trcExp); assignFromKeyfile(keyFile, "Color Management", "LabGridcieALow", icm.labgridcieALow, pedited->icm.labgridcieALow); assignFromKeyfile(keyFile, "Color Management", "LabGridcieBLow", icm.labgridcieBLow, pedited->icm.labgridcieBLow); assignFromKeyfile(keyFile, "Color Management", "LabGridcieAHigh", icm.labgridcieAHigh, pedited->icm.labgridcieAHigh); @@ -9792,6 +10114,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Color Management", "LabGridcieGy", icm.labgridcieGy, pedited->icm.labgridcieGy); assignFromKeyfile(keyFile, "Color Management", "LabGridcieWx", icm.labgridcieWx, pedited->icm.labgridcieWx); assignFromKeyfile(keyFile, "Color Management", "LabGridcieWy", icm.labgridcieWy, pedited->icm.labgridcieWy); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieMx", icm.labgridcieMx, pedited->icm.labgridcieMx); + assignFromKeyfile(keyFile, "Color Management", "LabGridcieMy", icm.labgridcieMy, pedited->icm.labgridcieMy); if (keyFile.has_key("Color Management", "aIntent")) { Glib::ustring intent = keyFile.get_string("Color Management", "aIntent"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 5ffcf9c6f..0eb991933 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -863,7 +863,7 @@ struct SHParams { */ struct ToneEqualizerParams { bool enabled; - std::array bands; + std::array bands; int regularization; bool show_colormap; double pivot; @@ -1223,7 +1223,7 @@ struct LocallabParams { bool expshadhigh; int complexshadhigh; Glib::ustring shMethod; // std, tone - int multsh[5]; + int multsh[6]; int highlights; int h_tonalwidth; int shadows; @@ -1592,8 +1592,13 @@ struct LocallabParams { bool fullimage; double repar; bool ciecam; + bool satlog; double blackEv; double whiteEv; + int whiteslog; + int blackslog; + double comprlog; + double strelog; double detail; int sensilog; Glib::ustring sursour; @@ -1646,6 +1651,7 @@ struct LocallabParams { //ciecam bool visicie; bool expcie; + bool expprecam; int complexcie; double reparcie; int sensicie; @@ -1654,8 +1660,14 @@ struct LocallabParams { bool forcebw; bool qtoj; bool jabcie; - bool sigmoidqjcie; + bool comprcieauto; + bool normcie; + bool gamutcie; + bool sigcie; bool logcie; + bool satcie; + bool logcieq; + bool smoothcie; bool logjz; bool sigjz; bool sigq; @@ -1665,6 +1677,7 @@ struct LocallabParams { Glib::ustring sursourcie; Glib::ustring modecie; Glib::ustring modecam; + Glib::ustring bwevMethod; double saturlcie; double rstprotectcie; double chromlcie; @@ -1688,8 +1701,10 @@ struct LocallabParams { double lightlcie; double lightjzcie; double lightqcie; + double lightsigqcie; double contlcie; double contjzcie; + double detailciejz; double adapjzcie; double jz100; double pqremap; @@ -1711,31 +1726,60 @@ struct LocallabParams { double targetjz; double sigmoidldacie; double sigmoidthcie; + double sigmoidsenscie; double sigmoidblcie; + double comprcie; + double strcielog; + double comprcieth; + double gamjcie; + double slopjcie; + double slopesmo; + int midtcie; + double grexl; + double greyl; + double bluxl; + double bluyl; + double redxl; + double redyl; + double refi; + double shiftxl; + double shiftyl; + double labgridcieALow; + double labgridcieBLow; + double labgridcieAHigh; + double labgridcieBHigh; + double labgridcieGx; + double labgridcieGy; + double labgridcieWx; + double labgridcieWy; + double labgridcieMx; + double labgridcieMy; + + int whitescie; + int blackscie; + Glib::ustring illMethod; + Glib::ustring smoothciemet; + Glib::ustring primMethod; + Glib::ustring catMethod; double sigmoidldajzcie; double sigmoidthjzcie; double sigmoidbljzcie; double contqcie; + double contsigqcie; double colorflcie; -/* - double lightlzcam; - double lightqzcam; - double contlzcam; - double contqzcam; - double contthreszcam; - double colorflzcam; - double saturzcam; - double chromzcam; -*/ double targabscie; double targetGraycie; double catadcie; double detailcie; Glib::ustring surroundcie; + double strgradcie; + double anggradcie; bool enacieMask; + bool enacieMaskall; std::vector CCmaskciecurve; std::vector LLmaskciecurve; std::vector HHmaskciecurve; + std::vector HHhmaskciecurve; int blendmaskcie; double radmaskcie; double chromaskcie; @@ -1747,7 +1791,16 @@ struct LocallabParams { double lowthrescie; double higthrescie; double decaycie; - + double strumaskcie; + bool toolcie; + bool fftcieMask; + double contcie; + double blurcie; + double highmaskcie; + double shadmaskcie; + std::vector LLmaskciecurvewav; + Threshold csthresholdcie; + LocallabSpot(); bool operator ==(const LocallabSpot& other) const; @@ -1947,7 +2000,8 @@ struct ColorManagementParams { D120, STDA, TUNGSTEN_2000K, - TUNGSTEN_1500K + TUNGSTEN_1500K, + E }; enum class Primaries { @@ -1960,6 +2014,7 @@ struct ColorManagementParams { WIDE_GAMUT, ACES_P0, JDC_MAX, + JDC_MAXSTDA, BRUCE_RGB, BETA_RGB, BEST_RGB, @@ -1967,6 +2022,14 @@ struct ColorManagementParams { CUSTOM_GRID }; + enum class Cat { + BRAD, + CAT16, + CAT02, + CAT_VK, + CAT_XYZ + }; + Glib::ustring inputProfile; bool toneCurve; bool applyLookTable; @@ -1978,16 +2041,23 @@ struct ColorManagementParams { WorkingTrc workingTRC; Illuminant will; Primaries wprim; + Cat wcat; double workingTRCGamma; double workingTRCSlope; + double wmidtcie; + bool wsmoothcie; double redx; double redy; double grex; double grey; double blux; double bluy; + double refi; + double shiftx; + double shifty; double preser; bool fbw; + bool trcExp; bool gamut; double labgridcieALow; double labgridcieBLow; @@ -1997,6 +2067,8 @@ struct ColorManagementParams { double labgridcieGy; double labgridcieWx; double labgridcieWy; + double labgridcieMx; + double labgridcieMy; RenderingIntent aRendIntent; Glib::ustring outputProfile; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index c027cd7d4..8308e5e9f 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -5290,7 +5290,7 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double itcwb_nopurple : false default - allow to bypass highlight recovery and inpait opposed when need flowers and not purple due to highlights... itcwb_green - adjust green refinement */ - BENCHFUN + // BENCHFUN MyTime t1, t2, t3, t4, t5, t6, t7, t8; t1.set(); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index c589e8ba4..5147e09ce 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -1108,7 +1108,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { AUTOEXP, //Evlocallabsigmoidldacie AUTOEXP, //Evlocallabsigmoidthcie AUTOEXP, //Evlocallabsigmoidblcie - AUTOEXP, //Evlocallabsigmoidqjcie + HDR, //Evlocallabcomprcieauto AUTOEXP, //Evlocallabhuecie AUTOEXP, //Evlocallabjabcie AUTOEXP, //Evlocallablightjzcie diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index fb669e1c8..fdd6676e6 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -424,12 +424,46 @@ public: double Lnres46; }; + struct locallabcieBEF { + double blackevbef; + double whiteevbef; + double sourcegbef; + double sourceabbef; + double targetgbef; + bool autocomputbef; + bool autociebef; + double jz1bef; + }; + + struct locallabcieLC { + double redxlc; + double redylc; + double grexlc; + double greylc; + double bluxlc; + double bluylc; + double wxlc; + double wylc; + double meanxlc; + double meanylc; + double meanxelc; + double meanyelc; + }; + + struct locallabcieSIG { + double contsigq; + double lightsigq; + }; + virtual ~LocallabListener() = default; // virtual void refChanged(const std::vector &ref, int selspot) = 0; virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; virtual void denChanged(const std::vector &denlc, int selspot) = 0; - virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) = 0; + virtual void cieChanged(const std::vector &cielc, int selspot) = 0; + virtual void sigChanged(const std::vector &ciesig, int selspot) = 0; + virtual void ciebefChanged(const std::vector &ciebef, int selspot) = 0; virtual void refChanged2(float *huerefp, float *chromarefp, float *lumarefp, float *fabrefp, int selspot) = 0; + }; class AutoColorTonListener @@ -444,7 +478,7 @@ class AutoprimListener public: virtual ~AutoprimListener() = default; virtual void primChanged(float rx, float ry, float bx, float by, float gx, float gy) = 0; - virtual void iprimChanged(float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y) = 0; + virtual void iprimChanged(float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y, float m_x, float m_y) = 0; }; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1ae5d30a7..1691912a1 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1534,7 +1534,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT ipf.softLight(labView, params.softlight); - if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE) { + if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params.icm.trcExp) { const int GW = labView->W; const int GH = labView->H; std::unique_ptr provis; @@ -1558,8 +1558,49 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT cmsHTRANSFORM dummy = nullptr; int ill = 0; - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, dummy, false, true, true); + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, true, false, false); + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone,0, illum, prim, locprim, rdx, rdy, grx, gry, blx, bly,meanx, meany, meanxe, meanye, dummy, false, true, true); + const int midton = params.icm.wmidtcie; + if(midton != 0) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[2] = midton; + params.bands[4] = 0; + params.bands[5] = 0; + int mid = abs(midton); + int threshmid = 50; + if(mid > threshmid) { + params.bands[1] = sign(midton) * (mid - threshmid); + params.bands[3] = sign(midton) * (mid - threshmid); + } + ipf.toneEqualizer(tmpImage1.get(), params, prof, 1, false); + } + + const bool smoothi = params.icm.wsmoothcie; + if(smoothi) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[1] = 0; + params.bands[2] = 0; + params.bands[3] = 0; + params.bands[4] = -40;//arbitrary value to adapt with WhiteEvjz - here White Ev # 10 + params.bands[5] = -80;//8 Ev and above + bool Evsix = true; + if(Evsix) {//EV = 6 majority of images + params.bands[4] = -15; + } + + ipf.toneEqualizer(tmpImage1.get(), params, prof, 1, false); + } ipf.rgb2lab(*tmpImage1, *labView, params.icm.workingProfile); // labView and provis diff --git a/rtengine/settings.h b/rtengine/settings.h index fbbb51bbb..739d6cbb8 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -99,7 +99,7 @@ public: bool itcwb_enable; double itcwb_deltaspec; double itcwb_powponder; - + double basecorlog; //wavelet levels double edghi; double edglo; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 4202ac336..e7d13884c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -231,7 +231,8 @@ private: bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast; double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast; - imgsrc->demosaic (params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl); + imgsrc->demosaic(params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl); + if (params.pdsharpening.enabled) { imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast, params.pdsharpening.deconvradius); } @@ -272,6 +273,7 @@ private: // set the color temperature currWB = ColorTemp(params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method, params.wb.observer); ColorTemp currWBitc; + if (params.wb.method == "autitcgreen" && flush) { imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw, params.wb); } @@ -349,6 +351,7 @@ private: params.wb.green = currWB.getGreen(); params.wb.equal = currWB.getEqual(); } + //end WB auto calclum = nullptr ; @@ -867,8 +870,8 @@ private: } // Spot Removal - if (params.spot.enabled && !params.spot.entries.empty ()) { - ipf.removeSpots (baseImg, imgsrc, params.spot.entries, pp, currWB, nullptr, tr); + if (params.spot.enabled && !params.spot.entries.empty()) { + ipf.removeSpots(baseImg, imgsrc, params.spot.entries, pp, currWB, nullptr, tr); } // at this stage, we can flush the raw data to free up quite an important amount of memory @@ -979,7 +982,7 @@ private: } ipf.transform(baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh, - imgsrc->getMetaData(), imgsrc->getRotateDegree(), true, true); + imgsrc->getMetaData(), imgsrc->getRotateDegree(), true, true); if (trImg != baseImg) { delete baseImg; @@ -995,14 +998,29 @@ private: ImProcFunctions &ipf = * (ipf_p.get()); for (int sp = 0; sp < (int)params.locallab.spots.size(); sp++) { - if(params.locallab.spots.at(sp).expsharp && params.dirpyrequalizer.cbdlMethod == "bef") { - if(params.locallab.spots.at(sp).shardamping < 1) { - params.locallab.spots.at(sp).shardamping = 1; - } - } - } + if (params.locallab.spots.at(sp).expsharp && params.dirpyrequalizer.cbdlMethod == "bef") { + if (params.locallab.spots.at(sp).shardamping < 1) { + params.locallab.spots.at(sp).shardamping = 1; + } + } + } - if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { + bool execcam = false; + + //execcam => work around for pre-ciecam in LA: about 0.1 second + for (int sp = 0; sp < (int)params.locallab.spots.size(); sp++) { + if (params.locallab.spots.at(sp).expprecam) { + execcam = true; + } + } + if ((params.dirpyrequalizer.cbdlMethod == "bef") && (params.dirpyrequalizer.enabled || execcam) && !params.colorappearance.enabled) { + if (execcam && !params.dirpyrequalizer.enabled) { + params.dirpyrequalizer.enabled = true; + + if (params.dirpyrequalizer.mult[0] == 1.) { + params.dirpyrequalizer.mult[0] = 1.01; + } + } const int W = baseImg->getWidth(); const int H = baseImg->getHeight(); LabImage labcbdl(W, H); @@ -1037,6 +1055,7 @@ private: LocLLmaskCurve locllmasCurve; LocHHmaskCurve lochhmasCurve; LocHHmaskCurve lochhhmasCurve; + LocHHmaskCurve lochhhmascieCurve; LocCCmaskCurve locccmasexpCurve; LocLLmaskCurve locllmasexpCurve; LocHHmaskCurve lochhmasexpCurve; @@ -1075,6 +1094,7 @@ private: LocwavCurve loclmasCurveblwav; LocwavCurve loclmasCurvecolwav; + LocwavCurve loclmasCurveciewav; LocwavCurve loclmasCurve_wav; LocwavCurve locwavCurve; LocwavCurve locwavCurvejz; @@ -1114,6 +1134,7 @@ private: LUTf czjzlocalcurve(65536, LUT_CLIP_OFF); array2D shbuffer; + for (size_t sp = 0; sp < params.locallab.spots.size(); sp++) { if (params.locallab.spots.at(sp).inverssha) { shbuffer(fw, fh); @@ -1136,6 +1157,7 @@ private: const bool llmasutili = locllmasCurve.Set(params.locallab.spots.at(sp).LLmaskcurve); const bool lhmasutili = lochhmasCurve.Set(params.locallab.spots.at(sp).HHmaskcurve); const bool lhhmasutili = lochhhmasCurve.Set(params.locallab.spots.at(sp).HHhmaskcurve); + const bool lhhmascieutili = lochhhmascieCurve.Set(params.locallab.spots.at(sp).HHhmaskciecurve); const bool lcmasexputili = locccmasexpCurve.Set(params.locallab.spots.at(sp).CCmaskexpcurve); const bool llmasexputili = locllmasexpCurve.Set(params.locallab.spots.at(sp).LLmaskexpcurve); const bool lhmasexputili = lochhmasexpCurve.Set(params.locallab.spots.at(sp).HHmaskexpcurve); @@ -1171,6 +1193,7 @@ private: const bool lhhmas_utili = lochhhmas_Curve.Set(params.locallab.spots.at(sp).HHhmask_curve); const bool lmasutiliblwav = loclmasCurveblwav.Set(params.locallab.spots.at(sp).LLmaskblcurvewav); const bool lmasutilicolwav = loclmasCurvecolwav.Set(params.locallab.spots.at(sp).LLmaskcolcurvewav); + const bool lmasutiliciewav = loclmasCurveciewav.Set(params.locallab.spots.at(sp).LLmaskciecurvewav); const bool lcmaslcutili = locccmaslcCurve.Set(params.locallab.spots.at(sp).CCmasklccurve); const bool llmaslcutili = locllmaslcCurve.Set(params.locallab.spots.at(sp).LLmasklccurve); const bool lmasutili_wav = loclmasCurve_wav.Set(params.locallab.spots.at(sp).LLmask_curvewav); @@ -1215,10 +1238,15 @@ private: double shcompr = params.locallab.spots.at(sp).shcompr; double br = params.locallab.spots.at(sp).lightness; double cont = params.locallab.spots.at(sp).contrast; - if (lblack < 0. && params.locallab.spots.at(sp).expMethod == "pde" ) { + + if (lblack < 0. && params.locallab.spots.at(sp).expMethod == "pde") { lblack *= 1.5; } + float contsig = params.locallab.spots.at(sp).contsigqcie; + + float lightsig = params.locallab.spots.at(sp).lightsigqcie; + // Reference parameters computation double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; int lastsav; @@ -1228,12 +1256,17 @@ private: float meanretie; float stdretie; float fab = 1.f; + float maxicam = -1000.f; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + int ill = 2; if (params.locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reservView.get(), reservView.get(), 0, 0, fw, fh, 1, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge, locwavCurveden, locwavdenutili); } else { ipf.calc_ref(sp, labView, labView, 0, 0, fw, fh, 1, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge, locwavCurveden, locwavdenutili); } + CurveFactory::complexCurvelocal(ecomp, lblack / 65535., lhlcompr, lhlcomprthresh, shcompr, br, cont, lumare, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, avge, 1); @@ -1247,7 +1280,7 @@ private: float Tmax; float highresi = 0.f; float nresi = 0.f; - float highresi46 =0.f; + float highresi46 = 0.f; float nresi46 = 0.f; float Lhighresi = 0.f; float Lnresi = 0.f; @@ -1256,60 +1289,61 @@ private: // No Locallab mask is shown in exported picture ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), fw, fh, 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, - lllocalcurve, locallutili, - cllocalcurve, localclutili, - lclocalcurve, locallcutili, - loclhCurve, lochhCurve, locchCurve, - lochhCurvejz, locchCurvejz,loclhCurvejz, - lmasklocalcurve, localmaskutili, - lmaskexplocalcurve, localmaskexputili, - lmaskSHlocalcurve, localmaskSHutili, - lmaskviblocalcurve, localmaskvibutili, - lmasktmlocalcurve, localmasktmutili, - lmaskretilocalcurve, localmaskretiutili, - lmaskcblocalcurve, localmaskcbutili, - lmaskbllocalcurve, localmaskblutili, - lmasklclocalcurve, localmasklcutili, - lmaskloglocalcurve, localmasklogutili, - lmasklocal_curve, localmask_utili, - lmaskcielocalcurve, localmaskcieutili, - cielocalcurve, localcieutili, - cielocalcurve2, localcieutili2, - jzlocalcurve, localjzutili, - czlocalcurve, localczutili, - czjzlocalcurve, localczjzutili, + lllocalcurve, locallutili, + cllocalcurve, localclutili, + lclocalcurve, locallcutili, + loclhCurve, lochhCurve, locchCurve, + lochhCurvejz, locchCurvejz, loclhCurvejz, + lmasklocalcurve, localmaskutili, + lmaskexplocalcurve, localmaskexputili, + lmaskSHlocalcurve, localmaskSHutili, + lmaskviblocalcurve, localmaskvibutili, + lmasktmlocalcurve, localmasktmutili, + lmaskretilocalcurve, localmaskretiutili, + lmaskcblocalcurve, localmaskcbutili, + lmaskbllocalcurve, localmaskblutili, + lmasklclocalcurve, localmasklcutili, + lmaskloglocalcurve, localmasklogutili, + lmasklocal_curve, localmask_utili, + lmaskcielocalcurve, localmaskcieutili, + cielocalcurve, localcieutili, + cielocalcurve2, localcieutili2, + jzlocalcurve, localjzutili, + czlocalcurve, localczutili, + czjzlocalcurve, localczjzutili, - locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, - locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, - locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, - locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, - locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, - locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, - locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, - locccmaslcCurve, lcmaslcutili, locllmaslcCurve, llmaslcutili, lochhmaslcCurve, lhmaslcutili, - locccmaslogCurve, lcmaslogutili, locllmaslogCurve, llmaslogutili, lochhmaslogCurve, lhmaslogutili, + locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, lochhhmasCurve, lhhmasutili, lochhhmascieCurve, lhhmascieutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, + locccmasvibCurve, lcmasvibutili, locllmasvibCurve, llmasvibutili, lochhmasvibCurve, lhmasvibutili, + locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, + locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, + locccmastmCurve, lcmastmutili, locllmastmCurve, llmastmutili, lochhmastmCurve, lhmastmutili, + locccmasblCurve, lcmasblutili, locllmasblCurve, llmasblutili, lochhmasblCurve, lhmasblutili, + locccmaslcCurve, lcmaslcutili, locllmaslcCurve, llmaslcutili, lochhmaslcCurve, lhmaslcutili, + locccmaslogCurve, lcmaslogutili, locllmaslogCurve, llmaslogutili, lochhmaslogCurve, lhmaslogutili, - locccmas_Curve, lcmas_utili, locllmas_Curve, llmas_utili, lochhmas_Curve, lhmas_utili, - locccmascieCurve, lcmascieutili, locllmascieCurve, llmascieutili, lochhmascieCurve, lhmascieutili, - lochhhmas_Curve, lhhmas_utili, - loclmasCurveblwav,lmasutiliblwav, - loclmasCurvecolwav,lmasutilicolwav, - locwavCurve, locwavutili, - locwavCurvejz, locwavutilijz, - loclevwavCurve, loclevwavutili, - locconwavCurve, locconwavutili, - loccompwavCurve, loccompwavutili, - loccomprewavCurve, loccomprewavutili, - locwavCurvehue, locwavhueutili, - locwavCurveden, locwavdenutili, - locedgwavCurve, locedgwavutili, - loclmasCurve_wav,lmasutili_wav, - LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, - huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, - highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46 -); + locccmas_Curve, lcmas_utili, locllmas_Curve, llmas_utili, lochhmas_Curve, lhmas_utili, + locccmascieCurve, lcmascieutili, locllmascieCurve, llmascieutili, lochhmascieCurve, lhmascieutili, + lochhhmas_Curve, lhhmas_utili, + loclmasCurveblwav, lmasutiliblwav, + loclmasCurvecolwav, lmasutilicolwav, + loclmasCurveciewav, lmasutiliciewav, + locwavCurve, locwavutili, + locwavCurvejz, locwavutilijz, + loclevwavCurve, loclevwavutili, + locconwavCurve, locconwavutili, + loccompwavCurve, loccompwavutili, + loccomprewavCurve, loccomprewavutili, + locwavCurvehue, locwavhueutili, + locwavCurveden, locwavdenutili, + locedgwavCurve, locedgwavutili, + loclmasCurve_wav, lmasutili_wav, + LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, + huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, + meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46 + ); if (sp + 1u < params.locallab.spots.size()) { // do not copy for last spot as it is not needed anymore @@ -1407,7 +1441,7 @@ private: ipf.rgbProc(baseImg, labView, nullptr, curve1, curve2, curve, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf, as, histToneCurve, options.chunkSizeRGB, options.measure); if (settings->verbose) { - printf ("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", static_cast(autor), static_cast(autog), static_cast(autob)); + printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", static_cast(autor), static_cast(autog), static_cast(autob)); } // if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS) @@ -1476,21 +1510,21 @@ private: if (params.colorToning.enabled && params.colorToning.method == "LabGrid") { - ipf.colorToningLabGrid(labView, 0,labView->W , 0, labView->H, false); + ipf.colorToningLabGrid(labView, 0, labView->W, 0, labView->H, false); } - ipf.shadowsHighlights(labView, params.sh.enabled, params.sh.lab,params.sh.highlights ,params.sh.shadows, params.sh.radius, 1, params.sh.htonalwidth, params.sh.stonalwidth); + ipf.shadowsHighlights(labView, params.sh.enabled, params.sh.lab, params.sh.highlights, params.sh.shadows, params.sh.radius, 1, params.sh.htonalwidth, params.sh.stonalwidth); if (params.localContrast.enabled) { // Alberto's local contrast - ipf.localContrast(labView, labView->L, params.localContrast, false, 1);//scale); + ipf.localContrast(labView, labView->L, params.localContrast, false, 1);//scale); } ipf.chromiLuminanceCurve(nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { - ipf.EPDToneMap (labView, 0, 1); + ipf.EPDToneMap(labView, 0, 1); } @@ -1500,7 +1534,7 @@ private: // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - ipf.impulsedenoise (labView); + ipf.impulsedenoise(labView); ipf.defringe(labView); } @@ -1528,7 +1562,8 @@ private: } } - if ((params.wavelet.enabled)) { + int savestr = params.wavelet.strength;//work around for abstract profile: time about = 0.1 second + if ((params.wavelet.enabled) || (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params.icm.trcExp)) { LabImage *unshar = nullptr; WaveletParams WaveParams = params.wavelet; WavCurve wavCLVCurve; @@ -1548,12 +1583,9 @@ private: bool proton = WaveParams.exptoning; bool pronois = WaveParams.expnoise; -/* - if(WaveParams.showmask) { - WaveParams.showmask = false; - WaveParams.expclari = true; + if(params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params.icm.trcExp) { + params.wavelet.strength = 0; } -*/ if (WaveParams.softrad > 0.f) { provradius = new LabImage(*labView, true); } @@ -1614,6 +1646,7 @@ private: tmpImage->b(ir, jr) = Z; ble[ir][jr] = Y / 32768.f; } + double epsilmax = 0.0001; double epsilmin = 0.00001; double aepsil = (epsilmax - epsilmin) / 100.f; @@ -1639,7 +1672,8 @@ private: Color::XYZ2Lab(X, Y, Z, L, a, b); labView->L[ir][jr] = L; } - delete tmpImage; + + delete tmpImage; } } @@ -1685,15 +1719,17 @@ private: wavCLVCurve.Reset(); } + params.wavelet.strength = savestr; ipf.softLight(labView, params.softlight); - if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE) { + if (params.icm.workingTRC != ColorManagementParams::WorkingTrc::NONE && params.icm.trcExp) { const int GW = labView->W; const int GH = labView->H; std::unique_ptr provis; const float pres = 0.01f * params.icm.preser; + if (pres > 0.f && params.icm.wprim != ColorManagementParams::Primaries::DEFAULT) { provis.reset(new LabImage(GW, GH)); provis->CopyFrom(labView); @@ -1713,23 +1749,69 @@ private: cmsHTRANSFORM dummy = nullptr; int ill = 0; - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, ill, 0, dummy, true, false, false); - ipf.workingtrc(tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, illum, prim, dummy, false, true, true); + bool gamutcontrol = params.icm.gamut; + int catc = toUnderlying(params.icm.wcat); + int locprim = 0; + float rdx, rdy, grx, gry, blx, bly = 0.f; + float meanx, meany, meanxe, meanye = 0.f; + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, -5, prof, 2.4, 12.92310, 0, ill, 0, 0, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, true, false, false, false); + ipf.workingtrc(0, tmpImage1.get(), tmpImage1.get(), GW, GH, 5, prof, gamtone, slotone, catc, illum, prim, locprim, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, dummy, false, true, true, gamutcontrol); + const int midton = params.icm.wmidtcie; + if(midton != 0) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[2] = midton; + params.bands[4] = 0; + params.bands[5] = 0; + int mid = abs(midton); + int threshmid = 50; + if(mid > threshmid) { + params.bands[1] = sign(midton) * (mid - threshmid); + params.bands[3] = sign(midton) * (mid - threshmid); + } + ipf.toneEqualizer(tmpImage1.get(), params, prof, 1, false); + } + + const bool smoothi = params.icm.wsmoothcie; + if(smoothi) { + ToneEqualizerParams params; + params.enabled = true; + params.regularization = 0.f; + params.pivot = 0.f; + params.bands[0] = 0; + params.bands[1] = 0; + params.bands[2] = 0; + params.bands[3] = 0; + params.bands[4] = -40;//arbitrary value to adapt with WhiteEvjz - here White Ev # 10 + params.bands[5] = -80;//8 Ev and above + bool Evsix = true; + if(Evsix) {//EV = 6 majority of images + params.bands[4] = -15; + } + + ipf.toneEqualizer(tmpImage1.get(), params, prof, 1, false); + } ipf.rgb2lab(*tmpImage1, *labView, params.icm.workingProfile); + // labView and provis - if(provis) { + if (provis) { ipf.preserv(labView, provis.get(), GW, GH); } - if(params.icm.fbw) { + + if (params.icm.fbw) { #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int x = 0; x < GH; x++) - for (int y = 0; y < GW; y++) { - labView->a[x][y] = 0.f; - labView->b[x][y] = 0.f; - } + + for (int x = 0; x < GH; x++) + for (int y = 0; y < GW; y++) { + labView->a[x][y] = 0.f; + labView->b[x][y] = 0.f; + } } } @@ -1768,7 +1850,7 @@ private: adap = 2000.; }//if no exif data or wrong else { - double E_V = fcomp + log2 ((fnum * fnum) / fspeed / (fiso / 100.f)); + double E_V = fcomp + log2((fnum * fnum) / fspeed / (fiso / 100.f)); double kexp = 0.; E_V += kexp * params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV E_V += 0.5 * log2(params.raw.expos); // exposure raw white point ; log2 ==> linear to EV @@ -1780,7 +1862,7 @@ private: float CAMMean = NAN; float d, dj, yb; - ipf.ciecam_02float (cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, 1, true, d, dj, yb, 1); + ipf.ciecam_02float(cieView, float (adap), 1, 2, labView, ¶ms, customColCurve1, customColCurve2, customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 0, 1, true, d, dj, yb, 1); } delete cieView; @@ -1896,21 +1978,26 @@ private: } Exiv2Metadata info(imgsrc->getFileName()); + switch (params.metadata.mode) { - case MetaDataParams::TUNNEL: - readyImg->setMetadata(std::move(info)); - break; - case MetaDataParams::EDIT: - info.setExif(params.metadata.exif); - info.setIptc(params.metadata.iptc); - if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "*")) { - info.setExifKeys(&(params.metadata.exifKeys)); - } - readyImg->setMetadata(std::move(info)); - break; - default: // case MetaDataParams::STRIP - // nothing to do - break; + case MetaDataParams::TUNNEL: + readyImg->setMetadata(std::move(info)); + break; + + case MetaDataParams::EDIT: + info.setExif(params.metadata.exif); + info.setIptc(params.metadata.iptc); + + if (!(params.metadata.exifKeys.size() == 1 && params.metadata.exifKeys[0] == "*")) { + info.setExifKeys(&(params.metadata.exifKeys)); + } + + readyImg->setMetadata(std::move(info)); + break; + + default: // case MetaDataParams::STRIP + // nothing to do + break; } diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index b563cbd3b..0390ef869 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -888,7 +888,8 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) curveMode3Changed(); // This will set the correct sensitive state of depending Adjusters nexttemp = pp->wb.temperature; - nextgreen = 1.; //pp->wb.green; + //nextgreen = 1.; //pp->wb.green; + nextgreen = pp->wb.green; if (pedited) { degree->setEditedState (pedited->colorappearance.degree ? Edited : UnEdited); @@ -1519,7 +1520,7 @@ void ColorAppearance::catmethodChanged() ybout->resetValue (false); tempout->resetValue (false); tempout->setAutoValue (true); - greenout->resetValue (false); + greenout->resetValue (true); enableListener(); } else if (catmethod->get_active_row_number() == 2) { disableListener(); @@ -1887,8 +1888,10 @@ void ColorAppearance::wbCamChanged (double temp, double tin) { disableListener(); tempout->setValue(temp); - greenout->setValue(tin); + greenout->setValue(tin); enableListener(); + listener->panelChanged (EvCATgreenout, greenout->getTextValue()); + listener->panelChanged (EvCATtempout, tempout->getTextValue()); return false; } ); diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 3ad1b01e4..d5e570994 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -647,7 +647,7 @@ void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) lastLumamode = pp->colorToning.lumamode; - labgrid->setParams(pp->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0,false); + labgrid->setParams(pp->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, pp->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0,false); if (pedited && !pedited->colorToning.method) { method->set_active (7); @@ -719,7 +719,7 @@ void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) double zerox = 0.; double zeroy = 0.; - labgrid->getParams(pp->colorToning.labgridALow, pp->colorToning.labgridBLow, pp->colorToning.labgridAHigh, pp->colorToning.labgridBHigh, zerox, zeroy, zerox, zeroy); + labgrid->getParams(pp->colorToning.labgridALow, pp->colorToning.labgridBLow, pp->colorToning.labgridAHigh, pp->colorToning.labgridBHigh, zerox, zeroy, zerox, zeroy, zerox, zeroy); pp->colorToning.labgridALow *= ColorToningParams::LABGRID_CORR_MAX; pp->colorToning.labgridAHigh *= ColorToningParams::LABGRID_CORR_MAX; pp->colorToning.labgridBLow *= ColorToningParams::LABGRID_CORR_MAX; @@ -835,7 +835,7 @@ void ColorToning::setDefaults (const ProcParams* defParams, const ParamsEdited* hlColSat->setDefault (defParams->colorToning.hlColSat); shadowsColSat->setDefault (defParams->colorToning.shadowsColSat); strength->setDefault (defParams->colorToning.strength); - labgrid->setDefault(defParams->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0); + labgrid->setDefault(defParams->colorToning.labgridALow / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridBLow / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridAHigh / ColorToningParams::LABGRID_CORR_MAX, defParams->colorToning.labgridBHigh / ColorToningParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0); if (pedited) { @@ -1435,7 +1435,7 @@ void ColorToning::labRegionGet(int idx) double la, lb; double zerox = 0.; double zeroy = 0.; - labRegionAB->getParams(la, lb, r.a, r.b, zerox, zeroy, zerox, zeroy); + labRegionAB->getParams(la, lb, r.a, r.b, zerox, zeroy, zerox, zeroy, zerox, zeroy); r.saturation = labRegionSaturation->getValue(); r.slope = labRegionSlope->getValue(); r.offset = labRegionOffset->getValue(); @@ -1573,7 +1573,7 @@ void ColorToning::labRegionShow(int idx, bool list_only) rtengine::procparams::ColorToningParams::LabCorrectionRegion dflt; auto &r = labRegionData[idx]; if (!list_only) { - labRegionAB->setParams(0, 0, r.a, r.b,0, 0, 0, 0, false); + labRegionAB->setParams(0, 0, r.a, r.b,0, 0, 0, 0, 0, 0, false); labRegionSaturation->setValue(r.saturation); labRegionSlope->setValue(r.slope); labRegionOffset->setValue(r.offset); diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 12eea86cc..31510acbc 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -66,15 +66,16 @@ ControlSpotPanel::ControlSpotPanel(): locYT_(Gtk::manage(new Adjuster(M("TP_LOCAL_HEIGHT_T"), 2, 3000, 1, 150))), centerX_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTER_X"), -1000, 1000, 1, 0))), centerY_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CENTER_Y"), -1000, 1000, 1, 0))), - circrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CIRCRADIUS"), 2, 150, 1, 18))), + circrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CIRCRADIUS"), 1.5, 150., 0.5, 18.))), transit_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITVALUE"), 2., 100., 0.1, 60.))), transitweak_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITWEAK"), 0.5, 25.0, 0.1, 1.0))), transitgrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITGRAD"), -1.0, 1.0, 0.01, 0.0))), feather_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))), - thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 10.0, 0.1, 2.0))), + thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 15.0, 0.1, 2.0))), iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0.2, 10.0, 0.1, 2.0))), - balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("circle-multicolor-small")), Gtk::manage(new RTImage("circle-white-small"))))), + // balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.05, 2.5, 0.05, 1.0, Gtk::manage(new RTImage("rawtherapee-logo-16")), Gtk::manage(new RTImage("circle-white-small"))))), + balan_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALAN"), 0.05, 2.5, 0.05, 1.0, Gtk::manage(new RTImage("circle-yellow-small")), Gtk::manage(new RTImage("circle-white-small"))))), balanh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BALANH"), 0.2, 2.5, 0.1, 1.0, Gtk::manage(new RTImage("circle-multicolor-small")), Gtk::manage(new RTImage("circle-red-green-small"))))), colorde_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORDE"), -15, 15, 2, 5, Gtk::manage(new RTImage("circle-blue-yellow-small")), Gtk::manage(new RTImage("circle-gray-green-small"))))), colorscope_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COLORSCOPE"), 0., 100.0, 1., 30.))), @@ -1456,7 +1457,7 @@ void ControlSpotPanel::adjusterChanged(Adjuster* a, double newval) } if (a == circrad_) { - row[spots_.circrad] = circrad_->getIntValue(); + row[spots_.circrad] = circrad_->getValue(); updateControlSpotCurve(row); diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 542234db2..eeca55265 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -32,7 +32,24 @@ #include "rtimage.h" #include "rtwindow.h" -const char* sTRCPreset[] = {"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", "Lab_g3.0s9.03296"}; //gamma free +const char* sTRCPreset[] = {"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", "Lab_g3.0s9.03296" /*, "PQ", "HLG" */}; //gamma free + + +// code take in ART thanks to Alberto Griggio +cmsToneCurve *make_trc(size_t size, float (*trcFunc)(float, bool)) +{ + std::vector values(size); + + for (size_t i = 0; i < size; ++i) { + float x = float(i) / (size - 1); + float y = trcFunc(x, false); //, 1.0f); + values[i] = y; + } + + cmsToneCurve *result = cmsBuildTabulatedToneCurveFloat(NULL, size, &values[0]); + return result; +} +/// ICCProfileCreator::ICCProfileCreator(RTWindow *rtwindow) : Gtk::Dialog(M("MAIN_BUTTON_ICCPROFCREATOR"), *rtwindow, true) @@ -1305,6 +1322,10 @@ void ICCProfileCreator::savePressed() GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildGamma(NULL, 1.0); } else if(gammaPreset == "Custom" && slope == 0.0) { GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildGamma(NULL, gamma); +// } else if(gammaPreset == "PQ") { +// GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = make_trc(4096, &rtengine::Color::eval_PQ_curve); //thanks to Alberto Griggio +// } else if(gammaPreset == "HLG") { +// GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = make_trc(4096, &rtengine::Color::eval_HLG_curve); //thanks to Alberto Griggio } else { GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(nullptr, 5, ga); } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 772f8e38e..649978cf9 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -65,12 +65,20 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu EvICMLabGridciexy = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICL_LABGRIDCIEXY"); EvICMfbw = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_FBW"); EvICMgamut = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_GAMUT"); + EvICMcat = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_CAT"); + EvICMrefi = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_REFI"); + EvICMtrcExp = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_TRCEXP"); + EvICMshiftx = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_SHIFTX"); + EvICMshifty = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_SHIFTY"); + EvICMwmidtcie = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_MIDTCIE"); + EvICMwsmoothcie = m->newEvent(LUMINANCECURVE, "HISTORY_MSG_ICM_SMOOTHCIE"); + isBatchMode = lastToneCurve = lastApplyLookTable = lastApplyBaselineExposureOffset = lastApplyHueSatMap = false; ipDialog = Gtk::manage(new MyFileChooserButton(M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); ipDialog->set_tooltip_text(M("TP_ICM_INPUTCUSTOM_TOOLTIP")); bindCurrentFolder(*ipDialog, options.lastIccDir); - labgridcie = Gtk::manage(new LabGrid(EvICMLabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true)); + labgridcie = Gtk::manage(new LabGrid(EvICMLabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, true)); // ------------------------------- Input profile @@ -205,12 +213,13 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu //-----------------gamma TRC working // Gtk::Frame *trcFrame = Gtk::manage(new Gtk::Frame(M("TP_ICM_TRCFRAME"))); - trcExp = Gtk::manage(new MyExpander(false, M("TP_ICM_TRCFRAME"))); + trcExp = Gtk::manage(new MyExpander(true, M("TP_ICM_TRCFRAME"))); setExpandAlignProperties(trcExp, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); // trcFrame->set_label_align(0.025, 0.5); Gtk::Box *trcProfVBox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); trcExp->set_tooltip_text(M("TP_ICM_TRCFRAME_TOOLTIP")); trcExp->signal_button_release_event().connect_notify ( sigc::bind ( sigc::mem_fun (this, &ICMPanel::foldAllButMe), trcExp) ); + trcExpconn = trcExp->signal_enabled_toggled().connect(sigc::mem_fun(*this, &ICMPanel::trcExpChanged)); wTRCBox = Gtk::manage(new Gtk::Box()); @@ -233,11 +242,19 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu wGamma = Gtk::manage(new Adjuster(M("TP_ICM_WORKING_TRC_GAMMA"), 0.40, 15.0, 0.001, 2.222)); wSlope = Gtk::manage(new Adjuster(M("TP_ICM_WORKING_TRC_SLOPE"), 0., 300., 0.01, 4.5)); + wmidtcie = Gtk::manage(new Adjuster(M("TP_LOCALLAB_MIDTCIE"), -100., 100., 1., 0.)); + wsmoothcie = Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SMOOTHCIE"))); trcProfVBox->pack_start(*wGamma, Gtk::PACK_SHRINK); wGamma->show(); trcProfVBox->pack_start(*wSlope, Gtk::PACK_SHRINK); wSlope->show(); + trcProfVBox->pack_start(*wmidtcie, Gtk::PACK_SHRINK); + wmidtcie->show(); + trcProfVBox->pack_start(*wsmoothcie, Gtk::PACK_SHRINK); + wsmoothcie->show(); + wsmoothcieconn = wsmoothcie->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::wsmoothcieChanged)); + wsmoothcie->set_active(false); willuBox = Gtk::manage(new Gtk::Box()); willulab = Gtk::manage(new Gtk::Label(M("TP_ICM_WORKING_ILLU") + ":")); @@ -257,6 +274,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu will->append(M("TP_ICM_WORKING_ILLU_STDA")); will->append(M("TP_ICM_WORKING_ILLU_2000")); will->append(M("TP_ICM_WORKING_ILLU_1500")); + will->append(M("TP_ICM_WORKING_ILLU_E")); will->set_active(0); will->set_tooltip_text(M("TP_ICM_ILLUMPRIM_TOOLTIP")); @@ -270,11 +288,11 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu fbw = Gtk::manage(new Gtk::CheckButton((M("TP_ICM_FBW")))); fbw->set_active(true); gamut = Gtk::manage(new Gtk::CheckButton((M("TP_ICM_GAMUT")))); - gamut->set_active(false); + gamut->set_active(true); trcProfVBox->pack_start(*wprimBox, Gtk::PACK_EXPAND_WIDGET); trcProfVBox->pack_start(*fbw, Gtk::PACK_EXPAND_WIDGET); - trcProfVBox->pack_start(*gamut, Gtk::PACK_EXPAND_WIDGET); +// trcProfVBox->pack_start(*gamut, Gtk::PACK_EXPAND_WIDGET); neutral = Gtk::manage (new Gtk::Button (M ("TP_ICM_NEUTRAL"))); setExpandAlignProperties (neutral, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -296,6 +314,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu wprim->append(M("TP_ICM_WORKING_PRIM_WID")); wprim->append(M("TP_ICM_WORKING_PRIM_AC0")); wprim->append(M("TP_ICM_WORKING_PRIM_JDCMAX")); + wprim->append(M("TP_ICM_WORKING_PRIM_JDCMAXSTDA")); wprim->append(M("TP_ICM_WORKING_PRIM_BRU")); wprim->append(M("TP_ICM_WORKING_PRIM_BET")); wprim->append(M("TP_ICM_WORKING_PRIM_BST")); @@ -327,6 +346,10 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu redFrame->set_label_align(0.025, 0.5); redFrame->set_tooltip_text(M("TP_ICM_WORKING_PRIMFRAME_TOOLTIP")); + colorFramecie = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_COLORFRAME"))); + colorFramecie->set_label_align(0.025, 0.5); + colorFramecie->set_tooltip_text(M("TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP")); + Gtk::Box *redVBox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); primCoordGrid = Gtk::manage(new Gtk::Grid()); primCoordGrid->set_column_homogeneous(true); @@ -355,22 +378,53 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu redVBox->pack_start(*cielab, Gtk::PACK_SHRINK); redVBox->pack_start(*labgridcie, Gtk::PACK_EXPAND_WIDGET, 4); + redVBox->pack_start(*gamut, Gtk::PACK_EXPAND_WIDGET); + refi = Gtk::manage(new Adjuster(M("TC_PRIM_REFI"), -0.5, 1., 0.0001, 0.)); + shiftx = Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTX"), -0.2, 0.2, 0.0001, 0.)); + shifty = Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTY"), -0.2, 0.2, 0.0001, 0.)); + + wcatBox = Gtk::manage(new Gtk::Box()); + wcatlab = Gtk::manage(new Gtk::Label(M("TP_ICM_WORKING_CAT") + ":")); + wcatBox->pack_start(*wcatlab, Gtk::PACK_SHRINK); + wcat = Gtk::manage(new MyComboBoxText()); + wcatBox->pack_start(*wcat, Gtk::PACK_EXPAND_WIDGET); + + wcat->append(M("TP_ICM_WORKING_CAT_BRAD")); + wcat->append(M("TP_ICM_WORKING_CAT_CAT16")); + wcat->append(M("TP_ICM_WORKING_CAT_CAT02")); + wcat->append(M("TP_ICM_WORKING_CAT_VK")); + wcat->append(M("TP_ICM_WORKING_CAT_XYZ")); + wcat->set_active(0); + redVBox->pack_start(*wcatBox, Gtk::PACK_SHRINK); + + ToolParamBlock* const colorBox = Gtk::manage(new ToolParamBlock()); + + colorBox->pack_start(*refi, Gtk::PACK_EXPAND_WIDGET); + colorBox->pack_start(*shiftx, Gtk::PACK_EXPAND_WIDGET); + colorBox->pack_start(*shifty, Gtk::PACK_EXPAND_WIDGET); + colorFramecie->add(*colorBox); + redVBox->pack_start(*colorFramecie); redFrame->add(*redVBox); wGamma->setAdjusterListener(this); wSlope->setLogScale(16, 0); wSlope->setAdjusterListener(this); + wmidtcie->setAdjusterListener(this); redx->setAdjusterListener(this); redy->setAdjusterListener(this); grex->setAdjusterListener(this); grey->setAdjusterListener(this); blux->setAdjusterListener(this); bluy->setAdjusterListener(this); + refi->setAdjusterListener(this); + shiftx->setAdjusterListener(this); + shifty->setAdjusterListener(this); wGamma->setDelay(std::max(options.adjusterMinDelay, options.adjusterMaxDelay)); wSlope->setDelay(std::max(options.adjusterMinDelay, options.adjusterMaxDelay)); + wmidtcie->setDelay(std::max(options.adjusterMinDelay, options.adjusterMaxDelay)); // Rendering intent riaHBox = Gtk::manage(new Gtk::Box()); @@ -479,6 +533,7 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, TOOL_NAME, M("TP_ICM_LABEL")), iu wtrcconn = wTRC->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wtrcinChanged)); willconn = will->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::willChanged)); wprimconn = wprim->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wprimChanged)); + wcatconn = wcat->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wcatChanged)); fbwconn = fbw->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::fbwChanged)); gamutconn = gamut->signal_toggled().connect(sigc::mem_fun(*this, &ICMPanel::gamutChanged)); @@ -525,6 +580,8 @@ void ICMPanel::neutral_pressed () wprim->set_active(toUnderlying(ColorManagementParams::Primaries::ACES_P0)); } else if (wProfNames->get_active_text() == "JDCmax") { wprim->set_active(toUnderlying(ColorManagementParams::Primaries::JDC_MAX)); + } else if (wProfNames->get_active_text() == "JDCmax stdA") { + wprim->set_active(toUnderlying(ColorManagementParams::Primaries::JDC_MAXSTDA)); } else if (wProfNames->get_active_text() == "BruceRGB") { wprim->set_active(toUnderlying(ColorManagementParams::Primaries::BRUCE_RGB)); } else if (wProfNames->get_active_text() == "Beta RGB") { @@ -535,9 +592,11 @@ void ICMPanel::neutral_pressed () const ColorManagementParams defPar; wGamma->setValue(defPar.workingTRCGamma);//2.4 wSlope->setValue(defPar.workingTRCSlope);//12.92 + wmidtcie->setValue(defPar.wmidtcie); preser->setValue(defPar.preser); fbw->set_active(defPar.fbw); gamut->set_active(defPar.gamut); + wsmoothcie->set_active(defPar.wsmoothcie); wTRC->set_active(toUnderlying(ColorManagementParams::WorkingTrc::NONE));//reset to none will->set_active(toUnderlying(ColorManagementParams::Illuminant::DEFAULT));//reset to default - after wprim } @@ -614,7 +673,7 @@ void ICMPanel::primChanged (float rx, float ry, float bx, float by, float gx, fl ); } -void ICMPanel::iprimChanged (float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y) +void ICMPanel::iprimChanged (float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y, float m_x, float m_y) {//update CIE xy graph nextrx = r_x; nextry = r_y; @@ -624,6 +683,8 @@ void ICMPanel::iprimChanged (float r_x, float r_y, float b_x, float b_y, float g nextgy = g_y; nextwx = w_x; nextwy = w_y; + nextmx = m_x; + nextmy = m_y; //convert xy datas in datas for labgrid areas nextrx = 1.81818f * (nextrx + 0.1f) - 1.f; nextry = 1.81818f * (nextry + 0.1f) - 1.f; @@ -633,12 +694,14 @@ void ICMPanel::iprimChanged (float r_x, float r_y, float b_x, float b_y, float g nextgy = 1.81818f * (nextgy + 0.1f) - 1.f; nextwx = 1.81818f * (nextwx + 0.1f) - 1.f; nextwy = 1.81818f * (nextwy + 0.1f) - 1.f; + nextmx = 1.81818f * (nextmx + 0.1f) - 1.f; + nextmy = 1.81818f * (nextmy + 0.1f) - 1.f; idle_register.add( [this]() -> bool { disableListener(); - labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, false); + labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, nextmx, nextmy, false); enableListener(); return false; } @@ -793,6 +856,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker obpcconn_(obpcconn); ConnectionBlocker fbwconn_(fbwconn); ConnectionBlocker gamutconn_(gamutconn); + ConnectionBlocker wsmoothcieconn_(wsmoothcieconn); ConnectionBlocker ipc_(ipc); ConnectionBlocker tcurveconn_(tcurveconn); ConnectionBlocker ltableconn_(ltableconn); @@ -806,6 +870,9 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) ConnectionBlocker wtrcconn_(wtrcconn); ConnectionBlocker willconn_(willconn); ConnectionBlocker wprimconn_(wprimconn); + ConnectionBlocker wcatconn_(wcatconn); + ConnectionBlocker trcExpconn_(trcExpconn); + trcExp->set_expanded(false); if (pp->icm.inputProfile.substr(0, 5) != "file:" && !ipDialog->get_filename().empty()) { @@ -847,10 +914,14 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) will->set_active(rtengine::toUnderlying(pp->icm.will)); wprim->set_active(rtengine::toUnderlying(pp->icm.wprim)); + wcat->set_active(rtengine::toUnderlying(pp->icm.wcat)); wtrcinChanged(); willChanged(); wprimChanged(); + wcatChanged(); + gamutChanged(); + wsmoothcieChanged(); if (pp->icm.outputProfile == ColorManagementParams::NoICMString) { oProfNames->set_active_text(M("TP_ICM_NOICM")); @@ -867,7 +938,9 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) obpc->set_active(pp->icm.outputBPC); fbw->set_active(pp->icm.fbw); + trcExp->setEnabled(pp->icm.trcExp); gamut->set_active(pp->icm.gamut); + wsmoothcie->set_active(pp->icm.wsmoothcie); ckbToneCurve->set_active(pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; ckbApplyLookTable->set_active(pp->icm.applyLookTable); @@ -879,20 +952,26 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) wGamma->setValue(pp->icm.workingTRCGamma); wSlope->setValue(pp->icm.workingTRCSlope); + wmidtcie->setValue(pp->icm.wmidtcie); redx->setValue(pp->icm.redx); redy->setValue(pp->icm.redy); grex->setValue(pp->icm.grex); grey->setValue(pp->icm.grey); blux->setValue(pp->icm.blux); bluy->setValue(pp->icm.bluy); + refi->setValue(pp->icm.refi); + shiftx->setValue(pp->icm.shiftx); + shifty->setValue(pp->icm.shifty); preser->setValue(pp->icm.preser); - labgridcie->setParams(pp->icm.labgridcieALow, pp->icm.labgridcieBLow, pp->icm.labgridcieAHigh, pp->icm.labgridcieBHigh, pp->icm.labgridcieGx, pp->icm.labgridcieGy, pp->icm.labgridcieWx, pp->icm.labgridcieWy, false); + labgridcie->setParams(pp->icm.labgridcieALow, pp->icm.labgridcieBLow, pp->icm.labgridcieAHigh, pp->icm.labgridcieBHigh, pp->icm.labgridcieGx, pp->icm.labgridcieGy, pp->icm.labgridcieWx, pp->icm.labgridcieWy, pp->icm.labgridcieMx, pp->icm.labgridcieMy, false); if (pedited) { iunchanged->set_active(!pedited->icm.inputProfile); obpc->set_inconsistent(!pedited->icm.outputBPC); fbw->set_inconsistent(!pedited->icm.fbw); + trcExp->set_inconsistent(!pedited->icm.trcExp); gamut->set_inconsistent(!pedited->icm.gamut); + wsmoothcie->set_inconsistent(!pedited->icm.wsmoothcie); ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve); ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable); ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset); @@ -929,17 +1008,26 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) if (!pedited->icm.wprim) { wprim->set_active_text(M("GENERAL_UNCHANGED")); } - labgridcie->setEdited(pedited->icm.labgridcieALow || pedited->icm.labgridcieBLow || pedited->icm.labgridcieAHigh || pedited->icm.labgridcieBHigh || pedited->icm.labgridcieGx || pedited->icm.labgridcieGy || pedited->icm.labgridcieWx || pedited->icm.labgridcieWy); + + if (!pedited->icm.wcat) { + wcat->set_active_text(M("GENERAL_UNCHANGED")); + } + + labgridcie->setEdited(pedited->icm.labgridcieALow || pedited->icm.labgridcieBLow || pedited->icm.labgridcieAHigh || pedited->icm.labgridcieBHigh || pedited->icm.labgridcieGx || pedited->icm.labgridcieGy || pedited->icm.labgridcieWx || pedited->icm.labgridcieWy || pedited->icm.labgridcieMx || pedited->icm.labgridcieMy); wGamma->setEditedState(pedited->icm.workingTRCGamma ? Edited : UnEdited); wSlope->setEditedState(pedited->icm.workingTRCSlope ? Edited : UnEdited); + wmidtcie->setEditedState(pedited->icm.wmidtcie ? Edited : UnEdited); redx->setEditedState(pedited->icm.redx ? Edited : UnEdited); redy->setEditedState(pedited->icm.redy ? Edited : UnEdited); grex->setEditedState(pedited->icm.grex ? Edited : UnEdited); grey->setEditedState(pedited->icm.grey ? Edited : UnEdited); blux->setEditedState(pedited->icm.blux ? Edited : UnEdited); bluy->setEditedState(pedited->icm.bluy ? Edited : UnEdited); + refi->setEditedState(pedited->icm.refi ? Edited : UnEdited); preser->setEditedState(pedited->icm.preser ? Edited : UnEdited); + shiftx->setEditedState(pedited->icm.shiftx ? Edited : UnEdited); + shifty->setEditedState(pedited->icm.shifty ? Edited : UnEdited); } @@ -947,11 +1035,15 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::WorkingTrc::NONE: { wSlope->set_sensitive(false); wGamma->set_sensitive(false); + wmidtcie->set_sensitive(false); will->set_sensitive(false); willulab->set_sensitive(false); wprim->set_sensitive(false); + wcat->set_sensitive(false); + wcatlab->set_sensitive(false); fbw->set_sensitive(false); gamut->set_sensitive(false); + wsmoothcie->set_sensitive(false); wprimlab->set_sensitive(false); riaHBox->set_sensitive(false); redFrame->hide(); @@ -962,8 +1054,17 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } + fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); @@ -992,9 +1093,11 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) if (pp->icm.workingTRCGamma <= 1.) { wGamma->set_sensitive(true); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); } else { wGamma->set_sensitive(true); wSlope->set_sensitive(true); + wmidtcie->set_sensitive(true); } break; } @@ -1002,14 +1105,24 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::WorkingTrc::BT709: wGamma->setValue(2.222); wSlope->setValue(4.5); - will->set_sensitive(true); + will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } + fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); } else { @@ -1020,14 +1133,23 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::WorkingTrc::SRGB: wGamma->setValue(2.4); wSlope->setValue(12.92); - will->set_sensitive(true); + will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); riaHBox->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); @@ -1038,15 +1160,24 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::WorkingTrc::GAMMA_2_2: wGamma->setValue(2.2); wSlope->setValue(0.); - will->set_sensitive(true); + will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); redFrame->show(); wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); riaHBox->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); @@ -1057,11 +1188,19 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::WorkingTrc::GAMMA_1_8: wGamma->setValue(1.8); wSlope->setValue(0.); - will->set_sensitive(true); + will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); riaHBox->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { @@ -1071,18 +1210,28 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) } wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); break; case ColorManagementParams::WorkingTrc::LINEAR: wGamma->setValue(1.); wSlope->setValue(1.); - will->set_sensitive(true); + will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(true); riaHBox->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { redFrame->hide(); @@ -1102,6 +1251,7 @@ void ICMPanel::read(const ProcParams* pp, const ParamsEdited* pedited) case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: case ColorManagementParams::Primaries::JDC_MAX: + case ColorManagementParams::Primaries::JDC_MAXSTDA: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1148,7 +1298,7 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pp->icm.workingProfile = wProfNames->get_active_text(); pp->icm.dcpIlluminant = rtengine::max(dcpIll->get_active_row_number(), 0); - labgridcie->getParams(pp->icm.labgridcieALow, pp->icm.labgridcieBLow, pp->icm.labgridcieAHigh, pp->icm.labgridcieBHigh, pp->icm.labgridcieGx, pp->icm.labgridcieGy, pp->icm.labgridcieWx, pp->icm.labgridcieWy); + labgridcie->getParams(pp->icm.labgridcieALow, pp->icm.labgridcieBLow, pp->icm.labgridcieAHigh, pp->icm.labgridcieBHigh, pp->icm.labgridcieGx, pp->icm.labgridcieGy, pp->icm.labgridcieWx, pp->icm.labgridcieWy, pp->icm.labgridcieMx, pp->icm.labgridcieMy); if (oProfNames->get_active_text() == M("TP_ICM_NOICM")) { pp->icm.outputProfile = ColorManagementParams::NoICMString; @@ -1175,6 +1325,7 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pp->icm.workingTRC = ColorManagementParams::WorkingTrc(wTRC->get_active_row_number()); pp->icm.will = ColorManagementParams::Illuminant(will->get_active_row_number()); pp->icm.wprim = ColorManagementParams::Primaries(wprim->get_active_row_number()); + pp->icm.wcat = ColorManagementParams::Cat(wcat->get_active_row_number()); pp->icm.toneCurve = ckbToneCurve->get_active(); pp->icm.applyLookTable = ckbApplyLookTable->get_active(); @@ -1182,15 +1333,21 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pp->icm.applyHueSatMap = ckbApplyHueSatMap->get_active(); pp->icm.outputBPC = obpc->get_active(); pp->icm.fbw = fbw->get_active(); + pp->icm.trcExp = trcExp->getEnabled(); pp->icm.gamut = gamut->get_active(); + pp->icm.wsmoothcie = wsmoothcie->get_active(); pp->icm.workingTRCGamma = wGamma->getValue(); pp->icm.workingTRCSlope = wSlope->getValue(); + pp->icm.wmidtcie = wmidtcie->getValue(); pp->icm.redx = redx->getValue(); pp->icm.redy = redy->getValue(); pp->icm.grex = grex->getValue(); pp->icm.grey = grey->getValue(); pp->icm.blux = blux->getValue(); pp->icm.bluy = bluy->getValue(); + pp->icm.refi = refi->getValue(); + pp->icm.shiftx = shiftx->getValue(); + pp->icm.shifty = shifty->getValue(); pp->toneCurve.fromHistMatching = false; pp->icm.preser = preser->getValue(); @@ -1202,7 +1359,9 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pedited->icm.aRendIntent = aRendIntent->getSelected() < 4; pedited->icm.outputBPC = !obpc->get_inconsistent(); pedited->icm.fbw = !fbw->get_inconsistent(); + pedited->icm.trcExp = !trcExp->get_inconsistent(); pedited->icm.gamut = !gamut->get_inconsistent(); + pedited->icm.wsmoothcie = !wsmoothcie->get_inconsistent(); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent(); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent(); @@ -1210,12 +1369,14 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) pedited->icm.applyHueSatMap = !ckbApplyHueSatMap->get_inconsistent(); pedited->icm.workingTRCGamma = wGamma->getEditedState(); pedited->icm.workingTRCSlope = wSlope->getEditedState(); + pedited->icm.wmidtcie = wmidtcie->getEditedState(); pedited->icm.workingTRC = wTRC->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.will = will->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.wprim = wprim->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->icm.wcat = wcat->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.redx = redx->getEditedState(); pedited->icm.redy = redy->getEditedState(); - pedited->icm.labgridcieALow = pedited->icm.labgridcieBLow = pedited->icm.labgridcieAHigh = pedited->icm.labgridcieBHigh = pedited->icm.labgridcieGx = pedited->icm.labgridcieGy = pedited->icm.labgridcieWx = pedited->icm.labgridcieWy = labgridcie->getEdited(); + pedited->icm.labgridcieALow = pedited->icm.labgridcieBLow = pedited->icm.labgridcieAHigh = pedited->icm.labgridcieBHigh = pedited->icm.labgridcieGx = pedited->icm.labgridcieGy = pedited->icm.labgridcieWx = pedited->icm.labgridcieWy = pedited->icm.labgridcieMx = pedited->icm.labgridcieMy = labgridcie->getEdited(); } } @@ -1223,36 +1384,48 @@ void ICMPanel::setDefaults(const ProcParams* defParams, const ParamsEdited* pedi { wGamma->setDefault(defParams->icm.workingTRCGamma); wSlope->setDefault(defParams->icm.workingTRCSlope); + wmidtcie->setDefault(defParams->icm.wmidtcie); redx->setDefault(defParams->icm.redx); redy->setDefault(defParams->icm.redy); grex->setDefault(defParams->icm.grex); grey->setDefault(defParams->icm.grey); blux->setDefault(defParams->icm.blux); bluy->setDefault(defParams->icm.bluy); + refi->setDefault(defParams->icm.refi); + shiftx->setDefault(defParams->icm.shiftx); + shifty->setDefault(defParams->icm.shifty); preser->setDefault(defParams->icm.preser); - labgridcie->setDefault(defParams->icm.labgridcieALow, defParams->icm.labgridcieBLow , defParams->icm.labgridcieAHigh, defParams->icm.labgridcieBHigh, defParams->icm.labgridcieGx, defParams->icm.labgridcieGy, defParams->icm.labgridcieWx, defParams->icm.labgridcieWy); + labgridcie->setDefault(defParams->icm.labgridcieALow, defParams->icm.labgridcieBLow , defParams->icm.labgridcieAHigh, defParams->icm.labgridcieBHigh, defParams->icm.labgridcieGx, defParams->icm.labgridcieGy, defParams->icm.labgridcieWx, defParams->icm.labgridcieWy, defParams->icm.labgridcieMx, defParams->icm.labgridcieMy); if (pedited) { wGamma->setDefaultEditedState(pedited->icm.workingTRCGamma ? Edited : UnEdited); wSlope->setDefaultEditedState(pedited->icm.workingTRCSlope ? Edited : UnEdited); + wmidtcie->setDefaultEditedState(pedited->icm.wmidtcie ? Edited : UnEdited); redx->setDefaultEditedState(pedited->icm.redx ? Edited : UnEdited); redy->setDefaultEditedState(pedited->icm.redy ? Edited : UnEdited); grex->setDefaultEditedState(pedited->icm.grex ? Edited : UnEdited); grey->setDefaultEditedState(pedited->icm.grey ? Edited : UnEdited); blux->setDefaultEditedState(pedited->icm.blux ? Edited : UnEdited); bluy->setDefaultEditedState(pedited->icm.bluy ? Edited : UnEdited); - labgridcie->setEdited((pedited->icm.labgridcieALow || pedited->icm.labgridcieBLow || pedited->icm.labgridcieAHigh || pedited->icm.labgridcieBHigh || pedited->icm.labgridcieGx || pedited->icm.labgridcieGy || pedited->icm.labgridcieWx || pedited->icm.labgridcieWy) ? Edited : UnEdited); + refi->setDefaultEditedState(pedited->icm.refi ? Edited : UnEdited); + shiftx->setDefaultEditedState(pedited->icm.shiftx ? Edited : UnEdited); + shifty->setDefaultEditedState(pedited->icm.shifty ? Edited : UnEdited); + labgridcie->setEdited((pedited->icm.labgridcieALow || pedited->icm.labgridcieBLow || pedited->icm.labgridcieAHigh || pedited->icm.labgridcieBHigh || pedited->icm.labgridcieGx || pedited->icm.labgridcieGy || pedited->icm.labgridcieWx || pedited->icm.labgridcieWy || pedited->icm.labgridcieMx || pedited->icm.labgridcieMy) ? Edited : UnEdited); preser->setDefaultEditedState(pedited->icm.preser ? Edited : UnEdited); } else { wGamma->setDefaultEditedState(Irrelevant); wSlope->setDefaultEditedState(Irrelevant); + wmidtcie->setDefaultEditedState(Irrelevant); redx->setDefaultEditedState(Irrelevant); redy->setDefaultEditedState(Irrelevant); grex->setDefaultEditedState(Irrelevant); grey->setDefaultEditedState(Irrelevant); blux->setDefaultEditedState(Irrelevant); bluy->setDefaultEditedState(Irrelevant); + refi->setDefaultEditedState(Irrelevant); + shiftx->setDefaultEditedState(Irrelevant); + shifty->setDefaultEditedState(Irrelevant); preser->setDefaultEditedState(Irrelevant); labgridcie->setEdited(Edited); @@ -1273,6 +1446,8 @@ void ICMPanel::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvICMgamm, costr2); } else if (a == wSlope) { listener->panelChanged(EvICMslop, costr2); + } else if (a == wmidtcie) { + listener->panelChanged(EvICMwmidtcie, costr2); } else if (a == redx) { listener->panelChanged(EvICMredx, costr2); } else if (a == redy) { @@ -1287,6 +1462,12 @@ void ICMPanel::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvICMbluy, costr2); } else if (a == preser) { listener->panelChanged(EvICMpreser, costr2); + } else if (a == refi) { + listener->panelChanged(EvICMrefi, costr2); + } else if (a == shiftx) { + listener->panelChanged(EvICMshiftx, costr2); + } else if (a == shifty) { + listener->panelChanged(EvICMshifty, costr2); } } @@ -1305,11 +1486,13 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::NONE: { wGamma->set_sensitive(false); wSlope->set_sensitive(false); + wmidtcie->set_sensitive(false); will->set_sensitive(false); willulab->set_sensitive(false); wprim->set_sensitive(false); fbw->set_sensitive(false); gamut->set_sensitive(false); + wsmoothcie->set_sensitive(false); wprimlab->set_sensitive(false); redFrame->hide(); riaHBox->set_sensitive(false); @@ -1319,8 +1502,12 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::CUSTOM: { will->set_sensitive(false); wprim->set_sensitive(true); + wmidtcie->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); willulab->set_sensitive(true); if (ColorManagementParams::Primaries(wprim->get_active_row_number()) == ColorManagementParams::Primaries::DEFAULT) { @@ -1350,11 +1537,15 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::BT709: { wGamma->setValue(2.222); wSlope->setValue(4.5); + wmidtcie->set_sensitive(true); will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1376,11 +1567,15 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::SRGB: { wGamma->setValue(2.4); wSlope->setValue(12.92); + wmidtcie->set_sensitive(true); will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); riaHBox->set_sensitive(true); @@ -1403,11 +1598,15 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::GAMMA_2_2: { wGamma->setValue(2.2); wSlope->setValue(0.); + wmidtcie->set_sensitive(true); will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1431,11 +1630,15 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::GAMMA_1_8: { wGamma->setValue(1.8); wSlope->setValue(0.); + wmidtcie->set_sensitive(true); will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1459,11 +1662,15 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::WorkingTrc::LINEAR: { wGamma->setValue(1.0); wSlope->setValue(1.); + wmidtcie->set_sensitive(true); will->set_sensitive(false); willulab->set_sensitive(true); wprim->set_sensitive(true); + wcat->set_sensitive(true); + wcatlab->set_sensitive(true); fbw->set_sensitive(true); gamut->set_sensitive(true); + wsmoothcie->set_sensitive(true); wprimlab->set_sensitive(true); wGamma->set_sensitive(false); wSlope->set_sensitive(false); @@ -1485,6 +1692,7 @@ void ICMPanel::wtrcinChanged() } } wprimChanged(); + wcatChanged(); switch (ColorManagementParams::Primaries(wprim->get_active_row_number())) { case ColorManagementParams::Primaries::DEFAULT: @@ -1496,6 +1704,7 @@ void ICMPanel::wtrcinChanged() case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: case ColorManagementParams::Primaries::JDC_MAX: + case ColorManagementParams::Primaries::JDC_MAXSTDA: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1519,6 +1728,8 @@ void ICMPanel::wtrcinChanged() if (ColorManagementParams::WorkingTrc(wTRC->get_active_row_number()) == ColorManagementParams::WorkingTrc::NONE) { redFrame->hide(); + will->set_sensitive(false); + } if (listener) { @@ -1538,6 +1749,7 @@ void ICMPanel::willChanged() case ColorManagementParams::Primaries::WIDE_GAMUT: case ColorManagementParams::Primaries::ACES_P0: case ColorManagementParams::Primaries::JDC_MAX: + case ColorManagementParams::Primaries::JDC_MAXSTDA: case ColorManagementParams::Primaries::BRUCE_RGB: case ColorManagementParams::Primaries::BETA_RGB: case ColorManagementParams::Primaries::BEST_RGB: { @@ -1663,6 +1875,17 @@ void ICMPanel::wprimChanged() break; } + case ColorManagementParams::Primaries::JDC_MAXSTDA: { + redx->setValue(0.734702); + redy->setValue(0.265302); + grex->setValue(0.021908); + grey->setValue(0.930288); + blux->setValue(0.120593); + bluy->setValue(0.001583); + will->set_active(toUnderlying(ColorManagementParams::Illuminant::STDA)); + break; + } + case ColorManagementParams::Primaries::BRUCE_RGB: { redx->setValue(0.64); redy->setValue(0.33); @@ -1762,7 +1985,15 @@ void ICMPanel::wprimChanged() grey->setValue(0.930288); blux->setValue(0.120593); bluy->setValue(0.001583); - will->set_active(toUnderlying(ColorManagementParams::Illuminant::D50)); + will->set_active(toUnderlying(ColorManagementParams::Illuminant::D50));//D50 + } else if (wProfNames->get_active_text() == "JDCmax stdA") { + redx->setValue(0.734702); + redy->setValue(0.265302); + grex->setValue(0.021908); + grey->setValue(0.930288); + blux->setValue(0.120593); + bluy->setValue(0.001583); + will->set_active(toUnderlying(ColorManagementParams::Illuminant::STDA)); } else if (wProfNames->get_active_text() == "BruceRGB") { redx->setValue(0.64); redy->setValue(0.33); @@ -1820,6 +2051,14 @@ void ICMPanel::wprimChanged() } } +void ICMPanel::wcatChanged() +{ + if (listener) { + listener->panelChanged(EvICMcat, wcat->get_active_text()); + } + +} + void ICMPanel::dcpIlluminantChanged() { if (listener) { @@ -2066,6 +2305,20 @@ void ICMPanel::oBPCChanged() } } +void ICMPanel::trcExpChanged() +{ + + if (listener) { + if (trcExp->getEnabled()) { + listener->panelChanged(EvICMtrcExp, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvICMtrcExp, M("GENERAL_DISABLED")); + } + } +} + + + void ICMPanel::fbwChanged() { if (multiImage) { @@ -2106,11 +2359,17 @@ void ICMPanel::gamutChanged() lastgamut = gamut->get_active(); } - + + if (gamut->get_active()) { + wcatBox->set_sensitive(true); + } else { + wcatBox->set_sensitive(false); + } + if (listener) { if (gamut->get_inconsistent()) { listener->panelChanged(EvICMgamut, M("GENERAL_UNCHANGED")); - } else if (fbw->get_active()) { + } else if (gamut->get_active()) { listener->panelChanged(EvICMgamut, M("GENERAL_ENABLED")); } else { listener->panelChanged(EvICMgamut, M("GENERAL_DISABLED")); @@ -2118,6 +2377,33 @@ void ICMPanel::gamutChanged() } } +void ICMPanel::wsmoothcieChanged() +{ + if (multiImage) { + if (wsmoothcie->get_inconsistent()) { + wsmoothcie->set_inconsistent(false); + wsmoothcieconn.block(true); + wsmoothcie->set_active(false); + wsmoothcieconn.block(false); + } else if (lastwsmoothcie) { + wsmoothcie->set_inconsistent(true); + } + + lastwsmoothcie = wsmoothcie->get_active(); + } + + + if (listener) { + if (wsmoothcie->get_inconsistent()) { + listener->panelChanged(EvICMwsmoothcie, M("GENERAL_UNCHANGED")); + } else if (wsmoothcie->get_active()) { + listener->panelChanged(EvICMwsmoothcie, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvICMwsmoothcie, M("GENERAL_DISABLED")); + } + } +} + void ICMPanel::setRawMeta(bool raw, const rtengine::FramesData* pMeta) { @@ -2230,12 +2516,16 @@ void ICMPanel::setBatchMode(bool batchMode) dcpIll->append(M("GENERAL_UNCHANGED")); wGamma->showEditedCB(); wSlope->showEditedCB(); + wmidtcie->showEditedCB(); redx->showEditedCB(); redy->showEditedCB(); grex->showEditedCB(); grey->showEditedCB(); blux->showEditedCB(); bluy->showEditedCB(); + refi->showEditedCB(); + shiftx->showEditedCB(); + shifty->showEditedCB(); preser->showEditedCB(); } diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index b11b9478c..0f05da2bb 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -49,10 +49,13 @@ protected: Gtk::Frame* dcpFrame; Gtk::Frame* coipFrame; Gtk::Frame* redFrame; + Gtk::Frame* colorFramecie; MyExpander* trcExp; Adjuster* wGamma; Adjuster* wSlope; + Adjuster* wmidtcie; + Gtk::CheckButton* wsmoothcie; Adjuster* redx; Adjuster* redy; Adjuster* grex; @@ -60,13 +63,19 @@ protected: Adjuster* blux; Adjuster* bluy; Adjuster* preser; - + Adjuster* refi; + Adjuster* shiftx; + Adjuster* shifty; + sigc::connection wsmoothcieconn; + bool lastwsmoothcie; Gtk::Label* labmga; Gtk::Box* gabox; //Gtk::Label* blr; //Gtk::Label* blg; //Gtk::Label* blb; Gtk::Button* neutral; + sigc::connection trcExpconn; + bool lasttrcExp; sigc::connection neutralconn; bool lastToneCurve; @@ -111,6 +120,13 @@ private: rtengine::ProcEvent EvICMLabGridciexy; rtengine::ProcEvent EvICMfbw; rtengine::ProcEvent EvICMgamut; + rtengine::ProcEvent EvICMcat; + rtengine::ProcEvent EvICMrefi; + rtengine::ProcEvent EvICMtrcExp; + rtengine::ProcEvent EvICMshiftx; + rtengine::ProcEvent EvICMshifty; + rtengine::ProcEvent EvICMwmidtcie; + rtengine::ProcEvent EvICMwsmoothcie; LabGrid *labgridcie; IdleRegister idle_register; @@ -127,6 +143,10 @@ private: Gtk::CheckButton* fbw; Gtk::CheckButton* gamut; + Gtk::Box* wcatBox; + Gtk::Label* wcatlab; + + Gtk::CheckButton* obpc; Gtk::RadioButton* inone; @@ -149,6 +169,9 @@ private: sigc::connection willconn; MyComboBoxText* wprim; sigc::connection wprimconn; + MyComboBoxText* wcat; + sigc::connection wcatconn; + std::unique_ptr aRendIntent; sigc::connection arendintentconn; @@ -180,6 +203,8 @@ private: float nextgy; float nextwx; float nextwy; + float nextmx; + float nextmy; public: static const Glib::ustring TOOL_NAME; @@ -193,18 +218,22 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; void primChanged (float rx, float ry, float bx, float by, float gx, float gy) override; - void iprimChanged (float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y) override; + void iprimChanged (float r_x, float r_y, float b_x, float b_y, float g_x, float g_y, float w_x, float w_y, float m_x, float m_y) override; void neutral_pressed(); void wpChanged(); void wtrcinChanged(); void willChanged(); void wprimChanged(); + void wcatChanged(); + void trcExpChanged(); void opChanged(); void oiChanged(int n); void aiChanged(int n); void oBPCChanged(); void fbwChanged(); + void wsmoothcieChanged(); + void gamutChanged(); void ipChanged(); void ipSelectionChanged(); diff --git a/rtgui/labgrid.cc b/rtgui/labgrid.cc index 0773b85c9..9babe17ca 100644 --- a/rtgui/labgrid.cc +++ b/rtgui/labgrid.cc @@ -76,17 +76,19 @@ bool LabGridArea::notifyListener() } -LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy): +LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool mous): Gtk::DrawingArea(), evt(evt), evtMsg(msg), litPoint(NONE), - low_a(0.f), high_a(0.f), low_b(0.f), high_b(0.f), gre_x(0.f), gre_y(0.f), whi_x(0.f), whi_y(0.f),//these variables are used as xy in Ciexy - no change labels - defaultLow_a(0.f), defaultHigh_a(0.f), defaultLow_b(0.f), defaultHigh_b(0.f), defaultgre_x(0.f), defaultgre_y(0.f), defaultwhi_x(0.f), defaultwhi_y(0.f), + low_a(0.f), high_a(0.f), low_b(0.f), high_b(0.f), gre_x(0.f), gre_y(0.f), whi_x(0.f), whi_y(0.f), me_x(0.f), me_y(0.f),//these variables are used as xy in Ciexy - no change labels + defaultLow_a(0.f), defaultHigh_a(0.f), defaultLow_b(0.f), defaultHigh_b(0.f), defaultgre_x(0.f), defaultgre_y(0.f), defaultwhi_x(0.f), defaultwhi_y(0.f), defaultme_x(0.f), defaultme_y(0.f), listener(nullptr), edited(false), isDragged(false), low_enabled(enable_low), - ciexy_enabled(ciexy) + ciexy_enabled(ciexy), + mous_enabled(mous) + { set_can_focus(false); // prevent moving the grid while you're moving a point @@ -95,7 +97,7 @@ LabGridArea::LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool get_style_context()->add_class("drawingarea"); } -void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy) const +void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const { la = low_a; ha = high_a; @@ -105,11 +107,13 @@ void LabGridArea::getParams(double &la, double &lb, double &ha, double &hb, doub gy = gre_y; wx = whi_x; wy = whi_y; + mx = me_x; + my = me_y; // printf("la=%f ha=%f lb=%f hb=%f gx=%f gy=%f\n", la, ha, lb, hb, gx, gy); } -void LabGridArea::setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, bool notify) +void LabGridArea::setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify) { const double lo = -1.0; const double hi = 1.0; @@ -121,6 +125,8 @@ void LabGridArea::setParams(double la, double lb, double ha, double hb, double g gre_y = rtengine::LIM(gy, lo, hi); whi_x = rtengine::LIM(wx, lo, hi); whi_y = rtengine::LIM(wy, lo, hi); + me_x = rtengine::LIM(mx, lo, hi); + me_y = rtengine::LIM(my, lo, hi); queue_draw(); if (notify) { @@ -128,7 +134,7 @@ void LabGridArea::setParams(double la, double lb, double ha, double hb, double g } } -void LabGridArea::setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy) +void LabGridArea::setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my) { defaultLow_a = la; defaultLow_b = lb; @@ -138,16 +144,18 @@ void LabGridArea::setDefault (double la, double lb, double ha, double hb, double defaultgre_y = gy; defaultwhi_x = wx; defaultwhi_y = wy; + defaultme_x = mx; + defaultme_y = my; } void LabGridArea::reset(bool toInitial) { if (toInitial) { - setParams(defaultLow_a, defaultLow_b, defaultHigh_a, defaultHigh_b, defaultgre_x, defaultgre_y, defaultwhi_x, defaultwhi_y, true); + setParams(defaultLow_a, defaultLow_b, defaultHigh_a, defaultHigh_b, defaultgre_x, defaultgre_y, defaultwhi_x, defaultwhi_y, defaultme_x, defaultme_y, true); } else { // printf("RESET \n"); - setParams(0., 0., 0., 0., 0., 0., 0., 0., true); + setParams(0., 0., 0., 0., 0., 0., 0., 0., 0., 0., true); } } @@ -322,6 +330,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) // Drawing the connection line cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); + // float loa, hia, lob, hib, grx, gry, whx, why, mex, mey; const double loa = .5 * (static_cast(width) + static_cast(width) * low_a); const double hia = .5 * (static_cast(width) + static_cast(width) * high_a); const double lob = .5 * (static_cast(height) + static_cast(height) * low_b); @@ -330,7 +339,11 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) const double gry = .5 * (static_cast(height) + static_cast(height) * gre_y); const double whx = .5 * (static_cast(width) + static_cast(width) * whi_x); const double why = .5 * (static_cast(height) + static_cast(height) * whi_y); + double mex = .5 * (static_cast(width) + static_cast(width) * me_x); + double mey = .5 * (static_cast(height) + static_cast(height) * me_y); cr->set_line_width(1.5); + mex = .5 * (width + width * me_x); + mey = .5 * (height + height * me_y); cr->set_source_rgb(0.6, 0.6, 0.6); cr->move_to(loa, lob); cr->line_to(hia, hib); @@ -412,6 +425,12 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) cr->fill(); } + if (ciexy_enabled) {//Dominant + cr->set_source_rgb(0.3, 0.4, 0.3); + cr->arc(mex, mey, 3., 0, 2. * rtengine::RT_PI); + cr->fill(); + } + cr->set_source_rgb(0.9, 0.9, 0.9);//white for blue en Ciexy if (litPoint == HIGH) { cr->arc(hia, hib, 5., 0., 2. * rtengine::RT_PI); @@ -426,7 +445,7 @@ bool LabGridArea::on_draw(const ::Cairo::RefPtr &cr) bool LabGridArea::on_button_press_event(GdkEventButton *event) { - if (event->button == 1) { + if (event->button == 1 && mous_enabled) { if (!ciexy_enabled) { if (event->type == GDK_2BUTTON_PRESS) { switch (litPoint) { @@ -450,14 +469,15 @@ bool LabGridArea::on_button_press_event(GdkEventButton *event) isDragged = true; } } else { - if (event->type == GDK_2BUTTON_PRESS) { - edited = true; - notifyListener(); - queue_draw(); - } else if (event->type == GDK_BUTTON_PRESS && litPoint != NONE) { - isDragged = true; + if(mous_enabled) { + if (event->type == GDK_2BUTTON_PRESS) { + edited = true; + notifyListener(); + queue_draw(); + } else if (event->type == GDK_BUTTON_PRESS && litPoint != NONE) { + isDragged = true; + } } - } return false; } @@ -467,7 +487,7 @@ bool LabGridArea::on_button_press_event(GdkEventButton *event) bool LabGridArea::on_button_release_event(GdkEventButton *event) { - if (event->button == 1) { + if (event->button == 1 && mous_enabled) { isDragged = false; return false; } @@ -591,12 +611,21 @@ void LabGridArea::setciexyEnabled(bool yes) } } +void LabGridArea::setmousEnabled(bool yes) +{ + if (mous_enabled != yes) { + mous_enabled = yes; + queue_draw(); + } +} + + //----------------------------------------------------------------------------- // LabGrid //----------------------------------------------------------------------------- -LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy): - grid(evt, msg, enable_low, ciexy) +LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low, bool ciexy, bool mous): + grid(evt, msg, enable_low, ciexy, mous) { Gtk::Button *reset = Gtk::manage(new Gtk::Button()); reset->set_tooltip_markup(M("ADJUSTER_RESET_TO_DEFAULT")); @@ -611,7 +640,7 @@ LabGrid::LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_ reset->set_can_focus(false); reset->set_size_request(-1, 20); - pack_start(grid, true, true); + pack_start(grid, true, true, true); pack_start(*reset, false, false); show_all_children(); } diff --git a/rtgui/labgrid.h b/rtgui/labgrid.h index d486574b4..9756af626 100644 --- a/rtgui/labgrid.h +++ b/rtgui/labgrid.h @@ -58,7 +58,8 @@ private: double gre_y; double whi_x; double whi_y; - + double me_x; + double me_y; double defaultLow_a; double defaultHigh_a; double defaultLow_b; @@ -67,6 +68,8 @@ private: double defaultgre_y; double defaultwhi_x; double defaultwhi_y; + double defaultme_x; + double defaultme_y; ToolPanelListener *listener; bool edited; @@ -76,16 +79,17 @@ private: bool low_enabled; bool ciexy_enabled; + bool mous_enabled; bool notifyListener(); void getLitPoint(); public: - LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false); + LabGridArea(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool mous=false); - void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy) const; - void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, bool notify); - void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy); + void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const; + void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify); + void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my); void setEdited(bool yes); bool getEdited() const; void reset(bool toInitial); @@ -95,6 +99,8 @@ public: void setLowEnabled(bool yes); bool ciexyEnabled() const; void setciexyEnabled(bool yes); + bool mousEnabled() const; + void setmousEnabled(bool yes); bool on_draw(const ::Cairo::RefPtr &cr) override; void on_style_updated () override; @@ -114,11 +120,11 @@ private: bool resetPressed(GdkEventButton *event); public: - LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false); + LabGrid(rtengine::ProcEvent evt, const Glib::ustring &msg, bool enable_low=true, bool ciexy=false, bool mous=true); - void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy) const { return grid.getParams(la, lb, ha, hb, gx, gy, wx, wy); } - void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, bool notify) { grid.setParams(la, lb, ha, hb, gx, gy, wx, wy, notify); } - void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy) { grid.setDefault(la, lb, ha, hb, gx, gy, wx, wy); } + void getParams(double &la, double &lb, double &ha, double &hb, double &gx, double &gy, double &wx, double &wy, double &mx, double &my) const { return grid.getParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } + void setParams(double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my, bool notify) { grid.setParams(la, lb, ha, hb, gx, gy, wx, wy, mx, my, notify); } + void setDefault (double la, double lb, double ha, double hb, double gx, double gy, double wx, double wy, double mx, double my) { grid.setDefault(la, lb, ha, hb, gx, gy, wx, wy, mx, my); } void setEdited(bool yes) { grid.setEdited(yes); } bool getEdited() const { return grid.getEdited(); } void reset(bool toInitial) { grid.reset(toInitial); } @@ -127,5 +133,8 @@ public: void setLowEnabled(bool yes) { grid.setLowEnabled(yes); } bool ciexyEnabled() const { return grid.ciexyEnabled(); } void setciexyEnabled(bool yes) { grid.setciexyEnabled(yes); } + bool mousEnabled() const { return grid.mousEnabled(); } + void setmousEnabled(bool yes) { grid.setmousEnabled(yes); } + }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 38e84154e..999653ad7 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -1131,18 +1131,69 @@ void Locallab::denChanged(const std::vector &denlc, int selsp } - -void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) +void Locallab::sigChanged(const std::vector &ciesig, int selspot) { - // Update Locallab Log Encoding and Ciecam accordingly - if(autocomput) { - explog.updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg, jz1); + cie_sig = ciesig; + + if (selspot < (int) cie_sig.size()) { + const double s1 = cie_sig.at(selspot).contsigq; + const double s2 = cie_sig.at(selspot).lightsigq; + + expcie.updatesigloc(s1, s2); } - if(autocie) { - expcie.updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg, jz1); + +} + +void Locallab::ciebefChanged(const std::vector &ciebef, int selspot) +{ + cie_bef = ciebef; + if (selspot < (int) cie_bef.size()) { + const double blackev = cie_bef.at(selspot).blackevbef; + const double whiteev = cie_bef.at(selspot).whiteevbef; + const double sourceg = cie_bef.at(selspot).sourcegbef; + const double sourceab = cie_bef.at(selspot).sourceabbef; + const double targetg = cie_bef.at(selspot).targetgbef; + const double jz1 = cie_bef.at(selspot).jz1bef; + const bool autocomput = cie_bef.at(selspot).autocomputbef; + const bool autocie = cie_bef.at(selspot).autociebef; + + if(autocomput) { + explog.updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg, jz1); + } + if(autocie) { + expcie.updateAutocompute(blackev, whiteev, sourceg, sourceab, targetg, jz1); + } + } } + +void Locallab::cieChanged(const std::vector &cielc, int selspot) +{ + // Saving transmitted min/max data + cie_lc = cielc; + + //Update Locallab Denoise tool lum chro + if (selspot < (int) cie_lc.size()) { + const double r1 = cie_lc.at(selspot).redxlc; + const double r2 = cie_lc.at(selspot).redylc; + const double g1 = cie_lc.at(selspot).grexlc; + const double g2 = cie_lc.at(selspot).greylc; + const double b1 = cie_lc.at(selspot).bluxlc; + const double b2 = cie_lc.at(selspot).bluylc; + const double w1 = cie_lc.at(selspot).wxlc; + const double w2 = cie_lc.at(selspot).wylc; + const double m1 = cie_lc.at(selspot).meanxlc; + const double m2 = cie_lc.at(selspot).meanylc; + const double me1 = cie_lc.at(selspot).meanxelc; + const double me2 = cie_lc.at(selspot).meanyelc; + + expcie.updateiPrimloc(r1, r2, g1, g2, b1, b2, w1, w2, m1, m2, me1, me2); + } + +} + + void Locallab::refChanged2(float *huerefp, float *chromarefp, float *lumarefp, float *fabrefp, int selspot) { const double huer = huerefp[selspot]; diff --git a/rtgui/locallab.h b/rtgui/locallab.h index e39f213cc..1848e6481 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -126,6 +126,13 @@ private: // Locallab tools mask background management data std::vector denoiselc; + + std::vector cie_bef; + + std::vector cie_lc; + + std::vector cie_sig; + // Locallab tools mask background management data std::vector maskBackRef; @@ -152,8 +159,14 @@ public: // Locallab Retinex tool min/man management function void denChanged(const std::vector &denlc, int selspot) override; - // Locallab Log Encoding autocompute function - void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) override; + // Locallab CIE tool primaries function + void cieChanged(const std::vector &cielc, int selspot) override; + + // Locallab Log Encoding and Cam16 autocompute function + void ciebefChanged(const std::vector &ciebef, int selspot) override; + + void sigChanged(const std::vector &ciesig, int selspot) override; + // Locallab tools mask background management function // void refChanged(const std::vector &ref, int selspot) override; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 9cdd74c9c..7db035e0b 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -1165,7 +1165,7 @@ void LocallabColor::read(const rtengine::procparams::ProcParams* pp, const Param spot.labgridBLow / LocallabParams::LABGRIDL_CORR_MAX, spot.labgridAHigh / LocallabParams::LABGRIDL_CORR_MAX, spot.labgridBHigh / LocallabParams::LABGRIDL_CORR_MAX, - 0, 0, 0, 0, false); + 0, 0, 0, 0, 0, 0, false); // printf("labgridlow=%f \n", spot.labgridALow); if (spot.gridMethod == "one") { gridMethod->set_active(0); @@ -1278,7 +1278,7 @@ void LocallabColor::read(const rtengine::procparams::ProcParams* pp, const Param labgridmerg->setParams(0, 0, spot.labgridAHighmerg / LocallabParams::LABGRIDL_CORR_MAX, spot.labgridBHighmerg / LocallabParams::LABGRIDL_CORR_MAX, - 0, 0, 0, 0, false); + 0, 0, 0, 0, 0, 0, false); merlucol->setValue(spot.merlucol); enaColorMask->set_active(spot.enaColorMask); CCmaskshape->setCurve(spot.CCmaskcurve); @@ -1342,7 +1342,7 @@ void LocallabColor::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pe labgrid->getParams(spot.labgridALow, spot.labgridBLow, spot.labgridAHigh, - spot.labgridBHigh, zerox, zeroy, zerox, zeroy); + spot.labgridBHigh, zerox, zeroy, zerox, zeroy, zerox, zeroy); spot.labgridALow *= LocallabParams::LABGRIDL_CORR_MAX; spot.labgridAHigh *= LocallabParams::LABGRIDL_CORR_MAX; spot.labgridBLow *= LocallabParams::LABGRIDL_CORR_MAX; @@ -1461,7 +1461,7 @@ void LocallabColor::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pe labgridmerg->getParams(spot.labgridALowmerg, spot.labgridBLowmerg, spot.labgridAHighmerg, - spot.labgridBHighmerg, zerox1, zeroy1, zerox1, zeroy1); + spot.labgridBHighmerg, zerox1, zeroy1, zerox1, zeroy1, zerox1, zeroy1); spot.labgridALowmerg *= LocallabParams::LABGRIDL_CORR_MAX; spot.labgridAHighmerg *= LocallabParams::LABGRIDL_CORR_MAX; spot.labgridBLowmerg *= LocallabParams::LABGRIDL_CORR_MAX; @@ -1508,7 +1508,7 @@ void LocallabColor::setDefaults(const rtengine::procparams::ProcParams* defParam labgrid->setDefault(defSpot.labgridALow / LocallabParams::LABGRIDL_CORR_MAX, defSpot.labgridBLow / LocallabParams::LABGRIDL_CORR_MAX, defSpot.labgridAHigh / LocallabParams::LABGRIDL_CORR_MAX, - defSpot.labgridBHigh / LocallabParams::LABGRIDL_CORR_MAX, 0, 0, 0, 0); + defSpot.labgridBHigh / LocallabParams::LABGRIDL_CORR_MAX, 0, 0, 0, 0, 0, 0); strengthgrid->setDefault((double) defSpot.strengthgrid); sensi->setDefault((double)defSpot.sensi); structcol->setDefault((double)defSpot.structcol); @@ -1524,7 +1524,7 @@ void LocallabColor::setDefaults(const rtengine::procparams::ProcParams* defParam labgridmerg->setDefault(defSpot.labgridALowmerg / LocallabParams::LABGRIDL_CORR_MAX, defSpot.labgridBLowmerg / LocallabParams::LABGRIDL_CORR_MAX, defSpot.labgridAHighmerg / LocallabParams::LABGRIDL_CORR_MAX, - defSpot.labgridBHighmerg / LocallabParams::LABGRIDL_CORR_MAX, 0, 0, 0, 0); + defSpot.labgridBHighmerg / LocallabParams::LABGRIDL_CORR_MAX, 0, 0, 0, 0, 0, 0); merlucol->setDefault(defSpot.merlucol); strumaskcol->setDefault(defSpot.strumaskcol); contcol->setDefault(defSpot.contcol); @@ -2002,7 +2002,7 @@ void LocallabColor::convertParamToNormal() labgridmerg->setParams(0, 0, defSpot.labgridAHighmerg / LocallabParams::LABGRIDL_CORR_MAX, defSpot.labgridBHighmerg / LocallabParams::LABGRIDL_CORR_MAX, - 0, 0, 0, 0, false); + 0, 0, 0, 0, 0, 0, false); merlucol->setValue(defSpot.merlucol); strumaskcol->setValue(defSpot.strumaskcol); toolcol->set_active(defSpot.toolcol); @@ -4014,16 +4014,16 @@ LocallabShadow::LocallabShadow(): // Shadow highlight specific widgets shMethod(Gtk::manage(new MyComboBoxText())), reparsh(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), - multipliersh([]() -> std::array + multipliersh([]() -> std::array { - std::array res = {}; + std::array res = {}; for (unsigned int i = 0; i < res.size(); ++i) { Glib::ustring ss = Glib::ustring::format(i); if (i == 0) { ss += Glib::ustring::compose(" (%1)", M("TP_LOCALLAB_LUMADARKEST")); - } else if (i == 4) { + } else if (i == 5) { ss += Glib::ustring::compose(" (%1)", M("TP_LOCALLAB_LUMAWHITESEST")); } @@ -4416,7 +4416,7 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para shMethod->set_active(1); } - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 6; i++) { multipliersh[i]->setValue((double)spot.multsh[i]); } recothress->setValue((double)spot.recothress); @@ -4486,7 +4486,7 @@ void LocallabShadow::write(rtengine::procparams::ProcParams* pp, ParamsEdited* p spot.shMethod = "tone"; } - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 6; i++) { spot.multsh[i] = multipliersh[i]->getIntValue(); } @@ -4535,7 +4535,7 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara const LocallabParams::LocallabSpot& defSpot = defParams->locallab.spots.at(index); // Set default values for adjuster widgets - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 6; i++) { multipliersh[i]->setDefault(defSpot.multsh[i]); } @@ -4573,15 +4573,16 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara void LocallabShadow::adjusterChanged(Adjuster* a, double newval) { if (isLocActivated && exp->getEnabled()) { - if (a == multipliersh[0] || a == multipliersh[1] || a == multipliersh[2] || a == multipliersh[3] || a == multipliersh[4]) { + if (a == multipliersh[0] || a == multipliersh[1] || a == multipliersh[2] || a == multipliersh[3] || a == multipliersh[4] || a == multipliersh[5]) { if (listener) { listener->panelChanged(EvlocallabEqualizersh, - Glib::ustring::compose("%1, %2, %3, %4, %5", + Glib::ustring::compose("%1, %2, %3, %4, %5, %6", Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[0]->getIntValue()), Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[1]->getIntValue()), Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[2]->getIntValue()), Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[3]->getIntValue()), - Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[4]->getIntValue())) + " (" + escapeHtmlChars(getSpotName()) + ")"); + Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[4]->getIntValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multipliersh[5]->getIntValue())) + " (" + escapeHtmlChars(getSpotName()) + ")"); } } diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index f99b3bc41..4a0e68564 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -55,7 +55,59 @@ protected: Normal = 1, Simple = 2 }; - + rtengine::ProcEvent Evlocallabnormcie; + rtengine::ProcEvent Evlocallabstrumaskcie; + rtengine::ProcEvent EvLocallabtoolcie; + rtengine::ProcEvent EvLocallabfftcieMask; + rtengine::ProcEvent Evlocallabcontcie; + rtengine::ProcEvent Evlocallabblurcie; + rtengine::ProcEvent Evlocallabhighmaskcie; + rtengine::ProcEvent Evlocallabshadmaskcie; + rtengine::ProcEvent Evlocallabsigmoidsenscie; + rtengine::ProcEvent EvlocallabLLmaskcieshapewav; + rtengine::ProcEvent EvlocallabcsThresholdcie; + rtengine::ProcEvent Evlocallabcomprcie; + rtengine::ProcEvent Evlocallabstrcielog; + rtengine::ProcEvent Evlocallabsatcie; + rtengine::ProcEvent Evlocallablogcieq; + rtengine::ProcEvent Evlocallabcomprcieth; + rtengine::ProcEvent EvlocallabHHhmaskcieshape; + rtengine::ProcEvent EvlocallabbwevMethod; + rtengine::ProcEvent Evlocallabgamjcie; + rtengine::ProcEvent Evlocallabslopjcie; + rtengine::ProcEvent Evlocallabmidtcie; + rtengine::ProcEvent Evlocallabslopesmo; + rtengine::ProcEvent Evlocallabsmoothcie; + rtengine::ProcEvent Evlocallabsmoothciemet; + rtengine::ProcEvent Evlocallabsigcie; + rtengine::ProcEvent Evlocallabillcie; + rtengine::ProcEvent Evlocallabprimcie; + rtengine::ProcEvent Evlocallabcatcie; + rtengine::ProcEvent Evlocallabwhitescie; + rtengine::ProcEvent Evlocallabblackscie; + rtengine::ProcEvent Evlocallabwhiteslog; + rtengine::ProcEvent Evlocallabblackslog; + rtengine::ProcEvent Evlocallabcomprlog; + rtengine::ProcEvent Evlocallabsatlog; + rtengine::ProcEvent Evlocallabstrelog; + rtengine::ProcEvent Evlocallabredxl; + rtengine::ProcEvent Evlocallabredyl; + rtengine::ProcEvent Evlocallabgrexl; + rtengine::ProcEvent Evlocallabgreyl; + rtengine::ProcEvent Evlocallabbluxl; + rtengine::ProcEvent Evlocallabbluyl; + rtengine::ProcEvent EvlocallabGridciexy; + rtengine::ProcEvent Evlocallabgamutcie; + rtengine::ProcEvent Evlocallabexpprecam; + rtengine::ProcEvent Evlocallablightsigqcie; + rtengine::ProcEvent Evlocallabcontsigqcie; + rtengine::ProcEvent Evlocallabrefi; + rtengine::ProcEvent Evlocallabshiftxl; + rtengine::ProcEvent Evlocallabshiftyl; + rtengine::ProcEvent Evlocallabanggradcie; + rtengine::ProcEvent Evlocallabstrgradcie; + rtengine::ProcEvent Evlocallabdetailciejz; + rtengine::ProcEvent EvlocallabenacieMaskall; // LocallabTool parameters bool needMode; bool isLocActivated; @@ -452,7 +504,7 @@ private: // Shadow highlight specific widgets MyComboBoxText* const shMethod; Adjuster* const reparsh; - const std::array multipliersh; + const std::array multipliersh; Adjuster* const detailSH; Adjuster* const tePivot; Adjuster* const highlights; @@ -1339,8 +1391,15 @@ private: Gtk::CheckButton* const ciecam; Gtk::ToggleButton* const autocompute; Gtk::Frame* const logPFrame; + Gtk::Frame* const logPFrame2; Adjuster* const blackEv; Adjuster* const whiteEv; + Adjuster* const whiteslog; + Adjuster* const blackslog; + Adjuster* const comprlog; + Adjuster* const strelog; + Gtk::CheckButton* const satlog; + Gtk::CheckButton* const fullimage; Gtk::Frame* const logFrame; Gtk::CheckButton* const Autogray; @@ -1395,7 +1454,7 @@ private: DiagonalCurveEditor* const LmaskshapeL; sigc::connection autoconn, ciecamconn, fullimageConn, AutograyConn; - sigc::connection surroundconn, sursourconn; + sigc::connection surroundconn, sursourconn, satlogconn; sigc::connection showmaskLMethodConn, enaLMaskConn; public: LocallabLog(); @@ -1409,6 +1468,7 @@ public: void surroundChanged(); void sursourChanged(); void setDefaultExpanderVisibility() override; + void satlogChanged(); void disableListener() override; void enableListener() override; @@ -1543,6 +1603,8 @@ private: Gtk::Box* const modeHBoxcam; Gtk::Box* const modeHBoxcie; Gtk::Frame* const cieFrame; + MyExpander* const expcamscene; + Gtk::CheckButton* const Autograycie; Adjuster* const sourceGraycie; Adjuster* const sourceabscie; @@ -1586,10 +1648,13 @@ private: Adjuster* const clarisoftjz; MyExpander* const expcam16; + MyExpander* const expcamviewing; Adjuster* const lightqcie; Adjuster* const contlcie; Adjuster* const contqcie; + Adjuster* const lightsigqcie; + Adjuster* const contsigqcie; Adjuster* const contthrescie; Gtk::Frame* const logjzFrame; Gtk::CheckButton* const logjz; @@ -1598,15 +1663,71 @@ private: Adjuster* const targetjz; Gtk::Frame* const bevwevFrame; Gtk::CheckButton* const forcebw; - + ToolParamBlock* const sigBox; Gtk::Frame* const sigmoidFrame; + Gtk::Frame* const sigmoidnormFrame; Gtk::CheckButton* const sigq; Adjuster* const sigmoidldacie; Adjuster* const sigmoidthcie; + Adjuster* const sigmoidsenscie; Adjuster* const sigmoidblcie; - Gtk::CheckButton* const sigmoidqjcie; + Gtk::Box* autocomprHBox; + Gtk::ToggleButton* const comprcieauto; + Gtk::CheckButton* const normcie; + Gtk::Box* const modeHBoxbwev; + MyComboBoxText* const bwevMethod; + Gtk::Frame* const logcieFrame; Gtk::CheckButton* const logcie; + ToolParamBlock* const comprBox; + Adjuster* const comprcie; + + Adjuster* const strcielog; + Gtk::CheckButton* const satcie; + Gtk::CheckButton* const logcieq; + Adjuster* const comprcieth; + MyExpander* const expprecam; + Adjuster* const gamjcie; + Adjuster* const slopjcie; + Adjuster* const midtcie; + Gtk::CheckButton* const smoothcie; + ToolParamBlock* const ciesmoothBox; + Gtk::Box* smoothBox; + MyComboBoxText* const smoothciemet; + Adjuster* const slopesmo; + + Adjuster* const whitescie; + Adjuster* const blackscie; + Gtk::Box* willBox; + MyComboBoxText* const illMethod; + Gtk::Box* wprimBox; + MyComboBoxText* const primMethod; + Gtk::Grid* primCoordGridl; + Gtk::Frame* trcFrame; + Gtk::Frame* smoothFrame; + Gtk::Frame* primillFrame; + ToolParamBlock* const redBox; + Adjuster* const redxl; + Adjuster* const redyl; + Adjuster* const grexl; + Adjuster* const greyl; + Adjuster* const bluxl; + Adjuster* const bluyl; + Adjuster* const refi; + + Gtk::Frame* const gridFramecie; + LabGrid* const labgridcie; + Gtk::Frame* const colorFramecie; + + Gtk::Box* catBox; + MyComboBoxText* const catMethod; + Gtk::Box* gamutcieBox; + Gtk::CheckButton* const gamutcie; + Adjuster* const shiftxl; + Adjuster* const shiftyl; + Gtk::Frame* const sigmoidjzFrame; + Gtk::Frame* const sigmoid2Frame; + Gtk::CheckButton* const sigcie; Gtk::CheckButton* const sigjz; Adjuster* const sigmoidldajzcie; Adjuster* const sigmoidthjzcie; @@ -1645,26 +1766,20 @@ private: Gtk::CheckButton* const chjzcie; Adjuster* const strsoftjzcie; -/* - Gtk::Frame* const ciezFrame; - Adjuster* const lightlzcam; - Adjuster* const lightqzcam; - Adjuster* const contlzcam; - Adjuster* const contqzcam; - Adjuster* const contthreszcam; - Adjuster* const colorflzcam; - Adjuster* const saturzcam; - Adjuster* const chromzcam; -*/ MyExpander* const expLcie; Gtk::Frame* const cie2Frame; Adjuster* const targetGraycie; Adjuster* const targabscie; Adjuster* const detailcie; + Adjuster* const detailciejz; Adjuster* const catadcie; MyComboBoxText* const surroundcie; Gtk::Box* const surrHBoxcie; + MyExpander* const expgradcie; + Adjuster* const strgradcie; + Adjuster* const anggradcie; + MyExpander* const exprecovcie; Gtk::Label* const maskusablecie; Gtk::Label* const maskunusablecie; @@ -1676,25 +1791,46 @@ private: MyExpander* const expmaskcie; MyComboBoxText* const showmaskcieMethod; Gtk::CheckButton* const enacieMask; + Gtk::CheckButton* const enacieMaskall; CurveEditorGroup* const maskcieCurveEditorG; FlatCurveEditor* const CCmaskcieshape; FlatCurveEditor* const LLmaskcieshape; FlatCurveEditor* const HHmaskcieshape; + Gtk::Frame* const struFramecie; + Adjuster* const strumaskcie; + Gtk::CheckButton* const toolcie; + Gtk::Frame* const blurFramecie; + Gtk::CheckButton* const fftcieMask; + Adjuster* const contcie; + Adjuster* const blurcie; + Adjuster* const blendmaskcie; Adjuster* const radmaskcie; Adjuster* const lapmaskcie; Adjuster* const chromaskcie; Adjuster* const gammaskcie; Adjuster* const slomaskcie; - + Adjuster* const highmaskcie; + Adjuster* const shadmaskcie; + CurveEditorGroup* const maskcieHCurveEditorG; + FlatCurveEditor* const HHhmaskcieshape; + CurveEditorGroup* const mask2cieCurveEditorG; DiagonalCurveEditor* const Lmaskcieshape; - - sigc::connection AutograycieConn, forcejzConn, forcebwConn, qtojConn, showmaskcieMethodConn, enacieMaskConn, jabcieConn, sursourcieconn, surroundcieconn, modecieconn, modecamconn, sigmoidqjcieconn, logcieconn, logjzconn, sigjzconn, sigqconn, chjzcieconn, toneMethodcieConn, toneMethodcieConn2; + Gtk::Frame* const wavFramecie; + CurveEditorGroup* const mask2cieCurveEditorGwav; + FlatCurveEditor* const LLmaskcieshapewav; + Gtk::Box* const quaHcieBox; + ThresholdAdjuster* const csThresholdcie; + int nextcomprciecount = 0; + + sigc::connection AutograycieConn, primMethodconn, illMethodconn, smoothciemetconn, catMethodconn, forcejzConn, forcebwConn, qtojConn, showmaskcieMethodConn, enacieMaskConn, enacieMaskallConn, jabcieConn, sursourcieconn, surroundcieconn, modecieconn, modecamconn, comprcieautoconn, normcieconn, logcieconn, satcieconn, logcieqconn,smoothcieconn, logjzconn, sigjzconn, sigqconn, chjzcieconn, toneMethodcieConn, toneMethodcieConn2, toolcieConn, bwevMethodConn, fftcieMaskConn, gamutcieconn, expprecamconn, sigcieconn; public: Locallabcie(); ~Locallabcie(); - + + void setListener(ToolPanelListener* tpl) override; + bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; @@ -1721,7 +1857,11 @@ public: void curveChanged(CurveEditor* ce) override; void toneMethodcieChanged(); void toneMethodcie2Changed(); + void bwevMethodChanged(); void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const float jz1); + void updatePrimloc(const float redx, const float redy, const float grex, const float grey, const float blux, const float bluy); + void updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y); + void updatesigloc(const float cont_sig, const float light_sig); private: void enabledChanged() override; @@ -1734,8 +1874,18 @@ private: void forcebwChanged(); void qtojChanged(); void jabcieChanged(); - void sigmoidqjcieChanged(); + void comprcieautoChanged(); + void normcieChanged(); + void gamutcieChanged(); + void illMethodChanged(); + void smoothciemetChanged(); + void primMethodChanged(); + void catMethodChanged(); void logcieChanged(); + void satcieChanged(); + void logcieqChanged(); + void smoothcieChanged(); + void sigcieChanged(); void logjzChanged(); void sigjzChanged(); void sigqChanged(); @@ -1744,6 +1894,23 @@ private: void updateMaskBackground(const double normChromar, const double normLumar, const double normHuer, const double normHuerjz) override; void showmaskcieMethodChanged(); void enacieMaskChanged(); + void enacieMaskallChanged(); + void enacieMaskallChanged2(); + void guijzczhz(); + void toolcieChanged(); + void fftcieMaskChanged(); + void expprecamChanged(); + + float nextrx; + float nextry; + float nextbx; + float nextby; + float nextgx; + float nextgy; + float nextwx; + float nextwy; + float nextmx; + float nextmy; }; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index b32ef5d6d..5417271ab 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -25,6 +25,8 @@ #include "locallab.h" #include "rtimage.h" #include "../rtengine/color.h" +#include "eventmapper.h" +#include "../rtengine/utils.h" #define MINNEIGH 0.1 #define MAXNEIGH 1500 @@ -141,7 +143,7 @@ LocallabTone::LocallabTone(): showmasktmMethod(Gtk::manage(new MyComboBoxText())), enatmMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), enatmMaskaft(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_AFTER_MASK")))), - // masktmCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), +// masktmCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), masktmCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), CCmasktmshape(static_cast(masktmCurveEditorG->addCurve(CT_Flat, "C", nullptr, false, false))), LLmasktmshape(static_cast(masktmCurveEditorG->addCurve(CT_Flat, "L", nullptr, false, false))), @@ -262,7 +264,7 @@ LocallabTone::LocallabTone(): tmBox3->pack_start(*lowthrest); tmBox3->pack_start(*higthrest); tmBox3->pack_start(*decayt); - // colBox3->pack_start(*invmaskc); + // colBox3->pack_start(*invmaskc); exprecovt->add(*tmBox3, false); pack_start(*exprecovt, false, false); @@ -568,6 +570,7 @@ void LocallabTone::adjusterChanged(Adjuster* a, double newval) } else if (a == decayt) { listener->panelChanged(Evlocallabdecayt, decayt->getTextValue() + spName); } + } } @@ -670,6 +673,7 @@ void LocallabTone::updateGUIToMode(const modeType new_type) expmasktm->show(); exprecovt->show(); decayt->hide(); + if (enatmMask->get_active()) { maskusablet->show(); maskunusablet->hide(); @@ -692,6 +696,7 @@ void LocallabTone::updateGUIToMode(const modeType new_type) slomasktm->show(); exprecovt->show(); decayt->show(); + if (enatmMask->get_active()) { maskusablet->show(); maskunusablet->hide(); @@ -717,7 +722,7 @@ void LocallabTone::updateMaskBackground(const double normChromar, const double n return false; } - ); + ); } void LocallabTone::equiltmChanged() @@ -742,7 +747,7 @@ void LocallabTone::showmasktmMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -834,7 +839,7 @@ LocallabRetinex::LocallabRetinex(): showmaskretiMethod(Gtk::manage(new MyComboBoxText())), enaretiMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), enaretiMasktmap(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_TM_MASK")))), - // maskretiCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), +// maskretiCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), maskretiCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), CCmaskretishape(static_cast(maskretiCurveEditorG->addCurve(CT_Flat, "C", nullptr, false, false))), LLmaskretishape(static_cast(maskretiCurveEditorG->addCurve(CT_Flat, "L", nullptr, false, false))), @@ -849,10 +854,10 @@ LocallabRetinex::LocallabRetinex(): Lmaskretishape(static_cast(mask2retiCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), inversret(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))) { - + auto m = ProcEventMapper::getInstance(); Evlocallabdehazeblack = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_DEHAZE_BLACK"); - + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -1005,9 +1010,9 @@ LocallabRetinex::LocallabRetinex(): deharetiBox->pack_start(*loglin); retiFrame->add(*deharetiBox); auxBox->add(*retiFrame); - // ToolParamBlock* const scopeBox = Gtk::manage(new ToolParamBlock()); - // scopeBox->pack_start(*sensih); - // auxBox->add(*scopeBox); +// ToolParamBlock* const scopeBox = Gtk::manage(new ToolParamBlock()); +// scopeBox->pack_start(*sensih); +// auxBox->add(*scopeBox); pack_start(*auxBox); ToolParamBlock* const retiBox = Gtk::manage(new ToolParamBlock()); retiBox->pack_start(*retinexMethod); @@ -1019,7 +1024,7 @@ LocallabRetinex::LocallabRetinex(): retiBox->pack_start(*limd); retiBox->pack_start(*offs); ToolParamBlock* const toolretiBox = Gtk::manage(new ToolParamBlock()); - // toolretiBox->pack_start(*chrrt); + // toolretiBox->pack_start(*chrrt); toolretiBox->pack_start(*darkness); toolretiBox->pack_start(*lightnessreti); toolretiBox->pack_start(*cliptm); @@ -1038,7 +1043,7 @@ LocallabRetinex::LocallabRetinex(): reBox3->pack_start(*lowthresr); reBox3->pack_start(*higthresr); reBox3->pack_start(*decayr); - // colBox3->pack_start(*invmaskc); + // colBox3->pack_start(*invmaskc); exprecovr->add(*reBox3, false); ToolParamBlock* const maskretiBox = Gtk::manage(new ToolParamBlock()); @@ -1095,7 +1100,7 @@ void LocallabRetinex::updateMinMax(const double cdma, const double cdmin, const return false; } - ); + ); } bool LocallabRetinex::isMaskViewActive() @@ -1275,7 +1280,7 @@ void LocallabRetinex::read(const rtengine::procparams::ProcParams* pp, const Par limd->setValue(spot.limd); offs->setValue(spot.offs); chrrt->setValue(0.); - // chrrt->setValue(spot.chrrt); + // chrrt->setValue(spot.chrrt); darkness->setValue(spot.darkness); lightnessreti->setValue(spot.lightnessreti); cliptm->setValue(spot.cliptm); @@ -1792,6 +1797,7 @@ void LocallabRetinex::updateGUIToMode(const modeType new_type) retitoolFrame->show(); exprecovr->show(); decayr->show(); + if (enaretiMask->get_active()) { maskusabler->show(); maskunusabler->hide(); @@ -1817,7 +1823,7 @@ void LocallabRetinex::updateMaskBackground(const double normChromar, const doubl return false; } - ); + ); } void LocallabRetinex::loglinChanged() @@ -1882,7 +1888,7 @@ void LocallabRetinex::showmaskretiMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -2357,7 +2363,7 @@ void LocallabSharp::showmasksharMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -2768,7 +2774,7 @@ LocallabContrast::LocallabContrast(): ToolParamBlock* const coBox = Gtk::manage(new ToolParamBlock()); coBox->pack_start(*sigmalc); coBox->pack_start(*LocalcurveEditorwav, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor - // coBox->pack_start(*csThreshold); + // coBox->pack_start(*csThreshold); contFrame->add(*coBox); pack_start(*contFrame); // pack_start(*levelwav); @@ -2906,7 +2912,7 @@ LocallabContrast::LocallabContrast(): wwBox3->pack_start(*lowthresw); wwBox3->pack_start(*higthresw); wwBox3->pack_start(*decayw); - // colBox3->pack_start(*invmaskc); + // colBox3->pack_start(*invmaskc); exprecovw->add(*wwBox3, false); pack_start(*exprecovw, false, false); @@ -4080,6 +4086,7 @@ void LocallabContrast::updateGUIToMode(const modeType new_type) expmasklc->show(); exprecovw->show(); decayw->hide(); + if (enalcMask->get_active()) { maskusablew->show(); maskunusablew->hide(); @@ -4088,6 +4095,7 @@ void LocallabContrast::updateGUIToMode(const modeType new_type) maskusablew->hide(); maskunusablew->show(); } + gamlc->hide(); break; @@ -4110,6 +4118,7 @@ void LocallabContrast::updateGUIToMode(const modeType new_type) expmasklc->show(); exprecovw->show(); decayw->show(); + if (enalcMask->get_active()) { maskusablew->show(); maskunusablew->hide(); @@ -4136,7 +4145,7 @@ void LocallabContrast::updateMaskBackground(const double normChromar, const doub return false; } - ); + ); } void LocallabContrast::localcontMethodChanged() @@ -4335,7 +4344,7 @@ void LocallabContrast::showmasklcMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -4384,6 +4393,7 @@ void LocallabContrast::updateContrastGUI1() expcontrastpyr->hide(); expcontrastpyr2->hide(); gamlc->hide(); + if (mode == Expert) { // Keep widget hidden in Normal and Simple mode fftwlc->show(); } @@ -4438,7 +4448,7 @@ LocallabCBDL::LocallabCBDL(): // CBDL specific widgets levFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LEVFRA")))), multiplier([]() -> std::array - { +{ std::array res = {}; for (unsigned int i = 0; i < res.size(); ++i) { @@ -4454,41 +4464,41 @@ LocallabCBDL::LocallabCBDL(): } return res; - } - ()), - chromacbdl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMACBDL"), 0., 1.5, 0.01, 0.))), - threshold(Gtk::manage(new Adjuster(M("TP_DIRPYREQUALIZER_THRESHOLD"), 0, 1., 0.01, 0.2))), - clarityml(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CLARITYML"), 0.1, 100., 0.1, 0.1))), - contresid(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTRESID"), -100, 100, 1, 0))), - softradiuscb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 0.))), - sensicb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), - exprecovcb(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), - maskusablecb(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), - maskunusablecb(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), - recothrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKRECOTHRES"), 1., 2., 0.01, 1.))), - lowthrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKLCTHRLOW"), 1., 80., 0.5, 12.))), - higthrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKLCTHR"), 20., 99., 0.5, 85.))), - decaycb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKDDECAY"), 0.5, 4., 0.1, 2.))), - expmaskcb(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWCB")))), - showmaskcbMethod(Gtk::manage(new MyComboBoxText())), - enacbMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), - // maskcbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), - maskcbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), - CCmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "C", nullptr, false, false))), - LLmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "L", nullptr, false, false))), - HHmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "LC(h)", nullptr, false, true))), - blendmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKCOL"), -100, 100, 1, 0))), - radmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_RADMASKCOL"), 0.0, 100.0, 0.1, 0.))), - lapmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LAPMASKCOL"), 0.0, 100.0, 0.1, 0.))), - chromaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMASKCOL"), -100.0, 100.0, 0.1, 0.))), - gammaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMMASKCOL"), 0.25, 4.0, 0.01, 1.))), - slomaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOMASKCOL"), 0.0, 15.0, 0.1, 0.))), - mask2cbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), - Lmaskcbshape(static_cast(mask2cbCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), +} +()), +chromacbdl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMACBDL"), 0., 1.5, 0.01, 0.))), +threshold(Gtk::manage(new Adjuster(M("TP_DIRPYREQUALIZER_THRESHOLD"), 0, 1., 0.01, 0.2))), +clarityml(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CLARITYML"), 0.1, 100., 0.1, 0.1))), +contresid(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTRESID"), -100, 100, 1, 0))), +softradiuscb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 0.))), +sensicb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), +exprecovcb(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), +maskusablecb(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), +maskunusablecb(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), +recothrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKRECOTHRES"), 1., 2., 0.01, 1.))), +lowthrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKLCTHRLOW"), 1., 80., 0.5, 12.))), +higthrescb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKLCTHR"), 20., 99., 0.5, 85.))), +decaycb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKDDECAY"), 0.5, 4., 0.1, 2.))), +expmaskcb(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWCB")))), +showmaskcbMethod(Gtk::manage(new MyComboBoxText())), +enacbMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), +// maskcbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), +maskcbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), +CCmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "C", nullptr, false, false))), +LLmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "L", nullptr, false, false))), +HHmaskcbshape(static_cast(maskcbCurveEditorG->addCurve(CT_Flat, "LC(h)", nullptr, false, true))), +blendmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKCOL"), -100, 100, 1, 0))), +radmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_RADMASKCOL"), 0.0, 100.0, 0.1, 0.))), +lapmaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LAPMASKCOL"), 0.0, 100.0, 0.1, 0.))), +chromaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMASKCOL"), -100.0, 100.0, 0.1, 0.))), +gammaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMMASKCOL"), 0.25, 4.0, 0.01, 1.))), +slomaskcb(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOMASKCOL"), 0.0, 15.0, 0.1, 0.))), +mask2cbCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), +Lmaskcbshape(static_cast(mask2cbCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), - lumacontrastMinusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS")))), - lumaneutralButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMANEUTRAL")))), - lumacontrastPlusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS")))) +lumacontrastMinusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS")))), +lumaneutralButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMANEUTRAL")))), +lumacontrastPlusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS")))) { set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -4609,7 +4619,7 @@ LocallabCBDL::LocallabCBDL(): cbBox3->pack_start(*lowthrescb); cbBox3->pack_start(*higthrescb); cbBox3->pack_start(*decaycb); - // colBox3->pack_start(*invmaskc); + // colBox3->pack_start(*invmaskc); exprecovcb->add(*cbBox3, false); pack_start(*exprecovcb, false, false); @@ -5114,6 +5124,7 @@ void LocallabCBDL::updateGUIToMode(const modeType new_type) expmaskcb->show(); exprecovcb->show(); decaycb->hide(); + if (enacbMask->get_active()) { maskusablecb->show(); maskunusablecb->hide(); @@ -5132,6 +5143,7 @@ void LocallabCBDL::updateGUIToMode(const modeType new_type) lapmaskcb->show(); exprecovcb->show(); decaycb->show(); + if (enacbMask->get_active()) { maskusablecb->show(); maskunusablecb->hide(); @@ -5157,7 +5169,7 @@ void LocallabCBDL::updateMaskBackground(const double normChromar, const double n return false; } - ); + ); } void LocallabCBDL::showmaskcbMethodChanged() @@ -5167,7 +5179,7 @@ void LocallabCBDL::showmaskcbMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -5234,18 +5246,25 @@ LocallabLog::LocallabLog(): LocallabTool(this, M("TP_LOCALLAB_LOG_TOOLNAME"), M("TP_LOCALLAB_LOG"), false), // Log encoding specific widgets - repar(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), + repar(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 0.5, 100.0))), ciecam(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_CIEC")))), autocompute(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_LOGAUTO")))), logPFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGPFRA")))), - blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), - whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0., 32.0, 0.1, 10.0))), + logPFrame2(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGPFRA2")))), + blackEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.00, 0.00, 0.01, -5.00))), + whiteEv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0.00, 32.00, 0.01, 10.00))), + whiteslog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGWHITESCIE"), -100, 100, 1, 0))), + blackslog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGBLACKSSCIE"), -100, 100, 1, 0))), + comprlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COMPRCIE"), 0., 1., 0.01, 0.4))), + strelog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRENGTHCIELOG"), 0., 100., 0.5, 100.))), + satlog(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SATCIE")))), + fullimage(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FULLIMAGE")))), logFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA")))), Autogray(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAY")))), sourceGray(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 10.0))), sourceabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 2000.0))), - sursour(Gtk::manage (new MyComboBoxText ())), + sursour(Gtk::manage(new MyComboBoxText())), surHBox(Gtk::manage(new Gtk::Box())), log1Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG1FRA")))), log2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), @@ -5264,7 +5283,7 @@ LocallabLog::LocallabLog(): //CurveEditorL(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_LOGCONTQ"))), //LshapeL(static_cast(CurveEditorL->addCurve(CT_Diagonal, "Q(Q)"))), targabs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), - surround(Gtk::manage (new MyComboBoxText ())), + surround(Gtk::manage(new MyComboBoxText())), surrHBox(Gtk::manage(new Gtk::Box())), baselog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BASELOG"), 1.3, 3., 0.05, 2.))),//, Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), exprecovl(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), @@ -5282,7 +5301,7 @@ LocallabLog::LocallabLog(): expmaskL(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWC")))), showmaskLMethod(Gtk::manage(new MyComboBoxText())), enaLMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), - // maskCurveEditorL(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASKCOL"))), +// maskCurveEditorL(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASKCOL"))), maskCurveEditorL(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), CCmaskshapeL(static_cast(maskCurveEditorL->addCurve(CT_Flat, "C", nullptr, false, false))), LLmaskshapeL(static_cast(maskCurveEditorL->addCurve(CT_Flat, "L", nullptr, false, false))), @@ -5295,6 +5314,13 @@ LocallabLog::LocallabLog(): { + auto m = ProcEventMapper::getInstance(); + Evlocallabwhiteslog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_WHITES"); + Evlocallabblackslog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_BLACKS"); + Evlocallabcomprlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_COMPR"); + Evlocallabstrelog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_STRE"); + Evlocallabsatlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_SAT"); + set_orientation(Gtk::ORIENTATION_VERTICAL); // Parameter Log encoding specific widgets @@ -5307,9 +5333,16 @@ LocallabLog::LocallabLog(): whiteEv->setLogScale(16, 0); whiteEv->setAdjusterListener(this); + + whiteslog->setAdjusterListener(this); + blackslog->setAdjusterListener(this); + comprlog->setAdjusterListener(this); + strelog->setAdjusterListener(this); + ciecamconn = ciecam->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::ciecamChanged)); fullimageConn = fullimage->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::fullimageChanged)); + satlogconn = satlog->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::satlogChanged)); AutograyConn = Autogray->signal_toggled().connect(sigc::mem_fun(*this, &LocallabLog::AutograyChanged)); @@ -5368,30 +5401,31 @@ LocallabLog::LocallabLog(): anglog->setAdjusterListener(this); - surHBox->set_spacing (2); - surHBox->set_tooltip_markup (M ("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); - Gtk::Label* surLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); - surHBox->pack_start (*surLabel, Gtk::PACK_SHRINK); - sursour->append (M ("TP_COLORAPP_SURROUND_AVER")); - sursour->append (M ("TP_COLORAPP_SURROUND_DIM")); - sursour->append (M ("TP_COLORAPP_SURROUND_DARK")); - sursour->set_active (0); - surHBox->pack_start (*sursour); - sursourconn = sursour->signal_changed().connect ( sigc::mem_fun (*this, &LocallabLog::sursourChanged) ); + surHBox->set_spacing(2); + surHBox->set_tooltip_markup(M("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); + Gtk::Label* surLabel = Gtk::manage(new Gtk::Label(M("TP_COLORAPP_SURROUND") + ":")); + surHBox->pack_start(*surLabel, Gtk::PACK_SHRINK); + sursour->append(M("TP_COLORAPP_SURROUND_AVER")); + sursour->append(M("TP_COLORAPP_SURROUND_DIM")); + sursour->append(M("TP_COLORAPP_SURROUND_DARK")); + sursour->append(M("TP_COLORAPP_SURROUND_EXDARK")); + sursour->set_active(0); + surHBox->pack_start(*sursour); + sursourconn = sursour->signal_changed().connect(sigc::mem_fun(*this, &LocallabLog::sursourChanged)); - surrHBox->set_spacing (2); - surrHBox->set_tooltip_markup (M ("TP_COLORAPP_SURROUND_TOOLTIP")); - Gtk::Label* surrLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); - surrHBox->pack_start (*surrLabel, Gtk::PACK_SHRINK); - surround->append (M ("TP_COLORAPP_SURROUND_AVER")); - surround->append (M ("TP_COLORAPP_SURROUND_DIM")); - surround->append (M ("TP_COLORAPP_SURROUND_DARK")); - surround->append (M ("TP_COLORAPP_SURROUND_EXDARK")); - surround->set_active (0); - surrHBox->pack_start (*surround); - surroundconn = surround->signal_changed().connect ( sigc::mem_fun (*this, &LocallabLog::surroundChanged) ); + surrHBox->set_spacing(2); + surrHBox->set_tooltip_markup(M("TP_COLORAPP_SURROUND_TOOLTIP")); + Gtk::Label* surrLabel = Gtk::manage(new Gtk::Label(M("TP_COLORAPP_SURROUND") + ":")); + surrHBox->pack_start(*surrLabel, Gtk::PACK_SHRINK); + surround->append(M("TP_COLORAPP_SURROUND_AVER")); + surround->append(M("TP_COLORAPP_SURROUND_DIM")); + surround->append(M("TP_COLORAPP_SURROUND_DARK")); + surround->append(M("TP_COLORAPP_SURROUND_EXDARK")); + surround->set_active(0); + surrHBox->pack_start(*surround); + surroundconn = surround->signal_changed().connect(sigc::mem_fun(*this, &LocallabLog::surroundChanged)); setExpandAlignProperties(expmaskL, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -5441,11 +5475,21 @@ LocallabLog::LocallabLog(): pack_start(*repar); pack_start(*ciecam); logPFrame->set_label_align(0.025, 0.5); + logPFrame2->set_label_align(0.025, 0.5); ToolParamBlock* const logPBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const logPBox2 = Gtk::manage(new ToolParamBlock()); logPBox->pack_start(*autocompute); logPBox->pack_start(*blackEv); logPBox->pack_start(*whiteEv); + logPBox->pack_start(*whiteslog); + logPBox->pack_start(*blackslog); + logPBox2->pack_start(*comprlog); + // logPBox2->pack_start(*strelog); + logPBox2->pack_start(*satlog); + logPFrame2->add(*logPBox2); + logPBox->pack_start(*logPFrame2); logPBox->pack_start(*fullimage); + logPFrame->add(*logPBox); pack_start(*logPFrame); // Gtk::Frame* const logFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA"))); @@ -5454,7 +5498,7 @@ LocallabLog::LocallabLog(): logFBox->pack_start(*Autogray); logFBox->pack_start(*sourceGray); logFBox->pack_start(*sourceabs); - logFBox->pack_start (*surHBox); + logFBox->pack_start(*surHBox); // logFBox->pack_start(*baselog); logFrame->add(*logFBox); pack_start(*logFrame); @@ -5483,7 +5527,7 @@ LocallabLog::LocallabLog(): logP2Box->pack_start(*targetGray); logP2Box->pack_start(*targabs); logP2Box->pack_start(*catad); - logP2Box->pack_start (*surrHBox); + logP2Box->pack_start(*surrHBox); ToolParamBlock* const logBox3 = Gtk::manage(new ToolParamBlock()); logBox3->pack_start(*maskusablel, Gtk::PACK_SHRINK, 0); logBox3->pack_start(*maskunusablel, Gtk::PACK_SHRINK, 0); @@ -5491,7 +5535,7 @@ LocallabLog::LocallabLog(): logBox3->pack_start(*lowthresl); logBox3->pack_start(*higthresl); logBox3->pack_start(*decayl); - // colBox3->pack_start(*invmaskc); + // colBox3->pack_start(*invmaskc); exprecovl->add(*logBox3, false); ToolParamBlock* const logP3Box = Gtk::manage(new ToolParamBlock()); @@ -5513,7 +5557,7 @@ LocallabLog::LocallabLog(): // pack_start(*sensilog); pack_start(*expmaskL, false, false); - // Gtk::Frame* const gradlogFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA"))); +// Gtk::Frame* const gradlogFrame = Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA"))); gradlogFrame->set_label_align(0.025, 0.5); ToolParamBlock* const gradlogBox = Gtk::manage(new ToolParamBlock()); gradlogBox->pack_start(*strlog); @@ -5550,11 +5594,15 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) log2Frame->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); autocompute->set_tooltip_text(M("TP_LOCALLAB_LOGAUTO_TOOLTIP")); Autogray->set_tooltip_text(M("TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP")); - // blackEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); - // whiteEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); + // blackEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); + // whiteEv->set_tooltip_text(M("TP_LOCALLAB_LOGBLACKWHEV_TOOLTIP")); exprecovl->set_tooltip_markup(M("TP_LOCALLAB_MASKRELOG_TOOLTIP")); blackEv->set_tooltip_text(""); whiteEv->set_tooltip_text(""); + whiteslog->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP")); + blackslog->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP")); + comprlog->set_tooltip_text(M("TP_LOCALLAB_COMPRLOG_TOOLTIP")); + sourceGray->set_tooltip_text(M("TP_LOCALLAB_JZLOGYBOUT_TOOLTIP")); sourceabs->set_tooltip_text(M("TP_COLORAPP_ADAPSCEN_TOOLTIP")); targabs->set_tooltip_text(M("TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP")); @@ -5634,6 +5682,9 @@ void LocallabLog::updateAdviceTooltips(const bool showTooltips) decayl->set_tooltip_text(""); lowthresl->set_tooltip_text(""); higthresl->set_tooltip_text(""); + whiteslog->set_tooltip_text(""); + blackslog->set_tooltip_text(""); + comprlog->set_tooltip_text(""); } } @@ -5645,9 +5696,10 @@ void LocallabLog::disableListener() autoconn.block(true); fullimageConn.block(true); ciecamconn.block(true); + satlogconn.block(true); enaLMaskConn.block(true); - surroundconn.block (true); - sursourconn.block (true); + surroundconn.block(true); + sursourconn.block(true); AutograyConn.block(true); showmaskLMethodConn.block(true); } @@ -5659,9 +5711,10 @@ void LocallabLog::enableListener() autoconn.block(false); fullimageConn.block(false); ciecamconn.block(false); + satlogconn.block(false); enaLMaskConn.block(false); - surroundconn.block (false); - sursourconn.block (false); + surroundconn.block(false); + sursourconn.block(false); AutograyConn.block(false); showmaskLMethodConn.block(false); } @@ -5706,34 +5759,43 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE repar->setValue(spot.repar); whiteEv->setValue(spot.whiteEv); -/* if(whiteEv->getValue() < 1.5){ - whiteEv->setValue(1.5); - } -*/ + whiteslog->setValue(spot.whiteslog); + blackslog->setValue(spot.blackslog); + comprlog->setValue(spot.comprlog); + strelog->setValue(spot.strelog); + + /* if(whiteEv->getValue() < 1.5){ + whiteEv->setValue(1.5); + } + */ if (spot.sursour == "Average") { - sursour->set_active (0); + sursour->set_active(0); } else if (spot.sursour == "Dim") { - sursour->set_active (1); + sursour->set_active(1); } else if (spot.sursour == "Dark") { - sursour->set_active (2); + sursour->set_active(2); + } else if (spot.sursour == "exDark") { + sursour->set_active(3); } if (spot.surround == "Average") { - surround->set_active (0); + surround->set_active(0); } else if (spot.surround == "Dim") { - surround->set_active (1); + surround->set_active(1); } else if (spot.surround == "Dark") { - surround->set_active (2); + surround->set_active(2); } else if (spot.surround == "ExtremelyDark") { - surround->set_active (3); + surround->set_active(3); } + recothresl->setValue((double)spot.recothresl); lowthresl->setValue((double)spot.lowthresl); higthresl->setValue((double)spot.higthresl); decayl->setValue((double)spot.decayl); ciecam->set_active(spot.ciecam); + satlog->set_active(spot.satlog); fullimage->set_active(spot.fullimage); Autogray->set_active(spot.Autogray); sourceGray->setValue(spot.sourceGray); @@ -5795,8 +5857,13 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.repar = repar->getValue(); spot.blackEv = blackEv->getValue(); spot.whiteEv = whiteEv->getValue(); + spot.whiteslog = whiteslog->getIntValue(); + spot.blackslog = blackslog->getIntValue(); + spot.comprlog = comprlog->getValue(); + spot.strelog = strelog->getValue(); spot.fullimage = fullimage->get_active(); spot.ciecam = ciecam->get_active(); + spot.satlog = satlog->get_active(); spot.Autogray = Autogray->get_active(); spot.sourceGray = sourceGray->getValue(); spot.sourceabs = sourceabs->getValue(); @@ -5837,6 +5904,8 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.sursour = "Dim"; } else if (sursour->get_active_row_number() == 2) { spot.sursour = "Dark"; + } else if (sursour->get_active_row_number() == 3) { + spot.sursour = "exDark"; } if (surround->get_active_row_number() == 0) { @@ -5887,12 +5956,12 @@ void LocallabLog::updateGUIToMode(const modeType new_type) case Simple: // Expert and Normal mode widgets are hidden in Simple mode ciecam->hide(); - ciecam->set_active(false); + ciecam->set_active(true); sourceabs->hide(); targabs->hide(); saturl->hide(); chroml->hide(); - contl->hide(); + contl->show(); contthres->hide(); lightl->hide(); lightq->hide(); @@ -5924,13 +5993,14 @@ void LocallabLog::updateGUIToMode(const modeType new_type) lightq->show(); contl->show(); contthres->show(); - contq->show(); + contq->hide(); colorfl->show(); surrHBox->show(); expL->hide(); surHBox->hide(); expmaskL->show(); gradlogFrame->show(); + if (enaLMask->get_active()) { maskusablel->show(); maskunusablel->hide(); @@ -5965,6 +6035,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) expmaskL->show(); gradlogFrame->show(); surHBox->show(); + if (enaLMask->get_active()) { maskusablel->show(); maskunusablel->hide(); @@ -5973,6 +6044,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) maskusablel->hide(); maskunusablel->show(); } + exprecovl->show(); decayl->show(); @@ -6036,7 +6108,7 @@ void LocallabLog::showmaskLMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -6096,6 +6168,10 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, repar->setDefault(defSpot.repar); blackEv->setDefault(defSpot.blackEv); whiteEv->setDefault(defSpot.whiteEv); + whiteslog->setDefault(defSpot.whiteslog); + blackslog->setDefault(defSpot.blackslog); + comprlog->setDefault(defSpot.comprlog); + strelog->setDefault(defSpot.strelog); sourceGray->setDefault(defSpot.sourceGray); sourceabs->setDefault(defSpot.sourceabs); targabs->setDefault(defSpot.targabs); @@ -6152,6 +6228,34 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == whiteslog) { + if (listener) { + listener->panelChanged(Evlocallabwhiteslog, + whiteslog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == blackslog) { + if (listener) { + listener->panelChanged(Evlocallabblackslog, + blackslog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == comprlog) { + if (listener) { + listener->panelChanged(Evlocallabcomprlog, + comprlog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == strelog) { + if (listener) { + listener->panelChanged(Evlocallabstrelog, + strelog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == sourceGray) { if (listener) { listener->panelChanged(EvlocallabsourceGray, @@ -6352,9 +6456,9 @@ void LocallabLog::updateAutocompute(const float blackev, const float whiteev, co enableListener(); - return false; + return false; } - ); + ); } } @@ -6439,7 +6543,7 @@ void LocallabLog::ciecamChanged() catad->hide(); surrHBox->hide(); } -*/ + */ if (isLocActivated && exp->getEnabled()) { if (listener) { if (ciecam->get_active()) { @@ -6453,6 +6557,21 @@ void LocallabLog::ciecamChanged() } } +void LocallabLog::satlogChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (satlog->get_active()) { + listener->panelChanged(Evlocallabsatlog, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsatlog, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + void LocallabLog::fullimageChanged() { @@ -6483,7 +6602,7 @@ void LocallabLog::updateMaskBackground(const double normChromar, const double no return false; } - ); + ); } @@ -6537,6 +6656,9 @@ void LocallabLog::updateLogGUI() blackEv->set_sensitive(false); whiteEv->set_sensitive(false); sourceGray->set_sensitive(false); + blackslog->set_sensitive(true); + whiteslog->set_sensitive(true); + if (mode == Expert || mode == Normal) { sourceabs->set_sensitive(false); } else { @@ -6546,15 +6668,19 @@ void LocallabLog::updateLogGUI() blackEv->set_sensitive(true); whiteEv->set_sensitive(true); sourceGray->set_sensitive(true); - if (mode == Expert || mode == Normal){ + blackslog->set_sensitive(false); + whiteslog->set_sensitive(false); + + if (mode == Expert || mode == Normal) { sourceabs->set_sensitive(true); } else { sourceabs->hide(); } } - if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode - exprecovl->show(); - } + + if (mode == Expert || mode == Normal) { // Keep widget hidden in Simple mode + exprecovl->show(); + } } @@ -7316,7 +7442,7 @@ void LocallabMask::updateMaskBackground(const double normChromar, const double n return false; } - ); + ); } void LocallabMask::showmask_MethodChanged() @@ -7326,7 +7452,7 @@ void LocallabMask::showmask_MethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -7401,16 +7527,17 @@ Locallabcie::Locallabcie(): sensicie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), reparcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), jabcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JAB")))), - modecam(Gtk::manage (new MyComboBoxText ())), - modecie(Gtk::manage (new MyComboBoxText ())), + modecam(Gtk::manage(new MyComboBoxText())), + modecie(Gtk::manage(new MyComboBoxText())), jzFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_JZFRA")))), modeHBoxcam(Gtk::manage(new Gtk::Box())), modeHBoxcie(Gtk::manage(new Gtk::Box())), cieFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGFRA")))), + expcamscene(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), Autograycie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_AUTOGRAYCIE")))), sourceGraycie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_GRAY"), 1.0, 100.0, 0.1, 18.0))), sourceabscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 2000.0))), - sursourcie(Gtk::manage (new MyComboBoxText ())), + sursourcie(Gtk::manage(new MyComboBoxText())), surHBoxcie(Gtk::manage(new Gtk::Box())), cie1Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG1FRA")))), cie1lightFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_CIELIGHTFRA")))), @@ -7426,7 +7553,7 @@ Locallabcie::Locallabcie(): adapjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZADAP"), 1., 10., 0.05, 4.))), jz100(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZ100"), 0.10, 0.90, 0.01, 0.25))), pqremap(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZPQREMAP"), 100., 10000., 0.1, 120.))), - pqremapcam16(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CAM16PQREMAP"), 100., 10000., 0.1, 100.))), + pqremapcam16(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CAM16PQREMAP"), 100., 10000., 1., 100.))), forcejz(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JZFORCE")))), expjz(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), jzshFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_JZSHFRA")))), @@ -7447,27 +7574,87 @@ Locallabcie::Locallabcie(): clarisoftjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 0.))), expcam16(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), + expcamviewing(Gtk::manage(new MyExpander(false, Gtk::manage(new Gtk::Box())))), lightqcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTQ"), -100., 100., 0.05, 0.))), contlcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTL"), -100., 100., 0.5, 0.))), contqcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONQL"), -100., 100., 0.5, 0.))), + lightsigqcie(Gtk::manage(new Adjuster(M(""), -100., 100., 0.5, 0.))), + contsigqcie(Gtk::manage(new Adjuster(M(""), -100., 100., 0.5, 0.))), + contthrescie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTHRES"), -1., 1., 0.01, 0.))), logjzFrame(Gtk::manage(new Gtk::Frame())), logjz(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JZLOG")))), - blackEvjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.0, 0.0, 0.1, -5.0))), - whiteEvjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0., 32.0, 0.1, 10.0))), + blackEvjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLACK_EV"), -16.00, 0.00, 0.01, -5.00))), + whiteEvjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_WHITE_EV"), 0.00, 32.000, 0.01, 10.00))), targetjz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZTARGET_EV"), 4., 80.0, 0.1, 18.0))), bevwevFrame(Gtk::manage(new Gtk::Frame())), forcebw(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_BWFORCE")))), - + sigBox(Gtk::manage(new ToolParamBlock())), sigmoidFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGFRA")))), + sigmoidnormFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGNORM")))), sigq(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGFRA")))), sigmoidldacie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDLAMBDA"), 0.0, 1., 0.01, 0.5))), - sigmoidthcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), - sigmoidblcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDBL"), 0.5, 1.5, 0.01, 1.))), - sigmoidqjcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGMOIDQJ")))), + sigmoidthcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1.2, Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), + sigmoidsenscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDSENSI"), 0.1, 1.5, 0.01, 0.9))), + sigmoidblcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDBL"), 0.05, 1., 0.01, 0.75))), + autocomprHBox(Gtk::manage(new Gtk::Box())), + comprcieauto(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_SIGMOIDLOGAUTO")))), + normcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGMOIDNORMCIE")))), + modeHBoxbwev(Gtk::manage(new Gtk::Box())), + bwevMethod(Gtk::manage(new MyComboBoxText())), + logcieFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOGCIE")))), logcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LOGCIE")))), + comprBox(Gtk::manage(new ToolParamBlock())), + comprcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COMPRCIE"), 0., 1., 0.01, 0.4))), + strcielog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRENGTHCIELOG"), 0., 100., 0.5, 80.))), + satcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SATCIE")))), + logcieq(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_LOGCIEQ")))), + comprcieth(Gtk::manage(new Adjuster(M("TP_LOCALLAB_COMPRCIETH"), 0., 25., 0.01, 6.))), + + expprecam(Gtk::manage(new MyExpander(true, Gtk::manage(new Gtk::Box())))), + + gamjcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGGAMJCIE"), 0.7, 10., 0.01, 2.4))), + slopjcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGSLOPJCIE"), 0., 500., 0.01, 12.923))), + midtcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MIDTCIE"), -100, 100, 1, 0))), + smoothcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SMOOTHCIE_SCA")))), + ciesmoothBox(Gtk::manage(new ToolParamBlock())), + smoothBox(Gtk::manage(new Gtk::Box())), + smoothciemet(Gtk::manage(new MyComboBoxText())), + slopesmo(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTH"), 0.6, 1.6, 0.01, 1.))), + whitescie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGWHITESCIE"), -100, 100, 1, 0))), + blackscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGBLACKSSCIE"), -100, 100, 1, 0))), + willBox(Gtk::manage(new Gtk::Box())), + illMethod(Gtk::manage(new MyComboBoxText())), + wprimBox(Gtk::manage(new Gtk::Box())), + primMethod(Gtk::manage(new MyComboBoxText())), + primCoordGridl(Gtk::manage(new Gtk::Grid())), + trcFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_TRCFRAME")))), + smoothFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_CIE_SMOOTHFRAME")))), + primillFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_PRIMILLFRAME")))), + redBox(Gtk::manage(new ToolParamBlock())), + redxl(Gtk::manage(new Adjuster(M("TC_PRIM_REDX"), 0.41, 1.0, 0.0001, 0.7347))), + redyl(Gtk::manage(new Adjuster(M("TC_PRIM_REDY"), 0.0, 0.70, 0.0001, 0.2653))), + grexl(Gtk::manage(new Adjuster(M("TC_PRIM_GREX"), -0.1, 0.4, 0.0001, 0.1596))), + greyl(Gtk::manage(new Adjuster(M("TC_PRIM_GREY"), 0.50, 1.0, 0.0001, 0.8404))), + bluxl(Gtk::manage(new Adjuster(M("TC_PRIM_BLUX"), -0.1, 0.4, 0.0001, 0.0366))), + bluyl(Gtk::manage(new Adjuster(M("TC_PRIM_BLUY"), -0.1, 0.49, 0.0001, 0.0001))), + refi(Gtk::manage(new Adjuster(M("TC_PRIM_REFI"), -0.5, 1., 0.0001, 0.))), + + gridFramecie(Gtk::manage(new Gtk::Frame(M("TP_ICM_WORKING_CIEDIAG")))), + labgridcie(Gtk::manage(new LabGrid(EvlocallabGridciexy, M("TP_ICM_LABGRID_CIEXY"), true, true, false))), + colorFramecie(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_COLORFRAME")))), + + catBox(Gtk::manage(new Gtk::Box())), + catMethod(Gtk::manage(new MyComboBoxText())), + gamutcieBox(Gtk::manage(new Gtk::Box())), + gamutcie(Gtk::manage(new Gtk::CheckButton(M("TP_ICM_GAMUT")))), + shiftxl(Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTX"), -0.20, 0.20, 0.0001, 0.))), + shiftyl(Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTY"), -0.20, 0.20, 0.0001, 0.))), + sigmoidjzFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGJZFRA")))), + sigmoid2Frame(Gtk::manage(new Gtk::Frame(M("")))), + sigcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGCIE")))), sigjz(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SIGJZFRA")))), sigmoidldajzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDLAMBDA"), 0., 1.0, 0.01, 0.5))), sigmoidthjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMOIDTH"), 0.1, 4., 0.01, 1., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), @@ -7504,26 +7691,19 @@ Locallabcie::Locallabcie(): chjzcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JZCH")))), strsoftjzcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_JZSTRSOFTCIE"), 0, 100., 0.5, 100.))), -/* - ciezFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_ZCAMFRA")))), - - lightlzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTL"), -100., 100., 0.5, 0.))), - lightqzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGLIGHTQ"), -100., 100., 0.05, 0.))), - contlzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONTL"), -100., 100., 0.5, 0.))), - contqzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCONQL"), -100., 100., 0.5, 0.))), - contthreszcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ZCAMTHRES"), 0., 1., 0.01, 0.))), - colorflzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGCOLORFL"), -100., 100., 0.5, 0.))), - saturzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SATURV"), -100., 100., 0.5, 0.))), - chromzcam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROML"), -100., 100., 0.5, 0.))), -*/ expLcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_CIETOOLEXP")))), cie2Frame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LOG2FRA")))), targetGraycie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TARGET_GRAY"), 5.0, 80.0, 0.1, 18.0))), targabscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOURCE_ABS"), 0.01, 16384.0, 0.01, 16.0))), - detailcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 100., 0.1, 0.))), + detailcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 100., 0.1, 30.))), + detailciejz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAIL"), 0., 100., 0.1, 30.))), catadcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CATAD"), -100., 100., 0.5, 0., Gtk::manage(new RTImage("circle-blue-small")), Gtk::manage(new RTImage("circle-orange-small"))))), - surroundcie(Gtk::manage (new MyComboBoxText ())), + surroundcie(Gtk::manage(new MyComboBoxText())), surrHBoxcie(Gtk::manage(new Gtk::Box())), + expgradcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPGRAD")))), + strgradcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4., 4., 0.05, 0.))), + anggradcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + exprecovcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusablecie(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), maskunusablecie(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), @@ -7534,22 +7714,89 @@ Locallabcie::Locallabcie(): expmaskcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWS")))), showmaskcieMethod(Gtk::manage(new MyComboBoxText())), enacieMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), + enacieMaskall(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASKALL")))), // maskSHCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), maskcieCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "", 1)), CCmaskcieshape(static_cast(maskcieCurveEditorG->addCurve(CT_Flat, "C", nullptr, false, false))), LLmaskcieshape(static_cast(maskcieCurveEditorG->addCurve(CT_Flat, "L", nullptr, false, false))), HHmaskcieshape(static_cast(maskcieCurveEditorG->addCurve(CT_Flat, "LC(h)", nullptr, false, true))), + struFramecie(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LABSTRUM")))), + strumaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUMASKCOL"), 0., 200., 0.1, 0.))), + toolcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_TOOLCOL")))), + blurFramecie(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LABBLURM")))), + fftcieMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_FFTCOL_MASK")))), + contcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CONTCOL"), 0., 200., 0.5, 0.))), + blurcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURCOL"), 0.2, 100., 0.5, 0.2))), blendmaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKCOL"), -100, 100, 1, 0))), radmaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_RADMASKCOL"), 0.0, 100.0, 0.1, 0.))), lapmaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LAPMASKCOL"), 0.0, 100.0, 0.1, 0.))), chromaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMASKCOL"), -100.0, 100.0, 0.1, 0.))), gammaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMMASKCOL"), 0.25, 4.0, 0.01, 1.))), slomaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOMASKCOL"), 0.0, 15.0, 0.1, 0.))), + highmaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_HIGHMASKCOL"), 0, 100, 1, 0))), + shadmaskcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHAMASKCOL"), 0, 100, 1, 0))), + maskcieHCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, "")), + HHhmaskcieshape(static_cast(maskcieHCurveEditorG->addCurve(CT_Flat, "h(h)", nullptr, false, true))), mask2cieCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), - Lmaskcieshape(static_cast(mask2cieCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) + Lmaskcieshape(static_cast(mask2cieCurveEditorG->addCurve(CT_Diagonal, "L(L)"))), + wavFramecie(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_TOOLMASK_2")))), + mask2cieCurveEditorGwav(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVMASK"))), + LLmaskcieshapewav(static_cast(mask2cieCurveEditorGwav->addCurve(CT_Flat, "L(L)", nullptr, false, false))), + quaHcieBox(Gtk::manage(new Gtk::Box())), + csThresholdcie(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) - { +{ + auto m = ProcEventMapper::getInstance(); + Evlocallabnormcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_NORM"); + Evlocallabstrumaskcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_STRU"); + EvLocallabtoolcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL"); + EvLocallabfftcieMask = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_BLURFFT"); + Evlocallabcontcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_BLURCONT"); + Evlocallabblurcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_BLURRAD"); + Evlocallabhighmaskcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_HIGH"); + Evlocallabshadmaskcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_SHAD"); + Evlocallabsigmoidsenscie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SIGADAP"); + EvlocallabLLmaskcieshapewav = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_WLC"); + EvlocallabcsThresholdcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_WLEV"); + Evlocallabcomprcie = m->newEvent(HDR, "HISTORY_MSG_LOCAL_CIE_BRICOMP"); + Evlocallabstrcielog = m->newEvent(HDR, "HISTORY_MSG_LOCAL_CIE_STRLOG"); + Evlocallabsatcie = m->newEvent(HDR, "HISTORY_MSG_LOCAL_CIE_SATCIE"); + Evlocallablogcieq = m->newEvent(HDR, "HISTORY_MSG_LOCAL_CIE_LOGCIEQ"); + Evlocallabcomprcieth = m->newEvent(HDR, "HISTORY_MSG_LOCAL_CIE_BRICOMPTH"); + EvlocallabHHhmaskcieshape = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_CHH"); + EvlocallabbwevMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SIGMET"); + Evlocallabgamjcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_GAM"); + Evlocallabslopjcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOP"); + Evlocallabmidtcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_MIDT"); + Evlocallabslopesmo = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOPESMO"); + Evlocallabsmoothcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTH"); + Evlocallabsigcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SIG"); + Evlocallabillcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_ILL"); + Evlocallabprimcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_PRIM"); + Evlocallabcatcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_CAT"); + Evlocallabwhitescie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_WHITES"); + Evlocallabblackscie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_BLACKS"); + Evlocallabredxl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_REDXL"); + Evlocallabredyl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_REDYL"); + Evlocallabgrexl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_GREXL"); + Evlocallabgreyl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_GREYL"); + Evlocallabbluxl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_BLUXL"); + Evlocallabbluyl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_BLUYL"); + EvlocallabGridciexy = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_LABGRIDCIE"); + Evlocallabgamutcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_GAMUTCIE"); + Evlocallabexpprecam = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_EXPPRECAM"); + Evlocallablightsigqcie = m->newEvent(AUTOEXP, ""); + Evlocallabcontsigqcie = m->newEvent(AUTOEXP, ""); + Evlocallabrefi = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_REFI"); + Evlocallabshiftxl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SHIFTXL"); + Evlocallabshiftyl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SHIFTYL"); + Evlocallabanggradcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_ANGGRAD"); + Evlocallabstrgradcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_STRGRAD"); + Evlocallabdetailciejz = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_DETAILJZ"); + EvlocallabenacieMaskall = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_ENAMASKALL"); + Evlocallabsmoothciemet = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTHMET"); + set_orientation(Gtk::ORIENTATION_VERTICAL); // Parameter Ciecam specific widgets @@ -7560,89 +7807,285 @@ Locallabcie::Locallabcie(): pack_start(*sensicie); pack_start(*reparcie); - modeHBoxcam->set_spacing (2); + modeHBoxcam->set_spacing(2); //modeHBoxcam->set_tooltip_markup (M ("TP_LOCALLAB_CAMMODE_TOOLTIP")); - Gtk::Label* modeLabelcam = Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_CAMMODE") + ":")); - modeHBoxcam->pack_start (*modeLabelcam, Gtk::PACK_SHRINK); - modecam->append (M ("TP_LOCALLAB_CAMMODE_CAM16")); - modecam->append (M ("TP_LOCALLAB_CAMMODE_JZ")); - // modecam->append (M ("TP_LOCALLAB_CAMMODE_ALL")); -// modecam->append (M ("TP_LOCALLAB_CAMMODE_ZCAM")); - modecam->set_active (0); - modeHBoxcam->pack_start (*modecam); - modecamconn = modecam->signal_changed().connect ( sigc::mem_fun (*this, &Locallabcie::modecamChanged) ); + Gtk::Label* modeLabelcam = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_CAMMODE") + ":")); + modeHBoxcam->pack_start(*modeLabelcam, Gtk::PACK_SHRINK); + modecam->append(M("TP_LOCALLAB_CAMMODE_CAM16")); + modecam->append(M("TP_LOCALLAB_CAMMODE_JZ")); + modecam->set_active(0); + modeHBoxcam->pack_start(*modecam); + modecamconn = modecam->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::modecamChanged)); pack_start(*modeHBoxcam); - modeHBoxcie->set_spacing (2); - modeHBoxcie->set_tooltip_markup (M ("TP_LOCALLAB_CIEMODE_TOOLTIP")); - Gtk::Label* modeLabel = Gtk::manage (new Gtk::Label (M ("TP_LOCALLAB_CIEMODE") + ":")); - modeHBoxcie->pack_start (*modeLabel, Gtk::PACK_SHRINK); - modecie->append (M ("TP_LOCALLAB_CIEMODE_COM")); - modecie->append (M ("TP_LOCALLAB_CIEMODE_TM")); - modecie->append (M ("TP_LOCALLAB_CIEMODE_WAV")); - modecie->append (M ("TP_LOCALLAB_CIEMODE_DR")); -// modecie->append (M ("TP_LOCALLAB_CIEMODE_LOG")); - modecie->set_active (0); - modeHBoxcie->pack_start (*modecie); - modecieconn = modecie->signal_changed().connect ( sigc::mem_fun (*this, &Locallabcie::modecieChanged) ); + modeHBoxcie->set_spacing(2); + modeHBoxcie->set_tooltip_markup(M("TP_LOCALLAB_CIEMODE_TOOLTIP")); + Gtk::Label* modeLabel = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_CIEMODE") + ":")); + modeHBoxcie->pack_start(*modeLabel, Gtk::PACK_SHRINK); + modecie->append(M("TP_LOCALLAB_CIEMODE_COM")); + modecie->append(M("TP_LOCALLAB_CIEMODE_TM")); + modecie->append(M("TP_LOCALLAB_CIEMODE_WAV")); + modecie->append(M("TP_LOCALLAB_CIEMODE_DR")); + modecie->set_active(0); + modeHBoxcie->pack_start(*modecie); + modecieconn = modecie->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::modecieChanged)); pack_start(*modeHBoxcie); - surHBoxcie->set_spacing (2); - surHBoxcie->set_tooltip_markup (M ("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); - Gtk::Label* surLabel = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); - surHBoxcie->pack_start (*surLabel, Gtk::PACK_SHRINK); - sursourcie->append (M ("TP_COLORAPP_SURROUND_AVER")); - sursourcie->append (M ("TP_COLORAPP_SURROUND_DIM")); - sursourcie->append (M ("TP_COLORAPP_SURROUND_DARK")); - sursourcie->set_active (0); - surHBoxcie->pack_start (*sursourcie); - sursourcieconn = sursourcie->signal_changed().connect ( sigc::mem_fun (*this, &Locallabcie::sursourcieChanged) ); + surHBoxcie->set_spacing(2); + surHBoxcie->set_tooltip_markup(M("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); + Gtk::Label* surLabel = Gtk::manage(new Gtk::Label(M("TP_COLORAPP_SURROUND") + ":")); + surHBoxcie->pack_start(*surLabel, Gtk::PACK_SHRINK); + sursourcie->append(M("TP_COLORAPP_SURROUND_AVER")); + sursourcie->append(M("TP_COLORAPP_SURROUND_DIM")); + sursourcie->append(M("TP_COLORAPP_SURROUND_DARK")); + sursourcie->append(M("TP_COLORAPP_SURROUND_EXDARK")); + sursourcie->append(M("TP_LOCALLAB_DISAB_CIECAM")); + sursourcie->set_active(0); + surHBoxcie->pack_start(*sursourcie); + sursourcieconn = sursourcie->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::sursourcieChanged)); cieFrame->set_label_align(0.025, 0.5); + + Gtk::Box *TittleVBoxcamscene; + TittleVBoxcamscene = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + TittleVBoxcamscene->set_spacing(2); + Gtk::Box* const LCTitleHBoxcamscene = Gtk::manage(new Gtk::Box()); + Gtk::Label* const LCLabelcamscene = Gtk::manage(new Gtk::Label()); + LCLabelcamscene->set_markup(Glib::ustring("") + (M("TP_LOCALLAB_LOGFRA")) + Glib::ustring("")); + LCTitleHBoxcamscene->pack_start(*LCLabelcamscene, Gtk::PACK_SHRINK); + TittleVBoxcamscene->pack_start(*LCTitleHBoxcamscene, Gtk::PACK_SHRINK); + expcamscene->setLabel(TittleVBoxcamscene); + + setExpandAlignProperties(expcamscene, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + + + + + ToolParamBlock* const cieFBox = Gtk::manage(new ToolParamBlock()); cieFBox->pack_start(*Autograycie); cieFBox->pack_start(*sourceGraycie); cieFBox->pack_start(*sourceabscie); cieFBox->pack_start(*pqremapcam16); + cieFBox->pack_start(*whitescie); + cieFBox->pack_start(*blackscie); + PQFrame->set_label_align(0.025, 0.5); ToolParamBlock* const PQFBox = Gtk::manage(new ToolParamBlock()); PQFBox->pack_start(*adapjzcie); PQFBox->pack_start(*jz100); PQFBox->pack_start(*pqremap); -// PQFBox->pack_start(*forcejz); -// PQFBox->pack_start(*contthreszcam); PQFrame->add(*PQFBox); - cieFBox->pack_start (*PQFrame); + cieFBox->pack_start(*PQFrame); logjzFrame->set_label_align(0.025, 0.5); logjzFrame->set_label_widget(*logjz); - // Gtk::Separator* const separatorjz = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); ToolParamBlock* const logjzBox = Gtk::manage(new ToolParamBlock()); - //logjzBox->pack_start(*blackEvjz); - // logjzBox->pack_start(*whiteEvjz); - // logjzBox->pack_start(*separatorjz); logjzBox->pack_start(*targetjz); logjzFrame->add(*logjzBox); - cieFBox->pack_start (*logjzFrame); + cieFBox->pack_start(*logjzFrame); bevwevFrame->set_label_align(0.025, 0.5); ToolParamBlock* const bevwevBox = Gtk::manage(new ToolParamBlock()); bevwevBox->pack_start(*blackEvjz); bevwevBox->pack_start(*whiteEvjz); bevwevFrame->add(*bevwevBox); - cieFBox->pack_start (*bevwevFrame); + cieFBox->pack_start(*bevwevFrame); sigmoidFrame->set_label_align(0.025, 0.5); sigmoidFrame->set_label_widget(*sigq); - ToolParamBlock* const sigBox = Gtk::manage(new ToolParamBlock()); - Gtk::Separator* const separatorsig = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)); + sigmoidnormFrame->set_label_align(0.025, 0.5); + sigmoidnormFrame->set_label_widget(*normcie); + + + Gtk::Box *TittleVBoxprecam; + TittleVBoxprecam = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + TittleVBoxprecam->set_spacing(2); + Gtk::Box* const LCTitleHBoxprecam = Gtk::manage(new Gtk::Box()); + Gtk::Label* const LCLabelprecam = Gtk::manage(new Gtk::Label()); + LCLabelprecam->set_markup(Glib::ustring("") + (M("TP_LOCALLAB_SIGTRCCIE")) + Glib::ustring("")); + LCTitleHBoxprecam->pack_start(*LCLabelprecam, Gtk::PACK_SHRINK); + TittleVBoxprecam->pack_start(*LCTitleHBoxprecam, Gtk::PACK_SHRINK); + expprecam->setLabel(TittleVBoxprecam); + + setExpandAlignProperties(expprecam, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + + sigmoid2Frame->set_label_align(0.025, 0.5); + //sigmoid2Frame->set_label_widget(*sigcie); + logcieFrame->set_label_align(0.025, 0.5); + logcieFrame->set_label_widget(*logcie); + Gtk::Label* illLabel = Gtk::manage(new Gtk::Label(M("TP_ICM_WORKING_ILLU") + ":")); + willBox->pack_start(*illLabel, Gtk::PACK_SHRINK); + willBox->pack_start(*illMethod, Gtk::PACK_EXPAND_WIDGET); + illMethod->append(M("TP_ICM_WORKING_ILLU_D41")); + illMethod->append(M("TP_ICM_WORKING_ILLU_D50")); + illMethod->append(M("TP_ICM_WORKING_ILLU_D55")); + illMethod->append(M("TP_ICM_WORKING_ILLU_D60")); + illMethod->append(M("TP_ICM_WORKING_ILLU_D65")); + illMethod->append(M("TP_ICM_WORKING_ILLU_D80")); + + illMethod->append(M("TP_ICM_WORKING_ILLU_D120")); + + illMethod->append(M("TP_ICM_WORKING_ILLU_STDA")); + illMethod->append(M("TP_ICM_WORKING_ILLU_2000")); + illMethod->append(M("TP_ICM_WORKING_ILLU_1500")); + illMethod->append(M("TP_ICM_WORKING_ILLU_E")); + + + illMethod->set_active(1); + illMethodconn = illMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::illMethodChanged)); + + + Gtk::Label* primLabel = Gtk::manage(new Gtk::Label(M("TP_ICM_WORKING_PRIM") + ":")); + wprimBox->pack_start(*primLabel, Gtk::PACK_SHRINK); + wprimBox->pack_start(*primMethod, Gtk::PACK_EXPAND_WIDGET); + primMethod->append(M("TP_ICM_WORKING_PRIM_PROP")); + primMethod->append(M("TP_ICM_WORKING_PRIM_BET")); + primMethod->append(M("TP_ICM_WORKING_PRIM_WID")); + primMethod->append(M("TP_ICM_WORKING_PRIM_ACE")); + primMethod->append(M("TP_ICM_WORKING_PRIM_REC")); + primMethod->append(M("TP_ICM_WORKING_PRIM_ADOB")); + primMethod->append(M("TP_ICM_WORKING_PRIM_SRGB")); + primMethod->append(M("TP_ICM_WORKING_PRIM_JDCMAX")); + primMethod->append(M("TP_ICM_WORKING_PRIM_JDCMAXSTDA")); + primMethod->append(M("TP_ICM_WORKING_PRIM_AC0")); + primMethod->append(M("TP_ICM_WORKING_PRIM_BST")); + primMethod->append(M("TP_ICM_WORKING_PRIM_BRU")); + primMethod->append(M("TP_ICM_WORKING_PRIM_FREE")); + + primMethod->set_active(0); + primMethodconn = primMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::primMethodChanged)); + trcFrame->set_label_align(0.025, 0.5); + smoothFrame->set_label_align(0.025, 0.5); + + primillFrame->set_label_align(0.025, 0.5); + setExpandAlignProperties(grexl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(greyl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(bluxl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(bluyl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(redxl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + setExpandAlignProperties(redyl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); + + + primCoordGridl->set_column_homogeneous(true); + primCoordGridl->attach(*redxl, 0, 0, 1, 1); + primCoordGridl->attach_next_to(*redyl, *redxl, Gtk::PositionType::POS_RIGHT, 1, 1); + primCoordGridl->attach_next_to(*grexl, *redxl, Gtk::PositionType::POS_BOTTOM, 1, 1); + primCoordGridl->attach_next_to(*greyl, *grexl, Gtk::PositionType::POS_RIGHT, 1, 1); + primCoordGridl->attach_next_to(*bluxl, *grexl, Gtk::PositionType::POS_BOTTOM, 1, 1); + primCoordGridl->attach_next_to(*bluyl, *bluxl, Gtk::PositionType::POS_RIGHT, 1, 1); + + redBox->pack_start(*primCoordGridl, Gtk::PACK_EXPAND_WIDGET); + + + redxl->setAdjusterListener(this); + redyl->setAdjusterListener(this); + grexl->setAdjusterListener(this); + greyl->setAdjusterListener(this); + bluxl->setAdjusterListener(this); + bluyl->setAdjusterListener(this); + refi->setAdjusterListener(this); + shiftxl->setAdjusterListener(this); + shiftyl->setAdjusterListener(this); + + + gridFramecie->set_label_align(0.025, 0.5); + ToolParamBlock* const gridBox = Gtk::manage(new ToolParamBlock()); + gridBox->pack_start(*labgridcie); + gridFramecie->add(*gridBox); + + Gtk::Label* catLabel = Gtk::manage(new Gtk::Label(M("TP_ICM_WORKING_CAT") + ":")); + catBox->pack_start(*catLabel, Gtk::PACK_SHRINK); + catBox->pack_start(*catMethod, Gtk::PACK_EXPAND_WIDGET); + catMethod->append(M("TP_ICM_WORKING_CAT_BRAD")); + catMethod->append(M("TP_ICM_WORKING_CAT_CAT16")); + catMethod->append(M("TP_ICM_WORKING_CAT_CAT02")); + catMethod->append(M("TP_ICM_WORKING_CAT_VK")); + catMethod->append(M("TP_ICM_WORKING_CAT_XYZ")); + catMethod->set_active(0); + catMethodconn = catMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::catMethodChanged)); + gamutcieBox->pack_start(*gamutcie, Gtk::PACK_EXPAND_WIDGET); + + gamutcieconn = gamutcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::gamutcieChanged)); + + ToolParamBlock* const signormBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const sigfraBox = Gtk::manage(new ToolParamBlock()); + + modeHBoxbwev->set_spacing(2); + ToolParamBlock* const gamcieBox = Gtk::manage(new ToolParamBlock()); + Gtk::Label* modeLabelbwev = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_SIGMOIDQJ") + ":")); + modeHBoxbwev->pack_start(*modeLabelbwev, Gtk::PACK_SHRINK); + + bwevMethod->append(M("TP_LOCALLAB_BWEVNONE")); + bwevMethod->append(M("TP_LOCALLAB_BWEVSIG")); + bwevMethod->set_active(1); + bwevMethodConn = bwevMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::bwevMethodChanged)); + modeHBoxbwev->pack_start(*bwevMethod); + + comprBox->pack_start(*comprcie); + comprBox->pack_start(*strcielog); + comprBox->pack_start(*satcie); + comprBox->pack_start(*logcieq); + logcieFrame->add(*comprBox); + gamcieBox->pack_start(*logcieFrame); + + ToolParamBlock* const trccieBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const smoothcieBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const primillBox = Gtk::manage(new ToolParamBlock()); + ToolParamBlock* const colorBox = Gtk::manage(new ToolParamBlock()); + + trccieBox->pack_start(*gamjcie); + trccieBox->pack_start(*slopjcie); + trccieBox->pack_start(*midtcie); + + smoothBox->pack_start(*smoothciemet, Gtk::PACK_EXPAND_WIDGET); + smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_NONE")); + smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_EV")); + smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF")); + smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_GAMMA")); + smoothciemet->set_active(0); + ciesmoothBox->pack_start(*smoothBox); + ciesmoothBox->pack_start(*slopesmo); + ciesmoothBox->pack_start(*smoothcie); + + smoothciemetconn = smoothciemet->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::smoothciemetChanged)); + + smoothcieBox->pack_start(*ciesmoothBox); + smoothFrame->add(*smoothcieBox); + trccieBox->pack_start(*smoothFrame); + trcFrame->add(*trccieBox); + gamcieBox->pack_start(*trcFrame); + primillBox->pack_start(*willBox); + colorFramecie->set_label_align(0.025, 0.5); + + primillBox->pack_start(*wprimBox); + primillBox->pack_start(*redBox); + primillBox->pack_start(*gridFramecie); + primillBox->pack_start(*gamutcieBox); + primillBox->pack_start(*catBox); + colorBox->pack_start(*refi); + colorBox->pack_start(*shiftxl); + colorBox->pack_start(*shiftyl); + colorFramecie->add(*colorBox); + primillBox->pack_start(*colorFramecie); + primillFrame->add(*primillBox); + gamcieBox->pack_start(*primillFrame); + + + + expprecam->add(*gamcieBox, false); + + + sigfraBox->pack_start(*sigmoidldacie); + sigfraBox->pack_start(*sigmoidthcie); + sigfraBox->pack_start(*sigmoidsenscie); + sigfraBox->pack_start(*modeHBoxbwev); + sigmoid2Frame->add(*sigfraBox); + sigBox->pack_start(*sigmoid2Frame); + + signormBox->pack_start(*sigmoidblcie); + sigmoidnormFrame->add(*signormBox); + sigBox->pack_start(*sigmoidnormFrame); - sigBox->pack_start(*sigmoidldacie); - sigBox->pack_start(*sigmoidthcie); - sigBox->pack_start(*sigmoidblcie); - sigBox->pack_start(*sigmoidqjcie); - sigBox->pack_start(*separatorsig); - sigBox->pack_start(*logcie); sigmoidFrame->add(*sigBox); - cieFBox->pack_start(*sigmoidFrame); sigmoidjzFrame->set_label_align(0.025, 0.5); @@ -7654,12 +8097,16 @@ Locallabcie::Locallabcie(): sigjzBox->pack_start(*forcebw); sigmoidjzFrame->add(*sigjzBox); - // jzBox->pack_start(*sigmoidjzFrame); cieFBox->pack_start(*sigmoidjzFrame); - cieFBox->pack_start (*surHBoxcie); - cieFrame->add(*cieFBox); - pack_start(*cieFrame); + cieFBox->pack_start(*surHBoxcie); + + + expcamscene->add(*cieFBox, false); + + pack_start(*expcamscene, false, false); + pack_start(*expprecam, false, false); + ToolParamBlock* const jzallBox = Gtk::manage(new ToolParamBlock()); Gtk::Box *TittleVBoxjz; @@ -7676,61 +8123,53 @@ Locallabcie::Locallabcie(): float R, G, B; std::vector six_shape; + for (int i = 0; i < 6; i++) { const float x = static_cast(i) * (1.f / 6.f); Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); six_shape.emplace_back(x, R, G, B); } + std::vector milestone; - milestone.push_back ( GradientMilestone (0., 0., 0., 0.) ); - milestone.push_back ( GradientMilestone (1., 1., 1., 1.) ); + milestone.push_back(GradientMilestone(0., 0., 0., 0.)); + milestone.push_back(GradientMilestone(1., 1., 1., 1.)); jz1CurveEditorG->setCurveListener(this); shapejz->setResetCurve(DiagonalCurveType(defSpot.jzcurve.at(0)), defSpot.jzcurve); - shapejz->setBottomBarBgGradient (milestone); - shapejz->setLeftBarBgGradient (milestone); + shapejz->setBottomBarBgGradient(milestone); + shapejz->setLeftBarBgGradient(milestone); shapecz->setResetCurve(DiagonalCurveType(defSpot.czcurve.at(0)), defSpot.czcurve); std::vector shapeczMilestones; -// float R, G, B; - shapecz->setBottomBarColorProvider (this, 1); - shapecz->setLeftBarColorProvider (this, 1); - shapecz->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapecz->setBottomBarColorProvider(this, 1); + shapecz->setLeftBarColorProvider(this, 1); + shapecz->setRangeDefaultMilestones(0.05, 0.2, 0.58); for (int i = 0; i < 7; i++) { float x = float (i) * (1.0f / 6.f); - Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B); - shapeczMilestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) ); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + shapeczMilestones.push_back(GradientMilestone(double (x), double (R), double (G), double (B))); } - shapecz->setBottomBarBgGradient (shapeczMilestones); - shapecz->setLeftBarBgGradient (shapeczMilestones); - shapecz->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapecz->setBottomBarBgGradient(shapeczMilestones); + shapecz->setLeftBarBgGradient(shapeczMilestones); + shapecz->setRangeDefaultMilestones(0.05, 0.2, 0.58); - shapeczjz->setLeftBarColorProvider (this, 1); - shapeczjz->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapeczjz->setLeftBarColorProvider(this, 1); + shapeczjz->setRangeDefaultMilestones(0.05, 0.2, 0.58); shapeczjz->setResetCurve(DiagonalCurveType(defSpot.czjzcurve.at(0)), defSpot.czjzcurve); - shapeczjz->setBottomBarBgGradient (milestone); - shapeczjz->setLeftBarBgGradient (shapeczMilestones); - shapeczjz->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapeczjz->setBottomBarBgGradient(milestone); + shapeczjz->setLeftBarBgGradient(shapeczMilestones); + shapeczjz->setRangeDefaultMilestones(0.05, 0.2, 0.58); jz1CurveEditorG->curveListComplete(); -/* - jz2CurveEditorG->setCurveListener(this); - shapeczjz->setLeftBarColorProvider (this, 1); - shapeczjz->setRangeDefaultMilestones (0.05, 0.2, 0.58); - shapeczjz->setResetCurve(DiagonalCurveType(defSpot.czjzcurve.at(0)), defSpot.czjzcurve); - shapeczjz->setBottomBarBgGradient (milestone); - shapeczjz->setLeftBarBgGradient (shapeczMilestones); - shapeczjz->setRangeDefaultMilestones (0.05, 0.2, 0.58); - jz2CurveEditorG->curveListComplete(); -*/ + jz2CurveEditorG->setCurveListener(this); LHshapejz->setIdentityValue(0.); LHshapejz->setResetCurve(FlatCurveType(defSpot.LHcurvejz.at(0)), defSpot.LHcurvejz); - // LHshapejz->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); + // LHshapejz->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); LHshapejz->setCurveColorProvider(this, 3); LHshapejz->setBottomBarBgGradient(six_shape); jz2CurveEditorG->curveListComplete(); @@ -7739,13 +8178,11 @@ Locallabcie::Locallabcie(): CHshapejz->setIdentityValue(0.); CHshapejz->setResetCurve(FlatCurveType(defSpot.CHcurvejz.at(0)), defSpot.CHcurvejz); - // CHshapejz->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); CHshapejz->setCurveColorProvider(this, 3); CHshapejz->setBottomBarBgGradient(six_shape); HHshapejz->setIdentityValue(0.); HHshapejz->setResetCurve(FlatCurveType(defSpot.HHcurvejz.at(0)), defSpot.HHcurvejz); - // HHshapejz->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP")); HHshapejz->setCurveColorProvider(this, 3); HHshapejz->setBottomBarBgGradient(six_shape); @@ -7760,6 +8197,7 @@ Locallabcie::Locallabcie(): ToolParamBlock* const ciePzlightBox = Gtk::manage(new ToolParamBlock()); ciePzlightBox->pack_start(*lightjzcie); ciePzlightBox->pack_start(*contjzcie); + ciePzlightBox->pack_start(*detailciejz); czlightFrame->add(*ciePzlightBox); jzBox->pack_start(*czlightFrame); @@ -7785,17 +8223,7 @@ Locallabcie::Locallabcie(): jzHHBox->pack_start(*softjzcie); HFramejz->add(*jzHHBox); jzBox->pack_start(*HFramejz); - /* - sigmoidjzFrame->set_label_align(0.025, 0.5); - ToolParamBlock* const sigjzBox = Gtk::manage(new ToolParamBlock()); - sigjzBox->pack_start(*sigmoidldajzcie); - sigjzBox->pack_start(*sigmoidthjzcie); - sigjzBox->pack_start(*sigmoidbljzcie); - sigjzBox->pack_start(*jabcie); - sigmoidjzFrame->add(*sigjzBox); - // jzBox->pack_start(*sigmoidjzFrame); - */ jzshFrame->set_label_align(0.025, 0.5); ToolParamBlock* const jzshBox = Gtk::manage(new ToolParamBlock()); jzshBox->pack_start(*hljzcie); @@ -7847,8 +8275,15 @@ Locallabcie::Locallabcie(): jabcieConn = jabcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::jabcieChanged)); AutograycieConn = Autograycie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::AutograycieChanged)); - sigmoidqjcieconn = sigmoidqjcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigmoidqjcieChanged)); + comprcieautoconn = comprcieauto->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::comprcieautoChanged)); + normcieconn = normcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::normcieChanged)); + expprecamconn = expprecam->signal_enabled_toggled().connect(sigc::mem_fun(*this, &Locallabcie::expprecamChanged)); + + sigcieconn = sigcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigcieChanged)); logcieconn = logcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::logcieChanged)); + satcieconn = satcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::satcieChanged)); + logcieqconn = logcieq->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::logcieqChanged)); + smoothcieconn = smoothcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::smoothcieChanged)); logjzconn = logjz->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::logjzChanged)); sigjzconn = sigjz->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigjzChanged)); sigqconn = sigq->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigqChanged)); @@ -7874,39 +8309,38 @@ Locallabcie::Locallabcie(): cieCurveEditorG->setCurveListener(this); - toneMethodcie->append (M ("TP_COLORAPP_TCMODE_LIGHTNESS")); - toneMethodcie->append (M ("TP_COLORAPP_TCMODE_BRIGHTNESS")); - toneMethodcie->set_active (0); + toneMethodcie->append(M("TP_COLORAPP_TCMODE_LIGHTNESS")); + toneMethodcie->append(M("TP_COLORAPP_TCMODE_BRIGHTNESS")); + toneMethodcie->set_active(0); toneMethodcieConn = toneMethodcie->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::toneMethodcieChanged)); shapecie->setResetCurve(DiagonalCurveType(defSpot.ciecurve.at(0)), defSpot.ciecurve); - shapecie->setBottomBarBgGradient (milestone); - shapecie->setLeftBarBgGradient (milestone); + shapecie->setBottomBarBgGradient(milestone); + shapecie->setLeftBarBgGradient(milestone); cieCurveEditorG->curveListComplete(); cieCurveEditorG2->setCurveListener(this); - toneMethodcie2->append (M ("TP_COLORAPP_TCMODE_CHROMA")); - toneMethodcie2->append (M ("TP_COLORAPP_TCMODE_SATUR")); - toneMethodcie2->append (M ("TP_COLORAPP_TCMODE_COLORF")); - toneMethodcie2->set_active (0); + toneMethodcie2->append(M("TP_COLORAPP_TCMODE_CHROMA")); + toneMethodcie2->append(M("TP_COLORAPP_TCMODE_SATUR")); + toneMethodcie2->append(M("TP_COLORAPP_TCMODE_COLORF")); + toneMethodcie2->set_active(0); toneMethodcieConn2 = toneMethodcie2->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::toneMethodcie2Changed)); shapecie2->setResetCurve(DiagonalCurveType(defSpot.ciecurve2.at(0)), defSpot.ciecurve2); - shapecie2->setBottomBarColorProvider (this, 1); - shapecie2->setLeftBarColorProvider (this, 1); - shapecie2->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapecie2->setBottomBarColorProvider(this, 1); + shapecie2->setLeftBarColorProvider(this, 1); + shapecie2->setRangeDefaultMilestones(0.05, 0.2, 0.58); std::vector shape2Milestones; -// float R, G, B; for (int i = 0; i < 7; i++) { float x = float (i) * (1.0f / 6.f); - Color::hsv2rgb01 (x, 0.5f, 0.5f, R, G, B); - shape2Milestones.push_back ( GradientMilestone (double (x), double (R), double (G), double (B)) ); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + shape2Milestones.push_back(GradientMilestone(double (x), double (R), double (G), double (B))); } - shapecie2->setBottomBarBgGradient (shape2Milestones); - shapecie2->setLeftBarBgGradient (shape2Milestones); + shapecie2->setBottomBarBgGradient(shape2Milestones); + shapecie2->setLeftBarBgGradient(shape2Milestones); - shapecie2->setRangeDefaultMilestones (0.05, 0.2, 0.58); + shapecie2->setRangeDefaultMilestones(0.05, 0.2, 0.58); cieCurveEditorG2->curveListComplete(); @@ -7922,12 +8356,14 @@ Locallabcie::Locallabcie(): lightjzcie->setAdjusterListener(this); lightqcie->setAdjusterListener(this); + lightsigqcie->setAdjusterListener(this); contlcie->setAdjusterListener(this); contjzcie->setAdjusterListener(this); adapjzcie->setAdjusterListener(this); jz100->setAdjusterListener(this); pqremap->setAdjusterListener(this); pqremapcam16->setAdjusterListener(this); + pqremapcam16->setLogScale(500, 100); hljzcie->setAdjusterListener(this); hlthjzcie->setAdjusterListener(this); shjzcie->setAdjusterListener(this); @@ -7942,23 +8378,24 @@ Locallabcie::Locallabcie(): targetjz->setLogScale(10, 18, true); sigmoidldacie->setAdjusterListener(this); sigmoidthcie->setAdjusterListener(this); + sigmoidsenscie->setAdjusterListener(this); sigmoidblcie->setAdjusterListener(this); + comprcie->setAdjusterListener(this); + strcielog->setAdjusterListener(this); + comprcieth->setAdjusterListener(this); + gamjcie->setAdjusterListener(this); + slopjcie->setAdjusterListener(this); + slopjcie->setLogScale(100, 1); + midtcie->setAdjusterListener(this); + whitescie->setAdjusterListener(this); + blackscie->setAdjusterListener(this); sigmoidldajzcie->setAdjusterListener(this); sigmoidthjzcie->setAdjusterListener(this); sigmoidbljzcie->setAdjusterListener(this); contqcie->setAdjusterListener(this); + contsigqcie->setAdjusterListener(this); colorflcie->setAdjusterListener(this); -/* - lightlzcam->setAdjusterListener(this); - lightqzcam->setAdjusterListener(this); - contlzcam->setAdjusterListener(this); - contqzcam->setAdjusterListener(this); - contthreszcam->setAdjusterListener(this); - colorflzcam->setAdjusterListener(this); - saturzcam->setAdjusterListener(this); - chromzcam->setAdjusterListener(this); -*/ targetGraycie->setAdjusterListener(this); targetGraycie->setLogScale(10, 18, true); targabscie->setLogScale(500, 0); @@ -7966,8 +8403,10 @@ Locallabcie::Locallabcie(): targabscie->setAdjusterListener(this); detailcie->setAdjusterListener(this); + detailciejz->setAdjusterListener(this); catadcie->setAdjusterListener(this); + slopesmo->setAdjusterListener(this); Gtk::Box *TittleVBoxcam16; TittleVBoxcam16 = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); @@ -7981,17 +8420,29 @@ Locallabcie::Locallabcie(): setExpandAlignProperties(expcam16, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); - surrHBoxcie->set_spacing (2); - surrHBoxcie->set_tooltip_markup (M ("TP_COLORAPP_SURROUND_TOOLTIP")); - Gtk::Label* surrLabelcie = Gtk::manage (new Gtk::Label (M ("TP_COLORAPP_SURROUND") + ":")); - surrHBoxcie->pack_start (*surrLabelcie, Gtk::PACK_SHRINK); - surroundcie->append (M ("TP_COLORAPP_SURROUND_AVER")); - surroundcie->append (M ("TP_COLORAPP_SURROUND_DIM")); - surroundcie->append (M ("TP_COLORAPP_SURROUND_DARK")); -// surroundcie->append (M ("TP_COLORAPP_SURROUND_EXDARK")); - surroundcie->set_active (0); - surrHBoxcie->pack_start (*surroundcie); - surroundcieconn = surroundcie->signal_changed().connect ( sigc::mem_fun (*this, &Locallabcie::surroundcieChanged) ); + + Gtk::Box *TittleVBoxcamviewing; + TittleVBoxcamviewing = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + TittleVBoxcamviewing->set_spacing(2); + Gtk::Box* const LCTitleHBoxcamviewing = Gtk::manage(new Gtk::Box()); + Gtk::Label* const LCLabelcamviewing = Gtk::manage(new Gtk::Label()); + LCLabelcamviewing->set_markup(Glib::ustring("") + (M("TP_LOCALLAB_LOG2FRA")) + Glib::ustring("")); + LCTitleHBoxcamviewing->pack_start(*LCLabelcamviewing, Gtk::PACK_SHRINK); + TittleVBoxcamviewing->pack_start(*LCTitleHBoxcamviewing, Gtk::PACK_SHRINK); + expcamviewing->setLabel(TittleVBoxcamviewing); + + setExpandAlignProperties(expcamviewing, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + + surrHBoxcie->set_spacing(2); + surrHBoxcie->set_tooltip_markup(M("TP_COLORAPP_SURROUND_TOOLTIP")); + Gtk::Label* surrLabelcie = Gtk::manage(new Gtk::Label(M("TP_COLORAPP_SURROUND") + ":")); + surrHBoxcie->pack_start(*surrLabelcie, Gtk::PACK_SHRINK); + surroundcie->append(M("TP_COLORAPP_SURROUND_AVER")); + surroundcie->append(M("TP_COLORAPP_SURROUND_DIM")); + surroundcie->append(M("TP_COLORAPP_SURROUND_DARK")); + surroundcie->set_active(0); + surrHBoxcie->pack_start(*surroundcie); + surroundcieconn = surroundcie->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::surroundcieChanged)); cie1Frame->set_label_align(0.025, 0.5); cie1lightFrame->set_label_align(0.025, 0.5); @@ -8001,13 +8452,19 @@ Locallabcie::Locallabcie(): ToolParamBlock* const cieP1lightBox = Gtk::manage(new ToolParamBlock()); cieP1lightBox->pack_start(*lightlcie); cieP1lightBox->pack_start(*lightqcie); + cieP1lightBox->pack_start(*lightsigqcie); cie1lightFrame->add(*cieP1lightBox); cieP1Box->pack_start(*cie1lightFrame); ToolParamBlock* const cieP1contBox = Gtk::manage(new ToolParamBlock()); cieP1contBox->pack_start(*detailcie); cieP1contBox->pack_start(*contlcie); cieP1contBox->pack_start(*contqcie); + cieP1contBox->pack_start(*contsigqcie); cieP1contBox->pack_start(*contthrescie); + + contsigqcie->hide(); + lightsigqcie->hide(); + cie1contFrame->add(*cieP1contBox); cieP1Box->pack_start(*cie1contFrame); ToolParamBlock* const cieP1colorBox = Gtk::manage(new ToolParamBlock()); @@ -8018,45 +8475,19 @@ Locallabcie::Locallabcie(): cieP1colorBox->pack_start(*rstprotectcie); cie1colorFrame->add(*cieP1colorBox); cieP1Box->pack_start(*cie1colorFrame); - // pack_start(*blackEvjz); - // pack_start(*whiteEvjz); -/* - sigmoidFrame->set_label_align(0.025, 0.5); - ToolParamBlock* const sigBox = Gtk::manage(new ToolParamBlock()); + cieP1Box->pack_start(*sigmoidFrame);//disable provisory Sigmoid + - sigBox->pack_start(*sigmoidldacie); - sigBox->pack_start(*sigmoidthcie); - sigBox->pack_start(*sigmoidblcie); - sigBox->pack_start(*sigmoidqjcie); - sigmoidFrame->add(*sigBox); - cieP1Box->pack_start(*sigmoidFrame); - */ ToolParamBlock* const cieP11Box = Gtk::manage(new ToolParamBlock()); cieP11Box->pack_start(*cieCurveEditorG); cieP11Box->pack_start(*cieCurveEditorG2); expLcie->add(*cieP11Box, false); cieP1Box->pack_start(*expLcie, false, false); - // cie1Frame->add(*cieP1Box); - // expcam16->pack_start(*cie1Frame); expcam16->add(*cieP1Box, false); pack_start(*expcam16, false, false); pack_start(*expjz, false, false); -/* - ciezFrame->set_label_align(0.025, 0.5); - ToolParamBlock* const ciePzBox = Gtk::manage(new ToolParamBlock()); - ciePzBox->pack_start(*lightlzcam); - ciePzBox->pack_start(*lightqzcam); - ciePzBox->pack_start(*contlzcam); - ciePzBox->pack_start(*contqzcam); -// ciePzBox->pack_start(*contthreszcam); - ciePzBox->pack_start(*colorflzcam); - ciePzBox->pack_start(*saturzcam); - ciePzBox->pack_start(*chromzcam); - ciezFrame->add(*ciePzBox); - pack_start(*ciezFrame); -*/ cie2Frame->set_label_align(0.025, 0.5); ToolParamBlock* const cieP2Box = Gtk::manage(new ToolParamBlock()); @@ -8064,16 +8495,19 @@ Locallabcie::Locallabcie(): cieP2Box->pack_start(*targabscie); cieP2Box->pack_start(*catadcie); cieP2Box->pack_start(*surrHBoxcie); -// cieP2Box->pack_start(*detailcie); -// cieP2Box->pack_start(*jabcie); - cie2Frame->add(*cieP2Box); - pack_start(*cie2Frame); + expcamviewing->add(*cieP2Box, false); + + pack_start(*expcamviewing, false, false); + recothrescie->setAdjusterListener(this); lowthrescie->setAdjusterListener(this); higthrescie->setAdjusterListener(this); decaycie->setAdjusterListener(this); + + setExpandAlignProperties(expgradcie, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + setExpandAlignProperties(exprecovcie, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -8089,6 +8523,7 @@ Locallabcie::Locallabcie(): showmaskcieMethodConn = showmaskcieMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::showmaskcieMethodChanged)); enacieMaskConn = enacieMask->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::enacieMaskChanged)); + enacieMaskallConn = enacieMaskall->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::enacieMaskallChanged)); maskcieCurveEditorG->setCurveListener(this); CCmaskcieshape->setIdentityValue(0.); @@ -8105,12 +8540,35 @@ Locallabcie::Locallabcie(): HHmaskcieshape->setBottomBarColorProvider(this, 2); maskcieCurveEditorG->curveListComplete(); + + struFramecie->set_label_align(0.025, 0.5); + + strumaskcie->setAdjusterListener(this); + + toolcieConn = toolcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::toolcieChanged)); + + blurFramecie->set_label_align(0.025, 0.5); + + fftcieMaskConn = fftcieMask->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::fftcieMaskChanged)); + + contcie->setAdjusterListener(this); + + blurcie->setAdjusterListener(this); + blendmaskcie->setAdjusterListener(this); radmaskcie->setAdjusterListener(this); lapmaskcie->setAdjusterListener(this); gammaskcie->setAdjusterListener(this); slomaskcie->setAdjusterListener(this); + highmaskcie->setAdjusterListener(this); + shadmaskcie->setAdjusterListener(this); + maskcieHCurveEditorG->setCurveListener(this); + HHhmaskcieshape->setIdentityValue(0.); + HHhmaskcieshape->setResetCurve(FlatCurveType(defSpot.HHhmaskciecurve.at(0)), defSpot.HHhmaskciecurve); + HHhmaskcieshape->setCurveColorProvider(this, 2); + HHhmaskcieshape->setBottomBarColorProvider(this, 2); + maskcieHCurveEditorG->curveListComplete(); chromaskcie->setAdjusterListener(this); mask2cieCurveEditorG->setCurveListener(this); @@ -8121,6 +8579,24 @@ Locallabcie::Locallabcie(): mask2cieCurveEditorG->curveListComplete(); + mask2cieCurveEditorGwav->setCurveListener(this); + + LLmaskcieshapewav->setIdentityValue(0.); + LLmaskcieshapewav->setResetCurve(FlatCurveType(defSpot.LLmaskciecurvewav.at(0)), defSpot.LLmaskciecurvewav); + LLmaskcieshapewav->setBottomBarBgGradient({{0., 0., 0., 0.}, {1., 1., 1., 1.}}); + + mask2cieCurveEditorGwav->curveListComplete(); + csThresholdcie->setAdjusterListener(this); + + + strgradcie->setAdjusterListener(this); + anggradcie->setAdjusterListener(this); + ToolParamBlock* const cieBoxgrad = Gtk::manage(new ToolParamBlock()); + cieBoxgrad->pack_start(*strgradcie); + cieBoxgrad->pack_start(*anggradcie); + expgradcie->add(*cieBoxgrad, false); + pack_start(*expgradcie, false, false); + ToolParamBlock* const cieBox3 = Gtk::manage(new ToolParamBlock()); cieBox3->pack_start(*maskusablecie, Gtk::PACK_SHRINK, 0); cieBox3->pack_start(*maskunusablecie, Gtk::PACK_SHRINK, 0); @@ -8134,20 +8610,54 @@ Locallabcie::Locallabcie(): ToolParamBlock* const maskcieBox = Gtk::manage(new ToolParamBlock()); maskcieBox->pack_start(*showmaskcieMethod, Gtk::PACK_SHRINK, 4); maskcieBox->pack_start(*enacieMask, Gtk::PACK_SHRINK, 0); + maskcieBox->pack_start(*enacieMaskall, Gtk::PACK_SHRINK, 0); maskcieBox->pack_start(*maskcieCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + ToolParamBlock* const strumBoxcie = Gtk::manage(new ToolParamBlock()); + strumBoxcie->pack_start(*strumaskcie); + strumBoxcie->pack_start(*toolcie); + struFramecie->add(*strumBoxcie); + maskcieBox->pack_start(*struFramecie, Gtk::PACK_SHRINK, 0); + ToolParamBlock* const blurcieBox = Gtk::manage(new ToolParamBlock()); + blurcieBox->pack_start(*fftcieMask, Gtk::PACK_SHRINK, 0); + blurcieBox->pack_start(*contcie); + blurcieBox->pack_start(*blurcie); + blurFramecie->add(*blurcieBox); + maskcieBox->pack_start(*blurFramecie, Gtk::PACK_SHRINK, 0); + maskcieBox->pack_start(*blendmaskcie, Gtk::PACK_SHRINK, 0); maskcieBox->pack_start(*radmaskcie, Gtk::PACK_SHRINK, 0); - maskcieBox->pack_start(*lapmaskcie, Gtk::PACK_SHRINK, 0); + //maskcieBox->pack_start(*lapmaskcie, Gtk::PACK_SHRINK, 0); maskcieBox->pack_start(*chromaskcie, Gtk::PACK_SHRINK, 0); maskcieBox->pack_start(*gammaskcie, Gtk::PACK_SHRINK, 0); maskcieBox->pack_start(*slomaskcie, Gtk::PACK_SHRINK, 0); + maskcieBox->pack_start(*highmaskcie, Gtk::PACK_SHRINK, 0); + maskcieBox->pack_start(*shadmaskcie, Gtk::PACK_SHRINK, 0); + maskcieBox->pack_start(*maskcieHCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + maskcieBox->pack_start(*mask2cieCurveEditorG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + wavFramecie->set_label_align(0.025, 0.5); + ToolParamBlock* const toolcieBox2 = Gtk::manage(new ToolParamBlock()); + toolcieBox2->pack_start(*mask2cieCurveEditorGwav, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + toolcieBox2->pack_start(*csThresholdcie, Gtk::PACK_SHRINK, 0); + wavFramecie->add(*toolcieBox2); + maskcieBox->pack_start(*wavFramecie); + + expmaskcie->add(*maskcieBox, false); pack_start(*expmaskcie, false, false); - } +} + +void Locallabcie::setListener(ToolPanelListener* tpl) +{ + LocallabTool::setListener(tpl); + + // labgridcie->setListener(tpl); +} + + Locallabcie::~Locallabcie() { delete jz1CurveEditorG; @@ -8156,9 +8666,10 @@ Locallabcie::~Locallabcie() delete cieCurveEditorG; delete cieCurveEditorG2; delete maskcieCurveEditorG; + delete maskcieHCurveEditorG; delete mask2cieCurveEditorG; delete LocalcurveEditorwavjz; - + delete mask2cieCurveEditorGwav; } bool Locallabcie::isMaskViewActive() @@ -8177,7 +8688,7 @@ void Locallabcie::resetMaskView() void Locallabcie::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) { - cieMask = showmaskcieMethod->get_active_row_number(); + cieMask = showmaskcieMethod->get_active_row_number(); } void Locallabcie::setDefaultExpanderVisibility() @@ -8185,19 +8696,28 @@ void Locallabcie::setDefaultExpanderVisibility() expLcie->set_expanded(false); expjz->set_expanded(false); expwavjz->set_expanded(false); + expcamscene->set_expanded(false); expcam16->set_expanded(false); + expcamviewing->set_expanded(false); + expprecam->set_expanded(false); expmaskcie->set_expanded(false); exprecovcie->set_expanded(false); + expgradcie->set_expanded(false); } void Locallabcie::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { recothrescie->set_tooltip_text(M("TP_LOCALLAB_RECOTHRES02_TOOLTIP")); reparcie->set_tooltip_text(M("TP_LOCALLAB_LOGREPART_TOOLTIP")); - cieFrame->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); + // cieFrame->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); + expcamscene->set_tooltip_text(M("TP_LOCALLAB_LOGSCENE_TOOLTIP")); PQFrame->set_tooltip_text(M("TP_LOCALLAB_JZPQFRA_TOOLTIP")); qtoj->set_tooltip_text(M("TP_LOCALLAB_JZQTOJ_TOOLTIP")); logcie->set_tooltip_text(M("TP_LOCALLAB_LOGCIE_TOOLTIP")); + logcieq->set_tooltip_text(M("TP_LOCALLAB_LOGCIEQ_TOOLTIP")); + smoothcie->set_tooltip_text(M("TP_LOCALLAB_SMOOTHCIE_TOOLTIP")); + slopesmo->set_tooltip_text(M("TP_LOCALLAB_SMOOTHCIE_TOOLTIP")); + smoothciemet->set_tooltip_text(M("TP_LOCALLAB_SMOOTHCIE_TOOLTIP")); modecam->set_tooltip_text(M("TP_LOCALLAB_JZMODECAM_TOOLTIP")); adapjzcie->set_tooltip_text(M("TP_LOCALLAB_JABADAP_TOOLTIP")); jz100->set_tooltip_text(M("TP_LOCALLAB_JZ100_TOOLTIP")); @@ -8219,7 +8739,7 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) sourceGraycie->set_tooltip_text(M("TP_LOCALLAB_JZLOGYBOUT_TOOLTIP")); sourceabscie->set_tooltip_text(M("TP_COLORAPP_ADAPSCEN_TOOLTIP")); cie1Frame->set_tooltip_text(M("TP_LOCALLAB_LOGIMAGE_TOOLTIP")); - sigmoidFrame->set_tooltip_text(M("TP_LOCALLAB_SIGMOID_TOOLTIP")); + sigmoidFrame->set_tooltip_text(M("TP_LOCALLAB_SIGMOID16_TOOLTIP")); sigmoidjzFrame->set_tooltip_text(M("TP_LOCALLAB_SIGMOID_TOOLTIP")); contlcie->set_tooltip_text(M("TP_LOCALLAB_LOGCONTL_TOOLTIP")); contqcie->set_tooltip_text(M("TP_LOCALLAB_LOGCONTQ_TOOLTIP")); @@ -8234,7 +8754,8 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) targetGraycie->set_tooltip_text(M("TP_COLORAPP_YBOUT_TOOLTIP")); detailcie->set_tooltip_text(M("TP_LOCALLAB_LOGDETAIL_TOOLTIP")); catadcie->set_tooltip_text(M("TP_LOCALLAB_LOGCATAD_TOOLTIP")); - cie2Frame->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); + // cie2Frame->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); + expcamviewing->set_tooltip_text(M("TP_LOCALLAB_LOGVIEWING_TOOLTIP")); sensicie->set_tooltip_text(M("TP_LOCALLAB_SENSI_TOOLTIP")); CCmaskcieshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); LLmaskcieshape->setTooltip(M("TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP")); @@ -8245,16 +8766,41 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) mask2cieCurveEditorG->set_tooltip_text(M("TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP")); Lmaskcieshape->setTooltip(M("TP_LOCALLAB_LMASK_LL_TOOLTIP")); exprecovcie->set_tooltip_markup(M("TP_LOCALLAB_MASKRESH_TOOLTIP")); - + // expgradcie->set_tooltip_markup(M("TP_LOCALLAB_MASKRESH_TOOLTIP")); + strumaskcie->set_tooltip_text(M("TP_LOCALLAB_STRUSTRMASK_TOOLTIP")); + fftcieMask->set_tooltip_text(M("TP_LOCALLAB_FFTMASK_TOOLTIP")); + contcie->set_tooltip_text(M("TP_LOCALLAB_CONTTHMASK_TOOLTIP")); + blurcie->set_tooltip_text(M("TP_LOCALLAB_BLURRMASK_TOOLTIP")); + LLmaskcieshapewav->setTooltip(M("TP_LOCALLAB_LMASK_LEVEL_TOOLTIP")); + maskcieHCurveEditorG->set_tooltip_text(M("TP_LOCALLAB_HHMASK_TOOLTIP")); + comprcieth->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP")); + gamjcie->set_tooltip_text(M("TP_LOCALLAB_PRECAM_TOOLTIP")); + slopjcie->set_tooltip_text(M("TP_LOCALLAB_PRECAM_TOOLTIP")); + trcFrame->set_tooltip_text(M("TP_LOCALLAB_PRECAM_TOOLTIP")); + midtcie->set_tooltip_text(M("TP_LOCALLAB_PRECAM_TOOLTIP")); + whitescie->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP")); + blackscie->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP")); + normcie->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP")); + sigmoidblcie->set_tooltip_text(M("TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP")); + catBox->set_tooltip_text(M("TP_ICM_WORKING_CAT_TOOLTIP")); + wprimBox->set_tooltip_text(M("TP_ICM_WORKING_PRIM_TOOLTIP")); + expprecam->set_tooltip_text(M("TP_LOCALLAB_PRECAM_TOOLTIP")); + refi->set_tooltip_text(M("TP_LOCALLAB_PRECAMREFI_TOOLTIP")); + colorFramecie->set_tooltip_text(M("TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP")); + gamutcie->set_tooltip_text(M("TP_LOCALLAB_PRECAMGAMUT_TOOLTIP")); + shiftxl->set_tooltip_text(M("TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP")); + shiftyl->set_tooltip_text(M("TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP")); } else { reparcie->set_tooltip_text(""); recothrescie->set_tooltip_text(""); - cieFrame->set_tooltip_text(""); + // cieFrame->set_tooltip_text(""); + expcamscene->set_tooltip_text(""); PQFrame->set_tooltip_text(""); modecam->set_tooltip_text(""); qtoj->set_tooltip_text(""); logcie->set_tooltip_text(""); + logcieq->set_tooltip_text(""); jabcie->set_tooltip_text(""); adapjzcie->set_tooltip_text(""); jz100->set_tooltip_text(""); @@ -8283,7 +8829,8 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) targetGraycie->set_tooltip_text(""); detailcie->set_tooltip_text(""); catadcie->set_tooltip_text(""); - cie2Frame->set_tooltip_text(""); + // cie2Frame->set_tooltip_text(""); + expcamviewing->set_tooltip_text(""); sensicie->set_tooltip_text(""); CCmaskcieshape->setTooltip(""); LLmaskcieshape->setTooltip(""); @@ -8294,6 +8841,7 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) mask2cieCurveEditorG->set_tooltip_text(""); Lmaskcieshape->setTooltip(""); exprecovcie->set_tooltip_markup(""); + expgradcie->set_tooltip_markup(""); sigmalcjz->set_tooltip_text(""); clarilresjz->set_tooltip_text(""); claricresjz->set_tooltip_text(""); @@ -8302,6 +8850,32 @@ void Locallabcie::updateAdviceTooltips(const bool showTooltips) wavshapejz->setTooltip(""); LocalcurveEditorwavjz->set_tooltip_markup(""); csThresholdjz->set_tooltip_markup(""); + strumaskcie->set_tooltip_text(""); + fftcieMask->set_tooltip_text(""); + contcie->set_tooltip_text(""); + blurcie->set_tooltip_text(""); + LLmaskcieshapewav->setTooltip(""); + maskcieHCurveEditorG->set_tooltip_text(""); + comprcieth->set_tooltip_text(""); + gamjcie->set_tooltip_text(""); + slopjcie->set_tooltip_text(""); + trcFrame->set_tooltip_text(""); + midtcie->set_tooltip_text(""); + smoothcie->set_tooltip_text(""); + slopesmo->set_tooltip_text(""); + smoothciemet->set_tooltip_text(""); + whitescie->set_tooltip_text(""); + blackscie->set_tooltip_text(""); + normcie->set_tooltip_text(""); + sigmoidblcie->set_tooltip_text(""); + catBox->set_tooltip_text(""); + expprecam->set_tooltip_text(""); + wprimBox->set_tooltip_text(""); + refi->set_tooltip_text(""); + gamutcie->set_tooltip_text(""); + colorFramecie->set_tooltip_text(""); + shiftxl->set_tooltip_text(""); + shiftyl->set_tooltip_text(""); } } @@ -8313,20 +8887,35 @@ void Locallabcie::disableListener() forcebwConn.block(true); qtojConn.block(true); jabcieConn.block(true); - sigmoidqjcieconn.block(true); + comprcieautoconn.block(true); + normcieconn.block(true); + expprecamconn.block(true); + gamutcieconn.block(true); + primMethodconn.block(true); + illMethodconn.block(true); + smoothciemetconn.block(true); + catMethodconn.block(true); + sigcieconn.block(true); logcieconn.block(true); + satcieconn.block(true); + logcieqconn.block(true); + smoothcieconn.block(true); logjzconn.block(true); sigjzconn.block(true); sigqconn.block(true); chjzcieconn.block(true); - sursourcieconn.block (true); - surroundcieconn.block (true); - modecieconn.block (true); - modecamconn.block (true); + sursourcieconn.block(true); + surroundcieconn.block(true); + modecieconn.block(true); + modecamconn.block(true); + bwevMethodConn.block(true); toneMethodcieConn.block(true); toneMethodcieConn2.block(true); showmaskcieMethodConn.block(true); + toolcieConn.block(true); enacieMaskConn.block(true); + enacieMaskallConn.block(true); + fftcieMaskConn.block(true); } void Locallabcie::enableListener() @@ -8337,20 +8926,35 @@ void Locallabcie::enableListener() forcebwConn.block(false); qtojConn.block(false); jabcieConn.block(false); - sigmoidqjcieconn.block(false); + comprcieautoconn.block(false); + normcieconn.block(false); + expprecamconn.block(false); + gamutcieconn.block(false); + primMethodconn.block(false); + illMethodconn.block(false); + smoothciemetconn.block(false); + catMethodconn.block(false); + sigcieconn.block(false); logcieconn.block(false); + satcieconn.block(false); + logcieqconn.block(false); + smoothcieconn.block(false); logjzconn.block(false); sigjzconn.block(false); sigqconn.block(false); chjzcieconn.block(false); - sursourcieconn.block (false); - surroundcieconn.block (false); - modecieconn.block (false); - modecamconn.block (false); + sursourcieconn.block(false); + surroundcieconn.block(false); + modecieconn.block(false); + modecamconn.block(false); + bwevMethodConn.block(false); toneMethodcieConn.block(false); toneMethodcieConn2.block(false); showmaskcieMethodConn.block(false); + toolcieConn.block(false); enacieMaskConn.block(false); + enacieMaskallConn.block(false); + fftcieMaskConn.block(false); } void Locallabcie::showmaskcieMethodChanged() @@ -8362,7 +8966,7 @@ void Locallabcie::showmaskcieMethodChanged() locToolListener->resetOtherMaskView(this); } - if(exp->getEnabled()) { + if (exp->getEnabled()) { if (listener) { listener->panelChanged(EvlocallabshowmaskMethod, ""); } @@ -8395,12 +8999,117 @@ void Locallabcie::enacieMaskChanged() } } + +void Locallabcie::enacieMaskallChanged2() +{ + const LocallabParams::LocallabSpot defSpot; + + // if (modecam->get_active_row_number() == 1) { + if(!enacieMaskall->get_active()) { + lapmaskcie->setValue(defSpot.lapmaskcie); + gammaskcie->setValue(defSpot.gammaskcie); + slomaskcie->setValue(defSpot.slomaskcie); + highmaskcie->setValue(defSpot.highmaskcie); + shadmaskcie->setValue(defSpot.shadmaskcie); + HHhmaskcieshape->setCurve(defSpot.HHhmaskciecurve); + strumaskcie->setValue(defSpot.strumaskcie); + toolcie->set_active(defSpot.toolcie); + fftcieMask->set_active(defSpot.fftcieMask); + LLmaskcieshapewav->setCurve(defSpot.LLmaskciecurvewav); + lapmaskcie->hide(); + gammaskcie->hide(); + slomaskcie->hide(); + highmaskcie->hide(); + shadmaskcie->hide(); + maskcieHCurveEditorG->hide(); + struFramecie->hide(); + blurFramecie->hide(); + strumaskcie->hide(); + contcie->setValue(defSpot.contcie); + blurcie->setValue(defSpot.blurcie); + + toolcie->hide(); + fftcieMask->hide(); + mask2cieCurveEditorGwav->hide(); + wavFramecie->hide(); + } else { + lapmaskcie->show(); + gammaskcie->show(); + slomaskcie->show(); + highmaskcie->show(); + shadmaskcie->show(); + maskcieHCurveEditorG->show(); + struFramecie->show(); + blurFramecie->show(); + strumaskcie->show(); + toolcie->show(); + fftcieMask->show(); + mask2cieCurveEditorGwav->show(); + wavFramecie->show(); + } + // } +} + +void Locallabcie::enacieMaskallChanged() +{ + + enacieMaskallChanged2(); + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (enacieMaskall->get_active()) { + listener->panelChanged(EvlocallabenacieMaskall, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(EvlocallabenacieMaskall, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + + + +void Locallabcie::toolcieChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (toolcie->get_active()) { + listener->panelChanged(EvLocallabtoolcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(EvLocallabtoolcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + + +void Locallabcie::fftcieMaskChanged() +{ + // updateColorGUI3(); // Update GUI according to fftColorMash button state + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (fftcieMask->get_active()) { + listener->panelChanged(EvLocallabfftcieMask, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(EvLocallabfftcieMask, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + + void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { disableListener(); // Update GUI to selected spot value const int index = pp->locallab.selspot; + Glib::ustring prof = pp->icm.workingProfile; if (index < (int)pp->locallab.spots.size()) { const LocallabParams::LocallabSpot& spot = pp->locallab.spots.at(index); @@ -8408,28 +9117,25 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE exp->set_visible(spot.visicie); exp->setEnabled(spot.expcie); complexity->set_active(spot.complexcie); + expprecam->setEnabled(spot.expprecam); reparcie->setValue(spot.reparcie); sensicie->setValue(spot.sensicie); if (spot.modecam == "cam16") { - modecam->set_active (0); + modecam->set_active(0); } else if (spot.modecam == "jz") { - modecam->set_active (1); -// } else if (spot.modecam == "all") { -// modecam->set_active (2); -// } else if (spot.modecam == "zcam") { -// modecam->set_active (3); + modecam->set_active(1); } if (spot.modecie == "com") { - modecie->set_active (0); + modecie->set_active(0); } else if (spot.modecie == "tm") { - modecie->set_active (1); + modecie->set_active(1); } else if (spot.modecie == "wav") { - modecie->set_active (2); + modecie->set_active(2); } else if (spot.modecie == "dr") { - modecie->set_active (3); + modecie->set_active(3); // } else if (spot.modecie == "log") { // modecie->set_active (4); } @@ -8453,47 +9159,162 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE forcebw->set_active(spot.forcebw); qtoj->set_active(spot.qtoj); sourceGraycie->setValue(spot.sourceGraycie); - sigmoidqjcie->set_active(spot.sigmoidqjcie); + comprcieauto->set_active(spot.comprcieauto); + + if (Autograycie->get_active()) { + comprcieauto->set_active(true); + } + + if (spot.smoothciemet == "none") { + smoothciemet->set_active(0); + } else if (spot.smoothciemet == "Ev") { + smoothciemet->set_active(1); + } else if (spot.smoothciemet == "gam") { + smoothciemet->set_active(2); + } else if (spot.smoothciemet == "gamnorol") { + smoothciemet->set_active(3); + } + + + if (spot.illMethod == "d41") { + illMethod->set_active(0); + } else if (spot.illMethod == "d50") { + illMethod->set_active(1); + } else if (spot.illMethod == "d55") { + illMethod->set_active(2); + } else if (spot.illMethod == "d60") { + illMethod->set_active(3); + } else if (spot.illMethod == "d65") { + illMethod->set_active(4); + } else if (spot.illMethod == "d80") { + illMethod->set_active(5); + } else if (spot.illMethod == "d120") { + illMethod->set_active(6); + } else if (spot.illMethod == "stda") { + illMethod->set_active(7); + } else if (spot.illMethod == "T2000") { + illMethod->set_active(8); + } else if (spot.illMethod == "T1500") { + illMethod->set_active(9); + } else if (spot.illMethod == "iE") { + illMethod->set_active(10); + } + + illMethod->set_sensitive(false); + + if (spot.primMethod == "pro") { + primMethod->set_active(0); + illMethod->set_active(1); + } else if (spot.primMethod == "beta") { + primMethod->set_active(1); + illMethod->set_active(1); + } else if (spot.primMethod == "wid") { + primMethod->set_active(2); + illMethod->set_active(1); + } else if (spot.primMethod == "ac1") { + primMethod->set_active(3); + illMethod->set_active(3); + } else if (spot.primMethod == "rec") { + primMethod->set_active(4); + illMethod->set_active(4); + } else if (spot.primMethod == "ado") { + primMethod->set_active(5); + illMethod->set_active(4); + } else if (spot.primMethod == "srgb") { + primMethod->set_active(6); + illMethod->set_active(4); + } else if (spot.primMethod == "jdcmax") { + primMethod->set_active(7); + illMethod->set_active(1); + } else if (spot.primMethod == "jdcmaxstdA") { + primMethod->set_active(8); + illMethod->set_active(7); + } else if (spot.primMethod == "ac0") { + primMethod->set_active(9); + illMethod->set_active(3); + } else if (spot.primMethod == "best") { + primMethod->set_active(10); + illMethod->set_active(1); + } else if (spot.primMethod == "bru") { + primMethod->set_active(11); + illMethod->set_active(4); + } else if (spot.primMethod == "free") { + primMethod->set_active(9); + illMethod->set_sensitive(true); + + } + + if (spot.catMethod == "brad") { + catMethod->set_active(0); + } else if (spot.catMethod == "cat16") { + catMethod->set_active(1); + } else if (spot.catMethod == "cat02") { + catMethod->set_active(2); + } else if (spot.catMethod == "vky") { + catMethod->set_active(3); + } else if (spot.catMethod == "xyz") { + catMethod->set_active(4); + } + + + normcie->set_active(spot.normcie); + gamutcie->set_active(spot.gamutcie); + sigcie->set_active(spot.sigcie); logcie->set_active(spot.logcie); + satcie->set_active(spot.satcie); + logcieq->set_active(spot.logcieq); + smoothcie->set_active(spot.smoothcie); logjz->set_active(spot.logjz); sigjz->set_active(spot.sigjz); sigq->set_active(spot.sigq); - // chjzcie->set_active(spot.chjzcie); chjzcie->set_active(true);//force to true to avoid other mode sourceabscie->setValue(spot.sourceabscie); jabcie->set_active(spot.jabcie); jabcieChanged(); modecamChanged(); + sursourcieChanged(); + bwevMethodChanged(); + normcieChanged(); + expprecamChanged(); + gamutcieChanged(); + sigcieChanged(); + comprcieautoChanged(); + sigqChanged(); + logcieChanged(); + satcieChanged(); + logcieqChanged(); + smoothcieChanged(); + primMethodChanged(); + illMethodChanged(); + smoothciemetChanged(); - if(logcie->get_active()) { - sigmoidldacie->set_sensitive(false); - sigmoidthcie->set_sensitive(false); - sigmoidblcie->set_sensitive(false); - sigmoidqjcie->set_sensitive(false); - } else { - sigmoidldacie->set_sensitive(true); - sigmoidthcie->set_sensitive(true); - sigmoidblcie->set_sensitive(true); - sigmoidqjcie->set_sensitive(true); + if (spot.bwevMethod == "none") { + bwevMethod->set_active(0); + } else if (spot.bwevMethod == "sig") { + bwevMethod->set_active(1); } if (spot.sursourcie == "Average") { - sursourcie->set_active (0); + sursourcie->set_active(0); } else if (spot.sursourcie == "Dim") { - sursourcie->set_active (1); + sursourcie->set_active(1); } else if (spot.sursourcie == "Dark") { - sursourcie->set_active (2); + sursourcie->set_active(2); + } else if (spot.sursourcie == "exDark") { + sursourcie->set_active(3); + } else if (spot.sursourcie == "disacie") { + sursourcie->set_active(4); } + if (spot.surroundcie == "Average") { - surroundcie->set_active (0); + surroundcie->set_active(0); } else if (spot.surroundcie == "Dim") { - surroundcie->set_active (1); + surroundcie->set_active(1); } else if (spot.surroundcie == "Dark") { - surroundcie->set_active (2); -// } else if (spot.surroundcie == "ExtremelyDark") { -// surroundcie->set_active (3); + surroundcie->set_active(2); } + shapecie->setCurve(spot.ciecurve); shapecie2->setCurve(spot.ciecurve2); @@ -8517,8 +9338,10 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE lightlcie->setValue(spot.lightlcie); lightjzcie->setValue(spot.lightjzcie); lightqcie->setValue(spot.lightqcie); + lightsigqcie->setValue(spot.lightsigqcie); contlcie->setValue(spot.contlcie); contjzcie->setValue(spot.contjzcie); + detailciejz->setValue(spot.detailciejz); adapjzcie->setValue(spot.adapjzcie); jz100->setValue(spot.jz100); pqremap->setValue(spot.pqremap); @@ -8540,27 +9363,55 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE targetjz->setValue(spot.targetjz); sigmoidldacie->setValue(spot.sigmoidldacie); sigmoidthcie->setValue(spot.sigmoidthcie); + sigmoidsenscie->setValue(spot.sigmoidsenscie); sigmoidblcie->setValue(spot.sigmoidblcie); + comprcie->setValue(spot.comprcie); + strcielog->setValue(spot.strcielog); + comprcieth->setValue(spot.comprcieth); + gamjcie->setValue(spot.gamjcie); + slopjcie->setValue(spot.slopjcie); + slopesmo->setValue(spot.slopesmo); + midtcie->setValue(spot.midtcie); + whitescie->setValue(spot.whitescie); + blackscie->setValue(spot.blackscie); sigmoidldajzcie->setValue(spot.sigmoidldajzcie); sigmoidthjzcie->setValue(spot.sigmoidthjzcie); sigmoidbljzcie->setValue(spot.sigmoidbljzcie); contqcie->setValue(spot.contqcie); + contsigqcie->setValue(spot.contsigqcie); colorflcie->setValue(spot.colorflcie); targabscie->setValue(spot.targabscie); targetGraycie->setValue(spot.targetGraycie); detailcie->setValue(spot.detailcie); catadcie->setValue(spot.catadcie); -/* - lightlzcam->setValue(spot.lightlzcam); - lightqzcam->setValue(spot.lightqzcam); - contlzcam->setValue(spot.contlzcam); - contqzcam->setValue(spot.contqzcam); - contthreszcam->setValue(spot.contthreszcam); - colorflzcam->setValue(spot.colorflzcam); - saturzcam->setValue(spot.saturzcam); - chromzcam->setValue(spot.chromzcam); -*/ + + grexl->setValue(spot.grexl); + greyl->setValue(spot.greyl); + bluxl->setValue(spot.bluxl); + bluyl->setValue(spot.bluyl); + redxl->setValue(spot.redxl); + redyl->setValue(spot.redyl); + refi->setValue(spot.refi); + shiftxl->setValue(spot.shiftxl); + shiftyl->setValue(spot.shiftyl); + + labgridcie->setParams(spot.labgridcieALow, + spot.labgridcieBLow, + spot.labgridcieAHigh, + spot.labgridcieBHigh, + spot.labgridcieGx, + spot.labgridcieGy, + spot.labgridcieWx, + spot.labgridcieWy, + spot.labgridcieMx, + spot.labgridcieMy, + false); + + strgradcie->setValue((double)spot.strgradcie); + anggradcie->setValue((double)spot.anggradcie); + enacieMask->set_active(spot.enacieMask); + enacieMaskall->set_active(spot.enacieMaskall); CCmaskcieshape->setCurve(spot.CCmaskciecurve); LLmaskcieshape->setCurve(spot.LLmaskciecurve); HHmaskcieshape->setCurve(spot.HHmaskciecurve); @@ -8570,14 +9421,26 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE lapmaskcie->setValue(spot.lapmaskcie); gammaskcie->setValue(spot.gammaskcie); slomaskcie->setValue(spot.slomaskcie); + highmaskcie->setValue(spot.highmaskcie); + shadmaskcie->setValue(spot.shadmaskcie); + HHhmaskcieshape->setCurve(spot.HHhmaskciecurve); Lmaskcieshape->setCurve(spot.Lmaskciecurve); recothrescie->setValue((double)spot.recothrescie); lowthrescie->setValue((double)spot.lowthrescie); higthrescie->setValue((double)spot.higthrescie); decaycie->setValue((double)spot.decaycie); + strumaskcie->setValue(spot.strumaskcie); + toolcie->set_active(spot.toolcie); + fftcieMask->set_active(spot.fftcieMask); + contcie->setValue(spot.contcie); +// updateColorGUI3(); + blurcie->setValue(spot.blurcie); + LLmaskcieshapewav->setCurve(spot.LLmaskciecurvewav); + csThresholdcie->setValue(spot.csthresholdcie); } + enableListener(); // Update GUI according to complexity mode updateGUIToMode(static_cast(complexity->get_active_row_number())); @@ -8587,13 +9450,14 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) { - const int index = pp->locallab.selspot; + const int index = pp->locallab.selspot; if (index < (int)pp->locallab.spots.size()) { LocallabParams::LocallabSpot& spot = pp->locallab.spots.at(index); spot.expcie = exp->getEnabled(); spot.visicie = exp->get_visible(); spot.complexcie = complexity->get_active_row_number(); + spot.expprecam = expprecam->getEnabled(); spot.reparcie = reparcie->getValue(); spot.sensicie = sensicie->getIntValue(); @@ -8602,10 +9466,6 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.modecam = "cam16"; } else if (modecam->get_active_row_number() == 1) { spot.modecam = "jz"; -// } else if (modecam->get_active_row_number() == 2) { -// spot.modecam = "all"; -// } else if (modecam->get_active_row_number() == 3) { -// spot.modecam = "zcam"; } if (modecie->get_active_row_number() == 0) { @@ -8634,6 +9494,26 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.toneMethodcie2 = "thrc"; } + spot.redxl = redxl->getValue(); + spot.redyl = redyl->getValue(); + spot.grexl = grexl->getValue(); + spot.greyl = greyl->getValue(); + spot.bluxl = bluxl->getValue(); + spot.bluyl = bluyl->getValue(); + spot.refi = refi->getValue(); + spot.shiftxl = shiftxl->getValue(); + spot.shiftyl = shiftyl->getValue(); + labgridcie->getParams(spot.labgridcieALow, + spot.labgridcieBLow, + spot.labgridcieAHigh, + spot.labgridcieBHigh, + spot.labgridcieGx, + spot.labgridcieGy, + spot.labgridcieWx, + spot.labgridcieWy, + spot.labgridcieMx, + spot.labgridcieMy); + spot.Autograycie = Autograycie->get_active(); spot.forcejz = forcejz->get_active(); spot.forcebw = forcebw->get_active(); @@ -8641,19 +9521,109 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.jabcie = jabcie->get_active(); spot.sourceGraycie = sourceGraycie->getValue(); spot.sourceabscie = sourceabscie->getValue(); - spot.sigmoidqjcie = sigmoidqjcie->get_active(); + spot.comprcieauto = comprcieauto->get_active(); + spot.normcie = normcie->get_active(); + spot.gamutcie = gamutcie->get_active(); + spot.sigcie = sigcie->get_active(); spot.logcie = logcie->get_active(); + spot.satcie = satcie->get_active(); + spot.logcieq = logcieq->get_active(); + spot.smoothcie = smoothcie->get_active(); spot.logjz = logjz->get_active(); spot.sigjz = sigjz->get_active(); spot.chjzcie = chjzcie->get_active(); spot.sigq = sigq->get_active(); - if(sursourcie->get_active_row_number() == 0) { + if (sursourcie->get_active_row_number() == 0) { spot.sursourcie = "Average"; } else if (sursourcie->get_active_row_number() == 1) { spot.sursourcie = "Dim"; } else if (sursourcie->get_active_row_number() == 2) { spot.sursourcie = "Dark"; + } else if (sursourcie->get_active_row_number() == 3) { + spot.sursourcie = "exDark"; + } else if (sursourcie->get_active_row_number() == 4) { + spot.sursourcie = "disacie"; + } + + if (bwevMethod->get_active_row_number() == 0) { + spot.bwevMethod = "none"; + } else if (bwevMethod->get_active_row_number() == 1) { + spot.bwevMethod = "sig"; + } + + if (smoothciemet->get_active_row_number() == 0) { + spot.smoothciemet = "none"; + } else if (smoothciemet->get_active_row_number() == 1) { + spot.smoothciemet = "Ev"; + } else if (smoothciemet->get_active_row_number() == 2) { + spot.smoothciemet = "gam"; + } else if (smoothciemet->get_active_row_number() == 3) { + spot.smoothciemet = "gamnorol"; + } + + if (illMethod->get_active_row_number() == 0) { + spot.illMethod = "d41"; + } else if (illMethod->get_active_row_number() == 1) { + spot.illMethod = "d50"; + } else if (illMethod->get_active_row_number() == 2) { + spot.illMethod = "d55"; + } else if (illMethod->get_active_row_number() == 3) { + spot.illMethod = "d60"; + } else if (illMethod->get_active_row_number() == 4) { + spot.illMethod = "d65"; + } else if (illMethod->get_active_row_number() == 5) { + spot.illMethod = "d80"; + } else if (illMethod->get_active_row_number() == 6) { + spot.illMethod = "d120"; + } else if (illMethod->get_active_row_number() == 7) { + spot.illMethod = "stda"; + } else if (illMethod->get_active_row_number() == 8) { + spot.illMethod = "T2000"; + } else if (illMethod->get_active_row_number() == 9) { + spot.illMethod = "T1500"; + } else if (illMethod->get_active_row_number() == 10) { + spot.illMethod = "iE"; + } + + if (primMethod->get_active_row_number() == 0) { + spot.primMethod = "pro"; + } else if (primMethod->get_active_row_number() == 1) { + spot.primMethod = "beta"; + } else if (primMethod->get_active_row_number() == 2) { + spot.primMethod = "wid"; + } else if (primMethod->get_active_row_number() == 3) { + spot.primMethod = "ac1"; + } else if (primMethod->get_active_row_number() == 4) { + spot.primMethod = "rec"; + } else if (primMethod->get_active_row_number() == 5) { + spot.primMethod = "ado"; + } else if (primMethod->get_active_row_number() == 6) { + spot.primMethod = "srgb"; + } else if (primMethod->get_active_row_number() == 7) { + spot.primMethod = "jdcmax"; + } else if (primMethod->get_active_row_number() == 8) { + spot.primMethod = "jdcmaxstdA"; + } else if (primMethod->get_active_row_number() == 9) { + spot.primMethod = "ac0"; + } else if (primMethod->get_active_row_number() == 10) { + spot.primMethod = "best"; + } else if (primMethod->get_active_row_number() == 11) { + spot.primMethod = "bru"; + } else if (primMethod->get_active_row_number() == 12) { + spot.primMethod = "free"; + } + + if (catMethod->get_active_row_number() == 0) { + spot.catMethod = "brad"; + } else if (catMethod->get_active_row_number() == 1) { + spot.catMethod = "cat16"; + } else if (catMethod->get_active_row_number() == 2) { + spot.catMethod = "cat02"; + } else if (catMethod->get_active_row_number() == 3) { + spot.catMethod = "vky"; + } else if (catMethod->get_active_row_number() == 4) { + spot.catMethod = "xyz"; } if (surroundcie->get_active_row_number() == 0) { @@ -8662,9 +9632,8 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.surroundcie = "Dim"; } else if (surroundcie->get_active_row_number() == 2) { spot.surroundcie = "Dark"; -// } else if (surroundcie->get_active_row_number() == 3) { -// spot.surroundcie = "ExtremelyDark"; } + spot.jzcurve = shapejz->getCurve(); spot.czcurve = shapecz->getCurve(); spot.czjzcurve = shapeczjz->getCurve(); @@ -8687,7 +9656,9 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.lightlcie = lightlcie->getValue(); spot.lightjzcie = lightjzcie->getValue(); spot.lightqcie = lightqcie->getValue(); + spot.lightsigqcie = lightsigqcie->getValue(); spot.contlcie = contlcie->getValue(); + spot.detailciejz = detailciejz->getValue(); spot.contjzcie = contjzcie->getValue(); spot.adapjzcie = adapjzcie->getValue(); spot.jz100 = jz100->getValue(); @@ -8710,27 +9681,32 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.targetjz = targetjz->getValue(); spot.sigmoidldacie = sigmoidldacie->getValue(); spot.sigmoidthcie = sigmoidthcie->getValue(); + spot.sigmoidsenscie = sigmoidsenscie->getValue(); spot.sigmoidblcie = sigmoidblcie->getValue(); + spot.comprcie = comprcie->getValue(); + spot.strcielog = strcielog->getValue(); + spot.comprcieth = comprcieth->getValue(); + spot.gamjcie = gamjcie->getValue(); + spot.slopjcie = slopjcie->getValue(); + spot.slopesmo = slopesmo->getValue(); + spot.midtcie = midtcie->getIntValue(); + spot.whitescie = whitescie->getIntValue(); + spot.blackscie = blackscie->getIntValue(); spot.sigmoidldajzcie = sigmoidldajzcie->getValue(); spot.sigmoidthjzcie = sigmoidthjzcie->getValue(); spot.sigmoidbljzcie = sigmoidbljzcie->getValue(); spot.contqcie = contqcie->getValue(); + spot.contsigqcie = contsigqcie->getValue(); spot.colorflcie = colorflcie->getValue(); spot.targabscie = targabscie->getValue(); spot.targetGraycie = targetGraycie->getValue(); spot.catadcie = catadcie->getValue(); spot.detailcie = detailcie->getValue(); -/* - spot.lightlzcam = lightlzcam->getValue(); - spot.lightqzcam = lightqzcam->getValue(); - spot.contlzcam = contlzcam->getValue(); - spot.contqzcam = contqzcam->getValue(); - spot.contthreszcam = contthreszcam->getValue(); - spot.colorflzcam = colorflzcam->getValue(); - spot.saturzcam = saturzcam->getValue(); - spot.chromzcam = chromzcam->getValue(); -*/ + spot.strgradcie = strgradcie->getValue(); + spot.anggradcie = anggradcie->getValue(); + spot.enacieMask = enacieMask->get_active(); + spot.enacieMaskall = enacieMaskall->get_active(); spot.LLmaskciecurve = LLmaskcieshape->getCurve(); spot.CCmaskciecurve = CCmaskcieshape->getCurve(); spot.HHmaskciecurve = HHmaskcieshape->getCurve(); @@ -8740,11 +9716,21 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.lapmaskcie = lapmaskcie->getValue(); spot.gammaskcie = gammaskcie->getValue(); spot.slomaskcie = slomaskcie->getValue(); + spot.highmaskcie = highmaskcie->getValue(); + spot.shadmaskcie = shadmaskcie->getValue(); + spot.HHhmaskciecurve = HHhmaskcieshape->getCurve(); spot.Lmaskciecurve = Lmaskcieshape->getCurve(); spot.recothrescie = recothrescie->getValue(); spot.lowthrescie = lowthrescie->getValue(); spot.higthrescie = higthrescie->getValue(); spot.decaycie = decaycie->getValue(); + spot.strumaskcie = strumaskcie->getValue(); + spot.toolcie = toolcie->get_active(); + spot.fftcieMask = fftcieMask->get_active(); + spot.contcie = contcie->getValue(); + spot.blurcie = blurcie->getValue(); + spot.LLmaskciecurvewav = LLmaskcieshapewav->getCurve(); + spot.csthresholdcie = csThresholdcie->getValue(); } } @@ -8789,10 +9775,96 @@ void Locallabcie::updateMaskBackground(const double normChromar, const double no LLmaskcieshape->updateLocallabBackground(normLumar); HHmaskcieshape->updateLocallabBackground(normHuer); Lmaskcieshape->updateLocallabBackground(normLumar); + HHhmaskcieshape->updateLocallabBackground(normHuer); + return false; + } + ); +} + +void Locallabcie::updatePrimloc(const float redx, const float redy, const float grex, const float grey, const float blux, const float bluy) +{ + idle_register.add( + [this, redx, redy, grex, grey, blux, bluy]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update adjuster values according to autocomputed ones + disableListener(); + redxl->setValue(redx); + redyl->setValue(redy); + grexl->setValue(grex); + greyl->setValue(grey); + bluxl->setValue(blux); + bluyl->setValue(bluy); + + enableListener(); return false; } - ); + ); + +} + +void Locallabcie::updatesigloc(const float cont_sig, const float light_sig) +{ + idle_register.add( + [this, cont_sig, light_sig]() -> bool { + GThreadLock lock; + disableListener(); + + contsigqcie->setValue(cont_sig); + lightsigqcie->setValue(light_sig); + + enableListener(); + return false; + } + ); + +} + + + +void Locallabcie::updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y) +{ + nextrx = r_x; + nextry = r_y; + nextbx = b_x; + nextby = b_y; + nextgx = g_x; + nextgy = g_y; + nextwx = w_x; + nextwy = w_y; + nextmx = m_x; + nextmy = m_y; + + //convert xy datas in datas for labgrid areas + nextrx = 1.81818f * (nextrx + 0.1f) - 1.f; + nextry = 1.81818f * (nextry + 0.1f) - 1.f; + nextbx = 1.81818f * (nextbx + 0.1f) - 1.f; + nextby = 1.81818f * (nextby + 0.1f) - 1.f; + nextgx = 1.81818f * (nextgx + 0.1f) - 1.f; + nextgy = 1.81818f * (nextgy + 0.1f) - 1.f; + nextwx = 1.81818f * (nextwx + 0.1f) - 1.f; + nextwy = 1.81818f * (nextwy + 0.1f) - 1.f; + nextmx = 1.81818f * (nextmx + 0.1f) - 1.f; + nextmy = 1.81818f * (nextmy + 0.1f) - 1.f; + + idle_register.add( + [this, r_x, r_y, g_x, g_y, b_x, b_y]() -> bool { + GThreadLock lock; + disableListener(); + + redxl->setValue(r_x); + redyl->setValue(r_y); + grexl->setValue(g_x); + greyl->setValue(g_y); + bluxl->setValue(b_x); + bluyl->setValue(b_y); + labgridcie->setParams(nextrx, nextry, nextbx, nextby, nextgx, nextgy, nextwx, nextwy, nextmx, nextmy, false); + enableListener(); + return false; + } + ); + } @@ -8818,12 +9890,10 @@ void Locallabcie::updateAutocompute(const float blackev, const float whiteev, co return false; } - ); + ); } } - - void Locallabcie::AutograycieChanged() { @@ -8834,6 +9904,11 @@ void Locallabcie::AutograycieChanged() jz100->set_sensitive(false); blackEvjz->set_sensitive(false); whiteEvjz->set_sensitive(false); + + comprcieauto->set_active(true); + whitescie->set_sensitive(true); + blackscie->set_sensitive(true); + } else { sourceGraycie->set_sensitive(true); sourceabscie->set_sensitive(true); @@ -8841,9 +9916,10 @@ void Locallabcie::AutograycieChanged() jz100->set_sensitive(true); blackEvjz->set_sensitive(true); whiteEvjz->set_sensitive(true); - // adapjzcie->set_sensitive(false); - // jz100->set_sensitive(false); + whitescie->set_sensitive(false); + blackscie->set_sensitive(false); } + if (isLocActivated && exp->getEnabled()) { if (listener) { if (Autograycie->get_active()) { @@ -8920,36 +9996,107 @@ void Locallabcie::jabcieChanged() } } -void Locallabcie::sigmoidqjcieChanged() +void Locallabcie::comprcieautoChanged() { + if (isLocActivated && exp->getEnabled()) { if (listener) { - if (sigmoidqjcie->get_active()) { - listener->panelChanged(Evlocallabsigmoidqjcie, + if (comprcieauto->get_active()) { + listener->panelChanged(Evlocallabcomprcieauto, M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); } else { - listener->panelChanged(Evlocallabsigmoidqjcie, + listener->panelChanged(Evlocallabcomprcieauto, M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); } } } } -void Locallabcie::logcieChanged() +void Locallabcie::normcieChanged() { - if(logcie->get_active()) { - sigmoidldacie->set_sensitive(false); - sigmoidthcie->set_sensitive(false); - sigmoidblcie->set_sensitive(false); - sigmoidqjcie->set_sensitive(false); - } else { - sigmoidldacie->set_sensitive(true); - sigmoidthcie->set_sensitive(true); + if (normcie->get_active()) { sigmoidblcie->set_sensitive(true); - sigmoidqjcie->set_sensitive(true); + } else { + sigmoidblcie->set_sensitive(false); } + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (normcie->get_active()) { + listener->panelChanged(Evlocallabnormcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabnormcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + +} + + +void Locallabcie::gamutcieChanged() +{ + if (gamutcie->get_active()) { + catBox->set_sensitive(true); + } else { + catBox->set_sensitive(false); + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (gamutcie->get_active()) { + listener->panelChanged(Evlocallabgamutcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabgamutcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + +} + +void Locallabcie::expprecamChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (expprecam->getEnabled()) { + listener->panelChanged(Evlocallabexpprecam, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabexpprecam, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + +} + + +void Locallabcie::sigcieChanged() +{ + contsigqcie->hide(); + lightsigqcie->hide(); + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (sigcie->get_active()) { + listener->panelChanged(Evlocallabsigcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsigcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + +} + + +void Locallabcie::logcieChanged() +{ if (isLocActivated && exp->getEnabled()) { if (listener) { if (logcie->get_active()) { @@ -8963,6 +10110,60 @@ void Locallabcie::logcieChanged() } } +void Locallabcie::satcieChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (satcie->get_active()) { + listener->panelChanged(Evlocallabsatcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsatcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + +void Locallabcie::logcieqChanged() +{ + if (logcieq->get_active()) { + satcie->hide(); + sigmoidnormFrame->hide(); + } else { + satcie->show(); + sigmoidnormFrame->show(); + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (logcieq->get_active()) { + listener->panelChanged(Evlocallablogcieq, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallablogcieq, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + + +void Locallabcie::smoothcieChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (smoothcie->get_active()) { + listener->panelChanged(Evlocallabsmoothcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsmoothcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + void Locallabcie::logjzChanged() { if (isLocActivated && exp->getEnabled()) { @@ -8995,6 +10196,9 @@ void Locallabcie::sigjzChanged() void Locallabcie::sigqChanged() { + contsigqcie->hide(); + lightsigqcie->hide(); + if (isLocActivated && exp->getEnabled()) { if (listener) { if (sigq->get_active()) { @@ -9015,6 +10219,7 @@ void Locallabcie::chjzcieChanged() } else { thrhjzcie->set_sensitive(false); } + if (isLocActivated && exp->getEnabled()) { if (listener) { if (chjzcie->get_active()) { @@ -9031,8 +10236,11 @@ void Locallabcie::chjzcieChanged() void Locallabcie::modecamChanged() { const int mode = complexity->get_active_row_number(); + contsigqcie->hide(); + lightsigqcie->hide(); + const LocallabParams::LocallabSpot defSpot; - if (modecam->get_active_row_number() == 1 || modecam->get_active_row_number() == 2) { + if (modecam->get_active_row_number() == 1) { expjz->show(); jzFrame->show(); adapjzcie->show(); @@ -9045,82 +10253,74 @@ void Locallabcie::modecamChanged() sigmoidjzFrame->show(); sigmoidFrame->hide(); forcejz->hide(); + expprecam->hide(); + expcam16->hide(); + expcamviewing->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); } else { expjz->hide(); + lapmaskcie->show(); + jzFrame->hide(); adapjzcie->hide(); jz100->hide(); pqremap->hide(); - pqremapcam16->show(); + + if (mode == Expert) { + pqremapcam16->show(); + } else { + pqremapcam16->hide(); + } + jabcie->hide(); PQFrame->hide(); logjzFrame->hide(); - if (modecam->get_active_row_number() == 0){ + + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); sigmoidFrame->show(); + expprecam->show(); + } + sigmoidjzFrame->hide(); forcejz->hide(); catadcie->show(); } + surHBoxcie->show(); cie1Frame->show(); expcam16->show(); - cie2Frame->show(); + expcamviewing->show(); sourceGraycie->show(); - cieFrame->show(); + expcamscene->show(); if (modecam->get_active_row_number() == 1) { + guijzczhz(); surHBoxcie->show(); - cie1Frame->hide(); - expcam16->hide(); - targetGraycie->hide(); - targabscie->hide(); - surrHBoxcie->hide(); - forcejz->hide(); - pqremapcam16->hide(); - catadcie->hide(); - cie2Frame->hide(); - exprecovcie->hide(); - expmaskcie->hide(); - if(mode == Expert) { + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + + if (mode == Expert) { exprecovcie->show(); expmaskcie->show(); + expgradcie->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + } - } - if (modecam->get_active_row_number() == 3) { - if(mode == Expert) { - cieFrame->show(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->show(); - targetGraycie->show(); - targabscie->show(); - surrHBoxcie->show(); - PQFrame->show(); - logjzFrame->show(); - adapjzcie->hide(); - jz100->hide(); - forcejz->hide(); - pqremap->show(); - pqremapcam16->hide(); - catadcie->hide(); - cie2Frame->hide(); - - } else { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->hide(); - catadcie->hide(); - cie2Frame->hide(); - - } + } else if (mode != Simple){ + exprecovcie->show(); + expgradcie->show(); + expmaskcie->show(); } - if(mode != Expert) { + + if (mode != Expert) { expjz->hide(); jzFrame->hide(); adapjzcie->hide(); @@ -9132,33 +10332,54 @@ void Locallabcie::modecamChanged() sigmoidjzFrame->hide(); sigmoidFrame->hide(); bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ + + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); sigmoidFrame->show(); } forcejz->hide(); - pqremapcam16->show(); + + if (mode == Expert) { + pqremapcam16->show(); + } else { + pqremapcam16->hide(); + } + catadcie->show(); sourceGraycie->show(); - if (modecam->get_active_row_number() == 1 || modecam->get_active_row_number() == 3) { + if (modecam->get_active_row_number() == 1) { pqremapcam16->hide(); - cieFrame->hide(); + expcamscene->hide(); cie1Frame->hide(); expcam16->hide(); - cie2Frame->hide(); + expcamviewing->hide(); catadcie->hide(); - cie2Frame->hide(); + expgradcie->hide(); + expcam16->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + + } else if (mode != Simple){ + exprecovcie->show(); + expgradcie->show(); + expmaskcie->show(); } } else { - cieFrame->show(); - cie2Frame->show(); - if (modecam->get_active_row_number() == 0){ + expcamscene->show(); + expcamviewing->show(); + + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); sigmoidjzFrame->hide(); + expprecam->show(); + lapmaskcie->show(); + } + if (modecam->get_active_row_number() == 1) { targetGraycie->hide(); targabscie->hide(); @@ -9171,7 +10392,13 @@ void Locallabcie::modecamChanged() sigmoidFrame->hide(); bevwevFrame->show(); catadcie->hide(); - cie2Frame->hide(); + expcamviewing->hide(); + expgradcie->hide(); + expcam16->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + if (chjzcie->get_active()) { thrhjzcie->set_sensitive(true); } else { @@ -9180,34 +10407,35 @@ void Locallabcie::modecamChanged() } - if (modecam->get_active_row_number() == 3) { - cieFrame->show(); - cie2Frame->show(); - targetGraycie->show(); - targabscie->show(); - surrHBoxcie->show(); - PQFrame->show(); - logjzFrame->show(); - adapjzcie->hide(); - jz100->hide(); - forcejz->hide(); - pqremap->show(); - pqremapcam16->hide(); - catadcie->hide(); - cie2Frame->hide(); - } + } - if (modecam->get_active_row_number() == 0 || modecam->get_active_row_number() == 2) { - targetGraycie->show(); - targabscie->show(); - surrHBoxcie->show(); - cie2Frame->show(); - pqremapcam16->show(); + + if (modecam->get_active_row_number() == 0) { + targetGraycie->show(); + targabscie->show(); + surrHBoxcie->show(); + expprecam->show(); + expcamviewing->show(); + if (mode != Simple){ + exprecovcie->show(); + expgradcie->show(); + expmaskcie->show(); } + if (mode == Expert) { + pqremapcam16->show(); + } else { + pqremapcam16->hide(); + } + } + + contsigqcie->hide(); + lightsigqcie->hide(); + + if (isLocActivated && exp->getEnabled()) { if (listener) { @@ -9223,26 +10451,34 @@ void Locallabcie::modecieChanged() if (isLocActivated && exp->getEnabled()) { const int mode = complexity->get_active_row_number(); - exprecovcie->show(); - expmaskcie->show(); + exprecovcie->show(); + expmaskcie->show(); + expgradcie->show(); - if (modecie->get_active_row_number() > 0) { + if (modecie->get_active_row_number() > 0 && mode == Expert) { sensicie->hide(); reparcie->hide(); - exprecovcie->hide(); - expmaskcie->hide(); + exprecovcie->show(); + expmaskcie->show(); + expgradcie->hide(); } else { sensicie->show(); reparcie->show(); - if(mode == Expert) { + + if (mode == Expert) { exprecovcie->show(); expmaskcie->show(); + expgradcie->show(); } } + + contsigqcie->hide(); + lightsigqcie->hide(); + if (mode == Simple || mode == Normal) { // Keep widget hidden in Normal and Simple mode - modecie->set_active (0); + modecie->set_active(0); sensicie->show(); reparcie->show(); @@ -9259,6 +10495,22 @@ void Locallabcie::modecieChanged() void Locallabcie::sursourcieChanged() { + const LocallabParams::LocallabSpot defSpot; + + if (sursourcie->get_active_row_number() == 4) { + expcam16->hide(); + expcamviewing->hide(); + } else { + expcam16->show(); + expcamviewing->show(); + if(modecam->get_active_row_number() == 1) { + expcam16->hide(); + expcamviewing->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + } + } + if (isLocActivated && exp->getEnabled()) { if (listener) { listener->panelChanged(Evlocallabsursourcie, @@ -9267,6 +10519,120 @@ void Locallabcie::sursourcieChanged() } } +void Locallabcie::catMethodChanged() +{ + + if (listener) { + listener->panelChanged(Evlocallabcatcie, catMethod->get_active_text()); + } + +} + +void Locallabcie::illMethodChanged() +{ + + if (listener) { + listener->panelChanged(Evlocallabillcie, illMethod->get_active_text()); + } + +} + +void Locallabcie::smoothciemetChanged() +{ + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } + + if (listener) { + listener->panelChanged(Evlocallabsmoothciemet, smoothciemet->get_active_text()); + } + +} + + +void Locallabcie::primMethodChanged() +{ + + if (primMethod->get_active_row_number() == 0) { + illMethod->set_active(1); + } else if (primMethod->get_active_row_number() == 1) { + illMethod->set_active(1); + } else if (primMethod->get_active_row_number() == 2) { + illMethod->set_active(1); + } else if (primMethod->get_active_row_number() == 3) { + illMethod->set_active(3); + } else if (primMethod->get_active_row_number() == 4) { + illMethod->set_active(4); + } else if (primMethod->get_active_row_number() == 5) { + illMethod->set_active(4); + } else if (primMethod->get_active_row_number() == 6) { + illMethod->set_active(4); + } else if (primMethod->get_active_row_number() == 7) { + illMethod->set_active(1); + } else if (primMethod->get_active_row_number() == 8) { + illMethod->set_active(7); + } else if (primMethod->get_active_row_number() == 9) { + illMethod->set_active(3); + } else if (primMethod->get_active_row_number() == 10) { + illMethod->set_active(1); + } else if (primMethod->get_active_row_number() == 11) { + illMethod->set_active(4); + } + + illMethod->set_sensitive(false); + + if (primMethod->get_active_row_number() == 12) { + redBox->set_sensitive(true); + illMethod->set_sensitive(true); + + } else { + redBox->set_sensitive(false); + } + + if (listener) { + listener->panelChanged(Evlocallabprimcie, primMethod->get_active_text()); + } + +} + +void Locallabcie::bwevMethodChanged() +{ + const LocallabParams::LocallabSpot defSpot; + const int mode = complexity->get_active_row_number(); + + if (bwevMethod->get_active_row_number() == 2) {// && sigcie->get_active()) { + comprcie->set_sensitive(true); + comprcieth->set_sensitive(true); + comprcieauto->set_sensitive(true); + comprcieauto->set_active(true); + + if (mode == Simple) { + comprcieth->set_sensitive(false); + comprcieauto->set_sensitive(false); + } + + } else { + comprcieth->set_sensitive(false); + comprcieauto->set_sensitive(false); + } + + if (bwevMethod->get_active_row_number() == 2) { + comprcie->setValue(defSpot.comprcie);//to test + } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + listener->panelChanged(EvlocallabbwevMethod, + bwevMethod->get_active_text() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } +} + + void Locallabcie::surroundcieChanged() { if (isLocActivated && exp->getEnabled()) { @@ -9277,8 +10643,37 @@ void Locallabcie::surroundcieChanged() } } +void Locallabcie::guijzczhz() +{ + expcamscene->hide(); + cie1Frame->hide(); + expcam16->hide(); + forcejz->hide(); + pqremapcam16->hide(); + PQFrame->hide(); + logjzFrame->hide(); + bevwevFrame->hide(); + sigmoidjzFrame->hide(); + sigmoidFrame->hide(); + catadcie->hide(); + expcamviewing->hide(); + maskusablecie->hide(); + maskunusablecie->hide(); + decaycie->hide(); + expmaskcie->hide(); + expprecam->hide(); + exprecovcie->hide(); + expgradcie->hide(); + lapmaskcie->hide(); +} + + + + void Locallabcie::updateGUIToMode(const modeType new_type) { + const LocallabParams::LocallabSpot defSpot; + switch (new_type) { case Simple: catadcie->show(); @@ -9297,102 +10692,122 @@ void Locallabcie::updateGUIToMode(const modeType new_type) surHBoxcie->show(); sourceabscie->show(); targabscie->show(); - detailcie->hide(); + detailcie->show(); //hide jabcie->hide(); modeHBoxcie->hide(); sensicie->show(); reparcie->show(); - sigmoidblcie->hide(); - + sigmoidsenscie->hide(); + sigmoidnormFrame->hide(); + pqremapcam16->hide(); expjz->hide(); jzFrame->hide(); adapjzcie->hide(); jz100->hide(); pqremap->show(); - pqremapcam16->show(); jabcie->hide(); targetGraycie->show(); targabscie->show(); surrHBoxcie->show(); forcejz->hide(); sourceGraycie->show(); - cieFrame->show(); + expcamscene->show(); exprecovcie->hide(); + expgradcie->hide(); maskusablecie->hide(); maskunusablecie->hide(); decaycie->hide(); expmaskcie->hide(); - expmaskcie->hide(); + comprcie->show(); + strcielog->show(); + satcie->show(); + logcieq->hide(); + blackEvjz->hide(); + whiteEvjz->hide(); + whitescie->hide(); + blackscie->hide(); + logcieFrame->hide(); + comprcieth->hide(); + comprcieauto->hide(); + comprBox->show(); + slopesmo->hide(); + smoothcie->hide(); - if (modecam->get_active_row_number() == 2) { - PQFrame->hide(); - logjzFrame->hide(); - sigmoidjzFrame->hide(); - bevwevFrame->hide(); - sigmoidFrame->hide(); - } - if (modecam->get_active_row_number() == 0){ + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); - sigmoidFrame->show(); + sigmoidFrame->hide(); //show + expprecam->show(); + primillFrame->hide(); + expmaskcie->hide(); + exprecovcie->hide(); + expgradcie->hide(); + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } } if (modecam->get_active_row_number() == 1) { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - forcejz->hide(); - pqremapcam16->hide(); - PQFrame->hide(); - logjzFrame->hide(); - bevwevFrame->hide(); - sigmoidjzFrame->hide(); - sigmoidFrame->hide(); - catadcie->hide(); - cie2Frame->hide(); - maskusablecie->hide(); - maskunusablecie->hide(); - decaycie->hide(); - expmaskcie->hide(); - } - if (modecam->get_active_row_number() == 3) { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->hide(); - pqremapcam16->hide(); - PQFrame->hide(); - logjzFrame->hide(); - catadcie->hide(); + // cieFrame->hide(); + guijzczhz(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + enacieMaskall->hide(); } + + contsigqcie->hide(); + lightsigqcie->hide(); + expmaskcie->hide(); + exprecovcie->hide(); + expgradcie->hide(); + break; + case Normal: // Expert mode widgets are hidden in Normal mode catadcie->show(); saturlcie->show(); rstprotectcie->show(); - chromlcie->hide(); - huecie->hide(); + chromlcie->show();//hide + huecie->show();//hide lightlcie->show(); - lightqcie->hide(); + lightqcie->show();//hide contlcie->show(); contthrescie->show(); - contqcie->hide(); + contqcie->show();//hide colorflcie->hide(); surrHBoxcie->show(); expLcie->hide(); surHBoxcie->show(); sourceabscie->show(); targabscie->show(); - detailcie->hide(); + detailcie->show();//hide jabcie->hide(); modeHBoxcie->hide(); sensicie->show(); reparcie->show(); sigmoidblcie->show(); + sigmoidsenscie->hide(); expjz->hide(); forcejz->hide(); + comprcie->show(); + strcielog->show(); + satcie->show(); + logcieq->hide(); + blackEvjz->show(); + whiteEvjz->show(); + whitescie->show(); + blackscie->show(); + + logcieFrame->hide(); + comprcieth->show(); + comprcieauto->show(); + comprBox->show(); jzFrame->hide(); adapjzcie->hide(); @@ -9402,15 +10817,24 @@ void Locallabcie::updateGUIToMode(const modeType new_type) targetGraycie->show(); targabscie->show(); surrHBoxcie->show(); - pqremapcam16->show(); + pqremapcam16->hide(); sourceGraycie->show(); - cieFrame->show(); + expcamscene->show(); exprecovcie->show(); + expgradcie->show(); expmaskcie->show(); decaycie->hide(); lapmaskcie->hide(); gammaskcie->hide(); slomaskcie->hide(); + highmaskcie->hide(); + shadmaskcie->hide(); + struFramecie->hide(); + blurFramecie->hide(); + wavFramecie->hide(); + maskcieHCurveEditorG->hide(); + sigmoidnormFrame->hide(); + if (enacieMask->get_active()) { maskusablecie->show(); maskunusablecie->hide(); @@ -9419,52 +10843,46 @@ void Locallabcie::updateGUIToMode(const modeType new_type) maskusablecie->hide(); maskunusablecie->show(); } - if (modecam->get_active_row_number() == 0){ + + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); sigmoidFrame->show(); + expprecam->show(); + primillFrame->hide();//show + enacieMaskall->hide(); + + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } } - if (modecam->get_active_row_number() == 2) { - PQFrame->hide(); - logjzFrame->hide(); - sigmoidjzFrame->hide(); - bevwevFrame->hide(); - } if (modecam->get_active_row_number() == 1) { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - forcejz->hide(); - pqremapcam16->hide(); - PQFrame->hide(); - logjzFrame->hide(); - sigmoidjzFrame->hide(); - bevwevFrame->hide(); - sigmoidFrame->hide(); - catadcie->hide(); - cie2Frame->hide(); - exprecovcie->hide(); - expmaskcie->hide(); - maskusablecie->hide(); - maskunusablecie->hide(); + guijzczhz(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + enacieMaskall->hide(); + } else { + exprecovcie->show(); + expgradcie->show(); + expmaskcie->show(); } - if (modecam->get_active_row_number() == 3) { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->hide(); - pqremapcam16->hide(); - PQFrame->hide(); - catadcie->hide(); - logjzFrame->hide(); - } + + if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); expmaskcie->hide(); + expgradcie->hide(); } + contsigqcie->hide(); + lightsigqcie->hide(); + break; case Expert: @@ -9488,20 +10906,48 @@ void Locallabcie::updateGUIToMode(const modeType new_type) detailcie->show(); modeHBoxcie->show(); sigmoidblcie->show(); + pqremapcam16->show(); + comprcie->show(); + strcielog->show(); + logcieq->show(); + blackEvjz->show(); + whiteEvjz->show(); + whitescie->show(); + blackscie->show(); + logcieFrame->show(); + comprcieth->show(); + comprcieauto->show(); + sigmoidsenscie->show(); + sigmoidnormFrame->show(); + + if (logcieq->get_active()) { + satcie->hide(); + sigmoidnormFrame->hide(); + } else { + satcie->show(); + sigmoidnormFrame->show(); + } + targetGraycie->show(); targabscie->show(); surrHBoxcie->show(); forcejz->hide(); - pqremapcam16->show(); sourceGraycie->show(); - cieFrame->show(); + expcamscene->show(); exprecovcie->show(); + expgradcie->show(); decaycie->show(); lapmaskcie->show(); gammaskcie->show(); slomaskcie->show(); + highmaskcie->show(); + shadmaskcie->show(); + maskcieHCurveEditorG->show(); expmaskcie->show(); - exprecovcie->show(); + struFramecie->show(); + blurFramecie->show(); + wavFramecie->show(); + comprBox->show(); if (enacieMask->get_active()) { maskusablecie->show(); @@ -9511,11 +10957,24 @@ void Locallabcie::updateGUIToMode(const modeType new_type) maskusablecie->hide(); maskunusablecie->show(); } - if (modecam->get_active_row_number() == 0){ + + if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); + expprecam->show(); + primillFrame->show(); + enacieMaskallChanged2(); + enacieMaskall->show(); + + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } } - if (modecam->get_active_row_number() == 1 || modecam->get_active_row_number() == 2) { + if (modecam->get_active_row_number() == 1) { jabcie->show(); expjz->show(); jzFrame->show(); @@ -9528,12 +10987,22 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sigmoidjzFrame->show(); sigmoidFrame->hide(); forcejz->hide(); + expprecam->hide(); + expgradcie->hide(); + expcam16->hide(); + exprecovcie->show(); + expmaskcie->show(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + enacieMaskall->show(); } - cieFrame->show(); - cie2Frame->show(); - if (modecam->get_active_row_number() == 0 || modecam->get_active_row_number() == 2) { + expcamscene->show(); + expcamviewing->show(); + + if (modecam->get_active_row_number() == 0) { targetGraycie->show(); targabscie->show(); surrHBoxcie->show(); @@ -9542,18 +11011,23 @@ void Locallabcie::updateGUIToMode(const modeType new_type) logjzFrame->hide(); sigmoidjzFrame->hide(); bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ - bevwevFrame->show(); - sigmoidFrame->show(); - } + bevwevFrame->show(); + sigmoidFrame->show(); + expprecam->show(); + primillFrame->show(); + enacieMaskallChanged2(); + enacieMaskall->show(); + + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } } - if (modecam->get_active_row_number() == 2) { - PQFrame->show(); - logjzFrame->hide(); - sigmoidjzFrame->hide(); - bevwevFrame->hide(); - } + if (modecam->get_active_row_number() == 1) { surHBoxcie->show(); @@ -9567,76 +11041,100 @@ void Locallabcie::updateGUIToMode(const modeType new_type) sigmoidFrame->hide(); bevwevFrame->show(); catadcie->hide(); - cie2Frame->hide(); + expcamviewing->hide(); exprecovcie->show(); + expgradcie->show(); expmaskcie->show(); maskusablecie->show(); maskunusablecie->show(); + expprecam->hide(); + expgradcie->hide(); + expcam16->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + enacieMaskall->show(); + if (chjzcie->get_active()) { thrhjzcie->set_sensitive(true); } else { thrhjzcie->set_sensitive(false); } - } - - if (modecam->get_active_row_number() == 3) { - cieFrame->show(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->show(); - targetGraycie->show(); - targabscie->show(); - surrHBoxcie->show(); - PQFrame->show(); - logjzFrame->show(); - adapjzcie->hide(); - jz100->hide(); - forcejz->hide(); - pqremap->show(); - pqremapcam16->hide(); - catadcie->hide(); } + + if (modecie->get_active_row_number() > 0) { exprecovcie->hide(); expmaskcie->hide(); + expgradcie->hide(); } + contsigqcie->hide(); + lightsigqcie->hide(); + } } void Locallabcie::updatecieGUI() { + const LocallabParams::LocallabSpot defSpot; const int mode = complexity->get_active_row_number(); expmaskcie->show(); exprecovcie->show(); + expgradcie->show(); + + contsigqcie->hide(); + lightsigqcie->hide(); + + if (modecie->get_active_row_number() > 0) { sensicie->hide(); reparcie->hide(); exprecovcie->hide(); + expgradcie->hide(); expmaskcie->hide(); } else { sensicie->show(); reparcie->show(); exprecovcie->show(); + expgradcie->show(); expmaskcie->show(); } - surHBoxcie->show(); - cie1Frame->show(); - cie2Frame->show(); - expcam16->show(); - if (modecam->get_active_row_number() == 0){ - bevwevFrame->show(); + + surHBoxcie->show(); + cie1Frame->show(); + expcam16->show(); + expcamviewing->show(); + + if (modecam->get_active_row_number() == 0) { + bevwevFrame->show(); + expprecam->show(); + + if (mode == Simple) { + expmaskcie->hide(); + exprecovcie->hide(); + primillFrame->hide(); + expgradcie->hide(); + + } else if (mode == Normal) { + primillFrame->hide(); + } else { + primillFrame->show(); + } + + if(smoothciemet->get_active_row_number() == 3) { + slopesmo->show(); + smoothcie->show(); + } else { + slopesmo->hide(); + smoothcie->hide(); + } } - if (modecam->get_active_row_number() == 2 && mode == Expert) { - PQFrame->show(); - logjzFrame->show(); - sigmoidjzFrame->show(); - bevwevFrame->show(); - } - sourceGraycie->show(); - cieFrame->show(); + + sourceGraycie->show(); + expcamscene->show(); if (enacieMask->get_active() && mode != Simple) { maskusablecie->show(); @@ -9647,7 +11145,58 @@ void Locallabcie::updatecieGUI() maskunusablecie->show(); } - if (modecam->get_active_row_number() == 1) { + + if (Autograycie->get_active()) { + sourceGraycie->set_sensitive(false); + sourceabscie->set_sensitive(false); + adapjzcie->set_sensitive(false); + jz100->set_sensitive(false); + blackEvjz->set_sensitive(false); + whiteEvjz->set_sensitive(false); + whitescie->set_sensitive(true); + blackscie->set_sensitive(true); + comprcieauto->set_active(true); + + } else { + sourceGraycie->set_sensitive(true); + sourceabscie->set_sensitive(true); + adapjzcie->set_sensitive(true); + blackEvjz->set_sensitive(true); + whiteEvjz->set_sensitive(true); + whitescie->set_sensitive(false); + blackscie->set_sensitive(false); + jz100->set_sensitive(true); + } + + if (mode == Simple || mode == Normal) { // Keep widget hidden in Normal and Simple mode + modecie->set_active(0); + sensicie->show(); + reparcie->show(); + } + + if (sursourcie->get_active_row_number() == 4) { + expcam16->hide(); + expcamviewing->hide(); + } else { + expcam16->show(); + expcamviewing->show(); + if(modecam->get_active_row_number() == 1) { + expcam16->hide(); + expcamviewing->hide(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + } + } + + + if (modecie->get_active_row_number() > 0) { + exprecovcie->hide(); + expgradcie->hide(); + expmaskcie->hide(); + } + + if (modecam->get_active_row_number() == 1 && (mode == Expert)) { surHBoxcie->show(); cie1Frame->hide(); expcam16->hide(); @@ -9661,80 +11210,19 @@ void Locallabcie::updatecieGUI() bevwevFrame->show(); sigmoidFrame->hide(); catadcie->hide(); - cie2Frame->hide(); - if(mode != Expert) { - cieFrame->hide(); - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->hide(); - PQFrame->hide(); - logjzFrame->hide(); - sigmoidjzFrame->hide(); - sigmoidFrame->hide(); - bevwevFrame->hide(); - if (modecam->get_active_row_number() == 0){ - bevwevFrame->show(); - sigmoidFrame->show(); - } - exprecovcie->hide(); - expmaskcie->hide(); - maskusablecie->hide(); - maskunusablecie->hide(); - } + expprecam->hide(); + expcamviewing->hide(); + expgradcie->hide(); + expcam16->hide(); + exprecovcie->show(); + expmaskcie->show(); + lapmaskcie->hide(); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + enacieMaskall->show(); } - if (modecam->get_active_row_number() == 3) { - if(mode == Expert) { - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->show(); - targetGraycie->show(); - targabscie->show(); - surrHBoxcie->show(); - cieFrame->show(); - PQFrame->show(); - logjzFrame->show(); - adapjzcie->hide(); - jz100->hide(); - forcejz->hide(); - pqremap->show(); - pqremapcam16->hide(); - PQFrame->show(); - catadcie->hide(); - } else { - cie1Frame->hide(); - expcam16->hide(); - cie2Frame->hide(); - PQFrame->hide(); - logjzFrame->hide(); - } - } - if (Autograycie->get_active()) { - sourceGraycie->set_sensitive(false); - sourceabscie->set_sensitive(false); - adapjzcie->set_sensitive(false); - jz100->set_sensitive(false); - blackEvjz->set_sensitive(false); - whiteEvjz->set_sensitive(false); - } else { - sourceGraycie->set_sensitive(true); - sourceabscie->set_sensitive(true); - adapjzcie->set_sensitive(true); - blackEvjz->set_sensitive(true); - whiteEvjz->set_sensitive(true); - jz100->set_sensitive(true); - } - - if (mode == Simple || mode == Normal) { // Keep widget hidden in Normal and Simple mode - modecie->set_active (0); - sensicie->show(); - reparcie->show(); - } - if (modecie->get_active_row_number() > 0) { - exprecovcie->hide(); - expmaskcie->hide(); - } } @@ -9746,9 +11234,28 @@ void Locallabcie::convertParamToSimple() // Disable all listeners disableListener(); sigmoidblcie->setValue(defSpot.sigmoidblcie); + normcie->set_active(defSpot.normcie); + logcieq->set_active(defSpot.logcieq); + logcie->set_active(defSpot.logcie); + blackEvjz->setValue(defSpot.blackEvjz); + whiteEvjz->setValue(defSpot.whiteEvjz); + whitescie->setValue(defSpot.whitescie); + blackscie->setValue(defSpot.blackscie); + + sigq->set_active(defSpot.sigq); + //sigq->set_active(defSpot.sigq); + pqremapcam16->setValue(defSpot.pqremapcam16); showmaskcieMethod->set_active(0); enacieMask->set_active(defSpot.enacieMask); + enacieMaskall->set_active(defSpot.enacieMaskall); + strgradcie->setValue(defSpot.strgradcie); + anggradcie->setValue(defSpot.anggradcie); + refi->setValue(defSpot.refi); modecie->set_active(0); + primMethod->set_active(0);//Prophoto + illMethod->set_active(1);//D50 + catMethod->set_active(0); + // Enable all listeners enableListener(); } @@ -9760,11 +11267,17 @@ void Locallabcie::convertParamToNormal() // Disable all listeners disableListener(); contqcie->setValue(defSpot.contqcie); + sigmoidblcie->setValue(defSpot.sigmoidblcie); + normcie->set_active(defSpot.normcie); + logcieq->set_active(defSpot.logcieq); + logcie->set_active(defSpot.logcie); + + //contsigqcie->setValue(defSpot.contsigqcie); colorflcie->setValue(defSpot.colorflcie); lightqcie->setValue(defSpot.lightqcie); chromlcie->setValue(defSpot.chromlcie); huecie->setValue(defSpot.huecie); - detailcie->setValue(defSpot.detailcie); + // detailcie->setValue(defSpot.detailcie); jabcie->set_active(defSpot.jabcie); LHshapejz->setCurve(defSpot.LHcurvejz); CHshapejz->setCurve(defSpot.CHcurvejz); @@ -9776,6 +11289,7 @@ void Locallabcie::convertParamToNormal() shapecie2->setCurve(defSpot.ciecurve2); lightjzcie->setValue(defSpot.lightjzcie); contjzcie->setValue(defSpot.contjzcie); + detailciejz->setValue(defSpot.detailciejz); sigmoidldajzcie->setValue(defSpot.sigmoidldajzcie); hljzcie->setValue(defSpot.hljzcie); shjzcie->setValue(defSpot.shjzcie); @@ -9786,15 +11300,41 @@ void Locallabcie::convertParamToNormal() strsoftjzcie->setValue(defSpot.strsoftjzcie); thrhjzcie->setValue(defSpot.thrhjzcie); modecie->set_active(0); + //primMethod->set_active(0); + catMethod->set_active(0); + primMethod->set_active(0);//Prophoto + illMethod->set_active(1);//D50 + refi->setValue(defSpot.refi); + + pqremapcam16->setValue(defSpot.pqremapcam16); + logcieChanged(); + satcieChanged(); + logcieqChanged(); + if (modecam->get_active_row_number() == 1) { showmaskcieMethod->set_active(0); enacieMask->set_active(defSpot.enacieMask); logjz->set_active(defSpot.logjz); sigjz->set_active(defSpot.sigjz); + lapmaskcie->setValue(defSpot.lapmaskcie); + enacieMaskallChanged2(); + } + lapmaskcie->setValue(defSpot.lapmaskcie); gammaskcie->setValue(defSpot.gammaskcie); slomaskcie->setValue(defSpot.slomaskcie); + highmaskcie->setValue(defSpot.highmaskcie); + shadmaskcie->setValue(defSpot.shadmaskcie); + HHhmaskcieshape->setCurve(defSpot.HHhmaskciecurve); + strumaskcie->setValue(defSpot.strumaskcie); + toolcie->set_active(defSpot.toolcie); + fftcieMask->set_active(defSpot.fftcieMask); + contcie->setValue(defSpot.contcie); + blurcie->setValue(defSpot.blurcie); + sigmoidsenscie->setValue(defSpot.sigmoidsenscie); + LLmaskcieshapewav->setCurve(defSpot.LLmaskciecurvewav); + csThresholdcie->setValue(defSpot.csthresholdcie); // Enable all listeners enableListener(); @@ -9814,8 +11354,8 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, sourceabscie->setDefault(defSpot.sourceabscie); saturlcie->setDefault(defSpot.saturlcie); rstprotectcie->setDefault(defSpot.rstprotectcie); - chromlcie->setDefault(defSpot.chromlcie); - huecie->setDefault(defSpot.huecie); + // chromlcie->setDefault(defSpot.chromlcie); + // huecie->setDefault(defSpot.huecie); chromjzcie->setDefault(defSpot.chromjzcie); saturjzcie->setDefault(defSpot.saturjzcie); huejzcie->setDefault(defSpot.huejzcie); @@ -9824,9 +11364,11 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, thrhjzcie->setDefault(defSpot.thrhjzcie); lightlcie->setDefault(defSpot.lightlcie); lightjzcie->setDefault(defSpot.lightjzcie); - lightqcie->setDefault(defSpot.lightqcie); + //lightqcie->setDefault(defSpot.lightqcie); + lightsigqcie->setDefault(defSpot.lightsigqcie); contlcie->setDefault(defSpot.contlcie); contjzcie->setDefault(defSpot.contjzcie); + detailciejz->setDefault(defSpot.detailciejz); adapjzcie->setDefault(defSpot.adapjzcie); jz100->setDefault(defSpot.jz100); pqremap->setDefault(defSpot.pqremap); @@ -9847,53 +11389,94 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, targetjz->setDefault(defSpot.targetjz); sigmoidldacie->setDefault(defSpot.sigmoidldacie); sigmoidthcie->setDefault(defSpot.sigmoidthcie); + sigmoidsenscie->setDefault(defSpot.sigmoidsenscie); sigmoidblcie->setDefault(defSpot.sigmoidblcie); + comprcie->setDefault(defSpot.comprcie); + strcielog->setDefault(defSpot.strcielog); + comprcieth->setDefault(defSpot.comprcieth); + gamjcie->setDefault(defSpot.gamjcie); + whitescie->setDefault(defSpot.whitescie); + blackscie->setDefault(defSpot.blackscie); + slopjcie->setDefault(defSpot.slopjcie); + slopesmo->setDefault(defSpot.slopesmo); + midtcie->setDefault(defSpot.midtcie); sigmoidldajzcie->setDefault(defSpot.sigmoidldajzcie); sigmoidthjzcie->setDefault(defSpot.sigmoidthjzcie); sigmoidbljzcie->setDefault(defSpot.sigmoidbljzcie); - contqcie->setDefault(defSpot.contqcie); + // contqcie->setDefault(defSpot.contqcie); + contsigqcie->setDefault(defSpot.contsigqcie); colorflcie->setDefault(defSpot.colorflcie); targabscie->setDefault(defSpot.targabscie); targetGraycie->setDefault(defSpot.targetGraycie); catadcie->setDefault(defSpot.catadcie); - detailcie->setDefault(defSpot.detailcie); + // detailcie->setDefault(defSpot.detailcie); + strgradcie->setDefault((double)defSpot.strgradcie); + anggradcie->setDefault((double)defSpot.anggradcie); blendmaskcie->setDefault((double)defSpot.blendmaskcie); radmaskcie->setDefault(defSpot.radmaskcie); chromaskcie->setDefault(defSpot.chromaskcie); lapmaskcie->setDefault(defSpot.lapmaskcie); gammaskcie->setDefault(defSpot.gammaskcie); slomaskcie->setDefault(defSpot.slomaskcie); + highmaskcie->setDefault(defSpot.highmaskcie); + shadmaskcie->setDefault(defSpot.shadmaskcie); recothrescie->setDefault((double)defSpot.recothrescie); lowthrescie->setDefault((double)defSpot.lowthrescie); higthrescie->setDefault((double)defSpot.higthrescie); decaycie->setDefault((double)defSpot.decaycie); + strumaskcie->setDefault(defSpot.strumaskcie); + contcie->setDefault(defSpot.contcie); + blurcie->setDefault(defSpot.blurcie); + csThresholdcie->setDefault(defSpot.csthresholdcie); + redxl->setDefault(defSpot.redxl); + redyl->setDefault(defSpot.redyl); + grexl->setDefault(defSpot.grexl); + greyl->setDefault(defSpot.greyl); + bluxl->setDefault(defSpot.bluxl); + bluyl->setDefault(defSpot.bluyl); + shiftxl->setDefault(defSpot.shiftxl); + shiftyl->setDefault(defSpot.shiftyl); + refi->setDefault(defSpot.refi); + labgridcie->setDefault(defSpot.labgridcieALow, + defSpot.labgridcieBLow, + defSpot.labgridcieAHigh, + defSpot.labgridcieBHigh, + defSpot.labgridcieGx, + defSpot.labgridcieGy, + defSpot.labgridcieWx, + defSpot.labgridcieWy, + defSpot.labgridcieMx, + defSpot.labgridcieMy); } } + + void Locallabcie::curveChanged(CurveEditor* ce) { if (isLocActivated && exp->getEnabled()) { - const auto spName = M("HISTORY_CUSTOMCURVE") + " (" + escapeHtmlChars(getSpotName()) + ")"; - if (ce == shapejz) { + const auto spName = M("HISTORY_CUSTOMCURVE") + " (" + escapeHtmlChars(getSpotName()) + ")"; + + if (ce == shapejz) { if (listener) { listener->panelChanged(Evlocallabshapejz, spName); } } - if (ce == shapecz) { + if (ce == shapecz) { if (listener) { listener->panelChanged(Evlocallabshapecz, spName); } } - if (ce == shapeczjz) { + if (ce == shapeczjz) { if (listener) { listener->panelChanged(Evlocallabshapeczjz, spName); } } - if (ce == HHshapejz) { + if (ce == HHshapejz) { if (listener) { listener->panelChanged(EvlocallabHHshapejz, spName); } @@ -9944,6 +11527,13 @@ void Locallabcie::curveChanged(CurveEditor* ce) } } + if (ce == HHhmaskcieshape) { + if (listener) { + listener->panelChanged(EvlocallabHHhmaskcieshape, + M("HISTORY_CUSTOMCURVE") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (ce == Lmaskcieshape) { if (listener) { listener->panelChanged(EvlocallabLmaskcieshape, @@ -9958,6 +11548,12 @@ void Locallabcie::curveChanged(CurveEditor* ce) } } + if (ce == LLmaskcieshapewav) { + if (listener) { + listener->panelChanged(EvlocallabLLmaskcieshapewav, + M("HISTORY_CUSTOMCURVE") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } } } @@ -9971,6 +11567,14 @@ void Locallabcie::adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int new csThresholdjz->getHistoryString() + " (" + escapeHtmlChars(getSpotName()) + ")"); } } + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + listener->panelChanged(EvlocallabcsThresholdcie, + csThresholdcie->getHistoryString() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } @@ -9980,6 +11584,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) if (isLocActivated && exp->getEnabled()) { const auto spName = " (" + escapeHtmlChars(getSpotName()) + ")"; + if (a == reparcie) { if (listener) { listener->panelChanged(Evlocallabreparcie, @@ -10009,7 +11614,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) if (listener) { listener->panelChanged(Evlocallabsourceabscie, - sourceabscie->getTextValue() + spName ); + sourceabscie->getTextValue() + spName); } } @@ -10104,11 +11709,18 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == lightsigqcie) { + if (listener) { + listener->panelChanged(Evlocallablightsigqcie, + lightsigqcie->getTextValue() + spName); + } + } + if (a == contlcie) { if (listener) { listener->panelChanged(Evlocallabcontlcie, - contlcie->getTextValue()+ spName); + contlcie->getTextValue() + spName); } } @@ -10119,6 +11731,13 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == detailciejz) { + if (listener) { + listener->panelChanged(Evlocallabdetailciejz, + detailciejz->getTextValue() + spName); + } + } + if (a == adapjzcie) { if (listener) { listener->panelChanged(Evlocallabadapjzcie, @@ -10136,14 +11755,14 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) if (a == pqremap) { if (listener) { listener->panelChanged(Evlocallabpqremap, - pqremap->getTextValue()+ spName ); + pqremap->getTextValue() + spName); } } if (a == pqremapcam16) { if (listener) { listener->panelChanged(Evlocallabpqremapcam16, - pqremapcam16->getTextValue()+ spName ); + pqremapcam16->getTextValue() + spName); } } @@ -10164,7 +11783,7 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) if (a == shjzcie) { if (listener) { listener->panelChanged(Evlocallabshjzcie, - shjzcie->getTextValue()+ spName ); + shjzcie->getTextValue() + spName); } } @@ -10259,10 +11878,17 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == sigmoidsenscie) { + if (listener) { + listener->panelChanged(Evlocallabsigmoidsenscie, + sigmoidsenscie->getTextValue() + spName); + } + } + if (a == sigmoidthjzcie) { if (listener) { listener->panelChanged(Evlocallabsigmoidthjzcie, - sigmoidthjzcie->getTextValue()+ spName ); + sigmoidthjzcie->getTextValue() + spName); } } @@ -10273,6 +11899,135 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == comprcie) { + if (listener) { + listener->panelChanged(Evlocallabcomprcie, + comprcie->getTextValue() + spName); + } + } + + if (a == strcielog) { + if (listener) { + listener->panelChanged(Evlocallabstrcielog, + strcielog->getTextValue() + spName); + } + } + + if (a == comprcieth) { + nextcomprciecount = 0; + + if (listener) { + listener->panelChanged(Evlocallabcomprcieth, + comprcieth->getTextValue() + spName); + } + } + + if (a == gamjcie) { + if (listener) { + listener->panelChanged(Evlocallabgamjcie, + gamjcie->getTextValue() + spName); + } + } + + if (a == slopjcie) { + if (listener) { + listener->panelChanged(Evlocallabslopjcie, + slopjcie->getTextValue() + spName); + } + } + + if (a == slopesmo) { + if (listener) { + listener->panelChanged(Evlocallabslopesmo, + slopesmo->getTextValue() + spName); + } + } + + if (a == midtcie) { + if (listener) { + listener->panelChanged(Evlocallabmidtcie, + midtcie->getTextValue() + spName); + } + } + + if (a == redxl) { + if (listener) { + listener->panelChanged(Evlocallabredxl, + redxl->getTextValue() + spName); + } + } + + if (a == redyl) { + if (listener) { + listener->panelChanged(Evlocallabredyl, + redyl->getTextValue() + spName); + } + } + + + if (a == grexl) { + if (listener) { + listener->panelChanged(Evlocallabgrexl, + grexl->getTextValue() + spName); + } + } + + if (a == greyl) { + if (listener) { + listener->panelChanged(Evlocallabgreyl, + greyl->getTextValue() + spName); + } + } + + if (a == bluxl) { + if (listener) { + listener->panelChanged(Evlocallabbluxl, + bluxl->getTextValue() + spName); + } + } + + if (a == bluyl) { + if (listener) { + listener->panelChanged(Evlocallabbluyl, + bluyl->getTextValue() + spName); + } + } + + if (a == refi) { + if (listener) { + listener->panelChanged(Evlocallabrefi, + refi->getTextValue() + spName); + } + } + + if (a == shiftxl) { + if (listener) { + listener->panelChanged(Evlocallabshiftxl, + shiftxl->getTextValue() + spName); + } + } + + if (a == shiftyl) { + if (listener) { + listener->panelChanged(Evlocallabshiftyl, + shiftyl->getTextValue() + spName); + } + } + + if (a == whitescie) { + if (listener) { + listener->panelChanged(Evlocallabwhitescie, + whitescie->getTextValue() + spName); + } + } + + if (a == blackscie) { + if (listener) { + listener->panelChanged(Evlocallabblackscie, + blackscie->getTextValue() + spName); + } + } + if (a == sigmoidbljzcie) { if (listener) { listener->panelChanged(Evlocallabsigmoidbljzcie, @@ -10287,70 +12042,20 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == contsigqcie) { + if (listener) { + listener->panelChanged(Evlocallabcontsigqcie, + contsigqcie->getTextValue() + spName); + } + } + if (a == colorflcie) { if (listener) { listener->panelChanged(Evlocallabcolorflcie, - colorflcie->getTextValue()+ spName ); + colorflcie->getTextValue() + spName); } } -/* - if (a == lightlzcam) { - if (listener) { - listener->panelChanged(Evlocallablightlzcam, - lightlzcam->getTextValue()+ spName ); - } - } - - if (a == lightqzcam) { - if (listener) { - listener->panelChanged(Evlocallablightqzcam, - lightqzcam->getTextValue()+ spName ); - } - } - - if (a == contlzcam) { - if (listener) { - listener->panelChanged(Evlocallabcontlzcam, - contlzcam->getTextValue()+ spName ); - } - } - - if (a == contqzcam) { - if (listener) { - listener->panelChanged(Evlocallabcontqzcam, - contqzcam->getTextValue()+ spName ); - } - } - - if (a == contthreszcam) { - if (listener) { - listener->panelChanged(Evlocallabcontthreszcam, - contthreszcam->getTextValue()+ spName ); - } - } - - if (a == colorflzcam) { - if (listener) { - listener->panelChanged(Evlocallabcolorflzcam, - colorflzcam->getTextValue()+ spName ); - } - } - - if (a == saturzcam) { - if (listener) { - listener->panelChanged(Evlocallabsaturzcam, - saturzcam->getTextValue()+ spName ); - } - } - - if (a == chromzcam) { - if (listener) { - listener->panelChanged(Evlocallabchromzcam, - chromzcam->getTextValue()+ spName ); - } - } -*/ if (a == targabscie) { if (listener) { listener->panelChanged(Evlocallabtargabscie, @@ -10379,6 +12084,20 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == strgradcie) { + if (listener) { + listener->panelChanged(Evlocallabstrgradcie, + strgradcie->getTextValue() + spName); + } + } + + if (a == anggradcie) { + if (listener) { + listener->panelChanged(Evlocallabanggradcie, + anggradcie->getTextValue() + spName); + } + } + if (a == blendmaskcie) { if (listener) { listener->panelChanged(Evlocallabblendmaskcie, @@ -10421,6 +12140,20 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == highmaskcie) { + if (listener) { + listener->panelChanged(Evlocallabhighmaskcie, + highmaskcie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == shadmaskcie) { + if (listener) { + listener->panelChanged(Evlocallabshadmaskcie, + shadmaskcie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == recothrescie) { if (listener) { @@ -10450,12 +12183,33 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == strumaskcie) { + if (listener) { + listener->panelChanged(Evlocallabstrumaskcie, + strumaskcie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == contcie) { + if (listener) { + listener->panelChanged(Evlocallabcontcie, + contcie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + + if (a == blurcie) { + if (listener) { + listener->panelChanged(Evlocallabblurcie, + blurcie->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } } void Locallabcie::enabledChanged() { - if (isLocActivated) { + if (isLocActivated) { if (listener) { if (exp->getEnabled()) { listener->panelChanged(EvLocenacie, diff --git a/rtgui/options.cc b/rtgui/options.cc index c8750809b..8bf431bc5 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -633,6 +633,7 @@ void Options::setDefaults() rtSettings.previewselection = 5;//between 1 to 40 rtSettings.cbdlsensi = 1.0;//between 0.001 to 1 rtSettings.fftwsigma = true; //choice between sigma^2 or empirical formula + rtSettings.basecorlog = 0.12;//reduction max Q in Cam16 sigmoid Log encoding between 0.05 and 0.5 // end locallab rtSettings.itcwb_enable = true; rtSettings.itcwb_deltaspec = 0.075; @@ -1977,6 +1978,10 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.cbdlsensi = keyFile.get_double("Color Management", "Cbdlsensi"); } + if (keyFile.has_key("Color Management", "Besecorlog")) {//sensi base log for Q + rtSettings.basecorlog = keyFile.get_double("Color Management", "Basecorlog"); + } + } @@ -2662,6 +2667,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("Color Management", "ClutsDirectory", clutsDir); keyFile.set_integer("Color Management", "Previewselection", rtSettings.previewselection); keyFile.set_double("Color Management", "Cbdlsensi", rtSettings.cbdlsensi); + keyFile.set_double("Color Management", "Basecorlog", rtSettings.basecorlog); keyFile.set_double("Wavelet", "Edghi", rtSettings.edghi); keyFile.set_double("Wavelet", "Edglo", rtSettings.edglo); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ca705682b..02d405f76 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -459,14 +459,20 @@ void ParamsEdited::set(bool v) icm.outputBPC = v; icm.workingTRCGamma = v; icm.workingTRCSlope = v; + icm.wmidtcie = v; + icm.wsmoothcie = v; icm.redx = v; icm.redy = v; icm.grex = v; icm.grey = v; icm.blux = v; icm.bluy = v; + icm.refi = v; + icm.shiftx = v; + icm.shifty = v; icm.preser = v; icm.fbw = v; + icm.trcExp = v; icm.gamut = v; icm.labgridcieALow = v; icm.labgridcieBLow = v; @@ -476,10 +482,13 @@ void ParamsEdited::set(bool v) icm.labgridcieGy = v; icm.labgridcieWx = v; icm.labgridcieWy = v; + icm.labgridcieMx = v; + icm.labgridcieMy = v; icm.aRendIntent = v; icm.workingTRC = v; icm.will = v; icm.wprim = v; + icm.wcat = v; raw.bayersensor.method = v; raw.bayersensor.border = v; raw.bayersensor.imageNum = v; @@ -1278,7 +1287,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).complexshadhigh = locallab.spots.at(j).complexshadhigh && pSpot.complexshadhigh == otherSpot.complexshadhigh; locallab.spots.at(j).shMethod = locallab.spots.at(j).shMethod && pSpot.shMethod == otherSpot.shMethod; - for (int k = 0; k < 5; k++) { + for (int k = 0; k < 6; k++) { locallab.spots.at(j).multsh[k] = locallab.spots.at(j).multsh[k] && pSpot.multsh[k] == otherSpot.multsh[k]; } @@ -1653,10 +1662,15 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).Autogray = locallab.spots.at(j).Autogray && pSpot.Autogray == otherSpot.Autogray; locallab.spots.at(j).fullimage = locallab.spots.at(j).fullimage && pSpot.fullimage == otherSpot.fullimage; locallab.spots.at(j).ciecam = locallab.spots.at(j).ciecam && pSpot.ciecam == otherSpot.ciecam; + locallab.spots.at(j).satlog = locallab.spots.at(j).satlog && pSpot.satlog == otherSpot.satlog; locallab.spots.at(j).enaLMask = locallab.spots.at(j).enaLMask && pSpot.enaLMask == otherSpot.enaLMask; locallab.spots.at(j).repar = locallab.spots.at(j).repar && pSpot.repar == otherSpot.repar; locallab.spots.at(j).blackEv = locallab.spots.at(j).blackEv && pSpot.blackEv == otherSpot.blackEv; locallab.spots.at(j).whiteEv = locallab.spots.at(j).whiteEv && pSpot.whiteEv == otherSpot.whiteEv; + locallab.spots.at(j).whiteslog = locallab.spots.at(j).whiteslog && pSpot.whiteslog == otherSpot.whiteslog; + locallab.spots.at(j).blackslog = locallab.spots.at(j).blackslog && pSpot.blackslog == otherSpot.blackslog; + locallab.spots.at(j).comprlog = locallab.spots.at(j).comprlog && pSpot.comprlog == otherSpot.comprlog; + locallab.spots.at(j).strelog = locallab.spots.at(j).strelog && pSpot.strelog == otherSpot.strelog; locallab.spots.at(j).detail = locallab.spots.at(j).detail && pSpot.detail == otherSpot.detail; locallab.spots.at(j).sursour = locallab.spots.at(j).sursour && pSpot.sursour == otherSpot.sursour; locallab.spots.at(j).surround = locallab.spots.at(j).surround && pSpot.surround == otherSpot.surround; @@ -1710,6 +1724,7 @@ void ParamsEdited::initFrom(const std::vector& //ciecam locallab.spots.at(j).visicie = locallab.spots.at(j).visicie && pSpot.visicie == otherSpot.visicie; locallab.spots.at(j).expcie = locallab.spots.at(j).expcie && pSpot.expcie == otherSpot.expcie; + locallab.spots.at(j).expprecam = locallab.spots.at(j).expprecam && pSpot.expprecam == otherSpot.expprecam; locallab.spots.at(j).complexcie = locallab.spots.at(j).complexcie && pSpot.complexcie == otherSpot.complexcie; locallab.spots.at(j).reparcie = locallab.spots.at(j).reparcie && pSpot.reparcie == otherSpot.reparcie; locallab.spots.at(j).sensicie = locallab.spots.at(j).sensicie && pSpot.sensicie == otherSpot.sensicie; @@ -1718,8 +1733,14 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).forcebw = locallab.spots.at(j).forcebw && pSpot.forcebw == otherSpot.forcebw; locallab.spots.at(j).qtoj = locallab.spots.at(j).qtoj && pSpot.qtoj == otherSpot.qtoj; locallab.spots.at(j).jabcie = locallab.spots.at(j).jabcie && pSpot.jabcie == otherSpot.jabcie; - locallab.spots.at(j).sigmoidqjcie = locallab.spots.at(j).sigmoidqjcie && pSpot.sigmoidqjcie == otherSpot.sigmoidqjcie; + locallab.spots.at(j).comprcieauto = locallab.spots.at(j).comprcieauto && pSpot.comprcieauto == otherSpot.comprcieauto; + locallab.spots.at(j).normcie = locallab.spots.at(j).normcie && pSpot.normcie == otherSpot.normcie; + locallab.spots.at(j).gamutcie = locallab.spots.at(j).gamutcie && pSpot.gamutcie == otherSpot.gamutcie; + locallab.spots.at(j).sigcie = locallab.spots.at(j).sigcie && pSpot.sigcie == otherSpot.sigcie; locallab.spots.at(j).logcie = locallab.spots.at(j).logcie && pSpot.logcie == otherSpot.logcie; + locallab.spots.at(j).satcie = locallab.spots.at(j).satcie && pSpot.satcie == otherSpot.satcie; + locallab.spots.at(j).logcieq = locallab.spots.at(j).logcieq && pSpot.logcieq == otherSpot.logcieq; + locallab.spots.at(j).smoothcie = locallab.spots.at(j).smoothcie && pSpot.smoothcie == otherSpot.smoothcie; locallab.spots.at(j).logjz = locallab.spots.at(j).logjz && pSpot.logjz == otherSpot.logjz; locallab.spots.at(j).sigjz = locallab.spots.at(j).sigjz && pSpot.sigjz == otherSpot.sigjz; locallab.spots.at(j).sigq = locallab.spots.at(j).sigq && pSpot.sigq == otherSpot.sigq; @@ -1728,6 +1749,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).sourceabscie = locallab.spots.at(j).sourceabscie && pSpot.sourceabscie == otherSpot.sourceabscie; locallab.spots.at(j).sursourcie = locallab.spots.at(j).sursourcie && pSpot.sursourcie == otherSpot.sursourcie; locallab.spots.at(j).modecam = locallab.spots.at(j).modecam && pSpot.modecam == otherSpot.modecam; + locallab.spots.at(j).bwevMethod = locallab.spots.at(j).bwevMethod && pSpot.bwevMethod == otherSpot.bwevMethod; locallab.spots.at(j).modecie = locallab.spots.at(j).modecie && pSpot.modecie == otherSpot.modecie; locallab.spots.at(j).saturlcie = locallab.spots.at(j).saturlcie && pSpot.saturlcie == otherSpot.saturlcie; locallab.spots.at(j).rstprotectcie = locallab.spots.at(j).rstprotectcie && pSpot.rstprotectcie == otherSpot.rstprotectcie; @@ -1752,8 +1774,10 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).lightlcie = locallab.spots.at(j).lightlcie && pSpot.lightlcie == otherSpot.lightlcie; locallab.spots.at(j).lightjzcie = locallab.spots.at(j).lightjzcie && pSpot.lightjzcie == otherSpot.lightjzcie; locallab.spots.at(j).lightqcie = locallab.spots.at(j).lightqcie && pSpot.lightqcie == otherSpot.lightqcie; + locallab.spots.at(j).lightsigqcie = locallab.spots.at(j).lightsigqcie && pSpot.lightsigqcie == otherSpot.lightsigqcie; locallab.spots.at(j).contlcie = locallab.spots.at(j).contlcie && pSpot.contlcie == otherSpot.contlcie; locallab.spots.at(j).contjzcie = locallab.spots.at(j).contjzcie && pSpot.contjzcie == otherSpot.contjzcie; + locallab.spots.at(j).detailciejz = locallab.spots.at(j).detailciejz && pSpot.detailciejz == otherSpot.detailciejz; locallab.spots.at(j).adapjzcie = locallab.spots.at(j).adapjzcie && pSpot.adapjzcie == otherSpot.adapjzcie; locallab.spots.at(j).jz100 = locallab.spots.at(j).jz100 && pSpot.jz100 == otherSpot.jz100; locallab.spots.at(j).pqremap = locallab.spots.at(j).pqremap && pSpot.pqremap == otherSpot.pqremap; @@ -1769,31 +1793,62 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).targetjz = locallab.spots.at(j).targetjz && pSpot.targetjz == otherSpot.targetjz; locallab.spots.at(j).sigmoidldacie = locallab.spots.at(j).sigmoidldacie && pSpot.sigmoidldacie == otherSpot.sigmoidldacie; locallab.spots.at(j).sigmoidthcie = locallab.spots.at(j).sigmoidthcie && pSpot.sigmoidthcie == otherSpot.sigmoidthcie; + locallab.spots.at(j).sigmoidsenscie = locallab.spots.at(j).sigmoidsenscie && pSpot.sigmoidsenscie == otherSpot.sigmoidsenscie; locallab.spots.at(j).sigmoidblcie = locallab.spots.at(j).sigmoidblcie && pSpot.sigmoidblcie == otherSpot.sigmoidblcie; + locallab.spots.at(j).comprcie = locallab.spots.at(j).comprcie && pSpot.comprcie == otherSpot.comprcie; + locallab.spots.at(j).strcielog = locallab.spots.at(j).strcielog && pSpot.strcielog == otherSpot.strcielog; + locallab.spots.at(j).comprcieth = locallab.spots.at(j).comprcieth && pSpot.comprcieth == otherSpot.comprcieth; + locallab.spots.at(j).gamjcie = locallab.spots.at(j).gamjcie && pSpot.gamjcie == otherSpot.gamjcie; + locallab.spots.at(j).slopjcie = locallab.spots.at(j).slopjcie && pSpot.slopjcie == otherSpot.slopjcie; + locallab.spots.at(j).slopesmo = locallab.spots.at(j).slopesmo && pSpot.slopesmo == otherSpot.slopesmo; + locallab.spots.at(j).midtcie = locallab.spots.at(j).midtcie && pSpot.midtcie == otherSpot.midtcie; + locallab.spots.at(j).grexl = locallab.spots.at(j).grexl && pSpot.grexl == otherSpot.grexl; + locallab.spots.at(j).greyl = locallab.spots.at(j).greyl && pSpot.greyl == otherSpot.greyl; + locallab.spots.at(j).redxl = locallab.spots.at(j).redxl && pSpot.redxl == otherSpot.redxl; + locallab.spots.at(j).redyl = locallab.spots.at(j).redyl && pSpot.redyl == otherSpot.redyl; + locallab.spots.at(j).bluxl = locallab.spots.at(j).bluxl && pSpot.bluxl == otherSpot.bluxl; + locallab.spots.at(j).bluyl = locallab.spots.at(j).bluyl && pSpot.bluyl == otherSpot.bluyl; + locallab.spots.at(j).refi = locallab.spots.at(j).refi && pSpot.refi == otherSpot.refi; + locallab.spots.at(j).shiftxl = locallab.spots.at(j).shiftxl && pSpot.shiftxl == otherSpot.shiftxl; + locallab.spots.at(j).shiftyl = locallab.spots.at(j).shiftyl && pSpot.shiftyl == otherSpot.shiftyl; + locallab.spots.at(j).labgridcieALow = locallab.spots.at(j).labgridcieALow && pSpot.labgridcieALow == otherSpot.labgridcieALow; + locallab.spots.at(j).labgridcieBLow = locallab.spots.at(j).labgridcieBLow && pSpot.labgridcieBLow == otherSpot.labgridcieBLow; + locallab.spots.at(j).labgridcieAHigh = locallab.spots.at(j).labgridcieAHigh && pSpot.labgridcieAHigh == otherSpot.labgridcieAHigh; + locallab.spots.at(j).labgridcieBHigh = locallab.spots.at(j).labgridcieBHigh && pSpot.labgridcieBHigh == otherSpot.labgridcieBHigh; + locallab.spots.at(j).labgridcieGx = locallab.spots.at(j).labgridcieGx && pSpot.labgridcieGx == otherSpot.labgridcieGx; + locallab.spots.at(j).labgridcieGy = locallab.spots.at(j).labgridcieGy && pSpot.labgridcieGy == otherSpot.labgridcieGy; + locallab.spots.at(j).labgridcieWx = locallab.spots.at(j).labgridcieWx && pSpot.labgridcieWx == otherSpot.labgridcieWx; + locallab.spots.at(j).labgridcieWy = locallab.spots.at(j).labgridcieWy && pSpot.labgridcieWy == otherSpot.labgridcieWy; + locallab.spots.at(j).labgridcieMx = locallab.spots.at(j).labgridcieMx && pSpot.labgridcieMx == otherSpot.labgridcieMx; + locallab.spots.at(j).labgridcieMy = locallab.spots.at(j).labgridcieMy && pSpot.labgridcieMy == otherSpot.labgridcieMy; + + locallab.spots.at(j).whitescie = locallab.spots.at(j).whitescie && pSpot.whitescie == otherSpot.whitescie; + locallab.spots.at(j).blackscie = locallab.spots.at(j).blackscie && pSpot.blackscie == otherSpot.blackscie; + locallab.spots.at(j).illMethod = locallab.spots.at(j).illMethod && pSpot.illMethod == otherSpot.illMethod; + locallab.spots.at(j).smoothciemet = locallab.spots.at(j).smoothciemet && pSpot.smoothciemet == otherSpot.smoothciemet; + locallab.spots.at(j).primMethod = locallab.spots.at(j).primMethod && pSpot.primMethod == otherSpot.primMethod; + locallab.spots.at(j).catMethod = locallab.spots.at(j).catMethod && pSpot.catMethod == otherSpot.catMethod; locallab.spots.at(j).sigmoidldajzcie = locallab.spots.at(j).sigmoidldajzcie && pSpot.sigmoidldajzcie == otherSpot.sigmoidldajzcie; locallab.spots.at(j).sigmoidthjzcie = locallab.spots.at(j).sigmoidthjzcie && pSpot.sigmoidthjzcie == otherSpot.sigmoidthjzcie; locallab.spots.at(j).sigmoidbljzcie = locallab.spots.at(j).sigmoidbljzcie && pSpot.sigmoidbljzcie == otherSpot.sigmoidbljzcie; locallab.spots.at(j).contqcie = locallab.spots.at(j).contqcie && pSpot.contqcie == otherSpot.contqcie; + locallab.spots.at(j).contsigqcie = locallab.spots.at(j).contsigqcie && pSpot.contsigqcie == otherSpot.contsigqcie; locallab.spots.at(j).colorflcie = locallab.spots.at(j).colorflcie && pSpot.colorflcie == otherSpot.colorflcie; locallab.spots.at(j).targabscie = locallab.spots.at(j).targabscie && pSpot.targabscie == otherSpot.targabscie; locallab.spots.at(j).targetGraycie = locallab.spots.at(j).targetGraycie && pSpot.targetGraycie == otherSpot.targetGraycie; locallab.spots.at(j).catadcie = locallab.spots.at(j).catadcie && pSpot.catadcie == otherSpot.catadcie; locallab.spots.at(j).detailcie = locallab.spots.at(j).detailcie && pSpot.detailcie == otherSpot.detailcie; locallab.spots.at(j).surroundcie = locallab.spots.at(j).surroundcie && pSpot.surroundcie == otherSpot.surroundcie; -/* - locallab.spots.at(j).lightlzcam = locallab.spots.at(j).lightlzcam && pSpot.lightlzcam == otherSpot.lightlzcam; - locallab.spots.at(j).lightqzcam = locallab.spots.at(j).lightqzcam && pSpot.lightqzcam == otherSpot.lightqzcam; - locallab.spots.at(j).contlzcam = locallab.spots.at(j).contlzcam && pSpot.contlzcam == otherSpot.contlzcam; - locallab.spots.at(j).contqzcam = locallab.spots.at(j).contqzcam && pSpot.contqzcam == otherSpot.contqzcam; - locallab.spots.at(j).contthreszcam = locallab.spots.at(j).contthreszcam && pSpot.contthreszcam == otherSpot.contthreszcam; - locallab.spots.at(j).colorflzcam = locallab.spots.at(j).colorflzcam && pSpot.colorflzcam == otherSpot.colorflzcam; - locallab.spots.at(j).saturzcam = locallab.spots.at(j).saturzcam && pSpot.saturzcam == otherSpot.saturzcam; - locallab.spots.at(j).chromzcam = locallab.spots.at(j).chromzcam && pSpot.chromzcam == otherSpot.chromzcam; -*/ - locallab.spots.at(j).enacieMask = locallab.spots.at(j).enaSHMask && pSpot.enaSHMask == otherSpot.enaSHMask; + + locallab.spots.at(j).strgradcie = locallab.spots.at(j).strgradcie && pSpot.strgradcie == otherSpot.strgradcie; + locallab.spots.at(j).anggradcie = locallab.spots.at(j).anggradcie && pSpot.anggradcie == otherSpot.anggradcie; + + locallab.spots.at(j).enacieMask = locallab.spots.at(j).enacieMask && pSpot.enacieMask == otherSpot.enacieMask; + locallab.spots.at(j).enacieMaskall = locallab.spots.at(j).enacieMaskall && pSpot.enacieMaskall == otherSpot.enacieMaskall; locallab.spots.at(j).CCmaskciecurve = locallab.spots.at(j).CCmaskciecurve && pSpot.CCmaskciecurve == otherSpot.CCmaskciecurve; locallab.spots.at(j).LLmaskciecurve = locallab.spots.at(j).LLmaskciecurve && pSpot.LLmaskciecurve == otherSpot.LLmaskciecurve; locallab.spots.at(j).HHmaskciecurve = locallab.spots.at(j).HHmaskciecurve && pSpot.HHmaskciecurve == otherSpot.HHmaskciecurve; + locallab.spots.at(j).HHhmaskciecurve = locallab.spots.at(j).HHhmaskciecurve && pSpot.HHhmaskciecurve == otherSpot.HHhmaskciecurve; locallab.spots.at(j).blendmaskcie = locallab.spots.at(j).blendmaskcie && pSpot.blendmaskcie == otherSpot.blendmaskcie; locallab.spots.at(j).radmaskcie = locallab.spots.at(j).radmaskcie && pSpot.radmaskcie == otherSpot.radmaskcie; locallab.spots.at(j).chromaskcie = locallab.spots.at(j).chromaskcie && pSpot.chromaskcie == otherSpot.chromaskcie; @@ -1811,6 +1866,15 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).clarilresjz = locallab.spots.at(j).clarilresjz && pSpot.clarilresjz == otherSpot.clarilresjz; locallab.spots.at(j).claricresjz = locallab.spots.at(j).claricresjz && pSpot.claricresjz == otherSpot.claricresjz; locallab.spots.at(j).clarisoftjz = locallab.spots.at(j).clarisoftjz && pSpot.clarisoftjz == otherSpot.clarisoftjz; + locallab.spots.at(j).strumaskcie = locallab.spots.at(j).strumaskcie && pSpot.strumaskcie == otherSpot.strumaskcie; + locallab.spots.at(j).toolcie = locallab.spots.at(j).toolcie && pSpot.toolcie == otherSpot.toolcie; + locallab.spots.at(j).fftcieMask = locallab.spots.at(j).fftcieMask && pSpot.fftcieMask == otherSpot.fftcieMask; + locallab.spots.at(j).blurcie = locallab.spots.at(j).blurcie && pSpot.blurcie == otherSpot.blurcie; + locallab.spots.at(j).contcie = locallab.spots.at(j).contcie && pSpot.contcie == otherSpot.contcie; + locallab.spots.at(j).highmaskcie = locallab.spots.at(j).highmaskcie && pSpot.highmaskcie == otherSpot.highmaskcie; + locallab.spots.at(j).shadmaskcie = locallab.spots.at(j).shadmaskcie && pSpot.shadmaskcie == otherSpot.shadmaskcie; + locallab.spots.at(j).LLmaskciecurvewav = locallab.spots.at(j).LLmaskciecurvewav && pSpot.LLmaskciecurvewav == otherSpot.LLmaskciecurvewav; + locallab.spots.at(j).csthresholdcie = locallab.spots.at(j).csthresholdcie && pSpot.csthresholdcie == otherSpot.csthresholdcie; } @@ -1890,12 +1954,17 @@ void ParamsEdited::initFrom(const std::vector& icm.outputBPC = icm.outputBPC && p.icm.outputBPC == other.icm.outputBPC ; icm.workingTRCGamma = icm.workingTRCGamma && p.icm.workingTRCGamma == other.icm.workingTRCGamma; icm.workingTRCSlope = icm.workingTRCSlope && p.icm.workingTRCSlope == other.icm.workingTRCSlope; + icm.wmidtcie = icm.wmidtcie && p.icm.wmidtcie == other.icm.wmidtcie; + icm.wsmoothcie = icm.wsmoothcie && p.icm.wsmoothcie == other.icm.wsmoothcie; icm.redx = icm.redx && p.icm.redx == other.icm.redx; icm.redy = icm.redy && p.icm.redy == other.icm.redy; icm.grex = icm.grex && p.icm.grex == other.icm.grex; icm.grey = icm.grey && p.icm.grey == other.icm.grey; icm.blux = icm.blux && p.icm.blux == other.icm.blux; icm.bluy = icm.bluy && p.icm.bluy == other.icm.bluy; + icm.refi = icm.refi && p.icm.refi == other.icm.refi; + icm.shiftx = icm.shiftx && p.icm.shiftx == other.icm.shiftx; + icm.shifty = icm.shifty && p.icm.shifty == other.icm.shifty; icm.labgridcieALow = icm.labgridcieALow && p.icm.labgridcieALow == other.icm.labgridcieALow; icm.labgridcieBLow = icm.labgridcieBLow && p.icm.labgridcieBLow == other.icm.labgridcieBLow; icm.labgridcieAHigh = icm.labgridcieAHigh && p.icm.labgridcieAHigh == other.icm.labgridcieAHigh; @@ -1904,13 +1973,17 @@ void ParamsEdited::initFrom(const std::vector& icm.labgridcieGy = icm.labgridcieGy && p.icm.labgridcieGy == other.icm.labgridcieGy; icm.labgridcieWx = icm.labgridcieWx && p.icm.labgridcieWx == other.icm.labgridcieWx; icm.labgridcieWy = icm.labgridcieWy && p.icm.labgridcieWy == other.icm.labgridcieWy; + icm.labgridcieMx = icm.labgridcieMx && p.icm.labgridcieMx == other.icm.labgridcieMx; + icm.labgridcieMy = icm.labgridcieMy && p.icm.labgridcieMy == other.icm.labgridcieMy; icm.preser = icm.preser && p.icm.preser == other.icm.preser; icm.fbw = icm.fbw && p.icm.fbw == other.icm.fbw; + icm.trcExp = icm.trcExp && p.icm.trcExp == other.icm.trcExp; icm.gamut = icm.gamut && p.icm.gamut == other.icm.gamut; icm.aRendIntent = icm.aRendIntent && p.icm.aRendIntent == other.icm.aRendIntent; icm.workingTRC = icm.workingTRC && p.icm.workingTRC == other.icm.workingTRC; icm.will = icm.will && p.icm.will == other.icm.will; icm.wprim = icm.wprim && p.icm.wprim == other.icm.wprim; + icm.wcat = icm.wcat && p.icm.wcat == other.icm.wcat; raw.bayersensor.method = raw.bayersensor.method && p.raw.bayersensor.method == other.raw.bayersensor.method; raw.bayersensor.border = raw.bayersensor.border && p.raw.bayersensor.border == other.raw.bayersensor.border; raw.bayersensor.imageNum = raw.bayersensor.imageNum && p.raw.bayersensor.imageNum == other.raw.bayersensor.imageNum; @@ -4155,7 +4228,7 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).shMethod = mods.locallab.spots.at(i).shMethod; } - for (int j = 0; j < 5; j++) { + for (int j = 0; j < 6; j++) { if (locallab.spots.at(i).multsh[j]) { toEdit.locallab.spots.at(i).multsh[j] = mods.locallab.spots.at(i).multsh[j]; } @@ -5606,6 +5679,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).ciecam = mods.locallab.spots.at(i).ciecam; } + if (locallab.spots.at(i).satlog) { + toEdit.locallab.spots.at(i).satlog = mods.locallab.spots.at(i).satlog; + } + if (locallab.spots.at(i).enaLMask) { toEdit.locallab.spots.at(i).enaLMask = mods.locallab.spots.at(i).enaLMask; } @@ -5622,6 +5699,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).whiteEv = mods.locallab.spots.at(i).whiteEv; } + if (locallab.spots.at(i).whiteslog) { + toEdit.locallab.spots.at(i).whiteslog = mods.locallab.spots.at(i).whiteslog; + } + + if (locallab.spots.at(i).blackslog) { + toEdit.locallab.spots.at(i).blackslog = mods.locallab.spots.at(i).blackslog; + } + + if (locallab.spots.at(i).comprlog) { + toEdit.locallab.spots.at(i).comprlog = mods.locallab.spots.at(i).comprlog; + } + + if (locallab.spots.at(i).strelog) { + toEdit.locallab.spots.at(i).strelog = mods.locallab.spots.at(i).strelog; + } + if (locallab.spots.at(i).detail) { toEdit.locallab.spots.at(i).detail = mods.locallab.spots.at(i).detail; } @@ -5816,6 +5909,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).expcie = mods.locallab.spots.at(i).expcie; } + if (locallab.spots.at(i).expprecam) { + toEdit.locallab.spots.at(i).expprecam = mods.locallab.spots.at(i).expprecam; + } + if (locallab.spots.at(i).complexcie) { toEdit.locallab.spots.at(i).complexcie = mods.locallab.spots.at(i).complexcie; } @@ -5848,14 +5945,39 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).jabcie = mods.locallab.spots.at(i).jabcie; } - if (locallab.spots.at(i).sigmoidqjcie) { - toEdit.locallab.spots.at(i).sigmoidqjcie = mods.locallab.spots.at(i).sigmoidqjcie; + if (locallab.spots.at(i).comprcieauto) { + toEdit.locallab.spots.at(i).comprcieauto = mods.locallab.spots.at(i).comprcieauto; + } + + if (locallab.spots.at(i).normcie) { + toEdit.locallab.spots.at(i).normcie = mods.locallab.spots.at(i).normcie; + } + + + if (locallab.spots.at(i).gamutcie) { + toEdit.locallab.spots.at(i).gamutcie = mods.locallab.spots.at(i).gamutcie; + } + + if (locallab.spots.at(i).sigcie) { + toEdit.locallab.spots.at(i).sigcie = mods.locallab.spots.at(i).sigcie; } if (locallab.spots.at(i).logcie) { toEdit.locallab.spots.at(i).logcie = mods.locallab.spots.at(i).logcie; } + if (locallab.spots.at(i).satcie) { + toEdit.locallab.spots.at(i).satcie = mods.locallab.spots.at(i).satcie; + } + + if (locallab.spots.at(i).logcieq) { + toEdit.locallab.spots.at(i).logcieq = mods.locallab.spots.at(i).logcieq; + } + + if (locallab.spots.at(i).smoothcie) { + toEdit.locallab.spots.at(i).smoothcie = mods.locallab.spots.at(i).smoothcie; + } + if (locallab.spots.at(i).logjz) { toEdit.locallab.spots.at(i).logjz = mods.locallab.spots.at(i).logjz; } @@ -5888,6 +6010,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).modecam = mods.locallab.spots.at(i).modecam; } + if (locallab.spots.at(i).bwevMethod) { + toEdit.locallab.spots.at(i).bwevMethod = mods.locallab.spots.at(i).bwevMethod; + } + if (locallab.spots.at(i).modecie) { toEdit.locallab.spots.at(i).modecie = mods.locallab.spots.at(i).modecie; } @@ -5980,6 +6106,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).lightqcie = mods.locallab.spots.at(i).lightqcie; } + if (locallab.spots.at(i).lightsigqcie) { + toEdit.locallab.spots.at(i).lightsigqcie = mods.locallab.spots.at(i).lightsigqcie; + } + if (locallab.spots.at(i).contlcie) { toEdit.locallab.spots.at(i).contlcie = mods.locallab.spots.at(i).contlcie; } @@ -5988,6 +6118,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).contjzcie = mods.locallab.spots.at(i).contjzcie; } + if (locallab.spots.at(i).detailciejz) { + toEdit.locallab.spots.at(i).detailciejz = mods.locallab.spots.at(i).detailciejz; + } + if (locallab.spots.at(i).adapjzcie) { toEdit.locallab.spots.at(i).adapjzcie = mods.locallab.spots.at(i).adapjzcie; } @@ -6048,10 +6182,142 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).sigmoidthcie = mods.locallab.spots.at(i).sigmoidthcie; } + if (locallab.spots.at(i).sigmoidsenscie) { + toEdit.locallab.spots.at(i).sigmoidsenscie = mods.locallab.spots.at(i).sigmoidsenscie; + } + if (locallab.spots.at(i).sigmoidblcie) { toEdit.locallab.spots.at(i).sigmoidblcie = mods.locallab.spots.at(i).sigmoidblcie; } + if (locallab.spots.at(i).comprcie) { + toEdit.locallab.spots.at(i).comprcie = mods.locallab.spots.at(i).comprcie; + } + + if (locallab.spots.at(i).strcielog) { + toEdit.locallab.spots.at(i).strcielog = mods.locallab.spots.at(i).strcielog; + } + + if (locallab.spots.at(i).comprcieth) { + toEdit.locallab.spots.at(i).comprcieth = mods.locallab.spots.at(i).comprcieth; + } + + if (locallab.spots.at(i).gamjcie) { + toEdit.locallab.spots.at(i).gamjcie = mods.locallab.spots.at(i).gamjcie; + } + + if (locallab.spots.at(i).slopjcie) { + toEdit.locallab.spots.at(i).slopjcie = mods.locallab.spots.at(i).slopjcie; + } + + if (locallab.spots.at(i).slopesmo) { + toEdit.locallab.spots.at(i).slopesmo = mods.locallab.spots.at(i).slopesmo; + } + + if (locallab.spots.at(i).midtcie) { + toEdit.locallab.spots.at(i).midtcie = mods.locallab.spots.at(i).midtcie; + } + + if (locallab.spots.at(i).grexl) { + toEdit.locallab.spots.at(i).grexl = mods.locallab.spots.at(i).grexl; + } + + if (locallab.spots.at(i).greyl) { + toEdit.locallab.spots.at(i).greyl = mods.locallab.spots.at(i).greyl; + } + + if (locallab.spots.at(i).redxl) { + toEdit.locallab.spots.at(i).redxl = mods.locallab.spots.at(i).redxl; + } + + if (locallab.spots.at(i).redyl) { + toEdit.locallab.spots.at(i).redyl = mods.locallab.spots.at(i).redyl; + } + + if (locallab.spots.at(i).bluxl) { + toEdit.locallab.spots.at(i).bluxl = mods.locallab.spots.at(i).bluxl; + } + + if (locallab.spots.at(i).bluyl) { + toEdit.locallab.spots.at(i).bluyl = mods.locallab.spots.at(i).bluyl; + } + + if (locallab.spots.at(i).refi) { + toEdit.locallab.spots.at(i).refi = mods.locallab.spots.at(i).refi; + } + + if (locallab.spots.at(i).shiftxl) { + toEdit.locallab.spots.at(i).shiftxl = mods.locallab.spots.at(i).shiftxl; + } + + if (locallab.spots.at(i).shiftyl) { + toEdit.locallab.spots.at(i).shiftyl = mods.locallab.spots.at(i).shiftyl; + } + + if (locallab.spots.at(i).labgridcieALow) { + toEdit.locallab.spots.at(i).labgridcieALow = mods.locallab.spots.at(i).labgridcieALow; + } + + if (locallab.spots.at(i).labgridcieBLow) { + toEdit.locallab.spots.at(i).labgridcieBLow = mods.locallab.spots.at(i).labgridcieBLow; + } + + if (locallab.spots.at(i).labgridcieAHigh) { + toEdit.locallab.spots.at(i).labgridcieAHigh = mods.locallab.spots.at(i).labgridcieAHigh; + } + + if (locallab.spots.at(i).labgridcieBHigh) { + toEdit.locallab.spots.at(i).labgridcieBHigh = mods.locallab.spots.at(i).labgridcieBHigh; + } + + if (locallab.spots.at(i).labgridcieGx) { + toEdit.locallab.spots.at(i).labgridcieGx = mods.locallab.spots.at(i).labgridcieGx; + } + + if (locallab.spots.at(i).labgridcieGy) { + toEdit.locallab.spots.at(i).labgridcieGy = mods.locallab.spots.at(i).labgridcieGy; + } + + if (locallab.spots.at(i).labgridcieWx) { + toEdit.locallab.spots.at(i).labgridcieWx = mods.locallab.spots.at(i).labgridcieWx; + } + + if (locallab.spots.at(i).labgridcieWy) { + toEdit.locallab.spots.at(i).labgridcieWy = mods.locallab.spots.at(i).labgridcieWy; + } + + if (locallab.spots.at(i).labgridcieMx) { + toEdit.locallab.spots.at(i).labgridcieMx = mods.locallab.spots.at(i).labgridcieMx; + } + + if (locallab.spots.at(i).labgridcieMy) { + toEdit.locallab.spots.at(i).labgridcieMy = mods.locallab.spots.at(i).labgridcieMy; + } + + if (locallab.spots.at(i).whitescie) { + toEdit.locallab.spots.at(i).whitescie = mods.locallab.spots.at(i).whitescie; + } + + if (locallab.spots.at(i).blackscie) { + toEdit.locallab.spots.at(i).blackscie = mods.locallab.spots.at(i).blackscie; + } + + if (locallab.spots.at(i).illMethod) { + toEdit.locallab.spots.at(i).illMethod = mods.locallab.spots.at(i).illMethod; + } + + if (locallab.spots.at(i).smoothciemet) { + toEdit.locallab.spots.at(i).smoothciemet = mods.locallab.spots.at(i).smoothciemet; + } + + if (locallab.spots.at(i).primMethod) { + toEdit.locallab.spots.at(i).primMethod = mods.locallab.spots.at(i).primMethod; + } + + if (locallab.spots.at(i).catMethod) { + toEdit.locallab.spots.at(i).catMethod = mods.locallab.spots.at(i).catMethod; + } + if (locallab.spots.at(i).sigmoidldajzcie) { toEdit.locallab.spots.at(i).sigmoidldajzcie = mods.locallab.spots.at(i).sigmoidldajzcie; } @@ -6069,42 +6335,13 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).contqcie = mods.locallab.spots.at(i).contqcie; } + if (locallab.spots.at(i).contsigqcie) { + toEdit.locallab.spots.at(i).contsigqcie = mods.locallab.spots.at(i).contsigqcie; + } + if (locallab.spots.at(i).colorflcie) { toEdit.locallab.spots.at(i).colorflcie = mods.locallab.spots.at(i).colorflcie; } -/* - if (locallab.spots.at(i).lightlzcam) { - toEdit.locallab.spots.at(i).lightlzcam = mods.locallab.spots.at(i).lightlzcam; - } - - if (locallab.spots.at(i).lightqzcam) { - toEdit.locallab.spots.at(i).lightqzcam = mods.locallab.spots.at(i).lightqzcam; - } - - if (locallab.spots.at(i).contlzcam) { - toEdit.locallab.spots.at(i).contlzcam = mods.locallab.spots.at(i).contlzcam; - } - - if (locallab.spots.at(i).contqzcam) { - toEdit.locallab.spots.at(i).contqzcam = mods.locallab.spots.at(i).contqzcam; - } - - if (locallab.spots.at(i).contthreszcam) { - toEdit.locallab.spots.at(i).contthreszcam = mods.locallab.spots.at(i).contthreszcam; - } - - if (locallab.spots.at(i).colorflzcam) { - toEdit.locallab.spots.at(i).colorflzcam = mods.locallab.spots.at(i).colorflzcam; - } - - if (locallab.spots.at(i).saturzcam) { - toEdit.locallab.spots.at(i).saturzcam = mods.locallab.spots.at(i).saturzcam; - } - - if (locallab.spots.at(i).chromzcam) { - toEdit.locallab.spots.at(i).chromzcam = mods.locallab.spots.at(i).chromzcam; - } -*/ if (locallab.spots.at(i).targabscie) { toEdit.locallab.spots.at(i).targabscie = mods.locallab.spots.at(i).targabscie; } @@ -6149,10 +6386,22 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).surroundcie = mods.locallab.spots.at(i).surroundcie; } + if (locallab.spots.at(i).strgradcie) { + toEdit.locallab.spots.at(i).strgradcie = mods.locallab.spots.at(i).strgradcie; + } + + if (locallab.spots.at(i).anggradcie) { + toEdit.locallab.spots.at(i).anggradcie = mods.locallab.spots.at(i).anggradcie; + } + if (locallab.spots.at(i).enacieMask) { toEdit.locallab.spots.at(i).enacieMask = mods.locallab.spots.at(i).enacieMask; } + if (locallab.spots.at(i).enacieMaskall) { + toEdit.locallab.spots.at(i).enacieMaskall = mods.locallab.spots.at(i).enacieMaskall; + } + if (locallab.spots.at(i).CCmaskciecurve) { toEdit.locallab.spots.at(i).CCmaskciecurve = mods.locallab.spots.at(i).CCmaskciecurve; } @@ -6165,6 +6414,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).HHmaskciecurve = mods.locallab.spots.at(i).HHmaskciecurve; } + if (locallab.spots.at(i).HHhmaskciecurve) { + toEdit.locallab.spots.at(i).HHhmaskciecurve = mods.locallab.spots.at(i).HHhmaskciecurve; + } + if (locallab.spots.at(i).blendmaskcie) { toEdit.locallab.spots.at(i).blendmaskcie = mods.locallab.spots.at(i).blendmaskcie; } @@ -6209,6 +6462,42 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).decaycie = mods.locallab.spots.at(i).decaycie; } + if (locallab.spots.at(i).strumaskcie) { + toEdit.locallab.spots.at(i).strumaskcie= mods.locallab.spots.at(i).strumaskcie; + } + + if (locallab.spots.at(i).toolcie) { + toEdit.locallab.spots.at(i).toolcie = mods.locallab.spots.at(i).toolcie; + } + + if (locallab.spots.at(i).fftcieMask) { + toEdit.locallab.spots.at(i).fftcieMask = mods.locallab.spots.at(i).fftcieMask; + } + + if (locallab.spots.at(i).blurcie) { + toEdit.locallab.spots.at(i).blurcie = mods.locallab.spots.at(i).blurcie; + } + + if (locallab.spots.at(i).contcie) { + toEdit.locallab.spots.at(i).contcie = mods.locallab.spots.at(i).contcie; + } + + if (locallab.spots.at(i).highmaskcie) { + toEdit.locallab.spots.at(i).highmaskcie = mods.locallab.spots.at(i).highmaskcie; + } + + if (locallab.spots.at(i).shadmaskcie) { + toEdit.locallab.spots.at(i).shadmaskcie = mods.locallab.spots.at(i).shadmaskcie; + } + + if (locallab.spots.at(i).LLmaskciecurvewav) { + toEdit.locallab.spots.at(i).LLmaskciecurvewav = mods.locallab.spots.at(i).LLmaskciecurvewav; + } + + if (locallab.spots.at(i).csthresholdcie) { + toEdit.locallab.spots.at(i).csthresholdcie = mods.locallab.spots.at(i).csthresholdcie; + } + } if (spot.enabled) { @@ -6461,6 +6750,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.workingTRCSlope = mods.icm.workingTRCSlope; } + if (icm.wmidtcie) { + toEdit.icm.wmidtcie = mods.icm.wmidtcie; + } + + if (icm.wsmoothcie) { + toEdit.icm.wsmoothcie = mods.icm.wsmoothcie; + } + if (icm.redx) { toEdit.icm.redx = mods.icm.redx; } @@ -6485,6 +6782,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.bluy = mods.icm.bluy; } + if (icm.refi) { + toEdit.icm.refi = mods.icm.refi; + } + + if (icm.shiftx) { + toEdit.icm.shiftx = mods.icm.shiftx; + } + + if (icm.shifty) { + toEdit.icm.shifty = mods.icm.shifty; + } + if (icm.preser) { toEdit.icm.preser = mods.icm.preser; } @@ -6493,6 +6802,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.fbw = mods.icm.fbw; } + if (icm.trcExp) { + toEdit.icm.trcExp = mods.icm.trcExp; + } + if (icm.gamut) { toEdit.icm.gamut = mods.icm.gamut; } @@ -6529,6 +6842,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.labgridcieWy = mods.icm.labgridcieWy; } + if (icm.labgridcieMx) { + toEdit.icm.labgridcieMx = mods.icm.labgridcieMx; + } + + if (icm.labgridcieMy) { + toEdit.icm.labgridcieMy = mods.icm.labgridcieMy; + } + if (icm.aRendIntent) { toEdit.icm.aRendIntent = mods.icm.aRendIntent; } @@ -6545,6 +6866,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.icm.wprim = mods.icm.wprim; } + if (icm.wcat) { + toEdit.icm.wcat = mods.icm.wcat; + } + if (raw.bayersensor.method) { toEdit.raw.bayersensor.method = mods.raw.bayersensor.method; } @@ -7685,7 +8010,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : expshadhigh(v), complexshadhigh(v), shMethod(v), - multsh{v, v, v, v, v, v}, + multsh{v, v, v, v, v, v, v}, highlights(v), h_tonalwidth(v), shadows(v), @@ -8054,8 +8379,13 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : fullimage(v), repar(v), ciecam(v), + satlog(v), blackEv(v), whiteEv(v), + whiteslog(v), + blackslog(v), + comprlog(v), + strelog(v), detail(v), sursour(v), surround(v), @@ -8108,6 +8438,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : visicie(v), complexcie(v), expcie(v), + expprecam(v), reparcie(v), sensicie(v), Autograycie(v), @@ -8115,8 +8446,14 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : forcebw(v), qtoj(v), jabcie(v), - sigmoidqjcie(v), + comprcieauto(v), + normcie(v), + gamutcie(v), + sigcie(v), logcie(v), + satcie(v), + logcieq(v), + smoothcie(v), logjz(v), sigjz(v), sigq(v), @@ -8125,6 +8462,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : sourceabscie(v), sursourcie(v), modecam(v), + bwevMethod(v), modecie(v), saturlcie(v), rstprotectcie(v), @@ -8149,8 +8487,10 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : lightlcie(v), lightjzcie(v), lightqcie(v), + lightsigqcie(v), contlcie(v), contjzcie(v), + detailciejz(v), adapjzcie(v), jz100(v), pqremap(v), @@ -8166,31 +8506,59 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : targetjz(v), sigmoidldacie(v), sigmoidthcie(v), + sigmoidsenscie(v), sigmoidblcie(v), + comprcie(v), + strcielog(v), + comprcieth(v), + gamjcie(v), + slopjcie(v), + slopesmo(v), + midtcie(v), + redxl(v), + redyl(v), + grexl(v), + greyl(v), + bluxl(v), + bluyl(v), + refi(v), + shiftxl(v), + shiftyl(v), + labgridcieALow(v), + labgridcieBLow(v), + labgridcieAHigh(v), + labgridcieBHigh(v), + labgridcieGx(v), + labgridcieGy(v), + labgridcieWx(v), + labgridcieWy(v), + labgridcieMx(v), + labgridcieMy(v), + whitescie(v), + blackscie(v), + illMethod(v), + smoothciemet(v), + primMethod(v), + catMethod(v), sigmoidldajzcie(v), sigmoidthjzcie(v), sigmoidbljzcie(v), contqcie(v), + contsigqcie(v), colorflcie(v), -/* - lightlzcam(v), - lightqzcam(v), - contlzcam(v), - contqzcam(v), - contthreszcam(v), - colorflzcam(v), - saturzcam(v), - chromzcam(v), -*/ targabscie(v), targetGraycie(v), catadcie(v), detailcie(v), surroundcie(v), + strgradcie(v), + anggradcie(v), enacieMask(v), + enacieMaskall(v), CCmaskciecurve(v), LLmaskciecurve(v), HHmaskciecurve(v), + HHhmaskciecurve(v), blendmaskcie(v), radmaskcie(v), sigmalcjz(v), @@ -8207,8 +8575,17 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : recothrescie(v), lowthrescie(v), higthrescie(v), - decaycie(v) - + decaycie(v), + strumaskcie(v), + toolcie(v), + fftcieMask(v), + contcie(v), + blurcie(v), + highmaskcie(v), + shadmaskcie(v), + LLmaskciecurvewav(v), + csthresholdcie(v) + { } @@ -8380,7 +8757,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) complexshadhigh = v; shMethod = v; - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 6; i++) { multsh[i] = v; } @@ -8755,8 +9132,13 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) fullimage = v; repar = v; ciecam = v; + satlog = v; blackEv = v; whiteEv = v; + whiteslog = v; + blackslog = v; + comprlog = v; + strelog = v; detail = v; sursour = v; surround = v; @@ -8809,6 +9191,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) visicie= v; complexcie= v; expcie = v; + expprecam = v; reparcie = v; sensicie = v; Autograycie = v; @@ -8816,8 +9199,14 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) forcebw = v; qtoj = v; jabcie = v; - sigmoidqjcie = v; + comprcieauto = v; + normcie = v; + gamutcie = v; + sigcie = v; logcie = v; + satcie = v; + logcieq = v; + smoothcie = v; logjz = v; sigjz = v; sigq = v; @@ -8826,6 +9215,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) sourceabscie = v; sursourcie = v; modecam = v; + bwevMethod = v; modecie = v; saturlcie = v; rstprotectcie = v; @@ -8850,8 +9240,10 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) lightlcie = v; lightjzcie = v; lightqcie = v; + lightsigqcie = v; contlcie = v; contjzcie = v; + detailciejz = v; adapjzcie = v; jz100 = v; pqremap = v; @@ -8867,31 +9259,59 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) targetjz = v; sigmoidldacie = v; sigmoidthcie = v; + sigmoidsenscie = v; sigmoidblcie = v; + comprcie = v; + strcielog = v; + comprcieth = v; + gamjcie = v; + slopjcie = v; + slopesmo = v; + midtcie = v; + redxl = v; + redyl = v; + grexl = v; + greyl = v; + bluxl = v; + bluyl = v; + refi = v; + shiftxl = v; + shiftyl = v; + labgridcieALow = v; + labgridcieBLow = v; + labgridcieAHigh= v; + labgridcieBHigh = v; + labgridcieGx = v; + labgridcieGy = v; + labgridcieWx = v; + labgridcieWy = v; + labgridcieMx = v; + labgridcieMy = v; + whitescie = v; + blackscie = v; + illMethod = v; + smoothciemet = v; + primMethod = v; + catMethod = v; sigmoidldajzcie = v; sigmoidthjzcie = v; sigmoidbljzcie = v; contqcie = v; + contsigqcie = v; colorflcie = v; -/* - lightlzcam = v; - lightqzcam = v; - contlzcam = v; - contqzcam = v; - contthreszcam = v; - colorflzcam = v; - saturzcam = v; - chromzcam = v; -*/ targabscie = v; targetGraycie = v; catadcie = v; detailcie = v; surroundcie = v; + anggradcie = v; + strgradcie = v; enacieMask = v; + enacieMaskall = v; CCmaskciecurve = v; LLmaskciecurve = v; HHmaskciecurve = v; + HHhmaskciecurve = v; blendmaskcie = v; radmaskcie = v; sigmalcjz = v; @@ -8909,6 +9329,15 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) lowthrescie = v; higthrescie = v; decaycie = v; + strumaskcie = v; + toolcie = v; + fftcieMask = v; + contcie = v; + blurcie = v; + highmaskcie = v; + shadmaskcie = v; + LLmaskciecurvewav = v; + csthresholdcie = v; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 260779a7f..c8bd39f9b 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -577,7 +577,7 @@ public: bool expshadhigh; bool complexshadhigh; bool shMethod; - bool multsh[6]; + bool multsh[7]; bool highlights; bool h_tonalwidth; bool shadows; @@ -946,8 +946,13 @@ public: bool fullimage; bool repar; bool ciecam; + bool satlog; bool blackEv; bool whiteEv; + bool whiteslog; + bool blackslog; + bool comprlog; + bool strelog; bool detail; bool sursour; bool surround; @@ -1000,6 +1005,7 @@ public: bool visicie; bool complexcie; bool expcie; + bool expprecam; bool reparcie; bool sensicie; bool Autograycie; @@ -1007,8 +1013,14 @@ public: bool forcebw; bool qtoj; bool jabcie; - bool sigmoidqjcie; + bool comprcieauto; + bool normcie; + bool gamutcie; + bool sigcie; bool logcie; + bool satcie; + bool logcieq; + bool smoothcie; bool logjz; bool sigjz; bool sigq; @@ -1017,6 +1029,7 @@ public: bool sourceabscie; bool sursourcie; bool modecam; + bool bwevMethod; bool modecie; bool saturlcie; bool rstprotectcie; @@ -1041,8 +1054,10 @@ public: bool lightlcie; bool lightjzcie; bool lightqcie; + bool lightsigqcie; bool contlcie; bool contjzcie; + bool detailciejz; bool adapjzcie; bool jz100; bool pqremap; @@ -1058,31 +1073,61 @@ public: bool targetjz; bool sigmoidldacie; bool sigmoidthcie; + bool sigmoidsenscie; bool sigmoidblcie; + bool comprcie; + bool strcielog; + bool comprcieth; + bool gamjcie; + bool slopjcie; + bool slopesmo; + bool midtcie; + bool redxl; + bool redyl; + bool grexl; + bool greyl; + bool bluxl; + bool bluyl; + bool refi; + bool shiftxl; + bool shiftyl; + bool labgridcieALow; + bool labgridcieBLow; + bool labgridcieAHigh; + bool labgridcieBHigh; + bool labgridcieGx; + bool labgridcieGy; + bool labgridcieWx; + bool labgridcieWy; + bool labgridcieMx; + bool labgridcieMy; + bool whitescie; + bool blackscie; + bool illMethod; + bool smoothciemet; + bool primMethod; + bool catMethod; bool sigmoidldajzcie; bool sigmoidthjzcie; bool sigmoidbljzcie; bool contqcie; + bool contsigqcie; bool colorflcie; -/* - bool lightlzcam; - bool lightqzcam; - bool contlzcam; - bool contqzcam; - bool contthreszcam; - bool colorflzcam; - bool saturzcam; - bool chromzcam; -*/ + bool targabscie; bool targetGraycie; bool catadcie; bool detailcie; bool surroundcie; + bool strgradcie; + bool anggradcie; + bool enacieMask; + bool enacieMaskall; bool CCmaskciecurve; bool LLmaskciecurve; bool HHmaskciecurve; + bool HHhmaskciecurve; bool blendmaskcie; bool radmaskcie; bool sigmalcjz; @@ -1100,7 +1145,16 @@ public: bool lowthrescie; bool higthrescie; bool decaycie; - + bool strumaskcie; + bool toolcie; + bool fftcieMask; + bool contcie; + bool blurcie; + bool highmaskcie; + bool shadmaskcie; + bool LLmaskciecurvewav; + bool csthresholdcie; + LocallabSpotEdited(bool v); void set(bool v); @@ -1242,16 +1296,23 @@ struct ColorManagementParamsEdited { bool workingTRC; bool workingTRCGamma; bool workingTRCSlope; + bool wmidtcie; + bool wsmoothcie; bool will; bool wprim; + bool wcat; bool redx; bool redy; bool grex; bool grey; bool blux; bool bluy; + bool refi; + bool shiftx; + bool shifty; bool preser; bool fbw; + bool trcExp; bool gamut; bool labgridcieALow; bool labgridcieBLow; @@ -1261,6 +1322,8 @@ struct ColorManagementParamsEdited { bool labgridcieGy; bool labgridcieWx; bool labgridcieWy; + bool labgridcieMx; + bool labgridcieMy; bool aRendIntent; bool outputProfile; bool outputIntent; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index c3ce7f6af..c807a1bd2 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -1749,7 +1749,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) strend->setValue(pp->wavelet.strend); detend->setValue(pp->wavelet.detend); thrend->setValue(pp->wavelet.thrend); - labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0, false); + labgrid->setParams(pp->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, pp->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0, false); sigm->setValue(pp->wavelet.sigm); levden->setValue(pp->wavelet.levden); @@ -2212,7 +2212,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.chromco = chromco->getValue(); double zerox = 0.; double zeroy = 0.; - labgrid->getParams(pp->wavelet.labgridALow, pp->wavelet.labgridBLow, pp->wavelet.labgridAHigh, pp->wavelet.labgridBHigh, zerox, zeroy, zerox, zeroy); + labgrid->getParams(pp->wavelet.labgridALow, pp->wavelet.labgridBLow, pp->wavelet.labgridAHigh, pp->wavelet.labgridBHigh, zerox, zeroy, zerox, zeroy, zerox, zeroy); pp->wavelet.labgridALow *= WaveletParams::LABGRID_CORR_MAX; pp->wavelet.labgridAHigh *= WaveletParams::LABGRID_CORR_MAX; pp->wavelet.labgridBLow *= WaveletParams::LABGRID_CORR_MAX; @@ -2672,7 +2672,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balchrom->setDefault(defParams->wavelet.balchrom); chromfi->setDefault(defParams->wavelet.chromfi); chromco->setDefault(defParams->wavelet.chromco); - labgrid->setDefault(defParams->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0); + labgrid->setDefault(defParams->wavelet.labgridALow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBLow / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridAHigh / WaveletParams::LABGRID_CORR_MAX, defParams->wavelet.labgridBHigh / WaveletParams::LABGRID_CORR_MAX, 0, 0, 0, 0, 0, 0); greenlow->setDefault(defParams->wavelet.greenlow); bluelow->setDefault(defParams->wavelet.bluelow); From 129e3f4dd8fdaad29e1bab650d5a12355f78a5d1 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Mon, 15 Apr 2024 07:54:24 +0200 Subject: [PATCH 180/291] Reset windows.yml appimage.yml --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index fd2652345..cf82dafb8 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:lacam16n2"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 2f752f978..6963df7c9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:lacam16n2"]' + publish_pre_dev_labels: '[]' jobs: build: From 4d715cf281c53eb49e1cb3d41afff776f9632d34 Mon Sep 17 00:00:00 2001 From: xiota Date: Tue, 16 Apr 2024 15:49:40 +0000 Subject: [PATCH 181/291] Make requested changes --- rtengine/imageio.cc | 91 +++++++++++++++++++++------------------------ rtengine/imageio.h | 2 +- rtengine/utils.cc | 3 +- rtgui/thumbnail.cc | 34 +++++++++-------- 4 files changed, 64 insertions(+), 66 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index c6576b3c8..5f5573265 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -24,6 +24,7 @@ #include #include #include + #include #include #include @@ -31,10 +32,7 @@ #include #ifdef LIBJXL -#include -#include "jxl/decode.h" #include "jxl/decode_cxx.h" -#include "jxl/resizable_parallel_runner.h" #include "jxl/resizable_parallel_runner_cxx.h" #endif @@ -832,17 +830,16 @@ int ImageIO::loadTIFF (const Glib::ustring &fname) #ifdef LIBJXL #define _PROFILE_ JXL_COLOR_PROFILE_TARGET_ORIGINAL // adapted from libjxl -int ImageIO::loadJxl(const Glib::ustring &fname) +int ImageIO::loadJXL(const Glib::ustring &fname) { if (pl) { pl->setProgressStr("PROGRESSBAR_LOADJXL"); pl->setProgress(0.0); } - std::vector icc_profile; - - gpointer buffer = nullptr; - size_t buffer_size = 0; + std::vector icc_profile; + std::vector buffer; + std::size_t buffer_size = 0; JxlBasicInfo info = {}; JxlPixelFormat format = {}; @@ -852,28 +849,25 @@ int ImageIO::loadJxl(const Glib::ustring &fname) format.endianness = JXL_NATIVE_ENDIAN; format.align = 0; - // get file contents - std::ifstream instream(fname.c_str(), std::ios::in | std::ios::binary); - std::vector compressed( - (std::istreambuf_iterator(instream)), - std::istreambuf_iterator()); - instream.close(); + std::string const contents = Glib::file_get_contents(fname); + std::vector const compressed(contents.begin(), contents.end()); // multi-threaded parallel runner. auto runner = JxlResizableParallelRunnerMake(nullptr); auto dec = JxlDecoderMake(nullptr); + if (JXL_DEC_SUCCESS != - JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | - JXL_DEC_COLOR_ENCODING | - JXL_DEC_FULL_IMAGE)) { + JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | + JXL_DEC_COLOR_ENCODING | + JXL_DEC_FULL_IMAGE)) { g_printerr("Error: JxlDecoderSubscribeEvents failed\n"); return IMIO_HEADERERROR; } if (JXL_DEC_SUCCESS != - JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, - runner.get())) { + JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, + runner.get())) { g_printerr("Error: JxlDecoderSetParallelRunner failed\n"); return IMIO_HEADERERROR; } @@ -897,31 +891,32 @@ int ImageIO::loadJxl(const Glib::ustring &fname) // check for ICC profile deleteLoadedProfileData(); embProfile = nullptr; - size_t icc_size = 0; + std::size_t icc_size = 0; if (JXL_DEC_SUCCESS != #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) - JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) + JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) #else - JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) + JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) #endif - ) { + ) { g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); } if (icc_size > 0) { icc_profile.resize(icc_size); + if (JXL_DEC_SUCCESS != #if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) - JxlDecoderGetColorAsICCProfile( - dec.get(), &format, _PROFILE_, - icc_profile.data(), icc_profile.size()) + JxlDecoderGetColorAsICCProfile( + dec.get(), &format, _PROFILE_, + icc_profile.data(), icc_profile.size()) #else - JxlDecoderGetColorAsICCProfile( - dec.get(), _PROFILE_, - icc_profile.data(), icc_profile.size()) + JxlDecoderGetColorAsICCProfile( + dec.get(), _PROFILE_, + icc_profile.data(), icc_profile.size()) #endif - ) { + ) { g_printerr( "Warning: JxlDecoderGetColorAsICCProfile failed\n"); } else { @@ -932,7 +927,10 @@ int ImageIO::loadJxl(const Glib::ustring &fname) g_printerr("Warning: Empty ICC data.\n"); } } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { - format.data_type = JXL_TYPE_FLOAT; + // Note: If this assert is ever triggered, it should be changed + // to an assignment. We want the maximum bit depth the decoder + // can provide regardless of the original encoding intent. + assert(format.data_type == JXL_TYPE_FLOAT); if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { @@ -940,20 +938,19 @@ int ImageIO::loadJxl(const Glib::ustring &fname) return IMIO_READERROR; } - buffer = g_malloc(buffer_size); - if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer, buffer_size)) { + buffer.resize(buffer_size); + + if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer.data(), buffer.size())) { g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); - g_free(buffer); return IMIO_READERROR; } } else if (status == JXL_DEC_FULL_IMAGE || status == JXL_DEC_FRAME) { // Nothing to do. If the image is an animation, more full frames // may be decoded. This example only keeps the first one. + break; } else if (status == JXL_DEC_SUCCESS) { - // All decoding successfully finished. - // It's not required to call JxlDecoderReleaseInput(dec.get()) - // since the decoder will be destroyed. + // Decoding complete. Decoder will be released automatically. break; } else if (status == JXL_DEC_NEED_MORE_INPUT) { g_printerr("Error: Already provided all input\n"); @@ -967,26 +964,24 @@ int ImageIO::loadJxl(const Glib::ustring &fname) } } // end grand decode loop - unsigned int width = info.xsize; - unsigned int height = info.ysize; + std::size_t width = info.xsize; + std::size_t height = info.ysize; allocate(width, height); - int line_length = width * 3 * 4; + std::size_t line_length = width * 3 * 4; - for (size_t row = 0; row < height; ++row) { - setScanline (row, ((const unsigned char*)buffer) + (row * line_length), 32); + for (std::size_t row = 0; row < height; ++row) { + setScanline(row, ((const unsigned char*)buffer.data()) + (row * line_length), 32); if (pl && !(row % 100)) { - pl->setProgress ((double)(row) / height); + pl->setProgress((double)(row) / height); } } - g_free(buffer); - if (pl) { - pl->setProgressStr ("PROGRESSBAR_READY"); - pl->setProgress (1.0); + pl->setProgressStr("PROGRESSBAR_READY"); + pl->setProgress(1.0); } return IMIO_SUCCESS; @@ -1484,7 +1479,7 @@ int ImageIO::load (const Glib::ustring &fname) return loadJPEG (fname); #ifdef LIBJXL } else if (hasJxlExtension(fname)) { - return loadJxl(fname); + return loadJXL(fname); #endif } else if (hasTiffExtension(fname)) { return loadTIFF (fname); diff --git a/rtengine/imageio.h b/rtengine/imageio.h index cfc54e629..3703839b2 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -91,7 +91,7 @@ public: int save (const Glib::ustring &fname) const; #ifdef LIBJXL - int loadJxl (const Glib::ustring &fname); + int loadJXL (const Glib::ustring &fname); #endif int loadPNG (const Glib::ustring &fname); diff --git a/rtengine/utils.cc b/rtengine/utils.cc index 4c4f18691..f631a410a 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -240,8 +240,7 @@ bool hasJpegExtension(const Glib::ustring& filename) #ifdef LIBJXL bool hasJxlExtension(const Glib::ustring& filename) { - const Glib::ustring extension = getFileExtension(filename); - return extension == "jxl"; + return getFileExtension(filename) == "jxl"; } #endif diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 18829d9e1..84f81ce76 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -182,12 +182,12 @@ Glib::ustring Thumbnail::xmpSidecarPath(const Glib::ustring &imagePath) return rtengine::Exiv2Metadata::xmpSidecarPath(imagePath); } -void Thumbnail::_generateThumbnailImage () +void Thumbnail::_generateThumbnailImage() { // delete everything loaded into memory delete tpp; tpp = nullptr; - delete [] lastImg; + delete[] lastImg; lastImg = nullptr; tw = options.maxThumbnailWidth; th = options.maxThumbnailHeight; @@ -211,21 +211,24 @@ void Thumbnail::_generateThumbnailImage () bool quick = false; rtengine::eSensorType sensorType = rtengine::ST_NONE; - if ( initial_ && options.internalThumbIfUntouched) { + + if (initial_ && options.internalThumbIfUntouched) { quick = true; - tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, sensorType, tw, th, 1, TRUE); + tpp = rtengine::Thumbnail::loadQuickFromRaw(fname, sensorType, tw, th, 1, TRUE); } - if ( tpp == nullptr ) { + if (!tpp) { quick = false; - tpp = rtengine::Thumbnail::loadFromRaw (fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); + tpp = rtengine::Thumbnail::loadFromRaw(fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); } cfs.sensortype = sensorType; + if (tpp) { cfs.format = FT_Raw; cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; - infoFromImage (fname); + infoFromImage(fname); + if (!quick) { cfs.width = tpp->full_width; cfs.height = tpp->full_height; @@ -234,7 +237,8 @@ void Thumbnail::_generateThumbnailImage () if (!tpp) { // this will load formats supported by imagio (jpg, png, jxl, and tiff) - tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); + tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); + if (tpp) { cfs.format = FT_Custom; infoFromImage(fname); @@ -243,12 +247,12 @@ void Thumbnail::_generateThumbnailImage () if (tpp) { tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul); - _saveThumbnail (); + _saveThumbnail(); cfs.supported = true; - cfs.save (getCacheFileName ("data", ".txt")); + cfs.save(getCacheFileName("data", ".txt")); - generateExifDateTimeStrings (); + generateExifDateTimeStrings(); } } @@ -718,10 +722,10 @@ rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::Pro MyMutex::MyLock lock(mutex); - if ( tpp == nullptr ) { + if (!tpp) { _loadThumbnail(); - if ( tpp == nullptr ) { + if (!tpp) { return nullptr; } } @@ -755,7 +759,7 @@ rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::Pro _generateThumbnailImage(); - if ( tpp == nullptr ) { + if (!tpp) { return nullptr; } @@ -961,7 +965,7 @@ void Thumbnail::_loadThumbnail(bool firstTrial) _loadThumbnail (false); } - if (tpp == nullptr) { + if (!tpp) { return; } } else if (!succ) { From a1eaa8f64e803d8bf884787f0ef3e56b8e920b9c Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 18 Apr 2024 15:12:42 +0200 Subject: [PATCH 182/291] fix ModifyDate --- rtengine/metadata.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 0a55c1424..2e75e1f3c 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -29,6 +29,7 @@ #include "imagedata.h" #include "../rtgui/version.h" #include "../rtgui/pathutils.h" +#include #if EXIV2_TEST_VERSION(0,28,0) @@ -312,6 +313,13 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag } dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; + + std::time_t t = std::time(nullptr); + char mbstr[100]; + if (std::strftime(mbstr, sizeof(mbstr), "%Y:%m:%d %H:%M:%S", std::localtime(&t))) { + dst->exifData()["Exif.Image.ModifyDate"] = mbstr; + } + import_exif_pairs(dst->exifData()); import_iptc_pairs(dst->iptcData()); bool xmp_tried = false; From 1aea652fea98df0268161bb84ff2f1dbd976973a Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 18 Apr 2024 16:48:08 +0200 Subject: [PATCH 183/291] Add correct DateTime (editing date) to Exif data Currently, RT does not save the editing date (Exif tag DateTime) in the exif data of the exported files, only DateTimeOriginal (the date/time the photo was captured). This patch fixes this. --- rtengine/metadata.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 2e75e1f3c..38d115b7e 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -317,7 +317,7 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag std::time_t t = std::time(nullptr); char mbstr[100]; if (std::strftime(mbstr, sizeof(mbstr), "%Y:%m:%d %H:%M:%S", std::localtime(&t))) { - dst->exifData()["Exif.Image.ModifyDate"] = mbstr; + dst->exifData()["Exif.Image.DateTime"] = mbstr; } import_exif_pairs(dst->exifData()); From b5abd46d0cfad8bd0cf9f1d63c46fe138c1b73c0 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 18 Apr 2024 23:13:21 -0700 Subject: [PATCH 184/291] Add divider in pop-up button for RawTherapee theme Provide a visual cue that there are two buttons. --- rtdata/themes/RawTherapee.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtdata/themes/RawTherapee.css b/rtdata/themes/RawTherapee.css index 499b2197e..486181ba9 100644 --- a/rtdata/themes/RawTherapee.css +++ b/rtdata/themes/RawTherapee.css @@ -1300,6 +1300,11 @@ combobox, .popupbutton-arrow { min-height: 2em; } +/* Visual divider between the icon and arrow in the pop-up button. */ +.image-combo button.Left { + border-right: solid 0.083333333333333333em #202020; +} + /* Makes image-combobox small icons centered */ button.toggle > grid > image { padding: 0.3333333333333333em; From 30cf3f721fdac985ca240db154377571913d5bfa Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 20 Apr 2024 17:11:31 +0200 Subject: [PATCH 185/291] UV photos - Wish from LarsHP Increased green (tint) value from 10 to 100 (#7043) * Change limits green to 40 instead of 10 * Publish uvgreen in pre-dev appimage.yml windows.yml * Change range setLogScale * Revert change to observer 2 - format * Set maxgreen 60 * Set maxgreen 100 and minequal 0.5 maxequal 1.8 * Set maxgreen 1000 minequal 0.4 maxequal 2.5 * Set maxgreen 100 minequal 0.5 maxequal 2 --- .github/workflows/appimage.yml | 4 ++-- .github/workflows/windows.yml | 1 + rtengine/colortemp.cc | 1 - rtengine/colortemp.h | 6 +++--- rtgui/whitebalance.cc | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index cf82dafb8..5a5c3b8d0 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,8 +15,8 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' - + publish_pre_dev_labels: '[]' + jobs: build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6963df7c9..e5f4ce166 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -17,6 +17,7 @@ on: env: publish_pre_dev_labels: '[]' + jobs: build: runs-on: windows-latest diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index 1c98b3e8b..f8a4b60b2 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -32,7 +32,6 @@ namespace rtengine { - static const color_match_type cie_colour_match_jd2 = {//350nm to 830nm 5 nm J.Desmis 2° Standard Observer. {0.0000000, 0.000000, 0.000000}, {0.0000000, 0.000000, 0.000000}, {0.0001299, 0.0003917, 0.0006061}, {0.0002321, 0.000006965, 0.001086}, {0.0004149, 0.00001239, 0.001946}, {0.0007416, 0.00002202, 0.003846}, diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h index db69abe2d..00b79ef85 100644 --- a/rtengine/colortemp.h +++ b/rtengine/colortemp.h @@ -31,9 +31,9 @@ using color_match_type = double [97][3]; constexpr double MINTEMP = 1500.0; constexpr double MAXTEMP = 60000.0; constexpr double MINGREEN = 0.02; -constexpr double MAXGREEN = 10.0; -constexpr double MINEQUAL = 0.8; -constexpr double MAXEQUAL = 1.5; +constexpr double MAXGREEN = 100.0; +constexpr double MINEQUAL = 0.5; +constexpr double MAXEQUAL = 2.; constexpr double INITIALBLACKBODY = 4000.0; enum class StandardObserver { diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 63a1d2100..d207ef7a2 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -31,9 +31,9 @@ #define MAXTEMP 60000 //12000 #define CENTERTEMP 4750 #define MINGREEN 0.02 -#define MAXGREEN 10.0 -#define MINEQUAL 0.8 -#define MAXEQUAL 1.5 +#define MAXGREEN 100.0 +#define MINEQUAL 0.5 +#define MAXEQUAL 2. using namespace rtengine; using namespace rtengine::procparams; @@ -396,7 +396,7 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC pack_start(*StudLabel); pack_start(*PatchLabel); pack_start(*PatchlevelLabel); - + green->setLogScale(MAXGREEN / MINGREEN, MINGREEN); pack_start (*temp); //pack_start (*boxgreen); pack_start (*green); From c72e67ae24b00cb669165a965cbd6633ff44e4de Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 20 Apr 2024 17:34:53 +0200 Subject: [PATCH 186/291] Limits incompatibility between Ciecam and CBDL and others to Cam02 #7017 (#7023) * CBDL and others only with ciecam Cam16 * Change windows and appimage yml * Remove appimage.yml and windows.yml --- rtengine/dcrop.cc | 18 ++++++++++++------ rtengine/improccoordinator.cc | 12 ++++++++---- rtengine/rtthumbnail.cc | 3 ++- rtengine/simpleprocess.cc | 20 +++++++++++++------- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a489bd681..bc0972092 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -813,7 +813,8 @@ void Crop::update(int todo) const bool needstransform = parent->ipf.needsTransform(skips(parent->fw, skip), skips(parent->fh, skip), parent->imgsrc->getRotateDegree(), parent->imgsrc->getMetaData()); // transform - if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) { + // if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) { + if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && params.colorappearance.modelmethod != "02")) { if (!transCrop) { transCrop = new Imagefloat(cropw, croph); } @@ -834,7 +835,8 @@ void Crop::update(int todo) transCrop = nullptr; } - if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { + // if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && params.colorappearance.modelmethod != "02") { const int W = baseCrop->getWidth(); const int H = baseCrop->getHeight(); @@ -1329,21 +1331,24 @@ void Crop::update(int todo) parent->ipf.vibrance(labnCrop, params.vibrance, params.toneCurve.hrenabled, params.icm.workingProfile); parent->ipf.labColorCorrectionRegions(labnCrop); - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (params.colorappearance.modelmethod != "02")) { parent->ipf.EPDToneMap(labnCrop, 0, skip); } //parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay. // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled if (skip == 1) { - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02")) { parent->ipf.impulsedenoise(labnCrop); parent->ipf.defringe(labnCrop); } parent->ipf.MLsharpen(labnCrop); - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02")) { parent->ipf.MLmicrocontrast(labnCrop); parent->ipf.sharpening(labnCrop, params.sharpening, parent->sharpMask); } @@ -1352,7 +1357,8 @@ void Crop::update(int todo) // if (skip==1) { if (params.dirpyrequalizer.cbdlMethod == "aft") { - if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { + // if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { + if (((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02"))) { parent->ipf.dirpyrequalizer(labnCrop, skip); // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 604d353c4..8a6fd06e4 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -860,7 +860,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bool needstransform = ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData()); - if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) { + // if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) { + if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && params->colorappearance.modelmethod != "02"))) { // Forking the image assert(oprevi); Imagefloat *op = oprevi; @@ -882,7 +883,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } - if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled) { + // if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled) { + if ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && params->colorappearance.modelmethod != "02") { const int W = oprevi->getWidth(); const int H = oprevi->getHeight(); LabImage labcbdl(W, H); @@ -1755,12 +1757,14 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) ipf.vibrance(nprevl, params->vibrance, params->toneCurve.hrenabled, params->icm.workingProfile); ipf.labColorCorrectionRegions(nprevl); - if ((params->colorappearance.enabled && !params->colorappearance.tonecie) || (!params->colorappearance.enabled)) { + // if ((params->colorappearance.enabled && !params->colorappearance.tonecie) || (!params->colorappearance.enabled)) { + if ((params->colorappearance.enabled && !params->colorappearance.tonecie) || (params->colorappearance.modelmethod != "02")) { ipf.EPDToneMap(nprevl, 0, scale); } if (params->dirpyrequalizer.cbdlMethod == "aft") { - if (((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled))) { + // if (((params->colorappearance.enabled && !settings->autocielab) || (!params->colorappearance.enabled))) { + if (((params->colorappearance.enabled && !settings->autocielab) || (params->colorappearance.modelmethod != "02"))) { ipf.dirpyrequalizer(nprevl, scale); } } diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1691912a1..1816a7470 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1528,7 +1528,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) { + // if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) { + if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || params.colorappearance.modelmethod != "02") { ipf.EPDToneMap (labView, 5, 6); } diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index e7d13884c..241d628e9 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1004,7 +1004,7 @@ private: } } } - + //colorappearance.modelmethod == "02" bool execcam = false; //execcam => work around for pre-ciecam in LA: about 0.1 second @@ -1523,7 +1523,8 @@ private: ipf.chromiLuminanceCurve(nullptr, 1, labView, labView, curve1, curve2, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy); - if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !params.colorappearance.tonecie) || (params.colorappearance.modelmethod != "02")) { ipf.EPDToneMap(labView, 0, 1); } @@ -1533,7 +1534,8 @@ private: // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02")) { ipf.impulsedenoise(labView); ipf.defringe(labView); } @@ -1543,12 +1545,14 @@ private: } if (params.sharpenMicro.enabled) { - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + // if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + if ((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02")) { ipf.MLmicrocontrast(labView); //!params.colorappearance.sharpcie } } - if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { + // if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { + if (((params.colorappearance.enabled && !settings->autocielab) || (params.colorappearance.modelmethod != "02")) && params.sharpening.enabled) { ipf.sharpening(labView, params.sharpening); } @@ -1557,7 +1561,8 @@ private: // directional pyramid wavelet if (params.dirpyrequalizer.cbdlMethod == "aft") { - if ((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { + // if ((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { + if ((params.colorappearance.enabled && !settings->autocielab) || params.colorappearance.modelmethod != "02") { ipf.dirpyrequalizer(labView, 1); //TODO: this is the luminance tonecurve, not the RGB one } } @@ -1935,7 +1940,8 @@ private: } } - bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili && !params.colorappearance.enabled; + // bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili && !params.colorappearance.enabled; + bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled && !autili && !butili && params.colorappearance.modelmethod != "02"; ///////////// Custom output gamma has been removed, the user now has to create ///////////// a new output profile with the ICCProfileCreator From 8c5fc60a7d3c3fb62f13f88d7c284f0ba7bd391f Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 21 Apr 2024 02:17:19 +0000 Subject: [PATCH 187/291] Make requested changes * Remove cast in scanline * Improve Glib::ustring conversion --- rtengine/imageio.cc | 36 ++++++++++++++++++++---------------- rtengine/utils.cc | 19 +++++++++++++++++++ rtengine/utils.h | 4 ++++ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 5f5573265..44297b10f 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -25,17 +25,17 @@ #include #include +#ifdef LIBJXL +#include "jxl/decode_cxx.h" +#include "jxl/resizable_parallel_runner_cxx.h" +#endif + #include #include #include #include #include -#ifdef LIBJXL -#include "jxl/decode_cxx.h" -#include "jxl/resizable_parallel_runner_cxx.h" -#endif - #ifdef _WIN32 #include #else @@ -849,8 +849,12 @@ int ImageIO::loadJXL(const Glib::ustring &fname) format.endianness = JXL_NATIVE_ENDIAN; format.align = 0; - std::string const contents = Glib::file_get_contents(fname); - std::vector const compressed(contents.begin(), contents.end()); + std::vector const compressed = getFileData(fname); + + if (compressed.empty()) { + g_printerr("Error: loadJXL failed to get data from file\n"); + return IMIO_READERROR; + } // multi-threaded parallel runner. auto runner = JxlResizableParallelRunnerMake(nullptr); @@ -894,7 +898,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) std::size_t icc_size = 0; if (JXL_DEC_SUCCESS != -#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0) JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) #else JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) @@ -907,7 +911,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) icc_profile.resize(icc_size); if (JXL_DEC_SUCCESS != -#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0,8,0) +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0) JxlDecoderGetColorAsICCProfile( dec.get(), &format, _PROFILE_, icc_profile.data(), icc_profile.size()) @@ -927,9 +931,9 @@ int ImageIO::loadJXL(const Glib::ustring &fname) g_printerr("Warning: Empty ICC data.\n"); } } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { - // Note: If this assert is ever triggered, it should be changed - // to an assignment. We want the maximum bit depth the decoder - // can provide regardless of the original encoding intent. + // Note: If assert is triggered, change to assignment. + // We want maximum bit depth from the decoder, + // regardless of the original encoding intent. assert(format.data_type == JXL_TYPE_FLOAT); if (JXL_DEC_SUCCESS != @@ -953,7 +957,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) // Decoding complete. Decoder will be released automatically. break; } else if (status == JXL_DEC_NEED_MORE_INPUT) { - g_printerr("Error: Already provided all input\n"); + g_printerr("Error: Decoder needs more input data\n"); return IMIO_READERROR; } else if (status == JXL_DEC_ERROR) { g_printerr("Error: Decoder error\n"); @@ -962,7 +966,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) g_printerr("Error: Unknown decoder status\n"); return IMIO_READERROR; } - } // end grand decode loop + } // end grand decode loop std::size_t width = info.xsize; std::size_t height = info.ysize; @@ -972,10 +976,10 @@ int ImageIO::loadJXL(const Glib::ustring &fname) std::size_t line_length = width * 3 * 4; for (std::size_t row = 0; row < height; ++row) { - setScanline(row, ((const unsigned char*)buffer.data()) + (row * line_length), 32); + setScanline(row, buffer.data() + (row * line_length), 32); if (pl && !(row % 100)) { - pl->setProgress((double)(row) / height); + pl->setProgress((double)(row + 1) / height); } } diff --git a/rtengine/utils.cc b/rtengine/utils.cc index f631a410a..6a8321d1c 100644 --- a/rtengine/utils.cc +++ b/rtengine/utils.cc @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "rt_math.h" #include "utils.h" @@ -222,6 +224,23 @@ void vflip(unsigned char* img, int w, int h) } } +std::vector getFileData(const Glib::ustring &filename) +{ + try { + const std::string fn = Glib::filename_from_utf8(filename); + std::ifstream instream(fn, std::ios::in | std::ios::binary); + + std::vector contents( + (std::istreambuf_iterator(instream)), + std::istreambuf_iterator()); + + instream.close(); + return contents; + } catch (...) { + return {}; + } +} + Glib::ustring getFileExtension(const Glib::ustring& filename) { const Glib::ustring::size_type lastdot_pos = filename.find_last_of('.'); diff --git a/rtengine/utils.h b/rtengine/utils.h index 7ff16c79b..5dec93f51 100644 --- a/rtengine/utils.h +++ b/rtengine/utils.h @@ -18,6 +18,8 @@ */ #pragma once +#include + #include #include @@ -43,6 +45,8 @@ constexpr typename std::underlying_type::type toUnderlying(ENUM value) return static_cast::type>(value); } +std::vector getFileData(const Glib::ustring &filename); + // Return lower case extension without the "." or "" if the given name contains no "." Glib::ustring getFileExtension(const Glib::ustring& filename); // Return true if file has .jpeg or .jpg extension (ignoring case) From 223afc3af869a8ea23d64a07203b0e028adc9efd Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Mon, 22 Apr 2024 06:36:33 +0800 Subject: [PATCH 188/291] ProcessorTargets: support PowerPC --- ProcessorTargets.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ProcessorTargets.cmake b/ProcessorTargets.cmake index 60fd1e35f..fdd4bc40a 100644 --- a/ProcessorTargets.cmake +++ b/ProcessorTargets.cmake @@ -10,6 +10,8 @@ set(PROC_TARGET_2_LABEL native CACHE STRING "Processor-2 label - use it for your # The flag is different on x86 and Arm based processors if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL arm64) set(PROC_TARGET_2_FLAGS "-mcpu=native" CACHE STRING "Processor-2 flags") +elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "ppc|powerpc") + set(PROC_TARGET_2_FLAGS "-mtune=native" CACHE STRING "Processor-2 flags") else() set(PROC_TARGET_2_FLAGS "-march=native" CACHE STRING "Processor-2 flags") endif() From 232c11c37c9e76cd8b1c76d982d5dcb55b137686 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 22 Apr 2024 09:45:12 +0200 Subject: [PATCH 189/291] dcp: avoid file descriptor leak on error. If the provided file doesn't contain valid dcp metadata the DCPProfile constructor will return without closing the file descriptor. --- rtengine/dcp.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 940b3c0c0..524ecf8af 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1134,6 +1134,7 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : DCPMetadata md(file); if (!md.parse()) { printf ("Unable to load DCP profile '%s'.", filename.c_str()); + fclose(file); return; } From ff65f865594d8914b9c68d0f1d1198ac15a4d7f6 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Wed, 24 Apr 2024 11:37:43 +0200 Subject: [PATCH 190/291] dcp: use std::unique_ptr to automatically close file descriptor Use std::unique_ptr to automatically close file descriptor instead of manually closing it at every return point. --- rtengine/dcp.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 524ecf8af..df5627d2e 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1124,17 +1124,20 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : 1.00000f }; - FILE* const file = g_fopen(filename.c_str(), "rb"); + const std::unique_ptr> file( + g_fopen(filename.c_str(), "rb"), + [](std::FILE *file) { + std::fclose(file); + }); if (file == nullptr) { printf ("Unable to load DCP profile '%s' !", filename.c_str()); return; } - DCPMetadata md(file); + DCPMetadata md(file.get()); if (!md.parse()) { printf ("Unable to load DCP profile '%s'.", filename.c_str()); - fclose(file); return; } @@ -1175,7 +1178,6 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Color Matrix (one is always there) if (!md.find(TAG_KEY_COLOR_MATRIX_1)) { std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; - fclose(file); return; } @@ -1352,10 +1354,6 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : } } - if (file) { - fclose(file); - } - valid = true; } From a53ddf4282bfa89c7694f86fa8cc11ec656069ff Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 1 May 2024 07:49:14 +0200 Subject: [PATCH 191/291] Ciecam - Change management viewing temperature and tint #7055 (#7058) * Change management viewing temperature and tint * Enable autotemp wbcamchanged and hide history message * Change wbcamchnaged as proposed by kaesa --- rtengine/improccoordinator.cc | 4 ++-- rtengine/rtengine.h | 2 +- rtgui/colorappearance.cc | 26 ++++++++++++++++++++++---- rtgui/colorappearance.h | 2 +- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8a6fd06e4..fbdddf63a 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -2308,8 +2308,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) tempsym = params->colorappearance.tempout; greensym = params->colorappearance.greenout; } - if (params->colorappearance.enabled) { - acListener->wbCamChanged(tempsym, greensym); //real temp and tint. + if (params->colorappearance.enabled && acListener) { + acListener->wbCamChanged(tempsym, greensym, params->colorappearance.autotempout); //real temp and tint. } } else { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index fdd6676e6..e76d17336 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -372,7 +372,7 @@ public : virtual void autoCamChanged(double ccam, double ccamout) = 0; virtual void adapCamChanged(double cadap) = 0; virtual void ybCamChanged(int yb) = 0; - virtual void wbCamChanged(double tem, double tin) = 0; + virtual void wbCamChanged(double tem, double tin, bool autotemp) = 0; }; diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc index 0390ef869..d18cddcad 100644 --- a/rtgui/colorappearance.cc +++ b/rtgui/colorappearance.cc @@ -1880,18 +1880,36 @@ void ColorAppearance::adapCamChanged (double cadap) } -void ColorAppearance::wbCamChanged (double temp, double tin) +void ColorAppearance::wbCamChanged (double temp, double tin, bool autotemp) {//reactivate this function idle_register.add( - [this, temp, tin]() -> bool + [this, temp, tin, autotemp]() -> bool + { + if (temp != tempout->getValue()) { + disableListener(); + tempout->setValue(temp); + enableListener(); + listener->panelChanged (EvCATtempout, tempout->getTextValue()); + } + if (tin != greenout->getValue()) { + disableListener(); + greenout->setValue(tin); + enableListener(); + listener->panelChanged (EvCATgreenout, greenout->getTextValue()); + } + /* disableListener(); tempout->setValue(temp); greenout->setValue(tin); enableListener(); - listener->panelChanged (EvCATgreenout, greenout->getTextValue()); - listener->panelChanged (EvCATtempout, tempout->getTextValue()); + + if(!autotemp) { + listener->panelChanged (EvCATgreenout, "");//greenout->getTextValue()); + listener->panelChanged (EvCATtempout, "");//tempout->getTextValue()); + }*/ + return false; } ); diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h index 714f3e557..e8f6084cd 100644 --- a/rtgui/colorappearance.h +++ b/rtgui/colorappearance.h @@ -66,7 +66,7 @@ public: void autoCamChanged (double ccam, double ccamout) override; bool autoCamComputed_ (); void adapCamChanged (double cadap) override; - void wbCamChanged(double tem, double tin) override; + void wbCamChanged(double tem, double tin, bool autotemp) override; bool adapCamComputed_ (); void ybCamChanged (int yb) override; bool ybCamComputed_ (); From ca569b051b258400cff14f72b32df69a33a13377 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Wed, 1 May 2024 10:48:15 +0200 Subject: [PATCH 192/291] Fixed bad variable assignement in iplocallab.cc --- rtengine/iplocallab.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 37ef276df..d7eca81ff 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -933,8 +933,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.balanexp = locallab.spots.at(sp).balanexp; lp.linear = locallab.spots.at(sp).linear; - if (locallab.spots.at(sp).smoothciemet == "norm") { - lp.smoothciem = 1; + if (locallab.spots.at(sp).smoothciemet == "none") { + lp.smoothciem = 0; } else if (locallab.spots.at(sp).smoothciemet == "Ev") { lp.smoothciem = 1; } else if (locallab.spots.at(sp).smoothciemet == "gam") { @@ -943,7 +943,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.smoothciem = 3; } - if (locallab.spots.at(sp).smoothciemet == "none") { + if (locallab.spots.at(sp).spotMethod == "norm") { lp.fullim = 0; } else if (locallab.spots.at(sp).spotMethod == "exc") { lp.fullim = 1; From b7749c0719c8e8e058b38a07a454df5c10eebd6f Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 2 May 2024 09:59:47 +0200 Subject: [PATCH 193/291] Add correct DateTime to Exif date --- rtengine/metadata.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/metadata.cc b/rtengine/metadata.cc index 38d115b7e..1e0962dd2 100644 --- a/rtengine/metadata.cc +++ b/rtengine/metadata.cc @@ -315,9 +315,9 @@ void Exiv2Metadata::saveToImage(const Glib::ustring &path, bool preserve_all_tag dst->exifData()["Exif.Image.Software"] = "RawTherapee " RTVERSION; std::time_t t = std::time(nullptr); - char mbstr[100]; + char mbstr[20]; if (std::strftime(mbstr, sizeof(mbstr), "%Y:%m:%d %H:%M:%S", std::localtime(&t))) { - dst->exifData()["Exif.Image.DateTime"] = mbstr; + dst->exifData()["Exif.Image.DateTime"] = mbstr; } import_exif_pairs(dst->exifData()); From 068420da605a57e60ba9b021a6c1f1009d39b1f7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 2 May 2024 22:12:44 -0700 Subject: [PATCH 194/291] Use camera crop factor to select Lensfun lens --- rtengine/rtlensfun.cc | 75 +++++++++++++++++++++++++++++++++++++------ rtengine/rtlensfun.h | 2 +- rtgui/lensprofile.cc | 6 ++-- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index fc5bb0017..df518c133 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -25,6 +25,61 @@ #include "rtlensfun.h" #include "settings.h" + +namespace +{ + +bool isCStringIn(const char *str, const char *const *list) +{ + for (auto element_ptr = list; *element_ptr; element_ptr++) { + if (!strcmp(str, *element_ptr)) { + return true; + } + } + return false; +} + +bool isNextLensCropFactorBetter(const lfLens *current_lens, const lfCamera *camera, float next_lens_crop_factor) +{ + if (!current_lens) { + // No current lens, so next lens's crop factor is + // automatically better. + return true; + } + + const float current_lens_crop_factor = current_lens->CropFactor; + + if (!camera) { + // Favor the smaller crop factor for maximum coverage. + return current_lens_crop_factor > next_lens_crop_factor; + } + + const float camera_crop_factor = camera->CropFactor; + + if (current_lens_crop_factor > camera_crop_factor) { + // Current lens's data does not cover the entire camera + // sensor. Any lens's data with a smaller crop factor is + // better. + return current_lens->CropFactor > next_lens_crop_factor; + } + + // Current lens's data covers the entire camera sensor. A lens + // with data from a larger crop factor will be more precise, but + // also must not be larger than the camera sensor's crop factor + // to maintain full coverage. + return current_lens->CropFactor < next_lens_crop_factor && + next_lens_crop_factor <= camera_crop_factor; +} + +bool isNextLensBetter(const lfCamera *camera, const lfLens *current_lens, const lfLens &next_lens, const Glib::ustring &lens_name, const Glib::ustring &next_lens_name) +{ + return isNextLensCropFactorBetter(current_lens, camera, next_lens.CropFactor) && + lens_name == next_lens_name && + (!camera || isCStringIn(camera->Mount, next_lens.Mounts)); +} + +} // namespace + namespace rtengine { @@ -460,20 +515,25 @@ LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring & } -LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) const +LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const { LFLens ret; if (data_ && !name.empty()) { MyMutex::MyLock lock(lfDBMutex); - if (!camera.data_) { + if (!autoMatch) { // Only the lens name provided. Try to find exact match by name. LFLens candidate; + LFLens bestCandidate; + for (auto lens_list = data_->GetLenses(); lens_list[0]; lens_list++) { candidate.data_ = lens_list[0]; - if (name == candidate.getLens()) { - return candidate; + if (isNextLensBetter(camera.data_, bestCandidate.data_, *(candidate.data_), name, candidate.getLens())) { + bestCandidate.data_ = candidate.data_; } } + if (bestCandidate.data_) { + return bestCandidate; + } } auto found = data_->FindLenses(camera.data_, nullptr, name.c_str()); for (size_t pos = 0; !found && pos < name.size(); ) { @@ -562,12 +622,7 @@ std::unique_ptr LFDatabase::findModifier( } const LFCamera c = findCamera(make, model, lensProf.lfAutoMatch()); - const LFLens l = findLens( - lensProf.lfAutoMatch() - ? c - : LFCamera(), - lens - ); + const LFLens l = findLens(c, lens, lensProf.lfAutoMatch()); bool swap_xy = false; if (rawRotationDeg >= 0) { diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index bcce77f34..1d941246f 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -121,7 +121,7 @@ public: std::vector getCameras() const; std::vector getLenses() const; LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model, bool autoMatch) const; - LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const; + LFLens findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const; std::unique_ptr findModifier( const procparams::LensProfParams &lensProf, diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 0e17b3f40..5f42a1cde 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -251,7 +251,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa if (pp->lensProf.lfAutoMatch()) { if (metadata) { - const LFLens l = db->findLens(c, metadata->getLens()); + const LFLens l = db->findLens(c, metadata->getLens(), true); setLensfunLens(l.getLens()); } } else if (pp->lensProf.lfManual()) { @@ -522,7 +522,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) } else if (metadata) { const LFDatabase* const db = LFDatabase::getInstance(); const LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel(), true); - const LFLens l = db->findLens(c, metadata->getLens()); + const LFLens l = db->findLens(c, metadata->getLens(), true); setLensfunCamera(c.getMake(), c.getModel()); setLensfunLens(l.getLens()); } @@ -808,7 +808,7 @@ void LensProfilePanel::updateLensfunWarning() return; } - const LFLens l = db->findLens(LFCamera(), (*itl)[lf->lensfunModelLens.lens]); + const LFLens l = db->findLens(c, (*itl)[lf->lensfunModelLens.lens], false); const float lenscrop = l.getCropFactor(); const float camcrop = c.getCropFactor(); From ca3d4a06b629dc7aa62f8ca1e9de1dac3e935301 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 Apr 2024 18:00:34 -0700 Subject: [PATCH 195/291] Fix Panasonic DMC-FX150 16:9 raw crop The dcraw default leaves a couple of unwanted pixels on the right and bottom edges. Other aspect ratios are fine. --- rtengine/camconst.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 06c23afae..3f78739a5 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2323,6 +2323,13 @@ Camera constants: "ranges": { "black": 15, "white": 4050 } // 15 is BL offset. dcraw/RT read the base offset from Exif and calculates total BL = BLbase+BLoffset }, + { // Quality C + "make_model": "Panasonic DMC-FX150", + "raw_crop": [ + { "frame": [ 4508, 2498 ], "crop": [ 0, 0, 4429, 2496] } // 16:9 ratio needs to shave a few extra pixels from dcraw's crop. + ] + }, + { // Quality A, replicated from rawimage.cc "make_model": "Panasonic DMC-FZ150", "dcraw_matrix": [ 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 ], // RT, copy from custom dcp d55 From 18d69a6af631329b381e082c80d9d04d74fba89d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 12 May 2024 07:33:48 +0200 Subject: [PATCH 196/291] Local adjustments - Colorappearance Cam16 - Source Data Adjustments - levels R G B and Black & White (#7071) * Change management viewing temperature and tint * Enable autotemp wbcamchanged and hide history message * Change wbcamchnaged as proposed by kaesa * First step levels * Levels with luminosity mode * History messages * Clean and comment code * Gamutmap xyz levels values * Change range slope R G B * Change range slope R G B * Harmonize case Slope and Levels * Harmonize case Slope and Levels 2 * Check Scale Yb viewing * Small change * Checbox black and white in source data adjustments * Change tooltip avoid color shift issue 7066 * modify appimage.yml and windows.yml * Fixed bad primaries space in free * Fixed bwcie only in advanced mode --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 17 ++- rtengine/dcrop.cc | 7 +- rtengine/improccoordinator.cc | 3 +- rtengine/improcfun.h | 2 +- rtengine/iplocallab.cc | 213 +++++++++++++++++++++++++--- rtengine/procparams.cc | 24 ++++ rtengine/procparams.h | 6 + rtengine/rtengine.h | 1 + rtengine/simpleprocess.cc | 3 +- rtgui/locallab.cc | 3 +- rtgui/locallabtools.h | 20 ++- rtgui/locallabtools2.cc | 250 ++++++++++++++++++++++++++++++++- rtgui/paramsedited.cc | 43 +++++- rtgui/paramsedited.h | 6 + 16 files changed, 567 insertions(+), 35 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5a5c3b8d0..90beb2c18 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:levels"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e5f4ce166..b30dd9f20 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:levels"]' jobs: diff --git a/rtdata/languages/default b/rtdata/languages/default index ad8962037..81c7bfeee 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1453,6 +1453,7 @@ HISTORY_MSG_ILLUM;CAL - SC - Illuminant HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local CIECAM - gradient angle HISTORY_MSG_LOCAL_CIE_BRICOMP;Local CIECAM Brightness compression HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local CIECAM Brightness compression threshold +HISTORY_MSG_LOCAL_CIE_BWCIE;Local CIECAM - black and white HISTORY_MSG_LOCAL_CIE_CAT;Matrix adaptation HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local JzCzHz Local contrast HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local CIECAM All mask tools @@ -1470,6 +1471,9 @@ HISTORY_MSG_LOCAL_CIE_SIGADAP;Local CIECAM Sigmoid adaptability HISTORY_MSG_LOCAL_CIE_SIGMET;Local CIECAM - Sigmoid method HISTORY_MSG_LOCAL_CIE_SLOP;Local CIECAM - Slope HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local CIECAM - Gray balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local CIECAM - Red balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local CIECAM - Green balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local CIECAM - Blue balance HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local CIECAM - Smooth lights method HISTORY_MSG_LOCAL_CIE_STRGRAD;Local CIECAM - gradient strength L HISTORY_MSG_LOCAL_CIE_TRC;Local CIECAM - TRC @@ -1483,6 +1487,8 @@ HISTORY_MSG_LOCAL_CIE_BLUYL;Local CIECAM - Blue Y HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local CIECAM - Shift x HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local CIECAM - Shift y HISTORY_MSG_LOCAL_CIE_SMOOTH;Local CIECAM - Scale Yb Scene +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local CIECAM - Scale Yb Viewing +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local CIECAM - levels - luminosity mode HISTORY_MSG_LOCAL_CIE_SATCIE;Local CIECAM - Saturation control HISTORY_MSG_LOCAL_CIE_STRLOG;Local CIECAM - Log encoding strength HISTORY_MSG_LOCAL_CIE_WHITES;Local CIECAM - Whites distribution @@ -2684,6 +2690,7 @@ TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). Th TP_ICM_APPLYLOOKTABLE;Look table TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. TP_ICM_BPC;Black Point Compensation +TP_ICM_BW;Black and White TP_ICM_DCPILLUMINANT;Illuminant TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -2843,7 +2850,7 @@ TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Automatic TP_LOCALLAB_AVOID;Avoid color shift -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. The result is not the same as Lab. TP_LOCALLAB_AVOIDMUN;Munsell correction only TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2920,9 +2927,10 @@ TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) TP_LOCALLAB_CIE_SMOOTH_NONE;None TP_LOCALLAB_CIE_SMOOTH_EV;Ev based -TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation +TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation & Levels TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels TP_LOCALLAB_CIEC;Use Ciecam environment parameters TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIECOLORFRA;Color @@ -3551,9 +3559,14 @@ TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic, when the dynamic TP_LOCALLAB_SLOMASKCOL;Slope TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) TP_LOCALLAB_SLOSH;Slope TP_LOCALLAB_SMOOTHCIE;Smooth & Tone-Mapping +TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma - Slope - based: choice (Standard and Advanced) allows you to simulate a "Tone mapping" using: a) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%); b) Viewing conditions: Mean luminance (Yb%).\nScale Yb Scene is function of White-Ev. TP_LOCALLAB_SOFT;Soft Light & Original Retinex TP_LOCALLAB_SOFTM;Soft Light diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index bc0972092..580475c37 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1062,10 +1062,11 @@ void Crop::update(int todo) float stdretie = parent->stdretis[sp]; float fab = 1.f; - float maxicam = -1000.f; + float maxicam = -1000.f; float rdx, rdy, grx, gry, blx, bly = 0.f; float meanx, meany, meanxe, meanye = 0.f; int ill = 2; + int prim = 3; float minCD; float maxCD; float mini; @@ -1155,7 +1156,7 @@ void Crop::update(int todo) huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, parent->previewDeltaE, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallvibMask, parent->localllcMask, parent->locallsharMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, parent->localllogMask, parent->locall_Mask, parent->locallcieMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, maxicam,rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye,ill, contsig, lightsig, + meantme, stdtme, meanretie, stdretie, fab, maxicam,rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); LocallabListener::locallabDenoiseLC denoiselc; @@ -1268,7 +1269,7 @@ void Crop::update(int todo) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, + meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index fbdddf63a..5f8a4df15 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1280,6 +1280,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float rdx, rdy, grx, gry, blx, bly = 0.f; float meanx, meany, meanxe, meanye = 0.f; int ill = 2; + int prim = 3; bool istm = params->locallab.spots.at(sp).equiltm && params->locallab.spots.at(sp).exptonemap; bool isreti = params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti; //preparation for mean and sigma on current RT-spot @@ -1426,7 +1427,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantm, stdtm, meanreti, stdreti, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, + meantm, stdtm, meanreti, stdreti, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 3283c8b64..9c6c794f0 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -364,7 +364,7 @@ enum class BlurType { double& huerefblur, double &chromarefblur, double& lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int &lastsav, bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &ill, float &contsig, float &lightsig, + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &prim, int &ill, float &contsig, float &lightsig, float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46); void tone_eqcam2(ImProcFunctions *ipf, Imagefloat *rgb, int whits, int blacks, const Glib::ustring &workingProfile, double scale, bool multithread); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index d7eca81ff..a40f2f146 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -941,8 +941,11 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.smoothciem = 2; } else if (locallab.spots.at(sp).smoothciemet == "gamnorol") { lp.smoothciem = 3; + } else if (locallab.spots.at(sp).smoothciemet == "level") { + lp.smoothciem = 4; } + if (locallab.spots.at(sp).spotMethod == "norm") { lp.fullim = 0; } else if (locallab.spots.at(sp).spotMethod == "exc") { @@ -2610,12 +2613,15 @@ float do_get(float x, bool rolloff_, float mid_gray_scene, float gamma, float dr //Copyright (c) 2023 Thatcher Freeman // Adapted to Rawtherapee Jacques Desmis 25 mars 2024 -void tonemapFreeman(float target_slope, float white_point, float black_point, float mid_gray_scene, float mid_gray_view, bool rolloff, LUTf& lut, int mode, bool scale) +void tonemapFreeman(float target_slope, float target_sloper, float target_slopeg , float target_slopeb, float white_point, float black_point, float mid_gray_scene, float mid_gray_view, bool rolloff, LUTf& lut, LUTf& lutr, LUTf& lutg, LUTf& lutb, int mode, bool scale, bool takeyb) { float dr;//Dynamic Range float b; float c;//black point float gamma; + float gammar; + float gammag; + float gammab; float mid_gray_scene_;//Mean luminance - Scene conditions // mid_gray_view //Mean luminance - Viewing conditions @@ -2630,8 +2636,18 @@ void tonemapFreeman(float target_slope, float white_point, float black_point, fl b = (dr / (mid_gray_scene_ - c)) * (1.f - ((mid_gray_scene_ - c) / dr)) * mid_gray_scene_;//b - ponderate mid_gray_scene taking into account the total DR, and the dark part below the mid_gray_scene gamma = target_slope * (float) std::pow((mid_gray_scene_ + b), 2.0) / (dr * b);//Caculate gamma with slope and mid_gray_scene + gammar = target_sloper * (float) std::pow((mid_gray_scene_ + b), 2.0) / (dr * b);//Caculate gamma with slope and mid_gray_scene + gammag = target_slopeg * (float) std::pow((mid_gray_scene_ + b), 2.0) / (dr * b);//Caculate gamma with slope and mid_gray_scene + gammab = target_slopeb * (float) std::pow((mid_gray_scene_ + b), 2.0) / (dr * b);//Caculate gamma with slope and mid_gray_scene float kmid = 1.f;//general case - if(mode == 3 && target_slope != 1.f) {//case tone-mapping + //float kyb = 1.f; + if(takeyb){ + kmid = mid_gray_scene / mid_gray_view; + kmid = cbrt(kmid); + } + // if(mode == 3 && target_slope != 1.f ) {//case tone-mapping +/* + float midutil = mid_gray_view / mid_gray_scene;//take into account ratio between Yb source and Yb viewing float midk = 1.f; float k_slope = 2.2f; @@ -2639,13 +2655,24 @@ void tonemapFreeman(float target_slope, float white_point, float black_point, fl midk = pow_F(midutil, k_slope * (target_slope - 1.f));//ponderation in function target_slope when "slope user" < 1.f } kmid = midk; + } - if (settings->verbose) { +*/ + if (mode == 3 && settings->verbose) { printf("b=%f gamma=%f slope=%f DynRange=%f kmid=%f black=%f Yb-scale=%f\n", (double) b, (double) gamma, (double) target_slope, (double) dr, (double) kmid, (double) c, (double) mid_gray_scene_); } //lut - take from Alberto Griggio - for (int i = 0; i < 65536; ++i) {// i - value image RGB - lut[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gamma, dr, b, c, kmid);//call main function + if(mode == 4) { + for (int i = 0; i < 65536; ++i) {// i - value image RGB + lutr[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gammar, dr, b, c, kmid);//call main function + lutg[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gammag, dr, b, c, kmid);//call main function + lutb[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gammab, dr, b, c, kmid);//call main function + } + } else { + kmid = 1.f; + for (int i = 0; i < 65536; ++i) {// i - value image RGB + lut[i] = do_get(float(i) / 65535.f, rolloff, mid_gray_scene_, gamma, dr, b, c, kmid);//call main function + } } } @@ -13769,7 +13796,7 @@ void ImProcFunctions::Lab_Local( double& huerefblur, double& chromarefblur, double& lumarefblur, double& hueref, double& chromaref, double& lumaref, double& sobelref, int &lastsav, bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float& minCD, float& maxCD, float& mini, float& maxi, float& Tmean, float& Tsigma, float& Tmin, float& Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab,float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &ill, float &contsig, float &lightsig, + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab,float &maxicam, float &rdx, float &rdy, float &grx, float &gry, float &blx, float &bly, float &meanx, float &meany, float &meanxe, float &meanye, int &prim, int &ill, float &contsig, float &lightsig, float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46 ) @@ -19961,6 +19988,42 @@ void ImProcFunctions::Lab_Local( } if (params->locallab.spots.at(sp).expprecam && params->locallab.spots.at(sp).modecam == "cam16") { + TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); + TMatrix wiprof = ICCStore::getInstance()->workingSpaceInverseMatrix(params->icm.workingProfile); + + float toxyz[3][3] = { + { + static_cast(wprof[0][0] / static_cast(Color::D50x)), + static_cast(wprof[0][1] / static_cast(Color::D50x)), + static_cast(wprof[0][2] / static_cast(Color::D50x)) + }, { + static_cast(wprof[1][0]), + static_cast(wprof[1][1]), + static_cast(wprof[1][2]) + }, { + static_cast(wprof[2][0] / static_cast(Color::D50z)), + static_cast(wprof[2][1] / static_cast(Color::D50z)), + static_cast(wprof[2][2] / static_cast(Color::D50z)) + } + }; + + float maxFactorToxyz = max(toxyz[1][0], toxyz[1][1], toxyz[1][2]); + float equalR = maxFactorToxyz / toxyz[1][0]; + float equalG = maxFactorToxyz / toxyz[1][1]; + float equalB = maxFactorToxyz / toxyz[1][2]; + //inverse matrix user select + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + + Imagefloat *tmpImage = nullptr; tmpImage = new Imagefloat(bfw, bfh); Imagefloat *tmpImagelog = nullptr; @@ -19972,7 +20035,7 @@ void ImProcFunctions::Lab_Local( float gamtone = params->locallab.spots.at(sp).gamjcie; float slotone = params->locallab.spots.at(sp).slopjcie; cmsHTRANSFORM dummy = nullptr; - int prim = 3; + //int prim = 3; int typ = 1; rdx = params->locallab.spots.at(sp).redxl; rdy = params->locallab.spots.at(sp).redyl; @@ -20095,42 +20158,147 @@ void ImProcFunctions::Lab_Local( if(lp.smoothciem == 1) { tone_eqsmooth(this, tmpImage, lp, params->icm.workingProfile, sk, multiThread);//reduce Ev > 0 < 12 - } else if(lp.smoothciem == 2 || lp.smoothciem == 3) {// 2 - only smmoth highlightd - 3 - Tone mapping with slope and mid_grey + } else if(lp.smoothciem == 2 || lp.smoothciem == 3 || lp.smoothciem == 4) {// 2 - only smmoth highlightd - 3 - Tone mapping with slope and mid_grey //TonemapFreeman - Copyright (c) 2023 Thatcher Freeman float mid_gray = 0.01f * lp.sourcegraycie;//Mean luminance Yb Scene float mid_gray_view = 0.01f * lp.targetgraycie;//Mean luminance Yb Viewing + // if(mode == 3 && target_slope != 1.f ) {//case tone-mapping +/* if(params->locallab.spots.at(sp).{ + float midutil = mid_gray_view / mid_gray_scene;//take into account ratio between Yb source and Yb viewing + float midk = 1.f; + float k_slope = 2.2f; + if(target_slope >= 1.f) { + midk = pow_F(midutil, k_slope * (target_slope - 1.f));//ponderation in function target_slope when "slope user" < 1.f + } + kmid = midk; + + } +*/ lp.whiteevjz = LIM(lp.whiteevjz, 0.1f, 31.5f);//limit whiteEv to avoid crash float white_point = xexpf(lp.whiteevjz * std::log(2.f) + xlogf(mid_gray));//lp.whiteevjz White_Ev lp.blackevjz = LIM(lp.blackevjz, -15.5f, -0.2f);//limit BlackEv to avoid crash float black_point = xexpf(lp.blackevjz * std::log(2.f) + xlogf(mid_gray));//lp.blackevjz Black_Ev bool rolloff = true;//only soften highlights float slopegray = 1.f;//slopegray between 0.8 and 1.6 - lineary light the shadows by the user - the gamma is calculated according to slope and the characteristics of the image DR, White, Black + float slopegrayr = 1.f; + float slopegrayg = 1.f; + float slopegrayb = 1.f; int mode = 1; float slopsmoot = 1.f - ((float) params->locallab.spots.at(sp).slopesmo - 1.f);//modify response so when increase slope the grays are becoming lighter + float slopsmootr = 1.f - ((float) params->locallab.spots.at(sp).slopesmor - 1.f); + float slopsmootg = 1.f - ((float) params->locallab.spots.at(sp).slopesmog - 1.f); + float slopsmootb = 1.f - ((float) params->locallab.spots.at(sp).slopesmob - 1.f); + bool takeyb = params->locallab.spots.at(sp).smoothcieyb; + bool lummod = params->locallab.spots.at(sp).smoothcielum; + float maxsl= 4.f;//maximum real slope + float minslider = 0.01f;//minimum slider value > 0.f + float aa = (1.9f - maxsl) / (0.1f - minslider);//interpolation : 1.9f slope value for slider = 0.1f + float bb = 1.9f - 0.1f * aa; + if(lp.smoothciem == 3) {//slope activ, only with choice gamma - slope - based rolloff = false;//allows tone-mapping slope + if(slopsmoot < 0.1f) { + slopsmoot = aa * slopsmoot + bb; + } slopegray = slopsmoot; + slopegrayr = slopsmoot; + slopegrayg = slopsmoot; + slopegrayb = slopsmoot; mode = 3; + }//modify slope + if(lp.smoothciem == 4) {//levels + rolloff = false;//allows tone-mapping slope + if(slopsmootr < 0.1f) { + slopsmootr = aa * slopsmootr + bb; + } + slopegrayr = slopsmootr; + if(slopsmootg < 0.1f) { + slopsmootg = aa * slopsmootg + bb; + } + slopegrayg = slopsmootg; + if(slopsmootb < 0.1f) { + slopsmootb = aa * slopsmootb + bb; + } + slopegrayb = slopsmootb; + mode = 4; } + LUTf lut(65536, LUT_CLIP_OFF);//take from Alberto Griggio + LUTf lutr(65536, LUT_CLIP_OFF); + LUTf lutg(65536, LUT_CLIP_OFF); + LUTf lutb(65536, LUT_CLIP_OFF); bool scale = lp.issmoothcie;//scale Yb mid_gray - WhiteEv and BlavkEv - tonemapFreeman(slopegray, white_point, black_point, mid_gray, mid_gray_view, rolloff, lut, mode, scale); + + tonemapFreeman(slopegray, slopegrayr, slopegrayg, slopegrayb, white_point, black_point, mid_gray, mid_gray_view, rolloff, lut, lutr, lutg, lutb, mode, scale, takeyb); + if(lp.smoothciem == 4) { + if(lummod) {//luminosity mode by Lab conversion #ifdef _OPENMP #pragma omp parallel for #endif - for (int y = 0; y < bfh ; ++ y) {//apply Lut tone-mapping or smooth: thanks to Alberto - gain time. - for (int x = 0; x < bfw ; ++x) { - tmpImage->r(y, x) = 65535.f * lut[tmpImage->r(y, x)]; - tmpImage->g(y, x) = 65535.f * lut[tmpImage->g(y, x)]; - tmpImage->b(y, x) = 65535.f * lut[tmpImage->b(y, x)]; + for (int y = 0; y < bfh ; ++ y) { + for (int x = 0; x < bfw ; ++x) { + float r = tmpImage->r(y, x); + float g = tmpImage->g(y, x); + float b = tmpImage->b(y, x); + //convert to Lab to get a&b before RGB + float xx = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float yy = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float zz = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; + + float fx = xx < MAXVALF ? Color::cachef[xx] : 327.68f * std::cbrt(xx / MAXVALF); + float fy = yy < MAXVALF ? Color::cachef[yy] : 327.68f * std::cbrt(yy / MAXVALF); + float fz = zz < MAXVALF ? Color::cachef[zz] : 327.68f * std::cbrt(zz / MAXVALF); + + float a_1 = 500.0f * (fx - fy); + float b_1 = 200.0f * (fy - fz); + float rNew = 65535.f * lutr[tmpImage->r(y, x)]; + float gNew = 65535.f * lutg[tmpImage->g(y, x)]; + float bNew = 65535.f * lutb[tmpImage->b(y, x)]; + r += (rNew - r) * equalR; + g += (gNew - g) * equalG; + b += (bNew - b) * equalB; + float newy = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float L_2 = newy <= MAXVALF ? Color::cachefy[newy] : 327.68f * (116.f * xcbrtf(newy / MAXVALF) - 16.f); + float x_, y_, z_; + //calculate RGB with L_2 and old value of a and b + Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; + if (params->locallab.spots.at(sp).avoidgamutMethod != "NONE") {//possibility of deactivating to see usefulness. is it necessary? + Color::gamutmap(x_, y_, z_, wp);//if none disabled + } + Color::xyz2rgb(x_, y_, z_, r, g, b, wip); + tmpImage->r(y, x) = r; + tmpImage->g(y, x) = g; + tmpImage->b(y, x) = b; + } + } + } else {//RGG case + #ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < bfh ; ++ y) {//apply Lut tone-mapping or smooth: thanks to Alberto - gain time. + for (int x = 0; x < bfw ; ++x) { + tmpImage->r(y, x) = 65535.f * lutr[tmpImage->r(y, x)]; + tmpImage->g(y, x) = 65535.f * lutg[tmpImage->g(y, x)]; + tmpImage->b(y, x) = 65535.f * lutb[tmpImage->b(y, x)]; + } + } + } + } else {//Slope case + #ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = 0; y < bfh ; ++ y) {//apply Lut tone-mapping or smooth: thanks to Alberto - gain time. + for (int x = 0; x < bfw ; ++x) { + tmpImage->r(y, x) = 65535.f * lut[tmpImage->r(y, x)]; + tmpImage->g(y, x) = 65535.f * lut[tmpImage->g(y, x)]; + tmpImage->b(y, x) = 65535.f * lut[tmpImage->b(y, x)]; + } } } - } - rgb2lab(*tmpImage, *bufexpfin, params->icm.workingProfile); delete tmpImage; @@ -20220,6 +20388,19 @@ void ImProcFunctions::Lab_Local( ImProcFunctions::localContrast(bufexpfin.get(), bufexpfin->L, localContrastParams, fftwlc, sk); } + if (params->locallab.spots.at(sp).bwcie) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + + for (int ir = 0; ir < bfh; ir++) { + for (int jr = 0; jr < bfw; jr++) { + bufexpfin->a[ir][jr] = 0.f; + bufexpfin->b[ir][jr] = 0.f; + } + } + } + const float repart = 1.0 - 0.01 * params->locallab.spots.at(sp).reparcie; int bw = bufexporig->W; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index cd80a8980..763decb75 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -4435,11 +4435,14 @@ LocallabParams::LocallabSpot::LocallabSpot() : comprcieauto(false), normcie(true), gamutcie(true), + bwcie(false), sigcie(true), logcie(false), satcie(true), logcieq(false), smoothcie(false), + smoothcieyb(false), + smoothcielum(false), logjz(false), sigjz(false), sigq(false), @@ -4624,6 +4627,9 @@ LocallabParams::LocallabSpot::LocallabSpot() : gamjcie(2.4), slopjcie(12.923), slopesmo(1.), + slopesmor(1.), + slopesmog(1.), + slopesmob(1.), midtcie(0), grexl(0.1596), greyl(0.8404), @@ -5392,11 +5398,14 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && comprcieauto == other.comprcieauto && normcie == other.normcie && gamutcie == other.gamutcie + && bwcie == other.bwcie && sigcie == other.sigcie && logcie == other.logcie && satcie == other.satcie && logcieq == other.logcieq && smoothcie == other.smoothcie + && smoothcieyb == other.smoothcieyb + && smoothcielum == other.smoothcielum && logjz == other.logjz && sigjz == other.sigjz && sigq == other.sigq @@ -5463,6 +5472,9 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && gamjcie == other.gamjcie && slopjcie == other.slopjcie && slopesmo == other.slopesmo + && slopesmor == other.slopesmor + && slopesmog == other.slopesmog + && slopesmob == other.slopesmob && midtcie == other.midtcie && redxl == other.redxl && redyl == other.redyl @@ -7334,11 +7346,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->comprcieauto, "Locallab", "comprcieauto_" + index_str, spot.comprcieauto, keyFile); saveToKeyfile(!pedited || spot_edited->normcie, "Locallab", "normcie_" + index_str, spot.normcie, keyFile); saveToKeyfile(!pedited || spot_edited->gamutcie, "Locallab", "gamutcie_" + index_str, spot.gamutcie, keyFile); + saveToKeyfile(!pedited || spot_edited->bwcie, "Locallab", "bwcie_" + index_str, spot.bwcie, keyFile); saveToKeyfile(!pedited || spot_edited->sigcie, "Locallab", "sigcie_" + index_str, spot.sigcie, keyFile); saveToKeyfile(!pedited || spot_edited->logcie, "Locallab", "logcie_" + index_str, spot.logcie, keyFile); saveToKeyfile(!pedited || spot_edited->satcie, "Locallab", "satcie_" + index_str, spot.satcie, keyFile); saveToKeyfile(!pedited || spot_edited->logcieq, "Locallab", "logcieq_" + index_str, spot.logcieq, keyFile); saveToKeyfile(!pedited || spot_edited->smoothcie, "Locallab", "smoothcie_" + index_str, spot.smoothcie, keyFile); + saveToKeyfile(!pedited || spot_edited->smoothcieyb, "Locallab", "smoothcieyb_" + index_str, spot.smoothcieyb, keyFile); + saveToKeyfile(!pedited || spot_edited->smoothcielum, "Locallab", "smoothcielum_" + index_str, spot.smoothcielum, keyFile); saveToKeyfile(!pedited || spot_edited->logjz, "Locallab", "Logjz_" + index_str, spot.logjz, keyFile); saveToKeyfile(!pedited || spot_edited->sigjz, "Locallab", "Sigjz_" + index_str, spot.sigjz, keyFile); saveToKeyfile(!pedited || spot_edited->sigq, "Locallab", "Sigq_" + index_str, spot.sigq, keyFile); @@ -7405,6 +7420,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->gamjcie, "Locallab", "gamjcie_" + index_str, spot.gamjcie, keyFile); saveToKeyfile(!pedited || spot_edited->slopjcie, "Locallab", "slopjcie_" + index_str, spot.slopjcie, keyFile); saveToKeyfile(!pedited || spot_edited->slopesmo, "Locallab", "slopesmo_" + index_str, spot.slopesmo, keyFile); + saveToKeyfile(!pedited || spot_edited->slopesmor, "Locallab", "slopesmor_" + index_str, spot.slopesmor, keyFile); + saveToKeyfile(!pedited || spot_edited->slopesmog, "Locallab", "slopesmog_" + index_str, spot.slopesmog, keyFile); + saveToKeyfile(!pedited || spot_edited->slopesmob, "Locallab", "slopesmob_" + index_str, spot.slopesmob, keyFile); saveToKeyfile(!pedited || spot_edited->midtcie, "Locallab", "midtcie_" + index_str, spot.midtcie, keyFile); saveToKeyfile(!pedited || spot_edited->redxl, "Locallab", "redxl_" + index_str, spot.redxl, keyFile); saveToKeyfile(!pedited || spot_edited->redyl, "Locallab", "redyl_" + index_str, spot.redyl, keyFile); @@ -9687,11 +9705,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "comprcieauto_" + index_str, spot.comprcieauto, spotEdited.comprcieauto); assignFromKeyfile(keyFile, "Locallab", "normcie_" + index_str, spot.normcie, spotEdited.normcie); assignFromKeyfile(keyFile, "Locallab", "gamutcie_" + index_str, spot.gamutcie, spotEdited.gamutcie); + assignFromKeyfile(keyFile, "Locallab", "bwcie_" + index_str, spot.bwcie, spotEdited.bwcie); assignFromKeyfile(keyFile, "Locallab", "sigcie_" + index_str, spot.sigcie, spotEdited.sigcie); assignFromKeyfile(keyFile, "Locallab", "logcie_" + index_str, spot.logcie, spotEdited.logcie); assignFromKeyfile(keyFile, "Locallab", "satcie_" + index_str, spot.satcie, spotEdited.satcie); assignFromKeyfile(keyFile, "Locallab", "logcieq_" + index_str, spot.logcieq, spotEdited.logcieq); assignFromKeyfile(keyFile, "Locallab", "smoothcie_" + index_str, spot.smoothcie, spotEdited.smoothcie); + assignFromKeyfile(keyFile, "Locallab", "smoothcieyb_" + index_str, spot.smoothcieyb, spotEdited.smoothcieyb); + assignFromKeyfile(keyFile, "Locallab", "smoothcielum_" + index_str, spot.smoothcielum, spotEdited.smoothcielum); assignFromKeyfile(keyFile, "Locallab", "Logjz_" + index_str, spot.logjz, spotEdited.logjz); assignFromKeyfile(keyFile, "Locallab", "Sigjz_" + index_str, spot.sigjz, spotEdited.sigjz); assignFromKeyfile(keyFile, "Locallab", "Sigq_" + index_str, spot.sigq, spotEdited.sigq); @@ -9767,7 +9788,10 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "gamjcie_" + index_str, spot.gamjcie, spotEdited.gamjcie); assignFromKeyfile(keyFile, "Locallab", "slopjcie_" + index_str, spot.slopjcie, spotEdited.slopjcie); assignFromKeyfile(keyFile, "Locallab", "slopesmo_" + index_str, spot.slopesmo, spotEdited.slopesmo); + assignFromKeyfile(keyFile, "Locallab", "slopesmor_" + index_str, spot.slopesmor, spotEdited.slopesmor); + assignFromKeyfile(keyFile, "Locallab", "slopesmog_" + index_str, spot.slopesmog, spotEdited.slopesmog); assignFromKeyfile(keyFile, "Locallab", "midtcie_" + index_str, spot.midtcie, spotEdited.midtcie); + assignFromKeyfile(keyFile, "Locallab", "slopesmob_" + index_str, spot.slopesmob, spotEdited.slopesmob); assignFromKeyfile(keyFile, "Locallab", "grexl_" + index_str, spot.grexl, spotEdited.grexl); assignFromKeyfile(keyFile, "Locallab", "greyl_" + index_str, spot.greyl, spotEdited.greyl); assignFromKeyfile(keyFile, "Locallab", "bluxl_" + index_str, spot.bluxl, spotEdited.bluxl); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0eb991933..d1cad0a5d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1663,11 +1663,14 @@ struct LocallabParams { bool comprcieauto; bool normcie; bool gamutcie; + bool bwcie; bool sigcie; bool logcie; bool satcie; bool logcieq; bool smoothcie; + bool smoothcieyb; + bool smoothcielum; bool logjz; bool sigjz; bool sigq; @@ -1734,6 +1737,9 @@ struct LocallabParams { double gamjcie; double slopjcie; double slopesmo; + double slopesmor; + double slopesmog; + double slopesmob; int midtcie; double grexl; double greyl; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index e76d17336..e27f372ae 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -448,6 +448,7 @@ public: double meanylc; double meanxelc; double meanyelc; + int primlc; }; struct locallabcieSIG { diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 241d628e9..06194e437 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1260,6 +1260,7 @@ private: float rdx, rdy, grx, gry, blx, bly = 0.f; float meanx, meany, meanxe, meanye = 0.f; int ill = 2; + int prim = 3; if (params.locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reservView.get(), reservView.get(), 0, 0, fw, fh, 1, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, avge, locwavCurveden, locwavdenutili); @@ -1341,7 +1342,7 @@ private: LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, ill, contsig, lightsig, + meantme, stdtme, meanretie, stdretie, fab, maxicam, rdx, rdy, grx, gry, blx, bly, meanx, meany, meanxe, meanye, prim, ill, contsig, lightsig, highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46 ); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 999653ad7..bc5e2144b 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -1187,8 +1187,9 @@ void Locallab::cieChanged(const std::vector &cielc, int selspot) const double m2 = cie_lc.at(selspot).meanylc; const double me1 = cie_lc.at(selspot).meanxelc; const double me2 = cie_lc.at(selspot).meanyelc; + const int pri = cie_lc.at(selspot).primlc; - expcie.updateiPrimloc(r1, r2, g1, g2, b1, b2, w1, w2, m1, m2, me1, me2); + expcie.updateiPrimloc(r1, r2, g1, g2, b1, b2, w1, w2, m1, m2, me1, me2, pri); } } diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 4a0e68564..1d43b6ef1 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -77,7 +77,12 @@ protected: rtengine::ProcEvent Evlocallabslopjcie; rtengine::ProcEvent Evlocallabmidtcie; rtengine::ProcEvent Evlocallabslopesmo; + rtengine::ProcEvent Evlocallabslopesmor; + rtengine::ProcEvent Evlocallabslopesmog; + rtengine::ProcEvent Evlocallabslopesmob; rtengine::ProcEvent Evlocallabsmoothcie; + rtengine::ProcEvent Evlocallabsmoothcieyb; + rtengine::ProcEvent Evlocallabsmoothcielum; rtengine::ProcEvent Evlocallabsmoothciemet; rtengine::ProcEvent Evlocallabsigcie; rtengine::ProcEvent Evlocallabillcie; @@ -98,6 +103,7 @@ protected: rtengine::ProcEvent Evlocallabbluyl; rtengine::ProcEvent EvlocallabGridciexy; rtengine::ProcEvent Evlocallabgamutcie; + rtengine::ProcEvent Evlocallabbwcie; rtengine::ProcEvent Evlocallabexpprecam; rtengine::ProcEvent Evlocallablightsigqcie; rtengine::ProcEvent Evlocallabcontsigqcie; @@ -1690,10 +1696,15 @@ private: Adjuster* const slopjcie; Adjuster* const midtcie; Gtk::CheckButton* const smoothcie; + Gtk::CheckButton* const smoothcieyb; + Gtk::CheckButton* const smoothcielum; ToolParamBlock* const ciesmoothBox; Gtk::Box* smoothBox; MyComboBoxText* const smoothciemet; Adjuster* const slopesmo; + Adjuster* const slopesmor; + Adjuster* const slopesmog; + Adjuster* const slopesmob; Adjuster* const whitescie; Adjuster* const blackscie; @@ -1724,6 +1735,8 @@ private: Gtk::CheckButton* const gamutcie; Adjuster* const shiftxl; Adjuster* const shiftyl; + Gtk::Box* bwcieBox; + Gtk::CheckButton* const bwcie; Gtk::Frame* const sigmoidjzFrame; Gtk::Frame* const sigmoid2Frame; @@ -1824,7 +1837,7 @@ private: ThresholdAdjuster* const csThresholdcie; int nextcomprciecount = 0; - sigc::connection AutograycieConn, primMethodconn, illMethodconn, smoothciemetconn, catMethodconn, forcejzConn, forcebwConn, qtojConn, showmaskcieMethodConn, enacieMaskConn, enacieMaskallConn, jabcieConn, sursourcieconn, surroundcieconn, modecieconn, modecamconn, comprcieautoconn, normcieconn, logcieconn, satcieconn, logcieqconn,smoothcieconn, logjzconn, sigjzconn, sigqconn, chjzcieconn, toneMethodcieConn, toneMethodcieConn2, toolcieConn, bwevMethodConn, fftcieMaskConn, gamutcieconn, expprecamconn, sigcieconn; + sigc::connection AutograycieConn, primMethodconn, illMethodconn, smoothciemetconn, catMethodconn, forcejzConn, forcebwConn, qtojConn, showmaskcieMethodConn, enacieMaskConn, enacieMaskallConn, jabcieConn, sursourcieconn, surroundcieconn, modecieconn, modecamconn, comprcieautoconn, normcieconn, logcieconn, satcieconn, logcieqconn,smoothcieconn, smoothcieybconn,smoothcielumconn, logjzconn, sigjzconn, sigqconn, chjzcieconn, toneMethodcieConn, toneMethodcieConn2, toolcieConn, bwevMethodConn, fftcieMaskConn, gamutcieconn, bwcieconn, expprecamconn, sigcieconn; public: Locallabcie(); ~Locallabcie(); @@ -1860,7 +1873,7 @@ public: void bwevMethodChanged(); void updateAutocompute(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const float jz1); void updatePrimloc(const float redx, const float redy, const float grex, const float grey, const float blux, const float bluy); - void updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y); + void updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y, const int pri_); void updatesigloc(const float cont_sig, const float light_sig); private: @@ -1877,6 +1890,7 @@ private: void comprcieautoChanged(); void normcieChanged(); void gamutcieChanged(); + void bwcieChanged(); void illMethodChanged(); void smoothciemetChanged(); void primMethodChanged(); @@ -1885,6 +1899,8 @@ private: void satcieChanged(); void logcieqChanged(); void smoothcieChanged(); + void smoothcieybChanged(); + void smoothcielumChanged(); void sigcieChanged(); void logjzChanged(); void sigjzChanged(); diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 5417271ab..17b5d3ead 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -7618,10 +7618,15 @@ Locallabcie::Locallabcie(): slopjcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGSLOPJCIE"), 0., 500., 0.01, 12.923))), midtcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MIDTCIE"), -100, 100, 1, 0))), smoothcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SMOOTHCIE_SCA")))), + smoothcieyb(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SMOOTHCIE_YB")))), + smoothcielum(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_SMOOTHCIE_LUM")))), ciesmoothBox(Gtk::manage(new ToolParamBlock())), smoothBox(Gtk::manage(new Gtk::Box())), smoothciemet(Gtk::manage(new MyComboBoxText())), - slopesmo(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTH"), 0.6, 1.6, 0.01, 1.))), + slopesmo(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTH"), 0.01, 1.6, 0.01, 1.))), + slopesmor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTHR"), 0.01, 1.6, 0.01, 1.))), + slopesmog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTHG"), 0.01, 1.6, 0.01, 1.))), + slopesmob(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOPESMOOTHB"), 0.01, 1.6, 0.01, 1.))), whitescie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGWHITESCIE"), -100, 100, 1, 0))), blackscie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGBLACKSSCIE"), -100, 100, 1, 0))), willBox(Gtk::manage(new Gtk::Box())), @@ -7651,6 +7656,8 @@ Locallabcie::Locallabcie(): gamutcie(Gtk::manage(new Gtk::CheckButton(M("TP_ICM_GAMUT")))), shiftxl(Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTX"), -0.20, 0.20, 0.0001, 0.))), shiftyl(Gtk::manage(new Adjuster(M("TC_LOCALLAB_PRIM_SHIFTY"), -0.20, 0.20, 0.0001, 0.))), + bwcieBox(Gtk::manage(new Gtk::Box())), + bwcie(Gtk::manage(new Gtk::CheckButton(M("TP_ICM_BW")))), sigmoidjzFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_SIGJZFRA")))), sigmoid2Frame(Gtk::manage(new Gtk::Frame(M("")))), @@ -7770,7 +7777,12 @@ Locallabcie::Locallabcie(): Evlocallabslopjcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOP"); Evlocallabmidtcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_MIDT"); Evlocallabslopesmo = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOPESMO"); + Evlocallabslopesmor = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOPESMOR"); + Evlocallabslopesmog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOPESMOG"); + Evlocallabslopesmob = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SLOPESMOB"); Evlocallabsmoothcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTH"); + Evlocallabsmoothcieyb = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTHYB"); + Evlocallabsmoothcielum = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM"); Evlocallabsigcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SIG"); Evlocallabillcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_ILL"); Evlocallabprimcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_PRIM"); @@ -7785,6 +7797,7 @@ Locallabcie::Locallabcie(): Evlocallabbluyl = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_BLUYL"); EvlocallabGridciexy = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_LABGRIDCIE"); Evlocallabgamutcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_GAMUTCIE"); + Evlocallabbwcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_BWCIE"); Evlocallabexpprecam = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_EXPPRECAM"); Evlocallablightsigqcie = m->newEvent(AUTOEXP, ""); Evlocallabcontsigqcie = m->newEvent(AUTOEXP, ""); @@ -8009,6 +8022,10 @@ Locallabcie::Locallabcie(): ToolParamBlock* const signormBox = Gtk::manage(new ToolParamBlock()); ToolParamBlock* const sigfraBox = Gtk::manage(new ToolParamBlock()); + bwcieBox->pack_start(*bwcie, Gtk::PACK_EXPAND_WIDGET); + + bwcieconn = bwcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::bwcieChanged)); + modeHBoxbwev->set_spacing(2); ToolParamBlock* const gamcieBox = Gtk::manage(new ToolParamBlock()); Gtk::Label* modeLabelbwev = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_SIGMOIDQJ") + ":")); @@ -8041,9 +8058,15 @@ Locallabcie::Locallabcie(): smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_EV")); smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF")); smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_GAMMA")); + smoothciemet->append(M("TP_LOCALLAB_CIE_SMOOTH_LEVELS")); smoothciemet->set_active(0); ciesmoothBox->pack_start(*smoothBox); ciesmoothBox->pack_start(*slopesmo); + ciesmoothBox->pack_start(*slopesmor); + ciesmoothBox->pack_start(*slopesmog); + ciesmoothBox->pack_start(*slopesmob); + ciesmoothBox->pack_start(*smoothcielum); + ciesmoothBox->pack_start(*smoothcieyb); ciesmoothBox->pack_start(*smoothcie); smoothciemetconn = smoothciemet->signal_changed().connect(sigc::mem_fun(*this, &Locallabcie::smoothciemetChanged)); @@ -8065,6 +8088,7 @@ Locallabcie::Locallabcie(): colorBox->pack_start(*shiftxl); colorBox->pack_start(*shiftyl); colorFramecie->add(*colorBox); + primillBox->pack_start(*bwcieBox); primillBox->pack_start(*colorFramecie); primillFrame->add(*primillBox); gamcieBox->pack_start(*primillFrame); @@ -8284,6 +8308,8 @@ Locallabcie::Locallabcie(): satcieconn = satcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::satcieChanged)); logcieqconn = logcieq->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::logcieqChanged)); smoothcieconn = smoothcie->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::smoothcieChanged)); + smoothcieybconn = smoothcieyb->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::smoothcieybChanged)); + smoothcielumconn = smoothcielum->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::smoothcielumChanged)); logjzconn = logjz->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::logjzChanged)); sigjzconn = sigjz->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigjzChanged)); sigqconn = sigq->signal_toggled().connect(sigc::mem_fun(*this, &Locallabcie::sigqChanged)); @@ -8407,6 +8433,9 @@ Locallabcie::Locallabcie(): catadcie->setAdjusterListener(this); slopesmo->setAdjusterListener(this); + slopesmor->setAdjusterListener(this); + slopesmog->setAdjusterListener(this); + slopesmob->setAdjusterListener(this); Gtk::Box *TittleVBoxcam16; TittleVBoxcam16 = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); @@ -8891,6 +8920,7 @@ void Locallabcie::disableListener() normcieconn.block(true); expprecamconn.block(true); gamutcieconn.block(true); + bwcieconn.block(true); primMethodconn.block(true); illMethodconn.block(true); smoothciemetconn.block(true); @@ -8900,6 +8930,8 @@ void Locallabcie::disableListener() satcieconn.block(true); logcieqconn.block(true); smoothcieconn.block(true); + smoothcieybconn.block(true); + smoothcielumconn.block(true); logjzconn.block(true); sigjzconn.block(true); sigqconn.block(true); @@ -8930,6 +8962,7 @@ void Locallabcie::enableListener() normcieconn.block(false); expprecamconn.block(false); gamutcieconn.block(false); + bwcieconn.block(false); primMethodconn.block(false); illMethodconn.block(false); smoothciemetconn.block(false); @@ -8939,6 +8972,8 @@ void Locallabcie::enableListener() satcieconn.block(false); logcieqconn.block(false); smoothcieconn.block(false); + smoothcieybconn.block(false); + smoothcielumconn.block(false); logjzconn.block(false); sigjzconn.block(false); sigqconn.block(false); @@ -9173,6 +9208,8 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE smoothciemet->set_active(2); } else if (spot.smoothciemet == "gamnorol") { smoothciemet->set_active(3); + } else if (spot.smoothciemet == "level") { + smoothciemet->set_active(4); } @@ -9239,7 +9276,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE primMethod->set_active(11); illMethod->set_active(4); } else if (spot.primMethod == "free") { - primMethod->set_active(9); + primMethod->set_active(12); illMethod->set_sensitive(true); } @@ -9259,11 +9296,14 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE normcie->set_active(spot.normcie); gamutcie->set_active(spot.gamutcie); + bwcie->set_active(spot.bwcie); sigcie->set_active(spot.sigcie); logcie->set_active(spot.logcie); satcie->set_active(spot.satcie); logcieq->set_active(spot.logcieq); smoothcie->set_active(spot.smoothcie); + smoothcieyb->set_active(spot.smoothcieyb); + smoothcielum->set_active(spot.smoothcielum); logjz->set_active(spot.logjz); sigjz->set_active(spot.sigjz); sigq->set_active(spot.sigq); @@ -9277,6 +9317,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE normcieChanged(); expprecamChanged(); gamutcieChanged(); + bwcieChanged(); sigcieChanged(); comprcieautoChanged(); sigqChanged(); @@ -9284,6 +9325,8 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE satcieChanged(); logcieqChanged(); smoothcieChanged(); + smoothcieybChanged(); + smoothcielumChanged(); primMethodChanged(); illMethodChanged(); smoothciemetChanged(); @@ -9371,6 +9414,9 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE gamjcie->setValue(spot.gamjcie); slopjcie->setValue(spot.slopjcie); slopesmo->setValue(spot.slopesmo); + slopesmor->setValue(spot.slopesmor); + slopesmog->setValue(spot.slopesmog); + slopesmob->setValue(spot.slopesmob); midtcie->setValue(spot.midtcie); whitescie->setValue(spot.whitescie); blackscie->setValue(spot.blackscie); @@ -9524,11 +9570,14 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.comprcieauto = comprcieauto->get_active(); spot.normcie = normcie->get_active(); spot.gamutcie = gamutcie->get_active(); + spot.bwcie = bwcie->get_active(); spot.sigcie = sigcie->get_active(); spot.logcie = logcie->get_active(); spot.satcie = satcie->get_active(); spot.logcieq = logcieq->get_active(); spot.smoothcie = smoothcie->get_active(); + spot.smoothcieyb = smoothcieyb->get_active(); + spot.smoothcielum = smoothcielum->get_active(); spot.logjz = logjz->get_active(); spot.sigjz = sigjz->get_active(); spot.chjzcie = chjzcie->get_active(); @@ -9560,6 +9609,8 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.smoothciemet = "gam"; } else if (smoothciemet->get_active_row_number() == 3) { spot.smoothciemet = "gamnorol"; + } else if (smoothciemet->get_active_row_number() == 4) { + spot.smoothciemet = "level"; } if (illMethod->get_active_row_number() == 0) { @@ -9689,6 +9740,9 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.gamjcie = gamjcie->getValue(); spot.slopjcie = slopjcie->getValue(); spot.slopesmo = slopesmo->getValue(); + spot.slopesmor = slopesmor->getValue(); + spot.slopesmog = slopesmog->getValue(); + spot.slopesmob = slopesmob->getValue(); spot.midtcie = midtcie->getIntValue(); spot.whitescie = whitescie->getIntValue(); spot.blackscie = blackscie->getIntValue(); @@ -9823,7 +9877,7 @@ void Locallabcie::updatesigloc(const float cont_sig, const float light_sig) -void Locallabcie::updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y) +void Locallabcie::updateiPrimloc(const float r_x, const float r_y, const float g_x, const float g_y, const float b_x, const float b_y, const float w_x, const float w_y, const float m_x, const float m_y, const float me_x, const float me_y, const int pri_) { nextrx = r_x; nextry = r_y; @@ -10058,6 +10112,24 @@ void Locallabcie::gamutcieChanged() } +void Locallabcie::bwcieChanged() +{ + + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (bwcie->get_active()) { + listener->panelChanged(Evlocallabbwcie, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabbwcie, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } + +} + + void Locallabcie::expprecamChanged() { if (isLocActivated && exp->getEnabled()) { @@ -10164,6 +10236,36 @@ void Locallabcie::smoothcieChanged() } } +void Locallabcie::smoothcieybChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (smoothcieyb->get_active()) { + listener->panelChanged(Evlocallabsmoothcieyb, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsmoothcieyb, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + +void Locallabcie::smoothcielumChanged() +{ + if (isLocActivated && exp->getEnabled()) { + if (listener) { + if (smoothcielum->get_active()) { + listener->panelChanged(Evlocallabsmoothcielum, + M("GENERAL_ENABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } else { + listener->panelChanged(Evlocallabsmoothcielum, + M("GENERAL_DISABLED") + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } +} + void Locallabcie::logjzChanged() { if (isLocActivated && exp->getEnabled()) { @@ -10541,10 +10643,28 @@ void Locallabcie::smoothciemetChanged() { if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcieyb->hide(); + smoothcielum->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } if (listener) { @@ -10731,7 +10851,12 @@ void Locallabcie::updateGUIToMode(const modeType new_type) comprcieauto->hide(); comprBox->show(); slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); if (modecam->get_active_row_number() == 0) { bevwevFrame->show(); @@ -10743,10 +10868,28 @@ void Locallabcie::updateGUIToMode(const modeType new_type) expgradcie->hide(); if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcielum->hide(); + smoothcieyb->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } } @@ -10853,10 +10996,28 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcielum->hide(); + smoothcieyb->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } } @@ -10967,10 +11128,28 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcielum->hide(); + smoothcieyb->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } } @@ -11021,10 +11200,28 @@ void Locallabcie::updateGUIToMode(const modeType new_type) if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcielum->hide(); + smoothcieyb->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } } @@ -11125,10 +11322,28 @@ void Locallabcie::updatecieGUI() if(smoothciemet->get_active_row_number() == 3) { slopesmo->show(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->show(); + smoothcielum->hide(); + smoothcieyb->hide(); + } else if(smoothciemet->get_active_row_number() == 4) { + slopesmo->hide(); + slopesmor->show(); + slopesmog->show(); + slopesmob->show(); + smoothcie->show(); + smoothcielum->show(); + smoothcieyb->show(); } else { slopesmo->hide(); + slopesmor->hide(); + slopesmog->hide(); + slopesmob->hide(); smoothcie->hide(); + smoothcielum->hide(); + smoothcieyb->hide(); } } @@ -11241,6 +11456,7 @@ void Locallabcie::convertParamToSimple() whiteEvjz->setValue(defSpot.whiteEvjz); whitescie->setValue(defSpot.whitescie); blackscie->setValue(defSpot.blackscie); + bwcie->set_active(defSpot.bwcie); sigq->set_active(defSpot.sigq); //sigq->set_active(defSpot.sigq); @@ -11271,7 +11487,7 @@ void Locallabcie::convertParamToNormal() normcie->set_active(defSpot.normcie); logcieq->set_active(defSpot.logcieq); logcie->set_active(defSpot.logcie); - + bwcie->set_active(defSpot.bwcie); //contsigqcie->setValue(defSpot.contsigqcie); colorflcie->setValue(defSpot.colorflcie); lightqcie->setValue(defSpot.lightqcie); @@ -11399,7 +11615,9 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, blackscie->setDefault(defSpot.blackscie); slopjcie->setDefault(defSpot.slopjcie); slopesmo->setDefault(defSpot.slopesmo); - midtcie->setDefault(defSpot.midtcie); + slopesmor->setDefault(defSpot.slopesmo); + slopesmog->setDefault(defSpot.slopesmog); + slopesmob->setDefault(defSpot.slopesmob); sigmoidldajzcie->setDefault(defSpot.sigmoidldajzcie); sigmoidthjzcie->setDefault(defSpot.sigmoidthjzcie); sigmoidbljzcie->setDefault(defSpot.sigmoidbljzcie); @@ -11943,6 +12161,28 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == slopesmor) { + if (listener) { + listener->panelChanged(Evlocallabslopesmor, + slopesmor->getTextValue() + spName); + } + } + + + if (a == slopesmog) { + if (listener) { + listener->panelChanged(Evlocallabslopesmog, + slopesmog->getTextValue() + spName); + } + } + + if (a == slopesmob) { + if (listener) { + listener->panelChanged(Evlocallabslopesmob, + slopesmob->getTextValue() + spName); + } + } + if (a == midtcie) { if (listener) { listener->panelChanged(Evlocallabmidtcie, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 02d405f76..66ea3f9aa 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1736,11 +1736,14 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).comprcieauto = locallab.spots.at(j).comprcieauto && pSpot.comprcieauto == otherSpot.comprcieauto; locallab.spots.at(j).normcie = locallab.spots.at(j).normcie && pSpot.normcie == otherSpot.normcie; locallab.spots.at(j).gamutcie = locallab.spots.at(j).gamutcie && pSpot.gamutcie == otherSpot.gamutcie; + locallab.spots.at(j).bwcie = locallab.spots.at(j).bwcie && pSpot.bwcie == otherSpot.bwcie; locallab.spots.at(j).sigcie = locallab.spots.at(j).sigcie && pSpot.sigcie == otherSpot.sigcie; locallab.spots.at(j).logcie = locallab.spots.at(j).logcie && pSpot.logcie == otherSpot.logcie; locallab.spots.at(j).satcie = locallab.spots.at(j).satcie && pSpot.satcie == otherSpot.satcie; locallab.spots.at(j).logcieq = locallab.spots.at(j).logcieq && pSpot.logcieq == otherSpot.logcieq; locallab.spots.at(j).smoothcie = locallab.spots.at(j).smoothcie && pSpot.smoothcie == otherSpot.smoothcie; + locallab.spots.at(j).smoothcieyb = locallab.spots.at(j).smoothcieyb && pSpot.smoothcieyb == otherSpot.smoothcieyb; + locallab.spots.at(j).smoothcielum = locallab.spots.at(j).smoothcielum && pSpot.smoothcielum == otherSpot.smoothcielum; locallab.spots.at(j).logjz = locallab.spots.at(j).logjz && pSpot.logjz == otherSpot.logjz; locallab.spots.at(j).sigjz = locallab.spots.at(j).sigjz && pSpot.sigjz == otherSpot.sigjz; locallab.spots.at(j).sigq = locallab.spots.at(j).sigq && pSpot.sigq == otherSpot.sigq; @@ -1801,6 +1804,9 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).gamjcie = locallab.spots.at(j).gamjcie && pSpot.gamjcie == otherSpot.gamjcie; locallab.spots.at(j).slopjcie = locallab.spots.at(j).slopjcie && pSpot.slopjcie == otherSpot.slopjcie; locallab.spots.at(j).slopesmo = locallab.spots.at(j).slopesmo && pSpot.slopesmo == otherSpot.slopesmo; + locallab.spots.at(j).slopesmor = locallab.spots.at(j).slopesmor && pSpot.slopesmor == otherSpot.slopesmor; + locallab.spots.at(j).slopesmog = locallab.spots.at(j).slopesmog && pSpot.slopesmog == otherSpot.slopesmog; + locallab.spots.at(j).slopesmob = locallab.spots.at(j).slopesmob && pSpot.slopesmob == otherSpot.slopesmob; locallab.spots.at(j).midtcie = locallab.spots.at(j).midtcie && pSpot.midtcie == otherSpot.midtcie; locallab.spots.at(j).grexl = locallab.spots.at(j).grexl && pSpot.grexl == otherSpot.grexl; locallab.spots.at(j).greyl = locallab.spots.at(j).greyl && pSpot.greyl == otherSpot.greyl; @@ -5953,11 +5959,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).normcie = mods.locallab.spots.at(i).normcie; } - if (locallab.spots.at(i).gamutcie) { toEdit.locallab.spots.at(i).gamutcie = mods.locallab.spots.at(i).gamutcie; } + if (locallab.spots.at(i).bwcie) { + toEdit.locallab.spots.at(i).bwcie = mods.locallab.spots.at(i).bwcie; + } + if (locallab.spots.at(i).sigcie) { toEdit.locallab.spots.at(i).sigcie = mods.locallab.spots.at(i).sigcie; } @@ -5978,6 +5987,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).smoothcie = mods.locallab.spots.at(i).smoothcie; } + if (locallab.spots.at(i).smoothcieyb) { + toEdit.locallab.spots.at(i).smoothcieyb = mods.locallab.spots.at(i).smoothcieyb; + } + + if (locallab.spots.at(i).smoothcielum) { + toEdit.locallab.spots.at(i).smoothcielum = mods.locallab.spots.at(i).smoothcielum; + } + if (locallab.spots.at(i).logjz) { toEdit.locallab.spots.at(i).logjz = mods.locallab.spots.at(i).logjz; } @@ -6214,6 +6231,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).slopesmo = mods.locallab.spots.at(i).slopesmo; } + if (locallab.spots.at(i).slopesmor) { + toEdit.locallab.spots.at(i).slopesmor = mods.locallab.spots.at(i).slopesmor; + } + + if (locallab.spots.at(i).slopesmog) { + toEdit.locallab.spots.at(i).slopesmog = mods.locallab.spots.at(i).slopesmog; + } + + if (locallab.spots.at(i).slopesmob) { + toEdit.locallab.spots.at(i).slopesmob = mods.locallab.spots.at(i).slopesmob; + } + if (locallab.spots.at(i).midtcie) { toEdit.locallab.spots.at(i).midtcie = mods.locallab.spots.at(i).midtcie; } @@ -8449,11 +8478,14 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : comprcieauto(v), normcie(v), gamutcie(v), + bwcie(v), sigcie(v), logcie(v), satcie(v), logcieq(v), smoothcie(v), + smoothcieyb(v), + smoothcielum(v), logjz(v), sigjz(v), sigq(v), @@ -8514,6 +8546,9 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : gamjcie(v), slopjcie(v), slopesmo(v), + slopesmor(v), + slopesmog(v), + slopesmob(v), midtcie(v), redxl(v), redyl(v), @@ -9202,11 +9237,14 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) comprcieauto = v; normcie = v; gamutcie = v; + bwcie = v; sigcie = v; logcie = v; satcie = v; logcieq = v; smoothcie = v; + smoothcieyb = v; + smoothcielum = v; logjz = v; sigjz = v; sigq = v; @@ -9267,6 +9305,9 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) gamjcie = v; slopjcie = v; slopesmo = v; + slopesmor = v; + slopesmog = v; + slopesmob = v; midtcie = v; redxl = v; redyl = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c8bd39f9b..57a3ea1cd 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1016,11 +1016,14 @@ public: bool comprcieauto; bool normcie; bool gamutcie; + bool bwcie; bool sigcie; bool logcie; bool satcie; bool logcieq; bool smoothcie; + bool smoothcieyb; + bool smoothcielum; bool logjz; bool sigjz; bool sigq; @@ -1081,6 +1084,9 @@ public: bool gamjcie; bool slopjcie; bool slopesmo; + bool slopesmor; + bool slopesmog; + bool slopesmob; bool midtcie; bool redxl; bool redyl; From 1adf2bbac32c3a26ebf405806253517e24a24f98 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 12 May 2024 08:40:32 +0200 Subject: [PATCH 197/291] Wavelet selection levels issue 7069 (#7070) * Fixed wavelet selective luminance * Enable PR appimage.yml windows.yml * disabled appimage.yml and windows.yml --- rtengine/ipwavelet.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index e5e90a77f..f0b6afaaf 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -434,7 +434,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.CHmet = 0; cp.HSmet = false; - if (params->wavelet.CHmethod == "with") { + + if (params->wavelet.CHmethod == "without") { + cp.CHmet = 0; + } else if (params->wavelet.CHmethod == "with") { cp.CHmet = 1; } else if (params->wavelet.CHmethod == "link") { cp.CHmet = 2; @@ -4139,8 +4142,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float maxkoeLi, bool lipschitz, float diagacc = 1.f; float alpha = (1024.f + 15.f * (float) cpMul * scale * scale2 * lbeta * diagacc) / 1024.f ; - // if (cp.HSmet && cp.contena) { - if (cp.HSmet && cp.contena && waOpacityCurveSH) { + if (cp.HSmet && cp.contena) { + // if (cp.HSmet && cp.contena && waOpacityCurveSH) {//waOpacityCurveSH no long use float aaal = (1.f - alpha) / ((cp.b_lhl - cp.t_lhl) * kH[level]); float bbal = 1.f - aaal * cp.b_lhl * kH[level]; float aaar = (alpha - 1.f) / (cp.t_rhl - cp.b_rhl) * kH[level]; From 5a25619bd50d42059abe9818420f639b6d10e3bf Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Sun, 12 May 2024 08:45:00 +0200 Subject: [PATCH 198/291] Restore appimage.yml and windows.yml --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 90beb2c18..5a5c3b8d0 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:levels"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b30dd9f20..e5f4ce166 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Beep6581:levels"]' + publish_pre_dev_labels: '[]' jobs: From 5571c3a4c68e73ecebd034c320551a24f2044216 Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 16 May 2024 08:21:16 +0200 Subject: [PATCH 199/291] Local adjustments tools used globally - Laspotmain (#6928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * First step LA globally * fixed several GUI bad behavior * better behavior shows additional settings * Improve transition in main * First step hide-show invers and scope * Hide show invers and scope step2 * hide show others inverse and scope * Try to improve * Change windows.yml and appimage.yml * In Preference set choice for default Spot Method * Optimization call idle_register * forgotten delete mainfp * Re-enable sliders scope in colorlight - shadows - vibrance - move setting checkbox others settings * Fixed bad behavior hide - show * Optimize behavior * Bad behavior scope when changing method * Clean and comment code * disable preview mask and modif for cbdl and retinex * Fixed preview deltaE mask and modif log encode - exposure - new button preview color and light * Button preview deltaE - exposure * Button preview SH * Button preview Vibrance * Improce code using mask * Fixed several bad behavior - preview TM and Contrast * Preview log button * Preview Ciecam button * Preview common mask button * Disable Preview button in settings when not used in tools * Change call to controspotpanel in improcoordinator * Change Local adjustments title to Selective Editing * Change default value spotmethod in option * Missing cddl in preview settings * Change parameter setting spot type * put selective editing tab just after exposure tab * Disable preview ΔE button when another is enabled Only one button should be active at any given time. * Deactivate preview ΔE buttons when switching spots * Change tooltip Spot method * Change selective editing position * Remove duplicate line in language default * Remove appimage.yml windows.yml --------- Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> --- .github/workflows/appimage.yml | 2 +- rtdata/languages/default | 14 +- rtengine/improccoordinator.cc | 72 +++++- rtengine/iplocallab.cc | 95 +++++-- rtengine/procparams.cc | 79 +++++- rtengine/rtengine.h | 25 ++ rtgui/controlspotpanel.cc | 194 +++++++++++++-- rtgui/controlspotpanel.h | 13 +- rtgui/guiutils.cc | 39 +++ rtgui/guiutils.h | 24 ++ rtgui/locallab.cc | 253 ++++++++++++++++++- rtgui/locallab.h | 16 +- rtgui/locallabtools.cc | 441 ++++++++++++++++++++++++++++++++- rtgui/locallabtools.h | 111 +++++++-- rtgui/locallabtools2.cc | 424 ++++++++++++++++++++++++++++++- rtgui/options.cc | 7 + rtgui/options.h | 2 + rtgui/preferences.cc | 26 +- rtgui/preferences.h | 2 + rtgui/toolpanelcoord.cc | 5 + 20 files changed, 1755 insertions(+), 89 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5a5c3b8d0..e144f4189 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/rtdata/languages/default b/rtdata/languages/default index 81c7bfeee..e363b1054 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1763,7 +1763,7 @@ MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u MAIN_TAB_FILTER; Filter MAIN_TAB_INSPECT; Inspect MAIN_TAB_IPTC;IPTC -MAIN_TAB_LOCALLAB;Local +MAIN_TAB_LOCALLAB;Selective Editing MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o MAIN_TAB_METADATA;Metadata MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m @@ -1850,8 +1850,8 @@ PARTIALPASTE_LABCURVE;L*a*b* adjustments PARTIALPASTE_LENSGROUP;Lens Related Settings PARTIALPASTE_LENSPROFILE;Profiled lens correction PARTIALPASTE_LOCALCONTRAST;Local contrast -PARTIALPASTE_LOCALLAB;Local Adjustments -PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +PARTIALPASTE_LOCALLAB;Selective Editing +PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings PARTIALPASTE_METADATA;Metadata mode PARTIALPASTE_METAGROUP;Metadata settings PARTIALPASTE_PCVIGNETTE;Vignette filter @@ -2083,6 +2083,7 @@ PREFERENCES_SND_HELP;Enter a full file path to set a sound, or leave blank for n PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done PREFERENCES_SND_QUEUEDONE;Queue processing done PREFERENCES_SND_THRESHOLDSECS;After seconds +PREFERENCES_SPOTLOC;Define Spot method for Local Adjustments PREFERENCES_STARTUPIMDIR;Image Directory at Startup PREFERENCES_TAB_BROWSER;File Browser PREFERENCES_TAB_COLORMGR;Color Management @@ -2959,7 +2960,7 @@ TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLev TP_LOCALLAB_CLIPTM;Clip restored data (gain) TP_LOCALLAB_COFR;Color & Light TP_LOCALLAB_COLORDE;ΔE preview color - intensity -TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening' or 'Soft Light and Original Retinex' or 'Blur/Grain and Denoise' or 'Dehaze and Retinex' or 'Contrast by Detail Levels' in 'Add tool to current spot' menu.\nFor others tools Preview ΔE button is 'in the tool' - to be able to preview ΔE with several tools enabled, use preferably Mask and modifications. TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. TP_LOCALLAB_COLORSCOPE;Scope (color tools) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. @@ -3048,9 +3049,10 @@ TP_LOCALLAB_EV_VIS_ALL;Show all TP_LOCALLAB_EXCLUF;Excluding TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. TP_LOCALLAB_EXCLUTYPE;Spot method -TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the local adjustment tools on the whole image, without using deltaE or transitions. TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXFULL;Full image +TP_LOCALLAB_EXMAIN;Global TP_LOCALLAB_EXNORM;Normal spot TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3182,7 +3184,7 @@ TP_LOCALLAB_JZTARGET_EV;Viewing Mean luminance (Yb%) TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) TP_LOCALLAB_JZWAVEXP;Wavelet Jz TP_LOCALLAB_LABBLURM;Blur Mask -TP_LOCALLAB_LABEL;Local Adjustments +TP_LOCALLAB_LABEL;Selective Editing TP_LOCALLAB_LABGRID;Color correction grid TP_LOCALLAB_LABGRIDMERG;Background TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 5f8a4df15..46dd7bc29 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1131,6 +1131,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) //std::vector locallref; std::vector locallretiminmax; std::vector locallcielc; + std::vector locallsetlc; std::vector locallciesig; huerefs.resize(params->locallab.spots.size()); huerefblurs.resize(params->locallab.spots.size()); @@ -1154,6 +1155,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lumarefp = new float[sizespot]; float *fabrefp = nullptr; fabrefp = new float[sizespot]; + //new controls mainfp and scopefp with multi spots + int *mainfp = nullptr; + mainfp = new int[sizespot]; + int *scopefp = nullptr; + scopefp = new int[sizespot]; for (int sp = 0; sp < (int)params->locallab.spots.size(); sp++) { @@ -1164,7 +1170,9 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti) { savenormreti.reset(new LabImage(*oprevl, true)); } - + if(params->locallab.spots.at(sp).colorscope != 30) {//compatibility with old method in controlspotpanel to change scope - default value 30 + scopefp[sp]= params->locallab.spots.at(sp).colorscope; + } // Set local curves of current spot to LUT locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); @@ -1537,7 +1545,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locciesig.contsigq = contsig; locciesig.lightsigq = lightsig; locallciesig.push_back(locciesig); - + + // Recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reserv.get(), reserv.get(), 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg, locwavCurveden, locwavdenutili); @@ -1555,6 +1564,50 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } + + // new used linked to global and scope + mainfp[sp] = 0; + if (params->locallab.spots.at(sp).spotMethod == "main") { + mainfp[sp] = 3; + } else if (params->locallab.spots.at(sp).spotMethod == "full") { + mainfp[sp] = 2; + } + //keep using tools + bool iscolor = params->locallab.spots.at(sp).expcolor; + bool issh = params->locallab.spots.at(sp).expshadhigh; + bool isvib = params->locallab.spots.at(sp).expvibrance; + bool isexpos = params->locallab.spots.at(sp).expexpose; + bool issoft = params->locallab.spots.at(sp).expsoft; + bool isblur = params->locallab.spots.at(sp).expblur; + bool istom = params->locallab.spots.at(sp).exptonemap; + bool isret = params->locallab.spots.at(sp).expreti; + bool issharp = params->locallab.spots.at(sp).expsharp; + bool iscont = params->locallab.spots.at(sp).expcontrast; + bool iscbdl = params->locallab.spots.at(sp).expcbdl; + bool islog = params->locallab.spots.at(sp).explog; + bool ismas = params->locallab.spots.at(sp).expmask; + bool iscie = params->locallab.spots.at(sp).expcie; + bool isset = iscolor || issh || isvib; + + //set select spot settings + LocallabListener::locallabsetLC locsetlc; + locsetlc.mainf = mainfp[sp]; + locsetlc.iscolo = iscolor; + locsetlc.iss = issh; + locsetlc.isvi = isvib; + locsetlc.isexpo = isexpos; + locsetlc.issof = issoft; + locsetlc.isblu = isblur; + locsetlc.isto = istom; + locsetlc.isre = isret; + locsetlc.isshar = issharp; + locsetlc.iscon = iscont; + locsetlc.iscbd = iscbdl; + locsetlc.islo = islog; + locsetlc.isma = ismas; + locsetlc.isci = iscie; + locallsetlc.push_back(locsetlc); + if (locallListener) { locallListener->refChanged2(huerefp, chromarefp, lumarefp, fabrefp, params->locallab.selspot); locallListener->minmaxChanged(locallretiminmax, params->locallab.selspot); @@ -1562,6 +1615,18 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locallListener->cieChanged(locallcielc,params->locallab.selspot); } locallListener->sigChanged(locallciesig,params->locallab.selspot); + if(params->locallab.spots.at(sp).colorscope != 30) {//compatibility with old method in controlspotpanel + locallListener->scopeChangedcol(scopefp[sp], params->locallab.selspot, iscolor); + locallListener->scopeChangedsh(scopefp[sp], params->locallab.selspot, issh); + locallListener->scopeChangedvib(scopefp[sp], params->locallab.selspot, isvib); + locallListener->scopeChangedset(scopefp[sp], params->locallab.selspot, isset); + params->locallab.spots.at(sp).colorscope = 30; + } + // if (mainfp[sp] >= 0) {//minimize call to idle register + //used by Global fullimage. + locallListener->maiChanged(locallsetlc,params->locallab.selspot); + // } + } } @@ -1570,7 +1635,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) delete [] chromarefp; delete [] lumarefp; delete [] fabrefp; - + delete [] mainfp; + delete [] scopefp; ipf.lab2rgb(*nprevl, *oprevi, params->icm.workingProfile); //************************************************************* // end locallab diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index a40f2f146..1d03f7adc 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -952,6 +952,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.fullim = 1; } else if (locallab.spots.at(sp).spotMethod == "full") { lp.fullim = 2; + } else if (locallab.spots.at(sp).spotMethod == "main") {//new Global + lp.fullim = 3; } lp.fftColorMask = locallab.spots.at(sp).fftColorMask; @@ -1097,6 +1099,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.excmet = 1; } else if (locallab.spots.at(sp).spotMethod == "full") { lp.excmet = 2; + } else if (locallab.spots.at(sp).spotMethod == "main") { + lp.excmet = 3; } if (locallab.spots.at(sp).merMethod == "mone") { @@ -1852,10 +1856,10 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.blwh = locallab.spots.at(sp).blwh; lp.senscolor = (int) locallab.spots.at(sp).colorscope; //replace scope color vibrance shadows - lp.sens = lp.senscolor; +/* lp.sens = lp.senscolor; lp.sensv = lp.senscolor; lp.senshs = lp.senscolor; - +*/ lp.mLjz = locallab.spots.at(sp).clarilresjz / 100.0; lp.mCjz = locallab.spots.at(sp).claricresjz / 100.0; lp.softrjz = locallab.spots.at(sp).clarisoftjz; @@ -4947,7 +4951,10 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab //simple algo , perhaps we can improve as the others, but noise is here and not good for hue detection // BENCHFUN lumaref *= 327.68f; - const float ach = lp.trans / 100.f; + float ach = lp.trans / 100.f; + if(lp.fullim == 3 ) {//disabled transit + ach = 1.f; + } const float factnoise1 = 1.f + (lp.noisecf) / 500.f; const float factnoise2 = 1.f + (lp.noisecc) / 500.f; @@ -5024,6 +5031,9 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } + if(lp.fullim == 3 ) {//disabled scope + localFactor = 1.f; + } if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values continue; @@ -5058,6 +5068,9 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab difa = tmp1.a[y][x] - original->a[y][x]; difb = tmp1.b[y][x] - original->b[y][x]; } + if(lp.fullim == 3 ) {//disable scope + reducdEL = reducdEa = reducdEb = 1.f; + } difL *= localFactor * reducdEL; difa *= localFactor * reducdEa; @@ -5103,7 +5116,10 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or lumaref *= 327.68f; - const float ach = lp.trans / 100.f; + float ach = lp.trans / 100.f; + if(lp.fullim == 3 ) {//disabled transit + ach = 1.f; + } const float factnoise1 = 1.f + (lp.noisecf) / 500.f; const float factnoise2 = 1.f + (lp.noisecc) / 500.f; @@ -5180,6 +5196,9 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } + if(lp.fullim == 3 ) {//disabled scope + localFactor = 1.f; + } if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values continue; @@ -5208,6 +5227,9 @@ void ImProcFunctions::DeNoise_Local2(const struct local_params& lp, LabImage* or difL = tmp1.L[y - ystart][x - xstart] - original->L[y][x]; difa = tmp1.a[y - ystart][x - xstart] - original->a[y][x]; difb = tmp1.b[y - ystart][x - xstart] - original->b[y][x]; + if(lp.fullim == 3 ) {//disable scope + reducdEL = reducdEa = reducdEb = 1.f; + } difL *= localFactor * reducdEL; difa *= localFactor * reducdEa; @@ -5297,7 +5319,10 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl float rL = origblur->L[y][x] / 327.68f; float dE = std::sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); - const float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensh); + float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensh); + if(lp.fullim == 3 ) {//disable scope + reducdE = 1.f; + } switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition @@ -5446,6 +5471,10 @@ void ImProcFunctions::InverseBlurNoise_Local(LabImage * originalmask, const stru float huedelta2 = abdelta2 - chrodelta2; float dE = std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - maskptr->L[y][x])); reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensbn); + if(lp.fullim == 3 ) {//disabled scope + reducdE = 1.f; + } + } switch (zone) { @@ -5795,13 +5824,19 @@ static void blendmask(const local_params& lp, int xstart, int ystart, int cx, in int zone; float localFactor = 1.f; - const float achm = lp.trans / 100.f; + float achm = lp.trans / 100.f; + if(lp.fullim == 3 ) {//disable transit + achm = 1.f; + } if (lp.shapmet == 0) { calcTransition(lox, loy, achm, lp, zone, localFactor); } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } + if(lp.fullim == 3 ) {//disable scope + localFactor = 1.f; + } if (inv == 0) { if (zone > 0) { @@ -8033,7 +8068,7 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage * bufexpo transformed->L[y][x] = CLIP(12000.f + difL); transformed->a[y][x] = clipC(difa); transformed->b[y][x] = clipC(difb); - } else if (previewcb || previewtm || lp.prevdE) { + } else if (/* previewcb ||*/ previewtm || lp.prevdE) { if (std::fabs(difb) < 500.f) { difb += difL; } @@ -8651,7 +8686,7 @@ void optfft(int N_fftwsize, int &bfh, int &bfw, int &bfhr, int &bfwr, struct loc } } - if (fulima == 2) { // if full image, the ftsizeH and ftsizeW is a bit larger (about 10 to 200 pixels) than the image dimensions so that it is fully processed (consumes a bit more resources) + if(fulima >= 2) {// if full image, the ftsizeH and ftsizeW is a bit larger (about 10 to 200 pixels) than the image dimensions so that it is fully processed (consumes a bit more resources) for (int ftfu = 0; ftfu < N_fftwsize; ftfu++) { //find best values if (fftw_size[ftfu] <= (H + deltah)) { ftsizeH = fftw_size[ftfu]; @@ -8961,16 +8996,16 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const bool masshow = ((lp.showmask_met == 1) && senstype == 20); - const bool previewvib = ((lp.showmaskvibmet == 4) && senstype == 2); - const bool previewexp = ((lp.showmaskexpmet == 5) && senstype == 1); - const bool previewcol = ((lp.showmaskcolmet == 5) && senstype == 0); - const bool previewSH = ((lp.showmaskSHmet == 4) && senstype == 9); - const bool previewtm = ((lp.showmasktmmet == 4) && senstype == 8); - const bool previewlc = ((lp.showmasklcmet == 4) && senstype == 10); + const bool previewvib = ((lp.showmaskvibmet == 4) && senstype == 2 && lp.fullim != 3); + const bool previewexp = ((lp.showmaskexpmet == 5) && senstype == 1 && lp.fullim != 3); + const bool previewcol = ((lp.showmaskcolmet == 5) && senstype == 0 && lp.fullim != 3); + const bool previewSH = ((lp.showmaskSHmet == 4) && senstype == 9 && lp.fullim != 3); + const bool previewtm = ((lp.showmasktmmet == 4) && senstype == 8 && lp.fullim != 3); + const bool previewlc = ((lp.showmasklcmet == 4) && senstype == 10 && lp.fullim != 3); const bool previeworig = ((lp.showmasksoftmet == 6) && senstype == 3 && lp.softmet == 1); - const bool previewmas = ((lp.showmask_met == 3) && senstype == 20); - const bool previewlog = ((lp.showmasklogmet == 4) && senstype == 11); - const bool previewcie = ((lp.showmaskciemet == 4) && senstype == 31); + const bool previewmas = ((lp.showmask_met == 3) && senstype == 20 && lp.fullim != 3); + const bool previewlog = ((lp.showmasklogmet == 4) && senstype == 11 && lp.fullim != 3); + const bool previewcie = ((lp.showmaskciemet == 4) && senstype == 31 && lp.fullim != 3); float radius = 3.f / sk; @@ -9175,7 +9210,10 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const int lox = x + xstart + cx; int zone; float localFactor = 1.f; - const float achm = lp.trans / 100.f; + float achm = lp.trans / 100.f; + if(lp.fullim == 3 ) {//disable transit + achm = 1.f; + } //calculate transition if (lp.shapmet == 0) { @@ -9183,6 +9221,9 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in } else { /*if (lp.shapmet == 1)*/ calcTransitionrect(lox, loy, achm, lp, zone, localFactor); } + if(lp.fullim == 3 ) {//disable scope + localFactor = 1.f; + } // float hueh = 0; #ifdef __SSE2__ @@ -9221,6 +9262,9 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in const float dE = rsob + std::sqrt(kab * (kch * chrodelta2 + kH * huedelta2) + kL * SQR(refL - maskptr->L[y][x])); //reduction action with deltaE float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens); + if(lp.fullim == 3 ) {//disable scope + reducdE = 1.f; + } if ((senstype == 11 || ( senstype == 31 && lp.islogcie)) && (varsens >= limvarsens)) { int maxvarsens = 90;//arbitrary value to get maximum incidence float ared = (1.f - reducdE) / (maxvarsens - limvarsens); @@ -9231,6 +9275,7 @@ void ImProcFunctions::transit_shapedetect2(int sp, float meantm, float stdtm, in if(varsens == 100.f) { reducdE = 1.f; } + float cli = (bufexpfin->L[y][x] - bufexporig->L[y][x]); float cla = (bufexpfin->a[y][x] - bufexporig->a[y][x]); float clb = (bufexpfin->b[y][x] - bufexporig->b[y][x]); @@ -15341,7 +15386,11 @@ void ImProcFunctions::Lab_Local( for (int y = 0; y < transformed->H ; y++) for (int x = 0; x < transformed->W; x++) { float dE = std::sqrt(SQR(refa - bufreti->a[y][x] / 327.68f) + SQR(refb - bufreti->b[y][x] / 327.68f) + SQR(static_cast(lumaref) - bufreti->b[y][x] / 327.68f)); - const float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sensibefore); + float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sensibefore); + if(lp.fullim == 3 ) {//disable scope + reducdE = 1.f; + } + reducDE[y][x] = clipDE(reducdE); } @@ -15702,7 +15751,11 @@ void ImProcFunctions::Lab_Local( for (int y = ystart; y < yend ; y++) { for (int x = xstart; x < xend; x++) { const float dE = std::sqrt(SQR(refa - bufreti->a[y - ystart][x - xstart] / 327.68f) + SQR(refb - bufreti->b[y - ystart][x - xstart] / 327.68f) + SQR(static_cast(lumaref) - bufreti->b[y - ystart][x - xstart] / 327.68f)); - const float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sensibefore); + float reducdE = calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, sensibefore); + if(lp.fullim == 3 ) {//disable scope + reducdE = 1.f; + } + reducDE[y - ystart][x - xstart] = clipDE(reducdE); } } @@ -17480,7 +17533,7 @@ void ImProcFunctions::Lab_Local( int yEn = lp.yc + lp.ly; int xEn = lp.xc + lp.lx; - if (lp.fullim == 2) { //limit sharpening to image dimension...no more...to avoid a long treatment + if(lp.fullim >= 2) {//full-iamge and global - limit sharpening to image dimension...no more...to avoid a long treatment begy = 0; begx = 0; yEn = original->H; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 763decb75..9d759a723 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3038,7 +3038,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : labgridAHighmerg(-3500.0), labgridBHighmerg(-4600.0), strengthgrid(30), - sensi(15), + sensi(30), structcol(0), strcol(0.), strcolab(0.), @@ -3384,7 +3384,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : shadows(0), s_tonalwidth(30), sh_radius(40), - sensihs(15), + sensihs(30), enaSHMask(false), CCmaskSHcurve{ static_cast(FCT_MinMaxCPoints), @@ -3471,7 +3471,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : protectskins(false), avoidcolorshift(true), pastsattog(true), - sensiv(15), + sensiv(30), skintonescurve{ static_cast(DCT_Linear) }, @@ -4768,9 +4768,80 @@ LocallabParams::LocallabSpot::LocallabSpot() : 0.35 }, csthresholdcie(0, 0, 6, 5, false) - + { + // init settings with Preferences / options : must be followed by call to spotMethodChanged in controlspotpanel.cc (idle_register) + // new values default with different SpotMethod. + + if(options.spotmet == 3) {//global + spotMethod = "main"; + loc = {3000, 3000, 3000, 3000}; + transit =100.; + shape = "RECT"; + + } else if(options.spotmet == 2) {//full image + spotMethod = "full"; + loc = {3000, 3000, 3000, 3000}; + transit =100.; + shape = "RECT"; + sensi = 30; + sensiex = 60; + sensihs = 30; + sensiv = 30; + sensisf = 30; + sensibn = 40; + sensiden = 60; + sensitm = 60; + sensih = 60; + sensisha = 40; + sensilc = 60; + sensicb = 60; + sensilog = 60; + sensimask = 60; + sensicie = 60; + + } else if(options.spotmet == 1) {//exclude + spotMethod = "exc"; + shape = "ELI"; + loc = {150, 150, 150, 150}; + transit= 60.; + sensi = 30; + sensiex = 60; + sensihs = 30; + sensiv = 30; + sensibn = 40; + sensiden = 60; + sensitm = 60; + sensih = 60; + sensisha = 40; + sensilc = 60; + sensicb = 60; + sensilog = 60; + sensimask = 60; + sensicie = 60; + + } else if(options.spotmet == 0) {//normal + spotMethod = "norm"; + shape = "ELI"; + loc = {150, 150, 150, 150}; + transit= 60.; + sensi = 30; + sensiex = 60; + sensihs = 30; + sensiv = 30; + sensibn = 40; + sensiden = 60; + sensitm = 60; + sensih = 60; + sensisha = 40; + sensilc = 60; + sensicb = 60; + sensilog = 60; + sensimask = 60; + sensicie = 60; + } + } bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index e27f372ae..f1ee4108c 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -451,6 +451,25 @@ public: int primlc; }; +//select spot settings + struct locallabsetLC { + int mainf; + bool iscolo; + bool iss; + bool isvi; + bool isexpo; + bool issof; + bool isblu; + bool isto; + bool isre; + bool isshar; + bool iscon; + bool iscbd; + bool islo; + bool isma; + bool isci; + }; + struct locallabcieSIG { double contsigq; double lightsigq; @@ -461,9 +480,15 @@ public: virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; virtual void denChanged(const std::vector &denlc, int selspot) = 0; virtual void cieChanged(const std::vector &cielc, int selspot) = 0; + virtual void maiChanged(const std::vector &csetlc, int selspot) = 0; virtual void sigChanged(const std::vector &ciesig, int selspot) = 0; virtual void ciebefChanged(const std::vector &ciebef, int selspot) = 0; virtual void refChanged2(float *huerefp, float *chromarefp, float *lumarefp, float *fabrefp, int selspot) = 0; +// virtual void mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie) = 0; + virtual void scopeChangedcol(int scope, int selspot, bool enab) = 0; + virtual void scopeChangedsh(int scope, int selspot, bool enab) = 0; + virtual void scopeChangedvib(int scope, int selspot, bool enab) = 0; + virtual void scopeChangedset(int scope, int selspot, bool enab) = 0; }; diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 31510acbc..8588f6057 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -100,8 +100,11 @@ ControlSpotPanel::ControlSpotPanel(): preview_(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), ctboxshape(Gtk::manage(new Gtk::Box())), + ctboxactivmethod(Gtk::manage(new Gtk::Box())), + ctboxspotmethod(Gtk::manage(new Gtk::Box())), ctboxshapemethod(Gtk::manage(new Gtk::Box())), ctboxgamut(Gtk::manage(new Gtk::Box())), + artifBox2(Gtk::manage(new ToolParamBlock())), controlPanelListener(nullptr), lastObject_(-1), @@ -116,7 +119,7 @@ ControlSpotPanel::ControlSpotPanel(): auto m = ProcEventMapper::getInstance(); EvLocallabavoidgamutMethod = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_GAMUTMUNSEL"); const bool showtooltip = options.showtooltip; - pack_start(*hishow_); +// pack_start(*hishow_); Gtk::Box* const ctboxprevmethod = Gtk::manage(new Gtk::Box()); prevMethod_->append(M("TP_LOCALLAB_PREVHIDE")); @@ -204,8 +207,9 @@ ControlSpotPanel::ControlSpotPanel(): scrolledwindow_->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); scrolledwindow_->set_min_content_height(150); pack_start(*scrolledwindow_); + pack_start(*hishow_); - Gtk::Box* const ctboxactivmethod = Gtk::manage(new Gtk::Box()); + // Gtk::Box* const ctboxactivmethod = Gtk::manage(new Gtk::Box()); ctboxactivmethod->pack_start(*activ_); pack_start(*ctboxactivmethod); @@ -223,7 +227,6 @@ ControlSpotPanel::ControlSpotPanel(): shape_->set_tooltip_text(M("TP_LOCALLAB_SHAPE_TOOLTIP")); } - Gtk::Box* const ctboxspotmethod = Gtk::manage(new Gtk::Box()); Gtk::Label* const labelspotmethod = Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_EXCLUTYPE") + ":")); ctboxspotmethod->pack_start(*labelspotmethod, Gtk::PACK_SHRINK, 4); @@ -234,6 +237,7 @@ ControlSpotPanel::ControlSpotPanel(): spotMethod_->append(M("TP_LOCALLAB_EXNORM")); spotMethod_->append(M("TP_LOCALLAB_EXECLU")); spotMethod_->append(M("TP_LOCALLAB_EXFULL")); + spotMethod_->append(M("TP_LOCALLAB_EXMAIN"));//new choice Global spotMethod_->set_active(0); spotMethodconn_ = spotMethod_->signal_changed().connect( sigc::mem_fun( @@ -388,10 +392,11 @@ ControlSpotPanel::ControlSpotPanel(): // artifBox->pack_start(*colorscope_); expShapeDetect_->add(*artifBox, false); pack_start(*expShapeDetect_, false, false); - ToolParamBlock* const artifBox2 = Gtk::manage(new ToolParamBlock()); +// ToolParamBlock* const artifBox2 = Gtk::manage(new ToolParamBlock()); artifBox2->pack_start(*preview_); - artifBox2->pack_start(*colorscope_); + artifBox2->pack_start(*colorscope_);//unused with contrlspotpanel since 17 / 01 : 2024 but data used in color, vibrance, sh + colorscope_->hide(); pack_start(*artifBox2); ToolParamBlock* const specCaseBox = Gtk::manage(new ToolParamBlock()); @@ -552,7 +557,6 @@ ControlSpotPanel::ControlSpotPanel(): pack_start(*ctboxwavmethod); */ show_all(); - // Define row background color // Mouseovered spot (opaque orange) colorMouseover.set_red(1.); @@ -795,6 +799,7 @@ bool ControlSpotPanel::on_button_visibility(GdkEventButton* event) return false; } + bool ControlSpotPanel::blockTreeviewSearch(GdkEventKey* event) { // printf("blockTreeviewSearch\n"); @@ -982,7 +987,7 @@ void ControlSpotPanel::prevMethodChanged() void ControlSpotPanel::spotMethodChanged() { - + //01 2024 take into account new problems linked to Global spotmethod // Get selected control spot const auto s = treeview_->get_selection(); @@ -995,15 +1000,20 @@ void ControlSpotPanel::spotMethodChanged() const int oldSpotMethod = row[spots_.spotMethod]; row[spots_.spotMethod] = spotMethod_->get_active_row_number(); + //ctboxspotmethod->show(); + hishow_->show(); + ctboxshape->show(); + artifBox2->show(); + colorscope_->hide(); // Update Control Spot GUI according to spotMethod_ combobox state (to be compliant with updateParamVisibility function) if (multiImage && spotMethod_->get_active_text() == M("GENERAL_UNCHANGED")) { excluFrame->show(); + } else if (spotMethod_->get_active_row_number() == 0) { // Normal case excluFrame->hide(); - - // Reset spot shape only if previous spotMethod is Full image - if (oldSpotMethod == 2) { + // Reset spot shape only if previous spotMethod is Full image or Global + if (oldSpotMethod == 2 || oldSpotMethod == 3) { disableParamlistener(true); locX_->setValue(150.); row[spots_.locX] = locX_->getIntValue(); @@ -1023,8 +1033,8 @@ void ControlSpotPanel::spotMethodChanged() } else if (spotMethod_->get_active_row_number() == 1) { // Excluding case excluFrame->show(); - // Reset spot shape only if previous spotMethod is Full image - if (oldSpotMethod == 2) { + // Reset spot shape only if previous spotMethod is Full image or Global + if (oldSpotMethod == 2 || oldSpotMethod == 3) { disableParamlistener(true); locX_->setValue(150.); row[spots_.locX] = locX_->getIntValue(); @@ -1041,7 +1051,7 @@ void ControlSpotPanel::spotMethodChanged() disableParamlistener(false); updateControlSpotCurve(row); } - } else if (spotMethod_->get_active_row_number() == 2) { // Full image case + } else if (spotMethod_->get_active_row_number() == 2 || spotMethod_->get_active_row_number() == 3) { // Full image or Global case excluFrame->hide(); shape_->set_active(0); @@ -1057,6 +1067,31 @@ void ControlSpotPanel::spotMethodChanged() row[spots_.shape] = shape_->get_active_row_number(); transit_->setValue(100.); row[spots_.transit] = transit_->getValue(); + + if(spotMethod_->get_active_row_number() == 3) { //global + ctboxshape->hide(); + artifBox2->hide(); + hishow_->hide(); + expTransGrad_->hide(); + expShapeDetect_->hide(); + expSpecCases_->hide(); + expMaskMerge_->hide(); + circrad_->hide(); + ctboxshape->hide(); + } else { + ctboxshape->show(); + circrad_->show(); + artifBox2->show(); + colorscope_->hide(); + + hishow_->show(); + if(hishow_->get_active()) { + expTransGrad_->show(); + expShapeDetect_->show(); + expSpecCases_->show(); + expMaskMerge_->show(); + } + } } // Raise event @@ -1304,7 +1339,12 @@ void ControlSpotPanel::updateParamVisibility() } else { avoidrad_->hide(); } - + // ctboxspotmethod->show(); + hishow_->show(); + artifBox2->show(); + ctboxshape->show(); + colorscope_->hide(); + // Update Control Spot GUI according to spotMethod_ combobox state (to be compliant with spotMethodChanged function) if (multiImage && spotMethod_->get_active_text() == M("GENERAL_UNCHANGED")) { excluFrame->show(); @@ -1312,8 +1352,35 @@ void ControlSpotPanel::updateParamVisibility() excluFrame->hide(); } else if (spotMethod_->get_active_row_number() == 1) { // Excluding case excluFrame->show(); - } else if (spotMethod_->get_active_row_number() == 2) {//full image + } else if (spotMethod_->get_active_row_number() == 2 || spotMethod_->get_active_row_number() == 3) {//full image or global excluFrame->hide(); + + if(spotMethod_->get_active_row_number() == 3) { + artifBox2->hide(); + hishow_->hide(); + hishow_->set_active(false); + ctboxshape->hide(); + circrad_->hide(); + expTransGrad_->hide(); + expShapeDetect_->hide(); + expSpecCases_->hide(); + expMaskMerge_->hide(); + + } else { + artifBox2->show(); + colorscope_->hide(); + hishow_->show(); + ctboxshape->show(); + circrad_->show(); + if(hishow_->get_active()) { + expTransGrad_->show(); + expShapeDetect_->show(); + expSpecCases_->show(); + expMaskMerge_->show(); + } + + } + } /* @@ -1326,13 +1393,35 @@ void ControlSpotPanel::updateParamVisibility() ctboxshape->show(); } else if (prevMethod_->get_active_row_number() == 0) { // Normal case */ - if (!hishow_->get_active()) { // Normal case + //ctboxshape->show(); + // artifBox2->show(); + + if (!hishow_->get_active() || spotMethod_->get_active_row_number() == 3) { // Normal case or Global expTransGrad_->hide(); expShapeDetect_->hide(); expSpecCases_->hide(); expMaskMerge_->hide(); circrad_->hide(); ctboxshape->hide(); + if(spotMethod_->get_active_row_number() == 3) { + artifBox2->hide(); + hishow_->hide(); + ctboxshape->hide(); + circrad_->hide(); + expTransGrad_->hide(); + expShapeDetect_->hide(); + expSpecCases_->hide(); + expMaskMerge_->hide(); + + } else { + hishow_->show(); + artifBox2->show(); + colorscope_->hide(); + hishow_->show(); + ctboxshape->show(); + circrad_->show(); + } + } else { // Excluding case expTransGrad_->show(); expShapeDetect_->show(); @@ -1340,6 +1429,8 @@ void ControlSpotPanel::updateParamVisibility() expMaskMerge_->show(); circrad_->show(); ctboxshape->show(); + hishow_->show(); + } @@ -1603,8 +1694,9 @@ void ControlSpotPanel::hishowChanged() row[spots_.hishow] = hishow_->get_active(); + ctboxshape->show(); - if (!hishow_->get_active()) { // Normal case + if (!hishow_->get_active() || spotMethod_->get_active_row_number() == 3) { // Normal case or Global expTransGrad_->hide(); expShapeDetect_->hide(); expSpecCases_->hide(); @@ -1612,6 +1704,20 @@ void ControlSpotPanel::hishowChanged() circrad_->hide(); ctboxshape->hide(); shapeMethod_->set_active(0); + if(spotMethod_->get_active_row_number() == 3) { + hishow_->hide(); + hishow_->set_active(false); + circrad_->hide(); + expTransGrad_->hide(); + expShapeDetect_->hide(); + expSpecCases_->hide(); + expMaskMerge_->hide(); + + } else { + hishow_->show(); + circrad_->show(); + + } } else { // Excluding case expTransGrad_->show(); @@ -1620,7 +1726,9 @@ void ControlSpotPanel::hishowChanged() expMaskMerge_->show(); circrad_->show(); ctboxshape->show(); - } + hishow_->show(); + + } // Raise event if (listener) { @@ -2764,6 +2872,56 @@ void ControlSpotPanel::deleteControlSpot(const int index) disableParamlistener(false); } +//new function linked to Global and options +void ControlSpotPanel::updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie) +{ + { //with this function we can 1) activate Settings SpotMethod + // also if need GUI for mask , todo... + idle_register.add( + [this, spottype, iscolor, issh , isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + if(spottype >= 2 && options.spotmet >= 2) {//optimize update + spotMethodChanged(); + } + + if((iscolor || issh || isvib || isexpos || istom || iscont || islog || ismas || iscie) + && !issharp && !issoft && !isret && !isblur & !iscbdl) { + preview_->hide(); + } else if (issoft || isblur || isret || issharp || iscbdl) { + preview_->show(); + } + enableListener(); + + return false; + } + ); + } + +} +//new function linked to change scope +void ControlSpotPanel::updateguiscopeset(int scope) +{ + { //with this function we can disabled old values scope + idle_register.add( + [this, scope]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + disableListener(); + colorscope_->setValue(scope); + adjusterChanged(colorscope_, 0.); + enableListener(); + + return false; + } + ); + } + +} + + void ControlSpotPanel::setDefaults(const rtengine::procparams::ProcParams * defParams, const ParamsEdited * pedited) { const int index = defParams->locallab.selspot; diff --git a/rtgui/controlspotpanel.h b/rtgui/controlspotpanel.h index e9eddf4e5..855f2d94a 100644 --- a/rtgui/controlspotpanel.h +++ b/rtgui/controlspotpanel.h @@ -55,7 +55,7 @@ public: bool isvisible; int prevMethod; // 0 = Normal, 1 = Excluding int shape; // 0 = Ellipse, 1 = Rectangle - int spotMethod; // 0 = Normal, 1 = Excluding + int spotMethod; // 0 = Normal, 1 = Excluding 2 = fullimage 3 = main int sensiexclu; int structexclu; int shapeMethod; // 0 = Independent (mouse), 1 = Symmetrical (mouse), 2 = Independent (mouse + sliders), 3 = Symmetrical (mouse + sliders) @@ -106,6 +106,7 @@ public: SpotDuplication = 4, SpotAllVisibilityChanged = 5 }; + IdleRegister idle_register; // Constructor and management functions /** @@ -220,6 +221,12 @@ public: // Batch mode management // Note: Batch mode is deactivated for Locallab + + /** + * upadte function to work with Preferences and spotMethod + */ + void updateguiset(int spottype, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie); + void updateguiscopeset(int scope); private: // Cell renderer @@ -435,8 +442,12 @@ private: sigc::connection previewConn_; Gtk::Box* const ctboxshape; + Gtk::Box* const ctboxactivmethod; + Gtk::Box* const ctboxspotmethod; + Gtk::Box* const ctboxshapemethod; Gtk::Box* const ctboxgamut; + ToolParamBlock* const artifBox2; // Internal variables ControlPanelListener* controlPanelListener; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 974cd36ec..2bbdcd8cd 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -2028,3 +2028,42 @@ void SpotPicker::spotSizeChanged() { _spotHalfWidth = atoi(_spotSizeSetter.get_active_text().c_str()); } + +// OptionalRadioButtonGroup class + +void OptionalRadioButtonGroup::onButtonToggled(Gtk::ToggleButton *button) +{ + if (!button) { + return; + } + + if (button->get_active()) { + if (active_button == button) { + // Same button, noting to do. + } else if (active_button) { + // Deactivate the other button. + active_button->set_active(false); + } + active_button = button; + } else { + if (active_button == button) { + // Active button got deactivated. + active_button = nullptr; + } else { + // No effect on other buttons. + } + } +} + +Gtk::ToggleButton *OptionalRadioButtonGroup::getActiveButton() const +{ + return active_button; +} + +void OptionalRadioButtonGroup::register_button(Gtk::ToggleButton &button) +{ + button.signal_toggled().connect(sigc::bind( + sigc::mem_fun(this, &OptionalRadioButtonGroup::onButtonToggled), + &button)); + onButtonToggled(&button); +} diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index e8e7d7930..169d0ae11 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -756,6 +756,30 @@ class SpotPicker : public Gtk::Grid void spotSizeChanged(); }; +/** + * Enforces the rule that zero or one registered toggle button is enabled at any + * given time. + */ +class OptionalRadioButtonGroup +{ + Gtk::ToggleButton *active_button{nullptr}; + + void onButtonToggled(Gtk::ToggleButton *button); + +public: + /** + * Returns the toggle button that is active, or null if none are active. + */ + Gtk::ToggleButton *getActiveButton() const; + /** + * Adds a toggle button to this group. + * + * If the provided button is active, any existing active button in this + * group will be deactivated. + */ + void register_button(Gtk::ToggleButton &button); +}; + inline void setActiveTextOrIndex(Gtk::ComboBoxText &comboBox, const Glib::ustring &text, int index) { bool valueSet = false; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index bc5e2144b..13b68ba6d 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -175,6 +175,28 @@ Locallab::Locallab(): toollist->setLocallabToolListListener(this); panel->pack_start(*toollist, false, false); + // Add all the tools' preview delta E buttons to one group. + for (auto button : { + expcolor.getPreviewDeltaEButton(), + expexpose.getPreviewDeltaEButton(), + expshadhigh.getPreviewDeltaEButton(), + expvibrance.getPreviewDeltaEButton(), + expsoft.getPreviewDeltaEButton(), + expblur.getPreviewDeltaEButton(), + exptonemap.getPreviewDeltaEButton(), + expreti.getPreviewDeltaEButton(), + expsharp.getPreviewDeltaEButton(), + expcontrast.getPreviewDeltaEButton(), + expcbdl.getPreviewDeltaEButton(), + explog.getPreviewDeltaEButton(), + expmask.getPreviewDeltaEButton(), + expcie.getPreviewDeltaEButton(), + }) { + if (button) { + delta_e_preview_button_group.register_button(*button); + } + } + // Add Locallab tools to panel widget ToolVBox* const toolpanel = Gtk::manage(new ToolVBox()); toolpanel->set_name("LocallabToolPanel"); @@ -249,7 +271,7 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit if (pp->locallab.spots.at(i).shape == "ELI") { r.shape = 0; - } else { + } else if (pp->locallab.spots.at(i).shape == "RECT") { r.shape = 1; } @@ -265,8 +287,10 @@ void Locallab::read(const rtengine::procparams::ProcParams* pp, const ParamsEdit r.spotMethod = 1; } else if (pp->locallab.spots.at(i).spotMethod == "full"){ r.spotMethod = 2; + } else if (pp->locallab.spots.at(i).spotMethod == "main"){ + r.spotMethod = 3; } - + r.sensiexclu = pp->locallab.spots.at(i).sensiexclu; r.structexclu = pp->locallab.spots.at(i).structexclu; @@ -420,7 +444,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited if (newSpot->shape == "ELI") { r.shape = 0; - } else { + } else if (newSpot->shape == "RECT"){ r.shape = 1; } @@ -437,6 +461,8 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r.spotMethod = 1; } else if(newSpot->spotMethod == "full") { r.spotMethod = 2; + } else if(newSpot->spotMethod == "main") { + r.spotMethod = 3; } r.sensiexclu = newSpot->sensiexclu; @@ -746,7 +772,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited if (newSpot->shape == "ELI") { r.shape = 0; - } else { + } else if (newSpot->shape == "RECT"){ r.shape = 1; } @@ -762,8 +788,10 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited r.spotMethod = 1; } else if (newSpot->spotMethod == "full") { r.spotMethod = 2; + } else if (newSpot->spotMethod == "main") { + r.spotMethod = 3; } - + r.sensiexclu = newSpot->sensiexclu; r.structexclu = newSpot->structexclu; @@ -810,7 +838,7 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited } } - if(r.spotMethod != 2) { + if(r.spotMethod == 0 || r.spotMethod == 1 ) { r.locX = newSpot->loc.at(0); r.locXL = newSpot->loc.at(1); r.locY = newSpot->loc.at(2); @@ -960,6 +988,8 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited pp->locallab.spots.at(pp->locallab.selspot).spotMethod = "exc"; } else if (r->spotMethod == 2) { pp->locallab.spots.at(pp->locallab.selspot).spotMethod = "full"; + } else if (r->spotMethod == 3) { + pp->locallab.spots.at(pp->locallab.selspot).spotMethod = "main"; } pp->locallab.spots.at(pp->locallab.selspot).sensiexclu = r->sensiexclu; @@ -1130,7 +1160,108 @@ void Locallab::denChanged(const std::vector &denlc, int selsp } } +// New fonctions to change Scope color +void Locallab::scopeChangedcol(int scope, int selspot, bool enab) +{ + if(enab) { + expcolor.updateguiscopecolor(scope); + } + +} +// New fonctions to change Scope Shadows Highlight +void Locallab::scopeChangedsh(int scope, int selspot, bool enab) +{ + if(enab) { + expshadhigh.updateguiscopesahd(scope); + } + +} + +// New fonctions to change Scope Vibrance + +void Locallab::scopeChangedvib(int scope, int selspot, bool enab) +{ + if(enab) { + expvibrance.updateguiscopevib(scope); + } + +} + +//reinit expsettings +void Locallab::scopeChangedset(int scope, int selspot, bool enab) +{ + if(enab) { + expsettings->updateguiscopeset(30);//30 defaut value..perhaps possible to pass default value ?? + } + +} +/* +//main new fonction global to hide show and activated or not some functions - inverse, scope... +void Locallab::mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie ) +{ + + + if(iscolor) { + expcolor.updateguicolor(spottype); + } + + if(issh) { + expshadhigh.updateguishad(spottype); + } + + if(isvib) { + expvibrance.updateguivib(spottype); + } + + if(isexpos) { + expexpose.updateguiexpos(spottype); + } + + if(issoft) { + expsoft.updateguisoft(spottype); + } + + if(isblur) { + expblur.updateguiblur(spottype); + } + + if(istom) { + exptonemap.updateguitone(spottype); + } + + if(isret) { + expreti.updateguireti(spottype); + } + + if(issharp) { + expsharp.updateguisharp(spottype); + } + + if(iscont) { + expcontrast.updateguicont(spottype); + } + + if(iscbdl) { + expcbdl.updateguicbdl(spottype); + } + + if(islog) { + explog.updateguilog(spottype); + } + + if(ismas) { + expmask.updateguimask(spottype); + } + + if(iscie) { + expcie.updateguicie(spottype); + } + + expsettings->updateguiset(spottype, iscolor, issh, isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie); + +} +*/ void Locallab::sigChanged(const std::vector &ciesig, int selspot) { cie_sig = ciesig; @@ -1168,6 +1299,86 @@ void Locallab::ciebefChanged(const std::vector &ciebef, int sels } +void Locallab::maiChanged(const std::vector &setlc, int selspot) +{ + set_lc = setlc; + if (selspot < (int) set_lc.size()) { + const int spottype = set_lc.at(selspot).mainf; + const bool iscolor = set_lc.at(selspot).iscolo; + const bool issh = set_lc.at(selspot).iss; + const bool isvib = set_lc.at(selspot).isvi; + const bool isexpos = set_lc.at(selspot).isexpo; + const bool issoft = set_lc.at(selspot).issof; + const bool isblur = set_lc.at(selspot).isblu; + const bool istom = set_lc.at(selspot).isto; + const bool isret = set_lc.at(selspot).isre; + const bool issharp = set_lc.at(selspot).isshar; + const bool iscont = set_lc.at(selspot).iscon; + const bool iscbdl = set_lc.at(selspot).iscbd; + const bool islog = set_lc.at(selspot).islo; + const bool ismas = set_lc.at(selspot).isma; + const bool iscie = set_lc.at(selspot).isci; + + if(iscolor) { + expcolor.updateguicolor(spottype); + } + + if(issh) { + expshadhigh.updateguishad(spottype); + } + + if(isvib) { + expvibrance.updateguivib(spottype); + } + + if(isexpos) { + expexpose.updateguiexpos(spottype); + } + + if(issoft) { + expsoft.updateguisoft(spottype); + } + + if(isblur) { + expblur.updateguiblur(spottype); + } + + if(istom) { + exptonemap.updateguitone(spottype); + } + + if(isret) { + expreti.updateguireti(spottype); + } + + if(issharp) { + expsharp.updateguisharp(spottype); + } + + if(iscont) { + expcontrast.updateguicont(spottype); + } + + if(iscbdl) { + expcbdl.updateguicbdl(spottype); + } + + if(islog) { + explog.updateguilog(spottype); + } + + if(ismas) { + expmask.updateguimask(spottype); + } + + if(iscie) { + expcie.updateguicie(spottype); + } + + expsettings->updateguiset(spottype, iscolor, issh, isvib, isexpos, issoft, isblur, istom, isret, issharp, iscont, iscbdl, islog, ismas, iscie); + } +} + void Locallab::cieChanged(const std::vector &cielc, int selspot) { // Saving transmitted min/max data @@ -1231,6 +1442,30 @@ void Locallab::resetMaskVisibility() // Reset deltaE preview expsettings->resetDeltaEPreview(); + for (auto tool : std::initializer_list{ + &expcolor, + &expexpose, + &expshadhigh, + &expvibrance, + &expsoft, + &expblur, + &exptonemap, + &expreti, + &expsharp, + &expcontrast, + &expcbdl, + &explog, + &expmask, + &expcie, + }) { + auto button = tool->getPreviewDeltaEButton(); + auto connection = tool->getPreviewDeltaEButtonConnection(); + if (button && connection) { + connection->block(); + button->set_active(false); + connection->unblock(); + } + } // Reset mask preview for all Locallab tools for (auto tool : locallabTools) { @@ -1370,6 +1605,12 @@ void Locallab::resetToolMaskView() for (auto tool : locallabTools) { tool->resetMaskView(); } + + // Deactivate any preview delta E toggle button. + auto active_preview_button = delta_e_preview_button_group.getActiveButton(); + if (active_preview_button) { + active_preview_button->set_active(false); + } } void Locallab::resetOtherMaskView(LocallabTool* current) diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 1848e6481..0add444ac 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -25,6 +25,7 @@ #pragma once #include "controlspotpanel.h" +#include "guiutils.h" #include "locallabtools.h" /* ==== LocallabToolListListener ==== */ @@ -118,6 +119,8 @@ private: LocallabMask expmask; Locallabcie expcie; + OptionalRadioButtonGroup delta_e_preview_button_group; + std::vector locallabTools; // Locallab tools mask background management data @@ -131,6 +134,8 @@ private: std::vector cie_lc; + std::vector set_lc; + std::vector cie_sig; // Locallab tools mask background management data @@ -154,7 +159,16 @@ public: // Locallab Retinex tool min/man management function void minmaxChanged(const std::vector &minmax, int selspot) override; - + + // new functions for global - normal use +// void mainChanged(int spottype, int selspot, bool iscolor, bool issh, bool isvib, bool isexpos, bool issoft, bool isblur, bool istom, bool isret, bool issharp, bool iscont, bool iscbdl, bool islog, bool ismas, bool iscie)override; + void scopeChangedcol(int scope, int selspot, bool enab)override; + void scopeChangedsh(int scope, int selspot, bool enab)override; + void scopeChangedvib(int scope, int selspot, bool enab)override; + void scopeChangedset(int scope, int selspot, bool enab)override; + + void maiChanged(const std::vector &setlc, int selspot) override; + //Locallab denoise // Locallab Retinex tool min/man management function void denChanged(const std::vector &denlc, int selspot) override; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 7db035e0b..fd4ed22be 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -300,6 +300,16 @@ void LocallabTool::refChanged(const double huer, const double lumar, const doubl updateMaskBackground(normChromar, normLumar, normHuer, normHuerjz); } +Gtk::ToggleButton *LocallabTool::getPreviewDeltaEButton() const +{ + return nullptr; +} + +sigc::connection *LocallabTool::getPreviewDeltaEButtonConnection() +{ + return nullptr; +} + void LocallabTool::colorForValue(double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) { float R = 0.f; @@ -367,6 +377,8 @@ void LocallabTool::enableListener() } } + + bool LocallabTool::on_remove_change(GdkEventButton* event) { if (event->button == GDK_BUTTON_PRIMARY) { @@ -445,7 +457,9 @@ LocallabColor::LocallabColor(): labgrid(Gtk::manage(new LabGrid(EvLocallabLabGridValue, M("TP_LOCALLAB_LABGRID_VALUES"), true, false))), gridMethod(Gtk::manage(new MyComboBoxText())), strengthgrid(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRGRID"), 0, 100, 1, 30))), - sensi(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))), + sensi(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 30))), + previewcol(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), + structcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL1"), 0, 100, 1, 0))), blurcolde(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURDE"), 2, 100, 1, 5))), softradiuscol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 0.))), @@ -526,6 +540,8 @@ LocallabColor::LocallabColor(): LLmaskcolshapewav(static_cast(mask2CurveEditorGwav->addCurve(CT_Flat, "L(L)", nullptr, false, false))), csThresholdcol(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewcol = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWCOL"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -596,6 +612,11 @@ LocallabColor::LocallabColor(): setExpandAlignProperties(expcurvcol, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewcol->set_active(false); + previewcolConn = previewcol->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabColor::previewcolChanged)); + qualitycurveMethod->append(M("TP_LOCALLAB_CURVNONE")); qualitycurveMethod->append(M("TP_LOCALLAB_CURVCURR")); qualitycurveMethod->set_active(0); @@ -813,6 +834,9 @@ LocallabColor::LocallabColor(): // Add Color & Light specific widgets to GUI pack_start(*reparcol); + pack_start(*sensi); + pack_start(*previewcol); + pack_start(*invers); ToolParamBlock* const lumBox = Gtk::manage(new ToolParamBlock()); lumBox->pack_start(*lightness); @@ -833,7 +857,7 @@ LocallabColor::LocallabColor(): superBox->pack_start(*gridFrame); superFrame->add(*superBox); pack_start(*superFrame); - // pack_start(*sensi); + // pack_start(*sensi); pack_start(*structcol); pack_start(*blurcolde); pack_start(*softradiuscol); @@ -949,6 +973,22 @@ LocallabColor::~LocallabColor() delete mask2CurveEditorGwav; } +void LocallabColor::previewcolChanged() +{ + + if(previewcol->get_active()) { + showmaskcolMethod->set_active(5); + } else { + showmaskcolMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewcol,""); + } + } +} + void LocallabColor::setListener(ToolPanelListener* tpl) { LocallabTool::setListener(tpl); @@ -957,6 +997,64 @@ void LocallabColor::setListener(ToolPanelListener* tpl) labgridmerg->setListener(tpl); } +//new function Global +void LocallabColor::updateguicolor(int spottype) +{ + { + // Disable all listeners + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + invers->hide(); + sensi->hide(); + showmaskcolMethod->set_active(0); + previewcol->hide(); + previewcol->set_active(false); + resetMaskView(); + } else { + invers->show(); + sensi->show(); + if(!invers->get_active()) { + previewcol->show(); + } else { + previewcol->hide(); + } + + } + enableListener(); + + return false; + } + ); + } + +} + +//new function scope +void LocallabColor::updateguiscopecolor(int scope) +{ + { + idle_register.add( + [this, scope]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + disableListener(); + sensi->setValue(scope); + enableListener(); + + return false; + } + ); + } + +} + + bool LocallabColor::isMaskViewActive() { return ((showmaskcolMethod->get_active_row_number() != 0) || (showmaskcolMethodinv->get_active_row_number() != 0)); @@ -980,6 +1078,16 @@ void LocallabColor::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, colorMaskinv = showmaskcolMethodinv->get_active_row_number(); } +Gtk::ToggleButton *LocallabColor::getPreviewDeltaEButton() const +{ + return previewcol; +} + +sigc::connection *LocallabColor::getPreviewDeltaEButtonConnection() +{ + return &previewcolConn; +} + void LocallabColor::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -1550,7 +1658,7 @@ void LocallabColor::setDefaults(const rtengine::procparams::ProcParams* defParam void LocallabColor::adjusterChanged(Adjuster* a, double newval) { if (isLocActivated && exp->getEnabled()) { - if (a == lightness) { + if (a == lightness) { if (listener) { listener->panelChanged(Evlocallablightness, lightness->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); @@ -1595,7 +1703,7 @@ void LocallabColor::adjusterChanged(Adjuster* a, double newval) if (a == sensi) { if (listener) { listener->panelChanged(Evlocallabsensi, - sensi->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + sensi->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); } } @@ -2574,6 +2682,8 @@ LocallabExposure::LocallabExposure(): fatanchor(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 0.1, 100.0, 0.01, 50., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), gamex(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMC"), 0.5, 3.0, 0.05, 1.))), sensiex(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewexe(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), + structexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_STRUCCOL"), 0, 100, 1, 0))), blurexpde(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURDE"), 2, 100, 1, 5))), exptoolexp(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPTOOL")))), @@ -2625,6 +2735,8 @@ LocallabExposure::LocallabExposure(): set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewexe = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWEXE"); // Parameter Exposure specific widgets expMethod->append(M("TP_LOCALLAB_STD")); @@ -2706,6 +2818,12 @@ LocallabExposure::LocallabExposure(): lowthrese->setAdjusterListener(this); higthrese->setAdjusterListener(this); decaye->setAdjusterListener(this); + + previewexe->set_active(false); + previewexeConn = previewexe->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabExposure::previewexeChanged)); + setExpandAlignProperties(exprecove, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); normConn = norm->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::normChanged)); fatsaturConn = fatsatur->signal_toggled().connect(sigc::mem_fun(*this, &LocallabExposure::fatsaturChanged)); @@ -2781,6 +2899,7 @@ LocallabExposure::LocallabExposure(): // Add Color & Light specific widgets to GUI pack_start(*sensiex); + pack_start(*previewexe); pack_start(*reparexp); pack_start(*inversex); ToolParamBlock* const pdeBox = Gtk::manage(new ToolParamBlock()); @@ -2873,6 +2992,60 @@ bool LocallabExposure::isMaskViewActive() return ((showmaskexpMethod->get_active_row_number() != 0) || (showmaskexpMethodinv->get_active_row_number() != 0)); } +//new function Global +void LocallabExposure::updateguiexpos(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + inversex->hide(); + sensiex->hide(); + previewexe->hide(); + showmaskexpMethod->set_active(0); + previewexe->set_active(false); + + resetMaskView(); + } else { + inversex->show(); + sensiex->show(); + if(!inversex->get_active()) { + previewexe->show(); + } else { + previewexe->hide(); + } + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabExposure::previewexeChanged() +{ + + if(previewexe->get_active()) { + showmaskexpMethod->set_active(5); + } else { + showmaskexpMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewexe,""); + } + } +} + + void LocallabExposure::resetMaskView() { showmaskexpMethodConn.block(true); @@ -2891,6 +3064,16 @@ void LocallabExposure::getMaskView(int &colorMask, int &colorMaskinv, int &expMa expMaskinv = showmaskexpMethodinv->get_active_row_number(); } +Gtk::ToggleButton *LocallabExposure::getPreviewDeltaEButton() const +{ + return previewexe; +} + +sigc::connection *LocallabExposure::getPreviewDeltaEButtonConnection() +{ + return &previewexeConn; +} + void LocallabExposure::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -3616,6 +3799,7 @@ void LocallabExposure::convertParamToSimple() softradiusexp->setValue(defSpot.softradiusexp); enaExpMask->set_active(defSpot.enaExpMask); enaExpMaskaft->set_active(defSpot.enaExpMaskaft); + showmaskexpMethod->set_active(0); gamex->setValue(defSpot.gamex); // CCmaskexpshape->setCurve(defSpot.CCmaskexpcurve); // LLmaskexpshape->setCurve(defSpot.CCmaskexpcurve); @@ -4040,7 +4224,8 @@ LocallabShadow::LocallabShadow(): shadows(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0))), s_tonalwidth(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 30))), sh_radius(Gtk::manage(new Adjuster(M("TP_SHADOWSHLIGHTS_RADIUS"), 0, 100, 1, 40))), - sensihs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt + sensihs(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 30))),//reused - unused here, but used for normalize_mean_dt + previewsh(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), blurSHde(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLURDE"), 2, 100, 1, 5))), exprecovs(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusables(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), @@ -4078,6 +4263,9 @@ LocallabShadow::LocallabShadow(): fatanchorSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FATANCHOR"), 1., 100., 1., 50., Gtk::manage(new RTImage("circle-black-small")), Gtk::manage(new RTImage("circle-white-small"))))), EvlocallabTePivot(ProcEventMapper::getInstance()->newEvent(AUTOEXP, "HISTORY_MSG_LOCALLAB_TE_PIVOT")) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewsh = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWSH"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -4134,6 +4322,11 @@ LocallabShadow::LocallabShadow(): setExpandAlignProperties(expmasksh, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewsh->set_active(false); + previewshConn = previewsh->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabShadow::previewshChanged)); + showmaskSHMethod->append(M("TP_LOCALLAB_SHOWMNONE")); showmaskSHMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskSHMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); @@ -4196,6 +4389,9 @@ LocallabShadow::LocallabShadow(): // Add Shadow highlight specific widgets to GUI pack_start(*reparsh); + pack_start(*sensihs);// reused / unused here, but used for normalize_mean_dt + pack_start(*previewsh); + pack_start(*inverssh); pack_start(*shMethod); @@ -4210,7 +4406,7 @@ LocallabShadow::LocallabShadow(): pack_start(*shadows); pack_start(*s_tonalwidth); pack_start(*sh_radius); - // pack_start(*sensihs);//unused here, but used for normalize_mean_dt +// pack_start(*sensihs);// reused / unused here, but used for normalize_mean_dt pack_start(*blurSHde); ToolParamBlock* const shBox3 = Gtk::manage(new ToolParamBlock()); shBox3->pack_start(*maskusables, Gtk::PACK_SHRINK, 0); @@ -4278,6 +4474,90 @@ void LocallabShadow::resetMaskView() showmaskSHMethodConninv.block(false); } +Gtk::ToggleButton *LocallabShadow::getPreviewDeltaEButton() const +{ + return previewsh; +} + +sigc::connection *LocallabShadow::getPreviewDeltaEButtonConnection() +{ + return &previewshConn; +} + +void LocallabShadow::previewshChanged() +{ + + if(previewsh->get_active()) { + showmaskSHMethod->set_active(4); + } else { + showmaskSHMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewsh,""); + } + } +} + + +//new function Global +void LocallabShadow::updateguishad(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + inverssh->hide(); + sensihs->hide(); + showmaskSHMethod->set_active(0); + previewsh->hide(); + previewsh->set_active(false); + resetMaskView(); + } else { + sensihs->show(); + inverssh->show(); + if(!inverssh->get_active()) { + previewsh->show(); + } else { + previewsh->hide(); + } + + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabShadow::updateguiscopesahd(int scope) +{ + { + idle_register.add( + [this, scope]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + disableListener(); + sensihs->setValue(scope); + + enableListener(); + return false; + } + ); + } + +} + + + void LocallabShadow::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) { shMask = showmaskSHMethod->get_active_row_number(); @@ -5154,7 +5434,8 @@ LocallabVibrance::LocallabVibrance(): protectSkins(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PROTECTSKINS")))), avoidColorShift(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_AVOIDCOLORSHIFT")))), pastSatTog(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PASTSATTOG")))), - sensiv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 15))),//unused here, but used for normalize_mean_dt + sensiv(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 30))),//reused - unused here, but used for normalize_mean_dt + previewvib(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), curveEditorGG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL"))), skinTonesCurve(static_cast(curveEditorGG->addCurve(CT_Diagonal, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES")))), exprecovv(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), @@ -5186,6 +5467,9 @@ LocallabVibrance::LocallabVibrance(): mask2vibCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), Lmaskvibshape(static_cast(mask2vibCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewvib = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWVIB"); + set_orientation(Gtk::ORIENTATION_VERTICAL); float R, G, B; @@ -5250,6 +5534,11 @@ LocallabVibrance::LocallabVibrance(): angvib->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); angvib->setAdjusterListener(this); + previewvib->set_active(false); + previewvibConn = previewvib->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabVibrance::previewvibChanged)); + setExpandAlignProperties(expmaskvib, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); showmaskvibMethod->append(M("TP_LOCALLAB_SHOWMNONE")); @@ -5301,6 +5590,8 @@ LocallabVibrance::LocallabVibrance(): mask2vibCurveEditorG->curveListComplete(); // Add Vibrance specific widgets to GUI + pack_start(*sensiv, Gtk::PACK_SHRINK, 0);//reused - nused here, but used for normalize_mean_dt + pack_start(*previewvib, Gtk::PACK_SHRINK, 0); pack_start(*saturated, Gtk::PACK_SHRINK, 0); pack_start(*pastels, Gtk::PACK_SHRINK, 0); pack_start(*vibgam, Gtk::PACK_SHRINK, 0); @@ -5311,7 +5602,7 @@ LocallabVibrance::LocallabVibrance(): pack_start(*protectSkins, Gtk::PACK_SHRINK, 0); pack_start(*avoidColorShift, Gtk::PACK_SHRINK, 0); pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0); - // pack_start(*sensiv, Gtk::PACK_SHRINK, 0);//unused here, but used for normalize_mean_dt +// pack_start(*sensiv, Gtk::PACK_SHRINK, 0);//reused - nused here, but used for normalize_mean_dt pack_start(*curveEditorGG, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor ToolParamBlock* const vibBox3 = Gtk::manage(new ToolParamBlock()); vibBox3->pack_start(*maskusablev, Gtk::PACK_SHRINK, 0); @@ -5365,6 +5656,81 @@ void LocallabVibrance::resetMaskView() showmaskvibMethodConn.block(false); } +Gtk::ToggleButton *LocallabVibrance::getPreviewDeltaEButton() const +{ + return previewvib; +} + +sigc::connection *LocallabVibrance::getPreviewDeltaEButtonConnection() +{ + return &previewvibConn; +} + +//new function Global +void LocallabVibrance::updateguivib(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensiv->hide(); + showmaskvibMethod->set_active(0); + previewvib->hide(); + previewvib->set_active(false); + resetMaskView(); + } else { + sensiv->show(); + previewvib->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabVibrance::previewvibChanged() +{ + + if(previewvib->get_active()) { + showmaskvibMethod->set_active(4); + } else { + showmaskvibMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewvib,""); + } + } +} + +//new function scope +void LocallabVibrance::updateguiscopevib(int scope) +{ + { + idle_register.add( + [this, scope]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + disableListener(); + sensiv->setValue(scope); + enableListener(); + + return false; + } + ); + } + +} + void LocallabVibrance::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) { vibMask = showmaskvibMethod->get_active_row_number(); @@ -6188,6 +6554,32 @@ void LocallabSoft::resetMaskView() showmasksoftMethodConn.block(false); } +//new function Global +void LocallabSoft::updateguisoft(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensisf->hide(); + } else { + sensisf->show(); + } + enableListener(); + + return false; + } + ); + } + +} + + void LocallabSoft::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) { softMask = showmasksoftMethod->get_active_row_number(); @@ -7062,6 +7454,39 @@ void LocallabBlur::resetMaskView() showmaskblMethodConn.block(false); } +//new function Global +void LocallabBlur::updateguiblur(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensibn->hide(); + sensiden->hide(); + invbl->hide(); + + } else { + sensibn->show(); + sensiden->show(); + invbl->show(); + + } + enableListener(); + + return false; + } + ); + } + +} + + + void LocallabBlur::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) { blMask = showmaskblMethod->get_active_row_number(); diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 1d43b6ef1..17f9bd5cb 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -55,6 +55,15 @@ protected: Normal = 1, Simple = 2 }; + rtengine::ProcEvent Evlocallabpreviewcol; + rtengine::ProcEvent Evlocallabpreviewexe; + rtengine::ProcEvent Evlocallabpreviewsh; + rtengine::ProcEvent Evlocallabpreviewvib; + rtengine::ProcEvent Evlocallabpreviewtm; + rtengine::ProcEvent Evlocallabpreviewlc; + rtengine::ProcEvent Evlocallabpreviewlog; + rtengine::ProcEvent Evlocallabpreviewcie; + rtengine::ProcEvent Evlocallabpreviewmas; rtengine::ProcEvent Evlocallabnormcie; rtengine::ProcEvent Evlocallabstrumaskcie; rtengine::ProcEvent EvLocallabtoolcie; @@ -186,6 +195,9 @@ public: virtual void resetMaskView() {}; virtual void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) {}; + virtual Gtk::ToggleButton *getPreviewDeltaEButton() const; + virtual sigc::connection *getPreviewDeltaEButtonConnection(); + // Advice tooltips management function virtual void updateAdviceTooltips(const bool showTooltips) {}; @@ -248,6 +260,8 @@ private: MyComboBoxText* const gridMethod; Adjuster* const strengthgrid; Adjuster* const sensi; + Gtk::ToggleButton* const previewcol; + Adjuster* const structcol; Adjuster* const blurcolde; Adjuster* const softradiuscol; @@ -326,18 +340,20 @@ private: FlatCurveEditor* const LLmaskcolshapewav; ThresholdAdjuster* const csThresholdcol; - sigc::connection curvactivConn, gridMethodConn, inversConn, qualitycurveMethodConn, toneMethodConn, specialConn, merMethodConn, mergecolMethodConn, showmaskcolMethodConn, showmaskcolMethodConninv, enaColorMaskConn, toolcolConn, fftColorMaskConn; + sigc::connection curvactivConn, previewcolConn, gridMethodConn, inversConn, qualitycurveMethodConn, toneMethodConn, specialConn, merMethodConn, mergecolMethodConn, showmaskcolMethodConn, showmaskcolMethodConninv, enaColorMaskConn, toolcolConn, fftColorMaskConn; public: LocallabColor(); ~LocallabColor(); void setListener(ToolPanelListener* tpl) override; - bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; void setDefaultExpanderVisibility() override; @@ -354,6 +370,9 @@ public: void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) override {}; // Not used void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; void curveChanged(CurveEditor* ce) override; + void updateguicolor(int spottype); + void updateguiscopecolor(int scope); + void previewcolChanged(); private: void enabledChanged() override; @@ -362,7 +381,6 @@ private: void updateGUIToMode(const modeType new_type) override; void updateMaskBackground(const double normChromar, const double normLumar, const double normHuer, const double normHuerjz) override; - void curvactivChanged(); void gridMethodChanged(); void inversChanged(); @@ -376,7 +394,6 @@ private: void enaColorMaskChanged(); void toolcolChanged(); void fftColorMaskChanged(); - void updateColorGUI1(); void updateColorGUI2(); void updateColorGUI3(); @@ -409,6 +426,8 @@ private: Adjuster* const fatanchor; Adjuster* const gamex; Adjuster* const sensiex; + Gtk::ToggleButton* const previewexe; + Adjuster* const structexp; Adjuster* const blurexpde; MyExpander* const exptoolexp; @@ -456,7 +475,7 @@ private: DiagonalCurveEditor* const Lmaskexpshape; rtengine::ProcEvent Evlocallabtmosatur; - sigc::connection expMethodConn, exnoiseMethodConn, inversexConn, normConn, fatsaturConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; + sigc::connection expMethodConn, exnoiseMethodConn, previewexeConn, inversexConn, normConn, fatsaturConn, showmaskexpMethodConn, showmaskexpMethodConninv, enaExpMaskConn, enaExpMaskaftConn; public: LocallabExposure(); @@ -466,6 +485,9 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; void setDefaultExpanderVisibility() override; @@ -476,6 +498,8 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; void curveChanged(CurveEditor* ce) override; + void updateguiexpos(int spottype); + void previewexeChanged(); private: void enabledChanged() override; @@ -519,6 +543,8 @@ private: Adjuster* const s_tonalwidth; Adjuster* const sh_radius; Adjuster* const sensihs; + Gtk::ToggleButton* const previewsh; + Adjuster* const blurSHde; MyExpander* const exprecovs; Gtk::Label* const maskusables; @@ -556,7 +582,7 @@ private: rtengine::ProcEvent EvlocallabTePivot; - sigc::connection shMethodConn, inversshConn, showmaskSHMethodConn, showmaskSHMethodConninv, enaSHMaskConn; + sigc::connection shMethodConn, previewshConn, inversshConn, showmaskSHMethodConn, showmaskSHMethodConninv, enaSHMaskConn; public: LocallabShadow(); @@ -566,8 +592,13 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; - void updateAdviceTooltips(const bool showTooltips) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; + void updateguishad(int spottype); + void updateguiscopesahd(int scope); + void setDefaultExpanderVisibility() override; void disableListener() override; void enableListener() override; @@ -576,6 +607,7 @@ public: void setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = nullptr) override; void adjusterChanged(Adjuster* a, double newval) override; void curveChanged(CurveEditor* ce) override; + void previewshChanged(); private: void enabledChanged() override; @@ -613,6 +645,8 @@ private: Gtk::CheckButton* const avoidColorShift; Gtk::CheckButton* const pastSatTog; Adjuster* const sensiv; + Gtk::ToggleButton* const previewvib; + CurveEditorGroup* const curveEditorGG; DiagonalCurveEditor* const skinTonesCurve; MyExpander* const exprecovv; @@ -643,7 +677,7 @@ private: CurveEditorGroup* const mask2vibCurveEditorG; DiagonalCurveEditor* const Lmaskvibshape; - sigc::connection pskinsConn, ashiftConn, pastsattogConn, showmaskvibMethodConn, enavibMaskConn; + sigc::connection pskinsConn, previewvibConn, ashiftConn, pastsattogConn, showmaskvibMethodConn, enavibMaskConn; public: LocallabVibrance(); @@ -653,7 +687,12 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; + void updateguivib(int spottype); + void updateguiscopevib(int scope); void setDefaultExpanderVisibility() override; void disableListener() override; @@ -670,6 +709,7 @@ public: void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override {}; // Not used std::vector getCurvePoints(ThresholdSelector* tAdjuster) const override; void curveChanged(CurveEditor* ce) override; + void previewvibChanged(); private: void enabledChanged() override; @@ -712,6 +752,7 @@ public: void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; void updateAdviceTooltips(const bool showTooltips) override; + void updateguisoft(int spottype); void disableListener() override; void enableListener() override; @@ -765,6 +806,7 @@ private: Adjuster* const lowthres; Adjuster* const higthres; Adjuster* const sensibn; + MyComboBoxText* const blurMethod; Gtk::CheckButton* const invbl; MyComboBoxText* const chroMethod; @@ -827,6 +869,7 @@ private: Adjuster* const nlgam; Adjuster* const bilateral; Adjuster* const sensiden; + Adjuster* const reparden; Gtk::Button* neutral; MyExpander* const expmaskbl; @@ -863,13 +906,13 @@ public: ~LocallabBlur(); void updatedenlc(const double highres, const double nres, const double highres46, const double nres46, const double Lhighres, const double Lnres, const double Lhighres46, const double Lnres46); - bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; void updateAdviceTooltips(const bool showTooltips) override; void neutral_pressed(); + void updateguiblur(int spottype); void setDefaultExpanderVisibility() override; void disableListener() override; @@ -931,6 +974,8 @@ private: Adjuster* const rewei; Adjuster* const softradiustm; Adjuster* const sensitm; + Gtk::ToggleButton* const previewtm; + MyExpander* const exprecovt; Gtk::Label* const maskusablet; Gtk::Label* const maskunusablet; @@ -955,7 +1000,7 @@ private: CurveEditorGroup* const mask2tmCurveEditorG; DiagonalCurveEditor* const Lmasktmshape; - sigc::connection equiltmConn, showmasktmMethodConn, enatmMaskConn, enatmMaskaftConn; + sigc::connection equiltmConn, previewtmConn, showmasktmMethodConn, enatmMaskConn, enatmMaskaftConn; public: LocallabTone(); @@ -965,8 +1010,12 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; - void updateAdviceTooltips(const bool showTooltips) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; + void updateguitone(int spottype); + void previewtmChanged(); void setDefaultExpanderVisibility() override; void disableListener() override; void enableListener() override; @@ -1062,6 +1111,7 @@ public: ~LocallabRetinex(); void updateMinMax(const double cdma, const double cdmin, const double mini, const double maxi, const double Tmean, const double Tsigma, const double Tmin, const double Tmax); + void updateguireti(int spottype); bool isMaskViewActive() override; void resetMaskView() override; @@ -1128,6 +1178,7 @@ public: void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; void updateAdviceTooltips(const bool showTooltips) override; + void updateguisharp(int spottype); void disableListener() override; void enableListener() override; @@ -1176,6 +1227,8 @@ private: Adjuster* const residgam; Adjuster* const residslop; Adjuster* const sensilc; + Gtk::ToggleButton* const previewlc; + Adjuster* const reparw; Gtk::Frame* const clariFrame; Adjuster* const clarilres; @@ -1251,7 +1304,7 @@ private: CurveEditorGroup* const mask2lcCurveEditorG; DiagonalCurveEditor* const Lmasklcshape; - sigc::connection localcontMethodConn, origlcConn, wavgradlConn, wavedgConn, localedgMethodConn, waveshowConn, localneiMethodConn, wavblurConn, blurlcConn, wavcontConn, wavcompreConn, wavcompConn, fftwlcConn, showmasklcMethodConn, enalcMaskConn; + sigc::connection localcontMethodConn, previewlcConn, origlcConn, wavgradlConn, wavedgConn, localedgMethodConn, waveshowConn, localneiMethodConn, wavblurConn, blurlcConn, wavcontConn, wavcompreConn, wavcompConn, fftwlcConn, showmasklcMethodConn, enalcMaskConn; public: LocallabContrast(); @@ -1261,8 +1314,11 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; - void updateAdviceTooltips(const bool showTooltips) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; + void updateguicont(int spottype); void setDefaultExpanderVisibility() override; void disableListener() override; void enableListener() override; @@ -1277,6 +1333,7 @@ public: void adjusterChanged(ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) override {}; // Not used void adjusterChanged2(ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) override; void curveChanged(CurveEditor* ce) override; + void previewlcChanged(); private: void enabledChanged() override; @@ -1361,6 +1418,7 @@ public: void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; void updateAdviceTooltips(const bool showTooltips) override; + void updateguicbdl(int spottype); void setDefaultExpanderVisibility() override; void disableListener() override; @@ -1443,6 +1501,8 @@ private: Adjuster* const decayl; Adjuster* const sensilog; + Gtk::ToggleButton* const previewlog; + Gtk::Frame* const gradlogFrame; Adjuster* const strlog; Adjuster* const anglog; @@ -1461,7 +1521,7 @@ private: sigc::connection autoconn, ciecamconn, fullimageConn, AutograyConn; sigc::connection surroundconn, sursourconn, satlogconn; - sigc::connection showmaskLMethodConn, enaLMaskConn; + sigc::connection showmaskLMethodConn, enaLMaskConn, previewlogConn; public: LocallabLog(); ~LocallabLog(); @@ -1469,6 +1529,11 @@ public: bool isMaskViewActive() override; void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + void updateguilog(int spottype); + void previewlogChanged(); + + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; void updateAdviceTooltips(const bool showTooltips) override; void surroundChanged(); @@ -1514,6 +1579,8 @@ class LocallabMask: { private: Adjuster* const sensimask; + Gtk::ToggleButton* const previewmas; + Adjuster* const blendmask; Adjuster* const blendmaskab; Adjuster* const softradiusmask; @@ -1548,7 +1615,7 @@ private: Adjuster* const str_mask; Adjuster* const ang_mask; - sigc::connection showmask_MethodConn, enamaskConn, toolmaskConn, fftmaskConn; + sigc::connection showmask_MethodConn, previewmasConn, enamaskConn, toolmaskConn, fftmaskConn; public: LocallabMask(); @@ -1558,7 +1625,12 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; + void updateguimask(int spottype); + void previewmasChanged(); void disableListener() override; void enableListener() override; @@ -1601,6 +1673,8 @@ class Locallabcie: { private: Adjuster* const sensicie; + Gtk::ToggleButton* const previewcie; + Adjuster* const reparcie; Gtk::CheckButton* const jabcie; MyComboBoxText* const modecam; @@ -1838,6 +1912,7 @@ private: int nextcomprciecount = 0; sigc::connection AutograycieConn, primMethodconn, illMethodconn, smoothciemetconn, catMethodconn, forcejzConn, forcebwConn, qtojConn, showmaskcieMethodConn, enacieMaskConn, enacieMaskallConn, jabcieConn, sursourcieconn, surroundcieconn, modecieconn, modecamconn, comprcieautoconn, normcieconn, logcieconn, satcieconn, logcieqconn,smoothcieconn, smoothcieybconn,smoothcielumconn, logjzconn, sigjzconn, sigqconn, chjzcieconn, toneMethodcieConn, toneMethodcieConn2, toolcieConn, bwevMethodConn, fftcieMaskConn, gamutcieconn, bwcieconn, expprecamconn, sigcieconn; + sigc::connection previewcieConn, sigmoidqjcieconn; public: Locallabcie(); ~Locallabcie(); @@ -1848,9 +1923,13 @@ public: void resetMaskView() override; void getMaskView(int &colorMask, int &colorMaskinv, int &expMask, int &expMaskinv, int &shMask, int &shMaskinv, int &vibMask, int &softMask, int &blMask, int &tmMask, int &retiMask, int &sharMask, int &lcMask, int &cbMask, int &logMask, int &maskMask, int &cieMask) override; + Gtk::ToggleButton *getPreviewDeltaEButton() const override; + sigc::connection *getPreviewDeltaEButtonConnection() override; + void updateAdviceTooltips(const bool showTooltips) override; void setDefaultExpanderVisibility() override; - + void updateguicie(int spottype); + void previewcieChanged(); void disableListener() override; void enableListener() override; void read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = nullptr) override; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index 17b5d3ead..af09224b5 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -132,6 +132,7 @@ LocallabTone::LocallabTone(): rewei(Gtk::manage(new Adjuster(M("TP_LOCALLAB_REWEI"), 0, 3, 1, 0))), softradiustm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.1, 0.))),//unused here, but used for normalize_mean_dt sensitm(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewtm(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), exprecovt(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusablet(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), maskunusablet(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), @@ -157,6 +158,9 @@ LocallabTone::LocallabTone(): mask2tmCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), Lmasktmshape(static_cast(mask2tmCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewtm = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWTM"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -191,6 +195,11 @@ LocallabTone::LocallabTone(): decayt->setAdjusterListener(this); setExpandAlignProperties(exprecovt, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewtm->set_active(false); + previewtmConn = previewtm->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabTone::previewtmChanged)); + setExpandAlignProperties(expmasktm, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); showmasktmMethod->append(M("TP_LOCALLAB_SHOWMNONE")); @@ -246,6 +255,7 @@ LocallabTone::LocallabTone(): // Add Tone Mapping specific widgets to GUI // pack_start(*amount); // To use if we change transit_shapedetect parameters pack_start(*sensitm); + pack_start(*previewtm); pack_start(*repartm); pack_start(*separatortm); pack_start(*stren); @@ -307,6 +317,16 @@ void LocallabTone::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, tmMask = showmasktmMethod->get_active_row_number(); } +Gtk::ToggleButton *LocallabTone::getPreviewDeltaEButton() const +{ + return previewtm; +} + +sigc::connection *LocallabTone::getPreviewDeltaEButtonConnection() +{ + return &previewtmConn; +} + void LocallabTone::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -395,6 +415,58 @@ void LocallabTone::enableListener() enatmMaskaftConn.block(false); } +//new function Global +void LocallabTone::updateguitone(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensitm->hide(); + // showmasktmMethodConn.block(true); + showmasktmMethod->set_active(0); + // showmasktmMethodConn.block(false); + previewtm->hide(); + // previewtmConn.block(true); + previewtm->set_active(false); + // previewtmConn.block(false); + resetMaskView(); + } else { + sensitm->show(); + previewtm->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabTone::previewtmChanged() +{ + // showmasktmMethodConn.block(true); + + if(previewtm->get_active()) { + showmasktmMethod->set_active(4); + } else { + showmasktmMethod->set_active(0); + } + // showmasktmMethodConn.block(false); + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewtm,""); + } + } +} + void LocallabTone::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { // Disable all listeners @@ -945,7 +1017,7 @@ LocallabRetinex::LocallabRetinex(): showmaskretiMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskretiMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); showmaskretiMethod->append(M("TP_LOCALLAB_SHOWMASK")); - showmaskretiMethod->append(M("TP_LOCALLAB_SHOWREF")); + // showmaskretiMethod->append(M("TP_LOCALLAB_SHOWREF")); showmaskretiMethod->set_active(0); showmaskretiMethod->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKCOL_TOOLTIP")); showmaskretiMethodConn = showmaskretiMethod->signal_changed().connect(sigc::mem_fun(*this, &LocallabRetinex::showmaskretiMethodChanged)); @@ -1103,6 +1175,32 @@ void LocallabRetinex::updateMinMax(const double cdma, const double cdmin, const ); } +//new function Global +void LocallabRetinex::updateguireti(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensih->hide(); + } else { + sensih->show(); + } + enableListener(); + + return false; + } + ); + } + +} + + bool LocallabRetinex::isMaskViewActive() { return (showmaskretiMethod->get_active_row_number() != 0); @@ -2109,6 +2207,33 @@ void LocallabSharp::enableListener() showmasksharMethodConn.block(false); } +//new function Global +void LocallabSharp::updateguisharp(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensisha->hide(); + inverssha->hide(); + } else { + sensisha->show(); + inverssha->show(); + } + enableListener(); + + return false; + } + ); + } + +} + void LocallabSharp::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { // Disable all listeners @@ -2397,6 +2522,7 @@ LocallabContrast::LocallabContrast(): residgam(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GAMSH"), 0.25, 15.0, 0.01, 2.4))), residslop(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SLOSH"), 0.0, 500.0, 0.01, 12.92))), sensilc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewlc(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), reparw(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), clariFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_CLARIFRA")))), clarilres(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CLARILRES"), -20., 100., 0.5, 0.))), @@ -2474,6 +2600,9 @@ LocallabContrast::LocallabContrast(): mask2lcCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK2"))), Lmasklcshape(static_cast(mask2lcCurveEditorG->addCurve(CT_Diagonal, "L(L)"))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewlc = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWLC"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -2720,6 +2849,11 @@ LocallabContrast::LocallabContrast(): setExpandAlignProperties(expmasklc, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewlc->set_active(false); + previewlcConn = previewlc->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabContrast::previewlcChanged)); + showmasklcMethod->append(M("TP_LOCALLAB_SHOWMNONE")); showmasklcMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmasklcMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); @@ -2764,6 +2898,7 @@ LocallabContrast::LocallabContrast(): // Add Local contrast specific widgets to GUI pack_start(*sensilc); + pack_start(*previewlc); pack_start(*reparw); pack_start(*localcontMethod); pack_start(*lcradius); @@ -2957,6 +3092,62 @@ void LocallabContrast::getMaskView(int &colorMask, int &colorMaskinv, int &expMa lcMask = showmasklcMethod->get_active_row_number(); } +Gtk::ToggleButton *LocallabContrast::getPreviewDeltaEButton() const +{ + return previewlc; +} + +sigc::connection *LocallabContrast::getPreviewDeltaEButtonConnection() +{ + return &previewlcConn; +} + +//new function Global +void LocallabContrast::updateguicont(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensilc->hide(); + showmasklcMethod->set_active(0); + previewlc->hide(); + previewlc->set_active(false); + resetMaskView(); + + } else { + sensilc->show(); + previewlc->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabContrast::previewlcChanged() +{ + if(previewlc->get_active()) { + showmasklcMethod->set_active(4); + } else { + showmasklcMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewlc,""); + } + } +} + void LocallabContrast::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -4532,7 +4723,7 @@ lumacontrastPlusButton(Gtk::manage(new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACON showmaskcbMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskcbMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); showmaskcbMethod->append(M("TP_LOCALLAB_SHOWMASK")); - showmaskcbMethod->append(M("TP_LOCALLAB_SHOWREF")); +// showmaskcbMethod->append(M("TP_LOCALLAB_SHOWREF")); showmaskcbMethod->set_active(0); showmaskcbMethod->set_tooltip_markup(M("TP_LOCALLAB_SHOWMASKCOL_TOOLTIP")); showmaskcbMethodConn = showmaskcbMethod->signal_changed().connect(sigc::mem_fun(*this, &LocallabCBDL::showmaskcbMethodChanged)); @@ -4662,6 +4853,32 @@ void LocallabCBDL::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, cbMask = showmaskcbMethod->get_active_row_number(); } +//new function Global +void LocallabCBDL::updateguicbdl(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensicb->hide(); + } else { + sensicb->show(); + } + enableListener(); + + return false; + } + ); + } + +} + + void LocallabCBDL::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -5295,6 +5512,7 @@ LocallabLog::LocallabLog(): decayl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKDDECAY"), 0.5, 4., 0.1, 2.))), sensilog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewlog(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), gradlogFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA")))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), anglog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), @@ -5315,6 +5533,7 @@ LocallabLog::LocallabLog(): { auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWLOG"); Evlocallabwhiteslog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_WHITES"); Evlocallabblackslog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_BLACKS"); Evlocallabcomprlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_COMPR"); @@ -5429,6 +5648,11 @@ LocallabLog::LocallabLog(): setExpandAlignProperties(expmaskL, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewlog->set_active(false); + previewlogConn = previewlog->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabLog::previewlogChanged)); + showmaskLMethod->append(M("TP_LOCALLAB_SHOWMNONE")); showmaskLMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskLMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); @@ -5472,6 +5696,8 @@ LocallabLog::LocallabLog(): // Add Log encoding specific widgets to GUI pack_start(*sensilog); + pack_start(*previewlog); + pack_start(*repar); pack_start(*ciecam); logPFrame->set_label_align(0.025, 0.5); @@ -5582,6 +5808,54 @@ void LocallabLog::setDefaultExpanderVisibility() } +//new function Global +void LocallabLog::updateguilog(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensilog->hide(); + showmaskLMethod->set_active(0); + previewlog->hide(); + previewlog->set_active(false); + resetMaskView(); + + } else { + sensilog->show(); + previewlog->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabLog::previewlogChanged() +{ + + if(previewlog->get_active()) { + showmaskLMethod->set_active(4); + } else { + showmaskLMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewlog,""); + } + } +} + + void LocallabLog::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -5738,6 +6012,16 @@ void LocallabLog::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, i logMask = showmaskLMethod->get_active_row_number(); } +Gtk::ToggleButton *LocallabLog::getPreviewDeltaEButton() const +{ + return previewlog; +} + +sigc::connection *LocallabLog::getPreviewDeltaEButtonConnection() +{ + return &previewlogConn; +} + void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) { @@ -5977,6 +6261,7 @@ void LocallabLog::updateGUIToMode(const modeType new_type) maskusablel->hide(); maskunusablel->hide(); decayl->hide(); + break; case Normal: @@ -6070,6 +6355,7 @@ void LocallabLog::convertParamToSimple() strlog->setValue(defSpot.strlog); anglog->setValue(defSpot.anglog); enaLMask->set_active(false); + showmaskLMethod->set_active(0); recothresl->setValue(defSpot.recothresl); lowthresl->setValue(defSpot.lowthresl); higthresl->setValue(defSpot.higthresl); @@ -6691,6 +6977,7 @@ LocallabMask::LocallabMask(): // Common mask specific widgets sensimask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewmas(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), blendmask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKMASK"), -100., 100., 0.1, -10.))), blendmaskab(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKMASKAB"), -100., 100., 0.1, -10.))), softradiusmask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 1.))), @@ -6727,6 +7014,9 @@ LocallabMask::LocallabMask(): ang_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180., 180., 0.1, 0.))) { + auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewmas = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWMAS"); + set_orientation(Gtk::ORIENTATION_VERTICAL); const LocallabParams::LocallabSpot defSpot; @@ -6742,6 +7032,11 @@ LocallabMask::LocallabMask(): softradiusmask->setAdjusterListener(this); + previewmas->set_active(false); + previewmasConn = previewmas->signal_clicked().connect( + sigc::mem_fun( + *this, &LocallabMask::previewmasChanged)); + showmask_Method->append(M("TP_LOCALLAB_SHOWMNONE")); showmask_Method->append(M("TP_LOCALLAB_SHOWMODIFMASK")); showmask_Method->append(M("TP_LOCALLAB_SHOWMASK")); @@ -6833,6 +7128,7 @@ LocallabMask::LocallabMask(): // Add Common mask specific widgets to GUI pack_start(*sensimask); + pack_start(*previewmas); pack_start(*blendmask); pack_start(*blendmaskab); pack_start(*softradiusmask); @@ -6895,6 +7191,64 @@ void LocallabMask::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, maskMask = showmask_Method->get_active_row_number(); } +Gtk::ToggleButton *LocallabMask::getPreviewDeltaEButton() const +{ + return previewmas; +} + +sigc::connection *LocallabMask::getPreviewDeltaEButtonConnection() +{ + return &previewmasConn; +} + +//new function Global +void LocallabMask::updateguimask(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensimask->hide(); + showmask_Method->set_active(0); + previewmas->hide(); + previewmas->set_active(false); + resetMaskView(); + + } else { + sensimask->show(); + previewmas->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void LocallabMask::previewmasChanged() +{ + + if(previewmas->get_active()) { + showmask_Method->set_active(3); + } else { + showmask_Method->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewmas,""); + } + } +} + + void LocallabMask::updateAdviceTooltips(const bool showTooltips) { if (showTooltips) { @@ -7365,6 +7719,7 @@ void LocallabMask::convertParamToSimple() // Set hidden specific GUI widgets in Simple mode to default spot values gammask->setValue(defSpot.gammask); slopmask->setValue(defSpot.slopmask); + //Lmask_shape->setCurve(defSpot.Lmask_curve); // Enable all listeners @@ -7525,6 +7880,8 @@ Locallabcie::Locallabcie(): LocallabTool(this, M("TP_LOCALLAB_CIE_TOOLNAME"), M("TP_LOCALLAB_CIE"), false), // ciecam specific widgets sensicie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), + previewcie(Gtk::manage(new Gtk::ToggleButton(M("TP_LOCALLAB_PREVIEW")))), + reparcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_LOGREPART"), 1.0, 100.0, 1., 100.0))), jabcie(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_JAB")))), modecam(Gtk::manage(new MyComboBoxText())), @@ -7755,6 +8112,7 @@ Locallabcie::Locallabcie(): { auto m = ProcEventMapper::getInstance(); + Evlocallabpreviewcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWCIE"); Evlocallabnormcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_NORM"); Evlocallabstrumaskcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_STRU"); EvLocallabtoolcie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL"); @@ -7819,6 +8177,7 @@ Locallabcie::Locallabcie(): pack_start(*sensicie); + pack_start(*previewcie); pack_start(*reparcie); modeHBoxcam->set_spacing(2); //modeHBoxcam->set_tooltip_markup (M ("TP_LOCALLAB_CAMMODE_TOOLTIP")); @@ -8542,6 +8901,11 @@ Locallabcie::Locallabcie(): setExpandAlignProperties(expmaskcie, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + previewcie->set_active(false); + previewcieConn = previewcie->signal_clicked().connect( + sigc::mem_fun( + *this, &Locallabcie::previewcieChanged)); + showmaskcieMethod->append(M("TP_LOCALLAB_SHOWMNONE")); showmaskcieMethod->append(M("TP_LOCALLAB_SHOWMODIF")); showmaskcieMethod->append(M("TP_LOCALLAB_SHOWMODIFMASK")); @@ -8720,6 +9084,62 @@ void Locallabcie::getMaskView(int &colorMask, int &colorMaskinv, int &expMask, i cieMask = showmaskcieMethod->get_active_row_number(); } +Gtk::ToggleButton *Locallabcie::getPreviewDeltaEButton() const +{ + return previewcie; +} + +sigc::connection *Locallabcie::getPreviewDeltaEButtonConnection() +{ + return &previewcieConn; +} + +//new function Global +void Locallabcie::updateguicie(int spottype) +{ + { + idle_register.add( + [this, spottype]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + + // Update GUI fullimage or main + disableListener(); + + if(spottype == 3) { + sensicie->hide(); + showmaskcieMethod->set_active(0); + previewcie->hide(); + previewcie->set_active(false); + resetMaskView(); + } else { + sensicie->show(); + previewcie->show(); + } + enableListener(); + + return false; + } + ); + } + +} + +void Locallabcie::previewcieChanged() +{ + + if(previewcie->get_active()) { + showmaskcieMethod->set_active(4); + } else { + showmaskcieMethod->set_active(0); + } + + if (isLocActivated) { + if (listener) { + listener->panelChanged(Evlocallabpreviewcie,""); + } + } +} + void Locallabcie::setDefaultExpanderVisibility() { expLcie->set_expanded(false); diff --git a/rtgui/options.cc b/rtgui/options.cc index 81bcac3f1..c96febe86 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,8 @@ void Options::setDefaults() histogramTraceBrightness = 1; curvebboxpos = 1; complexity = 2; + spotmet = 0; + inspectorWindow = false; zoomOnScroll = true; prevdemo = PD_Sidecar; @@ -1749,6 +1751,10 @@ void Options::readFromFile(Glib::ustring fname) complexity = keyFile.get_integer("GUI", "Complexity"); } + if (keyFile.has_key("GUI", "Spotmet")) { + spotmet = keyFile.get_integer("GUI", "Spotmet"); + } + if (keyFile.has_key("GUI", "InspectorWindow")) { inspectorWindow = keyFile.get_boolean("GUI", "InspectorWindow"); } @@ -2625,6 +2631,7 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("GUI", "CurveBBoxPosition", curvebboxpos); keyFile.set_boolean("GUI", "Showtooltip", showtooltip); keyFile.set_integer("GUI", "Complexity", complexity); + keyFile.set_integer("GUI", "Spotmet", spotmet); keyFile.set_boolean("GUI", "InspectorWindow", inspectorWindow); keyFile.set_boolean("GUI", "ZoomOnScroll", zoomOnScroll); keyFile.set_integer("GUI", "MaxZoom", static_cast(maxZoomLimit)); diff --git a/rtgui/options.h b/rtgui/options.h index d65013dac..b2221e844 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -330,6 +330,8 @@ public: bool internalThumbIfUntouched; bool overwriteOutputFile; int complexity; + int spotmet; + bool inspectorWindow; // open inspector in separate window bool zoomOnScroll; // translate scroll events to zoom diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index eddfc561e..d92080af8 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1111,6 +1111,9 @@ Gtk::Widget* Preferences::getGeneralPanel() workflowGrid->attach_next_to(*curveBBoxPosL, *flayoutlab, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*curveBBoxPosC, *editorLayout, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*curveBBoxPosRestartL, *lNextStart, Gtk::POS_BOTTOM, 1, 1); + + curveBBoxPosS = Gtk::manage(new Gtk::ComboBoxText()); + setExpandAlignProperties(curveBBoxPosS, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE); Gtk::Label* complexityL = Gtk::manage(new Gtk::Label(M("PREFERENCES_COMPLEXITYLOC") + ":")); setExpandAlignProperties(complexityL, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); @@ -1123,13 +1126,29 @@ Gtk::Widget* Preferences::getGeneralPanel() workflowGrid->attach_next_to(*complexityL, *curveBBoxPosL, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*complexitylocal, *curveBBoxPosC, Gtk::POS_BOTTOM, 1, 1); + + Gtk::Label* spotlocalL = Gtk::manage(new Gtk::Label(M("PREFERENCES_SPOTLOC") + ":")); + setExpandAlignProperties(spotlocalL, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); + spotlocal = Gtk::manage(new Gtk::ComboBoxText()); + setExpandAlignProperties(spotlocal, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE); + spotlocal->append(M("TP_LOCALLAB_EXNORM")); + spotlocal->append(M("TP_LOCALLAB_EXECLU")); + spotlocal->append(M("TP_LOCALLAB_EXFULL")); + spotlocal->append(M("TP_LOCALLAB_EXMAIN")); + spotlocal->set_active(2); + workflowGrid->attach_next_to(*spotlocalL, *complexityL, Gtk::POS_BOTTOM, 1, 1); + workflowGrid->attach_next_to(*spotlocal, *complexitylocal, Gtk::POS_BOTTOM, 1, 1); + + zoomOnScrollCB = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_ZOOMONSCROLL"))); setExpandAlignProperties(zoomOnScrollCB, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); - workflowGrid->attach_next_to(*zoomOnScrollCB, *complexityL, Gtk::POS_BOTTOM, 1, 1); + //workflowGrid->attach_next_to(*zoomOnScrollCB, *complexityL, Gtk::POS_BOTTOM, 1, 1); + workflowGrid->attach_next_to(*zoomOnScrollCB, *spotlocalL, Gtk::POS_BOTTOM, 1, 1); inspectorWindowCB = Gtk::manage(new Gtk::CheckButton(M("PREFERENCES_INSPECTORWINDOW"))); setExpandAlignProperties(inspectorWindowCB, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); - workflowGrid->attach_next_to(*inspectorWindowCB, *complexitylocal, Gtk::POS_BOTTOM, 1, 1); + // workflowGrid->attach_next_to(*inspectorWindowCB, *complexitylocal, Gtk::POS_BOTTOM, 1, 1); + workflowGrid->attach_next_to(*inspectorWindowCB, *spotlocal, Gtk::POS_BOTTOM, 1, 1); Gtk::Label* inspectorNextStartL = Gtk::manage(new Gtk::Label(Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")")); setExpandAlignProperties(inspectorNextStartL, false, false, Gtk::ALIGN_START, Gtk::ALIGN_BASELINE); workflowGrid->attach_next_to(*inspectorNextStartL, *inspectorWindowCB, Gtk::POS_RIGHT, 1, 1); @@ -1994,6 +2013,8 @@ void Preferences::storePreferences() moptions.curvebboxpos = curveBBoxPosC->get_active_row_number(); moptions.complexity = complexitylocal->get_active_row_number(); + moptions.spotmet = spotlocal->get_active_row_number(); + moptions.inspectorWindow = inspectorWindowCB->get_active(); moptions.zoomOnScroll = zoomOnScrollCB->get_active(); moptions.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2; @@ -2216,6 +2237,7 @@ void Preferences::fillPreferences() curveBBoxPosC->set_active(moptions.curvebboxpos); complexitylocal->set_active(moptions.complexity); + spotlocal->set_active(moptions.spotmet); inspectorWindowCB->set_active(moptions.inspectorWindow); zoomOnScrollCB->set_active(moptions.zoomOnScroll); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 191f122f5..e01ec85c0 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -162,8 +162,10 @@ class Preferences final : Gtk::ComboBoxText* cprevdemo; Gtk::CheckButton* ctiffserialize; Gtk::ComboBoxText* curveBBoxPosC; + Gtk::ComboBoxText* curveBBoxPosS; Gtk::ComboBoxText* complexitylocal; + Gtk::ComboBoxText* spotlocal; Gtk::CheckButton* inspectorWindowCB; Gtk::CheckButton* zoomOnScrollCB; diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 966a81b42..efad8f0a6 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -475,6 +475,11 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit toolPanelNotebook->append_page(*favoritePanelSW, *toiF); } toolPanelNotebook->append_page (*exposurePanelSW, *toiE); +/* + if (!batch) { + toolPanelNotebook->append_page(*locallabPanelSW, *toiL); + } +*/ toolPanelNotebook->append_page (*detailsPanelSW, *toiD); toolPanelNotebook->append_page (*colorPanelSW, *toiC); toolPanelNotebook->append_page (*advancedPanelSW, *toiW); From e316e872f3483de430b6fd8fe6cfeaa304ee1382 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Fri, 17 May 2024 07:46:17 +0200 Subject: [PATCH 200/291] Abstract Profile - Change label Highlight attenuation --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e363b1054..dfd7e76b7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -3565,7 +3565,7 @@ TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) TP_LOCALLAB_SLOSH;Slope -TP_LOCALLAB_SMOOTHCIE;Smooth & Tone-Mapping +TP_LOCALLAB_SMOOTHCIE;Highlight attenuation TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing From 7f405aa51ff8a37c58851ebace044f3cf762397b Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 18 May 2024 14:53:33 -0700 Subject: [PATCH 201/291] Update Chinese (Simplified) translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation provided by åä¸€å…ƒäººæ°‘å¸ (syyrmb) in https://github.com/Beep6581/RawTherapee/issues/7077. --- rtdata/languages/Chinese (Simplified) | 265 ++++++++++++++++++++------ 1 file changed, 212 insertions(+), 53 deletions(-) diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index f18513c15..53aca2046 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -7,6 +7,7 @@ #006 2020-08-11 åä¸€å…ƒäººæ°‘å¸ #007 2021-09-24 åä¸€å…ƒäººæ°‘å¸ #008 2022-07-26 åä¸€å…ƒäººæ°‘å¸ +#009 2023-12-25 åä¸€å…ƒäººæ°‘å¸ #100 #101 @LANGUAGE_DISPLAY_NAME=简体中文 @@ -58,8 +59,8 @@ DYNPROFILEEDITOR_NEW;新建 DYNPROFILEEDITOR_NEW_RULE;新建动æ€é…置规则 DYNPROFILEEDITOR_PROFILE;处ç†é…置规则 EDITWINDOW_TITLE;图片修改 -EDIT_OBJECT_TOOLTIP;在预览窗å£ä¸­æ˜¾ç¤ºä¸€ä¸ªå…许你调整本工具的å¯è§†çª—å£ -EDIT_PIPETTE_TOOLTIP;è‹¥å¸Œæœ›å‘æ›²çº¿ä¸­æ·»åŠ ä¸€ä¸ªè°ƒæ•´ç‚¹ï¼Œè¯·ç‚¹å‡»æ­¤æŒ‰é’®ï¼ŒæŒ‰ä½Ctrl键并用鼠标左键点击图åƒé¢„览中你想调整的地方。\nè‹¥è¦è°ƒæ•´ç‚¹çš„ä½ç½®ï¼Œè¯·æŒ‰ä½Ctrl键并用鼠标左键点击图åƒé¢„览中的对应ä½ç½®ï¼Œç„¶åŽæ¾å¼€Ctrl(除éžä½ å¸Œæœ›ç²¾è°ƒï¼‰åŒæ—¶æŒ‰ä½é¼ æ ‡å·¦é”®ï¼Œå°†é¼ æ ‡å‘上/下移动以上下调整曲线中的点 +EDIT_OBJECT_TOOLTIP;在预览区显示一个å…许你调整本工具的å¯è§†çª—å£ +EDIT_PIPETTE_TOOLTIP;若希望添加一个调整点,请å•å‡»æ­¤æŒ‰é’®ï¼Œç„¶åŽæŒ‰ä½Ctrl键并用鼠标左键点击预览区中你想调整的地方。\nè‹¥è¦å¯¹è¯¥ç‚¹åšè°ƒæ•´ï¼Œè¯·æŒ‰ä½Ctrlé”®å•击预览区中的对应ä½ç½®ï¼Œç„¶åŽæ¾å¼€Ctrl(除éžä½ å¸Œæœ›ç²¾è°ƒï¼‰å¹¶æŒ‰ä½é¼ æ ‡å·¦é”®ï¼Œä¸Š/下移动鼠标å³å¯è°ƒæ•´æ›²çº¿ä¸­çš„点 EXIFFILTER_APERTURE;光圈 EXIFFILTER_CAMERA;相机 EXIFFILTER_EXPOSURECOMPENSATION;æ›å…‰è¡¥å¿å€¼ (EV) @@ -107,11 +108,11 @@ EXPORT_FASTEXPORTOPTIONS;快速导出选项 EXPORT_INSTRUCTIONS;快速导出选项æä¾›è·³è¿‡å ç”¨èµ„æºå’Œæ—¶é—´çš„å¤„ç†æ­¥éª¤çš„选项,并使用快速导出设定æ¥è¿›è¡Œé˜Ÿåˆ—处ç†ã€‚\n此方法推è在优先追求速度,生æˆä½Žåˆ†è¾¨çŽ‡å›¾ç‰‡æ—¶ä½¿ç”¨ï¼›æˆ–æ˜¯è°ƒæ•´å°ºå¯¸çš„å›¾ç‰‡å¤§å°é€‚åˆä½ æƒ³å¾—到的图片,并且åˆä¸æƒ³ä¿®æ”¹è¿™äº›ç…§ç‰‡çš„åŽæœŸå¤„ç†å‚数时使用。 EXPORT_MAXHEIGHT;最大高度: EXPORT_MAXWIDTH;最大宽度: -EXPORT_PIPELINE;è¾“å‡ºæµæ°´çº¿ +EXPORT_PIPELINE;è¾“å‡ºæµæ°´çº¿ EXPORT_PUTTOQUEUEFAST;放入快速导出队列 EXPORT_RAW_DMETHOD;去马赛克算法 EXPORT_USE_FAST_PIPELINE;专门(对缩放大å°çš„图片应用全部处ç†ï¼‰ -EXPORT_USE_FAST_PIPELINE_TOOLTIP;ä½¿ç”¨ä¸“é—¨çš„å¤„ç†æµæ°´çº¿æ¥å¯¹å›¾ç‰‡è¿›è¡Œå¤„ç†ï¼Œé€šè¿‡ç‰ºç‰²è´¨é‡æ¥æ¢å–é€Ÿåº¦ã€‚å›¾ç‰‡çš„ç¼©å°æ“作会æå‰ï¼Œè€Œéžåœ¨æ­£å¸¸æµæ°´çº¿ä¸­é‚£æ ·åœ¨æœ€åŽè¿›è¡Œã€‚这能够大幅æå‡é€Ÿåº¦ï¼Œä½†æ˜¯è¾“出的图片中å¯èƒ½ä¼šæ‚点较多,画质较低。 +EXPORT_USE_FAST_PIPELINE_TOOLTIP;ä½¿ç”¨ä¸“é—¨çš„å¤„ç†æµæ°´çº¿æ¥å¤„ç†å›¾ç‰‡ï¼Œé€šè¿‡ç‰ºç‰²è´¨é‡æ¥æ¢å–é€Ÿåº¦ã€‚å›¾ç‰‡çš„ç¼©å°æ“作会æå‰ï¼Œè€Œä¸åƒæ­£å¸¸æƒ…况那样在最åŽè¿›è¡Œã€‚这能够大幅æå‡é€Ÿåº¦ï¼Œä½†æ˜¯è¾“出的图片å¯èƒ½ç”»è´¨è¾ƒä½Žä¸”有较多æ‚点,。 EXPORT_USE_NORMAL_PIPELINE;标准(跳过æŸäº›æ­¥éª¤ï¼Œå¹¶åœ¨æœ€åŽç¼©æ”¾å›¾ç‰‡ï¼‰ EXTPROGTARGET_1;raw EXTPROGTARGET_2;é˜Ÿåˆ—å·²å¤„ç† @@ -862,6 +863,8 @@ IPTCPANEL_RESETHINT;é‡ç½®ä¸ºé»˜è®¤é…ç½® IPTCPANEL_SOURCE;æ¥æº IPTCPANEL_TITLE;标题 MAIN_BUTTON_FULLSCREEN;å…¨å± +MAIN_BUTTON_NAVNEXT_TOOLTIP;跳转到当å‰ç¼–辑图片的下一张图åƒã€‚\nå¿«æ·é”®ï¼šShift-F4\n\nè‹¥è¦è·³è½¬åˆ°å½“å‰é€‰ä¸­å›¾ç‰‡çš„下一张图åƒï¼š\nå¿«æ·é”®ï¼š F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;跳转到当å‰ç¼–辑图片的上一张图åƒã€‚\nå¿«æ·é”®ï¼šShift-F3\n\nè‹¥è¦è·³è½¬åˆ°å½“å‰é€‰ä¸­å›¾ç‰‡çš„上一张图åƒï¼š\nShortcut: F3 MAIN_BUTTON_PREFERENCES;傿•°è®¾ç½® MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;将当å‰å›¾ç‰‡æ”¾å…¥å¤„ç†é˜Ÿåˆ—中\nå¿«æ·é”®ï¼šCtrl+b MAIN_BUTTON_SAVE;ä¿å­˜å›¾ç‰‡ @@ -874,17 +877,17 @@ 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;ä½ç½® MAIN_FRAME_PLACES_ADD;添加 MAIN_FRAME_PLACES_DEL;移除 -MAIN_FRAME_QUEUE;批处ç†é˜Ÿåˆ— +MAIN_FRAME_QUEUE;批处ç†é˜Ÿåˆ— MAIN_FRAME_QUEUE_TOOLTIP;处ç†é˜Ÿåˆ—\nå¿«æ·é”®ï¼šCtrl-F3 -MAIN_FRAME_RECENT;最近使用的文件夹 +MAIN_FRAME_RECENT;最近使用的文件夹 MAIN_MSG_ALREADYEXISTS;该文件已存在 MAIN_MSG_CANNOTLOAD;无法加载图片 MAIN_MSG_CANNOTSAVE;文件ä¿å­˜ä¸­å‡ºé”™ MAIN_MSG_CANNOTSTARTEDITOR;无法å¯åŠ¨ç¼–è¾‘å™¨ -MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;è¯·åœ¨â€œå‚æ•°è®¾ç½®â€ä¸­è®¾ç½®æ­£ç¡®çš„路径 +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;è¯·åœ¨â€œå‚æ•°è®¾ç½®â€ä¸­è®¾ç½®æ­£ç¡®çš„路径 MAIN_MSG_EMPTYFILENAME;未指定文件åï¼ MAIN_MSG_NAVIGATOR;导航窗 MAIN_MSG_OPERATIONCANCELLED;å–æ¶ˆ @@ -1254,7 +1257,7 @@ PROGRESSBAR_SAVETIFF;TIFF文件ä¿å­˜ä¸­... PROGRESSBAR_SNAPSHOT_ADDED;快照已添加 QINFO_FRAMECOUNT;%2帧 QINFO_HDR;HDR / %2帧 -QINFO_ISO;ISO +QINFO_ISO;ISO QINFO_NOEXIF;Exifæ•°æ®ä¸å¯ç”¨ QINFO_PIXELSHIFT;åƒç´ åç§»/ %2帧 QUEUE_AUTOSTART;自动开始 @@ -1310,7 +1313,7 @@ TP_BWMIX_FILTER_RED;红 TP_BWMIX_FILTER_REDYELLOW;红-黄 TP_BWMIX_FILTER_TOOLTIP;è‰²å½©è¿‡æ»¤èƒ½æ¨¡æ‹Ÿä½¿ç”¨è‰²å½©æ»¤ç‰‡æ‰€æ‹æ‘„出的照片。色彩滤片会å‡å°‘æŸä¸ªæ³¢æ®µçš„光的传入,因此影å“到其亮度,比如:红色滤片会让è“å¤©å˜æš—。 TP_BWMIX_FILTER_YELLOW;黄 -TP_BWMIX_GAMMA;伽马矫正 +TP_BWMIX_GAMMA;伽马矫正 TP_BWMIX_GAM_TOOLTIP;矫正红绿è“三色通é“(RGB)伽马 TP_BWMIX_LABEL;黑白 TP_BWMIX_MET;方法 @@ -1383,7 +1386,7 @@ TP_COLORAPP_CIECAT_DEGREE;CAT02/16色适应 TP_COLORAPP_CONTRAST;对比度 (J) TP_COLORAPP_CONTRAST_Q;对比度 (Q) TP_COLORAPP_CONTRAST_Q_TOOLTIP;CIECAM的对比度 (Q)以视明度为基准,与Labå’ŒRGB的对比度ä¸åŒ -TP_COLORAPP_CONTRAST_TOOLTIP;与CIECAM的对比度 (J)以明度为基准,Labå’ŒRGB的对比度ä¸åŒ +TP_COLORAPP_CONTRAST_TOOLTIP;CIECAM的对比度 (J)以明度为基准,与Labå’ŒRGB的对比度ä¸åŒ TP_COLORAPP_CURVEEDITOR1;色调曲线1 TP_COLORAPP_CURVEEDITOR1_TOOLTIP;显示在CIECAM02/16应用å‰çš„L*(L*a*b*)通é“直方图。\n若勾选“在曲线中显示CIECAM02/16输出直方图â€ï¼Œåˆ™æ˜¾ç¤ºCIECAM02/16应用åŽçš„J直方图。\n\nä¸»ç›´æ–¹å›¾é¢æ¿ä¸ä¼šæ˜¾ç¤ºJ的直方图\n\n最终的输出结果请å‚è€ƒä¸»ç›´æ–¹å›¾é¢æ¿ TP_COLORAPP_CURVEEDITOR2;色调曲线2 @@ -1419,7 +1422,7 @@ TP_COLORAPP_SURROUND_DARK;黑暗 TP_COLORAPP_SURROUND_DIM;æ˜æš— TP_COLORAPP_SURROUND_EXDARK;æžæš— TP_COLORAPP_SURROUND_TOOLTIP;改å˜è‰²è°ƒå’Œè‰²å½©ä»¥è€ƒè™‘到输出设备的观察æ¡ä»¶ã€‚\n\n一般:一般的光照环境(标准)。图åƒä¸ä¼šå˜åŒ–。\n\næ˜æš—ï¼šæ˜æš—环境(如电视)。图åƒä¼šç•¥å¾®å˜æš—。\n\n黑暗:黑暗环境(如投影仪)。图åƒä¼šå˜å¾—更暗。\n\næžæš—:éžå¸¸æš—的环境(Cutsheet)。图åƒä¼šå˜å¾—很暗 -TP_COLORAPP_SURSOURCE_TOOLTIP;改å˜è‰²è°ƒä¸Žè‰²å½©ä»¥è®¡å…¥åœºæ™¯æ¡ä»¶\n\nå¹³å‡ï¼šå¹³å‡çš„亮度æ¡ä»¶ï¼ˆæ ‡å‡†ï¼‰ã€‚图åƒä¸è¢«æ”¹å˜\n\næ˜æš—:较暗的场景。图åƒä¼šè¢«ç•¥å¾®æäº®\n\n黑暗:黑暗的环境。图åƒä¼šè¢«æäº®\n\næžæš—:éžå¸¸æš—的环境。图片会å˜å¾—éžå¸¸äº® +TP_COLORAPP_SURSOURCE_TOOLTIP;改å˜è‰²è°ƒä¸Žè‰²å½©ä»¥è®¡å…¥åœºæ™¯æ¡ä»¶\n\n一般:一般的亮度æ¡ä»¶ï¼ˆæ ‡å‡†ï¼‰ã€‚图åƒä¸è¢«æ”¹å˜\n\næ˜æš—:较暗的场景。图åƒä¼šè¢«ç•¥å¾®æäº®\n\n黑暗:黑暗的环境。图åƒä¼šè¢«æäº®\n\næžæš—:éžå¸¸æš—的环境。图片会å˜å¾—éžå¸¸äº® TP_COLORAPP_TCMODE_BRIGHTNESS;视明度 TP_COLORAPP_TCMODE_CHROMA;彩度 TP_COLORAPP_TCMODE_COLORF;视彩度 @@ -1430,7 +1433,7 @@ TP_COLORAPP_TCMODE_LIGHTNESS;明度 TP_COLORAPP_TCMODE_SATUR;饱和度 TP_COLORAPP_TONECIE;使用CIECAM02/16进行色调映射 TP_COLORAPP_TONECIE_TOOLTIP;ç¦ç”¨æ­¤é€‰é¡¹ï¼Œè‰²è°ƒæ˜ å°„会在L*a*b*色彩空间中进行。\nå¯ç”¨æ­¤é€‰é¡¹ï¼Œè‰²è°ƒæ˜ å°„会使用CIECAM进行。\n你需è¦å¯ç”¨è‰²è°ƒæ˜ å°„工具æ¥ä»¤æ­¤é€‰é¡¹ç”Ÿæ•ˆ -TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;观察环境的ç»å¯¹äº®åº¦ï¼ˆä¸€èˆ¬ä¸º16 cd/m²) +TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;观察æ¡ä»¶çš„ç»å¯¹äº®åº¦ï¼ˆä¸€èˆ¬ä¸º16 cd/m²) TP_COLORAPP_WBCAM;白平衡[RT+CAT02/16]+[输出] TP_COLORAPP_WBRT;白平衡[RT]+[输出] TP_COLORTONING_AUTOSAT;自动 @@ -1522,7 +1525,7 @@ TP_DIRPYRDENOISE_CHROMINANCE_MASTER;色度—主控 TP_DIRPYRDENOISE_CHROMINANCE_METHOD;方法 TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;手动\n作用于整张图片\n用户手动控制é™å™ªè®¾ç½®\n\n全局自动\n作用于整张图片\n使用9片区域æ¥è®¡ç®—全局的色度噪点去除设定\n\n预览处\n作用于整张图片\n使用当å‰é¢„览å¯è§çš„区域æ¥è®¡ç®—全局的色度噪点去除设定 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;预览处 -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;æ˜¾ç¤ºåœ¨å°æ³¢å±‚级之åŽçš„,当å‰é¢„览中的噪点水平。\n\n>300 噪点æžå¤š\n100-300 噪点多\n50-100 噪点略多\n<50 噪点æžå°‘\n\nä¸€å®šè¦æ³¨æ„:该数值在RGB模å¼ä¸Žåœ¨L*a*b*模å¼ä¸‹ä¼šæœ‰ä¸åŒã€‚RGB模å¼ä¸‹çš„æ•°å€¼ç›¸å¯¹æ›´ä¸ç²¾å‡†ï¼Œå› ä¸ºRGBæ¨¡å¼æ— æ³•完全分离亮度和色度 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;æ˜¾ç¤ºåœ¨å°æ³¢å±‚级之åŽçš„,当å‰é¢„览中的噪点水平。\n\n>300 噪点æžå¤š\n100-300 噪点多\n50-100 噪点略多\n<50 噪点æžå°‘\n\n务必注æ„:该数值在RGB模å¼ä¸Žåœ¨L*a*b*模å¼ä¸‹ä¼šæœ‰ä¸åŒã€‚RGB模å¼ä¸‹çš„æ•°å€¼è¾ƒä¸ºä¸å‡†ç¡®ï¼Œå› ä¸ºRGBæ¨¡å¼æ— æ³•完全分离亮度和色度 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;预览大å°=%1, 中心:Px=%2 Py=%3 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;当å‰é¢„è§ˆå¤„å™ªç‚¹ï¼šä¸­ä½æ•°=%1 最大=%2 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;当å‰é¢„è§ˆå¤„å™ªç‚¹ï¼šä¸­ä½æ•°= - 最大= - @@ -1537,7 +1540,7 @@ TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;亮度 TP_DIRPYRDENOISE_MAIN_COLORSPACE;色彩空间 TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB -TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;对于Raw文件,RGBå’ŒL*a*b*å‡å¯ç”¨\n\néžRaw文件åªå¯ç”¨L*a*b*空间,ä¸è®ºç”¨æˆ·é€‰æ‹©äº†å“ªä¸ª +TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;对于Raw文件,RGBå’ŒL*a*b*å‡å¯ç”¨\n\néžRaw文件åªèƒ½ä½¿ç”¨L*a*b*空间,ä¸è®ºç”¨æˆ·é€‰æ‹©çš„æ˜¯ä»€ä¹ˆ TP_DIRPYRDENOISE_MAIN_GAMMA;伽马 TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;伽马会令é™å™ªçš„力度在ä¸åŒè‰²è°ƒä¹‹é—´å‘生å˜åŒ–。åå°çš„值会åå‘阴影部分,å大的值会åå‘较亮的色调 TP_DIRPYRDENOISE_MAIN_MODE;æ¨¡å¼ @@ -1630,7 +1633,7 @@ TP_FILMNEGATIVE_REF_LABEL;输入RGB: %1 TP_FILMNEGATIVE_REF_PICK;选择白平衡点 TP_FILMNEGATIVE_REF_TOOLTIP;为输出的正片选择一å—ç°è‰²åŒºåŸŸè¿›è¡Œç™½å¹³è¡¡ TP_FILMSIMULATION_LABEL;胶片模拟 -TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee被设置寻找用于胶片模拟工具的Hald CLUT图åƒï¼Œå›¾åƒæ‰€åœ¨çš„æ–‡ä»¶å¤¹åŠ è½½æ—¶é—´è¿‡é•¿ã€‚\nå‰å¾€å‚数设置-图片处ç†-Hald CLUT路径\n以寻找被使用的文件夹是哪个。你应该令该文件夹指å‘ä¸€ä¸ªåªæœ‰Hald CLUT图åƒè€Œæ²¡æœ‰å…¶ä»–å›¾ç‰‡çš„æ–‡ä»¶å¤¹ï¼Œè€Œå¦‚æžœä½ ä¸æƒ³ç”¨èƒ¶ç‰‡æ¨¡æ‹ŸåŠŸèƒ½ï¼Œå°±å°†å®ƒæŒ‡å‘一个空文件夹。\n\n阅读RawPediaçš„Film Simulationè¯æ¡ä»¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚\n\nä½ çŽ°åœ¨æƒ³å–æ¶ˆæ‰«æå—? +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee被设置寻找用于胶片模拟工具的Hald CLUT图åƒï¼Œä½†å›¾åƒæ‰€åœ¨çš„æ–‡ä»¶å¤¹åŠ è½½æ—¶é—´è¿‡é•¿ã€‚\nå‰å¾€å‚数设置-图片处ç†-Hald CLUT路径\n以寻找被使用的文件夹是哪个。你应该令该文件夹指å‘ä¸€ä¸ªåªæœ‰Hald CLUT图åƒè€Œæ²¡æœ‰å…¶ä»–å›¾ç‰‡çš„æ–‡ä»¶å¤¹ã€‚å¦‚æžœä½ ä¸æƒ³ç”¨èƒ¶ç‰‡æ¨¡æ‹ŸåŠŸèƒ½ï¼Œå°±å°†å®ƒæŒ‡å‘一个空文件夹。\n\n阅读RawPediaçš„Film Simulationè¯æ¡ä»¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚\n\nä½ æƒ³å–æ¶ˆæ‰«æå—? TP_FILMSIMULATION_STRENGTH;力度 TP_FILMSIMULATION_ZEROCLUTSFOUND;åœ¨å‚æ•°è®¾ç½®ä¸­è®¾å®šHaldCLUT目录 TP_FLATFIELD_AUTOSELECT;自动选择 @@ -1641,7 +1644,7 @@ TP_FLATFIELD_BT_HORIZONTAL;æ°´å¹³ TP_FLATFIELD_BT_VERTHORIZ;垂直+æ°´å¹³ TP_FLATFIELD_BT_VERTICAL;垂直 TP_FLATFIELD_CLIPCONTROL;溢出控制 -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;溢出控制能够é¿å…由于平场的应用而导致的高光溢出。如果在应用平场之å‰å°±æœ‰æº¢å‡ºçš„高光,数值就会为0 +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;溢出控制能够é¿å…使用平场而导致的高光溢出。如果在应用平场之å‰å°±æœ‰æº¢å‡ºçš„高光,数值就会为0 TP_FLATFIELD_LABEL;平场 TP_GENERAL_11SCALE_TOOLTIP;此工具的效果仅在以1:1大å°é¢„览时æ‰å¯è§/准确 TP_GRADIENT_CENTER;中心 @@ -1662,7 +1665,7 @@ TP_HLREC_COLOR;色彩延伸 TP_HLREC_ENA_TOOLTIP;å¯èƒ½ä¼šè¢«è‡ªåŠ¨è‰²é˜¶åŠŸèƒ½å¯ç”¨ TP_HLREC_LABEL;高光还原 TP_HLREC_LUMINANCE;亮度还原 -TP_HLREC_METHOD;方法: +TP_HLREC_METHOD;方法: TP_HSVEQUALIZER_CHANNEL;é€šé“ TP_HSVEQUALIZER_HUE;H TP_HSVEQUALIZER_LABEL;HSVå‡è¡¡å™¨ @@ -1725,7 +1728,7 @@ TP_LENSPROFILE_CORRECTION_AUTOMATCH;自动选择 TP_LENSPROFILE_CORRECTION_LCPFILE;LCP文件 TP_LENSPROFILE_CORRECTION_MANUAL;手动选择 TP_LENSPROFILE_LABEL;镜头矫正档案 -TP_LENSPROFILE_LENS_WARNING;警告:制作镜头档案时相机所用的è£åˆ‡ç³»æ•°æ¯”æœ¬å›¾ç‰‡æ‹æ‘„æ—¶\n所使用的è£å‰ªç³»æ•°æ›´å¤§ã€‚矫正结果å¯èƒ½å‡ºçŽ°é”™è¯¯ +TP_LENSPROFILE_LENS_WARNING;警告:如果制作镜头档案时相机的è£åˆ‡ç³»æ•°æ¯”æœ¬å›¾ç‰‡æ‹æ‘„æ—¶\n所使用的è£å‰ªç³»æ•°æ›´å¤§ã€‚矫正结果å¯èƒ½å‡ºçŽ°é”™è¯¯ TP_LENSPROFILE_MODE_HEADER;镜头档案 TP_LENSPROFILE_USE_CA;色差 TP_LENSPROFILE_USE_GEOMETRIC;å‡ ä½•ç•¸å˜ @@ -1813,7 +1816,7 @@ TP_LOCALLAB_DIVGR;伽马 TP_LOCALLAB_DUPLSPOTNAME;å¤åˆ¶ TP_LOCALLAB_EDGFRA;边缘é”度 TP_LOCALLAB_EDGSHOW;显示所有工具 -TP_LOCALLAB_ELI;椭圆 +TP_LOCALLAB_ELI;椭圆 TP_LOCALLAB_ENABLE_AFTER_MASK;使用色调映射 TP_LOCALLAB_EPSBL;细节 TP_LOCALLAB_EV_NVIS;éšè— @@ -1833,7 +1836,7 @@ TP_LOCALLAB_EXPCOMPINV;æ›å…‰è¡¥å¿ TP_LOCALLAB_EXPCURV;曲线 TP_LOCALLAB_EXPGRAD;æ¸å˜æ»¤é•œ TP_LOCALLAB_EXPOSE;动æ€èŒƒå›´ & æ›å…‰ -TP_LOCALLAB_EXPTOOL;æ›å…‰å·¥å…· +TP_LOCALLAB_EXPTOOL;æ›å…‰å·¥å…· TP_LOCALLAB_EXP_TOOLNAME;动æ€èŒƒå›´ & æ›å…‰ TP_LOCALLAB_FATAMOUNT;æ•°é‡ TP_LOCALLAB_FATANCHOR;锚点 @@ -1843,7 +1846,6 @@ TP_LOCALLAB_FATSHFRA;动æ€èŒƒå›´åŽ‹ç¼©è’™ç‰ˆ Æ’ TP_LOCALLAB_FFTMASK_TOOLTIP;使用傅立å¶å˜æ¢ä»¥å¾—到更高的质é‡ï¼ˆå¤„ç†ç”¨æ—¶ä¸Žå†…å­˜å ç”¨ä¼šä¸Šå‡ï¼‰ TP_LOCALLAB_FFTW;Æ’ - 使用快速傅立å¶å˜æ¢ TP_LOCALLAB_FFTWBLUR;Æ’ - 永远使用快速傅立å¶å˜æ¢ -TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image TP_LOCALLAB_GAM;伽马 TP_LOCALLAB_GAMC;伽马 TP_LOCALLAB_GAMFRA;色调å“应曲线(TRC) @@ -1887,7 +1889,7 @@ TP_LOCALLAB_LOG2FRA;观察æ¡ä»¶ TP_LOCALLAB_LOGAUTO;自动 TP_LOCALLAB_LOGEXP;所有工具 TP_LOCALLAB_LOGFRA;场景æ¡ä»¶ -TP_LOCALLAB_LOGIMAGE_TOOLTIP;å°†CIECAMçš„ç›¸å…³å‚æ•°ä¸€åŒè¿›è¡Œè€ƒè™‘ï¼Œå‚æ•°åŒ…括:对比度(J),饱和度(s),以åŠå¯¹æ¯”度(Q),视明度(Q),明度(J),视彩度(M)(在高级模å¼ä¸‹ï¼‰ +TP_LOCALLAB_LOGIMAGE_TOOLTIP;å°†CIECAMçš„ç›¸å…³å‚æ•°ä¸€åŒåŠ å…¥è®¡ç®—ï¼Œå‚æ•°åŒ…括:对比度(J),饱和度(s),以åŠå¯¹æ¯”度(Q),视明度(Q),明度(J),视彩度(M)(在高级模å¼ä¸‹ï¼‰ TP_LOCALLAB_LOGLIGHTL;明度 (J) TP_LOCALLAB_LOGLIGHTL_TOOLTIP;与L*a*b*的明度相近。会考虑到感知色彩的å˜åŒ– TP_LOCALLAB_LOGLIGHTQ;视明度 (Q) @@ -2090,7 +2092,7 @@ TP_RAW_HPHD;HPHD TP_RAW_IGV;IGV TP_RAW_IMAGENUM;å­å›¾åƒ TP_RAW_IMAGENUM_SN;SNæ¨¡å¼ -TP_RAW_IMAGENUM_TOOLTIP;æŸäº›Raw文件包å«å¤šå¼ å­å›¾åƒï¼ˆå®¾å¾—/索尼的åƒç´ å移,宾得的3å¼ åˆå¹¶HDR,佳能的åŒåƒç´ ï¼Œå¯Œå£«çš„EXR)。\n\n当使用除åƒç´ å移外的任æ„一个去马赛克算法时,本æ ç”¨æ¥é€‰æ‹©å“ªå¸§å­å›¾åƒè¢«å¤„ç†ã€‚\n\n当在åƒç´ åç§»Raw文件上使用åƒç´ å移去马赛克算法时,所有å­å›¾åƒéƒ½ä¼šè¢«ä½¿ç”¨ï¼Œæ­¤æ—¶æœ¬æ ç”¨æ¥é€‰æ‹©å“ªå¸§å­å›¾åƒè¢«ç”¨æ¥å¤„ç†åЍ体 +TP_RAW_IMAGENUM_TOOLTIP;æŸäº›Raw文件包å«å¤šå¼ å­å›¾åƒï¼ˆå®¾å¾—/索尼的åƒç´ å移,宾得的3å¼ åˆå¹¶HDR,佳能的åŒåƒç´ ï¼Œå¯Œå£«çš„EXR)。\n\n当使用除åƒç´ å移外的任æ„一个去马赛克算法时,本æ ç”¨æ¥é€‰æ‹©å“ªå¼ å­å›¾åƒè¢«å¤„ç†ã€‚\n\n当在åƒç´ åç§»Raw文件上使用åƒç´ å移去马赛克算法时,所有å­å›¾åƒéƒ½ä¼šè¢«ä½¿ç”¨ï¼Œæ­¤æ—¶æœ¬æ ç”¨æ¥é€‰æ‹©å“ªå¼ å­å›¾åƒè¢«ç”¨æ¥å¤„ç†åЍ体 TP_RAW_LABEL;去马赛克 TP_RAW_LMMSE;LMMSE TP_RAW_LMMSEITERATIONS;LMMSE优化步长 @@ -2125,7 +2127,7 @@ TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;在图åƒä¸Šç”¨ç»¿è‰²è’™ç‰ˆæ˜¾ç¤ºåŠ¨ä½“åŒº TP_RAW_PIXELSHIFTSIGMA;模糊åŠå¾„ TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;默认åŠå¾„值1.0一般对于原生ISOæ¥è¯´è¶³å¤Ÿå¥½ã€‚\n对于高ISO照片,æé«˜æ­¤å€¼ï¼Œ5.0是ä¸é”™çš„起始点。\nåœ¨æ”¹å˜æ­¤å€¼çš„åŒæ—¶å…³æ³¨åŠ¨ä½“è’™ç‰ˆ TP_RAW_PIXELSHIFTSMOOTH;顺滑过渡 -TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;让存在动体的区域与没有动体之间的区域之间顺滑地过渡。\n将此值设置为0以ç¦ç”¨é¡ºæ»‘过渡\n将此值设置为1以使用AMaZE/LMMSE算法(这å–决于你是å¦é€‰æ‹©äº†â€œä½¿ç”¨LMMSEâ€ï¼‰æ‰€è§£å‡ºçš„你所选择的那一帧图åƒï¼Œå¦‚果你选择了“使用中值â€ï¼Œé‚£ä¹ˆå°±ä¼šæ ¹æ®é€šè¿‡æ‰€æœ‰å›¾åƒè®¡ç®—å‡ºçš„ä¸­å€¼è§£å‡ºå›¾åƒ +TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;让存在动体的区域与没有动体之间的区域之间顺滑地过渡。\n将此值设置为0以ç¦ç”¨é¡ºæ»‘过渡\n将此值设置为1以使用AMaZE/LMMSE算法(这å–决于你是å¦é€‰æ‹©äº†â€œä½¿ç”¨LMMSEâ€ï¼‰æ‰€è§£å‡ºçš„你所选择的那一张图åƒï¼Œå¦‚果你选择了“使用中值â€ï¼Œé‚£ä¹ˆå°±ä¼šæ ¹æ®é€šè¿‡æ‰€æœ‰å›¾åƒè®¡ç®—å‡ºçš„ä¸­å€¼è§£å‡ºå›¾åƒ TP_RAW_RCD;RCD TP_RAW_RCDVNG4;RCD+VNG4 TP_RAW_SENSOR_BAYER_LABEL;拜耳阵列传感器 @@ -2139,7 +2141,7 @@ TP_RESIZE_H;高: TP_RESIZE_HEIGHT;高度 TP_RESIZE_LABEL;è°ƒæ•´å¤§å° TP_RESIZE_LANCZOS;Lanczos算法 -TP_RESIZE_METHOD;方法: +TP_RESIZE_METHOD;方法: TP_RESIZE_NEAREST;最近点 TP_RESIZE_SCALE;ç¼©æ”¾å€æ•° TP_RESIZE_SPECIFY;调整: @@ -2164,7 +2166,7 @@ TP_RGBCURVES_CHANNEL;é€šé“ TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;RGB曲线 TP_RGBCURVES_LUMAMODE;äº®åº¦æ¨¡å¼ -TP_RGBCURVES_LUMAMODE_TOOLTIP;亮度模å¼å…许改å˜Rã€Gã€B三个通é“的亮度分é…而ä¸å½±å“色彩 +TP_RGBCURVES_LUMAMODE_TOOLTIP;亮度模å¼å…许改å˜Rã€Gã€B三个通é“的亮度分é…而ä¸å½±å“色彩 TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;角度 TP_ROTATE_LABEL;旋转 @@ -2316,7 +2318,7 @@ TP_WAVELET_EDVAL;力度 TP_WAVELET_FINAL;最终润色 TP_WAVELET_FINCFRAME;最终局部åå·® TP_WAVELET_FINEST;最精细 -TP_WAVELET_HIGHLIGHT;精细层级范围 +TP_WAVELET_HIGHLIGHT;精细层级亮度范围 TP_WAVELET_HS1;全部亮度范围 TP_WAVELET_HS2;选择性亮度范围 TP_WAVELET_HUESKIN;肤色和其它色彩 @@ -2445,6 +2447,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !EXIFPANEL_BASIC_GROUP;Basic !EXIFPANEL_VALUE_NOT_SHOWN;Not shown !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_OTHER;Other !HISTORY_MSG_112;--unused-- @@ -3002,7 +3005,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1086;Local - Jz contrast @@ -3080,15 +3083,22 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -3096,7 +3106,64 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local Cie mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local Cie mask blur fftw +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local Cie mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local Cie mask curve hh +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local Cie mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local Cie mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local Cie mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local Cie mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local CIECAM mask wavelet Lc +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local CIECAM mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local CIECAM - gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local CIECAM - Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local CIECAM - Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local CIECAM - Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local CIECAM - black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local CIECAM - Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local CIECAM - Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local CIECAM TRC Primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local CIECAM - Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local CIECAM - Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local CIECAM Refinement Colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local CIECAM - Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local CIECAM - Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local CIECAM - Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local CIECAM - Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local CIECAM - Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local CIECAM - Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local CIECAM - Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local CIECAM - Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local CIECAM - Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local CIECAM - Scale Yb Scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local CIECAM - Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local CIECAM - Scale Yb Viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local CIECAM - levels - luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local CIECAM - gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local CIECAM - Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local CIECAM - TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local CIECAM - Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze - black !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local Log - Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local Log - Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local Log - Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local Log - Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -3235,8 +3302,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !IPTCPANEL_TRANSREFERENCE;Job ID !IPTCPANEL_TRANSREFERENCEHINT;Enter a number or identifier needed for workflow control or tracking. !MAIN_BUTTON_ICCPROFCREATOR;ICC Profile Creator -!MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigate to the next image relative to image opened in the Editor.\nShortcut: Shift-F4\n\nTo navigate to the next image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F4 -!MAIN_BUTTON_NAVPREV_TOOLTIP;Navigate to the previous image relative to image opened in the Editor.\nShortcut: Shift-F3\n\nTo navigate to the previous image relative to the currently selected thumbnail in the File Browser or Filmstrip:\nShortcut: F3 !MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronize the File Browser or Filmstrip with the Editor to reveal the thumbnail of the currently opened image, and clear any active filters.\nShortcut: x\n\nAs above, but without clearing active filters:\nShortcut: y\n(Note that the thumbnail of the opened image will not be shown if filtered out). !MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. !MAIN_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. @@ -3244,6 +3309,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PARTIALPASTE_VIBRANCE;Vibrance +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans demosaic !PREFERENCES_CIE;Ciecam @@ -3264,12 +3332,15 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional +!PREFERENCES_SPOTLOC;Define Spot method for Local Adjustments !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3292,6 +3363,27 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) !PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAMPLEFORMAT_1;8-bit unsigned !SAMPLEFORMAT_2;16-bit unsigned !SAMPLEFORMAT_4;24-bit LogLuv @@ -3308,12 +3400,16 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors" allows you:\n 1) for low values adjust the image purity.\n 2) for higher values, carry out moderate Color Toning.\n 3) Be careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -3383,6 +3479,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT;Illuminant !TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -3403,8 +3500,15 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. !TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3416,7 +3520,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries !TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. @@ -3428,10 +3534,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Destination primaries (Advanced): which allows you to change the destination primaries to restore or change image color (saturation), the color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are not too different, 'Working Profiles' are not modified. Perform a gamut control.\nWhen 'Custom LA (sliders)' is selected you can modify the values of the 3 primaries Red, Green, Blue for X and Y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3458,7 +3567,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ADJ;Equalizer Color !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3482,9 +3591,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). !TP_LOCALLAB_BLWH;All changes forced in Black-and-White !TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. For example to match Cam16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 !TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz !TP_LOCALLAB_CH;CL - LC @@ -3500,6 +3612,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CIELIGHTCONTFRA;Lighting & Contrast !TP_LOCALLAB_CIELIGHTFRA;Lighting !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. !TP_LOCALLAB_CLARICRES;Merge chroma !TP_LOCALLAB_CLARIFRA;Clarity & Sharp mask/Blend & Soften Images @@ -3511,10 +3629,14 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CLARITYML;Clarity !TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. !TP_LOCALLAB_CLIPTM;Clip restored data (gain) -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening' or 'Soft Light and Original Retinex' or 'Blur/Grain and Denoise' or 'Dehaze and Retinex' or 'Contrast by Detail Levels' in 'Add tool to current spot' menu.\nFor others tools Preview ΔE button is 'in the tool' - to be able to preview ΔE with several tools enabled, use preferably Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the theshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. @@ -3530,11 +3652,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. !TP_LOCALLAB_CURVNONE;Disable curves !TP_LOCALLAB_DARKRETI;Darkness +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3550,8 +3673,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3559,13 +3684,14 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. !TP_LOCALLAB_ESTOP;Edge stopping !TP_LOCALLAB_EV_DUPL;Copy of -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the local adjustment tools on the whole image, without using deltaE or transitions. +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' !TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3581,6 +3707,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. !TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ +!TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image !TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. !TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. @@ -3675,8 +3802,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast etc.:\nThe user may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3684,13 +3813,14 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. !TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. @@ -3751,7 +3881,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3777,7 +3907,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_MERONE;Normal !TP_LOCALLAB_MERSAT;Saturation !TP_LOCALLAB_MERSEV;Soft Light (legacy) -!TP_LOCALLAB_MERSEV0;Soft Light Illusion !TP_LOCALLAB_MERSEV1;Soft Light W3C !TP_LOCALLAB_MERSEV2;Hard Light !TP_LOCALLAB_MERSIX;Divide @@ -3787,6 +3916,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MRFIV;Background @@ -3817,6 +3947,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ !TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked ensures a gamut control just after primary conversion to XYZ matrix. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y" allows you to carry out moderate Color Toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;This 'Source Data Adjustments' modifies: a)the Dynamic Range using Log encoding; b) the tones of the image and primaries(simplified Abstract Profile) and also midtones, just before the Ciecam process. The values are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\n\n\n-Destination primaries: which allows you to change the destination primaries to restore or change image color (saturation), the color balance is 'significantly' preserved when the 'Working Profile' and the 'Destination primaries' are not too different (be careful), 'Working Profiles' are not modified.\nYou can also finely adapt the primaries and the illuminant (white-point).\nMoving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_QUAL_METHOD;Global quality !TP_LOCALLAB_QUANONEALL;Off !TP_LOCALLAB_QUANONEWAV;Non-local means only @@ -3845,6 +3980,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. !TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SCALEGR;Scale !TP_LOCALLAB_SCALERETI;Scale !TP_LOCALLAB_SCALTM;Scale @@ -3855,7 +3991,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHARDAMPING;Damping !TP_LOCALLAB_SHARFRAME;Modifications !TP_LOCALLAB_SHORTC;Short Curves 'L' Mask @@ -3885,15 +4021,39 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_SHOWT;Mask and modifications !TP_LOCALLAB_SHOWVI;Mask and modifications !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' and 'Sigmoid Q'.\nSigmoid Q: three sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the comboxbox selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance : ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the comboxbox selection'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. This last value stands for brightness (Q) should be a near the possible value 'Compression treshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic, when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the 'Jz' and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma - Slope - based: choice (Standard and Advanced) allows you to simulate a "Tone mapping" using: a) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%); b) Viewing conditions: Mean luminance (Yb%).\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. !TP_LOCALLAB_SOFTRADIUSCOL;Soft radius @@ -3903,12 +4063,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_SPECIAL;Special use of RGB curves !TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3931,11 +4092,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Allows you to modify the mask, if one exists. !TP_LOCALLAB_TOOLMASK;Mask Tools !TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. @@ -4243,7 +4405,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) “Observer 10°†must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 @@ -4251,8 +4413,5 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_WBALANCE_SOLUX47;Solux 4700K (vendor) !TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) !TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 -!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 !TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 !TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. -!//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. -!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram From efdc5bce3b9794847093baeb040937ab55eba86e Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 19 May 2024 04:27:10 -0700 Subject: [PATCH 202/291] Fix linking with jpeg-turbo patch via Termux PR https://github.com/termux-user-repository/tur/pull/1027 --- rtengine/jdatasrc.cc | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/rtengine/jdatasrc.cc b/rtengine/jdatasrc.cc index fa13b9dd1..a0d12657f 100644 --- a/rtengine/jdatasrc.cc +++ b/rtengine/jdatasrc.cc @@ -247,20 +247,6 @@ my_error_exit (j_common_ptr cinfo) #endif } - -#ifdef _WIN32 -#define JVERSION "6b 27-Mar-1998" -#define JCOPYRIGHT_SHORT "(C) 1998, Thomas G. Lane" -#define JMESSAGE(code,string) string , - -const char * const jpeg_std_message_table[] = { -#include "jerror.h" - NULL -}; -#else -extern const char * const jpeg_std_message_table[]; -#endif - /* * Actual output of an error or trace message. * Applications may override this method to send JPEG messages somewhere @@ -409,24 +395,14 @@ reset_error_mgr (j_common_ptr cinfo) GLOBAL(struct jpeg_error_mgr *) my_jpeg_std_error (struct jpeg_error_mgr * err) { + err = jpeg_std_error(err); + /* override these functions */ 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 = nullptr; - err->first_addon_message = 0; /* for safety */ - err->last_addon_message = 0; - return err; } From 422a11866a26ca984f7948d33423890fff2a3182 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 19 May 2024 05:12:07 -0700 Subject: [PATCH 203/291] Bump codeql actions to v3 v2 is deprecated in github actions. Fixes warnings in codeql analysis. --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f57786098..5cb91e47a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -77,7 +77,7 @@ jobs: echo "REF_NAME_FILTERED=$REF_NAME_FILTERED" >> $GITHUB_ENV - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} @@ -90,6 +90,6 @@ jobs: mv AppDir/usr/bin/share AppDir/usr/ - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" From 7789a8574b454ebd874522a70930ae4b40726da4 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 19 May 2024 16:39:28 -0700 Subject: [PATCH 204/291] removes redundant jpeg error message Co-authored-by: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> --- rtengine/jdatasrc.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rtengine/jdatasrc.cc b/rtengine/jdatasrc.cc index a0d12657f..96b6f83b6 100644 --- a/rtengine/jdatasrc.cc +++ b/rtengine/jdatasrc.cc @@ -399,10 +399,6 @@ my_jpeg_std_error (struct jpeg_error_mgr * err) /* override these functions */ 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; return err; } From b57679ac158dc72156fff1ab90e9d91be1c91440 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sat, 30 Mar 2024 21:09:04 +0100 Subject: [PATCH 205/291] dcraw: add Panasonic DC-G9M2 to adobe_coeffs --- rtengine/dcraw.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 56d400d3d..6c54e0495 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8889,6 +8889,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-G8", 15, 0xfff, /* G8, G80, G81, G85 */ { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DC-G9M2", 0, 0, + { 8325,-3456,-623,-4330,12089,2528,-860,2646,5984 } }, { "Panasonic DC-G9", 15, 0xfff, { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } }, { "Panasonic DMC-GF1", 15, 0xf92, From 0d60258a96c5e98e1a4223102e0bcb2fe831b577 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sat, 30 Mar 2024 21:10:04 +0100 Subject: [PATCH 206/291] dcraw: add Panasonic DC-GH6 to adobe_coeffs --- rtengine/dcraw.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 56d400d3d..d96012094 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8919,6 +8919,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6929,-2355,-708,-4192,12534,1828,-1097,1989,5195 } }, { "Panasonic DC-GH5", 15, 0, { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } }, + { "Panasonic DC-GH6", 0, 0, + { 7949,-3491,-710,-3435,11681,1977,-503,1622,5065 } }, { "Panasonic DMC-GM1", 15, 0, { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, { "Panasonic DMC-GM5", 15, 0, From eb3b49eff73d786202a5dd46956787734e3fd674 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 13 May 2024 14:12:30 +0200 Subject: [PATCH 207/291] dcraw: add 12 bit raw handling to panasonic v6 decoder. Port panasonic v6 decoder handling of 12 bit raw from libraw. --- rtengine/panasonic_decoders.cc | 67 ++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index bbbfb7c20..62bac4526 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -60,7 +60,7 @@ unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) class pana_cs6_page_decoder { - unsigned int pixelbuffer[14], lastoffset, maxoffset; + unsigned int pixelbuffer[18], lastoffset, maxoffset; unsigned char current, *buffer; public: pana_cs6_page_decoder(unsigned char *_buffer, unsigned int bsize) @@ -68,10 +68,15 @@ public: { } void read_page(); // will throw IO error if not enough space in buffer + void read_page12(); // 12-bit variant unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; } + unsigned int nextpixel12() + { + return current < 18 ? pixelbuffer[current++] : 0; + } }; #define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i]) @@ -97,6 +102,37 @@ void pana_cs6_page_decoder::read_page() current = 0; lastoffset += 16; } + +void pana_cs6_page_decoder::read_page12() +{ + if (!buffer || (maxoffset - lastoffset < 16)) + ; + pixelbuffer[0] = (wbuffer(0) << 4) | (wbuffer(1) >> 4); // 12 bit: 8/0 + 4 upper bits of /1 + pixelbuffer[1] = (((wbuffer(1) & 0xf) << 8) | (wbuffer(2))) & 0xfff; // 12 bit: 4l/1 + 8/2 + + pixelbuffer[2] = (wbuffer(3) >> 6) & 0x3; // 2; 2u/3, 6 low bits remains in wbuffer(3) + pixelbuffer[3] = ((wbuffer(3) & 0x3f) << 2) | (wbuffer(4) >> 6); // 8; 6l/3 + 2u/4; 6 low bits remains in wbuffer(4) + pixelbuffer[4] = ((wbuffer(4) & 0x3f) << 2) | (wbuffer(5) >> 6); // 8: 6l/4 + 2u/5; 6 low bits remains in wbuffer(5) + pixelbuffer[5] = ((wbuffer(5) & 0x3f) << 2) | (wbuffer(6) >> 6); // 8: 6l/5 + 2u/6, 6 low bits remains in wbuffer(6) + + pixelbuffer[6] = (wbuffer(6) >> 4) & 0x3; // 2, 4 low bits remains in wbuffer(6) + pixelbuffer[7] = ((wbuffer(6) & 0xf) << 4) | (wbuffer(7) >> 4); // 8: 4 low bits from wbuffer(6), 4 upper bits from wbuffer(7) + pixelbuffer[8] = ((wbuffer(7) & 0xf) << 4) | (wbuffer(8) >> 4); // 8: 4 low bits from wbuffer(7), 4 upper bits from wbuffer(8) + pixelbuffer[9] = ((wbuffer(8) & 0xf) << 4) | (wbuffer(9) >> 4); // 8: 4 low bits from wbuffer(8), 4 upper bits from wbuffer(9) + + pixelbuffer[10] = (wbuffer(9) >> 2) & 0x3; // 2: bits 2-3 from wbuffer(9), two low bits remain in wbuffer(9) + pixelbuffer[11] = ((wbuffer(9) & 0x3) << 6) | (wbuffer(10) >> 2); // 8: 2 bits from wbuffer(9), 6 bits from wbuffer(10) + pixelbuffer[12] = ((wbuffer(10) & 0x3) << 6) | (wbuffer(11) >> 2); // 8: 2 bits from wbuffer(10), 6 bits from wbuffer(11) + pixelbuffer[13] = ((wbuffer(11) & 0x3) << 6) | (wbuffer(12) >> 2); // 8: 2 bits from wbuffer(11), 6 bits from wbuffer(12) + + pixelbuffer[14] = wbuffer(12) & 0x3; // 2: low bits from wbuffer(12) + pixelbuffer[15] = wbuffer(13); + pixelbuffer[16] = wbuffer(14); + pixelbuffer[17] = wbuffer(15); + current = 0; + lastoffset += 16; +} + #undef wbuffer void DCraw::panasonic_load_raw() @@ -176,8 +212,14 @@ void DCraw::panasonic_load_raw() void DCraw::panasonicC6_load_raw() { constexpr int rowstep = 16; - const int blocksperrow = raw_width / 11; + const bool _12bit = RT_pana_info.bpp == 12; + const int pixperblock = _12bit ? 14 : 11; + const int blocksperrow = raw_width / pixperblock; const int rowbytes = blocksperrow * 16; + const unsigned pixelbase0 = _12bit ? 0x80 : 0x200; + const unsigned pixelbase_compare = _12bit ? 0x800 : 0x2000; + const unsigned spix_compare = _12bit ? 0x3fff : 0xffff; + const unsigned pixel_mask = _12bit ? 0xfff : 0x3fff; unsigned char *iobuf = (unsigned char *)malloc(rowbytes * rowstep); merror(iobuf, "panasonicC6_load_raw()"); @@ -188,25 +230,28 @@ void DCraw::panasonicC6_load_raw() for (int crow = 0, col = 0; crow < rowstoread; ++crow, col = 0) { unsigned short *rowptr = &raw_image[(row + crow) * raw_width]; for (int rblock = 0; rblock < blocksperrow; rblock++) { - page.read_page(); + if (_12bit) + page.read_page12(); + else + page.read_page(); unsigned oddeven[2] = {0, 0}, nonzero[2] = {0, 0}; unsigned pmul = 0, pixel_base = 0; - for (int pix = 0; pix < 11; ++pix) { + for (int pix = 0; pix < pixperblock; ++pix) { if (pix % 3 == 2) { - unsigned base = page.nextpixel(); + unsigned base = _12bit ? page.nextpixel12(): page.nextpixel(); if (base > 3) { derror(); } if (base == 3) { base = 4; } - pixel_base = 0x200 << base; + pixel_base = pixelbase0 << base; pmul = 1 << base; } - unsigned epixel = page.nextpixel(); + unsigned epixel = _12bit ? page.nextpixel12() : page.nextpixel(); if (oddeven[pix % 2]) { epixel *= pmul; - if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base) { + if (pixel_base < pixelbase_compare && nonzero[pix % 2] > pixel_base) { epixel += nonzero[pix % 2] - pixel_base; } nonzero[pix % 2] = epixel; @@ -219,11 +264,11 @@ void DCraw::panasonicC6_load_raw() } } const unsigned spix = epixel - 0xf; - if (spix <= 0xffff) { - rowptr[col++] = spix & 0xffff; + if (spix <= spix_compare) { + rowptr[col++] = spix & spix_compare; } else { epixel = (((signed int)(epixel + 0x7ffffff1)) >> 0x1f); - rowptr[col++] = epixel & 0x3fff; + rowptr[col++] = epixel & pixel_mask; } } } From 6b14cf114b1f1b501ec489307357646cf99d3f32 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 13 May 2024 14:23:23 +0200 Subject: [PATCH 208/291] dcraw: add Panasonic DC-GH5M2 to adobe_coeffs --- rtengine/dcraw.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 56d400d3d..254af14ad 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8917,6 +8917,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, { "Panasonic DC-GH5S", 15, 0, { 6929,-2355,-708,-4192,12534,1828,-1097,1989,5195 } }, + { "Panasonic DC-GH5M2", 0, 0, + { 9300,-3659,-755,-2981,10988,2287,-190,1077,5016 } }, { "Panasonic DC-GH5", 15, 0, { 7641,-2336,-605,-3218,11299,2187,-485,1338,5121 } }, { "Panasonic DMC-GM1", 15, 0, From c74bcad19e99cca59e892ff844df2ccc24048d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=B6ssie?= Date: Fri, 24 May 2024 09:35:48 +0200 Subject: [PATCH 209/291] jdatasrc.cc: remove now unused functions --- rtengine/jdatasrc.cc | 145 ------------------------------------------- 1 file changed, 145 deletions(-) diff --git a/rtengine/jdatasrc.cc b/rtengine/jdatasrc.cc index 96b6f83b6..48d428914 100644 --- a/rtengine/jdatasrc.cc +++ b/rtengine/jdatasrc.cc @@ -247,151 +247,6 @@ my_error_exit (j_common_ptr cinfo) #endif } -/* - * 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 = nullptr; - 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 != nullptr && - 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 == nullptr) { - 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) { - snprintf(buffer, JMSG_LENGTH_MAX, msgtext, err->msg_parm.s); - } else - snprintf(buffer, JMSG_LENGTH_MAX, 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) { From 106ade3d8d5c4ba1a0d0fe231cbefa7f0024d684 Mon Sep 17 00:00:00 2001 From: xiota Date: Sat, 25 May 2024 06:49:09 +0000 Subject: [PATCH 210/291] Fix version for libjxl API change --- rtengine/imageio.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 44297b10f..22f796e7d 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -898,7 +898,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) std::size_t icc_size = 0; if (JXL_DEC_SUCCESS != -#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0) +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0) JxlDecoderGetICCProfileSize(dec.get(), &format, _PROFILE_, &icc_size) #else JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) @@ -911,7 +911,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) icc_profile.resize(icc_size); if (JXL_DEC_SUCCESS != -#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0) +#if JPEGXL_NUMERIC_VERSION < JPEGXL_COMPUTE_NUMERIC_VERSION(0, 9, 0) JxlDecoderGetColorAsICCProfile( dec.get(), &format, _PROFILE_, icc_profile.data(), icc_profile.size()) From a5954ad4c238c7fc801700f6b6a3e75959f0913b Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 26 May 2024 11:11:07 +0000 Subject: [PATCH 211/291] Switch g_printerr to std::cerr --- rtengine/imageio.cc | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 22f796e7d..8ecadd46c 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -852,7 +852,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) std::vector const compressed = getFileData(fname); if (compressed.empty()) { - g_printerr("Error: loadJXL failed to get data from file\n"); + std::cerr << "Error: loadJXL failed to get data from file" << std::endl; return IMIO_READERROR; } @@ -865,14 +865,14 @@ int ImageIO::loadJXL(const Glib::ustring &fname) JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE)) { - g_printerr("Error: JxlDecoderSubscribeEvents failed\n"); + std::cerr << "Error: JxlDecoderSubscribeEvents failed" << std::endl; return IMIO_HEADERERROR; } if (JXL_DEC_SUCCESS != JxlDecoderSetParallelRunner(dec.get(), JxlResizableParallelRunner, runner.get())) { - g_printerr("Error: JxlDecoderSetParallelRunner failed\n"); + std::cerr << "Error: JxlDecoderSetParallelRunner failed" << std::endl; return IMIO_HEADERERROR; } @@ -884,7 +884,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) if (status == JXL_DEC_BASIC_INFO) { if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec.get(), &info)) { - g_printerr("Error: JxlDecoderGetBasicInfo failed\n"); + std::cerr << "Error: JxlDecoderGetBasicInfo failed" << std::endl; return IMIO_HEADERERROR; } @@ -904,7 +904,7 @@ int ImageIO::loadJXL(const Glib::ustring &fname) JxlDecoderGetICCProfileSize(dec.get(), _PROFILE_, &icc_size) #endif ) { - g_printerr("Warning: JxlDecoderGetICCProfileSize failed\n"); + std::cerr << "Warning: JxlDecoderGetICCProfileSize failed" << std::endl; } if (icc_size > 0) { @@ -921,14 +921,13 @@ int ImageIO::loadJXL(const Glib::ustring &fname) icc_profile.data(), icc_profile.size()) #endif ) { - g_printerr( - "Warning: JxlDecoderGetColorAsICCProfile failed\n"); + std::cerr << "Warning: JxlDecoderGetColorAsICCProfile failed" << std::endl; } else { embProfile = cmsOpenProfileFromMem(icc_profile.data(), icc_profile.size()); } } else { - g_printerr("Warning: Empty ICC data.\n"); + std::cerr << "Warning: Empty ICC data." << std::endl; } } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { // Note: If assert is triggered, change to assignment. @@ -938,14 +937,14 @@ int ImageIO::loadJXL(const Glib::ustring &fname) if (JXL_DEC_SUCCESS != JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { - g_printerr("Error: JxlDecoderImageOutBufferSize failed\n"); + std::cerr << "Error: JxlDecoderImageOutBufferSize failed" << std::endl; return IMIO_READERROR; } buffer.resize(buffer_size); if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, buffer.data(), buffer.size())) { - g_printerr("Error: JxlDecoderSetImageOutBuffer failed\n"); + std::cerr << "Error: JxlDecoderSetImageOutBuffer failed" << std::endl; return IMIO_READERROR; } } else if (status == JXL_DEC_FULL_IMAGE || @@ -957,13 +956,13 @@ int ImageIO::loadJXL(const Glib::ustring &fname) // Decoding complete. Decoder will be released automatically. break; } else if (status == JXL_DEC_NEED_MORE_INPUT) { - g_printerr("Error: Decoder needs more input data\n"); + std::cerr << "Error: Decoder needs more input data" << std::endl; return IMIO_READERROR; } else if (status == JXL_DEC_ERROR) { - g_printerr("Error: Decoder error\n"); + std::cerr << "Error: Decoder error" << std::endl; return IMIO_READERROR; } else { - g_printerr("Error: Unknown decoder status\n"); + std::cerr << "Error: Unknown decoder status" << std::endl; return IMIO_READERROR; } } // end grand decode loop From 40f9eefabecc78342155d228f5abf87b80544fe9 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 26 May 2024 11:23:41 +0000 Subject: [PATCH 212/291] Add libjxl version to AboutThisBuild.txt --- AboutThisBuild.txt.in | 1 + CMakeLists.txt | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/AboutThisBuild.txt.in b/AboutThisBuild.txt.in index 4d8f4f3fe..065b6c6cc 100644 --- a/AboutThisBuild.txt.in +++ b/AboutThisBuild.txt.in @@ -8,6 +8,7 @@ System: ${SYSTEM} Bit depth: ${PROC_BIT_DEPTH} Gtkmm: V${GTKMM_VERSION} Lensfun: V${LENSFUN_VERSION} +libjxl: V${JXL_VERSION} Build type: ${BUILD_TYPE} Build flags: ${CXX_FLAGS} Link flags: ${LFLAGS} diff --git a/CMakeLists.txt b/CMakeLists.txt index fe7884ee9..b6c053dd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -560,14 +560,19 @@ if(WITH_JXL AND NOT WITH_JXL STREQUAL "AUTO") else() set(JXL_REQUIRED "") endif() -pkg_check_modules(JXL ${JXL_REQUIRED} IMPORTED_TARGET libjxl libjxl_threads) +pkg_check_modules(JXL ${JXL_REQUIRED} IMPORTED_TARGET libjxl) +pkg_check_modules(JXLTHREADS ${JXL_REQUIRED} IMPORTED_TARGET libjxl_threads) if(JXL_FOUND) if(WITH_JXL OR WITH_JXL STREQUAL "AUTO") add_definitions(-DLIBJXL) + list(APPEND JXL_INCLUDE_DIRS ${JXLTHREADS_INCLUDE_DIRS}) + list(APPEND JXL_LIBRARIES ${JXLTHREADS_LIBRARIES}) else() message(STATUS " JXL support disabled by WITH_JXL = ${WITH_JXL}") set(JXL_INCLUDE_DIRS "") set(JXL_LIBRARIES "") + set(JXLTHREADS_INCLUDE_DIRS "") + set(JXLTHREADS_LIBRARIES "") endif() endif() @@ -751,6 +756,7 @@ if(NOT APPLE) -DGTKMM_VERSION:STRING=${GTKMM_VERSION} -DOPTION_OMP:STRING=${OPTION_OMP} -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP} + -DJXL_VERSION:STRING=${JXL_VERSION} -DLENSFUN_VERSION:STRING=${LENSFUN_VERSION}) endif() @@ -780,6 +786,7 @@ elseif(APPLE) -DGTKMM_VERSION:STRING=${GTKMM_VERSION} -DOPTION_OMP:STRING=${OPTION_OMP} -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP} + -DJXL_VERSION:STRING=${JXL_VERSION} -DLENSFUN_VERSION:STRING=${LENSFUN_VERSION} -P ${PROJECT_SOURCE_DIR}/UpdateInfo.cmake) else() From 1b19ac162120dd153e5089333f6ebf29f25ffbe3 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 16 May 2024 10:31:30 +0200 Subject: [PATCH 213/291] dcraw/camconst: add Sony ILCE-6700 * Add dcraw adobe_coeffs entry for Sony ILCE-6700 * Add camconst raw crop for Sony ILCE-6700 --- rtengine/camconst.json | 5 +++++ rtengine/dcraw.cc | 2 ++ 2 files changed, 7 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 3f78739a5..b80d776b8 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -3028,6 +3028,11 @@ Camera constants: "pdaf_offset" : 3 }, + { // Quality C + "make_model": [ "Sony ILCE-6700" ], + "raw_crop": [ 0, 0, 6244, 4168 ] + }, + { // Quality C "make_model": "Sony ILCE-7C", "dcraw_matrix": [ 7374, -2389, -551, -5435, 13162, 2519, -1006, 1795, 6552 ] diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 56d400d3d..d4a29e6cb 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -9085,6 +9085,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, { "Sony ILCA-99M2", 0, 0, { 6660,-1918,-471,-4613,12398,2485,-649,1433,6447 } }, + { "Sony ILCE-6700", 0, 0, + { 6972,-2408,-600,-4330,12101,2515,-388,1277,5847 } }, { "Sony ILCE-6", 0, 0, /* 6300, 6500 */ { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, { "Sony ILCE-7M2", 0, 0, From 71f452aa1272eec0aa943ae579c6b5417fc204a6 Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Mon, 27 May 2024 11:13:09 -0700 Subject: [PATCH 214/291] Fix crash when trying to load DCP (#7039) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stream a C-string of the file name instead of the Glib::ustring. The ustring can throw an exception with certain locale settings and file name character combinations, such as with LANG=es_ES and the character "ä". Only print the message if verbose is true. --- rtengine/dcp.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index df5627d2e..96ade2e36 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -1177,7 +1177,9 @@ DCPProfile::DCPProfile(const Glib::ustring& filename) : // Color Matrix (one is always there) if (!md.find(TAG_KEY_COLOR_MATRIX_1)) { - std::cerr << "DCP '" << filename << "' is missing 'ColorMatrix1'. Skipped." << std::endl; + if (settings->verbose) { + std::cerr << "DCP '" << filename.c_str() << "' is missing 'ColorMatrix1'. Skipped." << std::endl; + } return; } From e81724645221e97b57e88053060fb268fddad2d5 Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 27 May 2024 21:01:59 +0000 Subject: [PATCH 215/291] AboutThisBuild: Distinguish JXL unavailable and disabled --- AboutThisBuild.txt.in | 6 +++--- CMakeLists.txt | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/AboutThisBuild.txt.in b/AboutThisBuild.txt.in index 065b6c6cc..7c42f244e 100644 --- a/AboutThisBuild.txt.in +++ b/AboutThisBuild.txt.in @@ -6,9 +6,9 @@ Compiler: ${COMPILER_INFO} Processor: ${PROC_LABEL} System: ${SYSTEM} Bit depth: ${PROC_BIT_DEPTH} -Gtkmm: V${GTKMM_VERSION} -Lensfun: V${LENSFUN_VERSION} -libjxl: V${JXL_VERSION} +Gtkmm: ${GTKMM_VERSION} +Lensfun: ${LENSFUN_VERSION} +libjxl: ${JXL_VERSION} Build type: ${BUILD_TYPE} Build flags: ${CXX_FLAGS} Link flags: ${LFLAGS} diff --git a/CMakeLists.txt b/CMakeLists.txt index b6c053dd0..18b4ef04f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -569,11 +569,14 @@ if(JXL_FOUND) list(APPEND JXL_LIBRARIES ${JXLTHREADS_LIBRARIES}) else() message(STATUS " JXL support disabled by WITH_JXL = ${WITH_JXL}") + set(JXL_VERSION "Disabled") set(JXL_INCLUDE_DIRS "") set(JXL_LIBRARIES "") set(JXLTHREADS_INCLUDE_DIRS "") set(JXLTHREADS_LIBRARIES "") endif() +else() + set(JXL_VERSION "Not installed") endif() # Check for libcanberra-gtk3 (sound events on Linux): From 4a5194e2d7df3e4ddc9acae19867eb46ee0c5130 Mon Sep 17 00:00:00 2001 From: "U-PCSPECIALIST01\\jdesm" Date: Tue, 28 May 2024 08:06:37 +0200 Subject: [PATCH 216/291] Change sizeband to 6 in ToneEqualizerParamsEdited issue 7085 --- rtgui/paramsedited.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 57a3ea1cd..27f9ac9cc 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -371,7 +371,7 @@ struct SHParamsEdited { struct ToneEqualizerParamsEdited { bool enabled; - std::array bands; + std::array bands; bool regularization; bool show_colormap; bool pivot; From 5ea3a4b979da6af5ccf42f2840cccee91be0630e Mon Sep 17 00:00:00 2001 From: xiota Date: Tue, 28 May 2024 06:45:49 +0000 Subject: [PATCH 217/291] AboutThisBuild: Make libjxl status strings less confusing --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18b4ef04f..7696270ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -569,14 +569,16 @@ if(JXL_FOUND) list(APPEND JXL_LIBRARIES ${JXLTHREADS_LIBRARIES}) else() message(STATUS " JXL support disabled by WITH_JXL = ${WITH_JXL}") - set(JXL_VERSION "Disabled") + string(APPEND JXL_VERSION " - Disabled") set(JXL_INCLUDE_DIRS "") set(JXL_LIBRARIES "") set(JXLTHREADS_INCLUDE_DIRS "") set(JXLTHREADS_LIBRARIES "") endif() +elseif(WITH_JXL STREQUAL "AUTO") + set(JXL_VERSION "Disabled, Auto") else() - set(JXL_VERSION "Not installed") + set(JXL_VERSION "Disabled") endif() # Check for libcanberra-gtk3 (sound events on Linux): From d2af04cea27ba951927ca6bbe704941e30f9a189 Mon Sep 17 00:00:00 2001 From: xiota Date: Tue, 28 May 2024 07:18:51 +0000 Subject: [PATCH 218/291] Add "Loading JXL" translations --- rtdata/languages/Catala | 1 + rtdata/languages/Chinese (Simplified) | 1 + rtdata/languages/Czech | 1 + rtdata/languages/Dansk | 1 + rtdata/languages/Deutsch | 1 + rtdata/languages/English (UK) | 1 + rtdata/languages/English (US) | 1 + rtdata/languages/Espanol (Castellano) | 1 + rtdata/languages/Espanol (Latin America) | 1 + rtdata/languages/Francais | 1 + rtdata/languages/Italiano | 1 + rtdata/languages/Japanese | 1 + rtdata/languages/Magyar | 1 + rtdata/languages/Nederlands | 1 + rtdata/languages/Polish | 1 + rtdata/languages/Portugues | 1 + rtdata/languages/Portugues (Brasil) | 1 + rtdata/languages/Russian | 1 + rtdata/languages/Serbian (Cyrilic Characters) | 1 + rtdata/languages/Slovenian | 1 + rtdata/languages/Swedish | 1 + rtdata/languages/default | 1 + 22 files changed, 22 insertions(+) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 03353cdb7..bc95d7546 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -555,6 +555,7 @@ PROFILEPANEL_TOOLTIPSAVE;Desa l'actual com a perfil.\nCtrl-click per sele PROGRESSBAR_LOADING;Carregant imatge... PROGRESSBAR_LOADINGTHUMBS;Carregant minifotos... PROGRESSBAR_LOADJPEG;Carregant fitxer JPEG... +PROGRESSBAR_LOADJXL;Carregant fitxer JXL... PROGRESSBAR_LOADPNG;Carregant fitxer PNG... PROGRESSBAR_LOADTIFF;Carregant fitxer TIFF... PROGRESSBAR_PROCESSING;Processant imatge... diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index f18513c15..2999c0c77 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -1241,6 +1241,7 @@ PROGRESSBAR_LINEDENOISE;线状噪点过滤... PROGRESSBAR_LOADING;图片加载中... PROGRESSBAR_LOADINGTHUMBS;读å–缩略图... PROGRESSBAR_LOADJPEG;JPEG文件加载中... +PROGRESSBAR_LOADJXL;JXL文件加载中... PROGRESSBAR_LOADPNG;PNG文件加载中... PROGRESSBAR_LOADTIFF;TIFF文件加载中... PROGRESSBAR_NOIMAGES;未找到图片 diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 232c094e0..995f089db 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -1306,6 +1306,7 @@ PROGRESSBAR_LINEDENOISE;Filtr linkového ruÅ¡ení… PROGRESSBAR_LOADING;NaÄítání obrázku... PROGRESSBAR_LOADINGTHUMBS;NaÄítání náhledů... PROGRESSBAR_LOADJPEG;NaÄítání JPEG... +PROGRESSBAR_LOADJXL;NaÄítání JXL... PROGRESSBAR_LOADPNG;NaÄítání PNG... PROGRESSBAR_LOADTIFF;NaÄítání TIFF... PROGRESSBAR_NOIMAGES;Složka neobsahuje obrázky diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index ed2e32616..e42f0bc83 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -1224,6 +1224,7 @@ PROGRESSBAR_LINEDENOISE;Linje støjfilter... PROGRESSBAR_LOADING;Indlæser billede... PROGRESSBAR_LOADINGTHUMBS;Indlæser thumbnails... PROGRESSBAR_LOADJPEG; Indlæser JPEG fil... +PROGRESSBAR_LOADJXL; Indlæser JXL fil... PROGRESSBAR_LOADPNG; Indlæser PNG fil... PROGRESSBAR_LOADTIFF;Indlæser TIFF fil... PROGRESSBAR_NOIMAGES;Ingen billeder fundet diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 84c52d64f..677efd8e0 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -2147,6 +2147,7 @@ PROGRESSBAR_LINEDENOISE;Linienrauschfilter... PROGRESSBAR_LOADING;Lade Bild... PROGRESSBAR_LOADINGTHUMBS;Lade Miniaturbilder... PROGRESSBAR_LOADJPEG;Lade JPEG... +PROGRESSBAR_LOADJXL;Lade JXL... PROGRESSBAR_LOADPNG;Lade PNG... PROGRESSBAR_LOADTIFF;Lade TIFF... PROGRESSBAR_NOIMAGES;Keine Bilder gefunden diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index f03dbd1af..37ccdc48f 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -2259,6 +2259,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PROGRESSBAR_LOADING;Loading image... !PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... !PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADJXL;Loading JXL file... !PROGRESSBAR_LOADPNG;Loading PNG file... !PROGRESSBAR_LOADTIFF;Loading TIFF file... !PROGRESSBAR_NOIMAGES;No images found diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 329925625..079713ac1 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -2082,6 +2082,7 @@ !PROGRESSBAR_LOADING;Loading image... !PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... !PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADJXL;Loading JXL file... !PROGRESSBAR_LOADPNG;Loading PNG file... !PROGRESSBAR_LOADTIFF;Loading TIFF file... !PROGRESSBAR_NOIMAGES;No images found diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index 32b5791dc..9f9cc48bf 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -2006,6 +2006,7 @@ PROGRESSBAR_LINEDENOISE;Filtro de ruido de línea... PROGRESSBAR_LOADING;Cargando imagen... PROGRESSBAR_LOADINGTHUMBS;Cargando miniaturas... PROGRESSBAR_LOADJPEG;Cargando archivo JPEG... +PROGRESSBAR_LOADJXL;Cargando archivo JXL... PROGRESSBAR_LOADPNG;Cargando archivo PNG... PROGRESSBAR_LOADTIFF;Cargando archivo TIFF... PROGRESSBAR_NOIMAGES;No se encuentran imágenes diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index 9d5e352bd..816b237c6 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -1253,6 +1253,7 @@ PROFILEPANEL_TOOLTIPSAVE;Guardar perfil actual.\nCtrl-click para seleccio PROGRESSBAR_LOADING;Abriendo imagen... PROGRESSBAR_LOADINGTHUMBS;Cargando miniaturas... PROGRESSBAR_LOADJPEG;Abriendo archivo JPEG... +PROGRESSBAR_LOADJXL;Abriendo archivo JXL... PROGRESSBAR_LOADPNG;Abriendo archivo PNG... PROGRESSBAR_LOADTIFF;Abriendo archivo TIFF... PROGRESSBAR_NOIMAGES;No se han encontrado imágenes diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 33ffc861c..53e478f78 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -1210,6 +1210,7 @@ PROFILEPANEL_TOOLTIPSAVE;Enregistrer le profil actuel\nCTRL-clic pour sé PROGRESSBAR_LOADING;Chargement de l'Image... PROGRESSBAR_LOADINGTHUMBS;Chargement des vignettes... PROGRESSBAR_LOADJPEG;Chargement du fichier JPEG... +PROGRESSBAR_LOADJXL;Chargement du fichier JXL... PROGRESSBAR_LOADPNG;Chargement du fichier PNG... PROGRESSBAR_LOADTIFF;Chargement du fichier TIFF... PROGRESSBAR_NOIMAGES;Pas d'image trouvée diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 5ef63de7b..8e1f6124d 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -2088,6 +2088,7 @@ PROGRESSBAR_LINEDENOISE;Filtro antirumore di linea... PROGRESSBAR_LOADING;Caricamento immagine... PROGRESSBAR_LOADINGTHUMBS;Caricamento miniature... PROGRESSBAR_LOADJPEG;Caricamento JPEG... +PROGRESSBAR_LOADJXL;Caricamento JXL... PROGRESSBAR_LOADPNG;Caricamento PNG... PROGRESSBAR_LOADTIFF;Caricamento TIFF... PROGRESSBAR_NOIMAGES;Nessuna immagine trovata diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 8bfbf0f42..290e42b57 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -2005,6 +2005,7 @@ PROGRESSBAR_LINEDENOISE;ラインノイズフィルタ。。。 PROGRESSBAR_LOADING;ç”»åƒèª­ã¿è¾¼ã¿ä¸­... PROGRESSBAR_LOADINGTHUMBS;サムãƒã‚¤ãƒ«ã®èª­ã¿è¾¼ã¿... PROGRESSBAR_LOADJPEG;JPEGファイル読ã¿è¾¼ã¿ä¸­... +PROGRESSBAR_LOADJXL;JXLファイル読ã¿è¾¼ã¿ä¸­... PROGRESSBAR_LOADPNG;PNGファイル読ã¿è¾¼ã¿ä¸­... PROGRESSBAR_LOADTIFF;TIFFファイル読ã¿è¾¼ã¿ä¸­... PROGRESSBAR_NOIMAGES;ç”»åƒãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 07ab9784b..8336efda8 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -1084,6 +1084,7 @@ PROGRESSBAR_LINEDENOISE;SorzajszűrÅ‘... PROGRESSBAR_LOADING;Kép betöltése... PROGRESSBAR_LOADINGTHUMBS;ElÅ‘nézeti képek betöltése... PROGRESSBAR_LOADJPEG;JPEG fájl betöltése... +PROGRESSBAR_LOADJXL;JXL fájl betöltése... PROGRESSBAR_LOADPNG;PNG fájl betöltése... PROGRESSBAR_LOADTIFF;TIFF fájl betöltése... PROGRESSBAR_NOIMAGES;Nem találhatóak képek diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index a0418e70c..af2862781 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -1242,6 +1242,7 @@ PROGRESSBAR_LINEDENOISE;Lijnruisfilter... PROGRESSBAR_LOADING;Afbeelding laden... PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... +PROGRESSBAR_LOADJXL;Laden JXL-bestand... PROGRESSBAR_LOADPNG;Laden PNG-bestand... PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... PROGRESSBAR_NOIMAGES;Geen afbeeldingen diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 94df4424f..7ad5c1792 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1192,6 +1192,7 @@ PROGRESSBAR_LINEDENOISE;Liniowy filtr szumu... PROGRESSBAR_LOADING;Wczytywanie obrazu... PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... PROGRESSBAR_LOADJPEG;Åadowanie pliku JPEG... +PROGRESSBAR_LOADJXL;Åadowanie pliku JXL... PROGRESSBAR_LOADPNG;Åadowanie pliku PNG... PROGRESSBAR_LOADTIFF;Åadowanie pliku TIFF... PROGRESSBAR_NOIMAGES;Nie znaleziono żadnych obrazów diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index 77ffcaf40..e037c565c 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -1197,6 +1197,7 @@ PROFILEPANEL_TOOLTIPSAVE;Guardar o perfil atual.\nCtrl-click para selecio PROGRESSBAR_LOADING;A carregar a imagem... PROGRESSBAR_LOADINGTHUMBS;A carregar as miniaturas... PROGRESSBAR_LOADJPEG;A carregar o ficheiro JPEG... +PROGRESSBAR_LOADJXL;A carregar o ficheiro JXL... PROGRESSBAR_LOADPNG;A carregar o ficheiro PNG... PROGRESSBAR_LOADTIFF;A carregar o ficheiro TIFF... PROGRESSBAR_NOIMAGES;Não foi encontrada nenhuma imagem diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index c22207212..133205a09 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -1207,6 +1207,7 @@ PROGRESSBAR_LINEDENOISE;Filtro de ruído de linha... PROGRESSBAR_LOADING;Carregando imagem... PROGRESSBAR_LOADINGTHUMBS;Carregando miniaturas... PROGRESSBAR_LOADJPEG;Carregando arquivo JPEG... +PROGRESSBAR_LOADJXL;Carregando arquivo JXL... PROGRESSBAR_LOADPNG;Carregando arquivo PNG... PROGRESSBAR_LOADTIFF;Carregando arquivo TIFF... PROGRESSBAR_NOIMAGES;Nenhuma imagem encontrada diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 74a08f2d3..de0846e01 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -843,6 +843,7 @@ PROFILEPANEL_TOOLTIPSAVE;Сохранить текущий профиль\nCt PROGRESSBAR_LOADING;Загрузка изображениÑ... PROGRESSBAR_LOADINGTHUMBS;Загрузка миниатюр... PROGRESSBAR_LOADJPEG;Чтение JPEG файла... +PROGRESSBAR_LOADJXL;Чтение JXL файла... PROGRESSBAR_LOADPNG;Чтение PNG файла... PROGRESSBAR_LOADTIFF;Чтение TIFF файла... PROGRESSBAR_NOIMAGES;Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ найдены diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 1cf1086bf..15bb90737 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -670,6 +670,7 @@ PROFILEPANEL_TOOLTIPSAVE;Чува тренутни профил PROGRESSBAR_LOADING;Учитавам Ñлику... PROGRESSBAR_LOADINGTHUMBS;Учитавам приказе... PROGRESSBAR_LOADJPEG;Учитавам JPEG датотеку... +PROGRESSBAR_LOADJPEG;Учитавам JXL датотеку... PROGRESSBAR_LOADPNG;Учитавам PNG датотеку... PROGRESSBAR_LOADTIFF;Учитавам TIFF датотеку... PROGRESSBAR_NOIMAGES;ÐиÑу пронађене Ñлике diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index 84ea9e72e..1ba151693 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -1221,6 +1221,7 @@ PROGRESSBAR_LINEDENOISE;Filter linijskega Å¡uma... PROGRESSBAR_LOADING;Nalagam sliko... PROGRESSBAR_LOADINGTHUMBS;Nalagam predogledne sliÄice... PROGRESSBAR_LOADJPEG;Nalagam datoteko JPEG... +PROGRESSBAR_LOADJXL;Nalagam datoteko JXL... PROGRESSBAR_LOADPNG;Nalagam datoteko PNG... PROGRESSBAR_LOADTIFF;Nalagam datoteko TIFF... PROGRESSBAR_NOIMAGES;Ne najdem nobene slike diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 0ff9f831f..edbeb9e3a 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -911,6 +911,7 @@ PROFILEPANEL_TOOLTIPSAVE;Spara nuvarande profil.\nCtrl-klicka för att v PROGRESSBAR_LOADING;Laddar bild... PROGRESSBAR_LOADINGTHUMBS;Laddar miniatyrbilder... PROGRESSBAR_LOADJPEG;Laddar JPEG-fil... +PROGRESSBAR_LOADJXL;Laddar JXL-fil... PROGRESSBAR_LOADPNG;Laddar PNG-fil... PROGRESSBAR_LOADTIFF;Laddar TIFF-fil... PROGRESSBAR_NOIMAGES;Inga bilder funna. diff --git a/rtdata/languages/default b/rtdata/languages/default index a6a8cdc5c..252564758 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2086,6 +2086,7 @@ PROGRESSBAR_LINEDENOISE;Line noise filter... PROGRESSBAR_LOADING;Loading image... PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... PROGRESSBAR_LOADJPEG;Loading JPEG file... +PROGRESSBAR_LOADJXL;Loading JXL file... PROGRESSBAR_LOADPNG;Loading PNG file... PROGRESSBAR_LOADTIFF;Loading TIFF file... PROGRESSBAR_NOIMAGES;No images found From 13804545781ec39b755a7c184dc9cc711fd38485 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Wed, 29 May 2024 18:19:43 -0700 Subject: [PATCH 219/291] Update Japanese translation Provided by Yz2house in #7083. --- rtdata/languages/Japanese | 951 ++++++++++++++++++++++---------------- 1 file changed, 554 insertions(+), 397 deletions(-) diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 8bfbf0f42..4d5562bfe 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -1,4 +1,5 @@ -#001 Last update 10-12-2022 +#001 2022-10-12 Yz2house +#002 2024-05-23 Yz2house #100 #101 @LANGUAGE_DISPLAY_NAME=日本語 @@ -52,6 +53,7 @@ DYNPROFILEEDITOR_PROFILE;処ç†ãƒ—ロファイル EDITWINDOW_TITLE;ç”»åƒç·¨é›† EDIT_OBJECT_TOOLTIP;ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã®ç›®å®‰ã«ã€ãƒ—レビュー画é¢ã«ã‚¬ã‚¤ãƒ‰ã‚’表示ã™ã‚‹ EDIT_PIPETTE_TOOLTIP;カーブ上ã«èª¿æ•´ãƒã‚¤ãƒ³ãƒˆã‚’追加ã™ã‚‹ã«ã¯ã€Ctrlキーを押ã—ãªãŒã‚‰ã€ãƒ—レビューã®ç”»åƒä¸Šã®ç›®æ¨™ãƒã‚¤ãƒ³ãƒˆã‚’左クリックã—ã¾ã™ã€‚\n追加ã•れãŸãã®ãƒã‚¤ãƒ³ãƒˆã‚’調整ã™ã‚‹ã«ã¯ã€Ctrlキーを押ã—ãªãŒã‚‰ã€ãƒ—レビュー画åƒã®ãã®ãƒã‚¤ãƒ³ãƒˆã«å½“ãŸã‚‹éƒ¨åˆ†ã‚’左クリックã—ã¾ã™ã€‚ãれã‹ã‚‰Ctrlキーを離ã—(微妙ãªèª¿æ•´ã‚’ã™ã‚‹å ´åˆã¯ãã®ã¾ã¾ï¼‰ã€å·¦ã‚¯ãƒªãƒƒã‚¯ã—ãŸã¾ã¾ãƒžã‚¦ã‚¹ã‚’ç”»é¢ä¸Šã§ä¸Šä¸‹ã«å‹•ã‹ã™ã¨ã€ãれã«åˆã‚ã›ã¦ãƒˆãƒ¼ãƒ³ã‚«ãƒ¼ãƒ–ãŒèª¿æ•´ã•れã¾ã™ã€‚ +ERROR_MSG_METADATA_VALUE;メタデータ: エラー設定 %1ã‹ã‚‰%2 EXIFFILTER_APERTURE;絞り EXIFFILTER_CAMERA;カメラ EXIFFILTER_EXPOSURECOMPENSATION;露光é‡è£œæ­£ (EV) @@ -61,12 +63,16 @@ EXIFFILTER_IMAGETYPE;ç”»åƒã®ç¨®é¡ž EXIFFILTER_ISO;ISO EXIFFILTER_LENS;レンズ EXIFFILTER_METADATAFILTER;メタデータ絞り込ã¿ã‚’有効ã«ã™ã‚‹ +EXIFFILTER_PATH;ファイルパス EXIFFILTER_SHUTTER;シャッター +EXIFPANEL_ACTIVATE_ALL_HINT;å…¨ã¦ã®ã‚¿ã‚°ã‚’é¸æŠž +EXIFPANEL_ACTIVATE_NONE_HINT;何れã®ã‚¿ã‚°ã‚‚é¸æŠžã—ãªã„ EXIFPANEL_ADDEDIT;追加/編集 EXIFPANEL_ADDEDITHINT;æ–°ã—ã„タグを追加ã€ã¾ãŸã¯ã‚¿ã‚°ã®ç·¨é›† EXIFPANEL_ADDTAGDLG_ENTERVALUE;値ã®å…¥åŠ› EXIFPANEL_ADDTAGDLG_SELECTTAG;ã‚¿ã‚°é¸æŠž EXIFPANEL_ADDTAGDLG_TITLE;ã‚¿ã‚°ã®è¿½åŠ /編集 +EXIFPANEL_BASIC_GROUP;ベーシック EXIFPANEL_KEEP;ãã®ã¾ã¾ EXIFPANEL_KEEPHINT;å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込む際ã€é¸æŠžã•れãŸã‚¿ã‚°ã‚’ãã®ã¾ã¾ã«ã™ã‚‹ EXIFPANEL_REMOVE;削除 @@ -75,9 +81,8 @@ EXIFPANEL_RESET;リセット EXIFPANEL_RESETALL;ã™ã¹ã¦ãƒªã‚»ãƒƒãƒˆ EXIFPANEL_RESETALLHINT;ã™ã¹ã¦ã®ã‚¿ã‚°ã‚’å…ƒã®å€¤ã«ãƒªã‚»ãƒƒãƒˆ EXIFPANEL_RESETHINT;é¸æŠžã•れãŸã‚¿ã‚°ã‚’å…ƒã®å€¤ã«ãƒªã‚»ãƒƒãƒˆ -EXIFPANEL_SHOWALL;å…¨ã¦è¡¨ç¤º -EXIFPANEL_SUBDIRECTORY;サブディレクトリ -EXPORT_BYPASS;迂回ã•ã›ã‚‹æ©Ÿèƒ½ +EXIFPANEL_VALUE_NOT_SHOWN;éžè¡¨ç¤º +EXPORT_BYPASS;処ç†å·¥ç¨‹ã‚’迂回 EXPORT_BYPASS_ALL;å…¨ã¦é¸æŠž / å…¨ã¦è§£é™¤ EXPORT_BYPASS_DEFRINGE;フリンジ低減を迂回 EXPORT_BYPASS_DIRPYRDENOISE;ノイズ低減を迂回 @@ -164,7 +169,8 @@ FILEBROWSER_POPUPRANK5;ランク 5 ***** FILEBROWSER_POPUPREMOVE;完全ã«å‰Šé™¤ FILEBROWSER_POPUPREMOVEINCLPROC;キュー処ç†ã«ä¿æŒã•れã¦ã„るファイルをå«ã‚ã¦å®Œå…¨ã«å‰Šé™¤ FILEBROWSER_POPUPRENAME;åå‰å¤‰æ›´ -FILEBROWSER_POPUPSELECTALL;å…¨é¸æŠž +FILEBROWSER_POPUPSELECTALL;å…¨ã¦é¸æŠž +FILEBROWSER_POPUPSORTBY;ファイルã®ä¸¦ã¹æ›¿ãˆ FILEBROWSER_POPUPTRASH;ゴミ箱ã¸ç§»å‹• FILEBROWSER_POPUPUNRANK;ランクãªã— FILEBROWSER_POPUPUNTRASH;ゴミ箱ã‹ã‚‰ç§»å‹• @@ -196,11 +202,12 @@ FILEBROWSER_SHOWRANK2HINT;ï¼’ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示\nショートカット: Shift-3 FILEBROWSER_SHOWRANK4HINT;ï¼”ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示\nショートカット: Shift-4 FILEBROWSER_SHOWRANK5HINT;ï¼•ã¤æ˜Ÿãƒ©ãƒ³ã‚¯ã‚’表示\nショートカット: Shift-5 -FILEBROWSER_SHOWRECENTLYSAVEDHINT;最近ä¿å­˜ã•れãŸç”»åƒã‚’表示\nショートカット: Alt-7 -FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;最近ä¿å­˜ã•れã¦ã„ãªã„ç”»åƒã‚’表示\nショートカット: Alt-6 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;ä¿å­˜ã•れãŸç”»åƒã‚’表示\nショートカット: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;ä¿å­˜ã•れã¦ã„ãªã„ç”»åƒã‚’表示\nショートカット: Alt-6 +FILEBROWSER_SHOWRECURSIVE;サブフォルダã®ä¸­ã®ç”»åƒã‚’å†å¸°çš„ã«è¡¨ç¤º FILEBROWSER_SHOWTRASHHINT;ゴミ箱ã®å†…容を表示\nショートカット: Ctrl-t -FILEBROWSER_SHOWUNCOLORHINT;カラー・ラベルã®ãªã„ç”»åƒã‚’表示\nショートカット: Alt-0 -FILEBROWSER_SHOWUNRANKHINT;ランクãªã—ç”»åƒã‚’表示\nショートカット: Shift-0 +FILEBROWSER_SHOWUNCOLORHINT;カラーラベルãªã—ã§ç”»åƒã‚’表示\nショートカット: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;ランクã®ãªã„ç”»åƒã‚’表示\nショートカット: Shift-0 FILEBROWSER_THUMBSIZE;サムãƒã‚¤ãƒ«ã®ã‚µã‚¤ã‚º FILEBROWSER_UNRANK_TOOLTIP;ランクãªã—\nショートカット: 0 FILEBROWSER_ZOOMINHINT;サムãƒã‚¤ãƒ«ã‚µã‚¤ã‚ºã®æ‹¡å¤§\nショートカット: +\n\nシングル編集タブã®ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆ: Alt-+ @@ -208,6 +215,7 @@ FILEBROWSER_ZOOMOUTHINT;サムãƒã‚¤ãƒ«ã‚µã‚¤ã‚ºã®ç¸®å°\nショートカット FILECHOOSER_FILTER_ANY;å…¨ã¦ã®ãƒ•ァイル FILECHOOSER_FILTER_COLPROF;カラープロファイル FILECHOOSER_FILTER_CURVE;カーブファイル +FILECHOOSER_FILTER_EXECUTABLE;実行å¯èƒ½ãƒ•ァイル FILECHOOSER_FILTER_LCP;レンズ補正プロファイル FILECHOOSER_FILTER_PP;処ç†ãƒ—ロファイル FILECHOOSER_FILTER_SAME;ç¾åœ¨ã®ç”»åƒã¨åŒã˜ãƒ•ォーマット @@ -222,11 +230,11 @@ GENERAL_CANCEL;キャンセル GENERAL_CLOSE;é–‰ã˜ã‚‹ GENERAL_CURRENT;ç¾åœ¨ GENERAL_DELETE_ALL;å…¨ã¦å‰Šé™¤ -GENERAL_DISABLE;無効 -GENERAL_DISABLED;無効 +GENERAL_DISABLE;無効ã«ã™ã‚‹ +GENERAL_DISABLED;無効ã«ãªã‚Šã¾ã—㟠GENERAL_EDIT;編集 -GENERAL_ENABLE;有効 -GENERAL_ENABLED;有効 +GENERAL_ENABLE;有効ã™ã‚‹ +GENERAL_ENABLED;有効ã«ãªã‚Šã¾ã—㟠GENERAL_FILE;ファイル GENERAL_HELP;ヘルプ GENERAL_LANDSCAPE;横 @@ -235,6 +243,7 @@ GENERAL_NO;No GENERAL_NONE;ãªã— GENERAL_OK;OK GENERAL_OPEN;é–‹ã +GENERAL_OTHER;ãã®ä»– GENERAL_PORTRAIT;縦 GENERAL_RESET;リセット GENERAL_SAVE;ä¿å­˜ @@ -735,21 +744,21 @@ HISTORY_MSG_496;ローカル スãƒãƒƒãƒˆ 削除 HISTORY_MSG_497;ローカル スãƒãƒƒãƒˆ é¸æŠž HISTORY_MSG_498;ローカル スãƒãƒƒãƒˆ åå‰ HISTORY_MSG_499;ローカル スãƒãƒƒãƒˆ 表示 -HISTORY_MSG_500;ローカル スãƒãƒƒãƒˆ 形状 -HISTORY_MSG_501;ローカル スãƒãƒƒãƒˆ 方法 -HISTORY_MSG_502;ローカル スãƒãƒƒãƒˆ å½¢çŠ¶ã®æ–¹å¼ -HISTORY_MSG_503;ローカル スãƒãƒƒãƒˆ å³ã®åž‚ç›´ç·š -HISTORY_MSG_504;ローカル スãƒãƒƒãƒˆ å·¦ã®åž‚ç›´ç·š -HISTORY_MSG_505;ローカル スãƒãƒƒãƒˆ ä¸‹ã®æ°´å¹³ç·š -HISTORY_MSG_506;ローカル スãƒãƒƒãƒˆ ä¸Šã®æ°´å¹³ç·š -HISTORY_MSG_507;ローカル スãƒãƒƒãƒˆ 中心 -HISTORY_MSG_508;ローカル スãƒãƒƒãƒˆ 大ãã• -HISTORY_MSG_509;ローカル スãƒãƒƒãƒˆ 質ã®ç¨®é¡ž -HISTORY_MSG_510;ローカル スãƒãƒƒãƒˆ 境界 -HISTORY_MSG_511;ローカル スãƒãƒƒãƒˆ ã—ãã„値 -HISTORY_MSG_512;ローカル スãƒãƒƒãƒˆ ΔEã®æ¸›è¡° -HISTORY_MSG_513;ローカル スãƒãƒƒãƒˆ スコープ -HISTORY_MSG_514;ローカル スãƒãƒƒãƒˆ 構造 +HISTORY_MSG_500;ローカル - スãƒãƒƒãƒˆå½¢çж +HISTORY_MSG_501;ローカル - スãƒãƒƒãƒˆæ–¹æ³• +HISTORY_MSG_502;ローカル - SC -å½¢çŠ¶ã®æ–¹å¼ +HISTORY_MSG_503;ローカル - スãƒãƒƒãƒˆ - å³ã®åž‚ç›´ç·š +HISTORY_MSG_504;ローカル - スãƒãƒƒãƒˆ - å·¦ã®åž‚ç›´ç·š +HISTORY_MSG_505;ローカル - スãƒãƒƒãƒˆ - ä¸‹ã®æ°´å¹³ç·š +HISTORY_MSG_506;ローカル - スãƒãƒƒãƒˆ - ä¸Šã®æ°´å¹³ç·š +HISTORY_MSG_507;ローカル - スãƒãƒƒãƒˆ - 中心 +HISTORY_MSG_508;ローカル - スãƒãƒƒãƒˆ - 大ãã• +HISTORY_MSG_509;ローカル - スãƒãƒƒãƒˆ - 質ã®ç¨®é¡ž +HISTORY_MSG_510;ローカル - TG - 変移ã®ä½ç½® +HISTORY_MSG_511;ローカル - SD - ΔEスコープã®ã—ãã„値 +HISTORY_MSG_512;ローカル - SD - ΔEã®æ¸›è¡° +HISTORY_MSG_513;ローカル - スãƒãƒƒãƒˆ - 除外 - スコープ +HISTORY_MSG_514;ローカル - スãƒãƒƒãƒˆã®æ§‹é€  HISTORY_MSG_515;ローカル編集 HISTORY_MSG_516;ローカル - è‰²ã¨æ˜Žã‚‹ã• HISTORY_MSG_517;ローカル - 強力を有効ã«ã™ã‚‹ @@ -856,7 +865,7 @@ HISTORY_MSG_618;ローカル - è‰²ã¨æ˜Žã‚‹ã• マスクを使ㆠHISTORY_MSG_619;ローカル - 露光補正 マスクを使ㆠHISTORY_MSG_620;ローカル - è‰²ã¨æ˜Žã‚‹ã• ã¼ã‹ã— HISTORY_MSG_621;ローカル - 露光補正 åå¯¾å‡¦ç† -HISTORY_MSG_622;ローカル - 構造ã®é™¤å¤– +HISTORY_MSG_622;ローカル - スãƒãƒƒãƒˆ - 除外 - スãƒãƒƒãƒˆã®æ§‹é€  HISTORY_MSG_623;ローカル - 露光補正 色ã®è£œé–“ HISTORY_MSG_624;ローカル - カラー補正グリッド HISTORY_MSG_625;ローカル - 補正グリッドã®å¼·ã• @@ -879,7 +888,7 @@ HISTORY_MSG_641;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆã€€ãƒžã‚¹ã‚¯ã‚’使用 HISTORY_MSG_642;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆã€€åŠå¾„ HISTORY_MSG_643;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆã€€ã¼ã‹ã— HISTORY_MSG_644;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆã€€åå¯¾å‡¦ç† -HISTORY_MSG_645;ローカル - 色差ã®ãƒãƒ©ãƒ³ã‚¹ã€€ab-L +HISTORY_MSG_645;ローカル - SD - ab-Lã®ãƒãƒ©ãƒ³ã‚¹ HISTORY_MSG_646;ローカル - 露光補正 色度ã®ãƒžã‚¹ã‚¯ HISTORY_MSG_647;ローカル - 露光補正 ガンマã®ãƒžã‚¹ã‚¯ HISTORY_MSG_648;ローカル - 露光補正 スロープã®ãƒžã‚¹ã‚¯ @@ -893,7 +902,7 @@ HISTORY_MSG_655;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆã€€ã‚¹ãƒ­ãƒ¼ãƒ—ã®ãƒž HISTORY_MSG_656;ローカル - è‰²ã¨æ˜Žã‚‹ã• ソフトãªåŠå¾„ HISTORY_MSG_657;ローカル - レティãƒãƒƒã‚¯ã‚¹ã€€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトã®è»½æ¸› HISTORY_MSG_658;ローカル - CbDL ソフトãªåŠå¾„ -HISTORY_MSG_659;ローカル スãƒãƒƒãƒˆ å¢ƒç•Œå€¤ã®æ¸›è¡° +HISTORY_MSG_659;ローカル - TG - å¤‰ç§»ã®æ¸›è¡° HISTORY_MSG_660;ローカル - CbDL 明瞭 HISTORY_MSG_661;ローカル - CbDL 残差ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ HISTORY_MSG_662;ローカル - deNoise è¼åº¦ã€€ç´°ã‹ã„0 @@ -910,7 +919,7 @@ HISTORY_MSG_672;ローカル - CbDL マスク CL HISTORY_MSG_673;ローカル - CbDL マスクを使ㆠHISTORY_MSG_674;ローカル - 削除ã•ã‚ŒãŸæ©Ÿèƒ½ HISTORY_MSG_675;ローカル - TM ソフトãªåŠå¾„ -HISTORY_MSG_676;ローカル スãƒãƒƒãƒˆã€€å¢ƒç•Œã®å·®ç•° +HISTORY_MSG_676;ローカル - TG - 変移ã®å·®ç•° HISTORY_MSG_677;ローカル - TM é‡ HISTORY_MSG_678;ローカル - TM 彩度 HISTORY_MSG_679;ローカル - レティãƒãƒƒã‚¯ã‚¹ã€€ãƒžã‚¹ã‚¯ C @@ -1012,19 +1021,19 @@ HISTORY_MSG_780;ローカル - è‰²ã¨æ˜Žã‚‹ã• シャドウã®ãƒžã‚¹ã‚¯ HISTORY_MSG_781;ローカル - コントラスト ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã®ãƒžã‚¹ã‚¯ HISTORY_MSG_782;ローカル - Blur Denoise ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã®ãƒžã‚¹ã‚¯ HISTORY_MSG_783;ローカル - è‰²ã¨æ˜Žã‚‹ã• ウェーブレットã®ãƒ¬ãƒ™ãƒ« -HISTORY_MSG_784;ローカル - ΔEã®ãƒžã‚¹ã‚¯ -HISTORY_MSG_785;ローカル - ΔEã®ã‚¹ã‚³ãƒ¼ãƒ—ã®ãƒžã‚¹ã‚¯ +HISTORY_MSG_784;ローカル - マスク - ΔEç”»åƒã®ãƒžã‚¹ã‚¯ +HISTORY_MSG_785;ローカル - マスク - スコープ HISTORY_MSG_786;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ æ–¹å¼ HISTORY_MSG_787;ローカル - イコライザã®ä¹—æ•° HISTORY_MSG_788;ローカル - イコライザã®ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ« HISTORY_MSG_789;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ マスクã®é‡ HISTORY_MSG_790;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ マスクã®ã‚¢ãƒ³ã‚«ãƒ¼ HISTORY_MSG_791;ローカル - マスク ショートLカーブ -HISTORY_MSG_792;ローカル - マスク 背景è¼åº¦ +HISTORY_MSG_792;ローカル - マスク - 背景 HISTORY_MSG_793;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ TRCã®ã‚¬ãƒ³ãƒž HISTORY_MSG_794;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ TRCã®ã‚¹ãƒ­ãƒ¼ãƒ— HISTORY_MSG_795;ローカル - マスク 復元ã—ãŸã‚¤ãƒ¡ãƒ¼ã‚¸ã®ä¿å­˜ -HISTORY_MSG_796;ローカル - 基準値ã®ç¹°ã‚Šè¿”ã— +HISTORY_MSG_796;ローカル - SC - 繰り返ã—ã®åŸºæº– HISTORY_MSG_797;ローカル - オリジナルã¨ã®èžåˆæ–¹å¼ HISTORY_MSG_798;ローカル - ä¸é€æ˜Žåº¦ HISTORY_MSG_799;ローカル - Color RGB トーンカーブ @@ -1060,7 +1069,7 @@ HISTORY_MSG_829;ローカル - シャドウãƒã‚¤ãƒ©ã‚¤ãƒˆ 階調 角度 HISTORY_MSG_830;ローカル - è‰²ã¨æ˜Žã‚‹ã• 階調 Lã®å¼·ã• HISTORY_MSG_831;ローカル - è‰²ã¨æ˜Žã‚‹ã• 階調 角度 HISTORY_MSG_832;ローカル - è‰²ã¨æ˜Žã‚‹ã• 階調 Cã®å¼·ã• -HISTORY_MSG_833;ローカル - 減光ã®ãƒ•ã‚§ã‚¶ãƒ¼å‡¦ç† +HISTORY_MSG_833;ローカル - TG - 減光ã®ãƒ•ã‚§ã‚¶ãƒ¼å‡¦ç† HISTORY_MSG_834;ローカル - è‰²ã¨æ˜Žã‚‹ã• 減光ã®å¼·ã• H HISTORY_MSG_835;ローカル - 自然ãªå½©åº¦ 諧調 Lã®å¼·ã• HISTORY_MSG_836;ローカル - 自然ãªå½©åº¦ 階調 角度 @@ -1093,7 +1102,7 @@ HISTORY_MSG_863;ローカル - ウェーブレット 元画åƒã¨èžåˆ HISTORY_MSG_864;ローカル - ウェーブレット æ–¹å‘åˆ¥ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®æ¸›è¡° HISTORY_MSG_865;ローカル - ウェーブレット æ–¹å‘別コントラスト Δ HISTORY_MSG_866;ローカル - ウェーブレット æ–¹å‘別コントラスト 圧縮ã®ã‚¬ãƒ³ãƒž -HISTORY_MSG_868;ローカル - ΔE C-Hã®ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_868;ローカル - SD - C-Hã®ãƒãƒ©ãƒ³ã‚¹ HISTORY_MSG_869;ローカル - レベルã«ã‚ˆã‚‹ãƒŽã‚¤ã‚ºé™¤åŽ» HISTORY_MSG_870;ローカル - ウェーブレット マスク カーブH HISTORY_MSG_871;ローカル - ウェーブレット マスク カーブC @@ -1118,7 +1127,7 @@ HISTORY_MSG_890;ローカル - コントラスト ウェーブレット 階調 HISTORY_MSG_891;ローカル - コントラスト ウェーブレット 階調フィルタ HISTORY_MSG_892;ローカル - 対数符å·åŒ– 階調ã®å¼·ã• HISTORY_MSG_893;ローカル - 対数符å·åŒ– 階調ã®è§’度 -HISTORY_MSG_894;ローカル - è‰²ã¨æ˜Žã‚‹ã• ΔEã®ãƒ—レビュー +HISTORY_MSG_894;ローカル - SD - ΔEプレビューã®è‰²ã®å¼·ã• HISTORY_MSG_897;ローカル - コントラスト ウェーブレット ES å¼·ã• HISTORY_MSG_898;ローカル - コントラスト ウェーブレット ES åŠå¾„ HISTORY_MSG_899;ローカル - コントラスト ウェーブレット ES ディテール @@ -1132,7 +1141,7 @@ HISTORY_MSG_906;ローカル - コントラスト ウェーブレット ES 感 HISTORY_MSG_907;ローカル - コントラスト ウェーブレット ES 増幅 HISTORY_MSG_908;ローカル - コントラスト ウェーブレット ES 隣接 HISTORY_MSG_909;ローカル - コントラスト ウェーブレット ES 表示 -HISTORY_MSG_910;ローカル - ウェーブレット エッジ検出ã®åŠ¹æžœ +HISTORY_MSG_910;ローカル - SC - ウェーブレット エッジ検出ã®åŠ¹æžœ HISTORY_MSG_911;ローカル - ã¼ã‹ã— 色度 è¼åº¦ HISTORY_MSG_912;ローカル - ガイド付ãフィルターã®å¼·ã•ã®ã¼ã‹ã— HISTORY_MSG_913;ローカル - コントラスト ウェーブレット シグマ DR @@ -1144,10 +1153,10 @@ HISTORY_MSG_918;ローカル - ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆã®æ®‹å·®ç”»åƒ ãƒã‚¤ãƒ©ã‚¤ HISTORY_MSG_919;ローカル - ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆã®æ®‹å·®ç”»åƒ ãƒã‚¤ãƒ©ã‚¤ãƒˆã®ã—ãã„値 HISTORY_MSG_920;ローカル - ウェーブレット シグマ LC HISTORY_MSG_921;ローカル - ウェーブレット 階調ã®ã‚·ã‚°ãƒž LC2 -HISTORY_MSG_922;ローカル - 白黒ã§ã®å¤‰æ›´ +HISTORY_MSG_922;ローカル - SC - 白黒ã§ã®å¤‰æ›´ HISTORY_MSG_923;ローカル - 機能ã®è¤‡é›‘度モード HISTORY_MSG_924;--æœªä½¿ç”¨ã®æ–‡å­—列-- -HISTORY_MSG_925;ローカル - カラー機能ã®ã‚¹ã‚³ãƒ¼ãƒ— +HISTORY_MSG_925;ローカル - スコープ(カラー機能) HISTORY_MSG_926;ローカル - マスクã®ã‚¿ã‚¤ãƒ—を表示 HISTORY_MSG_927;ローカル - シャドウマスク HISTORY_MSG_928;ローカル - 共通ã®ã‚«ãƒ©ãƒ¼ãƒžã‚¹ã‚¯ @@ -1206,7 +1215,7 @@ HISTORY_MSG_981;ローカル - 対数符å·åŒ– å¼·ã• HISTORY_MSG_982;ローカル - イコライザ 色相 HISTORY_MSG_983;ローカル - ノイズ除去 ã—ãã„値マスク 明るㄠHISTORY_MSG_984;ローカル - ノイズ除去 ã—ãã„値マスク æš—ã„ -HISTORY_MSG_985;ローカル - ノイズ除去 ãƒ©ãƒ—ãƒ©ã‚¹å¤‰æ› +HISTORY_MSG_985;ローカル - ノイズ除去 ラプラス作用素 HISTORY_MSG_986;ローカル - ノイズ除去 強化 HISTORY_MSG_987;ローカル - 階調フィルタ ã—ãã„値マスク HISTORY_MSG_988;ローカル - 階調フィルタ æš—ã„領域ã®ã—ãã„値マスク @@ -1255,13 +1264,13 @@ HISTORY_MSG_1030;ローカル - レティãƒãƒƒã‚¯ã‚¹ 復元ã®ã—ãã„値 HISTORY_MSG_1031;ローカル - レティãƒãƒƒã‚¯ã‚¹ æš—ã„領域ã®ã—ãã„値マスク HISTORY_MSG_1032;ローカル - レティãƒãƒƒã‚¯ã‚¹ 明るã„領域ã®ã—ãã„値マスク HISTORY_MSG_1033;ローカル - レティãƒãƒƒã‚¯ã‚¹ 減衰 -HISTORY_MSG_1034;ローカル - ノンローカルミーン - å¼·ã• -HISTORY_MSG_1035;ローカル - ノンローカルミーン - ディテール -HISTORY_MSG_1036;ローカル - ノンローカルミーン - パッム-HISTORY_MSG_1037;ローカル - ノンローカルミーン - åŠå¾„ -HISTORY_MSG_1038;ローカル - ノンローカルミーン - ガンマ +HISTORY_MSG_1034;ローカル - éžå±€æ‰€å¹³å‡ - å¼·ã• +HISTORY_MSG_1035;ローカル - éžå±€æ‰€å¹³å‡ - ディテール +HISTORY_MSG_1036;ローカル - éžå±€æ‰€å¹³å‡ - パッム+HISTORY_MSG_1037;ローカル - éžå±€æ‰€å¹³å‡ - åŠå¾„ +HISTORY_MSG_1038;ローカル - éžå±€æ‰€å¹³å‡ - ガンマ HISTORY_MSG_1039;ローカル - 質感 - ガンマ -HISTORY_MSG_1040;ローカル - スãƒãƒƒãƒˆ - ソフトãªåŠå¾„ +HISTORY_MSG_1040;ローカル - SC - ソフトãªåŠå¾„ HISTORY_MSG_1041;ローカル - スãƒãƒƒãƒˆ - マンセル補正 HISTORY_MSG_1042;ローカル - 対数符å·åŒ– - ã—ãã„値 HISTORY_MSG_1043;ローカル - Exp - 標準化 @@ -1352,8 +1361,8 @@ HISTORY_MSG_1127;ローカル - Cie マスク ガンマ HISTORY_MSG_1128;ローカル - Cie マスク スロープ HISTORY_MSG_1129;ローカル - Cie 相対è¼åº¦ HISTORY_MSG_1130;ローカル - Cie 彩度 Jz -HISTORY_MSG_1131;ローカル - マスク 色ノイズ除去  -HISTORY_MSG_1132;ローカル - Cie ウェーブレット シグマ Jz +HISTORY_MSG_1131;ローカル - マスク - ノイズ除去  +HISTORY_MSG_1132;ローカル - Cie ウェーブレット シグマ Jz HISTORY_MSG_1133;ローカル - Cie ウェーブレット レベル Jz HISTORY_MSG_1134;ローカル - Cie ウェーブレット ローカルコントラスト Jz HISTORY_MSG_1135;ローカル - Cie ウェーブレット 明瞭 Jz @@ -1401,40 +1410,112 @@ HISTORY_MSG_DEHAZE_ENABLED;霞除去 HISTORY_MSG_DEHAZE_SATURATION;霞除去 - 彩度 HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;霞除去 - 深度マップã®è¡¨ç¤º HISTORY_MSG_DEHAZE_STRENGTH;霞除去 - å¼·ã• +HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - 明るã•ã«å¿œã˜ãŸè£œæ•´ HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;デュアルデモザイク - 自動ã—ãã„値 HISTORY_MSG_DUALDEMOSAIC_CONTRAST;AMaZE+VNG4 - コントラストã®ã—ãã„値 -HISTORY_MSG_EDGEFFECT;エッジã®åŠ¹æžœèª¿æ•´ +HISTORY_MSG_EDGEFFECT;ã‚¨ãƒƒã‚¸ã®æ¸›è¡°å¿œç­” +HISTORY_MSG_FF_FROMMETADATA;フラットフィールド - メタデータã‹ã‚‰ HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - å‚考出力 HISTORY_MSG_FILMNEGATIVE_COLORSPACE;ãƒã‚¬ãƒ•ィルムã®è‰²ç©ºé–“ HISTORY_MSG_FILMNEGATIVE_ENABLED;ãƒã‚¬ãƒ•ィルム HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - å‚考入力 HISTORY_MSG_FILMNEGATIVE_VALUES;ãƒã‚¬ãƒ•ィルムã®å€¤ -HISTORY_MSG_HISTMATCHING;トーンカーブã®è‡ªå‹•調節 +HISTORY_MSG_GAMUTMUNSEL;色域-マンセル +HISTORY_MSG_HISTMATCHING;トーンカーブã®è‡ªå‹•æ•´åˆ HISTORY_MSG_HLBL;Color è‰²ã®æ³¢åŠ - ã¼ã‹ã— -HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy +HISTORY_MSG_HLTH;インペイント オãƒãƒ¼ã‚ºãƒ‰ - ゲインã®ã—ãã„値 +HISTORY_MSG_ICL_LABGRIDCIEXY;Cie表色系 xy HISTORY_MSG_ICM_AINTENT;ã‚¢ãƒ–ã‚¹ãƒˆãƒ©ã‚¯ãƒˆãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã®æ„図 -HISTORY_MSG_ICM_BLUX;原色 ブルー X +HISTORY_MSG_ICM_BLUX;原色 ブルー X HISTORY_MSG_ICM_BLUY;原色 ブルー Y +HISTORY_MSG_ICM_CAT;カラーマトリクスã®é©å¿œ HISTORY_MSG_ICM_FBW;白黒 +HISTORY_MSG_ICM_GAMUT;è‰²åŸŸã®æŠ‘åˆ¶ HISTORY_MSG_ICM_GREX;原色 グリーン X HISTORY_MSG_ICM_GREY;原色 グリーン Y -HISTORY_MSG_ICM_OUTPUT_PRIMARIES;出力 - プライマリ +HISTORY_MSG_ICM_MIDTCIE;中間トーン +HISTORY_MSG_ICM_OUTPUT_PRIMARIES;出力 - 原色 HISTORY_MSG_ICM_OUTPUT_TEMP;出力 - ICC-v4 å…‰æº D HISTORY_MSG_ICM_OUTPUT_TYPE;出力 - タイプ HISTORY_MSG_ICM_PRESER;ãƒ‹ãƒ¥ãƒ¼ãƒˆãƒ©ãƒ«ã‚’ç¶­æŒ HISTORY_MSG_ICM_REDX;原色 レッド X HISTORY_MSG_ICM_REDY;原色 レッド Y  -HISTORY_MSG_ICM_WORKING_GAMMA;作業色空間 - ガンマ +HISTORY_MSG_ICM_REFI;色ã®å¾®èª¿æ•´ +HISTORY_MSG_ICM_SHIFTX;色ã®å¾®èª¿æ•´ - シフト x +HISTORY_MSG_ICM_SHIFTY;色ã®å¾®èª¿æ•´ - シフト y +HISTORY_MSG_ICM_SMOOTHCIE;ãƒã‚¤ãƒ©ã‚¤ãƒˆèª¿æ•´ã®æ¸›è¡° +HISTORY_MSG_ICM_TRCEXP;アブストラクトプロファイル +HISTORY_MSG_ICM_WORKING_GAMMA;TRC - ガンマ HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;è¼åº¦ã€€æ–¹å¼ HISTORY_MSG_ICM_WORKING_PRIM_METHOD;åŽŸè‰²ã€€æ–¹å¼ -HISTORY_MSG_ICM_WORKING_SLOPE;作業色空間 - å‹¾é… +HISTORY_MSG_ICM_WORKING_SLOPE;TRC - スロープ HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRCã®æ–¹å¼ -HISTORY_MSG_ILLUM;è¼åº¦ +HISTORY_MSG_ILLUM;CAL - SC - è¼åº¦ HISTORY_MSG_LOCALCONTRAST_AMOUNT;ローカルコントラスト - é‡ HISTORY_MSG_LOCALCONTRAST_DARKNESS;ローカルコントラスト - æš—ã„部分 HISTORY_MSG_LOCALCONTRAST_ENABLED;ローカルコントラスト HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;ローカルコントラスト - 明るã„部分 HISTORY_MSG_LOCALCONTRAST_RADIUS;ローカルコントラスト - åŠå¾„ +HISTORY_MSG_LOCALLAB_TE_PIVOT;ローカル - イコライザ ピボット +HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ã¼ã‹ã— コントラスト +HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ã¼ã‹ã— é«˜é€Ÿãƒ•ãƒ¼ãƒªã‚¨å¤‰æ› +HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ã¼ã‹ã— åŠå¾„ +HISTORY_MSG_LOCAL_CIEMASK_CHH; ローカル編集 Cieã®ãƒžã‚¹ã‚¯ã€€è‰²ç›¸ã‚«ãƒ¼ãƒ– +HISTORY_MSG_LOCAL_CIEMASK_HIGH;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ãƒã‚¤ãƒ©ã‚¤ãƒˆ +HISTORY_MSG_LOCAL_CIEMASK_SHAD;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ シャドウ +HISTORY_MSG_LOCAL_CIEMASK_STRU;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ 構造 +HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;機能ã¨ã—ã¦ã®Cieã®æ§‹é€ ãƒžã‚¹ã‚¯ +HISTORY_MSG_LOCAL_CIEMASK_WLC;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ウェーブレット Lc +HISTORY_MSG_LOCAL_CIEMASK_WLEV;ローカル編集 Cieã®ãƒžã‚¹ã‚¯ ウェーブレットã®ãƒ¬ãƒ™ãƒ« +HISTORY_MSG_LOCAL_CIE_ANGGRAD;ローカル編集 CIECAM - 諧調フィルタã®è§’度 +HISTORY_MSG_LOCAL_CIE_BLACKS;ローカル編集 CIECAM - ブラックã®åˆ†å¸ƒ +HISTORY_MSG_LOCAL_CIE_BLUXL;ローカル編集 CIECAM - ブルー X +HISTORY_MSG_LOCAL_CIE_BLUYL;ローカル編集 CIECAM - ブルー Y +HISTORY_MSG_LOCAL_CIE_BRICOMP;ローカル編集 CIECAM 明るã•ã®åœ§ç¸® +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;ローカル編集 CIECAM 明るã•ã®åœ§ç¸®ã®ã—ãã„値 +HISTORY_MSG_LOCAL_CIE_BWCIE;ローカル編集 CIECAM - 白黒 +HISTORY_MSG_LOCAL_CIE_CAT;マトリクスã®é©åˆ +HISTORY_MSG_LOCAL_CIE_DETAILJZ;ローカル編集 JzCzHz ローカルコントラスト +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;ローカル編集 CIECAM å…¨ã¦ã®ãƒžã‚¹ã‚¯ãƒ„ール +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;ローカル編集 CIECAM å‰å‡¦ç† +HISTORY_MSG_LOCAL_CIE_GAM;ローカル編集 CIECAM ガンマ +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;ローカル編集 CIECAM 色域 +HISTORY_MSG_LOCAL_CIE_GREXL;ローカル編集 CIECAM - グリーン X +HISTORY_MSG_LOCAL_CIE_GREYL;ローカル編集 CIECAM - グリーン Y +HISTORY_MSG_LOCAL_CIE_ILL;ローカル編集 CIECAM TRC è¼åº¦ +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;ローカル編集 CIECAM 対数符å·åŒ– Q +HISTORY_MSG_LOCAL_CIE_MIDT;ローカル編集 CIECAM 中間トーン +HISTORY_MSG_LOCAL_CIE_NORM;ローカル編集 CIECAM è¼åº¦ã®æ­£å¸¸åŒ– +HISTORY_MSG_LOCAL_CIE_PRIM;ローカル編集 CIECAM TRC 原色 +HISTORY_MSG_LOCAL_CIE_REDXL;ローカル編集 CIECAM - レッド X +HISTORY_MSG_LOCAL_CIE_REDYL;ローカル編集 CIECAM - レッド Y +HISTORY_MSG_LOCAL_CIE_REFI;ローカル編集 CIECAM 色ã®å¾®èª¿æ•´ +HISTORY_MSG_LOCAL_CIE_SATCIE;ローカル編集 CIECAM - 彩度ã®åˆ¶å¾¡ +HISTORY_MSG_LOCAL_CIE_SHIFTXL;ローカル編集 CIECAM - シフト x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;ローカル編集 CIECAM - シフト y +HISTORY_MSG_LOCAL_CIE_SIG;シグモイド +HISTORY_MSG_LOCAL_CIE_SIGADAP;ローカル編集 CIECAM シグモイドã®é©å¿œæ€§ +HISTORY_MSG_LOCAL_CIE_SIGMET;ローカル編集 CIECAM - ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®æ–¹å¼ +HISTORY_MSG_LOCAL_CIE_SLOP;ローカル編集 CIECAM - スロープ +HISTORY_MSG_LOCAL_CIE_SLOPESMO;ローカル編集 CIECAM - グレーãƒã‚¤ãƒ³ãƒˆã®ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;ローカル編集 CIECAM - ブルーã®ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;ローカル編集 CIECAM - グリーンã®ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;ローカル編集 CIECAM - レッドã®ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_LOCAL_CIE_SMOOTH;ローカル編集 CIECAM - 場颿¡ä»¶ã®Ybã®ã‚¹ã‚±ãƒ¼ãƒ« +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;ローカル編集 CIECAM - 減衰ã®åŸºæº– +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;ローカル編集 CIECAM - 観視æ¡ä»¶ã®Ybã®å°ºåº¦ +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;ローカル編集 CIECAM - レベル - 明るã•ã®ãƒ¢ãƒ¼ãƒ‰ +HISTORY_MSG_LOCAL_CIE_STRGRAD;ローカル編集 CIECAM - 諧調ã®å¼·ã• L +HISTORY_MSG_LOCAL_CIE_STRLOG;ローカル編集 CIECAM - 対数符å·åŒ–ã®å¼·ã• +HISTORY_MSG_LOCAL_CIE_TRC;ローカル編集 CIECAM - TRC +HISTORY_MSG_LOCAL_CIE_WHITES;ローカル編集 CIECAM - ホワイトã®åˆ†å¸ƒ +HISTORY_MSG_LOCAL_DEHAZE_BLACK;ローカル - 霞除去 - ブラック +HISTORY_MSG_LOCAL_GAMUTMUNSEL;ローカル - SC - 色ãšã‚Œã®å›žé¿ +HISTORY_MSG_LOCAL_LOG_BLACKS;ローカル編集 対数符å·åŒ– - ブラックã®åˆ†å¸ƒ +HISTORY_MSG_LOCAL_LOG_COMPR;ローカル編集 対数符å·åŒ– - 明るã•ã®åœ§ç¸® +HISTORY_MSG_LOCAL_LOG_SAT;ローカル編集 対数符å·åŒ– - 彩度ã®åˆ¶å¾¡ +HISTORY_MSG_LOCAL_LOG_WHITES;ローカル編集 対数符å·åŒ– - ホワイトã®åˆ†å¸ƒ +HISTORY_MSG_LOCAL_TMO_SATUR;ローカル編集 露光 Fattal 彩度 HISTORY_MSG_METADATA_MODE;メタデータ コピーモード HISTORY_MSG_MICROCONTRAST_CONTRAST;マイクロコントラスト - コントラストã®ã—ãã„値 HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - ã—ãã„値ã®è‡ªå‹•設定 @@ -1480,10 +1561,15 @@ HISTORY_MSG_SPOT_ENTRY;スãƒãƒƒãƒˆé™¤åŽ» - ãƒã‚¤ãƒ³ãƒˆå¤‰æ›´ HISTORY_MSG_TEMPOUT;CAM02/16 自動色温度設定 HISTORY_MSG_THRESWAV;ãƒãƒ©ãƒ³ã‚¹ã®ã—ãã„値 HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - アンカー +HISTORY_MSG_TONE_EQUALIZER_BANDS;トーンイコライザ - ãƒãƒ³ãƒ‰ +HISTORY_MSG_TONE_EQUALIZER_ENABLED;トーンイコライザ +HISTORY_MSG_TONE_EQUALIZER_PIVOT;トーンイコライザ - ピボット +HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;トーンイコライザ - 円滑 +HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;トーンイコライザ - トーンã®é…分 HISTORY_MSG_TRANS_METHOD;ジオメトリ - æ–¹å¼ HISTORY_MSG_WAVBALCHROM;イコライザ 色度 HISTORY_MSG_WAVBALLUM;イコライザ è¼åº¦ -HISTORY_MSG_WAVBL;レベルã®ã¼ã‹ã— +HISTORY_MSG_WAVBL;詳細レベルã®ã¼ã‹ã— HISTORY_MSG_WAVCHR;レベルã®ã¼ã‹ã— - 色度ã®ã¼ã‹ã— HISTORY_MSG_WAVCHROMCO;大ãã„ディテールã®è‰²åº¦ HISTORY_MSG_WAVCHROMFI;å°ã•ã„ディテールã®è‰²åº¦ @@ -1519,6 +1605,23 @@ HISTORY_MSG_WAVSTREND;ソフトã®å¼·ã• HISTORY_MSG_WAVTHRDEN;ローカルコントラストã®ã—ãã„値 HISTORY_MSG_WAVTHREND;ローカルコントラストã®ã—ãã„値 HISTORY_MSG_WAVUSHAMET;æ˜Žçž­ã®æ–¹å¼ +HISTORY_MSG_WBALANCE_OBSERVER10;標準観測者10° +HISTORY_MSG_WBITC_CUSTOM;Itcwb カスタム +HISTORY_MSG_WBITC_DELTA;Itcwb 色åå·®ã®Î” +HISTORY_MSG_WBITC_FGREEN;Itcwb 色åå·® - スãƒãƒ¥ãƒ¼ãƒ‡ãƒ³ãƒˆæ¤œå®š +HISTORY_MSG_WBITC_FORCE;Itcwb 強制 +HISTORY_MSG_WBITC_GREEN;色åå·®ã®å¾®èª¿æ•´ +HISTORY_MSG_WBITC_MINSIZE;最å°ã®ãƒ‘ッム+HISTORY_MSG_WBITC_NOPURPLE;Itcwb éžãƒ‘ープル +HISTORY_MSG_WBITC_OBS;2段階アルゴリズムを外㙠+HISTORY_MSG_WBITC_PONDER;Itcwb ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_WBITC_PRECIS;Itcwb 精度 +HISTORY_MSG_WBITC_PRIM;原色 +HISTORY_MSG_WBITC_RGREEN;Itcwb 色åå·®ã®ç¯„囲 +HISTORY_MSG_WBITC_SAMPLING;ローサンプリング +HISTORY_MSG_WBITC_SIZE;Itcwb サイズ +HISTORY_MSG_WBITC_SORTED;Itcwb ãƒãƒ©ãƒ³ã‚¹ +HISTORY_MSG_WBITC_THRES;Itcwb ã—ãã„値 HISTORY_NEWSNAPSHOT;追加 HISTORY_NEWSNAPSHOT_TOOLTIP;ショートカット: Alt-s HISTORY_SNAPSHOT;スナップショット @@ -1564,8 +1667,8 @@ ICCPROFCREATOR_PRIM_WIDEG;Widegamut ICCPROFCREATOR_PROF_V2;ICC v2 ICCPROFCREATOR_PROF_V4;ICC v4 ICCPROFCREATOR_SAVEDIALOG_TITLE;...ã§ICCプロファイルをä¿å­˜ -ICCPROFCREATOR_SLOPE;å‹¾é… -ICCPROFCREATOR_TRC_PRESET;トーンリプレーススカーブ +ICCPROFCREATOR_SLOPE;スロープ +ICCPROFCREATOR_TRC_PRESET;トーンリプロダクションカーブ INSPECTOR_WINDOW_TITLE;カメラ出ã—ç”»åƒ IPTCPANEL_CATEGORY;カテゴリ IPTCPANEL_CATEGORYHINT;ç”»åƒã®æ„図 @@ -1661,7 +1764,7 @@ MAIN_TAB_FAVORITES_TOOLTIP;ショートカット: Alt-u MAIN_TAB_FILTER;絞り込㿠MAIN_TAB_INSPECT;カメラ出ã—JPEG MAIN_TAB_IPTC;IPTC -MAIN_TAB_LOCALLAB;ローカル編集 +MAIN_TAB_LOCALLAB;é¸æŠžçš„ãªç·¨é›† MAIN_TAB_LOCALLAB_TOOLTIP;ショートカット Alt-o MAIN_TAB_METADATA;メタデータ MAIN_TAB_METADATA_TOOLTIP;ショートカット: Alt-m @@ -1682,7 +1785,7 @@ MAIN_TOOLTIP_PREVIEWFOCUSMASK;フォーカス・マスク表示\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_PREVIEWSHARPMASK;プレビューã§è¦‹ã‚‹ã‚·ãƒ£ãƒ¼ãƒ—ニング機能ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãƒžã‚¹ã‚¯\nショートカット: p\n\nã“ã®æ©Ÿèƒ½ãŒä½¿ãˆã‚‹ã®ã¯ã‚·ãƒ£ãƒ¼ãƒ—ãƒ‹ãƒ³ã‚°æ©Ÿèƒ½ãŒæœ‰åйã§ã€ç”»åƒãŒ100ï¼…ä»¥ä¸Šã«æ‹¡å¤§ã•れã¦ã„ã‚‹å ´åˆã ã‘ +MAIN_TOOLTIP_PREVIEWSHARPMASK;シャープニングã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãƒžã‚¹ã‚¯\nショートカット: p\n\nã“ã®æ©Ÿèƒ½ãŒä½¿ãˆã‚‹ã®ã¯ã‚·ãƒ£ãƒ¼ãƒ—ãƒ‹ãƒ³ã‚°æ©Ÿèƒ½ãŒæœ‰åйã§ã€ç”»åƒãŒ100ï¼…ä»¥ä¸Šã«æ‹¡å¤§ã•れã¦ã„ã‚‹å ´åˆã ã‘ã§ã™ MAIN_TOOLTIP_QINFO;ç”»åƒã®æƒ…å ±\nショートカット: i MAIN_TOOLTIP_SHOWHIDELP1;表示/éžè¡¨ç¤º 左パãƒãƒ«\nショートカット: l MAIN_TOOLTIP_SHOWHIDERP1;表示/éžè¡¨ç¤º å³ãƒ‘ãƒãƒ«\nショートカット: Alt-l @@ -1738,6 +1841,7 @@ PARTIALPASTE_FLATFIELDBLURRADIUS;フラットフィールド ã¼ã‹ã—åŠå¾„ PARTIALPASTE_FLATFIELDBLURTYPE;フラットフィールド ã¼ã‹ã—タイプ PARTIALPASTE_FLATFIELDCLIPCONTROL;フラットフィールド クリップコントロール PARTIALPASTE_FLATFIELDFILE;フラットフィールド ファイル +PARTIALPASTE_FLATFIELDFROMMETADATA;メタデータã‹ã‚‰ãƒ•ãƒ©ãƒƒãƒˆãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’é¸æŠž PARTIALPASTE_GRADIENT;減光フィルター PARTIALPASTE_HSVEQUALIZER;HSV イコライザ PARTIALPASTE_ICMSETTINGS;ICM 設定 @@ -1747,8 +1851,8 @@ PARTIALPASTE_LABCURVE;L*a*b* 調整 PARTIALPASTE_LENSGROUP;レンズ関係ã®è¨­å®š PARTIALPASTE_LENSPROFILE;プロファイルã•れãŸãƒ¬ãƒ³ã‚ºè£œæ­£ PARTIALPASTE_LOCALCONTRAST;ローカルコントラスト -PARTIALPASTE_LOCALLAB;ローカル編集 -PARTIALPASTE_LOCALLABGROUP;ローカル編集ã®è¨­å®š +PARTIALPASTE_LOCALLAB;é¸æŠžçš„ãªç·¨é›† +PARTIALPASTE_LOCALLABGROUP;é¸æŠžçš„ãªç·¨é›†ã®è¨­å®š PARTIALPASTE_METADATA;メタデータモード PARTIALPASTE_METAGROUP;メタデータ PARTIALPASTE_PCVIGNETTE;ビãƒãƒƒãƒˆãƒ•ィルター @@ -1785,6 +1889,7 @@ PARTIALPASTE_SHARPENMICRO;マイクロコントラスト PARTIALPASTE_SOFTLIGHT;ソフトライト PARTIALPASTE_SPOT;スãƒãƒƒãƒˆé™¤åŽ» PARTIALPASTE_TM_FATTAL;ダイナミックレンジ圧縮 +PARTIALPASTE_TONE_EQUALIZER;トーンイコライザ PARTIALPASTE_VIBRANCE;自然ãªå½©åº¦ PARTIALPASTE_VIGNETTING;周辺光é‡è£œæ­£ PARTIALPASTE_WHITEBALANCE;ホワイトãƒãƒ©ãƒ³ã‚¹ @@ -1794,7 +1899,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;カラーピッカーã®ãƒ•ォント PREFERENCES_APPEARANCE_CROPMASKCOLOR;切り抜ãã®ãƒžã‚¹ã‚¯ã‚«ãƒ©ãƒ¼ PREFERENCES_APPEARANCE_MAINFONT;メインフォント PREFERENCES_APPEARANCE_NAVGUIDECOLOR;ナビゲーターã®ã‚¬ã‚¤ãƒ‰ã‚«ãƒ©ãƒ¼ -PREFERENCES_APPEARANCE_PSEUDOHIDPI;擬似HiDPIモード PREFERENCES_APPEARANCE_THEME;テーマ PREFERENCES_APPLNEXTSTARTUP;è¦å†èµ·å‹• PREFERENCES_AUTOMONPROFILE;OSã®ãƒ¡ã‚¤ãƒ³ãƒ¢ãƒ‹ã‚¿ãƒ¼ãƒ»ãƒ—ロファイルを使用 @@ -1802,9 +1906,12 @@ PREFERENCES_AUTOSAVE_TP_OPEN;ãƒ—ãƒ­ã‚°ãƒ©ãƒ çµ‚äº†æ™‚ã®æ©Ÿèƒ½ãƒ‘ãƒãƒ«ã®é–‹é–‰ PREFERENCES_BATCH_PROCESSING;ãƒãƒƒãƒå‡¦ç† PREFERENCES_BEHADDALL;ã™ã¹ã¦ '追加' PREFERENCES_BEHADDALLHINT;ã™ã¹ã¦ã®ãƒ‘ラメータを 追加モードã«ã—ã¾ã™\nãƒãƒƒãƒãƒ„ールパãƒãƒ«ã§è¨­å®šã•れる調整値ãŒã€å„ç”»åƒã®æ—¢å®šå€¤ã«åŠ ç®—ã•れã¾ã™ -PREFERENCES_BEHAVIOR;ビヘイビア +PREFERENCES_BEHAVIOR;作用 PREFERENCES_BEHSETALL;ã™ã¹ã¦ '設定' PREFERENCES_BEHSETALLHINT;ã™ã¹ã¦ã®ãƒ‘ラメータを 設定モードã«ã—ã¾ã™\nãƒãƒƒãƒãƒ„ールパãƒãƒ«ã§è¨­å®šã•れる調整値ãŒã€å„ç”»åƒã®æ—¢å®šå€¤ã«å–ã£ã¦ä»£ã‚りåŒä¸€ã«ãªã‚Šã¾ã™ +PREFERENCES_BROWSERECURSIVEDEPTH;サブフォルダ階層数ã®ãƒ–ラウズ +PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;サブフォルダをブラウズã™ã‚‹éš›ã¯ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã«å¾“ㆠ+PREFERENCES_BROWSERECURSIVEMAXDIRS;ã‚µãƒ–ãƒ•ã‚©ãƒ«ãƒ€ã®æœ€å¤§æ•° PREFERENCES_CACHECLEAR;クリア PREFERENCES_CACHECLEAR_ALL;cacheã«å…¥ã‚Œã‚‰ã‚ŒãŸãƒ•ァイルを全ã¦ã‚¯ãƒªã‚¢: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;cacheã«å…¥ã‚ŒãŸå‡¦ç†ãƒ—ロファイル以外をクリア: @@ -1813,6 +1920,7 @@ PREFERENCES_CACHECLEAR_SAFETY;casheã«å…¥ã‚ŒãŸãƒ•ァイルã ã‘をクリア。 PREFERENCES_CACHEMAXENTRIES;cacheã«å…¥ã‚Œã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¤§æ•° PREFERENCES_CACHEOPTS;cache オプション PREFERENCES_CACHETHUMBHEIGHT;サムãƒã‚¤ãƒ«ç¸¦ã®æœ€å¤§å€¤ +PREFERENCES_CAMERAPROFILESDIR;カメラプロファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª PREFERENCES_CHUNKSIZES;スレッドã”ã¨ã®ã‚¿ã‚¤ãƒ« PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE デモザイク PREFERENCES_CHUNKSIZE_RAW_CA;Raw 色åŽå·®è£œæ­£ @@ -1868,6 +1976,11 @@ PREFERENCES_EXTEDITOR_DIR_CUSTOM;カスタム PREFERENCES_EXTEDITOR_DIR_TEMP;OS 一時ディレクトリ PREFERENCES_EXTEDITOR_FLOAT32;32-ビット æµ®å‹•å°æ•°ç‚¹TIFF出力 PREFERENCES_EXTERNALEDITOR;外部エディタ +PREFERENCES_EXTERNALEDITOR_CHANGE;アプリケーションã®å¤‰æ›´ +PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;実行ファイルã®å¤‰æ›´ +PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;コマンド +PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;åå‰ +PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;ãƒã‚¤ãƒ†ã‚£ãƒ–コマンド PREFERENCES_FBROWSEROPTS;ファイルブラウザ/サムãƒã‚¤ãƒ«ã®ã‚ªãƒ—ション PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;ファイルブラウザã®ãƒ„ールãƒãƒ¼ã‚’圧縮 PREFERENCES_FLATFIELDFOUND;検出 @@ -1895,13 +2008,23 @@ PREFERENCES_INTENT_SATURATION;彩度 PREFERENCES_INTERNALTHUMBIFUNTOUCHED;rawãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªç·¨é›†ã®å ´åˆ JPEGã®ã‚µãƒ ãƒã‚¤ãƒ«ã‚’表示 PREFERENCES_LANG;言語 PREFERENCES_LANGAUTODETECT;OSã®è¨€èªžè¨­å®šã‚’使用 +PREFERENCES_LENSFUNDBDIR;Lensfunã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_LENSFUNDBDIR_TOOLTIP;ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯Lensfunã®ãƒ‡ãƒ¼ã‚¿ã‚’å«ã‚“ã§ã„ã¾ã™ã€‚デフォルトã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’使ã†ãŸã‚ã«ç©ºã®ã¾ã¾ã«ã—ã¦ãŠãã¾ã™ã€‚ +PREFERENCES_LENSPROFILESDIR;レンズプロファイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª +PREFERENCES_LENSPROFILESDIR_TOOLTIP;ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯Adobeã®ãƒ¬ãƒ³ã‚ºã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ï¼ˆLCP)ã®ãƒ‡ãƒ¼ã‚¿ã‚’å«ã‚“ã§ã„ã¾ã™ã€‚Directory containing Adobe Lens Correction Profiles (LCPs) PREFERENCES_MAXRECENTFOLDERS;ç›´è¿‘ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã®æœ€å¤§æ•° +PREFERENCES_MAX_ZOOM_TITLE;最大拡大率 PREFERENCES_MENUGROUPEXTPROGS;"..ã§é–‹ã"ã®ã‚°ãƒ«ãƒ¼ãƒ— PREFERENCES_MENUGROUPFILEOPERATIONS;"ファイルæ“作"ã®ã‚°ãƒ«ãƒ¼ãƒ— PREFERENCES_MENUGROUPLABEL;"カラーラベル"ã®ã‚°ãƒ«ãƒ¼ãƒ— PREFERENCES_MENUGROUPPROFILEOPERATIONS;"処ç†ãƒ—ロファイルæ“作"ã®ã‚°ãƒ«ãƒ¼ãƒ— PREFERENCES_MENUGROUPRANK;"ランキング"ã®ã‚°ãƒ«ãƒ¼ãƒ— -PREFERENCES_MENUOPTIONS;メニューオプションã®çŠ¶æ³ +PREFERENCES_MENUOPTIONS;コンテキストメニューã®ã‚ªãƒ—ション +PREFERENCES_METADATA;メタデータ +PREFERENCES_METADATA_SYNC;XMPサイドカーã¨åŒæœŸã—ã¦ã„るメタデータ +PREFERENCES_METADATA_SYNC_NONE;オフ +PREFERENCES_METADATA_SYNC_READ;読ã¿è¾¼ã¿ã ã‘ +PREFERENCES_METADATA_SYNC_READWRITE;åŒæ–¹å‘ PREFERENCES_MONINTENT;デフォルトã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚¤ãƒ³ãƒ†ãƒ³ãƒˆ PREFERENCES_MONITOR;モニター PREFERENCES_MONPROFILE;デフォルトã®ãƒ¢ãƒ‹ã‚¿ãƒ¼ãƒ—ロファイル @@ -1961,10 +2084,12 @@ PREFERENCES_SND_HELP;ファイルパスを入力 ã¾ãŸã¯ç©ºæ¬„(無音).\nWindo PREFERENCES_SND_LNGEDITPROCDONE;ç·¨é›†å‡¦ç† çµ‚äº† PREFERENCES_SND_QUEUEDONE;ã‚­ãƒ¥ãƒ¼å‡¦ç† çµ‚äº† PREFERENCES_SND_THRESHOLDSECS;数秒後 +PREFERENCES_SPOTLOC;ローカル編集ã®ã‚¹ãƒãƒƒãƒˆã®æ–¹å¼ã‚’決ã‚ã‚‹ PREFERENCES_STARTUPIMDIR;起動時ã®ç”»åƒãƒ»ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª PREFERENCES_TAB_BROWSER;ファイルブラウザ PREFERENCES_TAB_COLORMGR;カラーマãƒã‚¸ãƒ¡ãƒ³ãƒˆ PREFERENCES_TAB_DYNAMICPROFILE;ダイナミックプロファイルã®è¦å®š +PREFERENCES_TAB_FAVORITES;ãŠæ°—ã«å…¥ã‚Šã®æ©Ÿèƒ½ PREFERENCES_TAB_GENERAL;一般 PREFERENCES_TAB_IMPROC;ç”»åƒå‡¦ç† PREFERENCES_TAB_PERFORMANCE;パフォーマンス @@ -1973,10 +2098,32 @@ PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;埋ã‚è¾¼ã¾ã‚Œã¦ã„ã‚‹JPEGã®ãƒ—レビュ PREFERENCES_THUMBNAIL_INSPECTOR_MODE;表示ã™ã‚‹ç”»åƒ PREFERENCES_THUMBNAIL_INSPECTOR_RAW;ニュートラルãªrawレンダリング PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;埋ã‚è¾¼ã¾ã‚Œã¦ã„ã‚‹JPEGãŒãƒ•ルサイズã®å ´åˆã€æŒ‡å®šãŒãªã‘れã°ãƒ‹ãƒ¥ãƒ¼ãƒˆãƒ©ãƒ«ãªrawレンダリングã§è¡¨ç¤º -PREFERENCES_TP_LABEL;ツール パãƒãƒ«: +PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;サムãƒã‚¤ãƒ«ã®ãƒ©ãƒ³ã‚¯ã¨è‰²ã‚’XMPサイドカーã‹ã‚‰èª­ã¿è¾¼ã‚€ã€æˆ–ã„ã¯ã‚µã‚¤ãƒ‰ã‚«ãƒ¼ã«ä¿å­˜ã™ã‚‹ +PREFERENCES_TOOLPANEL_AVAILABLETOOLS;使用å¯èƒ½ãªæ©Ÿèƒ½ +PREFERENCES_TOOLPANEL_CLONE_FAVORITES;ãŠæ°—ã«å…¥ã‚Šã®æ©Ÿèƒ½ã‚’å…ƒã®å ´æ‰€ã«ã‚‚ä¿æŒã™ã‚‹ +PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;ã“れを設定ã™ã‚‹ã¨ã€ãŠæ°—ã«å…¥ã‚Šã®æ©Ÿèƒ½ãŒãŠæ°—ã«å…¥ã‚Šã®ã‚¿ãƒ–ã¨ç‹¬è‡ªã®ã‚¿ãƒ–ã®ä¸¡æ–¹ã«è¡¨ç¤ºã•れã¾ã™ã€‚\n\n注æ„: ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã¨ã‚¿ãƒ–を切り替ãˆã‚‹éš›ã«è‹¥å¹²ã®é…れãŒç”Ÿã˜ã‚‹å ´åˆãŒã‚りã¾ã™ã€‚ +PREFERENCES_TOOLPANEL_FAVORITE;ãŠæ°—ã«å…¥ã‚Š +PREFERENCES_TOOLPANEL_FAVORITESPANEL;ãŠæ°—ã«å…¥ã‚Šã®ãƒ‘ãƒãƒ« +PREFERENCES_TOOLPANEL_TOOL;機能 +PREFERENCES_TP_LABEL;機能パãƒãƒ«: PREFERENCES_TP_VSCROLLBAR;ツールパãƒãƒ«ã®åž‚直スクロールãƒãƒ¼ã‚’éš ã™ PREFERENCES_USEBUNDLEDPROFILES;付属ã®ãƒ—ロファイルを使用 +PREFERENCES_WBA;ホワイトãƒãƒ©ãƒ³ã‚¹ +PREFERENCES_WBACORR;自動ホワイトãƒãƒ©ãƒ³ã‚¹ - 色温度ã®ç›¸é–¢é–¢ä¿‚ +PREFERENCES_WBACORR_TOOLTIP;ç”»åƒï¼ˆrawファイルã®å½¢å¼ã€æ¸¬è‰²ãªã©ï¼‰ã«å¿œã˜ã¦ã€ã“れらã®è¨­å®šã§ “色温度ã®ç›¸é–¢é–¢ä¿‚â€ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’é©åˆã•ã›ã€ç·åˆçš„ã«è¦‹ã¦æœ€è‰¯ã®çµæžœã‚’求ã‚ã¾ã™ã€‚ãã®ãŸã‚ã®å„ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿èª¿æ•´ã«æ±ºã‚られãŸè¦å‰‡ã¯ç‰¹ã«ã‚りã¾ã›ã‚“。\n\n設定パラメータã¯3種類ã‚りã¾ã™ï¼š\n*インターフェイスã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè¨­å®šã™ã‚‹ã‚‚ã®ã€‚\n*å„pp3ファイルã‹ã‚‰èª­ã¿è¾¼ã‚€ã‚‚ã®ï¼šItcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false(詳ã—ãã¯RawPediaã‚’å‚照)\n*オプションファイルã§è¨­å®šã™ã‚‹ã‚‚ã®ï¼ˆRawPediaã‚’å‚照)\nçµæžœã«å¯¾ã™ã‚‹è£œæ­£ã§ã€â€œè‡ªå‹•ホワイトãƒãƒ©ãƒ³ã‚¹ã€€ãƒã‚¤ã‚¢ã‚¹â€ã‚„“色åå·®ã®å¾®èª¿æ•´â€ã‚’使ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ã“れらを調整ã™ã‚‹ã¨è‰²æ¸©åº¦ã€è‰²åå·®ã€ç›¸é–¢é–¢ä¿‚ãŒæ–°ãŸã«è¨ˆç®—ã•れã¾ã™ã€‚\n\n‘相関関係係数’ã€â€˜è‰²åº¦ã®ãƒ‘ッãƒâ€™ã€â€˜Î”E’ã®ï¼“ã¤ã®æŒ‡æ¨™ã¯ã€ã‚ãã¾ã§å‚考情報ã§å¤‰æ›´ã™ã‚‹ã“ã¨ã¯å‡ºæ¥ã¾ã›ã‚“。ã©ã‚Œã‹ä¸€ã¤ã®æŒ‡æ¨™ãŒè‰¯ã„ã‹ã‚‰ã¨è¨€ã£ã¦ã€çµæžœãŒè‰¯ããªã‚‹ã‚ã‘ã§ã¯ãªã„ã‹ã‚‰ã§ã™ã€‚ +PREFERENCES_WBAENA;自動ホワイトãƒãƒ©ãƒ³ã‚¹ã®è‰²æ¸©åº¦ã®ç›¸é–¢é–¢ä¿‚設定を表示ã™ã‚‹ +PREFERENCES_WBAENACUSTOM;カスタムã®è‰²æ¸©åº¦ã¨è‰²å差を使ㆠ+PREFERENCES_WBAFORC;追加的アルゴリズムã®å¼·åˆ¶ä½¿ç”¨ +PREFERENCES_WBAGREENDELTA;色åå·®ã®ç¹°ã‚Šè¿”ã—計算ã«ãŠã‘る色温度ã®Î” (追加的アルゴリズムを有効ã«ã—ãŸå ´åˆ) +PREFERENCES_WBANOPURP;パープルを使ã‚ãªã„ +PREFERENCES_WBAPATCH;ç”»åƒã§ä½¿ã‚ã‚Œã‚‹è‰²æ•°ã®æœ€å¤§å€¤ +PREFERENCES_WBAPRECIS;精度ã®é«˜ã„アルゴリズム - スケールを使ㆠ+PREFERENCES_WBASIZEREF;ヒストグラムカラーã®å¤§ãã•ã¨æ¯”較ã—ãŸåŸºæº–色ã®å¤§ãã• +PREFERENCES_WBASORT;ヒストグラムã®ä»£ã‚りã«è‰²åº¦ã®é †ã§ä¸¦ã¹æ›¿ãˆã‚‹ PREFERENCES_WORKFLOW;レイアウト +PREFERENCES_XMP_SIDECAR_MODE;XMP ã‚µã‚¤ãƒ‰ã‚«ãƒ¼å½¢å¼ +PREFERENCES_XMP_SIDECAR_MODE_EXT;darktableã«ä¼¼ãŸå½¢å¼(FILENAME.ext.xmp for FILENAME.ext) +PREFERENCES_XMP_SIDECAR_MODE_STD;標準 (FILENAME.xmp for FILENAME.ext) PREFERENCES_ZOOMONSCROLL;スクロールを使ã£ã¦ç”»åƒã®æ‹¡å¤§ãƒ»ç¸®å° PROFILEPANEL_COPYPPASTE;コピーã™ã‚‹ãƒ‘ラメータ PROFILEPANEL_GLOBALPROFILES;付属ã®ãƒ—ロファイル @@ -2025,21 +2172,43 @@ QINFO_PIXELSHIFT;ピクセルシフト / %2 フレーム QUEUE_AUTOSTART;オートスタート QUEUE_AUTOSTART_TOOLTIP;æ–°ã—ã„rawファイルãŒé€ã‚‰ã‚Œã¦æ¥ãŸã‚‰è‡ªå‹•çš„ã«ç¾åƒå‡¦ç†ã‚’é–‹å§‹ã—ã¾ã™ QUEUE_DESTFILENAME;パスã¨ãƒ•ァイルå +QUEUE_DESTPREVIEW_TITLE;移動先ã®ãƒ‘スを表示ã™ã‚‹ãŸã‚ã«ã‚µãƒ ãƒã‚¤ãƒ«ã‚’ã“ã“ã§é¸æŠž +QUEUE_DESTPREVIEW_TOOLTIP;最åˆã«é¸æŠžã—ãŸç”»åƒã®ç§»å‹•å…ˆã®ãƒ‘スãŒã“ã“ã«è¡¨ç¤ºã•れã¾ã™ QUEUE_FORMAT_TITLE;ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ QUEUE_LOCATION_FOLDER;フォルダã«ä¿å­˜ QUEUE_LOCATION_TEMPLATE;テンプレートを使ㆠ-QUEUE_LOCATION_TEMPLATE_TOOLTIP;æ¬¡ã®æ›¸å¼æ–‡å­—を使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™:\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 +QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;ロケーションテンプレートã®ä½œæˆã«é–¢ã™ã‚‹ãƒ˜ãƒ«ãƒ—パãƒãƒ«ã‚’表示/éžè¡¨ç¤ºã—ã¾ã™ +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;出力画åƒã‚’元画åƒã¨ä¸¦ã¹ã¦ä¿å­˜ã—ãŸã„å ´åˆã¯ã€æ¬¡ã®ã‚ˆã†ã«æ›¸ãã¾ã™ï¼š \n%p1/%f\n\n出力画åƒã‚’元画åƒã®ãƒ•ォルダã®ä¸­ã«ã‚ã‚‹'converted'ã¨ã„ã†ãƒ•ァルダã«ä¿å­˜ã—ãŸã„å ´åˆã¯ã€æ¬¡ã®ã‚ˆã†ã«æ›¸ãã¾ã™ï¼š \n%p1/converted/%f\n\n出力画åƒã‚’\n'/home/tom/photos/converted/2010-10-31',ã«ä¿å­˜ã—ãŸã„å ´åˆã¯æ¬¡ã®ã‚ˆã†ã«æ›¸ãã¾ã™ï¼š \n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;共通例 +QUEUE_LOCATION_TEMPLATE_HELP_INTRO;出力ã®ãƒ†ãƒ³ãƒ—レートフィールドã¯ç§»å‹•å…ˆã®ãƒ•ォルダやファイルãƒãƒ¼ãƒ ã‚’柔軟ã«ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚%ã§å§‹ã¾ã‚‹ç‰¹å®šã®æŒ‡å®šå­ã‚’å«ã‚ã‚‹ã¨ã€å„ファイルãŒä¿å­˜ã•れる際ã«ãƒ—ログラムã«ã‚ˆã‚Šç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚\n\n以下ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã§æŒ‡å®šå­ã®å„種類を説明ã—ã¾ã™ +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;ã“ã®ãƒ‘スåを例ã¨ã—ã¦ä½¿ã†ã¨: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;æ›¸å¼æ–‡å­—åˆ—ã®æ„味ã¯: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;Linuxã®å ´åˆã¯ã€/home/tom/photos/2010-10-31/photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;Windowsã®å ´åˆã¯D:\tom\photos\2010-10-31\photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;%dN〠%d-N〠%pN〠%p-N〠%PN åŠã³ %P-N (N ã¯1ã‹ã‚‰ï¼™) ã®æŒ‡å®šå­ã¯ç”»åƒãƒ•ァイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ‘スã®è¦ç´ ã«ã‚ˆã‚Šç½®ãæ›ãˆã‚‰ã‚Œã¾ã™\næ›¸å¼æŒ‡å®šå­ã¯æ¬¡ã®ã‚ˆã†ã«åƒãã¾ã™:\n %dN ã¯ãƒ‘ã‚¹ã®æœ€å¾Œã‹ã‚‰N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n %d-Nã¯ãƒ‘スã®åˆã‚ã‹ã‚‰N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n %pN ã¯ãƒ‘ã‚¹ã®æœ€å¾Œã‹ã‚‰N番目ã¾ã§ã®å…¨ã¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n %p-N ã¯ãƒ‘ã‚¹ã®æœ€åˆã®N個ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n %PN ã¯ãƒ‘ã‚¹ã®æœ€å¾Œã®N個ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n %P-N ã¯ãƒ‘スã®N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆã‹ã‚‰æœ€å¾Œã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¾ã§\n %f ã¯ãƒ™ãƒ¼ã‚¹ãƒãƒ¼ãƒ (æ‹¡å¼µå­ãªã—) +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;Windowsã®ãƒ‘スã¯ã€%d-1ãŒãƒ‰ãƒ©ã‚¤ãƒ–レターã¨ã‚³ãƒ­ãƒ³ã€%d-2ãŒãƒ‰ãƒ©ã‚¤ãƒ–ã®ãƒ™ãƒ¼ã‚¹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨ãªã‚Šã¾ã™ +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;ディレクトリã¨éƒ¨åˆ†çš„パス +QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r ã¯å†™çœŸã®ãƒ©ãƒ³ã‚¯ã§ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚写真ã«ãƒ©ãƒ³ã‚¯ãŒç„¡ã„å ´åˆã«ã¯'0'ãŒä½¿ã‚れã¾ã™ã€‚写真ãŒã‚´ãƒŸç®±ã«ã‚ã‚‹å ´åˆã¯ã€'x'ãŒä½¿ã‚れã¾ã™ã€‚ +QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;ランク +QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2番目ã®çµæžœã¯ç•°ãªã‚Šã¾ã™: +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1ã‹ã‚‰%s9 ã¯ãƒãƒƒãƒå‡¦ç†ãŒå§‹ã¾ã£ãŸæ™‚点ã§ã®ã‚­ãƒ¥ãƒ¼ã«ãŠã‘ã‚‹ç”»åƒã®å½“åˆã®ä½ç½®ã§ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚数値ã¯ãƒ‘ディングを指定ã—ã¾ã™ã€ä¾‹ãˆã°%s3ã¯'001'ã¨ãªã‚Šã¾ã™ã€‚ +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;キューã«ãŠã‘ã‚‹ä½ç½®ã¨é †ç•ª +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;テンプレートã§ã¯ï¼“ã¤ã®ç•°ãªã‚‹æ—¥ä»˜/時間ã®å€¤ãŒä½¿ãˆã¾ã™:\n %tE"%Y-%m-%d" ã¯æ›¸ã出ã—ãŒè¡Œã‚ã‚ŒãŸæ—¥æ™‚ \n %tF"%Y-%m-%d"ã¯ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœ€å¾Œã«ä¿å­˜ã•ã‚ŒãŸæ—¥æ™‚\n %tP"%Y-%m-%d" ã¯å†™çœŸãŒæ’®å½±ã•ã‚ŒãŸæ—¥æ™‚\n引用符ãŒä»˜ã‘ã‚‰ã‚ŒãŸæ–‡å­—åˆ—ã¯æ—¥ä»˜æˆ–ã„ã¯æ™‚é–“ã®æ›¸å¼ã‚’定義ã—ã¾ã™ã€‚%tF"%Y-%m-%d"ã¨ã„ã†æ›¸å¼æ–‡å­—列ã¯ãã®ï¼‘例ã§ã™ã€‚文字列ã¯g_date_time_format ã§æŒ‡å®šã•れãŸå…¨ã¦ã®æ–‡å­—列を使ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚https://docs.gtk.org/glib/method.DateTime.format.html +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;æ—¥ä»˜ã¨æ™‚é–“ +QUEUE_LOCATION_TEMPLATE_HELP_TITLE;出力テンプレートã®ä½œæˆ +QUEUE_LOCATION_TEMPLATE_TOOLTIP;ãã®å…ƒç”»åƒã®ã‚る場所ã€ãã®ç”»åƒã®ãƒ©ãƒ³ã‚¯ã€ãã®ç”»åƒãŒã‚´ãƒŸç®±ã«å…¥ã£ã¦ã„ã‚‹ã‹ã©ã†ã‹ã€æˆ–ã„ã¯ã€ãã®ç”»åƒãŒã‚­ãƒ¥ãƒ¼ã®ã©ã“ã«ã‚ã‚‹ã‹ã«å¿œã˜ã¦ã€å‡ºåŠ›ã®å ´æ‰€ã‚’明記ã—ã¾ã™ã€‚ \n\n%dN, %d-N, %pN, %p-N, %PN åŠã³ %P-N (N = 1..9) ã¯ç”»åƒãƒ•ァイルã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ‘スã®ã‚¨ãƒ¬ãƒ¡ãƒ³ãƒˆã«ã‚ˆã£ã¦ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ï¼ˆãƒ•ァイルãƒãƒ¼ãƒ ã¯å«ã¿ã¾ã›ã‚“):\n%dN =ãƒ‘ã‚¹ã®æœ€å¾Œã‹ã‚‰N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%d-N =ãƒ‘ã‚¹ã®æœ€åˆã‹ã‚‰N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%pN =ãƒ‘ã‚¹ã®æœ€å¾Œã‹ã‚‰N番目ã¾ã§ã®ã™ã¹ã¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%p-N =パスã®ä¸­ã®æœ€åˆã®N個ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%PN = パスã®ä¸­ã®æœ€å¾Œã®N個ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%P-N =パスã®ä¸­ã®N番目ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªæœ€å¾Œã¾ã§ã®ã™ã¹ã¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n%f = ベースファイルå(拡張å­ã¯å…¥ã‚Œãªã„)\nWindowsã®ãƒ‘スã§ã¯ã€%d-1ã¯ãƒ‰ãƒ©ã‚¤ãƒ–レターã¨ã‚³ãƒ­ãƒ³, %d-2 ã¯ãã®ãƒ‰ãƒ©ã‚¤ãƒ–ã®ãƒ™ãƒ¼ã‚¹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ãªã‚Šã¾ã™ã€‚\n\n一例ã¨ã—ã¦ä»¥ä¸‹ã®ãƒ‘スãƒãƒ¼ãƒ ã‚’使ã„ã¾ã™:\n/home/tom/photos/2010-10-31/photo1.raw\nãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã®æ–‡å­—åˆ—ã®æ„味ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™ï¼š\n%d4 = %d-1 = home\n%d3 = %d-2 = tom\n%d2 = %d-3 = photos\n%d1 = %d-4 = 2010-10-31\n%p1 = %p-4 = /home/tom/photos/2010-10-31/\n%p2 = %p-3 = /home/tom/photos/\n%p3 = %p-2 = /home/tom/\n%p4 = %p-1 = /home/\n%P1 = %P-4 = 2010-10-31/\n%P2 = %P-3 = photos/2010-10-31/\n%P3 = %P-2 = tom/photos/2010-10-31/\n%P4 = %P-1 = /home/tom/photos/2010-10-31/\n%f = photo1\n\n%rã¯ç”»åƒã®ãƒ©ãƒ³ã‚¯ã«ã‚ˆã‚Šç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚ç”»åƒã«ãƒ©ãƒ³ã‚¯ãŒä»˜ã„ã¦ã„ãªã„å ´åˆã¯ã€0'ãŒä½¿ã‚れã¾ã™ã€‚ ç”»åƒãŒã‚´ãƒŸç®±ã®ä¸­ã«ã‚ã‚‹å ´åˆã¯'x'ãŒä½¿ã‚れã¾ã™ã€‚\n\n%s1ã‹ã‚‰%s9 ã¯ã‚­ãƒ¥ãƒ¼ãŒå§‹ã¾ã£ãŸæ™‚ã®ç”»åƒã®å…ƒã€…ã®å ´æ‰€ã§ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚数値ã¯ãƒ‘ディングを指定ã—ã¾ã™ã€‚例ãˆã°ã€%s3 ã¨ã—ãŸå ´åˆã¯ã€çµæžœãŒ'001'ã®ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚\n\n出力画åƒã‚’元画åƒã«ä¸¦ã¹ã¦ä¿å­˜ã—ãŸã„ã®ã§ã‚れã°ã€æ¬¡ã®ã‚ˆã†ã«è¨˜è¿°ã—ã¾ã™ï¼š\n%p1/%f\n\n出力画åƒã‚’元画åƒã®ãƒ•ォルダー内ã«ã‚ã‚‹'converted'ã¨ã„ã†åå‰ã®ãƒ•ォルダーã«ä¿å­˜ã—ãŸã„å ´åˆã¯æ¬¡ã®ã‚ˆã†ã«è¨˜è¿°ã—ã¾ã™ï¼š \n%p1/converted/%f\n\n出力画åƒã‚’\n'/home/tom/photos/converted/2010-10-31',ã¨ã„ã†ãƒ•ォルダーã«ä¿å­˜ã—ãŸã„å ´åˆã¯ã€æ¬¡ã®ã‚ˆã†ã«è¨˜è¿°ã—ã¾ã™:\n%p-3/converted/%P-4/%f QUEUE_LOCATION_TITLE;出力ã®å ´æ‰€ QUEUE_STARTSTOP_TOOLTIP;キューã«ã‚ã‚‹ç”»åƒã®ç¾åƒã‚’å§‹ã‚ã‚‹ã€æˆ–ã„ã¯ä¸­æ­¢ã™ã‚‹\n\nショートカット: Ctrl+s SAMPLEFORMAT_0;データ形å¼ä¸æ˜Ž -SAMPLEFORMAT_1;符å·ãªã—8ビット -SAMPLEFORMAT_2;符å·ãªã—16ビット -SAMPLEFORMAT_4;LogLuv24ビット -SAMPLEFORMAT_8;LogLuv32ビット +SAMPLEFORMAT_1;8ビット符å·ãªã— +SAMPLEFORMAT_2;16ビット符å·ãªã— +SAMPLEFORMAT_4;24ビットLogLuv +SAMPLEFORMAT_8;32ビットLogLuv SAMPLEFORMAT_16;16ãƒ“ãƒƒãƒˆæµ®å‹•å°æ•°ç‚¹ SAMPLEFORMAT_32;24ãƒ“ãƒƒãƒˆæµ®å‹•å°æ•°ç‚¹ SAMPLEFORMAT_64;32ãƒ“ãƒƒãƒˆæµ®å‹•å°æ•°ç‚¹ SAVEDLG_AUTOSUFFIX;ファイルãŒå­˜åœ¨ã™ã‚‹å ´åˆã€è‡ªå‹•çš„ã«æœ«å°¾ã«æ–‡å­—を加ãˆã‚‹ +SAVEDLG_BIGTIFF;BigTIFF (メタデータã®ã‚µãƒãƒ¼ãƒˆãªã—) SAVEDLG_FILEFORMAT;ãƒ•ã‚¡ã‚¤ãƒ«å½¢å¼ SAVEDLG_FILEFORMAT_FLOAT;æµ®å‹•å°æ•°ç‚¹ SAVEDLG_FORCEFORMATOPTS;強制ä¿å­˜ã‚ªãƒ—ション @@ -2059,12 +2228,23 @@ SAVEDLG_WARNFILENAME;ファイルã«åå‰ãŒä»˜ã‘られã¾ã™ SHCSELECTOR_TOOLTIP;ã“ã®3ã¤ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã®ä½ç½®ã‚’リセットã™ã‚‹ã«ã¯\nマウスã®å³ãƒœã‚¿ãƒ³ã‚’クリック SOFTPROOF_GAMUTCHECK_TOOLTIP;有効ã«ã™ã‚‹ã¨ã€å‡ºåŠ›ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã®è‰²åŸŸã‹ã‚‰å¤–れãŸè‰²ã®ãƒ”クセルをグレーã§è¡¨ç¤ºã—ã¾ã™ SOFTPROOF_TOOLTIP;ソフトプルーフィング\n有効ã«ã™ã‚‹ã¨ã€ICMツールã®å‡ºåŠ›ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä½¿ã£ãŸç–‘似的ãªãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã‚’行ã„ã¾ã™ã€‚å°åˆ·ã—ãŸå ´åˆãªã©ã®ç”»åƒã®å°è±¡ã‚’掴むã®ã«å¤§å¤‰ä¾¿åˆ©ã§ã™ã€‚ +SORT_ASCENDING;昇順 +SORT_BY_DATE;日付順 +SORT_BY_EXIF;EXIFé † +SORT_BY_LABEL;カラーラベル順 +SORT_BY_NAME;åå‰é † +SORT_BY_RANK;ランク順 +SORT_DESCENDING;é™é † +TC_LOCALLAB_PRIM_SHIFTX;シフト x +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;“色ã®å¾®èª¿æ•´â€ã¨ä½µç”¨ã™ã‚‹ã“ã¨ã§ï¼š\n1)低ã„値を設定ã™ã‚‹ã¨ã€ç”»åƒã®å½©åº¦ãŒå¤‰ã‚りã¾ã™ã€‚\n2)高ã„値ã¯ã€ç©ã‚„ã‹ãªã‚«ãƒ©ãƒ¼ãƒˆãƒ¼ãƒ³èª¿æ•´ã«ãªã‚Šã¾ã™ã€‚\n3)但ã—ã€CIE xyダイヤグラムã‹ã‚‰å¤–れãªã„よã†ã«æ³¨æ„ã—ã¾ã™ã€‚ +TC_LOCALLAB_PRIM_SHIFTY;シフト y TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By TC_PRIM_GREX;Gx TC_PRIM_GREY;Gy TC_PRIM_REDX;Rx TC_PRIM_REDY;Ry +TC_PRIM_REFI;色ã®å¾®èª¿æ•´(ホワイトãƒã‚¤ãƒ³ãƒˆ) THRESHOLDSELECTOR_B;下 THRESHOLDSELECTOR_BL;下-å·¦ THRESHOLDSELECTOR_BR;下-å³ @@ -2141,7 +2321,7 @@ TP_CACORRECTION_LABEL;色åŽå·®è£œæ­£ TP_CACORRECTION_RED;レッド TP_CBDL_AFT;白黒é©ç”¨ã®å¾Œ TP_CBDL_BEF;白黒é©ç”¨ã®å‰ -TP_CBDL_METHOD;処ç†ã®é †ç•ª +TP_CBDL_METHOD;ä½ç½®ã¥ã‘られãŸå‡¦ç† TP_CBDL_METHOD_TOOLTIP;詳細レベルã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ã®å‡¦ç†ã‚’白黒処ç†ã®å‰ã«è¡Œã†ã‹ã€å¾Œã«è¡Œã†ã‹é¸ã³ã¾ã™ã€‚å‰ã‚’é¸ã‚“ã å ´åˆã¯åŒæ©Ÿèƒ½ã®ä½œæ¥­è‰²ç©ºé–“ã¯RGBã¨ãªã‚Šã€å¾Œã‚’é¸ã‚“ã å ´åˆã¯L*a*b*ã¨ãªã‚Šã¾ã™ã€‚ TP_CHMIXER_BLUE;ブルー TP_CHMIXER_GREEN;グリーン @@ -2175,7 +2355,8 @@ TP_COLORAPP_CHROMA_M_TOOLTIP;CIECAM02/16ã®é®®ã‚„ã‹ã•ã¯ã€ã‚°ãƒ¬ãƒ¼ã¨æ¯”較 TP_COLORAPP_CHROMA_S;彩度 (S) TP_COLORAPP_CHROMA_S_TOOLTIP;CIECAM02/16ã®å½©åº¦ã¯ã€è‰²åˆºæ¿€è‡ªä½“ãŒæŒã¤æ˜Žã‚‹ã•ã¨æ¯”較ã—ãŸãã®è‰²åˆã„ã«è©²å½“ã™ã‚‹ã‚‚ã®ã§ã€L*a*b*ã‚„RGBã®å½©åº¦ã¨ã¯ç•°ãªã‚Šã¾ã™ã€‚ TP_COLORAPP_CHROMA_TOOLTIP;CIECAM02/16ã®è‰²åº¦ã¯ã€åŒä¸€ã®è¦³è¦–環境ã®ä¸‹ã§ã¯ç™½ã«è¦‹ãˆã‚‹è‰²åˆºæ¿€ã¨æ¯”較ã—ãŸã€ãã®è‰²åˆºæ¿€ã®'色åˆã„'ã«ç›¸å½“ã™ã‚‹ã‚‚ã®ã§ã€L*a*b*ã‚„RGBã®è‰²åº¦ã¨ã¯ç•°ãªã‚Šã¾ã™ã€‚ -TP_COLORAPP_CIECAT_DEGREE;CAT02/16(色順応変æ›02/16) +TP_COLORAPP_CIECAT_DEGREE;è‰²é †å¿œå¤‰æ› å ´é¢æ¡ä»¶ +TP_COLORAPP_CIECAT_DEGREEOUT;è‰²é †å¿œå¤‰æ› è¦³è¦–æ¡ä»¶ TP_COLORAPP_CONTRAST;コントラスト (J) TP_COLORAPP_CONTRAST_Q;コントラスト (Q) TP_COLORAPP_CONTRAST_Q_TOOLTIP;CIECAM02/16ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ(Q) ã¯æ˜Žã‚‹ã•ã«åŸºã¥ãã‚‚ã®ã§ã€L*a*b*ã‚„RGBã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã¨ã¯ç•°ãªã‚Šã¾ã™ @@ -2224,12 +2405,12 @@ TP_COLORAPP_NEUTRAL_TOOLTIP;å…¨ã¦ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã¨ TP_COLORAPP_RSTPRO;レッドã¨è‚Œè‰²ãƒˆãƒ¼ãƒ³ã‚’ä¿è­· TP_COLORAPP_RSTPRO_TOOLTIP;レッドã¨è‚Œè‰²ãƒˆãƒ¼ãƒ³ã‚’ä¿è­·ã¯ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¨ã‚«ãƒ¼ãƒ–ã®ä¸¡æ–¹ã«å½±éŸ¿ã—ã¾ã™ TP_COLORAPP_SOURCEF_TOOLTIP;撮影æ¡ä»¶ã«åˆã‚ã›ã¦ã€ãã®æ¡ä»¶ã¨ãƒ‡ãƒ¼ã‚¿ã‚’通常ã®ç¯„囲ã«åŽã‚ã¾ã™ã€‚ã“ã“ã§è¨€ã†â€œé€šå¸¸â€ã¨ã¯ã€å¹³å‡çš„æˆ–ã„ã¯æ¨™æº–çš„ãªæ¡ä»¶ã¨ãƒ‡ãƒ¼ã‚¿ã®ã“ã¨ã§ã™ã€‚例ãˆã°ã€CIECAM02/16ã®è£œæ­£ã‚’計算ã«å…¥ã‚Œãšã«åŽã‚る。 -TP_COLORAPP_SURROUND;観視時ã®å‘¨å›²ç’°å¢ƒ +TP_COLORAPP_SURROUND;周囲環境 TP_COLORAPP_SURROUNDSRC;撮影時ã®å‘¨å›²ç’°å¢ƒ TP_COLORAPP_SURROUND_AVER;å¹³å‡ TP_COLORAPP_SURROUND_DARK;æš—ã„ TP_COLORAPP_SURROUND_DIM;è–„æš—ã„ -TP_COLORAPP_SURROUND_EXDARK;éžå¸¸ã«æš—ã„ +TP_COLORAPP_SURROUND_EXDARK;éžå¸¸ã«æš—ã„ TP_COLORAPP_SURROUND_TOOLTIP;出力デãƒã‚¤ã‚¹ã§è¦³è¦–ã™ã‚‹æ™‚ã®å‘¨å›²ç’°å¢ƒã‚’考慮ã™ã‚‹ãŸã‚ã€ç”»åƒã®æ˜Žæš—ã¨è‰²ã‚’変ãˆã¾ã™\n\nå¹³å‡:\n周囲ãŒå¹³å‡çš„ãªæ˜Žã‚‹ã•(標準)\nç”»åƒã¯å¤‰ã‚りã¾ã›ã‚“\n\nè–„æš—ã„:\nè–„æš—ã„環境ã€ä¾‹ã€TVを見る環境\nç”»åƒã¯è‹¥å¹²æš—ããªã‚Šã¾ã™\n\næš—ã„:\næš—ã„環境 例ã€ãƒ—ロジェクターを見る環境\nç”»åƒã¯ã‹ãªã‚Šæš—ããªã‚Šã¾ã™\n\néžå¸¸ã«æš—ã„:\néžå¸¸ã«æš—ã„環境 (例ã€ã‚«ãƒƒãƒˆã‚·ãƒ¼ãƒˆã‚’使ã£ã¦ã„る)\nç”»åƒã¯ã¨ã¦ã‚‚æš—ããªã‚Šã¾ã™ TP_COLORAPP_SURSOURCE_TOOLTIP;撮影時ã®å‘¨å›²ç’°å¢ƒã‚’考慮ã™ã‚‹ãŸã‚ã€ç”»åƒã®æ˜Žæš—ã¨è‰²ã‚’変ãˆã¾ã™ã€‚\nå¹³å‡ï¼šå‘¨å›²ãŒå¹³å‡çš„ãªæ˜Žã‚‹ã•(標準)。画åƒã¯å¤‰åŒ–ã—ã¾ã›ã‚“。\n\nè–„æš—ã„:画åƒãŒå°‘ã—æ˜Žã‚‹ããªã‚Šã¾ã™ã€‚\n\næš—ã„:画åƒãŒæ›´ã«æ˜Žã‚‹ããªã‚Šã¾ã™ã€‚\n\néžå¸¸ã«æš—ã„:画åƒã¯éžå¸¸ã«æ˜Žã‚‹ããªã‚Šã¾ã™ã€‚ TP_COLORAPP_TCMODE_BRIGHTNESS;明る㕠@@ -2241,6 +2422,7 @@ TP_COLORAPP_TCMODE_LABEL3;カーブ・色度モード TP_COLORAPP_TCMODE_LIGHTNESS;明度 TP_COLORAPP_TCMODE_SATUR;彩度 TP_COLORAPP_TEMP2_TOOLTIP;シンメトリカルモードã®å ´åˆã¯ãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹ã®è‰²æ¸©åº¦ã‚’使ã„ã¾ã™\n色åå·®ã¯å¸¸ã«1.0\n\nAå…‰æºã€€è‰²æ¸©åº¦=2856\nD41 色温度=4100\nD50 色温度=5003\nD55 色温度=5503\nD60 色温度=6000\nD65 色温度=6504\nD75 色温度=7504 +TP_COLORAPP_TEMPOUT_TOOLTIP;色温度ã¨è‰²åå·®\nå‰ã«è¡Œã‚れãŸé¸æŠžã«å¿œã˜ã¦ã€é¸æŠžã•れãŸè‰²æ¸©åº¦ã¯ï¼š\nホワイトãƒãƒ©ãƒ³ã‚¹ãŒæ¬¡ã®ã‚ˆã†ã«\nAå…‰æºï¼2856\nD41=4100\nD50=5003\nD55=5503\nD60=6000\nD65=6504\nD75=7504\n或ã„ã¯ãƒ•リー\nã«ãªã‚Šã¾ã™ TP_COLORAPP_TEMP_TOOLTIP;é¸æŠžã—ãŸå…‰æºã«é–¢ã—色åå·®ã¯å¸¸ã«1ãŒä½¿ã‚れã¾ã™\n\n色温度=2856\nD50 色温度=5003\nD55 色温度=5503\nD65 色温度=6504\nD75 色温度=7504 TP_COLORAPP_TONECIE;CIECAM02/16を使ã£ãŸãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ング TP_COLORAPP_TONECIE_TOOLTIP;ã“ã®ã‚ªãƒ—ションãŒç„¡åйã«ãªã£ã¦ã„ã‚‹å ´åˆã€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã¯L*a*b*空間を使用ã—ã¾ã™\nã“ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹å ´åˆã€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã¯ã€CIECAM02/16を使用ã—ã¾ã™\nトーンマッピング(L*a*b*/CIECAM02)ツールを有効ã«ã™ã‚‹ã«ã¯ã€ã“ã®è¨­å®šã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ @@ -2362,6 +2544,8 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;è¼åº¦ã‚«ãƒ¼ãƒ– TP_DIRPYRDENOISE_LUMINANCE_DETAIL;è¼åº¦ã€€ç´°éƒ¨ã®å¾©å…ƒ TP_DIRPYRDENOISE_LUMINANCE_FRAME;è¼åº¦ãƒŽã‚¤ã‚º TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;è¼åº¦ +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;明るã•ã«å¿œã˜ãŸè£œæ•´ +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;ç”»åƒã®æ˜Žã‚‹ã•ã«å¿œã˜ã¦ãƒŽã‚¤ã‚ºä½Žæ¸›ã®å¼·ã•を変ãˆã¾ã™ã€‚ç”»åƒãŒæš—ã„å ´åˆã¯ãƒŽã‚¤ã‚ºä½Žæ¸›ã®å¼·ã•を下ã’ã€æ˜Žã‚‹ã„ç”»åƒã§ã¯ä¸Šã’ã¾ã™ã€‚ TP_DIRPYRDENOISE_MAIN_COLORSPACE;色空間 TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB @@ -2455,9 +2639,11 @@ TP_FILMNEGATIVE_GUESS_TOOLTIP;レッドã¨ãƒ–ãƒ«ãƒ¼ã®æ¯”率をã€å…ƒç”»åƒã® TP_FILMNEGATIVE_LABEL;ãƒã‚¬ãƒ•ィルム TP_FILMNEGATIVE_OUT_LEVEL;出力ã®ãƒ¬ãƒ™ãƒ« TP_FILMNEGATIVE_PICK;ニュートラルãªãƒã‚¤ãƒ³ãƒˆã‚’ピック +TP_FILMNEGATIVE_PICK_SIZE;サイズ: TP_FILMNEGATIVE_RED;ãƒ¬ãƒƒãƒ‰ã®æ¯”率 TP_FILMNEGATIVE_REF_LABEL;入力RGB: %1 TP_FILMNEGATIVE_REF_PICK;ホワイトãƒãƒ©ãƒ³ã‚¹ã®ã‚¹ãƒãƒƒãƒˆã‚’ピックアップ +TP_FILMNEGATIVE_REF_SIZE;サイズ: TP_FILMNEGATIVE_REF_TOOLTIP;ãƒã‚¸ã®ç”»åƒã§ãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹ã®å–れã¦ã„るグレーã®éƒ¨åˆ†ã‚’ピックアップã—ã¾ã™ TP_FILMSIMULATION_LABEL;フィルムシミュレーション TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapeeã¯ãƒ•ィルムシミュレーション機能ã«ä½¿ã†ç”»åƒã‚’Hald CLUTフォルダーã®ä¸­ã‹ã‚‰æŽ¢ã™ã‚ˆã†è¨­è¨ˆã•れã¦ã„ã¾ã™ï¼ˆãƒ—ログラムã«çµ„ã¿è¾¼ã‚€ã«ã¯ãƒ•ォルダーãŒå¤§ãéŽãŽã‚‹ãŸã‚)。\n変更ã™ã‚‹ã«ã¯ã€ç’°å¢ƒè¨­å®š > ç”»åƒå‡¦ç† > フィルムシミュレーションã¨é€²ã¿\nã©ã®ãƒ•ォルダーãŒä½¿ã‚れã¦ã„ã‚‹ã‹ç¢ºèªã—ã¾ã™ã€‚機能を利用ã™ã‚‹å ´åˆã¯ã€Hald CLUTã ã‘ãŒå…¥ã£ã¦ã„るフォルダーを指定ã™ã‚‹ã‹ã€ ã“ã®æ©Ÿèƒ½ã‚’使ã‚ãªã„å ´åˆã¯ãã®ãƒ•ォルダーを空ã«ã—ã¦ãŠãã¾ã™ã€‚\n\n詳ã—ãã¯RawPediaã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„。\n\nフィルム画åƒã®ã‚¹ã‚­ãƒ£ãƒ³ã‚’æ­¢ã‚ã¾ã™ã‹ï¼Ÿ @@ -2472,6 +2658,7 @@ TP_FLATFIELD_BT_VERTHORIZ;垂直 + æ°´å¹³ TP_FLATFIELD_BT_VERTICAL;垂直 TP_FLATFIELD_CLIPCONTROL;クリップコントロール TP_FLATFIELD_CLIPCONTROL_TOOLTIP;クリップコントロールã¯ã€ãƒ•ラットフィールドを使ã£ãŸæ™‚ã«ç™½é£›ã³ãŒç™ºç”Ÿã™ã‚‹ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚é©ç”¨ã™ã‚‹å…ƒç”»åƒã«æ—¢ã«ç™½é£›ã³ãŒã‚ã‚‹å ´åˆã¯ã€ã‚¯ãƒªãƒƒãƒ—コントロールã®é©ç”¨ã§è‰²è¢«ã‚ŠãŒèµ·ã“ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ +TP_FLATFIELD_FROMMETADATA;メタデータã‹ã‚‰ TP_FLATFIELD_LABEL;フラットフィールド TP_GENERAL_11SCALE_TOOLTIP;ã“ã®æ©Ÿèƒ½ã®åŠ¹æžœã‚„ã€ãã®ã‚µãƒ–コンãƒãƒ¼ãƒãƒ³ãƒˆã®ç¢ºèªã«ã¯ã€ãƒ—レビューã§1:1以上ã®ã‚¹ã‚±ãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚ TP_GRADIENT_CENTER;中央ä½ç½® @@ -2489,8 +2676,10 @@ TP_GRADIENT_STRENGTH_TOOLTIP;終点ä½ç½®ã§ã®ãƒ•ィルターã®å¼·ã• TP_HLREC_BLEND;ブレンド TP_HLREC_CIELAB;CIEL*a*b* ブレンディング TP_HLREC_COLOR;è‰²ã®æ³¢åŠ +TP_HLREC_COLOROPP;インペイント オãƒãƒ¼ã‚ºãƒ‰ TP_HLREC_ENA_TOOLTIP;自動露光ã§ã‚‚å‹•ä½œå¯ TP_HLREC_HLBLUR;ã¼ã‹ã— +TP_HLREC_HLTH;ゲインã®ã—ãã„値 TP_HLREC_LABEL;ãƒã‚¤ãƒ©ã‚¤ãƒˆå¾©å…ƒ TP_HLREC_LUMINANCE;è¼åº¦å¾©å…ƒ TP_HLREC_METHOD;æ–¹å¼: @@ -2506,10 +2695,12 @@ TP_ICM_APPLYHUESATMAP_TOOLTIP;DCPã«åŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„るベーステーブ TP_ICM_APPLYLOOKTABLE;ルックテーブル TP_ICM_APPLYLOOKTABLE_TOOLTIP;DCPã«åŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„るルックテーブルを用ã„ã¾ã™ã€‚但ã—ã€é©ç”¨ã™ã‚‹DCPã«ã“ã®ã‚¿ã‚°ãŒã‚ã‚‹å ´åˆã«é™ã‚Šã¾ã™ã€‚ TP_ICM_BPC;ブラックãƒã‚¤ãƒ³ãƒˆè£œæ­£ +TP_ICM_BW;白黒 TP_ICM_DCPILLUMINANT;å…‰æº TP_ICM_DCPILLUMINANT_INTERPOLATED;補間 TP_ICM_DCPILLUMINANT_TOOLTIP;埋ã‚è¾¼ã¾ã‚Œã¦ã„ã‚‹DCPã®å…‰æºã®ã©ã¡ã‚‰ã‚’使ã†ã‹é¸æŠžã€‚デフォルトã§ã¯ãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹ã«åŸºã¥ã„ã¦äºŒã¤ã®å…‰æºã®ä¸­é–“ã«è£œé–“ã™ã‚‹ã€‚ã“ã®è¨­å®šã¯äºŒã¤ã®DCPã®å…‰æºãŒè£œé–“サãƒãƒ¼ãƒˆã•れるã€ã‚’é¸æŠžã—ã¦ã„ã‚‹å ´åˆã«æœ‰åŠ¹ã€‚ TP_ICM_FBW;白黒 +TP_ICM_GAMUT;色域ã®åˆ¶å¾¡ TP_ICM_ILLUMPRIM_TOOLTIP;撮影æ¡ä»¶ã«æœ€ã‚‚相応ã—ã„å…‰æºã‚’é¸ã³ã¾ã™\n変更ãŒè¡Œã‚れるã®ã¯ã€â€˜å¤‰æ›å…ˆã®åŽŸè‰²â€™ã§â€˜ã‚«ã‚¹ã‚¿ãƒ  (スライダー)’ãŒé¸æŠžã•ã‚ŒãŸæ™‚ã ã‘ã§ã™ã€‚ TP_ICM_INPUTCAMERA;ã‚«ãƒ¡ãƒ©ã®æ¨™æº–的プロファイル TP_ICM_INPUTCAMERAICC;カメラプロファイルã®è‡ªå‹•調和 @@ -2518,8 +2709,8 @@ TP_ICM_INPUTCAMERA_TOOLTIP;dcrawã®ã‚·ãƒ³ãƒ—ルãªã‚«ãƒ©ãƒ¼ãƒ»ãƒžãƒˆãƒªã‚¯ã‚¹ã€ TP_ICM_INPUTCUSTOM;カスタム TP_ICM_INPUTCUSTOM_TOOLTIP;独自㮠DCP/ICCãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž TP_ICM_INPUTDLGLABEL;DCP/ICC å…¥åŠ›ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž... -TP_ICM_INPUTEMBEDDED;埋ã‚è¾¼ã¿ä½¿ç”¨, å¯èƒ½ãªã‚‰ -TP_ICM_INPUTEMBEDDED_TOOLTIP;raw以外ã®ãƒ•ァイルã«åŸ‹ã‚è¾¼ã¾ã‚ŒãŸã‚«ãƒ©ãƒ¼ãƒ—ロファイルを使用 +TP_ICM_INPUTEMBEDDED;埋ã‚è¾¼ã¾ã‚Œã¦ã„るプロファイルを使用 +TP_ICM_INPUTEMBEDDED_TOOLTIP;ファイルã«åŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„るカラープロファイルを使用\nファイルãŒãªã„å ´åˆã¯ã€ã‚«ãƒ¡ãƒ©æ¨™æº–ã®ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã«æˆ»ã‚‹ TP_ICM_INPUTNONE;プロファイルãªã— TP_ICM_INPUTNONE_TOOLTIP;ã™ã¹ã¦ã«ã‚«ãƒ©ãƒ¼ãƒ—ロファイルを使用ã—ãªã„ 特殊ãªå ´åˆã«ã®ã¿ä½¿ç”¨ TP_ICM_INPUTPROFILE;入力プロファイル @@ -2529,9 +2720,9 @@ TP_ICM_NEUTRAL;リセット TP_ICM_NOICM;No ICM: sRGB 出力 TP_ICM_OUTPUTPROFILE;出力プロファイル TP_ICM_OUTPUTPROFILE_TOOLTIP;デフォルトã§ã¯ã€å…¨ã¦ã®RTv4或ã„ã¯RTv2プロファイルã§TRC - sRGB: ガンマ=2.4 勾é…=12.92ãŒé©ç”¨ã•れã¦ã„ã¾ã™\n\n'ICCプロファイルクリエーター'ã§v4或ã„ã¯v2ã®ãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä»¥ä¸‹ã®æ¡ä»¶ã§ä½œæˆå‡ºæ¥ã¾ã™ï¼›\n 原色: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Custom\n TRC: BT709, sRGB, ç·šå½¢, 標準ガンマ=2.2, 標準ガンマ=1.8, カスタム\n 光æº: D41, D50, D55, D60, D65, D80, stdA 2856K -TP_ICM_PRIMBLU_TOOLTIP;原色 ブルー:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 -TP_ICM_PRIMGRE_TOOLTIP;原色 グリーン:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 -TP_ICM_PRIMILLUM_TOOLTIP;ç”»åƒã‚’å…ƒã®ãƒ¢ãƒ¼ãƒ‰ï¼ˆâ€œä½œæ¥­ãƒ—ロファイルâ€ï¼‰ã‹ã‚‰ç•°ãªã‚‹ãƒ¢ãƒ¼ãƒ‰ï¼ˆâ€œå¤‰æ›å…ˆã®åŽŸè‰²â€ï¼‰ã«å¤‰ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ç”»åƒã«å¯¾ã—ç•°ãªã‚‹ã‚«ãƒ©ãƒ¼ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã™ã‚‹ã¨ã€ç”»åƒã®è‰²å€¤ã‚’æ’ä¹…çš„ã«å¤‰ãˆã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚\n\n‘原色’ã®å¤‰æ›´ã¯éžå¸¸ã«è¤‡é›‘ã§ã€ãã®ä½¿ã„æ–¹ã¯éžå¸¸ã«é›£ã—ã„ã‚‚ã®ã§ã™ã€‚熟é”ã—ãŸçµŒé¨“ãŒå¿…è¦ã§ã™ã€‚\nãƒãƒ£ãƒ³ãƒãƒ«ãƒŸã‚­ã‚µãƒ¼ã®åŽŸè‰²ã®ã‚ˆã†ã«ã€ã‚¨ã‚­ã‚¾ãƒãƒƒã‚¯ãªè‰²ã®èª¿æ•´ãŒå¯èƒ½ã§ã™ã€‚\nカスタム(スライダー)を使ã£ã¦ã‚«ãƒ¡ãƒ©ã®ã‚­ãƒ£ãƒªãƒ–レーションを変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ +TP_ICM_PRIMBLU_TOOLTIP;原色 ブルー:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 +TP_ICM_PRIMGRE_TOOLTIP;原色 グリーン:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 +TP_ICM_PRIMILLUM_TOOLTIP;ç”»åƒã‚’オリジナルモード(作業プロファイル)ã‹ã‚‰ç•°ãªã‚‹ãƒ¢ãƒ¼ãƒ‰ï¼ˆå¤‰æ›å…ˆã®åŽŸè‰²ï¼‰ã¸å¤‰æ›´ãŒå‡ºæ¥ã¾ã™ã€‚ç”»åƒã®ã‚«ãƒ©ãƒ¼ãƒ¢ãƒ¼ãƒ‰ã‚’ä»–ã®ãƒ¢ãƒ¼ãƒ‰ã«å¤‰ãˆã‚‹ã¨ã€ç”»åƒã®è‰²å€¤ã‚’完全ã«å¤‰æ›´ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚\n\n原色ã®å¤‰æ›´ã¯è¤‡é›‘ã§ãã®åˆ©ç”¨ã¯ç°¡å˜ã§ã¯ã‚りã¾ã›ã‚“。多ãã®æ¤œè¨¼ä½œæ¥­ãŒå¿…è¦ã§ã™ã€‚\n花ãªã©ã®æ´¾æ‰‹ãªè‰²ã¯ãƒãƒ£ãƒ³ãƒãƒ«ãƒŸã‚­ã‚µãƒ¼ã®åŽŸè‰²ã¨ã—ã¦å¤‰æ›´ãŒå‡ºæ¥ã¾ã™ã€‚\nカメラキャリブレーションã¯ã‚«ã‚¹ã‚¿ãƒ ï¼ˆã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼‰ã§å¤‰æ›´ãŒå‡ºæ¥ã¾ã™ã€‚ TP_ICM_PRIMRED_TOOLTIP;原色 レッド:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 TP_ICM_PROFILEINTENT;ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã®æ„図 TP_ICM_REDFRAME;カスタム 原色 @@ -2543,8 +2734,15 @@ TP_ICM_TONECURVE;トーンカーブ TP_ICM_TONECURVE_TOOLTIP;DCPã«åŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„るトーンカーブをé©ç”¨ã—ã¾ã™ã€‚但ã—ã€ã“ã®è¨­å®šã¯é¸æŠžã—ãŸDCPã«ãƒˆãƒ¼ãƒ³ã‚«ãƒ¼ãƒ–ãŒåŸ‹ã‚è¾¼ã¾ã‚Œã¦ã„ã‚‹å ´åˆã ã‘ã§ã™ã€‚ TP_ICM_TRCFRAME;アブストラクトプロファイル TP_ICM_TRCFRAME_TOOLTIP;ã“ã®ãƒ—ロファイルã¯â€˜ã‚·ãƒ³ã‚»ãƒ†ã‚£ãƒƒã‚¯â€™ã¾ãŸã¯â€˜ãƒãƒ¼ãƒãƒ£ãƒ«â€™ãƒ—ロファイルã¨ã—ã¦ã‚‚知られã€å‡¦ç†å·¥ç¨‹ã®æœ€å¾Œï¼ˆCIECAMã®å‰ï¼‰)ã«é©ç”¨ã•れるもã®ã§ã€ç‹¬è‡ªã®ç”»åƒåŠ¹æžœã‚’ä½œã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™\n以下ã®è¦ç´ ã«å¤‰æ›´ã‚’加ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ï¼š\n ç”»åƒã®ãƒˆãƒ¼ãƒ³ã‚’変ãˆã‚‰ã‚Œã‚‹â€˜ãƒˆãƒ¼ãƒ³ãƒªãƒ—ロダクションカーブ’\n 撮影æ¡ä»¶ã«é©åˆã™ã‚‹ã‚ˆã†ã«ãƒ—ロファイルã®åŽŸè‰²ã‚’å¤‰æ›´ã™ã‚‹â€˜å…‰æºâ€™\n 主ã«ãƒãƒ£ãƒ³ãƒãƒ«ãƒŸã‚­ã‚µãƒ¼ã€ã‚­ãƒ£ãƒªãƒ–レーションã®ï¼’ã¤ã‚’使ã£ã¦å¤‰æ›å…ˆã®åŽŸè‰²ã‚’å¤‰ãˆã‚‹â€˜å¤‰æ›å…ˆã®åŽŸè‰²â€™\n注æ„: アブストラクトプロファイルã¯çµ„ã¿è¾¼ã¾ã‚Œã¦ã„る作業プロファイルを考慮ã™ã‚‹ã ã‘ã§ã€ä½œæ¥­ãƒ—ロファイルã®å¤‰æ›´ã¯è¡Œã„ã¾ã›ã‚“。カスタム作業プロファイルã§ã¯å‹•作ã—ã¾ã›ã‚“ -TP_ICM_TRC_TOOLTIP;RawTherapeeã®ãƒ‡ãƒ•ォルトã§ä½¿ã‚れã¦ã„る‘トーンリプロダクションカーブ(TRC)’(g=2.4ã€s=12.92)を変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\nTRCã¯ç”»åƒã®ãƒˆãƒ¼ãƒ³ã‚’変ãˆã¾ã™ã€‚RGBã€L*a*b*ã®å€¤ã€ãƒ’ストグラムã€å‡ºåŠ›ï¼ˆã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã€TIFã€JPEG)ãŒå¤‰ã‚りã¾ã™ã€‚\nガンマã¯ä¸»ã«æ˜Žã‚‹ã„トーンを変ãˆã€å‹¾é…ã¯æš—ã„トーンを変ãˆã¾ã™ã€‚\nã©ã®æ§˜ãªâ€˜ã‚¬ãƒ³ãƒžâ€™ã¨â€˜å‹¾é…’ãŒé¸æŠžå‡ºæ¥ã¾ã™ï¼ˆä½†ã—ã€1より大ãã„値)。ã“ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã¯ã‚«ãƒ¼ãƒ–ã®ç·šå½¢éƒ¨åˆ†ã¨æ”¾ç‰©ç·šéƒ¨åˆ†ã®é€£ç¶šæ€§ã‚’確ä¿ã—ã¾ã™ã€‚\n‘ãªã—’以外ã®é¸æŠžã§ã€â€˜å…‰æºâ€™ã¨â€˜å¤‰æ›å…ˆã®åŽŸè‰²â€™ã®ä¸­ã®ä¸€è¦§ãŒæœ‰åйã«ãªã‚Šã¾ã™ã€‚ +TP_ICM_TRC_TOOLTIP;RawTherapeeã®ãƒ‡ãƒ•ォルトsRGBトーンリプロダクションカーブ(g=2.4 s=12.92)ã¯å¤‰æ›´ãŒå¯èƒ½ã§ã™ã€‚\nã“ã®ãƒˆãƒ¼ãƒ³ãƒªãƒ—ロダクションカーブã®å¤‰æ›´ã¯ç”»åƒã®ãƒˆãƒ¼ãƒ³ã‚’変ãˆã‚‹æ©Ÿèƒ½ã§ã™ã€‚RGB/Labã®å€¤ã€ãƒ’ストグラムã€å‡ºåŠ›ï¼ˆã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã€TIFã€JPG)ãŒå¤‰ã‚りã¾ã™ã€‚\nガンマã¯ä¸»ã«æ˜Žã‚‹ã„トーンã®å¤‰æ›´ã€ã‚¹ãƒ­ãƒ¼ãƒ—ã¯ä¸»ã«æš—ã„トーンã«ä½œç”¨ã—ã¾ã™ã€‚\nã©ã®æ§˜ãªã‚¬ãƒ³ãƒžã¨ã‚¹ãƒ­ãƒ¼ãƒ—(1より大ãã„)ã®çµ„ã¿åˆã‚ã›ãŒé¸ã¹ã¾ã™ã€‚アルゴリズムã¯ã‚«ãƒ¼ãƒ–ã®ç·šå½¢éƒ¨åˆ†ã¨éžç·šå½¢éƒ¨åˆ†ã®é€£ç¶šæ€§ã‚’確ä¿ã—ã¾ã™ã€‚\n“ãªã—â€ä»¥å¤–ã®é¸æŠžã‚’ã™ã‚‹ã¨ã€â€œå…‰æºâ€ã¨â€œç›¸æ‰‹å…ˆã®åŽŸè‰²â€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒæœ‰åйã«ãªã‚Šã¾ã™ã€‚ TP_ICM_WORKINGPROFILE;作業プロファイル +TP_ICM_WORKING_CAT;カラーマトリクスã®é©å¿œ +TP_ICM_WORKING_CAT_BRAD;ブラッドフォード +TP_ICM_WORKING_CAT_CAT02;Cat02 +TP_ICM_WORKING_CAT_CAT16;Cat16 +TP_ICM_WORKING_CAT_TOOLTIP;XYZ変æ›ãƒžãƒˆãƒªã‚¯ã‚¹ã®è‰²é †å¿œã‚’実行ã—ã¾ã™ã€‚デフォルトã¯ãƒ–ラッドフォードã§ã™ +TP_ICM_WORKING_CAT_VK;フォンクリース係数 +TP_ICM_WORKING_CAT_XYZ;XYZスケール TP_ICM_WORKING_CIEDIAG;CIE xy ダイヤグラム TP_ICM_WORKING_ILLU;å…‰æº TP_ICM_WORKING_ILLU_1500;タングステン 1500K @@ -2556,8 +2754,10 @@ TP_ICM_WORKING_ILLU_D60;D60 TP_ICM_WORKING_ILLU_D65;D65 TP_ICM_WORKING_ILLU_D80;D80 TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_E;E TP_ICM_WORKING_ILLU_NONE;デフォルト TP_ICM_WORKING_ILLU_STDA;stdA 2875K +TP_ICM_WORKING_NON;ãªã— TP_ICM_WORKING_PRESER;ãƒ‘ã‚¹ãƒ†ãƒ«ãƒˆãƒ¼ãƒ³ã‚’ç¶­æŒ TP_ICM_WORKING_PRIM;変æ›å…ˆã®åŽŸè‰² TP_ICM_WORKING_PRIMFRAME_TOOLTIP;‘変æ›å…ˆã®åŽŸè‰²â€™ã®ã‚³ãƒ³ãƒœãƒœãƒƒã‚¯ã‚¹ã®ä¸­ã‹ã‚‰â€˜ã‚«ã‚¹ã‚¿ãƒ CIE xyãƒ€ã‚¤ãƒ¤ã‚°ãƒ©ãƒ â€™ã‚’é¸æŠžã™ã‚‹ã¨ã€3ã¤ã®åŽŸè‰²ãŒãƒ€ã‚¤ãƒ¤ã‚°ãƒ©ãƒ ä¸Šã§å¤‰æ›´å¯èƒ½ã¨ãªã‚Šã¾ã™ã€‚\n注æ„:ã“ã®å ´åˆã€ãƒ€ã‚¤ãƒ¤ã‚°ãƒ©ãƒ ã®ãƒ›ãƒ¯ã‚¤ãƒˆãƒã‚¤ãƒ³ãƒˆã®ä½ç½®ã¯æ›´æ–°ã•れã¾ã›ã‚“。 @@ -2569,10 +2769,14 @@ TP_ICM_WORKING_PRIM_BRU;BruceRGB TP_ICM_WORKING_PRIM_BST;BestRGB TP_ICM_WORKING_PRIM_CUS;カスタム(スライダー) TP_ICM_WORKING_PRIM_CUSGR;カスタム(CIE xy ダイヤグラム) +TP_ICM_WORKING_PRIM_FREE;カスタム(スライダー) +TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max 標準Aå…‰æº TP_ICM_WORKING_PRIM_NONE;デフォルト TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_TOOLTIP;‘変æ›å…ˆã®åŽŸè‰²â€™ï¼ˆé«˜åº¦ï¼‰ã«ã‚ˆã‚Šã€ç”»åƒã®è‰²ï¼ˆå½©åº¦ï¼‰ã‚’復元或ã„ã¯å¤‰æ›´ã™ã‚‹ãŸã‚ã«å¤‰æ›å…ˆã®åŽŸè‰²ã‚’å¤‰ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚‘作業プロファイル’ã¨â€˜å¤‰æ›å…ˆã®åŽŸè‰²â€™ã®é•ã„ãŒå°ã•ã‘れã°ã€ã‚«ãƒ©ãƒ¼ãƒãƒ©ãƒ³ã‚¹ã¯å分ã«ä¿ãŸã‚Œã¾ã™ã€‚作業プロファイルã¯å¤‰ã‚りã¾ã›ã‚“。色域ãŒåˆ¶å¾¡ã•れã¾ã™ã€‚\nâ€˜ã‚«ã‚¹ã‚¿ãƒ ï¼ˆã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼‰â€™ã‚’é¸æŠžã™ã‚‹ã¨ã€Xã¨Yã«é–¢ã™ã‚‹ãƒ¬ãƒƒãƒ‰ã€ã‚°ãƒªãƒ¼ãƒ³ã€ãƒ–ルーã®3原色ã®å€¤ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ TP_ICM_WORKING_PRIM_WID;WideGamut TP_ICM_WORKING_TRC;トーンリプロダクションカーブ: TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2582,13 +2786,11 @@ TP_ICM_WORKING_TRC_CUSTOM;カスタム TP_ICM_WORKING_TRC_GAMMA;ガンマ TP_ICM_WORKING_TRC_LIN;リニア g=1 TP_ICM_WORKING_TRC_NONE;ãªã— -TP_ICM_WORKING_TRC_SLOPE;å‹¾é… +TP_ICM_WORKING_TRC_SLOPE;スロープ TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 TP_ICM_WORKING_TRC_TOOLTIP;組ã¿è¾¼ã¾ã‚ŒãŸãƒ—ロファイルã ã‘ TP_IMPULSEDENOISE_LABEL;インパルスノイズ低減 TP_IMPULSEDENOISE_THRESH;ã—ãã„値 -TP_LABCURVE_AVOIDCOLORSHIFT;色ãšã‚Œã‚’å›žé¿ -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;作業色空間ã®è‰²åŸŸã«è‰²ã‚’åˆã‚ã›ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ã‚’é©ç”¨ã—ã¾ã™ï¼ˆå‡ç­‰çŸ¥è¦šè‰²ç©ºé–“) TP_LABCURVE_BRIGHTNESS;明度 TP_LABCURVE_CHROMATICITY;色度 TP_LABCURVE_CHROMA_TOOLTIP;白黒トーンをé©ç”¨ã™ã‚‹ã«ã¯ã€å½©åº¦ã‚’-100ã«è¨­å®šã—ã¾ã™ @@ -2653,7 +2855,7 @@ TP_LOCALLAB_ARTIF_TOOLTIP;ΔE-スコープã®ã—ãã„å€¤ï¼šã‚¹ã‚³ãƒ¼ãƒ—ã‚’é© TP_LOCALLAB_AUTOGRAY;自動平å‡è¼åº¦ï¼ˆYbï¼…) TP_LOCALLAB_AUTOGRAYCIE;自動 TP_LOCALLAB_AVOID;色ãšã‚Œã®å›žé¿ -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;作業色空間ã®è‰²åŸŸã«è‰²ã‚’åŽã‚ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ã‚’行ã„ã¾ã™ï¼ˆå‡ä¸€çš„ãªçŸ¥è¦šã®Lab)\nJz或ã„ã¯CAM16ãŒä½¿ã‚れã¦ã„ã‚‹å ´åˆã¯ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒå¸¸ã«ç„¡åйã«ãªã‚Šã¾ã™ã€‚ +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;作業色空間ã®è‰²åŸŸã«è‰²ã‚’åŽã‚ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ã‚’行ã„ã¾ã™ï¼ˆå‡ä¸€çš„ãªçŸ¥è¦šã®Lab)\nJz或ã„ã¯CAM16ã€è‰²ã®è¦‹ãˆã¨æ˜Žã‚‹ã•ãŒä½¿ã‚れã¦ã„ã‚‹å ´åˆã¯ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒå¸¸ã«ç„¡åйã«ãªã‚Šã¾ã™ã€‚\n\nデフォルト:マンセル\nマンセル補正:色度ãŒä¿®æ­£ã•ã‚ŒãŸæ™‚ã«ã€éžç·šå½¢æ€§ã«èµ·å› ã™ã‚‹è‰²ãšã‚ŒãŒç™ºç”Ÿã™ã‚‹L*a*b*ã®æ¬ ç‚¹ã‚’修復ã—ã¾ã™ï¼ˆå‡ä¸€çš„ãªçŸ¥è¦šLab)\nL*a*b*: 色域制御ã€ç›¸å¯¾çš„色域ãŒé©ç”¨ã•れ後ã«ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒè¡Œã‚れã¾ã™\nXYZ 絶対:色域制御ã€çµ¶å¯¾çš„色域ãŒé©ç”¨ã•れãŸå¾Œã«ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒè¡Œã‚れã¾ã™ \nXYZ 相対: 色域制御ã€ç›¸å¯¾çš„色域ãŒé©ç”¨ã•れãŸå¾Œã«ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒè¡Œã‚れã¾ã™ã€‚çµæžœã¯Labã®å ´åˆã¨åŒã˜ã«ãªã‚Šã¾ã›ã‚“。 TP_LOCALLAB_AVOIDMUN;マンセル補正ã ã‘ TP_LOCALLAB_AVOIDMUN_TOOLTIP;Jz或ã„ã¯CAM16ãŒä½¿ã‚れã¦ã„ã‚‹å ´åˆã¯ã€ãƒžãƒ³ã‚»ãƒ«è£œæ­£ãŒå¸¸ã«ç„¡åйã«ãªã‚Šã¾ã™ã€‚ TP_LOCALLAB_AVOIDRAD;ソフトãªåŠå¾„ @@ -2666,7 +2868,7 @@ TP_LOCALLAB_BILATERAL;平滑化フィルタ TP_LOCALLAB_BLACK_EV;ブラックEv TP_LOCALLAB_BLCO;色度ã ã‘ TP_LOCALLAB_BLENDMASKCOL;ブレンド -TP_LOCALLAB_BLENDMASKMASK;マスクã®è¼åº¦ã®åŠ æ¸› +TP_LOCALLAB_BLENDMASKMASK;マスクã®è¼åº¦ã®åŠ æ¸› TP_LOCALLAB_BLENDMASKMASKAB;マスクã®è‰²åº¦ã®åŠ æ¸› TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;スライダーã®å€¤ãŒ0ã®å ´åˆã¯ä½œç”¨ã—ã¾ã›ã‚“\n元画åƒã«ãƒžã‚¹ã‚¯ã‚’追加ã—ãŸã‚Šã€è¿½åŠ ã—ãŸãƒžã‚¹ã‚¯ã‚’削除ã—ã¾ã™ TP_LOCALLAB_BLENDMASK_TOOLTIP;ブレンド=0ã®å ´åˆã¯ã€å½¢çŠ¶æ¤œå‡ºã ã‘ãŒæ”¹å–„ã—ã¾ã™\nブレンドãŒ0より大ãã„å ´åˆã¯ã€ç”»åƒã«ãƒžã‚¹ã‚¯ãŒè¿½åŠ ã•れã¾ã™ã€‚ ブレンドãŒ0よりå°ã•ã„å ´åˆã¯ã€ç”»åƒã‹ã‚‰ãƒžã‚¹ã‚¯ãŒé™¤ã‹ã‚Œã¾ã™ã€‚ @@ -2676,16 +2878,16 @@ TP_LOCALLAB_BLLC;è¼åº¦ã¨è‰²åº¦ TP_LOCALLAB_BLLO;è¼åº¦ã ã‘ TP_LOCALLAB_BLMED;メディアン TP_LOCALLAB_BLMETHOD_TOOLTIP;通常:全ã¦ã®è¨­å®šã«å¯¾ã—ã€ç›´æŽ¥çš„ãªã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºå‡¦ç†\nインãƒãƒ¼ã‚¹ï¼šã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºå‡¦ç†\n注æ„:設定ã«ã‚ˆã£ã¦ã¯äºˆæœŸã—ãªã„çµæžœã«ãªã‚‹ã“ã¨ãŒã‚りã¾ã™ -TP_LOCALLAB_BLNOI_EXP;ã¼ã‹ã— & ノイズ除去 +TP_LOCALLAB_BLNOI_EXP;ã¼ã‹ã— & ノイズ TP_LOCALLAB_BLNORM;通常 TP_LOCALLAB_BLUFR;ã¼ã‹ã—/質感ã¨ãƒŽã‚¤ã‚ºé™¤åŽ» -TP_LOCALLAB_BLUMETHOD_TOOLTIP;背景をã¼ã‹ã—ã€å‰æ™¯ã‚’区分ã‘ã™ã‚‹ãŸã‚ã«:\nç”»åƒå…¨ä½“ã‚’RT-スãƒãƒƒãƒˆã§å®Œå…¨ã«å›²ã¿ï¼ˆã‚¹ã‚³ãƒ¼ãƒ—ã¨å¢ƒç•Œå€¤ã¯é«˜ãã—ã¾ã™ï¼‰èƒŒæ™¯ã‚’ã¼ã‹ã—ã¾ã™-'通常’或ã„ã¯â€™ã‚¤ãƒ³ãƒãƒ¼ã‚¹â€™ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¾ã™\n*一ã¤ä»¥ä¸Šã®RT-スãƒãƒƒãƒˆã§â€™é™¤å¤–’モードを使ã„ã€ã‚¹ã‚³ãƒ¼ãƒ—値を高ãã—ã¦å‰æ™¯ã‚’区分ã‘ã—ã¾ã™\n\nã“ã®æ©Ÿèƒ½ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ï¼ˆ'メディアン’åŠã³â€™ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタ’をå«ã‚€ï¼‰ã¯ã€ãƒ¡ã‚¤ãƒ³ã®ãƒŽã‚¤ã‚ºä½Žæ¸›ã¨ä½µç”¨ã§ãã¾ã™ã€‚ +TP_LOCALLAB_BLUMETHOD_TOOLTIP;背景をã¼ã‹ã—ã€å‰æ™¯ã‚’区分ã‘ã™ã‚‹ãŸã‚ã«:\nç”»åƒå…¨ä½“ã‚’RT-スãƒãƒƒãƒˆã§å®Œå…¨ã«å›²ã¿ï¼ˆã‚¹ã‚³ãƒ¼ãƒ—ã¨å¤‰ç§»ã®ä½ç½®ã¯é«˜ãã—ã¾ã™ï¼‰èƒŒæ™¯ã‚’ã¼ã‹ã—ã¾ã™-'通常’或ã„ã¯â€™ã‚¤ãƒ³ãƒãƒ¼ã‚¹â€™ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¾ã™\n*一ã¤ä»¥ä¸Šã®RT-スãƒãƒƒãƒˆã§â€™é™¤å¤–’モードを使ã„ã€ã‚¹ã‚³ãƒ¼ãƒ—値を高ãã—ã¦å‰æ™¯ã‚’区分ã‘ã—ã¾ã™\n\nã“ã®æ©Ÿèƒ½ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ï¼ˆ'メディアン’åŠã³â€™ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタ’をå«ã‚€ï¼‰ã¯ã€ãƒ¡ã‚¤ãƒ³ã®ãƒŽã‚¤ã‚ºä½Žæ¸›ã¨ä½µç”¨ã§ãã¾ã™ã€‚ TP_LOCALLAB_BLUR;ガウスã¼ã‹ã— - ノイズ - 質感 TP_LOCALLAB_BLURCOL;åŠå¾„ TP_LOCALLAB_BLURCOLDE_TOOLTIP;孤立ã—ãŸãƒ”クセルãŒè¨ˆç®—ã«å…¥ã‚‹ã®é¿ã‘ã‚‹ãŸã‚ã€Î”Eを計算ã™ã‚‹ãŸã‚ã«ä½¿ã‚れる画åƒã«å°‘ã—ã¼ã‹ã—ã‚’ã‹ã‘ã¾ã™ TP_LOCALLAB_BLURDE;形状検出ã®ã¼ã‹ã— TP_LOCALLAB_BLURLC;è¼åº¦ã ã‘ -TP_LOCALLAB_BLURLEVELFRA;レベルã®ã¼ã‹ã— +TP_LOCALLAB_BLURLEVELFRA;詳細レベルã®ã¼ã‹ã— TP_LOCALLAB_BLURMASK_TOOLTIP;マスクを生æˆã™ã‚‹ãŸã‚ã«åŠå¾„ã®å¤§ããªã¼ã‹ã—を使ã„ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šç”»åƒã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’変ãˆãŸã‚Šã€ç”»åƒã®ä¸€éƒ¨ã‚’æš—ãã€åˆã¯æ˜Žã‚‹ãã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ TP_LOCALLAB_BLURRMASK_TOOLTIP;ガウスã¼ã‹ã—ã®â€™åŠå¾„’を変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ï¼ˆ0~1000) TP_LOCALLAB_BLUR_TOOLNAME;ã¼ã‹ã—/質感 & ノイズ除去 @@ -2696,10 +2898,13 @@ TP_LOCALLAB_BUTTON_DEL;削除 TP_LOCALLAB_BUTTON_DUPL;複製 TP_LOCALLAB_BUTTON_REN;åå‰ã®å¤‰æ›´ TP_LOCALLAB_BUTTON_VIS;表示/éžè¡¨ç¤º +TP_LOCALLAB_BWEVNONE;ãªã— +TP_LOCALLAB_BWEVSIG;有効 +TP_LOCALLAB_BWEVSIGLOG;シグモイド & 対数符å·åŒ– TP_LOCALLAB_BWFORCE;ブラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvを使ㆠTP_LOCALLAB_CAM16PQREMAP;HDR PQ(最大è¼åº¦) TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;CAM16ã«é©å¿œã—ãŸPQ (知覚é‡å­åŒ–)。ã“れã«ã‚ˆã‚ŠPQã®å†…部関数を変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™(通常ã¯10000カンデラ毎平方メートル - デフォルトã¯100カンデラ毎平方メートルã§ã™ãŒç„¡åйã«ãªã‚Šã¾ã™\nç•°ãªã‚‹ãƒ‡ãƒã‚¤ã‚¹ã‚„ç”»åƒã‚’扱ã†å ´åˆã«ä½¿ãˆã¾ã™ã€‚ -TP_LOCALLAB_CAM16_FRA;CAM16ã«ã‚ˆã‚‹ç”»åƒã®èª¿æ•´ +TP_LOCALLAB_CAM16_FRA;CAM16ã«ã‚ˆã‚‹ç”»åƒç·¨é›† TP_LOCALLAB_CAMMODE;CAMã®ãƒ¢ãƒ‡ãƒ« TP_LOCALLAB_CAMMODE_CAM16;CAM16 TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz @@ -2712,12 +2917,14 @@ TP_LOCALLAB_CBDL_TOOLNAME;詳細レベルã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ TP_LOCALLAB_CENTER_X;センターX TP_LOCALLAB_CENTER_Y;センターY TP_LOCALLAB_CH;CL - LC +TP_LOCALLAB_CHRO46LABEL;詳細レベル4ã‹ã‚‰ï¼–ã®è‰²åº¦: å¹³å‡=%1 高=%2 +TP_LOCALLAB_CHROLABEL;詳細レベルï¼ã‹ã‚‰ï¼“ã®è‰²åº¦: å¹³å‡=%1 高=%2 TP_LOCALLAB_CHROMA;色度 -TP_LOCALLAB_CHROMABLU;色度ã®ãƒ¬ãƒ™ãƒ« +TP_LOCALLAB_CHROMABLU;詳細レベルã®è‰²åº¦ TP_LOCALLAB_CHROMABLU_TOOLTIP;è¼åº¦ã®è¨­å®šã«å¿œã˜ã¦ã€åŠ¹æžœã‚’å¢—ã‚„ã—ãŸã‚Šæ¸›ã‚‰ã—ãŸã‚Šã—ã¾ã™\n設定値ãŒ1以下ã®å ´åˆã¯åŠ¹æžœãŒæ¸›ã‚Šã¾ã™ã€‚1より大ãã„ã¨åŠ¹æžœãŒå¢—ãˆã¾ã™ TP_LOCALLAB_CHROMACBDL;色度 TP_LOCALLAB_CHROMACB_TOOLTIP;è¼åº¦ã®è¨­å®šã«å¿œã˜ã¦ã€åŠ¹æžœã‚’å¢—ã‚„ã—ãŸã‚Šæ¸›ã‚‰ã—ãŸã‚Šã—ã¾ã™\n設定値ãŒ1以下ã®å ´åˆã¯åŠ¹æžœãŒæ¸›ã‚Šã¾ã™ã€‚1より大ãã„ã¨åŠ¹æžœãŒå¢—ãˆã¾ã™ -TP_LOCALLAB_CHROMALEV;色度ã®ãƒ¬ãƒ™ãƒ« +TP_LOCALLAB_CHROMALEV;詳細レベルã®è‰²åº¦ TP_LOCALLAB_CHROMASKCOL;色度 TP_LOCALLAB_CHROMASK_TOOLTIP;ã“ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã‚’使ã£ã¦èƒŒæ™¯ã®å½©åº¦ã‚’下ã’ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™(インãƒãƒ¼ã‚¹ãƒžã‚¹ã‚¯ã§è¨€ã†0ã«è¿‘ã„カーブ).\n色度ã«å¯¾ã™ã‚‹ãƒžã‚¹ã‚¯ã®ä½œç”¨ã‚’å¼·ã‚ã‚‹ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚ TP_LOCALLAB_CHROML;色度 (C) @@ -2727,19 +2934,25 @@ TP_LOCALLAB_CIEC;色ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«ã®ç’°å¢ƒå¤‰æ•°ã‚’使ㆠTP_LOCALLAB_CIECAMLOG_TOOLTIP;ã“ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯CIE色ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«ã‚’ベースã«ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒ¢ãƒ‡ãƒ«ã¯ç•°ãªã‚‹å…‰æºã®ä¸‹ã§äººã®ç›®ãŒçŸ¥è¦šã™ã‚‹è‰²ã‚’真似るもã®ã§ã™ã€‚\n最åˆã®å‡¦ç†ã¯â€™å ´é¢æ¡ä»¶â€™ã§å¯¾æ•°ç¬¦å·åŒ–ã«ã‚ˆã£ã¦å®Ÿè¡Œã•れã¾ã™ã€‚ã“ã®éš›ã€æ’®å½±æ™‚ã®â€™çµ¶å¯¾è¼åº¦â€™ãŒä½¿ã‚れã¾ã™ã€‚\n次ã®å‡¦ç†ã¯å˜ç´”化ã—ãŸâ€™ç”»åƒã®èª¿æ•´â€™ã§3ã¤ã«çµžã‚Šè¾¼ã‚“ã å¤‰æ•°ï¼ˆãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆJã€å½©åº¦S)を使ã„ã¾ã™ã€‚\n3ã¤ç›®ã®å‡¦ç†ã¯â€™è¦³è¦–æ¡ä»¶â€™ã§å‡ºåŠ›ç”»åƒã‚’見るæ¡ä»¶ï¼ˆãƒ¢ãƒ‹ã‚¿ãƒ¼ã€TVã€ãƒ—ロジェクターã€ãƒ—リンターãªã©ã®ã“ã¨ï¼‰ã‚’考慮ã—ã¾ã™ã€‚ã“ã®å‡¦ç†ã«ã‚ˆã‚Šè¡¨ç¤ºåª’体ã«é–¢ã‚らãšåŒã˜ç”»åƒã®è‰²ã‚„コントラストを維æŒã—ã¾ã™ã€‚ TP_LOCALLAB_CIECOLORFRA;色 TP_LOCALLAB_CIECONTFRA;コントラスト -TP_LOCALLAB_CIELIGHTCONTFRA;明るã•ã¨ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ -TP_LOCALLAB_CIELIGHTFRA;明度 -TP_LOCALLAB_CIEMODE;処ç†éŽç¨‹ã®ä½ç½®ã®å¤‰æ›´ +TP_LOCALLAB_CIELIGHTCONTFRA;明る㕠& コントラスト +TP_LOCALLAB_CIELIGHTFRA;明る㕠+TP_LOCALLAB_CIEMODE;機能ã®ä½ç½®å¤‰æ›´ TP_LOCALLAB_CIEMODE_COM;デフォルト TP_LOCALLAB_CIEMODE_DR;ダイナミックレンジ TP_LOCALLAB_CIEMODE_TM;トーンマッピング -TP_LOCALLAB_CIEMODE_TOOLTIP;デフォルトã§ã¯CIECAMãŒå‡¦ç†éŽç¨‹ã®æœ€å¾Œã«ãªã£ã¦ã„ã¾ã™ã€‚"マスクã¨ä¿®æ­£é ˜åŸŸ"ã¨"è¼åº¦ãƒžã‚¹ã‚¯ã‚’ベースã«ã—ãŸå›žå¾©"ã¯"CAM16 + JzCzHz"ã§ä½¿ãˆã¾ã™ã€‚\n好ã¿ã«ä½µã›ã¦ä»–ã®æ©Ÿèƒ½ï¼ˆãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã€ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸åœ§ç¸®ã€å¯¾æ•°ç¬¦å·åŒ–)ã«CIECAMã‚’çµ±åˆã™ã‚‹ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚èª¿æ•´çµæžœã¯CIECAMã‚’çµ±åˆã—ãªã‹ã£ãŸå ´åˆã¨ç•°ãªã‚Šã¾ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯"マスクã¨ä¿®æ­£é ˜åŸŸ"ã¨"è¼åº¦ãƒžã‚¹ã‚¯ã‚’ベースã«ã—ãŸå›žå¾©"ãŒä½¿ãˆã¾ã™ã€‚ +TP_LOCALLAB_CIEMODE_TOOLTIP;デフォルトã§ã¯CIECAMãŒå‡¦ç†éŽç¨‹ã®æœ€å¾Œã«ãªã£ã¦ã„ã¾ã™ã€‚"マスクã¨ä¿®æ­£"ã¨"è¼åº¦ãƒžã‚¹ã‚¯ã‚’ベースã«ã—ãŸè©³ç´°ã®å¾©å…ƒ"ã¯"CAM16 + JzCzHz"ã§ä½¿ãˆã¾ã™ã€‚\n好ã¿ã«ä½µã›ã¦ä»–ã®æ©Ÿèƒ½ï¼ˆãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã€ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸åœ§ç¸®ã€å¯¾æ•°ç¬¦å·åŒ–)ã«CIECAMã‚’çµ±åˆã™ã‚‹ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚èª¿æ•´çµæžœã¯CIECAMã‚’çµ±åˆã—ãªã‹ã£ãŸå ´åˆã¨ç•°ãªã‚Šã¾ã™ã€‚ã“ã®ãƒ¢ãƒ¼ãƒ‰ã§ã¯"マスクã¨ä¿®æ­£"ã¨"è¼åº¦ãƒžã‚¹ã‚¯ã‚’ベースã«ã—ãŸè©³ç´°ã®å¾©å…ƒ"ãŒä½¿ãˆã¾ã™ã€‚ TP_LOCALLAB_CIEMODE_WAV;ウェーブレット TP_LOCALLAB_CIETOOLEXP;カーブ +TP_LOCALLAB_CIE_SMOOTHFRAME;ãƒã‚¤ãƒ©ã‚¤ãƒˆã®æ¸›è¡°ã¨ãƒ¬ãƒ™ãƒ« +TP_LOCALLAB_CIE_SMOOTH_EV;Evをベースã«ã—ãŸæ¸›è¡° +TP_LOCALLAB_CIE_SMOOTH_GAMMA;スロープをベースã«ã—ãŸæ¸›è¡° +TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;ガンマをベースã«ã—ãŸæ¸›è¡° +TP_LOCALLAB_CIE_SMOOTH_LEVELS;レベル +TP_LOCALLAB_CIE_SMOOTH_NONE;ãªã— TP_LOCALLAB_CIE_TOOLNAME;色ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«(CAM16ã¨JzCzHz) -TP_LOCALLAB_CIRCRADIUS;スãƒãƒƒãƒˆã®ä¸­å¿ƒã®å¤§ãã• +TP_LOCALLAB_CIRCRADIUS;スãƒãƒƒãƒˆã®ä¸­å¿ƒå††ã®å¤§ãã• TP_LOCALLAB_CIRCRAD_TOOLTIP;ã“ã®å††å†…ã®æƒ…å ±ãŒRT-スãƒãƒƒãƒˆã®ç·¨é›†ã®åŸºæº–値ã¨ãªã‚Šã¾ã™ã€‚色相ã€è¼åº¦ã€è‰²åº¦ã€Sobelã®å½¢çŠ¶æ¤œå‡ºã«ä½¿ã„ã¾ã™ã€‚\nå°ã•ã„åŠå¾„ã¯èбã®è‰²ãªã©ã®è£œæ­£ã«ã€‚\n大ããªåŠå¾„ã¯è‚Œãªã©ã®è£œæ­£ã«é©ã—ã¦ã„ã¾ã™ã€‚ -TP_LOCALLAB_CLARICRES;色度をèžåˆ +TP_LOCALLAB_CLARICRES;色度ã®èžåˆ TP_LOCALLAB_CLARIFRA;明瞭ã¨ã‚·ãƒ£ãƒ¼ãƒ—マスク/ブレンド & ソフトイメージ TP_LOCALLAB_CLARIJZ_TOOLTIP;レベル0ã‹ã‚‰4ã¾ã§ã¯ã‚·ãƒ£ãƒ¼ãƒ—マスクãŒåƒãã¾ã™\nレベル5以上ã§ã¯æ˜Žçž­ãŒåƒãã¾ã™ TP_LOCALLAB_CLARILRES;è¼åº¦ã®èžåˆ @@ -2748,19 +2961,23 @@ TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;‘ソフトãªåŠå¾„’ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ (ガ TP_LOCALLAB_CLARISOFT_TOOLTIP;'ソフトãªåŠå¾„’ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯ï¼ˆã‚¬ã‚¤ãƒ‰ä»˜ãフィルタã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ï¼‰ã€æ˜Žçž­ã¨ã‚·ãƒ£ãƒ¼ãƒ—マスクã€åŠã³å…¨ã¦ã®ã‚¦ã‚§ãƒ¼ãƒ–レットピラミッドã®å‡¦ç†ã«èµ·å› ã™ã‚‹ãƒãƒ­ã¨ä¸è¦å‰‡æ€§ã‚’軽減ã—ã¾ã™ã€‚作用を無効ã«ã™ã‚‹ã«ã¯å€¤ã‚’0ã«ã—ã¾ã™ã€‚ TP_LOCALLAB_CLARITYML;明瞭 TP_LOCALLAB_CLARI_TOOLTIP;'シャープマスク’ã¯ãƒ¬ãƒ™ãƒ«0~4ã§æœ‰åйã§ã™ã€‚\n’明瞭’ã¯ãƒ¬ãƒ™ãƒ«5ä»¥ä¸Šã§æœ‰åйã§ã™ã€‚\n'レベルã®ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸åœ§ç¸®â€™ã‚’利用ã™ã‚‹å ´åˆã«å½¹ç«‹ã¡ã¾ã™ã€‚ -TP_LOCALLAB_CLIPTM;復元ã•れãŸãƒ‡ãƒ¼ã‚¿ã®åˆ‡ã‚Šå–り(ゲイン) +TP_LOCALLAB_CLIPTM;復元ã•れãŸãƒ‡ãƒ¼ã‚¿ã®åˆ‡ã‚Šè©°ã‚(ゲイン) TP_LOCALLAB_COFR;è‰²ã¨æ˜Žã‚‹ã• -TP_LOCALLAB_COLORDE;ΔEã®ãƒ—レビューカラー - å¼·ã• -TP_LOCALLAB_COLORDEPREV_TOOLTIP;有効ã«ãªã£ã¦ã„る機能ãŒ1ã¤ã ã‘ã®æ™‚ã¯ã€è¨­å®šã®ãƒ‘ãƒãƒ«ï¼ˆæ‹¡å¼µã™ã‚‹ï¼‰ã®Î”Eã®ãƒ—レビューボタンを使ã„ã¾ã™ã€‚\nè¤‡æ•°ã®æ©Ÿèƒ½ãŒæœ‰åйã«ãªã£ã¦ã„る時ã¯ã€å„機能ã«å‚™ã‚ã£ã¦ã„るマスクã¨èª¿ç¯€ã®ä¸­ã®Î”Eã®ãƒ—レビューを使ã„ã¾ã™ã€‚ +TP_LOCALLAB_COLORDE;プレビューΔEã®ã‚«ãƒ©ãƒ¼ - å¼·ã• +TP_LOCALLAB_COLORDEPREV_TOOLTIP;‘ç¾åœ¨ã®ã‚¹ãƒãƒƒãƒˆã«æ©Ÿèƒ½ã‚’追加’ã§é¸ã‚“ã æ©Ÿèƒ½ã®ä¸­ã§ã€è¨­å®šãƒ‘ãƒãƒ«ã§è¡¨ç¤ºã•れる‘プレビューΔEボタン’ãŒä½¿ãˆã‚‹ã®ã¯ã€ã‚·ãƒ£ãƒ¼ãƒ—ニングã€ã‚½ãƒ•トライト&独自ã®ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ã€ã¼ã‹ã—/質感&ノイズ除去ã€éœžé™¤åŽ»ï¼†ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ã€æˆ–ã„ã¯ã€è©³ç´°ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ã ã‘ã§ã™ã€‚\nä»–ã®æ©Ÿèƒ½ã®å ´åˆã¯ã€ãã®æ©Ÿèƒ½ãƒ‘ãƒãƒ«ã®ä¸­ã«è¡¨ç¤ºã•れるプレビューΔEボタンを使ã„ã¾ã™ã€‚ã¾ãŸã€åŒã˜RT-スãƒãƒƒãƒˆã§è¤‡æ•°ã®æ©Ÿèƒ½ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ã€ãƒžã‚¹ã‚¯ã¨ä¿®æ­£é ˜åŸŸã®ã‚³ãƒ³ãƒœãƒœãƒƒã‚¯ã‚¹ã®ä¸­ã«ã‚るプレビューΔEボタンを使ã„ã¾ã™ã€‚ TP_LOCALLAB_COLORDE_TOOLTIP;設定値ãŒãƒžã‚¤ãƒŠã‚¹ã®å ´åˆã¯è‰²å·®ï¼ˆÎ”E)ã®ãƒ—レビューã®è‰²ã‚’ブルーã§è¡¨ç¤ºã€ãƒ—ラスã®å ´åˆã¯ã‚°ãƒªãƒ¼ãƒ³ã§è¡¨ç¤º\n\nマスクã¨èª¿ç¯€ï¼ˆãƒžã‚¹ã‚¯ãªã—ã§å¤‰æ›´ã•れãŸé ˜åŸŸã‚’表示):プラスã§ã‚れã°ã€å®Ÿéš›ã®å¤‰æ›´ã‚’表示ã€ãƒžã‚¤ãƒŠã‚¹ã§ã‚れã°ã€å¼·åŒ–ã•れãŸå¤‰æ›´ï¼ˆè¼åº¦ã®ã¿ï¼‰ã‚’ブルーã¨ã‚¤ã‚¨ãƒ­ãƒ¼ã§è¡¨ç¤º +TP_LOCALLAB_COLORFRAME;主体色 TP_LOCALLAB_COLORSCOPE;カラー機能ã®ã‚¹ã‚³ãƒ¼ãƒ— TP_LOCALLAB_COLORSCOPE_TOOLTIP;è‰²ã¨æ˜Žã‚‹ã•ã€éœ²å…‰è£œæ­£ï¼ˆæ¨™æº–)ã€ã‚·ãƒ£ãƒ‰ã‚¦/ãƒã‚¤ãƒ©ã‚¤ãƒˆã€è‡ªç„¶ãªå½©åº¦ã®æ©Ÿèƒ½ã«ã¯ã“ã®ã‚¹ã‚³ãƒ¼ãƒ—を使ã„ã¾ã™ã€‚\nä»–ã®æ©Ÿèƒ½ã«é–¢ã—ã¦ã¯ã€ãれãžã‚Œã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã«å±žã—ã¦ã„るスコープを使ã„ã¾ã™ã€‚ TP_LOCALLAB_COLOR_CIE;カラーカーブ TP_LOCALLAB_COLOR_TOOLNAME;è‰²ã¨æ˜Žã‚‹ã• TP_LOCALLAB_COL_NAME;åå‰ TP_LOCALLAB_COL_VIS;ステータス -TP_LOCALLAB_COMPFRA;è©³ç´°ãƒ¬ãƒ™ãƒ«ã®æ–¹å‘ã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ +TP_LOCALLAB_COMPFRA;æ–¹å‘ã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ +TP_LOCALLAB_COMPRCIE;明るã•ã®åœ§ç¸® +TP_LOCALLAB_COMPRCIETH;圧縮ã®ã—ãã„値 TP_LOCALLAB_COMPREFRA;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã‚’使ã£ãŸãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ング +TP_LOCALLAB_COMPRLOG_TOOLTIP;ã“れã¯ã€ã—ãã„値以上ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã§ã€ãƒ‡ãƒ¼ã‚¿ã‚’対数変æ›ã™ã‚‹å‰ã«åœ§ç¸®ã™ã‚‹ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã§ã™ã€‚ホワイトã®åˆ†å¸ƒã¨ä½µç”¨ã—ã¦ä½¿ã„ã¾ã™ã€‚ TP_LOCALLAB_CONTCOL;コントラストã—ãã„値 TP_LOCALLAB_CONTFRA;レベルã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ TP_LOCALLAB_CONTRAST;コントラスト @@ -2784,6 +3001,7 @@ TP_LOCALLAB_CURVNONE;カーブを無効 TP_LOCALLAB_DARKRETI;æš—ã• TP_LOCALLAB_DEHAFRA;霞除去 TP_LOCALLAB_DEHAZ;å¼·ã• +TP_LOCALLAB_DEHAZE_BLACK;ブラック TP_LOCALLAB_DEHAZFRAME_TOOLTIP;大気ã«èµ·å› ã™ã‚‹éœžã‚’除去ã—ã¾ã™ã€‚全体ã®å½©åº¦ã¨ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ãŒå‘上ã—ã¾ã™\n色被りも除去ã§ãã¾ã™ãŒã€é’味ãŒã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚‹ã®ã§ã€ãã®å ´åˆã¯åˆ¥ãªæ©Ÿèƒ½ã§è£œæ­£ã—ã¾ã™ TP_LOCALLAB_DEHAZ_TOOLTIP;マイナス値ã«ã™ã‚‹ã¨éœžãŒå¢—ãˆã¾ã™ TP_LOCALLAB_DELTAD;デルタãƒãƒ©ãƒ³ã‚¹ @@ -2796,11 +3014,13 @@ TP_LOCALLAB_DENOICHRODET_TOOLTIP;漸進的ã«ãƒ•ーリエ変æ›ï¼ˆé›¢æ•£ã‚³ã‚µ TP_LOCALLAB_DENOICHROF_TOOLTIP;å°ã•ã„ディテールã®è‰²ãƒŽã‚¤ã‚ºã‚’調整ã—ã¾ã™ TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;ブルー/ã‚¤ã‚¨ãƒ­ãƒ¼ã€æˆ–ã„ã¯ãƒ¬ãƒƒãƒ‰/グリーンã®è£œè‰²æ¬¡å…ƒã§è‰²ãƒŽã‚¤ã‚ºã‚’軽減ã—ã¾ã™ TP_LOCALLAB_DENOIEQUAL_TOOLTIP;ã‚·ãƒ£ãƒ‰ã‚¦ã€æˆ–ã„ã¯ãƒã‚¤ãƒ©ã‚¤ãƒˆéƒ¨åˆ†ã§ã€ã‚る程度ノイズ低減を実行出æ¥ã¾ã™ -TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;漸進的ã«ãƒ•ーリエ変æ›ï¼ˆé›¢æ•£ã‚³ã‚µã‚¤ãƒ³å¤‰æ›ï¼‰ã‚’é©ç”¨ã™ã‚‹ã“ã¨ã§ã€è¼åº¦ã®ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã‚’回復ã—ã¾ã™ +TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;漸進的ã«ãƒ•ーリエ変æ›ï¼ˆé›¢æ•£ã‚³ã‚µã‚¤ãƒ³å¤‰æ›ï¼‰ã‚’é©ç”¨ã™ã‚‹ã“ã¨ã§ã€è¼åº¦ã®ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã‚’回復ã—ã¾ã™ TP_LOCALLAB_DENOIMASK;色ノイズã®ãƒžã‚¹ã‚¯ TP_LOCALLAB_DENOIMASK_TOOLTIP;å…¨ã¦ã®æ©Ÿèƒ½ã§ãƒžã‚¹ã‚¯ã®è‰²ãƒŽã‚¤ã‚ºã®ç¨‹åº¦ã‚’加減ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\nLC(h)カーブを使ã†éš›ã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトをé¿ã‘ãŸã‚Šã€è‰²åº¦ã‚’コントロールã™ã‚‹ã®ã«ä¾¿åˆ©ã§ã™ã€‚ -TP_LOCALLAB_DENOIQUA_TOOLTIP;’控ãˆç›®â€™ãªãƒ¢ãƒ¼ãƒ‰ã§ã¯ã€ä½Žå‘¨æ³¢ãƒŽã‚¤ã‚ºã¯é™¤åŽ»ã•れã¾ã›ã‚“ã€‚â€™ç©æ¥µçš„’ãªãƒ¢ãƒ¼ãƒ‰ã¯ä½Žå‘¨æ³¢ãƒŽã‚¤ã‚ºã‚‚除去ã—ã¾ã™ã€‚\n’控ãˆç›®â€™ã‚‚â€™ç©æ¥µçš„’もã€ã‚¦ã‚§ãƒ¼ãƒ–レットã¨DCTを使ã„ã¾ã™ãŒã€â€™è¼åº¦ã®ãƒŽãƒ³ãƒ­ãƒ¼ã‚«ãƒ«ãƒŸãƒ¼ãƒ³â€™ã‚’併用ã™ã‚‹ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚ -TP_LOCALLAB_DENOITHR_TOOLTIP;å‡ä¸€åŠã³ä½Žã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆéƒ¨åˆ†ã®ãƒŽã‚¤ã‚ºã‚’減らã™è£œåŠ©ã¨ã—ã¦ã‚¨ãƒƒã‚¸æ¤œå‡ºã‚’調整ã—ã¾ã™ +TP_LOCALLAB_DENOIQUA_TOOLTIP;’控ãˆç›®â€™ãªãƒ¢ãƒ¼ãƒ‰ã§ã¯ã€ä½Žå‘¨æ³¢ãƒŽã‚¤ã‚ºã¯é™¤åŽ»ã•れã¾ã›ã‚“ã€‚â€™ç©æ¥µçš„’ãªãƒ¢ãƒ¼ãƒ‰ã¯ä½Žå‘¨æ³¢ãƒŽã‚¤ã‚ºã‚‚除去ã—ã¾ã™ã€‚\n’控ãˆç›®â€™ã‚‚â€™ç©æ¥µçš„’もã€ã‚¦ã‚§ãƒ¼ãƒ–レットã¨DCTを使ã„ã¾ã™ãŒã€â€™è¼åº¦ã®éžå±€æ‰€å¹³å‡ãƒ•ィルタ’を併用ã™ã‚‹ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚ +TP_LOCALLAB_DENOITHR_TOOLTIP;å‡ä¸€åŠã³ä½Žã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆéƒ¨åˆ†ã®ãƒŽã‚¤ã‚ºã‚’減らã™è£œåŠ©ã¨ã—ã¦ã‚¨ãƒƒã‚¸æ¤œå‡ºã‚’調整ã—ã¾ã™ +TP_LOCALLAB_DENOIWAVCH;ウェーブレット: 色ノイズ +TP_LOCALLAB_DENOIWAVLUM;ウェーブレット: è¼åº¦ãƒŽã‚¤ã‚º TP_LOCALLAB_DENOI_EXP;ノイズ除去 TP_LOCALLAB_DENOI_TOOLTIP;ã“ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯å˜ç‹¬ã®ãƒŽã‚¤ã‚ºä½Žæ¸›æ©Ÿèƒ½ï¼ˆå‡¦ç†å·¥ç¨‹ã®æœ€å¾Œã®æ–¹ã«ä½ç½®ï¼‰ã¨ã—ã¦ã€æˆ–ã„ã¯ãƒ¡ã‚¤ãƒ³ã®ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã‚¿ãƒ–ã«ä»˜å±žã™ã‚‹ãƒŽã‚¤ã‚ºä½Žæ¸›ï¼ˆå‡¦ç†å·¥ç¨‹ã®æœ€åˆã®æ–¹ã«ä½ç½®ï¼‰ã®è¿½åŠ æ©Ÿèƒ½ã¨ã—ã¦ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n色(ΔE)を基本ã«ã€ã‚¹ã‚³ãƒ¼ãƒ—を使ã£ã¦ä½œç”¨ã«å·®ã‚’付ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n但ã—ã€RT-スãƒãƒƒãƒˆã¯æœ€ä½Ž128x128ã®å¤§ãã•ã®å¿…è¦ã§ã™ TP_LOCALLAB_DEPTH;深度 @@ -2808,6 +3028,7 @@ TP_LOCALLAB_DETAIL;ローカルコントラスト TP_LOCALLAB_DETAILFRA;エッジ検出 - DCT TP_LOCALLAB_DETAILSH;ディテール TP_LOCALLAB_DETAILTHR;è¼åº¦ã¨è‰²ã®è©³ç´°ã®ã—ãã„値 +TP_LOCALLAB_DISAB_CIECAM;CIECAMã€æˆ–ã„ã¯å¼±ã„Jz状態を無効ã«ã™ã‚‹ TP_LOCALLAB_DIVGR;ガンマ TP_LOCALLAB_DUPLSPOTNAME;コピー TP_LOCALLAB_EDGFRA;エッジシャープãƒã‚¹ @@ -2816,6 +3037,7 @@ TP_LOCALLAB_ELI;楕円 TP_LOCALLAB_ENABLE_AFTER_MASK;トーンマッピングを使ㆠTP_LOCALLAB_ENABLE_MASK;マスクを有効ã«ã™ã‚‹ TP_LOCALLAB_ENABLE_MASKAFT;露光補正ã®å…¨ã¦ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’使ㆠ+TP_LOCALLAB_ENABLE_MASKALL;å…¨ã¦ã®ãƒžã‚¹ã‚¯ãƒ„ールを有効ã«ã™ã‚‹ TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;å…ƒã®ãƒ‡ãƒ¼ã‚¿ã®ä»£ã‚りã«é€éŽãƒžãƒƒãƒ—を使ã£ãŸå¾Œã¯ã€æœ‰åйã«ã—ãŸãƒžã‚¹ã‚¯ã¯ä¿®å¾©ã•れãŸãƒ‡ãƒ¼ã‚¿ã‚’使ã„ã¾ã™ã€‚ TP_LOCALLAB_ENH;強化 TP_LOCALLAB_ENHDEN;強化 + 色ノイズã®è»½æ¸› @@ -2831,9 +3053,10 @@ TP_LOCALLAB_EV_VIS_ALL;å…¨ã¦è¡¨ç¤º TP_LOCALLAB_EXCLUF;除外 TP_LOCALLAB_EXCLUF_TOOLTIP;’除外’モードã¯RT-スãƒãƒƒãƒˆã®ä¸­ã«ç·¨é›†ã®å½±éŸ¿ã‚’å—ã‘ãŸããªã„部分ãŒã‚ã‚‹å ´åˆã€åˆ¥ãªRT-スãƒãƒƒãƒˆã§é™¤å¤–ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã€ãã®éƒ¨åˆ†ã®ç·¨é›†åŠ¹æžœã‚’ç„¡åŠ¹ã«ã—ã¾ã™ã€‚’スコープ’を使ãˆã°å½±éŸ¿ã‚’無効ã«ã™ã‚‹ç¯„囲を調整出æ¥ã¾ã™\n除外スãƒãƒƒãƒˆã«åˆ¥ãªæ©Ÿèƒ½ã‚’追加ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã‚‹ã®ã§ã€é€šå¸¸ã‚¹ãƒãƒƒãƒˆã®æ§˜ã«ä½¿ã†ã“ã¨ã‚‚å¯èƒ½ã§ã™ï¼ˆç›®æ¨™ã¨ã™ã‚‹åŠ¹æžœã‚’ç„¡åŠ¹ã«ã—ã¦ã€åˆ¥ãªæ©Ÿèƒ½ã®åŠ¹æžœã‚’å‡ºã™ã‚ˆã†ãªå ´åˆï¼‰ TP_LOCALLAB_EXCLUTYPE;スãƒãƒƒãƒˆã®ã‚¿ã‚¤ãƒ— -TP_LOCALLAB_EXCLUTYPE_TOOLTIP;通常スãƒãƒƒãƒˆãŒä½¿ã†æƒ…å ±ã¯å†å¸°çš„ã«ãªã‚Šã¾ã™ã€‚\n\n除外スãƒãƒƒãƒˆã¯ãƒ­ãƒ¼ã‚«ãƒ«èª¿æ•´ã®ãƒ‡ãƒ¼ã‚¿ã‚’å†åˆæœŸåŒ–ã—ã¾ã™ã€‚\nãれã¾ã§ã®ä½œç”¨ã‚’ä¸€éƒ¨ã€æˆ–ã„ã¯å…¨ã¦ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã™ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚或ã„ã¯ã€ã‚¤ãƒ³ãƒãƒ¼ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§å‹•作を実行ã™ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n\n’画åƒå…¨ä½“’ã¯ãƒ­ãƒ¼ã‚«ãƒ«ç·¨é›†ã®æ©Ÿèƒ½ã‚’ç”»åƒå…¨ä½“ã§ä½¿ã†ãŸã‚ã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚\nRT-スãƒãƒƒãƒˆã®ãƒ•レーム(外枠)ãŒãƒ—レビュー画åƒã®å¤–å´ã«è‡ªå‹•ã§è¨­å®šã•れã¾ã™ã€‚\n’境界ã®éšŽèª¿èª¿ç¯€â€™ã®å¢ƒç•Œå€¤ãŒè‡ªå‹•ã§100ã«è¨­å®šã•れã¾ã™ã€‚\n注æ„1:目標ã¨ã™ã‚‹èª¿æ•´ã«å¿œã˜ã¦ã€RT-スãƒãƒƒãƒˆã®ä¸­å¿ƒå††ã®ä½ç½®ã‚„大ãã•を変ãˆã¾ã™ã€‚\n注æ„2:ã“ã®ã‚¹ãƒãƒƒãƒˆã‚¿ã‚¤ãƒ—ã§ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚„ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆã€æˆ–ã„ã¯é«˜é€Ÿãƒ•ーリエ変æ›ã‚’使ã†å ´åˆã¯ãƒ¡ãƒ¢ãƒªãƒ¼æ¶ˆè²»é‡ãŒéžå¸¸ã«å¤§ãããªã‚Šã¾ã™ã€‚PCã®ã‚¹ãƒšãƒƒã‚¯ãŒä½Žã„ã¨ãƒ—ログラムãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã™ã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;通常スãƒãƒƒãƒˆãŒä½¿ã†æƒ…å ±ã¯å†å¸°çš„ã«ãªã‚Šã¾ã™ã€‚\n\n除外スãƒãƒƒãƒˆã¯ãƒ­ãƒ¼ã‚«ãƒ«èª¿æ•´ã®ãƒ‡ãƒ¼ã‚¿ã‚’å†åˆæœŸåŒ–ã—ã¾ã™ã€‚\nãれã¾ã§ã®ä½œç”¨ã‚’ä¸€éƒ¨ã€æˆ–ã„ã¯å…¨ã¦ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã™ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚或ã„ã¯ã€ã‚¤ãƒ³ãƒãƒ¼ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§å‹•作を実行ã™ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n\n’画åƒå…¨ä½“’ã¯ãƒ­ãƒ¼ã‚«ãƒ«ç·¨é›†ã®æ©Ÿèƒ½ã‚’ç”»åƒå…¨ä½“ã§ä½¿ã†ãŸã‚ã®ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚\nRT-スãƒãƒƒãƒˆã®ãƒ•レーム(外枠)ãŒãƒ—レビュー画åƒã®å¤–å´ã«è‡ªå‹•ã§è¨­å®šã•れã¾ã™ã€‚\n’変移ã®éšŽèª¿â€™ã®å¤‰ç§»ã®ä½ç½®ãŒè‡ªå‹•ã§100ã«è¨­å®šã•れã¾ã™ã€‚\n注æ„1:目標ã¨ã™ã‚‹èª¿æ•´ã«å¿œã˜ã¦ã€RT-スãƒãƒƒãƒˆã®ä¸­å¿ƒå††ã®ä½ç½®ã‚„大ãã•を変ãˆã¾ã™ã€‚\n注æ„2:ã“ã®ã‚¹ãƒãƒƒãƒˆã‚¿ã‚¤ãƒ—ã§ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚„ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆã€æˆ–ã„ã¯é«˜é€Ÿãƒ•ーリエ変æ›ã‚’使ã†å ´åˆã¯ãƒ¡ãƒ¢ãƒªãƒ¼æ¶ˆè²»é‡ãŒéžå¸¸ã«å¤§ãããªã‚Šã¾ã™ã€‚PCã®ã‚¹ãƒšãƒƒã‚¯ãŒä½Žã„ã¨ãƒ—ログラムãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã™ã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚\n\n‘グローãƒãƒ«â€™ã‚’é¸æŠžã™ã‚‹ã¨ã€Î”Eã¨å¤‰ç§»ã®éšŽèª¿ã«å½±éŸ¿ã‚’å—ã‘ãšã«ã€ç”»åƒå…¨ä½“ã§ãƒ­ãƒ¼ã‚«ãƒ«ç·¨é›†ã®æ©Ÿèƒ½ã‚’使ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ TP_LOCALLAB_EXECLU;除外スãƒãƒƒãƒˆ TP_LOCALLAB_EXFULL;ç”»åƒå…¨ä½“ +TP_LOCALLAB_EXMAIN;グローãƒãƒ« TP_LOCALLAB_EXNORM;通常スãƒãƒƒãƒˆ TP_LOCALLAB_EXPCBDL_TOOLTIP;ã‚»ãƒ³ã‚µãƒ¼ã‚„ãƒ¬ãƒ³ã‚ºã®æ±šã‚Œè·¡ã‚’ã€ãれã«è©²å½“ã™ã‚‹è©³ç´°ãƒ¬ãƒ™ãƒ«ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’減らã™ã“ã¨ã§é™¤åŽ»ã—ã¾ã™ã€‚ TP_LOCALLAB_EXPCHROMA;色度ã®è£œé–“ @@ -2841,22 +3064,22 @@ TP_LOCALLAB_EXPCHROMA_TOOLTIP;色ãŒè¤ªã›ã‚‹ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã€â€™éœ²å…‰ TP_LOCALLAB_EXPCOLOR_TOOLTIP;è‰²ã€æ˜Žåº¦ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®èª¿æ•´ã«ä½¿ã„ã¾ã™ã€‚èµ¤ç›®ã‚„ã‚»ãƒ³ã‚µãƒ¼ã®æ±šã‚Œã«èµ·å› ã™ã‚‹ä¸è‰¯ã®è£œæ­£ã«ã‚‚使ãˆã¾ã™ã€‚ TP_LOCALLAB_EXPCOMP;露光é‡è£œæ­£ Æ’ TP_LOCALLAB_EXPCOMPINV;露光é‡è£œæ­£ -TP_LOCALLAB_EXPCOMP_TOOLTIP;ãƒãƒ¼ãƒˆãƒ¬ãƒ¼ãƒˆæˆ–ã„ã¯è‰²ã®éšŽèª¿ãŒå°‘ãªã„ç”»åƒã®å ´åˆã€â€™è¨­å®šâ€™ã®â€™å½¢çŠ¶æ¤œå‡ºâ€™ã‚’èª¿æ•´ã—ã¾ã™:\n\n’ΔEスコープã®ã—ãã„値’を増やã—ã¾ã™\n’ΔEã®æ¸›è¡°â€™ã‚’減らã—ã¾ã™\n’ãƒãƒ©ãƒ³ã‚¹ã€€ab-L(ΔE)'を増やã—ã¾ã™ +TP_LOCALLAB_EXPCOMP_TOOLTIP;ãƒãƒ¼ãƒˆãƒ¬ãƒ¼ãƒˆæˆ–ã„ã¯è‰²ã®éšŽèª¿ãŒå°‘ãªã„ç”»åƒã®å ´åˆã€â€™è¨­å®šâ€™ã®â€™å½¢çŠ¶æ¤œå‡ºâ€™ã‚’èª¿æ•´ã—ã¾ã™:\n\n’ΔEスコープã®ã—ãã„値’を増やã—ã¾ã™\n’ΔEã®æ¸›è¡°â€™ã‚’減らã—ã¾ã™\n’ãƒãƒ©ãƒ³ã‚¹ã€€ab-L(ΔE)'を増やã—ã¾ã™ TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;RawPediaã®'ウェーブレットã®ãƒ¬ãƒ™ãƒ«â€™ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„。\nローカル編集ã®ã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ã¯ç•°ãªã‚‹éƒ¨åˆ†ãŒå¹¾ã¤ã‹ã‚りã¾ã™ï¼šå„ディテールã®ãƒ¬ãƒ™ãƒ«ã«å¯¾ã™ã‚‹èª¿æ•´æ©Ÿèƒ½ãŒã‚ˆã‚Šå¤šãã€å¤šæ§˜æ€§ãŒå¢—ã—ã¾ã™ã€‚\n例ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ã®ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã§ã™ã€‚ -TP_LOCALLAB_EXPCONTRAST_TOOLTIP;ã‚ã¾ã‚Šã«å°ã•ã„RT-スãƒãƒƒãƒˆã®è¨­å®šã¯é¿ã‘ã¾ã™ï¼ˆå°‘ãªãã¨ã‚‚32x32ピクセル以上)。\n低ã„’境界値’ã¨é«˜ã„â€™å¢ƒç•Œã®æ¸›è¡°â€™å€¤ã€åŠã³â€™ã‚¹ã‚³ãƒ¼ãƒ—’値を使ã„ã€å°ã•ã„RT-スãƒãƒƒãƒˆã‚’çœŸä¼¼ã¦æ¬ é™¥éƒ¨åˆ†ã‚’補正ã—ã¾ã™ã€‚\nアーティファクトを軽減ã™ã‚‹ãŸã‚ã«ã€å¿…è¦ã«å¿œã˜ã¦â€™ã‚½ãƒ•トãªåŠå¾„’を調整ã—㦠’明瞭ã¨ã‚·ãƒ£ãƒ¼ãƒ—マスク’ã€â€™ãƒ•ァイルã®èžåˆâ€™ã‚’使ã„ã¾ã™ã€‚ +TP_LOCALLAB_EXPCONTRAST_TOOLTIP;ã‚ã¾ã‚Šã«å°ã•ã„RT-スãƒãƒƒãƒˆã®è¨­å®šã¯é¿ã‘ã¾ã™ï¼ˆå°‘ãªãã¨ã‚‚32x32ピクセル以上)。\n低ã„’変移ã®ä½ç½®â€™ã¨é«˜ã„â€™å¤‰ç§»ã®æ¸›è¡°â€™å€¤ã€åŠã³â€™ã‚¹ã‚³ãƒ¼ãƒ—’値を使ã„ã€å°ã•ã„RT-スãƒãƒƒãƒˆã‚’çœŸä¼¼ã¦æ¬ é™¥éƒ¨åˆ†ã‚’補正ã—ã¾ã™ã€‚\nアーティファクトを軽減ã™ã‚‹ãŸã‚ã«ã€å¿…è¦ã«å¿œã˜ã¦â€™ã‚½ãƒ•トãªåŠå¾„’を調整ã—㦠’明瞭ã¨ã‚·ãƒ£ãƒ¼ãƒ—マスク’ã€â€™ãƒ•ァイルã®èžåˆâ€™ã‚’使ã„ã¾ã™ã€‚ TP_LOCALLAB_EXPCURV;カーブ TP_LOCALLAB_EXPGRAD;階調フィルタ TP_LOCALLAB_EXPGRADCOL_TOOLTIP;階調フィルタã¯â€™è‰²ã¨æ˜Žã‚‹ã•’ã®è¼åº¦ã€è‰²åº¦ã€è‰²ç›¸ã®éšŽèª¿ã¨ã€ãƒ•ァイルã®èžåˆã€'露光補正'ã®è¼åº¦ã®éšŽèª¿ã€ã€'露光補正マスク'ã®è¼åº¦ã®éšŽèª¿ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ'ã®è¼åº¦ã®éšŽèª¿ã€'自然ãªå½©åº¦'ã®è¼åº¦ã€è‰²åº¦ã€è‰²ç›¸ã®éšŽèª¿ã€â€™ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆï¼†ã‚¦ã‚§ãƒ¼ãƒ–レットピラミッド’ã®ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®éšŽèª¿ã§ä½¿ãˆã¾ã™ã€‚\nフェザー処ç†ã¯â€™è¨­å®šâ€™ã®ä¸­ã«ã‚りã¾ã™ã€‚ TP_LOCALLAB_EXPLAPBAL_TOOLTIP;変化ã•ã›ãŸç”»åƒã¨å…ƒã®ç”»åƒã®ãƒ–レンドを変ãˆã¾ã™ -TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;ラプラス変æ›å‰å¾Œã«ã‚¬ãƒ³ãƒžã‚«ãƒ¼ãƒ–を加ãˆã¦ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒéŽå‰°ãªã€æˆ–ã„ã¯ä¸è¶³ã—ãŸç”»åƒã‚’修正ã—ã¾ã™ -TP_LOCALLAB_EXPLAPLIN_TOOLTIP;ラプラス変æ›ã‚’é©ç”¨ã™ã‚‹å‰ã«ã€ç·šå½¢è¦ç´ ã‚’加ãˆã€éœ²å‡ºä¸è¶³ã®ç”»åƒã‚’修正ã—ã¾ã™ +TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;ラプラス作用素ã®å‰å¾Œã«ã‚¬ãƒ³ãƒžè£œæ­£ã‚’加ãˆã¦ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒéŽå‰°ãªã€æˆ–ã„ã¯ä¸è¶³ã—ãŸç”»åƒã‚’修正ã—ã¾ã™ +TP_LOCALLAB_EXPLAPLIN_TOOLTIP;ラプラス作用素をé©ç”¨ã™ã‚‹å‰ã«ã€ç·šå½¢è¦ç´ ã‚’加ãˆã€éœ²å‡ºä¸è¶³ã®ç”»åƒã‚’修正ã—ã¾ã™ TP_LOCALLAB_EXPLAP_TOOLTIP;スライダーをå³ã«ç§»å‹•ã™ã‚‹ã¨æ¼¸é€²çš„ã«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒæ¸›å°‘ã—ã¾ã™ TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;ä¸é€æ˜Žåº¦ã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«ã§ã€GIMPã‚„Photoshop(C)ã®ã€Difference, Multiply, Soft Light, Overlayãªã©ã®ãƒ¬ã‚¤ãƒ¤ãƒ¼èžåˆãƒ¢ãƒ¼ãƒ‰ãŒä½¿ãˆã¾ã™ã€‚\n元画åƒï¼šç¾åœ¨ã®RT-スãƒãƒƒãƒˆã¨å…ƒç”»åƒã®èžåˆ\nå‰ã®RT-スãƒãƒƒãƒˆï¼šç¾åœ¨ã®RT-スãƒãƒƒãƒˆã¨å‰ã®RT-スãƒãƒƒãƒˆã‚’èžåˆï¼ˆä½†ã—ã€å‰ã®ã‚¹ãƒãƒƒãƒˆãŒã‚ã‚‹å ´åˆã«é™ã‚‹ã€ãªã„å ´åˆã¯å…ƒç”»åƒã¨èžåˆï¼‰\n背景:ç¾åœ¨ã®RT-スãƒãƒƒãƒˆã¨èƒŒæ™¯ã®è‰²ã¨è¼åº¦ã‚’èžåˆ -TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;アーティファクト(ノイズ)ã®ç™ºç”Ÿã‚’é¿ã‘ã‚‹ãŸã‚ã€ãƒ©ãƒ—ラス変æ›ã®å‰ã«ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ³ãƒ•ィルタをé©ç”¨ã—ã¾ã™ +TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;アーティファクト(ノイズ)ã®ç™ºç”Ÿã‚’é¿ã‘ã‚‹ãŸã‚ã€ãƒ©ãƒ—ラス作用素をé©ç”¨ã™ã‚‹å‰ã«ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ³ãƒ•ィルタをé©ç”¨ã—ã¾ã™ TP_LOCALLAB_EXPOSE;ダイナミックレンジ & 露光補正 TP_LOCALLAB_EXPOSURE_TOOLTIP;シャドウ部分ãŒå¼·ã„よã†ãªå ´åˆã¯ã€â€™ã‚·ãƒ£ãƒ‰ã‚¦/ãƒã‚¤ãƒ©ã‚¤ãƒˆâ€™ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ãŒä½¿ãˆã¾ã™ TP_LOCALLAB_EXPRETITOOLS;高度ãªãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹æ©Ÿèƒ½ -TP_LOCALLAB_EXPSHARP_TOOLTIP;RT-スãƒãƒƒãƒˆã®å¤§ãã•ãŒæœ€ä½Žã§ã‚‚39x39ピクセル必è¦ã§ã™\nスãƒãƒƒãƒˆãŒå°ã•ã„å ´åˆã¯ã€ä½Žã„境界値ã€é«˜ã„減衰値ã€é«˜ã„スコープ値を設定ã—ã¾ã™ +TP_LOCALLAB_EXPSHARP_TOOLTIP;RT-スãƒãƒƒãƒˆã®å¤§ãã•ãŒæœ€ä½Žã§ã‚‚39x39ピクセル必è¦ã§ã™\nスãƒãƒƒãƒˆãŒå°ã•ã„å ´åˆã¯ã€ä½Žã„変移ã®ä½ç½®ã€é«˜ã„減衰値ã€é«˜ã„スコープ値を設定ã—ã¾ã™ TP_LOCALLAB_EXPTOOL;éœ²å…‰è£œæ­£ã®æ©Ÿèƒ½ TP_LOCALLAB_EXP_TOOLNAME;ダイナミックレンジ & 露光補正 TP_LOCALLAB_FATAMOUNT;é‡ @@ -2865,6 +3088,7 @@ TP_LOCALLAB_FATDETAIL;ディテール TP_LOCALLAB_FATFRA;ダイナミックレンジ圧縮 Æ’ TP_LOCALLAB_FATFRAME_TOOLTIP;ã“ã“ã§ã¯Fattalã®ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングアルゴリズムを使ã„ã¾ã™\nアンカーã§ç”»åƒã®éœ²å‡ºä¸è¶³ãƒ»éŽå¤šã«å¿œã˜ãŸé¸æŠžãŒå‡ºæ¥ã¾ã™\nç¾åœ¨ã®ã‚¹ãƒãƒƒãƒˆã«è¿‘ãã€ãƒžã‚¹ã‚¯ã‚’使用ã™ã‚‹2番目ã®ã‚¹ãƒãƒƒãƒˆã®è¼åº¦ã‚’増やã™ã®ã«ä¾¿åˆ©ã§ã™ TP_LOCALLAB_FATLEVEL;シグマ +TP_LOCALLAB_FATSAT;å½©åº¦ã®æŠ‘åˆ¶ TP_LOCALLAB_FATSHFRA;マスクã®ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸åœ§ç¸®ã®ãƒžã‚¹ã‚¯ Æ’ TP_LOCALLAB_FEATH_TOOLTIP;RT-スãƒãƒƒãƒˆã®å¯¾è§’ç·šã®é•·ã•ã«å¯¾ã™ã‚‹è«§èª¿å¹…ã®å‰²åˆã§ä½œç”¨ã—ã¾ã™\nã“れã¯éšŽèª¿ãƒ•ィルタを備ãˆã¦ã„るモジュール全ã¦ã«å…±é€šã§ã™\n但ã—ã€ãƒ•ェザー処ç†ãŒåƒãã®ã¯ã€éšŽèª¿ãƒ•ィルタã®ä¸­ã§ä¸€ã¤ä»¥ä¸Šã®èª¿æ•´ãŒè¡Œã‚れã¦ã„ã‚‹å ´åˆã ã‘ã§ã™ TP_LOCALLAB_FEATVALUE;ãƒ•ã‚§ã‚¶ãƒ¼å‡¦ç† @@ -2883,11 +3107,16 @@ TP_LOCALLAB_GAMM;ガンマ TP_LOCALLAB_GAMMASKCOL;ガンマ TP_LOCALLAB_GAMMASK_TOOLTIP;ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—を調整ã™ã‚‹ã¨ã€ä¸é€£ç¶šã«ãªã‚‹ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã«â€™L’ãŒå¾ã€…ã«å¤‰ã‚ã‚‹ãŸã‚ã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトを発生ã•ã›ãšã«ãƒžã‚¹ã‚¯ã®ä¿®æ­£ãŒå‡ºæ¥ã¾ã™ TP_LOCALLAB_GAMSH;ガンマ +TP_LOCALLAB_GAMUTLABRELA;L*a*b* +TP_LOCALLAB_GAMUTMUNSELL;マンセル補正ã ã‘ +TP_LOCALLAB_GAMUTNON;ãªã— +TP_LOCALLAB_GAMUTXYZABSO;XYZ 絶対 +TP_LOCALLAB_GAMUTXYZRELA;XYZ 相対 TP_LOCALLAB_GAMW;ガンマ(ウェーブレットピラミッド) TP_LOCALLAB_GRADANG;階調フィルタã®è§’度 TP_LOCALLAB_GRADANG_TOOLTIP;-180度ã‹ã‚‰+180度ã®é–“ã§è§’度を調整 TP_LOCALLAB_GRADFRA;階調フィルタã®ãƒžã‚¹ã‚¯ -TP_LOCALLAB_GRADGEN_TOOLTIP;éšŽèª¿ãƒ•ã‚£ãƒ«ã‚¿ã®æ©Ÿèƒ½ã¯â€™è‰²ã¨æ˜Žã‚‹ã•’ã¨ã€â€™éœ²å…‰â€™ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆâ€ã€â€™è‡ªç„¶ãªå½©åº¦â€™ã«å‚™ã‚ã£ã¦ã„ã¾ã™\n\n自然ãªå½©åº¦ã€è‰²ã¨æ˜Žã‚‹ã•ã«ã¯è¼åº¦ã€è‰²èª¿ã€è‰²ç›¸ã®éšŽèª¿ãƒ•ィルタãŒä½¿ãˆã¾ã™\nフェザー処ç†ã¯è¨­å®šã®ä¸­ã«ã‚りã¾ã™ +TP_LOCALLAB_GRADGEN_TOOLTIP;éšŽèª¿ãƒ•ã‚£ãƒ«ã‚¿ã®æ©Ÿèƒ½ã¯â€™è‰²ã¨æ˜Žã‚‹ã•’ã¨ã€â€™éœ²å…‰â€™ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆâ€ã€â€™è‡ªç„¶ãªå½©åº¦â€™ã«å‚™ã‚ã£ã¦ã„ã¾ã™\n\n自然ãªå½©åº¦ã€è‰²ã¨æ˜Žã‚‹ã•ã«ã¯è¼åº¦ã€è‰²èª¿ã€è‰²ç›¸ã®éšŽèª¿ãƒ•ィルタãŒä½¿ãˆã¾ã™\nフェザー処ç†ã¯è¨­å®šã®ä¸­ã«ã‚りã¾ã™ TP_LOCALLAB_GRADLOGFRA;è¼åº¦ã®éšŽèª¿ãƒ•ィルタ TP_LOCALLAB_GRADSTR;階調フィルタ 強㕠TP_LOCALLAB_GRADSTRAB_TOOLTIP;色度ã®éšŽèª¿ã®å¼·ã•を調整ã—ã¾ã™ @@ -2900,7 +3129,7 @@ TP_LOCALLAB_GRAINFRA;フィルムã®è³ªæ„Ÿ 1:1 TP_LOCALLAB_GRAINFRA2;ç²—ã„ TP_LOCALLAB_GRAIN_TOOLTIP;ç”»åƒã«ãƒ•ィルムã®ã‚ˆã†ãªè³ªæ„Ÿã‚’加ãˆã¾ã™ TP_LOCALLAB_GRALWFRA;階調フィルタ(ローカルコントラスト) -TP_LOCALLAB_GRIDFRAME_TOOLTIP;ã“ã®ãƒ„ールã¯ãƒ–ラシã¨ã—ã¦ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚å°ã•ã„RT-スãƒãƒƒãƒˆã¨ä½Žã„‘境界値’ã€â€˜å¢ƒç•Œå€¤ã®æ¸›è¡°â€™ã‚’設定ã—ã¾ã™ã€‚\n‘標準’モードã ã‘ã§ä½¿ã„ã¾ã™ã€‚èžåˆã™ã‚‹èƒŒæ™¯ï¼ˆÎ”E)ã«é–¢ä¿‚ã™ã‚‹ã®ã¯è‰²ç›¸ã€å½©åº¦ã€è‰²ã€è¼åº¦ã§ã™ã€‚ +TP_LOCALLAB_GRIDFRAME_TOOLTIP;ã“ã®ãƒ„ールã¯ãƒ–ラシã¨ã—ã¦ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚å°ã•ã„RT-スãƒãƒƒãƒˆã¨ä½Žã„‘変移ã®ä½ç½®â€™ã€â€˜å¤‰ç§»ã®æ¸›è¡°â€™ã‚’設定ã—ã¾ã™ã€‚\n‘標準’モードã ã‘ã§ä½¿ã„ã¾ã™ã€‚èžåˆã™ã‚‹èƒŒæ™¯ï¼ˆÎ”E)ã«é–¢ä¿‚ã™ã‚‹ã®ã¯è‰²ç›¸ã€å½©åº¦ã€è‰²ã€è¼åº¦ã§ã™ã€‚ TP_LOCALLAB_GRIDMETH_TOOLTIP;カラートーン調整:色ãŒå¤‰ã‚ã‚‹éš›ã«è¼åº¦ã‚’考慮ã—ã¾ã™ã€‚グリッド上ã®â€™ç™½ã„点’ã¯0ã®ä½ç½®ã€â€™é»’ã„点’ã ã‘を移動ã—ãŸå ´åˆã¯ã€H=f(H)ã¨åŒã˜åŠ¹æžœã§ã™ã€‚両方ã®ç‚¹ã‚’移動ã—ãŸå ´åˆã«â€™ã‚«ãƒ©ãƒ¼ãƒˆãƒ¼ãƒ³èª¿æ•´â€™ã®åŠ¹æžœã«ãªã‚Šã¾ã™ã€‚\n\n直接:色度ã«ç›´æŽ¥ä½œç”¨ã—ã¾ã™ã€‚ TP_LOCALLAB_GRIDONE;カラートーン調整 TP_LOCALLAB_GRIDTWO;直接 @@ -2908,7 +3137,7 @@ TP_LOCALLAB_GUIDBL;ソフトãªåŠå¾„ TP_LOCALLAB_GUIDBL_TOOLTIP;åŠå¾„を変ãˆã‚‰ã‚Œã‚‹ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタをé©ç”¨ã—ã¾ã™ã€‚アーティファクトを軽減ã—ãŸã‚Šã€ç”»åƒã«ã¼ã‹ã—を掛ã‘ãŸã‚Šå‡ºæ¥ã¾ã™ã€‚ TP_LOCALLAB_GUIDEPSBL_TOOLTIP;ガイド付ãフィルタã®é…分機能を変化ã•ã›ã¾ã™ã€‚マイナス値ã®è¨­å®šã¯ã‚¬ã‚¦ã‚¹ã¼ã‹ã—ã«ä¼¼ãŸåŠ¹æžœã¨ãªã‚Šã¾ã™ TP_LOCALLAB_GUIDFILTER;ガイド付ãフィルタã®åŠå¾„ -TP_LOCALLAB_GUIDFILTER_TOOLTIP;ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆãŒæ¸›ã£ãŸã‚Šã€å¢—ãˆãŸã‚Šã—ã¾ã™ +TP_LOCALLAB_GUIDFILTER_TOOLTIP;ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆãŒæ¸›ã£ãŸã‚Šã€å¢—ãˆãŸã‚Šã—ã¾ã™ TP_LOCALLAB_GUIDSTRBL_TOOLTIP;ガイド付ãフィルタã®å¼·ã• TP_LOCALLAB_HHMASK_TOOLTIP;例ãˆã°è‚Œã®å¾®å¦™ãªè‰²ç›¸èª¿æ•´ã«ä½¿ã„ã¾ã™ TP_LOCALLAB_HIGHMASKCOL;ãƒã‚¤ãƒ©ã‚¤ãƒˆ @@ -2945,8 +3174,8 @@ TP_LOCALLAB_JZLOGWB_TOOLTIP;自動を有効ã«ã™ã‚‹ã¨ã€ã‚¹ãƒãƒƒãƒˆå†…ã®Ev TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Ybã¯èƒŒæ™¯ã®å¹³å‡è¼åº¦ã‚’指ã—ã€ã‚°ãƒ¬ãƒ¼ã®å‰²åˆï¼ˆ%)ã§è¡¨ã—ã¾ã™ã€‚グレー18%ã¯èƒŒæ™¯ã®CIE Labã®è¼åº¦å€¤ãŒ50%ã§ã‚ã‚‹ã“ã¨ã¨åŒã˜ã§ã™ã€‚\nデータã¯ç”»åƒã®å¹³å‡è¼åº¦ã«åŸºã¥ã„ã¦ã„ã¾ã™\n対数符å·åŒ–ãŒä½¿ã‚れã¦ã„ã‚‹å ´åˆã¯ã€å¯¾æ•°ç¬¦å·åŒ–ãŒè¡Œã‚れるå‰ã«é©ç”¨ã™ã‚‹ã‚²ã‚¤ãƒ³ã®é‡ã‚’決ã‚ã‚‹ãŸã‚ã«å¹³å‡è¼åº¦ãŒä½¿ã‚れã¾ã™ã€‚å¹³å‡è¼åº¦ã®å€¤ãŒä½Žã„程ã€ã‚²ã‚¤ãƒ³ãŒå¢—ãˆã¾ã™ã€‚ TP_LOCALLAB_JZMODECAM_TOOLTIP;JzãŒä½¿ãˆã‚‹ã®ã¯æ©Ÿèƒ½æ°´æº–ãŒ'高度'ãªå ´åˆã ã‘ã§ã™ã€‚JzãŒæ©Ÿèƒ½ã™ã‚‹ã®ã¯å‡ºåŠ›ãƒ‡ãƒã‚¤ã‚¹ï¼ˆãƒ¢ãƒ‹ã‚¿ãƒ¼ï¼‰ãŒHDRã®å ´åˆã ã‘ã§ã™ï¼ˆæœ€å¤§å‡ºåŠ›è¼åº¦ãŒ100カンデラ毎平方メートル以上ã€ç†æƒ³çš„ã«ã¯4000ã‹ã‚‰10000カンデラ毎平方メートルã€ãƒ–ラックãƒã‚¤ãƒ³ãƒˆãŒ0.005カンデラ毎平方メートル以下ã®ãƒ¢ãƒ‹ã‚¿ãƒ¼ã§ã™ï¼‰ã€‚ã“ã“ã§æƒ³å®šã•れるã®ã¯ã€a)モニターã®ICCã®ãƒ—ロファイル接続色空間ã§Jzazbz (或ã„ã¯XYZ)ãŒä½¿ãˆã‚‹ã€b)実数精度ã§ä½œæ¥­å‡ºæ¥ã‚‹ã€c)モニターãŒã‚­ãƒ£ãƒªãƒ–レートã•れã¦ã„る(出æ¥ã‚Œã°ã€DCI-P3ã€æˆ–ã„ã¯Rec-2020ã®è‰²åŸŸã§ï¼‰ã€d) 通常ã®ã‚¬ãƒ³ãƒžï¼ˆsRGBã€æˆ–ã„ã¯BT709)ãŒçŸ¥è¦šé‡å­åŒ–ã®é–¢æ•°ã§ç½®ãæ›ãˆã‚‰ã‚Œã‚‹ã€ã“ã¨ã§ã™ã€‚ TP_LOCALLAB_JZPQFRA;Jz å†ãƒžãƒƒãƒ”ング -TP_LOCALLAB_JZPQFRA_TOOLTIP;Jzã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’ä»¥ä¸‹ã®æ§˜ã«SDR(標準ダイナミックレンジ)ã®ç’°å¢ƒã€æˆ–ã„ã¯HDR(ãƒã‚¤ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ï¼‰ã®ç’°å¢ƒã®ç‰¹æ€§ã«å¯¾ã—ã¦é©å¿œã•ã›ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ï¼š\n a) è¼åº¦å€¤ãŒ0ã‹ã‚‰100カンデラ毎平方メートルã®é–“ã§ã¯ã€ã‚·ã‚¹ãƒ†ãƒ ãŒSDRã§ã‚るよã†ã«ä½œç”¨ã™ã‚‹\n b) è¼åº¦å€¤ãŒ100ã‹ã‚‰10000カンデラ毎平方メートルã®é–“ã§ã¯ã€ç”»åƒã¨ãƒ¢ãƒ‹ã‚¿ãƒ¼ã®HDR特性ã«Jzã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’é©å¿œã•ã›ã‚‹ã€‚\n\n“PQ - 最大è¼åº¦Pâ€ã‚’10000カンデラ毎平方メートルã«è¨­å®šã™ã‚‹ã¨ã€â€œJzã®å†ãƒžãƒƒãƒ”ングâ€ãŒJzazbzã®ã‚ªãƒªã‚¸ãƒŠãƒ«ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã®ç‰¹æ€§ã‚’示ã—ã¾ã™ã€‚ -TP_LOCALLAB_JZPQREMAP;PQ - 最大è¼åº¦ +TP_LOCALLAB_JZPQFRA_TOOLTIP;Jzã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’ä»¥ä¸‹ã®æ§˜ã«SDR(標準ダイナミックレンジ)ã®ç’°å¢ƒã€æˆ–ã„ã¯HDR(ãƒã‚¤ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ï¼‰ã®ç’°å¢ƒã®ç‰¹æ€§ã«å¯¾ã—ã¦é©å¿œã•ã›ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ï¼š\n a) è¼åº¦å€¤ãŒ0ã‹ã‚‰100カンデラ毎平方メートルã®é–“ã§ã¯ã€ã‚·ã‚¹ãƒ†ãƒ ãŒSDRã§ã‚るよã†ã«ä½œç”¨ã™ã‚‹\n b) è¼åº¦å€¤ãŒ100ã‹ã‚‰10000カンデラ毎平方メートルã®é–“ã§ã¯ã€ç”»åƒã¨ãƒ¢ãƒ‹ã‚¿ãƒ¼ã®HDR特性ã«Jzã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’é©å¿œã•ã›ã‚‹ã€‚\n\n“PQ - 最大è¼åº¦Pâ€ã‚’10000カンデラ毎平方メートルã«è¨­å®šã™ã‚‹ã¨ã€â€œJzã®å†ãƒžãƒƒãƒ”ングâ€ãŒJzazbzã®ã‚ªãƒªã‚¸ãƒŠãƒ«ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã®ç‰¹æ€§ã‚’示ã—ã¾ã™ã€‚ +TP_LOCALLAB_JZPQREMAP;PQ - 最大è¼åº¦ TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (知覚é‡å­åŒ–) - PQã®å†…部関数を変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚デフォルトã§ã¯120カンデラ毎平方メートルãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€ä¸€èˆ¬çš„ãª10000カンデラ毎平方メートルã«å¤‰ãˆã‚‰ã‚Œã¾ã™ã€‚\nç•°ãªã‚‹ç”»åƒã€å‡¦ç†ã€ãƒ‡ãƒã‚¤ã‚¹ã«é©å¿œã•ã›ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚ TP_LOCALLAB_JZQTOJ;相対è¼åº¦ TP_LOCALLAB_JZQTOJ_TOOLTIP;"絶対è¼åº¦"ã®ä»£ã‚りã«"相対è¼åº¦"ãŒä½¿ãˆã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ - 明るã•ãŒæ˜Žåº¦ã§è¡¨ç¾ã•れるよã†ã«ãªã‚Šã¾ã™ã€‚\n変更ã«ã‚ˆã‚Šã€æ˜Žã‚‹ã•ã¨ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã€åŠã³Jz(Jz)カーブãŒå½±éŸ¿ã‚’å—ã‘ã¾ã™ã€‚ @@ -2958,25 +3187,27 @@ TP_LOCALLAB_JZTARGET_EV;観視ã®å¹³å‡è¼åº¦(Yb%) TP_LOCALLAB_JZTHRHCIE;Jz(Hz)ã®è‰²åº¦ã®ã—ãã„値 TP_LOCALLAB_JZWAVEXP;Jz ウェーブレット TP_LOCALLAB_LABBLURM;マスクã®ã¼ã‹ã— -TP_LOCALLAB_LABEL;ローカル編集 +TP_LOCALLAB_LABEL;é¸æŠžçš„ãªç·¨é›† TP_LOCALLAB_LABGRID;カラー補正グリッド TP_LOCALLAB_LABGRIDMERG;背景 TP_LOCALLAB_LABGRID_VALUES;高(a)=%1 高(b)=%2\n低(a)=%3 低(b)=%4 TP_LOCALLAB_LABSTRUM;構造マスク -TP_LOCALLAB_LAPLACC;ΔØ マスク ラプラス変æ›ã€€PDEã®å¢ƒç•Œæ¡ä»¶ã‚り -TP_LOCALLAB_LAPLACE;ラプラス変æ›ã®ã—ãã„値 ΔE -TP_LOCALLAB_LAPLACEXP;ラプラス変æ›ã®ã—ãã„値 -TP_LOCALLAB_LAPMASKCOL;ラプラス変æ›ã®ã—ãã„値 +TP_LOCALLAB_LAPLACC;ΔØ マスク ラプラシアン PDEã®å¢ƒç•Œæ¡ä»¶ã‚り +TP_LOCALLAB_LAPLACE;ラプラシアンã®ã—ãã„値 ΔE +TP_LOCALLAB_LAPLACEXP;ラプラシアンã®ã—ãã„値 +TP_LOCALLAB_LAPMASKCOL;ラプラシアンã®ã—ãã„値 TP_LOCALLAB_LAPRAD1_TOOLTIP;明るã„領域ã®è¼åº¦å€¤ã‚’上ã’ã‚‹ã“ã¨ã§ãƒžã‚¹ã‚¯ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’増やã—ã¾ã™ã€‚ TP_LOCALLAB_LAPRAD2_TOOLTIP;スムーズãªåŠå¾„ã¯ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトを軽減ã—ã€å¢ƒç•Œã‚’滑らã‹ã«ã™ã‚‹ãŸã‚ã«ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを使ã„ã¾ã™ã€‚ TP_LOCALLAB_LAPRAD_TOOLTIP;スムーズãªåŠå¾„ã¯ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを使ã£ã¦ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトを減らã—ã€å¢ƒç•Œã‚’スムーズã«ã—ã¾ã™ã€‚ -TP_LOCALLAB_LAP_MASK_TOOLTIP;å…¨ã¦ã®ãƒ©ãƒ—ラシアンマスクã®ãƒã‚¢ã‚½ãƒ³æ–¹ç¨‹å¼ã®è§£ã‚’求ã‚ã¾ã™\nラプラシアンã®ã—ãã„値マスクを有効ã«ã™ã‚‹ã¨ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトãŒè»½æ¸›ã•れã€ã‚¹ãƒ ãƒ¼ã‚ºãªåŠ¹æžœãŒå¾—られã¾ã™\n無効ã®å ´åˆã¯ç·šå½¢çš„ãªå¿œç­”ã¨ãªã‚Šã¾ã™ +TP_LOCALLAB_LAP_MASK_TOOLTIP;å…¨ã¦ã®ãƒ©ãƒ—ラシアンマスクã®ãƒã‚¢ã‚½ãƒ³æ–¹ç¨‹å¼ã®è§£ã‚’求ã‚ã¾ã™\nラプラシアンã®ã—ãã„値マスクを有効ã«ã™ã‚‹ã¨ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトãŒè»½æ¸›ã•れã€ã‚¹ãƒ ãƒ¼ã‚ºãªåŠ¹æžœãŒå¾—られã¾ã™\n無効ã®å ´åˆã¯ç·šå½¢çš„ãªå¿œç­”ã¨ãªã‚Šã¾ã™ +TP_LOCALLAB_LCLABELS;残差画åƒã®ãƒŽã‚¤ã‚ºãƒ¬ãƒ™ãƒ« +TP_LOCALLAB_LCLABELS_TOOLTIP;プレビューパãƒãƒ«ï¼ˆæ‹¡å¤§çއ100%)ã§è¡¨ç¤ºã•れã¦ã„る部分ã®ãƒŽã‚¤ã‚ºã®å¹³å‡å€¤ã¨æœ€ã‚‚高ã„値を表示ã—ã¾ã™ã€‚ノイズã®å€¤ã¯0ã‹ã‚‰3ã€4ã‹ã‚‰5ã®ã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ã§ã‚°ãƒ«ãƒ¼ãƒ—化ã•れã¦ã„ã¾ã™ã€‚\n表示ã•れる値ã¯ã‚ãã¾ã§ç›®å®‰ã§ã‚りã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã®è£œåŠ©çš„å½¹å‰²ã‚’æ‹…ã†ã‚‚ã®ã§ã™ã€‚絶対的ãªãƒŽã‚¤ã‚ºã®å€¤ã§ã¯ã‚りã¾ã›ã‚“。\n\n300:éžå¸¸ã«ãƒŽã‚¤ã‚ºãŒå¤šã„\n100ã‹ã‚‰300:ノイズãŒå¤šã„\n50ã‹ã‚‰100:ã‚る程度ã®ãƒŽã‚¤ã‚º\n50より低ã„:ノイズãŒå°‘ãªã„\n\nã“れらã®å€¤ã‹ã‚‰æ¬¡ã®ã“ã¨ãŒåˆ†ã‹ã‚Šã¾ã™ï¼š\n*ディテールタブã®ãƒŽã‚¤ã‚ºä½Žæ¸›æ©Ÿèƒ½ã®åŠ¹æžœ\n*éžå±€æ‰€å¹³å‡ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€DCT(コサイン変æ›ï¼‰æ©Ÿèƒ½ã«ã‚ˆã‚‹è¼åº¦ãƒŽã‚¤ã‚ºä½Žæ¸›ã®åŠ¹æžœ\n*キャプãƒãƒ£ãƒ¼ã‚·ãƒ£ãƒ¼ãƒ—ニングã¨ãƒ‡ãƒ¢ã‚¶ã‚¤ã‚¯å‡¦ç†ã®åŠ¹æžœ TP_LOCALLAB_LC_FFTW_TOOLTIP;高速フーリエ変æ›ã‚’使ã†ã¨è³ªãŒå‘上ã—ã€å¤§ããªåŠå¾„も使ãˆã¾ã™ãŒã€å‡¦ç†æ™‚é–“ãŒå¢—ãˆã¾ã™ï¼ˆå‡¦ç†ã™ã‚‹é ˜åŸŸæ¬¡ç¬¬ã§ï¼‰ã€‚大ãã„åŠå¾„ã‚’ä½¿ã†æ™‚ã ã‘ã«ä½¿ã†æ–¹ãŒã„ã„ã§ã—ょã†ã€‚FFTWã®æœ€é©åŒ–を図るãŸã‚ã€å‡¦ç†ã™ã‚‹é ˜åŸŸãŒæ•°ãƒ”クセルã»ã©å°ã•ããªã‚Šã¾ã™ã€‚ã“れã ã‘ã§ã€å‡¦ç†ã®åŠ¹çŽ‡ãŒãŒ1.5å€ï½ž10å€è‰¯ããªã‚Šã¾ã™ã€‚ TP_LOCALLAB_LC_TOOLNAME;ローカルコントラスト & ウェーブレット -TP_LOCALLAB_LEVELBLUR;ã¼ã‹ã—ã‚’æ–½ã™ãƒ¬ãƒ™ãƒ«ã®æœ€å¤§å€¤ +TP_LOCALLAB_LEVELBLUR;ã¼ã‹ã—効果ã®å¼·ã• TP_LOCALLAB_LEVELWAV;ウェーブレットã®ãƒ¬ãƒ™ãƒ« TP_LOCALLAB_LEVELWAV_TOOLTIP;詳細レベルã®ç•ªæ‰‹ã¯ã‚¹ãƒãƒƒãƒˆã¨ãƒ—レビューã®ã‚µã‚¤ã‚ºã«å¿œã˜ã¦è‡ªå‹•ã§æ±ºã¾ã‚Šã¾ã™\n最大512ピクセルã§è§£æžã™ã‚‹ãƒ¬ãƒ™ãƒ«9ã‹ã‚‰æœ€å¤§4ピクセルã§è§£æžã™ã‚‹ãƒ¬ãƒ™ãƒ«1ã¾ã§ -TP_LOCALLAB_LEVFRA;レベル +TP_LOCALLAB_LEVFRA;ウェーブレットã®ãƒ¬ãƒ™ãƒ« TP_LOCALLAB_LIGHTNESS;明度 TP_LOCALLAB_LIGHTN_TOOLTIP;インãƒãƒ¼ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«ã—ã¦ã€ã‚¹ã‚³ãƒ¼ãƒ—を高ã(75ä»¥ä¸Šï¼‰ã€æ˜Žåº¦ã‚’-100ã«ã—ã¦è‰²åº¦ã‚’下ã’ã‚‹ã¨ã€å¢ƒç•Œã®å¤–å´ã®è¼åº¦ãŒ0ã«ãªã‚Šã¾ã™ã€‚ TP_LOCALLAB_LIGHTRETI;明度 @@ -2993,7 +3224,7 @@ TP_LOCALLAB_LOC_CONTRASTPYR2LAB;レベルã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´/ト TP_LOCALLAB_LOC_CONTRASTPYRLAB;階調フィルタ/エッジシャープãƒã‚¹/ã¼ã‹ã— TP_LOCALLAB_LOC_RESIDPYR;残差画åƒã€€ãƒ¡ã‚¤ãƒ³ TP_LOCALLAB_LOG;対数符å·åŒ– -TP_LOCALLAB_LOG1FRA;CAM16ã«ã‚ˆã‚‹ç”»åƒã®èª¿æ•´ +TP_LOCALLAB_LOG1FRA;CAM16ã«ã‚ˆã‚‹ç”»åƒç·¨é›† TP_LOCALLAB_LOG2FRA;観視æ¡ä»¶ TP_LOCALLAB_LOGAUTO;自動 TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;場颿¡ä»¶ã®â€™å¹³å‡è¼åº¦â€™ã‚’自動ã§è¨ˆç®—ã—ã¾ã™ã€‚ @@ -3001,7 +3232,9 @@ TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;相対的ãªéœ²å…‰ãƒ¬ãƒ™ãƒ«ã®ä¸­ã®â€™è‡ªå‹•’ TP_LOCALLAB_LOGAUTO_TOOLTIP;'自動平å‡è¼åº¦ï¼ˆYb%)'ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйã«ãªã£ã¦ã„る時ã«ã€ã“ã®ãƒœã‚¿ãƒ³ã‚’押ã™ã¨æ’®å½±ç”»åƒã®ç’°å¢ƒã«é–¢ã™ã‚‹â€™ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸â€™ã¨â€™å¹³å‡è¼åº¦â€™ãŒè¨ˆç®—ã•れã¾ã™ã€‚\nã¾ãŸã€æ’®å½±æ™‚ã®çµ¶å¯¾è¼åº¦ã‚‚計算ã•れã¾ã™ã€‚\nå†åº¦ãƒœã‚¿ãƒ³ã‚’押ã™ã¨è‡ªå‹•çš„ã«ã“れら値ãŒèª¿æ•´ã•れã¾ã™ã€‚ TP_LOCALLAB_LOGBASE_TOOLTIP;デフォルト値ã¯2ã§ã™\n2以下ã§ã¯ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã®åƒããŒå¼±ã¾ã‚Šã€ã‚·ãƒ£ãƒ‰ã‚¦éƒ¨åˆ†ãŒæš—ãã€ãƒã‚¤ãƒ©ã‚¤ãƒˆéƒ¨åˆ†ãŒæ˜Žã‚‹ããªã‚Šã¾ã™\n2より大ãã„å ´åˆã¯ã€ã‚·ãƒ£ãƒ‰ã‚¦éƒ¨åˆ†ãŒæ¿ƒã„グレーã«å¤‰ã‚りã€ãƒã‚¤ãƒ©ã‚¤ãƒˆéƒ¨åˆ†ã¯ç™½ã£ã½ããªã‚Šã¾ã™ TP_LOCALLAB_LOGCATAD_TOOLTIP;色順応ã¨ã¯æ™‚空環境ã«å¿œã˜ã¦è‰²ã‚’èªè­˜ã™ã‚‹èƒ½åŠ›ã§ã™ã€‚\nå…‰æºãŒD50ã‹ã‚‰å¤§ãã外れã¦ã„ã‚‹å ´åˆã®ãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹èª¿æ•´ã«æœ‰ç”¨ã§ã™\nã“ã®æ©Ÿèƒ½ã§ã€å‡ºåŠ›ãƒ‡ãƒã‚¤ã‚¹ã®å…‰æºã®ä¸‹ã§åŒã˜è‰²ã«ãªã‚‹ã‚ˆã†ã«è¿‘ã¥ã‘ã¾ã™ã€‚ -TP_LOCALLAB_LOGCIE;シグモイドã®ä»£ã‚りã«å¯¾æ•°ç¬¦å·åŒ–を使ㆠ+TP_LOCALLAB_LOGCIE;対数符å·åŒ– +TP_LOCALLAB_LOGCIEQ;対数符å·åŒ– Q (CIECAMã‚’å«ã‚€) +TP_LOCALLAB_LOGCIEQ_TOOLTIP;ã“ã®ã‚ªãƒ—ションを有効(✓)ã«ã™ã‚‹ã¨ã€3ã¤ã®RGBãƒãƒ£ãƒ³ãƒãƒ«ã‚’ベースã«ã—ãŸå¯¾æ•°ç¬¦å·åŒ–ã‚’CIECAMã®æ˜Žã‚‹ã•(Q)ãƒãƒ£ãƒ³ãƒãƒ«ã ã‘をベースã«ã—ãŸå¯¾æ•°ç¬¦å·åŒ–ã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\nRGBãƒãƒ£ãƒ³ãƒãƒ«ã®ä»£ã‚りã«Qãƒãƒ£ãƒ³ãƒãƒ«ã‚’使ã†ã¨ã€è‰²ç›¸ã‚„彩度ã®ã‚ºãƒ¬ã«ã‚ˆã‚‹å¥½ã¾ã—ããªã„エッジ効果をé¿ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n但ã—ã€Qãƒãƒ£ãƒ³ãƒãƒ«ã®å€¤ã«ã¯åˆ¶é™ãŒã‚りã¾ã›ã‚“ãŒã€CIECAMã¯å‘¨å›²ç’°å¢ƒã‚„åŒæ™‚対比ãªã©ã«åˆã‚ã›ã¦ãƒ‡ãƒ¼ã‚¿ã‚’変化ã•ã›ã‚‹ãŸã‚ã€æœ€é©åŒ–を図る設定ã¯é›£ã—ããªã‚Šã¾ã™ã€‚\n次ã®ã‚ˆã†ãªæ©Ÿèƒ½èª¿æ•´ãŒå¿…è¦ã§ã—ょã†ï¼š\nâ€˜å ´é¢æ¡ä»¶â€™ã®å¹³å‡è¼åº¦ï¼ˆYb)ã€ãƒ›ãƒ¯ã‚¤ãƒˆã¨ãƒ–ラックã®åˆ†å¸ƒã€ãƒ–ラックEvã€ãƒ›ãƒ¯ã‚¤ãƒˆEv\n‘元データã®èª¿æ•´â€™ã®æ˜Žã‚‹ã•ã®åœ§ç¸®ã€å¼·ã•\n\n注æ„:対数符å·åŒ–(Q)を使ã†éš›ã«ã¯ã€å ´é¢æ¡ä»¶ã®å‘¨å›²ç’°å¢ƒã§CIECAMを無効ã«ã™ã‚‹ã‚ªãƒ—ションã¯é¸æŠžã—ãªã„よã†ã«ã—ã¾ã™ã€‚ TP_LOCALLAB_LOGCIE_TOOLTIP;対数符å·åŒ–Qを使ã†ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã§ã¯ã€ãƒ–ラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvã®èª¿ç¯€ã€å ´é¢æ¡ä»¶ã®å¹³å‡è¼åº¦ã¨è¦³è¦–æ¡ä»¶ã®å¹³å‡è¼åº¦ï¼ˆY%)ã®èª¿æ•´ãŒå‡ºæ¥ã¾ã™ã€‚ TP_LOCALLAB_LOGCOLORFL;鮮やã‹ã• (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;グレーã«å¯¾ã—ã¦çŸ¥è¦šã•れる色相ã®é‡ã®ã“ã¨ã§ã™ã€‚\n色刺激ãŒå¤šã‹ã‚Œå°‘ãªã‹ã‚Œè‰²ä»˜ã„ã¦è¦‹ãˆã‚‹ã“ã¨ã®æŒ‡æ¨™ã§ã™ã€‚ @@ -3018,11 +3251,12 @@ TP_LOCALLAB_LOGFRA;場颿¡ä»¶ TP_LOCALLAB_LOGFRAME_TOOLTIP;RT-スãƒãƒƒãƒˆã«é–¢ã™ã‚‹éœ²å‡ºã®ãƒ¬ãƒ™ãƒ«ã¨â€™å¹³å‡è¼åº¦ã€€Ybï¼…'(グレーãƒã‚¤ãƒ³ãƒˆã®æƒ…å ±æºï¼‰ã‚’計算ã—調整ã—ã¾ã™ã€‚çµæžœã¯å…¨ã¦ã®Lab関連処ç†ã¨æ®†ã©ã®RGB関連処ç†ã«ä½¿ã‚れã¾ã™ã€‚\nã¾ãŸã€å ´é¢ã®çµ¶å¯¾è¼åº¦ã‚‚考慮ã—ã¾ã™ã€‚ TP_LOCALLAB_LOGIMAGE_TOOLTIP;対応ã™ã‚‹è‰²ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«ã®å¤‰æ•°ï¼ˆä¾‹ãˆã°ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆJã¨å½©åº¦Sã€åŠã³æ©Ÿèƒ½æ°´æº–ãŒé«˜åº¦ãªå ´åˆã®ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆQã€æ˜Žã‚‹ã•Qã€æ˜Žåº¦Jã€é®®ã‚„ã‹ã•M)を考慮ã—ã¾ã™ã€‚ TP_LOCALLAB_LOGLIGHTL;明度 (J) -TP_LOCALLAB_LOGLIGHTL_TOOLTIP;L*a*b*ã®æ˜Žåº¦ã«è¿‘ã„ã‚‚ã®ã§ã™ãŒã€çŸ¥è¦šã•れる彩色ã®å¢—加を考慮ã¦ã„ã¾ã™ã€‚ +TP_LOCALLAB_LOGLIGHTL_TOOLTIP;L*a*b*ã®æ˜Žåº¦ã«è¿‘ã„ã‚‚ã®ã§ã™ãŒã€çŸ¥è¦šã•れる彩色ã®å¢—加を考慮ã¦ã„ã¾ã™ã€‚ TP_LOCALLAB_LOGLIGHTQ;明る㕠(Q) -TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;ãã®è‰²åˆºæ¿€ã‹ã‚‰ç™ºã›ã‚‰ã‚Œã‚‹çŸ¥è¦šã•れãŸå…‰ã®é‡ã‚’æ„味ã—ã¾ã™ã€‚\nãã®è‰²åˆºæ¿€ã®æ˜Žã‚‹ã•ã®å¤šå¯¡ã®æŒ‡æ¨™ã§ã™ã€‚ +TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;ãã®è‰²åˆºæ¿€ã‹ã‚‰ç™ºã›ã‚‰ã‚Œã‚‹çŸ¥è¦šã•れãŸå…‰ã®é‡ã‚’æ„味ã—ã¾ã™ã€‚\nãã®è‰²åˆºæ¿€ã®æ˜Žã‚‹ã•ã®å¤šå¯¡ã®æŒ‡æ¨™ã§ã™ã€‚ TP_LOCALLAB_LOGLIN;対数モード TP_LOCALLAB_LOGPFRA;相対的ãªéœ²å…‰ãƒ¬ãƒ™ãƒ« +TP_LOCALLAB_LOGPFRA2;対数符å·åŒ–ã®è¨­å®š TP_LOCALLAB_LOGREPART;全体ã®å¼·ã• TP_LOCALLAB_LOGREPART_TOOLTIP;元画åƒã¨æ¯”ã¹ãŸå¯¾æ•°ç¬¦å·åŒ–ã—ãŸç”»åƒã®å¼·ã•を調整ã—ã¾ã™ã€‚\n色ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«ã®æ§‹æˆè¦ç´ ã«ã¯å½±éŸ¿ã—ã¾ã›ã‚“。 TP_LOCALLAB_LOGSATURL_TOOLTIP;色ã®è¦‹ãˆãƒ¢ãƒ‡ãƒ«16ã®å½©åº¦Sã¯ã€ç‰©ä½“è‡ªèº«ãŒæŒã¤æ˜Žã‚‹ã•ã«é–¢ã—ãŸè‰²åˆºæ¿€ã®è‰²ã«è©²å½“ã—ã¾ã™\n主ã«ã€ä¸­é–“トーンã‹ã‚‰ãƒã‚¤ãƒ©ã‚¤ãƒˆã«ã‹ã‘ã¦ä½œç”¨ã—ã¾ã™ã€‚ @@ -3031,14 +3265,16 @@ TP_LOCALLAB_LOGSURSOUR_TOOLTIP;場颿¡ä»¶ã‚’考慮ã—ã¦æ˜Žæš—ã¨è‰²ã‚’調整 TP_LOCALLAB_LOGVIEWING_TOOLTIP;最終画åƒã‚’è¦‹ã‚‹å‘¨å›²ç’°å¢ƒåŒæ§˜ã€ãれを見る媒体(モニターã€TVã€ãƒ—ロジェクターã€ãƒ—リンターãªã©ï¼‰ã«å¯¾å¿œã—ã¾ã™ã€‚ TP_LOCALLAB_LOG_TOOLNAME;対数符å·åŒ– TP_LOCALLAB_LUM;LL - CC +TP_LOCALLAB_LUM46LABEL;4ã‹ã‚‰6ã®ãƒ¬ãƒ™ãƒ«ã®è¼åº¦: å¹³å‡=%1 高=%2 TP_LOCALLAB_LUMADARKEST;最も暗ã„部分 TP_LOCALLAB_LUMASK;マスクã®èƒŒæ™¯è‰²ã¨è¼åº¦ -TP_LOCALLAB_LUMASK_TOOLTIP;マスクã®è¡¨ç¤ºï¼ˆãƒžã‚¹ã‚¯ã¨ä¿®æ­£é ˜åŸŸï¼‰ã§ã€èƒŒæ™¯ã®ã‚°ãƒ¬ãƒ¼ã‚’調節ã—ã¾ã™ +TP_LOCALLAB_LUMASK_TOOLTIP;マスクã®è¡¨ç¤ºï¼ˆãƒžã‚¹ã‚¯ã¨ä¿®æ­£ï¼‰ã§ã€èƒŒæ™¯ã®ã‚°ãƒ¬ãƒ¼ã‚’調節ã—ã¾ã™ TP_LOCALLAB_LUMAWHITESEST;最も明るã„部分 TP_LOCALLAB_LUMFRA;L*a*b* 標準 +TP_LOCALLAB_LUMLABEL;0ã‹ã‚‰3ã®ãƒ¬ãƒ™ãƒ«ã®è¼åº¦: å¹³å‡=%1 高=%2 TP_LOCALLAB_MASFRAME;マスクã¨èžåˆã«é–¢ã™ã‚‹è¨­å®š TP_LOCALLAB_MASFRAME_TOOLTIP;ã“れã¯å…¨ã¦ã®ãƒžã‚¹ã‚¯ã«å…±é€šã—ã¾ã™\n以下ã®ãƒžã‚¹ã‚¯æ©Ÿèƒ½ãŒä½¿ã‚ã‚ŒãŸæ™‚ã«ç›®æ¨™ã¨ã™ã‚‹é ˜åŸŸãŒå¤‰åŒ–ã™ã‚‹ã®ã‚’é¿ã‘ã‚‹ãŸã‚ã«Î”Eç”»åƒã‚’考慮ã—ã¾ã™ï¼šã‚¬ãƒ³ãƒžã€ã‚¹ãƒ­ãƒ¼ãƒ—ã€è‰²åº¦ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚«ãƒ¼ãƒ–(ウェーブレットã®ãƒ¬ãƒ™ãƒ«ï¼‰ã€ã¼ã‹ã—ãƒžã‚¹ã‚¯ã€æ§‹é€ ã®ãƒžã‚¹ã‚¯ï¼ˆæœ‰åйã«ãªã£ã¦ã„ã‚‹å ´åˆï¼‰\nã“ã®æ©Ÿèƒ½ã¯ã‚¤ãƒ³ãƒãƒ¼ã‚¹ãƒ¢ãƒ¼ãƒ‰ã§ã¯ç„¡åйã«ãªã‚Šã¾ã™ -TP_LOCALLAB_MASK;カーブ +TP_LOCALLAB_MASK;コントラスト TP_LOCALLAB_MASK2;コントラストカーブ TP_LOCALLAB_MASKCOM;共通ã®ã‚«ãƒ©ãƒ¼ãƒžã‚¹ã‚¯ TP_LOCALLAB_MASKCOM_TOOLNAME;共通ã®ã‚«ãƒ©ãƒ¼ãƒžã‚¹ã‚¯ @@ -3047,51 +3283,51 @@ TP_LOCALLAB_MASKCURVE_TOOLTIP;デフォルトã§ã¯3ã¤ã®ã‚«ãƒ¼ãƒ–ã¯1(最大 TP_LOCALLAB_MASKDDECAY;減衰ã®å¼·ã• TP_LOCALLAB_MASKDECAY_TOOLTIP;マスクã®ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã®æ¸›è¡°ã®åº¦åˆã„をコントロールã—ã¾ã™\n 1ã¯ç·šå½¢ã§æ¸›è¡°ã€ 1より大ãã„å ´åˆã¯ãƒ‘ラボリックã€1よりå°ã•ã„å ´åˆã¯ã‚ˆã‚Šç·©ã‚„ã‹ãªæ¸›è¡°ã«ãªã‚Šã¾ã™ TP_LOCALLAB_MASKDEINV_TOOLTIP;マスクを解æžã™ã‚‹ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒå対ã®ä½œç”¨ã«ãªã‚Šã¾ã™\nã€€âœ”ã‚’å…¥ã‚Œã‚‹ã¨æš—ã„部分ã¨éžå¸¸ã«æ˜Žã‚‹ã„éƒ¨åˆ†ãŒæ¸›ã‚Šã¾ã™ -TP_LOCALLAB_MASKDE_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’ç›®çš„ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n マスクãŒ'æš—ã„'ã—ãã„値より暗ã„å ´åˆã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n マスクãŒ'明るã„'ã—ãã„値より明るã„å ´åˆã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n ãƒžã‚¹ã‚¯ã®æ˜Žã‚‹ã•ãŒ2ã¤ã®ã—ãã„値ã®é–“ã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ã€ã‚°ãƒ¬ãƒ¼é ˜åŸŸã®'è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ»'ã€æˆ–ã„ã¯'色ノイズ除去'を使ã£ã¦ãªã„é™ã‚Šã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’é™¤ãç”»åƒã®è¨­å®šãŒç¶­æŒã•れã¾ã™ -TP_LOCALLAB_MASKGF_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを目的ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n マスクãŒ'æš—ã„'ã—ãã„値より暗ã„å ´åˆã¯ã€éšŽèª¿èª¿æ•´ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n マスクãŒ'明るã„'ã—ãã„値より明るã„å ´åˆã¯ã€ã‚¬ã‚¤ãƒ‰ä»˜ããƒ•ã‚£ãƒ«ã‚¿ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n ãƒžã‚¹ã‚¯ã®æ˜Žã‚‹ã•ãŒ2ã¤ã®ã—ãã„値ã®é–“ã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを除ã„ãŸç”»åƒã®è¨­å®šãŒç¶­æŒã•れã¾ã™ +TP_LOCALLAB_MASKDE_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’ç›®çš„ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n マスクãŒ'æš—ã„'ã—ãã„値より暗ã„å ´åˆã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n マスクãŒ'明るã„'ã—ãã„値より明るã„å ´åˆã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n ãƒžã‚¹ã‚¯ã®æ˜Žã‚‹ã•ãŒ2ã¤ã®ã—ãã„値ã®é–“ã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ã€ã‚°ãƒ¬ãƒ¼é ˜åŸŸã®'è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ»'ã€æˆ–ã„ã¯'色ノイズ除去'を使ã£ã¦ãªã„é™ã‚Šã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’é™¤ãç”»åƒã®è¨­å®šãŒç¶­æŒã•れã¾ã™ +TP_LOCALLAB_MASKGF_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを目的ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n マスクãŒ'æš—ã„'ã—ãã„値より暗ã„å ´åˆã¯ã€éšŽèª¿èª¿æ•´ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n マスクãŒ'明るã„'ã—ãã„値より明るã„å ´åˆã¯ã€ã‚¬ã‚¤ãƒ‰ä»˜ããƒ•ã‚£ãƒ«ã‚¿ãŒæ¼¸é€²çš„ã«ä½œç”¨ã—ã¾ã™\n ãƒžã‚¹ã‚¯ã®æ˜Žã‚‹ã•ãŒ2ã¤ã®ã—ãã„値ã®é–“ã«ãªã£ã¦ã„ã‚‹å ´åˆã¯ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタを除ã„ãŸç”»åƒã®è¨­å®šãŒç¶­æŒã•れã¾ã™ TP_LOCALLAB_MASKH;色相ã®ã‚«ãƒ¼ãƒ– -TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€â€CBDL(è¼åº¦ã®ã¿ï¼‰â€ã®ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«æ¸›å°‘ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€â€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ï¼ˆè¼åº¦ã®ã¿ï¼‰â€ã®ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒâ€œãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングâ€ã®èª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKHIGTHRES_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«æ¸›å°‘ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€â€CBDL(è¼åº¦ã®ã¿ï¼‰â€ã®ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«æ¸›å°‘ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€â€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ï¼ˆè¼åº¦ã®ã¿ï¼‰â€ã®ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒâ€œãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングâ€ã®èª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKHIGTHRES_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«æ¸›å°‘ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯'ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§'ロックå¼ã‚«ãƒ©ãƒ¼ãƒ”ッカー'を使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€'設定'ã®'マスクã¨èžåˆ'ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ TP_LOCALLAB_MASKLCTHR;明るã„領域ã®è¼åº¦ã®ã—ãã„値 TP_LOCALLAB_MASKLCTHR2;明るã„領域ã®è¼åº¦ã®ã—ãã„値 TP_LOCALLAB_MASKLCTHRLOW;æš—ã„領域ã®è¼åº¦ã®ã—ãã„値 TP_LOCALLAB_MASKLCTHRLOW2;æš—ã„領域ã®è¼åº¦ã®ã—ãã„値 TP_LOCALLAB_MASKLCTHRMID;グレー領域ã®è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ» TP_LOCALLAB_MASKLCTHRMIDCH;グレー領域ã®è‰²ãƒŽã‚¤ã‚ºé™¤åŽ» -TP_LOCALLAB_MASKLC_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’ç›®çš„ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\nã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n'æš—ã„éƒ¨åˆ†ã¨æ˜Žã‚‹ã„部分ã®ãƒŽã‚¤ã‚ºé™¤åŽ»å¼·åŒ–'ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã®å€¤ãŒ1より大ãã„å ´åˆã€'æš—ã„領域ã®è¼åº¦ã®ã—ãã„値'ã§è¨­å®šã•れãŸã—ãã„値を0ï¼…ã€æœ€ã‚‚æš—ã„値(マスクã«ã‚ˆã£ã¦å®šç¾©ã•れる)を100ï¼…ã¨ã—ã¦ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n明るã„部分ã§ã¯ã€'明るã„領域ã®è¼åº¦ã®ã—ãã„値'ã§è¨­å®šã•れãŸã—ãã„値を0ï¼…ã€æœ€ã‚‚明るã„値(マスクã«ã‚ˆã£ã¦å®šç¾©ã•れる)を100ï¼…ã¨ã—ã¦ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«æ¸›è¡°ã—ã¾ã™ã€‚\n2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã®è¨­å®šã¯ãƒžã‚¹ã‚¯ã«ã‚ˆã‚‹å½±éŸ¿ã‚’å—ã‘ã¾ã›ã‚“。 -TP_LOCALLAB_MASKLNOISELOW;æš—ã„éƒ¨åˆ†ã¨æ˜Žã‚‹ã„部分ã®ãƒŽã‚¤ã‚ºé™¤åŽ»å¼·åŒ– -TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒ'CBDL(è¼åº¦ã®ã¿ï¼‰'ã®ãƒ‘ラメータ調整を行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒ'レティãƒãƒƒã‚¯ã‚¹'(è¼åº¦ã®ã¿ï¼‰ã®ãƒ‘ラメータ調整を行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ -TP_LOCALLAB_MASKRECOL_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€è‰²ã¨æ˜Žã‚‹ã•â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'è‰²ã¨æ˜Žã‚‹ã•'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'è‰²ã¨æ˜Žã‚‹ã•'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKLC_TOOLTIP;è¼åº¦ãƒŽã‚¤ã‚ºã‚’ウェーブレットを使ã£ã¦é™¤åŽ»ã—ã¾ã™ã€‚\n'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’ç›®çš„ã¨ã—ã¦ä½¿ã„ã¾ã™ã€‚\nã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n'æš—ã„/明るã„領域ã§ã®è£œåŠ©'ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã®å€¤ãŒ1より大ãã„å ´åˆã€'æš—ã„領域ã®è¼åº¦ã®ã—ãã„値'ã§è¨­å®šã•れãŸã—ãã„値を0ï¼…ã€æœ€ã‚‚æš—ã„値(マスクã«ã‚ˆã£ã¦å®šç¾©ã•れる)を100ï¼…ã¨ã—ã¦ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n明るã„部分ã§ã¯ã€'明るã„領域ã®è¼åº¦ã®ã—ãã„値'ã§è¨­å®šã•れãŸã—ãã„値を0ï¼…ã€æœ€ã‚‚明るã„値(マスクã«ã‚ˆã£ã¦å®šç¾©ã•れる)を100ï¼…ã¨ã—ã¦ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒæ¼¸é€²çš„ã«æ¸›è¡°ã—ã¾ã™ã€‚\n2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã®è¨­å®šã¯ãƒžã‚¹ã‚¯ã«ã‚ˆã‚‹å½±éŸ¿ã‚’å—ã‘ã¾ã›ã‚“。 +TP_LOCALLAB_MASKLNOISELOW;æš—ã„/明るã„領域ã§ã®è£œåŠ© +TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒ'CBDL(è¼åº¦ã®ã¿ï¼‰'ã®ãƒ‘ラメータ調整を行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;ã“ã®ã—ãã„値より明るã„部分ã§ã¯ã€ç”»åƒãŒ'レティãƒãƒƒã‚¯ã‚¹'(è¼åº¦ã®ã¿ï¼‰ã®ãƒ‘ラメータ調整を行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;ã“ã®ã—ãã„値より暗ã„部分ã§ã¯ã€ç”»åƒã®èª¿æ•´ãƒ‘ラメータãŒèª¿æ•´ã‚’行ã†å‰ã®å…ƒã®çŠ¶æ…‹ã«æ–¬æ–°çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;ã—ãã„値をホワイト値最大(マスクã§å®šç¾©ã•れãŸï¼‰ã§0ï¼…ã«è¨­å®šã™ã‚‹ã¨ã€ã‚¬ã‚¤ãƒ‰ä»˜ãフィルタã¯100ï¼…ã‹ã‚‰æ¼¸é€²çš„ã«å¢—加ã—ã¾ã™ã€‚\n 'マスクã¨ä¿®æ­£'ã®ä¸­ã®æ©Ÿèƒ½ï¼ˆ'構造ã®ãƒžã‚¹ã‚¯'ã€'ã¼ã‹ã—ã®ãƒžã‚¹ã‚¯ã€'スムーズãªåŠå¾„'ã€'ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—'ã€'コントラストカーブ'ã€'ウェーブレットを使ã£ãŸãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ')を使ã£ã¦ã‚°ãƒ¬ãƒ¼ãƒ¬ãƒ™ãƒ«ã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n マスク上ã§â€œãƒ­ãƒƒã‚¯å¼ã‚«ãƒ©ãƒ¼ãƒ”ッカーâ€ã‚’使ã„ã€ã©ã®éƒ¨åˆ†ãŒå½±éŸ¿ã‚’å—ã‘ã¦ã„ã‚‹ã‹è¦‹æ¥µã‚ã¾ã™ã€‚但ã—ã€â€œè¨­å®šâ€ã®â€œãƒžã‚¹ã‚¯ã¨èžåˆâ€ã®ä¸­ã«ã‚る’背景ã®è‰²/è¼åº¦ã®ãƒžã‚¹ã‚¯â€™ã®å€¤ã‚’0ã«ã—ã¦ãŠãå¿…è¦ãŒã‚りã¾ã™ã€‚ +TP_LOCALLAB_MASKRECOL_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€è‰²ã¨æ˜Žã‚‹ã•â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'è‰²ã¨æ˜Žã‚‹ã•'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'è‰²ã¨æ˜Žã‚‹ã•'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ TP_LOCALLAB_MASKRECOTHRES;復元ã®ã—ãã„値 -TP_LOCALLAB_MASKREEXP_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹ã€è¼åº¦æƒ…報をベースã«ã€â€œãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ã¨éœ²å…‰è£œæ­£â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯ã€L(L)マスクやLC(H)マスクを有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'ダイナミックレンジã¨éœ²å…‰è£œæ­£'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'ダイナミックレンジã¨éœ²å…‰è£œæ­£'ã®è¨­å®šãŒ100ï¼…åƒãã¾ã™ã€‚ -TP_LOCALLAB_MASKRELOG_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹ã€ç”»åƒã®è¼åº¦æƒ…報をベースã«ã—ãŸâ€œå¯¾æ•°ç¬¦å·åŒ–â€ã®åŠ¹æžœã‚’å’Œã‚‰ã’ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯ã€L(L)マスクやLC(H)マスクを有効ã«ã—ã¦ãŠã‹ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。\n 暗ã„領域ã®ã—ãã„値より暗ã„部分ã€ã¨æ˜Žã‚‹ã„領域ã®ã—ãã„値より明るã„部分ã§ã¯ã€'対数符å·åŒ–'ã«ã‚ˆã‚‹èª¿æ•´ãŒåƒãå‰ã®å…ƒç”»åƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚è‰²ã®æ³¢åŠã‚’使ã£ãŸãƒã‚¤ãƒ©ã‚¤ãƒˆå¾©å…ƒã®åŠ¹æžœã‚’ç¶­æŒã™ã‚‹ãŸã‚ã«ä½¿ãˆã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'対数符å·åŒ–'ã®è¨­å®šãŒ100ï¼…åƒãã¾ã™ã€‚ -TP_LOCALLAB_MASKRESCB_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€CBDLâ€ï¼ˆè¼åº¦ã®ã¿ï¼‰ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'CBDL'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'CBDL'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKRESH_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ã‚·ãƒ£ãƒ‰ã‚¦/ãƒã‚¤ãƒ©ã‚¤ãƒˆâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKRESRETI_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹â€ï¼ˆè¼åº¦ã®ã¿ï¼‰ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'レティãƒãƒƒã‚¯ã‚¹'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'レティãƒãƒƒã‚¯ã‚¹'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKRESTM_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'トーンマッピング'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'トーンマッピング'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKRESVIB_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€è‡ªç„¶ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'自然ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'自然ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKRESWAV_TOOLTIP;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã€€ã‚¦ã‚§ãƒ¼ãƒ–レットâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'ローカルコントラスト ウェーブレット'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'ローカルコントラスト ウェーブレット'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ -TP_LOCALLAB_MASKUNUSABLE;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ãƒžã‚¹ã‚¯ãŒç„¡åй -TP_LOCALLAB_MASKUSABLE;'マスクã¨ä¿®æ­£é ˜åŸŸ'ã®ãƒžã‚¹ã‚¯ãŒæœ‰åй +TP_LOCALLAB_MASKREEXP_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹ã€è¼åº¦æƒ…報をベースã«ã€â€œãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ã¨éœ²å…‰è£œæ­£â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯ã€L(L)マスクやLC(H)マスクを有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'ダイナミックレンジã¨éœ²å…‰è£œæ­£'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'ダイナミックレンジã¨éœ²å…‰è£œæ­£'ã®è¨­å®šãŒ100ï¼…åƒãã¾ã™ã€‚ +TP_LOCALLAB_MASKRELOG_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹ã€ç”»åƒã®è¼åº¦æƒ…報をベースã«ã—ãŸâ€œå¯¾æ•°ç¬¦å·åŒ–â€ã®åŠ¹æžœã‚’å’Œã‚‰ã’ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯ã€L(L)マスクやLC(H)マスクを有効ã«ã—ã¦ãŠã‹ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。\n 暗ã„領域ã®ã—ãã„値より暗ã„部分ã€ã¨æ˜Žã‚‹ã„領域ã®ã—ãã„値より明るã„部分ã§ã¯ã€'対数符å·åŒ–'ã«ã‚ˆã‚‹èª¿æ•´ãŒåƒãå‰ã®å…ƒç”»åƒã®çŠ¶æ…‹ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚è‰²ã®æ³¢åŠã‚’使ã£ãŸãƒã‚¤ãƒ©ã‚¤ãƒˆå¾©å…ƒã®åŠ¹æžœã‚’ç¶­æŒã™ã‚‹ãŸã‚ã«ä½¿ãˆã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'対数符å·åŒ–'ã®è¨­å®šãŒ100ï¼…åƒãã¾ã™ã€‚ +TP_LOCALLAB_MASKRESCB_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€CBDLâ€ï¼ˆè¼åº¦ã®ã¿ï¼‰ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'CBDL'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'CBDL'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKRESH_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ã‚·ãƒ£ãƒ‰ã‚¦/ãƒã‚¤ãƒ©ã‚¤ãƒˆâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKRESRETI_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹â€ï¼ˆè¼åº¦ã®ã¿ï¼‰ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'レティãƒãƒƒã‚¯ã‚¹'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'レティãƒãƒƒã‚¯ã‚¹'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKRESTM_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'トーンマッピング'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'トーンマッピング'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKRESVIB_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€è‡ªç„¶ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«â€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'自然ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'自然ãªå½©åº¦ã€€ã‚¦ã‚©ãƒ¼ãƒ ã¨ã‚¯ãƒ¼ãƒ«'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKRESWAV_TOOLTIP;'マスクã¨ä¿®æ­£'ã®L(L)ã‚„LC(H)マスクã«å†…包ã•れã¦ã„ã‚‹è¼åº¦ã®æƒ…報をベースã«ã€â€ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã€€ã‚¦ã‚§ãƒ¼ãƒ–レットâ€ã®è¨­å®šã«ã‚ˆã‚‹åŠ¹æžœã‚’å’Œã‚‰ã’ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚\n ã“ã®æ©Ÿèƒ½ã‚’使ã†ãŸã‚ã«ã¯L(L)ã‚„LC(H)ã®ãƒžã‚¹ã‚¯ã‚’有効ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n 暗ã„ã—ãã„å€¤ä»¥ä¸‹ã¨æ˜Žã‚‹ã„ã—ãã„値以上ã®'æš—ã„'領域ã¨'明るã„'領域ã¯ã€'ローカルコントラスト ウェーブレット'ã®è¨­å®šã«ã‚ˆã£ã¦å¤‰æ›´ã•れるå‰ã®å€¤ï¼ˆå…ƒã®å€¤ï¼‰ã«æ¼¸é€²çš„ã«å¾©å…ƒã•れã¾ã™ã€‚\n 2ã¤ã®ã—ãã„値ã®é–“ã®éƒ¨åˆ†ã§ã¯ã€'ローカルコントラスト ウェーブレット'ã®è¨­å®šå€¤ãŒ100ï¼…é©ç”¨ã•れã¾ã™ã€‚ +TP_LOCALLAB_MASKUNUSABLE;'マスクã¨ä¿®æ­£'ã®ãƒžã‚¹ã‚¯ãŒç„¡åй +TP_LOCALLAB_MASKUSABLE;'マスクã¨ä¿®æ­£'ã®ãƒžã‚¹ã‚¯ãŒæœ‰åй TP_LOCALLAB_MASK_TOOLTIP;一ã¤ã®æ©Ÿèƒ½ã®ä¸­ã§è¤‡æ•°ã®ãƒžã‚¹ã‚¯ã‚’活用ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ä»–ã®æ©Ÿèƒ½ã‚’有効ã«ã—ã¦ãã®ãƒžã‚¹ã‚¯ã ã‘を使ã„ã¾ã™ï¼ˆæ©Ÿèƒ½ã®ä¸­ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼å€¤ã¯å…¨ã¦0ã«ã™ã‚‹ï¼‰ã€‚\n\nã¾ãŸã¯ã€RT-スãƒãƒƒãƒˆã‚’複製ã—ã€åˆã‚ã®ã‚¹ãƒãƒƒãƒˆã®è¿‘ãã«ç½®ãã€ãã®RT-スãƒãƒƒãƒˆã®ãƒžã‚¹ã‚¯ã‚’使ã„ã¾ã™ã€‚ã“ã®å ´åˆã€èª¿æ•´ã®ãŸã‚ã®åŸºæº–値ã®é•ã„ãŒå°ã•ã„ãŸã‚ã€ã‚ˆã‚Šç²¾ç·»ãªèª¿æ•´ãŒå¯èƒ½ã§ã™ã€‚ TP_LOCALLAB_MEDIAN;メディアン 低 TP_LOCALLAB_MEDIANITER_TOOLTIP;メディアンフィルタé©ç”¨ã®ç¹°ã‚Šè¿”ã—回数を設定ã—ã¾ã™ @@ -3103,7 +3339,7 @@ TP_LOCALLAB_MERELE;明るãã™ã‚‹ã ã‘ TP_LOCALLAB_MERFIV;追加 TP_LOCALLAB_MERFOR;色ã®è¦†ã„焼ã TP_LOCALLAB_MERFOU;ä¹—ç®— -TP_LOCALLAB_MERGE1COLFRA;èžåˆã™ã‚‹ãƒ•ァイルã®é¸æŠžï¼šã‚ªãƒªã‚¸ãƒŠãƒ«/å‰ã®RT-スãƒãƒƒãƒˆ/背景 +TP_LOCALLAB_MERGE1COLFRA;èžåˆã™ã‚‹ãƒ•ァイルã®é¸æŠžï¼šå…ƒç”»åƒ/一ã¤å‰ã®ç”»åƒ/背景 TP_LOCALLAB_MERGECOLFRA;マスク:LChã¨æ§‹é€  TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;LChã®3ã¤ã®ã‚«ãƒ¼ãƒ–ã€æˆ–ã„ã¯æ§‹é€ æ¤œå‡ºã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã€ã¾ãŸã¯ãã®ä¸¡æ–¹ã‚’ベースã«ãƒžã‚¹ã‚¯ã‚’作りã¾ã™ TP_LOCALLAB_MERGEMER_TOOLTIP;ファイルを癒åˆã™ã‚‹éš›ã«Î”Eを考慮ã—ã¾ã™ï¼ˆã“ã®å ´åˆã¯ã‚¹ã‚³ãƒ¼ãƒ—ã¨åŒã˜åƒãã§ã™ï¼‰ @@ -3125,38 +3361,39 @@ TP_LOCALLAB_MERTHI;色ã®ç„¼ã込㿠TP_LOCALLAB_MERTHR;差異 TP_LOCALLAB_MERTWE;除外 TP_LOCALLAB_MERTWO;減算 -TP_LOCALLAB_METHOD_TOOLTIP;'強化 + 色ノイズ低減'ã‚’é¸ã¶ã¨å‡¦ç†æ™‚é–“ãŒè‘—ã—ã増加ã—ã¾ã™\nã—ã‹ã—ã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトã¯è»½æ¸›ã•れã¾ã™ +TP_LOCALLAB_METHOD_TOOLTIP;'強化 + 色ノイズ低減'ã‚’é¸ã¶ã¨å‡¦ç†æ™‚é–“ãŒè‘—ã—ã増加ã—ã¾ã™\nã—ã‹ã—ã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトã¯è»½æ¸›ã•れã¾ã™ +TP_LOCALLAB_MIDTCIE;中間トーン TP_LOCALLAB_MLABEL;復元ã•れãŸãƒ‡ãƒ¼ã‚¿ 最å°å€¤=%1 最大値=%2 TP_LOCALLAB_MLABEL_TOOLTIP;最低値を0ã€æœ€å¤§å€¤ã‚’32768(対数モード)ã«è¿‘ã¥ã‘ã‚‹å¿…è¦ãŒã‚りã¾ã™ãŒã€å¿…ãšã—も一致ã•ã›ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“。標準化ã®ãŸã‚ã«ã€'ゲイン'ã¨'オフセット'を調整ã—ã¾ã™\nブレンドã›ãšã«ç”»åƒã‚’回復ã—ã¾ã™ TP_LOCALLAB_MODE_EXPERT;高度 TP_LOCALLAB_MODE_NORMAL;標準 TP_LOCALLAB_MODE_SIMPLE;基本 TP_LOCALLAB_MRFIV;背景 -TP_LOCALLAB_MRFOU;å‰ã®RT-スãƒãƒƒãƒˆ +TP_LOCALLAB_MRFOU;一ã¤å‰ã®ã‚¹ãƒãƒƒãƒˆ TP_LOCALLAB_MRONE;ãªã— -TP_LOCALLAB_MRTHR;オリジナルRT-スãƒãƒƒãƒˆ -TP_LOCALLAB_MULTIPL_TOOLTIP;トーンã®å¹…ãŒåºƒã„ç”»åƒã€-18EV~+4EVã€ã‚’調整ã—ã¾ã™: 最åˆã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯-18EV~-6EVã®éžå¸¸ã«æš—ã„部分ã«ä½œç”¨ã—ã¾ã™ã€‚2ã¤ç›®ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯-6EV~+4EVã®éƒ¨åˆ†ã«ä½œç”¨ã—ã¾ã™ +TP_LOCALLAB_MRTHR;å…ƒç”»åƒ +TP_LOCALLAB_MULTIPL_TOOLTIP;トーンã®å¹…ãŒåºƒã„ç”»åƒã€-18EV~+4EVã€ã‚’調整ã—ã¾ã™: 最åˆã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯-18EV~-6EVã®éžå¸¸ã«æš—ã„部分ã«ä½œç”¨ã—ã¾ã™ã€‚2ã¤ç›®ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯-6EV~+4EVã®éƒ¨åˆ†ã«ä½œç”¨ã—ã¾ã™ TP_LOCALLAB_NEIGH;åŠå¾„ TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;値を低ãã™ã‚‹ã¨è©³ç´°ã¨è³ªæ„ŸãŒä¿ãŸã‚Œã¾ã™ã€‚高ãã™ã‚‹ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒå¼·ã¾ã‚Šã¾ã™ã€‚\nガンマãŒ3.0ã®å ´åˆã¯è¼åº¦ãƒŽã‚¤ã‚ºã®é™¤åŽ»ã«ã¯ç·šå½¢ãŒä½¿ã‚れã¾ã™ã€‚ TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;処ç†å¯¾è±¡ã®å¤§ãã•ã«å¯¾ã—ã¦é©ç”¨ã™ã‚‹ãƒŽã‚¤ã‚ºé™¤åŽ»ã®é‡ã‚’調節ã™ã‚‹ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã§ã™ã€‚ TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;値を高ãã™ã‚‹ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒå¼·ã¾ã‚Šã¾ã™ãŒã€ãã®åˆ†å‡¦ç†æ™‚é–“ãŒå¢—ãˆã¾ã™ã€‚ TP_LOCALLAB_NLDENOISE_TOOLTIP;'ディテールã®å¾©å…ƒ'ã¯ãƒ©ãƒ—ラス変æ›ã«ä½œç”¨ã—ã¾ã™ã€‚詳細をå«ã‚“ã éƒ¨åˆ†ã‚ˆã‚Šã€ã‚€ã—ã‚å‡è³ªãªéƒ¨åˆ†ã‚’目標ã«ã—ã¾ã™ã€‚ TP_LOCALLAB_NLDET;ディテールã®å¾©å…ƒ -TP_LOCALLAB_NLFRA;è¼åº¦ã®ãƒŽãƒ³ãƒ­ãƒ¼ã‚«ãƒ«ãƒŸãƒ¼ãƒ³ãƒ•ィルタ -TP_LOCALLAB_NLFRAME_TOOLTIP;ノンローカルミーンフィルタã«ã‚ˆã‚‹ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯ç”»åƒã®å…¨ãƒ”クセルã®å¹³å‡å€¤ã‚’使ã„ã€ãã®å¹³å‡å€¤ã¨ã®é¡žä¼¼æ€§ã«å¿œã˜ã¦ã€ç›®æ¨™ãƒ”クセルã®ãƒŽã‚¤ã‚ºé™¤åŽ»ã«é‡ã¿ã‚’付ã‘ã¾ã™ã€‚\nãƒ­ãƒ¼ã‚«ãƒ«ãƒŸãƒ¼ãƒ³ãƒ•ã‚£ãƒ«ã‚¿ã«æ¯”ã¹ã€è©³ç´°ã®æå¤±ãŒå°‘ãªãã¦æ¸ˆã¿ã¾ã™ã€‚\nè¼åº¦ãƒŽã‚¤ã‚ºã ã‘を考慮ã—ã¾ã™ã€‚色ノイズã®é™¤åŽ»ã¯ã‚¦ã‚§ãƒ¼ãƒ–レットã¨ãƒ•ーリエ変æ›ï¼ˆDCTï¼‰ã‚’ä½¿ã†æ–¹ãŒãƒ™ã‚¿ãƒ¼ã ã‹ã‚‰ã§ã™ã€‚\nã“ã®ãƒ•ィルタã¯å˜ç‹¬ã§ã‚‚ã€æˆ–ã„ã¯â€è©³ç´°ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹è¼åº¦ãƒŽã‚¤ã‚ºã®é™¤åŽ»â€ã¨ä½µç”¨ã—ã¦ã‚‚使ãˆã¾ã™ã€‚ +TP_LOCALLAB_NLFRA;éžå±€æ‰€å¹³å‡ãƒ•ィルタ:è¼åº¦ãƒŽã‚¤ã‚º +TP_LOCALLAB_NLFRAME_TOOLTIP;éžå±€æ‰€å¹³å‡ãƒ•ィルタã«ã‚ˆã‚‹ãƒŽã‚¤ã‚ºé™¤åŽ»ã¯ç”»åƒã®å…¨ãƒ”クセルã®å¹³å‡å€¤ã‚’使ã„ã€ãã®å¹³å‡å€¤ã¨ã®é¡žä¼¼æ€§ã«å¿œã˜ã¦ã€ç›®æ¨™ãƒ”クセルã®ãƒŽã‚¤ã‚ºé™¤åŽ»ã«é‡ã¿ã‚’付ã‘ã¾ã™ã€‚\nãƒ­ãƒ¼ã‚«ãƒ«ãƒŸãƒ¼ãƒ³ãƒ•ã‚£ãƒ«ã‚¿ã«æ¯”ã¹ã€è©³ç´°ã®æå¤±ãŒå°‘ãªãã¦æ¸ˆã¿ã¾ã™ã€‚\nè¼åº¦ãƒŽã‚¤ã‚ºã ã‘を考慮ã—ã¾ã™ã€‚色ノイズã®é™¤åŽ»ã¯ã‚¦ã‚§ãƒ¼ãƒ–レットã¨ãƒ•ーリエ変æ›ï¼ˆDCTï¼‰ã‚’ä½¿ã†æ–¹ãŒãƒ™ã‚¿ãƒ¼ã ã‹ã‚‰ã§ã™ã€‚\nã“ã®ãƒ•ィルタã¯å˜ç‹¬ã§ã‚‚ã€æˆ–ã„ã¯â€è©³ç´°ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹è¼åº¦ãƒŽã‚¤ã‚ºã®é™¤åŽ»â€ã¨ä½µç”¨ã—ã¦ã‚‚使ãˆã¾ã™ã€‚ TP_LOCALLAB_NLGAM;ガンマ TP_LOCALLAB_NLLUM;å¼·ã• TP_LOCALLAB_NLPAT;パッãƒã®æœ€å¤§å€¤ TP_LOCALLAB_NLRAD;åŠå¾„ã®æœ€å¤§å€¤ -TP_LOCALLAB_NOISECHROCOARSE;高ã„番手ã®è‰²åº¦(ウェーブレット) +TP_LOCALLAB_NOISECHROCOARSE;高ã„番手ã®è‰²ãƒŽã‚¤ã‚º(ウェーブレット) TP_LOCALLAB_NOISECHROC_TOOLTIP;0より大ãã„値ã§åŠ¹æžœã®é«˜ã„アルゴリズムãŒåƒãå§‹ã‚ã¾ã™\n大ã¾ã‹ãªã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã®å ´åˆã¯2以上ã‹ã‚‰ã§ã™ -TP_LOCALLAB_NOISECHRODETAIL;色度ã®è©³ç´°å¾©å…ƒ -TP_LOCALLAB_NOISECHROFINE;低ã„番手ã®è‰²åº¦ï¼ˆã‚¦ã‚§ãƒ¼ãƒ–レット) +TP_LOCALLAB_NOISECHRODETAIL;詳細復元(色) +TP_LOCALLAB_NOISECHROFINE;低ã„番手ã®è‰²ãƒŽã‚¤ã‚ºï¼ˆã‚¦ã‚§ãƒ¼ãƒ–レット) TP_LOCALLAB_NOISEGAM;ガンマ TP_LOCALLAB_NOISEGAM_TOOLTIP;ガンマãŒ1ã®æ™‚ã¯ã€"Lab"ã®è¼åº¦ãŒä½¿ã‚れã¾ã™ã€‚ガンマãŒ3.0ã®æ™‚ã¯"ç·šå½¢"ã®è¼åº¦ãŒä½¿ã‚れã¾ã™\n低ã„値ã«ã™ã‚‹ã¨ãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã¨è³ªæ„ŸãŒä¿ãŸã‚Œã¾ã™ã€‚高ã„値ã«ã™ã‚‹ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ãŒå¼·ã¾ã‚Šã¾ã™ã€‚ TP_LOCALLAB_NOISELEQUAL;イコライザ 白黒 TP_LOCALLAB_NOISELUMCOARSE;高ã„番手ã®è¼åº¦(ウェーブレット) -TP_LOCALLAB_NOISELUMDETAIL;è¼åº¦ã®è©³ç´°å¾©å…ƒ +TP_LOCALLAB_NOISELUMDETAIL;詳細復元(è¼åº¦ï¼‰ TP_LOCALLAB_NOISELUMFINE;è¼åº¦ã€€è©³ç´°ãƒ¬ãƒ™ãƒ«2(ウェーブレット) TP_LOCALLAB_NOISELUMFINETWO;è¼åº¦ã€€è©³ç´°ãƒ¬ãƒ™ãƒ«3(ウェーブレット) TP_LOCALLAB_NOISELUMFINEZERO;è¼åº¦ã€€è©³ç´°ãƒ¬ãƒ™ãƒ«1(ウェーブレット) @@ -3171,23 +3408,28 @@ TP_LOCALLAB_ORIGLC;元画åƒã ã‘ã¨èžåˆ TP_LOCALLAB_ORRETILAP_TOOLTIP;'スコープ'ã«ã‚ˆã‚‹å¤‰æ›´ã®å‰ã«ã€Î”Eを変更ã—ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šç”»åƒã®ç•°ãªã‚‹éƒ¨åˆ†ï¼ˆä¾‹ãˆã°èƒŒæ™¯ï¼‰ã«å¯¾ã™ã‚‹ä½œç”¨ã«å·®ã‚’付ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ TP_LOCALLAB_ORRETISTREN_TOOLTIP;1次ラプラシアンã®ã—ãã„値ã«ä½œç”¨ã—ã¾ã™ã€‚設定値を高ãã™ã‚‹ã»ã©ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®é•ã„ãŒæ¸›å°‘ã—ã¾ã™ TP_LOCALLAB_PASTELS2;自然ãªå½©åº¦ -TP_LOCALLAB_PDE;PDE IPOL - ダイナミックレンジ圧縮 +TP_LOCALLAB_PDE;ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®æ¸›è¡° - ダイナミックレンジ圧縮 TP_LOCALLAB_PDEFRA;ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®æ¸›è¡°ã€€Æ’ TP_LOCALLAB_PDEFRAME_TOOLTIP;Rawtherapeeã¯PDE IPOLã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’採用ã—ã¦ã„ã¾ã™ : ç•°ãªã‚‹åŠ¹æžœãŒæœŸå¾…ã§ãã¾ã™ãŒã€ãƒ¡ã‚¤ãƒ³ã®éœ²å…‰è£œæ­£æ©Ÿèƒ½ã¨ã¯ç•°ãªã‚‹è¨­å®šãŒå¿…è¦ã§ã™ã€‚\n露出ä¸è¶³ã‚„ãƒã‚¤ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ã®ç”»åƒã®è£œæ­£ã«ä¾¿åˆ©ã§ã—ょㆠ+TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;ã“ã®ã‚ªãƒ—ションを有効ã—ãŸå ´åˆã¯ã€XYZマトリクスã¸ã®ä¸€æ¬¡å¤‰æ›ç›´å¾Œã«è‰²åŸŸãŒæŠ‘制ã•れã¾ã™ã€‚ +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;ホワイトãƒã‚¤ãƒ³ãƒˆã‚’主体色ã«è¿‘ã¥ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚彩度ãŒå¤‰ã‚りã¾ã™ã€‚“シフトxâ€ã¨â€œã‚·ãƒ•トyâ€ã®çµ„ã¿åˆã‚ã›ã«ã‚ˆã‚Šã€ç©ã‚„ã‹ãªã‚«ãƒ©ãƒ¼ãƒˆãƒ¼ãƒ³èª¿æ•´ãŒå¯èƒ½ã§ã™ã€‚ +TP_LOCALLAB_PRECAMREFI_TOOLTIP;ホワイトãƒã‚¤ãƒ³ãƒˆã‚’主体色ã«è¿‘ã¥ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚彩度ãŒå¤‰ã‚りã¾ã™ã€‚ +TP_LOCALLAB_PRECAM_TOOLTIP;ã“ã®â€˜å…ƒãƒ‡ãƒ¼ã‚¿ã®èª¿æ•´â€™æ©Ÿèƒ½ã§ï¼ša)対数符å·åŒ–を使ã£ãŸãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ã®åœ§ç¸®ã€b)CIECAMã®å‡¦ç†ã‚’行ã†å‰ã®ç”»åƒå…¨ä½“ã®ãƒˆãƒ¼ãƒ³ã€åŽŸè‰²ï¼ˆå˜ç´”化ã—ãŸã‚¢ãƒ–ストラクトプロファイルを使用)ã€åŠã³ä¸­é–“トーンã®èª¿æ•´ã‚’行ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚å„パラメータ:\nガンマã¯ä¸»ã«æ˜Žã‚‹ã„トーンã«ä½œç”¨ã—ã€ã‚¹ãƒ­ãƒ¼ãƒ—ã¯æš—ã„トーンã«ä½œç”¨ã—ã¾ã™ã€‚\nガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—(両パラメータ>1)を併用ã™ã‚‹ã“ã¨ã§ã€ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒãƒˆãƒ¼ãƒ³ã‚«ãƒ¼ãƒ–ã®ç·šå½¢éƒ¨åˆ†ã¨éžç·šå½¢éƒ¨åˆ†ã®é€£ç¶šæ€§ã‚’ä¿ã¡ã¾ã™ã€‚\n\n\n変更先ã®åŽŸè‰²ï¼šã“れを使ã†ã¨ç”»åƒã®è‰²ï¼ˆå½©åº¦ï¼‰ã‚’復元或ã„ã¯å¤‰æ›´ã™ã‚‹ãŸã‚ã®å¤‰æ›´å…ˆã®åŽŸè‰²ã‚’å¤‰ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚‘作業プロファイル’ã¨â€˜å¤‰æ›´å…ˆã®åŽŸè‰²â€™ã®é•ã„ãŒæ¥µç«¯ã«å¤§ãããªã‘れã°ã€ã‚«ãƒ©ãƒ¼ãƒãƒ©ãƒ³ã‚¹ã¯å分ã«ä¿ãŸã‚Œã¾ã™ã€‚作業プロファイルã¯å¤‰æ›´ã•れã¾ã›ã‚“。\n原色ã¨å…‰æºï¼ˆãƒ›ãƒ¯ã‚¤ãƒˆãƒã‚¤ãƒ³ãƒˆï¼‰ã‚’ã‹ãªã‚Šæ­£ç¢ºã«é †å¿œã•ã›ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚\nホワイトãƒã‚¤ãƒ³ãƒˆã‹ã‚‰åŽŸè‰²ã‚’é›¢ã™ã»ã©ç”»åƒã®å½©åº¦ãŒä¸‹ãŒã‚Šã¾ã™ã€‚ãã®é€†ã‚‚然りã§ã™ãŒè‰²åŸŸã«ã¯æ³¨æ„ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚ TP_LOCALLAB_PREVHIDE;基本的ãªè¨­å®šé …ç›®ã ã‘を表示 -TP_LOCALLAB_PREVIEW;ΔEã®ãƒ—レビュー +TP_LOCALLAB_PREVIEW;プレビューΔE TP_LOCALLAB_PREVSHOW;å…¨ã¦ã®è¨­å®šé …目を表示 +TP_LOCALLAB_PRIMILLFRAME;原色 & å…‰æº TP_LOCALLAB_PROXI;ΔEã®æ¸›è¡° TP_LOCALLAB_QUAAGRES;ç©æ¥µçš„ TP_LOCALLAB_QUACONSER;控ãˆç›® TP_LOCALLAB_QUALCURV_METHOD;カーブã®ã‚¿ã‚¤ãƒ— TP_LOCALLAB_QUAL_METHOD;全体ã®è³ª TP_LOCALLAB_QUANONEALL;ãªã— -TP_LOCALLAB_QUANONEWAV;ノンローカルミーンã ã‘ +TP_LOCALLAB_QUANONEWAV;éžå±€æ‰€å¹³å‡ãƒ•ィルタã ã‘ TP_LOCALLAB_RADIUS;åŠå¾„ TP_LOCALLAB_RADIUS_TOOLTIP;åŠå¾„ãŒ30より大ãã„å ´åˆã¯ã€é«˜é€Ÿãƒ•ーリエ変æ›ã‚’使ã„ã¾ã™ TP_LOCALLAB_RADMASKCOL;スムーズãªåŠå¾„ -TP_LOCALLAB_RECOTHRES02_TOOLTIP;“回復ã®ã—ãã„値â€ãŒ1より大ãã„å ´åˆã¯ã€â€œãƒžã‚¹ã‚¯ã¨ä¿®æ­£é ˜åŸŸâ€ã«ä»˜å±žã™ã‚‹ãƒžã‚¹ã‚¯ã¯ã€ãã®å‰ã«ç”»åƒã«å¯¾ã—ã¦è¡Œã‚れãŸå…¨ã¦ã®èª¿æ•´ã‚’考慮ã—ã¾ã™ãŒã€ç¾åœ¨ã®ãƒ„ールã§è¡Œã‚れãŸèª¿æ•´ï¼ˆä¾‹ã€è‰²ã¨æ˜Žã‚‹ã•ã‚„ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€CAM16ã€ãªã©ï¼‰ã¯è€ƒæ…®ã—ã¾ã›ã‚“。\n“回復ã®ã—ãã„値â€ãŒ1よりå°ã•ã„å ´åˆã¯ã€â€œãƒžã‚¹ã‚¯ã¨ä¿®æ­£é ˜åŸŸâ€ã«ä»˜å±žã™ã‚‹ãƒžã‚¹ã‚¯ã¯ã€ãã®å‰ã«ç”»åƒã«å¯¾ã—ã¦è¡Œã‚れãŸå…¨ã¦ã®èª¿æ•´ã‚’考慮ã—ã¾ã›ã‚“。\n\nã©ã¡ã‚‰ã®å ´åˆã‚‚ã€â€œå›žå¾©ã®ã—ãã„値â€ã¯ç¾åœ¨ã®ãƒ„ール(例ã€è‰²ã¨æ˜Žã‚‹ã•ã‚„ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€CAM16ã€ãªã©ï¼‰ã§èª¿æ•´ã•れãŸãƒžã‚¹ã‚¯ã•れãŸç”»åƒã«ä½œç”¨ã—ã¾ã™ã€‚ +TP_LOCALLAB_RECOTHRES02_TOOLTIP;“回復ã®ã—ãã„値â€ãŒ1より大ãã„å ´åˆã¯ã€â€œãƒžã‚¹ã‚¯ã¨ä¿®æ­£â€ã«ä»˜å±žã™ã‚‹ãƒžã‚¹ã‚¯ã¯ã€ãã®å‰ã«ç”»åƒã«å¯¾ã—ã¦è¡Œã‚れãŸå…¨ã¦ã®èª¿æ•´ã‚’考慮ã—ã¾ã™ãŒã€ç¾åœ¨ã®ãƒ„ールã§è¡Œã‚れãŸèª¿æ•´ï¼ˆä¾‹ã€è‰²ã¨æ˜Žã‚‹ã•ã‚„ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€CAM16ã€ãªã©ï¼‰ã¯è€ƒæ…®ã—ã¾ã›ã‚“。\n“回復ã®ã—ãã„値â€ãŒ1よりå°ã•ã„å ´åˆã¯ã€â€œãƒžã‚¹ã‚¯ã¨ä¿®æ­£â€ã«ä»˜å±žã™ã‚‹ãƒžã‚¹ã‚¯ã¯ã€ãã®å‰ã«ç”»åƒã«å¯¾ã—ã¦è¡Œã‚れãŸå…¨ã¦ã®èª¿æ•´ã‚’考慮ã—ã¾ã›ã‚“。\n\nã©ã¡ã‚‰ã®å ´åˆã‚‚ã€â€œå›žå¾©ã®ã—ãã„値â€ã¯ç¾åœ¨ã®ãƒ„ール(例ã€è‰²ã¨æ˜Žã‚‹ã•ã‚„ã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€CAM16ã€ãªã©ï¼‰ã§èª¿æ•´ã•れãŸãƒžã‚¹ã‚¯ã•れãŸç”»åƒã«ä½œç”¨ã—ã¾ã™ã€‚ TP_LOCALLAB_RECT;長方形 TP_LOCALLAB_RECURS;åŸºæº–å€¤ã‚’ç¹°ã‚Šè¿”ã—æ›´æ–° TP_LOCALLAB_RECURS_TOOLTIP;儿©Ÿèƒ½ã®é©ç”¨å¾Œã«åŸºæº–値を強制的ã«å†è¨ˆç®—ã•ã›ã‚‹æ©Ÿèƒ½ã§ã™\nマスクを使ã£ãŸä½œæ¥­ã«ã‚‚便利ã§ã™ @@ -3200,7 +3442,7 @@ TP_LOCALLAB_REPARSH_TOOLTIP;元画åƒã«é–¢ã™ã‚‹ã‚·ãƒ£ãƒ‰ã‚¦/ãƒã‚¤ãƒ©ã‚¤ãƒˆã¨ TP_LOCALLAB_REPARTM_TOOLTIP;元画åƒã«é–¢ã™ã‚‹ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ãƒ³ã‚°ã®æ§‹æˆã®ç›¸å¯¾çš„å¼·ã•を調整出æ¥ã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚ TP_LOCALLAB_REPARW_TOOLTIP;元画åƒã«é–¢ã™ã‚‹ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã¨ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆã®æ§‹æˆã®ç›¸å¯¾çš„å¼·ã•を調整出æ¥ã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚ TP_LOCALLAB_RESID;æ®‹å·®ç”»åƒ -TP_LOCALLAB_RESIDBLUR;残差画åƒã‚’ã¼ã‹ã™ +TP_LOCALLAB_RESIDBLUR;残差画åƒã®ã¼ã‹ã— TP_LOCALLAB_RESIDCHRO;残差画åƒã®è‰²åº¦ TP_LOCALLAB_RESIDCOMP;残差画åƒã®åœ§ç¸® TP_LOCALLAB_RESIDCONT;残差画åƒã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ @@ -3217,7 +3459,7 @@ TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;'明度=1'或ã„ã¯'æš—ã•=2'ã®å ´åˆã¯åй TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;åŠ¹æžœã®æœ€é©åŒ–を図るãŸã‚内部ã®å¤‰æ•°ã‚’変ãˆã¾ã™\n'修復ã•れãŸãƒ‡ãƒ¼ã‚¿'ã¯æœ€ä½Žå€¤ãŒ0ã€æœ€å¤§å€¤ãŒ32768(対数モード)ã«è¿‘ã„ã“ã¨ãŒæœ›ã¾ã—ã„ã®ã§ã™ãŒã€å¿…ãšã—も一致ã•ã›ã‚‹å¿…è¦ã¯ã‚りã¾ã›ã‚“。 TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;対数モードを使ã†ã¨ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒå¢—ãˆã¾ã™ãŒã€ãƒãƒ­ãŒç™ºç”Ÿã™ã‚‹ã“ã¨ã‚‚ã‚りã¾ã™ TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;åŠå¾„ã¨åˆ†æ•£ï¼ˆãƒãƒªã‚¢ãƒ³ã‚¹ï¼‰ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯éœžã‚’調整ã—ã¾ã™ã€‚剿™¯æˆ–ã„ã¯èƒŒæ™¯ã‚’目標ã«ã—ã¾ã™ -TP_LOCALLAB_RETI_SCALE_TOOLTIP;スケールãŒ1ã®æ™‚ã¯ã€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’調整ã—ãŸæ§˜ãªåŠ¹æžœã«ãªã‚Šã¾ã™\nスケールã®å€¤ã‚’増やã™ã¨å›žå¸°ä½œç”¨ãŒå¼·åŒ–ã•れã¾ã™ãŒã€ãã®åˆ†å‡¦ç†æ™‚間も増加ã—ã¾ã™ +TP_LOCALLAB_RETI_SCALE_TOOLTIP;スケールãŒ1ã®æ™‚ã¯ã€ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’調整ã—ãŸæ§˜ãªåŠ¹æžœã«ãªã‚Šã¾ã™\nスケールã®å€¤ã‚’増やã™ã¨å›žå¸°ä½œç”¨ãŒå¼·åŒ–ã•れã¾ã™ãŒã€ãã®åˆ†å‡¦ç†æ™‚間も増加ã—ã¾ã™ TP_LOCALLAB_RET_TOOLNAME;霞除去 & レティãƒãƒƒã‚¯ã‚¹ TP_LOCALLAB_REWEI;å†åŠ é‡å¹³å‡ã®ç¹°ã‚Šè¿”ã— TP_LOCALLAB_RGB;RGB トーンカーブ @@ -3225,6 +3467,7 @@ TP_LOCALLAB_RGBCURVE_TOOLTIP;RGBモードã«ã¯4ã¤ã®é¸æŠžè‚¢ãŒã‚りã¾ã™ TP_LOCALLAB_ROW_NVIS;éžè¡¨ç¤º TP_LOCALLAB_ROW_VIS;表示 TP_LOCALLAB_RSTPROTECT_TOOLTIP;レッドã¨è‚Œè‰²ã®ä¿è­·ã¯ã€å½©åº¦ã‚„色度ã€é®®ã‚„ã‹ã•ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼èª¿æ•´ã«å½±éŸ¿ã—ã¾ã™ã€‚ +TP_LOCALLAB_SATCIE;彩度ã®åˆ¶å¾¡ TP_LOCALLAB_SATUR;彩度 TP_LOCALLAB_SATURV;彩度S TP_LOCALLAB_SCALEGR;スケール @@ -3259,49 +3502,73 @@ TP_LOCALLAB_SHARP_TOOLNAME;シャープニング TP_LOCALLAB_SHARRADIUS;åŠå¾„ TP_LOCALLAB_SHORTC;ショートカーブ'L'マスク TP_LOCALLAB_SHORTCMASK_TOOLTIP;L(L)ã¨L(H)2ã¤ã®ã‚«ãƒ¼ãƒ–をスキップã—ã¾ã™ã€‚\nマスクã®ä½œç”¨ã«ã‚ˆã£ã¦èª¿æ•´ã•れãŸç¾åœ¨ã®ã‚¤ãƒ¡ãƒ¼ã‚¸ã¨å…ƒã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’èžåˆã—ã¾ã™\n但ã—ã€ã“れãŒä½¿ãˆã‚‹ã®ã¯2, 3, 4, 6, 7ã®ãƒžã‚¹ã‚¯ã§ã™ -TP_LOCALLAB_SHOWC;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWC;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHOWC1;ファイルã®èžåˆ -TP_LOCALLAB_SHOWCB;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWCB;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHOWDCT;フーリエã®å‡¦ç†ã‚’表示 -TP_LOCALLAB_SHOWE;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWE;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHOWFOURIER;フーリエ (DCT) TP_LOCALLAB_SHOWLAPLACE;Δ ラプラシアン (一次) -TP_LOCALLAB_SHOWLC;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWLC;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHOWMASK;マスクã®è¡¨ç¤º -TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;マスクã¨ä¿®æ­£ç®‡æ‰€ã®è¡¨ç¤ºï¼š\n注æ„:一度ã«ä¸€ã¤ã®æ©Ÿèƒ½ã®ãƒžã‚¹ã‚¯ã—ã‹è¦‹ã‚‹ã“ã¨ãŒå‡ºæ¥ãã¾ã›ã‚“\n調整åŠã³ä¿®æ­£ã—ãŸç”»åƒï¼šæ©Ÿèƒ½ã«ã‚ˆã‚‹èª¿æ•´ã¨ãƒžã‚¹ã‚¯ã«ã‚ˆã‚‹ä¿®æ­£ã®ä¸¡æ–¹ã‚’å«ã‚€ç”»åƒã‚’表示\n修正領域をマスクãªã—ã§è¡¨ç¤ºï¼šãƒžã‚¹ã‚¯ã‚’é©ç”¨ã™ã‚‹å‰ã®ä¿®æ­£é ˜åŸŸã‚’表示\n修正領域をマスクã¨å…±ã«è¡¨ç¤ºï¼šãƒžã‚¹ã‚¯ã‚’é©ç”¨ã—ãŸä¿®æ­£é ˜åŸŸã‚’表示\nマスクã®è¡¨ç¤ºï¼šã‚«ãƒ¼ãƒ–やフィルタã®åŠ¹æžœã‚’å«ã‚ãŸãƒžã‚¹ã‚¯ã®æ§˜å­ã‚’表示ã—ã¾ã™\nスãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示:'スãƒãƒƒãƒˆã®æ§‹é€ 'スライダー(機能水準ãŒé«˜åº¦ã®å ´åˆï¼‰ãŒæœ‰åйã«ãªã£ãŸæ™‚ã«ã€æ§‹é€ æ¤œå‡ºãƒžã‚¹ã‚¯ã‚’見るã“ã¨ãŒå‡ºæ¥ã¾ã™\n注æ„:形状検出ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒä½œç”¨ã™ã‚‹å‰ã«ãƒžã‚¹ã‚¯ãŒé©ç”¨ã•れã¾ã™ +TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;マスクã¨ä¿®æ­£ç®‡æ‰€ã®è¡¨ç¤ºï¼š\n注æ„:一度ã«ä¸€ã¤ã®æ©Ÿèƒ½ã®ãƒžã‚¹ã‚¯ã—ã‹è¦‹ã‚‹ã“ã¨ãŒå‡ºæ¥ãã¾ã›ã‚“\n修正ã•れãŸç”»åƒï¼šæ©Ÿèƒ½ã«ã‚ˆã‚‹èª¿æ•´ã¨ãƒžã‚¹ã‚¯ã«ã‚ˆã‚‹ä¿®æ­£ã®ä¸¡æ–¹ã‚’å«ã‚€ç”»åƒã‚’表示\n修正領域をマスクãªã—ã§è¡¨ç¤ºï¼šãƒžã‚¹ã‚¯ã‚’é©ç”¨ã™ã‚‹å‰ã®ä¿®æ­£é ˜åŸŸã‚’表示\n修正領域をマスクã¨å…±ã«è¡¨ç¤ºï¼šãƒžã‚¹ã‚¯ã‚’é©ç”¨ã—ãŸä¿®æ­£é ˜åŸŸã‚’表示\nマスクã®è¡¨ç¤ºï¼šã‚«ãƒ¼ãƒ–やフィルタã®åŠ¹æžœã‚’å«ã‚ãŸãƒžã‚¹ã‚¯ã®æ§˜å­ã‚’表示ã—ã¾ã™\nスãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示:'スãƒãƒƒãƒˆã®æ§‹é€ 'スライダー(機能水準ãŒé«˜åº¦ã®å ´åˆï¼‰ãŒæœ‰åйã«ãªã£ãŸæ™‚ã«ã€æ§‹é€ æ¤œå‡ºãƒžã‚¹ã‚¯ã‚’見るã“ã¨ãŒå‡ºæ¥ã¾ã™\n注æ„:形状検出ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒä½œç”¨ã™ã‚‹å‰ã«ãƒžã‚¹ã‚¯ãŒé©ç”¨ã•れã¾ã™ TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;フーリエ変æ›ã«ã‚ˆã‚‹å‡¦ç†ã‚’段階的ã«è¦‹ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™\nラプラス - ã—ãã„値ã®é–¢æ•°ã¨ã—ã¦ãƒ©ãƒ—ラス変æ›ã®2次微分を計算仕ã—ã¾ã™\nフーリエ - 離散コサイン変æ›ï¼ˆDCT)ã§ãƒ©ãƒ—ラス変æ›ã‚’表示ã—ã¾ã™\nãƒã‚¢ã‚½ãƒ³ - ãƒã‚¢ã‚½ãƒ³æ–¹ç¨‹å¼ã®è§£ã‚’表示ã—ã¾ã™\nè¼åº¦ã®æ¨™æº–化ãªã— - è¼åº¦ã®æ¨™æº–化ãªã—ã§çµæžœã‚’表示ã—ã¾ã™ -TP_LOCALLAB_SHOWMASKTYP1;ã¼ã‹ã—&ノイズ除去 +TP_LOCALLAB_SHOWMASKTYP1;ã¼ã‹ã—&ノイズ TP_LOCALLAB_SHOWMASKTYP2;ノイズ除去 -TP_LOCALLAB_SHOWMASKTYP3;ã¼ã‹ã—&ノイズ除去 + ノイズ除去 -TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;‘マスクã¨ä¿®æ­£é ˜åŸŸâ€™ã¨ä½µã›ã¦ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n‘ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€™ã‚’é¸æŠžã—ãŸå ´åˆã€ãƒžã‚¹ã‚¯ã¯ãƒŽã‚¤ã‚ºé™¤åŽ»ã«ã¯ä½¿ãˆã¾ã›ã‚“。\nâ€˜ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’é¸æŠžã—ãŸå ´åˆã€ãƒžã‚¹ã‚¯ã¯â€™ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€˜ã«ã¯ä½¿ãˆã¾ã›ã‚“。\n’ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºã€€+ã€€ãƒŽã‚¤ã‚ºé™¤åŽ»â€˜ã‚’é¸æŠžã—ãŸå ´åˆã¯ã€ãƒžã‚¹ã‚¯ã‚’共有ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚但ã—ã€ã“ã®å ´åˆã€â€™ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€˜ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ã®ã‚¹ã‚³ãƒ¼ãƒ—ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ãŒæœ‰åйã¨ãªã‚‹ã®ã§ã€ä¿®æ­£ã‚’行ã†éš›ã«ã¯â€™ãƒžã‚¹ã‚¯ã¨å…±ã«ä¿®æ­£é ˜åŸŸã‚’表示‘ã®ã‚ªãƒ—ションを使ã†ã“ã¨ã‚’奨ã‚ã¾ã™ã€‚ -TP_LOCALLAB_SHOWMNONE;調整åŠã³ä¿®æ­£ã—ãŸç”»åƒ +TP_LOCALLAB_SHOWMASKTYP3;ã¼ã‹ã—&ノイズ + ノイズ除去 +TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;‘マスクã¨ä¿®æ­£â€™ã¨ä½µã›ã¦ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n‘ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€™ã‚’é¸æŠžã—ãŸå ´åˆã€ãƒžã‚¹ã‚¯ã¯ãƒŽã‚¤ã‚ºé™¤åŽ»ã«ã¯ä½¿ãˆã¾ã›ã‚“。\nâ€˜ãƒŽã‚¤ã‚ºé™¤åŽ»ã‚’é¸æŠžã—ãŸå ´åˆã€ãƒžã‚¹ã‚¯ã¯â€™ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€˜ã«ã¯ä½¿ãˆã¾ã›ã‚“。\n’ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºã€€+ã€€ãƒŽã‚¤ã‚ºé™¤åŽ»â€˜ã‚’é¸æŠžã—ãŸå ´åˆã¯ã€ãƒžã‚¹ã‚¯ã‚’共有ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚但ã—ã€ã“ã®å ´åˆã€â€™ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºâ€˜ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ã®ã‚¹ã‚³ãƒ¼ãƒ—ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ãŒæœ‰åйã¨ãªã‚‹ã®ã§ã€ä¿®æ­£ã‚’行ã†éš›ã«ã¯â€™ãƒžã‚¹ã‚¯ã¨å…±ã«ä¿®æ­£é ˜åŸŸã‚’表示‘ã®ã‚ªãƒ—ションを使ã†ã“ã¨ã‚’奨ã‚ã¾ã™ã€‚ +TP_LOCALLAB_SHOWMNONE;修正ã•れãŸç”»åƒã‚’表示 TP_LOCALLAB_SHOWMODIF;修正領域をマスクãªã—ã§è¡¨ç¤º TP_LOCALLAB_SHOWMODIF2;マスクã®è¡¨ç¤º TP_LOCALLAB_SHOWMODIFMASK;修正領域をマスクã¨å…±ã«è¡¨ç¤º TP_LOCALLAB_SHOWNORMAL;è¼åº¦ã®æ¨™æº–化をã—ãªã„ -TP_LOCALLAB_SHOWPLUS;マスクã¨ä¿®æ­£é ˜åŸŸï¼ˆã¼ã‹ã—&ノイズ除去) +TP_LOCALLAB_SHOWPLUS;マスクã¨ä¿®æ­£ï¼ˆã¼ã‹ã—&ノイズ) TP_LOCALLAB_SHOWPOISSON;ãƒã‚¢ã‚½ãƒ³ (pde f) -TP_LOCALLAB_SHOWR;マスクã¨ä¿®æ­£é ˜åŸŸ -TP_LOCALLAB_SHOWREF;ΔEã®ãƒ—レビュー -TP_LOCALLAB_SHOWS;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWR;マスクã¨ä¿®æ­£ +TP_LOCALLAB_SHOWREF;プレビューΔE +TP_LOCALLAB_SHOWS;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHOWSTRUC;スãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示 TP_LOCALLAB_SHOWSTRUCEX;スãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示 -TP_LOCALLAB_SHOWT;マスクã¨ä¿®æ­£é ˜åŸŸ -TP_LOCALLAB_SHOWVI;マスクã¨ä¿®æ­£é ˜åŸŸ +TP_LOCALLAB_SHOWT;マスクã¨ä¿®æ­£ +TP_LOCALLAB_SHOWVI;マスクã¨ä¿®æ­£ TP_LOCALLAB_SHRESFRA;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ&TRC TP_LOCALLAB_SHTRC_TOOLTIP;'作業プロファイル'をベースã«ï¼ˆä½†ã—ã€ãã‚ŒãŒæä¾›ã•れã¦ã„ã‚‹å ´åˆã®ã¿ï¼‰ã€TRC(トーンレスãƒãƒ³ã‚¹ã‚«ãƒ¼ãƒ–)を使ã£ã¦ç”»åƒã®ãƒˆãƒ¼ãƒ³ã‚’調節ã—ã¾ã™ã€‚\nガンマã¯ä¸»ã«æ˜Žã‚‹ã„トーンã«ä½œç”¨ã—ã¾ã™\n勾é…ã¯ä¸»ã«æš—ã„トーンã«ä½œç”¨ã—ã¾ã™ TP_LOCALLAB_SH_TOOLNAME;シャドウ/ãƒã‚¤ãƒ©ã‚¤ãƒˆ & トーンイコライザ -TP_LOCALLAB_SIGFRA;シグモイドQã¨å¯¾æ•°ç¬¦å·åŒ–Q -TP_LOCALLAB_SIGJZFRA;Jz シグモイド +TP_LOCALLAB_SIGBLACKSSCIE;ブラックã®åˆ†å¸ƒ +TP_LOCALLAB_SIGCIE;シグモイド +TP_LOCALLAB_SIGFRA;シグモイドQ +TP_LOCALLAB_SIGGAMJCIE;ガンマ +TP_LOCALLAB_SIGJZFRA;シグモイド Jz TP_LOCALLAB_SIGMAWAV;減衰応答 +TP_LOCALLAB_SIGMOID16_TOOLTIP;‘CIECAM’ã¨â€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰Q’を併用ã™ã‚‹ã“ã¨ã§ã€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã«ä¼¼ãŸåŠ¹æžœã‚’å‡ºã›ã¾ã™ã€‚\nシグモイドQã®ï¼“ã¤ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼ša)コントラストã¯ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®ã‚«ãƒ¼ãƒ–形状ã«ä½œç”¨ã—å¼·ã•を調整ã—ã¾ã™ã€b)ã—ãã„値(グレーãƒã‚¤ãƒ³ãƒˆï¼‰ã¯è¼åº¦ã«å¿œã˜ãŸä½œç”¨ã®é…分を調整ã—ã¾ã™ã€c)順応性ã¯å†…éƒ¨ã®æŒ‡æ•°é–¢æ•°ã«ä½œç”¨ã™ã‚‹ã“ã¨ã§ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®ä½œç”¨ã«é‡ã¿ã‚’ã‹ã‘ã¾ã™ã€‚ TP_LOCALLAB_SIGMOIDBL;ブレンド TP_LOCALLAB_SIGMOIDLAMBDA;コントラスト -TP_LOCALLAB_SIGMOIDQJ;ブラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvを使ㆠ+TP_LOCALLAB_SIGMOIDLOGAUTO;自動ã®ã—ãã„値 +TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;コンボボックスã«ã‚ˆã‚‹é¸æŠžã§ã€â€˜ãƒ–ラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEv’ãŒâ€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®ã¿â€™ã§ã¯ãªãã€â€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã¨å¯¾æ•°ç¬¦å·åŒ–’ã®å ´åˆã¯ã€ï¼’ã¤ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã€â€˜å¯¾æ•°ç¬¦å·åŒ–’ã¨â€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰â€™ã®åŒæ–¹ãŒä½µç”¨ã—ã¦ä½¿ã‚れã¾ã™ã€‚ +TP_LOCALLAB_SIGMOIDNORMCIE;è¼åº¦ã®æ¨™æº–化 +TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;ブレンドã§ç”»åƒã®æœ€çµ‚é¢ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆåŠã³è¼åº¦ã«ä½œç”¨ã™ã‚‹å…ƒç”»åƒã¨å‡ºåŠ›ç”»åƒã®æ¯”率を決ã‚ã¾ã™ã€‚ +TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;元画åƒã®è¼åº¦ã®å¹³å‡ã¨åˆ†æ•£ã‚’考慮ã™ã‚‹ã“ã¨ã§è¼åº¦ã®å¾©å…ƒã‚’行ã„ã¾ã™ã€‚\nシグモイドQã«é–¢é€£ãŒãªã„調整もå«ã‚ã€J或ã„ã¯Qã«ä½œç”¨ã™ã‚‹å…¨ã¦ã®èª¿æ•´ãŒè€ƒæ…®ã•れã¾ã™ã€‚ +TP_LOCALLAB_SIGMOIDQJ;ブラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEv +TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;コンボボックスã‹ã‚‰ã®é¸æŠžã§ã€â€˜ãƒ–ラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvを使ã†â€™ãŒã€â€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã¨å¯¾æ•°ç¬¦å·åŒ–Qâ€™ã€æˆ–ã„ã¯â€˜ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®ä»£ã‚りã«å¯¾æ•°ç¬¦å·åŒ–’ã«ãƒã‚§ãƒƒã‚¯ãŒå…¥ã£ã¦ã„ã‚‹å ´åˆã¯ã€ã“ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã¯ã—ãã„値ã®è¨­å®šå€¤ä»¥ä¸Šã®ãƒ‡ãƒ¼ã‚¿ã‚’圧縮ã—ã¾ã™ã€‚ã“ã®æœ€å¾Œã®å€¤ã¯æ˜Žã‚‹ã•Qを表ã—ã¦ã„ã¦ã€è€ƒãˆã‚‰ã‚Œã‚‹â€˜åœ§ç¸®ã®ã—ãã„値’ (‘自動ã®ã—ãã„値ã«ãƒã‚§ãƒƒã‚¯ãŒå…¥ã£ã¦ã„ã‚‹å ´åˆã«ç®—出ã•れã€å¤šãã®å ´åˆ1より大ãã„)ã«è¿‘ããªã‚‹ã¹ãã§ã™ã€‚ +TP_LOCALLAB_SIGMOIDSENSI;順応性 TP_LOCALLAB_SIGMOIDTH;ã—ãã„値(グレーãƒã‚¤ãƒ³ãƒˆ) -TP_LOCALLAB_SIGMOID_TOOLTIP;'CIECAM'(或ã„ã¯â€™Jz)ã¨'シグモイド'関数を使ã£ã¦ã€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ãƒ³ã‚°ã®æ§˜ãªåŠ¹æžœã‚’ä½œã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n3ã¤ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã‚’使ã„ã¾ã™: a) コントラストã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®å½¢çŠ¶ã‚’å¤‰ãˆã‚‹ã“ã¨ã§å¼·ã•を変ãˆã¾ã™ã€‚ b) ã—ãã„値(グレーãƒã‚¤ãƒ³ãƒˆï¼‰ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯ã€è¼åº¦ã«å¿œã˜ã¦ä½œç”¨ã‚’変ãˆã¾ã™ã€‚ c)ブレンドã¯ç”»åƒã®æœ€çµ‚çš„ãªã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚„è¼åº¦ã‚’変ãˆã¾ã™ã€‚ +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;ç”»åƒã®ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ãŒé«˜ã„å ´åˆã€éžå¸¸ã«æ˜Žã‚‹ã„部分ã®åˆ†å¸ƒã¨éžå¸¸ã«æš—ã„部分ã®åˆ†å¸ƒã‚’自動ã§èª¿æ•´ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n対数符å·åŒ–ã€æˆ–ã„ã¯ãƒ–ラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvを有効ã«ã—ãŸã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã§ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n\nアルゴリズムãŒå…ƒã®ãƒ‡ãƒ¼ã‚¿ã‚’変ãˆã‚‹ã“ã¨ã¯ã‚りã¾ã›ã‚“ãŒã€ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ¬ãƒ³ã‚¸ã€ãƒ–ラックEvã€ãƒ›ãƒ¯ã‚¤ãƒˆEvã€åŠã³ã‚°ãƒ¬ãƒ¼ãƒã‚¤ãƒ³ãƒˆã‚’計算ã™ã‚‹éš›ã«å¿…è¦ãªæ§‹æˆè¦ç´ ã«ä½œç”¨ã—ã¾ã™ã€‚ +TP_LOCALLAB_SIGMOID_TOOLTIP;'Jz’ã¨'シグモイド'関数を使ã£ã¦ã€ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã«ä¼¼ãŸåŠ¹æžœã‚’å‡ºã›ã¾ã™ã€‚\n3ã¤ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã‚’使ã„ã¾ã™: a) コントラストã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯ã‚·ã‚°ãƒ¢ã‚¤ãƒ‰ã®å½¢çŠ¶ã‚’å¤‰ãˆã‚‹ã“ã¨ã§å¼·ã•を変ãˆã¾ã™ã€‚ b) ã—ãã„値(グレーãƒã‚¤ãƒ³ãƒˆï¼‰ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã¯ã€è¼åº¦ã«å¿œã˜ã¦ä½œç”¨ã‚’変ãˆã¾ã™ã€‚ c)ブレンドã¯ç”»åƒã®æœ€çµ‚çš„ãªã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚„è¼åº¦ã‚’変ãˆã¾ã™ã€‚ +TP_LOCALLAB_SIGSLOPJCIE;スロープ +TP_LOCALLAB_SIGTRCCIE;元データã®èª¿æ•´ +TP_LOCALLAB_SIGWHITESCIE;ホワイトã®åˆ†å¸ƒ TP_LOCALLAB_SLOMASKCOL;スロープ TP_LOCALLAB_SLOMASK_TOOLTIP;ガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—を調整ã™ã‚‹ã“ã¨ã§ã€ä¸é€£ç¶šã‚’é¿ã‘ã‚‹ãŸã‚ã®â€œLâ€ã®æ¼¸é€²çš„修正ã«ã‚ˆã‚Šã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトã®ç„¡ã„マスクã®ä¿®æ­£ãŒå‡ºæ¥ã¾ã™ +TP_LOCALLAB_SLOPESMOOTH;グレーãƒãƒ©ãƒ³ã‚¹(スロープ) +TP_LOCALLAB_SLOPESMOOTHB;ブルーã®ãƒãƒ©ãƒ³ã‚¹(スロープ) +TP_LOCALLAB_SLOPESMOOTHG;グリーンã®ãƒãƒ©ãƒ³ã‚¹(スロープ) +TP_LOCALLAB_SLOPESMOOTHR;レッドã®ãƒãƒ©ãƒ³ã‚¹(スロープ) TP_LOCALLAB_SLOSH;スロープ +TP_LOCALLAB_SMOOTHCIE;ãƒã‚¤ãƒ©ã‚¤ãƒˆã®æ¸›è¡° +TP_LOCALLAB_SMOOTHCIE_LUM;明るã•ã®ãƒ¢ãƒ¼ãƒ‰ +TP_LOCALLAB_SMOOTHCIE_SCA;å ´é¢ã®Ybã®å°ºåº¦ +TP_LOCALLAB_SMOOTHCIE_TOOLTIP;ガンマã€ã‚¹ãƒ­ãƒ¼ãƒ—åŠã³ä¸­é–“トーンã«ã‚ˆã‚Šå®Ÿè¡Œã•れãŸå‡¦ç†ã®åŠ¹æžœã‚’æ»‘ã‚‰ã‹ã«ã™ã‚‹ã‚‚ã®ã§ã€æ˜Žã‚‹ã•ãŒè‹¥å¹²ä¸‹ãŒã‚Šã¾ã™ã€‚但ã—ã€ã“れã¯ãƒã‚¤ãƒ©ã‚¤ãƒˆã®å¾©å…ƒæ©Ÿèƒ½ã®ä»£ã‚りã«ã¯ãªã‚Šã¾ã›ã‚“。\n\nガンマã¨ã‚¹ãƒ­ãƒ¼ãƒ—ã®èª¿æ•´ã¯ä»¥ä¸‹ã«ç¤ºã™èª¿æ•´ã¨åˆã‚ã›ã‚Œã°ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã«ä¼¼ãŸåŠ¹æžœã‚’ã‚‚ãŸã‚‰ã—ã¾ã™ã€‚aï¼‰å ´é¢æ¡ä»¶ã®ãƒ–ラックEvã¨ãƒ›ãƒ¯ã‚¤ãƒˆEvã€å¹³å‡è¼åº¦ï¼ˆYb%)ã€b)観視æ¡ä»¶ã®å¹³å‡è¼åº¦ï¼ˆYb%)。\nå ´é¢ã®Ybã®å°ºåº¦ã¯ãƒ›ãƒ¯ã‚¤ãƒˆEvã«å¿œã˜ã¦æ±ºã¾ã‚Šã¾ã™ã€‚ +TP_LOCALLAB_SMOOTHCIE_YB;観視æ¡ä»¶ã®Ybã®å°ºåº¦ TP_LOCALLAB_SOFT;ソフトライト & 独自ã®ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ TP_LOCALLAB_SOFTM;ソフトライト TP_LOCALLAB_SOFTMETHOD_TOOLTIP;独自ã®ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹ã¯ä»–ã®ãƒ¬ãƒ†ã‚£ãƒãƒƒã‚¯ã‚¹æ–¹å¼ã¨ã¯å¤§ããç•°ãªã‚Šã¾ã™\nグレーã¨è¼åº¦ã®ãƒãƒ©ãƒ³ã‚¹ã«ä½œç”¨ã—ã¾ã™ @@ -3313,7 +3580,7 @@ TP_LOCALLAB_SOURCE_ABS;絶対è¼åº¦ TP_LOCALLAB_SOURCE_GRAY;å¹³å‡è¼åº¦ï¼ˆY%) TP_LOCALLAB_SPECCASE;特有ã®è¨­å®š TP_LOCALLAB_SPECIAL;RGBカーブã®ç‰¹æ®Šãªåˆ©ç”¨ -TP_LOCALLAB_SPECIAL_TOOLTIP;ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã«âœ”を入れるã¨ã€ä»–ã®å…¨ã¦ã®ä½œç”¨ãŒå–り除ã‹ã‚Œã¾ã™ã€‚例ãˆã°ã€â€œã‚¹ã‚³ãƒ¼ãƒ—â€, マスク, スライダーãªã©ã®ä½œç”¨(境界を除ãã¾ã™) ãŒé™¤ã‹ã‚ŒRGBトーンカーブã®åŠ¹æžœã ã‘ãŒä½¿ã‚れã¾ã™ +TP_LOCALLAB_SPECIAL_TOOLTIP;ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã«âœ”を入れるã¨ã€ä»–ã®å…¨ã¦ã®ä½œç”¨ãŒå–り除ã‹ã‚Œã¾ã™ã€‚例ãˆã°ã€â€œã‚¹ã‚³ãƒ¼ãƒ—â€, マスク, スライダーãªã©ã®ä½œç”¨(境界を除ãã¾ã™) ãŒé™¤ã‹ã‚ŒRGBトーンカーブã®åŠ¹æžœã ã‘ãŒä½¿ã‚れã¾ã™ TP_LOCALLAB_SPOTNAME;æ–°ã—ã„スãƒãƒƒãƒˆ TP_LOCALLAB_STD;標準 TP_LOCALLAB_STR;å¼·ã• @@ -3323,19 +3590,21 @@ TP_LOCALLAB_STRENG;å¼·ã• TP_LOCALLAB_STRENGR;å¼·ã• TP_LOCALLAB_STRENGRID_TOOLTIP;望む効果ã¯'å¼·ã•'ã§èª¿æ•´å‡ºæ¥ã¾ã™ãŒã€ä½œç”¨ã®ç¯„囲を制é™ã™ã‚‹'スコープ'を使ã†ã“ã¨ã‚‚出æ¥ã¾ã™ã€‚ TP_LOCALLAB_STRENGTH;ノイズ +TP_LOCALLAB_STRENGTHCIELOG;å¼·ã• TP_LOCALLAB_STRGRID;å¼·ã• TP_LOCALLAB_STRUC;構造 TP_LOCALLAB_STRUCCOL;スãƒãƒƒãƒˆã®æ§‹é€  TP_LOCALLAB_STRUCCOL1;スãƒãƒƒãƒˆã®æ§‹é€  -TP_LOCALLAB_STRUCT_TOOLTIP;形状検出ã«é–¢ã™ã‚‹æ§‹é€ ã‚’考慮ã™ã‚‹Sobelアルゴリズムを使ã„ã¾ã™.\n'マスクã¨ä¿®æ­£é ˜åŸŸ'を有効ã«ã—ã¦ã€ãƒžã‚¹ã‚¯ã®ãƒ—レビュー(変更ãªã—)を見るãŸã‚ã«'スãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示'を有効ã«ã—ã¾ã™\n\nエッジ検出ã®ç²¾åº¦ã‚’上ã’ã‚‹ãŸã‚ã€æ§‹é€ ãƒžã‚¹ã‚¯ã€ã¼ã‹ã—マスクã€ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆï¼ˆã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ï¼‰ã¨å…±ã«ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™\n\n明るã•ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã€è‰²åº¦ã€éœ²å…‰è£œæ­£ã€æˆ–ã„ã¯ãƒžã‚¹ã‚¯ã«é–¢ä¿‚ã—ãªã„機能を使ã£ãŸèª¿æ•´åŠ¹æžœã¯ã€'調整åŠã³ä¿®æ­£ã—ãŸç”»åƒ'ã€æˆ–ã„ã¯'修正ã•れãŸé ˜åŸŸã‚’マスクã¨å…±ã«è¡¨ç¤º'ã§ã€è¦‹ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ +TP_LOCALLAB_STRUCT_TOOLTIP;形状検出ã«é–¢ã™ã‚‹æ§‹é€ ã‚’考慮ã™ã‚‹Sobelアルゴリズムを使ã„ã¾ã™.\n'マスクã¨ä¿®æ­£'を有効ã«ã—ã¦ã€ãƒžã‚¹ã‚¯ã®ãƒ—レビュー(変更ãªã—)を見るãŸã‚ã«'スãƒãƒƒãƒˆã®æ§‹é€ ã‚’表示'を有効ã«ã—ã¾ã™\n\nエッジ検出ã®ç²¾åº¦ã‚’上ã’ã‚‹ãŸã‚ã€æ§‹é€ ãƒžã‚¹ã‚¯ã€ã¼ã‹ã—マスクã€ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆï¼ˆã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ï¼‰ã¨å…±ã«ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™\n\n明るã•ã€ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã€è‰²åº¦ã€éœ²å…‰è£œæ­£ã€æˆ–ã„ã¯ãƒžã‚¹ã‚¯ã«é–¢ä¿‚ã—ãªã„機能を使ã£ãŸèª¿æ•´åŠ¹æžœã¯ã€'修正ã•れãŸç”»åƒã‚’表示'ã€æˆ–ã„ã¯'修正ã•れãŸé ˜åŸŸã‚’マスクã¨å…±ã«è¡¨ç¤º'ã§ã€è¦‹ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ TP_LOCALLAB_STRUMASKCOL;構造マスクã®å¼·ã• -TP_LOCALLAB_STRUMASK_TOOLTIP;“機能ã¨ã—ã¦ã®æ§‹é€ ã®ãƒžã‚¹ã‚¯â€ã‚ªãƒ—ションを無効ã®ã¾ã¾ã§æ§‹é€ ã®ãƒžã‚¹ã‚¯ï¼ˆã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼‰ã‚’使ã†ï¼šã“ã®å ´åˆã€3ã¤ã®ã‚«ãƒ¼ãƒ–ãŒæ´»ç”¨ã•れã¦ã„ãªãã¦ã‚‚ã€æ§‹é€ ã‚’表示ã™ã‚‹ãƒžã‚¹ã‚¯ãŒç”Ÿæˆã•れã¾ã™ã€‚構造ã®ãƒžã‚¹ã‚¯ã¯ãƒžã‚¹ã‚¯1(ã¼ã‹ã—ã¨ãƒŽã‚¤ã‚ºé™¤åŽ»ï¼‰ã¨ãƒžã‚¹ã‚¯7ï¼ˆè‰²ã¨æ˜Žã‚‹ã•)ã§ä½¿ãˆã¾ã™ +TP_LOCALLAB_STRUMASK_TOOLTIP;“機能ã¨ã—ã¦ã®æ§‹é€ ã®ãƒžã‚¹ã‚¯â€ã‚ªãƒ—ションを無効ã®ã¾ã¾ã§æ§‹é€ ã®ãƒžã‚¹ã‚¯ï¼ˆã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼‰ã‚’使ã†ï¼šã“ã®å ´åˆã€3ã¤ã®ã‚«ãƒ¼ãƒ–ãŒæ´»ç”¨ã•れã¦ã„ãªãã¦ã‚‚ã€æ§‹é€ ã‚’表示ã™ã‚‹ãƒžã‚¹ã‚¯ãŒç”Ÿæˆã•れã¾ã™ã€‚構造ã®ãƒžã‚¹ã‚¯ã¯ãƒžã‚¹ã‚¯1(ã¼ã‹ã—&ノイズ)ã¨ãƒžã‚¹ã‚¯7ï¼ˆè‰²ã¨æ˜Žã‚‹ã•)ã§ä½¿ãˆã¾ã™ TP_LOCALLAB_STRUSTRMASK_TOOLTIP;ã“ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ã®èª¿æ•´ã¯æŽ§ãˆã‚ã«è¡Œã†ã“ã¨ã‚’奨ã‚ã¾ã™ TP_LOCALLAB_STYPE;スãƒãƒƒãƒˆã®å¤‰å½¢æ–¹æ³• TP_LOCALLAB_STYPE_TOOLTIP;2ã¤ã®ã‚¿ã‚¤ãƒ—ã‹ã‚‰é¸ã³ã¾ã™:\nシンメトリックã¯å·¦ã¨å³ã®å¢ƒç•Œç·šã€ä¸Šéƒ¨ã¨åº•部ã®å¢ƒç•Œç·šãŒãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™\n独立ã¯å…¨ã¦ã®å¢ƒç•Œç·šã‚’独立ã§å‹•ã‹ã™ã“ã¨ãŒå‡ºæ¥ã¾ã™ TP_LOCALLAB_SYM;シンメトリック(マウス) TP_LOCALLAB_SYMSL;シンメトリック(マウス + スライダー) TP_LOCALLAB_TARGET_GRAY;å¹³å‡è¼åº¦ï¼ˆYb%) +TP_LOCALLAB_TE_PIVOT;ピボット(Ev) TP_LOCALLAB_THRES;ã—ãã„å€¤ã®æ§‹é€  TP_LOCALLAB_THRESDELTAE;ΔE-スコープã®ã—ãã„値 TP_LOCALLAB_THRESRETI;ã—ãã„値 @@ -3355,17 +3624,18 @@ TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;マスクãŒã‚れã°ã€ãれを修正ã™ã‚‹ TP_LOCALLAB_TOOLMASK;マスクツール TP_LOCALLAB_TOOLMASK_2;ウェーブレット TP_LOCALLAB_TOOLMASK_TOOLTIP;'機能ã¨ã—ã¦ã®æ§‹é€ ã®ãƒžã‚¹ã‚¯'ã®ã‚ªãƒ—ションを有効ã«ã—ã¦ã€æ§‹é€ ãƒžã‚¹ã‚¯ï¼ˆã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼ï¼‰ã‚’使ã†ï¼šã“ã®å ´åˆã€æ§‹é€ ã‚’表示ã™ã‚‹ãƒžã‚¹ã‚¯ã¯ã€1回以上2ã¤ã®ã‚«ãƒ¼ãƒ–ã€L(L)或ã„ã¯LC(H)ãŒå¤‰æ›´ã•れãŸå¾Œã«ç”Ÿæˆã•れã¾ã™\nã“ã“ã§ã€'構造マスク'ã¯ä»–ã®ãƒžã‚¹ã‚¯ã®æ§˜ãªæ©Ÿèƒ½ã‚’æžœãŸã—ã¾ã™ï¼šã‚¬ãƒ³ãƒžã€ã‚¹ãƒ­ãƒ¼ãƒ—ãªã©\nç”»åƒã®æ§‹é€ ã«å¿œã˜ã¦ãƒžã‚¹ã‚¯ã®ä½œç”¨ã‚’変ãˆã‚‰ã‚Œã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã¯'ΔEç”»åƒã®ãƒžã‚¹ã‚¯'ã¨ä»˜éšã™ã‚‹'スコープ(Δâ€ç”»åƒã®ãƒžã‚¹ã‚¯ï¼‰'ã«æ•感ã«ä½œç”¨ã—ã¾ã™ -TP_LOCALLAB_TRANSIT;境界ã®éšŽèª¿èª¿æ•´ -TP_LOCALLAB_TRANSITGRAD;XY軸方å‘ã®å¢ƒç•Œã®å·®åˆ¥ -TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Y軸方å‘ã®ä½œç”¨ã®é ˜åŸŸã‚’変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ -TP_LOCALLAB_TRANSITVALUE;境界値 -TP_LOCALLAB_TRANSITWEAK;å¢ƒç•Œå€¤ã®æ¸›è¡°ï¼ˆç·šå½¢ï½žLog) -TP_LOCALLAB_TRANSITWEAK_TOOLTIP;å¢ƒç•Œå€¤ã®æ¸›è¡°ã‚’調節 : 処ç†ã®æ»‘らã‹ã•を変ãˆã‚‹ - 1 ç·šå½¢ - 2 パラボリック - 3~25ä¹—\néžå¸¸ã«ä½Žã„境界値ã¨ä½µã›ã‚Œã°ã€CBDLã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€è‰²ã¨æ˜Žã‚‹ã•を使ã£ãŸä¸è‰¯éƒ¨åˆ†ã®è£œæ­£ã«ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ -TP_LOCALLAB_TRANSIT_TOOLTIP;RT-スãƒãƒƒãƒˆã®ä¸­å¿ƒå††ã‹ã‚‰ãƒ•レームã®é–“ã§ä½œç”¨ãŒåƒã領域ã¨ä½œç”¨ãŒæ¸›è¡°ã™ã‚‹é ˜åŸŸã®å¢ƒç•Œã‚’ã€ä¸­å¿ƒå††ã‹ã‚‰ãƒ•レームã¾ã§ã®ï¼…ã§èª¿æ•´ã—ã¾ã™ +TP_LOCALLAB_TRANSIT;変移ã®éšŽèª¿ +TP_LOCALLAB_TRANSITGRAD;XY軸方å‘ã«ã‚ˆã‚‹å¤‰ç§»ã®å·®åˆ¥åŒ– +TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Y軸方å‘ã®ä½œç”¨ã®ç¯„囲を変ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ +TP_LOCALLAB_TRANSITVALUE;変移ã®ä½ç½® +TP_LOCALLAB_TRANSITWEAK;å¤‰ç§»ã®æ¸›è¡°ï¼ˆç·šå½¢ï½žLog) +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;å¤‰ç§»ã®æ¸›è¡°ã‚’調節 : 処ç†ã®æ»‘らã‹ã•を変ãˆã‚‹ - 1 ç·šå½¢ - 2 パラボリック - 3~25ä¹—\néžå¸¸ã«ä½Žã„変移ã®ä½ç½®ã¨ä½µã›ã‚Œã°ã€CBDLã€ã‚¦ã‚§ãƒ¼ãƒ–レットã€è‰²ã¨æ˜Žã‚‹ã•を使ã£ãŸä¸è‰¯éƒ¨åˆ†ã®è£œæ­£ã«ä½¿ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ +TP_LOCALLAB_TRANSIT_TOOLTIP;RT-スãƒãƒƒãƒˆã®ä¸­å¿ƒå††ã‹ã‚‰ãƒ•レームã®é–“ã§ä½œç”¨ãŒåƒã領域ã¨ä½œç”¨ãŒæ¸›è¡°ã™ã‚‹é ˜åŸŸã®å¤‰ç§»ã®ä½ç½®ã‚’ã€ä¸­å¿ƒå††ã‹ã‚‰ãƒ•レームã¾ã§ã®ï¼…ã§èª¿æ•´ã—ã¾ã™ TP_LOCALLAB_TRANSMISSIONGAIN;é€éŽã®ã‚²ã‚¤ãƒ³ TP_LOCALLAB_TRANSMISSIONMAP;é€éŽãƒžãƒƒãƒ— TP_LOCALLAB_TRANSMISSION_TOOLTIP;é€éŽã«å¿œã˜ã¦é€éŽã‚’決ã‚るカーブã§ã™\n横軸ã¯ãƒžã‚¤ãƒŠã‚¹å€¤ï¼ˆæœ€å°ï¼‰ã‹ã‚‰å¹³å‡å€¤ã€ãƒ—ラス値(最大)ã¾ã§ã‚りã¾ã™\n\nã“ã®ã‚«ãƒ¼ãƒ–を使ã£ã¦é€éŽã‚’変ãˆã€ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ァクトを軽減ã§ãã¾ã™ -TP_LOCALLAB_USEMASK;ãƒ©ãƒ—ãƒ©ã‚¹å¤‰æ› +TP_LOCALLAB_TRCFRAME;トーンリプロダクションカーブ & 中間トーン +TP_LOCALLAB_USEMASK;ラプラス作用素 TP_LOCALLAB_VART;分散(コントラスト) TP_LOCALLAB_VIBRANCE;自然ãªå½©åº¦ & ウォーム/クール TP_LOCALLAB_VIBRA_TOOLTIP;自然ãªå½©åº¦ã‚’調整ã™ã‚‹æ©Ÿèƒ½ã§ã™ï¼ˆåŸºæœ¬çš„ã«ã¯ãƒ¡ã‚¤ãƒ³ã®è‡ªç„¶ãªå½©åº¦ã¨åŒã˜ã§ã™ï¼‰\nCIECAMã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’使ã£ãŸãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹èª¿æ•´ã¨åŒç­‰ã®ä½œç”¨ã‚’ã—ã¾ã™ @@ -3401,11 +3671,11 @@ TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;X軸ã¯å³å´ã»ã©ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ TP_LOCALLAB_WAT_WAVTM_TOOLTIP;å„レベルã®åœ§ç¸®ã‚«ãƒ¼ãƒ–を中央より下ã’る(マイナス)ã¨ãƒˆãƒ¼ãƒ³ãƒžãƒƒãƒ”ングã®ã‚ˆã†ãªåŠ¹æžœã«ãªã‚Šã¾ã™ã€‚\n中央より上ã§ã¯ï¼ˆãƒ—ラス)ã€ãƒ¬ãƒ™ãƒ«ã®ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒæ¸›è¡°ã—ã¾ã™ã€‚\nX軸ã¯å·¦ã‹ã‚‰å³ã«å‘ã£ã¦ã€å¤§ããªãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã®ãƒ¬ãƒ™ãƒ«ã‚’表ã—ã¦ã„ã¾ã™ã€‚ TP_LOCALLAB_WAV;ローカルコントラスト TP_LOCALLAB_WAVBLUR_TOOLTIP;分解ã•れãŸå„レベルã€åŠã³æ®‹å·®ç”»åƒã«ã¼ã‹ã—ã‚’ã‹ã‘ã¾ã™ -TP_LOCALLAB_WAVCOMP;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹åœ§ç¸® -TP_LOCALLAB_WAVCOMPRE;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹åœ§ç¸® +TP_LOCALLAB_WAVCOMP;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã®åœ§ç¸® +TP_LOCALLAB_WAVCOMPRE;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã®åœ§ç¸® TP_LOCALLAB_WAVCOMPRE_TOOLTIP;トーンマッピングをé©ç”¨ã™ã‚‹ã€æˆ–ã„ã¯å„レベルã®ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’減らã™ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\nX軸ã¯å·¦ã‹ã‚‰å³ã«å‘ã£ã¦ã€å¤§ããªãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã®ãƒ¬ãƒ™ãƒ«ã‚’表ã—ã¦ã„ã¾ã™ã€‚ TP_LOCALLAB_WAVCOMP_TOOLTIP;ã‚¦ã‚§ãƒ¼ãƒ–ãƒ¬ãƒƒãƒˆåˆ†è§£ã®æ–¹å‘(水平ã€åž‚ç›´ã€æ–œã‚)をベースã«ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’é©ç”¨ã—ã¾ã™ã€‚ -TP_LOCALLAB_WAVCON;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ +TP_LOCALLAB_WAVCON;レベルã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´ TP_LOCALLAB_WAVCONTF_TOOLTIP;â€è©³ç´°ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆèª¿æ•´â€ã«ä¼¼ã¦ã„ã¾ã™ã€‚X軸ã®å³å´ã»ã©å¤§ãã„ディテールã®ãƒ¬ãƒ™ãƒ«ã‚’æ„味ã—ã¾ã™ã€‚ TP_LOCALLAB_WAVDEN;è¼åº¦ãƒŽã‚¤ã‚ºé™¤åŽ» TP_LOCALLAB_WAVE;ウェーブレット @@ -3414,7 +3684,7 @@ TP_LOCALLAB_WAVEEDG_TOOLTIP;エッジã«å¯¾ã™ã‚‹ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆ TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;’ローカルコントラスト’ã§ä½¿ã†ã‚¦ã‚§ãƒ¼ãƒ–レットã®ãƒ¬ãƒ™ãƒ«ã®ç¯„囲 TP_LOCALLAB_WAVGRAD_TOOLTIP;設定ã—ãŸéšŽèª¿ã¨è§’度ã«å¿œã˜ã¦ã€ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆãŒå¤‰ã‚るよã†ã«ã—ã¾ã™ã€‚è¼åº¦å€¤ã§ã¯ãªãã€è¼åº¦å€¤ã®å·®ã‚’考慮ã—ã¦ã„ã¾ã™ã€‚ TP_LOCALLAB_WAVHUE_TOOLTIP;色相ã«åŸºã¥ã„ã¦ãƒŽã‚¤ã‚ºé™¤åŽ»ã®å¼·å¼±ã‚’加減ã§ãã¾ã™ã€‚ -TP_LOCALLAB_WAVLEV;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã«ã‚ˆã‚‹ã¼ã‹ã— +TP_LOCALLAB_WAVLEV;ウェーブレットã®ãƒ¬ãƒ™ãƒ«ã®ã¼ã‹ã— TP_LOCALLAB_WAVMASK;ローカルコントラスト TP_LOCALLAB_WAVMASK_TOOLTIP;マスクã®ãƒ­ãƒ¼ã‚«ãƒ«ã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã‚’変ãˆã‚‹ãŸã‚ã«ã‚¦ã‚§ãƒ¼ãƒ–レットを使ã„ã€æ§‹é€ ï¼ˆè‚Œã€å»ºç‰©ãªã©ï¼‰ã‚’強化ã—ãŸã‚Šå¼±ã‚ãŸã‚Šã—ã¾ã™ TP_LOCALLAB_WEDIANHI;メディアン 高 @@ -3732,6 +4002,16 @@ TP_TM_FATTAL_AMOUNT;é‡ TP_TM_FATTAL_ANCHOR;アンカー TP_TM_FATTAL_LABEL;ダイナミックレンジ圧縮 TP_TM_FATTAL_THRESHOLD;ディテール +TP_TONE_EQUALIZER_BANDS;ãƒãƒ³ãƒ‰ +TP_TONE_EQUALIZER_BAND_0;ブラック +TP_TONE_EQUALIZER_BAND_1;シャドウ +TP_TONE_EQUALIZER_BAND_2;中間トーン +TP_TONE_EQUALIZER_BAND_3;ãƒã‚¤ãƒ©ã‚¤ãƒˆ +TP_TONE_EQUALIZER_BAND_4;ホワイト +TP_TONE_EQUALIZER_DETAIL;円滑化 +TP_TONE_EQUALIZER_LABEL;トーンイコライザ +TP_TONE_EQUALIZER_PIVOT;ピボット(Ev) +TP_TONE_EQUALIZER_SHOW_COLOR_MAP;トーンã®é…分を表示 TP_VIBRANCE_AVOIDCOLORSHIFT;色ãšã‚Œã‚’å›žé¿ TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;肌色トーン @@ -3983,7 +4263,7 @@ TP_WAVELET_STRENGTH;å¼·ã• TP_WAVELET_SUPE;エキストラ TP_WAVELET_THR;シャドウã®ã—ãã„値 TP_WAVELET_THRDEN_TOOLTIP;ローカルコントラストã«å¿œã˜ãŸãƒŽã‚¤ã‚ºé™¤åŽ»ã®ç›®å®‰ã«ä½¿ã†ãŸã‚ã€ã‚¹ãƒ†ãƒƒãƒ—カーブを作æˆã—ã¾ã™ã€‚ノイズ除去ãŒã‚³ãƒ³ãƒˆãƒ©ã‚¹ãƒˆã®ä½Žã„å‡ä¸€ãªç”»è³ªéƒ¨åˆ†ã«é©ç”¨ã•れã¾ã™ã€‚詳細ãŒã‚る部分(コントラストãŒé«˜ã„)ã¯ä¿æŒã•れã¾ã™ã€‚ -TP_WAVELET_THREND;ローカルコントラストã®ã—ãã„値 +TP_WAVELET_THREND;ローカルコントラストã®ã—ãã„値 TP_WAVELET_THRESHOLD;調整レベル(å°ã•ã„ディテール) TP_WAVELET_THRESHOLD2;調整レベル(大ãã„ディテール) TP_WAVELET_THRESHOLD2_TOOLTIP;設定値より上ã®ãƒ¬ãƒ™ãƒ«ã ã‘ãŒã€å¤§ããªãƒ‡ã‚£ãƒ†ãƒ¼ãƒ«ã®ãƒ¬ãƒ™ãƒ«ã®è¼åº¦ç¯„囲ã§è¨­å®šã•ã‚ŒãŸæ¡ä»¶ã§èª¿æ•´ã•れã¾ã™ã€‚ @@ -4035,6 +4315,45 @@ TP_WBALANCE_FLUO_HEADER;è›å…‰ç¯ TP_WBALANCE_GREEN;色åå·® TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI +TP_WBALANCE_ITCWALG_TOOLTIP;å¯èƒ½ã§ã‚れã°ã€åˆ¥ãªä»£æ›¿ãˆè‰²æ¸©åº¦ã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚\n“å˜ä¸€ã®é¸æŠžâ€ã®å ´åˆã¯å‡ºæ¥ã¾ã›ã‚“。 +TP_WBALANCE_ITCWBDELTA_TOOLTIP;“色åå·®â€ã®ç¹°ã‚Šè¿”ã—計算ã®éš›ã«å›ºå®šã•れã¾ã™ã€‚色温度ã®é•ã„ã¯è€ƒæ…®ã•れã¾ã™ã€‚ +TP_WBALANCE_ITCWBFGREEN_TOOLTIP;スãƒãƒ¥ãƒ¼ãƒ‡ãƒ³ãƒˆã®æ¤œå®šçµæžœã¨è‰²ç·¨é–“ã®æœ€è‰¯ã®å¦¥å”点を探りã¾ã™ã€‚ +TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;最å°ãƒ‘ッãƒã®å€¤ã®è¨­å®šãŒå¯èƒ½ã§ã™ã€‚設定値ãŒå°ã•éŽãŽã‚‹ã¨ç›¸é–¢é–¢ä¿‚ã®æ¬ å¦‚ã«ã¤ãªãŒã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚ +TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;マゼンタ/パープルã®è‰²ãƒ‡ãƒ¼ã‚¿ã‚’ç”»åƒã‹ã‚‰å–り除ãã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã¨ã€Y値を制é™ã™ã‚‹ãƒ•ィルタãŒé©ç”¨ã•れã¾ã™ã€‚デフォルトã§ã¯ã“ã®å€¤ãŒ0.4ã«è¨­å®šã•れã¦ã„ã¾ã™ã€‚変更ã¯â€˜ã‚ªãƒ—ション‘ファイルã®â€˜Itcwb Ypurple‘(最大値1)ã§è¡Œã„ã¾ã™ã€‚ +TP_WBALANCE_ITCWBPRECIS_TOOLTIP;値ãŒä½Žã„ã»ã©å‡¦ç†ã«ä¿‚るデータãŒå¢—ãˆå‡¦ç†æ™‚é–“ãŒé•·ããªã‚Šã¾ã™ãŒã€å…ƒã€…å‡¦ç†æ™‚é–“ã¯çŸ­ã„ã®ã§ã€æ™®é€šã¯ãƒ‡ãƒ•ォルトã§è¨­å®šã•れã¦ã„る低ã„è¨­å®šå€¤ã§æ§‹ã‚ãªã„ã§ã—ょã†ã€‚ +TP_WBALANCE_ITCWBRGREEN_TOOLTIP;繰り返ã—計算ã«ãŠã‘る色å差値ã®è©•価ã®å¹…ã§ã™ã€‚低幅ã®å ´åˆã¯0.82ã‹ã‚‰1.25ã€æœ€å¤§å¹…ã¯0.4ã‹ã‚‰4.0ã«ãªã‚Šã¾ã™ã€‚ +TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;アルゴリズムãŒä½¿ç”¨ã™ã‚‹ã‚«ãƒ©ãƒ¼ãƒ‡ãƒ¼ã‚¿ã®å¤§ãã•を設定ã™ã‚‹ã‚‚ã®ã§ã™ã€‚ +TP_WBALANCE_ITCWBSIZE_TOOLTIP;å‚考スペクトルカラーã¨ç”»åƒã®è‰²ã®xyY値ã¨ã®é–“ã§æœ€è‰¯ã®å¯¾å¿œã‚’探るãŸã‚ã®ç¹°ã‚Šè¿”ã—計算ã®å›žæ•°ã‚’設定ã—ã¾ã™ã€‚設定値3ãŒç¨‹å¥½ã„妥å”ç‚¹ã¨æ€ã‚れã¾ã™ã€‚ +TP_WBALANCE_ITCWBTHRES_TOOLTIP;スペクトルデータã¨ç”»åƒãƒ‡ãƒ¼ã‚¿ã®é–“ã®æ¯”較ã®ã‚µãƒ³ãƒ—リングを制é™ã—ã¾ã™ã€‚ +TP_WBALANCE_ITCWB_ALG;2工程アルゴリズムを除外 +TP_WBALANCE_ITCWB_CUSTOM;独自ã®è‰²æ¸©åº¦ã¨è‰²å差を使用 +TP_WBALANCE_ITCWB_DELTA;色åå·®ã®ãƒ«ãƒ¼ãƒ—ã«ãŠã‘るΔ色温度 +TP_WBALANCE_ITCWB_FGREEN;色åå·®ã®ã‚¹ãƒãƒ¥ãƒ¼ãƒ‡ãƒ³ãƒˆæ¤œå®šã‚’探㙠+TP_WBALANCE_ITCWB_FORCED;CIEãƒ€ã‚¤ãƒ¤ã‚°ãƒ©ãƒ ã¨æ¦‚ã­åŒã˜ç¯„囲 +TP_WBALANCE_ITCWB_FRA;自動色温度相関関係ã®è¨­å®š +TP_WBALANCE_ITCWB_FRA_TOOLTIP;ç”»åƒï¼ˆrawã®å½¢å¼ã€æ¸¬è‰²ãªã©ï¼‰ã«å¿œã˜ã¦ã€ã“れらã®è¨­å®šã§â€˜è‰²æ¸©åº¦ã®ç›¸é–¢é–¢ä¿‚‘アルゴリズムã®é©å¿œã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚最良ã®çµæžœã‚’å¾—ã‚‹ãŸã‚ã®ãƒ‘ラメータ調整ã«ç‰¹åˆ¥ãªæ³•則ã¯ã‚りã¾ã›ã‚“。 +TP_WBALANCE_ITCWB_MINSIZEPATCH;最å°ã®ãƒ‘ッãƒã‚µã‚¤ã‚º +TP_WBALANCE_ITCWB_NOPURPLE;パープルã®ãƒ•ィルタ +TP_WBALANCE_ITCWB_PRECIS;精度ã®é«˜ã„アルゴリズム - スケールを使用 +TP_WBALANCE_ITCWB_PRIM_ACE;CIEダイヤグラム全体を使ã†ã“ã¨ã‚’強制ã™ã‚‹ +TP_WBALANCE_ITCWB_PRIM_ADOB;ミディアムサンプリング +TP_WBALANCE_ITCWB_PRIM_BETA;ミディアムサンプリング - ãƒã‚¤ãƒ³ã‚¿ãƒ¼ã‚“色域ã«è¿‘ã„ +TP_WBALANCE_ITCWB_PRIM_JDCMAX;完全ãªCIEダイヤグラムã«è¿‘ã„ +TP_WBALANCE_ITCWB_PRIM_REC;ãƒã‚¤ã‚µãƒ³ãƒ—リング +TP_WBALANCE_ITCWB_PRIM_SRGB;ローサンプリングを使用ã€ã‚«ãƒ¡ãƒ©ã®è¨­å®šã‚’無視ã™ã‚‹ +TP_WBALANCE_ITCWB_PRIM_XYZCAM;カメラã®XYZマトリクス +TP_WBALANCE_ITCWB_PRIM_XYZCAM2;カメラã®XYZマトリクス後ã®JDCmax +TP_WBALANCE_ITCWB_RGREEN;色åå·®ã®ç¯„囲 +TP_WBALANCE_ITCWB_SAMPLING;ローサンプリング 5.9 +TP_WBALANCE_ITCWB_SIZE;ãƒ’ã‚¹ãƒˆã‚°ãƒ©ãƒ ã¨æ¯”較ã—ãŸå‚考色ã®å¤§ãã• +TP_WBALANCE_ITCWB_SIZEPATCH;カラーパッãƒã®å¤§ãã• +TP_WBALANCE_ITCWB_THRES;ç”»åƒã«ä½¿ã‚れã¦ã„る色(プリセット) +TP_WBALANCE_ITCWCUSTOM_TOOLTIP;色温度ã¨è‰²åå·®ã®ç‹¬è‡ªè¨­å®šãŒå¯èƒ½ã§ã™ã€‚\n\n 利用ã®ãŸã‚ã®ãƒ’ント:\n 1)Itcwbã‚’é¸æŠžã—ã€â€˜ç‹¬è‡ªã®è‰²æ¸©åº¦ã¨è‰²å差‘有効ã«ã™ã‚‹ã€‚\n 2)好ã¿ã®è‰²æ¸©åº¦ã¨è‰²å差を設定:自由ã€ãƒ”ック。。。(独自)\n 3)‘色温度ã®ç›¸é–¢é–¢ä¿‚â€˜ã«æˆ»ã‚‹ã€‚\n\n ã“れを使用ã™ã‚‹å ´åˆã¯ã€ï¼’工程ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã€è‡ªå‹•色温度ãƒã‚¤ã‚¢ã‚¹ã€è‰²åå·®ã®å¾®èª¿æ•´ã¯ä½¿ãˆã¾ã›ã‚“。 +TP_WBALANCE_ITCWFORCED_TOOLTIP;デフォルトã§ã¯ï¼ˆãƒœãƒƒã‚¯ã‚¹ã«ãƒã‚§ãƒƒã‚¯ãŒå…¥ã£ã¦ã„ãªã„状態)ã€ã‚µãƒ³ãƒ—リングã®éš›ã«ã‚¹ã‚­ãƒ£ãƒ³ã•れãŸãƒ‡ãƒ¼ã‚¿ã¯ã€DCPã®ã‚­ãƒ£ãƒªãƒ–レーションã€ICCプロファイルã€ã‚«ãƒ©ãƒ¼ãƒã‚§ãƒƒã‚«ãƒ¼24ã€ã‚¦ã‚§ãƒ–サイトãªã©ã«å¹…広ã使ã‚れるsRGBãƒ—ãƒ­ãƒ•ã‚¡ã‚¤ãƒ«ã«æˆ»ã•れã¾ã™ã€‚\n 色域ãŒéžå¸¸ã«åºƒã„ç”»åƒï¼ˆèŠ±ã‚„äººå£è‰²ï¼‰ã®å ´åˆã€CIExyダイヤグラム全体を使ã†å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。ãã®å ´åˆã¯ãƒ—ロファイルã«ACESP0ãŒä½¿ã‚れるã§ã—ょã†ã€‚後者ã®ã‚±ãƒ¼ã‚¹ã§ã¯ã€ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã«å¯¾ã—内部ã§ä½¿ã‚ã‚Œã‚‹è‰²ã®æ•°ãŒã‚ˆã‚Šé‡è¦ã«ãªã‚Šã¾ã™ã€‚ +TP_WBALANCE_ITCWGREEN;色åå·®ã®å¾®èª¿æ•´ +TP_WBALANCE_ITCWGREEN_TOOLTIP;ã“ã®æ©Ÿèƒ½ã¯ã€ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã‚’スタートã•ã›ã‚‹éš›ã®å‚考地ã¨ãªã‚‹â€œè‰²åå·®â€ã®å¤‰æ›´ã‚’å¯èƒ½ã«ã™ã‚‹ã‚‚ã®ã§ã™ã€‚“自動ホワイトãƒãƒ©ãƒ³ã‚¹ã®è‰²æ¸©åº¦ã€€ãƒã‚¤ã‚¢ã‚¹â€ã¨ã»ã¼åŒã˜åƒãを色編ã«å¯¾ã—ã¦åŠã¼ã—ã¾ã™ã€‚\n 変更を行ã†ã¨ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã¯è¨ˆç®—を最åˆã‹ã‚‰ã‚„り直ã—ã¾ã™ã€‚ +TP_WBALANCE_ITCWPRIM_TOOLTIP;ç”»åƒã‚µãƒ³ãƒ—リングã®é¸æŠžãŒå‡ºæ¥ã¾ã™ã€‚\n ‘CIEダイヤグラムã«è¿‘ã„サンプリング‘ ã“れã¯ã‚«ãƒ¡ãƒ©ã®æ’®åƒã‚»ãƒ³ã‚µãƒ¼ãŒæ‰ãˆãŸãƒ‡ãƒ¼ã‚¿ã®æ®†ã©ã‚’対象ã¨ã—ã¾ã™ãŒã€æƒ³åƒä¸Šã®è‰²ãŒå«ã¾ã‚Œã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n ‘カメラã®XYZマトリクス‘ カラーマトリクスã‹ã‚‰ç›´æŽ¥çš„ã«å°Žã„ãŸãƒžãƒˆãƒªã‚¯ã‚¹ã§ã™ã€‚\n ミディアムサンプリング(デフォル)â€ãƒã‚¤ãƒ³ã‚¿ãƒ¼ã®è‰²åŸŸã«è¿‘ã„ã‚‚ã®ã§ã™ï¼šäººé–“ã®è¦–覚ã«éžå¸¸ã«è¿‘ã„色域ã§ã™ã€‚\n 他ã«ã‚‚‘ローサンプリング‘ã¨â€˜ã‚«ãƒ¡ãƒ©ã®è¨­å®šã‚’無視‘ã¨ã„ã†é¸æŠžè‚¢ãŒã‚りã¾ã™ã€‚ã“れらã¯ç”»åƒã®è‰²åº¦ãŒé«˜ã„部分を計算ã«å…¥ã‚Œãªã„ã€ã¾ãŸã¯è‰²åå·®ãŒ0.8より大ãã„å ´åˆã«ã€ã‚«ãƒ¡ãƒ©ã®è¨­å®šã‚’無視ã—ã¾ã™ã®ã§ã€çµæžœã«ãれãªã‚Šã®å½±éŸ¿ã å‡ºã¾ã™ã€‚\n\nã“れらサンプリングã¯ãƒãƒ£ãƒ³ãƒãƒ«ä¹—æ•°ã ã‘ã«å½±éŸ¿ã™ã‚‹ã‚‚ã®ã§ã€â€˜ä½œæ¥­ãƒ—ロファイル‘ã«ã¯å½±éŸ¿ã›ãšã€ç”»åƒã®è‰²åŸŸã‚’変ãˆã‚‹ã“ã¨ã‚‚ã‚りã¾ã›ã‚“。 +TP_WBALANCE_ITCWSAMPLING_TOOLTIP;ãƒãƒ¼ã‚¸ãƒ§ãƒ³5.9ã¨ã®äº’æ›æ€§ãŒè‰¯ã„å¤ã„サンプリングアルゴリズムを使ã†ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚標準観測者10°ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã¯æœ‰åйã«ã—ã¦ãŠãã¾ã™ï¼ˆãƒ‡ãƒ•ォルト)。 TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;ホワイトãƒãƒ©ãƒ³ã‚¹ TP_WBALANCE_LAMP_HEADER;ランプ @@ -4042,6 +4361,14 @@ TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 TP_WBALANCE_LED_HEADER;LED TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;æ–¹å¼ +TP_WBALANCE_MULLABEL;ä¹—æ•°: レッド=%1 グリーン=%2 ブルー=%3 +TP_WBALANCE_MULLABEL_TOOLTIP;ä¹—æ•°ã¯æƒ…å ±ã¨ã—ã¦è¡¨ç¤ºã•れるã ã‘ã§ã€å¤‰æ›´ã¯å‡ºæ¥ã¾ã›ã‚“。 +TP_WBALANCE_OBSERVER10;標準観測者2°ã®ä»£ã‚ã‚Šã«æ¨™æº–観測者10°を使用 +TP_WBALANCE_OBSERVER10_TOOLTIP;RawTherapeeã®ã‚«ãƒ©ãƒ¼ãƒžãƒã‚¸ãƒ¡ãƒ³ãƒˆï¼ˆãƒ›ãƒ¯ã‚¤ãƒˆãƒãƒ©ãƒ³ã‚¹ã€ãƒãƒ£ãƒ³ãƒãƒ«ä¹—æ•°ã€ãƒã‚¤ãƒ©ã‚¤ãƒˆå¾©å…ƒã€‚。。)ã§ã¯ã€å…‰æºã‚„色ã®ã‚¹ãƒšã‚¯ãƒˆãƒ«ãƒ‡ãƒ¼ã‚¿ã‚’使ã£ã¦ã„ã¾ã™ã€‚ç›®ã®çŸ¥è¦šè§’度を考慮ã™ã‚‹æ¨™æº–観測者ã¯ã€ã‚«ãƒ©ãƒ¼ãƒžãƒã‚¸ãƒ¡ãƒ³ãƒˆã®é‡è¦ãªå¤‰æ•°ã®ä¸€ã¤ã§ã™ã€‚1931å¹´ã€ãã®è§’度ã¯2°ã«å›ºå®šã•れã¾ã—ãŸãŒï¼ˆç›®ã®éŒä½“を優先)ã€1964å¹´ã«ãªã‚‹ã¨10°(éŒä½“ãŒå„ªå…ˆã•れるãŒã€æ¡¿ä½“も部分的ã«è€ƒæ…®ã™ã‚‹ï¼‰ãŒä½¿ã‚れるよã†ã«ãªã‚Šã¾ã—ãŸã€‚\n稀ã«â€æ¨™æº–観測者2°ã§è‰²ãšã‚ŒãŒç”Ÿã˜ãŸæ™‚ã¯ï¼ˆæã‚‰ã変æ›ãƒžãƒˆãƒªã‚¯ã‚¹ã«èµ·å› ã™ã‚‹ï¼‰ã€â€æ¨™æº–観測者10°â€ã«åˆ‡ã‚Šæ›¿ãˆã¦ä¸‹ã•ã„。 +TP_WBALANCE_PATCHLABEL;色ã®èª­ã¿è¾¼ã¿=%1 色ã®ãƒ‘ッãƒ=%2 サイズ=%3 +TP_WBALANCE_PATCHLABEL_TOOLTIP;読ã¿è¾¼ã‚“ã è‰²ã®æ•°ã‚’表示ã—ã¾ã™ï¼ˆæœ€å¤§237個)。\n 算出ã•れãŸãƒ‘ッãƒã®è‰²åº¦ã‚’表示ã—ã¾ã™ã€‚\n 自動ホワイトãƒãƒ©ãƒ³ã‚¹ã®è‰²æ¸©åº¦ãƒã‚¤ã‚¢ã‚¹ã®å€¤ã‚’下ã’ã¦ã¿ã¦ä¸‹ã•ã„。最低値を設定ã™ã‚‹ã¨ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ãŒæœ€é©ã«ãªã‚‹ã‚ˆã†ã§ã™ã€‚\n パッãƒã‚µã‚¤ã‚ºã¯è‰²åº¦ã®æœ€é©åŒ–ã«ã¤ãªãŒã‚Šã¾ã™ã€‚ +TP_WBALANCE_PATCHLEVELLABEL;パッãƒ: ΔE=%1 - データ x 9 最å°å€¤ï¼%2 最大値=%3 +TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;ç”»åƒã¨ã‚¹ãƒšã‚¯ãƒˆãƒ«ãƒ‡ãƒ¼ã‚¿é–“ã®Î”Eパッãƒï¼ˆå分ãªã‚¹ãƒšã‚¯ãƒˆãƒ«ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚‹ã¨ã„ã†å‰æã§ï¼‰ã‚’表示ã—ã¾ã™ã€‚\n 見ã¤ã‘ãŸãƒ‡ãƒ¼ã‚¿ã‚’表示ã—ã¾ã™ã€‚ã“れら2ã¤ã®å€¤ã¯ãれãžã‚Œè€ƒæ…®ã•れる最å°å€¤ã¨æœ€å¤§å€¤ã‚’示ã—ã¦ã„ã¾ã™ã€‚ç”»åƒã®é–¢ä¿‚ã™ã‚‹ãƒ”クセル数を得るãŸã‚ã«ã€ä¿‚æ•°xï¼™ã®å€¤ã¯è€ƒæ…®ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“。 TP_WBALANCE_PICKER;ピック TP_WBALANCE_SHADE;日陰 TP_WBALANCE_SIZE;サイズ: @@ -4050,8 +4377,9 @@ TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SOLUX47;Solux 4700K (vendor) TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;ピペットを使ã£ã¦ãƒ—レビュー画åƒã®ãƒ‹ãƒ¥ãƒ¼ãƒˆãƒ©ãƒ«ãªéƒ¨åˆ†ã‚’ピックアップ -TP_WBALANCE_STUDLABEL;t検定 Itcwb: %1 -TP_WBALANCE_STUDLABEL_TOOLTIP;t検定ã®çµæžœã‚’表示\n低ã„値ã»ã©ç›¸é–¢é–¢ä¿‚ãŒè‰¯ã„ã“ã¨ã«ãªã‚Šã¾ã™\n値ãŒ0.002以下ã¯ã‚¨ã‚¯ã‚»ãƒ¬ãƒ³ãƒˆ\n0.005以下ã¯éžå¸¸ã«è‰¯ã„\n0.01以下ã¯è‰¯ã„\n0.05以下ã¯å分\n0.5ä»¥ä¸Šã¯æ‚ªã„\nå…‰æºãŒæ¨™æº–çš„ã§ã¯ãªã„å ´åˆã¯ã€t検定ãŒè‰¯å¥½ã§ã‚ã£ã¦ã‚‚ホワイトãƒãƒ©ã‚¹ãŒè‰¯ã„ã“ã¨ã«ã¯ãªã‚Šã¾ã›ã‚“\ntæ¤œå®šçµæžœãŒ1000ã¨è¡¨ç¤ºã•れãŸå ´åˆã¯å復解æžãŒè¡Œã‚れãªã‹ã£ãŸã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚良ã„çµæžœã¨æƒ³å®šã•れるå‰ã®è¨ˆç®—çµæžœãŒä½¿ã‚れã¾ã™ +TP_WBALANCE_STUDLABEL;相関関係:%1 工程:%2 悪ã„入れ替ãˆï¼š%3 +TP_WBALANCE_STUDLABEL1;相関関係:%1 工程:%2 最é©ãªå…¥ã‚Œæ›¿ãˆï¼š%3 +TP_WBALANCE_STUDLABEL_TOOLTIP;t検定ã®çµæžœã‚’表示\n低ã„値ã»ã©ç›¸é–¢é–¢ä¿‚ãŒè‰¯ã„ã“ã¨ã«ãªã‚Šã¾ã™\n値ãŒ0.002以下ã¯ã‚¨ã‚¯ã‚»ãƒ¬ãƒ³ãƒˆ\n0.005以下ã¯éžå¸¸ã«è‰¯ã„\n0.01以下ã¯è‰¯ã„\n0.05以下ã¯å分\n0.5ä»¥ä¸Šã¯æ‚ªã„\nå…‰æºãŒæ¨™æº–çš„ã§ã¯ãªã„å ´åˆã¯ã€t検定ãŒè‰¯å¥½ã§ã‚ã£ã¦ã‚‚ホワイトãƒãƒ©ã‚¹ãŒè‰¯ã„ã“ã¨ã«ã¯ãªã‚Šã¾ã›ã‚“\ntæ¤œå®šçµæžœãŒ1000ã¨è¡¨ç¤ºã•れãŸå ´åˆã¯å復解æžãŒè¡Œã‚れãªã‹ã£ãŸã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚良ã„çµæžœã¨æƒ³å®šã•れるå‰ã®è¨ˆç®—çµæžœãŒä½¿ã‚れã¾ã™ TP_WBALANCE_TEMPBIAS;自動ホワイトãƒãƒ©ãƒ³ã‚¹ã€€è‰²æ¸©åº¦ã®ãƒã‚¤ã‚¢ã‚¹ TP_WBALANCE_TEMPBIAS_TOOLTIP;'自動ホワイトãƒãƒ©ãƒ³ã‚¹ã®è¨ˆç®—ã«å¤‰æ›´ã‚’加ãˆã¾ã™'\n色温度を変ãˆã‚‹ã“ã¨ã§ç”»åƒã®æš–ã‹ã¿ã‚’増やã—ãŸã‚Šã€å†·ãŸã•を増やã—ãŸã‚Šã—ã¾ã™ã€‚\nåå‘ã®åº¦åˆã„ã¯è‰²æ¸©åº¦ã®å‰²åˆã§è¡¨ç¤ºã•れã¾ã™\n従ã£ã¦è¨ˆç®—値㯠"算出ã—ãŸè‰²æ¸©åº¦ + 算出ã—ãŸè‰²æ¸©åº¦ * åå‘"ã§è¨ˆç®—ã—ãŸã‚‚ã®ã§ã™ TP_WBALANCE_TEMPERATURE;色温度 @@ -4071,177 +4399,6 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!EXIFFILTER_PATH;File path -!EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags -!EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags -!EXIFPANEL_BASIC_GROUP;Basic -!EXIFPANEL_VALUE_NOT_SHOWN;Not shown -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!GENERAL_OTHER;Other -!HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness -!HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata -!HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell -!HISTORY_MSG_HLTH;Inpaint opposed - gain threshold -!HISTORY_MSG_ICM_GAMUT;Gamut control -!HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -!HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift -!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!HISTORY_MSG_TONE_EQUALIZER_BANDS;Tone equalizer - Bands -!HISTORY_MSG_TONE_EQUALIZER_ENABLED;Tone equalizer -!HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot -!HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization -!HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map -!HISTORY_MSG_WBALANCE_OBSERVER10;Observer 10° -!HISTORY_MSG_WBITC_CUSTOM;Itcwb Custom -!HISTORY_MSG_WBITC_DELTA;Itcwb Delta green -!HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student -!HISTORY_MSG_WBITC_FORCE;Itcwb Force -!HISTORY_MSG_WBITC_GREEN;Green refinement -!HISTORY_MSG_WBITC_MINSIZE;Patch min size -!HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple -!HISTORY_MSG_WBITC_OBS;Remove algo 2 passes -!HISTORY_MSG_WBITC_PONDER;Itcwb ponderated -!HISTORY_MSG_WBITC_PRECIS;Itcwb Precision -!HISTORY_MSG_WBITC_PRIM;Primaries -!HISTORY_MSG_WBITC_RGREEN;Itcwb Green range -!HISTORY_MSG_WBITC_SAMPLING;Low sampling -!HISTORY_MSG_WBITC_SIZE;Itcwb Size -!HISTORY_MSG_WBITC_SORTED;Itcwb ponderated -!HISTORY_MSG_WBITC_THRES;Itcwb Threshold -!PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory -!PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application -!PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable -!PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Command -!PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Name -!PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Native command -!PREFERENCES_LENSFUNDBDIR;Lensfun database directory -!PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. -!PREFERENCES_LENSPROFILESDIR;Lens profiles directory -!PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) -!PREFERENCES_METADATA;Metadata -!PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars -!PREFERENCES_METADATA_SYNC_NONE;Off -!PREFERENCES_METADATA_SYNC_READ;Read only -!PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_TAB_FAVORITES;Favorites -!PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations -!PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. -!PREFERENCES_TOOLPANEL_FAVORITE;Favorite -!PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel -!PREFERENCES_TOOLPANEL_TOOL;Tool -!PREFERENCES_WBA;White Balance -!PREFERENCES_WBACORR;White Balance - Automatic temperature correlation -!PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -!PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings -!PREFERENCES_WBAENACUSTOM;Use Custom temperature & tint -!PREFERENCES_WBAFORC;Forces Extra algoritm -!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) -!PREFERENCES_WBANOPURP;No purple color used -!PREFERENCES_WBAPATCH;Number maximum of colors used in picture -!PREFERENCES_WBAPRECIS;Precision algorithm - scale used -!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color -!PREFERENCES_WBASORT;Sort in chroma order instead of histogram -!PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style -!PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) -!PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) -!SAVEDLG_BIGTIFF;BigTIFF (no metadata support) -!SORT_ASCENDING;Ascending -!SORT_BY_DATE;By Date -!SORT_BY_EXIF;By EXIF -!SORT_BY_LABEL;By Color Label -!SORT_BY_NAME;By Name -!SORT_BY_RANK;By Rank -!SORT_DESCENDING;Descending -!TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing -!TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness -!TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images. -!TP_FILMNEGATIVE_PICK_SIZE;Size: -!TP_FILMNEGATIVE_REF_SIZE;Size: -!TP_FLATFIELD_FROMMETADATA;From Metadata -!TP_HLREC_COLOROPP;Inpaint Opposed -!TP_HLREC_HLTH;Gain threshold -!TP_ICM_GAMUT;Gamut control -!TP_ICM_WORKING_PRIM_JDCMAX;JDC Max -!TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance -!TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance -!TP_LOCALLAB_FATSAT;Saturation control -!TP_LOCALLAB_GAMUTLABRELA;Lab -!TP_LOCALLAB_GAMUTMUNSELL;Munsell only -!TP_LOCALLAB_GAMUTNON;None -!TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute -!TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative -!TP_LOCALLAB_LCLABELS;Residual noise levels -!TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. -!TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 -!TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 -!TP_LOCALLAB_TE_PIVOT;Pivot (Ev) !TP_NEUTRAL_TOOLTIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. -!TP_TONE_EQUALIZER_BANDS;Bands -!TP_TONE_EQUALIZER_BAND_0;Blacks -!TP_TONE_EQUALIZER_BAND_1;Shadows -!TP_TONE_EQUALIZER_BAND_2;Midtones -!TP_TONE_EQUALIZER_BAND_3;Highlights -!TP_TONE_EQUALIZER_BAND_4;Whites -!TP_TONE_EQUALIZER_DETAIL;Regularization -!TP_TONE_EQUALIZER_LABEL;Tone Equalizer -!TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) -!TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map -!TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. -!TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. -!TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. -!TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Allows you to set the minimum patch value. values that are too low can lead to a lack of correlation. -!TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Allows you to filter magenta/purple data from the image. If the box is checked a filter limiting the value of Y is applied. By default this value is 0.4. You can change it in 'options' Itcwb_Ypurple (Maximum 1) -!TP_WBALANCE_ITCWBPRECIS_TOOLTIP;The lower the value, the more relevant the data, but increases the processing time. Since the processing time is low, this parameter should generally be able to remain at the default value -!TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Sets the green value review amplitude in iterations, from low amplitude 0.82 to 1.25 to maximum amplitude 0.4 to 4. -!TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;This setting sets the size of color datas used by algorithm. -!TP_WBALANCE_ITCWBSIZE_TOOLTIP;This setting sets the number of iterations to find the best correspondence between the reference spectral colors and those in xyY value of the image. A value of 3 seams a good compromise. -!TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. -!TP_WBALANCE_ITCWB_ALG;Remove 2 pass algorithm -!TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint -!TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop -!TP_WBALANCE_ITCWB_FGREEN;Find green student -!TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram -!TP_WBALANCE_ITCWB_FRA;Auto temperature correlation settings -!TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. -!TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimum size -!TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple color -!TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used -!TP_WBALANCE_ITCWB_PRIM_ACE;Forces use of the entire CIE diagram -!TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling -!TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - near Pointer's gamut -!TP_WBALANCE_ITCWB_PRIM_JDCMAX;Close to full CIE diagram -!TP_WBALANCE_ITCWB_PRIM_REC;High sampling -!TP_WBALANCE_ITCWB_PRIM_SRGB;Low sampling & Ignore Camera settings -!TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ matrix -!TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax after Camera XYZ matrix -!TP_WBALANCE_ITCWB_RGREEN;Green range -!TP_WBALANCE_ITCWB_SAMPLING;Low sampling 5.9 -!TP_WBALANCE_ITCWB_SIZE;Size of ref. color compare to histogram -!TP_WBALANCE_ITCWB_SIZEPATCH;Size of color patch -!TP_WBALANCE_ITCWB_THRES;Colors used in picture (preset) -!TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and Green (tint).\n\nUsage tips:\n1) start Itcwb , enable 'Use Custom temperature and tint'.\n2) Set 'Temperature and tint' to your liking :free, Pick,...(Custom)\n3) go back to 'Temperature correlation'.\n\nYou cannot use : 2 passes, AWB temperature bias, Green refinement. -!TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. -!TP_WBALANCE_ITCWGREEN;Green refinement -!TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. -!TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). -!TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 -!TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. -!TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. -!TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 -!TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. -!TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 -!TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Display ΔE patch (this assumes there is enough spectral data), between image and spectral datas.\n Display read datas found. The 2 values correspond to the minimum and maximum data values taken into account. The coefficient x9 must be taken into account to obtain the number of pixels concerned in the image. -!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 -!TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 !//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. !//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram From 0d9bafdc887b4fe90c99ad0bff4687776468ebc0 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sat, 30 Mar 2024 17:05:11 +0100 Subject: [PATCH 220/291] dcraw: add panasonic v8 decoder. Port panasonic v8 decoder from libraw. * Extract data required for the decoder from the panasonic custom exif tags * Add panasonic v8 decoder --- rtengine/dcraw.cc | 125 ++++++++- rtengine/dcraw.h | 38 ++- rtengine/panasonic_decoders.cc | 486 ++++++++++++++++++++++++++++++++- 3 files changed, 630 insertions(+), 19 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 6a9674faa..2b2d36013 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6458,16 +6458,123 @@ int CLASS parse_tiff_ifd (int base) FORC3 cam_mul[c] = get2(); break; case 45: - if (pana_raw && len == 1 && type == 3) - { - RT_pana_info.encoding = get2(); - } - break; + if (pana_raw && len == 1 && type == 3) { + RT_pana_info.encoding = get2(); + } + break; case 46: - if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; - thumb_offset = ftell(ifp) - 2; - thumb_length = len; - break; + if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + case 57: + if (pana_raw && len == 26 && type == 7) { + ushort cnt = get2(); + if (cnt > 6) cnt = 6; + for (i = 0; i < cnt; i++) + RT_pana_info.v8tags.tag39[i] = get4(); + } + break; + case 58: + if (pana_raw && type == 7 && len == 26) { + ushort cnt = get2(); + if (cnt > 6) cnt = 6; + for (i = 0; i < cnt; i++) { + get2(); + RT_pana_info.v8tags.tag3A[i] = get2(); + } + } + break; + case 59: + if (pana_raw && type == 3 && len == 1) + RT_pana_info.v8tags.tag3B = get2(); + break; + case 60: + case 61: + case 62: + case 63: + if (pana_raw && type == 3 && len == 1) + RT_pana_info.v8tags.initial[tag - 0x3c] = get2(); + break; + case 64: + if (pana_raw && type == 7 && len == 70) { + ushort count = get2(); + if (count > 17) count = 17; + for (i = 0; i < count; i++) { + ushort v1 = get2(); + if (v1 > 16u) v1 = 16u; + RT_pana_info.v8tags.tag40a[i] = v1; + ushort v2 = get2(); + if (v2 > 0xfffu) v2 = 0xfffu; + RT_pana_info.v8tags.tag40b[i] = v2; + } + } + break; + case 65: + if (pana_raw && type == 7 && len == 36) { + ushort count = get2(); + if (count > 17) count = 17; + for (i = 0; i < count; i++) { + ushort v1 = get2(); + if (v1 > 0x40u) v1 = 64; + RT_pana_info.v8tags.tag41[i] = v1; + } + } + break; + case 66: + if (pana_raw && type == 3 && len == 1) { + ushort val = get2(); + if (val > 5) val = 5; + RT_pana_info.v8tags.stripe_count = val; + } + break; + case 67: + if (pana_raw && type == 3 && len == 1) { + ushort val = get2(); + if (val > 5) val = 5; + RT_pana_info.v8tags.tag43 = val; + } + break; + case 68: + if (pana_raw && type == 7 && len == 50) { + ushort count = get2(); + if (count > 5) count = 5; + for (i = 0; i < count; i++) + RT_pana_info.v8tags.stripe_offsets[i] = get4(); + } + break; + case 69: + if (pana_raw && type == 7 && len == 50) { + ushort count = get2(); + if (count > 5) count = 5; + for (i = 0; i < count; i++) + RT_pana_info.v8tags.stripe_left[i] = get4(); + } + break; + case 70: + if (pana_raw && type == 7 && len == 50) { + ushort count = get2(); + if (count > 5) count = 5; + for (i = 0; i < count; i++) + RT_pana_info.v8tags.stripe_compressed_size[i] = get4(); + } + break; + case 71: + if (pana_raw && type == 7 && len == 26) { + ushort count = get2(); + if (count > 5) count = 5; + for (i = 0; i < count; i++) + RT_pana_info.v8tags.stripe_width[i] = get2(); + } + break; + case 72: + if (pana_raw && type == 7 && len == 26) { + ushort count = get2(); + if (count > 5) count = 5; + for (i = 0; i < count; i++) + RT_pana_info.v8tags.stripe_height[i] = get2(); + } + break; case 61440: /* Fuji HS10 table */ fseek (ifp, get4()+base, SEEK_SET); parse_tiff_ifd (base); diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index eaf87d618..30fce90e3 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -192,12 +192,6 @@ protected: std::string RT_software; double RT_baseline_exposure; - struct PanasonicRW2Info { - ushort bpp; - ushort encoding; - PanasonicRW2Info(): bpp(0), encoding(0) {} - }; - PanasonicRW2Info RT_pana_info; std::vector gainMaps; public: @@ -229,6 +223,29 @@ public: short CR3_CTMDtag; }; + struct PanasonicRW2Info { + struct v8_tags_t + { + uint32_t tag39[6]; + uint16_t tag3A[6]; + uint16_t tag3B; + uint16_t initial[4]; + uint16_t tag40a[17], tag40b[17], tag41[17]; + uint16_t stripe_count; // 0x42 + uint16_t tag43; + int64_t stripe_offsets[5]; //0x44 + uint16_t stripe_left[5]; // 0x45 + uint32_t stripe_compressed_size[5]; //0x46 + uint16_t stripe_width[5]; //0x47 + uint16_t stripe_height[5]; + }; + + ushort bpp; + ushort encoding; + v8_tags_t v8tags; + PanasonicRW2Info(): bpp(0), encoding(0), v8tags{} {} + }; + bool isBayer() const { return (filters != 0 && filters != 9); @@ -250,9 +267,11 @@ public: protected: CanonCR3Data RT_canon_CR3_data; - + CanonLevelsData RT_canon_levels_data; + PanasonicRW2Info RT_pana_info; + float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; void (DCraw::*write_thumb)(); @@ -411,7 +430,9 @@ void fuji_decode_strip (fuji_compressed_params* params, int cur_block, INT64 raw void fuji_compressed_load_raw(); void fuji_decode_loop(fuji_compressed_params* common_info, int count, INT64* raw_block_offsets, unsigned *block_sizes, uchar *q_bases); void parse_fuji_compressed_header(); -void fuji_14bit_load_raw(); +void fuji_14bit_load_raw(); +void pana8_decode_loop(void *data); +bool pana8_decode_strip(void* data, int stream); void pentax_load_raw(); void nikon_load_raw(); int nikon_is_compressed(); @@ -503,6 +524,7 @@ private: void panasonicC6_load_raw(); void panasonicC7_load_raw(); +void panasonicC8_load_raw(); void canon_rmf_load_raw(); void panasonic_load_raw(); diff --git a/rtengine/panasonic_decoders.cc b/rtengine/panasonic_decoders.cc index 62bac4526..5211b09b8 100644 --- a/rtengine/panasonic_decoders.cc +++ b/rtengine/panasonic_decoders.cc @@ -13,14 +13,17 @@ * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . -*/ + */ #include +#include #include "dcraw.h" +#include "rt_math.h" + // Code adapted from libraw /* -*- C++ -*- - * Copyright 2019 LibRaw LLC (info@libraw.org) + * Copyright (C) 2022-2024 Alex Tutubalin, LibRaw LLC * LibRaw is free software; you can redistribute it and/or modify it under the terms of the one of two licenses as you choose: @@ -33,6 +36,431 @@ */ +namespace +{ + +using pana8_tags_t = DCraw::PanasonicRW2Info::v8_tags_t; +using ushort = DCraw::ushort; +using INT64 = DCraw::INT64; + +// in 8-byte words, 800kb +#define PANA8_BUFSIZE 102400 + +class pana8_bufio_t +{ +public: + pana8_bufio_t(rtengine::IMFILE *stream, INT64 start, uint32_t len) : + data(PANA8_BUFSIZE), input(stream), baseoffset(start), begin(0), end(0), _size(len) + { + } + uint32_t size() { return ((_size + 7) / 8) * 8; } + uint64_t getQWord(uint32_t offset) + { + if (offset >= begin && offset < end) + return data[offset - begin]; + if (!input) return 0; + refill(offset); + if (offset >= begin && offset < end) + return data[offset - begin]; + return 0; + } + void refill(uint32_t newoffset); + + std::vector data; + rtengine::IMFILE *input; + INT64 baseoffset; + INT64 begin, end; + uint32_t _size; +}; + +struct pana8_param_t { + uint32_t range_shift, gamma_base; + uint32_t tag3A[6]; + uint32_t tag39[6]; + uint32_t tag3B; + uint32_t initial[4]; + uint32_t huff_coeff[17]; + uint32_t tag3B_2; + uint32_t noGammaFlag; + uint64_t hufftable1[17]; + uint64_t hufftable2[17]; + std::vector gammaTable; + std::vector extrahuff; + + pana8_param_t(const pana8_tags_t &init); + int32_t gammaCurve(uint32_t i); + bool DecodeC8( + pana8_bufio_t &bufio, + unsigned int width, unsigned int height, ushort *raw_image, ushort raw_width, ushort raw_height, uint16_t left_margin); + uint32_t GetDBit(uint64_t a2); +}; + +void invertBits(void *buf, size_t size); + +void pana8_bufio_t::refill(uint32_t newoffset) +{ + if (newoffset >= begin && newoffset < end) + return; + uint32_t readwords, remainwords, toread; +#ifdef _OPENMP +#pragma omp critical + { +#endif + fseek(input, baseoffset + newoffset * sizeof(int64_t), SEEK_SET); + remainwords = (_size - newoffset * sizeof(int64_t) + 7) >> 3; + toread = MIN(PANA8_BUFSIZE, remainwords); + uint32_t readbytes = fread(data.data(), 1, toread * sizeof(uint64_t), input); + readwords = (readbytes + 7) >> 3; +#ifdef _OPENMP + } +#endif + + if (INT64(readwords) < INT64(toread) - 1LL) + throw std::runtime_error("Unexpected end of file in CRX bitstream"); + + if (readwords > 0) + invertBits(data.data(), readwords * sizeof(uint64_t)); + begin = newoffset; + end = newoffset + readwords; +} + +struct pana8_base_t { + pana8_base_t() { coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0; } + pana8_base_t(const pana8_base_t &s) { clone(s.coeff); } + void clone(const uint32_t *scoeff) + { // TODO: implement SSE load for SSE-enabled code + coeff[0] = scoeff[0]; + coeff[1] = scoeff[1]; + coeff[2] = scoeff[2]; + coeff[3] = scoeff[3]; + } + uint32_t coeff[4]; +}; + +bool pana8_param_t::DecodeC8(pana8_bufio_t &bufio, unsigned int width, unsigned int height, ushort *raw_image, ushort raw_width, ushort raw_height, uint16_t left_margin) +{ + unsigned halfwidth = width >> 1; + unsigned halfheight = height >> 1; + if (!halfwidth || !halfheight || bufio.size() < 9) + return false; // invalid input + + uint32_t datamax = tag3B_2 >> range_shift; + + pana8_base_t start_coeff; + for (int i = 0; i < 4; i++) + start_coeff.coeff[i] = initial[i] & 0xffffu; + + bool _extrahuff = (extrahuff.size() >= 0x10000); + + uint8_t *big_huff_table = nullptr; + if (_extrahuff) + big_huff_table = extrahuff.data(); + + uint16_t *gammatable = (gammaTable.size() >= 0x10000) && !noGammaFlag ? (uint16_t *)gammaTable.data() : 0; + +#ifdef PANA8_FULLY_BUFFERED + const uint8_t *inputbyteptr = source.data(); + uint32_t jobsz_in_qwords = source.size() >> 3; +#else + uint32_t jobsz_in_qwords = bufio.size() >> 3; +#endif + int32_t doublewidth = 4 * halfwidth; + std::vector outline(4 * doublewidth); + pana8_base_t line_base(start_coeff); + int64_t bittail = 0LL; + int32_t bitportion = 0; + uint32_t inqword = 0u; + + try { + for (uint32_t current_row = 0; current_row < halfheight; current_row++) { + uint8_t *outrowp = outline.data(); + pana8_base_t current_base(line_base); + + for (int32_t col = 0; col < doublewidth; col++) { + uint64_t pixbits; + if (bitportion < 0) { + uint32_t inqword_next = inqword + 1; + if ((int)inqword + 1 >= int(jobsz_in_qwords)) + return false; + bitportion += 64; + uint64_t inputqword = bufio.getQWord(inqword); + uint64_t inputqword_next = bufio.getQWord(inqword_next); + pixbits = (inputqword_next >> bitportion) | (inputqword << (64 - (uint8_t)(bitportion & 0xffu))); + if ((unsigned int)inqword < jobsz_in_qwords) + inqword = inqword_next; + } else { + if ((unsigned int)inqword >= jobsz_in_qwords) + return false; + uint64_t inputqword = bufio.getQWord(inqword); + pixbits = (inputqword >> bitportion) | bittail; + uint32_t step = (bitportion == 0); + if (!bitportion) + bitportion = 64; + inqword += step; + } + int huff_index = 0; + if (_extrahuff) { + huff_index = *(uint8_t *)(big_huff_table + ((pixbits >> 48) & 0xffffu)); + } else { + huff_index = int(GetDBit(pixbits)); + datamax = tag3B_2; + } + int32_t v37 = (huff_coeff[huff_index] >> 24) & 0x1F; + uint32_t hc = huff_coeff[huff_index]; + int64_t v38 = pixbits << (((hc >> 16) & 0xffffu) & 0x1F); + uint64_t v90 = (uint32_t)(huff_index - v37); + int32_t v39 = (uint16_t)((uint64_t)v38 >> ((uint8_t)v37 - (uint8_t)huff_index)) << ((huff_coeff[huff_index] >> 24) & 0xffu); + + if (huff_index - v37 <= 0) + v39 &= 0xffff0000u; + + int32_t delta1; + if (v38 < 0) { + delta1 = (uint16_t)v39; + } else if (huff_index) { + int32_t v40 = -1 << huff_index; + if ((uint8_t)v37) + delta1 = (uint16_t)v39 + v40; + else + delta1 = (uint16_t)v39 + v40 + 1; + } else { + delta1 = 0; + } + + uint32_t v42 = bitportion - ((huff_coeff[huff_index] >> 16) & 0x1F); + int32_t delta2 = uint8_t(v37) ? 1 << (v37 - 1) : 0; + uint32_t *destpixel = (uint32_t *)(outrowp + 16LL * (col >> 2)); + + int32_t delta = delta1 + delta2; + int32_t col_amp_3 = col & 3; + if (col_amp_3 == 2) { + int32_t val = current_base.coeff[1] + delta; + destpixel[1] = uint32_t(rtengine::LIM(val, 0, int(datamax))); + } else if (col_amp_3 == 1) { + int32_t val = current_base.coeff[2] + delta; + destpixel[2] = uint32_t(rtengine::LIM(val, 0, int(datamax))); + } else if ((col & 3) != 0) { // == 3 + int32_t val = current_base.coeff[3] + delta; + destpixel[3] = uint32_t(rtengine::LIM(val, 0, int(datamax))); + } else { // 0 + int32_t val = current_base.coeff[0] + delta; + destpixel[0] = uint32_t(rtengine::LIM(val, 0, int(datamax))); + } + if (huff_index <= v37) + v90 = 0LL; + bittail = v38 << v90; + bitportion = int32_t(v42 - v90); + + if (col_amp_3 == 3) + current_base.clone((uint32_t *)(outrowp + 16LL * (col >> 2))); + if (col == 3) + line_base.clone((uint32_t *)(outrowp)); + } + + int destrow = current_row * 2; + uint16_t *destrow0 = raw_image + (destrow * raw_width) + left_margin; + uint16_t *destrow1 = + raw_image + (destrow + 1) * raw_width + left_margin; + uint16_t *srcrow = (uint16_t *)(outrowp); + if (gammatable) { + for (unsigned col = 0; col < width - 1; col += 2) { + const int c6 = col * 4; + destrow0[col] = gammatable[srcrow[c6]]; + destrow0[col + 1] = gammatable[srcrow[c6 + 2]]; + destrow1[col] = gammatable[srcrow[c6 + 4]]; + destrow1[col + 1] = gammatable[srcrow[c6 + 6]]; + } + } else { + for (unsigned col = 0; col < width - 1; col += 2) { + const int c6 = col * 4; + destrow0[col] = srcrow[c6]; + destrow0[col + 1] = srcrow[c6 + 2]; + destrow1[col] = srcrow[c6 + 4]; + destrow1[col + 1] = srcrow[c6 + 6]; + } + } + } + } catch (...) { // buffer read may throw an exception + return false; + } + + return true; +} + +uint32_t pana8_param_t::GetDBit(uint64_t a2) +{ + for (int i = 0; i < 16; i++) { + if ((a2 & hufftable2[i]) == hufftable1[i]) + return i; + } + + return uint32_t((hufftable2[16] & a2) == hufftable1[16]) ^ 0x11u; +} + +pana8_param_t::pana8_param_t(const pana8_tags_t &meta) : + gammaTable(0) +{ + range_shift = gamma_base = tag3B = 0; + + memset(tag3A, 0, sizeof(tag3A)); + memset(tag39, 0, sizeof(tag3A)); + memset(tag3A, 0, sizeof(tag3A)); + memset(initial, 0, sizeof(tag3A)); + memset(huff_coeff, 0, sizeof(tag3A)); + memset(hufftable1, 0, sizeof(tag3A)); + memset(hufftable2, 0, sizeof(tag3A)); + + noGammaFlag = 1; + + for (int i = 0; i < 6; i++) { + tag3A[i] = meta.tag3A[i]; + tag39[i] = meta.tag39[i]; + } + + tag3B_2 = tag3B = meta.tag3B; + + for (int i = 0; i < 4; i++) + initial[i] = meta.initial[i]; + + for (int i = 0; i < 17; i++) + huff_coeff[i] = (uint32_t(meta.tag41[i]) << 24) | (uint32_t(meta.tag40a[i]) << 16) | meta.tag40b[i]; + + std::vector tempGamma(0x10000); + for (unsigned i = 0; i < 0x10000; i++) { + uint64_t val = gammaCurve(i); + tempGamma[i] = uint16_t(val & 0xffffu); + if (i != val) + noGammaFlag = 0; + } + + if (!noGammaFlag) + gammaTable = tempGamma; + + int v7 = 0; + + for (unsigned hindex = 0; hindex < 17; hindex++) { + uint32_t hc = huff_coeff[hindex]; + uint32_t hlow = (hc >> 16) & 0x1F; + int16_t v8 = 0; + if ((hc & 0x1F0000) != 0) { + int h7 = ((hc >> 16) & 0xffffu) & 7; + if (hlow - 1 >= 7) { + uint32_t hdiff = h7 - hlow; + v8 = 0; + do { + v8 = (v8 << 8) | 0xFFu; + hdiff += 8; + } while (hdiff); + } else { + v8 = 0; + } + for (; h7; --h7) { + v8 = 2 * v8 + 1; + } + } + + uint16_t v9 = hc & v8; + if (uint32_t(v7) < hlow) { + v7 = ((huff_coeff[hindex] >> 16) & 0xFFFFu) & 0x1F; + } + hufftable2[hindex] = 0xFFFFULL << (64 - hlow); + hufftable1[hindex] = (uint64_t)v9 << (64 - hlow); + } + + if (v7 < 17) { + if (extrahuff.size() < 0x10000) + extrahuff.resize(0x10000); + uint64_t v17 = 0LL; + + for (int j = 0LL; j < 0x10000; ++j) { + extrahuff[j] = uint8_t(GetDBit(v17) & 0xffu); + v17 += 0x1000000000000ULL; + } + } +} + +int32_t pana8_param_t::gammaCurve(uint32_t idx) +{ + unsigned int v2 = idx | 0xFFFF0000; + if ((idx & 0x10000) == 0) + v2 = idx & 0x1FFFF; + + int v3 = gamma_base + v2; + unsigned int v4 = MIN(v3, 0xFFFF); + + int v5 = 0; + if ((v4 & 0x80000000) != 0) + v4 = 0; + + if (v4 >= (0xFFFF & tag3A[1])) { + v5 = 1; + if (v4 >= (0xFFFF & tag3A[2])) { + v5 = 2; + if (v4 >= (0xFFFF & tag3A[3])) { + v5 = 3; + if (v4 >= (0xFFFF & tag3A[4])) + v5 = ((v4 | 0x500000000LL) - (uint64_t)(0xFFFF & tag3A[5])) >> 32; + } + } + } + unsigned int v6 = tag3A[v5]; + int v7 = tag39[v5]; + unsigned int v8 = v4 - (uint16_t)v6; + char v9 = v7 & 0x1F; + int64_t result = 0; + + if (v9 == 31) { + result = v5 == 5 ? 0xFFFFLL : ((tag3A[v5 + 1] >> 16) & 0xFFFF); + return MIN(uint32_t(result), tag3B); + } + if ((v7 & 0x10) == 0) { + if (v9 == 15) { + result = ((v6 >> 16) & 0xFFFF); + return MIN(uint32_t(result), tag3B); + } else if (v9 != 0) { + v8 = (v8 + (1 << (v9 - 1))) >> v9; + } + } else { + v8 <<= v7 & 0xF; + } + + result = v8 + ((v6 >> 16) & 0xFFFF); + + return MIN(uint32_t(result), tag3B); +} + +const static uint8_t _bitRevTable[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, + 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, + 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, + 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, + 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, + 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, + 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, + 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, + 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, + 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, + 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, + 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, + 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF}; + +void invertBits(void *buf, size_t size) +{ + unsigned sz = unsigned(size / 8); + uint64_t *ptr = static_cast(buf); + for (unsigned i = 0; i < sz; i++) { + uint8_t *b = reinterpret_cast(&ptr[i]); + uint64_t r = ((uint64_t)_bitRevTable[b[0]] << 56) | ((uint64_t)_bitRevTable[b[1]] << 48) | + ((uint64_t)_bitRevTable[b[2]] << 40) | ((uint64_t)_bitRevTable[b[3]] << 32) | + ((uint64_t)_bitRevTable[b[4]] << 24) | ((uint64_t)_bitRevTable[b[5]] << 16) | + ((uint64_t)_bitRevTable[b[6]] << 8) | _bitRevTable[b[7]]; + ptr[i] = r; + } +} + +} // namespace + unsigned DCraw::pana_bits_t::operator() (int nbits, unsigned *bytes) { int byte; @@ -177,6 +605,8 @@ void DCraw::panasonic_load_raw() panasonicC6_load_raw(); } else if (RT_pana_info.encoding == 7) { panasonicC7_load_raw(); + } else if (RT_pana_info.encoding == 8) { + panasonicC8_load_raw(); } else { pana_bits_t pana_bits(ifp, load_flags, RT_pana_info.encoding); pana_bits(0, 0); @@ -321,3 +751,55 @@ void DCraw::panasonicC7_load_raw() free(iobuf); tiff_bps = RT_pana_info.bpp; } + +void DCraw::panasonicC8_load_raw() +{ + int errs = 0; + unsigned totalw = 0; + + if (RT_pana_info.v8tags.stripe_count > 5) errs++; + for (int i = 0; i < RT_pana_info.v8tags.stripe_count && i < 5; i++) { + if (RT_pana_info.v8tags.stripe_height[i] != raw_height) + errs++; + if (RT_pana_info.v8tags.stripe_offsets[i] < 0 || (RT_pana_info.v8tags.stripe_offsets[i] + INT64((RT_pana_info.v8tags.stripe_compressed_size[i] + 7u) / 8u)) > INT64(ifp->size)) + errs++; + totalw += RT_pana_info.v8tags.stripe_width[i]; + } + if (totalw != raw_width) errs++; + + if (errs) + derror(); + + pana8_param_t pana8_param(RT_pana_info.v8tags); + pana8_decode_loop(&pana8_param); +} + +void DCraw::pana8_decode_loop(void *data) +{ +#ifdef _OPENMP + int errs = 0, scount = MIN(5, RT_pana_info.v8tags.stripe_count); +#pragma omp parallel for + for (int stream = 0; stream < scount; stream++) { + if (!pana8_decode_strip(data, stream)) + errs++; + } + if (errs) + derror(); +#else + for (int stream = 0; stream < RT_pana_info.v8tags.stripe_count && stream < 5; stream++) + if (!pana8_decode_strip(data, stream)) + derror(); +#endif +} + +bool DCraw::pana8_decode_strip(void *data, int stream) +{ + pana8_param_t *pana8_param = (pana8_param_t *)data; + if (!data || stream < 0 || stream > 4 || stream > RT_pana_info.v8tags.stripe_count) return 1; // error + + unsigned exactbytes = (RT_pana_info.v8tags.stripe_compressed_size[stream] + 7u) / 8u; + pana8_bufio_t bufio(ifp, RT_pana_info.v8tags.stripe_offsets[stream], exactbytes); + return pana8_param->DecodeC8(bufio, RT_pana_info.v8tags.stripe_width[stream], + RT_pana_info.v8tags.stripe_height[stream], raw_image, raw_width, raw_height, + RT_pana_info.v8tags.stripe_left[stream]); +} From 3b4642fd07bd3d7d88feb3c07c3075cf2390a152 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sat, 30 Mar 2024 17:18:25 +0100 Subject: [PATCH 221/291] dcraw: add Panasonic DC-S5M2 and DC-S5M2X to adobe_coeffs --- rtengine/dcraw.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 2b2d36013..cfb949b86 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8996,6 +8996,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-G8", 15, 0xfff, /* G8, G80, G81, G85 */ { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DC-S5M2", 0, 0, /* DC-S5M2, DC-S5M2X */ + { 10308,-4206,-783,-4088,12102,2229,-125,1051,5912 } }, { "Panasonic DC-G9M2", 0, 0, { 8325,-3456,-623,-4330,12089,2528,-860,2646,5984 } }, { "Panasonic DC-G9", 15, 0xfff, From fab4b4f614b47890f21cf54df8f8654980ac7204 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:15:20 -0700 Subject: [PATCH 222/291] Upgrade deprecated GitHub actions Actions based on Node.js 16 are deprecated. The following must be upgraded one major version. - actions/checkout@v3 - actions/cache@v3 - actions/upload-artifact@v3 - softprops/action-gh-release@v1 --- .github/workflows/appimage.yml | 10 +++++----- .github/workflows/codeql.yml | 2 +- .github/workflows/macos.yml | 6 +++--- .github/workflows/windows.yml | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index e144f4189..bbdd2f383 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -26,7 +26,7 @@ jobs: build_type: [release, debug] steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -150,7 +150,7 @@ jobs: - name: Restore AppImage tools from cache id: appimage-tools-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: key: appimage-tools-1 path: | @@ -203,7 +203,7 @@ jobs: echo "ARTIFACT_NAME=$ARTIFACT_NAME" >> $GITHUB_ENV - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.ARTIFACT_NAME}}.AppImage path: ${{github.workspace}}/build/${{env.ARTIFACT_NAME}}.AppImage @@ -225,7 +225,7 @@ jobs: echo "PUBLISH_NAME=$PUBLISH_NAME" >> $GITHUB_ENV - name: Publish artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} with: tag_name: nightly-github-actions @@ -255,7 +255,7 @@ jobs: echo "PUBLISH_NAME=$PUBLISH_NAME" >> $GITHUB_ENV - name: Publish pre-dev artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} with: tag_name: pre-dev-github-actions diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5cb91e47a..ffcd1dd3c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8755f7c66..a4ed80519 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -18,7 +18,7 @@ jobs: build: runs-on: macos-12 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install dependencies run: | date -u @@ -97,7 +97,7 @@ jobs: "ARTIFACT_FILE: ${ARTIFACT_FILE}" \ "PUBLISH_NAME: ${PUBLISH_NAME}" exit - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{env.ARTIFACT_FILE}} path: ${{env.ARTIFACT_PATH}} @@ -107,7 +107,7 @@ jobs: zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' - name: Publish artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} with: tag_name: nightly-github-actions diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e5f4ce166..c4de2478f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -30,7 +30,7 @@ jobs: build_type: [release, debug] steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -189,14 +189,14 @@ jobs: 7z a -tzip "%ARTIFACT_NAME%.zip" "./%ARTIFACT_NAME%" - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.ARTIFACT_NAME}} path: build\${{env.ARTIFACT_NAME}} - name: Upload installer if: ${{matrix.build_type == 'release' && (github.ref_type == 'tag' || github.ref_name == 'dev')}} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.ARTIFACT_NAME}}.exe path: build\${{env.ARTIFACT_NAME}}.exe @@ -222,7 +222,7 @@ jobs: echo "PUBLISH_NAME=$PUBLISH_NAME" >> "$(cygpath -u $GITHUB_ENV)" - name: Publish artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} with: tag_name: nightly-github-actions @@ -231,7 +231,7 @@ jobs: build/${{env.PUBLISH_NAME}}-AboutThisBuild.txt - name: Publish installer - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{matrix.build_type == 'release' && (github.ref_type == 'tag' || github.ref_name == 'dev')}} with: tag_name: nightly-github-actions @@ -263,7 +263,7 @@ jobs: echo "PUBLISH_NAME=$PUBLISH_NAME" >> "$(cygpath -u $GITHUB_ENV)" - name: Publish pre-dev artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} with: tag_name: pre-dev-github-actions @@ -272,7 +272,7 @@ jobs: build/${{env.PUBLISH_NAME}}-AboutThisBuild.txt - name: Publish pre-dev installer - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: ${{steps.prepare-publish-pre-dev.outcome == 'success' && matrix.build_type == 'release'}} with: tag_name: pre-dev-github-actions From 21c7d828be58073731b6b3ca17410121ebc77385 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 Jun 2024 18:00:25 -0700 Subject: [PATCH 223/291] Fix opening image in existing window on Windows Include gdbus.exe in the installer. This allows RawTherapee to detect running instances of itself and tell it to open an image instead of launching a new instance. --- tools/win/InnoSetup/WindowsInnoSetup.iss.in | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/win/InnoSetup/WindowsInnoSetup.iss.in b/tools/win/InnoSetup/WindowsInnoSetup.iss.in index f95657bd7..aa30ad2a5 100644 --- a/tools/win/InnoSetup/WindowsInnoSetup.iss.in +++ b/tools/win/InnoSetup/WindowsInnoSetup.iss.in @@ -119,6 +119,7 @@ Source: "{#MyBuildBasePath}\options"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\*.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\gdbus.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyBuildBasePath}\gdb.exe"; DestDir: "{app}"; Flags: skipifsourcedoesntexist ignoreversion ;Source: "{#MyBuildBasePath}\fonts\DroidSansMonoSlashed.ttf"; DestDir: "{fonts}"; FontInstall: "Droid Sans Mono Slashed"; Flags: onlyifdoesntexist uninsneveruninstall ; NOTE: Don't use "Flags: ignoreversion" on any shared system files From 324f488f5b0a6b5ce841e0f780f5cd595b1d34bf Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 Jun 2024 18:59:42 -0700 Subject: [PATCH 224/291] Fix jpg file not writable after save Use a unique_ptr to automatically close the jpg file after. --- rtengine/imageio.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index f096213dc..85afb08ea 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -480,7 +480,11 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize) int ImageIO::loadJPEG (const Glib::ustring &fname) { - FILE *file = g_fopen(fname.c_str (), "rb"); + std::unique_ptr file( + g_fopen(fname.c_str(), "rb"), + [](FILE *f) { + fclose(f); + }); if (!file) { return IMIO_CANNOTREADFILE; @@ -491,7 +495,7 @@ int ImageIO::loadJPEG (const Glib::ustring &fname) cinfo.err = my_jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); - my_jpeg_stdio_src (&cinfo, file); + my_jpeg_stdio_src (&cinfo, file.get()); #if defined( _WIN32 ) && defined( __x86_64__ ) && !defined(__clang__) if ( __builtin_setjmp((reinterpret_cast(cinfo.src))->error_jmp_buf) == 0 ) { @@ -553,7 +557,7 @@ int ImageIO::loadJPEG (const Glib::ustring &fname) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - fclose(file); + file.reset(); if (pl) { pl->setProgressStr ("PROGRESSBAR_READY"); From 5d75c44287aa5d6452ff74447fbe1c7063bf79d8 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 Jun 2024 17:38:36 -0700 Subject: [PATCH 225/291] Add Fujifilm X-H2S color matrix and raw crop --- rtengine/camconst.json | 5 +++++ rtengine/dcraw.cc | 2 ++ 2 files changed, 7 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index b80d776b8..65e57929a 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -1539,6 +1539,11 @@ Camera constants: "ranges": { "white": 3838 } }, + { // Quality B + "make_model": [ "Fujifilm X-H2S" ], + "raw_crop": [ 0, 5, 6264, 4176 ] + }, + { // Quality B "make_model": [ "FUJIFILM X-T10", "FUJIFILM X-E2" ], "dcraw_matrix": [ 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 ], // DNG D65 diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index cfb949b86..cef0e9fff 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8463,6 +8463,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, { "Fujifilm X-H1", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { "Fujifilm X-H2S", 0, 0, + { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, { "Fujifilm X-M1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-S1", 0, 0, From 29370904fb689c438ebe492403610fd05fffda18 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 Jun 2024 18:16:46 -0700 Subject: [PATCH 226/291] Fix pre-dev publishing from forks --- .github/workflows/appimage.yml | 1 + .github/workflows/windows.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5c37486f0..aacdfb75b 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -259,6 +259,7 @@ jobs: if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} with: tag_name: pre-dev-github-actions + repository: Beep6581/RawTherapee files: | ${{env.PUBLISH_NAME}}.AppImage ${{env.PUBLISH_NAME}}-AppImage-AboutThisBuild.txt diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 802b25431..d785e9cfe 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -268,6 +268,7 @@ jobs: if: ${{steps.prepare-publish-pre-dev.outcome == 'success'}} with: tag_name: pre-dev-github-actions + repository: Beep6581/RawTherapee files: | build/${{env.PUBLISH_NAME}}.zip build/${{env.PUBLISH_NAME}}-AboutThisBuild.txt @@ -277,4 +278,5 @@ jobs: if: ${{steps.prepare-publish-pre-dev.outcome == 'success' && matrix.build_type == 'release'}} with: tag_name: pre-dev-github-actions + repository: Beep6581/RawTherapee files: build/${{env.PUBLISH_NAME}}.exe From 29f4f37cdb114e86e7e8d8ee5a34f126bf10905d Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 10 Jun 2024 04:23:19 +0000 Subject: [PATCH 227/291] Enable extensions that are missing from config --- rtdata/options/options.lin | 4 ++-- rtdata/options/options.osx | 4 ++-- rtdata/options/options.win | 4 ++-- rtgui/options.cc | 29 +++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin index 2a96c6997..18cb01901 100644 --- a/rtdata/options/options.lin +++ b/rtdata/options/options.lin @@ -12,8 +12,8 @@ MultiUser=true [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions= +ParseExtensionsEnabled= [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx index eff9cd8d9..8d954529f 100644 --- a/rtdata/options/options.osx +++ b/rtdata/options/options.osx @@ -13,8 +13,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions= +ParseExtensionsEnabled= [Output] PathTemplate=%p1/converted/%f diff --git a/rtdata/options/options.win b/rtdata/options/options.win index e3f43343e..a88cc3db2 100644 --- a/rtdata/options/options.win +++ b/rtdata/options/options.win @@ -14,8 +14,8 @@ UseSystemTheme=false [File Browser] # Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) -ParseExtensions=3fr;arw;arq;cr2;cr3;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;jxl;kdc;mef;mos;mrw;nef;nrw;orf;ori;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; -ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;1;1;1;1;1;1;1; +ParseExtensions= +ParseExtensionsEnabled= [Output] PathTemplate=%p1/converted/%f diff --git a/rtgui/options.cc b/rtgui/options.cc index c96febe86..643012dfe 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -1268,6 +1268,35 @@ void Options::readFromFile(Glib::ustring fname) } } + // check and add extensions that are missing from config + static const std::vector extensions_known = { + "3fr", "arw", "arq", "cr2", "cr3", "crf", "crw", "dcr", "dng", + "fff", "iiq", "jpg", "jpeg", "jxl", "kdc", "mef", "mos", "mrw", + "nef", "nrw", "orf", "ori", "pef", "png", "raf", "raw", "rw2", + "rwl", "rwz", "sr2", "srf", "srw", "tif", "tiff", "x3f"}; + + std::map extensions_checked; + + if (parseExtensions.size() == parseExtensionsEnabled.size()) { + for (auto i = 0; i < parseExtensions.size(); ++i) { + extensions_checked[parseExtensions[i]] = parseExtensionsEnabled[i]; + } + } + + parseExtensions.clear(); + parseExtensionsEnabled.clear(); + + for (auto const &i : extensions_known) { + if (extensions_checked.count(i) == 0) { + extensions_checked[i] = 1; + } + } + + for (auto const &x : extensions_checked) { + parseExtensions.emplace_back(x.first); + parseExtensionsEnabled.emplace_back(x.second); + } + if (keyFile.has_key("File Browser", "ThumbnailArrangement")) { fbArrangement = keyFile.get_integer("File Browser", "ThumbnailArrangement"); } From 8503d5323e5b05dc79c583d59de395e4d1544714 Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 10 Jun 2024 13:46:17 +0000 Subject: [PATCH 228/291] Fix whitespace/formatting --- rtgui/options.cc | 16 ++++++++-------- rtgui/options.h | 6 +++--- rtgui/preferences.cc | 13 +++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index 643012dfe..af40595aa 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -471,7 +471,7 @@ void Options::setDefaults() curvebboxpos = 1; complexity = 2; spotmet = 0; - + inspectorWindow = false; zoomOnScroll = true; prevdemo = PD_Sidecar; @@ -580,8 +580,8 @@ void Options::setDefaults() rtSettings.darkFramesPath = ""; rtSettings.flatFieldsPath = ""; - rtSettings.cameraProfilesPath = ""; - rtSettings.lensProfilesPath = ""; + rtSettings.cameraProfilesPath = ""; + rtSettings.lensProfilesPath = ""; #ifdef _WIN32 const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" @@ -673,8 +673,8 @@ void Options::setDefaults() lastIccDir = rtSettings.iccDirectory; lastDarkframeDir = rtSettings.darkFramesPath; lastFlatfieldDir = rtSettings.flatFieldsPath; - lastCameraProfilesDir = rtSettings.cameraProfilesPath; - lastLensProfilesDir = rtSettings.lensProfilesPath; + lastCameraProfilesDir = rtSettings.cameraProfilesPath; + lastLensProfilesDir = rtSettings.lensProfilesPath; // rtSettings.bw_complementary = true; // There is no reasonable default for curves. We can still suppose that they will take place // in a subdirectory of the user's own ProcParams presets, i.e. in a subdirectory @@ -816,7 +816,7 @@ void Options::readFromFile(Glib::ustring fname) rtSettings.cameraProfilesPath = keyFile.get_string("General", "CameraProfilesPath"); } - if (keyFile.has_key("General", "LensProfilesPath")) { + if (keyFile.has_key("General", "LensProfilesPath")) { rtSettings.lensProfilesPath = keyFile.get_string("General", "LensProfilesPath"); } @@ -2424,8 +2424,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_string("General", "Version", RTVERSION); keyFile.set_string("General", "DarkFramesPath", rtSettings.darkFramesPath); keyFile.set_string("General", "FlatFieldsPath", rtSettings.flatFieldsPath); - keyFile.set_string("General", "CameraProfilesPath", rtSettings.cameraProfilesPath); - keyFile.set_string("General", "LensProfilesPath", rtSettings.lensProfilesPath); + keyFile.set_string("General", "CameraProfilesPath", rtSettings.cameraProfilesPath); + keyFile.set_string("General", "LensProfilesPath", rtSettings.lensProfilesPath); keyFile.set_boolean("General", "Verbose", rtSettings.verbose); keyFile.set_integer("General", "Cropsleep", rtSettings.cropsleep); keyFile.set_double("General", "Reduchigh", rtSettings.reduchigh); diff --git a/rtgui/options.h b/rtgui/options.h index b2221e844..38f4fe896 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -331,7 +331,7 @@ public: bool overwriteOutputFile; int complexity; int spotmet; - + bool inspectorWindow; // open inspector in separate window bool zoomOnScroll; // translate scroll events to zoom @@ -472,8 +472,8 @@ public: Glib::ustring lastIccDir; Glib::ustring lastDarkframeDir; Glib::ustring lastFlatfieldDir; - Glib::ustring lastCameraProfilesDir; - Glib::ustring lastLensProfilesDir; + Glib::ustring lastCameraProfilesDir; + Glib::ustring lastLensProfilesDir; Glib::ustring lastRgbCurvesDir; Glib::ustring lastLabCurvesDir; Glib::ustring lastRetinexDir; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d92080af8..04a9ece60 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -656,7 +656,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () Gtk::Grid* dirgrid = Gtk::manage(new Gtk::Grid()); setExpandAlignProperties(dirgrid, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); - // Dark Frames Dir + // Dark Frames Dir Gtk::Label *dfLab = Gtk::manage(new Gtk::Label(M("PREFERENCES_DIRDARKFRAMES") + ":")); setExpandAlignProperties(dfLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); darkFrameDir = Gtk::manage(new MyFileChooserButton(M("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); @@ -705,7 +705,7 @@ Gtk::Widget* Preferences::getImageProcessingPanel () dirgrid->attach_next_to(*cameraProfilesDirLabel, *clutsDirLabel, Gtk::POS_BOTTOM, 1, 1); dirgrid->attach_next_to(*cameraProfilesDir, *cameraProfilesDirLabel, Gtk::POS_RIGHT, 1, 1); - //Lens Profiles Dir + //Lens Profiles Dir Gtk::Label *lensProfilesDirLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LENSPROFILESDIR") + ":")); lensProfilesDirLabel->set_tooltip_text(M("PREFERENCES_LENSPROFILESDIR_TOOLTIP")); setExpandAlignProperties(lensProfilesDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -1111,7 +1111,7 @@ Gtk::Widget* Preferences::getGeneralPanel() workflowGrid->attach_next_to(*curveBBoxPosL, *flayoutlab, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*curveBBoxPosC, *editorLayout, Gtk::POS_BOTTOM, 1, 1); workflowGrid->attach_next_to(*curveBBoxPosRestartL, *lNextStart, Gtk::POS_BOTTOM, 1, 1); - + curveBBoxPosS = Gtk::manage(new Gtk::ComboBoxText()); setExpandAlignProperties(curveBBoxPosS, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_BASELINE); @@ -2013,8 +2013,8 @@ void Preferences::storePreferences() moptions.curvebboxpos = curveBBoxPosC->get_active_row_number(); moptions.complexity = complexitylocal->get_active_row_number(); - moptions.spotmet = spotlocal->get_active_row_number(); - + moptions.spotmet = spotlocal->get_active_row_number(); + moptions.inspectorWindow = inspectorWindowCB->get_active(); moptions.zoomOnScroll = zoomOnScrollCB->get_active(); moptions.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2; @@ -2673,10 +2673,11 @@ void Preferences::addExtPressed() Gtk::TreeNodeChildren c = extensionModel->children(); - for (size_t i = 0; i < c.size(); i++) + for (size_t i = 0; i < c.size(); i++) { if (c[i][extensionColumns.ext] == extension->get_text()) { return; } + } Gtk::TreeRow row = * (extensionModel->append()); From 7f7e808b9c07d6da896af462a8ab63146735fd74 Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 10 Jun 2024 14:03:41 +0000 Subject: [PATCH 229/291] Don't allow deleting known extensions --- rtgui/options.cc | 18 ++++++------------ rtgui/options.h | 7 +++++++ rtgui/preferences.cc | 23 ++++++++++++++++++++++- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/rtgui/options.cc b/rtgui/options.cc index af40595aa..a6756d37d 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -1269,30 +1269,24 @@ void Options::readFromFile(Glib::ustring fname) } // check and add extensions that are missing from config - static const std::vector extensions_known = { - "3fr", "arw", "arq", "cr2", "cr3", "crf", "crw", "dcr", "dng", - "fff", "iiq", "jpg", "jpeg", "jxl", "kdc", "mef", "mos", "mrw", - "nef", "nrw", "orf", "ori", "pef", "png", "raf", "raw", "rw2", - "rwl", "rwz", "sr2", "srf", "srw", "tif", "tiff", "x3f"}; - - std::map extensions_checked; + std::map checkedExtensions; if (parseExtensions.size() == parseExtensionsEnabled.size()) { for (auto i = 0; i < parseExtensions.size(); ++i) { - extensions_checked[parseExtensions[i]] = parseExtensionsEnabled[i]; + checkedExtensions[parseExtensions[i]] = parseExtensionsEnabled[i]; } } parseExtensions.clear(); parseExtensionsEnabled.clear(); - for (auto const &i : extensions_known) { - if (extensions_checked.count(i) == 0) { - extensions_checked[i] = 1; + for (auto const &i : knownExtensions) { + if (checkedExtensions.count(i) == 0) { + checkedExtensions[i] = 1; } } - for (auto const &x : extensions_checked) { + for (auto const &x : checkedExtensions) { parseExtensions.emplace_back(x.first); parseExtensionsEnabled.emplace_back(x.second); } diff --git a/rtgui/options.h b/rtgui/options.h index 38f4fe896..6a2b0c35d 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -310,6 +310,13 @@ public: int maxThumbnailWidth; std::size_t maxCacheEntries; int thumbInterp; // 0: nearest, 1: bilinear + + std::vector knownExtensions = { + "3fr", "arw", "arq", "cr2", "cr3", "crf", "crw", "dcr", "dng", + "fff", "iiq", "jpg", "jpeg", "jxl", "kdc", "mef", "mos", "mrw", + "nef", "nrw", "orf", "ori", "pef", "png", "raf", "raw", "rw2", + "rwl", "rwz", "sr2", "srf", "srw", "tif", "tiff", "x3f"}; + 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) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 04a9ece60..97bfb92b6 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2687,8 +2687,29 @@ void Preferences::addExtPressed() void Preferences::delExtPressed() { + const Glib::RefPtr selection = extensions->get_selection(); - extensionModel->erase(extensions->get_selection()->get_selected()); + if (!selection) { + return; + } + + const Gtk::TreeModel::iterator selected = selection->get_selected(); + + if (!selected) { + return; + } + + bool delOkay = true; + for (auto const &x : moptions.knownExtensions) { + if (x == (*selected)[extensionColumns.ext]) { + delOkay = false; + break; + } + } + + if (delOkay) { + extensionModel->erase(selected); + } } void Preferences::moveExtUpPressed() From 02e8d3f33c9cd6cd97d09f8cf9453a096b449408 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 16 Jun 2024 02:30:40 +0000 Subject: [PATCH 230/291] Change order of image/raw loading to generate thumbnails --- rtgui/thumbnail.cc | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 228592a70..f5098ae6d 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -248,44 +248,44 @@ void Thumbnail::_generateThumbnailImage() cfs.exifValid = false; cfs.timeValid = false; - // 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::eSensorType sensorType = rtengine::ST_NONE; - - if (initial_ && options.internalThumbIfUntouched) { - quick = true; - tpp = rtengine::Thumbnail::loadQuickFromRaw(fname, sensorType, tw, th, 1, TRUE); - } - - if (!tpp) { - quick = false; - tpp = rtengine::Thumbnail::loadFromRaw(fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); - } - - cfs.sensortype = sensorType; + // this will load formats supported by imagio (jpg, png, jxl, and tiff) + tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); if (tpp) { - cfs.format = FT_Raw; - cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; + cfs.format = FT_Custom; infoFromImage(fname); - - if (!quick) { - cfs.width = tpp->full_width; - cfs.height = tpp->full_height; - } } if (!tpp) { - // this will load formats supported by imagio (jpg, png, jxl, and tiff) - tpp = rtengine::Thumbnail::loadFromImage(fname, tw, th, -1, pparams->wb.equal, pparams->wb.observer); + // 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::eSensorType sensorType = rtengine::ST_NONE; + + if (initial_ && options.internalThumbIfUntouched) { + quick = true; + tpp = rtengine::Thumbnail::loadQuickFromRaw(fname, sensorType, tw, th, 1, TRUE); + } + + if (!tpp) { + quick = false; + tpp = rtengine::Thumbnail::loadFromRaw(fname, sensorType, tw, th, 1, pparams->wb.equal, pparams->wb.observer, TRUE, &(pparams->raw)); + } + + cfs.sensortype = sensorType; if (tpp) { - cfs.format = FT_Custom; + cfs.format = FT_Raw; + cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; infoFromImage(fname); + + if (!quick) { + cfs.width = tpp->full_width; + cfs.height = tpp->full_height; + } } } From 3b2990dd78424cda3a57434fc405646cac138ced Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:55:10 -0700 Subject: [PATCH 231/291] Add/update dcraw constants from LibRaw Add or update adobe_coeff constants from LibRaw public snapshot 202403. --- rtengine/dcraw.cc | 481 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 474 insertions(+), 7 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index cfb949b86..3358dc91b 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -8113,6 +8113,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, { "Apple QuickTake", 0, 0, /* DJC */ { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, + { "Broadcom RPi IMX219", 66, 0x3ff, + { 5302,1083,-728,-5320,14112,1699,-863,2371,5136 } }, /* LibRaw */ // From LibRaw + { "Broadcom RPi OV5647", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ // From LibRaw + { "Broadcom Pi", 16, 0x3ff, + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, /* DJC */ // From LibRaw { "Canon EOS D2000", 0, 0, { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, { "Canon EOS D6000", 0, 0, @@ -8151,6 +8157,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 250D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, // From LibRaw { "Canon EOS 60D", 0, 0x2ff7, { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, { "Canon EOS 70D", 0, 0x3bc7, @@ -8161,6 +8169,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7457,-671,-937,-4849,12495,2643,-1213,2354,5492 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 250D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565 } }, // From LibRaw { "Canon EOS 200D", 0, 0, { 7377,-742,-998,-4235,11981,2549,-673,1918,5538 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -8185,8 +8195,14 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, { "Canon EOS 760D", 0, 0x350f, { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS 850D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, // From LibRaw { "Canon EOS 800D", 0, 0, { 6970,-512,-968,-4425,12161,2553,-739,1982,5601 } }, + { "EOS 850D", 0, 0, + { 9079,-1923,-1236,-4677,12454,2492,-922,2319,5565}}, // From LibRaw + { "Canon EOS 90D", 0, 0, + { 11498, -3759, -1516, -5073, 12954, 2349, -892, 1867, 6118}}, // From LibRaw { "Canon EOS 1000D", 0, 0xe43, { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, { "Canon EOS 1100D", 0, 0x3510, @@ -8199,12 +8215,46 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { "Canon EOS 3000D", 0, 0, { 6939,-1016,-866,-4428,12473,2177,-1175,2178,6162 } }, + { "Canon EOS RP", 0, 0, + { 8608,-2097,-1178,-5425,13265,2383,-1149,2238,5680 } }, // From LibRaw + { "Canon EOS R3", 0, 0, + { 9423,-2839,-1195,-4532,12377,2415,-483,1374,5276 } }, // From LibRaw + { "Canon EOS R50", 0, 0, + { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, // From LibRaw + { "Canon EOS R100", 0, 0, + { 8230, -1515, -1032, -4179, 12005, 2454, -649, 2076, 4711 } }, // From LibRaw + { "Canon EOS R5", 0, 0, + { 9766,-2953,-1254,-4276,12116,2433,-437,1336,5131 } }, // From LibRaw + { "Canon EOS R6 Mark II", 0, 0, + { 9539, -2795, -1224, -4175, 11998, 2458, -465, 1755,6048 } }, // From LibRaw + { "Canon EOS R6", 0, 0, + { 8293,-1611,-1132,-4759,12711,2275,-1013,2415,5509 } }, // From LibRaw + { "Canon EOS R7", 0, 0, + { 10424, -3138, -1300, -4221, 11938, 2584, -547, 1658, 6183 } }, // From LibRaw + { "Canon EOS R8", 0, 0, + { 9539, -2795, -1224, -4175, 11998, 2458, -465, 1755, 6048 } }, // From LibRaw + { "Canon EOS R10", 0, 0, + { 9269, -2012, -1107, -3990, 11762, 2527, -569, 2093, 4913 } }, // From LibRaw + { "Canon EOS Ra", 0, 0, + { 22880,-11531,-2223,-2034,10469,1809, 316,1401,5769 } }, // From LibRaw + { "Canon EOS R", 0, 0, + { 8293,-1789,-1094,-5025,12925,2327,-1199,2769,6108 } }, // v.2 // From LibRaw + { "Canon EOS M6 Mark II", 0, 0, + { 11498,-3759,-1516,-5073,12954,2349,-892,1867,6118 } }, // From LibRaw { "Canon EOS M6", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { "Canon EOS M50 Mark II", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, // From LibRaw + { "Canon EOS M50", 0, 0, + { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, // From LibRaw { "Canon EOS M5", 0, 0, /* also M50 */ { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { "Canon EOS M3", 0, 0, { 6362,-823,-847,-4426,12109,2616,-743,1857,5635 } }, + { "Canon EOS M200", 0, 0, + { 10463,-2173,-1437,-4856,12635,2482,-1216,2915,7237 } }, // From LibRaw + { "Canon EOS M2", 0, 0, + { 6400,-480,-888,-5294,13416,2047,-1296,2203,6137 } }, // From LibRaw { "Canon EOS M100", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, { "Canon EOS M10", 0, 0, @@ -8227,6 +8277,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, { "Canon EOS-1D C", 0, 0x3c4e, { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D X Mark III", 0, 0, + { 8971, -2022, -1242, -5405, 13249, 2380, -1280, 2483, 6072}}, // From LibRaw { "Canon EOS-1D X Mark II", 0, 0, { 7596,-978,-967,-4808,12571,2503,-1398,2567,5752 } }, { "Canon EOS-1D X", 0, 0x3c4e, @@ -8235,12 +8287,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, { "Canon EOS C500", 853, 0, /* DJC */ { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, + { "Canon PowerShot 600", 0, 0, + { -3822,10019,1311,4085,-157,3386,-5341,10829,4812,-1969,10969,1126 } }, // From LibRaw { "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 D10", 127, 0, + { 14052,-5229,-1156,-1325,9420,2252,-498,1957,4116 } }, /* DJC */ // From LibRaw { "Canon PowerShot G10", 0, 0, { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, { "Canon PowerShot G11", 0, 0, @@ -8253,6 +8309,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, { "Canon PowerShot G1 X Mark III", 0, 0, { 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 } }, + { "Canon PowerShot G1 X Mark II", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, // From LibRaw { "Canon PowerShot G1 X", 0, 0, { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, { "Canon PowerShot G1", 0, 0, @@ -8263,12 +8321,18 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9701,-3857,-921,-3149,11537,1817,-786,1817,5147 } }, { "Canon PowerShot G3", 0, 0, { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5 X Mark II",0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, // From LibRaw { "Canon PowerShot G5 X", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G5", 0, 0, { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, { "Canon PowerShot G6", 0, 0, { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G7 X Mark III", 0, 0, + { 11629, -5713, -914, -2706, 11090, 1842, -206, 1225, 5515 } }, // From LibRaw + { "Canon PowerShot G7 X Mark II", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, // From LibRaw { "Canon PowerShot G7 X", 0, 0, { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G9 X Mark II", 0, 0, @@ -8305,14 +8369,24 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, { "Canon PowerShot S120", 0, 0, { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, + { "Canon PowerShot SD300", 0, 0, + { 6526,-1720,-1075,-1390,5945,602,-90,820,2380 } }, // CHDK // From LibRaw { "Canon PowerShot SX1 IS", 0, 0, { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX20 IS", 0, 0, + { 8275,-2904,-1260,-128,5305,505,51,481,2450 } }, // CHDK // From LibRaw + { "Canon PowerShot SX30 IS", 0, 0, + { 13014,-4698,-1026,-2001,9615,2386,-164,1423,3759 } }, // CHDK // From LibRaw { "Canon PowerShot SX50 HS", 0, 0, { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, { "Canon PowerShot SX60 HS", 0, 0, { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { "Canon PowerShot SX70 HS", 0, 0, + { 18285,-8907,-1951,-1845,10688,1323,364,1101,5139 } }, // From LibRaw { "Canon PowerShot A3300", 0, 0, /* DJC */ { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, + { "Canon PowerShot A460", 0, 0, + { 6493,-2338,-885,-1589,5934,697,-445,1368,2543 } }, // CHDK // From LibRaw { "Canon PowerShot A470", 0, 0, /* DJC */ { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, { "Canon PowerShot A610", 0, 0, /* DJC */ @@ -8327,14 +8401,24 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 S2 IS", 0, 0, + { 5477,-1435,-992,-1868,6639,510,-58,792,2670 } }, // CHDK // From LibRaw { "Canon PowerShot S3 IS", 0, 0, /* DJC */ { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { "Canon PowerShot SX120 IS", 0, 0, + { 7286,-2242,-1047,41,4401,457,269,684,1864 } }, // CHDK // From LibRaw { "Canon PowerShot SX220", 0, 0, /* DJC */ { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, + { "Canon PowerShot SX710 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, // From LibRaw { "Canon IXUS 160", 0, 0, /* DJC */ { 11657,-3781,-1136,-3544,11262,2283,-160,1219,4700 } }, + { "Casio EX-F1", 0, 0, + { 9084,-2016,-848,-6711,14351,2570,-1059,1725,6135 } }, // From LibRaw + { "Casio EX-FH100", 0, 0, + { 12771,-4179,-1558,-2149,10938,1375,-453,1751,4494 } }, // From LibRaw { "Casio EX-S20", 0, 0, /* DJC */ { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, { "Casio EX-Z750", 0, 0, /* DJC */ @@ -8353,6 +8437,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Epson R-D1", 0, 0, { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "Fujifilm DBP for GX680", 128, 0x0fff, + { 12741,-4916,-1420,-8510,16791,1715,-1767,2302,7771 } }, /* temp, copy from S2Pro */ // From LibRaw { "Fujifilm E550", 0, 0, { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, { "Fujifilm E900", 0, 0, @@ -8365,9 +8451,15 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm F7", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm F810", 0, 0, + { 11044,-3888,-1120,-7248,15167,2208,-1531,2276,8069 } }, // From LibRaw { "Fujifilm F8", 0, 0, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, - { "Fujifilm GFX 50S", 0, 0, + { "Fujifilm GFX 100 II", 0, 0, + { 12806,-5779,-1110,-3546,11507,2318,-177,996,5715 } }, // From LibRaw + { "Fujifilm GFX 100", 0, 0, // same CMs: "GFX 100", "GFX 100S"/"GFX100S", "GFX 100 IR" + { 16212,-8423,-1583,-4336,12583,1937,-195,726,6199 } }, // From LibRaw + { "Fujifilm GFX 50", 0, 0, // same CMs: "GFX 50S", "GFX 50R", "GFX 50S II" { 11756,-4754,-874,-3056,11045,2305,-381,1457,6006 } }, { "Fujifilm S100FS", 514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, @@ -8411,7 +8503,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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, + { "Fujifilm HS10", 0, 0xf68, { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, { "Fujifilm HS2", 0, 0xfef, { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, @@ -8427,6 +8519,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, { "Fujifilm X100T", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100V", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // From LibRaw { "Fujifilm X100", 0, 0, { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, { "Fujifilm X10", 0, 0, @@ -8441,6 +8535,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-Pro2", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { "Fujifilm X-Pro3", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // From LibRaw { "Fujifilm X-A10", 0, 0, { 11540,-4999,-991,-2949,10963,2278,-382,1049,5605 } }, { "Fujifilm X-A20", 0, 0, @@ -8453,6 +8549,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12407,-5222,-1086,-2971,11116,2120,-294,1029,5284 } }, { "Fujifilm X-A5", 0, 0, { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, + { "Fujifilm X-A7", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, // From LibRaw { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-E2S", 0, 0, @@ -8461,22 +8559,123 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm X-E3", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { "Fujifilm X-E4", 0, 0, + { 13426, -6334, -1177, -4244, 12136, 2371, -580, 1303, 5980 } }, // From LibRaw { "Fujifilm X-H1", 0, 0, { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { "Fujifilm X-H2S", 0, 0, + { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, // From LibRaw + { "Fujifilm X-H2", 0, 0, + { 11809, -5358, -1141, -4248, 12164, 2343, -514, 1097, 5848 } }, // From LibRaw { "Fujifilm X-M1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-S20", 0, 0, + { 12836, -5909, -1032, -3087, 11132, 2236, -35, 872, 5330 } }, // From LibRaw + { "Fujifilm X-S10", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,-580,1303,5980 } }, // From LibRaw { "Fujifilm X-S1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-T100", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, // From LibRaw { "Fujifilm X-T1", 0, 0, /* also X-T10 */ { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm X-T200", 0, 0, + { 15055,-7391,-1274,-4062,12071,2238,-610,1217,6147 } }, // From LibRaw { "Fujifilm X-T2", 0, 0, /* also X-T20 */ { 11434,-4948,-1210,-3746,12042,1903,-666,1479,5235 } }, + { "Fujifilm X-T3", 0, 0, // same CMs: X-T3, X-T30, "X-T30 II" + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // v.2 // From LibRaw + { "Fujifilm X-T4", 0, 0, + { 13426,-6334,-1177,-4244,12136,2371,580,1303,5980 } }, // From LibRaw + { "Fujifilm X-T5", 0, 0, + { 11809, -5358, -1141, -4248, 12164, 2343, -514, 1097, 5848 } }, // From LibRaw + { "Fujifilm XF10", 0, 0, + { 11673,-4760,-1041,-3988,12058,2166,-771,1417,5569 } }, // From LibRaw { "Fujifilm XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { "Fujifilm XQ", 0, 0, /* XQ1 and XQ2 */ { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, + { "GITUP G3DUO", 130, 62000, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, // From LibRaw + { "GITUP GIT2P", 4160, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, // From LibRaw + { "GITUP GIT2", 3200, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, // From LibRaw { "GoPro HERO5 Black", 0, 0, { 10344,-4210,-620,-2315,10625,1948,93,1058,5541 } }, + { "Hasselblad L1D-20c", 0, 0, + { 7310, -2746, -646, -2991, 10847, 2469, 163, 585, 6324}}, // From LibRaw +// TODO: These Hasselblad camera names are from LibRaw. dcraw names are different. +// { "Hasselblad 16-Uncoated-3FR", 0, 0, +// { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, +// { "Hasselblad 16-Uncoated-FFF", 0, 0, +// { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, +// { "Hasselblad 16-Uncoated", 0, 0, +// { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, +// { "Hasselblad 22-Uncoated-3FR", 0, 0, +// { 8523, -3257, -280, -5078, 13458, 1743, -1449, 2961, 7809}}, +// { "Hasselblad 22-Uncoated-FFF", 0, 0, +// { 8068, -2959, -108, -5788, 13608, 2389, -1002, 2237, 8162}}, +// { "Hasselblad 22-Uncoated", 0, 0, +// { 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809}}, +// { "Hasselblad 31-Uncoated-FFF", 0, 0, +// { 5155, -1201, 200, -5841, 13197, 2950, -1101, 2317, 6988}}, +// { "Hasselblad 31-Uncoated", 0, 0, +// { 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710}}, +// { "Hasselblad 39-Uncoated-3FR", 0, 0, +// { 3904, -100, 262, -4318, 12407, 2128, -1598, 3594, 6233}}, +// { "Hasselblad 39-Uncoated-FFF", 0, 0, +// { 4739, -932, 295, -4829, 12220, 2952, -1027, 2341, 7083}}, +// { "Hasselblad 39-Uncoated", 0, 0, +// { 3894, -110, 287, -4672, 12610, 2295, -2092, 4100, 6196}}, +// { "Hasselblad 39-Coated-3FR", 0, 0, +// { 5427, -1147, 173, -3834, 12073, 1969, -1444, 3320, 5621}}, +// { "Hasselblad 39-Coated-FFF", 0, 0, +// { 5323, -1233, 399, -4926, 12362, 2894, -856, 2471, 5961}}, +// { "Hasselblad 39-Coated", 0, 0, +// { 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718}}, +// { "Hasselblad 40-Coated5-3FR", 0, 0, +// { 7014, -2067, -540, -4821, 13016, 1980, -1663, 3089, 6940}}, +// { "Hasselblad 40-Coated5-FFF", 0, 0, +// { 5963, -1357, -172, -5439, 12762, 3007, -964, 2222, 7172}}, +// { "Hasselblad 40-Coated5", 0, 0, +// { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, +// { "Hasselblad 40-Coated-3FR", 0, 0, +// { 6550, -1681, -399, -4626, 12598, 2257, -1807, 3354, 6486}}, +// { "Hasselblad 40-Coated-FFF", 0, 0, +// { 6041, -1375, -174, -5439, 10000, 3007, -930, 2145, 6923}}, +// { "Hasselblad 40-Coated", 0, 0, +// { 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104}}, +// { "Hasselblad 50-Coated5-3FR", 0, 0, +// { 5707, -693, -382, -4285, 12669, 1773, -1615, 3519, 5410}}, +// { "Hasselblad 50-Coated5-FFF", 0, 0, +// { 5263, -612, 39, -4950, 12426, 2843, -935, 2423, 5941}}, +// { "Hasselblad 50-Coated5", 0, 0, +// { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, +// { "Hasselblad 50-Coated-3FR", 0, 0, +// { 5656, -659, -346, -3923, 12305, 1790, -1602, 3509, 5442}}, +// { "Hasselblad 50-Coated-FFF", 0, 0, +// { 5280, -614, 39, -4950, 12426, 2843, -939, 2434, 5968}}, +// { "Hasselblad 50-Coated", 0, 0, +// { 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442}}, +// { "Hasselblad 50-15-Coated5-II-3FR", 0, 0, +// { 10887, -6152, 1034, -3564, 12412, 4224, 63, 626, 10123}}, +// { "Hasselblad 50-15-Coated5-II-FFF", 0, 0, +// { 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067}}, +// { "Hasselblad 50-15-Coated5-II", 0, 0, +// { 8737, -4937, 830, -2860, 9961, 3390, 51, 502, 8124}}, +// { "Hasselblad 50-15-Coated5", 0, 0, +// { 4932,-835,141,-4878,11868,3437,-1138,1961,7067 } }, +// { "Hasselblad 60-Coated-3FR", 0, 0, +// { 9296, 336, -1088, -6442, 14323, 2289, -1433, 2942, 5756}}, +// { "Hasselblad 60-Coated", 0, 0, +// { 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024}}, +// { "Hasselblad 100-17-Coated5", 0, 0, +// { 5110, -1357, -308, -5573, 12835, 3077, -1279, 2025, 7010}}, +// { "Hasselblad 100-20-Coated6", 0, 0, +// { 6468,-1899,-545,-4526,12267,2542,-388,1276,6096 } }, + { "HTC One A9", 64, 1023, + { 101,-20,-2,-11,145,41,-24,1,56 } }, /* this is FM1 transposed */ // From LibRaw { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, { "Kodak NC2000", 0, 0, @@ -8487,11 +8686,11 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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, + { "Kodak DCS46", 0, 0, // same CM as EOSDCS1 and DCS465 DB { 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, + { "Kodak EOSDCS3", 0, 0, { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, { "Kodak DCS520C", 178, 0, { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, @@ -8517,6 +8716,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, { "Kodak ProBack", 0, 0, { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "Kodak PIXPRO AZ901", 0, 0, // dng + { 21875, -8006, -2558, 634, 8194, 1104, 1535, 951, 6969}}, // From LibRaw { "Kodak P712", 0, 0, { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, { "Kodak P850", 0, 0xf7c, @@ -8531,16 +8732,62 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } }, { "Kodak EASYSHARE Z1015", 0, 0xef1, { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + { "Leaf AFi 54S", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw + { "Leaf AFi 65S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, // From LibRaw + { "Leaf AFi 75S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, // From LibRaw { "Leaf CMost", 0, 0, { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Credo 40", 0, 0, + { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, // From LibRaw + { "Leaf Credo 50", 0, 0, // emb + { 10325, 845, -604, -4113, 13385, 481, -1791, 4163, 6924}}, // From LibRaw + { "Leaf Credo 60", 0, 0, + { 8035, 435, -962, -6001, 13872, 2320, -1159, 3065, 5434}}, // From LibRaw + { "Leaf Credo 80", 0, 0, + { 6294, 686, -712, -5435, 13417, 2211, -1006, 2435, 5042}}, // From LibRaw + { "Leaf Valeo 11", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw + { "Leaf Valeo 17", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw + { "Leaf Valeo 22", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw { "Leaf Valeo 6", 0, 0, { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf AFi-II 7", 0, 0, + { 7691,-108,-339,-6185,13627,2833,-2046,3899,5952 } }, // From LibRaw + { "Leaf AFi-II 10", 0, 0, + { 6719,1147,-148,-6929,14061,3176,-1781,3343,5424 } }, // From LibRaw + { "Leaf Aptus 17", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw + { "Leaf Aptus 22", 0, 0, + { 8236, 1746, -1313, -8251, 15953, 2428, -3672, 5786, 5771}}, // From LibRaw { "Leaf Aptus 54S", 0, 0, { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Leaf Aptus 65S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, // From LibRaw { "Leaf Aptus 65", 0, 0, { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus 75S", 0, 0, + { 7914, 1414, -1190, -8776, 16582, 2280, -2811, 4605, 5562}}, // From LibRaw { "Leaf Aptus 75", 0, 0, { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus-II 5", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, // From LibRaw + { "Leaf Aptus-II 6", 0, 0, + { 7989,-113,-352,-6185,13627,2833,-2028,3866,5901 } }, // From LibRaw + { "Leaf Aptus-II 7", 0, 0, + { 8209,-116,-362,-6185,13627,2833,-1962,3740,5709 } }, // From LibRaw + { "Leaf Aptus-II 8", 0, 0, + { 7361,1257,-163,-6929,14061,3176,-1839,3454,5603 } }, // From LibRaw + { "Leaf Aptus-II 10R", 0, 0, + { 7167,1224,-158,-6929,14061,3176,-1826,3429,5562 } }, // From LibRaw + { "Leaf Aptus-II 10", 0, 0, + { 7527,1285,-166,-6929,14061,3176,-1995,3747,6077 } }, // From LibRaw + { "Leaf Aptus-II 12", 0, 0, + { 7361,1257,-163,-6929,14061,3176,-1695,3182,5162 } }, // From LibRaw { "Leaf", 0, 0, { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, { "Mamiya ZD", 0, 0, @@ -8551,6 +8798,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 7i", 0, 0xf7d, + { 11050,-3791,-1199,-7875,15585,2434,-2797,3359,7560 } }, // From LibRaw { "Minolta DiMAGE 7", 0, 0xf7d, { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, { "Minolta DiMAGE A1", 0, 0xf8b, @@ -8591,6 +8840,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D3400", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D3500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, // From LibRaw { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, { "Nikon D3X", 0, 0, @@ -8633,6 +8884,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D60", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "Nikon D6", 0, 0, + { 9028,-3423,-1035,-6321,14265,2217,-1013,1683,6928 } }, // From LibRaw { "Nikon D7000", 0, 0, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D7100", 0, 0, @@ -8641,6 +8894,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { "Nikon D7500", 0, 0, { 8813,-3210,-1036,-4703,12868,2021,-1054,1940,6129 } }, + { "Nikon D780", 0, 0, + { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, // From LibRaw { "Nikon D750", 0, 0, { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { "Nikon D700", 0, 0, @@ -8649,6 +8904,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D850", 0, 0, { 10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785 } }, + { "Nikon D810A", 0, 0, + { 11973,-5685,-888,-1965,10326,1901,-115,1123,7169 } }, // From LibRaw { "Nikon D810", 0, 0, { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, { "Nikon D800", 0, 0, @@ -8687,6 +8944,24 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { "Nikon E8800", 0, 0, { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "Nikon Z 30", 0, 0, + { 10339,-3822,-890,-4183,12023,2436,-671,1638,7049 } }, // From LibRaw + { "Nikon Z 50", 0, 0, + { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, // From LibRaw + { "Nikon Z 5", 0, 0, + { 8695,-2558,-648,-5015,12711,2575,-1279,2215,7514 } }, // From LibRaw + { "Nikon Z 6", 0, 0, + { 9943,-3269,-839,-5323,13269,2259,-1198,2083,7557 } }, // 'Z 6'(v.2) // From LibRaw, 'Z 6_2' + { "Nikon Z 7", 0, 0, + { 13705,-6004,-1400,-5464,13568,2062,-940,1706,7618 } }, // 'Z 7'(v.2), 'Z 7_2' // From LibRaw + { "Nikon Z 8", 0, 0, + {11423,-4564,-1123,-4816,12895,2119,-210,1061,7282 } }, // From LibRaw + { "Nikon Z 9", 0, 0, + { 13389,-6049,-1441,-4544,12757,1969,229,498,7390 } }, // From LibRaw + { "Nikon Z fc", 0, 0, + { 11640,-4829,-1079,-5107,13006,2325,-972,1711,7380 } }, // From LibRaw + { "Nikon COOLPIX A1000", 0, 0, + { 10601,-3487,-1127,-2931,11443,1676,-587,1740,5278 } }, // From LibRaw { "Nikon COOLPIX A", 0, 0, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon COOLPIX B700", 200, 0, @@ -8695,6 +8970,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P340", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon Coolpix P950", 0, 0, + { 13307, -5641, -1290, -2048, 10581, 1689, -64, 1222, 5176}}, // From LibRaw + { "Nikon COOLPIX P1000", 0, 0, + { 14294,-6116,-1333,-1628,10219,1637,-14,1158,5022 } }, // From LibRaw { "Nikon COOLPIX P6000", 0, 0, { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, { "Nikon COOLPIX P7000", 0, 0, @@ -8775,6 +9054,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-P5", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-P7", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, // From LibRaw + { "Olympus E-PL10", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, // From LibRaw { "Olympus E-PL1s", 0, 0, { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, { "Olympus E-PL1", 0, 0, @@ -8797,12 +9080,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M10MarkIV", 0, 0, + { 9476,-3182,-765,-2613,10958,1893,-449,1315,5268 } }, // From LibRaw { "Olympus E-M10", 0, 0, /* also E-M10 Mark II & III */ { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M1X", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, // From LibRaw + { "Olympus E-M1MarkIII", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, // From LibRaw { "Olympus E-M1Mark II", 0, 0, { 9383,-3170,-763,-2457,10702,2020,-384,1236,5552 } }, { "Olympus E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + { "Olympus E-M5MarkIII", 0, 0, + { 11896,-5110,-1076,-3181,11378,2048,-519,1224,5166 } }, // From LibRaw { "Olympus E-M5MarkII", 0, 0, { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, @@ -8824,13 +9115,15 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, { "Olympus SP560UZ", 0, 0xff9, { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { "Olympus SP565UZ", 0, 0, + { 11856,-4469,-1159,-4814,12368,2756,-993,1779,5589 } }, // From LibRaw { "Olympus SP570UZ", 0, 0, { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, { "Olympus STYLUS1", 0, 0, { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, { "Olympus TG-4", 0, 0, { 11426,-4159,-1126,-2066,10678,1593,-120,1327,4998 } }, - { "Olympus TG-5", 0, 0, + { "Olympus TG-", 0, 0, // same CMs: TG-5, TG-6 { 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, @@ -8840,6 +9133,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "OM Digital Solutions OM-1", 0, 0, { 9488, -3984, -714, -2887, 10945, 2229, -137, 960, 5786 } }, // From LibRaw + { "OM Digital Solutions OM-5", 0, 0, + { 11896, -5110, -1076, -3181, 11378, 2048, -519, 1224, 5166 } }, // From LibRaw { "OmniVision", 0, 0, /* DJC */ { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, { "Pentax *ist DL2", 0, 0, @@ -8852,6 +9147,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, { "Pentax *ist D", 0, 0, { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "Pentax K-01", 0, 0, + { 8134,-2728,-645,-4365,11987,2694,-838,1509,6498 } }, // From LibRaw { "Pentax K10D", 0, 0, { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } }, { "Pentax K1", 0, 0, @@ -8872,10 +9169,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8596,-2981,-639,-4202,12046,2431,-685,1424,6122 } }, { "Pentax K-30", 0, 0, { 8710,-2632,-1167,-3995,12301,1881,-981,1719,6535 } }, + { "Pentax K-3 Mark III", 0, 0, + { 9251, -3817, -1069, -4627, 12667, 2175, -798, 1660, 5633 } }, // From LibRaw { "Pentax K-3 II", 0, 0, { 8626,-2607,-1155,-3995,12301,1881,-1039,1822,6925 } }, { "Pentax K-3", 0, 0, { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, + { "Pentax K-500", 0, 0, + { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, // From LibRaw + { "Pentax K-50", 0, 0, + { 8109,-2740,-608,-4593,12175,2731,-1006,1515,6545 } }, // From LibRaw { "Pentax K-5 II", 0, 0, { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, { "Pentax K-5", 0, 0, @@ -8892,8 +9195,18 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8617,-3228,-1034,-4674,12821,2044,-803,1577,5728 } }, { "Pentax Q-S1", 0, 0, { 12995,-5593,-1107,-1879,10139,2027,-64,1233,4919 } }, + { "Pentax Q7", 0, 0, + { 10901,-3938,-1025,-2743,11210,1738,-823,1805,5344 } }, // From LibRaw + { "Pentax Q10", 0, 0, + { 11562,-4183,-1172,-2357,10919,1641,-582,1726,5112 } }, // From LibRaw + { "Pentax Q", 0, 0, + { 11731,-4169,-1267,-2015,10727,1473,-217,1492,4870 } }, // From LibRaw + { "Pentax MX-1", 0, 0, + { 9296,-3146,-888,-2860,11287,1783,-618,1698,5151 } }, // From LibRaw { "Pentax 645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "Pentax 645Z", 0, 0, + { 9519,-3591,-664,-4074,11725,2671,-624,1501,6653 } }, // From LibRaw { "Panasonic DMC-CM1", 15, 0, { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, { "Panasonic DC-FZ80", 0, 0, @@ -8932,6 +9245,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { "Leica DIGILUX 2", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DC-LX100M2", 15, 0, + { 8585,-3127,-833,-4005,12250,1953,-650,1494,4862 } }, // v.2 // From LibRaw { "Panasonic DMC-LX100", 15, 0, { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, { "Leica D-LUX (Typ 109)", 15, 0, @@ -8962,6 +9277,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, { "Panasonic DMC-LX9", 15, 0, { 7790,-2736,-755,-3452,11870,1769,-628,1647,4898 } }, + { "Panasonic DC-FZ10002", 15, 0, + { 9803,-4185,-992,-4066,12578,1628,-838,1824,5288 } }, // From LibRaw { "Panasonic DMC-FZ1000", 15, 0, { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, { "Leica V-LUX (Typ 114)", 15, 0, @@ -8996,12 +9313,26 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-G8", 15, 0xfff, /* G8, G80, G81, G85 */ { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DC-S1R", 0, 0, + { 11822,-5321,-1249,-5958,15114,766,-614,1264,7043 } }, // From LibRaw + { "Panasonic DC-S1H", 0, 0, + { 9397,-3719,-805,-5425,13326,2309,-972,1715,6034 } }, // From LibRaw + { "Panasonic DC-S1", 0, 0, + { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, // From LibRaw { "Panasonic DC-S5M2", 0, 0, /* DC-S5M2, DC-S5M2X */ { 10308,-4206,-783,-4088,12102,2229,-125,1051,5912 } }, + { "Panasonic DC-S5", 0, 0, + { 9744,-3905,-779,-4899,12807,2324,-798,1630,5827 } }, // From LibRaw + { "Panasonic DC-G99", 15, 0, + { 9657,-3963,-748,-3361,11378,2258,-568,1415,5158 } }, // From LibRaw + { "Panasonic DC-G100", 15, 0, + { 8370,-2869,-710,-3389,11372,2298,-640,1599,4887 } }, // From LibRaw { "Panasonic DC-G9M2", 0, 0, { 8325,-3456,-623,-4330,12089,2528,-860,2646,5984 } }, { "Panasonic DC-G9", 15, 0xfff, { 7685,-2375,-634,-3687,11700,2249,-748,1546,5111 } }, + { "Panasonic DC-GF10", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, // From LibRaw { "Panasonic DMC-GF1", 15, 0xf92, { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, { "Panasonic DMC-GF2", 15, 0xfff, @@ -9062,28 +9393,74 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8550,-2908,-842,-3195,11529,1881,-338,1603,4631 } }, { "Panasonic DMC-ZS70", 15, 0, { 9052,-3117,-883,-3045,11346,1927,-205,1520,4730 } }, + { "Panasonic DMC-ZS80", 15, 0, + { 12194,-5340,-1329,-3035,11394,1858,-50,1418,5219 } }, // From LibRaw { "Leica S (Typ 007)", 0, 0, { 6063,-2234,-231,-5210,13787,1500,-1043,2866,6997 } }, + { "Leica X2", 0, 0, + { 8336,-2853,-699,-4425,11989,2760,-954,1625,6396 } }, // From LibRaw + { "Leica X1", 0, 0, + { 9055,-2611,-666,-4906,12652,2519,-555,1384,7417 } }, // From LibRaw { "Leica X", 0, 0, /* X and X-U, both (Typ 113) */ { 7712,-2059,-653,-3882,11494,2726,-710,1332,5958 } }, { "Leica Q (Typ 116)", 0, 0, { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, + { "Leica Q2", 0, 0, + { 12312,-5440,-1307,-6408,15499,824,-1075,1677,7220 } }, // From LibRaw { "Leica M (Typ 262)", 0, 0, { 6653,-1486,-611,-4221,13303,929,-881,2416,7226 } }, + { "Leica M (Typ 2", 0, 0, // same CMs: "M (Typ 240)", "M-D (Typ 262)" + { 7199,-2140,-712,-4005,13327,649,-810,2521,6673 } }, // From LibRaw { "Leica SL (Typ 601)", 0, 0, { 11865,-4523,-1441,-5423,14458,935,-1587,2687,4830 } }, + { "Leica S2", 0, 0, + { 5627,-721,-447,-4423,12456,2192,-1048,2948,7379 } }, // From LibRaw + { "Leica S3", 0, 0, + { 5092,-1630,-470,-6313,14297,2170,-1603,3135,5982 } }, // From LibRaw + { "Leica S", 0, 0, // same CMs: "S-E (Typ 006)", "S (Typ 006)" + { 5749,-1072,-382,-4274,12432,2048,-1166,3104,7105 } }, // From LibRaw { "Leica TL2", 0, 0, { 5836,-1626,-647,-5384,13326,2261,-1207,2129,5861 } }, { "Leica TL", 0, 0, { 5463,-988,-364,-4634,12036,2946,-766,1389,6522 } }, + { "Leica T", 0, 0, // same CMs: TL, "T (Typ 701)" + { 6295,-1679,-475,-5586,13046,2837,-1410,1889,7075 } }, // From LibRaw { "Leica CL", 0, 0, { 7414,-2393,-840,-5127,13180,2138,-1585,2468,5064 } }, + { "Leica M8", 0, 0, + { 7675,-2196,-305,-5860,14119,1856,-2425,4006,6578 } }, // From LibRaw + { "Leica M9", 0, 0, + { 6687,-1751,-291,-3556,11373,2492,-548,2204,7146 } }, // From LibRaw { "Leica M10", 0, 0, { 8249,-2849,-620,-5415,14756,565,-957,3074,6517 } }, { "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 IQ140", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, // From LibRaw + { "Phase One IQ150", 0, 0, + {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* temp */ /* emb // From LibRaw */ + { "Phase One IQ160", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, // From LibRaw + { "Phase One IQ180", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, // From LibRaw + { "Phase One IQ250",0, 0, + {10325,845,-604,-4113,13385,481,-1791,4163,6924}}, /* emb */ // From LibRaw + { "Phase One IQ260", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, // From LibRaw + { "Phase One IQ280", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, // From LibRaw + { "Phase One IQ3 100MP", 0, 0, + { 10999,354,-742,-4590,13342,937,-1060,2166,8120} }, /* emb */ // From LibRaw + { "Phase One IQ3 50MP", 0, 0, + {10058,1079,-587,-4135,12903,944,-916,2726,7480}}, /* emb */ // From LibRaw + { "Phase One IQ3 60MP", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, // From LibRaw + { "Phase One IQ3 80MP", 0, 0, + { 6294,686,-712,-5435,13417,2211,-1006,2435,5042 } }, // From LibRaw + { "Phase One P21", 0, 0, + { 6516,-2050,-507,-8217,16703,1479,-3492,4741,8489 } }, // From LibRaw { "Phase One P 2", 0, 0, { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, { "Phase One P 30", 0, 0, @@ -9096,20 +9473,60 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, { "Photron BC2-HD", 0, 0, /* DJC */ { 14603,-4122,-528,-1810,9794,2017,-297,2763,5936 } }, + { "Polaroid x530", 0, 0, + { 13458,-2556,-510,-5444,15081,205,0,0,12120 } }, // From LibRaw { "Red One", 704, 0xffff, /* DJC */ { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, + { "Ricoh S10 24-72mm F2.5-4.4 VC", 0, 0, + { 10531,-4043,-878,-2038,10270,2052,-107,895,4577 } }, // From LibRaw + { "Ricoh GR A12 50mm F2.5 MACRO", 0, 0, + { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, // From LibRaw + { "Ricoh GR DIGITAL 2", 0, 0, + { 8846,-2704,-729,-5265,12708,2871,-1471,1955,6218 } }, // From LibRaw + { "Ricoh GR DIGITAL 3", 0, 0, + { 8170,-2496,-655,-5147,13056,2312,-1367,1859,5265 } }, // From LibRaw + { "Ricoh GR DIGITAL 4", 0, 0, + { 8771,-3151,-837,-3097,11015,2389,-703,1343,4924 } }, // From LibRaw + { "Ricoh GR III", 0, 0, + { 6127,-1777,-585,-5913,13699,2428,-1088,1780,6017 } }, // From LibRaw { "Ricoh GR II", 0, 0, { 4630,-834,-423,-4977,12805,2417,-638,1467,6115 } }, { "Ricoh GR", 0, 0, { 3708,-543,-160,-5381,12254,3556,-1471,1929,8234 } }, + { "Ricoh GX200", 0, 0, + { 8040,-2368,-626,-4659,12543,2363,-1125,1581,5660 } }, // From LibRaw + { "Ricoh GXR Mount A12", 0, 0, + { 7834,-2182,-739,-5453,13409,2241,-952,2005,6620 } }, // From LibRaw + { "Ricoh GXR A12 50mm", 0, 0, + { 8849,-2560,-689,-5092,12831,2520,-507,1280,7104 } }, // From LibRaw + { "Ricoh GXR A12 28mm", 0, 0, + { 10228,-3159,-933,-5304,13158,2371,-943,1873,6685 } }, // From LibRaw + { "Ricoh GXR A16", 0, 0, + { 7837,-2538,-730,-4370,12184,2461,-868,1648,5830 } }, // From LibRaw + { "Ricoh GXR P10", 0, 0, + { 13168,-5128,-1663,-3006,11569,1611,-373,1244,4907 } }, // From LibRaw + { "Ricoh GXR S10", 0, 0, + { 8963,-2926,-754,-4881,12921,2164,-1464,1944,4901 } }, // From LibRaw { "Samsung EX1", 0, 0x3e00, { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, { "Samsung EX2F", 0, 0x7ff, { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, { "Samsung EK-GN120", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung Galaxy S6", 0, 0, // same CMs: "Galaxy S6", "Galaxy S6 Edge" + { 13699,-5767,-1384,-4449,13879,499,-467,1691,5892 } }, // From LibRaw + { "Samsung Galaxy S7", 0, 0, // same CMs: "Galaxy S7", "Galaxy S7 Edge" + { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, // From LibRaw + { "Samsung Galaxy S8", 0, 0, // same CMs: "Galaxy S8", "Galaxy S8+" + { 9927,-3704,-1024,-3935,12758,1257,-389,1512,4993 } }, // From LibRaw + { "Samsung Galaxy S9", 0, 0, // same CMs: "Galaxy S9", "Galaxy S9+" + { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, // From LibRaw + { "Samsung Galaxy Note 9 Rear Camera", 0, 0, + { 13292,-6142,-1268,-4095,12890,1283,-557,1930,5163 } }, // From LibRaw { "Samsung NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + { "Samsung NX U", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, // From LibRaw { "Samsung NX3300", 0, 0, { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, { "Samsung NX3000", 0, 0, @@ -9136,6 +9553,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { "Samsung WB2000", 0, 0xfff, { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, + { "Samsung WB5000", 0, 0, + { 7675, -2195, -305, -5860, 14118, 1857, -2425, 4007, 6578}}, // From LibRaw { "Samsung GX-1", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, { "Samsung GX20", 0, 0, /* copied from Pentax K20D */ @@ -9150,6 +9569,20 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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-HX9", 200, 0, // same CMs: DSC-HX95, DSC-HX99. RT: BL divided by 4 + { 13076,-5686,-1481,-4027,12851,1251,-167,725,4937 } }, // From LibRaw + { "Sony ZV-1", 200, 0, // same CMs: ZV-1, ZV-1B, ZV-1M2. RT: BL divided by 4 + { 8280,-2987,-703,-3531,11645,2133,-550,1542,5312 } }, // From LibRaw + { "Sony ZV-E10", 0, 0, + { 6355,-2067,-490,-3653,11542,2400,-406,1258,5506 } }, // From LibRaw + { "Sony ZV-E1", 0, 0, + { 6912,-2127,-469,-4470,12175,2587,-398,1478,6492 } }, // From LibRaw + { "Sony DSC-RX100M7", 0, 0, + {10315, -4390, -937, -4859, 12734, 2365, -734, 1537, 5997 } }, // From LibRaw + { "Sony DSC-RX100M6", 0, 0, + { 7325,-2321,-596,-3494,11674,2055,-668,1562,5031 } }, // From LibRaw + { "Sony DSC-RX100M5A", 0, 0, + { 11176,-4700,-965,-4004,12184,2032,-763,1726,5876 } }, // From LibRaw { "Sony DSC-RX100M", 0, 0, /* M2, M3, M4, and M5 */ { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Sony DSC-RX100", 0, 0, @@ -9160,6 +9593,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, { "Sony DSC-RX1RM2", 0, 0, { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, + { "Sony DSC-RX1R", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, // From LibRaw { "Sony DSC-RX1", 0, 0, { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, { "Sony DSC-RX0", 200, 0, @@ -9200,28 +9635,56 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, { "Sony ILCA-99M2", 0, 0, { 6660,-1918,-471,-4613,12398,2485,-649,1433,6447 } }, + { "Sony ILCE-1", 0, 0, + { 8161, -2947, -739, -4811, 12668, 2389, -437, 1229, 6524}}, // From LibRaw + { "Sony ILCE-6100", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, // From LibRaw + { "Sony ILCE-6300", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { "Sony ILCE-6400", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, // From LibRaw + { "Sony ILCE-6500", 0, 0, + { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, + { "Sony ILCE-6600", 0, 0, + { 7657,-2847,-607,-4083,11966,2389,-684,1418,5844 } }, // From LibRaw { "Sony ILCE-6700", 0, 0, { 6972,-2408,-600,-4330,12101,2515,-388,1277,5847 } }, - { "Sony ILCE-6", 0, 0, /* 6300, 6500 */ - { 5973,-1695,-419,-3826,11797,2293,-639,1398,5789 } }, { "Sony ILCE-7M2", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, { "Sony ILCE-7M3", 0, 0, { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, + { "Sony ILCE-7M4", 0, 0, + { 7460,-2365,-588,-5687,13442,2474,-624,1156,6584 } }, // From LibRaw + { "Sony ILCE-7SM3", 0, 0, + { 6912,-2127,-469,-4470,12175,2587,-398,1478,6492 } }, // From LibRaw { "Sony ILCE-7S", 0, 0, /* also ILCE-7SM2 */ { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, + { "Sony ILCE-7RM5", 0, 0, + { 8200, -2976, -719, -4296, 12053, 2532, -429, 1282, 5774 } }, // From LibRaw + { "Sony ILCE-7RM4", 0, 0, // same CMs: ILCE-7RM4, ILCE-7RM4A + { 7662, -2686,-660,-5240, 12965,2530, -796, 1508, 6167 } }, // From LibRaw { "Sony ILCE-7RM3", 0, 0, { 6640,-1847,-503,-5238,13010,2474,-993,1673,6527 } }, { "Sony ILCE-7RM2", 0, 0, { 6629,-1900,-483,-4618,12349,2550,-622,1381,6514 } }, { "Sony ILCE-7R", 0, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + { "Sony ILCE-7CR", 0, 0, + { 8200,-2976,-719,-4296,12053,2532,-429,1282,5774 } }, // temp // From LibRaw + { "Sony ILCE-7CM2", 0, 0, + { 7460,-2365,-588,-5687,13442,2474,-624,1156,6584 } }, // temp // From LibRaw + { "Sony ILCE-7C", 0, 0, + { 7374,-2389,-551,-5435,13162,2519,-1006,1795,6552 } }, // From LibRaw { "Sony ILCE-7", 0, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, { "Sony ILCE-9", 0, 0, { 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 } }, { "Sony ILCE", 0, 0, /* 3000, 5000, 5100, 6000, and QX1 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony ILME-FX30", 0, 0, + { 6972, -2408, -600, -4330, 12101, 2515, -388, 1277, 5847 } }, // From LibRaw + { "Sony ILME-FX3", 0, 0, + { 6912, -2127, -469, -4470, 12175, 2587, -398, 1478, 6492 } }, // From LibRaw { "Sony NEX-5N", 0, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony NEX-5R", 0, 0, @@ -9242,6 +9705,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-7", 0, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony NEX-VG30", 0, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, // From LibRaw + { "Sony NEX-VG900", 0, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, // From LibRaw { "Sony NEX", 0, 0, /* NEX-C3, NEX-F3 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony SLT-A33", 0, 0, From a4724b2d6ebf7455ff6998e2b94a6731249b300e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:27:35 -0700 Subject: [PATCH 232/291] Remove libraw-copylib from pre-dev publishing --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index aacdfb75b..c7e699d3f 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Lawrence37:libraw-copylib"]' + publish_pre_dev_labels: '[]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d785e9cfe..7555891d3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '["Lawrence37:libraw-copylib"]' + publish_pre_dev_labels: '[]' jobs: From a1c6ce5dd2b34df5a55e0073aef5b07deaab4280 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 16 Jun 2024 07:35:50 +0200 Subject: [PATCH 233/291] Selective editing - adds the feather slider for each Graduated Filter (#7079) * Feather GF color and vibrance * Feather exposure * Graduated filer feather wavelet * Graduated filter feather log * Graduated filter Cam16 feather * Change history msg * GF shadows highlight feather * GF mask common feather * Move feather settings in settings mask * Change history msg * Change label feather * Change 2 labels --- rtdata/languages/default | 18 ++++++++--- rtengine/iplocallab.cc | 43 ++++++++++++++++++++++++-- rtengine/procparams.cc | 34 ++++++++++++++++++++- rtengine/procparams.h | 8 +++++ rtgui/controlspotpanel.cc | 5 ++-- rtgui/locallabtools.cc | 63 +++++++++++++++++++++++++++++++++++++-- rtgui/locallabtools.h | 16 ++++++++++ rtgui/locallabtools2.cc | 60 +++++++++++++++++++++++++++++++++++++ rtgui/paramsedited.cc | 58 ++++++++++++++++++++++++++++++++++- rtgui/paramsedited.h | 8 +++++ 10 files changed, 300 insertions(+), 13 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 75d060dec..f8f7cf114 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1068,7 +1068,7 @@ HISTORY_MSG_829;Local - SH gradient angle HISTORY_MSG_830;Local - Color gradient strength L HISTORY_MSG_831;Local - Color gradient angle HISTORY_MSG_832;Local - Color gradient strength C -HISTORY_MSG_833;Local - TG - Feather gradient +HISTORY_MSG_833;Local - Mask gradient feather HISTORY_MSG_834;Local - Color gradient strength H HISTORY_MSG_835;Local - Vib gradient strength L HISTORY_MSG_836;Local - Vib gradient angle @@ -1502,6 +1502,15 @@ HISTORY_MSG_LOCAL_CIEMASK_STRU;Local Cie mask structure HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local Cie mask structure as tool HISTORY_MSG_LOCAL_CIEMASK_WLC;Local CIECAM mask wavelet Lc HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local CIECAM mask wavelet levels +HISTORY_MSG_LOCAL_FEATHERCOL;Local Color gradient feather +HISTORY_MSG_LOCAL_FEATHEREXE;Local Exp gradient feather +HISTORY_MSG_LOCAL_FEATHERVIB;Local Vib gradient feather +HISTORY_MSG_LOCAL_FEATHERWAV;Local Wav gradient feather +HISTORY_MSG_LOCAL_FEATHERLOG;Local Log gradient feather +HISTORY_MSG_LOCAL_FEATHERCIE;Local CIECAM gradient feather +HISTORY_MSG_LOCAL_FEATHERSH;Local SH gradient feather +HISTORY_MSG_LOCAL_FEATHERMAS;Local Mask common gradient feather + HISTORY_MSG_LOCAL_LOG_BLACKS;Local Log - Blacks distribution HISTORY_MSG_LOCAL_LOG_COMPR;Local Log - Compress brightness HISTORY_MSG_LOCAL_LOG_SAT;Local Log - Saturation control @@ -2929,7 +2938,7 @@ TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) TP_LOCALLAB_CIE_SMOOTH_NONE;None TP_LOCALLAB_CIE_SMOOTH_EV;Ev based -TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation & Levels +TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels @@ -3089,7 +3098,8 @@ TP_LOCALLAB_FATLEVEL;Sigma TP_LOCALLAB_FATSAT;Saturation control TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +TP_LOCALLAB_FEATVALUE;Feather gradient +TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3566,7 +3576,7 @@ TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) TP_LOCALLAB_SLOSH;Slope -TP_LOCALLAB_SMOOTHCIE;Highlight attenuation +TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 1d03f7adc..9cf83d9cb 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -501,19 +501,25 @@ struct local_params { float angmaexp; float str_mas; float ang_mas; + float feather_mas; float strexp; float angexp; + float featherexp; float strSH; float angSH; + float featherSH; float strcol; float strcolab; float strcolh; float angcol; + float feathcol; float strvib; float strvibab; float strvibh; float angvib; + float feathervib; float angwav; + float featherwav; float strwav; float blendmaL; float radmaL; @@ -529,6 +535,7 @@ struct local_params { float basew; float anglog; + float featherlog; float strlog; float softradiusexp; float softradiuscol; @@ -804,6 +811,7 @@ struct local_params { float detailcie; float strgradcie; float anggradcie; + float feathercie; bool satcie; bool satlog; int sensilog; @@ -1367,22 +1375,29 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float angmaskexpo = ((float) locallab.spots.at(sp).angmaskexp); float strmask = ((float) locallab.spots.at(sp).str_mask); float angmask = ((float) locallab.spots.at(sp).ang_mask); + float feathermask = ((float) locallab.spots.at(sp).feather_mask); float strexpo = ((float) locallab.spots.at(sp).strexp); float angexpo = ((float) locallab.spots.at(sp).angexp); + float featherexpo = ((float) locallab.spots.at(sp).featherexp); float strSH = ((float) locallab.spots.at(sp).strSH); float angSH = ((float) locallab.spots.at(sp).angSH); + float featherSH = ((float) locallab.spots.at(sp).featherSH); float strcol = ((float) locallab.spots.at(sp).strcol); float strcolab = ((float) locallab.spots.at(sp).strcolab); float strcolh = ((float) locallab.spots.at(sp).strcolh); float angcol = ((float) locallab.spots.at(sp).angcol); + float feathcol = ((float) locallab.spots.at(sp).feathercol); float strvib = ((float) locallab.spots.at(sp).strvib); float strvibab = ((float) locallab.spots.at(sp).strvibab); float strvibh = ((float) locallab.spots.at(sp).strvibh); float angvib = ((float) locallab.spots.at(sp).angvib); + float feathervib = ((float) locallab.spots.at(sp).feathervib); float strwav = ((float) locallab.spots.at(sp).strwav); float angwav = ((float) locallab.spots.at(sp).angwav); + float featherwav = ((float) locallab.spots.at(sp).featherwav); float strlog = ((float) locallab.spots.at(sp).strlog); float anglog = ((float) locallab.spots.at(sp).anglog); + float featherlog = ((float) locallab.spots.at(sp).featherlog); float softradiusexpo = ((float) locallab.spots.at(sp).softradiusexp); float softradiuscolor = ((float) locallab.spots.at(sp).softradiuscol); float softradiusreti = ((float) locallab.spots.at(sp).softradiusret); @@ -1515,6 +1530,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float contciemask = (float) locallab.spots.at(sp).contcie; float strgradcie = ((float) locallab.spots.at(sp).strgradcie); float anggradcie = ((float) locallab.spots.at(sp).anggradcie); + float feathercie = ((float) locallab.spots.at(sp).feathercie); lp.comprlo = locallab.spots.at(sp).comprlog; lp.comprlocie = locallab.spots.at(sp).comprcie; @@ -1550,23 +1566,30 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.angmaexp = angmaskexpo; lp.str_mas = strmask; lp.ang_mas = angmask; + lp.feather_mas = feathermask; lp.strexp = strexpo; lp.angexp = angexpo; + lp.featherexp = featherexpo; lp.strSH = strSH; lp.angSH = angSH; + lp.featherSH = featherSH; lp.strcol = strcol; lp.strcolab = strcolab; lp.strcolh = strcolh; lp.angcol = angcol; + lp.feathcol = feathcol; lp.strvib = strvib; lp.strvibab = strvibab; lp.strvibh = strvibh; lp.angvib = angvib; + lp.feathervib = feathervib; lp.strwav = strwav; lp.angwav = angwav; + lp.featherwav = featherwav; lp.strlog = strlog; lp.anglog = anglog; + lp.featherlog = featherlog; lp.softradiusexp = softradiusexpo; lp.softradiuscol = softradiuscolor; lp.softradiusret = softradiusreti; @@ -1779,6 +1802,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.contciemask = 0.01f * contciemask; lp.strgradcie = strgradcie; lp.anggradcie = anggradcie; + lp.feathercie = feathercie; lp.blendmacie = blendmaskcie; lp.radmacie = radmaskcie; @@ -5621,19 +5645,24 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& int h = bfh; float stops = 0.f; float angs = 0.f; + double varfeath = 0.25; //0.01f * lp.feath; if (indic == 0) { stops = -lp.strmaexp; angs = lp.angmaexp; + varfeath = 0.01f * lp.feath;//for all masks when present } else if (indic == 1) { stops = lp.strexp; angs = lp.angexp; + varfeath = 0.01f * lp.featherexp; } else if (indic == 2) { stops = lp.strSH; angs = lp.angSH; + varfeath = 0.01f * lp.featherSH; } else if (indic == 3) { stops = lp.strcol; angs = lp.angcol; + varfeath = 0.01f * lp.feathcol; } else if (indic == 4) { float redu = 1.f; @@ -5645,41 +5674,49 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& stops = redu * lp.strcolab; angs = lp.angcol; + varfeath = 0.01f * lp.feathcol; } else if (indic == 5) { stops = lp.strcolab; angs = lp.angcol; + varfeath = 0.01f * lp.feathcol; } else if (indic == 6) { stops = lp.strcolh; angs = lp.angcol; + varfeath = 0.01f * lp.feathcol; } else if (indic == 7) { stops = lp.strvib; angs = lp.angvib; + varfeath = 0.01f * lp.feathervib; } else if (indic == 8) { float redu = 1.f; - if (lp.strvibab > 0.f) { redu = 0.7f; } else { redu = 0.5f; } - stops = redu * lp.strvibab; angs = lp.angvib; + varfeath = 0.01f * lp.feathervib; } else if (indic == 9) { stops = lp.strvibh; angs = lp.angvib; + varfeath = 0.01f * lp.feathervib; } else if (indic == 10) { stops = std::fabs(lp.strwav); angs = lp.angwav; + varfeath = 0.01f * lp.featherwav; } else if (indic == 11) { stops = lp.strlog; angs = lp.anglog; + varfeath = 0.01f * lp.featherlog; } else if (indic == 12) { stops = -lp.str_mas; angs = lp.ang_mas; + varfeath = 0.01f * lp.feather_mas; } else if (indic == 15) { stops = lp.strgradcie; angs = lp.anggradcie; + varfeath = 0.01f * lp.feathercie; } @@ -5687,7 +5724,7 @@ void calclocalGradientParams(const struct local_params& lp, struct grad_params& double gradient_center_x = LIM01((lp.xc - xstart) / bfw); double gradient_center_y = LIM01((lp.yc - ystart) / bfh); double gradient_angle = static_cast(angs) / 180.0 * rtengine::RT_PI; - double varfeath = 0.01f * lp.feath; + // double varfeath = 0.01f * lp.feath; //printf("xstart=%f ysta=%f lpxc=%f lpyc=%f stop=%f bb=%f cc=%f ang=%f ff=%d gg=%d\n", xstart, ystart, lp.xc, lp.yc, gradient_stops, gradient_center_x, gradient_center_y, gradient_angle, w, h); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9d759a723..1ba92c366 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -3044,6 +3044,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : strcolab(0.), strcolh(0.), angcol(0.), + feathercol(25.), blurcolde(5), blurcol(0.2), contcol(0.), @@ -3286,6 +3287,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : gamex(1.), strexp(0.), angexp(0.), + featherexp(25.), excurve{ static_cast(DCT_NURBS), 0.0, @@ -3436,6 +3438,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : blurSHde(5), strSH(0.), angSH(0.), + featherSH(25.), inverssh(false), chromaskSH(0.0), gammaskSH(1.0), @@ -3531,6 +3534,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : strvibab(0.0), strvibh(0.0), angvib(0.0), + feathervib(25.0), Lmaskvibcurve{ static_cast(DCT_NURBS), 0.0, @@ -3975,6 +3979,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : sigmalc2(1.0), strwav(0.0), angwav(0.0), + featherwav(25.0), strengthw(0.0), sigmaed(1.0), radiusw(15.0), @@ -4259,6 +4264,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : baselog(2.), strlog(0.0), anglog(0.0), + featherlog(25.0), CCmaskcurveL{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -4386,6 +4392,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : shadmask(0.0), str_mask(0), ang_mask(0), + feather_mask(25), HHhmask_curve{ static_cast(FCT_MinMaxCPoints), 0.0, @@ -4669,6 +4676,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : surroundcie("Average"), strgradcie(0.), anggradcie(0.), + feathercie(25.), enacieMask(false), enacieMaskall(false), CCmaskciecurve{ @@ -4912,6 +4920,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && strcolab == other.strcolab && strcolh == other.strcolh && angcol == other.angcol + && feathercol == other.feathercol && blurcolde == other.blurcolde && blurcol == other.blurcol && contcol == other.contcol @@ -4974,6 +4983,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && gamex == other.gamex && strexp == other.strexp && angexp == other.angexp + && featherexp == other.featherexp && excurve == other.excurve && norm == other.norm && inversex == other.inversex @@ -5037,6 +5047,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && blurSHde == other.blurSHde && strSH == other.strSH && angSH == other.angSH + && featherSH == other.featherSH && inverssh == other.inverssh && chromaskSH == other.chromaskSH && gammaskSH == other.gammaskSH @@ -5082,6 +5093,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && strvibab == other.strvibab && strvibh == other.strvibh && angvib == other.angvib + && feathervib == other.feathervib && Lmaskvibcurve == other.Lmaskvibcurve && recothresv == other.recothresv && lowthresv == other.lowthresv @@ -5298,6 +5310,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && sigmalc2 == other.sigmalc2 && strwav == other.strwav && angwav == other.angwav + && featherwav == other.featherwav && strengthw == other.strengthw && sigmaed == other.sigmaed && radiusw == other.radiusw @@ -5412,6 +5425,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && surround == other.surround && strlog == other.strlog && anglog == other.anglog + && featherlog == other.featherlog && CCmaskcurveL == other.CCmaskcurveL && LLmaskcurveL == other.LLmaskcurveL && HHmaskcurveL == other.HHmaskcurveL @@ -5450,6 +5464,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && shadmask == other.shadmask && str_mask == other.str_mask && ang_mask == other.ang_mask + && feather_mask == other.feather_mask && HHhmask_curve == other.HHhmask_curve && Lmask_curve == other.Lmask_curve && LLmask_curvewav == other.LLmask_curvewav @@ -5584,6 +5599,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && detailcie == other.detailcie && strgradcie == other.strgradcie && anggradcie == other.anggradcie + && feathercie == other.feathercie && surroundcie == other.surroundcie && enacieMask == other.enacieMask && enacieMaskall == other.enacieMaskall @@ -6856,6 +6872,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->strcolab, "Locallab", "Strcolab_" + index_str, spot.strcolab, keyFile); saveToKeyfile(!pedited || spot_edited->strcolh, "Locallab", "Strcolh_" + index_str, spot.strcolh, keyFile); saveToKeyfile(!pedited || spot_edited->angcol, "Locallab", "Angcol_" + index_str, spot.angcol, keyFile); + saveToKeyfile(!pedited || spot_edited->feathercol, "Locallab", "Feathercol_" + index_str, spot.feathercol, keyFile); saveToKeyfile(!pedited || spot_edited->blurcolde, "Locallab", "Blurcolde_" + index_str, spot.blurcolde, keyFile); saveToKeyfile(!pedited || spot_edited->blurcol, "Locallab", "Blurcol_" + index_str, spot.blurcol, keyFile); saveToKeyfile(!pedited || spot_edited->contcol, "Locallab", "Contcol_" + index_str, spot.contcol, keyFile); @@ -6919,6 +6936,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->gamex, "Locallab", "Gamex_" + index_str, spot.gamex, keyFile); saveToKeyfile(!pedited || spot_edited->strexp, "Locallab", "Strexp_" + index_str, spot.strexp, keyFile); saveToKeyfile(!pedited || spot_edited->angexp, "Locallab", "Angexp_" + index_str, spot.angexp, keyFile); + saveToKeyfile(!pedited || spot_edited->featherexp, "Locallab", "Featherexp_" + index_str, spot.featherexp, keyFile); saveToKeyfile(!pedited || spot_edited->excurve, "Locallab", "ExCurve_" + index_str, spot.excurve, keyFile); saveToKeyfile(!pedited || spot_edited->norm, "Locallab", "Norm_" + index_str, spot.norm, keyFile); saveToKeyfile(!pedited || spot_edited->inversex, "Locallab", "Inversex_" + index_str, spot.inversex, keyFile); @@ -6979,6 +6997,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->blurSHde, "Locallab", "BlurSHde_" + index_str, spot.blurSHde, keyFile); saveToKeyfile(!pedited || spot_edited->strSH, "Locallab", "StrSH_" + index_str, spot.strSH, keyFile); saveToKeyfile(!pedited || spot_edited->angSH, "Locallab", "AngSH_" + index_str, spot.angSH, keyFile); + saveToKeyfile(!pedited || spot_edited->featherSH, "Locallab", "FeatherSH_" + index_str, spot.featherSH, keyFile); saveToKeyfile(!pedited || spot_edited->inverssh, "Locallab", "Inverssh_" + index_str, spot.inverssh, keyFile); saveToKeyfile(!pedited || spot_edited->chromaskSH, "Locallab", "ChromaskSH_" + index_str, spot.chromaskSH, keyFile); saveToKeyfile(!pedited || spot_edited->gammaskSH, "Locallab", "GammaskSH_" + index_str, spot.gammaskSH, keyFile); @@ -7024,6 +7043,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->strvibab, "Locallab", "Strvibab_" + index_str, spot.strvibab, keyFile); saveToKeyfile(!pedited || spot_edited->strvibh, "Locallab", "Strvibh_" + index_str, spot.strvibh, keyFile); saveToKeyfile(!pedited || spot_edited->angvib, "Locallab", "Angvib_" + index_str, spot.angvib, keyFile); + saveToKeyfile(!pedited || spot_edited->angvib, "Locallab", "Feathervib_" + index_str, spot.feathervib, keyFile); saveToKeyfile(!pedited || spot_edited->Lmaskvibcurve, "Locallab", "LmaskvibCurve_" + index_str, spot.Lmaskvibcurve, keyFile); saveToKeyfile(!pedited || spot_edited->recothresv, "Locallab", "Recothresv_" + index_str, spot.recothresv, keyFile); saveToKeyfile(!pedited || spot_edited->lowthresv, "Locallab", "Lowthresv_" + index_str, spot.lowthresv, keyFile); @@ -7246,6 +7266,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->sigmalc2, "Locallab", "Sigmalc2_" + index_str, spot.sigmalc2, keyFile); saveToKeyfile(!pedited || spot_edited->strwav, "Locallab", "Strwav_" + index_str, spot.strwav, keyFile); saveToKeyfile(!pedited || spot_edited->angwav, "Locallab", "Angwav_" + index_str, spot.angwav, keyFile); + saveToKeyfile(!pedited || spot_edited->featherwav, "Locallab", "Featherwav_" + index_str, spot.featherwav, keyFile); saveToKeyfile(!pedited || spot_edited->strengthw, "Locallab", "Strengthw_" + index_str, spot.strengthw, keyFile); saveToKeyfile(!pedited || spot_edited->sigmaed, "Locallab", "Sigmaed_" + index_str, spot.sigmaed, keyFile); saveToKeyfile(!pedited || spot_edited->radiusw, "Locallab", "Radiusw_" + index_str, spot.radiusw, keyFile); @@ -7358,6 +7379,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->surround, "Locallab", "Surround_" + index_str, spot.surround, keyFile); saveToKeyfile(!pedited || spot_edited->strlog, "Locallab", "Strlog_" + index_str, spot.strlog, keyFile); saveToKeyfile(!pedited || spot_edited->anglog, "Locallab", "Anglog_" + index_str, spot.anglog, keyFile); + saveToKeyfile(!pedited || spot_edited->featherlog, "Locallab", "Featherlog_" + index_str, spot.featherlog, keyFile); saveToKeyfile(!pedited || spot_edited->CCmaskcurveL, "Locallab", "CCmaskCurveL_" + index_str, spot.CCmaskcurveL, keyFile); saveToKeyfile(!pedited || spot_edited->LLmaskcurveL, "Locallab", "LLmaskCurveL_" + index_str, spot.LLmaskcurveL, keyFile); saveToKeyfile(!pedited || spot_edited->HHmaskcurveL, "Locallab", "HHmaskCurveL_" + index_str, spot.HHmaskcurveL, keyFile); @@ -7397,6 +7419,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->shadmask, "Locallab", "Shadmask_" + index_str, spot.shadmask, keyFile); saveToKeyfile(!pedited || spot_edited->str_mask, "Locallab", "Str_mask_" + index_str, spot.str_mask, keyFile); saveToKeyfile(!pedited || spot_edited->ang_mask, "Locallab", "Ang_mask_" + index_str, spot.ang_mask, keyFile); + saveToKeyfile(!pedited || spot_edited->feather_mask, "Locallab", "Feather_mask_" + index_str, spot.feather_mask, keyFile); saveToKeyfile(!pedited || spot_edited->HHhmask_curve, "Locallab", "HHhmask_Curve_" + index_str, spot.HHhmask_curve, keyFile); saveToKeyfile(!pedited || spot_edited->Lmask_curve, "Locallab", "Lmask_Curve_" + index_str, spot.Lmask_curve, keyFile); saveToKeyfile(!pedited || spot_edited->LLmask_curvewav, "Locallab", "LLmask_Curvewav_" + index_str, spot.LLmask_curvewav, keyFile); @@ -7534,6 +7557,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || spot_edited->detailcie, "Locallab", "Detailcie_" + index_str, spot.detailcie, keyFile); saveToKeyfile(!pedited || spot_edited->strgradcie, "Locallab", "Strgradcie_" + index_str, spot.strgradcie, keyFile); saveToKeyfile(!pedited || spot_edited->anggradcie, "Locallab", "Anggradcie_" + index_str, spot.anggradcie, keyFile); + saveToKeyfile(!pedited || spot_edited->feathercie, "Locallab", "Feathercie_" + index_str, spot.feathercie, keyFile); saveToKeyfile(!pedited || spot_edited->surroundcie, "Locallab", "Surroundcie_" + index_str, spot.surroundcie, keyFile); saveToKeyfile(!pedited || spot_edited->enacieMask, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, keyFile); saveToKeyfile(!pedited || spot_edited->enacieMaskall, "Locallab", "EnacieMaskall_" + index_str, spot.enacieMaskall, keyFile); @@ -9126,6 +9150,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Strcolab_" + index_str, spot.strcolab, spotEdited.strcolab); assignFromKeyfile(keyFile, "Locallab", "Strcolh_" + index_str, spot.strcolh, spotEdited.strcolh); assignFromKeyfile(keyFile, "Locallab", "Angcol_" + index_str, spot.angcol, spotEdited.angcol); + assignFromKeyfile(keyFile, "Locallab", "Fetahercol_" + index_str, spot.feathercol, spotEdited.feathercol); assignFromKeyfile(keyFile, "Locallab", "Blurcolde_" + index_str, spot.blurcolde, spotEdited.blurcolde); assignFromKeyfile(keyFile, "Locallab", "Blurcol_" + index_str, spot.blurcol, spotEdited.blurcol); assignFromKeyfile(keyFile, "Locallab", "Contcol_" + index_str, spot.contcol, spotEdited.contcol); @@ -9202,6 +9227,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Gamex_" + index_str, spot.gamex, spotEdited.gamex); assignFromKeyfile(keyFile, "Locallab", "Strexp_" + index_str, spot.strexp, spotEdited.strexp); assignFromKeyfile(keyFile, "Locallab", "Angexp_" + index_str, spot.angexp, spotEdited.angexp); + assignFromKeyfile(keyFile, "Locallab", "Featherexp_" + index_str, spot.featherexp, spotEdited.featherexp); assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + index_str, spot.excurve, spotEdited.excurve); assignFromKeyfile(keyFile, "Locallab", "Norm_" + index_str, spot.norm, spotEdited.norm); assignFromKeyfile(keyFile, "Locallab", "Inversex_" + index_str, spot.inversex, spotEdited.inversex); @@ -9266,6 +9292,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "BlurSHde_" + index_str, spot.blurSHde, spotEdited.blurSHde); assignFromKeyfile(keyFile, "Locallab", "StrSH_" + index_str, spot.strSH, spotEdited.strSH); assignFromKeyfile(keyFile, "Locallab", "AngSH_" + index_str, spot.angSH, spotEdited.angSH); + assignFromKeyfile(keyFile, "Locallab", "FeatherSH_" + index_str, spot.featherSH, spotEdited.featherSH); assignFromKeyfile(keyFile, "Locallab", "Inverssh_" + index_str, spot.inverssh, spotEdited.inverssh); assignFromKeyfile(keyFile, "Locallab", "ChromaskSH_" + index_str, spot.chromaskSH, spotEdited.chromaskSH); assignFromKeyfile(keyFile, "Locallab", "GammaskSH_" + index_str, spot.gammaskSH, spotEdited.gammaskSH); @@ -9325,6 +9352,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Strvibab_" + index_str, spot.strvibab, spotEdited.strvibab); assignFromKeyfile(keyFile, "Locallab", "Strvibh_" + index_str, spot.strvibh, spotEdited.strvibh); assignFromKeyfile(keyFile, "Locallab", "Angvib_" + index_str, spot.angvib, spotEdited.angvib); + assignFromKeyfile(keyFile, "Locallab", "Feathervib_" + index_str, spot.feathervib, spotEdited.feathervib); assignFromKeyfile(keyFile, "Locallab", "LmaskvibCurve_" + index_str, spot.Lmaskvibcurve, spotEdited.Lmaskvibcurve); assignFromKeyfile(keyFile, "Locallab", "Recothresv_" + index_str, spot.recothresv, spotEdited.recothresv); assignFromKeyfile(keyFile, "Locallab", "Lowthresv_" + index_str, spot.lowthresv, spotEdited.lowthresv); @@ -9574,6 +9602,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Sigmalc2_" + index_str, spot.sigmalc2, spotEdited.sigmalc2); assignFromKeyfile(keyFile, "Locallab", "Strwav_" + index_str, spot.strwav, spotEdited.strwav); assignFromKeyfile(keyFile, "Locallab", "Angwav_" + index_str, spot.angwav, spotEdited.angwav); + assignFromKeyfile(keyFile, "Locallab", "Featherwav_" + index_str, spot.featherwav, spotEdited.featherwav); assignFromKeyfile(keyFile, "Locallab", "Strengthw_" + index_str, spot.strengthw, spotEdited.strengthw); assignFromKeyfile(keyFile, "Locallab", "Sigmaed_" + index_str, spot.sigmaed, spotEdited.sigmaed); assignFromKeyfile(keyFile, "Locallab", "Radiusw_" + index_str, spot.radiusw, spotEdited.radiusw); @@ -9703,6 +9732,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, spot.surround, spotEdited.surround); assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, spot.strlog, spotEdited.strlog); assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, spot.anglog, spotEdited.anglog); + assignFromKeyfile(keyFile, "Locallab", "Featherlog_" + index_str, spot.featherlog, spotEdited.featherlog); assignFromKeyfile(keyFile, "Locallab", "CCmaskCurveL_" + index_str, spot.CCmaskcurveL, spotEdited.CCmaskcurveL); assignFromKeyfile(keyFile, "Locallab", "LLmaskCurveL_" + index_str, spot.LLmaskcurveL, spotEdited.LLmaskcurveL); assignFromKeyfile(keyFile, "Locallab", "HHmaskCurveL_" + index_str, spot.HHmaskcurveL, spotEdited.HHmaskcurveL); @@ -9740,6 +9770,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Shadmask_" + index_str, spot.shadmask, spotEdited.shadmask); assignFromKeyfile(keyFile, "Locallab", "Str_mask_" + index_str, spot.str_mask, spotEdited.str_mask); assignFromKeyfile(keyFile, "Locallab", "Ang_mask_" + index_str, spot.ang_mask, spotEdited.ang_mask); + assignFromKeyfile(keyFile, "Locallab", "Feather_mask_" + index_str, spot.feather_mask, spotEdited.feather_mask); assignFromKeyfile(keyFile, "Locallab", "HHhmask_Curve_" + index_str, spot.HHhmask_curve, spotEdited.HHhmask_curve); assignFromKeyfile(keyFile, "Locallab", "Lmask_Curve_" + index_str, spot.Lmask_curve, spotEdited.Lmask_curve); assignFromKeyfile(keyFile, "Locallab", "LLmask_Curvewav_" + index_str, spot.LLmask_curvewav, spotEdited.LLmask_curvewav); @@ -9902,7 +9933,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Surroundcie_" + index_str, spot.surroundcie, spotEdited.surroundcie); assignFromKeyfile(keyFile, "Locallab", "Strgradcie_" + index_str, spot.strgradcie, spotEdited.strgradcie); assignFromKeyfile(keyFile, "Locallab", "Anggradcie_" + index_str, spot.anggradcie, spotEdited.anggradcie); - + assignFromKeyfile(keyFile, "Locallab", "Feathercie_" + index_str, spot.feathercie, spotEdited.feathercie); + assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, spotEdited.enacieMask); assignFromKeyfile(keyFile, "Locallab", "EnacieMaskall_" + index_str, spot.enacieMaskall, spotEdited.enacieMaskall); assignFromKeyfile(keyFile, "Locallab", "CCmaskcieCurve_" + index_str, spot.CCmaskciecurve, spotEdited.CCmaskciecurve); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d1cad0a5d..d71c3d172 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1122,6 +1122,7 @@ struct LocallabParams { double strcolab; double strcolh; double angcol; + double feathercol; int blurcolde; double blurcol; double contcol; @@ -1184,6 +1185,7 @@ struct LocallabParams { double gamex; double strexp; double angexp; + double featherexp; std::vector excurve; bool norm; bool inversex; @@ -1239,6 +1241,7 @@ struct LocallabParams { int blurSHde; double strSH; double angSH; + double featherSH; bool inverssh; double chromaskSH; double gammaskSH; @@ -1284,6 +1287,7 @@ struct LocallabParams { double strvibab; double strvibh; double angvib; + double feathervib; std::vector Lmaskvibcurve; double recothresv; double lowthresv; @@ -1500,6 +1504,7 @@ struct LocallabParams { double sigmalc2; double strwav; double angwav; + double featherwav; double strengthw; double sigmaed; double radiusw; @@ -1606,6 +1611,7 @@ struct LocallabParams { double baselog; double strlog; double anglog; + double featherlog; std::vector CCmaskcurveL; std::vector LLmaskcurveL; std::vector HHmaskcurveL; @@ -1644,6 +1650,7 @@ struct LocallabParams { double shadmask; int str_mask; int ang_mask; + int feather_mask; std::vector HHhmask_curve; std::vector Lmask_curve; std::vector LLmask_curvewav; @@ -1780,6 +1787,7 @@ struct LocallabParams { Glib::ustring surroundcie; double strgradcie; double anggradcie; + double feathercie; bool enacieMask; bool enacieMaskall; std::vector CCmaskciecurve; diff --git a/rtgui/controlspotpanel.cc b/rtgui/controlspotpanel.cc index 8588f6057..783f253c7 100644 --- a/rtgui/controlspotpanel.cc +++ b/rtgui/controlspotpanel.cc @@ -70,7 +70,7 @@ ControlSpotPanel::ControlSpotPanel(): transit_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITVALUE"), 2., 100., 0.1, 60.))), transitweak_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITWEAK"), 0.5, 25.0, 0.1, 1.0))), transitgrad_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_TRANSITGRAD"), -1.0, 1.0, 0.01, 0.0))), - feather_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), + feather_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE_MASK"), 10., 100., 0.1, 25.))), struc_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRES"), 1.0, 12.0, 0.1, 4.0))), thresh_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_THRESDELTAE"), 0.0, 15.0, 0.1, 2.0))), iter_(Gtk::manage(new Adjuster(M("TP_LOCALLAB_PROXI"), 0.2, 10.0, 0.1, 2.0))), @@ -351,7 +351,7 @@ ControlSpotPanel::ControlSpotPanel(): transitBox->pack_start(*transit_); transitBox->pack_start(*transitweak_); transitBox->pack_start(*transitgrad_); - transitBox->pack_start(*feather_); + //transitBox->pack_start(*feather_); expTransGrad_->add(*transitBox, false); pack_start(*expTransGrad_, false, false); @@ -504,6 +504,7 @@ ControlSpotPanel::ControlSpotPanel(): maskBox->pack_start(*deltae_); maskBox->pack_start(*scopemask_); maskBox->pack_start(*denoichmask_); + maskBox->pack_start(*feather_); // maskBox->pack_start(*shortc_); maskBox->pack_start(*lumask_); // maskBox->pack_start(*savrest_); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index fd4ed22be..4c68b004e 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -476,6 +476,7 @@ LocallabColor::LocallabColor(): strcolab(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTRCHRO"), -6., 6., 0.05, 0.))), strcolh(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTRHUE"), -6., 6., 0.05, 0.))), angcol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + feathercol(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), expcurvcol(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPCURV")))), labqualcurv(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_QUALCURV_METHOD") + ":"))), qualitycurveMethod(Gtk::manage(new MyComboBoxText())), @@ -541,8 +542,9 @@ LocallabColor::LocallabColor(): csThresholdcol(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))) { auto m = ProcEventMapper::getInstance(); + //rtengine::ProcEvent EvlocallabenacieMaskall; + Evlocallabfeathercol = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERCOL"); Evlocallabpreviewcol = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWCOL"); - set_orientation(Gtk::ORIENTATION_VERTICAL); float R, G, B; @@ -609,6 +611,7 @@ LocallabColor::LocallabColor(): strcolh->set_tooltip_text(M("TP_LOCALLAB_GRADSTRHUE_TOOLTIP")); angcol->setAdjusterListener(this); + feathercol->setAdjusterListener(this); setExpandAlignProperties(expcurvcol, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -879,6 +882,7 @@ LocallabColor::LocallabColor(): gradcolBox->pack_start(*strcolab); gradcolBox->pack_start(*strcolh); gradcolBox->pack_start(*angcol); + gradcolBox->pack_start(*feathercol); expgradcol->add(*gradcolBox, false); pack_start(*expgradcol, false, false); ToolParamBlock* const curvBox = Gtk::manage(new ToolParamBlock()); @@ -1291,6 +1295,7 @@ void LocallabColor::read(const rtengine::procparams::ProcParams* pp, const Param strcolab->setValue(spot.strcolab); strcolh->setValue(spot.strcolh); angcol->setValue(spot.angcol); + feathercol->setValue(spot.feathercol); if (spot.qualitycurveMethod == "none") { qualitycurveMethod->set_active(0); @@ -1472,6 +1477,7 @@ void LocallabColor::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pe spot.strcolab = strcolab->getValue(); spot.strcolh = strcolh->getValue(); spot.angcol = angcol->getValue(); + spot.feathercol = feathercol->getValue(); spot.recothresc = recothresc->getValue(); spot.lowthresc = lowthresc->getValue(); @@ -1626,6 +1632,7 @@ void LocallabColor::setDefaults(const rtengine::procparams::ProcParams* defParam strcolab->setDefault(defSpot.strcolab); strcolh->setDefault(defSpot.strcolh); angcol->setDefault(defSpot.angcol); + feathercol->setDefault(defSpot.feathercol); mercol->setDefault(defSpot.mercol); opacol->setDefault(defSpot.opacol); conthrcol->setDefault(defSpot.conthrcol); @@ -1786,6 +1793,13 @@ void LocallabColor::adjusterChanged(Adjuster* a, double newval) } } + if (a == feathercol) { + if (listener) { + listener->panelChanged(Evlocallabfeathercol, + feathercol->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == mercol) { if (listener) { listener->panelChanged(Evlocallabmercol, @@ -2147,6 +2161,7 @@ void LocallabColor::convertParamToSimple() softradiuscol->setValue(defSpot.softradiuscol); strcol->setValue(defSpot.strcol); angcol->setValue(defSpot.angcol); + feathercol->setValue(defSpot.feathercol); gamc->setValue(defSpot.gamc); if (defSpot.qualitycurveMethod == "none") { @@ -2706,6 +2721,7 @@ LocallabExposure::LocallabExposure(): expgradexp(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPGRAD")))), strexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4., 4., 0.05, 0.))), angexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + featherexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), softradiusexp(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 100.0, 0.5, 0.))), inversex(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), expmaskexp(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWE")))), @@ -2737,6 +2753,7 @@ LocallabExposure::LocallabExposure(): const LocallabParams::LocallabSpot defSpot; auto m = ProcEventMapper::getInstance(); Evlocallabpreviewexe = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWEXE"); + Evlocallabfeatherexp = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHEREXE"); // Parameter Exposure specific widgets expMethod->append(M("TP_LOCALLAB_STD")); @@ -2811,6 +2828,7 @@ LocallabExposure::LocallabExposure(): angexp->setAdjusterListener(this); angexp->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); + featherexp->setAdjusterListener(this); softradiusexp->setLogScale(10, 0); softradiusexp->setAdjusterListener(this); @@ -2954,6 +2972,7 @@ LocallabExposure::LocallabExposure(): ToolParamBlock* const gradBox = Gtk::manage(new ToolParamBlock()); gradBox->pack_start(*strexp); gradBox->pack_start(*angexp); + gradBox->pack_start(*featherexp); expgradexp->add(*gradBox, false); pack_start(*expgradexp); pack_start(*softradiusexp); @@ -3272,6 +3291,7 @@ void LocallabExposure::read(const rtengine::procparams::ProcParams* pp, const Pa shapeexpos->setCurve(spot.excurve); strexp->setValue(spot.strexp); angexp->setValue(spot.angexp); + featherexp->setValue(spot.featherexp); softradiusexp->setValue(spot.softradiusexp); norm->set_active(spot.norm); fatsatur->set_active(spot.fatsatur); @@ -3363,6 +3383,7 @@ void LocallabExposure::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.excurve = shapeexpos->getCurve(); spot.strexp = strexp->getValue(); spot.angexp = angexp->getValue(); + spot.featherexp = featherexp->getValue(); spot.softradiusexp = softradiusexp->getValue(); spot.inversex = inversex->get_active(); spot.norm = norm->get_active(); @@ -3416,6 +3437,7 @@ void LocallabExposure::setDefaults(const rtengine::procparams::ProcParams* defPa expchroma->setDefault((double)defSpot.expchroma); strexp->setDefault(defSpot.strexp); angexp->setDefault(defSpot.angexp); + featherexp->setDefault(defSpot.featherexp); softradiusexp->setDefault(defSpot.softradiusexp); blendmaskexp->setDefault((double)defSpot.blendmaskexp); radmaskexp->setDefault(defSpot.radmaskexp); @@ -3640,6 +3662,13 @@ void LocallabExposure::adjusterChanged(Adjuster* a, double newval) } } + if (a == featherexp) { + if (listener) { + listener->panelChanged(Evlocallabfeatherexp, + featherexp->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == softradiusexp) { if (listener) { listener->panelChanged(Evlocallabsoftradiusexp, @@ -3796,6 +3825,7 @@ void LocallabExposure::convertParamToSimple() // Set hidden specific GUI widgets in Simple mode to default spot values strexp->setValue(defSpot.strexp); angexp->setValue(defSpot.angexp); + featherexp->setValue(defSpot.featherexp); softradiusexp->setValue(defSpot.softradiusexp); enaExpMask->set_active(defSpot.enaExpMask); enaExpMaskaft->set_active(defSpot.enaExpMaskaft); @@ -4240,6 +4270,7 @@ LocallabShadow::LocallabShadow(): expgradsh(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPGRAD")))), strSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4., 4., 0.05, 0.))), angSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + featherSH(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), inverssh(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), expmasksh(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWS")))), showmaskSHMethod(Gtk::manage(new MyComboBoxText())), @@ -4265,6 +4296,7 @@ LocallabShadow::LocallabShadow(): { auto m = ProcEventMapper::getInstance(); Evlocallabpreviewsh = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWSH"); + EvlocallabfeatherSH = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERSH"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -4316,6 +4348,7 @@ LocallabShadow::LocallabShadow(): angSH->setAdjusterListener(this); angSH->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); + featherSH->setAdjusterListener(this); inversshConn = inverssh->signal_toggled().connect(sigc::mem_fun(*this, &LocallabShadow::inversshChanged)); inverssh->set_tooltip_text(M("TP_LOCALLAB_INVERS_TOOLTIP")); @@ -4427,6 +4460,7 @@ LocallabShadow::LocallabShadow(): ToolParamBlock* const gradSHBox = Gtk::manage(new ToolParamBlock()); gradSHBox->pack_start(*strSH); gradSHBox->pack_start(*angSH); + gradSHBox->pack_start(*featherSH); expgradsh->add(*gradSHBox, false); pack_start(*expgradsh); // pack_start(*inverssh); @@ -4718,6 +4752,7 @@ void LocallabShadow::read(const rtengine::procparams::ProcParams* pp, const Para sloSH->setValue(spot.sloSH); strSH->setValue(spot.strSH); angSH->setValue(spot.angSH); + featherSH->setValue(spot.featherSH); inverssh->set_active(spot.inverssh); enaSHMask->set_active(spot.enaSHMask); CCmaskSHshape->setCurve(spot.CCmaskSHcurve); @@ -4784,6 +4819,7 @@ void LocallabShadow::write(rtengine::procparams::ProcParams* pp, ParamsEdited* p spot.sloSH = sloSH->getValue(); spot.strSH = strSH->getValue(); spot.angSH = angSH->getValue(); + spot.featherSH = featherSH->getValue(); spot.inverssh = inverssh->get_active(); spot.enaSHMask = enaSHMask->get_active(); spot.LLmaskSHcurve = LLmaskSHshape->getCurve(); @@ -4833,6 +4869,7 @@ void LocallabShadow::setDefaults(const rtengine::procparams::ProcParams* defPara sloSH->setDefault(defSpot.sloSH); strSH->setDefault(defSpot.strSH); angSH->setDefault(defSpot.angSH); + featherSH->setDefault(defSpot.featherSH); blendmaskSH->setDefault((double)defSpot.blendmaskSH); radmaskSH->setDefault(defSpot.radmaskSH); lapmaskSH->setDefault(defSpot.lapmaskSH); @@ -4994,6 +5031,13 @@ void LocallabShadow::adjusterChanged(Adjuster* a, double newval) } } + if (a == featherSH) { + if (listener) { + listener->panelChanged(EvlocallabfeatherSH, + featherSH->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == blendmaskSH) { if (listener) { listener->panelChanged(EvlocallabblendmaskSH, @@ -5133,6 +5177,7 @@ void LocallabShadow::convertParamToSimple() sloSH->setValue(defSpot.sloSH); strSH->setValue(defSpot.strSH); angSH->setValue(defSpot.angSH); + featherSH->setValue(defSpot.featherSH); showmaskSHMethod->set_active(0); showmaskSHMethodinv->set_active(0); enaSHMask->set_active(defSpot.enaSHMask); @@ -5450,6 +5495,7 @@ LocallabVibrance::LocallabVibrance(): strvibab(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTRCHRO"), -4., 4., 0.05, 0.))), strvibh(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTRHUE2"), -6., 6., 0.05, 0.))), angvib(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + feathervib(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), expmaskvib(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWVI")))), showmaskvibMethod(Gtk::manage(new MyComboBoxText())), enavibMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), @@ -5469,7 +5515,7 @@ LocallabVibrance::LocallabVibrance(): { auto m = ProcEventMapper::getInstance(); Evlocallabpreviewvib = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWVIB"); - + Evlocallabfeathervib = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERVIB"); set_orientation(Gtk::ORIENTATION_VERTICAL); float R, G, B; @@ -5533,6 +5579,7 @@ LocallabVibrance::LocallabVibrance(): angvib->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); angvib->setAdjusterListener(this); + feathervib->setAdjusterListener(this); previewvib->set_active(false); previewvibConn = previewvib->signal_clicked().connect( @@ -5620,6 +5667,7 @@ LocallabVibrance::LocallabVibrance(): gradvibBox->pack_start(*strvibab); gradvibBox->pack_start(*strvibh); gradvibBox->pack_start(*angvib); + gradvibBox->pack_start(*feathervib); expgradvib->add(*gradvibBox, false); pack_start(*expgradvib); ToolParamBlock* const maskvibBox = Gtk::manage(new ToolParamBlock()); @@ -5872,6 +5920,7 @@ void LocallabVibrance::read(const rtengine::procparams::ProcParams* pp, const Pa strvibab->setValue(spot.strvibab); strvibh->setValue(spot.strvibh); angvib->setValue(spot.angvib); + feathervib->setValue(spot.feathervib); enavibMask->set_active(spot.enavibMask); CCmaskvibshape->setCurve(spot.CCmaskvibcurve); LLmaskvibshape->setCurve(spot.LLmaskvibcurve); @@ -5926,6 +5975,7 @@ void LocallabVibrance::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.strvibab = strvibab->getValue(); spot.strvibh = strvibh->getValue(); spot.angvib = angvib->getValue(); + spot.feathervib = feathervib->getValue(); spot.enavibMask = enavibMask->get_active(); spot.CCmaskvibcurve = CCmaskvibshape->getCurve(); spot.LLmaskvibcurve = LLmaskvibshape->getCurve(); @@ -5964,6 +6014,7 @@ void LocallabVibrance::setDefaults(const rtengine::procparams::ProcParams* defPa strvibab->setDefault(defSpot.strvibab); strvibh->setDefault(defSpot.strvibh); angvib->setDefault(defSpot.angvib); + feathervib->setDefault(defSpot.feathervib); blendmaskvib->setDefault((double)defSpot.blendmaskvib); radmaskvib->setDefault(defSpot.radmaskvib); lapmaskvib->setDefault(defSpot.lapmaskvib); @@ -6079,6 +6130,13 @@ void LocallabVibrance::adjusterChanged(Adjuster* a, double newval) } } + if (a == feathervib) { + if (listener) { + listener->panelChanged(Evlocallabfeathervib, + feathervib->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == blendmaskvib) { if (listener) { listener->panelChanged(Evlocallabblendmaskvi, @@ -6277,6 +6335,7 @@ void LocallabVibrance::convertParamToSimple() // Set hidden specific GUI widgets in Simple mode to default spot values strvib->setValue(defSpot.strvib); angvib->setValue(defSpot.angvib); + feathervib->setValue(defSpot.feathervib); showmaskvibMethod->set_active(0); enavibMask->set_active(defSpot.enavibMask); // CCmaskvibshape->setCurve(defSpot.CCmaskvibcurve); diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index 17f9bd5cb..828615ba3 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -123,6 +123,14 @@ protected: rtengine::ProcEvent Evlocallabstrgradcie; rtengine::ProcEvent Evlocallabdetailciejz; rtengine::ProcEvent EvlocallabenacieMaskall; + rtengine::ProcEvent Evlocallabfeathercol; + rtengine::ProcEvent Evlocallabfeathervib; + rtengine::ProcEvent Evlocallabfeatherexp; + rtengine::ProcEvent Evlocallabfeatherwav; + rtengine::ProcEvent Evlocallabfeatherlog; + rtengine::ProcEvent Evlocallabfeathercie; + rtengine::ProcEvent EvlocallabfeatherSH; + rtengine::ProcEvent Evlocallabfeather_mask; // LocallabTool parameters bool needMode; bool isLocActivated; @@ -278,6 +286,7 @@ private: Adjuster* const strcolab; Adjuster* const strcolh; Adjuster* const angcol; + Adjuster* const feathercol; MyExpander* const expcurvcol; Gtk::Label* const labqualcurv; MyComboBoxText* const qualitycurveMethod; @@ -451,6 +460,7 @@ private: MyExpander* const expgradexp; Adjuster* const strexp; Adjuster* const angexp; + Adjuster* const featherexp; Adjuster* const softradiusexp; Gtk::CheckButton* const inversex; MyExpander* const expmaskexp; @@ -559,6 +569,7 @@ private: MyExpander* const expgradsh; Adjuster* const strSH; Adjuster* const angSH; + Adjuster* const featherSH; Gtk::CheckButton* const inverssh; MyExpander* const expmasksh; MyComboBoxText* const showmaskSHMethod; @@ -661,6 +672,7 @@ private: Adjuster* const strvibab; Adjuster* const strvibh; Adjuster* const angvib; + Adjuster* const feathervib; MyExpander* const expmaskvib; MyComboBoxText* const showmaskvibMethod; Gtk::CheckButton* const enavibMask; @@ -1240,6 +1252,7 @@ private: Adjuster* const sigmalc2; Adjuster* const strwav; Adjuster* const angwav; + Adjuster* const featherwav; Gtk::CheckButton* const wavedg; Adjuster* const strengthw; Adjuster* const sigmaed; @@ -1506,6 +1519,7 @@ private: Gtk::Frame* const gradlogFrame; Adjuster* const strlog; Adjuster* const anglog; + Adjuster* const featherlog; MyExpander* const expmaskL; MyComboBoxText* const showmaskLMethod; Gtk::CheckButton* const enaLMask; @@ -1613,6 +1627,7 @@ private: ThresholdAdjuster* const csThresholdmask; Gtk::Frame* const gradFramemask; Adjuster* const str_mask; + Adjuster* const feather_mask; Adjuster* const ang_mask; sigc::connection showmask_MethodConn, previewmasConn, enamaskConn, toolmaskConn, fftmaskConn; @@ -1866,6 +1881,7 @@ private: MyExpander* const expgradcie; Adjuster* const strgradcie; Adjuster* const anggradcie; + Adjuster* const feathercie; MyExpander* const exprecovcie; Gtk::Label* const maskusablecie; diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index af09224b5..b13148cd1 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -2534,6 +2534,7 @@ LocallabContrast::LocallabContrast(): sigmalc2(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMAWAV"), 0.2, 2.5, 0.01, 1.))), strwav(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4.0, 4.0, 0.05, 0.))), angwav(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + featherwav(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), wavedg(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EDGFRA")))), strengthw(Gtk::manage(new Adjuster(M("TP_WAVELET_EDVAL"), 0., 100.0, 0.5, 0.))), sigmaed(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SIGMAWAV"), 0.2, 2.5, 0.01, 1.))), @@ -2602,6 +2603,7 @@ LocallabContrast::LocallabContrast(): { auto m = ProcEventMapper::getInstance(); Evlocallabpreviewlc = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWLC"); + Evlocallabfeatherwav = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERWAV"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -2708,6 +2710,7 @@ LocallabContrast::LocallabContrast(): strwav->setAdjusterListener(this); angwav->setAdjusterListener(this); + featherwav->setAdjusterListener(this); wavedgConn = wavedg->signal_toggled().connect(sigc::mem_fun(*this, &LocallabContrast::wavedgChanged)); @@ -2949,6 +2952,7 @@ LocallabContrast::LocallabContrast(): gradwavBox->pack_start(*sigmalc2); gradwavBox->pack_start(*strwav); gradwavBox->pack_start(*angwav); + gradwavBox->pack_start(*featherwav); gradwavFrame->add(*gradwavBox); blurcontBox->pack_start(*gradwavFrame); Gtk::Frame* const edgFrame = Gtk::manage(new Gtk::Frame()); @@ -3400,6 +3404,7 @@ void LocallabContrast::read(const rtengine::procparams::ProcParams* pp, const Pa sigmalc2->setValue(spot.sigmalc2); strwav->setValue(spot.strwav); angwav->setValue(spot.angwav); + featherwav->setValue(spot.featherwav); wavedg->set_active(spot.wavedg); strengthw->setValue(spot.strengthw); sigmaed->setValue(spot.sigmaed); @@ -3525,6 +3530,7 @@ void LocallabContrast::write(rtengine::procparams::ProcParams* pp, ParamsEdited* spot.sigmalc2 = sigmalc2->getValue(); spot.strwav = strwav->getValue(); spot.angwav = angwav->getValue(); + spot.featherwav = featherwav->getValue(); spot.wavedg = wavedg->get_active(); spot.strengthw = strengthw->getValue(); spot.sigmaed = sigmaed->getValue(); @@ -3627,6 +3633,7 @@ void LocallabContrast::setDefaults(const rtengine::procparams::ProcParams* defPa sigmalc2->setDefault(defSpot.sigmalc2); strwav->setDefault(defSpot.strwav); angwav->setDefault(defSpot.angwav); + featherwav->setDefault(defSpot.featherwav); strengthw->setDefault(defSpot.strengthw); sigmaed->setDefault(defSpot.sigmaed); gradw->setDefault(defSpot.gradw); @@ -3825,6 +3832,13 @@ void LocallabContrast::adjusterChanged(Adjuster* a, double newval) } } + if (a == featherwav) { + if (listener) { + listener->panelChanged(Evlocallabfeatherwav, + featherwav->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == strengthw) { if (listener) { listener->panelChanged(Evlocallabstrengthw, @@ -4146,6 +4160,7 @@ void LocallabContrast::convertParamToNormal() sigmalc2->setValue(defSpot.sigmalc2); strwav->setValue(defSpot.strwav); angwav->setValue(defSpot.angwav); + featherwav->setValue(defSpot.featherwav); wavedg->set_active(defSpot.wavedg); strengthw->setValue(defSpot.strengthw); sigmaed->setValue(defSpot.sigmaed); @@ -5516,6 +5531,7 @@ LocallabLog::LocallabLog(): gradlogFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADLOGFRA")))), strlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2.0, 2.0, 0.05, 0.))), anglog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + featherlog(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), expmaskL(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_SHOWC")))), showmaskLMethod(Gtk::manage(new MyComboBoxText())), enaLMask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), @@ -5539,6 +5555,7 @@ LocallabLog::LocallabLog(): Evlocallabcomprlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_COMPR"); Evlocallabstrelog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_STRE"); Evlocallabsatlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_LOG_SAT"); + Evlocallabfeatherlog = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERLOG"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -5619,6 +5636,7 @@ LocallabLog::LocallabLog(): strlog->setAdjusterListener(this); anglog->setAdjusterListener(this); + featherlog->setAdjusterListener(this); surHBox->set_spacing(2); surHBox->set_tooltip_markup(M("TP_LOCALLAB_LOGSURSOUR_TOOLTIP")); @@ -5788,6 +5806,7 @@ LocallabLog::LocallabLog(): ToolParamBlock* const gradlogBox = Gtk::manage(new ToolParamBlock()); gradlogBox->pack_start(*strlog); gradlogBox->pack_start(*anglog); + gradlogBox->pack_start(*featherlog); gradlogFrame->add(*gradlogBox); pack_start(*gradlogFrame); } @@ -6101,6 +6120,7 @@ void LocallabLog::read(const rtengine::procparams::ProcParams* pp, const ParamsE sensilog->setValue((double)spot.sensilog); strlog->setValue(spot.strlog); anglog->setValue(spot.anglog); + featherlog->setValue(spot.featherlog); CCmaskshapeL->setCurve(spot.CCmaskcurveL); LLmaskshapeL->setCurve(spot.LLmaskcurveL); HHmaskshapeL->setCurve(spot.HHmaskcurveL); @@ -6168,6 +6188,7 @@ void LocallabLog::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.sensilog = sensilog->getIntValue(); spot.strlog = strlog->getValue(); spot.anglog = anglog->getValue(); + spot.featherlog = featherlog->getValue(); spot.CCmaskcurveL = CCmaskshapeL->getCurve(); spot.LLmaskcurveL = LLmaskshapeL->getCurve(); spot.HHmaskcurveL = HHmaskshapeL->getCurve(); @@ -6354,6 +6375,7 @@ void LocallabLog::convertParamToSimple() sursour->set_active(0); strlog->setValue(defSpot.strlog); anglog->setValue(defSpot.anglog); + featherlog->setValue(defSpot.featherlog); enaLMask->set_active(false); showmaskLMethod->set_active(0); recothresl->setValue(defSpot.recothresl); @@ -6476,6 +6498,7 @@ void LocallabLog::setDefaults(const rtengine::procparams::ProcParams* defParams, sensilog->setDefault((double)defSpot.sensilog); strlog->setDefault(defSpot.strlog); anglog->setDefault(defSpot.anglog); + featherlog->setDefault(defSpot.featherlog); blendmaskL->setDefault(defSpot.blendmaskL); radmaskL->setDefault(defSpot.radmaskL); chromaskL->setDefault(defSpot.chromaskL); @@ -6699,6 +6722,13 @@ void LocallabLog::adjusterChanged(Adjuster* a, double newval) } } + if (a == featherlog) { + if (listener) { + listener->panelChanged(Evlocallabfeatherlog, + featherlog->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + if (a == blendmaskL) { if (listener) { listener->panelChanged(EvLocallabblendmaskL, @@ -7011,11 +7041,13 @@ LocallabMask::LocallabMask(): csThresholdmask(Gtk::manage(new ThresholdAdjuster(M("TP_LOCALLAB_CSTHRESHOLDBLUR"), 0, 9, 0, 0, 6, 5, 0, false))), gradFramemask(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_GRADFRA")))), str_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -2., 2., 0.05, 0.))), + feather_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), ang_mask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180., 180., 0.1, 0.))) { auto m = ProcEventMapper::getInstance(); Evlocallabpreviewmas = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_PREVIEWMAS"); + Evlocallabfeather_mask = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERMAS"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -7125,6 +7157,7 @@ LocallabMask::LocallabMask(): ang_mask->setAdjusterListener(this); ang_mask->set_tooltip_text(M("TP_LOCALLAB_GRADANG_TOOLTIP")); + feather_mask->setAdjusterListener(this); // Add Common mask specific widgets to GUI pack_start(*sensimask); @@ -7160,6 +7193,7 @@ LocallabMask::LocallabMask(): ToolParamBlock* const gradmaskBox = Gtk::manage(new ToolParamBlock()); gradmaskBox->pack_start(*str_mask); gradmaskBox->pack_start(*ang_mask); + gradmaskBox->pack_start(*feather_mask); gradFramemask->add(*gradmaskBox); toolmaskBox->pack_start(*gradFramemask, Gtk::PACK_SHRINK, 0); toolmaskFrame->add(*toolmaskBox); @@ -7375,6 +7409,7 @@ void LocallabMask::read(const rtengine::procparams::ProcParams* pp, const Params csThresholdmask->setValue(spot.csthresholdmask); str_mask->setValue((double)spot.str_mask); ang_mask->setValue((double)spot.ang_mask); + feather_mask->setValue((double)spot.feather_mask); } // Enable all listeners @@ -7422,6 +7457,7 @@ void LocallabMask::write(rtengine::procparams::ProcParams* pp, ParamsEdited* ped spot.csthresholdmask = csThresholdmask->getValue(); spot.str_mask = str_mask->getIntValue(); spot.ang_mask = ang_mask->getIntValue(); + spot.feather_mask = feather_mask->getIntValue(); } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -7451,6 +7487,7 @@ void LocallabMask::setDefaults(const rtengine::procparams::ProcParams* defParams csThresholdmask->setDefault(defSpot.csthresholdmask); str_mask->setDefault((double)defSpot.str_mask); ang_mask->setDefault((double)defSpot.ang_mask); + feather_mask->setDefault((double)defSpot.feather_mask); } // Note: No need to manage pedited as batch mode is deactivated for Locallab @@ -7565,6 +7602,13 @@ void LocallabMask::adjusterChanged(Adjuster* a, double newval) } } + if (a == feather_mask) { + if (listener) { + listener->panelChanged(Evlocallabfeather_mask, + feather_mask->getTextValue() + " (" + escapeHtmlChars(getSpotName()) + ")"); + } + } + } } @@ -7700,6 +7744,7 @@ void LocallabMask::convertParamToNormal() csThresholdmask->setValue(defSpot.csthresholdmask); str_mask->setValue((double)defSpot.str_mask); ang_mask->setValue((double)defSpot.ang_mask); + feather_mask->setValue((double)defSpot.feather_mask); // Enable all listeners enableListener(); @@ -8067,6 +8112,7 @@ Locallabcie::Locallabcie(): expgradcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_EXPGRAD")))), strgradcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADSTR"), -4., 4., 0.05, 0.))), anggradcie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_GRADANG"), -180, 180, 0.1, 0.))), + feathercie(Gtk::manage(new Adjuster(M("TP_LOCALLAB_FEATVALUE"), 10., 100., 0.1, 25.))), exprecovcie(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI2_EXP")))), maskusablecie(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), @@ -8167,6 +8213,7 @@ Locallabcie::Locallabcie(): Evlocallabdetailciejz = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_DETAILJZ"); EvlocallabenacieMaskall = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_ENAMASKALL"); Evlocallabsmoothciemet = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_CIE_SMOOTHMET"); + Evlocallabfeathercie = m->newEvent(AUTOEXP, "HISTORY_MSG_LOCAL_FEATHERCIE"); set_orientation(Gtk::ORIENTATION_VERTICAL); @@ -8984,9 +9031,11 @@ Locallabcie::Locallabcie(): strgradcie->setAdjusterListener(this); anggradcie->setAdjusterListener(this); + feathercie->setAdjusterListener(this); ToolParamBlock* const cieBoxgrad = Gtk::manage(new ToolParamBlock()); cieBoxgrad->pack_start(*strgradcie); cieBoxgrad->pack_start(*anggradcie); + cieBoxgrad->pack_start(*feathercie); expgradcie->add(*cieBoxgrad, false); pack_start(*expgradcie, false, false); @@ -9875,6 +9924,7 @@ void Locallabcie::read(const rtengine::procparams::ProcParams* pp, const ParamsE strgradcie->setValue((double)spot.strgradcie); anggradcie->setValue((double)spot.anggradcie); + feathercie->setValue((double)spot.feathercie); enacieMask->set_active(spot.enacieMask); enacieMaskall->set_active(spot.enacieMaskall); @@ -10178,6 +10228,7 @@ void Locallabcie::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedi spot.detailcie = detailcie->getValue(); spot.strgradcie = strgradcie->getValue(); spot.anggradcie = anggradcie->getValue(); + spot.feathercie = feathercie->getValue(); spot.enacieMask = enacieMask->get_active(); spot.enacieMaskall = enacieMaskall->get_active(); @@ -11886,6 +11937,7 @@ void Locallabcie::convertParamToSimple() enacieMaskall->set_active(defSpot.enacieMaskall); strgradcie->setValue(defSpot.strgradcie); anggradcie->setValue(defSpot.anggradcie); + feathercie->setValue(defSpot.feathercie); refi->setValue(defSpot.refi); modecie->set_active(0); primMethod->set_active(0);//Prophoto @@ -12050,6 +12102,7 @@ void Locallabcie::setDefaults(const rtengine::procparams::ProcParams* defParams, // detailcie->setDefault(defSpot.detailcie); strgradcie->setDefault((double)defSpot.strgradcie); anggradcie->setDefault((double)defSpot.anggradcie); + feathercie->setDefault((double)defSpot.feathercie); blendmaskcie->setDefault((double)defSpot.blendmaskcie); radmaskcie->setDefault(defSpot.radmaskcie); chromaskcie->setDefault(defSpot.chromaskcie); @@ -12758,6 +12811,13 @@ void Locallabcie::adjusterChanged(Adjuster* a, double newval) } } + if (a == feathercie) { + if (listener) { + listener->panelChanged(Evlocallabfeathercie, + feathercie->getTextValue() + spName); + } + } + if (a == blendmaskcie) { if (listener) { listener->panelChanged(Evlocallabblendmaskcie, diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 66ea3f9aa..81b6b34d8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1185,6 +1185,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).strcolab = locallab.spots.at(j).strcolab && pSpot.strcolab == otherSpot.strcolab; locallab.spots.at(j).strcolh = locallab.spots.at(j).strcolh && pSpot.strcolh == otherSpot.strcolh; locallab.spots.at(j).angcol = locallab.spots.at(j).angcol && pSpot.angcol == otherSpot.angcol; + locallab.spots.at(j).feathercol = locallab.spots.at(j).feathercol && pSpot.feathercol == otherSpot.feathercol; locallab.spots.at(j).blurcolde = locallab.spots.at(j).blurcolde && pSpot.blurcolde == otherSpot.blurcolde; locallab.spots.at(j).blurcol = locallab.spots.at(j).blurcol && pSpot.blurcol == otherSpot.blurcol; locallab.spots.at(j).contcol = locallab.spots.at(j).contcol && pSpot.contcol == otherSpot.contcol; @@ -1247,6 +1248,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).blurexpde = locallab.spots.at(j).blurexpde && pSpot.blurexpde == otherSpot.blurexpde; locallab.spots.at(j).strexp = locallab.spots.at(j).strexp && pSpot.strexp == otherSpot.strexp; locallab.spots.at(j).angexp = locallab.spots.at(j).angexp && pSpot.angexp == otherSpot.angexp; + locallab.spots.at(j).featherexp = locallab.spots.at(j).featherexp && pSpot.featherexp == otherSpot.featherexp; locallab.spots.at(j).excurve = locallab.spots.at(j).excurve && pSpot.excurve == otherSpot.excurve; locallab.spots.at(j).norm = locallab.spots.at(j).norm && pSpot.norm == otherSpot.norm; locallab.spots.at(j).inversex = locallab.spots.at(j).inversex && pSpot.inversex == otherSpot.inversex; @@ -1306,6 +1308,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).blurSHde = locallab.spots.at(j).blurSHde && pSpot.blurSHde == otherSpot.blurSHde; locallab.spots.at(j).strSH = locallab.spots.at(j).strSH && pSpot.strSH == otherSpot.strSH; locallab.spots.at(j).angSH = locallab.spots.at(j).angSH && pSpot.angSH == otherSpot.angSH; + locallab.spots.at(j).featherSH = locallab.spots.at(j).featherSH && pSpot.featherSH == otherSpot.featherSH; locallab.spots.at(j).inverssh = locallab.spots.at(j).inverssh && pSpot.inverssh == otherSpot.inverssh; locallab.spots.at(j).chromaskSH = locallab.spots.at(j).chromaskSH && pSpot.chromaskSH == otherSpot.chromaskSH; locallab.spots.at(j).gammaskSH = locallab.spots.at(j).gammaskSH && pSpot.gammaskSH == otherSpot.gammaskSH; @@ -1351,6 +1354,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).strvibab = locallab.spots.at(j).strvibab && pSpot.strvibab == otherSpot.strvibab; locallab.spots.at(j).strvibh = locallab.spots.at(j).strvibh && pSpot.strvibh == otherSpot.strvibh; locallab.spots.at(j).angvib = locallab.spots.at(j).angvib && pSpot.angvib == otherSpot.angvib; + locallab.spots.at(j).feathervib = locallab.spots.at(j).feathervib && pSpot.feathervib == otherSpot.feathervib; locallab.spots.at(j).Lmaskvibcurve = locallab.spots.at(j).Lmaskvibcurve && pSpot.Lmaskvibcurve == otherSpot.Lmaskvibcurve; locallab.spots.at(j).recothresv = locallab.spots.at(j).recothresv && pSpot.recothresv == otherSpot.recothresv; locallab.spots.at(j).lowthresv = locallab.spots.at(j).lowthresv && pSpot.lowthresv == otherSpot.lowthresv; @@ -1567,6 +1571,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).sigmalc2 = locallab.spots.at(j).sigmalc2 && pSpot.sigmalc2 == otherSpot.sigmalc2; locallab.spots.at(j).strwav = locallab.spots.at(j).strwav && pSpot.strwav == otherSpot.strwav; locallab.spots.at(j).angwav = locallab.spots.at(j).angwav && pSpot.angwav == otherSpot.angwav; + locallab.spots.at(j).featherwav = locallab.spots.at(j).featherwav && pSpot.featherwav == otherSpot.featherwav; locallab.spots.at(j).strengthw = locallab.spots.at(j).strengthw && pSpot.strengthw == otherSpot.strengthw; locallab.spots.at(j).sigmaed = locallab.spots.at(j).sigmaed && pSpot.sigmaed == otherSpot.sigmaed; locallab.spots.at(j).radiusw = locallab.spots.at(j).radiusw && pSpot.radiusw == otherSpot.radiusw; @@ -1678,6 +1683,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).baselog = locallab.spots.at(j).baselog && pSpot.baselog == otherSpot.baselog; locallab.spots.at(j).strlog = locallab.spots.at(j).strlog && pSpot.strlog == otherSpot.strlog; locallab.spots.at(j).anglog = locallab.spots.at(j).anglog && pSpot.anglog == otherSpot.anglog; + locallab.spots.at(j).featherlog = locallab.spots.at(j).featherlog && pSpot.featherlog == otherSpot.featherlog; locallab.spots.at(j).CCmaskcurveL = locallab.spots.at(j).CCmaskcurveL && pSpot.CCmaskcurveL == otherSpot.CCmaskcurveL; locallab.spots.at(j).LLmaskcurveL = locallab.spots.at(j).LLmaskcurveL && pSpot.LLmaskcurveL == otherSpot.LLmaskcurveL; locallab.spots.at(j).HHmaskcurveL = locallab.spots.at(j).HHmaskcurveL && pSpot.HHmaskcurveL == otherSpot.HHmaskcurveL; @@ -1716,6 +1722,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).shadmask = locallab.spots.at(j).shadmask && pSpot.shadmask == otherSpot.shadmask; locallab.spots.at(j).str_mask = locallab.spots.at(j).str_mask && pSpot.str_mask == otherSpot.str_mask; locallab.spots.at(j).ang_mask = locallab.spots.at(j).ang_mask && pSpot.ang_mask == otherSpot.ang_mask; + locallab.spots.at(j).feather_mask = locallab.spots.at(j).feather_mask && pSpot.feather_mask == otherSpot.feather_mask; locallab.spots.at(j).HHhmask_curve = locallab.spots.at(j).HHhmask_curve && pSpot.HHhmask_curve == otherSpot.HHhmask_curve; locallab.spots.at(j).Lmask_curve = locallab.spots.at(j).Lmask_curve && pSpot.Lmask_curve == otherSpot.Lmask_curve; locallab.spots.at(j).LLmask_curvewav = locallab.spots.at(j).LLmask_curvewav && pSpot.LLmask_curvewav == otherSpot.LLmask_curvewav; @@ -1848,7 +1855,8 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).strgradcie = locallab.spots.at(j).strgradcie && pSpot.strgradcie == otherSpot.strgradcie; locallab.spots.at(j).anggradcie = locallab.spots.at(j).anggradcie && pSpot.anggradcie == otherSpot.anggradcie; - + locallab.spots.at(j).feathercie = locallab.spots.at(j).feathercie && pSpot.feathercie == otherSpot.feathercie; + locallab.spots.at(j).enacieMask = locallab.spots.at(j).enacieMask && pSpot.enacieMask == otherSpot.enacieMask; locallab.spots.at(j).enacieMaskall = locallab.spots.at(j).enacieMaskall && pSpot.enacieMaskall == otherSpot.enacieMaskall; locallab.spots.at(j).CCmaskciecurve = locallab.spots.at(j).CCmaskciecurve && pSpot.CCmaskciecurve == otherSpot.CCmaskciecurve; @@ -3832,6 +3840,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).angcol = mods.locallab.spots.at(i).angcol; } + if (locallab.spots.at(i).feathercol) { + toEdit.locallab.spots.at(i).feathercol = mods.locallab.spots.at(i).feathercol; + } + if (locallab.spots.at(i).blurcolde) { toEdit.locallab.spots.at(i).blurcolde = mods.locallab.spots.at(i).blurcolde; } @@ -4081,6 +4093,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).angexp = mods.locallab.spots.at(i).angexp; } + if (locallab.spots.at(i).featherexp) { + toEdit.locallab.spots.at(i).featherexp = mods.locallab.spots.at(i).featherexp; + } + if (locallab.spots.at(i).excurve) { toEdit.locallab.spots.at(i).excurve = mods.locallab.spots.at(i).excurve; } @@ -4300,6 +4316,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).angSH = mods.locallab.spots.at(i).angSH; } + if (locallab.spots.at(i).featherSH) { + toEdit.locallab.spots.at(i).featherSH = mods.locallab.spots.at(i).featherSH; + } + if (locallab.spots.at(i).inverssh) { toEdit.locallab.spots.at(i).inverssh = mods.locallab.spots.at(i).inverssh; } @@ -4477,6 +4497,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).angvib = mods.locallab.spots.at(i).angvib; } + if (locallab.spots.at(i).feathervib) { + toEdit.locallab.spots.at(i).feathervib = mods.locallab.spots.at(i).feathervib; + } + if (locallab.spots.at(i).Lmaskvibcurve) { toEdit.locallab.spots.at(i).Lmaskvibcurve = mods.locallab.spots.at(i).Lmaskvibcurve; } @@ -5325,6 +5349,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).angwav = mods.locallab.spots.at(i).angwav; } + if (locallab.spots.at(i).featherwav) { + toEdit.locallab.spots.at(i).featherwav = mods.locallab.spots.at(i).featherwav; + } + if (locallab.spots.at(i).strengthw) { toEdit.locallab.spots.at(i).strengthw = mods.locallab.spots.at(i).strengthw; } @@ -5749,6 +5777,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).anglog = mods.locallab.spots.at(i).anglog; } + if (locallab.spots.at(i).featherlog) { + toEdit.locallab.spots.at(i).featherlog = mods.locallab.spots.at(i).featherlog; + } + if (locallab.spots.at(i).CCmaskcurveL) { toEdit.locallab.spots.at(i).CCmaskcurveL = mods.locallab.spots.at(i).CCmaskcurveL; } @@ -5890,6 +5922,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).ang_mask = mods.locallab.spots.at(i).ang_mask; } + if (locallab.spots.at(i).feather_mask) { + toEdit.locallab.spots.at(i).feather_mask = mods.locallab.spots.at(i).feather_mask; + } + if (locallab.spots.at(i).HHhmask_curve) { toEdit.locallab.spots.at(i).HHhmask_curve = mods.locallab.spots.at(i).HHhmask_curve; } @@ -6423,6 +6459,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).anggradcie = mods.locallab.spots.at(i).anggradcie; } + if (locallab.spots.at(i).feathercie) { + toEdit.locallab.spots.at(i).feathercie = mods.locallab.spots.at(i).feathercie; + } + if (locallab.spots.at(i).enacieMask) { toEdit.locallab.spots.at(i).enacieMask = mods.locallab.spots.at(i).enacieMask; } @@ -7938,6 +7978,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : strcolab(v), strcolh(v), angcol(v), + feathercol(v), blurcolde(v), blurcol(v), contcol(v), @@ -8000,6 +8041,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : blurexpde(v), strexp(v), angexp(v), + featherexp(v), excurve(v), norm(v), inversex(v), @@ -8055,6 +8097,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : blurSHde(v), strSH(v), angSH(v), + featherSH(v), inverssh(v), chromaskSH(v), gammaskSH(v), @@ -8100,6 +8143,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : strvibab(v), strvibh(v), angvib(v), + feathervib(v), Lmaskvibcurve(v), recothresv(v), lowthresv(v), @@ -8316,6 +8360,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : sigmalc2(v), strwav(v), angwav(v), + featherwav(v), strengthw(v), sigmaed(v), radiusw(v), @@ -8422,6 +8467,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : baselog(v), strlog(v), anglog(v), + featherlog(v), CCmaskcurveL(v), LLmaskcurveL(v), HHmaskcurveL(v), @@ -8459,6 +8505,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : shadmask(v), str_mask(v), ang_mask(v), + feather_mask(v), HHhmask_curve(v), Lmask_curve(v), LLmask_curvewav(v), @@ -8588,6 +8635,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : surroundcie(v), strgradcie(v), anggradcie(v), + feathercie(v), enacieMask(v), enacieMaskall(v), CCmaskciecurve(v), @@ -8690,6 +8738,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) strcolab = v; strcolh = v; angcol = v; + feathercol = v; blurcolde = v; blurcol = v; contcol = v; @@ -8752,6 +8801,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) blurexpde = v; strexp = v; angexp = v; + featherexp = v; excurve = v; norm = v; inversex = v; @@ -8811,6 +8861,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) blurSHde = v; strSH = v; angSH = v; + featherSH = v; inverssh = v; chromaskSH = v; gammaskSH = v; @@ -8856,6 +8907,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) strvibab = v; strvibh = v; angvib = v; + feathervib = v; Lmaskvibcurve = v; recothresv = v; lowthresv = v; @@ -9071,6 +9123,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) sigmalc2 = v; strwav = v; angwav = v; + featherwav = v; strengthw = v; sigmaed = v; radiusw = v; @@ -9181,6 +9234,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) baselog = v; strlog = v; anglog = v; + featherlog = v; CCmaskcurveL = v; LLmaskcurveL = v; HHmaskcurveL = v; @@ -9218,6 +9272,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) shadmask = v; str_mask = v; ang_mask = v; + feather_mask = v; HHhmask_curve = v; Lmask_curve = v; LLmask_curvewav = v; @@ -9346,6 +9401,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) detailcie = v; surroundcie = v; anggradcie = v; + feathercie = v; strgradcie = v; enacieMask = v; enacieMaskall = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 27f9ac9cc..bc617612c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -476,6 +476,7 @@ public: bool strcolab; bool strcolh; bool angcol; + bool feathercol; bool blurcolde; bool blurcol; bool contcol; @@ -538,6 +539,7 @@ public: bool blurexpde; bool strexp; bool angexp; + bool featherexp; bool excurve; bool norm; bool inversex; @@ -593,6 +595,7 @@ public: bool blurSHde; bool strSH; bool angSH; + bool featherSH; bool inverssh; bool chromaskSH; bool gammaskSH; @@ -638,6 +641,7 @@ public: bool strvibab; bool strvibh; bool angvib; + bool feathervib; bool Lmaskvibcurve; bool recothresv; bool lowthresv; @@ -854,6 +858,7 @@ public: bool sigmalc2; bool strwav; bool angwav; + bool featherwav; bool strengthw; bool sigmaed; bool radiusw; @@ -960,6 +965,7 @@ public: bool baselog; bool strlog; bool anglog; + bool featherlog; bool CCmaskcurveL; bool LLmaskcurveL; bool HHmaskcurveL; @@ -997,6 +1003,7 @@ public: bool shadmask; bool str_mask; bool ang_mask; + bool feather_mask; bool HHhmask_curve; bool Lmask_curve; bool LLmask_curvewav; @@ -1127,6 +1134,7 @@ public: bool surroundcie; bool strgradcie; bool anggradcie; + bool feathercie; bool enacieMask; bool enacieMaskall; From c478c7caa32cbb0b2ec9b8d65e588d4d91123b8b Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 16 Jun 2024 10:47:04 -0700 Subject: [PATCH 234/291] Remove Itanium architecture support for Windows --- UpdateInfo.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UpdateInfo.cmake b/UpdateInfo.cmake index b0c2bdff6..350adc071 100644 --- a/UpdateInfo.cmake +++ b/UpdateInfo.cmake @@ -100,15 +100,15 @@ if(WIN32) if(BIT_DEPTH EQUAL 4) set(BUILD_BIT_DEPTH 32) # 32 bits builds has to be installable on 64 bits system, to support WinXP/64. - set(ARCHITECTURE_ALLOWED "x86 x64 ia64") + set(ARCHITECTURE_ALLOWED "x86 x64") # installing in 32 bits mode even on 64 bits OS and architecture set(INSTALL_MODE "") elseif(BIT_DEPTH EQUAL 8) set(BUILD_BIT_DEPTH 64) # Restricting the 64 bits builds to 64 bits systems only - set(ARCHITECTURE_ALLOWED "x64 ia64 arm64") + set(ARCHITECTURE_ALLOWED "x64 arm64") # installing in 64 bits mode for all 64 bits processors, even for itanium architecture - set(INSTALL_MODE "x64 ia64 arm64") + set(INSTALL_MODE "x64 arm64") endif() # set part of the output archive name set(SYSTEM_NAME "WinVista") From 3433741bb6df4849003def58503411f0f0d5e9ff Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:33:46 -0700 Subject: [PATCH 235/291] Mention capture sharpening in contrast mask tool-tip Closes #7087. --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index f8f7cf114..5ef480ce4 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1793,7 +1793,7 @@ MAIN_TOOLTIP_PREVIEWFOCUSMASK;Preview the focus mask.\nShortcut: Shift 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_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l From 89de9792480b239fe7b5f5bbb584019c0ce7e1c9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 16 Jun 2024 16:41:55 -0700 Subject: [PATCH 236/291] Add Nikon Z f color matrix --- rtengine/camconst.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtengine/camconst.json b/rtengine/camconst.json index b80d776b8..00fc2cf5d 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -2101,6 +2101,11 @@ Camera constants: "pdaf_pattern": [285, 297, 309, 321, 333, 345, 357, 369, 381, 393, 405, 417, 429, 441, 453, 465, 477, 489, 501, 513, 525, 537, 549, 561, 573, 585, 597, 609, 621, 633, 645, 657, 669, 681, 693, 705, 717, 729, 741, 753, 765, 777, 789, 801, 813, 825, 837, 849, 861, 873, 885, 897, 909, 921, 933, 945, 957, 969, 981, 993, 1005, 1017, 1029, 1041, 1053, 1065, 1077, 1089, 1101, 1113, 1125, 1137, 1149, 1161, 1173, 1185, 1197, 1209, 1221, 1233, 1245, 1257, 1269, 1281, 1293, 1305, 1317, 1329, 1341, 1353, 1365, 1377, 1389, 1401, 1413, 1425, 1437, 1449, 1461, 1473, 1485, 1497, 1509, 1521, 1533, 1545, 1557, 1569, 1581, 1593, 1605, 1617, 1629, 1641, 1653, 1665, 1677, 1689, 1701, 1713, 1725, 1737, 1749, 1761, 1773, 1785, 1797, 1809, 1821, 1833, 1845, 1857, 1869, 1881, 1893, 1905, 1917, 1929, 1941, 1953, 1965, 1977, 1989, 2001, 2013, 2025, 2037, 2049, 2061, 2073, 2085, 2097, 2109, 2121, 2133, 2145, 2157, 2169, 2181, 2193, 2205, 2217, 2229, 2241, 2253, 2265, 2277, 2289, 2301, 2313, 2325, 2337, 2349, 2361, 2373, 2385, 2397, 2409, 2421, 2433, 2445, 2457, 2469, 2481, 2493, 2505, 2517, 2529, 2541, 2553, 2565, 2577, 2589, 2601, 2613, 2625, 2637, 2649, 2661, 2673, 2685, 2697, 2709, 2721, 2733, 2745, 2757, 2769, 2781, 2793, 2805, 2817, 2829, 2841, 2853, 2865, 2877, 2889, 2901, 2913, 2925, 2937, 2949, 2961, 2973, 2985, 2997, 3009, 3021, 3033, 3045, 3057, 3069, 3081, 3093, 3105, 3117, 3129, 3141, 3153, 3165, 3177, 3189, 3201, 3213, 3225, 3237, 3249, 3261, 3273, 3285, 3297, 3309, 3321, 3333, 3345, 3357, 3369, 3381, 3393, 3405, 3417, 3429, 3441] }, + { // Quality C + "make_model" : "Nikon Z f", + "dcraw_matrix" : [ 11607, -4491, -977, -4522, 12460, 2304, -458, 1519, 7616 ] // DNG v16.1 + }, + { // Quality B, 16Mp and 64Mp raw frames "make_model": "OLYMPUS E-M5MarkII", "dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65 From cffba6c3b065a3d537107875d98ab527484d014d Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 17 Jun 2024 02:15:19 +0000 Subject: [PATCH 237/291] Move add-extension panel to top of frame --- rtgui/preferences.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 97bfb92b6..54e0c6725 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1552,9 +1552,9 @@ Gtk::Widget* Preferences::getFileBrowserPanel() frmnu->add (*menuGrid); - Gtk::Frame* fre = Gtk::manage(new Gtk::Frame(M("PREFERENCES_PARSEDEXT"))); Gtk::Box* vbre = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + Gtk::Box* hb0 = Gtk::manage(new Gtk::Box()); Gtk::Label* elab = Gtk::manage (new Gtk::Label (M("PREFERENCES_PARSEDEXTADD") + ":", Gtk::ALIGN_START)); hb0->pack_start(*elab, Gtk::PACK_SHRINK, 4); @@ -1582,6 +1582,7 @@ Gtk::Widget* Preferences::getFileBrowserPanel() hb0->pack_end(*moveExtUp, Gtk::PACK_SHRINK, 4); 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); @@ -1591,8 +1592,9 @@ Gtk::Widget* Preferences::getFileBrowserPanel() 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); + vbre->pack_start(*hscrollw); fre->add(*vbre); @@ -2679,7 +2681,7 @@ void Preferences::addExtPressed() } } - Gtk::TreeRow row = * (extensionModel->append()); + Gtk::TreeRow row = * (extensionModel->prepend()); row[extensionColumns.enabled] = true; row[extensionColumns.ext] = extension->get_text(); From 6eb191c5e5e55044c357a0c27869c7bf2c744277 Mon Sep 17 00:00:00 2001 From: xiota Date: Mon, 17 Jun 2024 01:25:06 +0000 Subject: [PATCH 238/291] Disable addExt/delExt buttons based on context --- rtgui/preferences.cc | 81 +++++++++++++++++++++++++++++--------------- rtgui/preferences.h | 2 ++ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 54e0c6725..94dc68e65 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1566,8 +1566,10 @@ Gtk::Widget* Preferences::getFileBrowserPanel() delExt = Gtk::manage(new Gtk::Button()); moveExtUp = Gtk::manage(new Gtk::Button()); moveExtDown = Gtk::manage(new Gtk::Button()); - addExt->set_tooltip_text(M("PREFERENCES_PARSEDEXTADDHINT")); - delExt->set_tooltip_text(M("PREFERENCES_PARSEDEXTDELHINT")); + addExt->set_sensitive(false); + delExt->set_sensitive(false); + addExt->set_tooltip_markup(M("PREFERENCES_PARSEDEXTADDHINT")); + delExt->set_tooltip_markup(M("PREFERENCES_PARSEDEXTDELHINT")); moveExtUp->set_tooltip_text(M("PREFERENCES_PARSEDEXTUPHINT")); moveExtDown->set_tooltip_text(M("PREFERENCES_PARSEDEXTDOWNHINT")); Gtk::Image* addExtImg = Gtk::manage ( new RTImage ("add-small", Gtk::ICON_SIZE_BUTTON) ); @@ -1672,11 +1674,14 @@ Gtk::Widget* Preferences::getFileBrowserPanel() vbFileBrowser->pack_start (*hb6, Gtk::PACK_SHRINK, 4); + extensions->signal_cursor_changed().connect(sigc::mem_fun(*this, &Preferences::extensionsChanged)); + extension->signal_changed().connect(sigc::mem_fun(*this, &Preferences::extensionChanged)); + addExt->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::addExtPressed)); delExt->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::delExtPressed)); moveExtUp->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::moveExtUpPressed)); moveExtDown->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::moveExtDownPressed)); - extension->signal_activate().connect(sigc::mem_fun(*this, &Preferences::addExtPressed)); + clearThumbsBtn->signal_clicked().connect ( sigc::mem_fun (*this, &Preferences::clearThumbImagesPressed) ); if (moptions.saveParamsCache) { clearProfilesBtn->signal_clicked().connect(sigc::mem_fun(*this, &Preferences::clearProfilesPressed)); @@ -2670,9 +2675,50 @@ void Preferences::workflowUpdate() } } +void Preferences::extensionsChanged() +{ + const Glib::RefPtr selection = extensions->get_selection(); + if (!selection) { + delExt->set_sensitive(false); + return; + } + + const Gtk::TreeModel::iterator selected = selection->get_selected(); + if (!selected) { + delExt->set_sensitive(false); + return; + } + + bool delOkay = true; + for (auto const &x : moptions.knownExtensions) { + if (x == (*selected)[extensionColumns.ext]) { + delOkay = false; + break; + } + } + delExt->set_sensitive(delOkay); +} + +void Preferences::extensionChanged() +{ + if (extension->get_text()[0] == '\0') { + addExt->set_sensitive(false); + return; + } + + Gtk::TreeNodeChildren c = extensionModel->children(); + for (size_t i = 0; i < c.size(); i++) { + if (c[i][extensionColumns.ext] == extension->get_text()) { + addExt->set_sensitive(false); + return; + } + } + + addExt->set_sensitive(true); +} + void Preferences::addExtPressed() { - Gtk::TreeNodeChildren c = extensionModel->children(); for (size_t i = 0; i < c.size(); i++) { @@ -2685,33 +2731,14 @@ void Preferences::addExtPressed() row[extensionColumns.enabled] = true; row[extensionColumns.ext] = extension->get_text(); + + extension->set_text(""); + addExt->set_sensitive(false); } void Preferences::delExtPressed() { - const Glib::RefPtr selection = extensions->get_selection(); - - if (!selection) { - return; - } - - const Gtk::TreeModel::iterator selected = selection->get_selected(); - - if (!selected) { - return; - } - - bool delOkay = true; - for (auto const &x : moptions.knownExtensions) { - if (x == (*selected)[extensionColumns.ext]) { - delOkay = false; - break; - } - } - - if (delOkay) { - extensionModel->erase(selected); - } + extensionModel->erase(extensions->get_selection()->get_selected()); } void Preferences::moveExtUpPressed() diff --git a/rtgui/preferences.h b/rtgui/preferences.h index e01ec85c0..b98a8a306 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -323,6 +323,8 @@ public: void observer10Toggled (); void selectStartupDir (); + void extensionsChanged (); + void extensionChanged (); void addExtPressed (); void delExtPressed (); void moveExtUpPressed (); From 021b7dfff0bfea4fd32427ccb95a27d2c235fd58 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 22 Jun 2024 18:55:01 -0700 Subject: [PATCH 239/291] Fix Foveon row alignment regression --- rtengine/rawimage.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 301107034..53914694a 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -1211,15 +1211,18 @@ float** RawImage::compress_image(unsigned int frameNum, bool freeImage) height -= top_margin; width -= left_margin; } + + const auto image_width = get_maker() == "Sigma" ? raw_width : iwidth; // Foveon: Image has all raw data. + #ifdef _OPENMP #pragma omp parallel for #endif for (int row = 0; row < height; row++) for (int col = 0; col < width; col++) { - this->data[row][3 * col + 0] = image[(row + top_margin) * iwidth + col + left_margin][0]; - this->data[row][3 * col + 1] = image[(row + top_margin) * iwidth + col + left_margin][1]; - this->data[row][3 * col + 2] = image[(row + top_margin) * iwidth + col + left_margin][2]; + this->data[row][3 * col + 0] = image[(row + top_margin) * image_width + col + left_margin][0]; + this->data[row][3 * col + 1] = image[(row + top_margin) * image_width + col + left_margin][1]; + this->data[row][3 * col + 2] = image[(row + top_margin) * image_width + col + left_margin][2]; } } From 51277dc7d2521a306ae4314cc3e1dc0deedb315e Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 23 Jun 2024 12:40:51 -0700 Subject: [PATCH 240/291] Move function into anonymous namespace --- rtengine/rawimagesource.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 03823644b..63969a21c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -420,6 +420,16 @@ void transLineD1x(const float* const red, const float* const green, const float* } } +bool checkRawDataDimensions(const array2D &rawData, const rtengine::RawImage &rawImage, int width, int height) +{ + const int colors = (rawImage.getSensorType() == rtengine::ST_BAYER || + rawImage.getSensorType() == rtengine::ST_FUJI_XTRANS || + rawImage.get_colors() == 1) + ? 1 + : 3; + return rawData.getHeight() == height && rawData.getWidth() == colors * width; +} + } @@ -742,16 +752,6 @@ void RawImageSource::getWBMults(const ColorTemp &ctemp, const RAWParams &raw, st autoGainComp = camInitialGain / initialGain; } -bool checkRawDataDimensions(const array2D &rawData, const RawImage &rawImage, int width, int height) -{ - const int colors = (rawImage.getSensorType() == rtengine::ST_BAYER || - rawImage.getSensorType() == rtengine::ST_FUJI_XTRANS || - rawImage.get_colors() == 1) - ? 1 - : 3; - return rawData.getHeight() == height && rawData.getWidth() == colors * width; -} - void RawImageSource::getImage(const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const ToneCurveParams &hrp, const RAWParams &raw) { assert(checkRawDataDimensions(rawData, *ri, W, H)); From 082207eb6033c0c413b5f654998aab66d3d03b38 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 17:21:18 -0700 Subject: [PATCH 241/291] macOS CI: update libomp library to current --- .github/workflows/macos.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 3a0f27483..60bee53aa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -25,7 +25,7 @@ jobs: mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl | tee -a depslog + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring @@ -69,7 +69,6 @@ jobs: -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DOSX_CONTINUOUS=ON \ .. - curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' - name: Compile RawTherapee run: | From 5a8f048e8aa94ad8c0b537347f92ad3147027bab Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 17:25:53 -0700 Subject: [PATCH 242/291] mac: bundle libjxl_cms --- tools/osx/macosx_bundle.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index bd0dcf3e1..83689d45b 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -220,6 +220,9 @@ ModifyInstallNames 2>&1 # Copy libpng16 to the app bundle cp ${LOCAL_PREFIX}/lib/libpng16.16.dylib "${CONTENTS}/Frameworks/libpng16.16.dylib" +# Copy libjxl_cms to the app bundle +cp ${LOCAL_PREFIX}/lib/libjxl_cms.0.10.dylib "${CONTENTS}/Frameworks/libjxl_cms.0.10.dylib" + # Copy graphite to Frameworks cp ${LOCAL_PREFIX}/lib/libgraphite2.3.dylib "${CONTENTS}/Frameworks" From 893c4a153e56e251b614bab67b6dbe966772d106 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 18:00:40 -0700 Subject: [PATCH 243/291] macOS CI: point to new location of libomp --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 60bee53aa..1188ae017 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -63,7 +63,7 @@ jobs: -DOpenMP_CXX_FLAGS="${C_FLAGS}" \ -DOpenMP_C_LIB_NAMES=libomp \ -DOpenMP_CXX_LIB_NAMES=libomp \ - -DOpenMP_libomp_LIBRARY=/usr/local/lib/libomp.dylib \ + -DOpenMP_libomp_LIBRARY=/usr/local/opt/libomp/lib/libomp.dylib \ -DCMAKE_AR=/usr/bin/ar \ -DCMAKE_RANLIB=/usr/bin/ranlib \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ From df607d5e0418b769d43b0952c68b96ecdcdddbe5 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 18:07:07 -0700 Subject: [PATCH 244/291] macOS CI: point linker to opt/libomp --- .github/workflows/macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 1188ae017..307236fcf 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -35,7 +35,7 @@ jobs: CMAKE_CXX_STANDARD: 11 PKG_CONFIG_PATH: /usr/local/opt/libtiff/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/expat/lib/pkgconfig RAW_THERAPEE_MAJOR: '5' - RAW_THERAPEE_MINOR: '8' + RAW_THERAPEE_MINOR: '10' C_FLAGS: > -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include run: | @@ -48,7 +48,7 @@ jobs: cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ + -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libomp/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_MAJOR}.${RAW_THERAPEE_MINOR}-${REF}" \ -DPROC_TARGET_NUMBER="1" \ -DPROC_LABEL="generic processor" \ From 688f9696286c4e4a7c72deb64d6bda4c7af60e6f Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 18:11:34 -0700 Subject: [PATCH 245/291] macOS CI: also point cflags to opt/libomp --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 307236fcf..ef27c6dcb 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -37,7 +37,7 @@ jobs: RAW_THERAPEE_MAJOR: '5' RAW_THERAPEE_MINOR: '10' C_FLAGS: > - -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include + -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/opt/libomp/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include run: | # GITHUB_REF is the ref that triggered the build, like # refs/heads/new-feature - the next line parses that to REF: the branch From 1235cb202008630a41677ccaea0bb9f941e2b993 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 25 Jun 2024 18:16:04 -0700 Subject: [PATCH 246/291] macOS CI: add include to cflags --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ef27c6dcb..fd2928a58 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -37,7 +37,7 @@ jobs: RAW_THERAPEE_MAJOR: '5' RAW_THERAPEE_MINOR: '10' C_FLAGS: > - -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/opt/libomp/lib/libomp.dylib -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include + -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/opt/libomp/lib/libomp.dylib -I/usr/local/opt/libomp/include -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include run: | # GITHUB_REF is the ref that triggered the build, like # refs/heads/new-feature - the next line parses that to REF: the branch From b673154531bd3582f25cdb2fb5fd3b468f8d5324 Mon Sep 17 00:00:00 2001 From: Daniel Martinez Date: Tue, 17 May 2022 23:03:55 -0400 Subject: [PATCH 247/291] Support more ARQ files, 4 and 16 Shot ARQ from ILCE-1 --- rtengine/dcraw.cc | 7 ++++--- rtengine/pixelshift.cc | 36 ++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 3358dc91b..7131eabf4 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -6590,9 +6590,10 @@ int CLASS parse_tiff_ifd (int base) break; case 258: /* BitsPerSample */ case 61443: - tiff_ifd[ifd].samples = len & 7; + if(!tiff_ifd[ifd].samples || tag != 258) + tiff_ifd[ifd].samples = len & 7; if ((tiff_ifd[ifd].bps = getint(type)) > 32) - tiff_ifd[ifd].bps = 8; + tiff_ifd[ifd].bps = 8; if (tiff_bps < tiff_ifd[ifd].bps) tiff_bps = tiff_ifd[ifd].bps; break; @@ -7288,7 +7289,7 @@ void CLASS apply_tiff() load_raw = &CLASS olympus_load_raw; // ------- RT ------- if (!strncmp(make,"SONY",4) && - (!strncmp(model,"ILCE-7RM3",9) || !strncmp(model,"ILCE-7RM4",9)) && + (!strncmp(model,"ILCE-7RM3",9) || !strncmp(model,"ILCE-7RM4",9) || !strncmp(model,"ILCE-1",6)) && tiff_samples == 4 && tiff_ifd[raw].bytes == raw_width*raw_height*tiff_samples*2) { load_raw = &CLASS sony_arq_load_raw; diff --git a/rtengine/pixelshift.cc b/rtengine/pixelshift.cc index 8088e2e9c..2df07f074 100644 --- a/rtengine/pixelshift.cc +++ b/rtengine/pixelshift.cc @@ -592,6 +592,7 @@ BENCHFUN static const float ePerIsoILCE7RM3 = 0.8f; + //TODO: Add data for ILCE-7RM4, and ILCE-1 if(plistener) { plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_PIXELSHIFT"))); plistener->setProgress(0.0); @@ -610,18 +611,29 @@ BENCHFUN int nReadIndex = static_cast(round(log2(idata->getISOSpeed() / 100.f) * 3.f)); - if(model.find("K-3") != string::npos) { - nRead = nReadK3II[nReadIndex]; - eperIsoModel = ePerIsoK3II; - } else if(model.find("K-1") != string::npos) { // this also matches K-1 Mark II - nRead = nReadK1[nReadIndex]; - eperIsoModel = ePerIsoK1; - } else if(model.find("ILCE-7RM3") != string::npos) { - nRead = nReadILCE7RM3[nReadIndex]; - eperIsoModel = ePerIsoILCE7RM3; - } else { // as long as we don't have values for Pentax KP, we use the values from K-70 - nRead = nReadK70[nReadIndex]; - eperIsoModel = ePerIsoK70; + if(make.find("Sony") != string::npos) { + if(model.find("ILCE-7RM3") != string::npos) { + nRead = nReadILCE7RM3[nReadIndex]; + eperIsoModel = ePerIsoILCE7RM3; + /* TODO: When we have data for missing ILCE-7RM4, and ILCE-1, add it here + } else if(model.find("ILCE-7RM4") != string::npos) { + } else if(model.find("ILCE-1") != string::npos) { + */ + } else { // default to ILCE-7RM3 for Sony cameras without data + nRead = nReadILCE7RM3[nReadIndex]; + eperIsoModel = ePerIsoILCE7RM3; + } + } else { // Pentax + if(model.find("K-3") != string::npos) { + nRead = nReadK3II[nReadIndex]; + eperIsoModel = ePerIsoK3II; + } else if(model.find("K-1") != string::npos) { // this also matches K-1 Mark II + nRead = nReadK1[nReadIndex]; + eperIsoModel = ePerIsoK1; + } else { // as long as we don't have values for Pentax KP, we use the values from K-70 + nRead = nReadK70[nReadIndex]; + eperIsoModel = ePerIsoK70; + } } eperIsoModel *= pow(2.f, eperIso - 1.f); From 88160bd8b858256260253546b5b014f7b9991259 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 30 Jun 2024 02:53:49 +0000 Subject: [PATCH 248/291] Update PREFERENCES_PARSEDEXTDELHINT (default/English) --- rtdata/languages/English (UK) | 2 +- rtdata/languages/English (US) | 2 +- rtdata/languages/default | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 37ccdc48f..5d22fa61f 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -2154,7 +2154,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_PARSEDEXT;Parsed Extensions !PREFERENCES_PARSEDEXTADD;Add extension !PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. -!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list.\nPredefined extensions cannot be deleted. !PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. !PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PERFORMANCE_MEASURE;Measure diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 079713ac1..4cd01622a 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -1971,7 +1971,7 @@ !PREFERENCES_PARSEDEXT;Parsed Extensions !PREFERENCES_PARSEDEXTADD;Add extension !PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. -!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list.\nPredefined extensions cannot be deleted. !PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. !PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PERFORMANCE_MEASURE;Measure diff --git a/rtdata/languages/default b/rtdata/languages/default index 75d060dec..7a4c8aea7 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2038,7 +2038,7 @@ PREFERENCES_PANFACTORLABEL;Pan rate amplification PREFERENCES_PARSEDEXT;Parsed Extensions PREFERENCES_PARSEDEXTADD;Add extension PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. -PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list.\nPredefined extensions cannot be deleted. PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. PREFERENCES_PERFORMANCE_MEASURE;Measure From 7168870d695d887e65c4bf595843d1170b542ea7 Mon Sep 17 00:00:00 2001 From: xiota Date: Sun, 30 Jun 2024 02:55:30 +0000 Subject: [PATCH 249/291] Improve empty string check --- rtgui/preferences.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 94dc68e65..f6f80a2d3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2701,7 +2701,7 @@ void Preferences::extensionsChanged() void Preferences::extensionChanged() { - if (extension->get_text()[0] == '\0') { + if (extension->get_text().empty()) { addExt->set_sensitive(false); return; } From 819b65af7fc0b6b62d598681b8a5b47103d73068 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 30 Jun 2024 07:47:55 +0200 Subject: [PATCH 250/291] Keep values scope from 5.10 Selective Editing - for color & light - shadow/highlight - vibrance #7102 (#7107) * ppversion 351 and keep valus scope for color and light shadow-highligt vibrance * Change comment in ppversion.h * Change procparams for colorscope pp<351 * Remove not used isset --- rtengine/improccoordinator.cc | 16 ++++++++++------ rtengine/procparams.cc | 29 ++++++++++++++++++++++++++--- rtgui/ppversion.h | 4 +++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 46dd7bc29..127c65248 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1170,9 +1170,11 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) if (params->locallab.spots.at(sp).equilret && params->locallab.spots.at(sp).expreti) { savenormreti.reset(new LabImage(*oprevl, true)); } - if(params->locallab.spots.at(sp).colorscope != 30) {//compatibility with old method in controlspotpanel to change scope - default value 30 - scopefp[sp]= params->locallab.spots.at(sp).colorscope; - } + + // if(params->locallab.spots.at(sp).colorscope != 30) {//compatibility with old method in controlspotpanel to change scope - default value 30 + // scopefp[sp]= params->locallab.spots.at(sp).colorscope; + // } + // Set local curves of current spot to LUT locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); @@ -1587,7 +1589,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) bool islog = params->locallab.spots.at(sp).explog; bool ismas = params->locallab.spots.at(sp).expmask; bool iscie = params->locallab.spots.at(sp).expcie; - bool isset = iscolor || issh || isvib; + // bool isset = iscolor || issh || isvib; //set select spot settings LocallabListener::locallabsetLC locsetlc; @@ -1615,13 +1617,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) locallListener->cieChanged(locallcielc,params->locallab.selspot); } locallListener->sigChanged(locallciesig,params->locallab.selspot); - if(params->locallab.spots.at(sp).colorscope != 30) {//compatibility with old method in controlspotpanel + /* + if(params->locallab.spots.at(sp).colorscope != 0) {//compatibility with old method in controlspotpanel locallListener->scopeChangedcol(scopefp[sp], params->locallab.selspot, iscolor); locallListener->scopeChangedsh(scopefp[sp], params->locallab.selspot, issh); locallListener->scopeChangedvib(scopefp[sp], params->locallab.selspot, isvib); locallListener->scopeChangedset(scopefp[sp], params->locallab.selspot, isset); - params->locallab.spots.at(sp).colorscope = 30; + //params->locallab.spots.at(sp).colorscope = 30; } + */ // if (mainfp[sp] >= 0) {//minimize call to idle register //used by Global fullimage. locallListener->maiChanged(locallsetlc,params->locallab.selspot); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1ba92c366..d5cad43c9 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -9144,7 +9144,16 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "labgridAHighmerg_" + index_str, spot.labgridAHighmerg, spotEdited.labgridAHighmerg); assignFromKeyfile(keyFile, "Locallab", "labgridBHighmerg_" + index_str, spot.labgridBHighmerg, spotEdited.labgridBHighmerg); assignFromKeyfile(keyFile, "Locallab", "Strengthgrid_" + index_str, spot.strengthgrid, spotEdited.strengthgrid); - assignFromKeyfile(keyFile, "Locallab", "Sensi_" + index_str, spot.sensi, spotEdited.sensi); + assignFromKeyfile(keyFile, "Locallab", "Colorscope_" + index_str, spot.colorscope, spotEdited.colorscope); + + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Colorscope_" + index_str)) { + spot.sensi = keyFile.get_integer("Locallab", "Colorscope_" + index_str); + spotEdited.sensi = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Sensi_" + index_str, spot.sensi, spotEdited.sensi); + } assignFromKeyfile(keyFile, "Locallab", "Structcol_" + index_str, spot.structcol, spotEdited.structcol); assignFromKeyfile(keyFile, "Locallab", "Strcol_" + index_str, spot.strcol, spotEdited.strcol); assignFromKeyfile(keyFile, "Locallab", "Strcolab_" + index_str, spot.strcolab, spotEdited.strcolab); @@ -9282,7 +9291,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "shadows_" + index_str, spot.shadows, spotEdited.shadows); assignFromKeyfile(keyFile, "Locallab", "s_tonalwidth_" + index_str, spot.s_tonalwidth, spotEdited.s_tonalwidth); assignFromKeyfile(keyFile, "Locallab", "sh_radius_" + index_str, spot.sh_radius, spotEdited.sh_radius); - assignFromKeyfile(keyFile, "Locallab", "sensihs_" + index_str, spot.sensihs, spotEdited.sensihs); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Colorscope_" + index_str)) { + spot.sensihs = keyFile.get_integer("Locallab", "Colorscope_" + index_str); + spotEdited.sensihs = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "sensihs_" + index_str, spot.sensihs, spotEdited.sensihs); + } assignFromKeyfile(keyFile, "Locallab", "EnaSHMask_" + index_str, spot.enaSHMask, spotEdited.enaSHMask); assignFromKeyfile(keyFile, "Locallab", "CCmaskSHCurve_" + index_str, spot.CCmaskSHcurve, spotEdited.CCmaskSHcurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskSHCurve_" + index_str, spot.LLmaskSHcurve, spotEdited.LLmaskSHcurve); @@ -9336,7 +9352,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "ProtectSkins_" + index_str, spot.protectskins, spotEdited.protectskins); assignFromKeyfile(keyFile, "Locallab", "AvoidColorShift_" + index_str, spot.avoidcolorshift, spotEdited.avoidcolorshift); assignFromKeyfile(keyFile, "Locallab", "PastSatTog_" + index_str, spot.pastsattog, spotEdited.pastsattog); - assignFromKeyfile(keyFile, "Locallab", "Sensiv_" + index_str, spot.sensiv, spotEdited.sensiv); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Colorscope_" + index_str)) { + spot.sensiv = keyFile.get_integer("Locallab", "Colorscope_" + index_str); + spotEdited.sensiv = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Sensiv_" + index_str, spot.sensiv, spotEdited.sensiv); + } assignFromKeyfile(keyFile, "Locallab", "SkinTonesCurve_" + index_str, spot.skintonescurve, spotEdited.skintonescurve); assignFromKeyfile(keyFile, "Locallab", "CCmaskvibCurve_" + index_str, spot.CCmaskvibcurve, spotEdited.CCmaskvibcurve); assignFromKeyfile(keyFile, "Locallab", "LLmaskvibCurve_" + index_str, spot.LLmaskvibcurve, spotEdited.LLmaskvibcurve); diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index f2455699c..6b7909edf 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -1,11 +1,13 @@ #pragma once // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 350 +#define PPVERSION 351 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* Log of version changes + 351 2024-06-19 + take into account Global in selective editing 350 2023-03-05 introduced white balance standard observer 349 2020-10-29 From 89c90774af8df5cc1f37fc556a286b2603b9318e Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 1 Jul 2024 09:35:33 +0200 Subject: [PATCH 251/291] Selective Editing - compatibility 5.10 - Feather - Log encoding (#7120) * Fixed pp3 from 5.10 feather and ciecam log encoding * Fixed 2 wrong typo feather in procparams.cc * Fixed 2 wrong typo feather in procparams.cc * Remove unused line in procparams --- rtengine/procparams.cc | 86 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 9 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index d5cad43c9..b868a7627 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -9159,7 +9159,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Strcolab_" + index_str, spot.strcolab, spotEdited.strcolab); assignFromKeyfile(keyFile, "Locallab", "Strcolh_" + index_str, spot.strcolh, spotEdited.strcolh); assignFromKeyfile(keyFile, "Locallab", "Angcol_" + index_str, spot.angcol, spotEdited.angcol); - assignFromKeyfile(keyFile, "Locallab", "Fetahercol_" + index_str, spot.feathercol, spotEdited.feathercol); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.feathercol = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.feathercol = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Feathercol_" + index_str, spot.feathercol, spotEdited.feathercol); + } assignFromKeyfile(keyFile, "Locallab", "Blurcolde_" + index_str, spot.blurcolde, spotEdited.blurcolde); assignFromKeyfile(keyFile, "Locallab", "Blurcol_" + index_str, spot.blurcol, spotEdited.blurcol); assignFromKeyfile(keyFile, "Locallab", "Contcol_" + index_str, spot.contcol, spotEdited.contcol); @@ -9236,7 +9243,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Gamex_" + index_str, spot.gamex, spotEdited.gamex); assignFromKeyfile(keyFile, "Locallab", "Strexp_" + index_str, spot.strexp, spotEdited.strexp); assignFromKeyfile(keyFile, "Locallab", "Angexp_" + index_str, spot.angexp, spotEdited.angexp); - assignFromKeyfile(keyFile, "Locallab", "Featherexp_" + index_str, spot.featherexp, spotEdited.featherexp); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.featherexp = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.featherexp = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Featherexp_" + index_str, spot.featherexp, spotEdited.featherexp); + } assignFromKeyfile(keyFile, "Locallab", "ExCurve_" + index_str, spot.excurve, spotEdited.excurve); assignFromKeyfile(keyFile, "Locallab", "Norm_" + index_str, spot.norm, spotEdited.norm); assignFromKeyfile(keyFile, "Locallab", "Inversex_" + index_str, spot.inversex, spotEdited.inversex); @@ -9308,7 +9322,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "BlurSHde_" + index_str, spot.blurSHde, spotEdited.blurSHde); assignFromKeyfile(keyFile, "Locallab", "StrSH_" + index_str, spot.strSH, spotEdited.strSH); assignFromKeyfile(keyFile, "Locallab", "AngSH_" + index_str, spot.angSH, spotEdited.angSH); - assignFromKeyfile(keyFile, "Locallab", "FeatherSH_" + index_str, spot.featherSH, spotEdited.featherSH); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.featherSH = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.featherSH = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "FeatherSH_" + index_str, spot.featherSH, spotEdited.featherSH); + } + assignFromKeyfile(keyFile, "Locallab", "Inverssh_" + index_str, spot.inverssh, spotEdited.inverssh); assignFromKeyfile(keyFile, "Locallab", "ChromaskSH_" + index_str, spot.chromaskSH, spotEdited.chromaskSH); assignFromKeyfile(keyFile, "Locallab", "GammaskSH_" + index_str, spot.gammaskSH, spotEdited.gammaskSH); @@ -9375,7 +9397,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Strvibab_" + index_str, spot.strvibab, spotEdited.strvibab); assignFromKeyfile(keyFile, "Locallab", "Strvibh_" + index_str, spot.strvibh, spotEdited.strvibh); assignFromKeyfile(keyFile, "Locallab", "Angvib_" + index_str, spot.angvib, spotEdited.angvib); - assignFromKeyfile(keyFile, "Locallab", "Feathervib_" + index_str, spot.feathervib, spotEdited.feathervib); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.feathervib = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.feathervib = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Feathervib_" + index_str, spot.feathervib, spotEdited.feathervib); + } + assignFromKeyfile(keyFile, "Locallab", "LmaskvibCurve_" + index_str, spot.Lmaskvibcurve, spotEdited.Lmaskvibcurve); assignFromKeyfile(keyFile, "Locallab", "Recothresv_" + index_str, spot.recothresv, spotEdited.recothresv); assignFromKeyfile(keyFile, "Locallab", "Lowthresv_" + index_str, spot.lowthresv, spotEdited.lowthresv); @@ -9625,7 +9655,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Sigmalc2_" + index_str, spot.sigmalc2, spotEdited.sigmalc2); assignFromKeyfile(keyFile, "Locallab", "Strwav_" + index_str, spot.strwav, spotEdited.strwav); assignFromKeyfile(keyFile, "Locallab", "Angwav_" + index_str, spot.angwav, spotEdited.angwav); - assignFromKeyfile(keyFile, "Locallab", "Featherwav_" + index_str, spot.featherwav, spotEdited.featherwav); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.featherwav = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.featherwav = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Featherwav_" + index_str, spot.featherwav, spotEdited.featherwav); + } + assignFromKeyfile(keyFile, "Locallab", "Strengthw_" + index_str, spot.strengthw, spotEdited.strengthw); assignFromKeyfile(keyFile, "Locallab", "Sigmaed_" + index_str, spot.sigmaed, spotEdited.sigmaed); assignFromKeyfile(keyFile, "Locallab", "Radiusw_" + index_str, spot.radiusw, spotEdited.radiusw); @@ -9740,7 +9778,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "AutoGray_" + index_str, spot.Autogray, spotEdited.Autogray); assignFromKeyfile(keyFile, "Locallab", "Fullimage_" + index_str, spot.fullimage, spotEdited.fullimage); assignFromKeyfile(keyFile, "Locallab", "Repart_" + index_str, spot.repar, spotEdited.repar); - assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, spot.ciecam, spotEdited.ciecam); + if (ppVersion <= 350) {//issue 7114 + if (keyFile.has_key("Locallab", "Ciecam_" + index_str)) { + spot.ciecam = true; + spotEdited.ciecam = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Ciecam_" + index_str, spot.ciecam, spotEdited.ciecam); + } + assignFromKeyfile(keyFile, "Locallab", "Satlog_" + index_str, spot.satlog, spotEdited.satlog); assignFromKeyfile(keyFile, "Locallab", "BlackEv_" + index_str, spot.blackEv, spotEdited.blackEv); assignFromKeyfile(keyFile, "Locallab", "WhiteEv_" + index_str, spot.whiteEv, spotEdited.whiteEv); @@ -9755,7 +9801,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Surround_" + index_str, spot.surround, spotEdited.surround); assignFromKeyfile(keyFile, "Locallab", "Strlog_" + index_str, spot.strlog, spotEdited.strlog); assignFromKeyfile(keyFile, "Locallab", "Anglog_" + index_str, spot.anglog, spotEdited.anglog); - assignFromKeyfile(keyFile, "Locallab", "Featherlog_" + index_str, spot.featherlog, spotEdited.featherlog); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.featherlog = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.featherlog = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Featherlog_" + index_str, spot.featherlog, spotEdited.featherlog); + } assignFromKeyfile(keyFile, "Locallab", "CCmaskCurveL_" + index_str, spot.CCmaskcurveL, spotEdited.CCmaskcurveL); assignFromKeyfile(keyFile, "Locallab", "LLmaskCurveL_" + index_str, spot.LLmaskcurveL, spotEdited.LLmaskcurveL); assignFromKeyfile(keyFile, "Locallab", "HHmaskCurveL_" + index_str, spot.HHmaskcurveL, spotEdited.HHmaskcurveL); @@ -9793,7 +9846,15 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Shadmask_" + index_str, spot.shadmask, spotEdited.shadmask); assignFromKeyfile(keyFile, "Locallab", "Str_mask_" + index_str, spot.str_mask, spotEdited.str_mask); assignFromKeyfile(keyFile, "Locallab", "Ang_mask_" + index_str, spot.ang_mask, spotEdited.ang_mask); - assignFromKeyfile(keyFile, "Locallab", "Feather_mask_" + index_str, spot.feather_mask, spotEdited.feather_mask); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.feather_mask = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.feather_mask = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Feather_mask_" + index_str, spot.feather_mask, spotEdited.feather_mask); + } + assignFromKeyfile(keyFile, "Locallab", "HHhmask_Curve_" + index_str, spot.HHhmask_curve, spotEdited.HHhmask_curve); assignFromKeyfile(keyFile, "Locallab", "Lmask_Curve_" + index_str, spot.Lmask_curve, spotEdited.Lmask_curve); assignFromKeyfile(keyFile, "Locallab", "LLmask_Curvewav_" + index_str, spot.LLmask_curvewav, spotEdited.LLmask_curvewav); @@ -9956,7 +10017,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Surroundcie_" + index_str, spot.surroundcie, spotEdited.surroundcie); assignFromKeyfile(keyFile, "Locallab", "Strgradcie_" + index_str, spot.strgradcie, spotEdited.strgradcie); assignFromKeyfile(keyFile, "Locallab", "Anggradcie_" + index_str, spot.anggradcie, spotEdited.anggradcie); - assignFromKeyfile(keyFile, "Locallab", "Feathercie_" + index_str, spot.feathercie, spotEdited.feathercie); + if (ppVersion <= 350) { + if (keyFile.has_key("Locallab", "Feather_" + index_str)) { + spot.feathercie = keyFile.get_integer("Locallab", "Feather_" + index_str); + spotEdited.feathercie = true; + } + } else { + assignFromKeyfile(keyFile, "Locallab", "Feathercie_" + index_str, spot.feathercie, spotEdited.feathercie); + } assignFromKeyfile(keyFile, "Locallab", "EnacieMask_" + index_str, spot.enacieMask, spotEdited.enacieMask); assignFromKeyfile(keyFile, "Locallab", "EnacieMaskall_" + index_str, spot.enacieMaskall, spotEdited.enacieMaskall); From 6da48b933aa7edc56f4e8749174617df9c97e5a9 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 5 Jul 2024 22:21:46 -0700 Subject: [PATCH 252/291] Handle masked area black level with LibRaw Copied from ART commit 9a24f2567a452f0ca788f51e88b92b479002b149. --- rtengine/rawimage.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc index 53914694a..02f6e42c5 100644 --- a/rtengine/rawimage.cc +++ b/rtengine/rawimage.cc @@ -839,6 +839,13 @@ int RawImage::loadRaw(bool loadData, unsigned int imageNum, bool closeFile, Prog profile_data = new char[profile_length]; memcpy(profile_data, libraw->imgdata.color.profile, profile_length); } + + if (isBayer() && RT_blacklevel_from_constant == ThreeValBool::T && max(black, cblack[0], cblack[1], cblack[2], cblack[3]) == 0) { + auto &black_stat = libraw->imgdata.color.black_stat; + for (int i = 0; i < 4; ++i) { + cblack[i] = black_stat[i] / (1+black_stat[i+4]); + } + } } if (!float_raw_image) { // apply baseline exposure only for float DNGs From b10d3e36ea034daa374dfa64fc276f12d6f02502 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 6 Jul 2024 22:24:32 -0700 Subject: [PATCH 253/291] Add improved version of generateTranslationDiffs A Python script with better performance and does not have a bug in which the '0' (zero) number is ignored when sorting and removing duplicates. --- tools/generateTranslationDiffs.py | 630 ++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 tools/generateTranslationDiffs.py diff --git a/tools/generateTranslationDiffs.py b/tools/generateTranslationDiffs.py new file mode 100644 index 000000000..2b1284efb --- /dev/null +++ b/tools/generateTranslationDiffs.py @@ -0,0 +1,630 @@ +#!/usr/bin/env python + +# This script iterates through interface translation files, moves comments to +# the front, puts translated strings next, and finally looks for +# untranslated/missing strings by matching against "default" which it then adds +# to the translation, each line prepended by "!". +# +# Developers should run it after receiving a translation file from a +# translator: +# cp /tmp/new_japanese_translation rtdata/languages/Japanese +# ./tools/generateTranslationDiffs "Japanese" +# +# Running the script without an argument iterates through all files. +# +# Locale files are generated automatically: +# - English (UK) + +import argparse +from collections import defaultdict +from datetime import datetime +from functools import cmp_to_key, reduce +import logging +import os +from pathlib import Path +import re +from sys import stdout +from typing import Dict, Iterable, List, Mapping, Optional + + +FILE_DEFAULT = 'default' +FILE_ENGLISH_US = 'English (US)' +FILE_ENGLISH_UK = 'English (UK)' + + +class SortHelper: + """ + String sorting utilities. + """ + char_indices: Optional[Dict[str, str]] = None + + @staticmethod + def get_char_index(char: str): + """ + Return the sort order of a character. + """ + if SortHelper.char_indices is None: + # Printable characters sorted using the `sort -V` command. + characters = ( + '.~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz\t\x0b\x0c\n ' + '!"#$%&\'()*+,-/:;<=>?@[\\]^_`{|}' + ) + SortHelper.char_indices = {} + for i, char in enumerate(characters): + SortHelper.char_indices[char] = i + return SortHelper.char_indices.get(char) + + +class TranslationEntry: + """ + An entry in a translation file, consisting of a key and value. + """ + + def __init__(self, line: str, key: str, value: str): + """ + :param line: The entire line containing the entry. + :param key: The key. + :param value: The value. + """ + self.line = line + self.key = key + self.value = value + + def __repr__(self): + return ( + f'TranslationEntry(line={self.line}, key={self.key},' + f' value={self.value})' + ) + + def __str__(self): + return repr(self) + + @staticmethod + def create_from_line(line: str): + """ + Create an instance of this class from a line containing the entry + definition. + + :raises ValueError: If the line does not contain a valid definition + consisting of a key and value separated by a ';' character. + """ + split_line = line.split(';', maxsplit=1) + if len(split_line) != 2: + raise ValueError() + key, value = split_line + return TranslationEntry(line, key, value) + + +class FileLines: + """ + Lines of a translation file categorized by type. + + The types are: + - Comment: Comments, which start with the '#' character. + - Changed: Translation entries consisting of a key and value. + Other lines are ignored. + """ + + def __init__( + self, + all: List[str], + comments: List[str], + changed: List[TranslationEntry] + ): + self.all = all + self.comments = comments + self.changed = changed + + def __repr__(self): + return ( + f'FileLines(all={self.all}, comments={self.comments},' + f' changed={self.changed})' + ) + + def __str__(self): + return repr(self) + + +def main(): + args = parse_args() + configure_logger() + start_time = datetime.now() + file_paths = get_file_paths(args.file_names) + default_file_lines = format_default() + format_files(file_paths, default_file_lines) + generate_locale_files(default_file_lines, file_paths) + end_time = datetime.now() + log_duration(start_time, end_time, len(file_paths)) + + +def parse_args(): + """ + Return the arguments passed to this program. + """ + parser = argparse.ArgumentParser( + prog='generateTranslationDiffs', + description='Formats translation files in rtdata/languages.', + ) + parser.add_argument( + 'file_names', + nargs='*', + help='list of language files to format, or leave empty to format all', + ) + return parser.parse_args() + + +def configure_logger(): + """ + Set up the logger. + """ + logger = get_logger() + handler = logging.StreamHandler(stdout) + formatter = logging.Formatter('%(levelname)s: %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + + +def get_logger(): + """ + Return the logger. + """ + return logging.getLogger('generateTranslationDiffs') + + +def get_file_paths(file_names: List[str]): + """ + Return the paths for all the given file names if they exist and are + writable. If no files names are given, return paths of all translation + files. + + :param file_names: List of file names, as path strings and/or name. + """ + if not file_names: + return get_default_file_paths() + return list(filter(lambda p: p, (get_file_path(n) for n in file_names))) + + +def get_languages_path(): + """ + Return the path of the languages directory. + """ + return Path(__file__).parent.parent / 'rtdata' / 'languages' + + +def get_file_path(file_name): + """ + Return the path for the translation file, or None if it doesn't exist or is + not writable. + + :param file_name: The file name as a path string or name. + """ + file_path = None + if Path(file_name).exists(): + file_path = Path(file_name) + elif (get_languages_path() / file_name).exists(): + file_path = get_languages_path() / file_name + + if not is_writable_file(file_path): + get_logger().warning('File "%s" not found or not writable.', file_name) + return None + return file_path + + +def get_default_file_paths(): + """ + Return a list of paths for all translation files excluding "default" and + locale translations. + """ + ignored_files = [ + FILE_DEFAULT, FILE_ENGLISH_UK, 'LICENSE', 'README', 'temp_file' + ] + ignored_files_regex = '|'.join(re.escape(file) for file in ignored_files) + ignore_pattern = re.compile(rf'({ignored_files_regex}|.*\.sh|\..*)') + return list(filter( + lambda p: p.is_file() and not ignore_pattern.fullmatch(p.name), + get_languages_path().iterdir() + )) + + +def is_writable_file(path: Path): + """ + Return if the file is writable with the current permissions. + """ + return path and path.is_file() and os.access(path, os.W_OK) + + +def format_default(): + """ + Format the default language file. + + :return: File lines of "default". + """ + get_logger().info('Formatting %s.', FILE_DEFAULT) + path = get_languages_path() / FILE_DEFAULT + file_lines = read_file(path) + changed_lines = [key_line.line for key_line in file_lines.changed] + file_lines.all = file_lines.comments + changed_lines + [''] + new_contents = '\n'.join(file_lines.all) + get_logger().debug( + 'New contents for file %s:\n%s', + FILE_DEFAULT, + new_contents + ) + path.write_text(new_contents) + return file_lines + + +def format_files(file_paths: List[Path], default_file_lines: FileLines): + """ + Format the translation files. + + :param file_paths: Files to format. + :param default_file_lines: File lines of the default language file. + """ + if not file_paths: + get_logger().info('No language files to format.') + for file_path in file_paths: + format_file(file_path, default_file_lines) + + +def generate_locale_files( + default_file_lines: FileLines, + file_paths: List[Path] +): + """ + Generate locale translation files. + + :param default_file_lines: File lines of the default language file. + :param file_paths: Paths of files to generate locale translations of. + """ + file_name_to_generator = { + FILE_ENGLISH_US: generate_english_locales, + } + for path in file_paths: + generator = file_name_to_generator.get(path.name) + if generator: + generator(default_file_lines, path) + + +def generate_english_locales(default_file_lines: FileLines, us_path: Path): + """ + Generate English locale files. + """ + us_file_lines: FileLines = read_file(us_path) + generate_english_locale_uk(default_file_lines, us_file_lines) + + +def generate_english_locale_uk( + default_file_lines: FileLines, + us_file_lines: FileLines +): + """ + Generate the UK English locale file. + """ + get_logger().info('Creating %s file', FILE_ENGLISH_UK) + + new_lines = list(us_file_lines.comments) + new_lines.extend(get_english_uk_translations(default_file_lines)) + new_lines.extend(get_english_uk_untranslated(us_file_lines.all)) + new_lines.append('') + + new_contents = '\n'.join(new_lines) + get_logger().debug( + 'New contents for file %s:\n%s', + FILE_ENGLISH_UK, + new_contents + ) + path = get_languages_path() / FILE_ENGLISH_UK + path.write_text(new_contents) + + +def get_english_uk_translations(default_file_lines: FileLines): + """ + Return a list of lines with translated entries for UK English. + + :param default_file_lines: File lines of "default". + """ + line_pattern = re.compile(r'(color|behavior|center)', flags=re.IGNORECASE) + replacements = { + 'olor': 'olour', + 'ehavior': 'ehaviour', + 'center': 'centre', + 'Center': 'Centre', + } + entries_to_translate = filter( + lambda entry: line_pattern.search(entry.value), + default_file_lines.changed + ) + + translations = [] + for default_entry in entries_to_translate: + new_value = reduce( + lambda value, replacement: value.replace(*replacement), + replacements.items(), + default_entry.value + ) + translations.append(f'{default_entry.key};{new_value}') + return translations + + +def get_english_uk_untranslated(us_lines: List[str]): + """ + Return a list of lines from the US English file excluding comments and + those translated for UK English. + """ + pattern = re.compile( + r'.+;.*(color|behavior|center).*', + flags=re.IGNORECASE + ) + return list(filter( + lambda line: not pattern.search(line) and not line.startswith('#'), + us_lines + )) + + +def format_file(path: Path, default_file_lines: FileLines): + """ + Format a translation file. + + :param path: Path of the translation file. + :param default_file_lines: File lines of "default". + """ + get_logger().info(f'Formatting {path.name}.') + file_lines = read_file(path) + translated_lines, untranslated_lines = get_translated_untranslated_lines( + file_lines, + default_file_lines + ) + warn_removed_entry(file_lines, default_file_lines) + new_lines = list(file_lines.comments) + new_lines.append('') + new_lines.extend(translated_lines) + new_lines.append('') + new_lines.extend(untranslated_lines) + new_lines.append('') + file_lines.all = new_lines + new_contents = '\n'.join(file_lines.all) + get_logger().debug( + 'New contents for file %s:\n%s', + path.name, + new_contents + ) + path.write_text(new_contents) + + +def get_translated_untranslated_lines( + file_lines: FileLines, + default_file_lines: FileLines +): + """ + Return a tuple containing a list of translated lines and a list of + untranslated lines. + """ + key_to_entry = { + entry.key: entry for entry in file_lines.changed + } + translated_lines = [] + untranslated_lines = [] + for default_key_line in default_file_lines.changed: + key = default_key_line.key + if key in key_to_entry: + translated_lines.append(key_to_entry[key].line) + else: + untranslated_lines.append(f'!{default_key_line.line}') + if untranslated_lines: + header = [ + '!!!!!!!!!!!!!!!!!!!!!!!!!', + ( + '! Untranslated keys follow;' + ' remove the ! prefix after an entry is translated.' + ), + '!!!!!!!!!!!!!!!!!!!!!!!!!', + '', + ] + untranslated_lines = header + untranslated_lines + return translated_lines, untranslated_lines + + +def warn_removed_entry(file_lines: FileLines, default_file_lines: FileLines): + """ + Emit a warning for any translation entries in the translation file but not + in the default file, if any. + """ + default_keys = set(entry.key for entry in default_file_lines.changed) + removed_lines = [ + entry.line for entry in file_lines.changed if entry.key not in + default_keys + ] + if removed_lines: + warning_lines = ['Removed entry/entries'] + warning_lines.extend([f'\t{line}' for line in removed_lines]) + get_logger().warning('\n'.join(warning_lines)) + + +def read_file(path: Path): + """ + Return the file lines from a language file. + """ + # Begins with '#' followed by 1+ characters. + comment_pattern = re.compile(r'^#.+') + # Does not begin with '!', '#', or end of line. + changed_pattern = re.compile(r'^[^!#$]') + file_lines = FileLines(path.read_text().splitlines(), [], []) + for line_num, line in enumerate(file_lines.all): + if comment_pattern.match(line): + file_lines.comments.append(line) + elif changed_pattern.match(line): + try: + translation_entry = TranslationEntry.create_from_line(line) + except ValueError: + get_logger().warning( + 'Malformed translation entry in "%s" on line %d: %s', + path.name, + line_num, + line + ) + else: + file_lines.changed.append(translation_entry) + sort_file_lines(file_lines) + return file_lines + + +def sort_file_lines(file_lines: FileLines): + """ + Sort the comments and changed entries of a file lines. + """ + comments = sort_comment_lines(file_lines.comments) + changed = sort_changed_unchanged_lines(file_lines.changed) + file_lines.comments.clear() + file_lines.changed.clear() + file_lines.comments.extend(comments) + file_lines.changed.extend(changed) + + +def sort_comment_lines(lines: List[str]): + """ + Sort comment lines using natural sort. + """ + return sorted(set(lines), key=cmp_to_key(compare_string_natural)) + + +def sort_changed_unchanged_lines(entries: List[TranslationEntry]): + """ + Sort changed or unchanged lines using natural sort of the translation entry + keys. + """ + key_to_lines = defaultdict(set) + for entry in entries: + key_to_lines[entry.key].add(entry.line) + + warn_duplicate_entries(key_to_lines) + + sort_key = cmp_to_key(lambda a, b: compare_string_natural(a[0], b[0])) + return list(map( + lambda item: TranslationEntry.create_from_line(item[1].pop()), + sorted(key_to_lines.items(), key=sort_key) + )) + + +def warn_duplicate_entries(key_to_lines: Mapping[str, Iterable[str]]): + """ + Emit a warning if there are duplicate translation entries. + + :param key_to_lines: Mapping from entry key to iterable containing all + values. + """ + duplicate_key_to_lines = { + k: v for k, v in key_to_lines.items() if len(v) > 1 + } + if duplicate_key_to_lines: + warning_lines = ['Duplicate key(s)'] + for key, lines in duplicate_key_to_lines.items(): + warning_lines.append(f'\t{key}') + warning_lines.extend(f'\t\t{line}' for line in lines) + get_logger().warning('\n'.join(warning_lines)) + + +def compare_string_natural(a: str, b: str): + """ + Compare two strings using natural ordering. + + :return: Negative integer if a comes before b, positive integer if b comes + before a, or zero if a and b are identical. + """ + ia = 0 # Character index for a. + ib = 0 # Character index for b. + while ia < len(a) and ib < len(b): + if a[ia].isdigit(): + if b[ib].isdigit(): + # Compare numbers + a_number, ia = read_int(a, ia) + b_number, ib = read_int(b, ib) + if a_number != b_number: + return a_number - b_number + else: + # Compare number with character. + return cmp_chars(a[ia], b[ib]) + else: + if b[ib].isdigit(): + # Compare character with number. + return cmp_chars(a[ia], b[ib]) + else: + # Compare character with character. + if a[ia] != b[ib]: + return cmp_chars(a[ia], b[ib]) + ia += 1 + ib += 1 + if ia < len(a): + # a is "longer". + return 1 + if ib < len(b): + # b is "longer". + return -1 + # a and b are equivalent. + return cmp_string(a, b) + + +def read_int(string: str, index: int): + """ + Read an integer from the string starting at the index. + + :param string: The string. + :param index: Index in the string where the number starts. + :return: A tuple containing the number and the index after the end of where + the number was extracted in the string. If there is no number, returns zero + and the original index. + """ + i = index + while i < len(string) and string[i].isdigit(): + i += 1 + number = 0 if i == index else int(string[index:i]) + return number, i + + +def cmp_chars(a: str, b: str): + """ + Compare two characters according to the `sort -v` command. + + :return: Negative integer if a comes before b, positive integer if b comes + before a, or zero if a and b are identical. + """ + a_index = SortHelper.get_char_index(a) + b_index = SortHelper.get_char_index(b) + if a_index is not None and b_index is not None: + return a_index - b_index + if a == b: + return 0 + return -1 if a < b else 1 + + +def cmp_string(a: str, b: str): + """ + Compare two strings according to a character-by-character comparison using + the `sort -v` command. + + :return: Negative integer if a comes before b, positive integer if b comes + before a, or zero if a and b are identical. + """ + for a_char, b_char in zip(a, b): + cmp_result = cmp_chars(a_char, b_char) + if cmp_result != 0: + return cmp_result + return len(a) - len(b) + + +def log_duration(start_time: datetime, end_time: datetime, file_count): + """ + Log the time it took to format the files. + """ + duration = end_time - start_time + get_logger().info( + 'Finished updating %d files.\nTotal time: %fs', + file_count, + duration.total_seconds() + ) + + +if __name__ == '__main__': + main() From 363f3cc2a65fa5c3d96ed519247eb073b9f9cd20 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Sat, 15 Jun 2024 09:04:22 +0200 Subject: [PATCH 254/291] iptransform: correct profile based distortion/CA before rotation Like perspective correction also rotation correction should be applied after distortion/CA correction. --- rtengine/iptransform.cc | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 3d384ee62..d62a87199 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -515,14 +515,14 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, break; } - if (pLCPMap && params->lensProf.useDist) { - pLCPMap->correctDistortion(x_d, y_d, w2, h2); - } - // rotate double Dx = x_d * cost - y_d * sint; double Dy = x_d * sint + y_d * cost; + if (pLCPMap && params->lensProf.useDist) { + pLCPMap->correctDistortion(Dx, Dy, w2, h2); + } + // distortion correction double s = 1; @@ -700,7 +700,7 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, } } transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get(), useOriginalBuffer); - + if (highQuality && dest != transformed) { transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get(), useOriginalBuffer); } @@ -1240,25 +1240,25 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I break; } - if (enableLCPDist) { - pLCPMap->correctDistortion(x_d, y_d, w2, h2); - } - // rotate - const double Dxc = x_d * cost - y_d * sint; - const double Dyc = x_d * sint + y_d * cost; + double Dxr = x_d * cost - y_d * sint; + double Dyr = x_d * sint + y_d * cost; + + if (enableLCPDist) { + pLCPMap->correctDistortion(Dxr, Dyr, w2, h2); + } // distortion correction double s = 1.0; if (enableDistortion) { - const double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; + const double r = sqrt(Dxr * Dxr + Dyr * Dyr) / maxRadius; s = 1.0 - distAmount + distAmount * r; } for (int c = 0; c < (enableCA ? 3 : 1); ++c) { - double Dx = Dxc * (s + chDist[c]); - double Dy = Dyc * (s + chDist[c]); + double Dx = Dxr * (s + chDist[c]); + double Dy = Dyr * (s + chDist[c]); // de-center Dx += w2; @@ -1386,7 +1386,7 @@ void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *trans for (int c = 0; c < 3; c++) { double Dx = x; double Dy = y; - + pLCPMap->correctCA(Dx, Dy, cx, cy, c); // Extract integer and fractions of coordinates @@ -1522,4 +1522,3 @@ bool ImProcFunctions::needsTransform (int oW, int oH, int rawRotationDeg, const } - From 55fd4b975e48141e73e068c8332a46caba5755d1 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 09:34:14 +0200 Subject: [PATCH 255/291] iptransform: move profile based CA with and after distortion Doing profile based CA as the really first correction in a separate steps is probably not useful. Additionally many lens profile (lensfun) and future one provide functions to do them in a single step with better precision while other just provide a single step that does both (i.e. DNG WarpRectilinear). For the above reasons this patch removes the additional pass for CA correction. This will also improve the perfomance due to less work. --- rtengine/iptransform.cc | 136 +++++++++------------------------------- 1 file changed, 29 insertions(+), 107 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index d62a87199..757d3d54c 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -420,7 +420,6 @@ homogeneous::Matrix perspectiveMatrix(double camera_focal_length, double bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, std::vector &red, std::vector &green, std::vector &blue, double ascaleDef, const LensCorrection *pLCPMap) const { - enum PerspType { NONE, SIMPLE, CAMERA_BASED }; const PerspType perspectiveType = needsPerspective() ? ( (params->perspective.method == "camera_based") ? @@ -686,24 +685,8 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, highQuality = false; } else { highQuality = true; - // agriggio: CA correction via the lens profile has to be - // performed before separately from the the other transformations - // (except for the coarse rotation/flipping). In order to not - // change the code too much, I simply introduced a new mode - // TRANSFORM_HIGH_QUALITY_CA, which applies *only* profile-based - // CA correction. So, the correction in this case occurs in two - // steps, using an intermediate temporary image. There's room for - // optimization of course... - if (pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable()) { - tmpimg.reset(new Imagefloat(transformed->getWidth(), transformed->getHeight())); - dest = tmpimg.get(); - } } transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get(), useOriginalBuffer); - - if (highQuality && dest != transformed) { - transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get(), useOriginalBuffer); - } } } @@ -1095,7 +1078,9 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I // set up stuff, depending on the mode we are enum PerspType { NONE, SIMPLE, CAMERA_BASED }; const bool enableLCPDist = pLCPMap && params->lensProf.useDist; + const bool enableLCPCA = pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable(); const bool enableCA = highQuality && needsCA(); + const bool doCACorrection = enableCA || enableLCPCA; const bool enableGradient = needsGradient(); const bool enablePCVignetting = needsPCVignetting(); const bool enableVignetting = needsVignetting(); @@ -1241,24 +1226,32 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } // rotate - double Dxr = x_d * cost - y_d * sint; - double Dyr = x_d * sint + y_d * cost; + const double Dxr = x_d * cost - y_d * sint; + const double Dyr = x_d * sint + y_d * cost; - if (enableLCPDist) { - pLCPMap->correctDistortion(Dxr, Dyr, w2, h2); - } + for (int c = 0; c < (doCACorrection ? 3 : 1); ++c) { + double Dx = Dxr; + double Dy = Dyr; - // distortion correction - double s = 1.0; + if (enableLCPCA) { + pLCPMap->correctCA(Dx, Dy, w2, h2, c); + } - if (enableDistortion) { - const double r = sqrt(Dxr * Dxr + Dyr * Dyr) / maxRadius; - s = 1.0 - distAmount + distAmount * r; - } + if (enableLCPDist) { + pLCPMap->correctDistortion(Dx, Dy, w2, h2); + } - for (int c = 0; c < (enableCA ? 3 : 1); ++c) { - double Dx = Dxr * (s + chDist[c]); - double Dy = Dyr * (s + chDist[c]); + // distortion correction + double s = 1.0; + + if (enableDistortion) { + const double r = sqrt(Dx * Dx + Dy * Dy) / maxRadius; + s = 1.0 - distAmount + distAmount * r; + } + + // CA correction + Dx *= s + chDist[c]; + Dy *= s + chDist[c]; // de-center Dx += w2; @@ -1305,13 +1298,13 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I 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 if (!useLog) { - if (enableCA) { + if (doCACorrection) { 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 { - if (enableCA) { + if (doCACorrection) { interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul); } else { interpolateTransformCubicLog(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul); @@ -1325,7 +1318,7 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I const int x2 = LIM(xc + 1, 0, original->getWidth() - 1); if (useLog) { - if (enableCA) { + if (doCACorrection) { chTrans[c][y][x] = vignmul * xexpf(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 * xexpf(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); @@ -1333,7 +1326,7 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I transformed->b(y, x) = vignmul * xexpf(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) { + if (doCACorrection) { 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); @@ -1343,7 +1336,7 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } } } else { - if (enableCA) { + if (doCACorrection) { // not valid (source pixel x,y not inside source image, etc.) chTrans[c][y][x] = 0; } else { @@ -1357,77 +1350,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I } } - -void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer) -{ - assert(pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable()); - const bool useLog = params->commonTrans.method == "log"; - - float** chTrans[3] = {transformed->r.ptrs, transformed->g.ptrs, transformed->b.ptrs}; - - std::unique_ptr tempLog; - if (useLog) { - if (!useOriginalBuffer) { - tempLog.reset(new Imagefloat(original->getWidth(), original->getHeight())); - logEncode(original, tempLog.get(), multiThread); - original = tempLog.get(); - } else { - logEncode(original, original, multiThread); - } - } - float** chOrig[3] = {original->r.ptrs, original->g.ptrs, original->b.ptrs}; - -#ifdef _OPENMP - #pragma omp parallel for if (multiThread) -#endif - - for (int y = 0; y < transformed->getHeight(); y++) { - for (int x = 0; x < transformed->getWidth(); x++) { - for (int c = 0; c < 3; c++) { - double Dx = x; - double Dy = y; - - pLCPMap->correctCA(Dx, Dy, cx, cy, c); - - // Extract integer and fractions of coordinates - int xc = (int)Dx; - Dx -= (double)xc; - int yc = (int)Dy; - Dy -= (double)yc; - - // Convert only valid pixels - if (yc >= 0 && yc < original->getHeight() && xc >= 0 && xc < original->getWidth()) { - - // multiplier for vignetting correction - if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) { - // all interpolation pixels inside image - if (!useLog) { - interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0); - } else { - interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0); - } - } else { - // edge pixels - int y1 = LIM (yc, 0, original->getHeight() - 1); - int y2 = LIM (yc + 1, 0, original->getHeight() - 1); - int x1 = LIM (xc, 0, original->getWidth() - 1); - int x2 = LIM (xc + 1, 0, original->getWidth() - 1); - if (!useLog) { - chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy); - } else { - chTrans[c][y][x] = xexpf(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 { - // not valid (source pixel x,y not inside source image, etc.) - chTrans[c][y][x] = 0; - } - } - } - } -} - - double ImProcFunctions::getTransformAutoFill (int oW, int oH, const LensCorrection *pLCPMap) const { if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap == nullptr)) { From dc0e23c82c4ebedd901fb66593702ae3fb6df724 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:02:15 +0200 Subject: [PATCH 256/291] iptransform: apply distortion and CA correction in a single pass Some lens profile methods provides a way to correct distortion and CA in a single step. When available, applying distortion and CA correction when both enabled in a single pass is more precise (see lensfun ApplySubpixelGeometryDistortion doc) since it's usually how the profile is done. Instead applying the CA correction in a step after distortion correction could lead to a bit different (also if not always visible) correction. This is also required for future lens correction methods (like DNG WarpRectilinear or corrections based on vendor metadata) that provides only merged distortion and CA correction in a single pass. --- rtengine/iptransform.cc | 10 +++++----- rtengine/lcp.cc | 6 ++++++ rtengine/lcp.h | 3 +++ rtengine/rtlensfun.cc | 30 +++++++++++++++++++++++++++--- rtengine/rtlensfun.h | 1 + 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 757d3d54c..08ee9a4a0 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -1233,12 +1233,12 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I double Dx = Dxr; double Dy = Dyr; - if (enableLCPCA) { - pLCPMap->correctCA(Dx, Dy, w2, h2, c); - } - - if (enableLCPDist) { + if (enableLCPDist && enableLCPCA) { + pLCPMap->correctDistortionAndCA(Dx, Dy, w2, h2, c); + } else if (enableLCPDist) { pLCPMap->correctDistortion(Dx, Dy, w2, h2); + } else if (enableLCPCA) { + pLCPMap->correctCA(Dx, Dy, w2, h2, c); } // distortion correction diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index 7507bbb11..ba96147dc 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -990,6 +990,12 @@ bool rtengine::LCPMapper::isCACorrectionAvailable() const return enableCA; } +void rtengine::LCPMapper::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const +{ + correctDistortion(x, y, cx, cy); + correctCA(x, y, cx, cy, channel); +} + void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy) const { x += cx; diff --git a/rtengine/lcp.h b/rtengine/lcp.h index b59cc84c6..97cdd0890 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -166,6 +166,8 @@ private: class LensCorrection { public: virtual ~LensCorrection() {} + + virtual void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const = 0; virtual void correctDistortion(double &x, double &y, int cx, int cy) const = 0; virtual bool isCACorrectionAvailable() const = 0; virtual void correctCA(double &x, double &y, int cx, int cy, int channel) const = 0; @@ -194,6 +196,7 @@ public: ); + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; bool isCACorrectionAvailable() const override; void correctCA(double& x, double& y, int cx, int cy, int channel) const override; diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 08010f50f..505346ad0 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -125,7 +125,6 @@ void LFModifier::correctDistortion(double &x, double &y, int cx, int cy) const } } - bool LFModifier::isCACorrectionAvailable() const { return (flags_ & LF_MODIFY_TCA); @@ -141,7 +140,7 @@ void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) co // channels. We could consider caching the info to speed this up x += cx; y += cy; - + float pos[6]; if (swap_xy_) { std::swap(x, y); @@ -156,6 +155,31 @@ void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) co y -= cy; } +void LFModifier::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const +{ + assert(channel >= 0 && channel <= 2); + + // RT currently applies the CA correction per channel, whereas + // lensfun applies it to all the three channels simultaneously. This means + // we do the work 3 times, because each time we discard 2 of the 3 + // channels. We could consider caching the info to speed this up + x += cx; + y += cy; + + float pos[6]; + if (swap_xy_) { + std::swap(x, y); + } + data_->ApplySubpixelGeometryDistortion(x, y, 1, 1, pos); // This is thread-safe + x = pos[2*channel]; + y = pos[2*channel+1]; + if (swap_xy_) { + std::swap(x, y); + } + x -= cx; + y -= cy; +} + #ifdef _OPENMP void LFModifier::processVignette(int width, int height, float** rawData) const { @@ -396,7 +420,7 @@ bool LFDatabase::init(const Glib::ustring &dbdir) if (settings->verbose) { std::cout << (ok ? "OK" : "FAIL") << std::endl; } - + return ok; } diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 1d941246f..39ca67ec2 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -53,6 +53,7 @@ public: explicit operator bool() const; + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; bool isCACorrectionAvailable() const override; void correctCA(double &x, double &y, int cx, int cy, int channel) const override; From b98fa4285720ccc1caeb475904af03c9649d4a79 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:03:07 +0200 Subject: [PATCH 257/291] lens profile: report availability of distortion and vignetting Beside CA, report also distortion and vignetting availability. Rename is${CORRECTION}Available methods to has${CORRECTION}. --- rtengine/iptransform.cc | 6 +++--- rtengine/lcp.cc | 14 +++++++++++++- rtengine/lcp.h | 10 ++++++++-- rtengine/rtlensfun.cc | 20 +++++++++++++++----- rtengine/rtlensfun.h | 5 ++++- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 08ee9a4a0..468507385 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -518,7 +518,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, double Dx = x_d * cost - y_d * sint; double Dy = x_d * sint + y_d * cost; - if (pLCPMap && params->lensProf.useDist) { + if (pLCPMap && params->lensProf.useDist && pLCPMap->hasDistortionCorrection()) { pLCPMap->correctDistortion(Dx, Dy, w2, h2); } @@ -1077,8 +1077,8 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I // set up stuff, depending on the mode we are enum PerspType { NONE, SIMPLE, CAMERA_BASED }; - const bool enableLCPDist = pLCPMap && params->lensProf.useDist; - const bool enableLCPCA = pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable(); + const bool enableLCPDist = pLCPMap && params->lensProf.useDist && pLCPMap->hasDistortionCorrection(); + const bool enableLCPCA = pLCPMap && params->lensProf.useCA && pLCPMap->hasCACorrection(); const bool enableCA = highQuality && needsCA(); const bool doCACorrection = enableCA || enableLCPCA; const bool enableGradient = needsGradient(); diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index ba96147dc..0947cf709 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -985,11 +985,23 @@ rtengine::LCPMapper::LCPMapper( isFisheye = pProf->isFisheye; } -bool rtengine::LCPMapper::isCACorrectionAvailable() const +bool rtengine::LCPMapper::hasDistortionCorrection() const +{ + // assume lcp always provides distortion correction + return true; +} + +bool rtengine::LCPMapper::hasCACorrection() const { return enableCA; } +bool rtengine::LCPMapper::hasVignettingCorrection() const +{ + // assume lcp always provides vignetting correction + return true; +} + void rtengine::LCPMapper::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const { correctDistortion(x, y, cx, cy); diff --git a/rtengine/lcp.h b/rtengine/lcp.h index 97cdd0890..114131b4a 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -167,9 +167,12 @@ class LensCorrection { public: virtual ~LensCorrection() {} + virtual bool hasDistortionCorrection() const = 0; + virtual bool hasCACorrection() const = 0; + virtual bool hasVignettingCorrection() const = 0; + virtual void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const = 0; virtual void correctDistortion(double &x, double &y, int cx, int cy) const = 0; - virtual bool isCACorrectionAvailable() const = 0; virtual void correctCA(double &x, double &y, int cx, int cy, int channel) const = 0; virtual void processVignette(int width, int height, float** rawData) const = 0; virtual void processVignette3Channels(int width, int height, float** rawData) const = 0; @@ -196,9 +199,12 @@ public: ); + bool hasDistortionCorrection() const override; + bool hasCACorrection() const override; + bool hasVignettingCorrection() const override; + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; - bool isCACorrectionAvailable() const override; void correctCA(double& x, double& y, int cx, int cy, int channel) const override; void processVignette(int width, int height, float** rawData) const override; void processVignette3Channels(int width, int height, float** rawData) const override; diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 505346ad0..f4714b6f7 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -102,6 +102,21 @@ LFModifier::operator bool() const } +bool LFModifier::hasDistortionCorrection() const +{ + return (flags_ & LF_MODIFY_DISTORTION); +} + +bool LFModifier::hasCACorrection() const +{ + return (flags_ & LF_MODIFY_TCA); +} + +bool LFModifier::hasVignettingCorrection() const +{ + return (flags_ & LF_MODIFY_VIGNETTING); +} + void LFModifier::correctDistortion(double &x, double &y, int cx, int cy) const { if (!data_) { @@ -125,11 +140,6 @@ void LFModifier::correctDistortion(double &x, double &y, int cx, int cy) const } } -bool LFModifier::isCACorrectionAvailable() const -{ - return (flags_ & LF_MODIFY_TCA); -} - void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) const { assert(channel >= 0 && channel <= 2); diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 39ca67ec2..78c9c9ff6 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -53,9 +53,12 @@ public: explicit operator bool() const; + bool hasDistortionCorrection() const override; + bool hasCACorrection() const override; + bool hasVignettingCorrection() const override; + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; - bool isCACorrectionAvailable() const override; void correctCA(double &x, double &y, int cx, int cy, int channel) const override; void processVignette(int width, int height, float** rawData) const override; void processVignette3Channels(int width, int height, float** rawData) const override; From 5159de89cbb113e51dbeda546294f7cb5b65a6ab Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 09:42:15 +0200 Subject: [PATCH 258/291] imagedata: report if file is DNG --- rtengine/imagedata.cc | 7 +++++++ rtengine/imagedata.h | 2 ++ rtengine/rtengine.h | 2 ++ rtgui/cacheimagedata.cc | 6 ++++++ rtgui/cacheimagedata.h | 2 ++ 5 files changed, 19 insertions(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 6507a970d..45db99f1e 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -565,6 +565,8 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : meta.getDimensions(w_, h_); + isDNG = find_exif_tag("Exif.Image.DNGVersion"); + // ----------------------- // Special file type detection (HDR, PixelShift) // ------------------------ @@ -778,6 +780,11 @@ bool FramesData::getHDR() const return isHDR; } +bool FramesData::getDNG() const +{ + return isDNG; +} + std::string FramesData::getImageType() const { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index 08f55bd62..f999d59e6 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -59,6 +59,7 @@ private: time_t modTimeStamp; bool isPixelShift; bool isHDR; + bool isDNG; int w_; int h_; @@ -69,6 +70,7 @@ public: unsigned int getFrameCount() const override; bool getPixelShift() const override; bool getHDR() const override; + bool getDNG() const override; std::string getImageType() const override; IIOSampleFormat getSampleFormat() const override; bool hasExif() const override; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index f1ee4108c..0010f42b8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -130,6 +130,8 @@ public: virtual bool getPixelShift () const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ virtual bool getHDR() const = 0; + /** @return true if the file is a DNG file */ + virtual bool getDNG() const = 0; /** @return false: not an HDR file ; true: single or multi-frame HDR file (e.g. Pentax HDR raw file or 32 bit float DNG file or Log compressed) */ virtual std::string getImageType() const = 0; diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc index 0e9cc7f0f..872c60504 100644 --- a/rtgui/cacheimagedata.cc +++ b/rtgui/cacheimagedata.cc @@ -59,6 +59,7 @@ CacheImageData::CacheImageData() : iso(0), rating(0), isHDR (false), + isDNG (false), isPixelShift (false), sensortype(rtengine::ST_NONE), sampleFormat(rtengine::IIOSF_UNKNOWN), @@ -194,6 +195,10 @@ int CacheImageData::load (const Glib::ustring& fname) isHDR = keyFile.get_boolean ("ExifInfo", "IsHDR"); } + if (keyFile.has_key ("ExifInfo", "IsDNG")) { + isDNG = keyFile.get_boolean ("ExifInfo", "IsDNG"); + } + if (keyFile.has_key ("ExifInfo", "IsPixelShift")) { isPixelShift = keyFile.get_boolean ("ExifInfo", "IsPixelShift"); } @@ -316,6 +321,7 @@ int CacheImageData::save (const Glib::ustring& fname) keyFile.set_double ("ExifInfo", "FocusDist", focusDist); keyFile.set_integer ("ExifInfo", "ISO", iso); keyFile.set_boolean ("ExifInfo", "IsHDR", isHDR); + keyFile.set_boolean ("ExifInfo", "IsDNG", isDNG); keyFile.set_boolean ("ExifInfo", "IsPixelShift", isPixelShift); keyFile.set_string ("ExifInfo", "ExpComp", expcomp); } diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h index 8c0fa6513..e3d5cc3da 100644 --- a/rtgui/cacheimagedata.h +++ b/rtgui/cacheimagedata.h @@ -60,6 +60,7 @@ public: unsigned iso; int rating; bool isHDR; + bool isDNG; bool isPixelShift; int sensortype; rtengine::IIO_Sample_Format sampleFormat; @@ -114,6 +115,7 @@ public: int getRating () const override { return rating; } // FIXME-piotr : missing rating bool getPixelShift () const override { return isPixelShift; } bool getHDR() const override { return isHDR; } + bool getDNG() const override { return isDNG; } std::string getImageType() const override { return isPixelShift ? "PS" : isHDR ? "HDR" : "STD"; } rtengine::IIOSampleFormat getSampleFormat() const override { return sampleFormat; } void getDimensions(int &w, int &h) const override From 2b97de233f330becff648c296daf009e3a6d1e07 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 09:51:08 +0200 Subject: [PATCH 259/291] Add initial metadata lens correction handling --- rtdata/languages/default | 1 + rtengine/CMakeLists.txt | 1 + rtengine/dcrop.cc | 2 +- rtengine/improcfun.h | 3 +- rtengine/iptransform.cc | 18 +++++- rtengine/lensmetadata.cc | 42 +++++++++++++ rtengine/lensmetadata.h | 47 +++++++++++++++ rtengine/procparams.cc | 8 ++- rtengine/procparams.h | 4 +- rtengine/rawimagesource.cc | 9 ++- rtgui/lensprofile.cc | 120 +++++++++++++++++++++++++++---------- rtgui/lensprofile.h | 6 +- 12 files changed, 222 insertions(+), 39 deletions(-) create mode 100644 rtengine/lensmetadata.cc create mode 100644 rtengine/lensmetadata.h diff --git a/rtdata/languages/default b/rtdata/languages/default index 46496826a..e6eb09b06 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2837,6 +2837,7 @@ TP_LENSGEOM_FILL;Auto-fill TP_LENSGEOM_LABEL;Lens / Geometry TP_LENSGEOM_LIN;Linear TP_LENSGEOM_LOG;Logarithmic +TP_LENSPROFILE_CORRECTION_METADATA;From file metadata TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 5d87310b9..c937198c8 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -148,6 +148,7 @@ set(RTENGINESOURCEFILES jpeg_ijg/jpeg_memsrc.cc labimage.cc lcp.cc + lensmetadata.cc lmmse_demosaic.cc loadinitial.cc metadata.cc diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 580475c37..e630d1936 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -1850,7 +1850,7 @@ bool check_need_larger_crop_for_lcp_distortion(int fw, int fh, int x, int y, int return false; } - return (params.lensProf.useDist && (params.lensProf.useLensfun() || params.lensProf.useLcp())); + return (params.lensProf.useDist && (params.lensProf.useLensfun() || params.lensProf.useLcp() || params.lensProf.useMetadata())); } } // namespace diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 9c6c794f0..c8c6e166e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -130,6 +130,7 @@ class ImProcFunctions bool needsGradient() const; bool needsVignetting() const; bool needsLCP() const; + bool needsMetadata() const; bool needsLensfun() const; // static cmsUInt8Number* Mempro = NULL; @@ -155,7 +156,7 @@ enum class BlurType { ~ImProcFunctions(); bool needsLuminanceOnly() const { - return !(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient()); + return !(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun() || needsMetadata()) && (needsVignetting() || needsPCVignetting() || needsGradient()); } void setScale(double iscale); diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 468507385..10f37e781 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -26,6 +26,7 @@ #include "rt_math.h" #include "rtengine.h" #include "rtlensfun.h" +#include "lensmetadata.h" #include "sleef.h" using namespace std; @@ -659,7 +660,13 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, std::unique_ptr pLCPMap; - if (needsLensfun()) { + if (needsMetadata()) { + auto corr = MetadataLensCorrectionFinder::findCorrection(metadata); + if (corr) { + corr->initCorrections(oW, oH, params->coarse, rawRotationDeg); + pLCPMap = std::move(corr); + } + } else if (needsLensfun()) { pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); } else if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile (params->lensProf.lcpFile); @@ -675,7 +682,7 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, } } - if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { + if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsMetadata() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { transformLuminanceOnly (original, transformed, cx, cy, oW, oH, fW, fH); } else { bool highQuality; @@ -1422,6 +1429,11 @@ bool ImProcFunctions::needsVignetting () const return params->vignetting.amount; } +bool ImProcFunctions::needsMetadata () const +{ + return params->lensProf.useMetadata(); +} + bool ImProcFunctions::needsLCP () const { return params->lensProf.useLcp(); @@ -1439,7 +1451,7 @@ bool ImProcFunctions::needsTransform (int oW, int oH, int rawRotationDeg, const std::unique_ptr pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); needsLf = pLCPMap.get(); } - return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLf; + return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsMetadata() || needsLf; } diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc new file mode 100644 index 000000000..e92fc6cc9 --- /dev/null +++ b/rtengine/lensmetadata.cc @@ -0,0 +1,42 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2024 Rawtherapee developers + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General 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 "lensmetadata.h" + +namespace rtengine +{ + +std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) +{ + static const std::unordered_set makers = {}; + + std::string make = Glib::ustring(meta->getMake()).uppercase(); + + if (makers.find(make) == makers.end()) { + return nullptr; + } + + std::unique_ptr correction; + + return correction; +} + +} // namespace rtengine diff --git a/rtengine/lensmetadata.h b/rtengine/lensmetadata.h new file mode 100644 index 000000000..7991af8cd --- /dev/null +++ b/rtengine/lensmetadata.h @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2024 Rawtherapee developers + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#pragma once + +#include + +#include "lcp.h" +#include "metadata.h" +#include "procparams.h" +#include "rtengine.h" + +namespace rtengine +{ + +/* MetadataLensCorrection is an abstract class for various lens correction based on raw file metadata + this metadata is vendor dependent */ +class MetadataLensCorrection : public LensCorrection, + public NonCopyable +{ +public: + virtual void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) = 0; +}; + +/* MetadataLensCorrectionFinder tries to find and return MetadataLensCorrection for the provided metadata */ +class MetadataLensCorrectionFinder +{ +public: + static std::unique_ptr findCorrection(const FramesMetaData *meta); +}; + +} // namespace rtengine diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b868a7627..e1a56a533 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2064,13 +2064,19 @@ bool LensProfParams::lfManual() const return lcMode == LcMode::LENSFUNMANUAL; } +bool LensProfParams::useMetadata() const +{ + return lcMode == LcMode::METADATA; +} + const std::vector& LensProfParams::getMethodStrings() const { static const std::vector method_strings = { "none", "lfauto", "lfmanual", - "lcp" + "lcp", + "metadata" }; return method_strings; } diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d71c3d172..e6945cfbd 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -966,7 +966,8 @@ struct LensProfParams { NONE, // No lens correction LENSFUNAUTOMATCH, // Lens correction using auto matched lensfun database entry LENSFUNMANUAL, // Lens correction using manually selected lensfun database entry - LCP // Lens correction using lcp file + LCP, // Lens correction using lcp file + METADATA // Lens correction using embedded metadata }; LcMode lcMode; @@ -985,6 +986,7 @@ struct LensProfParams { bool lfAutoMatch() const; bool useLcp() const; bool lfManual() const; + bool useMetadata() const; const std::vector& getMethodStrings() const; Glib::ustring getMethodString(LcMode mode) const; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 09b64ad41..8cd6ffedd 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -44,6 +44,7 @@ #include "rt_math.h" #include "rtengine.h" #include "rtlensfun.h" +#include "lensmetadata.h" #include "../rtgui/options.h" #define BENCHMARK @@ -1583,7 +1584,13 @@ void RawImageSource::preprocess(const RAWParams &raw, const LensProfParams &lens if (!hasFlatField && lensProf.useVign && lensProf.lcMode != LensProfParams::LcMode::NONE) { std::unique_ptr pmap; - if (lensProf.useLensfun()) { + if (lensProf.useMetadata()) { + auto corr = MetadataLensCorrectionFinder::findCorrection(idata); + if (corr) { + corr->initCorrections(W, H, coarse, -1); + pmap = std::move(corr); + } + } else if (lensProf.useLensfun()) { pmap = LFDatabase::getInstance()->findModifier(lensProf, idata, W, H, coarse, -1); } else { const std::shared_ptr pLCPProf = LCPStore::getInstance()->getProfile(lensProf.lcpFile); diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 5f42a1cde..4410b2fe0 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -32,6 +32,7 @@ #include "../rtengine/lcp.h" #include "../rtengine/procparams.h" #include "../rtengine/rtlensfun.h" +#include "../rtengine/lensmetadata.h" using namespace rtengine; using namespace rtengine::procparams; @@ -56,6 +57,7 @@ LensProfilePanel::LensProfilePanel() : distGrid(Gtk::manage((new Gtk::Grid()))), corrUnchangedRB(Gtk::manage((new Gtk::RadioButton(M("GENERAL_UNCHANGED"))))), corrOffRB(Gtk::manage((new Gtk::RadioButton(corrGroup, M("GENERAL_NONE"))))), + corrMetadata(Gtk::manage((new Gtk::RadioButton(corrGroup, M("TP_LENSPROFILE_CORRECTION_METADATA"))))), corrLensfunAutoRB(Gtk::manage((new Gtk::RadioButton(corrGroup, M("TP_LENSPROFILE_CORRECTION_AUTOMATCH"))))), corrLensfunManualRB(Gtk::manage((new Gtk::RadioButton(corrGroup, M("TP_LENSPROFILE_CORRECTION_MANUAL"))))), corrLcpFileRB(Gtk::manage((new Gtk::RadioButton(corrGroup, M("TP_LENSPROFILE_CORRECTION_LCPFILE"))))), @@ -144,17 +146,18 @@ LensProfilePanel::LensProfilePanel() : // Populate modes grid: modesGrid->attach(*corrOffRB, 0, 0, 3, 1); - modesGrid->attach(*corrLensfunAutoRB, 0, 1, 3, 1); - modesGrid->attach(*corrLensfunManualRB, 0, 2, 3, 1); + modesGrid->attach(*corrMetadata, 0, 1, 3, 1); + modesGrid->attach(*corrLensfunAutoRB, 0, 2, 3, 1); + modesGrid->attach(*corrLensfunManualRB, 0, 3, 3, 1); - modesGrid->attach(*lensfunCamerasLbl, 0, 3, 1, 1); - modesGrid->attach(*lensfunCameras, 1, 3, 1, 1); - modesGrid->attach(*lensfunLensesLbl, 0, 4, 1, 1); - modesGrid->attach(*lensfunLenses, 1, 4, 1, 1); - modesGrid->attach(*warning, 2, 3, 1, 2); + modesGrid->attach(*lensfunCamerasLbl, 0, 4, 1, 1); + modesGrid->attach(*lensfunCameras, 1, 4, 1, 1); + modesGrid->attach(*lensfunLensesLbl, 0, 5, 1, 1); + modesGrid->attach(*lensfunLenses, 1, 5, 1, 1); + modesGrid->attach(*warning, 2, 4, 1, 2); - modesGrid->attach(*corrLcpFileRB, 0, 5, 1, 1); - modesGrid->attach(*corrLcpFileChooser, 1, 5, 1, 1); + modesGrid->attach(*corrLcpFileRB, 0, 6, 1, 1); + modesGrid->attach(*corrLcpFileChooser, 1, 6, 1, 1); // Populate distortions grid: @@ -179,6 +182,7 @@ LensProfilePanel::LensProfilePanel() : lensfunCameras->signal_changed().connect(sigc::mem_fun(*this, &LensProfilePanel::onLensfunCameraChanged)); lensfunLenses->signal_changed().connect(sigc::mem_fun(*this, &LensProfilePanel::onLensfunLensChanged)); corrOffRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrOffRB)); + corrMetadata->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrMetadata)); corrLensfunAutoRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrLensfunAutoRB)); corrLensfunManualRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrLensfunManualRB)); corrLcpFileRB->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &LensProfilePanel::onCorrModeChanged), corrLcpFileRB)); @@ -211,30 +215,52 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa break; } + case procparams::LensProfParams::LcMode::METADATA: { + if (metadata) { + auto metadataCorrection= rtengine::MetadataLensCorrectionFinder::findCorrection(metadata); + if (metadataCorrection) { + corrMetadata->set_active(true); + corrMetadata->set_sensitive(true); + } else { + corrMetadata->set_sensitive(false); + corrOffRB->set_active(true); + } + } else { + corrMetadata->set_sensitive(false); + } + break; + } + case procparams::LensProfParams::LcMode::NONE: { corrOffRB->set_active(true); setManualParamsVisibility(false); + + ckbUseDist->set_sensitive(false); + ckbUseVign->set_sensitive(false); + ckbUseCA->set_sensitive(false); break; } } - if (pp->lensProf.lcpFile.empty()) { - const Glib::ustring lastFolder = corrLcpFileChooser->get_current_folder(); - corrLcpFileChooser->set_current_folder(lastFolder); - corrLcpFileChooser->unselect_all(); - bindCurrentFolder(*corrLcpFileChooser, options.lastLensProfileDir); - updateDisabled(false); - } - else if (LCPStore::getInstance()->isValidLCPFileName(pp->lensProf.lcpFile)) { - corrLcpFileChooser->set_filename(pp->lensProf.lcpFile); - - if (corrLcpFileRB->get_active()) { - updateDisabled(true); + if (pp->lensProf.lcMode == procparams::LensProfParams::LcMode::LCP) { + if (pp->lensProf.lcpFile.empty()) { + const Glib::ustring lastFolder = corrLcpFileChooser->get_current_folder(); + corrLcpFileChooser->set_current_folder(lastFolder); + corrLcpFileChooser->unselect_all(); + bindCurrentFolder(*corrLcpFileChooser, options.lastLensProfileDir); + updateLCPDisabled(false); + } + else if (LCPStore::getInstance()->isValidLCPFileName(pp->lensProf.lcpFile)) { + corrLcpFileChooser->set_filename(pp->lensProf.lcpFile); + + if (corrLcpFileRB->get_active()) { + updateLCPDisabled(true); + } + } + else { + corrLcpFileChooser->unselect_filename(corrLcpFileChooser->get_filename()); + updateLCPDisabled(false); } - } - else { - corrLcpFileChooser->unselect_filename(corrLcpFileChooser->get_filename()); - updateDisabled(false); } const LFDatabase* const db = LFDatabase::getInstance(); @@ -308,6 +334,9 @@ void LensProfilePanel::write(rtengine::procparams::ProcParams* pp, ParamsEdited* if (corrLcpFileRB->get_active()) { pp->lensProf.lcMode = procparams::LensProfParams::LcMode::LCP; } + else if (corrMetadata->get_active()) { + pp->lensProf.lcMode = procparams::LensProfParams::LcMode::METADATA; + } else if (corrLensfunManualRB->get_active()) { pp->lensProf.lcMode = procparams::LensProfParams::LcMode::LENSFUNMANUAL; } @@ -367,12 +396,18 @@ void LensProfilePanel::setRawMeta(bool raw, const rtengine::FramesMetaData* pMet // CA is very focus layer dependent, otherwise it might even worsen things allowFocusDep = false; - ckbUseCA->set_active(false); - ckbUseCA->set_sensitive(false); enableListener(); } + corrMetadata->set_sensitive(false); + if (pMeta) { + metadataCorrection = MetadataLensCorrectionFinder::findCorrection(pMeta); + if (metadataCorrection) { + corrMetadata->set_sensitive(true); + } + } + isRaw = raw; metadata = pMeta; } @@ -381,7 +416,7 @@ void LensProfilePanel::onLCPFileChanged() { lcpFileChanged = true; const bool valid = LCPStore::getInstance()->isValidLCPFileName(corrLcpFileChooser->get_filename()); - updateDisabled(valid); + updateLCPDisabled(valid); if (listener) { if (valid) { @@ -552,10 +587,20 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged) lensfunAutoChanged = true; lcpFileChanged = true; - updateDisabled(true); + updateLCPDisabled(true); mode = M("TP_LENSPROFILE_CORRECTION_LCPFILE"); + } else if (rbChanged == corrMetadata) { + lcModeChanged = true; + useLensfunChanged = true; + lensfunAutoChanged = true; + lcpFileChanged = true; + + updateMetadataDisabled(); + + mode = M("TP_LENSPROFILE_CORRECTION_METADATA"); + } else if (rbChanged == corrUnchangedRB) { lcModeChanged = false; useLensfunChanged = false; @@ -680,7 +725,7 @@ void LensProfilePanel::LFDbHelper::fillLensfunLenses() } } -void LensProfilePanel::updateDisabled(bool enable) +void LensProfilePanel::updateLCPDisabled(bool enable) { if (!batchMode) { ckbUseDist->set_sensitive(enable); @@ -689,6 +734,21 @@ void LensProfilePanel::updateDisabled(bool enable) } } +void LensProfilePanel::updateMetadataDisabled() +{ + if (!batchMode) { + if (metadataCorrection) { + ckbUseDist->set_sensitive(metadataCorrection->hasDistortionCorrection()); + ckbUseVign->set_sensitive(metadataCorrection->hasVignettingCorrection()); + ckbUseCA->set_sensitive(metadataCorrection->hasCACorrection()); + } else { + ckbUseDist->set_sensitive(false); + ckbUseVign->set_sensitive(false); + ckbUseCA->set_sensitive(false); + } + } +} + bool LensProfilePanel::setLensfunCamera(const Glib::ustring& make, const Glib::ustring& model) { if (!make.empty() && !model.empty()) { diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h index 42746f41e..cdf7bd6e4 100644 --- a/rtgui/lensprofile.h +++ b/rtgui/lensprofile.h @@ -22,6 +22,7 @@ #include "guiutils.h" #include "toolpanel.h" +#include "../rtengine/lensmetadata.h" class LensProfilePanel final : public ToolParamBlock, @@ -89,7 +90,8 @@ private: void fillLensfunLenses(); }; - void updateDisabled(bool enable); + void updateLCPDisabled(bool enable); + void updateMetadataDisabled(); bool setLensfunCamera(const Glib::ustring& make, const Glib::ustring& model); bool setLensfunLens(const Glib::ustring& lens); @@ -113,12 +115,14 @@ private: bool allowFocusDep; bool isRaw; const rtengine::FramesMetaData* metadata; + std::unique_ptr metadataCorrection; Gtk::Grid* const modesGrid; Gtk::Grid* const distGrid; Gtk::RadioButton* const corrUnchangedRB; Gtk::RadioButton::Group corrGroup; Gtk::RadioButton* const corrOffRB; + Gtk::RadioButton* const corrMetadata; Gtk::RadioButton* const corrLensfunAutoRB; Gtk::RadioButton* const corrLensfunManualRB; Gtk::RadioButton* const corrLcpFileRB; From f64ad13363c340815b67fe74119189126536f40c Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:23:25 +0200 Subject: [PATCH 260/291] lensmetadata: add abstract center radius helper class Add a CenterRadiusMetadataLensCorrection helper class that will be implemented by vendor specific corrections based on center radius. --- rtengine/lensmetadata.cc | 108 +++++++++++++++++++++++++++++++++++++++ rtengine/lensmetadata.h | 42 +++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index e92fc6cc9..c531de65b 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -24,6 +24,114 @@ namespace rtengine { +CenterRadiusMetadataLensCorrection::CenterRadiusMetadataLensCorrection(const FramesMetaData *meta) : + swap_xy(false) +{ + metadata = Exiv2Metadata(meta->getFileName()); + metadata.load(); +} + +void CenterRadiusMetadataLensCorrection::initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) +{ + if (rawRotationDeg >= 0) { + int rot = (coarse.rotate + rawRotationDeg) % 360; + swap_xy = (rot == 90 || rot == 270); + if (swap_xy) { + std::swap(width, height); + } + } + + w2 = width * 0.5f; + h2 = height * 0.5f; + rf = 1 / std::sqrt(SQR(w2) + SQR(h2)); +} + +void CenterRadiusMetadataLensCorrection::process(double &x, double &y, int cx, int cy, int channel, bool dist, bool ca) const +{ + double xx = x + cx; + double yy = y + cy; + if (swap_xy) { + std::swap(xx, yy); + } + + double xc = xx - w2; + double yc = yy - h2; + + double rout = rf * std::sqrt(SQR(xc) + SQR(yc)); + double cf = 1; + if (dist && ca) { + cf = distortionAndCACorrectionFactor(rout, channel); + } else if (dist) { + cf = distortionCorrectionFactor(rout); + } else if (ca) { + cf = caCorrectionFactor(rout, channel); + } + + x = cf * xc + w2; + y = cf * yc + h2; + + if (swap_xy) { + std::swap(x, y); + } + x -= cx; + y -= cy; +} + +void CenterRadiusMetadataLensCorrection::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const +{ + if (!hasDistortionCorrection() || !hasCACorrection()) { + return; + } + + process(x, y, cx, cy, channel, true, true); +} + +void CenterRadiusMetadataLensCorrection::correctDistortion(double &x, double &y, int cx, int cy) const +{ + if (!hasDistortionCorrection()) { + return; + } + + process(x, y, cx, cy, 1, true, false); +} + +void CenterRadiusMetadataLensCorrection::correctCA(double &x, double &y, int cx, int cy, int channel) const +{ + if (!hasCACorrection()) { + return; + } + + process(x, y, cx, cy, channel, false, true); +} + +void CenterRadiusMetadataLensCorrection::processVignetteNChannels(int width, int height, float **rawData, int channels) const +{ + if (!hasVignettingCorrection()) { + return; + } + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + double xc = x - w2; + double yc = y - h2; + double sf = vignettingCorrectionFactor(rf * std::sqrt(SQR(xc) + SQR(yc))); + for (int c = 0; c < channels; c++) { + rawData[y][x + c] *= sf; + } + } + } +} + +void CenterRadiusMetadataLensCorrection::processVignette(int width, int height, float **rawData) const +{ + return processVignetteNChannels(width, height, rawData, 1); +} + +void CenterRadiusMetadataLensCorrection::processVignette3Channels(int width, int height, float **rawData) const +{ + return processVignetteNChannels(width, height, rawData, 3); +} + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { static const std::unordered_set makers = {}; diff --git a/rtengine/lensmetadata.h b/rtengine/lensmetadata.h index 7991af8cd..ac042b7ce 100644 --- a/rtengine/lensmetadata.h +++ b/rtengine/lensmetadata.h @@ -37,6 +37,48 @@ public: virtual void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) = 0; }; +/* CenterRadiusMetadataLensCorrection is an abstract class the extends MetadataLensCorrection to easily handle center radius based corrections */ +class CenterRadiusMetadataLensCorrection : public MetadataLensCorrection +{ +public: + CenterRadiusMetadataLensCorrection(const FramesMetaData *meta); + + void process(double &x, double &y, int cx, int cy, int channel, bool dist, bool ca) const; + + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; + void correctDistortion(double &x, double &y, int cx, int cy) const override; + void correctCA(double &x, double &y, int cx, int cy, int channel) const override; + void processVignette(int width, int height, float **rawData) const override; + void processVignette3Channels(int width, int height, float **rawData) const override; + + void processVignetteNChannels(int width, int height, float **rawData, int channels) const; + void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) override; + + /* Implementers should implement the below methods */ + virtual bool hasDistortionCorrection() const override = 0; + virtual bool hasCACorrection() const override = 0; + virtual bool hasVignettingCorrection() const override = 0; + + /* These methods should return the distortion correction factor (cf) for the + * provided radius rout (radius of the output image (corrected)). + * So rin = rout * cf + * */ + virtual double distortionCorrectionFactor(double rout) const = 0; + virtual double caCorrectionFactor(double rout, int channel) const = 0; + virtual double distortionAndCACorrectionFactor(double rout, int channel) const = 0; + + /* This methods should return the vignetting correction factor (cf) for the + * provided radius */ + virtual double vignettingCorrectionFactor(double r) const = 0; + +protected: + bool swap_xy; + double w2; + double h2; + double rf; + Exiv2Metadata metadata; +}; + /* MetadataLensCorrectionFinder tries to find and return MetadataLensCorrection for the provided metadata */ class MetadataLensCorrectionFinder { From 27dc084e81b3145eae103919a2395d3d25b0c036 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:26:22 +0200 Subject: [PATCH 261/291] Add Sony metadata lens correction --- rtengine/lensmetadata.cc | 163 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index c531de65b..0e8156f39 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -24,6 +24,31 @@ namespace rtengine { +namespace +{ + +/* interpolateLinearSpline does a simple linear spline interpolation. Values + * outside the external knots will return the value of the nearest knot without + * any additional interpolation. */ +double interpolateLinearSpline(const std::vector &xi, const std::vector &yi, double x) +{ + if (x < xi[0]) { + return yi[0]; + } + + for (size_t i = 1; i < xi.size(); i++) { + if (x >= xi[i - 1] && x <= xi[i]) { + double dydx = (yi[i] - yi[i - 1]) / (xi[i] - xi[i - 1]); + + return yi[i - 1] + (x - xi[i - 1]) * dydx; + } + } + + return yi[yi.size() - 1]; +} + +} // namespace + CenterRadiusMetadataLensCorrection::CenterRadiusMetadataLensCorrection(const FramesMetaData *meta) : swap_xy(false) { @@ -132,9 +157,133 @@ void CenterRadiusMetadataLensCorrection::processVignette3Channels(int width, int return processVignetteNChannels(width, height, rawData, 3); } +/* Fuji, Sony, Olympus metadata handling and algorithms adapted from + * - src/iop/lens.cc + * - src/common/exif.cc + * in darktable 4.6 */ +/* + This file is part of darktable, + Copyright (C) 2019-2024 darktable developers. + + darktable is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + darktable is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with darktable. If not, see . +*/ + +class SonyMetadataLensCorrection : public CenterRadiusMetadataLensCorrection +{ +public: + SonyMetadataLensCorrection(const FramesMetaData *meta) : + CenterRadiusMetadataLensCorrection(meta) + { + parse(); + setup(); + } + +private: + int nc; + std::array distortion; + std::array ca_r; + std::array ca_b; + std::array vignetting; + + std::vector knots; + std::vector dist; + std::array, 3> ca; + std::vector vig; + + void parse() + { + if (Exiv2::versionNumber() < EXIV2_MAKE_VERSION(0, 27, 4)) { + throw std::runtime_error("cannot get Sony correction data, too old exiv2 version " + Exiv2::versionString()); + } + + auto &exif = metadata.exifData(); + + auto posd = exif.findKey(Exiv2::ExifKey("Exif.SubImage1.DistortionCorrParams")); + auto posc = exif.findKey(Exiv2::ExifKey("Exif.SubImage1.ChromaticAberrationCorrParams")); + auto posv = exif.findKey(Exiv2::ExifKey("Exif.SubImage1.VignettingCorrParams")); + + /* Sony metadata corrections parameters define some splines with N knots */ + if (posd == exif.end() || posc == exif.end() || posv == exif.end()) { + throw std::runtime_error("cannot get Sony correction data"); + } + + const int nc = to_long(posd); + if (nc <= 16 && 2 * nc == to_long(posc) && nc == to_long(posv)) { + this->nc = nc; + for (int i = 0; i < nc; i++) { + distortion[i] = to_long(posd, i + 1); + ca_r[i] = to_long(posc, i + 1); + ca_b[i] = to_long(posc, nc + i + 1); + vignetting[i] = to_long(posv, i + 1); + } + } else { + throw std::runtime_error("cannot get Sony correction data"); + } + } + + void setup() + { + knots.resize(nc); + dist.resize(nc); + vig.resize(nc); + for (int i = 0; i < 3; ++i) { + ca[i].resize(nc); + } + + for (int i = 0; i < this->nc; i++) { + knots[i] = (i + 0.5) / (nc - 1); + + dist[i] = distortion[i] * powf(2, -14) + 1; + + ca[0][i] = ca[1][i] = ca[2][i] = 1.f; + ca[0][i] *= ca_r[i] * powf(2, -21) + 1; + ca[2][i] *= ca_b[i] * powf(2, -21) + 1; + + vig[i] = 1 / powf(2, 0.5f - powf(2, vignetting[i] * powf(2, -13) - 1)); + } + } + + double distortionCorrectionFactor(double rout) const override + { + return interpolateLinearSpline(knots, dist, rout); + } + + double caCorrectionFactor(double rout, int channel) const override + { + return interpolateLinearSpline(knots, ca[channel], rout); + } + + double distortionAndCACorrectionFactor(double rout, int channel) const override + { + return distortionCorrectionFactor(rout) * caCorrectionFactor(rout, channel); + } + + double vignettingCorrectionFactor(double r) const override + { + return interpolateLinearSpline(knots, vig, r); + } + + bool hasDistortionCorrection() const override { return true; } + bool hasVignettingCorrection() const override { return true; } + bool hasCACorrection() const override { return true; } +}; + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { - static const std::unordered_set makers = {}; + static const std::unordered_set makers = { + "SONY", + }; std::string make = Glib::ustring(meta->getMake()).uppercase(); @@ -144,6 +293,18 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec std::unique_ptr correction; + try { + if (make == "SONY") { + correction.reset(new SonyMetadataLensCorrection(meta)); + } + } catch (std::exception &exc) { + if (settings->verbose) { + std::cerr << "error parsing lens metadata: " << exc.what() << std::endl; + } + + correction.reset(nullptr); + } + return correction; } From b570c70f5b47233e3a3b8d99ac0502041a5692a4 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:27:16 +0200 Subject: [PATCH 262/291] Add Fujifilm metadata lens correction --- rtengine/lensmetadata.cc | 207 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index 0e8156f39..006976371 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -279,10 +279,215 @@ private: bool hasCACorrection() const override { return true; } }; +class FujiMetadataLensCorrection : public CenterRadiusMetadataLensCorrection +{ +public: + FujiMetadataLensCorrection(const FramesMetaData *meta) : + CenterRadiusMetadataLensCorrection(meta) + { + parse(); + setup(); + } + +private: + const static int MAXKNOTS = 16; + + int nc; + double cropf; + + std::array fuji_knots; + std::array fuji_distortion; + std::array fuji_ca_r; + std::array fuji_ca_b; + std::array fuji_vignetting; + + std::vector knots_dist; + std::vector dist; + std::array, 3> ca; + std::vector knots_vig; + std::vector vig; + + void parse() + { + if (Exiv2::versionNumber() < EXIV2_MAKE_VERSION(0, 27, 4)) { + throw std::runtime_error("cannot get Fuji correction data, too old exiv2 version " + Exiv2::versionString()); + } + + auto &exif = metadata.exifData(); + + /* FujiFilm metadata corrections parameters define some splines with N knots */ + auto posd = exif.findKey(Exiv2::ExifKey("Exif.Fujifilm.GeometricDistortionParams")); + auto posc = exif.findKey(Exiv2::ExifKey("Exif.Fujifilm.ChromaticAberrationParams")); + auto posv = exif.findKey(Exiv2::ExifKey("Exif.Fujifilm.VignettingParams")); + + // X-Trans IV/V + if (posd != exif.end() && posc != exif.end() && posv != exif.end() && + posd->count() == 19 && posc->count() == 29 && posv->count() == 19) { + const int nc = 9; + this->nc = nc; + + for (int i = 0; i < nc; i++) { + const float kd = posd->toFloat(i + 1); + const float kc = posc->toFloat(i + 1); + const float kv = posv->toFloat(i + 1); + + // Check that the knots position is the same for distortion, ca and vignetting, + if (kd != kc || kd != kv) { + throw std::runtime_error("cannot get Fuji correction data: unexpected data"); + } + + fuji_knots[i] = kd; + fuji_distortion[i] = posd->toFloat(i + 10); + fuji_ca_r[i] = posc->toFloat(i + 10); + fuji_ca_b[i] = posc->toFloat(i + 19); + fuji_vignetting[i] = posv->toFloat(i + 10); + } + + // Account for the 1.25x crop modes in some Fuji cameras + auto it = exif.findKey(Exiv2::ExifKey("Exif.Fujifilm.CropMode")); + + if (it != exif.end() && (to_long(it) == 2 || to_long(it) == 4)) { + cropf = 1.25f; + } else { + cropf = 1; + } + } + // X-Trans I/II/III + else if (posd != exif.end() && posc != exif.end() && posv != exif.end() && + posd->count() == 23 && posc->count() == 31 && posv->count() == 23) { + const int nc = 11; + this->nc = nc; + + for (int i = 0; i < nc; i++) { + const float kd = posd->toFloat(i + 1); + float kc = 0; + // ca data doesn't provide first knot (0) + if (i != 0) kc = posc->toFloat(i); + const float kv = posv->toFloat(i + 1); + // check that the knots position is the same for distortion, ca and vignetting, + if (kd != kc || kd != kv) { + throw std::runtime_error("cannot get Fuji correction data: unexpected data"); + } + + fuji_knots[i] = kd; + fuji_distortion[i] = posd->toFloat(i + 12); + + // ca data doesn't provide first knot (0) + if (i == 0) { + fuji_ca_r[i] = 0; + fuji_ca_b[i] = 0; + } else { + fuji_ca_r[i] = posc->toFloat(i + 10); + fuji_ca_b[i] = posc->toFloat(i + 20); + } + fuji_vignetting[i] = posv->toFloat(i + 12); + } + + // Account for the 1.25x crop modes in some Fuji cameras + auto it = exif.findKey(Exiv2::ExifKey("Exif.Fujifilm.CropMode")); + + if (it != exif.end() && (to_long(it) == 2 || to_long(it) == 4)) { + cropf = 1.25f; + } else { + cropf = 1; + } + } else { + throw std::runtime_error("cannot get Fuji correction data"); + } + } + + void setup() + { + std::vector knots_in; + std::vector distortion_in; + std::vector ca_r_in; + std::vector ca_b_in; + + // add a knot with no corrections at 0 value if not existing + int size = nc; + if (fuji_knots[0] > 0.f) { + knots_in.push_back(0); + distortion_in.push_back(1); + ca_r_in.push_back(0); + ca_b_in.push_back(0); + + knots_vig.push_back(0); + vig.push_back(1); + + size++; + } + + knots_in.reserve(size); + vig.reserve(size); + + for (int i = 0; i < nc; i++) { + knots_in.push_back(cropf * fuji_knots[i]); + distortion_in.push_back(fuji_distortion[i] / 100 + 1); + ca_r_in.push_back(fuji_ca_r[i]); + ca_b_in.push_back(fuji_ca_b[i]); + + // vignetting correction is applied before distortion correction. So the + // spline is related to the source image before distortion. + knots_vig.push_back(cropf * fuji_knots[i]); + + vig.push_back(100 / fuji_vignetting[i]); + } + + knots_dist.resize(MAXKNOTS); + dist.resize(MAXKNOTS); + for (int i = 0; i < 3; ++i) { + ca[i].resize(MAXKNOTS); + } + + // convert from spline related to source image (input is source image + // radius) to spline related to dest image (input is dest image radius) + for (int i = 0; i < MAXKNOTS; i++) { + const double rin = static_cast(i) / static_cast(nc - 1); + const double m = interpolateLinearSpline(knots_in, distortion_in, rin); + const double r = rin / m; + knots_dist[i] = r; + + dist[i] = m; + + const double mcar = interpolateLinearSpline(knots_in, ca_r_in, rin); + const double mcab = interpolateLinearSpline(knots_in, ca_b_in, rin); + + ca[0][i] = ca[1][i] = ca[2][i] = 1.f; + ca[0][i] *= mcar + 1; + ca[2][i] *= mcab + 1; + } + } + + double distortionCorrectionFactor(double rout) const override + { + return interpolateLinearSpline(knots_dist, dist, rout); + } + + double caCorrectionFactor(double rout, int channel) const override + { + return interpolateLinearSpline(knots_dist, ca[channel], rout); + } + + double distortionAndCACorrectionFactor(double rout, int channel) const override + { + return distortionCorrectionFactor(rout) * caCorrectionFactor(rout, channel); + } + + double vignettingCorrectionFactor(double r) const override + { + return interpolateLinearSpline(knots_vig, vig, r); + } + + bool hasDistortionCorrection() const override { return true; } + bool hasVignettingCorrection() const override { return true; } + bool hasCACorrection() const override { return true; } +}; + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { static const std::unordered_set makers = { "SONY", + "FUJIFILM", }; std::string make = Glib::ustring(meta->getMake()).uppercase(); @@ -296,6 +501,8 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec try { if (make == "SONY") { correction.reset(new SonyMetadataLensCorrection(meta)); + } else if (make == "FUJIFILM") { + correction.reset(new FujiMetadataLensCorrection(meta)); } } catch (std::exception &exc) { if (settings->verbose) { From 3189efddceb1d28b5b619caec56527ecacc5a974 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:28:19 +0200 Subject: [PATCH 263/291] Add Olympus metadata lens correction --- rtengine/lensmetadata.cc | 131 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index 006976371..91adadd8a 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -483,11 +483,140 @@ private: bool hasCACorrection() const override { return true; } }; +class OlympusMetadataLensCorrection : public CenterRadiusMetadataLensCorrection +{ +public: + OlympusMetadataLensCorrection(const FramesMetaData *meta) : + CenterRadiusMetadataLensCorrection(meta), has_dist(false), has_ca(false) + { + parse(); + } + +private: + bool has_dist, has_ca; + + double drs; + double dk2; + double dk4; + double dk6; + + double car0; + double car2; + double car4; + double cab0; + double cab2; + double cab4; + + void parse() + { + if (Exiv2::versionNumber() < EXIV2_MAKE_VERSION(0, 27, 4)) { + throw std::runtime_error("cannot get Olympus correction data, too old exiv2 version " + Exiv2::versionString()); + } + + auto &exif = metadata.exifData(); + + std::array distortion; + std::array cacorr; + + auto it = exif.findKey(Exiv2::ExifKey("Exif.OlympusIp.0x150a")); + if (it != exif.end() && it->count() == 4) { + for (int i = 0; i < 4; ++i) { + distortion[i] = it->toFloat(i); + } + has_dist = true; + } + + it = exif.findKey(Exiv2::ExifKey("Exif.OlympusIp.0x150c")); + if (it != exif.end() && it->count() == 6) { + for (int i = 0; i < 6; ++i) { + cacorr[i] = it->toFloat(i); + } + has_ca = true; + } + + if (has_dist) { + drs = distortion[3]; + dk2 = distortion[0]; + dk4 = distortion[1]; + dk6 = distortion[2]; + } + + if (has_ca) { + car0 = cacorr[0]; + car2 = cacorr[1]; + car4 = cacorr[2]; + cab0 = cacorr[3]; + cab2 = cacorr[4]; + cab4 = cacorr[5]; + } + + if (!has_dist && !has_ca) { + throw std::runtime_error("no Olympus correction data"); + } + } + + double distortionCorrectionFactor(double rout) const override + { + // The distortion polynomial maps a radius Rout in the output + // (undistorted) image, where the corner is defined as Rout=1, to a + // radius in the input (distorted) image, where the corner is defined + // as Rin=1. + // Rin = Rout*drs * (1 + dk2 * (Rout*drs)^2 + dk4 * (Rout*drs)^4 + dk6 * (Rout*drs)^6) + // + // cf is Rin / Rout. + + const double rs2 = std::pow(rout * drs, 2); + const double cf = drs * (1 + rs2 * (dk2 + rs2 * (dk4 + rs2 * dk6))); + + return cf; + } + + double caCorrectionFactor(double rout, int channel) const override + { + // ca corrects only red and blue channel + if (channel != 0 && channel != 2) return 1; + + // CA correction is applied as: + // Rin = Rout * ((1 + car0) + car2 * Rout^2 + car4 * Rout^4) + // + // cf is Rin / Rout. + + const double r2 = powf(rout, 2); + if (channel == 0) { + return 1 + (car0 + r2 * (car2 + r2 * car4)); + } else if (channel == 2) { + return 1 + (cab0 + r2 * (cab2 + r2 * cab4)); + } + + return 1; + } + + double distortionAndCACorrectionFactor(double rout, int channel) const override + { + return distortionCorrectionFactor(rout) * caCorrectionFactor(rout, channel); + } + + double vignettingCorrectionFactor(double r) const override + { + return 1; + } + + bool hasDistortionCorrection() const override { return has_dist; } + // Olympus cameras have a shading correction option that fixes vignetting + // already in the raw file. Looks like they don't report vignetting + // correction parameters inside metadata even if shading correction is + // disabled. + bool hasVignettingCorrection() const override { return false; } + bool hasCACorrection() const override { return has_ca; } +}; + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { static const std::unordered_set makers = { "SONY", "FUJIFILM", + "OLYMPUS", + "OM DIGITAL SOLUTIONS", }; std::string make = Glib::ustring(meta->getMake()).uppercase(); @@ -503,6 +632,8 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec correction.reset(new SonyMetadataLensCorrection(meta)); } else if (make == "FUJIFILM") { correction.reset(new FujiMetadataLensCorrection(meta)); + } else if (make == "OLYMPUS" || make == "OM DIGITAL SOLUTIONS") { + correction.reset(new OlympusMetadataLensCorrection(meta)); } } catch (std::exception &exc) { if (settings->verbose) { From c589e9d469cb41bfc24f39051735647d315d0d29 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:29:07 +0200 Subject: [PATCH 264/291] Add Panasonic metadata lens correction --- rtengine/lensmetadata.cc | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index 91adadd8a..f6b7e7331 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -610,6 +610,95 @@ private: bool hasCACorrection() const override { return has_ca; } }; +/* Panasonic metadata lens correction + * Currently disabled since the algorithm is not stable and works well with only some lenses. + * + * Data extraction and distortion correction formula from: + * https://web.archive.org/web/20120701131817/https://syscall.eu/#pana + * + * TODO(sgotti) + * * CA corrections not yet reverse engineered. + * * From a post on the exiftool forum: + * https://exiftool.org/forum/index.php?topic=9366.0 + * looks like there's another additional tag that provides similar data and it's + * used by newer cameras. + */ +class PanasonicMetadataLensCorrection : public CenterRadiusMetadataLensCorrection +{ +public: + PanasonicMetadataLensCorrection(const FramesMetaData *meta) : + CenterRadiusMetadataLensCorrection(meta), has_dist(false), a(0), b(0), c(0) + { + // Currently disabled since the algorithm is not stable and works well with only some lenses. + throw std::runtime_error("panasonic correction disabled as it's not yet working properly"); + + // parse(); + } + +private: + bool has_dist; + double scale, a, b, c; + + void parse() + { + if (Exiv2::versionNumber() < EXIV2_MAKE_VERSION(0, 27, 4)) { + throw std::runtime_error("cannot get Panasonic correction data, too old exiv2 version " + Exiv2::versionString()); + } + + auto &exif = metadata.exifData(); + + auto it = exif.findKey(Exiv2::ExifKey("Exif.PanasonicRaw.0x0119")); + if (it != exif.end()) { + std::vector buf; + buf.resize(it->value().size()); + it->value().copy(buf.data(), Exiv2::littleEndian); + + const Exiv2::byte *data = buf.data(); + // n is currently unused + // uint32_t n = Exiv2::getShort(data + 24, Exiv2::littleEndian); + scale = 1.0f / (1.0f + Exiv2::getShort(data + 10, Exiv2::littleEndian) / 32768.0f); + a = Exiv2::getShort(data + 16, Exiv2::littleEndian) / 32768.0f; + b = Exiv2::getShort(data + 8, Exiv2::littleEndian) / 32768.0f; + c = Exiv2::getShort(data + 22, Exiv2::littleEndian) / 32768.0f; + + has_dist = true; + } + } + + double distortionCorrectionFactor(double rout) const override + { + const double rs2 = std::pow(rout, 2); + + const double rin = scale * rout * (1 + rs2 * (a + rs2 * (b + rs2 * c))); + const double cf = rout / rin; + + return cf; + } + + double caCorrectionFactor(double rout, int channel) const override + { + return 1; + } + + double distortionAndCACorrectionFactor(double rout, int channel) const override + { + return distortionCorrectionFactor(rout); + } + + double vignettingCorrectionFactor(double r) const override + { + return 1; + } + + bool hasDistortionCorrection() const override { return has_dist; } + // Panasonic cameras have a shading correction option that fixes vignetting + // already in the raw file. Looks like they don't report vignetting + // correction parameters inside metadata even if shading correction is + // disabled. + bool hasVignettingCorrection() const override { return false; } + bool hasCACorrection() const override { return false; } +}; + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { static const std::unordered_set makers = { @@ -617,6 +706,7 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec "FUJIFILM", "OLYMPUS", "OM DIGITAL SOLUTIONS", + "PANASONIC", }; std::string make = Glib::ustring(meta->getMake()).uppercase(); @@ -634,6 +724,8 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec correction.reset(new FujiMetadataLensCorrection(meta)); } else if (make == "OLYMPUS" || make == "OM DIGITAL SOLUTIONS") { correction.reset(new OlympusMetadataLensCorrection(meta)); + } else if (make == "PANASONIC") { + correction.reset(new PanasonicMetadataLensCorrection(meta)); } } catch (std::exception &exc) { if (settings->verbose) { From 7deb2754d1f31beff891063b476905d4093e8570 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 13 Jun 2024 20:29:30 +0200 Subject: [PATCH 265/291] Add DNG metadata lens correction --- rtengine/lensmetadata.cc | 306 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 304 insertions(+), 2 deletions(-) diff --git a/rtengine/lensmetadata.cc b/rtengine/lensmetadata.cc index f6b7e7331..89a1ab13b 100644 --- a/rtengine/lensmetadata.cc +++ b/rtengine/lensmetadata.cc @@ -699,6 +699,306 @@ private: bool hasCACorrection() const override { return false; } }; +// Class DNGMetadatalensCorrection handles OpcodeList3 operations: operations to +// be done after demosaicing. +// OpcodeList1 is already handled by rawimagesource.cc. OpcodeList2 is not yet +// handled by rawtherapee. +// TODO(sgotti): dng spec provides clear rules on how and when to process the +// various opcodeList1/2/3 and the order of the various operations that should +// be done. +// Currently we only handle a subset of all the available opcodes and only one +// WarpRectilinar for distortion and FixVignetteRadial for vignetting (that's +// usually the case with Leica DNGs and ADC generated DNGs). +// This should be extended to support more exotic operations lists (i.e. +// multiple WarpRectilinear) +class DNGMetadataLensCorrection : public MetadataLensCorrection +{ +public: + DNGMetadataLensCorrection(const FramesMetaData *meta) : + MetadataLensCorrection(), swap_xy(false) + { + metadata = Exiv2Metadata(meta->getFileName()); + metadata.load(); + + parse(); + } + +private: + Exiv2Metadata metadata; + + bool swap_xy; + int width, height; + + double crx_d; + double cry_d; + double crx_v; + double cry_v; + + double cx_d; + double cy_d; + double m_v; + + double cx_v; + double cy_v; + double m_d; + + int planes; + + bool has_dist, has_ca, has_vign; + std::array, 3> warp_rectilinear; + std::array vignette_radial; + + void initCorrections(int width, int height, const procparams::CoarseTransformParams &coarse, int rawRotationDeg) override + { + if (rawRotationDeg >= 0) { + int rot = (coarse.rotate + rawRotationDeg) % 360; + swap_xy = (rot == 90 || rot == 270); + if (swap_xy) { + std::swap(width, height); + } + } + + this->width = width; + this->height = height; + + setup(); + } + + void parse() + { + std::set processed_opcodes; + + has_dist = has_ca = has_vign = false; + + auto &exif = metadata.exifData(); + + auto it = exif.findKey(Exiv2::ExifKey("Exif.SubImage1.OpcodeList3")); + + if (it != exif.end()) { + std::vector buf; + buf.resize(it->value().size()); + it->value().copy(buf.data(), Exiv2::invalidByteOrder); + + const Exiv2::byte *data = buf.data(); + uint32_t num_entries = Exiv2::getULong(data, Exiv2::bigEndian); + size_t idx = 4; + + for (size_t i = 0; i < num_entries && idx < buf.size(); ++i) { + uint32_t opcodeID = Exiv2::getULong(data + idx, Exiv2::bigEndian); + idx += 4; + idx += 4; // version + uint32_t flags = Exiv2::getULong(data + idx, Exiv2::bigEndian); + idx += 4; + size_t paramSize = Exiv2::getULong(data + idx, Exiv2::bigEndian); + idx += 4; + + if (idx + paramSize > buf.size()) { + throw std::runtime_error("error parsing DNG OpcodeList3"); + } + + if (processed_opcodes.find(opcodeID) != processed_opcodes.end()) { + // we currently handle only one opcode per type and ignore next ones if provided. + if (settings->verbose) { + std::printf("DNG OpcodeList3 %s opcode %d already processed\n", flags & 1 ? "optional" : "mandatory", opcodeID); + } + + idx += paramSize; + continue; + } + + processed_opcodes.insert(opcodeID); + + // we currently handle only one dist correction + if (opcodeID == 1 && !has_dist) { // WarpRectilinear + + planes = Exiv2::getULong(data + idx, Exiv2::bigEndian); + + if ((planes != 1) && (planes != 3)) { + throw std::runtime_error("cannot parse DNG WarpRectilinear"); + } + + for (int p = 0; p < planes; p++) { + for (int i = 0; i < 6; i++) { + warp_rectilinear[p][i] = Exiv2::getDouble(data + idx + 4 + 8 * (i + p * 6), Exiv2::bigEndian); + } + } + + crx_d = Exiv2::getDouble(data + idx + 4 + 8 * (0 + planes * 6), Exiv2::bigEndian); + cry_d = Exiv2::getDouble(data + idx + 4 + 8 * (1 + planes * 6), Exiv2::bigEndian); + + has_dist = true; + if (planes == 3) { + has_ca = true; + } + + // we currently handle only one vignetting correction + } else if (opcodeID == 3 && !has_vign) { // FixVignetteRadial + size_t start = idx; + size_t end = idx + 7 * 8; + if (end > buf.size()) { + throw std::runtime_error("cannot parse DNG FixVignetteRadial"); + } + for (int j = 0; j < 5; j++) { + vignette_radial[j] = Exiv2::getDouble(data + start, Exiv2::bigEndian); + start += 8; + } + crx_v = Exiv2::getDouble(data + start, Exiv2::bigEndian); + start += 8; + cry_v = Exiv2::getDouble(data + start, Exiv2::bigEndian); + has_vign = true; + + } else { + if (settings->verbose) { + std::printf("DNG OpcodeList3 has unsupported %s opcode %d\n", flags & 1 ? "optional" : "mandatory", opcodeID); + } + } + + idx += paramSize; + } + } + + if (!has_dist && !has_vign) { + throw std::runtime_error("no known DNG correction data"); + } + } + + void setup() + { + cx_d = crx_d * width; + cy_d = cry_d * height; + cx_v = crx_v * width; + cy_v = cry_v * height; + double mx_d = std::max(cx_d, width - cx_d); + double my_d = std::max(cy_d, height - cy_d); + m_d = std::sqrt(SQR(mx_d) + SQR(my_d)); + double mx_v = std::max(cx_v, width - cx_v); + double my_v = std::max(cy_v, height - cy_v); + m_v = std::sqrt(SQR(mx_v) + SQR(my_v)); + } + + void correctPlaneDistortion(double &x, double &y, int cx, int cy, int plane) const + { + if (plane < 0 || plane > 2 || plane > planes) { + return; + } + + double xx = x + cx; + double yy = y + cy; + if (swap_xy) { + std::swap(xx, yy); + } + + const double cx1 = cx_d; + const double cy1 = cy_d; + const double m = m_d; + + const double dx = (xx - cx1) / m; + const double dy = (yy - cy1) / m; + const double dx2 = SQR(dx); + const double dy2 = SQR(dy); + const double r2 = dx2 + dy2; + const double f = warp_rectilinear[plane][0] + r2 * (warp_rectilinear[plane][1] + r2 * (warp_rectilinear[plane][2] + r2 * warp_rectilinear[plane][3])); + const double dx_r = f * dx; + const double dy_r = f * dy; + const double dxdy2 = 2 * dx * dy; + const double dx_t = warp_rectilinear[plane][4] * dxdy2 + warp_rectilinear[plane][5] * (r2 + 2 * dx2); + const double dy_t = warp_rectilinear[plane][5] * dxdy2 + warp_rectilinear[plane][4] * (r2 + 2 * dy2); + + x = cx1 + m * (dx_r + dx_t); + y = cy1 + m * (dy_r + dy_t); + + if (swap_xy) { + std::swap(x, y); + } + x -= cx; + y -= cy; + } + + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override + { + if (!hasDistortionCorrection() || !hasCACorrection()) { + return; + } + + correctPlaneDistortion(x, y, cx, cy, channel); + } + + void correctDistortion(double &x, double &y, int cx, int cy) const override + { + if (!hasDistortionCorrection()) { + return; + } + + int plane = 1; // 3 planes correction, use plane 1 (green) + if (planes == 1) { + plane = 0; // 1 single plane correction + } + + correctPlaneDistortion(x, y, cx, cy, plane); + } + + void correctCA(double &x, double &y, int cx, int cy, int channel) const override + { + if (!hasCACorrection()) { + return; + } + + // we use plane 0 (red) and plane 2 (blue) for ca correction + if (channel != 0 && channel != 2) return; + if (planes != 3) return; + + double xgreen = x, ygreen = y; + correctPlaneDistortion(xgreen, ygreen, cx, cy, 1); + + double xch = x, ych = y; + correctPlaneDistortion(xch, ych, cx, cy, channel); + + // Calculate diff from green plane + x += xch - xgreen; + y += ych - ygreen; + } + + void processVignetteNChannels(int width, int height, float **rawData, int channels) const + { + if (!hasVignettingCorrection()) { + return; + } + + const double cx = cx_v; + const double cy = cy_v; + const double m2 = 1.f / SQR(m_v); + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + const double r2 = m2 * (SQR(x - cx) + SQR(y - cy)); + const double g = 1.f + r2 * (vignette_radial[0] + r2 * (vignette_radial[1] + r2 * (vignette_radial[2] + r2 * (vignette_radial[3] + r2 * vignette_radial[4])))); + for (int c = 0; c < channels; ++c) { + rawData[y][x*channels + c] *= g; + } + } + } + } + + void processVignette(int width, int height, float **rawData) const override + { + return processVignetteNChannels(width, height, rawData, 1); + } + + void processVignette3Channels(int width, int height, float **rawData) const override + { + return processVignetteNChannels(width, height, rawData, 3); + } + + bool isCACorrectionAvailable() const + { + return hasCACorrection(); + } + + bool hasDistortionCorrection() const override { return has_dist; } + bool hasVignettingCorrection() const override { return has_vign; } + bool hasCACorrection() const override { return has_ca; } +}; + std::unique_ptr MetadataLensCorrectionFinder::findCorrection(const FramesMetaData *meta) { static const std::unordered_set makers = { @@ -711,14 +1011,16 @@ std::unique_ptr MetadataLensCorrectionFinder::findCorrec std::string make = Glib::ustring(meta->getMake()).uppercase(); - if (makers.find(make) == makers.end()) { + if (!meta->getDNG() && makers.find(make) == makers.end()) { return nullptr; } std::unique_ptr correction; try { - if (make == "SONY") { + if (meta->getDNG()) { + correction.reset(new DNGMetadataLensCorrection(meta)); + } else if (make == "SONY") { correction.reset(new SonyMetadataLensCorrection(meta)); } else if (make == "FUJIFILM") { correction.reset(new FujiMetadataLensCorrection(meta)); From 79aaba1bcbd54578f9730b940af71bcc4b16fc19 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:22:27 -0700 Subject: [PATCH 266/291] Refactor isDNG flag --- rtengine/imagedata.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 89f1f0105..77be8c1a3 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -732,8 +732,6 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : meta.getDimensions(w_, h_); - isDNG = find_exif_tag("Exif.Image.DNGVersion"); - // ----------------------- // Special file type detection (HDR, PixelShift) // ------------------------ @@ -937,6 +935,8 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : } } + isDNG = dngVersion; + // Read DNG OpcodeList1. if (dngVersion && (find_exif_tag("Exif.SubImage1.OpcodeList1") || find_exif_tag("Exif.Image.OpcodeList1"))) { readOpcodesList(pos->value(), &fixBadPixelsConstant, &hasFixBadPixelsConstant_, nullptr); From 28bb2add0736a6a552dfccffc1f2c4c6c22254ab Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sat, 20 Jul 2024 10:57:55 +0700 Subject: [PATCH 267/291] Mac: clarify installation instructions Resolution of #6580 Per @databu https://github.com/Beep6581/RawTherapee/issues/6580#issuecomment-2220407772 --- tools/osx/INSTALL.readme.rtf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/osx/INSTALL.readme.rtf b/tools/osx/INSTALL.readme.rtf index dea38c37f..9a4183a0d 100644 --- a/tools/osx/INSTALL.readme.rtf +++ b/tools/osx/INSTALL.readme.rtf @@ -1,7 +1,7 @@ To install the RawTherapee application: 1. Open the RawTherapee .dmg Disk Image included alongside this document. -2. Drag the RawTherapee icon onto the /Applications folder icon +2. To install RT, drag icon onto /Applications (it will not start if in another location). To run the RawTherapee application: From a4de981329a83fb63f8357af76c7c2ab8f265277 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 13 Jul 2024 22:00:37 -0700 Subject: [PATCH 268/291] Review the default language file --- rtdata/languages/default | 198 +++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 100 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2841f9603..f38d51d7d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -758,7 +758,7 @@ HISTORY_MSG_511;Local - SD - ΔE scope threshold HISTORY_MSG_512;Local - SD - ΔE decay HISTORY_MSG_513;Local - Spot - Excluding - Scope HISTORY_MSG_514;Local - Spot structure -HISTORY_MSG_515;Local Adjustments +HISTORY_MSG_515;Selective Editing HISTORY_MSG_516;Local - Color and light HISTORY_MSG_517;Local - Enable super HISTORY_MSG_518;Local - Lightness @@ -1440,8 +1440,8 @@ HISTORY_MSG_ICM_PRESER;Preserve neutral HISTORY_MSG_ICM_REDX;Primaries Red X HISTORY_MSG_ICM_REDY;Primaries Red Y HISTORY_MSG_ICM_REFI;Refinement Colors -HISTORY_MSG_ICM_SHIFTX;Refinement Colors - shift x -HISTORY_MSG_ICM_SHIFTY;Refinement Colors - shift y +HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights HISTORY_MSG_ICM_TRCEXP;Abstract Profile HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma @@ -1450,78 +1450,77 @@ HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method HISTORY_MSG_ILLUM;CAL - SC - Illuminant -HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local CIECAM - gradient angle -HISTORY_MSG_LOCAL_CIE_BRICOMP;Local CIECAM Brightness compression -HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local CIECAM Brightness compression threshold -HISTORY_MSG_LOCAL_CIE_BWCIE;Local CIECAM - black and white -HISTORY_MSG_LOCAL_CIE_CAT;Matrix adaptation -HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local JzCzHz Local contrast -HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local CIECAM All mask tools -HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local CIECAM Pre-Cam -HISTORY_MSG_LOCAL_CIE_GAM;Local CIECAM Gamma -HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local CIECAM Gamut -HISTORY_MSG_LOCAL_CIE_ILL;Local CIECAM TRC Illuminant -HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local CIECAM Log encoding Q -HISTORY_MSG_LOCAL_CIE_MIDT;Local CIECAM Mid Tones -HISTORY_MSG_LOCAL_CIE_NORM;Local CIECAM Normalize L -HISTORY_MSG_LOCAL_CIE_PRIM;Local CIECAM TRC Primaries -HISTORY_MSG_LOCAL_CIE_REFI;Local CIECAM Refinement Colors -HISTORY_MSG_LOCAL_CIE_SIG;Sigmoid -HISTORY_MSG_LOCAL_CIE_SIGADAP;Local CIECAM Sigmoid adaptability -HISTORY_MSG_LOCAL_CIE_SIGMET;Local CIECAM - Sigmoid method -HISTORY_MSG_LOCAL_CIE_SLOP;Local CIECAM - Slope -HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local CIECAM - Gray balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local CIECAM - Red balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local CIECAM - Green balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local CIECAM - Blue balance -HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local CIECAM - Smooth lights method -HISTORY_MSG_LOCAL_CIE_STRGRAD;Local CIECAM - gradient strength L -HISTORY_MSG_LOCAL_CIE_TRC;Local CIECAM - TRC -HISTORY_MSG_LOCAL_CIE_REDXL;Local CIECAM - Red X -HISTORY_MSG_LOCAL_CIE_REDYL;Local CIECAM - Red Y -HISTORY_MSG_LOCAL_CIE_GREXL;Local CIECAM - Green X -HISTORY_MSG_LOCAL_CIE_GREYL;Local CIECAM - Green Y -HISTORY_MSG_LOCAL_CIE_BLACKS;Local CIECAM - Blacks distribution -HISTORY_MSG_LOCAL_CIE_BLUXL;Local CIECAM - Blue X -HISTORY_MSG_LOCAL_CIE_BLUYL;Local CIECAM - Blue Y -HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local CIECAM - Shift x -HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local CIECAM - Shift y -HISTORY_MSG_LOCAL_CIE_SMOOTH;Local CIECAM - Scale Yb Scene -HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local CIECAM - Scale Yb Viewing -HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local CIECAM - levels - luminosity mode -HISTORY_MSG_LOCAL_CIE_SATCIE;Local CIECAM - Saturation control -HISTORY_MSG_LOCAL_CIE_STRLOG;Local CIECAM - Log encoding strength -HISTORY_MSG_LOCAL_CIE_WHITES;Local CIECAM - Whites distribution -HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local Cie mask blur contrast -HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local Cie mask blur fftw -HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local Cie mask blur radius -HISTORY_MSG_LOCAL_CIEMASK_CHH;Local Cie mask curve hh -HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local Cie mask highlights -HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local Cie mask shadows -HISTORY_MSG_LOCAL_CIEMASK_STRU;Local Cie mask structure -HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local Cie mask structure as tool -HISTORY_MSG_LOCAL_CIEMASK_WLC;Local CIECAM mask wavelet Lc -HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local CIECAM mask wavelet levels -HISTORY_MSG_LOCAL_FEATHERCOL;Local Color gradient feather -HISTORY_MSG_LOCAL_FEATHEREXE;Local Exp gradient feather -HISTORY_MSG_LOCAL_FEATHERVIB;Local Vib gradient feather -HISTORY_MSG_LOCAL_FEATHERWAV;Local Wav gradient feather -HISTORY_MSG_LOCAL_FEATHERLOG;Local Log gradient feather -HISTORY_MSG_LOCAL_FEATHERCIE;Local CIECAM gradient feather -HISTORY_MSG_LOCAL_FEATHERSH;Local SH gradient feather -HISTORY_MSG_LOCAL_FEATHERMAS;Local Mask common gradient feather - -HISTORY_MSG_LOCAL_LOG_BLACKS;Local Log - Blacks distribution -HISTORY_MSG_LOCAL_LOG_COMPR;Local Log - Compress brightness -HISTORY_MSG_LOCAL_LOG_SAT;Local Log - Saturation control -HISTORY_MSG_LOCAL_LOG_WHITES;Local Log - Whites distribution +HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze - black +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation HISTORY_MSG_METADATA_MODE;Metadata copy mode @@ -1942,7 +1941,7 @@ PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs PREFERENCES_CLUTSDIR;HaldCLUT directory PREFERENCES_CMMBPC;Black point compensation -PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing PREFERENCES_COMPLEXITY_EXP;Advanced PREFERENCES_COMPLEXITY_NORM;Standard PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2086,7 +2085,7 @@ PREFERENCES_SHOWBASICEXIF;Show basic Exif info PREFERENCES_SHOWDATETIME;Show date and time PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows PREFERENCES_SINGLETAB;Single Editor Tab Mode PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs @@ -2094,7 +2093,7 @@ PREFERENCES_SND_HELP;Enter a full file path to set a sound, or leave blank for n PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done PREFERENCES_SND_QUEUEDONE;Queue processing done PREFERENCES_SND_THRESHOLDSECS;After seconds -PREFERENCES_SPOTLOC;Define Spot method for Local Adjustments +PREFERENCES_SPOTLOC;Define Spot method for Selective Editing PREFERENCES_STARTUPIMDIR;Image Directory at Startup PREFERENCES_TAB_BROWSER;File Browser PREFERENCES_TAB_COLORMGR;Color Management @@ -2741,14 +2740,14 @@ TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile TP_ICM_TONECURVE;Tone curve TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. TP_ICM_TRCFRAME;Abstract Profile -TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. TP_ICM_WORKINGPROFILE;Working Profile TP_ICM_WORKING_CAT;Matrix adaptation TP_ICM_WORKING_CAT_BRAD;Bradford TP_ICM_WORKING_CAT_CAT16;Cat16 TP_ICM_WORKING_CAT_CAT02;Cat02 -TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default Bradford +TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford TP_ICM_WORKING_CAT_VK;Von Kries TP_ICM_WORKING_CAT_XYZ;XYZ scale TP_ICM_WORKING_CIEDIAG;CIE xy diagram @@ -2768,8 +2767,8 @@ TP_ICM_WORKING_ILLU_STDA;stdA 2875K TP_ICM_WORKING_NON;None TP_ICM_WORKING_PRESER;Preserves Pastel tones TP_ICM_WORKING_PRIM;Destination primaries -TP_ICM_WORKING_PRIM_TOOLTIP;Destination primaries (Advanced): which allows you to change the destination primaries to restore or change image color (saturation), the color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are not too different, 'Working Profiles' are not modified. Perform a gamut control.\nWhen 'Custom LA (sliders)' is selected you can modify the values of the 3 primaries Red, Green, Blue for X and Y. -TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. +TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2864,7 +2863,7 @@ TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Automatic TP_LOCALLAB_AVOID;Avoid color shift -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. The result is not the same as Lab. +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. TP_LOCALLAB_AVOIDMUN;Munsell correction only TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2912,7 +2911,7 @@ TP_LOCALLAB_BWEVSIG;Activated TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. For example to match Cam16 processing with the maximum monitor brightness of 400cd/m2. +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments TP_LOCALLAB_CAMMODE;CAM model TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2973,7 +2972,7 @@ TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLev TP_LOCALLAB_CLIPTM;Clip restored data (gain) TP_LOCALLAB_COFR;Color & Light TP_LOCALLAB_COLORDE;ΔE preview color - intensity -TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening' or 'Soft Light and Original Retinex' or 'Blur/Grain and Denoise' or 'Dehaze and Retinex' or 'Contrast by Detail Levels' in 'Add tool to current spot' menu.\nFor others tools Preview ΔE button is 'in the tool' - to be able to preview ΔE with several tools enabled, use preferably Mask and modifications. +TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. TP_LOCALLAB_COLORSCOPE;Scope (color tools) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. @@ -2986,7 +2985,7 @@ TP_LOCALLAB_COMPFRA;Directional contrast TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping TP_LOCALLAB_COMPRCIE;Brightness compression TP_LOCALLAB_COMPRCIETH;Compression threshold -TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the theshold slider value. To use in conjunction with Whites distribution. +TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. TP_LOCALLAB_CONTCOL;Contrast threshold TP_LOCALLAB_CONTFRA;Contrast by level TP_LOCALLAB_CONTRAST;Contrast @@ -3001,7 +3000,7 @@ TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance 'Super' TP_LOCALLAB_CURVCURR;Normal TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3062,7 +3061,7 @@ TP_LOCALLAB_EV_VIS_ALL;Show all TP_LOCALLAB_EXCLUF;Excluding TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. TP_LOCALLAB_EXCLUTYPE;Spot method -TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the local adjustment tools on the whole image, without using deltaE or transitions. +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXFULL;Full image TP_LOCALLAB_EXMAIN;Global @@ -3074,7 +3073,7 @@ TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ TP_LOCALLAB_EXPCOMPINV;Exposure compensation TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_EXPCURV;Curves TP_LOCALLAB_EXPGRAD;Graduated Filter @@ -3244,10 +3243,9 @@ TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic rang TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. TP_LOCALLAB_LOGCIE;Log encoding -TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. +TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) -TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast etc.:\nThe user may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. - +TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3421,18 +3419,18 @@ TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. TP_LOCALLAB_PASTELS2;Vibrance TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression -TP_LOCALLAB_PRECAM_TOOLTIP;This 'Source Data Adjustments' modifies: a)the Dynamic Range using Log encoding; b) the tones of the image and primaries(simplified Abstract Profile) and also midtones, just before the Ciecam process. The values are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\n\n\n-Destination primaries: which allows you to change the destination primaries to restore or change image color (saturation), the color balance is 'significantly' preserved when the 'Working Profile' and the 'Destination primaries' are not too different (be careful), 'Working Profiles' are not modified.\nYou can also finely adapt the primaries and the illuminant (white-point).\nMoving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. -TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked ensures a gamut control just after primary conversion to XYZ matrix. +TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. -TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y" allows you to carry out moderate Color Toning. +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. TP_LOCALLAB_PREVHIDE;Hide additional settings TP_LOCALLAB_PREVIEW;Preview ΔE TP_LOCALLAB_PREVSHOW;Show additional settings TC_LOCALLAB_PRIM_SHIFTX;Shift x TC_LOCALLAB_PRIM_SHIFTY;Shift y -TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors" allows you:\n 1) for low values adjust the image purity.\n 2) for higher values, carry out moderate Color Toning.\n 3) Be careful not to go outside the CIE xy diagram. +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant TP_LOCALLAB_PROXI;ΔE decay TP_LOCALLAB_QUAAGRES;Aggressive @@ -3550,7 +3548,7 @@ TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer TP_LOCALLAB_SIGCIE;Sigmoid -TP_LOCALLAB_SIGFRA;Sigmoid Q +TP_LOCALLAB_SIGFRA;Sigmoid Q TP_LOCALLAB_SIGGAMJCIE;Gamma TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Attenuation response @@ -3560,18 +3558,18 @@ TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev TP_LOCALLAB_SIGMOIDSENSI;Adaptability TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the 'Jz' and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. -TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' and 'Sigmoid Q'.\nSigmoid Q: three sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Adaptability weights the action of the sigmoid by action on the internal exponential function. -TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the comboxbox selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. -TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance : ratio between original and output image. -TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the comboxbox selection'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. This last value stands for brightness (Q) should be a near the possible value 'Compression treshold' (calculate when 'Auto threshold" checked, often > 1). +TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). TP_LOCALLAB_SIGSLOPJCIE;Slope TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution TP_LOCALLAB_SIGWHITESCIE;Whites distribution -TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic, when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. TP_LOCALLAB_SLOMASKCOL;Slope TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) @@ -3583,7 +3581,7 @@ TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing -TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma - Slope - based: choice (Standard and Advanced) allows you to simulate a "Tone mapping" using: a) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%); b) Viewing conditions: Mean luminance (Yb%).\nScale Yb Scene is function of White-Ev. +TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. TP_LOCALLAB_SOFT;Soft Light & Original Retinex TP_LOCALLAB_SOFTM;Soft Light TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -4379,7 +4377,7 @@ TP_WBALANCE_METHOD;Method TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) “Observer 10°†must be selected. +TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 From 98bd3d1912c63182c77e30154e7ac930f555a46a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 14 Jul 2024 11:16:29 -0700 Subject: [PATCH 269/291] Run generateTranslationDiffs --- rtdata/languages/Catala | 250 +- rtdata/languages/Chinese (Simplified) | 209 +- rtdata/languages/Czech | 247 +- rtdata/languages/Dansk | 255 +- rtdata/languages/Deutsch | 174 +- rtdata/languages/English (UK) | 254 +- rtdata/languages/English (US) | 254 +- rtdata/languages/Espanol (Castellano) | 181 +- rtdata/languages/Espanol (Latin America) | 262 +- rtdata/languages/Francais | 206 +- rtdata/languages/Italiano | 1179 +++-- rtdata/languages/Japanese | 16 +- rtdata/languages/Magyar | 239 +- rtdata/languages/Nederlands | 4330 +++++++++-------- rtdata/languages/Polish | 252 +- rtdata/languages/Portugues | 249 +- rtdata/languages/Portugues (Brasil) | 250 +- rtdata/languages/Russian | 252 +- rtdata/languages/Serbian (Cyrilic Characters) | 258 +- rtdata/languages/Slovenian | 249 +- rtdata/languages/Swedish | 252 +- rtdata/languages/default | 199 +- 22 files changed, 6619 insertions(+), 3398 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index bc95d7546..9ce1d8f6d 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -51,7 +51,6 @@ EXIFPANEL_RESET;Reinicialitza EXIFPANEL_RESETALL;Reinic. tot EXIFPANEL_RESETALLHINT;Reinicialitza atributs als valors originals EXIFPANEL_RESETHINT;Reinic. atributs seleccionats als valors originals -EXIFPANEL_SUBDIRECTORY;Subdirectori EXPORT_BYPASS_ALL;Selecciona / Deselecciona tot EXPORT_BYPASS_DEFRINGE;Salta desserrellar EXPORT_BYPASS_DIRPYRDENOISE;Salta reducció de soroll @@ -707,8 +706,6 @@ TP_ICM_TONECURVE_TOOLTIP;Habilita l'ús de corbes de to incloses en els perfils TP_ICM_WORKINGPROFILE;Perfil de treball TP_IMPULSEDENOISE_LABEL;Impuls Reducció de Soroll TP_IMPULSEDENOISE_THRESH;Llindar d'impuls RS -TP_LABCURVE_AVOIDCOLORSHIFT;Evita alteració de color -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fica colors al gamut de l'espai de color de treball\ni aplica la correcció Munsell TP_LABCURVE_BRIGHTNESS;Brillantor TP_LABCURVE_CHROMATICITY;Cromaticitat TP_LABCURVE_CONTRAST;Contrast @@ -955,6 +952,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !FILEBROWSER_RESETDEFAULTPROFILE;Reset to default !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: 0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles (*.icc) @@ -1328,7 +1326,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -1638,7 +1636,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -1881,7 +1879,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -1997,16 +1995,23 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2019,7 +2024,72 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2213,10 +2283,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -2243,8 +2313,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_GRADIENT;Graduated filter !PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PCVIGNETTE;Vignette filter !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -2268,13 +2338,15 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color !PREFERENCES_APPEARANCE_MAINFONT;Main font !PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator guide color -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_APPEARANCE_THEME;Theme !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit !PREFERENCES_BEHADDALL;All to 'Add' !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. !PREFERENCES_BEHSETALL;All to 'Set' !PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR;Clear !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: @@ -2293,7 +2365,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2338,6 +2410,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -2365,6 +2438,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_PROFILE_NONE;None !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now @@ -2372,7 +2447,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_PERFORMANCE;Performance @@ -2380,6 +2456,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2420,6 +2497,27 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !QINFO_HDR;HDR / %2 frame(s) !QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) !QUEUE_DESTFILENAME;Path and file name +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAMPLEFORMAT_0;Unknown data format @@ -2443,12 +2541,16 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_BWMIX_ALGO;Algorithm OYCPM @@ -2800,6 +2902,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT;Illuminant !TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -2820,8 +2923,15 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2833,11 +2943,13 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2846,11 +2958,14 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2876,6 +2991,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_CA;Chromatic aberration @@ -2894,9 +3010,9 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2939,9 +3055,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2981,6 +3100,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -2996,8 +3121,9 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3005,7 +3131,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3020,7 +3149,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3029,13 +3158,14 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3055,6 +3185,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3063,6 +3194,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3078,9 +3210,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3089,11 +3222,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3115,7 +3248,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3211,7 +3345,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3256,8 +3390,10 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3265,7 +3401,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3278,6 +3414,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3347,7 +3484,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3383,6 +3520,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3430,10 +3568,15 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3478,10 +3621,11 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3502,7 +3646,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3548,17 +3692,41 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3580,13 +3748,14 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3618,11 +3787,12 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4181,7 +4351,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_EQBLUERED;Blue/Red equalizer !TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of 'white balance' by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. @@ -4226,7 +4396,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index bf485e4cd..2ed7cf262 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -84,8 +84,6 @@ EXIFPANEL_RESET;é‡ç½® EXIFPANEL_RESETALL;全部é‡ç½® EXIFPANEL_RESETALLHINT;é‡ç½®æ‰€æœ‰æ ‡ç­¾å†…容 EXIFPANEL_RESETHINT;é‡ç½®æ‰€é€‰æ ‡ç­¾å†…容 -EXIFPANEL_SHOWALL;显示所有 -EXIFPANEL_SUBDIRECTORY;å­æ–‡ä»¶å¤¹ EXPORT_BYPASS;è¦è·³è¿‡çš„å¤„ç†æ­¥éª¤ EXPORT_BYPASS_ALL;选择/å–æ¶ˆé€‰æ‹©å…¨éƒ¨é€‰é¡¹ EXPORT_BYPASS_DEFRINGE;è·³è¿‡åŽ»é™¤è‰²è¾¹å¤„ç† @@ -827,7 +825,7 @@ HISTORY_MSG_SOFTLIGHT_ENABLED;柔光 HISTORY_MSG_SOFTLIGHT_STRENGTH;柔光-力度 HISTORY_MSG_SPOT;污点移除 HISTORY_MSG_TM_FATTAL_ANCHOR;DRC-锚点 -HISTORY_MSG_TRANS_Method;几何-方法 +HISTORY_MSG_TRANS_METHOD;几何-方法 HISTORY_MSG_WAVLEVELSIGM;去噪-åŠå¾„ HISTORY_MSG_WAVLEVSIGM;åŠå¾„ HISTORY_MSG_WAVOFFSET;åç§» @@ -867,7 +865,6 @@ MAIN_BUTTON_NAVNEXT_TOOLTIP;跳转到当å‰ç¼–辑图片的下一张图åƒã€‚\n MAIN_BUTTON_NAVPREV_TOOLTIP;跳转到当å‰ç¼–辑图片的上一张图åƒã€‚\nå¿«æ·é”®ï¼šShift-F3\n\nè‹¥è¦è·³è½¬åˆ°å½“å‰é€‰ä¸­å›¾ç‰‡çš„上一张图åƒï¼š\nShortcut: F3 MAIN_BUTTON_PREFERENCES;傿•°è®¾ç½® MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;将当å‰å›¾ç‰‡æ”¾å…¥å¤„ç†é˜Ÿåˆ—中\nå¿«æ·é”®ï¼šCtrl+b -MAIN_BUTTON_SAVE;ä¿å­˜å›¾ç‰‡ MAIN_BUTTON_SAVE_TOOLTIP;ä¿å­˜å½“å‰å›¾åƒ\nå¿«æ·é”®ï¼šCtrl+S MAIN_BUTTON_SENDTOEDITOR;å‘é€åˆ°ç¼–辑器 MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;使用外部工具编辑当å‰å›¾åƒ\nå¿«æ·é”®ï¼šCtrl+E @@ -1034,16 +1031,15 @@ PARTIALPASTE_SHARPENMICRO;å¾®åå·® PARTIALPASTE_SOFTLIGHT;柔光 PARTIALPASTE_SPOT;污点移除 PARTIALPASTE_TM_FATTAL;动æ€èŒƒå›´åŽ‹ç¼© +PARTIALPASTE_VIBRANCE;鲜艳度 PARTIALPASTE_VIGNETTING;暗角矫正 PARTIALPASTE_WHITEBALANCE;白平衡 -PARTIALPASTE_鲜明度;鲜艳度 PREFERENCES_ADD;相加 PREFERENCES_APPEARANCE;外观 PREFERENCES_APPEARANCE_COLORPICKERFONT;拾色器字体 PREFERENCES_APPEARANCE_CROPMASKCOLOR;è£å‰ªè’™ç‰ˆé¢œè‰² PREFERENCES_APPEARANCE_MAINFONT;主字体 PREFERENCES_APPEARANCE_NAVGUIDECOLOR;导航窗图框颜色 -PREFERENCES_APPEARANCE_PSEUDOHIDPI;伪-高DPIæ¨¡å¼ PREFERENCES_APPEARANCE_THEME;主题 PREFERENCES_APPLNEXTSTARTUP;下次å¯åŠ¨ç”Ÿæ•ˆ PREFERENCES_AUTOMONPROFILE;使用æ“作系统主显示器的色彩档案 @@ -1598,7 +1594,6 @@ TP_EXPOSURE_COMPRHIGHLIGHTS;高光压缩 TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;高光压缩阈值 TP_EXPOSURE_COMPRSHADOWS;阴影压缩 TP_EXPOSURE_CONTRAST;对比度 -TP_EXPOSURE_CURVEEDITOR;色调曲线 TP_EXPOSURE_CURVEEDITOR1;色调曲线 1 TP_EXPOSURE_CURVEEDITOR2;色调曲线 2 TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;请在RawPediaçš„Exposure > Tone Curve文章中了解如何使用åŒè‰²è°ƒæ›²çº¿ @@ -1696,8 +1691,6 @@ TP_ICM_WORKING_TRC;色调å“应曲线: TP_ICM_WORKING_TRC_CUSTOM;自定义 TP_IMPULSEDENOISE_LABEL;脉冲噪声é™ä½Ž TP_IMPULSEDENOISE_THRESH;阈值 -TP_LABCURVE_AVOIDCOLORSHIFT;é¿å…色彩åç§» -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;使色彩适应当å‰è‰²å½©ç©ºé—´èŒƒå›´ï¼Œå¹¶ä½¿ç”¨Munsell色矫正 TP_LABCURVE_BRIGHTNESS;明度 TP_LABCURVE_CHROMATICITY;色度 TP_LABCURVE_CHROMA_TOOLTIP;è‹¥è¦åº”用黑白色调,将色度值é™ä½Žä¸º-100 @@ -2788,7 +2781,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -3096,8 +3089,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y !HISTORY_MSG_ICM_REFI;Refinement Colors -!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - shift x -!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - shift y +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y !HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights !HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma @@ -3107,64 +3100,72 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local Cie mask blur contrast -!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local Cie mask blur fftw -!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local Cie mask blur radius -!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local Cie mask curve hh -!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local Cie mask highlights -!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local Cie mask shadows -!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local Cie mask structure -!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local Cie mask structure as tool -!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local CIECAM mask wavelet Lc -!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local CIECAM mask wavelet levels -!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local CIECAM - gradient angle -!HISTORY_MSG_LOCAL_CIE_BLACKS;Local CIECAM - Blacks distribution -!HISTORY_MSG_LOCAL_CIE_BLUXL;Local CIECAM - Blue X -!HISTORY_MSG_LOCAL_CIE_BLUYL;Local CIECAM - Blue Y -!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local CIECAM Brightness compression -!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local CIECAM Brightness compression threshold -!HISTORY_MSG_LOCAL_CIE_BWCIE;Local CIECAM - black and white -!HISTORY_MSG_LOCAL_CIE_CAT;Matrix adaptation -!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local JzCzHz Local contrast -!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local CIECAM All mask tools -!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local CIECAM Pre-Cam -!HISTORY_MSG_LOCAL_CIE_GAM;Local CIECAM Gamma -!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local CIECAM Gamut -!HISTORY_MSG_LOCAL_CIE_GREXL;Local CIECAM - Green X -!HISTORY_MSG_LOCAL_CIE_GREYL;Local CIECAM - Green Y -!HISTORY_MSG_LOCAL_CIE_ILL;Local CIECAM TRC Illuminant -!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local CIECAM Log encoding Q -!HISTORY_MSG_LOCAL_CIE_MIDT;Local CIECAM Mid Tones -!HISTORY_MSG_LOCAL_CIE_NORM;Local CIECAM Normalize L -!HISTORY_MSG_LOCAL_CIE_PRIM;Local CIECAM TRC Primaries -!HISTORY_MSG_LOCAL_CIE_REDXL;Local CIECAM - Red X -!HISTORY_MSG_LOCAL_CIE_REDYL;Local CIECAM - Red Y -!HISTORY_MSG_LOCAL_CIE_REFI;Local CIECAM Refinement Colors -!HISTORY_MSG_LOCAL_CIE_SATCIE;Local CIECAM - Saturation control -!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local CIECAM - Shift x -!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local CIECAM - Shift y -!HISTORY_MSG_LOCAL_CIE_SIG;Sigmoid -!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local CIECAM Sigmoid adaptability -!HISTORY_MSG_LOCAL_CIE_SIGMET;Local CIECAM - Sigmoid method -!HISTORY_MSG_LOCAL_CIE_SLOP;Local CIECAM - Slope -!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local CIECAM - Gray balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local CIECAM - Blue balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local CIECAM - Green balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local CIECAM - Red balance -!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local CIECAM - Scale Yb Scene -!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local CIECAM - Smooth lights method -!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local CIECAM - Scale Yb Viewing -!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local CIECAM - levels - luminosity mode -!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local CIECAM - gradient strength L -!HISTORY_MSG_LOCAL_CIE_STRLOG;Local CIECAM - Log encoding strength -!HISTORY_MSG_LOCAL_CIE_TRC;Local CIECAM - TRC -!HISTORY_MSG_LOCAL_CIE_WHITES;Local CIECAM - Whites distribution -!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze - black +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift -!HISTORY_MSG_LOCAL_LOG_BLACKS;Local Log - Blacks distribution -!HISTORY_MSG_LOCAL_LOG_COMPR;Local Log - Compress brightness -!HISTORY_MSG_LOCAL_LOG_SAT;Local Log - Saturation control -!HISTORY_MSG_LOCAL_LOG_WHITES;Local Log - Whites distribution +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -3190,7 +3191,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot !HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization !HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map -!HISTORY_MSG_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance !HISTORY_MSG_WAVBL;Blur levels @@ -3309,7 +3309,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PARTIALPASTE_VIBRANCE;Vibrance !PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth !PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders !PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders @@ -3339,7 +3338,9 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SPOTLOC;Define Spot method for Local Adjustments +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools @@ -3402,7 +3403,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending !TC_LOCALLAB_PRIM_SHIFTX;Shift x -!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors" allows you:\n 1) for low values adjust the image purity.\n 2) for higher values, carry out moderate Color Toning.\n 3) Be careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. !TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By @@ -3501,13 +3502,13 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. !TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. !TP_ICM_WORKING_CAT;Matrix adaptation !TP_ICM_WORKING_CAT_BRAD;Bradford !TP_ICM_WORKING_CAT_CAT02;Cat02 !TP_ICM_WORKING_CAT_CAT16;Cat16 -!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default Bradford +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford !TP_ICM_WORKING_CAT_VK;Von Kries !TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram @@ -3526,7 +3527,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3541,7 +3542,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB -!TP_ICM_WORKING_PRIM_TOOLTIP;Destination primaries (Advanced): which allows you to change the destination primaries to restore or change image color (saturation), the color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are not too different, 'Working Profiles' are not modified. Perform a gamut control.\nWhen 'Custom LA (sliders)' is selected you can modify the values of the 3 primaries Red, Green, Blue for X and Y. +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3565,10 +3566,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull !TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel !TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ADJ;Equalizer Color !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\n\nDefault: Munsell only.\nMunsell only, fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab, applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. The result is not the same as Lab. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3597,7 +3599,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. For example to match Cam16 processing with the maximum monitor brightness of 400cd/m2. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 !TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz !TP_LOCALLAB_CH;CL - LC @@ -3613,7 +3615,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CIELIGHTCONTFRA;Lighting & Contrast !TP_LOCALLAB_CIELIGHTFRA;Lighting !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. -!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels !TP_LOCALLAB_CIE_SMOOTH_EV;Ev based !TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based !TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based @@ -3630,14 +3632,14 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CLARITYML;Clarity !TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. !TP_LOCALLAB_CLIPTM;Clip restored data (gain) -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening' or 'Soft Light and Original Retinex' or 'Blur/Grain and Denoise' or 'Dehaze and Retinex' or 'Contrast by Detail Levels' in 'Add tool to current spot' menu.\nFor others tools Preview ΔE button is 'in the tool' - to be able to preview ΔE with several tools enabled, use preferably Mask and modifications. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. !TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COMPFRA;Directional contrast !TP_LOCALLAB_COMPRCIE;Brightness compression !TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping -!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the theshold slider value. To use in conjunction with Whites distribution. +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. @@ -3648,7 +3650,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. !TP_LOCALLAB_CURVNONE;Disable curves @@ -3685,12 +3687,12 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. !TP_LOCALLAB_ESTOP;Edge stopping !TP_LOCALLAB_EV_DUPL;Copy of -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the local adjustment tools on the whole image, without using deltaE or transitions. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. @@ -3706,7 +3708,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_FATLEVEL;Sigma !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image !TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. @@ -3805,8 +3808,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. !TP_LOCALLAB_LOGCIE;Log encoding !TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) -!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast etc.:\nThe user may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3908,6 +3911,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_MERONE;Normal !TP_LOCALLAB_MERSAT;Saturation !TP_LOCALLAB_MERSEV;Soft Light (legacy) +!TP_LOCALLAB_MERSEV0;Soft Light Illusion !TP_LOCALLAB_MERSEV1;Soft Light W3C !TP_LOCALLAB_MERSEV2;Hard Light !TP_LOCALLAB_MERSIX;Divide @@ -3947,11 +3951,11 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. -!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked ensures a gamut control just after primary conversion to XYZ matrix. -!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y" allows you to carry out moderate Color Toning. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. !TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. -!TP_LOCALLAB_PRECAM_TOOLTIP;This 'Source Data Adjustments' modifies: a)the Dynamic Range using Log encoding; b) the tones of the image and primaries(simplified Abstract Profile) and also midtones, just before the Ciecam process. The values are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\n\n\n-Destination primaries: which allows you to change the destination primaries to restore or change image color (saturation), the color balance is 'significantly' preserved when the 'Working Profile' and the 'Destination primaries' are not too different (be careful), 'Working Profiles' are not modified.\nYou can also finely adapt the primaries and the illuminant (white-point).\nMoving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_QUAL_METHOD;Global quality !TP_LOCALLAB_QUANONEALL;Off @@ -4027,19 +4031,19 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_SIGFRA;Sigmoid Q !TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz -!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' and 'Sigmoid Q'.\nSigmoid Q: three sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold -!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the comboxbox selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. !TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance -!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance : ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. !TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. !TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev -!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the comboxbox selection'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. This last value stands for brightness (Q) should be a near the possible value 'Compression treshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). !TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic, when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the 'Jz' and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. !TP_LOCALLAB_SIGSLOPJCIE;Slope !TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments !TP_LOCALLAB_SIGWHITESCIE;Whites distribution @@ -4050,10 +4054,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) !TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope -!TP_LOCALLAB_SMOOTHCIE;Highlight attenuation +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation !TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode !TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene -!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma - Slope - based: choice (Standard and Advanced) allows you to simulate a "Tone mapping" using: a) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%); b) Viewing conditions: Mean luminance (Yb%).\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. !TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -4406,7 +4410,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) “Observer 10°†must be selected. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 @@ -4414,5 +4418,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_WBALANCE_SOLUX47;Solux 4700K (vendor) !TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) !TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 +!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 !TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 !TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. +!//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. +!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index 995f089db..34cd3bc5d 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -122,8 +122,6 @@ EXIFPANEL_RESET;Obnovit EXIFPANEL_RESETALL;Obnovit vÅ¡e EXIFPANEL_RESETALLHINT;Obnoví původní hodnoty u vÅ¡ech Å¡títků. EXIFPANEL_RESETHINT;Obnoví původní hodnoty u vybraných Å¡títků. -EXIFPANEL_SHOWALL;Zobrazit vÅ¡e -EXIFPANEL_SUBDIRECTORY;Podadresář EXPORT_BYPASS;Kroky zpracování pro pÅ™eskoÄení EXPORT_BYPASS_ALL;Vybrat / ZruÅ¡it výbÄ›r vÅ¡eho EXPORT_BYPASS_DEFRINGE;Vynechat odstranÄ›ní lemu @@ -1110,7 +1108,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Písmo Průzkumníka barev PREFERENCES_APPEARANCE_CROPMASKCOLOR;Barva masky oÅ™ezu PREFERENCES_APPEARANCE_MAINFONT;Hlavní písmo PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Barva vodítek navigátoru -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI režim PREFERENCES_APPEARANCE_THEME;Motiv PREFERENCES_APPLNEXTSTARTUP;vyžaduje restart aplikace PREFERENCES_AUTOMONPROFILE;Použít barevný profil hlavního monitoru z operaÄního systému @@ -1802,8 +1799,6 @@ TP_ICM_WORKING_TRC_SLOPE;Sklon TP_ICM_WORKING_TRC_TOOLTIP;Pouze pro vložené profily. TP_IMPULSEDENOISE_LABEL;Redukce impulzního Å¡umu TP_IMPULSEDENOISE_THRESH;Práh -TP_LABCURVE_AVOIDCOLORSHIFT;Zabránit posunu barev -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Napasovat barvy do gamutu barevného pracovního prostoru a aplikovat Munsellovu korekci. TP_LABCURVE_BRIGHTNESS;SvÄ›tlost TP_LABCURVE_CHROMATICITY;Barevnost TP_LABCURVE_CHROMA_TOOLTIP;Pro Äernobílé tónování nastavte barevnost na -100. @@ -2435,6 +2430,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !EXIFPANEL_VALUE_NOT_SHOWN;Not shown !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2483,7 +2479,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2793,7 +2789,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -3036,7 +3032,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -3123,17 +3119,89 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -3192,17 +3260,20 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3222,13 +3293,18 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3251,6 +3327,27 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending !SORT_BY_DATE;By Date @@ -3259,12 +3356,16 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3308,6 +3409,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3320,8 +3422,15 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3333,11 +3442,13 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3346,17 +3457,21 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 !TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 !TP_ICM_WORKING_TRC_LIN;Linear g=1 !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ACTIVSPOT;Enable Spot !TP_LOCALLAB_ADJ;Equalizer Color @@ -3364,9 +3479,9 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3409,9 +3524,12 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3451,6 +3569,12 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3466,8 +3590,9 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3475,7 +3600,10 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3490,7 +3618,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3499,13 +3627,14 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3525,6 +3654,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3533,6 +3663,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3548,9 +3679,10 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3559,11 +3691,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3585,7 +3717,8 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3681,7 +3814,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3726,8 +3859,10 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3735,7 +3870,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3748,6 +3883,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3817,7 +3953,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3853,6 +3989,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3900,10 +4037,15 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3948,10 +4090,11 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3972,7 +4115,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -4018,17 +4161,41 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -4050,13 +4217,14 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -4088,11 +4256,12 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4283,7 +4452,7 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index e42f0bc83..1285895a4 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -15,11 +15,11 @@ CURVEEDITOR_AXIS_OUT;O: CURVEEDITOR_AXIS_RIGHT_TAN;RT: CURVEEDITOR_CATMULLROM;Fleksibel CURVEEDITOR_CURVE;Kurve +CURVEEDITOR_CURVES;Kurver CURVEEDITOR_CUSTOM;Standard CURVEEDITOR_DARKS;Mørke CURVEEDITOR_EDITPOINT_HINT;Aktivér redigering af node ind/ud værdier.\n\nHøjreklik pÃ¥ en node for at vælge den.\nHøjreklik pÃ¥ et tomt omrÃ¥de for at fravælge noden. CURVEEDITOR_HIGHLIGHTS;Højlys -CURVEEDITOR_Kurver;Kurver CURVEEDITOR_LIGHTS;Lyse partier CURVEEDITOR_LINEAR;Lineær CURVEEDITOR_LOADDLGLABEL;Indlæs kurve... @@ -75,8 +75,6 @@ EXIFPANEL_RESET;Nulstil EXIFPANEL_RESETALL;Nulstil Alt EXIFPANEL_RESETALLHINT;Nulstil alle mærkater til deres oprindelige værdier. EXIFPANEL_RESETHINT;Nulstil alle valgte mærkater til deres oprindelige værdier. -EXIFPANEL_SHOWALL;Vis alt -EXIFPANEL_SUBDIRECTORY;Undermappe EXPORT_BYPASS;Redigeringstrin der skal fravælges EXPORT_BYPASS_ALL;Vælg / fravælg alt EXPORT_BYPASS_DEFRINGE;Spring over Defringe @@ -761,7 +759,7 @@ HISTORY_MSG_SH_COLORSPACE;Farverum HISTORY_MSG_SOFTLIGHT_ENABLED;Blødt lys HISTORY_MSG_SOFTLIGHT_STRENGTH;Blødt lys - Styrke HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anker -HISTORY_MSG_TRANS_Method;Geometri - Metode +HISTORY_MSG_TRANS_METHOD;Geometri - Metode HISTORY_NEWSNAPSHOT;Tilføj HISTORY_NEWSNAPSHOT_TOOLTIP;Genvej: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1028,7 +1026,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Farvevælgers skrifttype PREFERENCES_APPEARANCE_CROPMASKCOLOR;Beskæringsmaskens farve PREFERENCES_APPEARANCE_MAINFONT;Hovedskrifttype PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigeringsguide farve -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI tilstand PREFERENCES_APPEARANCE_THEME;Tema PREFERENCES_APPLNEXTSTARTUP;genstart nødvendig PREFERENCES_AUTOMONPROFILE;Brug operativsystemets hovedskærmfarveprofil @@ -1709,8 +1706,6 @@ TP_ICM_WORKING_TRC_SLOPE;Hældning TP_ICM_WORKING_TRC_TOOLTIP;Kun til indbyggede profiler. TP_IMPULSEDENOISE_LABEL;Impuls støjreduktion TP_IMPULSEDENOISE_THRESH;Tærskel -TP_LABCURVE_AVOIDCOLORSHIFT;UndgÃ¥ farveforskydning -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Tilpas farver til farveskalaen af arbejdsfarverum og tilføj Munsell korrektion. TP_LABCURVE_BRIGHTNESS;Lyshed TP_LABCURVE_CHROMATICITY;Kromaticitet TP_LABCURVE_CHROMA_TOOLTIP;Indstil kromacitet til -100 for at anvende S/H toning. @@ -2279,7 +2274,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!CURVEEDITOR_CURVES;Curves !ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 !EXIFFILTER_PATH;File path !EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags @@ -2288,6 +2282,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !EXIFPANEL_VALUE_NOT_SHOWN;Not shown !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2336,7 +2331,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2646,7 +2641,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2889,7 +2884,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2981,18 +2976,90 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera !HISTORY_MSG_PERSP_CAM_FL;Perspective - Camera @@ -3021,7 +3088,6 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot !HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization !HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map -!HISTORY_MSG_TRANS_METHOD;Geometry - Method !HISTORY_MSG_WAVBALCHROM;Equalizer chrominance !HISTORY_MSG_WAVBALLUM;Equalizer luminance !HISTORY_MSG_WAVBL;Blur levels @@ -3080,18 +3146,21 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3111,13 +3180,18 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3140,6 +3214,27 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending !SORT_BY_DATE;By Date @@ -3148,12 +3243,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3208,6 +3307,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3220,8 +3320,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3233,11 +3340,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3246,11 +3355,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3258,6 +3370,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_ICM_WORKING_TRC_LIN;Linear g=1 !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 !TP_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ACTIVSPOT;Enable Spot !TP_LOCALLAB_ADJ;Equalizer Color @@ -3265,9 +3378,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3310,9 +3423,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3352,6 +3468,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3367,8 +3489,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3376,7 +3499,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3391,7 +3517,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3400,13 +3526,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3426,6 +3553,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3434,6 +3562,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3449,9 +3578,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3460,11 +3590,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3486,7 +3616,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3582,7 +3713,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3627,8 +3758,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3636,7 +3769,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3649,6 +3782,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3718,7 +3852,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3754,6 +3888,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3801,10 +3936,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3849,10 +3989,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3873,7 +4014,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3919,17 +4060,41 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3951,13 +4116,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3989,11 +4155,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4193,7 +4360,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4236,7 +4403,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Ud\nGenvej: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 677efd8e0..9283ce0e2 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -1906,7 +1906,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Schriftart Farbwähler PREFERENCES_APPEARANCE_CROPMASKCOLOR;Farbe/Transparenz für Schnittmaske PREFERENCES_APPEARANCE_MAINFONT;Schriftart: PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Farbe der Navigationshilfe -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI-Modus PREFERENCES_APPEARANCE_THEME;Oberflächendesign PREFERENCES_APPLNEXTSTARTUP;erfordert Neustart PREFERENCES_AUTOMONPROFILE;Automatisch das für den aktuellen Monitor festgelegte Profil verwenden @@ -4305,6 +4304,78 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - !!!!!!!!!!!!!!!!!!!!!!!!! !ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. +!HISTORY_MSG_ICM_CAT;Matrix adaptation +!HISTORY_MSG_ICM_MIDTCIE;Midtones +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_WBITC_DELTA;Itcwb Delta green !HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student @@ -4317,6 +4388,14 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - !HISTORY_MSG_WBITC_SIZE;Itcwb Size !HISTORY_MSG_WBITC_SORTED;Itcwb ponderated !HISTORY_MSG_WBITC_THRES;Itcwb Threshold +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_WBAFORC;Forces Extra algoritm !PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) !PREFERENCES_WBANOPURP;No purple color used @@ -4324,6 +4403,99 @@ ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - !PREFERENCES_WBAPRECIS;Precision algorithm - scale used !PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color !PREFERENCES_WBASORT;Sort in chroma order instead of histogram +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y +!TC_PRIM_REFI;Refine colors (white-point) +!TP_ICM_BW;Black and White +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale +!TP_ICM_WORKING_ILLU_E;E +!TP_ICM_WORKING_NON;None +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None +!TP_LOCALLAB_COLORFRAME;Dominant color +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. +!TP_LOCALLAB_DEHAZE_BLACK;Black +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_FATSAT;Saturation control +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings +!TP_LOCALLAB_MIDTCIE;Midtones +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant +!TP_LOCALLAB_SATCIE;Saturation control +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGGAMJCIE;Gamma +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing +!TP_LOCALLAB_STRENGTHCIELOG;Strength +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used !TP_WBALANCE_ITCWB_SIZE;Size of ref. color compare to histogram diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index 5d22fa61f..b96535923 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -80,6 +80,11 @@ HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Colour correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Colour correction HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Film negative colour space HISTORY_MSG_HLBL;Colour propagation - blur +HISTORY_MSG_ICM_REFI;Refinement Colours +HISTORY_MSG_ICM_SHIFTX;Refinement Colours - Shift x +HISTORY_MSG_ICM_SHIFTY;Refinement Colours - Shift y +HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colours +HISTORY_MSG_LOCAL_FEATHERCOL;Local - Colour Gradient feather HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Colour Shift HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid colour shift HISTORY_MSG_SH_COLORSPACE;S/H - Colourspace @@ -107,6 +112,7 @@ PREFERENCES_MENUGROUPLABEL;Group 'Colour label' PREFERENCES_MONPROFILE;Default colour profile PREFERENCES_PRTPROFILE;Colour profile PREFERENCES_TAB_COLORMGR;Colour Management +PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and colour from/to XMP sidecars PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colourimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. PREFERENCES_WBANOPURP;No purple colour used PREFERENCES_WBAPATCH;Number maximum of colours used in picture @@ -114,6 +120,8 @@ PREFERENCES_WBASIZEREF;Size of reference colour compare to size of histogram col SOFTPROOF_GAMUTCHECK_TOOLTIP;Highlight pixels with out-of-gamut colours with respect to:\n- the printer profile, if one is set and soft-proofing is enabled,\n- the output profile, if a printer profile is not set and soft-proofing is enabled,\n- the monitor profile, if soft-proofing is disabled. SOFTPROOF_TOOLTIP;Soft-proofing simulates the appearance of the image:\n- when printed, if a printer profile is set in Preferences > Colour Management,\n- when viewed on a display that uses the current output profile, if a printer profile is not set. SORT_BY_LABEL;By Colour Label +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colours", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate colour toning.\nBe careful not to go outside the CIE xy diagram. +TC_PRIM_REFI;Refine colours (white-point) TOOLBAR_TOOLTIP_COLORPICKER;Lockable Colour Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. TOOLBAR_TOOLTIP_STRAIGHTEN;Straighten / fine rotation.\nShortcut: s\n\nIndicate the vertical or horizontal by drawing a guide line over the image. Angle of rotation will be shown next to the guide line. Centre of rotation is the geometrical centre of the image. TP_BWMIX_CC_ENABLED;Adjust complementary colour @@ -168,13 +176,15 @@ TP_HLREC_COLOR;Colour Propagation TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input colour profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple colour matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC colour profile file for the camera. -TP_ICM_INPUTEMBEDDED_TOOLTIP;Use colour profile embedded in non-raw files. +TP_ICM_INPUTEMBEDDED_TOOLTIP;Use the colour profile embedded in the file.\nIf unavailable, fall back to Camera standard TP_ICM_INPUTNONE_TOOLTIP;Use no input colour profile at all.\nUse only in special cases. TP_ICM_LABEL;Colour Management TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different colour mode for an image, you permanently change the colour values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic colour adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). +TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image colour (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. +TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image colour (saturation). The colour balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. TP_LOCALLAB_ADJ;Equalizer Colour TP_LOCALLAB_AVOID;Avoid colour shift -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colours into gamut of the working colour space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Colour Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colourimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colourimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colourimetric, Munsell is then applied. +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colours into gamut of the working colour space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colourimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colourimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colourimetric. Munsell is then applied. The result is not the same as Lab. TP_LOCALLAB_BLWH_TOOLTIP;Force colour components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. TP_LOCALLAB_CENTER_X;Centre X TP_LOCALLAB_CENTER_Y;Centre Y @@ -185,6 +195,7 @@ TP_LOCALLAB_CIE_TOOLNAME;Colour appearance (Cam16 & JzCzHz) TP_LOCALLAB_COFR;Colour & Light TP_LOCALLAB_COLORDE;ΔE preview colour - intensity TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue colour preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +TP_LOCALLAB_COLORFRAME;Dominant colour TP_LOCALLAB_COLORSCOPE;Scope (colour tools) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Colour and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. TP_LOCALLAB_COLOR_CIE;Colour curve @@ -199,7 +210,7 @@ TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influen TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colours. TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust colour, lightness, contrast and correct small defects such as red-eye, sensor dust etc. TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low colour gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Colour and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Colour and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a colour and luminance background (fewer possibilties). TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Colour, Luminosity are concerned by Merge background (ΔE). TP_LOCALLAB_GRIDMETH_TOOLTIP;Colour toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Colour toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. @@ -245,6 +256,9 @@ TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding se TP_LOCALLAB_MERCOL;Colour TP_LOCALLAB_MERFOR;Colour Dodge TP_LOCALLAB_MERTHI;Colour Burn +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant colour. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate colour toning. +TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant colour. This action modifies the purity. +TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image colour (saturation). The colour balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Colour and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Colour and Light, Wavelet, Cam16, etc.). TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Colour and Light image with respect to the original image. TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colourfulness sliders. @@ -252,8 +266,8 @@ TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colours to be excluded. TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the centre of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colours similar to those in the centre of the spot.\nHigh values let the tool act on a wider range of colours. TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular colour). -TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Colour & Light). -TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Colour & Light). +TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Colour & Light). +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Colour & Light). TP_LOCALLAB_WARM;Warm/Cool & Colour artifacts TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the colour temperature of the selected area warmer or cooler.\nIt can also reduce colour artifacts in some cases. TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to centre,\n100 = to centre. @@ -284,11 +298,12 @@ TP_WBALANCE_ITCWB_SIZEPATCH;Size of colour patch TP_WBALANCE_ITCWB_THRES;Colours used in picture (preset) TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colourchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colours), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colours that can be used in internal to the algorithm will be more important. TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colours.\n'Camera XYZ matrix' - uses the matrix directly derived from Colour Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. -TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colours. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colours due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +TP_WBALANCE_OBSERVER10_TOOLTIP;The colour management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colours. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a colour drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. TP_WBALANCE_PATCHLABEL;Read colours:%1 Patch: Chroma:%2 Size=%3 TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. //TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colours are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colours. + !!!!!!!!!!!!!!!!!!!!!!!!! ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! @@ -491,6 +506,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: Shift-5 !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t !FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: Shift-0 !FILEBROWSER_THUMBSIZE;Thumbnail size @@ -1021,7 +1037,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness !HISTORY_MSG_519;Local - Contrast @@ -1295,7 +1311,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !HISTORY_MSG_827;Local - Exp gradient angle !HISTORY_MSG_828;Local - SH gradient strength !HISTORY_MSG_829;Local - SH gradient angle -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle !HISTORY_MSG_837;Local - Vib gradient strength C @@ -1526,7 +1542,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -1635,16 +1651,20 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -1657,6 +1677,69 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -1902,7 +1985,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !MAIN_TAB_FILTER; Filter !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_IPTC;IPTC -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TAB_METADATA;Metadata !MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m @@ -1919,7 +2002,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !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_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i !MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l !MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l @@ -1981,8 +2064,8 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PARTIALPASTE_LENSGROUP;Lens Related Settings !PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_METAGROUP;Metadata settings !PARTIALPASTE_PCVIGNETTE;Vignette filter @@ -2024,7 +2107,6 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_ADD;Add !PREFERENCES_APPEARANCE;Appearance !PREFERENCES_APPEARANCE_MAINFONT;Main font -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_APPEARANCE_THEME;Theme !PREFERENCES_APPLNEXTSTARTUP;restart required !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit @@ -2033,6 +2115,9 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_BEHADDALLHINT;Set all parameters to the Add mode.\nAdjustments of parameters in the batch tool panel will be deltas to the stored values. !PREFERENCES_BEHSETALL;All to 'Set' !PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR;Clear !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: @@ -2055,7 +2140,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2131,6 +2216,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' !PREFERENCES_MENUGROUPPROFILEOPERATIONS;Group 'Processing profile operations' @@ -2178,6 +2264,8 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_PROPERTY;Property !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PSPATH;Adobe Photoshop installation directory +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now @@ -2190,7 +2278,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_SHOWDATETIME;Show date and time !PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips !PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows !PREFERENCES_SINGLETAB;Single Editor Tab Mode !PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs @@ -2198,6 +2286,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done !PREFERENCES_SND_QUEUEDONE;Queue processing done !PREFERENCES_SND_THRESHOLDSECS;After seconds +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_STARTUPIMDIR;Image Directory at Startup !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules @@ -2280,10 +2369,31 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !QUEUE_AUTOSTART;Auto-start !QUEUE_AUTOSTART_TOOLTIP;Start processing automatically when a new job arrives. !QUEUE_DESTFILENAME;Path and file name +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here !QUEUE_FORMAT_TITLE;File Format !QUEUE_LOCATION_FOLDER;Save to folder !QUEUE_LOCATION_TEMPLATE;Use template -!QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = photo1\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 photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p2/converted/%d1/%f +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +!QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. !QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAMPLEFORMAT_0;Unknown data format @@ -2319,6 +2429,8 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx @@ -2724,6 +2836,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT;Illuminant !TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -2734,7 +2847,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_ICM_INPUTCAMERAICC;Auto-matched camera profile !TP_ICM_INPUTCUSTOM;Custom !TP_ICM_INPUTDLGLABEL;Select Input DCP/ICC Profile... -!TP_ICM_INPUTEMBEDDED;Use embedded, if possible +!TP_ICM_INPUTEMBEDDED;Use embedded !TP_ICM_INPUTNONE;No profile !TP_ICM_INPUTPROFILE;Input Profile !TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 @@ -2754,9 +2867,15 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_ICM_TONECURVE;Tone curve !TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. !TP_ICM_WORKINGPROFILE;Working Profile +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2768,11 +2887,13 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2781,7 +2902,9 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 @@ -2843,6 +2966,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile @@ -2861,7 +2985,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2903,9 +3027,12 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2940,6 +3067,12 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. !TP_LOCALLAB_CLARICRES;Merge chroma @@ -2952,11 +3085,14 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_CLARITYML;Clarity !TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. !TP_LOCALLAB_CLIPTM;Clip restored data (gain) -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -2969,7 +3105,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_CSTHRESHOLDBLUR;Wavelet level selection !TP_LOCALLAB_CURV;Lightness - Contrast - Chrominance 'Super' !TP_LOCALLAB_CURVCURR;Normal -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. !TP_LOCALLAB_CURVES_CIE;Tone curve @@ -2977,12 +3113,13 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3000,6 +3137,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3008,6 +3146,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3022,15 +3161,16 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_EV_VIS_ALL;Show all !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter @@ -3054,7 +3194,8 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3147,7 +3288,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 !TP_LOCALLAB_LABSTRUM;Structure Mask @@ -3190,12 +3331,14 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCONQL;Contrast (Q) !TP_LOCALLAB_LOGCONTHRES;Contrast threshold (J & Q) !TP_LOCALLAB_LOGCONTL;Contrast (J) -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3206,6 +3349,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. @@ -3245,7 +3389,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3278,6 +3422,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3325,10 +3470,12 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3371,9 +3518,10 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3391,7 +3539,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3437,17 +3585,41 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3468,6 +3640,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_STRENG;Strength !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure @@ -3509,6 +3682,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4142,7 +4316,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_WBALANCE_AUTO;Auto !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_CAMERA;Camera !TP_WBALANCE_CLOUDY;Cloudy !TP_WBALANCE_CUSTOM;Custom diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 4cd01622a..1e7630225 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -1,4 +1,5 @@ + !!!!!!!!!!!!!!!!!!!!!!!!! ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! @@ -204,6 +205,7 @@ !FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: Shift-5 !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 !FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: Shift-0 @@ -758,7 +760,7 @@ !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -1068,7 +1070,7 @@ !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -1311,7 +1313,7 @@ !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -1427,16 +1429,23 @@ !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -1449,7 +1458,72 @@ !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -1699,7 +1773,7 @@ !MAIN_TAB_FILTER; Filter !MAIN_TAB_INSPECT; Inspect !MAIN_TAB_IPTC;IPTC -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TAB_METADATA;Metadata !MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m @@ -1720,7 +1794,7 @@ !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_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i !MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l !MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l @@ -1786,8 +1860,8 @@ !PARTIALPASTE_LENSGROUP;Lens Related Settings !PARTIALPASTE_LENSPROFILE;Profiled lens correction !PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_METAGROUP;Metadata settings !PARTIALPASTE_PCVIGNETTE;Vignette filter @@ -1834,7 +1908,6 @@ !PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color !PREFERENCES_APPEARANCE_MAINFONT;Main font !PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator guide color -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_APPEARANCE_THEME;Theme !PREFERENCES_APPLNEXTSTARTUP;restart required !PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile @@ -1845,6 +1918,9 @@ !PREFERENCES_BEHAVIOR;Behavior !PREFERENCES_BEHSETALL;All to 'Set' !PREFERENCES_BEHSETALLHINT;Set all parameters to the Set mode.\nAdjustments of parameters in the batch tool panel will be absolute, the actual values will be displayed. +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR;Clear !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: @@ -1867,7 +1943,7 @@ !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -1946,6 +2022,7 @@ !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' !PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' !PREFERENCES_MENUGROUPLABEL;Group 'Color label' @@ -1996,6 +2073,8 @@ !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile !PREFERENCES_PSPATH;Adobe Photoshop installation directory +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now @@ -2008,7 +2087,7 @@ !PREFERENCES_SHOWDATETIME;Show date and time !PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips !PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows !PREFERENCES_SINGLETAB;Single Editor Tab Mode !PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs @@ -2016,6 +2095,7 @@ !PREFERENCES_SND_LNGEDITPROCDONE;Editor processing done !PREFERENCES_SND_QUEUEDONE;Queue processing done !PREFERENCES_SND_THRESHOLDSECS;After seconds +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_STARTUPIMDIR;Image Directory at Startup !PREFERENCES_TAB_BROWSER;File Browser !PREFERENCES_TAB_COLORMGR;Color Management @@ -2029,6 +2109,7 @@ !PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2103,10 +2184,31 @@ !QUEUE_AUTOSTART;Auto-start !QUEUE_AUTOSTART_TOOLTIP;Start processing automatically when a new job arrives. !QUEUE_DESTFILENAME;Path and file name +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here !QUEUE_FORMAT_TITLE;File Format !QUEUE_LOCATION_FOLDER;Save to folder !QUEUE_LOCATION_TEMPLATE;Use template -!QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on the source photo's location, rank, trash status or position in the queue.\n\nUsing the following pathname as an example:\n/home/tom/photos/2010-10-31/photo1.raw\nthe meaning of the formatting strings follows:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = photo1\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 photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used.\n\n%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'.\n\nIf you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p2/converted/%d1/%f +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +!QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. !QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAMPLEFORMAT_0;Unknown data format @@ -2145,12 +2247,16 @@ !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !THRESHOLDSELECTOR_B;Bottom !THRESHOLDSELECTOR_BL;Bottom-left !THRESHOLDSELECTOR_BR;Bottom-right @@ -2601,6 +2707,7 @@ !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT;Illuminant !TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -2614,8 +2721,8 @@ !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_INPUTEMBEDDED;Use embedded +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use the color profile embedded in the file.\nIf unavailable, fall back to Camera standard !TP_ICM_INPUTNONE;No profile !TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. !TP_ICM_INPUTPROFILE;Input Profile @@ -2638,9 +2745,16 @@ !TP_ICM_TONECURVE;Tone curve !TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. !TP_ICM_WORKINGPROFILE;Working Profile +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2652,11 +2766,13 @@ !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2665,11 +2781,14 @@ !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2727,6 +2846,7 @@ !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile @@ -2746,9 +2866,9 @@ !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2791,9 +2911,12 @@ !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2833,6 +2956,12 @@ !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -2848,8 +2977,9 @@ !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -2857,7 +2987,10 @@ !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -2872,7 +3005,7 @@ !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -2881,13 +3014,14 @@ !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -2907,6 +3041,7 @@ !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -2915,6 +3050,7 @@ !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -2930,9 +3066,10 @@ !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -2941,11 +3078,11 @@ !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -2967,7 +3104,8 @@ !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3063,7 +3201,7 @@ !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3108,8 +3246,10 @@ !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3117,7 +3257,7 @@ !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3130,6 +3270,7 @@ !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3199,7 +3340,7 @@ !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3235,6 +3376,7 @@ !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3282,10 +3424,15 @@ !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3330,10 +3477,11 @@ !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3354,7 +3502,7 @@ !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3400,17 +3548,41 @@ !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3432,13 +3604,14 @@ !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3470,11 +3643,12 @@ !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4128,7 +4302,7 @@ !TP_WBALANCE_AUTO;Auto !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_CAMERA;Camera !TP_WBALANCE_CLOUDY;Cloudy !TP_WBALANCE_CUSTOM;Custom @@ -4204,7 +4378,7 @@ !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Espanol (Castellano) b/rtdata/languages/Espanol (Castellano) index 9f9cc48bf..e554df27d 100644 --- a/rtdata/languages/Espanol (Castellano) +++ b/rtdata/languages/Espanol (Castellano) @@ -76,8 +76,6 @@ EXIFPANEL_RESET;Restablecer EXIFPANEL_RESETALL;Restablecer todo EXIFPANEL_RESETALLHINT;Restablece todos los atributos a los valores predeterminados. EXIFPANEL_RESETHINT;Restablece los atributos seleccionados a los valores predeterminados. -EXIFPANEL_SHOWALL;Mostrar todo -EXIFPANEL_SUBDIRECTORY;Subdirectorio EXPORT_BYPASS;Pasos del revelado que se ignorarán EXPORT_BYPASS_ALL;Seleccionar / Deseleccionar todo EXPORT_BYPASS_DEFRINGE;Ignorar «Quitar borde púrpura» @@ -1795,7 +1793,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Tipo de letra del muestreador de color PREFERENCES_APPEARANCE_CROPMASKCOLOR;Color de la máscara de recorte PREFERENCES_APPEARANCE_MAINFONT;Tipo de letra principal PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Color de la guía del navegador -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Modo pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Tema PREFERENCES_APPLNEXTSTARTUP;Se necesita reiniciar PREFERENCES_AUTOMONPROFILE;Usar el perfil de color del monitor principal del sistema operativo @@ -2589,8 +2586,6 @@ TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 TP_ICM_WORKING_TRC_TOOLTIP;Aquí se selecciona uno de los perfiles incorporados en RawTherapee, que será el que utilizará el motor del programa. TP_IMPULSEDENOISE_LABEL;Reducción de ruido impulsivo TP_IMPULSEDENOISE_THRESH;Umbral -TP_LABCURVE_AVOIDCOLORSHIFT;Evitar la deriva de colores -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Encaja los colores en el rango del espacio de color de trabajo y aplica la corrección de Munsell. TP_LABCURVE_BRIGHTNESS;Luminosidad TP_LABCURVE_CHROMATICITY;Cromaticidad TP_LABCURVE_CHROMA_TOOLTIP;Para aplicar virado de color en B/N, se ajusta la cromaticidad a -100. @@ -4080,15 +4075,88 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !EXIFPANEL_BASIC_GROUP;Basic !EXIFPANEL_VALUE_NOT_SHOWN;Not shown !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_OTHER;Other !HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness !HISTORY_MSG_FF_FROMMETADATA;Flat-Field - From Metadata !HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell !HISTORY_MSG_HLTH;Inpaint opposed - gain threshold +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_GAMUT;Gamut control +!HISTORY_MSG_ICM_MIDTCIE;Midtones +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_TONE_EQUALIZER_BANDS;Tone equalizer - Bands !HISTORY_MSG_TONE_EQUALIZER_ENABLED;Tone equalizer @@ -4114,6 +4182,9 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !HISTORY_MSG_WBITC_THRES;Itcwb Threshold !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application !PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable @@ -4124,12 +4195,17 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -4151,6 +4227,27 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending !SORT_BY_DATE;By Date @@ -4159,6 +4256,10 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y +!TC_PRIM_REFI;Refine colors (white-point) !TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. !TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness @@ -4168,13 +4269,45 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !TP_FLATFIELD_FROMMETADATA;From Metadata !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_GAMUT;Gamut control +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale +!TP_ICM_WORKING_ILLU_E;E +!TP_ICM_WORKING_NON;None +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 !TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None +!TP_LOCALLAB_COLORFRAME;Dominant color +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance !TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_FATSAT;Saturation control +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_GAMUTLABRELA;Lab !TP_LOCALLAB_GAMUTMUNSELL;Munsell only !TP_LOCALLAB_GAMUTNON;None @@ -4182,9 +4315,45 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative !TP_LOCALLAB_LCLABELS;Residual noise levels !TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 !TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 +!TP_LOCALLAB_MIDTCIE;Midtones +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant +!TP_LOCALLAB_SATCIE;Saturation control +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGGAMJCIE;Gamma +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_TE_PIVOT;Pivot (Ev) +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_TONE_EQUALIZER_BANDS;Bands !TP_TONE_EQUALIZER_BAND_0;Blacks !TP_TONE_EQUALIZER_BAND_1;Shadows @@ -4237,7 +4406,7 @@ ZOOMPANEL_ZOOMOUT;Alejar\nAtajo de teclado: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Espanol (Latin America) b/rtdata/languages/Espanol (Latin America) index 816b237c6..f0e10ceb1 100644 --- a/rtdata/languages/Espanol (Latin America) +++ b/rtdata/languages/Espanol (Latin America) @@ -136,8 +136,6 @@ EXIFPANEL_RESET;Restablecer EXIFPANEL_RESETALL;Restablecer todo EXIFPANEL_RESETALLHINT;Restablecer todos los atributos a los valores predeterminados EXIFPANEL_RESETHINT;Restablecer atributos seleccionados a los valores predeterminados -EXIFPANEL_SHOWALL;Mostrar todo -EXIFPANEL_SUBDIRECTORY;Subcarpeta EXPORT_BYPASS;Procesamiento de pasos a bypass EXPORT_BYPASS_ALL;Seleccionar / Deseleccionar todo EXPORT_BYPASS_DEFRINGE;Saltar Quitar borde púrpura @@ -889,19 +887,13 @@ IPTCPANEL_TITLE;Título IPTCPANEL_TITLEHINT;Ingrese un nombre corto legible y humano para la imagen, este puede ser el nombre del archivo. IPTCPANEL_TRANSREFERENCE;Identificación del trabajo IPTCPANEL_TRANSREFERENCEHINT;Ingrese un número o identificador necesario para el control o seguimiento del flujo de trabajo. -LENSPROFILE_CORRECTION_AUTOMATCH;Parámetros de corrección auto-emparejados -LENSPROFILE_CORRECTION_LCPFILE;LCP archivo -LENSPROFILE_CORRECTION_MANUAL;Parámetros de corrección manual -LENSPROFILE_LENS_WARNING;Advertencia: el factor de recorte utilizado para el perfilado de la lente es mayor que el factor de recorte de la cámara, los resultados pueden ser incorrectos. MAIN_BUTTON_FULLSCREEN;Pantalla completa MAIN_BUTTON_ICCPROFCREATOR;Creador de perfiles ICC MAIN_BUTTON_NAVNEXT_TOOLTIP;Navegar hasta la imagen Siguiente a la que está abierta en el editor:\nShift-F4\n\nPara navegar hasta la imagen Siguiente a aquella cuya miniatura está seleccionada en el Explorador de Archivos:\nF4 MAIN_BUTTON_NAVPREV_TOOLTIP;Navegar hasta la imagen Anterior a la que está abierta en el editor:\nShift-F3\n\nPara navegar hasta la imagen Anterior a aquella cuya miniatura está seleccionada en el Explorador de Archivos:\nF3 MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizar el Navegador de Archivos con el Editor para mostrar la miniatura de la imagen actualmente abierta y quitar los filtros en el Navegador de Archivos:\nx\n\nPara hacer lo dicho anteriormente, pero sin quitar los filtros en el Navegador de Archivos:\ny\n(Note que la miniatura del archivo abierto no será mostrada si los filtros la excluyen). MAIN_BUTTON_PREFERENCES;Preferencias -MAIN_BUTTON_PUTTOQUEUE;Poner en la cola MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Añadir imagen actual a la cola de procesamiento.\nTecla de Atajo: Ctrl+B -MAIN_BUTTON_SAVE;Guardar imagen MAIN_BUTTON_SAVE_TOOLTIP;Guardar imagen actual.\nTecla de Atajo: Ctrl+S MAIN_BUTTON_SENDTOEDITOR;Abrir con editor MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Editar imagen actual en editor externo.\nTecla de Atajo: Ctrl+E @@ -1151,7 +1143,6 @@ PREFERENCES_INTENT_SATURATION;Saturación PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostrar miniatura JPEG incrustada si foto Raw no se ha editado PREFERENCES_LANG;Idioma PREFERENCES_LANGAUTODETECT;Usar idioma del sistema -PREFERENCES_MAX;Maxi (baldoza) PREFERENCES_MAXRECENTFOLDERS;Número máximo de carpetas recientes PREFERENCES_MENUGROUPEXTPROGS;Grupo "Abrir con" PREFERENCES_MENUGROUPFILEOPERATIONS;Grupo "Operaciones de archivo" @@ -1729,8 +1720,6 @@ TP_ICM_WORKING_TRC_SLOPE;Bajar TP_ICM_WORKING_TRC_TOOLTIP;Solo para perfiles incorporados. TP_IMPULSEDENOISE_LABEL;Impulsar Reducc. ruido TP_IMPULSEDENOISE_THRESH;Umbral -TP_LABCURVE_AVOIDCOLORSHIFT;Evitar desplazamiento de colores -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Encaja los colores dentro de la gamma del espacio de color de trabajo y aplica la corrección de Munsell TP_LABCURVE_BRIGHTNESS;Brillo TP_LABCURVE_CHROMATICITY;Cromaticidad (Saturación) TP_LABCURVE_CHROMA_TOOLTIP;Para aplicar mapeo tonal en blanco y negro, establezca la Cromaticidad a -100 @@ -1769,7 +1758,9 @@ TP_LABCURVE_RSTPRO_TOOLTIP;Puede usarse con el deslizador Cromaticidad y con la TP_LENSGEOM_AUTOCROP;Auto recorte TP_LENSGEOM_FILL;Auto relleno TP_LENSGEOM_LABEL;Lente / Geometría +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Parámetros de corrección auto-emparejados TP_LENSPROFILE_CORRECTION_LCPFILE;LCP archivo +TP_LENSPROFILE_CORRECTION_MANUAL;Parámetros de corrección manual TP_LENSPROFILE_LABEL;Perfil de corrección de lente TP_LENSPROFILE_LENS_WARNING;Advertencia: el factor de recorte utilizado para el perfilado de la lente es mayor que el factor de recorte de la cámara, los resultados pueden ser incorrectos. TP_LENSPROFILE_USE_CA;Aberración cromática @@ -1881,7 +1872,6 @@ TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Use la mediana de todos los cuadros en lugar del TP_RAW_PIXELSHIFTMM_AUTO;Automático TP_RAW_PIXELSHIFTMM_CUSTOM;Personalizado TP_RAW_PIXELSHIFTMM_OFF;Apagado -TP_RAW_PIXELSHIFTMOTION;Nivel de detección de movimiento (en desuso) TP_RAW_PIXELSHIFTMOTIONMETHOD;Corrección del movimiento TP_RAW_PIXELSHIFTNONGREENCROSS;Compruebe los canales rojos/azules para el movimiento TP_RAW_PIXELSHIFTSHOWMOTION;Mostrar máscara de movimiento @@ -2209,7 +2199,6 @@ TP_WAVELET_SKIN;Enfocar piel/proteción TP_WAVELET_SKIN_TOOLTIP;A (menos)-100 los tonos de piel están afectados. \nA 0 todos los tonos se tratan por igual. \nA +100 los tonos de piel están protegidos, mientras que todos los demás tonos están afectados. TP_WAVELET_SKY;protección del cielo al enfocar TP_WAVELET_SKY_TOOLTIP;A -100 se apuntan los tonos del cielo. \nEn 0 todos los tonos se tratan por igual. \nEn +100 los tonos del cielo están protegidos, mientras que todos los demás tonos están afectados. -TP_WAVELET_SKY_TOOLTIPEn (menos)-100se afecta a los tonos del cielo. \nEn 0 todos los tonos se tratan por igual. \nen +100 los tonos del cielo están protegidos, mientras que todos los demás tonos están afectados. TP_WAVELET_STREN;Fuerza TP_WAVELET_STRENGTH;Fuerza TP_WAVELET_SUPE;Extra @@ -2305,6 +2294,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2355,7 +2345,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2665,7 +2655,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2908,7 +2898,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -3002,18 +2992,90 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -3112,16 +3174,18 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !MAIN_FRAME_PLACES_DEL;Remove !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CHUNKSIZES;Tiles per thread !PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE demosaic @@ -3131,7 +3195,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PREFERENCES_CHUNKSIZE_RGB;RGB processing !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3151,6 +3215,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -3158,8 +3223,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional !PREFERENCES_PERFORMANCE_MEASURE;Measure !PREFERENCES_PERFORMANCE_MEASURE_HINT;Logs processing times in console -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3188,6 +3257,27 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending @@ -3197,12 +3287,16 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3264,6 +3358,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3276,8 +3371,15 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3289,11 +3391,13 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3302,11 +3406,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3315,8 +3422,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 !TP_LENSGEOM_LIN;Linear !TP_LENSGEOM_LOG;Logarithmic -!TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected -!TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct @@ -3327,9 +3433,9 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3372,9 +3478,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3414,6 +3523,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3429,8 +3544,9 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3438,7 +3554,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3453,7 +3572,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3462,13 +3581,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3488,6 +3608,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3496,6 +3617,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3511,9 +3633,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3522,11 +3645,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3548,7 +3671,8 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3644,7 +3768,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3689,8 +3813,10 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3698,7 +3824,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3711,6 +3837,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3780,7 +3907,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3816,6 +3943,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3863,10 +3991,15 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3911,10 +4044,11 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3935,7 +4069,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3981,17 +4115,41 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -4013,13 +4171,14 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -4051,11 +4210,12 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4262,7 +4422,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4305,7 +4465,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nTecla de Atajo: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 53e478f78..d0b926bb2 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -75,8 +75,6 @@ EXIFPANEL_RESET;Réinitialiser EXIFPANEL_RESETALL;Réinitialiser tout EXIFPANEL_RESETALLHINT;Réinitialise tous les tags à leur valeur initiale EXIFPANEL_RESETHINT;Réinitialise les données sélectionnées à la valeur initiale -EXIFPANEL_SHOWALL;Voir tout -EXIFPANEL_SUBDIRECTORY;Sous-répertoire EXPORT_BYPASS;Étapes de traitement à ignorer EXPORT_BYPASS_ALL;Sélectionner / Désélectionner tout EXPORT_BYPASS_DEFRINGE;Ignorer la corr. d'aberration chromatique @@ -836,7 +834,6 @@ IPTCPANEL_TITLE;Titre IPTCPANEL_TITLEHINT;Enterez un nom court et humainement lisible pour l'image, cela peut être le nom du fichier. IPTCPANEL_TRANSREFERENCE;ID du travail IPTCPANEL_TRANSREFERENCEHINT;Enterez un nombre ou identifiant servant au contrôle du flux de travail ou au suivi. -LENSPROFILE_LENS_WARNING;Attention: la taille du capteur utilisé pour le profilage de l'objectif est plus grand que celui de l'appareil sélectionné, le résultat peut être faux. MAIN_BUTTON_FULLSCREEN;Plein écran MAIN_BUTTON_ICCPROFCREATOR;Créateur de Profil ICC MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigue à l'image Suivante relativement à l'image ouverte dans l'Éditeur\nRaccourci: Shift-F4\n\nPour naviguer à l'image Suivante relativement à la vignette sélectionnée dans le Navigateur de fichiers\nRaccourci: F4 @@ -1019,7 +1016,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Police des ancres de vérification couleu PREFERENCES_APPEARANCE_CROPMASKCOLOR;Couleur du masque de recadrage PREFERENCES_APPEARANCE_MAINFONT;Police principale PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Couleur du cadre dans le Navigateur -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Mode pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Thème PREFERENCES_APPLNEXTSTARTUP;appliqué au prochain lancement PREFERENCES_AUTOMONPROFILE;Utiliser automatiquement le profil de l'écran principal @@ -1705,8 +1701,6 @@ TP_ICM_WORKING_TRC_SLOPE;Pente TP_ICM_WORKING_TRC_TOOLTIP;Seulement pour les profils internes 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ène les données dans le gamut de l'espace couleur de travail\npuis applique la correction de Munsell TP_LABCURVE_BRIGHTNESS;Luminosité TP_LABCURVE_CHROMATICITY;Chromaticité TP_LABCURVE_CHROMA_TOOLTIP;Pour activer la colorisation du N&B par les courbes 'a' et 'b', réglez la Chromaticité à -100 @@ -2180,7 +2174,6 @@ TP_LOCALLAB_MASKRESWAV_TOOLTIP;Utilisé pour moduler l'action des réglages de C TP_LOCALLAB_MASKUNUSABLE;Masque désactivé (Masque & modifications) TP_LOCALLAB_MASKUSABLE;Masque activé (Masque & modifications) TP_LOCALLAB_MASK_TOOLTIP;Vous pouvez activer plusieurs masques pour un simple outil, ceci nécessite d'activer un autre outil (mais sans utilser l'outil : curseurs à 0,...)où est le masque que vous souhaitez activer.\n\nVous pouvez aussi dupliquer le RT-spot et le placer juste à côté de l'autre,les variations de références autorisent un travail fin sur les images. -TP_LOCALLAB_MED;Medium TP_LOCALLAB_MEDIAN;Median Bas TP_LOCALLAB_MEDIANITER_TOOLTIP;Nombre d'applications successives du median TP_LOCALLAB_MEDIAN_TOOLTIP;Choisir un median 3x3 à 9x9: plus les valeurs sont élévées, plus la réduction du bruit ou le flou seront marqués @@ -2620,7 +2613,6 @@ TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Utilise la médianes de toutes les sous-images a TP_RAW_PIXELSHIFTMM_AUTO;Automatique TP_RAW_PIXELSHIFTMM_CUSTOM;Manuel TP_RAW_PIXELSHIFTMM_OFF;Arrêt -TP_RAW_PIXELSHIFTMOTION;Niveau de détection de mouvement (dépréconisé) TP_RAW_PIXELSHIFTMOTIONMETHOD;Correction de Mouvement TP_RAW_PIXELSHIFTNONGREENCROSS;Vérifier les canaux rouge/bleu pour le mouvement TP_RAW_PIXELSHIFTSHOWMOTION;Voir le masque de mouvement @@ -3051,6 +3043,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -3101,7 +3094,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -3411,7 +3404,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -3654,7 +3647,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -3743,18 +3736,90 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -3852,10 +3917,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3875,13 +3943,18 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3910,6 +3983,27 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending @@ -3919,12 +4013,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_CATCLASSIC;Classic !TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. @@ -3967,6 +4065,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3979,8 +4078,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3992,11 +4098,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -4005,11 +4113,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -4020,26 +4131,45 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_LENSGEOM_LOG;Logarithmic !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct -!TP_LOCALLAB_AUTOGRAYCIE;Auto -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AUTOGRAYCIE;Automatic +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_CATAD;Chromatic adaptation/Cat16 !TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 !TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 !TP_LOCALLAB_CHROML;Chroma (C) +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLOR_CIE;Color curve +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CURVES_CIE;Tone curve +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DENOIMASK;Denoise chroma mask !TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. !TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance !TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_FATSAT;Saturation control +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_GAMC;Gamma !TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. @@ -4055,23 +4185,59 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. !TP_LOCALLAB_LCLABELS;Residual noise levels !TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 !TP_LOCALLAB_LUMFRA;L*a*b* standard !TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 !TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. !TP_LOCALLAB_MASKLCTHR2;Light area luma threshold !TP_LOCALLAB_MASKLCTHRLOW2;Dark area luma threshold +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MODE_SIMPLE;Basic !TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_NLGAM;Gamma !TP_LOCALLAB_NOISEGAM;Gamma !TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. !TP_LOCALLAB_NUL_TOOLTIP;. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATURV;Saturation (s) +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGGAMJCIE;Gamma +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_TE_PIVOT;Pivot (Ev) !TP_LOCALLAB_TOOLMASK_2;Wavelets +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. !TP_LOCALLAB_ZCAMFRA;ZCAM Image Adjustments !TP_LOCALLAB_ZCAMTHRES;Retrieve high datas @@ -4194,7 +4360,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4237,7 +4403,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 8e1f6124d..c78af3958 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -42,8 +42,8 @@ CURVEEDITOR_TYPE;Tipologia: DIRBROWSER_FOLDERS;Cartelle DONT_SHOW_AGAIN;Non mostrare più questo messaggio. DYNPROFILEEDITOR_DELETE;Elimina -DYNPROFILEEDITOR_EDIT_RULE;Modifica regola profilo dinamico DYNPROFILEEDITOR_EDIT;Modifica +DYNPROFILEEDITOR_EDIT_RULE;Modifica regola profilo dinamico DYNPROFILEEDITOR_ENTRY_TOOLTIP;La corrispondenza non fa distinzione tra maiuscole e minuscole.\nUtilizzare il prefisso 're:' per inserire\na un'espressione regolare. DYNPROFILEEDITOR_IMGTYPE_ANY;Qualsiasi DYNPROFILEEDITOR_IMGTYPE_HDR;HDR @@ -51,12 +51,12 @@ DYNPROFILEEDITOR_IMGTYPE_PS;Pixel Shift DYNPROFILEEDITOR_IMGTYPE_STD;Standard DYNPROFILEEDITOR_MOVE_DOWN;Muovi Giù DYNPROFILEEDITOR_MOVE_UP;Muovi Sù -DYNPROFILEEDITOR_NEW_RULE;Nuova regola del profilo dinamico DYNPROFILEEDITOR_NEW;Nuovo +DYNPROFILEEDITOR_NEW_RULE;Nuova regola del profilo dinamico DYNPROFILEEDITOR_PROFILE;Profilo di elaborazione +EDITWINDOW_TITLE;Modifica immagine EDIT_OBJECT_TOOLTIP;Mostra un widget nella finestra anteprima che ti permette di configurare questo strumento. EDIT_PIPETTE_TOOLTIP;Per aggiungere un punto di regolazione alla curva, tieni premuto il tasto Ctrl e fai click sul punto desiderato nell'anteprima dell'immagine.\nPer sistemare il punto, tieni premuto il tasto Ctrl mentre fai click sulla corrispondente area nell'anteprima, poi lascia il tasto Ctrl (a meno che non desideri un controllo fine) e mentre tieni premuto il tasto sinistro del mouse, muovilo in su e in giù per muovere il punto su e giù sulla curva. -EDITWINDOW_TITLE;Modifica immagine ERROR_MSG_METADATA_VALUE;Metadata: errore di setting %1 di %2 EXIFFILTER_APERTURE;Diaframma EXIFFILTER_CAMERA;Fotocamera @@ -85,8 +85,8 @@ EXIFPANEL_RESET;Ripristina EXIFPANEL_RESETALL;Ripristina tutto EXIFPANEL_RESETALLHINT;Ripristina tutti i campi al loro valore originario EXIFPANEL_RESETHINT;Ripristina i campi selezionati ai loro valori originari -EXIFPANEL_SUBDIRECTORY;Sottocartella EXIFPANEL_VALUE_NOT_SHOWN;Non mostrare +EXPORT_BYPASS;Passaggi di elaborazione da bypassare EXPORT_BYPASS_ALL;Seleziona/Deseleziona Tutto EXPORT_BYPASS_DEFRINGE;Ignora Defringe EXPORT_BYPASS_DIRPYRDENOISE;Ignora Riduzione Rumore @@ -104,7 +104,6 @@ EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Ignora i Passaggi di Miglioramento LMMSE EXPORT_BYPASS_SHARPENEDGE;Ignora Nitidezza dei bordi EXPORT_BYPASS_SHARPENING;Ignora Nitidezza EXPORT_BYPASS_SHARPENMICRO;Ignora Microcontrasto -EXPORT_BYPASS;Passaggi di elaborazione da bypassare EXPORT_FASTEXPORTOPTIONS;Opzioni di Esportazione Rapida EXPORT_INSTRUCTIONS;Le opzioni di Esportazione Rapida forniscono opzioni per ignorare le impostazioni di sviluppo ad elevato consumo di tempo e risorse ed avviare quindi la coda di sviluppo usando solo le impostazioni veloci. Questo metodo è consigliato per la lavorazione veloce di immagini a bassa risoluzione quando è importante la rapidità, oppure quando si desidera ridimensionare una o più immagini senza apportare modifiche ai parametri di sviluppo salvati. EXPORT_MAXHEIGHT;Altezza Massima: @@ -112,13 +111,13 @@ EXPORT_MAXWIDTH;Larghezza Massima: EXPORT_PIPELINE;Pipeline di elaborazione EXPORT_PUTTOQUEUEFAST; Aggiungi alla Coda di sviluppo per l'Esportazione Rapida EXPORT_RAW_DMETHOD;Metodo di Demosaicizzazione -EXPORT_USE_FAST_PIPELINE_TOOLTIP;Utilizza una pipeline di elaborazione dedicata per le immagini in modalità Esportazione rapida, che baratta la velocità con la qualità. Il ridimensionamento dell'immagine viene effettuato il prima possibile, invece di farlo alla fine come nella pipeline normale. L'accelerazione può essere significativa, ma preparati a vedere artefatti e un generale degrado della qualità dell'output. EXPORT_USE_FAST_PIPELINE;Dedicato (elaborazione completa sull'immagine ridimensionata) +EXPORT_USE_FAST_PIPELINE_TOOLTIP;Utilizza una pipeline di elaborazione dedicata per le immagini in modalità Esportazione rapida, che baratta la velocità con la qualità. Il ridimensionamento dell'immagine viene effettuato il prima possibile, invece di farlo alla fine come nella pipeline normale. L'accelerazione può essere significativa, ma preparati a vedere artefatti e un generale degrado della qualità dell'output. EXPORT_USE_NORMAL_PIPELINE;Standard (ignora alcuni passaggi, ridimensiona alla fine) EXTPROGTARGET_1;raw EXTPROGTARGET_2;Lavorato dalla Coda -FILEBROWSER_APPLYPROFILE_PARTIAL;Applica (parziale) FILEBROWSER_APPLYPROFILE;Applica +FILEBROWSER_APPLYPROFILE_PARTIAL;Applica (parziale) FILEBROWSER_AUTODARKFRAME;Dark Frame automatico FILEBROWSER_AUTOFLATFIELD;Flat Field automatico FILEBROWSER_BROWSEPATHBUTTONHINT;Fare clic per aprire il percorso specificato, ricaricare la cartella e applicare le parole chiave "trova". @@ -250,8 +249,8 @@ GENERAL_OPEN;Apri GENERAL_OTHER;Altro GENERAL_PORTRAIT;Ritratto GENERAL_RESET;Ripristina -GENERAL_SAVE_AS;Salva come… GENERAL_SAVE;Salva +GENERAL_SAVE_AS;Salva come… GENERAL_SLIDER;Cursore GENERAL_UNCHANGED;(Invariato) GENERAL_WARNING;Attenzione @@ -266,8 +265,8 @@ HISTOGRAM_TOOLTIP_MODE;Alterna tra il ridimensionamento lineare, log-lineare e l HISTOGRAM_TOOLTIP_R;Mostra/Nascondi l'istogramma del Rosso. HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Attiva/disattiva la visibilità dei pulsanti di opzione dell'ambito. HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Regola la luminosità dell'oscilloscopio. -HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Istogramma grezzo HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Istogramma +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Istogramma grezzo HISTOGRAM_TOOLTIP_TYPE_PARADE;Parata RGB HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Vectorscope tonalità-croma HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Vectorscope tonalità-saturazione @@ -1448,15 +1447,15 @@ HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Metodo delle primarie HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Pendenza HISTORY_MSG_ICM_WORKING_TRC_METHOD;Metodo TRC HISTORY_MSG_ILLUM;CAL - SC - Illuminante -HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Riduzione Foschia - Nero -HISTORY_MSG_LOCAL_GAMUTMUNSEL;Locale - SC - Evita il cambiamento di colore -HISTORY_MSG_LOCAL_TMO_SATUR;Local Saturazione Fattale dell'esposizione HISTORY_MSG_LOCALCONTRAST_AMOUNT;Contrasto Locale - Quantità HISTORY_MSG_LOCALCONTRAST_DARKNESS;Contrasto Locale - Durezza HISTORY_MSG_LOCALCONTRAST_ENABLED;Contrasto Locale HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Contrasto Locale - Luminosità HISTORY_MSG_LOCALCONTRAST_RADIUS;Contrasto Locale - Raggio HISTORY_MSG_LOCALLAB_TE_PIVOT;Locale - Perno dell'equalizzatore +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Riduzione Foschia - Nero +HISTORY_MSG_LOCAL_GAMUTMUNSEL;Locale - SC - Evita il cambiamento di colore +HISTORY_MSG_LOCAL_TMO_SATUR;Local Saturazione Fattale dell'esposizione HISTORY_MSG_METADATA_MODE;Modalità di copia dei metadati HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrasto - Soglia di contrasto HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Soglia automatica @@ -1464,8 +1463,8 @@ HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Raggio automatico HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Iterazioni di limite automatico HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Soglia di contrasto HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Iterazione -HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Aumento del raggio d'angolo HISTORY_MSG_PDSHARPEN_RADIUS;CS - Raggio +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Aumento del raggio d'angolo HISTORY_MSG_PERSP_CAM_ANGLE;Prospettiva - Camera HISTORY_MSG_PERSP_CAM_FL;Prospettiva - Camera HISTORY_MSG_PERSP_CAM_SHIFT;Prospettiva - Camera @@ -1482,23 +1481,23 @@ HISTORY_MSG_PREPROCWB_MODE;Preelabora la modalità WB HISTORY_MSG_PROTAB;Protezione HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Soglia di contrasto HISTORY_MSG_RANGEAB;Allineare ab -HISTORY_MSG_RAW_BORDER;Raw confine HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correzione - Iterazione HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correzione - Evita il cambiamento di colore +HISTORY_MSG_RAW_BORDER;Raw confine HISTORY_MSG_RESIZE_ALLOWUPSCALING;Ridimensiona - Consente l'ingrandimento HISTORY_MSG_RESIZE_LONGEDGE;Ridimensiona - Bordo lungo HISTORY_MSG_RESIZE_SHORTEDGE;Ridimensiona - Bordo corto -HISTORY_MSG_SH_COLORSPACE;S/H - Spazio colore HISTORY_MSG_SHARPENING_BLUR;Nitidezza - Raggio di sfocatura HISTORY_MSG_SHARPENING_CONTRAST;Nitidezza - Soglia di contrasto +HISTORY_MSG_SH_COLORSPACE;S/H - Spazio colore HISTORY_MSG_SIGMACOL;Risposta all'attenuazione cromatica HISTORY_MSG_SIGMADIR;Risposta di attenuazione Dir HISTORY_MSG_SIGMAFIN;Risposta di attenuazione del contrasto finale HISTORY_MSG_SIGMATON;Risposta all'attenuazione toni HISTORY_MSG_SOFTLIGHT_ENABLED;Luce soffusa HISTORY_MSG_SOFTLIGHT_STRENGTH;Luce soffusa - Intensità -HISTORY_MSG_SPOT_ENTRY;Rimozione delle macchie - modifica punto HISTORY_MSG_SPOT;Rimozione delle macchie +HISTORY_MSG_SPOT_ENTRY;Rimozione delle macchie - modifica punto HISTORY_MSG_TEMPOUT;CAM02 temperature automatica HISTORY_MSG_THRESWAV;Soglia bilanciamento HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Ancora @@ -1563,18 +1562,19 @@ HISTORY_MSG_WBITC_SAMPLING;Campionamento basso HISTORY_MSG_WBITC_SIZE;Itcwb Dimensione HISTORY_MSG_WBITC_SORTED;Itcwb Ponderata HISTORY_MSG_WBITC_THRES;Itcwb Soglia -HISTORY_NEWSNAPSHOT_TOOLTIP;Scorciatoia: Alt-s HISTORY_NEWSNAPSHOT;Aggiungi +HISTORY_NEWSNAPSHOT_TOOLTIP;Scorciatoia: Alt-s HISTORY_SNAPSHOT;Istantanea HISTORY_SNAPSHOTS;Istantanee -ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Ripristina il copyright predefinito, concesso a "RawTherapee, CC0". ICCPROFCREATOR_COPYRIGHT;Copyright: +ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Ripristina il copyright predefinito, concesso a "RawTherapee, CC0". ICCPROFCREATOR_CUSTOM;Predefinito +ICCPROFCREATOR_DESCRIPTION;Descrizione: ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Aggiungi i valori gamma e pendenza alla descrizione ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Lascia vuoto per impostare la descrizione predefinita. -ICCPROFCREATOR_DESCRIPTION;Descrizione: ICCPROFCREATOR_GAMMA;Gamma ICCPROFCREATOR_ICCVERSION;ICC versione: +ICCPROFCREATOR_ILL;Illuminante: ICCPROFCREATOR_ILL_41;D41 ICCPROFCREATOR_ILL_50;D50 ICCPROFCREATOR_ILL_55;D55 @@ -1585,7 +1585,7 @@ ICCPROFCREATOR_ILL_80;D80 ICCPROFCREATOR_ILL_DEF;Default ICCPROFCREATOR_ILL_INC;StdA 2856K ICCPROFCREATOR_ILL_TOOLTIP;È possibile impostare l'illuminante per i profili ICC v4 e anche per i profili ICC v2. -ICCPROFCREATOR_ILL;Illuminante: +ICCPROFCREATOR_PRIMARIES;Primarie: ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) @@ -1604,7 +1604,6 @@ ICCPROFCREATOR_PRIM_REDY;Rosso Y ICCPROFCREATOR_PRIM_SRGB;sRGB ICCPROFCREATOR_PRIM_TOOLTIP;È possibile impostare primari personalizzati per i profili ICC v4 e anche per i profili ICC v2. ICCPROFCREATOR_PRIM_WIDEG;Ampia gamma -ICCPROFCREATOR_PRIMARIES;Primarie: ICCPROFCREATOR_PROF_V2;ICC v2 ICCPROFCREATOR_PROF_V4;ICC v4 ICCPROFCREATOR_SAVEDIALOG_TITLE;Salva il profilo ICC come... @@ -1661,25 +1660,25 @@ MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizza il Navigatore o il Rullino con la scheda MAIN_BUTTON_PREFERENCES;Preferenze MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Aggiungi l'immagine corrente alla coda di sviluppo.\nScorciatoia: Ctrl+B MAIN_BUTTON_SAVE_TOOLTIP;Salva l'immagine corrente.\nSscorciatoia: Ctrl+S -MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Modifica l'immagine corrente con un programma di fotoritocco.\nScorciatoia: Ctrl+E MAIN_BUTTON_SENDTOEDITOR;Modifica l'immagine nell'editor esterno +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Modifica l'immagine corrente con un programma di fotoritocco.\nScorciatoia: Ctrl+E MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/Nascondi tutti i pannelli laterali.\nScorciatoia: m MAIN_BUTTON_UNFULLSCREEN;Esci da schermo intero -MAIN_FRAME_EDITOR_TOOLTIP;Modifica.\nScorciatoia: Ctrl-F4 MAIN_FRAME_EDITOR;Modifica -MAIN_FRAME_FILEBROWSER_TOOLTIP;Navigatore.\nScorciatoia: Ctrl-F2 +MAIN_FRAME_EDITOR_TOOLTIP;Modifica.\nScorciatoia: Ctrl-F4 MAIN_FRAME_FILEBROWSER;Navigatore +MAIN_FRAME_FILEBROWSER_TOOLTIP;Navigatore.\nScorciatoia: Ctrl-F2 +MAIN_FRAME_PLACES;Risorse MAIN_FRAME_PLACES_ADD;Aggiungi MAIN_FRAME_PLACES_DEL;Rimuovere -MAIN_FRAME_PLACES;Risorse -MAIN_FRAME_QUEUE_TOOLTIP;Coda di sviluppo.\nScorciatoia: Ctrl-F3 MAIN_FRAME_QUEUE;Coda di sviluppo +MAIN_FRAME_QUEUE_TOOLTIP;Coda di sviluppo.\nScorciatoia: Ctrl-F3 MAIN_FRAME_RECENT;Cartelle recenti MAIN_MSG_ALREADYEXISTS;File già esistente MAIN_MSG_CANNOTLOAD;Impossibile caricare l'immagine MAIN_MSG_CANNOTSAVE;Errore nel salvataggio del file -MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Inserisci il percorso corretto nelle "Preferenze". MAIN_MSG_CANNOTSTARTEDITOR;Non riesco ad avviare il programma di fotoritocco. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Inserisci il percorso corretto nelle "Preferenze". MAIN_MSG_EMPTYFILENAME;Nome del file non specificato! MAIN_MSG_IMAGEUNPROCESSED;Questo comando richiede che tutte le immagini selezionate vengano prima elaborate nella coda. MAIN_MSG_NAVIGATOR;Navigatore @@ -1689,30 +1688,30 @@ MAIN_MSG_QOVERWRITE;Vuoi sovrascriverlo? MAIN_MSG_SETPATHFIRST;Per utilizzare questa funzione\ndevi impostare un percorso nelle Preferenze. MAIN_MSG_TOOMANYOPENEDITORS;Troppi editor aperti.\nChiudi un editor per continuare. MAIN_MSG_WRITEFAILED;Impossibile scrivere\n\n"%1"\n\nAssicurati che la cartella esista e di averne i permessi di scrittura. -MAIN_TAB_ADVANCED_TOOLTIP;Scorciatoia: Alt-a MAIN_TAB_ADVANCED;Avanzate -MAIN_TAB_COLOR_TOOLTIP;Scorciatoia: Alt-c +MAIN_TAB_ADVANCED_TOOLTIP;Scorciatoia: Alt-a MAIN_TAB_COLOR;Colore -MAIN_TAB_DETAIL_TOOLTIP;Scorciatoia: Alt-d +MAIN_TAB_COLOR_TOOLTIP;Scorciatoia: Alt-c MAIN_TAB_DETAIL;Dettaglio +MAIN_TAB_DETAIL_TOOLTIP;Scorciatoia: Alt-d MAIN_TAB_DEVELOP; Modifiche Batch MAIN_TAB_EXIF;Exif MAIN_TAB_EXPORT; Esportazione Rapida -MAIN_TAB_EXPOSURE_TOOLTIP;Scorciatoia: Alt-e MAIN_TAB_EXPOSURE;Esposizione -MAIN_TAB_FAVORITES_TOOLTIP;Scorciatoia: Alt-u +MAIN_TAB_EXPOSURE_TOOLTIP;Scorciatoia: Alt-e MAIN_TAB_FAVORITES;Preferiti +MAIN_TAB_FAVORITES_TOOLTIP;Scorciatoia: Alt-u MAIN_TAB_FILTER; Filtro MAIN_TAB_INSPECT; Inspect MAIN_TAB_IPTC;IPTC -MAIN_TAB_LOCALLAB_TOOLTIP;Scorciatoia: Alt-o MAIN_TAB_LOCALLAB;Local -MAIN_TAB_METADATA_TOOLTIP;Scorciatoia: Alt-m +MAIN_TAB_LOCALLAB_TOOLTIP;Scorciatoia: Alt-o MAIN_TAB_METADATA;Metadati -MAIN_TAB_RAW_TOOLTIP;Scorciatoia: Alt-r +MAIN_TAB_METADATA_TOOLTIP;Scorciatoia: Alt-m MAIN_TAB_RAW;Raw -MAIN_TAB_TRANSFORM_TOOLTIP;Scorciatoia: Alt-t +MAIN_TAB_RAW_TOOLTIP;Scorciatoia: Alt-r MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TAB_TRANSFORM_TOOLTIP;Scorciatoia: Alt-t MAIN_TOOLTIP_BACKCOLOR0;Colore di sfondo dell'anteprima: Basato sul tema\nScorciatoia: 9 MAIN_TOOLTIP_BACKCOLOR1;Colore di sfondo dell'anteprima: Nero\nScorciatoia: 9 MAIN_TOOLTIP_BACKCOLOR2;Colore di sfondo dell'anteprima: Bianco\nScorciatoia: 9 @@ -1805,6 +1804,12 @@ PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro per rumore a bande PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;Filtro linee PDAF PARTIALPASTE_PREPROCWB;Preelaborare il bilanciamento del bianco PARTIALPASTE_PRSHARPENING;Affinamento post-ridimensionamento +PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC +PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA evitare cambiamenti di colore +PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rosso e blu +PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero +PARTIALPASTE_RAWEXPOS_LINEAR;Correzione Punto del Bianco +PARTIALPASTE_RAWGROUP;Impostazioni del Raw PARTIALPASTE_RAW_BORDER;Bordo del raw PARTIALPASTE_RAW_DCBENHANCE;Miglioramento DCB PARTIALPASTE_RAW_DCBITERATIONS;Numero di iterazioni DCB @@ -1813,12 +1818,6 @@ PARTIALPASTE_RAW_FALSECOLOR;Soppressione di falsi colori demosaicizzati PARTIALPASTE_RAW_IMAGENUM;Sotto-immagine PARTIALPASTE_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE PARTIALPASTE_RAW_PIXELSHIFT;Spostamento dei pixel -PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC -PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA evitare cambiamenti di colore -PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rosso e blu -PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero -PARTIALPASTE_RAWEXPOS_LINEAR;Correzione Punto del Bianco -PARTIALPASTE_RAWGROUP;Impostazioni del Raw PARTIALPASTE_RESIZE;Ridimensionamento PARTIALPASTE_RETINEX;Retinex PARTIALPASTE_RGBCURVES;Curve RGB @@ -1835,13 +1834,12 @@ PARTIALPASTE_VIBRANCE;Vividezza PARTIALPASTE_VIGNETTING;Correzione Vignettatura PARTIALPASTE_WHITEBALANCE;Bilanciamento del bianco PREFERENCES_ADD;Somma +PREFERENCES_APPEARANCE;Aspetto PREFERENCES_APPEARANCE_COLORPICKERFONT;Carattere di selezione colore PREFERENCES_APPEARANCE_CROPMASKCOLOR;Colore della maschera di ritaglio PREFERENCES_APPEARANCE_MAINFONT;Carattere principale PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Colore delle guide del Navigatore -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Modo Pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Tema -PREFERENCES_APPEARANCE;Aspetto PREFERENCES_APPLNEXTSTARTUP;applicato al prossimo avvio PREFERENCES_AUTOMONPROFILE;Usa il profilo colore dello schermo principale del sistema operativo PREFERENCES_AUTOSAVE_TP_OPEN;Salva lo stato compresso/espanso dello strumento all'uscita @@ -1851,48 +1849,48 @@ PREFERENCES_BEHADDALLHINT;Imposta tutti i parametri nella modalità Somma PREFERENCES_BEHAVIOR;Comportamento PREFERENCES_BEHSETALL;Tutti a 'Imposta' PREFERENCES_BEHSETALLHINT;Imposta tutti i parametri nella modalità Imposta.\nLe regolazioni dei parametri nel pannello strumenti batch saranno assoluti, verranno mostrati i valori reali. +PREFERENCES_CACHECLEAR;Pulisci PREFERENCES_CACHECLEAR_ALL;Pulisci tutti i file della cache: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Cancella tutti i file memorizzati nella cache ad eccezione dei profili di elaborazione memorizzati nella cache: PREFERENCES_CACHECLEAR_ONLYPROFILES;Cancella solo i profili di elaborazione memorizzati nella cache: PREFERENCES_CACHECLEAR_SAFETY;Vengono cancellati solo i file nella cache. I profili di elaborazione memorizzati insieme alle immagini sorgente non vengono toccati. -PREFERENCES_CACHECLEAR;Pulisci PREFERENCES_CACHEMAXENTRIES;Numero massimo di voci in memoria PREFERENCES_CACHEOPTS;Opzioni della memoria PREFERENCES_CACHETHUMBHEIGHT;Massima altezza delle miniature PREFERENCES_CAMERAPROFILESDIR;Directory dei profili della fotocamera +PREFERENCES_CHUNKSIZES;Riquadri per tipo di esecuzione PREFERENCES_CHUNKSIZE_RAW_AMAZE;Demosaicizzazione AMaZE PREFERENCES_CHUNKSIZE_RAW_CA;Correzione CA Raw PREFERENCES_CHUNKSIZE_RAW_RCD;Demosaicizzazione RCD PREFERENCES_CHUNKSIZE_RAW_XT;Demosaicizzazione Xtrans PREFERENCES_CHUNKSIZE_RGB;Elaborazione RGB -PREFERENCES_CHUNKSIZES;Riquadri per tipo di esecuzione PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Evita artefatti PREFERENCES_CLIPPINGIND;Indicazione di tosaggio -PREFERENCES_CLUTSCACHE_LABEL;Numero massimo di cache CLUTs PREFERENCES_CLUTSCACHE;HaldCLUT Cache +PREFERENCES_CLUTSCACHE_LABEL;Numero massimo di cache CLUTs PREFERENCES_CLUTSDIR;Directory HaldCLUT PREFERENCES_CMMBPC;Compensazione del punti di Nero +PREFERENCES_COMPLEXITYLOC;Complessità predefinita per le regolazioni locali PREFERENCES_COMPLEXITY_EXP;Avanzate PREFERENCES_COMPLEXITY_NORM;Standard PREFERENCES_COMPLEXITY_SIMP;Di base -PREFERENCES_COMPLEXITYLOC;Complessità predefinita per le regolazioni locali +PREFERENCES_CROP;Modifica del ritaglio PREFERENCES_CROP_AUTO_FIT;Zoom automaticamente per adattare il ritaglio +PREFERENCES_CROP_GUIDES;Guide visualizzate quando non si modifica il ritaglio PREFERENCES_CROP_GUIDES_FRAME;Frame PREFERENCES_CROP_GUIDES_FULL;Originale PREFERENCES_CROP_GUIDES_NONE;Nessuno -PREFERENCES_CROP_GUIDES;Guide visualizzate quando non si modifica il ritaglio -PREFERENCES_CROP;Modifica del ritaglio +PREFERENCES_CURVEBBOXPOS;Posizione dei pulsanti copia e incolla della curva PREFERENCES_CURVEBBOXPOS_ABOVE;Sopra PREFERENCES_CURVEBBOXPOS_BELOW;Sotto PREFERENCES_CURVEBBOXPOS_LEFT;Sinistra PREFERENCES_CURVEBBOXPOS_RIGHT;Destra -PREFERENCES_CURVEBBOXPOS;Posizione dei pulsanti copia e incolla della curva PREFERENCES_CUSTPROFBUILD;Generatore profili personalizzati PREFERENCES_CUSTPROFBUILDHINT;File eseguibile (o script) richiamato quando è necessario generare un nuovo profilo per un'immagine.\nIl percorso del file di comunicazione (del tipo *.ini, detto "Keyfile") è aggiunto come parametro da linea di comando. Contiene diversi paramentri necessari agli script e ai dati Exif per generare un profilo di elaborazione.\n\nATTENZIONE:: Devi utilizzare le virgolette doppie quando necessario se utilizzi percorsi contenenti spazi. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formato tasti PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nome PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID -PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formato tasti PREFERENCES_CUSTPROFBUILDPATH;Percorso dell'eseguibile PREFERENCES_DARKFRAMEFOUND;Trovati PREFERENCES_DARKFRAMESHOTS;fotogrammi @@ -1909,17 +1907,17 @@ PREFERENCES_DIRSOFTWARE;Cartella d'installazione PREFERENCES_EDITORCMDLINE;Riga di comando personalizzata PREFERENCES_EDITORLAYOUT;Disposizione PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Ignora profilo di destinazione +PREFERENCES_EXTEDITOR_DIR;Cartella di destinazione PREFERENCES_EXTEDITOR_DIR_CURRENT;Uguale all'immagine di input PREFERENCES_EXTEDITOR_DIR_CUSTOM;Personalizza PREFERENCES_EXTEDITOR_DIR_TEMP;OS Directory temporanea -PREFERENCES_EXTEDITOR_DIR;Cartella di destinazione PREFERENCES_EXTEDITOR_FLOAT32;Output TIFF in virgola mobile a 32 bit -PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Modifica eseguibile +PREFERENCES_EXTERNALEDITOR;Programma di ritocco esterni PREFERENCES_EXTERNALEDITOR_CHANGE;Cambia applicazione +PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Modifica eseguibile PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Comando PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Nome PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Comando nativo -PREFERENCES_EXTERNALEDITOR;Programma di ritocco esterni PREFERENCES_FBROWSEROPTS;Opzioni del Navigatore e delle miniature PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Barre degli strumenti compatte nel browser dei file PREFERENCES_FLATFIELDFOUND;Trovati @@ -1928,18 +1926,18 @@ PREFERENCES_FLATFIELDSHOTS;fotogrammi PREFERENCES_FLATFIELDTEMPLATES;modelli PREFERENCES_FORIMAGE;Per foto non raw PREFERENCES_FORRAW;Per foto raw -PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Avere dimensioni delle miniature separate richiederà più tempo di elaborazione ogni volta che passerai dalla scheda Editor singolo al Browser file. PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Stessa altezza della miniatura tra la pellicola e il browser dei file +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Avere dimensioni delle miniature separate richiederà più tempo di elaborazione ogni volta che passerai dalla scheda Editor singolo al Browser file. PREFERENCES_GIMPPATH;Cartella d'installazione di GIMP -PREFERENCES_HISTOGRAM_TOOLTIP;Se abilitato, Navigatore e Istogramma usano il Profilo di Lavoro anziché il Profilo di Uscita (con gamma) PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro +PREFERENCES_HISTOGRAM_TOOLTIP;Se abilitato, Navigatore e Istogramma usano il Profilo di Lavoro anziché il Profilo di Uscita (con gamma) PREFERENCES_HLTHRESHOLD;Soglia per le alteluci tosate PREFERENCES_ICCDIR;Cartella profili colore PREFERENCES_IMPROCPARAMS;Parametri predefiniti di elaborazione dell'immagine +PREFERENCES_INSPECTORWINDOW;Apri la visualizzazione nella tua finestra o a schermo intero PREFERENCES_INSPECT_LABEL;Ispezionare PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Numero massimo di immagini memorizzate nella cache PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Imposta il numero massimo di immagini archiviate nella cache quando passi il mouse sopra di esse nel Browser file; i sistemi con poca RAM (2GB) dovrebbero mantenere questo valore impostato su 1 o 2. -PREFERENCES_INSPECTORWINDOW;Apri la visualizzazione nella tua finestra o a schermo intero PREFERENCES_INTENT_ABSOLUTE;Colorimetrico Assoluto PREFERENCES_INTENT_PERCEPTUAL;Percettivo PREFERENCES_INTENT_RELATIVE;Colorimetrico Relativo @@ -1947,10 +1945,10 @@ PREFERENCES_INTENT_SATURATION;Saturazione PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostra miniatura JPEG incorporata, se il raw non è stato lavorato PREFERENCES_LANG;Lingua PREFERENCES_LANGAUTODETECT;Usa l'impostazione di lingua del sistema -PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory contenente il database Lensfun. Lascia vuoto per utilizzare le directory predefinite. PREFERENCES_LENSFUNDBDIR;Directory del database di Lensfun -PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory contenente i profili di correzione dell'obiettivo Adobe (LCP) +PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory contenente il database Lensfun. Lascia vuoto per utilizzare le directory predefinite. PREFERENCES_LENSPROFILESDIR;Directory dei profili degli obiettivi +PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory contenente i profili di correzione dell'obiettivo Adobe (LCP) PREFERENCES_MAXRECENTFOLDERS;Numero massimo di cartelle recenti PREFERENCES_MENUGROUPEXTPROGS;Raggruppa "Apri con" PREFERENCES_MENUGROUPFILEOPERATIONS;Raggruppa "Operazioni sui file" @@ -1958,20 +1956,20 @@ PREFERENCES_MENUGROUPLABEL;Raggruppa "Etichette Colore" PREFERENCES_MENUGROUPPROFILEOPERATIONS;Raggruppa "Operazioni sui profili" PREFERENCES_MENUGROUPRANK;Raggruppa "Classificazioni" PREFERENCES_MENUOPTIONS;Opzioni del menù a discesa +PREFERENCES_METADATA;Metadata +PREFERENCES_METADATA_SYNC;Sincronizzazione dei metadati con sidecar XMP PREFERENCES_METADATA_SYNC_NONE;Spento PREFERENCES_METADATA_SYNC_READ;Solo lettura PREFERENCES_METADATA_SYNC_READWRITE;Bidirezionale -PREFERENCES_METADATA_SYNC;Sincronizzazione dei metadati con sidecar XMP -PREFERENCES_METADATA;Metadata PREFERENCES_MONINTENT;Intento di rendering predefinito PREFERENCES_MONITOR;Monitor -PREFERENCES_MONPROFILE_WARNOSX;A causa delle limitazioni di MacOS, è supportato solo sRGB. PREFERENCES_MONPROFILE;Profilo colore predefinito +PREFERENCES_MONPROFILE_WARNOSX;A causa delle limitazioni di MacOS, è supportato solo sRGB. PREFERENCES_MULTITAB;Modalità a Schede Multiple PREFERENCES_MULTITABDUALMON;Modalità a Schede Multiple (se disponibile sul secondo schermo) PREFERENCES_NAVIGATIONFRAME;Navigazione -PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Sovrapponi i nomi dei file alle miniature nel pannello dell'editor PREFERENCES_OVERLAY_FILENAMES;Mostra i nomi dei file sovrapposti alle miniature +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Sovrapponi i nomi dei file alle miniature nel pannello dell'editor PREFERENCES_OVERWRITEOUTPUTFILE;Sovrascrivi file esistenti PREFERENCES_PANFACTORLABEL;Fattore PREFERENCES_PARSEDEXT;Estensioni riconosciute @@ -1980,16 +1978,15 @@ PREFERENCES_PARSEDEXTADDHINT;Aggiungi l'estensione alla lista. PREFERENCES_PARSEDEXTDELHINT;Rimuovi l'estensione selezionata dalla lista. PREFERENCES_PARSEDEXTDOWNHINT;Sposta l'estensione selezionata verso il basso nell'elenco. PREFERENCES_PARSEDEXTUPHINT;Sposta l'estensione selezionata in alto nell'elenco. -PREFERENCES_PERFORMANCE_MEASURE_HINT;Registra i tempi di elaborazione nella console PREFERENCES_PERFORMANCE_MEASURE;Misurare -PREFERENCES_PERFORMANCE_THREADS_LABEL;Numero massimo di thread per la riduzione del rumore e i livelli wavelet (0 = automatico) +PREFERENCES_PERFORMANCE_MEASURE_HINT;Registra i tempi di elaborazione nella console PREFERENCES_PERFORMANCE_THREADS;Discussioni +PREFERENCES_PERFORMANCE_THREADS_LABEL;Numero massimo di thread per la riduzione del rumore e i livelli wavelet (0 = automatico) +PREFERENCES_PREVDEMO;Anteprima metodo di Demosaicizzazione PREFERENCES_PREVDEMO_FAST;Veloce PREFERENCES_PREVDEMO_LABEL;Metodo di demosaicizzazione utilizzato per l'anteprima con zoom <100%: PREFERENCES_PREVDEMO_SIDECAR;Come in PP3 -PREFERENCES_PREVDEMO;Anteprima metodo di Demosaicizzazione PREFERENCES_PRINTER;Stampa (Soft-Proofing) -PREFERENCES_PROFILE_NONE;Nessuno PREFERENCES_PROFILEHANDLING;Gestione dei profilo di sviluppo PREFERENCES_PROFILELOADPR;Priorità nel caricamento del profilo PREFERENCES_PROFILEPRCACHE;Profilo nella memoria @@ -1998,17 +1995,18 @@ PREFERENCES_PROFILESAVEBOTH;Salva il profilo di elaborazione sia nella cache che PREFERENCES_PROFILESAVECACHE;Salva il profilo di sviluppo nella memoria PREFERENCES_PROFILESAVEINPUT;Salva il profilo di sviluppo a fianco del file originario PREFERENCES_PROFILESAVELOCATION;Posizione di salvataggio del profilo di elaborazione +PREFERENCES_PROFILE_NONE;Nessuno PREFERENCES_PROPERTY;Proprietà PREFERENCES_PRTINTENT;Intento di rendering PREFERENCES_PRTPROFILE;Profilo Colore PREFERENCES_PSPATH;Cartella d'installazione di Adobe Photoshop -PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Ricorda la percentuale di zoom e l'offset di panoramica dell'immagine corrente quando si apre una nuova immagine.\n\nQuesta opzione funziona solo in 'Modalità scheda editor singola' e quando 'Metodo di demosaicizzazione utilizzato per l'anteprima con zoom <100%' è impostato su ' Come in PP3'. PREFERENCES_REMEMBERZOOMPAN;Ricorda la percentuale di zoom e l'offset del pan +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Ricorda la percentuale di zoom e l'offset di panoramica dell'immagine corrente quando si apre una nuova immagine.\n\nQuesta opzione funziona solo in 'Modalità scheda editor singola' e quando 'Metodo di demosaicizzazione utilizzato per l'anteprima con zoom <100%' è impostato su ' Come in PP3'. PREFERENCES_SAVE_TP_OPEN_NOW;Salva ora lo stato compresso/espanso dello strumento PREFERENCES_SELECTLANG;Seleziona la lingua +PREFERENCES_SERIALIZE_TIFF_READ;Impostazioni di lettura TIFF PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serializza la lettura dei file TIFF PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Abilitando questa opzione quando si lavora con cartelle contenenti file TIFF non compressi è possibile aumentare le prestazioni di generazione delle miniature. -PREFERENCES_SERIALIZE_TIFF_READ;Impostazioni di lettura TIFF PREFERENCES_SET;Imposta PREFERENCES_SHOWBASICEXIF;Mostra dati Exif di base PREFERENCES_SHOWDATETIME;Mostra data e ora @@ -2033,11 +2031,11 @@ PREFERENCES_TAB_PERFORMANCE;Prestazione PREFERENCES_TAB_SOUND;Suoni PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Anteprima JPEG incorporata PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Immagine da mostrare -PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;JPEG incorporato se a grandezza naturale, raw neutro altrimenti PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Rendering RAW neutro +PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;JPEG incorporato se a grandezza naturale, raw neutro altrimenti PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Strumenti disponibili -PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Se impostati, gli strumenti preferiti verranno visualizzati sia nella scheda dei preferiti che nelle relative schede originali.\n\nNota: l'abilitazione di questa opzione potrebbe comportare un leggero ritardo quando si passa da una scheda all'altra. PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Mantieni gli strumenti preferiti nelle posizioni originali +PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Se impostati, gli strumenti preferiti verranno visualizzati sia nella scheda dei preferiti che nelle relative schede originali.\n\nNota: l'abilitazione di questa opzione potrebbe comportare un leggero ritardo quando si passa da una scheda all'altra. PREFERENCES_TOOLPANEL_FAVORITE;Preferito PREFERENCES_TOOLPANEL_FAVORITESPANEL;Pannello Preferiti PREFERENCES_TOOLPANEL_TOOL;Strumento @@ -2045,8 +2043,8 @@ PREFERENCES_TP_LABEL;Pannello Strumenti: PREFERENCES_TP_VSCROLLBAR;Nascondi la barra di scorrimento verticale PREFERENCES_USEBUNDLEDPROFILES;Usa profili inclusi PREFERENCES_WBA;Bilanciamento del bianco -PREFERENCES_WBACORR_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di file raw, colorimetria, ecc.), un adattamento dell'algoritmo "Correlazione della temperatura" per ottenere i migliori risultati complessivi. Non esiste una regola assoluta, che lega questi parametri ai risultati ottenuti.\n\nLe impostazioni sono di 3 tipi: \n* quelle accessibili all'utente dalla GUI.\n* quelle accessibili solo in lettura da ogni file pp3 : Itcwb_minsize =20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (Vedi Rawpedia)\n* quelli accessibili all'utente in 'opzioni' (vedi Rawpedia)\n Puoi usare "Bias temperatura Awb" e "Raffinamento verde" per regolare il risultati. Ogni movimento di questi comandi comporta un nuovo calcolo di temperatura, tinta e correlazione.\n\nNota che i 3 indicatori "Fattore di correlazione", "Crominanza patch" e ΔE sono forniti solo a titolo informativo. Non è perché uno di questi indicatori è migliore che il risultato sarà necessariamente migliore. PREFERENCES_WBACORR;Bilanciamento del bianco - correlazione automatica della temperatura +PREFERENCES_WBACORR_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di file raw, colorimetria, ecc.), un adattamento dell'algoritmo "Correlazione della temperatura" per ottenere i migliori risultati complessivi. Non esiste una regola assoluta, che lega questi parametri ai risultati ottenuti.\n\nLe impostazioni sono di 3 tipi: \n* quelle accessibili all'utente dalla GUI.\n* quelle accessibili solo in lettura da ogni file pp3 : Itcwb_minsize =20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (Vedi Rawpedia)\n* quelli accessibili all'utente in 'opzioni' (vedi Rawpedia)\n Puoi usare "Bias temperatura Awb" e "Raffinamento verde" per regolare il risultati. Ogni movimento di questi comandi comporta un nuovo calcolo di temperatura, tinta e correlazione.\n\nNota che i 3 indicatori "Fattore di correlazione", "Crominanza patch" e ΔE sono forniti solo a titolo informativo. Non è perché uno di questi indicatori è migliore che il risultato sarà necessariamente migliore. PREFERENCES_WBAENA;Mostra le impostazioni automatiche di correlazione della temperatura del bilanciamento del bianco PREFERENCES_WBAENACUSTOM;Utilizza temperatura e tinta personalizzate PREFERENCES_WBAFORC;Algoritmo Intensità Extra @@ -2057,9 +2055,9 @@ PREFERENCES_WBAPRECIS;Algoritmo di precisione - scala utilizzata PREFERENCES_WBASIZEREF;La dimensione del colore di riferimento viene confrontata con la dimensione del colore dell'istogramma PREFERENCES_WBASORT;Ordina in ordine cromatico anziché in istogramma PREFERENCES_WORKFLOW;Disposizione +PREFERENCES_XMP_SIDECAR_MODE;Stile sidecar XMP PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) -PREFERENCES_XMP_SIDECAR_MODE;Stile sidecar XMP PREFERENCES_ZOOMONSCROLL;Ingrandire le immagini scorrendole PROFILEPANEL_COPYPPASTE;Parametri da copiare PROFILEPANEL_GLOBALPROFILES;Profili inclusi @@ -2092,8 +2090,8 @@ PROGRESSBAR_LOADJXL;Caricamento JXL... PROGRESSBAR_LOADPNG;Caricamento PNG... PROGRESSBAR_LOADTIFF;Caricamento TIFF... PROGRESSBAR_NOIMAGES;Nessuna immagine trovata -PROGRESSBAR_PROCESSING_PROFILESAVED;Profilo di sviluppo salvato PROGRESSBAR_PROCESSING;Elaborazione dell'immagine... +PROGRESSBAR_PROCESSING_PROFILESAVED;Profilo di sviluppo salvato PROGRESSBAR_RAWCACORR;Correzione CA RAW... PROGRESSBAR_READY;Pronto PROGRESSBAR_SAVEJPEG;Salvataggio del file JPEG... @@ -2106,29 +2104,29 @@ QINFO_HDR;HDR / %2 frame(s) QINFO_ISO;ISO QINFO_NOEXIF;Dati Exif non disponibili. QINFO_PIXELSHIFT;Spostamento dei pixel / %2 frame(s) -QUEUE_AUTOSTART_TOOLTIP;Inizia a sviluppare automaticamente quando un nuovo lavoro viene accodato QUEUE_AUTOSTART;Autoavvia +QUEUE_AUTOSTART_TOOLTIP;Inizia a sviluppare automaticamente quando un nuovo lavoro viene accodato QUEUE_DESTFILENAME;Percorso e nome file QUEUE_DESTPREVIEW_TITLE;Seleziona una miniatura per visualizzare qui l'anteprima del percorso di destinazione QUEUE_DESTPREVIEW_TOOLTIP;Il percorso di destinazione per la prima immagine selezionata viene visualizzato qui QUEUE_FORMAT_TITLE;Formato file QUEUE_LOCATION_FOLDER;Salva nella cartella -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono ai vari livelli del percorso in cui si trova la foto.\n\nPer esempio, se la foto sviluppata si trovasse nel seguente percorso:\n/home/mario/foto/31-10-2010/dsc0042.nef\nil significato delle stringhe di formattazione sarebbe:\n%d4 = home\n%d3 = mario\n%d2 = foto\n%d1 = 31-10-2010\n%f = dsc0042\n%p1 = /home/mario/foto/31-10-2010/\n%p2 = /home/mario/foto/\n%p3 = /home/mario/\n%p4 = /home/\n\nPer salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nPer salvare l'immagine finale in una cartella chiamata "sviluppate" situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nPer salvare l'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f QUEUE_LOCATION_TEMPLATE;Usa lo schema +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono ai vari livelli del percorso in cui si trova la foto.\n\nPer esempio, se la foto sviluppata si trovasse nel seguente percorso:\n/home/mario/foto/31-10-2010/dsc0042.nef\nil significato delle stringhe di formattazione sarebbe:\n%d4 = home\n%d3 = mario\n%d2 = foto\n%d1 = 31-10-2010\n%f = dsc0042\n%p1 = /home/mario/foto/31-10-2010/\n%p2 = /home/mario/foto/\n%p3 = /home/mario/\n%p4 = /home/\n\nPer salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nPer salvare l'immagine finale in una cartella chiamata "sviluppate" situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nPer salvare l'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f QUEUE_LOCATION_TITLE;Posizione di uscita QUEUE_STARTSTOP_TOOLTIP;Avvia o interrompe l'elaborazione delle immagini in coda.\n\nScorciatoia: Ctrl+s SAMPLEFORMAT_0;Formato dati sconosciuto SAMPLEFORMAT_1;8-bit non firmato -SAMPLEFORMAT_16;16-bit virgola mobile SAMPLEFORMAT_2;16-bit non firmato -SAMPLEFORMAT_32;24-bit virgola mobile SAMPLEFORMAT_4;24-bit LogLuv -SAMPLEFORMAT_64;32-bit virgola mobile SAMPLEFORMAT_8;32-bit LogLuv +SAMPLEFORMAT_16;16-bit virgola mobile +SAMPLEFORMAT_32;24-bit virgola mobile +SAMPLEFORMAT_64;32-bit virgola mobile SAVEDLG_AUTOSUFFIX;Aggiungi automaticamente un suffisso se il file esiste già SAVEDLG_BIGTIFF;Grande TIFF (no supporto ai metadati) -SAVEDLG_FILEFORMAT_FLOAT; virgola mobile SAVEDLG_FILEFORMAT;Formato file +SAVEDLG_FILEFORMAT_FLOAT; virgola mobile SAVEDLG_FORCEFORMATOPTS;Opzioni di salvataggio forzato SAVEDLG_JPEGQUAL;Qualità JPEG SAVEDLG_PUTTOQUEUE;Inserisci nella coda di sviluppo @@ -2136,11 +2134,11 @@ SAVEDLG_PUTTOQUEUEHEAD;Metti in cima alla coda di sviluppo SAVEDLG_PUTTOQUEUETAIL;Metti in fondo alla coda di sviluppo SAVEDLG_SAVEIMMEDIATELY;Salva subito SAVEDLG_SAVESPP;Salva i parametri di elaborazione con l'immagine +SAVEDLG_SUBSAMP;Sottocampionamento SAVEDLG_SUBSAMP_1;Migliore Compressione SAVEDLG_SUBSAMP_2;Bilanciato SAVEDLG_SUBSAMP_3;Migliore Qualità SAVEDLG_SUBSAMP_TOOLTIP;Migliore compressione:\nJ:a:b 4:2:0\nh/v 2/2\nCromaticità dimezzata orizzontalmente e verticalmente.\n\nBilanciato:\nJ:a:b 4:2:2\nh/v 2/ 1\nCromazia dimezzata orizzontalmente.\n\nQualità migliore:\nJ:a:b 4:4:4\nh/v 1/1\nNessun sottocampionamento della crominanza. -SAVEDLG_SUBSAMP;Sottocampionamento SAVEDLG_TIFFUNCOMPRESSED;TIFF non compresso SAVEDLG_WARNFILENAME;Il file verrà chiamato SHCSELECTOR_TOOLTIP;Click destro per ripristinare la posizione di questi tre cursori. @@ -2172,19 +2170,20 @@ TOOLBAR_TOOLTIP_HAND;Strumento mano.\nScorciatoia: h TOOLBAR_TOOLTIP_PERSPECTIVE;Correzione prospettica\n\nModifica le linee di controllo per correggere la distorsione prospettica. Fare di nuovo clic su questo pulsante per applicare la correzione. TOOLBAR_TOOLTIP_STRAIGHTEN;Linea Dritta/Rotazione Precisa.\nScorciatoia: s\n\nTraccia il verticale o l'orizzontale disegnando una linea sull'anteprima dell'immagine. L'angolo di rotazione verrà mostrato accanto alla linea guida. Il centro della rotazione è il centro geometrico dell'immagine. TOOLBAR_TOOLTIP_WB;Bilanciamento del bianco puntuale.\nScorciatoia: w +TP_BWMIX_ALGO;Algoritmo OYCPM TP_BWMIX_ALGO_LI;Lineare TP_BWMIX_ALGO_SP;Effetti speciali TP_BWMIX_ALGO_TOOLTIP;Lineare: produrrà una risposta normale lineare.\nEffetti speciali: produrrà effetti speciali miscelando i canali non-linearmente. -TP_BWMIX_ALGO;Algoritmo OYCPM TP_BWMIX_AUTOCH;Auto TP_BWMIX_CC_ENABLED;Regola il colore complementare TP_BWMIX_CC_TOOLTIP;Abilita per consentire le regolazioni automatiche dei colori complementari nella modalità ROYGCBPM. TP_BWMIX_CHANNEL;Equalizzatore di Luminanza +TP_BWMIX_CURVEEDITOR1;Curva 'Prima' +TP_BWMIX_CURVEEDITOR2;Curva 'Dopo' TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Curva Tono, dopo la conversione B&W, alla fine del trattamento. TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Curva Tono, appena prima della conversione B&W.\nPuò prendere in considerazione le componenti colore. TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminosità secondo Tonalità L=f(H).\nFai attenzione ai valori estermi: possono generare artefatti. -TP_BWMIX_CURVEEDITOR1;Curva 'Prima' -TP_BWMIX_CURVEEDITOR2;Curva 'Dopo' +TP_BWMIX_FILTER;Filtro Colore TP_BWMIX_FILTER_BLUE;Blu TP_BWMIX_FILTER_BLUEGREEN;Blu-Verde TP_BWMIX_FILTER_GREEN;Verde @@ -2195,19 +2194,20 @@ TP_BWMIX_FILTER_RED;Rosso TP_BWMIX_FILTER_REDYELLOW;Rosso-Giallo TP_BWMIX_FILTER_TOOLTIP;Il filtro colore simula uno scatto con un filtro colorato posto davanti all'obiettivo. I filtri colorati riducono la trasmissione di uno specifico intervallo di colori modificando la loro luminosità. Ad esempio, un filtro rosso scurisce i cieli blu. TP_BWMIX_FILTER_YELLOW;Giallo -TP_BWMIX_FILTER;Filtro Colore -TP_BWMIX_GAM_TOOLTIP;Corregge il gamma per ogni canale RGB. TP_BWMIX_GAMMA;Correzione Gamma +TP_BWMIX_GAM_TOOLTIP;Corregge il gamma per ogni canale RGB. TP_BWMIX_LABEL;Bianco-Nero +TP_BWMIX_MET;Metodo TP_BWMIX_MET_CHANMIX;Miscelatore Canali TP_BWMIX_MET_DESAT;Desaturazione TP_BWMIX_MET_LUMEQUAL;Equalizzatore di Luminanza -TP_BWMIX_MET;Metodo TP_BWMIX_MIXC;Miscelatore di canali TP_BWMIX_NEUTRAL;Ripristina -TP_BWMIX_RGB_TOOLTIP;Miscela i canali RGB. Usa i valori preimpostati per orientarti.\nFai attenzione ai valori negativi: possono causare artefatti o comportamenti imprevisti. -TP_BWMIX_RGBLABEL_HINT;Fattori RGB finali che si occupano di tutte le opzioni del miscelatore.\n"Totale" mostra la somma dei valori RGB:\n- sempre 100% nella modalità relativa\n- Più alto (luminoso) or più basso (scuro) del 100% nella modalità assoluta. TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totale: %4%% +TP_BWMIX_RGBLABEL_HINT;Fattori RGB finali che si occupano di tutte le opzioni del miscelatore.\n"Totale" mostra la somma dei valori RGB:\n- sempre 100% nella modalità relativa\n- Più alto (luminoso) or più basso (scuro) del 100% nella modalità assoluta. +TP_BWMIX_RGB_TOOLTIP;Miscela i canali RGB. Usa i valori preimpostati per orientarti.\nFai attenzione ai valori negativi: possono causare artefatti o comportamenti imprevisti. +TP_BWMIX_SETTING;Preimpostazioni +TP_BWMIX_SETTING_TOOLTIP;Impostazioni delle Preimpostazioni (pellicola, panorama, etc.) o del Miscelatore Canali manuale. TP_BWMIX_SET_HIGHCONTAST;Contrasto Elevato TP_BWMIX_SET_HIGHSENSIT;Sensibilità Elevata TP_BWMIX_SET_HYPERPANCHRO;Iper-Pancromatica @@ -2223,8 +2223,6 @@ TP_BWMIX_SET_RGBABS;RGB assoluto TP_BWMIX_SET_RGBREL;RGB relativo TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM assoluto TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM relativo -TP_BWMIX_SETTING_TOOLTIP;Impostazioni delle Preimpostazioni (pellicola, panorama, etc.) o del Miscelatore Canali manuale. -TP_BWMIX_SETTING;Preimpostazioni TP_BWMIX_TCMODE_FILMLIKE;BN tipo pellicola TP_BWMIX_TCMODE_SATANDVALBLENDING;BN Fusione Saturazione e Valore TP_BWMIX_TCMODE_STANDARD;BN Standard @@ -2235,8 +2233,8 @@ TP_CACORRECTION_LABEL;Correzione AC TP_CACORRECTION_RED;Rosso TP_CBDL_AFT;Dopo il bianco e nero TP_CBDL_BEF;Prima del bianco e nero -TP_CBDL_METHOD_TOOLTIP;Scegliere se lo strumento Contrasto per livelli di dettaglio deve essere posizionato dopo lo strumento Bianco e nero, che lo fa funzionare nello spazio L*a*b*, o prima di esso, che lo fa funzionare nello spazio RGB. TP_CBDL_METHOD;Processo individuato +TP_CBDL_METHOD_TOOLTIP;Scegliere se lo strumento Contrasto per livelli di dettaglio deve essere posizionato dopo lo strumento Bianco e nero, che lo fa funzionare nello spazio L*a*b*, o prima di esso, che lo fa funzionare nello spazio RGB. TP_CHMIXER_BLUE;Canale Blu TP_CHMIXER_GREEN;Canale Verde TP_CHMIXER_LABEL;Miscelatore Canali @@ -2247,50 +2245,50 @@ TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra.\nScorciatoie:\n] - Modalit TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente TP_COLORAPP_ABSOLUTELUMINANCE;Luminanza assoluta TP_COLORAPP_ADAPSCEN_TOOLTIP;Corrisponde alla luminanza in candele per m2 al momento dello scatto, calcolata automaticamente dai dati EXIF. +TP_COLORAPP_ALGO;Algoritmo TP_COLORAPP_ALGO_ALL;Tutto TP_COLORAPP_ALGO_JC;Chiarezza + Croma (JC) TP_COLORAPP_ALGO_JS;Chiarezza + Saturazione (JS) TP_COLORAPP_ALGO_QM;Brillanza + Pienezza (QM) TP_COLORAPP_ALGO_TOOLTIP;Scegli un sottoinsieme di parametri o tutti -TP_COLORAPP_ALGO;Algoritmo -TP_COLORAPP_BADPIXSL_TOOLTIP;Soppressione dei pixel surriscaldati/guasti (eccessivamente colorati).\n0 = nessun effetto\n1 = mediana\n2 = gaussiana.\n\nQuesti artefatti derivano dalle limitazioni di CIECAM02. Alternativamente, regola l'immagine per evitare ombre eccessivamente scure. TP_COLORAPP_BADPIXSL;Filtro pixel surriscaldati/guasti -TP_COLORAPP_BRIGHT_TOOLTIP;La Brillanza in CIECAM02 prende in considerazione la luminosità del bianco ed è diversa da quella in Lab e RGB. +TP_COLORAPP_BADPIXSL_TOOLTIP;Soppressione dei pixel surriscaldati/guasti (eccessivamente colorati).\n0 = nessun effetto\n1 = mediana\n2 = gaussiana.\n\nQuesti artefatti derivano dalle limitazioni di CIECAM02. Alternativamente, regola l'immagine per evitare ombre eccessivamente scure. TP_COLORAPP_BRIGHT;Brillanza (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;La Brillanza in CIECAM02 prende in considerazione la luminosità del bianco ed è diversa da quella in Lab e RGB. TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Quando si imposta manualmente, si consigliano valori superiori a 65. TP_COLORAPP_CATCLASSIC;Classico TP_COLORAPP_CATMET_TOOLTIP;Classico - funzionamento tradizionale CIECAM. Le trasformazioni dell'adattamento cromatico vengono applicate separatamente su 'Condizioni della scena' e illuminante di base da un lato, e su illuminante di base e 'Condizioni di visualizzazione' dall'altro.\n\nSimmetrico: l'adattamento cromatico si basa sul bilanciamento del bianco. Le impostazioni 'Condizioni scena', 'Regolazioni immagine' e 'Condizioni di visualizzazione' vengono neutralizzate.\n\nMisto: come l'opzione 'Classico' ma in questo caso l'adattamento cromatico si basa sul bilanciamento del bianco. TP_COLORAPP_CATMOD;Modo TP_COLORAPP_CATSYMGEN;Simmetrico automatico TP_COLORAPP_CATSYMSPE;Misto -TP_COLORAPP_CHROMA_M_TOOLTIP;La Pienezza in CIECAM02 è diversa da quella in Lab e RGB. -TP_COLORAPP_CHROMA_M;Pienezza (M) -TP_COLORAPP_CHROMA_S_TOOLTIP;La Saturazione in CIECAM02 è diversa da quella in Lab e RGB. -TP_COLORAPP_CHROMA_S;Saturazione (S) -TP_COLORAPP_CHROMA_TOOLTIP;Il Croma in CIECAM02 è diverso da quello in Lab e RGB. TP_COLORAPP_CHROMA;Croma (C) +TP_COLORAPP_CHROMA_M;Pienezza (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;La Pienezza in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA_S;Saturazione (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;La Saturazione in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Il Croma in CIECAM02 è diverso da quello in Lab e RGB. TP_COLORAPP_CIECAT_DEGREE;Adattamento CAT02 TP_COLORAPP_CIECAT_DEGREEOUT;Visualizzazione dell'adattamento cromatico -TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrasto per il cursore Q in CIECAM02; è diverso da quello in Lab e RGB. -TP_COLORAPP_CONTRAST_Q;Contrasto (Q) -TP_COLORAPP_CONTRAST_TOOLTIP;Contrasto per il cursore J in CIECAM02; è diverso da quello in Lab e RGB. TP_COLORAPP_CONTRAST;Contrasto (J) -TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Mostra l'istogramma di L (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, mostra gli istogrammi di J o Q dopo CIECAM02.\n\nJ e Q non sono mostrati nel pannello Istogramma.\n\nPer l'output finale fare riferimento al pannello Istogramma +TP_COLORAPP_CONTRAST_Q;Contrasto (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrasto per il cursore Q in CIECAM02; è diverso da quello in Lab e RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Contrasto per il cursore J in CIECAM02; è diverso da quello in Lab e RGB. TP_COLORAPP_CURVEEDITOR1;Curva Tono 1 -TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Stesso utilizzo della Curva Tono 2 di Esposizione +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Mostra l'istogramma di L (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, mostra gli istogrammi di J o Q dopo CIECAM02.\n\nJ e Q non sono mostrati nel pannello Istogramma.\n\nPer l'output finale fare riferimento al pannello Istogramma TP_COLORAPP_CURVEEDITOR2;Curva Tono 2 -TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Regola Croma, Saturazione o Pienezza.\nL'Istogramma mostra la Cromaticità (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, l'Istogramma mostra C, s e M dopo CIECAM02.\nC, s e M non sono mostrati direttamente nel pannello Istogramma.\nPer l'output finale fare riferimento al pannello Istogramma +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Stesso utilizzo della Curva Tono 2 di Esposizione TP_COLORAPP_CURVEEDITOR3;Curva Colore -TP_COLORAPP_DATACIE_TOOLTIP;Quando abilitato, gli istogrammi nelle curve CIECAM02 mostrano valori e intervalli approssimati di J o Q, e C, s o M dopo le regolazioni CIECAM02.\nQuesta selezione non ha effetto nel pannello Istogramma principale.\n\nQuando disabilitato, gli istogrammi nelle curve CIECAM02 mostrano i valori Lab, come sono prima delle regolazioni CIECAM02. +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Regola Croma, Saturazione o Pienezza.\nL'Istogramma mostra la Cromaticità (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, l'Istogramma mostra C, s e M dopo CIECAM02.\nC, s e M non sono mostrati direttamente nel pannello Istogramma.\nPer l'output finale fare riferimento al pannello Istogramma TP_COLORAPP_DATACIE;Mostra gli istogrammi di uscita CIECAM02 nelle curve +TP_COLORAPP_DATACIE_TOOLTIP;Quando abilitato, gli istogrammi nelle curve CIECAM02 mostrano valori e intervalli approssimati di J o Q, e C, s o M dopo le regolazioni CIECAM02.\nQuesta selezione non ha effetto nel pannello Istogramma principale.\n\nQuando disabilitato, gli istogrammi nelle curve CIECAM02 mostrano i valori Lab, come sono prima delle regolazioni CIECAM02. TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 è un adattamento cromatico. Converte i valori di un'immagine il cui punto di bianco è quello di un dato illuminante (ad esempio D65) in nuovi valori il cui punto di bianco è quello del nuovo illuminante - vedi modello WP (ad esempio D50 o D55). TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 è un adattamento cromatico. Converte i valori di un'immagine il cui punto di bianco è quello di un dato illuminante (ad esempio D50) in nuovi valori il cui punto di bianco è quello del nuovo illuminante - vedi modello WP (ad esempio D75). TP_COLORAPP_FREE;Temp. libera + tinta + CAT02/16 +[uscita] TP_COLORAPP_GAMUT;Controllo Gamut (Lab) -TP_COLORAPP_GEN_TOOLTIP;Questo modulo si basa sui modelli di aspetto del colore CIECAM, progettati per simulare meglio il modo in cui la visione umana percepisce i colori in diverse condizioni di illuminazione, ad es. contro contesti diversi. Tiene conto dell'ambiente di ciascun colore e ne modifica l'aspetto per avvicinarsi il più possibile alla percezione umana. Inoltre, adatta l'output alle condizioni di visualizzazione previste (monitor, TV, proiettore, stampante, ecc.) in modo che l'aspetto cromatico venga preservato nella scena e negli ambienti di visualizzazione. TP_COLORAPP_GEN;Impostazioni -TP_COLORAPP_HUE_TOOLTIP;Tinta (h) - angolo tra 0° e 360° +TP_COLORAPP_GEN_TOOLTIP;Questo modulo si basa sui modelli di aspetto del colore CIECAM, progettati per simulare meglio il modo in cui la visione umana percepisce i colori in diverse condizioni di illuminazione, ad es. contro contesti diversi. Tiene conto dell'ambiente di ciascun colore e ne modifica l'aspetto per avvicinarsi il più possibile alla percezione umana. Inoltre, adatta l'output alle condizioni di visualizzazione previste (monitor, TV, proiettore, stampante, ecc.) in modo che l'aspetto cromatico venga preservato nella scena e negli ambienti di visualizzazione. TP_COLORAPP_HUE;Tinta (h) +TP_COLORAPP_HUE_TOOLTIP;Tinta (h) - angolo tra 0° e 360° TP_COLORAPP_IL41;D41 TP_COLORAPP_IL50;D50 TP_COLORAPP_IL55;D55 @@ -2299,33 +2297,33 @@ TP_COLORAPP_IL65;D65 TP_COLORAPP_IL75;D75 TP_COLORAPP_ILA;Incandescente StdA 2856K TP_COLORAPP_ILFREE;Libero -TP_COLORAPP_ILLUM_TOOLTIP;Seleziona l'illuminante più vicino alle condizioni di scatto.\nIn generale D50, ma può cambiare a seconda dell'ora e della latitudine. TP_COLORAPP_ILLUM;Illuminante +TP_COLORAPP_ILLUM_TOOLTIP;Seleziona l'illuminante più vicino alle condizioni di scatto.\nIn generale D50, ma può cambiare a seconda dell'ora e della latitudine. +TP_COLORAPP_LABEL;Modello di Aspetto Colore CIE 2002 TP_COLORAPP_LABEL_CAM02;Regolazioni Immagine TP_COLORAPP_LABEL_SCENE;Caratteristiche della scena TP_COLORAPP_LABEL_VIEWING;Caratteristiche della visualizzazione -TP_COLORAPP_LABEL;Modello di Aspetto Colore CIE 2002 -TP_COLORAPP_LIGHT_TOOLTIP;La Chiarezza in CIECAM02 è diversa da quella in Lab e RGB. TP_COLORAPP_LIGHT;Chiarezza (J) +TP_COLORAPP_LIGHT_TOOLTIP;La Chiarezza in CIECAM02 è diversa da quella in Lab e RGB. TP_COLORAPP_MEANLUMINANCE;Luminanza media (Yb%) TP_COLORAPP_MOD02;CAM02 TP_COLORAPP_MOD16;CAM16 -TP_COLORAPP_MODEL_TOOLTIP;Modello del Punto di bianco.\n\nWB [RT] + [output]: Per la scena viene usato il Bilanciamento del Bianco di RT, CIECAM02 è impostato a D50, il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore.\n\nWB [RT+CAT02] + [output]: Le impostazioni di Bilanciamento del Bianco di RT sono utilizzate da CAT02 e il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore. TP_COLORAPP_MODEL;Modello del Punto di Bianco -TP_COLORAPP_MODELCAT_TOOLTIP;Ti consente di scegliere tra CAM02 o CAM16.\nCAM02 a volte sarà più preciso.\nCAM16 dovrebbe generare meno artefatti. TP_COLORAPP_MODELCAT;CAM -TP_COLORAPP_NEUTRAL_TOOLTIP;Ripristina tutte le caselle di controllo e le curve dei cursori ai valori predefiniti. +TP_COLORAPP_MODELCAT_TOOLTIP;Ti consente di scegliere tra CAM02 o CAM16.\nCAM02 a volte sarà più preciso.\nCAM16 dovrebbe generare meno artefatti. +TP_COLORAPP_MODEL_TOOLTIP;Modello del Punto di bianco.\n\nWB [RT] + [output]: Per la scena viene usato il Bilanciamento del Bianco di RT, CIECAM02 è impostato a D50, il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore.\n\nWB [RT+CAT02] + [output]: Le impostazioni di Bilanciamento del Bianco di RT sono utilizzate da CAT02 e il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore. TP_COLORAPP_NEUTRAL;Reset -TP_COLORAPP_RSTPRO_TOOLTIP;Protezione dei toni rossi e dell'incarnato (cursori e curve) +TP_COLORAPP_NEUTRAL_TOOLTIP;Ripristina tutte le caselle di controllo e le curve dei cursori ai valori predefiniti. TP_COLORAPP_RSTPRO;Protezione rossi e incarnato +TP_COLORAPP_RSTPRO_TOOLTIP;Protezione dei toni rossi e dell'incarnato (cursori e curve) TP_COLORAPP_SOURCEF_TOOLTIP;Corrisponde alle condizioni di ripresa e a come riportare le condizioni e i dati in un'area "normale". Normale significa condizioni e dati medi o standard, ovvero senza tenere conto delle correzioni CIECAM. +TP_COLORAPP_SURROUND;Ambiente +TP_COLORAPP_SURROUNDSRC;Circondare TP_COLORAPP_SURROUND_AVER;Medio TP_COLORAPP_SURROUND_DARK;Scuro TP_COLORAPP_SURROUND_DIM;Fioco TP_COLORAPP_SURROUND_EXDARK;Estremamente Scuro (Pieghevole) TP_COLORAPP_SURROUND_TOOLTIP;Cambia toni e colori per tenere conto delle condizioni di visualizzazione del dispositivo di uscita\n\nMedio: Ambiente mediamente illuminato (standard)\nL'immagine non verrà modificata.\n\nFioco: Ambiente fioco (TV)\nL'immagine diverrà leggermente più scura\n\nScuro: Ambiente scuro (proiettore)\nL'immagine diventerà più scura\n\nEstremamente Scuro: Ambiente buio (Pieghevole)\nL'immagine diventerà molto più scura. -TP_COLORAPP_SURROUND;Ambiente -TP_COLORAPP_SURROUNDSRC;Circondare TP_COLORAPP_SURSOURCE_TOOLTIP;Modifica toni e colori per tenere conto delle condizioni circostanti dell'illuminazione della scena. Quanto più scure sono le condizioni circostanti, tanto più luminosa risulterà l'immagine. La luminosità dell'immagine non verrà modificata quando il surround è impostato su medio. TP_COLORAPP_TCMODE_BRIGHTNESS;Brillanza TP_COLORAPP_TCMODE_CHROMA;Croma @@ -2335,13 +2333,13 @@ TP_COLORAPP_TCMODE_LABEL2;Modo Curva 2 TP_COLORAPP_TCMODE_LABEL3;Modo Curva Croma TP_COLORAPP_TCMODE_LIGHTNESS;Chiarezza TP_COLORAPP_TCMODE_SATUR;Saturazione -TP_COLORAPP_TEMP_TOOLTIP;Per selezionare un illuminante impostare sempre Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 TP_COLORAPP_TEMP2_TOOLTIP;Modalità simmetrica Temp = Bilanciamento del bianco.\nSeleziona illuminante impostato sempre Tinta=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504 \nD75 temperatura=7504 TP_COLORAPP_TEMPOUT_TOOLTIP;Temperatura e Tinta.\nA seconda delle scelte effettuate in precedenza, la temperatura selezionata è:\nBilanciamento del bianco\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504 \nD75 temp=7504\nLibero. -TP_COLORAPP_TONECIE_TOOLTIP;Se questa opzione è disabilitata, il Tone Mapping è eseguito nello spazio Lab.\nSe l'opzione è abilitata, il Tone Mapping è fatto usando CIECAM02.\nLo strumento Tone Mapping (Lab/CIECAM02) deve essere abilitato affinché questa impostazione abbia effetto. +TP_COLORAPP_TEMP_TOOLTIP;Per selezionare un illuminante impostare sempre Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 TP_COLORAPP_TONECIE;Tone mapping con CIECAM02 -TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Luminanza assoluta dell'ambiente di visualizzazione\n(normalmente 16cd/m²). +TP_COLORAPP_TONECIE_TOOLTIP;Se questa opzione è disabilitata, il Tone Mapping è eseguito nello spazio Lab.\nSe l'opzione è abilitata, il Tone Mapping è fatto usando CIECAM02.\nLo strumento Tone Mapping (Lab/CIECAM02) deve essere abilitato affinché questa impostazione abbia effetto. TP_COLORAPP_VIEWINGF_TOOLTIP;Tiene conto del supporto su cui verrà visualizzata l'immagine finale (monitor, TV, proiettore, stampante, ecc.), nonché del suo ambiente. Questo processo prenderà i dati provenienti dal processo 'Regolazioni immagine' e li 'porterà' al supporto in modo tale che le condizioni di visualizzazione e il suo ambiente siano presi in considerazione. +TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Luminanza assoluta dell'ambiente di visualizzazione\n(normalmente 16cd/m²). TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] TP_COLORAPP_WBRT;WB [RT] + [output] TP_COLORAPP_YBOUT_TOOLTIP;Yb è la luminanza relativa dello sfondo, espressa in % di grigio. Il 18% di grigio corrisponde ad una luminanza di sfondo del 50% espressa in CIE L.\nI dati si basano sulla luminanza media dell'immagine. @@ -2357,14 +2355,15 @@ TP_COLORTONING_HIGHLIGHT;Alteluci TP_COLORTONING_HUE;Tonalità TP_COLORTONING_LAB;L*a*b* miscelazione TP_COLORTONING_LABEL;Toni Colore -TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 TP_COLORTONING_LABGRID;L*a*b* griglia correzione colore +TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 +TP_COLORTONING_LABREGIONS;Zona correzione colore TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 +TP_COLORTONING_LABREGION_CHANNEL;Canale TP_COLORTONING_LABREGION_CHANNEL_ALL;Tutto TP_COLORTONING_LABREGION_CHANNEL_B;Blu TP_COLORTONING_LABREGION_CHANNEL_G;Verde TP_COLORTONING_LABREGION_CHANNEL_R;Rosso -TP_COLORTONING_LABREGION_CHANNEL;Canale TP_COLORTONING_LABREGION_CHROMATICITYMASK;C TP_COLORTONING_LABREGION_HUEMASK;H TP_COLORTONING_LABREGION_LIGHTNESS;Luminosità @@ -2377,15 +2376,14 @@ TP_COLORTONING_LABREGION_POWER;Potenza TP_COLORTONING_LABREGION_SATURATION;Saturazione TP_COLORTONING_LABREGION_SHOWMASK;Mostra maschera TP_COLORTONING_LABREGION_SLOPE;Pendenza -TP_COLORTONING_LABREGIONS;Zona correzione colore TP_COLORTONING_LUMA;Luminanza -TP_COLORTONING_LUMAMODE_TOOLTIP;Se abilitato, quando si cambia colore (rosso, verde, ciano, blu, ecc.) viene preservata la luminanza di ciascun pixel. TP_COLORTONING_LUMAMODE;Preserva la luminanza -TP_COLORTONING_METHOD_TOOLTIP;"Miscelazione L*a*b*", "Cursori RGB" e "Curve RGB" utilizzano la fusione dei colori interpolati.\n"Bilanciamento colore (ombre/mezzitoni/luci)" e "Saturazione 2 colori" utilizzano colori diretti.\n\ nLo strumento Bianco e nero può essere abilitato quando si utilizza qualsiasi metodo di tonalità del colore che consenta la tonalità del colore. +TP_COLORTONING_LUMAMODE_TOOLTIP;Se abilitato, quando si cambia colore (rosso, verde, ciano, blu, ecc.) viene preservata la luminanza di ciascun pixel. TP_COLORTONING_METHOD;Metodo +TP_COLORTONING_METHOD_TOOLTIP;"Miscelazione L*a*b*", "Cursori RGB" e "Curve RGB" utilizzano la fusione dei colori interpolati.\n"Bilanciamento colore (ombre/mezzitoni/luci)" e "Saturazione 2 colori" utilizzano colori diretti.\n\ nLo strumento Bianco e nero può essere abilitato quando si utilizza qualsiasi metodo di tonalità del colore che consenta la tonalità del colore. TP_COLORTONING_MIDTONES;Mezzitoni -TP_COLORTONING_NEUTRAL_TOOLTIP;Ripristina tutti i valori (ombre, mezzitoni, luci) ai valori predefiniti. TP_COLORTONING_NEUTRAL;Ripristina i cursori +TP_COLORTONING_NEUTRAL_TOOLTIP;Ripristina tutti i valori (ombre, mezzitoni, luci) ai valori predefiniti. TP_COLORTONING_OPACITY;Opacità: TP_COLORTONING_RGBCURVES;RGB - Curve TP_COLORTONING_RGBSLIDERS;RGB - Cursori @@ -2436,21 +2434,21 @@ TP_DEHAZE_STRENGTH;Intensità TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Multizona automatica TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Globale automatico TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Crominanza - Blu-Giallo -TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Aumenta (moltiplica) il valore di tutti i cursori della crominanza.\nQuesta curva consente di regolare l'intensità della riduzione del rumore cromatico in funzione della cromaticità, ad esempio per aumentare l'azione nelle aree a bassa saturazione e per diminuirla in quelle ad alta saturazione. TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Curva di crominanza +TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Aumenta (moltiplica) il valore di tutti i cursori della crominanza.\nQuesta curva consente di regolare l'intensità della riduzione del rumore cromatico in funzione della cromaticità, ad esempio per aumentare l'azione nelle aree a bassa saturazione e per diminuirla in quelle ad alta saturazione. TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Crominanza TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Manuale TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Crominanza (Principale) -TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manuale\nAgisce sull'immagine intera.\nControlli manualmente le impostazioni di riduzione del rumore.\n\nGlobale automatico\nAgisce sull'immagine intera.\n9 zone vengono utilizzate per calcolare un'impostazione globale di riduzione del rumore della crominanza.\n\nMultizone automatiche \nNessuna anteprima: funziona solo durante il salvataggio, ma utilizzando il metodo 'Anteprima' facendo corrispondere la dimensione e il centro della tessera alla dimensione e al centro dell'anteprima puoi avere un'idea dei risultati attesi.\nL'immagine è divisa in tessere (da circa 10 a 70 a seconda della dimensione dell'immagine) e ogni riquadro riceve le proprie impostazioni di riduzione del rumore della crominanza.\n\nAnteprima\nAgisce sull'intera immagine.\nLa parte dell'immagine visibile nell'anteprima viene utilizzata per calcolare le impostazioni globali di riduzione del rumore della crominanza. TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Metodo TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Manuale\nAgisce sull'immagine intera.\nControlli manualmente le impostazioni di riduzione del rumore.\n\nGlobale automatico\nAgisce sull'immagine intera.\n9 zone vengono utilizzate per calcolare un'impostazione globale di riduzione del rumore della crominanza.\n\nAnteprima\nAgisce su l'intera immagine.\nLa parte dell'immagine visibile nell'anteprima viene utilizzata per calcolare le impostazioni globali di riduzione del rumore della crominanza. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Manuale\nAgisce sull'immagine intera.\nControlli manualmente le impostazioni di riduzione del rumore.\n\nGlobale automatico\nAgisce sull'immagine intera.\n9 zone vengono utilizzate per calcolare un'impostazione globale di riduzione del rumore della crominanza.\n\nMultizone automatiche \nNessuna anteprima: funziona solo durante il salvataggio, ma utilizzando il metodo 'Anteprima' facendo corrispondere la dimensione e il centro della tessera alla dimensione e al centro dell'anteprima puoi avere un'idea dei risultati attesi.\nL'immagine è divisa in tessere (da circa 10 a 70 a seconda della dimensione dell'immagine) e ogni riquadro riceve le proprie impostazioni di riduzione del rumore della crominanza.\n\nAnteprima\nAgisce sull'intera immagine.\nLa parte dell'immagine visibile nell'anteprima viene utilizzata per calcolare le impostazioni globali di riduzione del rumore della crominanza. TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Anteprima multizona -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Dimensione anteprima=%1, Centro: Px=%2 Py=%3 -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Preview noise: Mean= - High= - -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Rumore dell'anteprima: Medio=%1 Alto=%2 -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Dimensione tessera=%1, Centro: Tx=%2 Ty=%3 TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Anteprima TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Visualizza i livelli di rumore rimanenti della parte dell'immagine visibile nell'anteprima dopo il wavelet.\n\n>300 Molto rumoroso\n100-300 Rumoroso\n50-100 Un po' rumoroso\n<50 Rumore molto basso\n\nAttenzione, i valori differiranno tra la modalità RGB e L*a*b*. I valori RGB sono meno accurati perché la modalità RGB non separa completamente luminanza e crominanza. +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Dimensione anteprima=%1, Centro: Px=%2 Py=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Rumore dell'anteprima: Medio=%1 Alto=%2 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Preview noise: Mean= - High= - +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Dimensione tessera=%1, Centro: Tx=%2 Ty=%3 TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Crominanza - Rosso-Verde TP_DIRPYRDENOISE_LABEL;Riduzione del rumore TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Controllo della luminanza @@ -2458,18 +2456,19 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Curva di luminanza TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Dettaglio di Luminanza TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminanza TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminanza -TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Modificare l'intensità della riduzione del rumore in base alla luminosità dell'immagine. L'intensità viene ridotta per le immagini scure e aumentata per le immagini luminose. TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensazione per leggerezza +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Modificare l'intensità della riduzione del rumore in base alla luminosità dell'immagine. L'intensità viene ridotta per le immagini scure e aumentata per le immagini luminose. +TP_DIRPYRDENOISE_MAIN_COLORSPACE;Metodo TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;Lab TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Per immagini raw può essere usato il metodo RGB o Lab.\n\nPer immagini non raw verrà utilizzato il metodo Lab, indipendentemente dalla selezione. -TP_DIRPYRDENOISE_MAIN_COLORSPACE;Metodo -TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Il gamma varia la forza della riduzione rumore su tutto l'intervallo di toni. Valori più piccoli incideranno sulle ombre, mentre valori maggiori estenderanno l'effetto ai toni più luminosi. TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma +TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Il gamma varia la forza della riduzione rumore su tutto l'intervallo di toni. Valori più piccoli incideranno sulle ombre, mentre valori maggiori estenderanno l'effetto ai toni più luminosi. +TP_DIRPYRDENOISE_MAIN_MODE;Modo TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Aggressivo TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Conservativo TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;Il conservativo preserva i modelli di crominanza a bassa frequenza, mentre l'aggressivo li cancella. -TP_DIRPYRDENOISE_MAIN_MODE;Modo +TP_DIRPYRDENOISE_MEDIAN_METHOD;Metodo mediano TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Solo crominanza TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Filtro mediano @@ -2477,30 +2476,29 @@ TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Solo luminanza TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;Quando si utilizzano i metodi "Solo luminanza" e "L*a*b*", il filtraggio mediano verrà eseguito subito dopo il passaggio wavelet nella pipeline di riduzione del rumore.\nQuando si utilizza la modalità "RGB", verrà eseguito proprio fine del gasdotto di riduzione del rumore. TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Ponderato L* (poco) + a*b* (normale) -TP_DIRPYRDENOISE_MEDIAN_METHOD;Metodo mediano -TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;L'applicazione di tre iterazioni del filtro mediano con una dimensione della finestra 3×3 spesso porta a risultati migliori rispetto all'utilizzo di un'iterazione del filtro mediano con una dimensione della finestra 7×7. TP_DIRPYRDENOISE_MEDIAN_PASSES;Iterazioni mediane -TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Applicare un filtro medio della dimensione della finestra desiderata. Maggiore è la dimensione della finestra, maggiore è il tempo necessario.\n\n3×3 soft: tratta 5 pixel in una finestra di 3×3 pixel.\n3×3: tratta 9 pixel in una finestra di 3×3 pixel.\n5×5 soft: tratta 13 pixel in una finestra da 5×5 pixel.\n5×5: tratta 25 pixel in una finestra da 5×5 pixel.\n7×7: tratta 49 pixel in una finestra da 7×7 pixel.\n9×9: tratta 81 pixel in una finestra di 9×9 pixel.\n\nA volte è possibile ottenere una qualità superiore eseguendo diverse iterazioni con una dimensione della finestra più piccola rispetto a un'iterazione con una più grande. +TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;L'applicazione di tre iterazioni del filtro mediano con una dimensione della finestra 3×3 spesso porta a risultati migliori rispetto all'utilizzo di un'iterazione del filtro mediano con una dimensione della finestra 7×7. TP_DIRPYRDENOISE_MEDIAN_TYPE;Tipo mediano +TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Applicare un filtro medio della dimensione della finestra desiderata. Maggiore è la dimensione della finestra, maggiore è il tempo necessario.\n\n3×3 soft: tratta 5 pixel in una finestra di 3×3 pixel.\n3×3: tratta 9 pixel in una finestra di 3×3 pixel.\n5×5 soft: tratta 13 pixel in una finestra da 5×5 pixel.\n5×5: tratta 25 pixel in una finestra da 5×5 pixel.\n7×7: tratta 49 pixel in una finestra da 7×7 pixel.\n9×9: tratta 81 pixel in una finestra di 9×9 pixel.\n\nA volte è possibile ottenere una qualità superiore eseguendo diverse iterazioni con una dimensione della finestra più piccola rispetto a un'iterazione con una più grande. TP_DIRPYRDENOISE_TYPE_3X3;3×3 TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 soft TP_DIRPYRDENOISE_TYPE_5X5;5×5 TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 soft TP_DIRPYRDENOISE_TYPE_7X7;7×7 TP_DIRPYRDENOISE_TYPE_9X9;9×9 -TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: più simile ai colori dell'incarnato, minimizzando l'azione di altri colori\nAmpio: evita ulteriori artefatti TP_DIRPYREQUALIZER_ALGO;Algoritmo Pelle +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: più simile ai colori dell'incarnato, minimizzando l'azione di altri colori\nAmpio: evita ulteriori artefatti TP_DIRPYREQUALIZER_ARTIF;Ridurre gli artefatti -TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Questa piramide è per la parte superiore, con l'algoritmo alla sua massima efficienza.\nNella parte inferiore, le zone di transizione.\nSe devi muovere in modo significativo la zona verso destra o verso sinistra (o se ci sono artefatti): il bilanciamento del bianco è sbagliato\nPuoi ridurre leggermente la zona per evitare che la parte rimante dell'immagine ne sia influenzata TP_DIRPYREQUALIZER_HUESKIN;Tonalità della Pelle +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Questa piramide è per la parte superiore, con l'algoritmo alla sua massima efficienza.\nNella parte inferiore, le zone di transizione.\nSe devi muovere in modo significativo la zona verso destra o verso sinistra (o se ci sono artefatti): il bilanciamento del bianco è sbagliato\nPuoi ridurre leggermente la zona per evitare che la parte rimante dell'immagine ne sia influenzata TP_DIRPYREQUALIZER_LABEL;Contrasto per livelli di dettaglio (CbDL) TP_DIRPYREQUALIZER_LUMACOARSEST;Estesissimo TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrasto- TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrasto+ TP_DIRPYREQUALIZER_LUMAFINEST;Finissimo TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutro -TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100 i toni della pelle sono elaborati.\nA 0 tutti i toni sono trattati allo stesso modo.\nA +100 i toni della pelle sono protetti mentre gli altri toni sono elaborati. TP_DIRPYREQUALIZER_SKIN;Toni della Pelle - Elaborazione/Protezione +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100 i toni della pelle sono elaborati.\nA 0 tutti i toni sono trattati allo stesso modo.\nA +100 i toni della pelle sono protetti mentre gli altri toni sono elaborati. TP_DIRPYREQUALIZER_THRESHOLD;Soglia TP_DIRPYREQUALIZER_TOOLTIP;Tenta di ridurre gli artefatti dovuti alle transizioni tra colori (tonalità, croma, luma) dell'incarnato e del resto dell'immagine TP_DISTORTION_AMOUNT;Quantità @@ -2512,25 +2510,23 @@ TP_EPD_LABEL;Tone Mapping TP_EPD_REWEIGHTINGITERATES;Iterazioni di Ribilanciamento TP_EPD_SCALE;Scala TP_EPD_STRENGTH;Intensità -TP_EXPOS_BLACKPOINT_LABEL;Raw Punto di nero -TP_EXPOS_WHITEPOINT_LABEL;Raw Punto di bianco -TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Abilita l'esecuzione dei livelli automatici per impostare automaticamente il cursore Esposizione in base all'analisi dell'immagine.\nSe necessario, abilita Ricostruzione Alteluci. TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Abilita l'esecuzione dei livelli automatici per impostare automaticamente il cursore Esposizione in base all'analisi dell'immagine.\nSe necessario, abilita Ricostruzione Alteluci. TP_EXPOSURE_BLACKLEVEL;Livello del nero TP_EXPOSURE_BRIGHTNESS;Luminosità TP_EXPOSURE_CLAMPOOG;Ritaglia i colori fuori gamma -TP_EXPOSURE_CLIP_TOOLTIP;La frazione di pixel da tosare nell'operazione di livelli automatici. TP_EXPOSURE_CLIP;Tosaggio % +TP_EXPOSURE_CLIP_TOOLTIP;La frazione di pixel da tosare nell'operazione di livelli automatici. TP_EXPOSURE_COMPRHIGHLIGHTS;Compressione Alteluci TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Soglia di Compressione Alteluci TP_EXPOSURE_COMPRSHADOWS;Compressione Ombre TP_EXPOSURE_CONTRAST;Contrasto TP_EXPOSURE_CURVEEDITOR1;Curva Tono 1 -TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Fare riferimento alla pagina "Exposure > Tone Curves" di RawPedia per capire come ottenere i risultati migliori con le doppie curve. TP_EXPOSURE_CURVEEDITOR2;Curva Tono 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Fare riferimento alla pagina "Exposure > Tone Curves" di RawPedia per capire come ottenere i risultati migliori con le doppie curve. TP_EXPOSURE_EXPCOMP;Compensazione Esposizione -TP_EXPOSURE_HISTMATCHING_TOOLTIP;Regola automaticamente i cursori e le curve (eccetto la compensazione dell'esposizione) per adattarli all'aspetto della miniatura JPEG incorporata. TP_EXPOSURE_HISTMATCHING;Curva di tono con abbinamento automatico +TP_EXPOSURE_HISTMATCHING_TOOLTIP;Regola automaticamente i cursori e le curve (eccetto la compensazione dell'esposizione) per adattarli all'aspetto della miniatura JPEG incorporata. TP_EXPOSURE_LABEL;Esposizione TP_EXPOSURE_SATURATION;Saturazione TP_EXPOSURE_TCMODE_FILMLIKE;Pellicola @@ -2541,19 +2537,21 @@ TP_EXPOSURE_TCMODE_PERCEPTUAL;Percentule TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Fusione Saturazione/Valore TP_EXPOSURE_TCMODE_STANDARD;Standard TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Standard Pesata +TP_EXPOS_BLACKPOINT_LABEL;Raw Punto di nero +TP_EXPOS_WHITEPOINT_LABEL;Raw Punto di bianco TP_FILMNEGATIVE_BLUE;Rapporto blu TP_FILMNEGATIVE_BLUEBALANCE;Caldo/Freddo +TP_FILMNEGATIVE_COLORSPACE;Inversione spazio colore: TP_FILMNEGATIVE_COLORSPACE_INPUT;Spazio colore in ingresso TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Seleziona lo spazio colore utilizzato per eseguire l'inversione negativa:\nSpazio colore di input: esegue l'inversione prima che venga applicato il profilo di input, come nelle versioni precedenti di RT.\nSpazio colore di lavoro< /b>: esegue l'inversione dopo il profilo di input, utilizzando il profilo di lavoro attualmente selezionato. TP_FILMNEGATIVE_COLORSPACE_WORKING;Spazio colore di lavoro -TP_FILMNEGATIVE_COLORSPACE;Inversione spazio colore: TP_FILMNEGATIVE_GREEN;Esponente di riferimento TP_FILMNEGATIVE_GREENBALANCE;Magenta/Verde TP_FILMNEGATIVE_GUESS_TOOLTIP;Imposta automaticamente i rapporti rosso e blu selezionando due patch che avevano una tonalità neutra (nessun colore) nella scena originale. Le patch dovrebbero differire in luminosità. TP_FILMNEGATIVE_LABEL;Negativo Pellicola TP_FILMNEGATIVE_OUT_LEVEL;Livelli di uscita -TP_FILMNEGATIVE_PICK_SIZE;Misura: TP_FILMNEGATIVE_PICK;Scegli punti neutri +TP_FILMNEGATIVE_PICK_SIZE;Misura: TP_FILMNEGATIVE_RED;Rapporto rosso TP_FILMNEGATIVE_REF_LABEL;Ingresso RGB: %1 TP_FILMNEGATIVE_REF_PICK;Scegli il punto di WB @@ -2570,23 +2568,23 @@ TP_FLATFIELD_BT_AREA;Area TP_FLATFIELD_BT_HORIZONTAL;Orizzontale TP_FLATFIELD_BT_VERTHORIZ;Vert. + Oriz. TP_FLATFIELD_BT_VERTICAL;Verticale -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Il controllo clip evita le evidenziazioni ritagliate causate dall'applicazione del flat field. Se sono già presenti luci ritagliate prima dell'applicazione del flat field, viene utilizzato il valore 0. TP_FLATFIELD_CLIPCONTROL;Controllo della clip +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Il controllo clip evita le evidenziazioni ritagliate causate dall'applicazione del flat field. Se sono già presenti luci ritagliate prima dell'applicazione del flat field, viene utilizzato il valore 0. TP_FLATFIELD_FROMMETADATA;Da Metadata TP_FLATFIELD_LABEL;Flat Field TP_GENERAL_11SCALE_TOOLTIP;L'effetto di questo strumento è visibile solo (o è accurato solo) con l'anteprima in scala 1:1. -TP_GRADIENT_CENTER_X_TOOLTIP;Sposta il gradiente a sinistra (valori negativi) o a destra (valori positivi). -TP_GRADIENT_CENTER_X;Centro X -TP_GRADIENT_CENTER_Y_TOOLTIP;Sposta il gradiente su (valori negativi) o giù (valori positivi). -TP_GRADIENT_CENTER_Y;Centro Y TP_GRADIENT_CENTER;Centro -TP_GRADIENT_DEGREE_TOOLTIP;Angolo di rotazione in gradi. +TP_GRADIENT_CENTER_X;Centro X +TP_GRADIENT_CENTER_X_TOOLTIP;Sposta il gradiente a sinistra (valori negativi) o a destra (valori positivi). +TP_GRADIENT_CENTER_Y;Centro Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Sposta il gradiente su (valori negativi) o giù (valori positivi). TP_GRADIENT_DEGREE;Angolo -TP_GRADIENT_FEATHER_TOOLTIP;Ampiezza del gradiente in percento della diagonale dell'immagine. +TP_GRADIENT_DEGREE_TOOLTIP;Angolo di rotazione in gradi. TP_GRADIENT_FEATHER;Scia +TP_GRADIENT_FEATHER_TOOLTIP;Ampiezza del gradiente in percento della diagonale dell'immagine. TP_GRADIENT_LABEL;Filtro Graduato -TP_GRADIENT_STRENGTH_TOOLTIP;intensità del filtro in stop. TP_GRADIENT_STRENGTH;intensità +TP_GRADIENT_STRENGTH_TOOLTIP;intensità del filtro in stop. TP_HLREC_BLEND;Fusione TP_HLREC_CIELAB;Fusione in CIELab TP_HLREC_COLOR;Propagazione di crominanza @@ -2602,66 +2600,69 @@ TP_HSVEQUALIZER_HUE;H TP_HSVEQUALIZER_LABEL;Equalizzatore HSV TP_HSVEQUALIZER_SAT;S TP_HSVEQUALIZER_VAL;V -TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Utilizzare la compensazione dell'esposizione di base DCP incorporata. L'impostazione è disponibile solo se il DCP selezionato ne ha uno. TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Esposizione di base -TP_ICM_APPLYHUESATMAP_TOOLTIP;Utilizza la tabella base DCP incorporata (HueSatMap). L'impostazione è disponibile solo se il DCP selezionato ne ha uno. +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Utilizzare la compensazione dell'esposizione di base DCP incorporata. L'impostazione è disponibile solo se il DCP selezionato ne ha uno. TP_ICM_APPLYHUESATMAP;Tabella base -TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. +TP_ICM_APPLYHUESATMAP_TOOLTIP;Utilizza la tabella base DCP incorporata (HueSatMap). L'impostazione è disponibile solo se il DCP selezionato ne ha uno. TP_ICM_APPLYLOOKTABLE;Guarda la tabella +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. TP_ICM_BPC;Compensazione punto di nero +TP_ICM_DCPILLUMINANT;Illuminazione TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolato TP_ICM_DCPILLUMINANT_TOOLTIP;Seleziona il DCP del tipo di illuminazione da utilizzare. Il predefinito è "interpolato", un mix tra i due basato sul bilanciamento del bianco. Questa impostazione è abilitata solo se è selezionato Doppia Illuminazione con supporto interpolato. -TP_ICM_DCPILLUMINANT;Illuminazione TP_ICM_FBW;Bianco e Nero TP_ICM_GAMUT;Controllo della gamma TP_ICM_ILLUMPRIM_TOOLTIP;Scegli l'illuminante più vicino alle condizioni di ripresa.\nLe modifiche possono essere apportate solo quando la selezione "Destinazione primarie" è impostata su "Personalizzato (cursori)". -TP_ICM_INPUTCAMERA_TOOLTIP;Utilizza i semplici color matrix di dcraw, migliorati nella versione di RawTherapee (qualunque sia disponibile in base al modello di fotocamera) o inclusi nel DNG. TP_ICM_INPUTCAMERA;Predefinito della fotocamera -TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilizza i profili colore di ingresso DCP o ICC di RawTherapee specifici per la fotocamera. Questi profili sono più precisi dei semplici matrix. Non sono però disponibili per tutte le fotocamere. Questi profili sono archiviati nelle cartelle /iccprofiles/input e /dcpprofiles e sono recuperati automaticamente in base all'esatta corrispondenza tra nome del file e modello di fotocamera. TP_ICM_INPUTCAMERAICC;Specifico della fotocamera -TP_ICM_INPUTCUSTOM_TOOLTIP;Seleziona il tuo profilo colore DCP/ICC per la fotocamera. +TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilizza i profili colore di ingresso DCP o ICC di RawTherapee specifici per la fotocamera. Questi profili sono più precisi dei semplici matrix. Non sono però disponibili per tutte le fotocamere. Questi profili sono archiviati nelle cartelle /iccprofiles/input e /dcpprofiles e sono recuperati automaticamente in base all'esatta corrispondenza tra nome del file e modello di fotocamera. +TP_ICM_INPUTCAMERA_TOOLTIP;Utilizza i semplici color matrix di dcraw, migliorati nella versione di RawTherapee (qualunque sia disponibile in base al modello di fotocamera) o inclusi nel DNG. TP_ICM_INPUTCUSTOM;Personalizzato +TP_ICM_INPUTCUSTOM_TOOLTIP;Seleziona il tuo profilo colore DCP/ICC per la fotocamera. TP_ICM_INPUTDLGLABEL;Seleziona il profilo DCP/ICC di ingresso... -TP_ICM_INPUTEMBEDDED_TOOLTIP;Utilizza il profilo colore incluso nei file non-raw. TP_ICM_INPUTEMBEDDED;Incorporato, se disponibile -TP_ICM_INPUTNONE_TOOLTIP;Non applicare un profilo colore.\nDa utilizzare solo in casi particolari. +TP_ICM_INPUTEMBEDDED_TOOLTIP;Utilizza il profilo colore incluso nei file non-raw. TP_ICM_INPUTNONE;Nessun profilo +TP_ICM_INPUTNONE_TOOLTIP;Non applicare un profilo colore.\nDa utilizzare solo in casi particolari. TP_ICM_INPUTPROFILE;Profilo di ingresso TP_ICM_LABEL;Gestione Colore TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 TP_ICM_NEUTRAL;Ripristina TP_ICM_NOICM;Nessun ICM: uscita in sRGB -TP_ICM_OUTPUTPROFILE_TOOLTIP;Per impostazione predefinita tutti i profili RTv4 o RTv2 sono con TRC - sRGB: g=2.4 s=12.92\n\nCon 'ICC Profile Creator' puoi generare profili v4 o v2 con le seguenti scelte;\n-Primarie: Aces AP0, Aces AP1 , AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Personalizzato\n-TRC: BT709, sRGB, lineare, standard g=2,2, standard g=1,8, Personalizzato\n-Illuminante: D41, D50, D55 , D60, D65, D80, standard A 2856K TP_ICM_OUTPUTPROFILE;Profilo di Uscita +TP_ICM_OUTPUTPROFILE_TOOLTIP;Per impostazione predefinita tutti i profili RTv4 o RTv2 sono con TRC - sRGB: g=2.4 s=12.92\n\nCon 'ICC Profile Creator' puoi generare profili v4 o v2 con le seguenti scelte;\n-Primarie: Aces AP0, Aces AP1 , AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Personalizzato\n-TRC: BT709, sRGB, lineare, standard g=2,2, standard g=1,8, Personalizzato\n-Illuminante: D41, D50, D55 , D60, D65, D80, standard A 2856K TP_ICM_PRIMBLU_TOOLTIP;Blu primari:\nsRGB x=0,15 y=0,06\nAdobe x=0,15 y=0,06\nWidegamut x=0,157 y=0,018\nRec2020 x=0,131 y=0,046\nACES P1 x=0,128 y= 0,044\nACES P0 x=0,0001 y=-0,077\nProphoto x=0,0366 y=0,0001\nBruceRGB x=0,15 y=0,06\nBeta RGB x=0,1265 y=0,0352\nBestRGB x=0,131 y=0,046 TP_ICM_PRIMGRE_TOOLTIP;Verde primario:\nsRGB x=0,3 y=0,6\nAdobe x=0,21 y=0,71\nWidegamut x=0,115 y=0,826\nRec2020 x=0,17 y=0,797\nACES P1 x=0,165 y= 0,83\n ASSI P0 x=0,0 y=1,0\nProphoto x=0,1596 y=0,8404\nBruceRGB x=0,28 y=0,65\nBeta RGB x=0,1986 y=0,7551\nMigliore RGB x=0,2150 0,7750 TP_ICM_PRIMILLUM_TOOLTIP;È possibile modificare un'immagine dalla modalità originale ("profilo di lavoro") a una modalità diversa ("primarie di destinazione"). Quando scegli una modalità colore diversa per un'immagine, modifichi in modo permanente i valori del colore nell'immagine.\n\nCambiare i "primari" è piuttosto complesso e difficile da usare. Richiede molta sperimentazione.\n È in grado di apportare regolazioni esotiche ai colori come primari del Mixer canali.\n Consente di modificare la calibrazione della fotocamera con personalizzazione (cursori). TP_ICM_PRIMRED_TOOLTIP;Rosso primario:\nsRGB x=0,64 y=0,33\nAdobe x=0,64 y=0,33\nWidegamut x=0,735 y=0,265\nRec2020 x=0,708 y=0,292\nACES P1 x=0,713 y= 0,293\nACES P0 x=0,7347 y=0,2653\nProphoto x=0,7347 y=0,2653\nBruceRGB x=0,64 y=0,33\nBeta RGB x=0,688 y=0,3112\nBestRGB x=0,7347 y=0,2653 TP_ICM_PROFILEINTENT;Intento di rendering TP_ICM_REDFRAME;Primarie personalizzate -TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;In genere, applicare il bilanciamento del bianco quando si salvano le immagini per creare profili ICC e non applicare il bilanciamento del bianco per creare profili DCP. -TP_ICM_SAVEREFERENCE_APPLYWB;Applicare il bilanciamento del bianco -TP_ICM_SAVEREFERENCE_TOOLTIP;Salva l'immagine TIFF lineare prima che sia applicato il profilo colore. Il risultato può essere utilizzato per la calibrazione e generazione del profilo della fotocamera. TP_ICM_SAVEREFERENCE;Salva immagine di riferimento -TP_ICM_TONECURVE_TOOLTIP;Utilizza le curve tono incluse nel DCP. Questa opzione è abilitata solo se il DCP selezionato possiede una curva tono. +TP_ICM_SAVEREFERENCE_APPLYWB;Applicare il bilanciamento del bianco +TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;In genere, applicare il bilanciamento del bianco quando si salvano le immagini per creare profili ICC e non applicare il bilanciamento del bianco per creare profili DCP. +TP_ICM_SAVEREFERENCE_TOOLTIP;Salva l'immagine TIFF lineare prima che sia applicato il profilo colore. Il risultato può essere utilizzato per la calibrazione e generazione del profilo della fotocamera. TP_ICM_TONECURVE;Usa la curva tono del DCP -TP_ICM_TRC_TOOLTIP;Ti consente di modificare la "curva di risposta tonale" sRGB predefinita in RT (g=2,4 s=12,92).\nQuesto TRC modifica i toni dell'immagine. I valori RGB e Lab, l'istogramma e l'output (schermo, TIF, JPG) vengono modificati:\n-Gamma agisce principalmente sui toni chiari -Slope agisce principalmente sui toni scuri.\nPuoi scegliere qualsiasi coppia di 'gamma e pendenza' (valori >1) e l'algoritmo garantirà che vi sia continuità tra le parti lineari e paraboliche della curva.\nUna selezione diversa da "nessuno" attiva i menu "Illuminante" e "Destinazione primari". -TP_ICM_TRCFRAME_TOOLTIP;Noti anche come profili "sintetici" o "virtuali", che vengono applicati alla fine della pipeline di elaborazione (prima di ciecam) consentendo di creare effetti immagine personalizzati.\nÈ possibile apportare modifiche a:\n "Curva di risposta tonale" , che modifica i toni dell'immagine.\n 'Illuminante': che permette di modificare i primari del profilo per adattarli alle condizioni di ripresa.\n 'Primari di destinazione': che permette di modificare i primari di destinazione con due utilizzi principali - mixer canali e calibrazione.\nNota: i profili astratti tengono conto dei profili di lavoro integrati senza modificarli. Non funzionano con i profili di lavoro personalizzati. +TP_ICM_TONECURVE_TOOLTIP;Utilizza le curve tono incluse nel DCP. Questa opzione è abilitata solo se il DCP selezionato possiede una curva tono. TP_ICM_TRCFRAME;Profilo astratto +TP_ICM_TRCFRAME_TOOLTIP;Noti anche come profili "sintetici" o "virtuali", che vengono applicati alla fine della pipeline di elaborazione (prima di ciecam) consentendo di creare effetti immagine personalizzati.\nÈ possibile apportare modifiche a:\n "Curva di risposta tonale" , che modifica i toni dell'immagine.\n 'Illuminante': che permette di modificare i primari del profilo per adattarli alle condizioni di ripresa.\n 'Primari di destinazione': che permette di modificare i primari di destinazione con due utilizzi principali - mixer canali e calibrazione.\nNota: i profili astratti tengono conto dei profili di lavoro integrati senza modificarli. Non funzionano con i profili di lavoro personalizzati. +TP_ICM_TRC_TOOLTIP;Ti consente di modificare la "curva di risposta tonale" sRGB predefinita in RT (g=2,4 s=12,92).\nQuesto TRC modifica i toni dell'immagine. I valori RGB e Lab, l'istogramma e l'output (schermo, TIF, JPG) vengono modificati:\n-Gamma agisce principalmente sui toni chiari -Slope agisce principalmente sui toni scuri.\nPuoi scegliere qualsiasi coppia di 'gamma e pendenza' (valori >1) e l'algoritmo garantirà che vi sia continuità tra le parti lineari e paraboliche della curva.\nUna selezione diversa da "nessuno" attiva i menu "Illuminante" e "Destinazione primari". +TP_ICM_WORKINGPROFILE;Profilo di lavoro TP_ICM_WORKING_CIEDIAG;Diagramma xy di CIE +TP_ICM_WORKING_ILLU;Illuminante TP_ICM_WORKING_ILLU_1500;Tungsteno 1500K TP_ICM_WORKING_ILLU_2000;Tungsteno 2000K -TP_ICM_WORKING_ILLU_D120;D120 TP_ICM_WORKING_ILLU_D41;D41 TP_ICM_WORKING_ILLU_D50;D50 TP_ICM_WORKING_ILLU_D55;D55 TP_ICM_WORKING_ILLU_D60;D60 TP_ICM_WORKING_ILLU_D65;D65 TP_ICM_WORKING_ILLU_D80;D80 +TP_ICM_WORKING_ILLU_D120;D120 TP_ICM_WORKING_ILLU_NONE;Default TP_ICM_WORKING_ILLU_STDA;stdA 2875K -TP_ICM_WORKING_ILLU;Illuminante TP_ICM_WORKING_PRESER;Preserva i toni pastello +TP_ICM_WORKING_PRIM;Destinatione primaria +TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Quando è selezionato 'Diagramma xy CIE personalizzato' nella casella combinata 'Destinazione- primarie', è possibile modificare i valori dei 3 primari direttamente sul grafico.\nNota che in questo caso, la posizione del punto bianco sul grafico non verrà aggiornata . TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2676,8 +2677,7 @@ TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB TP_ICM_WORKING_PRIM_WID;Ampia gamma -TP_ICM_WORKING_PRIM;Destinatione primaria -TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Quando è selezionato 'Diagramma xy CIE personalizzato' nella casella combinata 'Destinazione- primarie', è possibile modificare i valori dei 3 primari direttamente sul grafico.\nNota che in questo caso, la posizione del punto bianco sul grafico non verrà aggiornata . +TP_ICM_WORKING_TRC;Curva di risposta tonale: TP_ICM_WORKING_TRC_18;Prophoto g=1.8 TP_ICM_WORKING_TRC_22;Adobe g=2.2 TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 @@ -2688,16 +2688,13 @@ TP_ICM_WORKING_TRC_NONE;Nessuno TP_ICM_WORKING_TRC_SLOPE;Pendenza TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 TP_ICM_WORKING_TRC_TOOLTIP;Solo per profili integrati. -TP_ICM_WORKING_TRC;Curva di risposta tonale: -TP_ICM_WORKINGPROFILE;Profilo di lavoro TP_IMPULSEDENOISE_LABEL;Riduzione Rumore Puntuale TP_IMPULSEDENOISE_THRESH;Soglia -#TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori all'interno del gamut dello spazio colore di lavoro e applica la correzione Munsell. -#TP_LABCURVE_AVOIDCOLORSHIFT;Evita il color shift TP_LABCURVE_BRIGHTNESS;Luminosità -TP_LABCURVE_CHROMA_TOOLTIP;Per applicare il toning BN impostare la Cromaticità a -100. TP_LABCURVE_CHROMATICITY;Cromaticità +TP_LABCURVE_CHROMA_TOOLTIP;Per applicare il toning BN impostare la Cromaticità a -100. TP_LABCURVE_CONTRAST;Contrasto +TP_LABCURVE_CURVEEDITOR;Curva di luminanza TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verde Saturo TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verde Pastello TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rosso Pastello @@ -2706,29 +2703,28 @@ TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blu Saturo TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blu Pastello TP_LABCURVE_CURVEEDITOR_B_RANGE3;Giallo Pastello TP_LABCURVE_CURVEEDITOR_B_RANGE4;Giallo Saturo +TP_LABCURVE_CURVEEDITOR_CC;CC TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutri TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Opachi TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastello TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturi TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticità secondo Cromaticità C=f(C) -TP_LABCURVE_CURVEEDITOR_CC;CC -TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticità secondo Tonalità C=f(H) TP_LABCURVE_CURVEEDITOR_CH;CH -TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Cromaticità secondo Luminanza C=f(L) +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticità secondo Tonalità C=f(H) TP_LABCURVE_CURVEEDITOR_CL;CL -TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Tonalità secondo Tonalità H=f(H) +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Cromaticità secondo Luminanza C=f(L) TP_LABCURVE_CURVEEDITOR_HH;HH -TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanza secondo Cromaticità L=f(C) +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Tonalità secondo Tonalità H=f(H) TP_LABCURVE_CURVEEDITOR_LC;LC -TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminanza secondo Tonalità L=f(H) +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanza secondo Cromaticità L=f(C) TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminanza secondo Tonalità L=f(H) TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminanza secondo Luminanza L=f(L) -TP_LABCURVE_CURVEEDITOR;Curva di luminanza TP_LABCURVE_LABEL;Regolazioni Lab -TP_LABCURVE_LCREDSK_TOOLTIP;Se abilitato, la Curva LC è applicata solo ai toni rossi e dell'incarnato.\nSe disabilitato, ha effetto su tutti i toni. TP_LABCURVE_LCREDSK;Limita LC ai toni rossi e all'incarnato -TP_LABCURVE_RSTPRO_TOOLTIP;Può essere utilizzato con il cursore Cromaticità e la curva CC. +TP_LABCURVE_LCREDSK_TOOLTIP;Se abilitato, la Curva LC è applicata solo ai toni rossi e dell'incarnato.\nSe disabilitato, ha effetto su tutti i toni. TP_LABCURVE_RSTPROTECTION;Protezione Toni rossi e dell'incarnato +TP_LABCURVE_RSTPRO_TOOLTIP;Può essere utilizzato con il cursore Cromaticità e la curva CC. TP_LENSGEOM_AUTOCROP; Ritaglio automatico TP_LENSGEOM_FILL;Adattamento automatico TP_LENSGEOM_LABEL;Obiettivo/Geometria @@ -2744,10 +2740,6 @@ TP_LENSPROFILE_USE_CA;Aberrazione Cromatica TP_LENSPROFILE_USE_GEOMETRIC;Distorsione geometrica TP_LENSPROFILE_USE_HEADER;Correzione TP_LENSPROFILE_USE_VIGNETTING;Vignettatura -TP_LOCAL_HEIGHT_T;Alto -TP_LOCAL_HEIGHT;Basso -TP_LOCAL_WIDTH_L;Sinistro -TP_LOCAL_WIDTH;Destro TP_LOCALCONTRAST_AMOUNT;Quantità TP_LOCALCONTRAST_DARKNESS;Livello durezza TP_LOCALCONTRAST_LABEL;Contrasto locale @@ -2757,28 +2749,28 @@ TP_LOCALLAB_ACTIV;Solo Luminanza TP_LOCALLAB_ACTIVSPOT;Abilita Spot TP_LOCALLAB_ADJ;Equalizzatore Colore TP_LOCALLAB_AMOUNT;Quantità -TP_LOCALLAB_ARTIF_TOOLTIP;La soglia dell'ambito ΔE aumenta la portata dell'ambito ΔE. I valori elevati si riferiscono a immagini con una gamma molto ampia.\nL'aumento del decadimento ΔE può migliorare il rilevamento della forma, ma può anche ridurre l'ambito. TP_LOCALLAB_ARTIF;Rilevamento della forma +TP_LOCALLAB_ARTIF_TOOLTIP;La soglia dell'ambito ΔE aumenta la portata dell'ambito ΔE. I valori elevati si riferiscono a immagini con una gamma molto ampia.\nL'aumento del decadimento ΔE può migliorare il rilevamento della forma, ma può anche ridurre l'ambito. TP_LOCALLAB_AUTOGRAY;Luminanza media automatica (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Auto TP_LOCALLAB_AVOID;Evita il cambiamento di colore TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori alla gamma dello spazio colore di lavoro e applica la correzione Munsell (Uniform Perceptual Lab).\nLa correzione Munsell è sempre disabilitata quando si utilizza Jz o CAM16 o Aspetto colore e illuminazione.\n\nPredefinito: Munsell.\nCorrezione Munsell: corregge la modalità Lab la tonalità si sposta a causa della non linearità, quando la cromaticità viene modificata (Uniform Perceptual Lab).\nLab: applica un controllo della gamma, in colorimetrico relativo, viene quindi applicato Munsell.\nXYZ Assoluto, applica il controllo della gamma, in colorimetrico assoluto, viene quindi applicato Munsell. applicato.\nXYZ Relativo, applica il controllo gamma, in colorimetrico relativo, viene quindi applicato Munsell. -TP_LOCALLAB_AVOIDMUN_TOOLTIP;La correzione Munsell è sempre disabilitata quando si utilizza Jz o CAM16. TP_LOCALLAB_AVOIDMUN;Solo correzione Munsell +TP_LOCALLAB_AVOIDMUN_TOOLTIP;La correzione Munsell è sempre disabilitata quando si utilizza Jz o CAM16. TP_LOCALLAB_AVOIDRAD;Raggio Morbido -TP_LOCALLAB_BALAN_TOOLTIP;Modifica i parametri dell'algoritmo ΔE.\nPrende in considerazione più o meno a*b* o L*, o più o meno C o H.\nNon per Denoise. TP_LOCALLAB_BALAN;ab-L bilanciato (ΔE) TP_LOCALLAB_BALANEXP;Bilanciamento Laplacian TP_LOCALLAB_BALANH;C-H bilanciato (ΔE) +TP_LOCALLAB_BALAN_TOOLTIP;Modifica i parametri dell'algoritmo ΔE.\nPrende in considerazione più o meno a*b* o L*, o più o meno C o H.\nNon per Denoise. TP_LOCALLAB_BASELOG;Intervallo delle ombre (base logaritmica) TP_LOCALLAB_BILATERAL;Filtro bilateralte TP_LOCALLAB_BLACK_EV;Compensazione dell'esposizione dei neri TP_LOCALLAB_BLCO;Solo crominanza -TP_LOCALLAB_BLENDMASK_TOOLTIP;Se fusione = 0 viene migliorato solo il rilevamento della forma.\nSe fusione > 0 la maschera viene aggiunta all'immagine. Se la mescola < 0 la maschera viene sottratta dall'immagine. TP_LOCALLAB_BLENDMASKCOL;Miscela -TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;Se questo cursore = 0 nessuna azione.\nAggiungi o sottrai la maschera dall'immagine originale. TP_LOCALLAB_BLENDMASKMASK;Aggiungi/sottrai la maschera luminanza TP_LOCALLAB_BLENDMASKMASKAB;Aggiungi/sottrai la maschera crominanza +TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;Se questo cursore = 0 nessuna azione.\nAggiungi o sottrai la maschera dall'immagine originale. +TP_LOCALLAB_BLENDMASK_TOOLTIP;Se fusione = 0 viene migliorato solo il rilevamento della forma.\nSe fusione > 0 la maschera viene aggiunta all'immagine. Se la mescola < 0 la maschera viene sottratta dall'immagine. TP_LOCALLAB_BLGUID;Filtro guidato TP_LOCALLAB_BLINV;Inverso TP_LOCALLAB_BLLC;Luminanza e Crominanza @@ -2789,7 +2781,6 @@ TP_LOCALLAB_BLNOI_EXP;Sfocatura e rumore TP_LOCALLAB_BLNORM;Normale TP_LOCALLAB_BLUFR;Sfocatura/grana e riduzione rumore TP_LOCALLAB_BLUMETHOD_TOOLTIP;Per sfocare lo sfondo e isolare il primo piano:\n-sfoca lo sfondo coprendo completamente l'immagine con un punto (valori elevati per ambito e transizione e 'Normale' o 'Inverso' nella casella di controllo).\n-Isola il primo piano utilizzando uno o più punti 'Esclusioni' e aumentare l'ambito.\n\nQuesto modulo (incluso il 'mediano' e il 'Filtro guidato') può essere utilizzato in aggiunta alla riduzione del rumore nel menu principale. -TP_LOCALLAB_BLUR_TOOLNAME;Sfocatura/grana e riduzione rumore TP_LOCALLAB_BLUR;Sfocatura gaussiana - Rumore - Grana TP_LOCALLAB_BLURCOL;Raggio TP_LOCALLAB_BLURCOLDE_TOOLTIP;L'immagine utilizzata per calcolare ΔE è leggermente sfocata per evitare di prendere in considerazione i pixel isolati. @@ -2798,42 +2789,42 @@ TP_LOCALLAB_BLURLC;Solo luminanza TP_LOCALLAB_BLURLEVELFRA;Livello di sfocatura TP_LOCALLAB_BLURMASK_TOOLTIP;Utilizza una sfocatura ad ampio raggio per creare una maschera che consente di variare il contrasto dell'immagine e/o scurire/schiarire parti di essa. TP_LOCALLAB_BLURRMASK_TOOLTIP;Permette di variare il 'raggio' della sfocatura gaussiana (da 0 a 1000). -TP_LOCALLAB_BLWH_TOOLTIP;Forza i componenti del colore 'a' e 'b' a zero.\nUtile per l'elaborazione in bianco e nero o la simulazione di film. +TP_LOCALLAB_BLUR_TOOLNAME;Sfocatura/grana e riduzione rumore TP_LOCALLAB_BLWH;Tutti i cambiamenti forzati in bianco e nero +TP_LOCALLAB_BLWH_TOOLTIP;Forza i componenti del colore 'a' e 'b' a zero.\nUtile per l'elaborazione in bianco e nero o la simulazione di film. TP_LOCALLAB_BUTTON_ADD;Aggiungi TP_LOCALLAB_BUTTON_DEL;Elimina TP_LOCALLAB_BUTTON_DUPL;Duplica TP_LOCALLAB_BUTTON_REN;Rinomina TP_LOCALLAB_BUTTON_VIS;Mostra/Nascondi TP_LOCALLAB_BWFORCE;Usa la compensazione dell'esposizione dei neri e la compensazione dell'esposizione dei bianchi -TP_LOCALLAB_CAM16_FRA;Regolazioni dell'immagine Cam16 -TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (quantizzatore percettivo) adattato al CAM16. Consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 100 cd/m2 - disabilitato per 100 cd/m2).\nPuò essere utilizzato per adattarsi a diversi dispositivi e immagini. TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Luminanza di picco) +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (quantizzatore percettivo) adattato al CAM16. Consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 100 cd/m2 - disabilitato per 100 cd/m2).\nPuò essere utilizzato per adattarsi a diversi dispositivi e immagini. +TP_LOCALLAB_CAM16_FRA;Regolazioni dell'immagine Cam16 +TP_LOCALLAB_CAMMODE;Modello CAM TP_LOCALLAB_CAMMODE_CAM16;CAM 16 TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz -TP_LOCALLAB_CAMMODE;Modello CAM TP_LOCALLAB_CATAD;Adattamento cromatico/Cat16 +TP_LOCALLAB_CBDL;Contrasto per livelli di dettaglio +TP_LOCALLAB_CBDLCLARI_TOOLTIP;Migliora il contrasto locale dei mezzitoni. TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Come le wavelet.\nIl primo livello (0) agisce su dettagli di 2x2 pixel.\nL'ultimo livello (5) agisce su dettagli di 64x64 pixel. TP_LOCALLAB_CBDL_THRES_TOOLTIP;Previene l'acutizzazione del rumore. TP_LOCALLAB_CBDL_TOOLNAME;Contrasto per livelli di dettaglio -TP_LOCALLAB_CBDL;Contrasto per livelli di dettaglio -TP_LOCALLAB_CBDLCLARI_TOOLTIP;Migliora il contrasto locale dei mezzitoni. TP_LOCALLAB_CENTER_X;Centra X TP_LOCALLAB_CENTER_Y;Centra Y TP_LOCALLAB_CH;CL - LC TP_LOCALLAB_CHRO46LABEL;Livelli di crominanza 456: Medio=%1 Alto=%2 TP_LOCALLAB_CHROLABEL;Livelli di crominanza 0123: Medio=%1 Alto=%2 TP_LOCALLAB_CHROMA;Crominanza -TP_LOCALLAB_CHROMABLU_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. TP_LOCALLAB_CHROMABLU;Livelli di crominanza -TP_LOCALLAB_CHROMACB_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. +TP_LOCALLAB_CHROMABLU_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. TP_LOCALLAB_CHROMACBDL;Crominanza +TP_LOCALLAB_CHROMACB_TOOLTIP;Aumenta o riduce l'effetto a seconda delle impostazioni di luminanza.\nI valori inferiori a 1 riducono l'effetto. Valori maggiori di 1 aumentano l'effetto. TP_LOCALLAB_CHROMALEV;Livelli di crominanza -TP_LOCALLAB_CHROMASK_TOOLTIP;Cambia la crominanza della maschera se ne esiste una (cioè C(C) o LC(H) è attivato). TP_LOCALLAB_CHROMASKCOL;Crominanza +TP_LOCALLAB_CHROMASK_TOOLTIP;Cambia la crominanza della maschera se ne esiste una (cioè C(C) o LC(H) è attivato). TP_LOCALLAB_CHROML;Crominanza (C) TP_LOCALLAB_CHRRT;Crominanza -TP_LOCALLAB_CIE_TOOLNAME;Aspetto del colore (Cam16 & JzCzHz) TP_LOCALLAB_CIE;Aspetto del colore (Cam16 & JzCzHz) TP_LOCALLAB_CIEC;Utilizza i parametri dell'ambiente CIECAM TP_LOCALLAB_CIECAMLOG_TOOLTIP;Questo modulo si basa sul modello di aspetto del colore CIECAM che è stato progettato per simulare meglio il modo in cui la visione umana percepisce i colori in diverse condizioni di illuminazione.\nIl primo processo Ciecam 'Condizioni di scena' viene eseguito mediante codifica Log, utilizza anche 'Luminanza assoluta' a l'ora dello scatto.\nIl secondo processo Ciecam 'Regolazioni immagine' è semplificato e utilizza solo 3 variabili (contrasto locale, contrasto J, saturazione s).\nIl terzo processo Ciecam 'Condizioni di visualizzazione' adatta l'output alle condizioni di visualizzazione previste ( monitor, TV, proiettore, stampante, ecc.) in modo che l'aspetto cromatico e di contrasto venga preservato in tutto l'ambiente di visualizzazione. @@ -2841,35 +2832,36 @@ TP_LOCALLAB_CIECOLORFRA;Colore TP_LOCALLAB_CIECONTFRA;Contrasto TP_LOCALLAB_CIELIGHTCONTFRA;Illuminazione e contrasto TP_LOCALLAB_CIELIGHTFRA;Illuminazione +TP_LOCALLAB_CIEMODE;Modificare la posizione dello strumento TP_LOCALLAB_CIEMODE_COM;Default TP_LOCALLAB_CIEMODE_DR;Gamma dinamica TP_LOCALLAB_CIEMODE_TM;Mappatura dei toni TP_LOCALLAB_CIEMODE_TOOLTIP;Nella modalità predefinita, Ciecam viene aggiunto alla fine del processo. 'Maschera e modifiche' e 'Recupero basato sulla maschera di luminanza' sono disponibili per'Cam16 e JzCzHz' a tua disposizione.\nPuoi anche integrare Ciecam in altri strumenti se lo desideri (TM, Wavelet, Dynamic Range, Log Encoding). I risultati per questi strumenti saranno diversi rispetto a quelli senza Ciecam. In questa modalità è anche possibile utilizzare 'Maschera e modifiche' e 'Ripristino basato sulla maschera di luminanza'. TP_LOCALLAB_CIEMODE_WAV;Wavelet -TP_LOCALLAB_CIEMODE;Modificare la posizione dello strumento TP_LOCALLAB_CIETOOLEXP;Curve -TP_LOCALLAB_CIRCRAD_TOOLTIP;Contiene i riferimenti della macchia, utili per il rilevamento della forma (tonalità, luminanza, crominanza, Sobel).\bValori bassi possono essere utili per l'elaborazione del fogliame.\Valori alti possono essere utili per l'elaborazione della pelle. +TP_LOCALLAB_CIE_TOOLNAME;Aspetto del colore (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Dimensione del punto -TP_LOCALLAB_CLARI_TOOLTIP;Livelli da 0 a 4 (inclusi): 'Maschera nitida' è abilitata\nLivelli 5 e superiori: 'Chiarezza' è abilitata.\nUtile se si utilizza la 'Mappatura toni livello Wavelet'. +TP_LOCALLAB_CIRCRAD_TOOLTIP;Contiene i riferimenti della macchia, utili per il rilevamento della forma (tonalità, luminanza, crominanza, Sobel).\bValori bassi possono essere utili per l'elaborazione del fogliame.\Valori alti possono essere utili per l'elaborazione della pelle. TP_LOCALLAB_CLARICRES;Unisci crominanza TP_LOCALLAB_CLARIFRA;Maschera Chiarezza e Nitidezza/Unisci e ammorbidisci le immagini TP_LOCALLAB_CLARIJZ_TOOLTIP;Livelli da 0 a 4 (inclusi): 'Maschera nitida' è abilitata\nLivelli 5 e superiori: 'Chiarezza' è abilitata. TP_LOCALLAB_CLARILRES;Unisci luminanza -TP_LOCALLAB_CLARISOFT_TOOLTIP;Il cursore 'Raggio morbido' (algoritmo di filtro guidato) riduce gli aloni e le irregolarità per Chiarezza, Maschera nitida e tutti i processi piramidali wavelet. Per disattivare, impostare il cursore su zero. TP_LOCALLAB_CLARISOFT;Raggio morbido TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;Il dispositivo di scorrimento "Raggio morbido" (algoritmo di filtro guidato) riduce gli aloni e le irregolarità per Chiarezza, Maschera nitida e Wavelet di contrasto locale Jz. +TP_LOCALLAB_CLARISOFT_TOOLTIP;Il cursore 'Raggio morbido' (algoritmo di filtro guidato) riduce gli aloni e le irregolarità per Chiarezza, Maschera nitida e tutti i processi piramidali wavelet. Per disattivare, impostare il cursore su zero. TP_LOCALLAB_CLARITYML;Clarity +TP_LOCALLAB_CLARI_TOOLTIP;Livelli da 0 a 4 (inclusi): 'Maschera nitida' è abilitata\nLivelli 5 e superiori: 'Chiarezza' è abilitata.\nUtile se si utilizza la 'Mappatura toni livello Wavelet'. TP_LOCALLAB_CLIPTM;Clip dei dati ripristinati (guadagno) TP_LOCALLAB_COFR;Colore e luce -TP_LOCALLAB_COL_NAME;Nome -TP_LOCALLAB_COL_VIS;Stato -TP_LOCALLAB_COLOR_CIE;Curva colore -TP_LOCALLAB_COLOR_TOOLNAME;Colore e luce -TP_LOCALLAB_COLORDE_TOOLTIP;Mostra un'anteprima di colore blu per la selezione ΔE se negativa e verde se positiva.\n\nMaschera e modifiche (mostra aree modificate senza maschera): mostra le modifiche effettive se positive, mostra le modifiche migliorate (solo luminanza) con blu e giallo se negative. TP_LOCALLAB_COLORDE;ΔE anteprima colore - intensità TP_LOCALLAB_COLORDEPREV_TOOLTIP;Il pulsante Anteprima ΔE funzionerà solo se hai attivato uno (e solo uno) degli strumenti nel menu 'Aggiungi strumento al punto corrente'.\nPer poter visualizzare l'anteprima ΔE con diversi strumenti abilitati, usa Maschera e modifiche - Anteprima ΔE. -TP_LOCALLAB_COLORSCOPE_TOOLTIP;Cursore di ambito comune per Colore e luce, Ombre/Alte luci, Vividezza.\nAltri strumenti hanno i propri controlli di ambito. +TP_LOCALLAB_COLORDE_TOOLTIP;Mostra un'anteprima di colore blu per la selezione ΔE se negativa e verde se positiva.\n\nMaschera e modifiche (mostra aree modificate senza maschera): mostra le modifiche effettive se positive, mostra le modifiche migliorate (solo luminanza) con blu e giallo se negative. TP_LOCALLAB_COLORSCOPE;Ambito (strumenti colore) +TP_LOCALLAB_COLORSCOPE_TOOLTIP;Cursore di ambito comune per Colore e luce, Ombre/Alte luci, Vividezza.\nAltri strumenti hanno i propri controlli di ambito. +TP_LOCALLAB_COLOR_CIE;Curva colore +TP_LOCALLAB_COLOR_TOOLNAME;Colore e luce +TP_LOCALLAB_COL_NAME;Nome +TP_LOCALLAB_COL_VIS;Stato TP_LOCALLAB_COMPFRA;Contrasto direzionale TP_LOCALLAB_COMPREFRA;Mappatura dei toni del livello wavelet TP_LOCALLAB_CONTCOL;Soglia di contrasto @@ -2884,39 +2876,39 @@ TP_LOCALLAB_CSTHRESHOLD;Livelli di Wavelet TP_LOCALLAB_CSTHRESHOLDBLUR;Selezione del livello wavelet TP_LOCALLAB_CURV;LighQualità - Contrasto - Crominanza 'Super' TP_LOCALLAB_CURVCURR;Normale +TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;Se le curve sono in alto, la maschera è completamente nera e non viene apportata alcuna modifica all'immagine.\nMan mano che si abbassa la curva, la maschera diventa gradualmente più colorata e luminosa, modificando progressivamente l'immagine.\n\nSi consiglia ( ma non obbligatorio) posizionare la parte superiore delle curve sulla linea di confine grigia che rappresenta i valori di riferimento di crominanza, luminanza, tonalità per lo spot. TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;Se le curve sono in alto, la maschera è completamente nera e non viene apportata alcuna modifica all'immagine.\nMan mano che si abbassa la curva, la maschera diventa gradualmente più colorata e luminosa, cambiando progressivamente l'immagine.\n\nÈ consigliato (ma (non obbligatorio) posizionare la parte superiore delle curve sulla linea di confine grigia che rappresenta i valori di riferimento di crominanza, luminanza, tonalità per lo spot. TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;Per attivare le curve, impostare la casella combinata 'Tipo di curva' su 'Normale'. TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Curva del tono TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), può essere utilizzato con L(H) in Colore e Luce. -TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;Se le curve sono in alto, la maschera è completamente nera e non viene apportata alcuna modifica all'immagine.\nMan mano che si abbassa la curva, la maschera diventa gradualmente più colorata e luminosa, modificando progressivamente l'immagine.\n\nSi consiglia ( ma non obbligatorio) posizionare la parte superiore delle curve sulla linea di confine grigia che rappresenta i valori di riferimento di crominanza, luminanza, tonalità per lo spot. TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normale', la curva L=f(L) utilizza lo stesso algoritmo del cursore della luminosità. TP_LOCALLAB_CURVES_CIE;Curva del tono TP_LOCALLAB_CURVNONE;Disabilita curve TP_LOCALLAB_DARKRETI;Durezza TP_LOCALLAB_DEHAFRA;Rimouovi foschia -TP_LOCALLAB_DEHAZ_TOOLTIP;I valori negativi aggiungono foschia. TP_LOCALLAB_DEHAZ;Intensità TP_LOCALLAB_DEHAZE_BLACK;Nero TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Rimuove la foschia atmosferica. Aumenta la saturazione e il dettaglio complessivi.\nPuò rimuovere dominanti di colore, ma può anche introdurre una dominante blu che può essere corretta con altri strumenti. +TP_LOCALLAB_DEHAZ_TOOLTIP;I valori negativi aggiungono foschia. TP_LOCALLAB_DELTAD;Equilibrio delta TP_LOCALLAB_DELTAEC;ΔE Maschera immagine -TP_LOCALLAB_DENOI_EXP;Riduzione rumore -TP_LOCALLAB_DENOI_TOOLTIP;Questo modulo può essere utilizzato per la riduzione del rumore da solo (alla fine della pipeline di elaborazione) o in aggiunta al modulo Riduzione del rumore nella scheda Dettagli (che funziona all'inizio della pipeline).\n L'ambito ti consente di differenziare l'azione in base al colore (ΔE).\nDimensione minima dello spot: 128x128. TP_LOCALLAB_DENOI1_EXP;Riduzione rumore basato sulla maschera di luminanza TP_LOCALLAB_DENOI2_EXP;Recupero basato sulla maschera di luminanza TP_LOCALLAB_DENOIBILAT_TOOLTIP;Consente di ridurre il rumore impulsivo o "sale e pepe". TP_LOCALLAB_DENOICHROC_TOOLTIP;Ti consente di gestire macchie e pacchetti di rumore. TP_LOCALLAB_DENOICHRODET_TOOLTIP;Permette di recuperare il dettaglio della crominanza applicando progressivamente una trasformata di Fourier (DCT). TP_LOCALLAB_DENOICHROF_TOOLTIP;Consente di regolare il rumore della crominanza nei minimi dettagli. -TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Consente di effettuare una riduzione maggiore o minore del rumore sia nelle ombre che nelle luci. TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Consente di indirizzare la riduzione del rumore cromatico verso i colori blu-giallo o rosso-verde. +TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Consente di effettuare una riduzione maggiore o minore del rumore sia nelle ombre che nelle luci. TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Permette di recuperare il dettaglio della luminanza applicando progressivamente una trasformata di Fourier (DCT). -TP_LOCALLAB_DENOIMASK_TOOLTIP;Per tutti gli strumenti, consente di controllare il livello di rumore cromatico della maschera.\nUtile per un migliore controllo della crominanza e per evitare artefatti quando si utilizza la curva LC(h). TP_LOCALLAB_DENOIMASK;Ruzione rumore maschera di crominanza +TP_LOCALLAB_DENOIMASK_TOOLTIP;Per tutti gli strumenti, consente di controllare il livello di rumore cromatico della maschera.\nUtile per un migliore controllo della crominanza e per evitare artefatti quando si utilizza la curva LC(h). TP_LOCALLAB_DENOIQUA_TOOLTIP;La modalità conservativa preserva i dettagli a bassa frequenza. La modalità aggressiva rimuove i dettagli a bassa frequenza.\nLe modalità conservativa e aggressiva utilizzano wavelet e DCT e possono essere utilizzate insieme a "Mezzi non locali – Luminanza". TP_LOCALLAB_DENOITHR_TOOLTIP;Regola il rilevamento dei bordi per ridurre il rumore nelle aree uniformi e a basso contrasto. TP_LOCALLAB_DENOIWAVCH;Wavelets: Crominanza TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminanza +TP_LOCALLAB_DENOI_EXP;Riduzione rumore +TP_LOCALLAB_DENOI_TOOLTIP;Questo modulo può essere utilizzato per la riduzione del rumore da solo (alla fine della pipeline di elaborazione) o in aggiunta al modulo Riduzione del rumore nella scheda Dettagli (che funziona all'inizio della pipeline).\n L'ambito ti consente di differenziare l'azione in base al colore (ΔE).\nDimensione minima dello spot: 128x128. TP_LOCALLAB_DEPTH;Profondità TP_LOCALLAB_DETAIL;Contrasto locale TP_LOCALLAB_DETAILFRA;Rilevamento dei bordi - DCT @@ -2938,34 +2930,33 @@ TP_LOCALLAB_EQUIL;Normalizza la luminanza TP_LOCALLAB_EQUILTM_TOOLTIP;Ricostruire la luminanza in modo che la media e la varianza dell'immagine di output siano identiche a quelle dell'originale. TP_LOCALLAB_ESTOP;Arresto sul bordo TP_LOCALLAB_EV_DUPL;Copia di -TP_LOCALLAB_EV_NVIS_ALL;Nascondi tutto TP_LOCALLAB_EV_NVIS;Nascondi -TP_LOCALLAB_EV_VIS_ALL;Mostra tutto +TP_LOCALLAB_EV_NVIS_ALL;Nascondi tutto TP_LOCALLAB_EV_VIS;Mostra -TP_LOCALLAB_EXCLUF_TOOLTIP;La modalità 'Esclusione' impedisce ai punti adiacenti di influenzare alcune parti dell'immagine. La regolazione di 'Ambito' estenderà la gamma di colori.\n Puoi anche aggiungere strumenti a un punto di esclusione e utilizzarli come per un punto normale. +TP_LOCALLAB_EV_VIS_ALL;Mostra tutto TP_LOCALLAB_EXCLUF;Escluso -TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +TP_LOCALLAB_EXCLUF_TOOLTIP;La modalità 'Esclusione' impedisce ai punti adiacenti di influenzare alcune parti dell'immagine. La regolazione di 'Ambito' estenderà la gamma di colori.\n Puoi anche aggiungere strumenti a un punto di esclusione e utilizzarli come per un punto normale. TP_LOCALLAB_EXCLUTYPE;Metodo Spot +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. TP_LOCALLAB_EXECLU;Escluso spot TP_LOCALLAB_EXFULL;Immagine piena TP_LOCALLAB_EXNORM;Spot normale -TP_LOCALLAB_EXP_TOOLNAME;Gamma dinamica ed esposizione TP_LOCALLAB_EXPCBDL_TOOLTIP;Può essere utilizzato per rimuovere segni sul sensore o sull'obiettivo riducendo il contrasto ai livelli di dettaglio appropriati. -TP_LOCALLAB_EXPCHROMA_TOOLTIP;Utilizzare insieme a 'Compensazione dell'esposizione f' e 'Attenuatore contrasto f' per evitare la desaturazione dei colori. TP_LOCALLAB_EXPCHROMA;Compensazione cromatica +TP_LOCALLAB_EXPCHROMA_TOOLTIP;Utilizzare insieme a 'Compensazione dell'esposizione f' e 'Attenuatore contrasto f' per evitare la desaturazione dei colori. TP_LOCALLAB_EXPCOLOR_TOOLTIP;Regola colore, luminosità, contrasto e correggi piccoli difetti come occhi rossi, polvere del sensore, ecc. -TP_LOCALLAB_EXPCOMP_TOOLTIP;Per ritratti o immagini con una bassa sfumatura di colore. Puoi modificare il "Rilevamento della forma" in "Impostazioni":\n\nAumenta la "Soglia ambito ΔE"\nRiduci il "Decadimento ΔE"\nAumenta il "Bilanciamento ab-L (ΔE)" TP_LOCALLAB_EXPCOMP;Compensazione dell'esposizione Æ’ TP_LOCALLAB_EXPCOMPINV;Compensazione dell'esposizione -TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Evita punti troppo piccoli (< 32x32 pixel).\nUtilizza un 'Valore di transizione' basso e un 'Decadimento della transizione' e un''Ambito' alti per simulare piccoli punti e gestire i difetti.\nUtilizza la maschera Chiarezza e Nitidezza e Fondi e ammorbidisci immagini ' se necessario regolando 'Raggio morbido' per ridurre gli artefatti. +TP_LOCALLAB_EXPCOMP_TOOLTIP;Per ritratti o immagini con una bassa sfumatura di colore. Puoi modificare il "Rilevamento della forma" in "Impostazioni":\n\nAumenta la "Soglia ambito ΔE"\nRiduci il "Decadimento ΔE"\nAumenta il "Bilanciamento ab-L (ΔE)" TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Consulta la documentazione per i Livelli Wavelet.\nCi sono alcune differenze nella versione Regolazioni Locali, che ha più strumenti e più possibilità per lavorare su livelli di dettaglio individuali.\nEs. mappatura dei toni a livello wavelet. +TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Evita punti troppo piccoli (< 32x32 pixel).\nUtilizza un 'Valore di transizione' basso e un 'Decadimento della transizione' e un''Ambito' alti per simulare piccoli punti e gestire i difetti.\nUtilizza la maschera Chiarezza e Nitidezza e Fondi e ammorbidisci immagini ' se necessario regolando 'Raggio morbido' per ridurre gli artefatti. TP_LOCALLAB_EXPCURV;Curve TP_LOCALLAB_EXPGRAD;Filtro graduato TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Un filtro graduato è disponibile in Colore e Luce (luminanza, crominanza e gradienti di tonalità e "Unisci file"), Esposizione (grado di luminanza), Maschera esposizione (grado di luminanza), Ombre/Alte luci (grado di luminanza), Vividezza ( luminanza, crominanza e gradienti di tonalità), contrasto locale e piramide wavelet (gradazione di contrasto locale).\nPiuma si trova in Impostazioni. -TP_LOCALLAB_EXPLAP_TOOLTIP;Spostando il cursore verso destra si riduce progressivamente il contrasto. TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Modifica la fusione dell'immagine trasformata/originale. TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Modifica il comportamento delle immagini con contrasto eccessivo o insufficiente aggiungendo una curva gamma prima e dopo la trasformata di Laplace. TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. +TP_LOCALLAB_EXPLAP_TOOLTIP;Spostando il cursore verso destra si riduce progressivamente il contrasto. TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Consente di utilizzare le modalità di fusione dei livelli di GIMP o Photoshop (differenza, moltiplicazione, luce soffusa, sovrapposizione, ecc.) con controllo dell'opacità.\nImmagine originale: unisci il punto corrente con l'originale.\nPunto precedente: unisci il punto corrente con quello precedente (se presente solo uno spot, precedente = originale).\nSfondo: unisce lo spot corrente con uno sfondo di colore e luminanza (meno possibilità). TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applica un filtro mediano prima della trasformazione di Laplace per prevenire artefatti (rumore).\nPuoi anche utilizzare lo strumento "Rimuovi rumore". TP_LOCALLAB_EXPOSE;Gamma dinamica ed esposizione @@ -2973,6 +2964,7 @@ TP_LOCALLAB_EXPOSURE_TOOLTIP;Modificare l'esposizione nello spazio L*a*b utilizz TP_LOCALLAB_EXPRETITOOLS;Strumenti Retinex avanzati TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimo 39*39.\nUtilizza valori di transizione bassi e valori alti di "Decadimento transizione" e "Ambito" per simulare spot più piccoli. TP_LOCALLAB_EXPTOOL;Strumenti di esposizione +TP_LOCALLAB_EXP_TOOLNAME;Gamma dinamica ed esposizione TP_LOCALLAB_FATAMOUNT;Quantità TP_LOCALLAB_FATANCHOR;Ancora TP_LOCALLAB_FATDETAIL;Dettaglio @@ -2990,13 +2982,13 @@ TP_LOCALLAB_FFTWBLUR;Æ’ - Utilizza sempre la trasformata veloce di Fourier TP_LOCALLAB_FULLIMAGE;Compensazione dell'esposizione dei neri e compensazione dell'esposizione dei bianchi per l'intera immagine TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calcola i livelli Ev per l'intera immagine. TP_LOCALLAB_GAM;Gamma -TP_LOCALLAB_GAMC_TOOLTIP;Applicare una gamma sui dati di luminanza L*a*b* prima e dopo il trattamento Piramide 1 e Piramide 2.\nSe gamma = 3.0 Viene utilizzata la luminanza 'lineare'. TP_LOCALLAB_GAMC;Gamma TP_LOCALLAB_GAMCOL_TOOLTIP;Applica una gamma sui dati di luminanza L*a*b*.\nSe gamma = 3.0 viene utilizzata la luminanza 'lineare'. +TP_LOCALLAB_GAMC_TOOLTIP;Applicare una gamma sui dati di luminanza L*a*b* prima e dopo il trattamento Piramide 1 e Piramide 2.\nSe gamma = 3.0 Viene utilizzata la luminanza 'lineare'. TP_LOCALLAB_GAMFRA;Curva di risposta tonale (CRT) TP_LOCALLAB_GAMM;Gamma -TP_LOCALLAB_GAMMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente "L" per evitare eventuali discontinuità. TP_LOCALLAB_GAMMASKCOL;Gamma +TP_LOCALLAB_GAMMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente "L" per evitare eventuali discontinuità. TP_LOCALLAB_GAMSH;Gamma TP_LOCALLAB_GAMUTLABRELA;Lab TP_LOCALLAB_GAMUTMUNSELL;Solo Munsell @@ -3004,31 +2996,31 @@ TP_LOCALLAB_GAMUTNON;Nessuno TP_LOCALLAB_GAMUTXYZABSO;XYZ Assoluto TP_LOCALLAB_GAMUTXYZRELA;XYZ Relativo TP_LOCALLAB_GAMW;Gamma (piramide di wavelet) -TP_LOCALLAB_GRADANG_TOOLTIP;Angolo di rotazione in gradi: -180 o +180. TP_LOCALLAB_GRADANG;Angolo gradiente +TP_LOCALLAB_GRADANG_TOOLTIP;Angolo di rotazione in gradi: -180 o +180. TP_LOCALLAB_GRADFRA;Maschera con filtro graduato TP_LOCALLAB_GRADGEN_TOOLTIP;Regola l'intensità del gradiente di luminanza. TP_LOCALLAB_GRADLOGFRA;Luminanza del filtro graduato TP_LOCALLAB_GRADSTR;Intensità del gradiente TP_LOCALLAB_GRADSTRAB_TOOLTIP;Regola l'intensità del gradiente cromatico. TP_LOCALLAB_GRADSTRCHRO;Intensità del gradiente cromatico -TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Regola l'intensità del gradiente di tonalità. TP_LOCALLAB_GRADSTRHUE;Intensità del gradiente di tonalità TP_LOCALLAB_GRADSTRHUE2;Intensità del gradiente di tonalità +TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Regola l'intensità del gradiente di tonalità. TP_LOCALLAB_GRADSTRLUM;Intensità del gradiente luminanza -TP_LOCALLAB_GRAIN_TOOLTIP;Aggiunge una grana simile a una pellicola all'immagine. TP_LOCALLAB_GRAINFRA;Grana della pellicola 1:1 TP_LOCALLAB_GRAINFRA2;Ruvidezza +TP_LOCALLAB_GRAIN_TOOLTIP;Aggiunge una grana simile a una pellicola all'immagine. TP_LOCALLAB_GRALWFRA;Filtro graduato (contrasto locale) TP_LOCALLAB_GRIDFRAME_TOOLTIP;Puoi usare questo strumento come un pennello. Usa un piccolo punto e adatta il 'Valore di transizione' e il 'Decadimento della transizione'\nSolo la modalità 'Normale' ed eventualmente Tonalità, Saturazione, Colore e Luminosità sono interessate da Unisci sfondo (ΔE). TP_LOCALLAB_GRIDMETH_TOOLTIP;Tonalità del colore: la luminanza viene presa in considerazione quando si varia la crominanza. Equivalente a H=f(H) se il 'punto bianco' sulla griglia rimane a zero e si varia solo il 'punto nero'. Equivalente a 'Viraggio colore' se si variano i 2 punti.\n\nDiretto: agisce direttamente sulla crominanza. TP_LOCALLAB_GRIDONE;Tonificazione del colore TP_LOCALLAB_GRIDTWO;Diretto -TP_LOCALLAB_GUIDBL_TOOLTIP;Applica un filtro guidato con raggio regolabile. Consente di ridurre gli artefatti o sfocare l'immagine. TP_LOCALLAB_GUIDBL;Raggio morbido +TP_LOCALLAB_GUIDBL_TOOLTIP;Applica un filtro guidato con raggio regolabile. Consente di ridurre gli artefatti o sfocare l'immagine. TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Modifica la funzione di distribuzione del filtro guidato. I valori negativi simulano una sfocatura gaussiana. -TP_LOCALLAB_GUIDFILTER_TOOLTIP;Può ridurre o aumentare gli artefatti. TP_LOCALLAB_GUIDFILTER;Raggio del filtro guidato +TP_LOCALLAB_GUIDFILTER_TOOLTIP;Può ridurre o aumentare gli artefatti. TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensità del filtro guidato. TP_LOCALLAB_HHMASK_TOOLTIP;Regolazioni fini della tonalità, ad esempio per la pelle. TP_LOCALLAB_HIGHMASKCOL;Alteluci @@ -3036,40 +3028,40 @@ TP_LOCALLAB_HLH;H TP_LOCALLAB_HUECIE;Tonalità TP_LOCALLAB_IND;Independente (mouse) TP_LOCALLAB_INDSL;Independento (mouse + scorrimento) -TP_LOCALLAB_INVBL_TOOLTIP;Alternativa alla modalità 'Inversa': usa due spot\Primo spot:\nell'immagine intera\in\Secondo spot: escluso lo spot. TP_LOCALLAB_INVBL;Inverso -TP_LOCALLAB_INVERS_TOOLTIP;Meno possibilità se selezionato (Inverso).\n\nAlternativa: usa due spot\nPrimo spot:\n Immagine intera\n \nSecondo spot: escluso spot\n\n Inverso abiliterà questo strumento per l'area esterna allo spot, mentre il l'area all'interno dello spot non verrà influenzata dallo strumento. +TP_LOCALLAB_INVBL_TOOLTIP;Alternativa alla modalità 'Inversa': usa due spot\Primo spot:\nell'immagine intera\in\Secondo spot: escluso lo spot. TP_LOCALLAB_INVERS;Inverso +TP_LOCALLAB_INVERS_TOOLTIP;Meno possibilità se selezionato (Inverso).\n\nAlternativa: usa due spot\nPrimo spot:\n Immagine intera\n \nSecondo spot: escluso spot\n\n Inverso abiliterà questo strumento per l'area esterna allo spot, mentre il l'area all'interno dello spot non verrà influenzata dallo strumento. TP_LOCALLAB_INVMASK;Algoritmo inverso TP_LOCALLAB_ISOGR;Distribuzione (ISO) TP_LOCALLAB_JAB;Usa la compensazione dell'esposizione dei neri e la compensazione dell'esposizione dei bianchi TP_LOCALLAB_JABADAP_TOOLTIP;Adattamento uniforme percettivo.\nRegola automaticamente il rapporto tra Jz e saturazione tenendo conto della 'Luminanza assoluta'. -TP_LOCALLAB_JZ100_TOOLTIP;Regola automaticamente il livello di riferimento Jz 100 cd/m2 (segnale immagine).\nModifica il livello di saturazione e l'azione dell''adattamento PU' (adattamento uniforme percettivo). TP_LOCALLAB_JZ100;Riferimento Jz 100cd/m2 +TP_LOCALLAB_JZ100_TOOLTIP;Regola automaticamente il livello di riferimento Jz 100 cd/m2 (segnale immagine).\nModifica il livello di saturazione e l'azione dell''adattamento PU' (adattamento uniforme percettivo). TP_LOCALLAB_JZADAP; Adattamento PU TP_LOCALLAB_JZCH;Crominanza TP_LOCALLAB_JZCHROM;Crominanza TP_LOCALLAB_JZCLARICRES;Unisci crominanza Cz TP_LOCALLAB_JZCLARILRES;Unisci Jz TP_LOCALLAB_JZCONT;Contrasto -TP_LOCALLAB_JZFORCE_TOOLTIP;Consente di forzare il valore Jz massimo su 1 per una migliore risposta dello slider e della curva. TP_LOCALLAB_JZFORCE;Forza il massimo Jz di 1 +TP_LOCALLAB_JZFORCE_TOOLTIP;Consente di forzare il valore Jz massimo su 1 per una migliore risposta dello slider e della curva. TP_LOCALLAB_JZFRA;Jz Cz Hz Regolazioni dell'immagine TP_LOCALLAB_JZHFRA;Curve Hz TP_LOCALLAB_JZHJZFRA;Curva Jz(Hz) TP_LOCALLAB_JZHUECIE;Rotazione della tonalità TP_LOCALLAB_JZLIGHT;Luminosità TP_LOCALLAB_JZLOG;Codifica del registro Jz -TP_LOCALLAB_JZLOGWB_TOOLTIP;Se Auto è abilitato, calcolerà e regolerà i livelli Ev e la 'Luminanza media Yb%' per l'area spot. I valori risultanti verranno utilizzati da tutte le operazioni Jz inclusa 'Log Encoding Jz'.\nCalcola anche la luminanza assoluta al momento dello scatto. TP_LOCALLAB_JZLOGWBS_TOOLTIP;Le regolazioni Ev nero e Ev bianco possono essere diverse a seconda che venga utilizzata la codifica Log o Sigmoid.\nPer Sigmoid, potrebbe essere necessario un cambiamento (aumento nella maggior parte dei casi) di Ev bianco per ottenere una migliore resa delle luci, del contrasto e della saturazione. +TP_LOCALLAB_JZLOGWB_TOOLTIP;Se Auto è abilitato, calcolerà e regolerà i livelli Ev e la 'Luminanza media Yb%' per l'area spot. I valori risultanti verranno utilizzati da tutte le operazioni Jz inclusa 'Log Encoding Jz'.\nCalcola anche la luminanza assoluta al momento dello scatto. TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb è la luminanza relativa dello sfondo, espressa come percentuale di grigio. Il 18% di grigio corrisponde a una luminanza di sfondo del 50% quando espressa in CIE L.\nI dati si basano sulla luminanza media dell'immagine.\nSe utilizzata con Log Encoding, la luminanza media viene utilizzata per determinare la quantità di guadagno necessaria da applicare al segnale prima della codifica del log. Valori più bassi di luminanza media si tradurranno in un aumento del guadagno. TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (solo in modalità 'Avanzata'). Funziona solo se il dispositivo di output (monitor) è HDR (luminanza di picco superiore a 100 cd/m2 - idealmente tra 4000 e 10000 cd/m2. Luminanza del punto nero inferiore a 0,005 cd/m2). Ciò presuppone che a) l'ICC-PCS per lo schermo utilizzi Jzazbz (o XYZ), b) funzioni con precisione reale, c) che il monitor sia calibrato (se possibile con una gamma DCI-P3 o Rec-2020), d) che la solita gamma (sRGB o BT709) è sostituita da una funzione Perceptual Quantiser (PQ). -TP_LOCALLAB_JZPQFRA_TOOLTIP;Permette di adattare l'algoritmo Jz ad un ambiente SDR o alle caratteristiche (prestazioni) di un ambiente HDR come segue:\n a) per valori di luminanza compresi tra 0 e 100 cd/m2, il sistema si comporta come se fosse in un ambiente SDR .\n b) per valori di luminanza compresi tra 100 e 10000 cd/m2 è possibile adattare l'algoritmo alle caratteristiche HDR dell'immagine e del monitor.\n\nSe 'PQ - Luminanza di picco' è impostato su 10000, 'Rimappatura Jz' si comporta allo stesso modo dell'algoritmo Jzazbz originale. TP_LOCALLAB_JZPQFRA;Rimappatura Jz -TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Quantizzatore percettivo): consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 120 cd/m2).\nPuò essere utilizzato per adattarsi a diverse immagini, processi e dispositivi. +TP_LOCALLAB_JZPQFRA_TOOLTIP;Permette di adattare l'algoritmo Jz ad un ambiente SDR o alle caratteristiche (prestazioni) di un ambiente HDR come segue:\n a) per valori di luminanza compresi tra 0 e 100 cd/m2, il sistema si comporta come se fosse in un ambiente SDR .\n b) per valori di luminanza compresi tra 100 e 10000 cd/m2 è possibile adattare l'algoritmo alle caratteristiche HDR dell'immagine e del monitor.\n\nSe 'PQ - Luminanza di picco' è impostato su 10000, 'Rimappatura Jz' si comporta allo stesso modo dell'algoritmo Jzazbz originale. TP_LOCALLAB_JZPQREMAP;PQ - Luminanza di picco -TP_LOCALLAB_JZQTOJ_TOOLTIP;Ti permette di utilizzare 'Luminanza relativa' invece di 'Luminanza assoluta' - La luminosità diventa Luminosità.\nLe modifiche influiscono: sul cursore Luminosità, sul cursore Contrasto e sulla curva Jz(Jz). +TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Quantizzatore percettivo): consente di modificare la funzione PQ interna (solitamente 10000 cd/m2 - predefinito 120 cd/m2).\nPuò essere utilizzato per adattarsi a diverse immagini, processi e dispositivi. TP_LOCALLAB_JZQTOJ;Luminanza relativa +TP_LOCALLAB_JZQTOJ_TOOLTIP;Ti permette di utilizzare 'Luminanza relativa' invece di 'Luminanza assoluta' - La luminosità diventa Luminosità.\nLe modifiche influiscono: sul cursore Luminosità, sul cursore Contrasto e sulla curva Jz(Jz). TP_LOCALLAB_JZSAT;Saturatione TP_LOCALLAB_JZSHFRA;Ombre/Alteluci Jz TP_LOCALLAB_JZSOFTCIE;Raggio morbido (Filtro guidato) @@ -3079,59 +3071,58 @@ TP_LOCALLAB_JZTHRHCIE;Soglia cromatica per Jz(Hz) TP_LOCALLAB_JZWAVEXP;Wavelet Jz TP_LOCALLAB_LABBLURM;Maschera di sfocatura TP_LOCALLAB_LABEL;Aggiustamenti locali -TP_LOCALLAB_LABGRID_VALUES;Alto(a)=%1 Alto(b)=%2\nBasso(a)=%3 Basso(b)=%4 TP_LOCALLAB_LABGRID;Griglia di correzione del colore TP_LOCALLAB_LABGRIDMERG;Sfondo +TP_LOCALLAB_LABGRID_VALUES;Alto(a)=%1 Alto(b)=%2\nBasso(a)=%3 Basso(b)=%4 TP_LOCALLAB_LABSTRUM;Maschera di struttura -TP_LOCALLAB_LAP_MASK_TOOLTIP;Risolve i PDE per tutte le maschere laplaciane.\nSe abilitata, la maschera della soglia laplaciana riduce gli artefatti e uniforma il risultato.\nSe disabilitata, la risposta è lineare. TP_LOCALLAB_LAPLACC;ΔØ La maschera laplaciana risolve la PDE TP_LOCALLAB_LAPLACE;Soglia laplaciana ΔE TP_LOCALLAB_LAPLACEXP;Soglia laplaciana TP_LOCALLAB_LAPMASKCOL;Soglia laplaciana -TP_LOCALLAB_LAPRAD_TOOLTIP;Il raggio uniforme utilizza un filtro guidato per ridurre gli artefatti e uniformare la transizione. TP_LOCALLAB_LAPRAD1_TOOLTIP;Aumenta il contrasto della maschera aumentando i valori di luminanza delle aree più chiare. Può essere utilizzato insieme alle curve L(L) e LC(H). TP_LOCALLAB_LAPRAD2_TOOLTIP;Il raggio uniforme utilizza un filtro guidato per ridurre gli artefatti e uniformare la transizione. +TP_LOCALLAB_LAPRAD_TOOLTIP;Il raggio uniforme utilizza un filtro guidato per ridurre gli artefatti e uniformare la transizione. +TP_LOCALLAB_LAP_MASK_TOOLTIP;Risolve i PDE per tutte le maschere laplaciane.\nSe abilitata, la maschera della soglia laplaciana riduce gli artefatti e uniforma il risultato.\nSe disabilitata, la risposta è lineare. +TP_LOCALLAB_LCLABELS;Livelli di rumore residuo +TP_LOCALLAB_LCLABELS_TOOLTIP;Visualizza i valori di rumore medio e alto per l'area mostrata nel pannello di anteprima (con zoom al 100%). I valori del rumore sono raggruppati per livelli wavelet 0,1,2,3 e 4,5,6.\nI valori visualizzati sono solo indicativi e sono progettati per assistere nelle regolazioni del rumore. Non devono essere interpretati come livelli di rumore assoluti.\n\n 300: Molto rumoroso\n 100-300: Rumoroso\n 50-100: Moderatamente rumoroso\n < 50: Basso rumore\n\nPermettono di vedere:\ n*L'impatto della riduzione del rumore nella scheda Dettagli del menu principale.\n*L'influenza delle medie non locali, delle wavelet e del DCT sul rumore della luminanza.\n*L'influenza delle wavelet e del DCT sul rumore della crominanza.\n *L'influenza di cattura nitidezza e demosaicizzazione. TP_LOCALLAB_LC_FFTW_TOOLTIP;La FFT migliora la qualità e consente l'utilizzo di raggi ampi, ma aumenta i tempi di lavorazione (dipende dall'area da trattare). Preferibile l'utilizzo solo per raggi ampi. La dimensione dell'area può essere ridotta di alcuni pixel per ottimizzare la FFTW. Ciò può ridurre il tempo di elaborazione di un fattore da 1,5 a 10. TP_LOCALLAB_LC_TOOLNAME;Contrasto locale e wavelet -TP_LOCALLAB_LCLABELS_TOOLTIP;Visualizza i valori di rumore medio e alto per l'area mostrata nel pannello di anteprima (con zoom al 100%). I valori del rumore sono raggruppati per livelli wavelet 0,1,2,3 e 4,5,6.\nI valori visualizzati sono solo indicativi e sono progettati per assistere nelle regolazioni del rumore. Non devono essere interpretati come livelli di rumore assoluti.\n\n 300: Molto rumoroso\n 100-300: Rumoroso\n 50-100: Moderatamente rumoroso\n < 50: Basso rumore\n\nPermettono di vedere:\ n*L'impatto della riduzione del rumore nella scheda Dettagli del menu principale.\n*L'influenza delle medie non locali, delle wavelet e del DCT sul rumore della luminanza.\n*L'influenza delle wavelet e del DCT sul rumore della crominanza.\n *L'influenza di cattura nitidezza e demosaicizzazione. -TP_LOCALLAB_LCLABELS;Livelli di rumore residuo TP_LOCALLAB_LEVELBLUR;Livelli massimi di sfocatura -TP_LOCALLAB_LEVELWAV_TOOLTIP;Il Livello si adatta automaticamente alla dimensione dello spot e dell'anteprima.\Dal livello 9 dimensione max 512 al livello 1 dimensione max = 4. TP_LOCALLAB_LEVELWAV;Livelli di Wavelet +TP_LOCALLAB_LEVELWAV_TOOLTIP;Il Livello si adatta automaticamente alla dimensione dello spot e dell'anteprima.\Dal livello 9 dimensione max 512 al livello 1 dimensione max = 4. TP_LOCALLAB_LEVFRA;Livelli -TP_LOCALLAB_LIGHTN_TOOLTIP;In modalità inversa: la selezione = -100 forza la luminanza a zero. TP_LOCALLAB_LIGHTNESS;Luminosità +TP_LOCALLAB_LIGHTN_TOOLTIP;In modalità inversa: la selezione = -100 forza la luminanza a zero. TP_LOCALLAB_LIGHTRETI;Luminosità TP_LOCALLAB_LINEAR;Linearità TP_LOCALLAB_LIST_NAME;Aggiungi strumento al punto corrente... TP_LOCALLAB_LIST_TOOLTIP;Puoi selezionare 3 livelli di complessità per ciascuno strumento: Base, Standard e Avanzato.\nL'impostazione predefinita per tutti gli strumenti è Base ma può essere modificata nella finestra Preferenze.\nPuoi anche modificare il livello di complessità per strumento base durante la modifica. TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Permette di diminuire o aumentare l'effetto su particolari livelli di dettaglio della maschera puntando su determinate zone di luminanza (in genere le più chiare). TP_LOCALLAB_LMASK_LL_TOOLTIP;Ti permette di cambiare liberamente il contrasto della maschera.\n Ha una funzione simile ai cursori Gamma e Pendenza.\n Ti permette di individuare alcune parti dell'immagine (solitamente le parti più chiare della maschera utilizzando la curva per escludere le parti più scure). Può creare artefatti. +TP_LOCALLAB_LOCCONT;Maschera di contrasto TP_LOCALLAB_LOC_CONTRAST;Contrasto locale e wavelet TP_LOCALLAB_LOC_CONTRASTPYR;Piramide 1: TP_LOCALLAB_LOC_CONTRASTPYR2;Piramide 2: TP_LOCALLAB_LOC_CONTRASTPYR2LAB; Contrasto per livello/TM/Contrasto direzionale TP_LOCALLAB_LOC_CONTRASTPYRLAB; Filtro graduato/Nitidezza bordi/Sfocatura TP_LOCALLAB_LOC_RESIDPYR;Immagine residua (principale) -TP_LOCALLAB_LOCCONT;Maschera di contrasto -TP_LOCALLAB_LOG_TOOLNAME;Codifica del registro TP_LOCALLAB_LOG;Codifica del registro TP_LOCALLAB_LOG1FRA;CAM16 Regolazioni dell'immagine TP_LOCALLAB_LOG2FRA;Condizioni di visualizzazione -TP_LOCALLAB_LOGAUTO_TOOLTIP;Premendo questo pulsante si calcolerà la gamma dinamica e la 'Luminanza media' per le condizioni della scena se è selezionata la 'Luminanza media automatica (Yb%)).\nCalcola anche la luminanza assoluta al momento dello scatto.\nPremere nuovamente il pulsante per regolare i valori calcolati automaticamente. TP_LOCALLAB_LOGAUTO;Automatico -TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Calcola automaticamente la "luminanza media" per le condizioni della scena quando viene premuto il pulsante "Automatico" in Livelli di esposizione relativa. TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Calcola automaticamente la "luminanza media" per le condizioni della scena. +TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Calcola automaticamente la "luminanza media" per le condizioni della scena quando viene premuto il pulsante "Automatico" in Livelli di esposizione relativa. +TP_LOCALLAB_LOGAUTO_TOOLTIP;Premendo questo pulsante si calcolerà la gamma dinamica e la 'Luminanza media' per le condizioni della scena se è selezionata la 'Luminanza media automatica (Yb%)).\nCalcola anche la luminanza assoluta al momento dello scatto.\nPremere nuovamente il pulsante per regolare i valori calcolati automaticamente. TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValori inferiori a 2 riducono l'azione dell'algoritmo rendendo le ombre più scure e le luci più luminose.\nCon valori maggiori di 2, le ombre sono più grigie e le luci diventano più sbiadite. TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -TP_LOCALLAB_LOGCIE_TOOLTIP;Consente di utilizzare Nero Ev, Bianco Ev, Luminanza media scena (Yb%) e Luminanza media visualizzazione (Yb%) per la mappatura dei toni utilizzando la codifica Log Q. TP_LOCALLAB_LOGCIE;Codifica del registro anziché Sigmoid -TP_LOCALLAB_LOGCOLORF_TOOLTIP;Quantità di tonalità percepita in relazione al grigio.\nIndicatore che uno stimolo appare più o meno colorato. +TP_LOCALLAB_LOGCIE_TOOLTIP;Consente di utilizzare Nero Ev, Bianco Ev, Luminanza media scena (Yb%) e Luminanza media visualizzazione (Yb%) per la mappatura dei toni utilizzando la codifica Log Q. TP_LOCALLAB_LOGCOLORFL;Colorazione (M) +TP_LOCALLAB_LOGCOLORF_TOOLTIP;Quantità di tonalità percepita in relazione al grigio.\nIndicatore che uno stimolo appare più o meno colorato. TP_LOCALLAB_LOGCONQL;Contrasto (Q) TP_LOCALLAB_LOGCONTHRES;Soglia di Contrasto (J & Q) -TP_LOCALLAB_LOGCONTL_TOOLTIP;Il contrasto (J) in CIECAM16 tiene conto dell'aumento della colorazione percepita con la luminanza. TP_LOCALLAB_LOGCONTL;Contrasto (J) +TP_LOCALLAB_LOGCONTL_TOOLTIP;Il contrasto (J) in CIECAM16 tiene conto dell'aumento della colorazione percepita con la luminanza. TP_LOCALLAB_LOGCONTQ_TOOLTIP;Il contrasto (Q) in CIECAM16 tiene conto dell'aumento della colorazione percepita con la luminosità. TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Regola la gamma di contrasto dei toni medi (J e Q).\nI valori positivi riducono progressivamente l'effetto dei cursori Contrasto (J e Q). I valori negativi aumentano progressivamente l'effetto dei cursori Contrasto. TP_LOCALLAB_LOGDETAIL_TOOLTIP;Agisce principalmente sulle alte frequenze. @@ -3140,44 +3131,43 @@ TP_LOCALLAB_LOGEXP;Tutti gli strumenti TP_LOCALLAB_LOGFRA;Condizioni della scena TP_LOCALLAB_LOGFRAME_TOOLTIP;Consente di calcolare e regolare i livelli Ev e la "luminanza media Yb%" (punto grigio sorgente) per l'area spot. I valori risultanti verranno utilizzati da tutte le operazioni di laboratorio e dalla maggior parte delle operazioni RGB in corso.\nCalcola inoltre la luminanza assoluta al momento dello scatto. TP_LOCALLAB_LOGIMAGE_TOOLTIP;Tiene conto delle variabili Ciecam corrispondenti: ovvero Contrasto (J) e Saturazione (s), nonché Contrasto (Q), Luminosità (Q), Luminosità (J) e Colorazione (M) (in modalità Avanzata). -TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Vicino alla Luminosità (L*a*b*). Tiene conto dell'aumento della colorazione percepita. TP_LOCALLAB_LOGLIGHTL;Luminosità (J) -TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Quantità percepita di luce emanata da uno stimolo.\nIndicatore che uno stimolo sembra essere più o meno luminoso, chiaro. +TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Vicino alla Luminosità (L*a*b*). Tiene conto dell'aumento della colorazione percepita. TP_LOCALLAB_LOGLIGHTQ;Luminosità (Q) +TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Quantità percepita di luce emanata da uno stimolo.\nIndicatore che uno stimolo sembra essere più o meno luminoso, chiaro. TP_LOCALLAB_LOGLIN;Modalità logaritmo TP_LOCALLAB_LOGPFRA;Livelli di esposizione relativa -TP_LOCALLAB_LOGREPART_TOOLTIP;Consente di regolare la forza relativa dell'immagine con codifica log rispetto all'immagine originale.\nNon influisce sul componente Ciecam. TP_LOCALLAB_LOGREPART;Overall strength +TP_LOCALLAB_LOGREPART_TOOLTIP;Consente di regolare la forza relativa dell'immagine con codifica log rispetto all'immagine originale.\nNon influisce sul componente Ciecam. TP_LOCALLAB_LOGSATURL_TOOLTIP;La saturazione (s) in CIECAM16 corrisponde al colore di uno stimolo in relazione alla propria luminosità.\nAgisce principalmente sui toni medi e sulle alte luci. TP_LOCALLAB_LOGSCENE_TOOLTIP;Corrisponde alle condizioni di ripresa. TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Modifica toni e colori per tenere conto delle condizioni della scena.\n\nMedia: condizioni di luce medie (standard). L'immagine non cambierà.\n\nDim: condizioni di luminosità. L'immagine diventerà leggermente più luminosa.\n\nScuro: condizioni di oscurità. L'immagine diventerà più luminosa. TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corrisponde al supporto su cui verrà visualizzata l'immagine finale (monitor, TV, proiettore, stampante, ecc.), nonché alle condizioni circostanti. +TP_LOCALLAB_LOG_TOOLNAME;Codifica del registro TP_LOCALLAB_LUM;LL - CC TP_LOCALLAB_LUM46LABEL;Livelli luminanza 456: Media=%1 Alta=%2 TP_LOCALLAB_LUMADARKEST;Più oscuro -TP_LOCALLAB_LUMASK_TOOLTIP;Regola la tonalità di grigio o il colore dello sfondo della maschera in Mostra maschera (Maschera e modifiche). TP_LOCALLAB_LUMASK;Maschera colore/luminosità dello sfondo +TP_LOCALLAB_LUMASK_TOOLTIP;Regola la tonalità di grigio o il colore dello sfondo della maschera in Mostra maschera (Maschera e modifiche). TP_LOCALLAB_LUMAWHITESEST;Il più leggero TP_LOCALLAB_LUMFRA;Norma L*a*b* TP_LOCALLAB_LUMLABEL;Livelli luminanza 0123: Media=%1 Alta=%2 -TP_LOCALLAB_MASFRAME_TOOLTIP;Per tutte le maschere.\nPrende in considerazione l'immagine ΔE per evitare di modificare l'area di selezione quando vengono utilizzati i seguenti strumenti maschera: Gamma, Pendenza, Crominanza, Curva di contrasto, Contrasto locale (per livello wavelet), Maschera di sfocatura e Maschera di struttura (se abilitata ).\nDisabilitato quando viene utilizzata la modalità Inversa. TP_LOCALLAB_MASFRAME;Maschera e Unisci -TP_LOCALLAB_MASK_TOOLTIP;Puoi abilitare più maschere per uno strumento attivando un altro strumento e utilizzando solo la maschera (imposta i cursori dello strumento su 0 ).\n\nPuoi anche duplicare il punto e posizionarlo vicino al primo punto. Le piccole variazioni nei riferimenti spot consentono di effettuare regolazioni fini. +TP_LOCALLAB_MASFRAME_TOOLTIP;Per tutte le maschere.\nPrende in considerazione l'immagine ΔE per evitare di modificare l'area di selezione quando vengono utilizzati i seguenti strumenti maschera: Gamma, Pendenza, Crominanza, Curva di contrasto, Contrasto locale (per livello wavelet), Maschera di sfocatura e Maschera di struttura (se abilitata ).\nDisabilitato quando viene utilizzata la modalità Inversa. TP_LOCALLAB_MASK;Curve TP_LOCALLAB_MASK2;Curva di contrasto +TP_LOCALLAB_MASKCOM;Maschera di colore comune TP_LOCALLAB_MASKCOM_TOOLNAME;Maschera di colore comune TP_LOCALLAB_MASKCOM_TOOLTIP;Uno strumento a sé stante.\Può essere utilizzato per regolare l'aspetto dell'immagine (crominanza, luminanza, contrasto) e la trama in funzione di Scope. -TP_LOCALLAB_MASKCOM;Maschera di colore comune TP_LOCALLAB_MASKCURVE_TOOLTIP;Le 3 curve sono impostate su 1 (massimo) per impostazione predefinita:\nC=f(C) la crominanza varia in base alla crominanza. È possibile diminuire la crominanza per migliorare la selezione. Impostando questa curva vicino allo zero (con un valore basso di C per attivare la curva) è possibile desaturare lo sfondo in modalità Inversa.\nL=f(L) la luminanza varia in base alla luminanza, quindi è possibile diminuire la luminosità a migliorare la selezione.\nL e C = f(H) la luminanza e la crominanza variano con la tonalità, quindi è possibile diminuire la luminanza e la crominanza per migliorare la selezione. TP_LOCALLAB_MASKDDECAY;Intensità di decadimento -TP_LOCALLAB_MASKDE_TOOLTIP;Utilizzato per indirizzare l'eliminazione del rumore in funzione delle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitata per utilizzare questa funzione.\n Se la maschera è al di sotto della soglia 'scura', la riduzione del rumore verrà applicata progressivamente.\n iSe la maschera è al di sopra della soglia 'chiara', la riduzione del rumore verrà applicata progressivamente.\n Tra In entrambi i casi, le impostazioni dell'immagine senza Denoise verranno mantenute, a meno che non si regoli i cursori 'Rimozione rumore luminanza area grigia' o 'Rimozione rumore crominanza area grigia'. TP_LOCALLAB_MASKDECAY_TOOLTIP;Gestisce il tasso di decadimento per i livelli di grigio nella maschera.\n Decay = 1 lineare, Decay > 1 transizioni paraboliche più nette, Decay < 1 transizioni più graduali. TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. +TP_LOCALLAB_MASKDE_TOOLTIP;Utilizzato per indirizzare l'eliminazione del rumore in funzione delle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitata per utilizzare questa funzione.\n Se la maschera è al di sotto della soglia 'scura', la riduzione del rumore verrà applicata progressivamente.\n iSe la maschera è al di sopra della soglia 'chiara', la riduzione del rumore verrà applicata progressivamente.\n Tra In entrambi i casi, le impostazioni dell'immagine senza Denoise verranno mantenute, a meno che non si regoli i cursori 'Rimozione rumore luminanza area grigia' o 'Rimozione rumore crominanza area grigia'. TP_LOCALLAB_MASKGF_TOOLTIP;Utilizzato per indirizzare il filtro guidato in funzione delle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o la maschera LC(H) deve essere abilitato a utilizzare questa funzione.\n Se la maschera è al di sotto della soglia 'scura', il GF verrà applicato progressivamente.\n Se la maschera è al di sopra della soglia 'chiara', il GF verrà applicato progressivamente.\n Tra i due, verranno mantenute le impostazioni dell'immagine senza GF. TP_LOCALLAB_MASKH;Curva tonalità -TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; Il filtro guidato viene progressivamente ridotto dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (come determinato dalla maschera).\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'struttura maschera', 'Raggio uniforme', 'Gamma e pendenza', 'Curva di contrasto', 'Wavelet di contrasto locale'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. -TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura' , 'Maschera di sfocatura', 'Raggio attenuato', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Limite del tono più chiaro oltre il quale i parametri CBDL (solo luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni CBDL.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio :'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\nUtilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura' , 'Maschera di sfocatura', 'Raggio attenuato', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; Il rumore viene progressivamente ridotto dal 100% dell'impostazione della soglia allo 0% al valore massimo del bianco (come determinato dalla maschera).\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura ', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai valori originali prima di essere modificati dalle impostazioni "Gamma dinamica ed esposizione".\n Puoi utilizzare alcuni strumenti in "Maschera e modifiche" per modificare i livelli di grigio: " Raggio uniforme", Gamma e Pendenza, "Curva di contrasto".\n Utilizza un "selettore colori bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di codifica del registro.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Raggio uniforme', 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. @@ -3186,17 +3176,17 @@ TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Limite di tono più chiaro oltre il quale i pa TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Mappatura tono.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Limite del tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Vividezza e Caldo Freddo.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Raggio uniforme ', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Limite di tono più chiaro oltre il quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Contrasto locale e Wavelet.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme ', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. -TP_LOCALLAB_MASKLC_TOOLTIP;Utilizzato dalla luminanza wavelet.\nCiò consente di indirizzare la riduzione del rumore in base alle informazioni sulla luminanza dell'immagine contenute nella maschera L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n 'Soglia luminanza area scura'. Se 'Rafforza il denoise nelle aree scure e chiare' > 1 il denoise viene progressivamente aumentato dallo 0% all'impostazione della soglia al 100% al valore massimo del nero (determinato dalla maschera).\n 'Soglia luminanza dell'area chiara'. La riduzione del rumore viene progressivamente ridotta dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (determinato dalla maschera).\n Nell'area tra le due soglie, le impostazioni della riduzione del rumore non sono influenzate dalla maschera. +TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; Il filtro guidato viene progressivamente ridotto dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (come determinato dalla maschera).\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'struttura maschera', 'Raggio uniforme', 'Gamma e pendenza', 'Curva di contrasto', 'Wavelet di contrasto locale'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLCTHR;Soglia di luminanza dell'area chiara TP_LOCALLAB_MASKLCTHR2;Soglia luminanza dell'area chiara TP_LOCALLAB_MASKLCTHRLOW;Soglia di luminanza dell'area scura TP_LOCALLAB_MASKLCTHRLOW2;Soglia luminanza dell'area scura TP_LOCALLAB_MASKLCTHRMID;Rimuovi rumore luminanza dell'area grigia TP_LOCALLAB_MASKLCTHRMIDCH;Rimuovi rumore crominanza area grigia +TP_LOCALLAB_MASKLC_TOOLTIP;Utilizzato dalla luminanza wavelet.\nCiò consente di indirizzare la riduzione del rumore in base alle informazioni sulla luminanza dell'immagine contenute nella maschera L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC( H) la maschera deve essere abilitata per utilizzare questa funzione.\n 'Soglia luminanza area scura'. Se 'Rafforza il denoise nelle aree scure e chiare' > 1 il denoise viene progressivamente aumentato dallo 0% all'impostazione della soglia al 100% al valore massimo del nero (determinato dalla maschera).\n 'Soglia luminanza dell'area chiara'. La riduzione del rumore viene progressivamente ridotta dal 100% dell'impostazione della soglia allo 0% del valore massimo del bianco (determinato dalla maschera).\n Nell'area tra le due soglie, le impostazioni della riduzione del rumore non sono influenzate dalla maschera. TP_LOCALLAB_MASKLNOISELOW;Rinforza le aree scure/chiare -TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;Il filtro guidato viene progressivamente aumentato dallo 0% dell'impostazione della soglia al 100% del valore massimo del nero (come determinato dalla maschera).\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio : 'Maschera struttura', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. -TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: ' Maschera struttura", "Maschera di sfocatura", "Raggio uniforme", Gamma e pendenza, "Curva di contrasto", "Contrasto locale" (wavelet).\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate . Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri CBDL (solo Luminanza) verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni CBDL.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare il grigio livelli: "Raggio uniforme", Gamma e pendenza, "Curva di contrasto".\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Colore e Luce.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: ' Maschera struttura", "Maschera di sfocatura", "Raggio uniforme", Gamma e pendenza, "Curva di contrasto", "Contrasto locale" (wavelet).\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate . Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;Il rumore viene progressivamente aumentato dallo 0% dell'impostazione della soglia al 100% del valore massimo del nero (come determinato dalla maschera).\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Maschera struttura', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni 'Gamma dinamica ed esposizione'.\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare il grigio livelli: "Raggio uniforme", Gamma e pendenza, "Curva di contrasto".\n Utilizza un "selettore colore bloccabile" sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di codifica del registro.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio:'Smussato raggio', 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. @@ -3205,6 +3195,7 @@ TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Limite del tono scuro al di sotto del quale i TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni di Mappatura toni.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Smussato raggio', Gamma e Pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Vividezza e Caldo Freddo.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Limite del tono scuro al di sotto del quale i parametri verranno ripristinati progressivamente ai loro valori originali prima di essere modificati dalle impostazioni Contrasto locale e Wavelet.\n Puoi utilizzare alcuni strumenti in 'Maschera e modifiche' per modificare i livelli di grigio: 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto'.\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. +TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;Il filtro guidato viene progressivamente aumentato dallo 0% dell'impostazione della soglia al 100% del valore massimo del nero (come determinato dalla maschera).\n Puoi utilizzare determinati strumenti in 'Maschera e modifiche' per modificare i livelli di grigio : 'Maschera struttura', 'Raggio uniforme', Gamma e pendenza, 'Curva di contrasto', 'Contrasto locale' (wavelet).\n Utilizza un 'selettore colore bloccabile' sulla maschera per vedere quali aree saranno interessate. Assicurati di impostare "Maschera colore di sfondo" = 0 in Impostazioni. TP_LOCALLAB_MASKRECOL_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni Colore e Luce in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o LC La maschera (H) deve essere abilitata per utilizzare questa funzione.\n Le aree 'scure' e 'chiare' sotto la soglia scura e sopra la soglia chiara verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dalle impostazioni Colore e Luce \n Tra queste due aree, verrà applicato l'intero valore delle impostazioni Colore e Luce. TP_LOCALLAB_MASKRECOTHRES;Soglia di ripristino TP_LOCALLAB_MASKREEXP_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni 'Gamma dinamica ed esposizione' in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) oppure per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree 'scure' e 'chiare' sotto la soglia di buio e sopra la soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dal ' Impostazioni di "Gamma dinamica ed esposizione" \n Tra queste due aree, verrà applicato il valore completo delle impostazioni di "Gamma dinamica ed esposizione". @@ -3217,9 +3208,10 @@ TP_LOCALLAB_MASKRESVIB_TOOLTIP;Utilizzato per modulare l'effetto delle impostazi TP_LOCALLAB_MASKRESWAV_TOOLTIP;Utilizzato per modulare l'effetto delle impostazioni Contrasto locale e Wavelet in base alle informazioni sulla luminanza dell'immagine contenute nelle maschere L(L) o LC(H) (Maschera e modifiche).\n La maschera L(L) o Per utilizzare questa funzione è necessario abilitare la maschera LC(H).\n Le aree "scure" e "chiare" al di sotto della soglia di buio e al di sopra della soglia di luce verranno ripristinate progressivamente ai loro valori originali prima di essere modificate dal Contrasto locale e Impostazioni Wavelet \n Tra queste due aree, verrà applicato il valore completo delle impostazioni Contrasto locale e Wavelet. TP_LOCALLAB_MASKUNUSABLE;Maschera disabilitata (Maschera e modifiche) TP_LOCALLAB_MASKUSABLE;Maschera abilitata (Maschera e modifiche) -TP_LOCALLAB_MEDIAN_TOOLTIP;Puoi scegliere un valore medio compreso tra 3x3 e 9x9 pixel. Valori più alti aumentano la riduzione del rumore e la sfocatura. +TP_LOCALLAB_MASK_TOOLTIP;Puoi abilitare più maschere per uno strumento attivando un altro strumento e utilizzando solo la maschera (imposta i cursori dello strumento su 0 ).\n\nPuoi anche duplicare il punto e posizionarlo vicino al primo punto. Le piccole variazioni nei riferimenti spot consentono di effettuare regolazioni fini. TP_LOCALLAB_MEDIAN;Mediana bassa TP_LOCALLAB_MEDIANITER_TOOLTIP;Il numero di iterazioni successive eseguite dal filtro mediano. +TP_LOCALLAB_MEDIAN_TOOLTIP;Puoi scegliere un valore medio compreso tra 3x3 e 9x9 pixel. Valori più alti aumentano la riduzione del rumore e la sfocatura. TP_LOCALLAB_MEDNONE;Nessuno TP_LOCALLAB_MERCOL;Colore TP_LOCALLAB_MERDCOL;Unisci sfondo (ΔE) @@ -3250,8 +3242,8 @@ TP_LOCALLAB_MERTHR;Differenza TP_LOCALLAB_MERTWE;Esclusione TP_LOCALLAB_MERTWO;Sottrai TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' aumenta significativamente i tempi di elaborazione.\nMa riduce gli artefatti. -TP_LOCALLAB_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Ritaglia dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. TP_LOCALLAB_MLABEL;Dati ripristinati Min=%1 Max=%2 +TP_LOCALLAB_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Ritaglia dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. TP_LOCALLAB_MODE_EXPERT;Avanzato TP_LOCALLAB_MODE_NORMAL;Standard TP_LOCALLAB_MODE_SIMPLE;Base @@ -3261,10 +3253,10 @@ TP_LOCALLAB_MRONE;Nessuno TP_LOCALLAB_MRTHR;Immagine originale TP_LOCALLAB_MULTIPL_TOOLTIP;Ampia gamma di regolazione del tono: da -18EV a +4EV. Il primo cursore agisce su toni molto scuri compresi tra -18EV e -6EV. L'ultimo cursore agisce sui toni chiari fino a 4EV. TP_LOCALLAB_NEIGH;Raggio -TP_LOCALLAB_NLDENOISE_TOOLTIP;'Recupero dettagli' agisce su una trasformazione laplaciana per individuare aree uniformi anziché aree con dettagli. TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Valori più bassi preservano dettagli e texture, valori più alti aumentano il denoise.\nSe gamma = 3.0 Viene utilizzata la luminanza 'lineare'. TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Utilizza questo cursore per adattare la quantità di riduzione rumore alla dimensione degli oggetti da elaborare. TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Valori più alti aumentano il rumore a scapito del tempo di elaborazione. +TP_LOCALLAB_NLDENOISE_TOOLTIP;'Recupero dettagli' agisce su una trasformazione laplaciana per individuare aree uniformi anziché aree con dettagli. TP_LOCALLAB_NLDET;Recupero dettagli TP_LOCALLAB_NLFRA;Mezzi non locali: Luminanza TP_LOCALLAB_NLFRAME_TOOLTIP;Il denoising delle medie non locali prende una media di tutti i pixel dell'immagine, ponderata in base alla loro somiglianza con il pixel di destinazione.\nRiduce la perdita di dettaglio rispetto agli algoritmi della media locale.\nViene preso in considerazione solo il rumore della luminanza. Il rumore della crominanza viene elaborato al meglio utilizzando wavelet e trasformate di Fourier (DCT).\nPuò essere utilizzato insieme a "Rimozione rumore luminanza per livello" o da solo. @@ -3272,13 +3264,12 @@ TP_LOCALLAB_NLGAM;Gamma TP_LOCALLAB_NLLUM;Forza TP_LOCALLAB_NLPAT;Dimensione massima della patch TP_LOCALLAB_NLRAD;Dimensione massima del raggio -TP_LOCALLAB_NOISE_TOOLTIP;Aggiunge rumore di luminanza. -TP_LOCALLAB_NOISECHROC_TOOLTIP;Se superiore a zero, l'algoritmo di alta qualità è abilitato.\nCoarse è per slider >=0.02. TP_LOCALLAB_NOISECHROCOARSE;Crominanza grossolana (Wav) +TP_LOCALLAB_NOISECHROC_TOOLTIP;Se superiore a zero, l'algoritmo di alta qualità è abilitato.\nCoarse è per slider >=0.02. TP_LOCALLAB_NOISECHRODETAIL;Recupero dettagli crominanza TP_LOCALLAB_NOISECHROFINE;Crominanza fine (Wav) -TP_LOCALLAB_NOISEGAM_TOOLTIP;Se gamma = 1 Luminanza viene utilizzato 'Lab'. Se gamma = 3.0 Viene utilizzata la luminanza 'lineare'.\nValori più bassi preservano dettagli e texture, valori più alti aumentano il rumore. TP_LOCALLAB_NOISEGAM;Gamma +TP_LOCALLAB_NOISEGAM_TOOLTIP;Se gamma = 1 Luminanza viene utilizzato 'Lab'. Se gamma = 3.0 Viene utilizzata la luminanza 'lineare'.\nValori più bassi preservano dettagli e texture, valori più alti aumentano il rumore. TP_LOCALLAB_NOISELEQUAL;Equalizzatore bianco-nero TP_LOCALLAB_NOISELUMCOARSE;Luminanza grossolana (Wav) TP_LOCALLAB_NOISELUMDETAIL;Recupero dettaglio luminanza @@ -3286,6 +3277,7 @@ TP_LOCALLAB_NOISELUMFINE;Luminanza fine 1 (Wav) TP_LOCALLAB_NOISELUMFINETWO;Luminanza fine 2 (Wav) TP_LOCALLAB_NOISELUMFINEZERO;Luminanza fine 0 (Wav) TP_LOCALLAB_NOISEMETH;Rimuovi rumore +TP_LOCALLAB_NOISE_TOOLTIP;Aggiunge rumore di luminanza. TP_LOCALLAB_NONENOISE;Nessuno TP_LOCALLAB_NUL_TOOLTIP;. TP_LOCALLAB_OFFS;Spostamento @@ -3304,17 +3296,17 @@ TP_LOCALLAB_PREVSHOW;Mostra impostazioni aggiuntive TP_LOCALLAB_PROXI;Decadimento ΔE TP_LOCALLAB_QUAAGRES;Aggressivo TP_LOCALLAB_QUACONSER;Conservatore -TP_LOCALLAB_QUAL_METHOD;Qualità globale TP_LOCALLAB_QUALCURV_METHOD;Tipo di curva +TP_LOCALLAB_QUAL_METHOD;Qualità globale TP_LOCALLAB_QUANONEALL;Disattivato TP_LOCALLAB_QUANONEWAV;Significa solo non-locale -TP_LOCALLAB_RADIUS_TOOLTIP;Utilizza una trasformata veloce di Fourier per raggio > 30. TP_LOCALLAB_RADIUS;Raggio +TP_LOCALLAB_RADIUS_TOOLTIP;Utilizza una trasformata veloce di Fourier per raggio > 30. TP_LOCALLAB_RADMASKCOL;Raggio uniforme TP_LOCALLAB_RECOTHRES02_TOOLTIP;Se il valore della 'Soglia di ripristino' è maggiore di 1, la maschera in Maschera e Modifiche tiene conto di eventuali modifiche precedenti apportate all'immagine ma non di quelle apportate con lo strumento corrente (es. Colore e Luce, Wavelet, Cam16, ecc.) .)\nSe il valore della 'Soglia di ripristino' è inferiore a 1, la maschera in Maschera e Modifiche non tiene conto di eventuali modifiche precedenti all'immagine.\n\nIn entrambi i casi, la 'Soglia di ripristino' agisce sulla immagine mascherata modificata dallo strumento corrente (Colore e Luce, Wavelet, Cam16, ecc.). TP_LOCALLAB_RECT;Rettangolo -TP_LOCALLAB_RECURS_TOOLTIP;Forza l'algoritmo a ricalcolare i riferimenti dopo l'applicazione di ogni strumento.\nUtile anche per lavorare con le maschere. TP_LOCALLAB_RECURS;Riferimenti ricorsivi +TP_LOCALLAB_RECURS_TOOLTIP;Forza l'algoritmo a ricalcolare i riferimenti dopo l'applicazione di ogni strumento.\nUtile anche per lavorare con le maschere. TP_LOCALLAB_REN_DIALOG_LAB;Inserisci il nome del nuovo punto di controllo TP_LOCALLAB_REN_DIALOG_NAME;Rinominare punto di controllo TP_LOCALLAB_REPARCOL_TOOLTIP;Permette di regolare l'intensità relativa dell'immagine Colore e Luce rispetto all'immagine originale. @@ -3332,17 +3324,17 @@ TP_LOCALLAB_RESIDHI;Alteluci TP_LOCALLAB_RESIDHITHR;Soglia evidenziazioni TP_LOCALLAB_RESIDSHA;Ombre TP_LOCALLAB_RESIDSHATHR;Soglia ombre -TP_LOCALLAB_RET_TOOLNAME;Rimozione foschia e Retinex -TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Non ha effetto quando il valore di 'Chiarezza = 1' o 'Scurità =2'.\nPer altri valori, viene applicato l'ultimo passaggio di un algoritmo 'Retinex a scala multipla' (simile a 'contrasto locale'). Questi 2 cursori, associati a 'Intensità', consentono di effettuare regolazioni a monte del contrasto locale. -TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Regola i parametri interni per ottimizzare la risposta.\nPreferibile mantenere i valori 'Dati ripristinati' vicini a Min=0 e Max=32768 (modalità registro), ma sono possibili altri valori. -TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;La modalità logaritmo introduce più contrasto ma genererà anche più aloni. -TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;I cursori del raggio e della varianza ti consentono di regolare la foschia e puntare al primo piano o allo sfondo. -TP_LOCALLAB_RETI_SCALE_TOOLTIP;Se Scala=1, Retinex si comporta come contrasto locale con possibilità aggiuntive.\nAumentando il valore di Scala aumenta l'intensità dell'azione ricorsiva a scapito del tempo di elaborazione. TP_LOCALLAB_RETI;Rimozione foschia e Retinex TP_LOCALLAB_RETIFRA;Retinex TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex può essere utile per elaborare immagini:\nche sono sfocate, nebbiose o confuse (oltre a Dehaze).\nche contengono grandi differenze di luminanza.\nPuò essere utilizzato anche per effetti speciali (mappatura dei toni). TP_LOCALLAB_RETIM;Retinex originale TP_LOCALLAB_RETITOOLFRA;Strumenti Retinex +TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Non ha effetto quando il valore di 'Chiarezza = 1' o 'Scurità =2'.\nPer altri valori, viene applicato l'ultimo passaggio di un algoritmo 'Retinex a scala multipla' (simile a 'contrasto locale'). Questi 2 cursori, associati a 'Intensità', consentono di effettuare regolazioni a monte del contrasto locale. +TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Regola i parametri interni per ottimizzare la risposta.\nPreferibile mantenere i valori 'Dati ripristinati' vicini a Min=0 e Max=32768 (modalità registro), ma sono possibili altri valori. +TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;La modalità logaritmo introduce più contrasto ma genererà anche più aloni. +TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;I cursori del raggio e della varianza ti consentono di regolare la foschia e puntare al primo piano o allo sfondo. +TP_LOCALLAB_RETI_SCALE_TOOLTIP;Se Scala=1, Retinex si comporta come contrasto locale con possibilità aggiuntive.\nAumentando il valore di Scala aumenta l'intensità dell'azione ricorsiva a scapito del tempo di elaborazione. +TP_LOCALLAB_RET_TOOLNAME;Rimozione foschia e Retinex TP_LOCALLAB_REWEI;La riponderazione itera TP_LOCALLAB_RGB;Curva toni RGB TP_LOCALLAB_RGBCURVE_TOOLTIP;In modalità RGB hai 4 scelte: Standard, Standard ponderato, Luminanza e Simil-pellicola. @@ -3354,15 +3346,14 @@ TP_LOCALLAB_SATURV;Saturazione (s) TP_LOCALLAB_SCALEGR;Scala TP_LOCALLAB_SCALERETI;Scala TP_LOCALLAB_SCALTM;Scala -TP_LOCALLAB_SCOPEMASK_TOOLTIP;Abilitato se la maschera immagine ΔE è abilitata.\nValori bassi evitano il ritocco dell'area selezionata. TP_LOCALLAB_SCOPEMASK;Ambito (maschera immagine ΔE) -TP_LOCALLAB_SENSI_TOOLTIP;Regola l'ambito dell'azione:\nValori piccoli limitano l'azione a colori simili a quelli al centro del punto.\nValori alti consentono allo strumento di agire su una gamma più ampia di colori. +TP_LOCALLAB_SCOPEMASK_TOOLTIP;Abilitato se la maschera immagine ΔE è abilitata.\nValori bassi evitano il ritocco dell'area selezionata. TP_LOCALLAB_SENSI;Ambito -TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Regola i colori da escludere. TP_LOCALLAB_SENSIEXCLU;Ambito +TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Regola i colori da escludere. TP_LOCALLAB_SENSIMASK_TOOLTIP;Regolazione dell'ambito specifica per il comune strumento maschera.\nAgisce sulla differenza tra l'immagine originale e la maschera.\nUtilizza i riferimenti luminanza, crominanza e tonalità dal centro dello spot\n\nPuoi anche regolare il ΔE del mascherarsi utilizzando 'Ambito (maschera immagine ΔE)' in 'Impostazioni' > 'Maschera e unisci'. +TP_LOCALLAB_SENSI_TOOLTIP;Regola l'ambito dell'azione:\nValori piccoli limitano l'azione a colori simili a quelli al centro del punto.\nValori alti consentono allo strumento di agire su una gamma più ampia di colori. TP_LOCALLAB_SETTINGS;Impostazioni -TP_LOCALLAB_SH_TOOLNAME;Ombre/luci ed equalizzatore toni TP_LOCALLAB_SH1;Evidenzia ombre TP_LOCALLAB_SH2;Equalizzatore TP_LOCALLAB_SHADEX;Ombre @@ -3372,15 +3363,15 @@ TP_LOCALLAB_SHADHMASK_TOOLTIP;Abbassa le luci della maschera allo stesso modo de TP_LOCALLAB_SHADMASK_TOOLTIP;Alza le ombre della maschera allo stesso modo dell'algoritmo ombre/luci. TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Regola ombre e luci con i cursori ombre e luci o con un equalizzatore di toni.\nPuò essere utilizzato al posto o insieme al modulo Esposizione.\nPuò anche essere utilizzato come filtro graduato. TP_LOCALLAB_SHAMASKCOL;Ombre -TP_LOCALLAB_SHAPE_TOOLTIP;'Ellisse' è la modalità normale.\n 'Rettangolo' può essere utilizzato in alcuni casi, ad esempio per lavorare in modalità immagine intera posizionando i delimitatori all'esterno dell'area di anteprima. In questo caso, imposta transizione = 100.\n\nGli sviluppi futuri includeranno forme poligonali e curve di Bezier. TP_LOCALLAB_SHAPETYPE;Forma del punto +TP_LOCALLAB_SHAPE_TOOLTIP;'Ellisse' è la modalità normale.\n 'Rettangolo' può essere utilizzato in alcuni casi, ad esempio per lavorare in modalità immagine intera posizionando i delimitatori all'esterno dell'area di anteprima. In questo caso, imposta transizione = 100.\n\nGli sviluppi futuri includeranno forme poligonali e curve di Bezier. TP_LOCALLAB_SHARAMOUNT;Quantità TP_LOCALLAB_SHARBLUR;Raggio di sfocatura TP_LOCALLAB_SHARDAMPING;Smorzamento TP_LOCALLAB_SHARFRAME;Modifiche TP_LOCALLAB_SHARITER;Iterazioni -TP_LOCALLAB_SHARP_TOOLNAME;Nitidezza TP_LOCALLAB_SHARP;Nitidezza +TP_LOCALLAB_SHARP_TOOLNAME;Nitidezza TP_LOCALLAB_SHARRADIUS;Raggio TP_LOCALLAB_SHORTC;Maschera curve corte 'L' TP_LOCALLAB_SHORTCMASK_TOOLTIP;Cortocircuita le 2 curve L(L) e L(H).\nPermette di mixare l'immagine corrente con l'immagine originale modificata dal lavoro della maschera.\nUtilizzabile con le maschere 2, 3, 4, 6, 7. @@ -3395,10 +3386,10 @@ TP_LOCALLAB_SHOWLC;Maschera e modifiche TP_LOCALLAB_SHOWMASK;Mostra maschera TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Visualizza maschere e modifiche.\nAttenzione, puoi visualizzare solo una maschera strumento alla volta.\nMostra immagine modificata: mostra l'immagine modificata compreso l'effetto di eventuali regolazioni e maschere.\nMostra aree modificate senza maschera: mostra le modifiche prima dell'applicazione di qualsiasi maschera.\nMostra aree modificate con maschera: mostra le modifiche dopo l'applicazione di una maschera.\nMostra maschera: mostra l'aspetto della maschera compreso l'effetto di eventuali curve e filtri.\nMostra struttura spot: consente di vedere la maschera di rilevamento della struttura quando il cursore 'Spot struttura' è attivato (se disponibile).\nNota: la maschera viene applicata prima dell'algoritmo di rilevamento della forma. TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Permette di visualizzare le diverse fasi del processo di Fourier.\n Laplace - calcola la derivata seconda della trasformata di Laplace in funzione della soglia.\nFourier - mostra la trasformata laplaciana con DCT.\nPoisson - mostra la soluzione del Poisson DCE.\nNessuna normalizzazione della luminanza: mostra il risultato senza alcuna normalizzazione della luminanza. -TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Può essere utilizzato con 'Maschera e modifiche'.\nSe è selezionato 'Sfocatura e rumore', la maschera non può essere utilizzata per Rimuovi rumore.\nSe è selezionato Riduci rumore, la maschera non può essere utilizzata per 'Sfocatura e rumore'.\ nSe è selezionato 'Sfocatura e rumore + Riduzione rumore', la maschera viene condivisa. Tieni presente che in questo caso, i cursori dell'ambito sia per "Sfocatura e rumore" che per Riduci rumore saranno attivi, quindi è consigliabile utilizzare l'opzione "Mostra modifiche con maschera" quando si apportano eventuali modifiche. TP_LOCALLAB_SHOWMASKTYP1;Sfocatura e rumore TP_LOCALLAB_SHOWMASKTYP2;Rimuovi rumore TP_LOCALLAB_SHOWMASKTYP3;Sfocatura e rumore + Rimuovi rumore +TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Può essere utilizzato con 'Maschera e modifiche'.\nSe è selezionato 'Sfocatura e rumore', la maschera non può essere utilizzata per Rimuovi rumore.\nSe è selezionato Riduci rumore, la maschera non può essere utilizzata per 'Sfocatura e rumore'.\ nSe è selezionato 'Sfocatura e rumore + Riduzione rumore', la maschera viene condivisa. Tieni presente che in questo caso, i cursori dell'ambito sia per "Sfocatura e rumore" che per Riduci rumore saranno attivi, quindi è consigliabile utilizzare l'opzione "Mostra modifiche con maschera" quando si apportano eventuali modifiche. TP_LOCALLAB_SHOWMNONE;Mostra immagine modificata TP_LOCALLAB_SHOWMODIF;Mostra le aree modificate senza maschera TP_LOCALLAB_SHOWMODIF2;Mostra aree modificate @@ -3415,29 +3406,30 @@ TP_LOCALLAB_SHOWT;Maschera e modifiche TP_LOCALLAB_SHOWVI;Maschera e modifiche TP_LOCALLAB_SHRESFRA;Ombre/Alte luci e TRC TP_LOCALLAB_SHTRC_TOOLTIP;In base al 'profilo di lavoro' (solo quelli forniti), modifica i toni dell'immagine agendo su una TRC (Curva di risposta del tono).\nGamma agisce principalmente sui toni chiari.\nSlope agisce principalmente sui toni scuri.\n si consiglia che il TRC di entrambi i dispositivi (monitor e profilo di output) sia sRGB (predefinito). +TP_LOCALLAB_SH_TOOLNAME;Ombre/luci ed equalizzatore toni TP_LOCALLAB_SIGFRA;Sigmoide Q e codifica registro Q TP_LOCALLAB_SIGJZFRA;Sigmoide Jz TP_LOCALLAB_SIGMAWAV;Risposta di attenuazione -TP_LOCALLAB_SIGMOID_TOOLTIP;Permette di simulare un aspetto di Tone-mapping utilizzando sia la funzione 'Ciecam' (o 'Jz') che 'Sigmoid'.\nTre slider: a) Il contrasto agisce sulla forma della curva sigmoidea e di conseguenza sull'intensità ; b) Soglia (punto grigio) distribuisce l'azione in base alla luminanza; c)Blend agisce sull'aspetto finale dell'immagine, contrasto e luminanza. TP_LOCALLAB_SIGMOIDBL;Miscela TP_LOCALLAB_SIGMOIDLAMBDA;Contrasto TP_LOCALLAB_SIGMOIDQJ;Utilizza Ev nero e Ev bianco TP_LOCALLAB_SIGMOIDTH;Soglia (punto grigio) -TP_LOCALLAB_SLOMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente 'L' per evitare eventuali discontinuità. +TP_LOCALLAB_SIGMOID_TOOLTIP;Permette di simulare un aspetto di Tone-mapping utilizzando sia la funzione 'Ciecam' (o 'Jz') che 'Sigmoid'.\nTre slider: a) Il contrasto agisce sulla forma della curva sigmoidea e di conseguenza sull'intensità ; b) Soglia (punto grigio) distribuisce l'azione in base alla luminanza; c)Blend agisce sull'aspetto finale dell'immagine, contrasto e luminanza. TP_LOCALLAB_SLOMASKCOL;Pendenza +TP_LOCALLAB_SLOMASK_TOOLTIP;La regolazione di Gamma e Pendenza può fornire una trasformazione morbida e priva di artefatti della maschera modificando progressivamente 'L' per evitare eventuali discontinuità. TP_LOCALLAB_SLOSH;Pendenza -TP_LOCALLAB_SOFT_TOOLNAME;Luce soffusa e Retinex originale TP_LOCALLAB_SOFT;Luce soffusa e Retinex originale TP_LOCALLAB_SOFTM;Luce soffusa TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Applica una miscela di luce soffusa (identica alla regolazione globale). Esegui scherma e brucia utilizzando l'algoritmo Retinex originale. -TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applica un filtro guidato all'immagine di output per ridurre possibili artefatti. TP_LOCALLAB_SOFTRADIUSCOL;Raggio morbido +TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applica un filtro guidato all'immagine di output per ridurre possibili artefatti. TP_LOCALLAB_SOFTRETI;Riduci gli artefatti ΔE +TP_LOCALLAB_SOFT_TOOLNAME;Luce soffusa e Retinex originale TP_LOCALLAB_SOURCE_ABS;Luminanza assoluta TP_LOCALLAB_SOURCE_GRAY;Luminanza media (Yb%) TP_LOCALLAB_SPECCASE;Casi specifici -TP_LOCALLAB_SPECIAL_TOOLTIP;La casella di controllo ti consente di rimuovere tutte le altre azioni, ad esempio 'Ambito', maschere, cursori ecc., (eccetto le transizioni) e utilizzare solo l'effetto della curva di tono RGB. TP_LOCALLAB_SPECIAL;Utilizzo speciale delle curve RGB +TP_LOCALLAB_SPECIAL_TOOLTIP;La casella di controllo ti consente di rimuovere tutte le altre azioni, ad esempio 'Ambito', maschere, cursori ecc., (eccetto le transizioni) e utilizzare solo l'effetto della curva di tono RGB. TP_LOCALLAB_SPOTNAME;Nuovo punto TP_LOCALLAB_STD;Standard TP_LOCALLAB_STR;Intensità @@ -3452,11 +3444,11 @@ TP_LOCALLAB_STRUC;Struttura TP_LOCALLAB_STRUCCOL;Struttura del punto TP_LOCALLAB_STRUCCOL1;Struttura del punto TP_LOCALLAB_STRUCT_TOOLTIP;Utilizza l'algoritmo Sobel per prendere in considerazione la struttura per il rilevamento della forma.\nAttiva 'Maschera e modifiche' > 'Mostra struttura spot' (Modalità avanzata) per vedere un'anteprima della maschera (senza modifiche).\n\nPuò essere utilizzato insieme alla maschera di struttura, alla maschera di sfocatura e al "Contrasto locale" (per livello wavelet) per migliorare il rilevamento dei bordi.\n\nEffetti delle regolazioni utilizzando Luminosità, Contrasto, Crominanza, Esposizione o altri strumenti non correlati alla maschera visibili utilizzando 'Mostra immagine modificata' o 'Mostra aree modificate con maschera'. -TP_LOCALLAB_STRUMASK_TOOLTIP;Maschera struttura (slider) con la casella di controllo 'Maschera struttura come strumento' deselezionata: In questo caso verrà generata una maschera che mostra la struttura anche se nessuna delle 3 curve è attivata. Le maschere di struttura sono disponibili per maschera (Sfocatura e riduzione disturbo) e maschera (Colore e luce). TP_LOCALLAB_STRUMASKCOL;Intensità maschera struttura +TP_LOCALLAB_STRUMASK_TOOLTIP;Maschera struttura (slider) con la casella di controllo 'Maschera struttura come strumento' deselezionata: In questo caso verrà generata una maschera che mostra la struttura anche se nessuna delle 3 curve è attivata. Le maschere di struttura sono disponibili per maschera (Sfocatura e riduzione disturbo) e maschera (Colore e luce). TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Si consiglia un uso moderato di questo cursore! -TP_LOCALLAB_STYPE_TOOLTIP;Puoi scegliere tra:\nSimmetrico - maniglia sinistra collegata a destra, maniglia superiore collegata a quella inferiore.\nIndipendente - tutte le maniglie sono indipendenti. TP_LOCALLAB_STYPE;Metodo forma +TP_LOCALLAB_STYPE_TOOLTIP;Puoi scegliere tra:\nSimmetrico - maniglia sinistra collegata a destra, maniglia superiore collegata a quella inferiore.\nIndipendente - tutte le maniglie sono indipendenti. TP_LOCALLAB_SYM;Simmetrico (mouse) TP_LOCALLAB_SYMSL;Simmetrico (mouse + cursori) TP_LOCALLAB_TARGET_GRAY;Luminanza media (Yb%) @@ -3465,39 +3457,39 @@ TP_LOCALLAB_THRES;Struttura della soglia TP_LOCALLAB_THRESDELTAE;Soglia ambito ΔE TP_LOCALLAB_THRESRETI;Soglia TP_LOCALLAB_THRESWAV;Soglia di bilanciamento -TP_LOCALLAB_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max sono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nPuoi normalizzare i risultati con il cursore della soglia. TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Media=%3 Sig=%4 -TP_LOCALLAB_TM_MASK;Utilizza mappa di trasmissione +TP_LOCALLAB_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max sono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nPuoi normalizzare i risultati con il cursore della soglia. TP_LOCALLAB_TM;Mappatura toni -TP_LOCALLAB_TONE_TOOLNAME;Mappatura toni -TP_LOCALLAB_TONEMAP_TOOLTIP;Uguale allo strumento di mappatura dei toni nel menu principale.\nLo strumento del menu principale deve essere disattivato se si utilizza questo strumento. +TP_LOCALLAB_TM_MASK;Utilizza mappa di trasmissione TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;Questo cursore influisce sulla sensibilità dei bordi.\n Maggiore è il valore, più è probabile che un cambiamento di contrasto venga interpretato come un 'bordo'.\n Se impostato su zero, la mappatura dei toni avrà un effetto simile alla maschera di contrasto. TP_LOCALLAB_TONEMAPGAM_TOOLTIP;Il cursore Gamma sposta l'effetto di mappatura dei toni verso le ombre o le luci. TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In alcuni casi la mappatura dei toni può risultare in un aspetto da cartone animato, e in alcuni rari casi possono apparire aloni morbidi ma ampi.\n Aumentare il numero di iterazioni di riponderazione aiuterà a combattere alcuni di questi problemi. +TP_LOCALLAB_TONEMAP_TOOLTIP;Uguale allo strumento di mappatura dei toni nel menu principale.\nLo strumento del menu principale deve essere disattivato se si utilizza questo strumento. TP_LOCALLAB_TONEMASCALE_TOOLTIP;Questo cursore ti consente di regolare la transizione tra il contrasto 'locale' e 'globale'.\nMaggiore è il valore, maggiore deve essere il dettaglio per essere potenziato. +TP_LOCALLAB_TONE_TOOLNAME;Mappatura toni TP_LOCALLAB_TOOLCOL;Maschera struttura come strumento TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Permette di modificare la maschera, se ne esiste una. +TP_LOCALLAB_TOOLMASK;Strumenti maschera TP_LOCALLAB_TOOLMASK_2;Wavelets TP_LOCALLAB_TOOLMASK_TOOLTIP;Maschera struttura (slider) con la casella di controllo 'Maschera struttura come strumento' selezionata: in questo caso una maschera che mostra la struttura verrà generata dopo che una o più delle 2 curve L(L) o LC(H) sono state modificate .\n Qui, la 'Maschera Struttura' si comporta come gli altri strumenti Maschera: Gamma, Pendenza, ecc.\n Permette di variare l'azione sulla maschera in base alla struttura dell'immagine. -TP_LOCALLAB_TOOLMASK;Strumenti maschera -TP_LOCALLAB_TRANSIT_TOOLTIP;Regola la morbidezza della transizione tra le aree interessate e quelle non interessate come percentuale del 'raggio'. TP_LOCALLAB_TRANSIT;Gradiente di transizione -TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Permette di variare la transizione dell'asse y. TP_LOCALLAB_TRANSITGRAD;Differenziazione transizione XY +TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Permette di variare la transizione dell'asse y. TP_LOCALLAB_TRANSITVALUE;Valore di transizione -TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Regola la funzione di decadimento della transizione: 1 lineare, 2 parabolica, 3 cubica fino a ^25.\nPuò essere utilizzato insieme a valori di transizione molto bassi per ridurre i difetti (CBDL, Wavelets, Colore e Luce). TP_LOCALLAB_TRANSITWEAK;Decadimento della transizione (log lineare) -TP_LOCALLAB_TRANSMISSION_TOOLTIP;Trasmissione secondo la trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione.\nÈ possibile regolare questa curva per modificare la trasmissione e ridurre gli artefatti. +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Regola la funzione di decadimento della transizione: 1 lineare, 2 parabolica, 3 cubica fino a ^25.\nPuò essere utilizzato insieme a valori di transizione molto bassi per ridurre i difetti (CBDL, Wavelets, Colore e Luce). +TP_LOCALLAB_TRANSIT_TOOLTIP;Regola la morbidezza della transizione tra le aree interessate e quelle non interessate come percentuale del 'raggio'. TP_LOCALLAB_TRANSMISSIONGAIN;Guadagno di trasmissione TP_LOCALLAB_TRANSMISSIONMAP;Mappa di trasmissione +TP_LOCALLAB_TRANSMISSION_TOOLTIP;Trasmissione secondo la trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione.\nÈ possibile regolare questa curva per modificare la trasmissione e ridurre gli artefatti. TP_LOCALLAB_USEMASK;Laplaciano TP_LOCALLAB_VART;Varianza (contrasto) -TP_LOCALLAB_VIB_TOOLNAME;Vibranza e caldo/freddo -TP_LOCALLAB_VIBRA_TOOLTIP;Regola la vivacità (essenzialmente uguale alla regolazione globale).\nEsegue l'equivalente di una regolazione del bilanciamento del bianco utilizzando un algoritmo CIECAM. TP_LOCALLAB_VIBRANCE;Vivace e caldo/freddo +TP_LOCALLAB_VIBRA_TOOLTIP;Regola la vivacità (essenzialmente uguale alla regolazione globale).\nEsegue l'equivalente di una regolazione del bilanciamento del bianco utilizzando un algoritmo CIECAM. +TP_LOCALLAB_VIB_TOOLNAME;Vibranza e caldo/freddo TP_LOCALLAB_VIS_TOOLTIP;Fai clic per mostrare/nascondere tutti i punti di controllo selezionati.\nCtrl+clic per mostrare/nascondere tutti i punti di controllo. -TP_LOCALLAB_WARM_TOOLTIP;Questo cursore utilizza l'algoritmo CIECAM e agisce come controllo del bilanciamento del bianco per rendere la temperatura del colore dell'area selezionata più calda o più fredda.\nIn alcuni casi può anche ridurre gli artefatti di colore. TP_LOCALLAB_WARM;Artefatti caldo/freddo e colore +TP_LOCALLAB_WARM_TOOLTIP;Questo cursore utilizza l'algoritmo CIECAM e agisce come controllo del bilanciamento del bianco per rendere la temperatura del colore dell'area selezionata più calda o più fredda.\nIn alcuni casi può anche ridurre gli artefatti di colore. TP_LOCALLAB_WASDEN_TOOLTIP;Riduzione del rumore di luminanza: il lato sinistro della curva compreso il confine grigio scuro/grigio chiaro corrisponde ai primi 3 livelli 0, 1, 2 (dettaglio fine). Il lato destro della curva corrisponde ai dettagli più grossolani (livello 3, 4, 5, 6). TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Bilancia l'azione all'interno di ogni livello. TP_LOCALLAB_WAT_BLURLC_TOOLTIP;L'impostazione di sfocatura predefinita influisce su tutti e 3 i componenti L*a* b* (luminanza e colore).\nSe selezionata, solo la luminanza viene sfocata. @@ -3526,10 +3518,10 @@ TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Contrasto locale da basso ad alto da sinistra a TP_LOCALLAB_WAT_WAVTM_TOOLTIP;La parte inferiore (negativa) comprime ciascun livello di scomposizione creando un effetto di mappatura dei toni.\nLa parte superiore (positiva) attenua il contrasto per livello.\nI livelli di scomposizione da più piccoli a più grossolani sono da sinistra a destra sulla x- asse. TP_LOCALLAB_WAV;Contrasto locale TP_LOCALLAB_WAVBLUR_TOOLTIP;Permette di sfocare ogni livello della scomposizione, così come l'immagine residua. -TP_LOCALLAB_WAVCOMP_TOOLTIP;Permette di applicare il contrasto locale in base alla direzione della scomposizione wavelet: orizzontale, verticale, diagonale. TP_LOCALLAB_WAVCOMP;Compressione per livello -TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Consente di applicare la mappatura dei toni o ridurre il contrasto locale su livelli individuali.\nLivelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. TP_LOCALLAB_WAVCOMPRE;Compressione per livello +TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Consente di applicare la mappatura dei toni o ridurre il contrasto locale su livelli individuali.\nLivelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. +TP_LOCALLAB_WAVCOMP_TOOLTIP;Permette di applicare il contrasto locale in base alla direzione della scomposizione wavelet: orizzontale, verticale, diagonale. TP_LOCALLAB_WAVCON;Contrasto per livello TP_LOCALLAB_WAVCONTF_TOOLTIP;Simile a Contrasto per livelli di dettaglio. Livelli di dettaglio da fine a grossolano da sinistra a destra sull'asse x. TP_LOCALLAB_WAVDEN;Rimozione rumore luminanza @@ -3540,26 +3532,30 @@ TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Gamma di livelli wavelet utilizzati in 'Contr TP_LOCALLAB_WAVGRAD_TOOLTIP;Permette di variare il contrasto locale in base al gradiente e all'angolo scelti. Viene presa in considerazione la variazione del segnale di luminanza e non la luminanza. TP_LOCALLAB_WAVHUE_TOOLTIP;Permette di ridurre o aumentare la riduzione del rumore in base alla tonalità. TP_LOCALLAB_WAVLEV;Sfocatura per livello -TP_LOCALLAB_WAVMASK_TOOLTIP;Utilizza wavelet per modificare il contrasto locale della maschera e rinforzare o ridurre la struttura (pelle, edifici, ecc.). TP_LOCALLAB_WAVMASK;Contrasto locale +TP_LOCALLAB_WAVMASK_TOOLTIP;Utilizza wavelet per modificare il contrasto locale della maschera e rinforzare o ridurre la struttura (pelle, edifici, ecc.). TP_LOCALLAB_WEDIANHI;Medio alto TP_LOCALLAB_WHITE_EV;Compensazione dell'esposizione del bianco TP_LOCALLAB_ZCAMFRA;Regolazioni immagine ZCAM TP_LOCALLAB_ZCAMTHRES;Recupera alti dati +TP_LOCAL_HEIGHT;Basso +TP_LOCAL_HEIGHT_T;Alto +TP_LOCAL_WIDTH;Destro +TP_LOCAL_WIDTH_L;Sinistro TP_LOCRETI_METHOD_TOOLTIP;Basso = Rinforza la luce scarsa.\Uniformemente = Distribuito uniformemente.\Alto = Rinforza la luce forte. TP_METADATA_EDIT;Apply modifications TP_METADATA_MODE;Modalità di copia dei metadati TP_METADATA_STRIP;Elimina tutti i metadati TP_METADATA_TUNNEL;Copia invariata -TP_NEUTRAL_TOOLTIP;Riporta i controlli dell'esposizione ai valori neutrali.\nVale per gli stessi controlli cui è applicato Livelli Automatici, indipendentemente dal fatto che Livelli Automatici sia abilitato. TP_NEUTRAL;Ripristina -TP_PCVIGNETTE_FEATHER_TOOLTIP;Scia:\n0 = solo i bordi,\n50 = a metà strada con il centro,\n100 = al centro. +TP_NEUTRAL_TOOLTIP;Riporta i controlli dell'esposizione ai valori neutrali.\nVale per gli stessi controlli cui è applicato Livelli Automatici, indipendentemente dal fatto che Livelli Automatici sia abilitato. TP_PCVIGNETTE_FEATHER;Scia +TP_PCVIGNETTE_FEATHER_TOOLTIP;Scia:\n0 = solo i bordi,\n50 = a metà strada con il centro,\n100 = al centro. TP_PCVIGNETTE_LABEL;Filtro Vignettatura -TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rotondità:\n0 = rettangolo,\n50 = ellisse riempito,\n100 = cerchio. TP_PCVIGNETTE_ROUNDNESS;Rotondità -TP_PCVIGNETTE_STRENGTH_TOOLTIP;intensità del filtro in stop (raggiunta agli angoli). +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rotondità:\n0 = rettangolo,\n50 = ellisse riempito,\n100 = cerchio. TP_PCVIGNETTE_STRENGTH;intensità +TP_PCVIGNETTE_STRENGTH_TOOLTIP;intensità del filtro in stop (raggiunta agli angoli). TP_PDSHARPENING_LABEL;Acquisisci nitidezza TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Fattore di ritaglio TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Lunghezza focale @@ -3569,14 +3565,14 @@ TP_PERSPECTIVE_CAMERA_ROLL;Rotazione TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Spostamento orizzontale TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Spostamento verticale TP_PERSPECTIVE_CAMERA_YAW;Orizzontale -TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;Sono necessarie almeno due linee di controllo orizzontali o due verticali. -TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+trascina: traccia una nuova riga\nclic destro: elimina la riga TP_PERSPECTIVE_CONTROL_LINES;Linee di controllo +TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+trascina: traccia una nuova riga\nclic destro: elimina la riga +TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;Sono necessarie almeno due linee di controllo orizzontali o due verticali. TP_PERSPECTIVE_HORIZONTAL;Orizzontale TP_PERSPECTIVE_LABEL;Prospettiva +TP_PERSPECTIVE_METHOD;Metodo TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-base TP_PERSPECTIVE_METHOD_SIMPLE;Semplice -TP_PERSPECTIVE_METHOD;Metodo TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Aggiustamento post-correzione TP_PERSPECTIVE_PROJECTION_PITCH;Verticale TP_PERSPECTIVE_PROJECTION_ROTATE;Rotatione @@ -3585,106 +3581,31 @@ TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Spostamento verticale TP_PERSPECTIVE_PROJECTION_YAW;Orizzontale TP_PERSPECTIVE_RECOVERY_FRAME;Recupera TP_PERSPECTIVE_VERTICAL;Verticale -TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controlla la forza di defringe dal colore.\nPiù alto = di più,\nPiù basso = di meno. TP_PFCURVE_CURVEEDITOR_CH;Tonalità -TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tenta di sopprimere i pixel morti. +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controlla la forza di defringe dal colore.\nPiù alto = di più,\nPiù basso = di meno. TP_PREPROCESS_DEADPIXFILT;Filtro pixel morti +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tenta di sopprimere i pixel morti. TP_PREPROCESS_GREENEQUIL;Bilanciamento del verde -TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tenta di sopprimere i pixel bruciati. TP_PREPROCESS_HOTPIXFILT;Filtro pixel bruciati +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tenta di sopprimere i pixel bruciati. TP_PREPROCESS_LABEL;Pre-elaborazione +TP_PREPROCESS_LINEDENOISE;Filtro per rumore a bande +TP_PREPROCESS_LINEDENOISE_DIRECTION;Direzione TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Entrambi TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Orizzontale TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Orizzontale solo su righe PDAF TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Verticale -TP_PREPROCESS_LINEDENOISE_DIRECTION;Direzione -TP_PREPROCESS_LINEDENOISE;Filtro per rumore a bande TP_PREPROCESS_NO_FOUND;Nessuno presente TP_PREPROCESS_PDAFLINESFILTER;Filtro linee PDAF TP_PREPROCWB_LABEL;Preelaborare il bilanciamento del bianco +TP_PREPROCWB_MODE;Modo TP_PREPROCWB_MODE_AUTO;Auto TP_PREPROCWB_MODE_CAMERA;Camera -TP_PREPROCWB_MODE;Modo TP_PRSHARPENING_LABEL;Nitidezza post-ridimensionamento TP_PRSHARPENING_TOOLTIP;Rende più nitida l'immagine dopo il ridimensionamento. Funziona solo quando viene utilizzato il metodo di ridimensionamento 'Lanczos'. È impossibile prevedere in anteprima gli effetti di questo strumento. Vedi RawPedia per le istruzioni d'uso. -TP_RAW_1PASSMEDIUM;1-passaggio (Markesteijn) -TP_RAW_2PASS;1-passaggio+veloce -TP_RAW_3PASSBEST;3-passaggi (Markesteijn) -TP_RAW_4PASS;3-passaggi+veloce -TP_RAW_AHD;AHD -TP_RAW_AMAZE;AMaZE -TP_RAW_AMAZEBILINEAR;AMaZE+Bilineare -TP_RAW_AMAZEVNG4;AMaZE+VNG4 -TP_RAW_BORDER;Bordo -TP_RAW_DCB;DCB -TP_RAW_DCBBILINEAR;DCB+Bilineare -TP_RAW_DCBENHANCE;Miglioramento DCB -TP_RAW_DCBITERATIONS;Numero di iterazioni DCB -TP_RAW_DCBVNG4;DCB+VNG4 -TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... -TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione %1... -TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO per aiutare nella riduzione rumore senza comportare posterizzazione o colori lavati. -TP_RAW_DMETHOD;Metodo -TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Se la casella è selezionata (consigliato), RawTherapee calcola un valore ottimale in base alle regioni piatte nell'immagine.\nSe non c'è alcuna regione piatta nell'immagine o se l'immagine è troppo rumorosa, il valore verrà impostato su 0.\nPer impostare il valore manualmente, deselezionare prima la casella di controllo (valori ragionevoli dipendono dall'immagine). -TP_RAW_DUALDEMOSAICAUTOCONTRAST;Soglia Automatica -TP_RAW_DUALDEMOSAICCONTRAST;Soglia di contrasto -TP_RAW_EAHD;EAHD -TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori -TP_RAW_FAST;Veloce -TP_RAW_HD_TOOLTIP;Valori più bassi rendono il rilevamento dei pixel caldi/morti più aggressivo, ma i falsi positivi possono causare artefatti. Se noti artefatti quando abiliti i filtri pixel caldi/morti, aumenta gradualmente il valore di soglia finché non scompaiono. -TP_RAW_HD;Soglia -TP_RAW_HPHD;HPHD -TP_RAW_IGV;IGV -TP_RAW_IMAGENUM_SN;Modo SN -TP_RAW_IMAGENUM_TOOLTIP;Alcuni file RAW sono costituiti da diverse immagini secondarie (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nQuando si utilizza qualsiasi metodo di demosaicizzazione diverso da Pixel Shift, questo seleziona quali sotto-immagini viene utilizzata l'immagine.\n\nQuando si utilizza il metodo di demosaicizzazione Pixel Shift su un Pixel Shift raw, vengono utilizzate tutte le immagini secondarie e viene selezionato quale immagine secondaria deve essere utilizzata per lo spostamento delle parti. -TP_RAW_IMAGENUM;Immagine secondaria -TP_RAW_LABEL;Demosaicizzazione -TP_RAW_LMMSE_TOOLTIP;Aggiunge gamma (passo 1) - Aggiunge mediana (passi 2-4), poi perfeziona (passi 5-6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore. -TP_RAW_LMMSE;LMMSE -TP_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE -TP_RAW_MONO;Mono -TP_RAW_NONE;Nessuno (mostra il modello del sensore) -TP_RAW_PIXELSHIFT;Pixel Shift (spostamento dei pixel) -TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Utilizza la media di tutti i fotogrammi invece del fotogramma selezionato per le regioni con movimento.\nFornisce effetti di movimento su oggetti che si muovono lentamente (sovrapposti). -TP_RAW_PIXELSHIFTAVERAGE;Utilizzare la media per le parti in movimento -TP_RAW_PIXELSHIFTBLUR;Maschera di movimento sfocato -TP_RAW_PIXELSHIFTDMETHOD;Metodo di demosaicizzazione per il movimento -TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;Il valore predefinito di 0 dovrebbe funzionare correttamente per l'ISO di base.\nValori più alti aumentano la sensibilità del rilevamento del movimento.\nCambia a piccoli passi e osserva la maschera di movimento mentre cambia.\nAumenta la sensibilità per immagini sottoesposte o con ISO elevati. -TP_RAW_PIXELSHIFTEPERISO;Sensibilità -TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalizza la luminosità dei fotogrammi alla luminosità del fotogramma selezionato.\nSe ci sono aree sovraesposte nei fotogrammi, seleziona il fotogramma più luminoso per evitare la dominante di colore magenta nelle aree sovraesposte o abilitare la correzione del movimento. -TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalizza la luminosità dei fotogrammi -TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Abilitato: equalizza i canali RGB individualmente.\nDisabilitato: utilizza lo stesso fattore di equalizzazione per tutti i canali. -TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalizza per canale -TP_RAW_PIXELSHIFTGREEN;Controllare il movimento nel canale verde -TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Riempi i buchi nella maschera di movimento. -TP_RAW_PIXELSHIFTHOLEFILL;Riempi i buchi nella maschera di movimento -TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Utilizza la mediana di tutti i fotogrammi anziché il fotogramma selezionato per le regioni con movimento.\nRimuove gli oggetti che si trovano in posizioni diverse in tutti i fotogrammi.\nConferisce un effetto di movimento agli oggetti che si muovono lentamente (sovrapposti). -TP_RAW_PIXELSHIFTMEDIAN;Utilizzare la mediana per le parti in movimento -TP_RAW_PIXELSHIFTMM_AUTO;Automatico -TP_RAW_PIXELSHIFTMM_CUSTOM;Personalizzato -TP_RAW_PIXELSHIFTMM_OFF;Chiuso -TP_RAW_PIXELSHIFTMOTIONMETHOD;Correzione del movimento -TP_RAW_PIXELSHIFTNONGREENCROSS;Controllare i canali rosso/blu per il movimento -TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Sovrappone l'immagine con una maschera verde che mostra le regioni in movimento. -TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask -TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Mostra la maschera di movimento senza l'immagine. -TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Mostra solo la maschera di movimento -TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Il raggio predefinito di 1,0 di solito si adatta bene agli ISO di base.\nAumenta il valore per gli scatti con ISO elevati, 5,0 è un buon punto di partenza.\nGuarda la maschera di movimento mentre modifichi il valore. -TP_RAW_PIXELSHIFTSIGMA;Raggio di sfocatura -TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Transizioni uniformi tra aree con movimento e aree senza.\nImposta su 0 per disattivare l'arrotondamento della transizione.\nImposta su 1 per ottenere il risultato AMaZE/LMMSE del fotogramma selezionato (a seconda che sia selezionato "Utilizza LMMSE") o la mediana di tutti e quattro i fotogrammi se è selezionato 'Usa mediana'. -TP_RAW_PIXELSHIFTSMOOTH;Transizioni fluide -TP_RAW_RCD;RCD -TP_RAW_RCDBILINEAR;RCD+Bilineare -TP_RAW_RCDVNG4;RCD+VNG4 -TP_RAW_SENSOR_BAYER_LABEL;Sensore con Matrice di Bayer -TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;La modalità a 3 passaggi offre i migliori risultati (consigliata per immagini a ISO bassi).\nLa modalità a 1 passaggio è quasi indistinguibile dalla modalità a 3 passaggi per immagini a ISO elevati ed è più veloce.\n+la modalità veloce fornisce meno artefatti nelle aree piatte. -TP_RAW_SENSOR_XTRANS_LABEL;Sensore con Matrice X-Trans -TP_RAW_VNG4;VNG4 -TP_RAW_XTRANS;X-Trans -TP_RAW_XTRANSFAST;Fast X-Trans TP_RAWCACORR_AUTO;Autocorrezione -TP_RAWCACORR_AUTOIT_TOOLTIP;Questa impostazione è disponibile se è selezionata l'opzione "Correzione automatica".\nLa correzione automatica è conservativa, ovvero spesso non corregge tutta l'aberrazione cromatica.\nPer correggere l'aberrazione cromatica rimanente, puoi utilizzare fino a cinque iterazioni dell'aberrazione cromatica automatica. correzione.\nOgni iterazione ridurrà l'aberrazione cromatica rimanente dall'ultima iterazione al costo di ulteriore tempo di elaborazione. TP_RAWCACORR_AUTOIT;Iterazioni +TP_RAWCACORR_AUTOIT_TOOLTIP;Questa impostazione è disponibile se è selezionata l'opzione "Correzione automatica".\nLa correzione automatica è conservativa, ovvero spesso non corregge tutta l'aberrazione cromatica.\nPer correggere l'aberrazione cromatica rimanente, puoi utilizzare fino a cinque iterazioni dell'aberrazione cromatica automatica. correzione.\nOgni iterazione ridurrà l'aberrazione cromatica rimanente dall'ultima iterazione al costo di ulteriore tempo di elaborazione. TP_RAWCACORR_AVOIDCOLORSHIFT;Evita il cambiamento di colore TP_RAWCACORR_CABLUE;Blu TP_RAWCACORR_CARED;Rosso @@ -3699,6 +3620,81 @@ TP_RAWEXPOS_BLACK_RED;Rosso TP_RAWEXPOS_LINEAR;Punto del Bianco - Correzione TP_RAWEXPOS_RGB;Rosso, Verde, Blu TP_RAWEXPOS_TWOGREEN;Valori del verde uniti +TP_RAW_1PASSMEDIUM;1-passaggio (Markesteijn) +TP_RAW_2PASS;1-passaggio+veloce +TP_RAW_3PASSBEST;3-passaggi (Markesteijn) +TP_RAW_4PASS;3-passaggi+veloce +TP_RAW_AHD;AHD +TP_RAW_AMAZE;AMaZE +TP_RAW_AMAZEBILINEAR;AMaZE+Bilineare +TP_RAW_AMAZEVNG4;AMaZE+VNG4 +TP_RAW_BORDER;Bordo +TP_RAW_DCB;DCB +TP_RAW_DCBBILINEAR;DCB+Bilineare +TP_RAW_DCBENHANCE;Miglioramento DCB +TP_RAW_DCBITERATIONS;Numero di iterazioni DCB +TP_RAW_DCBVNG4;DCB+VNG4 +TP_RAW_DMETHOD;Metodo +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... +TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO per aiutare nella riduzione rumore senza comportare posterizzazione o colori lavati. +TP_RAW_DUALDEMOSAICAUTOCONTRAST;Soglia Automatica +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Se la casella è selezionata (consigliato), RawTherapee calcola un valore ottimale in base alle regioni piatte nell'immagine.\nSe non c'è alcuna regione piatta nell'immagine o se l'immagine è troppo rumorosa, il valore verrà impostato su 0.\nPer impostare il valore manualmente, deselezionare prima la casella di controllo (valori ragionevoli dipendono dall'immagine). +TP_RAW_DUALDEMOSAICCONTRAST;Soglia di contrasto +TP_RAW_EAHD;EAHD +TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori +TP_RAW_FAST;Veloce +TP_RAW_HD;Soglia +TP_RAW_HD_TOOLTIP;Valori più bassi rendono il rilevamento dei pixel caldi/morti più aggressivo, ma i falsi positivi possono causare artefatti. Se noti artefatti quando abiliti i filtri pixel caldi/morti, aumenta gradualmente il valore di soglia finché non scompaiono. +TP_RAW_HPHD;HPHD +TP_RAW_IGV;IGV +TP_RAW_IMAGENUM;Immagine secondaria +TP_RAW_IMAGENUM_SN;Modo SN +TP_RAW_IMAGENUM_TOOLTIP;Alcuni file RAW sono costituiti da diverse immagini secondarie (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\nQuando si utilizza qualsiasi metodo di demosaicizzazione diverso da Pixel Shift, questo seleziona quali sotto-immagini viene utilizzata l'immagine.\n\nQuando si utilizza il metodo di demosaicizzazione Pixel Shift su un Pixel Shift raw, vengono utilizzate tutte le immagini secondarie e viene selezionato quale immagine secondaria deve essere utilizzata per lo spostamento delle parti. +TP_RAW_LABEL;Demosaicizzazione +TP_RAW_LMMSE;LMMSE +TP_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE +TP_RAW_LMMSE_TOOLTIP;Aggiunge gamma (passo 1) - Aggiunge mediana (passi 2-4), poi perfeziona (passi 5-6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore. +TP_RAW_MONO;Mono +TP_RAW_NONE;Nessuno (mostra il modello del sensore) +TP_RAW_PIXELSHIFT;Pixel Shift (spostamento dei pixel) +TP_RAW_PIXELSHIFTAVERAGE;Utilizzare la media per le parti in movimento +TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Utilizza la media di tutti i fotogrammi invece del fotogramma selezionato per le regioni con movimento.\nFornisce effetti di movimento su oggetti che si muovono lentamente (sovrapposti). +TP_RAW_PIXELSHIFTBLUR;Maschera di movimento sfocato +TP_RAW_PIXELSHIFTDMETHOD;Metodo di demosaicizzazione per il movimento +TP_RAW_PIXELSHIFTEPERISO;Sensibilità +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;Il valore predefinito di 0 dovrebbe funzionare correttamente per l'ISO di base.\nValori più alti aumentano la sensibilità del rilevamento del movimento.\nCambia a piccoli passi e osserva la maschera di movimento mentre cambia.\nAumenta la sensibilità per immagini sottoesposte o con ISO elevati. +TP_RAW_PIXELSHIFTEQUALBRIGHT;Equalizza la luminosità dei fotogrammi +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Equalizza per canale +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Abilitato: equalizza i canali RGB individualmente.\nDisabilitato: utilizza lo stesso fattore di equalizzazione per tutti i canali. +TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Equalizza la luminosità dei fotogrammi alla luminosità del fotogramma selezionato.\nSe ci sono aree sovraesposte nei fotogrammi, seleziona il fotogramma più luminoso per evitare la dominante di colore magenta nelle aree sovraesposte o abilitare la correzione del movimento. +TP_RAW_PIXELSHIFTGREEN;Controllare il movimento nel canale verde +TP_RAW_PIXELSHIFTHOLEFILL;Riempi i buchi nella maschera di movimento +TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Riempi i buchi nella maschera di movimento. +TP_RAW_PIXELSHIFTMEDIAN;Utilizzare la mediana per le parti in movimento +TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Utilizza la mediana di tutti i fotogrammi anziché il fotogramma selezionato per le regioni con movimento.\nRimuove gli oggetti che si trovano in posizioni diverse in tutti i fotogrammi.\nConferisce un effetto di movimento agli oggetti che si muovono lentamente (sovrapposti). +TP_RAW_PIXELSHIFTMM_AUTO;Automatico +TP_RAW_PIXELSHIFTMM_CUSTOM;Personalizzato +TP_RAW_PIXELSHIFTMM_OFF;Chiuso +TP_RAW_PIXELSHIFTMOTIONMETHOD;Correzione del movimento +TP_RAW_PIXELSHIFTNONGREENCROSS;Controllare i canali rosso/blu per il movimento +TP_RAW_PIXELSHIFTSHOWMOTION;Show motion mask +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Mostra solo la maschera di movimento +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Mostra la maschera di movimento senza l'immagine. +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Sovrappone l'immagine con una maschera verde che mostra le regioni in movimento. +TP_RAW_PIXELSHIFTSIGMA;Raggio di sfocatura +TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;Il raggio predefinito di 1,0 di solito si adatta bene agli ISO di base.\nAumenta il valore per gli scatti con ISO elevati, 5,0 è un buon punto di partenza.\nGuarda la maschera di movimento mentre modifichi il valore. +TP_RAW_PIXELSHIFTSMOOTH;Transizioni fluide +TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Transizioni uniformi tra aree con movimento e aree senza.\nImposta su 0 per disattivare l'arrotondamento della transizione.\nImposta su 1 per ottenere il risultato AMaZE/LMMSE del fotogramma selezionato (a seconda che sia selezionato "Utilizza LMMSE") o la mediana di tutti e quattro i fotogrammi se è selezionato 'Usa mediana'. +TP_RAW_RCD;RCD +TP_RAW_RCDBILINEAR;RCD+Bilineare +TP_RAW_RCDVNG4;RCD+VNG4 +TP_RAW_SENSOR_BAYER_LABEL;Sensore con Matrice di Bayer +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;La modalità a 3 passaggi offre i migliori risultati (consigliata per immagini a ISO bassi).\nLa modalità a 1 passaggio è quasi indistinguibile dalla modalità a 3 passaggi per immagini a ISO elevati ed è più veloce.\n+la modalità veloce fornisce meno artefatti nelle aree piatte. +TP_RAW_SENSOR_XTRANS_LABEL;Sensore con Matrice X-Trans +TP_RAW_VNG4;VNG4 +TP_RAW_XTRANS;X-Trans +TP_RAW_XTRANSFAST;Fast X-Trans TP_RESIZE_ALLOW_UPSCALING;Consenti l'upscaling TP_RESIZE_APPLIESTO;Applica a: TP_RESIZE_CROPPEDAREA;Zona ritagliata @@ -3722,87 +3718,87 @@ TP_RETINEX_CONTEDIT_HSL;HSL istogramma TP_RETINEX_CONTEDIT_LAB;L*a*b* istogramma TP_RETINEX_CONTEDIT_LH;Tonalità TP_RETINEX_CONTEDIT_MAP;Equalizzatore -TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminanza in base alla luminanza L=f(L)\nCorreggere i dati grezzi per ridurre aloni e artefatti. TP_RETINEX_CURVEEDITOR_CD;L=f(L) -TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensità in base alla tonalità Intensità=f(H)\nQuesta curva agisce anche sulla crominanza quando si utilizza il metodo Retinex 'Alteluci'. +TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminanza in base alla luminanza L=f(L)\nCorreggere i dati grezzi per ridurre aloni e artefatti. TP_RETINEX_CURVEEDITOR_LH;Intensità=f(H) -TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Questa curva può essere applicata da sola o con una maschera gaussiana o una maschera wavelet.\nAttenzione agli artefatti! +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensità in base alla tonalità Intensità=f(H)\nQuesta curva agisce anche sulla crominanza quando si utilizza il metodo Retinex 'Alteluci'. TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Questa curva può essere applicata da sola o con una maschera gaussiana o una maschera wavelet.\nAttenzione agli artefatti! TP_RETINEX_EQUAL;Equalizzatore TP_RETINEX_FREEGAMMA;Gamma libera TP_RETINEX_GAIN;Guadagno TP_RETINEX_GAINOFFS;Guadagno e compensazione (luminosità) -TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Aumentare o ridurre la mappa di trasmissione per ottenere la luminanza desiderata. L'asse x è la trasmissione. L'asse y è il guadagno. TP_RETINEX_GAINTRANSMISSION;Transmissione guadagno +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Aumentare o ridurre la mappa di trasmissione per ottenere la luminanza desiderata. L'asse x è la trasmissione. L'asse y è il guadagno. +TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Libero TP_RETINEX_GAMMA_HIGH;Alto TP_RETINEX_GAMMA_LOW;Basso TP_RETINEX_GAMMA_MID;Medio TP_RETINEX_GAMMA_NONE;Nessuno TP_RETINEX_GAMMA_TOOLTIP;Ripristina i toni applicando gamma prima e dopo Retinex. Differenti dalle curve Retinex o da altre curve (Lab, Exposure, ecc.). -TP_RETINEX_GAMMA;Gamma -TP_RETINEX_GRAD_TOOLTIP;Se il dispositivo di scorrimento è impostato su 0, tutte le iterazioni sono identiche.\nSe > 0 Varianza e Soglia vengono ridotte quando le iterazioni aumentano e viceversa. TP_RETINEX_GRAD;Gradiente di trasmissione -TP_RETINEX_GRADS_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 La forza viene ridotta quando le iterazioni aumentano e viceversa. TP_RETINEX_GRADS;Gradiente di forza +TP_RETINEX_GRADS_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 La forza viene ridotta quando le iterazioni aumentano e viceversa. +TP_RETINEX_GRAD_TOOLTIP;Se il dispositivo di scorrimento è impostato su 0, tutte le iterazioni sono identiche.\nSe > 0 Varianza e Soglia vengono ridotte quando le iterazioni aumentano e viceversa. TP_RETINEX_HIGH;Alto TP_RETINEX_HIGHLIG;Alteluci -TP_RETINEX_HIGHLIGHT_TOOLTIP;Aumenta l'azione dell'algoritmo Alto.\nPotrebbe essere necessario regolare nuovamente i "Pixel vicini" e aumentare la "Correzione del punto bianco" nella scheda Raw -> strumento Punti bianchi grezzi. TP_RETINEX_HIGHLIGHT;Soglia alteluci +TP_RETINEX_HIGHLIGHT_TOOLTIP;Aumenta l'azione dell'algoritmo Alto.\nPotrebbe essere necessario regolare nuovamente i "Pixel vicini" e aumentare la "Correzione del punto bianco" nella scheda Raw -> strumento Punti bianchi grezzi. TP_RETINEX_HSLSPACE_LIN;HSL-Lineare TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmica -TP_RETINEX_ITER_TOOLTIP;Simula un operatore di mappatura dei toni.\nValori elevati aumentano il tempo di elaborazione. TP_RETINEX_ITER;Iterazioni (mappatura dei toni) TP_RETINEX_ITERF;Mappatura dei toni -TP_RETINEX_LABEL_MASK;Maschera +TP_RETINEX_ITER_TOOLTIP;Simula un operatore di mappatura dei toni.\nValori elevati aumentano il tempo di elaborazione. TP_RETINEX_LABEL;Retinex +TP_RETINEX_LABEL_MASK;Maschera TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Basso +TP_RETINEX_MAP;Metodo TP_RETINEX_MAP_GAUS;Maschera Gaussiana TP_RETINEX_MAP_MAPP;Maschera nitida (wavelet parziale) TP_RETINEX_MAP_MAPT;Maschera nitida (wavelet totale) TP_RETINEX_MAP_METHOD_TOOLTIP;Usa la maschera generata dalla funzione gaussiana sopra (Raggio, Metodo) per ridurre aloni e artefatti.\n\nSolo curva: applica una curva di contrasto diagonale sulla maschera.\nAttenzione agli artefatti!\n\nMaschera gaussiana: genera e usa una Sfocatura gaussiana della maschera originale.\nVeloce.\n\nMaschera nitida: genera e utilizza un'onda sulla maschera originale.\nLento. TP_RETINEX_MAP_NONE;Nessuno -TP_RETINEX_MAP;Metodo TP_RETINEX_MEDIAN;Filtro mediano di trasmissione -TP_RETINEX_METHOD_TOOLTIP;Basso = Rinforza la luce scarsa.\Uniforme = Equalizza l'azione.\Alto = Rinforza la luce alta.\Alte luci = Rimuove il magenta nelle alte luci. TP_RETINEX_METHOD;Metodo -TP_RETINEX_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Clip dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. +TP_RETINEX_METHOD_TOOLTIP;Basso = Rinforza la luce scarsa.\Uniforme = Equalizza l'azione.\Alto = Rinforza la luce alta.\Alte luci = Rimuove il magenta nelle alte luci. TP_RETINEX_MLABEL;Ripristino dati Min=%1 Max=%2 +TP_RETINEX_MLABEL_TOOLTIP;I valori dovrebbero essere vicini a Min=0 Max=32768 (modalità registro) ma sono possibili altri valori. Puoi regolare 'Clip dati ripristinati (guadagno)' e 'Offset' per normalizzare.\nRecupera i dati dell'immagine senza fusione. TP_RETINEX_NEIGHBOR;Raggio -TP_RETINEX_NEUTRAL_TOOLTIP;Ripristina tutti i cursori e le curve ai valori predefiniti. TP_RETINEX_NEUTRAL;Ripristina +TP_RETINEX_NEUTRAL_TOOLTIP;Ripristina tutti i cursori e le curve ai valori predefiniti. TP_RETINEX_OFFSET;Compensazione (luminosità) -TP_RETINEX_SCALES_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 Scala e raggio vengono ridotti quando le iterazioni aumentano e viceversa. TP_RETINEX_SCALES;Gradiente Gaussiano +TP_RETINEX_SCALES_TOOLTIP;Se il dispositivo di scorrimento è a 0, tutte le iterazioni sono identiche.\nSe > 0 Scala e raggio vengono ridotti quando le iterazioni aumentano e viceversa. TP_RETINEX_SETTINGS;Impostazioni TP_RETINEX_SKAL;Scala TP_RETINEX_SLOPE;Pendenza gamma libera TP_RETINEX_STRENGTH;Intensità -TP_RETINEX_THRESHOLD_TOOLTIP;Limiti in/out.\nIn = sorgente immagine,\nOut = gauss immagine. TP_RETINEX_THRESHOLD;Soglia -TP_RETINEX_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max vengono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nÈ possibile normalizzare i risultati con il cursore della soglia. +TP_RETINEX_THRESHOLD_TOOLTIP;Limiti in/out.\nIn = sorgente immagine,\nOut = gauss immagine. TP_RETINEX_TLABEL;Dati TM Min=%1 Max=%2 Media=%3 Sigma=%4 TP_RETINEX_TLABEL2;TM Effettivo Tm=%1 TM=%2 +TP_RETINEX_TLABEL_TOOLTIP;Risultato della mappa di trasmissione.\nMin e Max vengono utilizzati dalla varianza.\nTm=Min TM=Max della mappa di trasmissione.\nÈ possibile normalizzare i risultati con il cursore della soglia. TP_RETINEX_TRANF;Transmissione -TP_RETINEX_TRANSMISSION_TOOLTIP;Trasmissione secondo trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione. TP_RETINEX_TRANSMISSION;Mappa di transmissione +TP_RETINEX_TRANSMISSION_TOOLTIP;Trasmissione secondo trasmissione.\nAscissa: trasmissione da valori negativi (min), media e valori positivi (max).\nOrdinata: amplificazione o riduzione. TP_RETINEX_UNIFORM;Uniforme -TP_RETINEX_VARIANCE_TOOLTIP;Una varianza bassa aumenta il contrasto e la saturazione locali, ma può causare artefatti. TP_RETINEX_VARIANCE;Contrasto +TP_RETINEX_VARIANCE_TOOLTIP;Una varianza bassa aumenta il contrasto e la saturazione locali, ma può causare artefatti. +TP_RETINEX_VIEW;Processo TP_RETINEX_VIEW_MASK;Maschera TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Visualizzazione normale.\nMaschera - Visualizza la maschera.\nMaschera di contrasto - Visualizza l'immagine con una maschera di contrasto ad alto raggio.\nTrasmissione - Automatica/Fissa - Visualizza la mappa di trasmissione del file, prima di qualsiasi azione su contrasto e luminosità.\n \nAttenzione: la maschera non corrisponde alla realtà, ma viene amplificata per renderla più visibile. TP_RETINEX_VIEW_NONE;Standard TP_RETINEX_VIEW_TRAN;Trasmissione - Automatica TP_RETINEX_VIEW_TRAN2;Trasmissione - Risolto TP_RETINEX_VIEW_UNSHARP;Maschera di contrasto -TP_RETINEX_VIEW;Processo TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Canale TP_RGBCURVES_GREEN;G TP_RGBCURVES_LABEL;Curve RGB -TP_RGBCURVES_LUMAMODE_TOOLTIP;La Modalità Luminosità consente di variare il contributo dei canali R, G e B alla luminosità dell'immagine, senza alterarne il colore. TP_RGBCURVES_LUMAMODE;Modalità Luminosità +TP_RGBCURVES_LUMAMODE_TOOLTIP;La Modalità Luminosità consente di variare il contributo dei canali R, G e B alla luminosità dell'immagine, senza alterarne il colore. TP_RGBCURVES_RED;R TP_ROTATE_DEGREE;Angolo TP_ROTATE_LABEL;Ruota @@ -3829,12 +3825,12 @@ TP_SHARPENING_ITERCHECK;Limite di iterazione automatica TP_SHARPENING_LABEL;Nitidezza TP_SHARPENING_METHOD;Metodo TP_SHARPENING_ONLYEDGES;Definisci solo i bordi -TP_SHARPENING_RADIUS_BOOST;Aumento del raggio d'angolo TP_SHARPENING_RADIUS;Raggio +TP_SHARPENING_RADIUS_BOOST;Aumento del raggio d'angolo +TP_SHARPENING_RLD;Deconvoluzione RL TP_SHARPENING_RLD_AMOUNT;Quantità TP_SHARPENING_RLD_DAMPING;Attenuazione TP_SHARPENING_RLD_ITERATIONS;Iterazioni -TP_SHARPENING_RLD;Deconvoluzione RL TP_SHARPENING_THRESHOLD;Soglia TP_SHARPENING_USM;Maschera di contrasto TP_SHARPENMICRO_AMOUNT;Quantità @@ -3853,37 +3849,37 @@ TP_TM_FATTAL_AMOUNT;Quantità TP_TM_FATTAL_ANCHOR;Ancora TP_TM_FATTAL_LABEL;Compressione della gamma dinamica TP_TM_FATTAL_THRESHOLD;Dettagli +TP_TONE_EQUALIZER_BANDS;Bande TP_TONE_EQUALIZER_BAND_0;Neri TP_TONE_EQUALIZER_BAND_1;Ombre TP_TONE_EQUALIZER_BAND_2;Mezzitoni TP_TONE_EQUALIZER_BAND_3;Alteluci TP_TONE_EQUALIZER_BAND_4;Bianchi -TP_TONE_EQUALIZER_BANDS;Bande TP_TONE_EQUALIZER_DETAIL;Regolarizzazione TP_TONE_EQUALIZER_LABEL;Equalizzatore di toni TP_TONE_EQUALIZER_PIVOT;Perno (Ev) TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map TP_VIBRANCE_AVOIDCOLORSHIFT;Evita il color shift +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Incarnato TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rosso/Viola TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rosso TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rosso/Giallo TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Giallo TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tonalità a seconda della Tinta H=f(H) -TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH TP_VIBRANCE_LABEL;Vividezza TP_VIBRANCE_PASTELS;Toni Pastello TP_VIBRANCE_PASTSATTOG;Lega i toni pastello e saturi TP_VIBRANCE_PROTECTSKINS;Proteggi l'incarnato +TP_VIBRANCE_PSTHRESHOLD;Soglia toni pastello/saturi TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Soglia Saturazione TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;L'asse verticale rappresenta i toni pastello alla base e i toni saturi in cima.\nL'asse orizzontale rappresenta l'intervallo di saturazione. TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Peso della transizione pastello/saturi -TP_VIBRANCE_PSTHRESHOLD;Soglia toni pastello/saturi TP_VIBRANCE_SATURATED;Toni Saturi TP_VIGNETTING_AMOUNT;Quantità +TP_VIGNETTING_CENTER;Centro TP_VIGNETTING_CENTER_X;Centra X TP_VIGNETTING_CENTER_Y;Centra Y -TP_VIGNETTING_CENTER;Centro TP_VIGNETTING_LABEL;Correzione Vignettatura TP_VIGNETTING_RADIUS;Raggio TP_VIGNETTING_STRENGTH;intensità @@ -3903,11 +3899,11 @@ TP_WAVELET_B1;Grigio TP_WAVELET_B2;Residuale TP_WAVELET_BACKGROUND;Sfondo TP_WAVELET_BACUR;Curva -TP_WAVELET_BALANCE_TOOLTIP;Altera il bilanciamento tra le direzioni delle wavelet: verticale-orizzontale e diagonale.\nSe sono attivati contrasto, crominanza o mappatura del tono residuo, l'effetto dovuto al bilanciamento viene amplificato. TP_WAVELET_BALANCE;Bilanciamento di contrasto d/v-h -TP_WAVELET_BALCHRO_TOOLTIP;Se abilitata, la curva o il cursore "Bilanciamento del contrasto" modifica anche il bilanciamento della crominanza. +TP_WAVELET_BALANCE_TOOLTIP;Altera il bilanciamento tra le direzioni delle wavelet: verticale-orizzontale e diagonale.\nSe sono attivati contrasto, crominanza o mappatura del tono residuo, l'effetto dovuto al bilanciamento viene amplificato. TP_WAVELET_BALCHRO;Bilanciamento cromatico TP_WAVELET_BALCHROM;Equalizzazione colore +TP_WAVELET_BALCHRO_TOOLTIP;Se abilitata, la curva o il cursore "Bilanciamento del contrasto" modifica anche il bilanciamento della crominanza. TP_WAVELET_BALLUM;Equalizzatore antirumore Bianco-Nero TP_WAVELET_BANONE;Nessuno TP_WAVELET_BASLI;Dispositivo di scorrimento @@ -3916,22 +3912,22 @@ TP_WAVELET_BL;Livelli di sfocatura TP_WAVELET_BLCURVE;Sfocatura per livelli TP_WAVELET_BLURFRAME;Sfoca TP_WAVELET_BLUWAV;Risposta di attenuazione -TP_WAVELET_CB_TOOLTIP;Con valori elevati puoi creare effetti speciali, simili a quelli ottenuti con il Modulo Chroma, ma focalizzati sull'immagine residua.\nCon valori moderati puoi correggere manualmente il bilanciamento del bianco. TP_WAVELET_CBENAB;Tonalità e bilanciamento del colore +TP_WAVELET_CB_TOOLTIP;Con valori elevati puoi creare effetti speciali, simili a quelli ottenuti con il Modulo Chroma, ma focalizzati sull'immagine residua.\nCon valori moderati puoi correggere manualmente il bilanciamento del bianco. TP_WAVELET_CCURVE;Contrasto locale TP_WAVELET_CH1;Intera gamma cromatica TP_WAVELET_CH2;Saturato/pastello TP_WAVELET_CH3;Collega i livelli di contrasto TP_WAVELET_CHCU;Curva -TP_WAVELET_CHR_TOOLTIP;Regola la crominanza in funzione dei "livelli di contrasto" e della "forza del collegamento crominanza-contrasto". TP_WAVELET_CHR;Intensità coll.to contrasto cromatico -TP_WAVELET_CHRO_TOOLTIP;Imposta il livello wavelet che sarà la soglia tra i colori saturi e pastello.\n1-x: saturi\nx-9: pastello\n\nSe il valore supera la quantità di livelli wavelet che stai utilizzando, verrà ignorato. TP_WAVELET_CHRO;Soglia saturata/pastello TP_WAVELET_CHROFRAME;Riduce il rumore di crominanza TP_WAVELET_CHROMAFRAME;Crominanza TP_WAVELET_CHROMCO;Crominanza grossolana TP_WAVELET_CHROMFI;Crominanza fine +TP_WAVELET_CHRO_TOOLTIP;Imposta il livello wavelet che sarà la soglia tra i colori saturi e pastello.\n1-x: saturi\nx-9: pastello\n\nSe il valore supera la quantità di livelli wavelet che stai utilizzando, verrà ignorato. TP_WAVELET_CHRWAV;Sfocatura cromatica +TP_WAVELET_CHR_TOOLTIP;Regola la crominanza in funzione dei "livelli di contrasto" e della "forza del collegamento crominanza-contrasto". TP_WAVELET_CHSL;Cursori TP_WAVELET_CHTYPE;Metodo della crominanza TP_WAVELET_CLA;Chiarezza @@ -3939,37 +3935,37 @@ TP_WAVELET_CLARI;Maschera di nitidezza e chiarezza TP_WAVELET_COLORT;Opacità rosso-verde TP_WAVELET_COMPCONT;Contrasto TP_WAVELET_COMPEXPERT;Avanzate -TP_WAVELET_COMPGAMMA_TOOLTIP;La regolazione della gamma dell'immagine residua consente di equilibrare i dati e l'istogramma. TP_WAVELET_COMPGAMMA;Compressione di gamma -TP_WAVELET_COMPLEX_TOOLTIP;Standard: mostra un set ridotto di strumenti adatti alla maggior parte delle operazioni di elaborazione.\nAvanzato: mostra il set completo di strumenti per operazioni di elaborazione avanzate. +TP_WAVELET_COMPGAMMA_TOOLTIP;La regolazione della gamma dell'immagine residua consente di equilibrare i dati e l'istogramma. TP_WAVELET_COMPLEXLAB;Complessità +TP_WAVELET_COMPLEX_TOOLTIP;Standard: mostra un set ridotto di strumenti adatti alla maggior parte delle operazioni di elaborazione.\nAvanzato: mostra il set completo di strumenti per operazioni di elaborazione avanzate. TP_WAVELET_COMPNORMAL;Standard TP_WAVELET_COMPTM;Mappatura dei toni TP_WAVELET_CONTEDIT;Curva di contrasto 'dopo' TP_WAVELET_CONTFRAME;Contrasto - Compressione TP_WAVELET_CONTR;Gamma -TP_WAVELET_CONTRA_TOOLTIP;Modifica il contrasto residuo dell'immagine. TP_WAVELET_CONTRA;Contrasto TP_WAVELET_CONTRAST_MINUS;Contrasto - TP_WAVELET_CONTRAST_PLUS;Contrasto + +TP_WAVELET_CONTRA_TOOLTIP;Modifica il contrasto residuo dell'immagine. TP_WAVELET_CTYPE;Controllo della crominanza TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Disabilitato se lo zoom > circa 300%. TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifica il contrasto locale in funzione del contrasto locale originale (ascissa).\nI valori bassi dell'ascissa rappresentano un contrasto locale piccolo (valori reali circa 10..20).\nIl 50% dell'ascissa rappresenta il contrasto locale medio (valore reale circa 100..300) .\nIl 66% dell'ascissa rappresenta la deviazione standard del contrasto locale (valore reale circa 300..800).\nIl 100% dell'ascissa rappresenta il contrasto locale massimo (valore reale circa 3000..8000). -TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifica il contrasto di ciascun livello in funzione della tonalità.\nFare attenzione a non sovrascrivere le modifiche apportate con i controlli della tonalità dello strumento secondario Gamut.\nLa curva avrà effetto solo quando i cursori del livello di contrasto wavelet sono diversi da zero. TP_WAVELET_CURVEEDITOR_CH;Livelli di contrasto=f(Tonalità) -TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applica una curva finale di contrasto-luminanza al termine dell'elaborazione wavelet. +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifica il contrasto di ciascun livello in funzione della tonalità.\nFare attenzione a non sovrascrivere le modifiche apportate con i controlli della tonalità dello strumento secondario Gamut.\nLa curva avrà effetto solo quando i cursori del livello di contrasto wavelet sono diversi da zero. TP_WAVELET_CURVEEDITOR_CL;L -TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifica la tonalità residua dell'immagine in funzione della tonalità. +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applica una curva finale di contrasto-luminanza al termine dell'elaborazione wavelet. TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifica la tonalità residua dell'immagine in funzione della tonalità. TP_WAVELET_DALL;Tutte le direzioni -TP_WAVELET_DAUB_TOOLTIP;Modifiche ai coefficienti Daubechies:\nD4 = Standard,\nD14 = Spesso la migliore prestazione, il 10% in più in termini di tempo.\n\nInfluisce sul rilevamento dei bordi e sulla qualità generale dei primi livelli. Tuttavia la qualità non è strettamente legata a questo coefficiente e può variare a seconda dell'immagine e dell'utilizzo. TP_WAVELET_DAUB;Prestazioni ai bordi -TP_WAVELET_DAUB10;D10 - medio -TP_WAVELET_DAUB14;D14 - alto TP_WAVELET_DAUB2;D2 - basso TP_WAVELET_DAUB4;D4 - standard TP_WAVELET_DAUB6;D6 - standard + +TP_WAVELET_DAUB10;D10 - medio +TP_WAVELET_DAUB14;D14 - alto TP_WAVELET_DAUBLOCAL;Prestazioni ai bordi Wavelet +TP_WAVELET_DAUB_TOOLTIP;Modifiche ai coefficienti Daubechies:\nD4 = Standard,\nD14 = Spesso la migliore prestazione, il 10% in più in termini di tempo.\n\nInfluisce sul rilevamento dei bordi e sulla qualità generale dei primi livelli. Tuttavia la qualità non è strettamente legata a questo coefficiente e può variare a seconda dell'immagine e dell'utilizzo. TP_WAVELET_DEN5THR;Soglia guidata TP_WAVELET_DENCURV;Curva TP_WAVELET_DENL;Correctione struttura @@ -3992,23 +3988,23 @@ TP_WAVELET_DONE;Verticale TP_WAVELET_DTHR;Diagonale TP_WAVELET_DTWO;Orizzontale TP_WAVELET_EDCU;Curva -TP_WAVELET_EDEFFECT_TOOLTIP;Questo cursore seleziona l'intervallo di valori di contrasto che riceveranno il pieno effetto di qualsiasi regolazione. TP_WAVELET_EDEFFECT;Risposta di attenuazione -TP_WAVELET_EDGCONT_TOOLTIP;Regolando i punti a sinistra si diminuisce il contrasto, mentre a destra lo si aumenta.\nIn basso a sinistra, in alto a sinistra, in alto a destra e in basso a destra rappresentano rispettivamente il contrasto locale per valori bassi, media, media+std. dev. e massimi. +TP_WAVELET_EDEFFECT_TOOLTIP;Questo cursore seleziona l'intervallo di valori di contrasto che riceveranno il pieno effetto di qualsiasi regolazione. TP_WAVELET_EDGCONT;Contrasto locale +TP_WAVELET_EDGCONT_TOOLTIP;Regolando i punti a sinistra si diminuisce il contrasto, mentre a destra lo si aumenta.\nIn basso a sinistra, in alto a sinistra, in alto a destra e in basso a destra rappresentano rispettivamente il contrasto locale per valori bassi, media, media+std. dev. e massimi. TP_WAVELET_EDGE;Nitidezza dei bordi TP_WAVELET_EDGEAMPLI;Amplificazione di base -TP_WAVELET_EDGEDETECT_TOOLTIP;Spostando il cursore verso destra si aumenta la sensibilità dei bordi. Ciò influisce sul contrasto locale, sulle impostazioni dei bordi e sul rumore. TP_WAVELET_EDGEDETECT;Sensibilità gradiente -TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Questo cursore imposta una soglia al di sotto della quale i dettagli più fini non verranno considerati un vantaggio. TP_WAVELET_EDGEDETECTTHR;Soglia bassa (rumore) TP_WAVELET_EDGEDETECTTHR2;Miglioramento dei bordi +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Questo cursore imposta una soglia al di sotto della quale i dettagli più fini non verranno considerati un vantaggio. +TP_WAVELET_EDGEDETECT_TOOLTIP;Spostando il cursore verso destra si aumenta la sensibilità dei bordi. Ciò influisce sul contrasto locale, sulle impostazioni dei bordi e sul rumore. TP_WAVELET_EDGESENSI;Sensibilità dei bordi TP_WAVELET_EDGREINF_TOOLTIP;Rafforzare o ridurre l'azione del primo livello, fare il contrario del secondo livello e lasciare invariato il resto. -TP_WAVELET_EDGTHRESH_TOOLTIP;Cambia la ripartizione tra i primi livelli e gli altri. Più alta è la soglia più l'azione è centrata sui primi livelli. Fare attenzione ai valori negativi, aumentano l'azione a livelli elevati e possono introdurre artefatti. TP_WAVELET_EDGTHRESH;Dettagli -TP_WAVELET_EDRAD_TOOLTIP;Questa regolazione controlla il miglioramento locale. Un valore pari a zero ha comunque effetto. +TP_WAVELET_EDGTHRESH_TOOLTIP;Cambia la ripartizione tra i primi livelli e gli altri. Più alta è la soglia più l'azione è centrata sui primi livelli. Fare attenzione ai valori negativi, aumentano l'azione a livelli elevati e possono introdurre artefatti. TP_WAVELET_EDRAD;Raggio +TP_WAVELET_EDRAD_TOOLTIP;Questa regolazione controlla il miglioramento locale. Un valore pari a zero ha comunque effetto. TP_WAVELET_EDSL;Cursori di soglia TP_WAVELET_EDTYPE;Metodo di contrasto locale TP_WAVELET_EDVAL;Intensità @@ -4020,12 +4016,12 @@ TP_WAVELET_GUIDFRAME;Smoothing finale (filtro guidato) TP_WAVELET_HIGHLIGHT;Gamma di luminanza a livelli più fini TP_WAVELET_HS1;Intero intervallo di luminanza TP_WAVELET_HS2;Gamma di luminanza selettiva -TP_WAVELET_HUESKIN_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. TP_WAVELET_HUESKIN;Tonalità della pelle -TP_WAVELET_HUESKY_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. +TP_WAVELET_HUESKIN_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. TP_WAVELET_HUESKY;Gamma di tonalità -TP_WAVELET_ITER_TOOLTIP;Sinistra: aumenta i livelli bassi e riduci i livelli alti,\nDestra: riduci i livelli bassi e aumenta i livelli alti. +TP_WAVELET_HUESKY_TOOLTIP;I punti in basso impostano l'inizio della zona di transizione e i punti in alto la fine, dove l'effetto è al massimo.\n\nSe è necessario spostare l'area in modo significativo o se sono presenti artefatti, allora il bilanciamento del bianco non è corretto. TP_WAVELET_ITER;Livelli di equilibrio delta +TP_WAVELET_ITER_TOOLTIP;Sinistra: aumenta i livelli bassi e riduci i livelli alti,\nDestra: riduci i livelli bassi e aumenta i livelli alti. TP_WAVELET_LABEL;Livelli wavelet TP_WAVELET_LABGRID_VALUES;Alto(a)=%1 Alto(b)=%2\nBasso(a)=%3 Basso(b)=%4 TP_WAVELET_LARGEST;Grossolano @@ -4037,9 +4033,9 @@ TP_WAVELET_LEVDIR_ONE;Un livello TP_WAVELET_LEVDIR_SUP;Livelli di dettaglio più grossolani, escluso il livello selezionato TP_WAVELET_LEVELHIGH;Raggio 5-6 TP_WAVELET_LEVELLOW;Raggio 1-4 -TP_WAVELET_LEVELS_TOOLTIP;Scegli il numero di livelli di decomposizione wavelet per l'immagine.\nPiù livelli richiedono più RAM e un tempo di elaborazione più lungo. TP_WAVELET_LEVELS;Livelli di Wavelet TP_WAVELET_LEVELSIGM;Raggio +TP_WAVELET_LEVELS_TOOLTIP;Scegli il numero di livelli di decomposizione wavelet per l'immagine.\nPiù livelli richiedono più RAM e un tempo di elaborazione più lungo. TP_WAVELET_LEVF;Contrasto TP_WAVELET_LEVFOUR;Riduzione rumore e soglia guidata livello 5-6 TP_WAVELET_LEVLABEL;Anteprima dei livelli massimi possibili = %1 @@ -4054,8 +4050,8 @@ TP_WAVELET_LOWLIGHT;Gamma di luminanza a livelli più grossolani TP_WAVELET_LOWTHR_TOOLTIP;Previene l'amplificazione delle texture fini e del rumore. TP_WAVELET_MEDGREINF;Primo livello TP_WAVELET_MEDI;Riduci gli artefatti nel cielo blu -TP_WAVELET_MEDILEV_TOOLTIP;Quando abiliti il rilevamento dei bordi, si consiglia di:\n- disattivare i livelli di contrasto bassi per evitare artefatti,\n- utilizzare valori elevati di sensibilità del gradiente.\n\nPuoi modulare l'intensità con 'perfeziona' da Riduci rumore e Affina. TP_WAVELET_MEDILEV;Rilevamento dei bordi +TP_WAVELET_MEDILEV_TOOLTIP;Quando abiliti il rilevamento dei bordi, si consiglia di:\n- disattivare i livelli di contrasto bassi per evitare artefatti,\n- utilizzare valori elevati di sensibilità del gradiente.\n\nPuoi modulare l'intensità con 'perfeziona' da Riduci rumore e Affina. TP_WAVELET_MERGEC;Unisci crominanza TP_WAVELET_MERGEL;Unisci luminanza TP_WAVELET_MIXCONTRAST;Riferimento @@ -4069,14 +4065,14 @@ TP_WAVELET_NOISE;Elimina rumore e perfeziona TP_WAVELET_NPHIGH;Alto TP_WAVELET_NPLOW;Basso TP_WAVELET_NPNONE;Nessuno -TP_WAVELET_NPTYPE_TOOLTIP;Questo algoritmo utilizza la vicinanza di un pixel e otto dei suoi vicini. Se la differenza è inferiore, i bordi sono rinforzati. TP_WAVELET_NPTYPE;Pixel vicini +TP_WAVELET_NPTYPE_TOOLTIP;Questo algoritmo utilizza la vicinanza di un pixel e otto dei suoi vicini. Se la differenza è inferiore, i bordi sono rinforzati. TP_WAVELET_OFFSET_TOOLTIP;L'offset modifica il bilanciamento tra i dettagli a basso contrasto e quelli ad alto contrasto.\nValori elevati amplificheranno le modifiche del contrasto ai dettagli a contrasto più elevato, mentre valori bassi amplificheranno le modifiche del contrasto ai dettagli a basso contrasto.\nUtilizzando un valore di risposta dell'attenuazione basso è possibile selezionare quale contrasto i valori verranno valorizzati. TP_WAVELET_OLDSH;Algoritmo che utilizza valori negativi TP_WAVELET_OPACITY;Opacità blu-giallo TP_WAVELET_OPACITYW;Curva d/v-h del bilanciamento del contrasto -TP_WAVELET_OPACITYWL_TOOLTIP;Modificare il contrasto locale finale al termine del trattamento wavelet.\n\nIl lato sinistro rappresenta il contrasto locale più piccolo, procedendo fino al contrasto locale più grande sulla destra. TP_WAVELET_OPACITYWL;Contrasto locale +TP_WAVELET_OPACITYWL_TOOLTIP;Modificare il contrasto locale finale al termine del trattamento wavelet.\n\nIl lato sinistro rappresenta il contrasto locale più piccolo, procedendo fino al contrasto locale più grande sulla destra. TP_WAVELET_PASTEL;Cromia pastello TP_WAVELET_PROC;Processo TP_WAVELET_PROTAB;Protezione @@ -4087,9 +4083,9 @@ TP_WAVELET_RANGEAB;Allineare a e b % TP_WAVELET_RE1;Rinforzata TP_WAVELET_RE2;Invariato TP_WAVELET_RE3;Ridotto -TP_WAVELET_RESBLUR_TOOLTIP;Disabilitato se lo zoom > circa 500%. TP_WAVELET_RESBLUR;Luminanza sfocata TP_WAVELET_RESBLURC;Blur chromaSfocatura cromatica +TP_WAVELET_RESBLUR_TOOLTIP;Disabilitato se lo zoom > circa 500%. TP_WAVELET_RESCHRO;Intensità TP_WAVELET_RESCON;Ombre TP_WAVELET_RESCONH;Alteluci @@ -4100,13 +4096,13 @@ TP_WAVELET_SHA;Maschera definita TP_WAVELET_SHFRAME;Ombre/Alteluci TP_WAVELET_SHOWMASK;Mostra la 'maschera' wavelet TP_WAVELET_SIGM;Raggio -TP_WAVELET_SIGMA_TOOLTIP;L'effetto dei cursori del contrasto è più forte nei dettagli a contrasto medio e più debole nei dettagli ad alto e basso contrasto.\n Con questo cursore puoi controllare quanto velocemente l'effetto si attenua verso i contrasti estremi.\n Più alto è impostato il cursore, più ampia è la gamma di contrasti che otterrà un forte cambiamento e maggiore è il rischio di generare artefatti.\n .Più basso è, più l'effetto sarà localizzato verso una gamma ristretta di valori di contrasto. TP_WAVELET_SIGMA;Risposta di attenuazione TP_WAVELET_SIGMAFIN;Risposta di attenuazione -TP_WAVELET_SKIN_TOOLTIP;A -100 le tonalità della pelle vengono prese di mira.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità della pelle vengono protette mentre tutte le altre tonalità vengono influenzate. +TP_WAVELET_SIGMA_TOOLTIP;L'effetto dei cursori del contrasto è più forte nei dettagli a contrasto medio e più debole nei dettagli ad alto e basso contrasto.\n Con questo cursore puoi controllare quanto velocemente l'effetto si attenua verso i contrasti estremi.\n Più alto è impostato il cursore, più ampia è la gamma di contrasti che otterrà un forte cambiamento e maggiore è il rischio di generare artefatti.\n .Più basso è, più l'effetto sarà localizzato verso una gamma ristretta di valori di contrasto. TP_WAVELET_SKIN;Mira/protezione della pelle -TP_WAVELET_SKY_TOOLTIP;Consente di scegliere o proteggere una gamma di tonalità.\nA -100 vengono prese di mira le tonalità selezionate.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità selezionate vengono protette mentre tutte le altre tonalità vengono prese di mira. +TP_WAVELET_SKIN_TOOLTIP;A -100 le tonalità della pelle vengono prese di mira.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità della pelle vengono protette mentre tutte le altre tonalità vengono influenzate. TP_WAVELET_SKY;Mira/protezione della tonalità +TP_WAVELET_SKY_TOOLTIP;Consente di scegliere o proteggere una gamma di tonalità.\nA -100 vengono prese di mira le tonalità selezionate.\nA 0 tutte le tonalità vengono trattate allo stesso modo.\nA +100 le tonalità selezionate vengono protette mentre tutte le altre tonalità vengono prese di mira. TP_WAVELET_SOFTRAD;Raggio morbido TP_WAVELET_STREN;Perfeziona TP_WAVELET_STREND;Intensità @@ -4115,46 +4111,42 @@ TP_WAVELET_SUPE;Extra TP_WAVELET_THR;Soglia delle ombre TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. TP_WAVELET_THREND;Soglia di contrasto locale -TP_WAVELET_THRESHOLD_TOOLTIP;Solo i livelli inferiori e compresi nel valore scelto saranno influenzati dall'intervallo di luminanza delle alte luci. TP_WAVELET_THRESHOLD;Livelli più fini -TP_WAVELET_THRESHOLD2_TOOLTIP;Solo i livelli dal valore scelto al numero selezionato di 'livelli wavelet' saranno influenzati dall'intervallo di luminanza dell'ombra. TP_WAVELET_THRESHOLD2;Livelli più grossolani +TP_WAVELET_THRESHOLD2_TOOLTIP;Solo i livelli dal valore scelto al numero selezionato di 'livelli wavelet' saranno influenzati dall'intervallo di luminanza dell'ombra. +TP_WAVELET_THRESHOLD_TOOLTIP;Solo i livelli inferiori e compresi nel valore scelto saranno influenzati dall'intervallo di luminanza delle alte luci. TP_WAVELET_THRH;Soglia delle Alteluci -TP_WAVELET_TILES_TOOLTIP;L'elaborazione dell'immagine completa porta a una migliore qualità ed è l'opzione consigliata, mentre l'utilizzo dei riquadri è una soluzione di ripiego per gli utenti con poca RAM. Fare riferimento a RawPedia per i requisiti di memoria. TP_WAVELET_TILESBIG;Riquadri TP_WAVELET_TILESFULL;Immagine completa TP_WAVELET_TILESIZE;Metodo di quadrettatura +TP_WAVELET_TILES_TOOLTIP;L'elaborazione dell'immagine completa porta a una migliore qualità ed è l'opzione consigliata, mentre l'utilizzo dei riquadri è una soluzione di ripiego per gli utenti con poca RAM. Fare riferimento a RawPedia per i requisiti di memoria. TP_WAVELET_TMEDGS;Arresto del bordo TP_WAVELET_TMSCALE;Scala -TP_WAVELET_TMSTRENGTH_TOOLTIP;Controlla l'intensità della mappatura dei toni o della compressione del contrasto dell'immagine residua. TP_WAVELET_TMSTRENGTH;Intensità della compressione +TP_WAVELET_TMSTRENGTH_TOOLTIP;Controlla l'intensità della mappatura dei toni o della compressione del contrasto dell'immagine residua. TP_WAVELET_TMTYPE;Metodo di compressione TP_WAVELET_TON;Tonificante TP_WAVELET_TONFRAME;Colori esclusi -TP_WAVELET_USH_TOOLTIP;Se selezioni Maschera nitida, puoi scegliere qualsiasi livello (in Impostazioni) da 1 a 4 per l'elaborazione.\nSe selezioni Chiarezza, puoi scegliere qualsiasi livello (in Impostazioni) tra 5 ed Extra. TP_WAVELET_USH;Nessuno TP_WAVELET_USHARP;Metodo di chiarezza +TP_WAVELET_USH_TOOLTIP;Se selezioni Maschera nitida, puoi scegliere qualsiasi livello (in Impostazioni) da 1 a 4 per l'elaborazione.\nSe selezioni Chiarezza, puoi scegliere qualsiasi livello (in Impostazioni) tra 5 ed Extra. TP_WAVELET_WAVLOWTHR;Soglia di contrasto basso TP_WAVELET_WAVOFFSET;Compensa -TP_WBALANCE_AUTO_HEADER;Automatico e perfezionamento TP_WBALANCE_AUTO;Automatico TP_WBALANCE_AUTOITCGREEN;Correlazione della temperatura TP_WBALANCE_AUTOOLD;Grigio RGB +TP_WBALANCE_AUTO_HEADER;Automatico e perfezionamento TP_WBALANCE_CAMERA;Fotocamera TP_WBALANCE_CLOUDY;Nuvoloso TP_WBALANCE_CUSTOM;Personalizzato TP_WBALANCE_DAYLIGHT;Luce Diurna (soleggiato) -TP_WBALANCE_EQBLUERED_TOOLTIP;Consente di deviare dal comportamento normale del "bilanciamento del bianco" modulando il bilanciamento blu/rosso.\nPuò essere utile quando le condizioni di ripresa:\na) sono molto diverse dalle illuminazioni normali (ad esempio, sott'acqua),\nb) sono molto diverse dalle condizioni alle quali sono state effettuate le calibrazioni,\nc) quando le matrici o i profili ICC non sono disponibili. TP_WBALANCE_EQBLUERED;Equalizzatore Blu/Rosso -TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_EQBLUERED_TOOLTIP;Consente di deviare dal comportamento normale del "bilanciamento del bianco" modulando il bilanciamento blu/rosso.\nPuò essere utile quando le condizioni di ripresa:\na) sono molto diverse dalle illuminazioni normali (ad esempio, sott'acqua),\nb) sono molto diverse dalle condizioni alle quali sono state effettuate le calibrazioni,\nc) quando le matrici o i profili ICC non sono disponibili. TP_WBALANCE_FLASH55;Leica TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta -TP_WBALANCE_FLUO_HEADER;Fluorescente +TP_WBALANCE_FLASH_HEADER;Flash TP_WBALANCE_FLUO1;F1 - Luce Diurna -TP_WBALANCE_FLUO10;F10 - Philips TL85 -TP_WBALANCE_FLUO11;F11 - Philips TL84 -TP_WBALANCE_FLUO12;F12 - Philips TL83 TP_WBALANCE_FLUO2;F2 - Bianco Freddo TP_WBALANCE_FLUO3;F3 - Bianco TP_WBALANCE_FLUO4;F4 - Bianco Caldo @@ -4163,17 +4155,30 @@ TP_WBALANCE_FLUO6;F6 - Bianco Chiaro TP_WBALANCE_FLUO7;F7 - D65 Simulatore di Luce Diurna TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design TP_WBALANCE_FLUO9;F9 - Bianco Freddo Deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescente TP_WBALANCE_GREEN;Tinta TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI TP_WBALANCE_ITCWALG_TOOLTIP;Permette di passare all'altra temperatura Alternativa (Alt_temp), quando possibile.\nNon attivo nel caso "scelta singola". +TP_WBALANCE_ITCWBDELTA_TOOLTIP;Risolto il problema per ogni iterazione "verde" tentata, della differenza di temperatura da prendere in considerazione. +TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Trova il miglior compromesso tra Student e green. +TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Consente di impostare il valore patch minimo. valori troppo bassi possono portare ad una mancanza di correlazione. +TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Consente di filtrare i dati magenta/viola dall'immagine. Se la casella è selezionata, viene applicato un filtro che limita il valore di Y. Per impostazione predefinita questo valore è 0,4. Puoi cambiarlo nelle 'opzioni' Itcwb_Yporpora (Massimo 1) +TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Più basso è il valore, più rilevanti sono i dati, ma aumenta il tempo di elaborazione. Poiché il tempo di elaborazione è basso, questo parametro dovrebbe generalmente poter rimanere al valore predefinito +TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Imposta l'ampiezza di revisione del valore verde in iterazioni, dall'ampiezza bassa da 0,82 a 1,25 all'ampiezza massima da 0,4 a 4. +TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Questa impostazione imposta la dimensione dei dati di colore utilizzati dall'algoritmo. +TP_WBALANCE_ITCWBSIZE_TOOLTIP;Questa impostazione imposta il numero di iterazioni per trovare la migliore corrispondenza tra i colori spettrali di riferimento e quelli nel valore xyY dell'immagine. Un valore pari a 3 sembra un buon compromesso. +TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limita il campionamento comparativo tra i dati spettrali e i dati dell'immagine. TP_WBALANCE_ITCWB_ALG;Rimuovi l'algoritmo a 2 passaggi TP_WBALANCE_ITCWB_CUSTOM;Utilizza temperatura e tinta personalizzate TP_WBALANCE_ITCWB_DELTA;Delta temperatura nel circuito verde TP_WBALANCE_ITCWB_FGREEN;Trova uno alunno verde TP_WBALANCE_ITCWB_FORCED;Vicino al diagramma CIE completo -TP_WBALANCE_ITCWB_FRA_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di raw, colorimetria, ecc.), un adattamento dell'algoritmo di 'Correlazione della temperatura'. Non esiste una regola assoluta che lega questi parametri ai risultati ottenuti. TP_WBALANCE_ITCWB_FRA;Impostazioni correlazione temperatura auto +TP_WBALANCE_ITCWB_FRA_TOOLTIP;Queste impostazioni consentono, a seconda delle immagini (tipo di raw, colorimetria, ecc.), un adattamento dell'algoritmo di 'Correlazione della temperatura'. Non esiste una regola assoluta che lega questi parametri ai risultati ottenuti. TP_WBALANCE_ITCWB_MINSIZEPATCH;Dimensione minima della patch TP_WBALANCE_ITCWB_NOPURPLE;Filtra sul colore viola TP_WBALANCE_ITCWB_PRECIS;Algoritmo di precisione: scala utilizzata @@ -4190,19 +4195,10 @@ TP_WBALANCE_ITCWB_SAMPLING;Campionamento basso 5.9 TP_WBALANCE_ITCWB_SIZE;Dimensioni di riferimento il colore viene confrontato con l'istogramma TP_WBALANCE_ITCWB_SIZEPATCH;Dimensioni della toppa colorata TP_WBALANCE_ITCWB_THRES;Colori utilizzati nell'immagine (preimpostati) -TP_WBALANCE_ITCWBDELTA_TOOLTIP;Risolto il problema per ogni iterazione "verde" tentata, della differenza di temperatura da prendere in considerazione. -TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Trova il miglior compromesso tra Student e green. -TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Consente di impostare il valore patch minimo. valori troppo bassi possono portare ad una mancanza di correlazione. -TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Consente di filtrare i dati magenta/viola dall'immagine. Se la casella è selezionata, viene applicato un filtro che limita il valore di Y. Per impostazione predefinita questo valore è 0,4. Puoi cambiarlo nelle 'opzioni' Itcwb_Yporpora (Massimo 1) -TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Più basso è il valore, più rilevanti sono i dati, ma aumenta il tempo di elaborazione. Poiché il tempo di elaborazione è basso, questo parametro dovrebbe generalmente poter rimanere al valore predefinito -TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Imposta l'ampiezza di revisione del valore verde in iterazioni, dall'ampiezza bassa da 0,82 a 1,25 all'ampiezza massima da 0,4 a 4. -TP_WBALANCE_ITCWBSIZE_TOOLTIP;Questa impostazione imposta il numero di iterazioni per trovare la migliore corrispondenza tra i colori spettrali di riferimento e quelli nel valore xyY dell'immagine. Un valore pari a 3 sembra un buon compromesso. -TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Questa impostazione imposta la dimensione dei dati di colore utilizzati dall'algoritmo. -TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limita il campionamento comparativo tra i dati spettrali e i dati dell'immagine. TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Ti consente di utilizzare le impostazioni personalizzate Temperatura e Verde (tinta).\n\nSuggerimenti per l'uso:\n1) avvia Itcwb, attiva 'Utilizza temperatura e tinta personalizzate'.\n2) Imposta 'Temperatura e tinta' a tuo piacimento: gratis, scegli ,...(Personalizzato)\n3) torna a 'Correlazione temperatura'.\n\nNon è possibile utilizzare: 2 passaggi, bias temperatura AWB, perfezionamento verde. TP_WBALANCE_ITCWFORCED_TOOLTIP;Per impostazione predefinita (casella non selezionata) i dati scansionati durante il campionamento vengono riportati al profilo sRGB, che è il più diffuso, sia per la calibrazione dei profili DCP o ICC con il Colorchecker24, sia utilizzato sul web.\n Se avete valori molto alti immagini della gamma (alcuni fiori, colori artificiali), potrebbe essere necessario utilizzare l'intero diagramma CIExy, il profilo utilizzato sarà ACESP0. In questo secondo caso sarà più importante il numero di colori che potranno essere utilizzati all’interno dell’algoritmo. -TP_WBALANCE_ITCWGREEN_TOOLTIP;Permette di cambiare la "tinta" (verde) che servirà da riferimento all'avvio dell'algoritmo. Ha sostanzialmente lo stesso ruolo per i verdi del "bias temperatura AWB" per la temperatura.\nL'intero algoritmo viene ricalcolato. TP_WBALANCE_ITCWGREEN;Raffinatezza del verde +TP_WBALANCE_ITCWGREEN_TOOLTIP;Permette di cambiare la "tinta" (verde) che servirà da riferimento all'avvio dell'algoritmo. Ha sostanzialmente lo stesso ruolo per i verdi del "bias temperatura AWB" per la temperatura.\nL'intero algoritmo viene ricalcolato. TP_WBALANCE_ITCWPRIM_TOOLTIP;Permette di selezionare il campionamento dell'immagine.\n'Vicino al diagramma CIE completo' utilizza quasi i dati presenti sul sensore, eventualmente includendo i colori immaginari.\n'Matrice XYZ della fotocamera' - utilizza la matrice derivata direttamente da Color Matrix.\ n'Campionamento medio' (predefinito) - vicino alla gamma del puntatore: corrisponde sostanzialmente ai casi più comuni di visione umana.\nL'altra scelta 'Campionamento basso e Impostazioni fotocamera inutilizzata' consentono di isolare parti ad alta gamma dell'immagine e forzare il algoritmo in alcuni casi (tinta > 0,8,...) per non utilizzare le impostazioni della fotocamera. Ciò ovviamente avrà un impatto sul risultato.\n\nQuesto campionamento influisce solo sui moltiplicatori di canale, non ha nulla a che vedere con il "profilo di lavoro" e non modifica il gamut dell'immagine. TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Consente di utilizzare il vecchio algoritmo di campionamento per garantire una migliore compatibilità con 5.9. È necessario abilitare Observer 10° (impostazione predefinita). TP_WBALANCE_JUDGEIII;JudgeIII @@ -4212,33 +4208,33 @@ TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 TP_WBALANCE_LED_HEADER;LED TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Metodo -TP_WBALANCE_MULLABEL_TOOLTIP;Valori forniti a scopo informativo. Non puoi cambiarli. TP_WBALANCE_MULLABEL;Multi: r=%1 g=%2 b=%3 -TP_WBALANCE_OBSERVER10_TOOLTIP;La gestione del colore in Rawtherapee (bilanciamento del bianco, moltiplicatori di canali, recupero delle luci,...) utilizza i dati spettrali degli illuminanti e dei colori. L'osservatore è un parametro importante di questa gestione che tiene conto dell'angolo di percezione dell'occhio. Nel 1931 fu fissata a 2° (privilegia l'uso dei coni). Nel 1964 è stato fissato a 10° (privilegia l'uso dei coni, ma tiene parzialmente conto dei bastoncelli).\nPer evitare una (rara) deriva dei colori dovuta alla scelta dell'Osservatore 10° - probabilmente dovuta alla matrice di conversione - È necessario selezionare l'Osservatore 2°.\nNella maggior parte dei casi l'Osservatore 10° (predefinito) sarà una scelta più rilevante. +TP_WBALANCE_MULLABEL_TOOLTIP;Valori forniti a scopo informativo. Non puoi cambiarli. TP_WBALANCE_OBSERVER10;Osservatore 10° invece di 2° -TP_WBALANCE_PATCHLABEL_TOOLTIP;Visualizza il numero di colori letti (max=237).\nVisualizza la crominanza patch calcolata.\nBias di temperatura AWB, proviamo a ridurre questo valore, un minimo potrebbe sembrare per ottimizzare l'algoritmo.\n\nOttimizzazione della crominanza corrispondente alla dimensione della patch. +TP_WBALANCE_OBSERVER10_TOOLTIP;La gestione del colore in Rawtherapee (bilanciamento del bianco, moltiplicatori di canali, recupero delle luci,...) utilizza i dati spettrali degli illuminanti e dei colori. L'osservatore è un parametro importante di questa gestione che tiene conto dell'angolo di percezione dell'occhio. Nel 1931 fu fissata a 2° (privilegia l'uso dei coni). Nel 1964 è stato fissato a 10° (privilegia l'uso dei coni, ma tiene parzialmente conto dei bastoncelli).\nPer evitare una (rara) deriva dei colori dovuta alla scelta dell'Osservatore 10° - probabilmente dovuta alla matrice di conversione - È necessario selezionare l'Osservatore 2°.\nNella maggior parte dei casi l'Osservatore 10° (predefinito) sarà una scelta più rilevante. TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 -TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Visualizza patch ΔE (questo presuppone che ci siano abbastanza dati spettrali), tra l'immagine e i dati spettrali.\n Visualizza i dati letti trovati. I 2 valori corrispondono ai valori dei dati minimo e massimo presi in considerazione. È necessario tenere conto del coefficiente x9 per ottenere il numero di pixel interessati nell'immagine. +TP_WBALANCE_PATCHLABEL_TOOLTIP;Visualizza il numero di colori letti (max=237).\nVisualizza la crominanza patch calcolata.\nBias di temperatura AWB, proviamo a ridurre questo valore, un minimo potrebbe sembrare per ottimizzare l'algoritmo.\n\nOttimizzazione della crominanza corrispondente alla dimensione della patch. TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 +TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Visualizza patch ΔE (questo presuppone che ci siano abbastanza dati spettrali), tra l'immagine e i dati spettrali.\n Visualizza i dati letti trovati. I 2 valori corrispondono ai valori dei dati minimo e massimo presi in considerazione. È necessario tenere conto del coefficiente x9 per ottenere il numero di pixel interessati nell'immagine. TP_WBALANCE_PICKER;Scegli TP_WBALANCE_SHADE;Ombra TP_WBALANCE_SIZE;Dim.: TP_WBALANCE_SOLUX35;Solux 3500K TP_WBALANCE_SOLUX41;Solux 4100K -TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) TP_WBALANCE_SPOTWB;Punto BB -TP_WBALANCE_STUDLABEL_TOOLTIP;Visualizza la correlazione Student calcolata.\nValori più bassi sono migliori, dove <0,005 è eccellente,\n<0,01 è buono e >0,5 è scarso.\nValori bassi non significano che il bilanciamento del bianco è buono:\nse l'illuminante non è standard i risultati possono essere irregolari.\nUn valore di 1000 significa che vengono utilizzati i calcoli precedenti e\ni risultati sono probabilmente buoni.\n\nPassaggi: numero di passaggi effettuati.\nAlt_temp: temperatura alternativa. TP_WBALANCE_STUDLABEL;Correlation factor: %1 Passes:%2 Worst_alt=%3 TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 TP_WBALANCE_STUDLABEL1;Correlation factor: %1 Passes:%2 Best_alt=%3 -TP_WBALANCE_TEMPBIAS_TOOLTIP;Permette di alterare il calcolo del 'bilanciamento automatico del bianco'\nspostandolo verso temperature più calde o più fredde. Il bias\nè espresso come percentuale della temperatura calcolata,\nin modo che il risultato sia dato da 'computedTemp + computedTemp * bias'.\n\nÈ possibile utilizzare il "bias temperatura Awb" per regolare i risultati della "correlazione della temperatura". Ogni movimento di questo comando comporta un nuovo calcolo di temperatura, tinta e correlazione. +TP_WBALANCE_STUDLABEL_TOOLTIP;Visualizza la correlazione Student calcolata.\nValori più bassi sono migliori, dove <0,005 è eccellente,\n<0,01 è buono e >0,5 è scarso.\nValori bassi non significano che il bilanciamento del bianco è buono:\nse l'illuminante non è standard i risultati possono essere irregolari.\nUn valore di 1000 significa che vengono utilizzati i calcoli precedenti e\ni risultati sono probabilmente buoni.\n\nPassaggi: numero di passaggi effettuati.\nAlt_temp: temperatura alternativa. TP_WBALANCE_TEMPBIAS;Distorsione temperatura AWB +TP_WBALANCE_TEMPBIAS_TOOLTIP;Permette di alterare il calcolo del 'bilanciamento automatico del bianco'\nspostandolo verso temperature più calde o più fredde. Il bias\nè espresso come percentuale della temperatura calcolata,\nin modo che il risultato sia dato da 'computedTemp + computedTemp * bias'.\n\nÈ possibile utilizzare il "bias temperatura Awb" per regolare i risultati della "correlazione della temperatura". Ogni movimento di questo comando comporta un nuovo calcolo di temperatura, tinta e correlazione. TP_WBALANCE_TEMPERATURE;Temperatura TP_WBALANCE_TUNGSTEN;Tungsteno -TP_WBALANCE_WATER_HEADER;Subacqueo TP_WBALANCE_WATER1;Subacqueo 1 TP_WBALANCE_WATER2;Subacqueo 2 +TP_WBALANCE_WATER_HEADER;Subacqueo ZOOMPANEL_100;(100%) ZOOMPANEL_NEWCROPWINDOW;Apri (nuova) finestra di dettaglio ZOOMPANEL_ZOOM100;Ingrandimento al 100%.\nScorciatoia: z @@ -4246,5 +4242,180 @@ ZOOMPANEL_ZOOMFITCROPSCREEN;Adatta il ritaglio allo schermo\nScorciatoia: fAlt-f ZOOMPANEL_ZOOMIN;Ingrandisci.\nScorciatoia: + ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - -//TP_WBALANCE_ITCWB_FORCED;Forza l'uso dell'intero diagramma CIE //TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Per impostazione predefinita, quando è attivato "Inpaint opposto", i colori viola non vengono presi in considerazione. Tuttavia, se l'immagine non necessita di ricostruzione delle alte luci o se l'immagine contiene naturalmente tinte viola (fiori, ecc.), potrebbe essere necessario disattivarla per tenere conto di tutti i colori. +//TP_WBALANCE_ITCWB_FORCED;Forza l'uso dell'intero diagramma CIE + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. +!HISTORY_MSG_ICM_CAT;Matrix adaptation +!HISTORY_MSG_ICM_MIDTCIE;Midtones +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y +!TC_PRIM_REFI;Refine colors (white-point) +!TP_ICM_BW;Black and White +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale +!TP_ICM_WORKING_ILLU_E;E +!TP_ICM_WORKING_NON;None +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None +!TP_LOCALLAB_COLORFRAME;Dominant color +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools +!TP_LOCALLAB_EXMAIN;Global +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings +!TP_LOCALLAB_MIDTCIE;Midtones +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant +!TP_LOCALLAB_SATCIE;Saturation control +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGGAMJCIE;Gamma +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing +!TP_LOCALLAB_STRENGTHCIELOG;Strength +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 0ab26491d..235d68e11 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -3702,7 +3702,7 @@ TP_METADATA_MODE;メタデータ コピーモード TP_METADATA_STRIP;メタデータを全ã¦å–り除ã TP_METADATA_TUNNEL;変更ãªã—ã§ã‚³ãƒ”ー TP_NEUTRAL;リセット -TP_NEUTRAL_TIP;露光é‡è£œæ­£ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼å€¤ã‚’ニュートラルã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã€‚\n自動露光補正ã®èª¿æ•´å€¤ã¤ã„ã¦ã‚‚åŒæ§˜ã«ãƒªã‚»ãƒƒãƒˆã•れã¾ã™ +TP_NEUTRAL_TOOLTIP;露光é‡è£œæ­£ã®ã‚¹ãƒ©ã‚¤ãƒ€ãƒ¼å€¤ã‚’ニュートラルã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã€‚\n自動露光補正ã®èª¿æ•´å€¤ã¤ã„ã¦ã‚‚åŒæ§˜ã«ãƒªã‚»ãƒƒãƒˆã•れã¾ã™ TP_PCVIGNETTE_FEATHER;フェザー TP_PCVIGNETTE_FEATHER_TOOLTIP;フェザー: 0=四隅ã ã‘ã€50=中央ã¾ã§ã®åŠåˆ†ã€100=中央ã¾ã§ TP_PCVIGNETTE_LABEL;ビãƒãƒƒãƒˆãƒ•ィルター @@ -4400,6 +4400,18 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!TP_NEUTRAL_TOOLTIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) +!TP_WBALANCE_STUDLABEL0;Correlation factor: %1 Passes:%2 Alt=%3 !//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. !//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index 8336efda8..f1a425951 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -128,7 +128,6 @@ EXIFPANEL_RESET;Visszaállít EXIFPANEL_RESETALL;Mindent visszaállít EXIFPANEL_RESETALLHINT;Az összes metaadat visszaállítása az eredeti állapotba EXIFPANEL_RESETHINT;A kijelölt adatok visszaállítása az eredeti állapotba -EXIFPANEL_SUBDIRECTORY;Alkönyvtár EXPORT_BYPASS_ALL;Mindent kijelöl/Kijelölés megszüntetése EXPORT_BYPASS_DEFRINGE;Színihiba-korrekció kihagyása EXPORT_BYPASS_DIRPYRDENOISE;Zajszűrés kihagyása @@ -693,9 +692,7 @@ MAIN_BUTTON_NAVNEXT_TOOLTIP;A SzerkesztÅ‘ben megnyitott képet követÅ‘ képhez MAIN_BUTTON_NAVPREV_TOOLTIP;A SzerkesztÅ‘ben megnyitott képet megelÅ‘zÅ‘ képhez navigálás.\nGyorsbillentyű: Shift-F3\n\nA Fájl böngészÅ‘ben vagy Filmszalagban jelenleg kijelölt ikont megelÅ‘zÅ‘ képhez navigálás.\nGyorsbillentyű: F3 MAIN_BUTTON_NAVSYNC_TOOLTIP;A Fájl böngészÅ‘ben vagy Filmszalag szinkronizálása a SzerkesztÅ‘vel a jelenleg megnyitott kép ikonjának felfedéséért, és minden aktív szűrÅ‘ törlése.\nGyorsbillentyű: x\n\nMint fentebb, de az aktív szűrÅ‘k törlése nélkül.\nGyorsbillentyű: y\n(Vedd figyelembe, hogy a megnyitott kép ikonja nem fog megjelenni, amennyiben az ki van szűrve). MAIN_BUTTON_PREFERENCES;Beállítások -MAIN_BUTTON_PUTTOQUEUE;Feldolgozási sorba helyez MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add hozzá a kiválasztott képet a feldolgozási sorhoz Ctrl+B -MAIN_BUTTON_SAVE;Kép mentése MAIN_BUTTON_SAVE_TOOLTIP;Kiválasztott kép mentése Ctrl+S MAIN_BUTTON_SENDTOEDITOR;Megnyitás külsÅ‘ programmal MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Kiválasztott kép szerkesztése külsÅ‘ programmal Ctrl+E @@ -874,7 +871,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Színválasztó betűtípusa PREFERENCES_APPEARANCE_CROPMASKCOLOR;Vágómaszk színe PREFERENCES_APPEARANCE_MAINFONT;FÅ‘betűtípus PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigátor útmutató színe -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pszeudo-magasDPI mód PREFERENCES_APPEARANCE_THEME;Téma PREFERENCES_APPLNEXTSTARTUP;újraindítás után érvényes PREFERENCES_AUTOMONPROFILE;Oprendszerben beállított monitor-színprofil automatikus használata @@ -1370,7 +1366,6 @@ TP_EXPOSURE_COMPRHIGHLIGHTS;Világos tónusok tömörítése TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Csúcsfények helyreállításának küszöbe 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 @@ -1575,6 +1570,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !EXPORT_PIPELINE;Processing pipeline !EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_OTHER;Other !HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB Parade @@ -1776,7 +1772,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2086,7 +2082,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2329,7 +2325,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2445,16 +2441,23 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2467,7 +2470,72 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2578,6 +2646,9 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_EXTERNALEDITOR_CHANGE;Change Application !PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Change Executable @@ -2588,13 +2659,18 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional !PREFERENCES_PRINTER;Printer (Soft-Proofing) +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2616,6 +2692,27 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PREFERENCES_XMP_SIDECAR_MODE;XMP sidecar style !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SOFTPROOF_GAMUTCHECK_TOOLTIP;Highlight pixels with out-of-gamut colors with respect to:\n- the printer profile, if one is set and soft-proofing is enabled,\n- the output profile, if a printer profile is not set and soft-proofing is enabled,\n- the monitor profile, if soft-proofing is disabled. !SOFTPROOF_TOOLTIP;Soft-proofing simulates the appearance of the image:\n- when printed, if a printer profile is set in Preferences > Color Management,\n- when viewed on a display that uses the current output profile, if a printer profile is not set. @@ -2626,6 +2723,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y +!TC_PRIM_REFI;Refine colors (white-point) !TP_COLORAPP_CIECAT_DEGREEOUT;Chromatic Adaptation Viewing !TP_COLORAPP_SURROUND;Surround !TP_COLORAPP_SURROUNDSRC;Surround @@ -2827,6 +2928,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT;Illuminant !TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. @@ -2849,8 +2951,15 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_ICM_TONECURVE;Tone curve !TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only available if the selected DCP has a tone curve. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2862,11 +2971,13 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2875,11 +2986,14 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2928,6 +3042,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LABEL;Profiled Lens Correction !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile @@ -2947,9 +3062,9 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2992,9 +3107,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3034,6 +3152,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3049,8 +3173,9 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3058,7 +3183,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3073,7 +3201,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3082,13 +3210,14 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3108,6 +3237,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3116,6 +3246,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3131,9 +3262,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3142,11 +3274,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3168,7 +3300,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3264,7 +3397,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3309,8 +3442,10 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3318,7 +3453,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3331,6 +3466,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3400,7 +3536,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3436,6 +3572,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3483,10 +3620,15 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3531,10 +3673,11 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3555,7 +3698,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3601,17 +3744,41 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3633,13 +3800,14 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3671,11 +3839,12 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4244,7 +4413,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_EQBLUERED;Blue/Red equalizer !TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of 'white balance' by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. @@ -4289,7 +4458,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index af2862781..b36284af5 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -70,6 +70,7 @@ DYNPROFILEEDITOR_PROFILE;Profiel verwerken EDITWINDOW_TITLE;Bewerk afbeelding EDIT_OBJECT_TOOLTIP;Toont een widget in het voorbeeldscherm waarmee de werking van het gereedschap kan worden aangepast. EDIT_PIPETTE_TOOLTIP;Voeg een punt aan de curve toe met Ctrl+muisklik op de gewenste plek in het voorbeeld.\nKlik op een punt in de tooncurve om deze te selecteren (wordt rood), verplaats 'm vervolgens met de linkermuisknop ingedrukt.\n Hou de Ctrl-toets ingedrukt voor fijnmazige controle. +ERROR_MSG_METADATA_VALUE;Metadata: fout bij omzetting %1 naar %2 EXIFFILTER_APERTURE;Diafragma EXIFFILTER_CAMERA;Camera EXIFFILTER_EXPOSURECOMPENSATION;Belichtingscompensatie (LW) @@ -79,12 +80,16 @@ EXIFFILTER_IMAGETYPE;Type afbeelding EXIFFILTER_ISO;ISO-waarde EXIFFILTER_LENS;Objectief EXIFFILTER_METADATAFILTER;Activeer metadatafilters +EXIFFILTER_PATH;Bestandspad EXIFFILTER_SHUTTER;Sluitertijd +EXIFPANEL_ACTIVATE_ALL_HINT;Selecteer alle tags +EXIFPANEL_ACTIVATE_NONE_HINT;Deselecteer alle tags EXIFPANEL_ADDEDIT;Voeg toe/bewerk EXIFPANEL_ADDEDITHINT;Voeg nieuwe tag toe of bewerk tag EXIFPANEL_ADDTAGDLG_ENTERVALUE;Geef waarde EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecteer tag EXIFPANEL_ADDTAGDLG_TITLE;Voeg tag toe of bewerk +EXIFPANEL_BASIC_GROUP;Basis EXIFPANEL_KEEP;Bewaar EXIFPANEL_KEEPHINT;Bewaar geselecteerde tags in doelbestand EXIFPANEL_REMOVE;Verwijder @@ -93,8 +98,7 @@ EXIFPANEL_RESET;Herstel EXIFPANEL_RESETALL;Herstel alles EXIFPANEL_RESETALLHINT;Zet alle tags terug naar hun oorspronkelijke waarden EXIFPANEL_RESETHINT;Zet geselecteerde tags terug naar hun oorspronkelijke waarden -EXIFPANEL_SHOWALL;Toon alles -EXIFPANEL_SUBDIRECTORY;Submap +EXIFPANEL_VALUE_NOT_SHOWN;Niet getoond EXPORT_BYPASS;Verwerkingsstappen die worden overgeslagen EXPORT_BYPASS_ALL;Alles selecteren/deselecteren EXPORT_BYPASS_DEFRINGE;Verzachten niet toepassen @@ -163,6 +167,7 @@ FILEBROWSER_POPUPCOLORLABEL4;Label: Blauw FILEBROWSER_POPUPCOLORLABEL5;Label: Paars FILEBROWSER_POPUPCOPYTO;Kopieer naar... FILEBROWSER_POPUPFILEOPERATIONS;Bestandsbewerkingen +FILEBROWSER_POPUPINSPECT;Inspecteer FILEBROWSER_POPUPMOVEEND;Naar einde van de verwerkingsrij FILEBROWSER_POPUPMOVEHEAD;Naar begin van de verwerkingsrij FILEBROWSER_POPUPMOVETO;Verplaats naar... @@ -182,6 +187,7 @@ FILEBROWSER_POPUPREMOVE;Permanent verwijderen FILEBROWSER_POPUPREMOVEINCLPROC;Verwijder definitief, inclusief met uitvoer in de verwerkingsrij FILEBROWSER_POPUPRENAME;Hernoem FILEBROWSER_POPUPSELECTALL;Alles selecteren +FILEBROWSER_POPUPSORTBY;Sorteer bestanden FILEBROWSER_POPUPTRASH;Verplaats naar prullenbak FILEBROWSER_POPUPUNRANK;Verwijder sterwaardering FILEBROWSER_POPUPUNTRASH;Haal terug uit prullenbak @@ -225,6 +231,7 @@ FILEBROWSER_ZOOMOUTHINT;Kleiner FILECHOOSER_FILTER_ANY;Alle bestanden FILECHOOSER_FILTER_COLPROF;Kleurprofielen FILECHOOSER_FILTER_CURVE;Curve-bestanden +FILECHOOSER_FILTER_EXECUTABLE;Uitvoerbare bestanden FILECHOOSER_FILTER_LCP;Lenscorrectieprofielen FILECHOOSER_FILTER_PP;Profiel verwerken FILECHOOSER_FILTER_SAME;Hetzelfde formaat als huidige foto @@ -238,8 +245,10 @@ GENERAL_BEFORE;Voor GENERAL_CANCEL;Annuleren GENERAL_CLOSE;Sluiten GENERAL_CURRENT;Huidig +GENERAL_DELETE_ALL;Wis alles GENERAL_DISABLE;Deactiveren GENERAL_DISABLED;Gedeactiveerd +GENERAL_EDIT;Bewerk GENERAL_ENABLE;Activeer GENERAL_ENABLED;Geactiveerd GENERAL_FILE;Bestand @@ -250,6 +259,7 @@ GENERAL_NO;Nee GENERAL_NONE;Geen GENERAL_OK;OK GENERAL_OPEN;Open +GENERAL_OTHER;Ander GENERAL_PORTRAIT;Portret GENERAL_RESET;Terugzetten GENERAL_SAVE;Opslaan @@ -261,10 +271,19 @@ GIMP_PLUGIN_INFO;Welkom bij de RawTherapee GIMP plug-in!\nAls uw bewerking geree HISTOGRAM_TOOLTIP_B;Toon/verberg blauw histogram HISTOGRAM_TOOLTIP_BAR;Toon/verberg RGB-indicatie\nRechtermuisklik op foto om te starten/stoppen HISTOGRAM_TOOLTIP_CHRO;Toon/Verberg chromaticiteitshistogram +HISTOGRAM_TOOLTIP_CROSSHAIR;Toon/verberg indicatorkruis HISTOGRAM_TOOLTIP_G;Toon/verberg groen histogram HISTOGRAM_TOOLTIP_L;Toon/verberg CIELAB-luminantiehistogram HISTOGRAM_TOOLTIP_MODE;Wissel tussen lineair, log-lineair en log-log schalen van het histogram. HISTOGRAM_TOOLTIP_R;Toon/verberg rood histogram +HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toon/verberg optieknoppen +HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Pas helderheid aan +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw-histogram +HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-Parade +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Tint-Chroma vectorscope +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Tint-Verzadiging vectorscope +HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Golfvorm HISTORY_CHANGED;Veranderd HISTORY_CUSTOMCURVE;Handmatig HISTORY_FROMCLIPBOARD;Van klembord @@ -721,1631 +740,8 @@ HISTORY_MSG_491;Witbalans HISTORY_MSG_492;RGB-curven HISTORY_MSG_493;L*a*b* aanpassingen HISTORY_MSG_494;verscherpen -HISTORY_MSG_CLAMPOOG;Kleuren afkappen die buiten het gamma vallen -HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Kleurcorrectie -HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Kleurcorrectie -HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Kanaal -HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - gebied C-masker -HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H-masker -HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Licht -HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L-masker -HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - Lijst -HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - verzachtingsmasker gebied -HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - verschuiving gebied -HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - sterkte gebied -HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Verzadiging -HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - toon gebiedsmasker -HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - hellingsgebied -HISTORY_MSG_DEHAZE_DEPTH;Ontnevelen - Diepte -HISTORY_MSG_DEHAZE_ENABLED;Ontnevelen -HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Ontnevelen - Toon dieptemap -HISTORY_MSG_DEHAZE_STRENGTH;Ontnevelen - Sterkte -HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual-demozaïek - auto-drempel -HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual-demozaïek - Contrastdrempel -HISTORY_MSG_FILMNEGATIVE_ENABLED;Filmnegatief -HISTORY_MSG_FILMNEGATIVE_VALUES;Filmnegatief waarden -HISTORY_MSG_HISTMATCHING;Auto-tooncurve -HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaire kleuren -HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 illuminant D -HISTORY_MSG_ICM_OUTPUT_TYPE;Uitvoer - Type -HISTORY_MSG_ICM_WORKING_GAMMA;Werkend - Gamma -HISTORY_MSG_ICM_WORKING_SLOPE;Werkend - Helling -HISTORY_MSG_ICM_WORKING_TRC_METHOD;Werkend - TRC-methode -HISTORY_MSG_LOCALCONTRAST_AMOUNT;Lokaal Contrast - Hoeveelheid -HISTORY_MSG_LOCALCONTRAST_DARKNESS;Lokaal Contrast - Donker -HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokaal Contrast -HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokaal Contrast - Licht -HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokaal Contrast - Radius -HISTORY_MSG_METADATA_MODE;Metadata kopieermodus -HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrastdrempel -HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto-drempel -HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto-radius -HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto-limiet herhalingen -HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrastdrempel -HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Herhalingen -HISTORY_MSG_PDSHARPEN_RADIUS;CS - Straal -HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Toename hoekstraal -HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demozaïekmethode voor beweging -HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Lijnruisfilter richting -HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter -HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrastdrempel -HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correctie - Herhalingen -HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correctie - Vermijd kleurverschuiving -HISTORY_MSG_RAW_BORDER;Raw rand -HISTORY_MSG_RESIZE_ALLOWUPSCALING;Schalen - sta vergroting toe -HISTORY_MSG_SHARPENING_BLUR;Verscherpen - Vervagingsradius -HISTORY_MSG_SHARPENING_CONTRAST;Verscherpen - Contrastdrempel -HISTORY_MSG_SH_COLORSPACE;S/H - Kleurruimte -HISTORY_MSG_SOFTLIGHT_ENABLED;Zacht licht -HISTORY_MSG_SOFTLIGHT_STRENGTH;Zacht licht - Sterkte -HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anker -HISTORY_MSG_TRANS_METHOD;Geometrie - Methode -HISTORY_NEWSNAPSHOT;Nieuw -HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt+S -HISTORY_SNAPSHOT;Nieuw -HISTORY_SNAPSHOTS;Snapshots -ICCPROFCREATOR_COPYRIGHT;Copyright: -ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Zet terug naar standaard copyright, verleend aan "RawTherapee, CC0" -ICCPROFCREATOR_CUSTOM;Handmatig -ICCPROFCREATOR_DESCRIPTION;Beschriiving: -ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Voeg gamma- en hellingwaarden toe aan de beschrijving -ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Laat leeg voor de standaardbeschrijving. -ICCPROFCREATOR_GAMMA;Gamma -ICCPROFCREATOR_ICCVERSION;ICC-versie: -ICCPROFCREATOR_ILL;Illuminant: -ICCPROFCREATOR_ILL_41;D41 -ICCPROFCREATOR_ILL_50;D50 -ICCPROFCREATOR_ILL_55;D55 -ICCPROFCREATOR_ILL_60;D60 -ICCPROFCREATOR_ILL_65;D65 -ICCPROFCREATOR_ILL_80;D80 -ICCPROFCREATOR_ILL_DEF;Standaard -ICCPROFCREATOR_ILL_INC;StdA 2856K -ICCPROFCREATOR_ILL_TOOLTIP;U kunt alleen de illuminant instellen voor ICC v4-profielen. -ICCPROFCREATOR_PRIMARIES;Primaire kleuren: -ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 -ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 -ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) -ICCPROFCREATOR_PRIM_BEST;BestRGB -ICCPROFCREATOR_PRIM_BETA;BetaRGB -ICCPROFCREATOR_PRIM_BLUX;Blauw X -ICCPROFCREATOR_PRIM_BLUY;Blauw Y -ICCPROFCREATOR_PRIM_BRUCE;BruceRGB -ICCPROFCREATOR_PRIM_GREX;Groen X -ICCPROFCREATOR_PRIM_GREY;Groen Y -ICCPROFCREATOR_PRIM_PROPH;Prophoto -ICCPROFCREATOR_PRIM_REC2020;Rec2020 -ICCPROFCREATOR_PRIM_REDX;Rood X -ICCPROFCREATOR_PRIM_REDY;Rood Y -ICCPROFCREATOR_PRIM_SRGB;sRGB -ICCPROFCREATOR_PRIM_TOOLTIP;U kunt alleen aangepaste primaries voor ICC v4-profielen instellen. -ICCPROFCREATOR_PRIM_WIDEG;Wijd kleurenscala -ICCPROFCREATOR_PROF_V2;ICC v2 -ICCPROFCREATOR_PROF_V4;ICC v4 -ICCPROFCREATOR_SAVEDIALOG_TITLE;Bewaar ICC-profiel als... -ICCPROFCREATOR_SLOPE;Helling -ICCPROFCREATOR_TRC_PRESET;Toonresponscurve: -IPTCPANEL_CATEGORY;Categorie -IPTCPANEL_CATEGORYHINT;Het onderwerp van de afbeelding. -IPTCPANEL_CITY;Plaats -IPTCPANEL_CITYHINT;Plaats waar de afbeelding is genomen. -IPTCPANEL_COPYHINT;Kopieer IPTC-instellingen naar klembord -IPTCPANEL_COPYRIGHT;Copyright-melding -IPTCPANEL_COPYRIGHTHINT;Melding over de huidige copyright-houder van de afbeelding, bijvoorbeeld ©2008 Jane Doe. -IPTCPANEL_COUNTRY;Land -IPTCPANEL_COUNTRYHINT;Land waar de afbeelding is genomen. -IPTCPANEL_CREATOR;Maker -IPTCPANEL_CREATORHINT;Naam van de maker. -IPTCPANEL_CREATORJOBTITLE;Functie van de maker. -IPTCPANEL_CREATORJOBTITLEHINT;De functie van de maker. -IPTCPANEL_CREDIT;Credit -IPTCPANEL_CREDITHINT;Naam van de leverancier van de foto, niet noodzakelijkerwijs de eigenaar/maker (Credit) -IPTCPANEL_DATECREATED;Opnamedatum -IPTCPANEL_DATECREATEDHINT;Datum waarop de afbeelding is genomen. -IPTCPANEL_DESCRIPTION;Beschrijving -IPTCPANEL_DESCRIPTIONHINT;Bijschrift dat het wie, wat of waarom beschrijft van wat er gebeurt in de afbeelding. Dit kan inclusief de namen van de personen zijn en of hun rol in de actie die plaatsvindt in de afbeelding. -IPTCPANEL_DESCRIPTIONWRITER;Schrijver van de beschrijving. -IPTCPANEL_DESCRIPTIONWRITERHINT;De naam van de persoon die is betrokken bij het schrijven, wijzigen of corrigeren van de beschrijving van de afbeelding. -IPTCPANEL_EMBEDDED;Ingebed -IPTCPANEL_EMBEDDEDHINT;Keer terug naar IPTC-data die in de foto zijn opgeslagen -IPTCPANEL_HEADLINE;Titel -IPTCPANEL_HEADLINEHINT;Een korte samenvatting van de inhoud van de afbeelding. -IPTCPANEL_INSTRUCTIONS;Instructies -IPTCPANEL_INSTRUCTIONSHINT;Infomatie over embargo of andere beperkingen die buiten het Copyright vallen. -IPTCPANEL_KEYWORDS;Sleutelwoorden -IPTCPANEL_KEYWORDSHINT;Gebruik steekwoorden of zinnen om het onderwerp van de afbeelding te beschrijven. -IPTCPANEL_PASTEHINT;Plak IPTC-instellingen van klembord -IPTCPANEL_PROVINCE;Provincie -IPTCPANEL_PROVINCEHINT;Provincie waar de afbeelding is genomen. -IPTCPANEL_RESET;Standaardwaarden -IPTCPANEL_RESETHINT;Terug naar standaardwaarden -IPTCPANEL_SOURCE;Bron -IPTCPANEL_SOURCEHINT;De naam van de persoon of de partij die verantwoordelijk is voor de verspreiding van de afbeelding, zoals de persoon of partij van wie de afbeelding afkomstig is. -IPTCPANEL_SUPPCATEGORIES;Aanvullende categorieën. -IPTCPANEL_SUPPCATEGORIESHINT;Verfijnt het onderwerp van de afbeelding. -IPTCPANEL_TITLE;Titel -IPTCPANEL_TITLEHINT;De korte naam van de afbeelding. Dit kan de bestandsnaam zijn. -IPTCPANEL_TRANSREFERENCE;Referentienummer -IPTCPANEL_TRANSREFERENCEHINT;Het nummer dat wordt gebruikt voor de 'workflow control' of voor de tracking. -MAIN_BUTTON_FULLSCREEN;Volledig scherm -MAIN_BUTTON_ICCPROFCREATOR;ICC Profielmaker -MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 -MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 -MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Fotobewerker om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB. De miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) -MAIN_BUTTON_PREFERENCES;Voorkeuren -MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij.\nSneltoets: Ctrl+B -MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto.\nSneltoets: Ctrl+S -MAIN_BUTTON_SENDTOEDITOR;Bewerk afbeelding in externe fotobewerker -MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma.\nSneltoets: Ctrl+E -MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: M -MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm -MAIN_FRAME_EDITOR;Fotobewerker -MAIN_FRAME_EDITOR_TOOLTIP; Bewerking.\nSneltoets: Ctrl+F4 -MAIN_FRAME_FILEBROWSER;Bestandsnavigator -MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator.\nSneltoets: Ctrl+F2 -MAIN_FRAME_PLACES;Locaties -MAIN_FRAME_PLACES_ADD;Nieuw -MAIN_FRAME_PLACES_DEL;Verwijderen -MAIN_FRAME_QUEUE;Verwerkingsrij -MAIN_FRAME_QUEUE_TOOLTIP; Verwerkingsrij.\nSneltoets: Ctrl+F3 -MAIN_FRAME_RECENT;Recente mappen -MAIN_MSG_ALREADYEXISTS;Bestand bestaat al -MAIN_MSG_CANNOTLOAD;Fout bij laden -MAIN_MSG_CANNOTSAVE;Fout bij opslaan van de afbeelding -MAIN_MSG_CANNOTSTARTEDITOR;Kan fotoprogramma niet starten. -MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Geef juiste pad op in 'Voorkeuren'. -MAIN_MSG_EMPTYFILENAME;Geen bestandsnaam opgegeven! -MAIN_MSG_IMAGEUNPROCESSED;Deze opdracht vereist dat alle geselecteerde foto's eerst moeten zijn verwerkt. -MAIN_MSG_NAVIGATOR;Navigator -MAIN_MSG_OPERATIONCANCELLED;Opdracht afgebroken -MAIN_MSG_PATHDOESNTEXIST;Het pad\n\n%1\n\nbestaat niet. Geef een correct pad op in Voorkeuren. -MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? -MAIN_MSG_SETPATHFIRST;Specificeer eerst een doelmap in Voorkeuren\nom deze functionaliteit te kunnen gebruiken! -MAIN_MSG_TOOMANYOPENEDITORS;Teveel open fotobewerkers.\nSluit er een om verder te kunnen. -MAIN_MSG_WRITEFAILED;Niet opgeslagen\n\n"%1"\n\nControleer of de map bestaat en dat u schrijfrechten heeft. -MAIN_TAB_ADVANCED;Geavanceerd -MAIN_TAB_ADVANCED_TOOLTIP;Sneltoets: Alt+A -MAIN_TAB_COLOR;Kleur -MAIN_TAB_COLOR_TOOLTIP;Sneltoets: Alt+C -MAIN_TAB_DETAIL;Detail -MAIN_TAB_DETAIL_TOOLTIP;Sneltoets: Alt+D -MAIN_TAB_DEVELOP;Ontwikkel -MAIN_TAB_EXIF;Exif -MAIN_TAB_EXPORT; Exporteren -MAIN_TAB_EXPOSURE;Belichting -MAIN_TAB_EXPOSURE_TOOLTIP;Sneltoets: Alt+E -MAIN_TAB_FAVORITES;Favorieten -MAIN_TAB_FAVORITES_TOOLTIP;Sneltoets: Alt+U -MAIN_TAB_FILTER;Filter -MAIN_TAB_INSPECT; Inspecteer -MAIN_TAB_IPTC;IPTC -MAIN_TAB_METADATA;Metadata -MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt+M -MAIN_TAB_RAW;RAW -MAIN_TAB_RAW_TOOLTIP;Sneltoets: Alt+R -MAIN_TAB_TRANSFORM;Transformeer -MAIN_TAB_TRANSFORM_TOOLTIP;Sneltoets: Alt+T -MAIN_TOOLTIP_BACKCOLOR0;Achtergrond kleur van het voorbeeld: Gebaseerd op thema\nSneltoets: 8 -MAIN_TOOLTIP_BACKCOLOR1;Achtergrond kleur van het voorbeeld: Zwart\nSneltoets: 9 -MAIN_TOOLTIP_BACKCOLOR2;Achtergrond kleur van het voorbeeld: Wit\nSneltoets: 0 -MAIN_TOOLTIP_BACKCOLOR3;Achtergrondkleur van het voorbeeld: Middelgrijs\nSneltoets: 9 -MAIN_TOOLTIP_BEFOREAFTERLOCK;Vergrendel/Ontgrendel de Voorafbeelding.\n\nVergrendeld: 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\nOntgrendeld: de Voorafbeelding volgt een stap achter de Naafbeelding en laat de afbeelding zien zonder het effect van het huidige gereedschap. -MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis).\nSneltoets: H -MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: > -MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: < -MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: B -MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focusmasker.\nSneltoets: Shift+F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focusmasker aanstaat. -MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: G -MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSneltoets: V\n\n0.299*R + 0.587*G + 0.114*B -MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSneltoets: R -MAIN_TOOLTIP_PREVIEWSHARPMASK;Bekijk het Scherptecontrastmasker.\nSneltoets: P\nWerkt alleen als verscherping is geactiveerd en het zoomniveau >= 100%. -MAIN_TOOLTIP_QINFO;Beknopte fotogegevens -MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel.\nSneltoets: L -MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt+L -MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift+L -MAIN_TOOLTIP_THRESHOLD;Drempel -MAIN_TOOLTIP_TOGGLE;Vergelijk origineel en bewerking -MONITOR_PROFILE_SYSTEM;Systeem standaardwaarde -NAVIGATOR_B;B: -NAVIGATOR_G;G: -NAVIGATOR_H;H: -NAVIGATOR_LAB_A;a*: -NAVIGATOR_LAB_B;b*: -NAVIGATOR_LAB_L;L*: -NAVIGATOR_NA; -- -NAVIGATOR_R;R: -NAVIGATOR_S;S: -NAVIGATOR_V;V: -NAVIGATOR_XY_FULL;Breedte: %1, Hoogte: %2 -NAVIGATOR_XY_NA;x: --, y: -- -OPTIONS_BUNDLED_MISSING;Het gebundelde profiel "%1" werd niet gevonden!\n\nUw installatie kan beschadigd zijn.\n\nDaarom worden interne standaardwaarden gebruikt. -OPTIONS_DEFIMG_MISSING;Het standaardprofiel voor niet-RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. -OPTIONS_DEFRAW_MISSING;Het standaardprofiel voor RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. -PARTIALPASTE_ADVANCEDGROUP;Geavanceerd -PARTIALPASTE_BASICGROUP;Basisinstellingen -PARTIALPASTE_CACORRECTION;C/A-correctie -PARTIALPASTE_CHANNELMIXER;Kleurkanaalmixer -PARTIALPASTE_CHANNELMIXERBW;Zwart-wit -PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen -PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 -PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen -PARTIALPASTE_COLORTONING;Kleurtinten -PARTIALPASTE_COMMONTRANSFORMPARAMS;Automatisch uitvullen -PARTIALPASTE_COMPOSITIONGROUP;Compositie-instellingen -PARTIALPASTE_CROP;Bijsnijden -PARTIALPASTE_DARKFRAMEAUTOSELECT;Donkerframe autom. selectie -PARTIALPASTE_DARKFRAMEFILE;Donkerframe-opname -PARTIALPASTE_DEFRINGE;Verzachten -PARTIALPASTE_DEHAZE;Ontnevelen -PARTIALPASTE_DETAILGROUP;Detailinstellingen -PARTIALPASTE_DIALOGLABEL;Profiel gedeeltelijk plakken... -PARTIALPASTE_DIRPYRDENOISE;Ruisonderdrukking -PARTIALPASTE_DIRPYREQUALIZER;Detailcontrast -PARTIALPASTE_DISTORTION;Corrigeer lensvervorming -PARTIALPASTE_EPD;Toonmappen -PARTIALPASTE_EQUALIZER;Wavelet Balans -PARTIALPASTE_EVERYTHING;Alles -PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens -PARTIALPASTE_EXPOSURE;Belichting -PARTIALPASTE_FILMNEGATIVE;Filmnegatief -PARTIALPASTE_FILMSIMULATION;Filmsimulatie -PARTIALPASTE_FLATFIELDAUTOSELECT;Vlakveld autoselectie -PARTIALPASTE_FLATFIELDBLURRADIUS;Vlakveld verzachting straal -PARTIALPASTE_FLATFIELDBLURTYPE;Vlakveld verzachting type -PARTIALPASTE_FLATFIELDCLIPCONTROL;Vlakveld afkapcontrole -PARTIALPASTE_FLATFIELDFILE;Vlakveldopname -PARTIALPASTE_GRADIENT;Grijsverloopfilter -PARTIALPASTE_HSVEQUALIZER;HSV-balans -PARTIALPASTE_ICMSETTINGS;ICM-instellingen -PARTIALPASTE_IMPULSEDENOISE;Spot-ruisonderdrukking -PARTIALPASTE_IPTCINFO;IPTC-informatie -PARTIALPASTE_LABCURVE;LAB-curve -PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen -PARTIALPASTE_LENSPROFILE;Lenscorrectieprofiel -PARTIALPASTE_LOCALCONTRAST;Lokaal contrast -PARTIALPASTE_METADATA;Metadata modus -PARTIALPASTE_METAGROUP;Metadata -PARTIALPASTE_PCVIGNETTE;Vignetteringsfilter -PARTIALPASTE_PERSPECTIVE;Perspectief -PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dodepixels-filter -PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans -PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hetepixels-filter -PARTIALPASTE_PREPROCESS_LINEDENOISE;Lijnruisfilter -PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter -PARTIALPASTE_PRSHARPENING;Verscherp na verkleinen -PARTIALPASTE_RAWCACORR_AUTO;Autom. C/A-correctie -PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA vermijd kleurverschuiving -PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rood & blauw -PARTIALPASTE_RAWEXPOS_BLACK;Zwartniveau -PARTIALPASTE_RAWEXPOS_LINEAR;Raw witpunt- lineaire corr. factor -PARTIALPASTE_RAWGROUP;Raw-instellingen -PARTIALPASTE_RAW_BORDER;Raw rand -PARTIALPASTE_RAW_DCBENHANCE;Pas DCB-verbetering toe -PARTIALPASTE_RAW_DCBITERATIONS;aantal DCB-herhalingen -PARTIALPASTE_RAW_DMETHOD;Demozaïekmethode -PARTIALPASTE_RAW_FALSECOLOR;Demozaïek stapgrootte kleurfoutonderdrukking -PARTIALPASTE_RAW_IMAGENUM;Sub-afbeelding -PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE-verbetering -PARTIALPASTE_RAW_PIXELSHIFT;Pixelverschuiving -PARTIALPASTE_RESIZE;Wijzig grootte -PARTIALPASTE_RETINEX;Retinex -PARTIALPASTE_RGBCURVES;RGB-curven -PARTIALPASTE_ROTATION;Roteren -PARTIALPASTE_SHADOWSHIGHLIGHTS;Schaduwen/hoge lichten -PARTIALPASTE_SHARPENEDGE;Randen -PARTIALPASTE_SHARPENING;Verscherping -PARTIALPASTE_SHARPENMICRO;Microcontrast -PARTIALPASTE_SOFTLIGHT;Zacht licht -PARTIALPASTE_TM_FATTAL;Compressie dynamisch bereik -PARTIALPASTE_VIBRANCE;Levendigheid -PARTIALPASTE_VIGNETTING;Vignetteringscorrectie -PARTIALPASTE_WHITEBALANCE;Witbalans -PREFERENCES_ADD;Toevoegen -PREFERENCES_APPEARANCE;Uiterlijk -PREFERENCES_APPEARANCE_COLORPICKERFONT;Lettertype kleurenkiezer -PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kleur bijsnijmasker -PREFERENCES_APPEARANCE_MAINFONT;Standaard lettertype -PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator randkleur -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI modus -PREFERENCES_APPEARANCE_THEME;Thema -PREFERENCES_APPLNEXTSTARTUP;herstart vereist -PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingssysteem -PREFERENCES_AUTOSAVE_TP_OPEN;Bewaar positie gereedschappen (open/dicht) bij afsluiten -PREFERENCES_BATCH_PROCESSING;Groepsverwerking -PREFERENCES_BEHADDALL;Alles op 'Toevoegen' -PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen-modus.\nWijzigingen van de parameters voor groepsverwerking zijn deltas op de opgeslagen waarden. -PREFERENCES_BEHAVIOR;Gedrag -PREFERENCES_BEHSETALL;Alles op 'Activeer' -PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer-modus.\nWijzigingen van de parameters voor groepsverwerking zijn absoluut. De actuele waarden worden gebruikt. -PREFERENCES_CACHECLEAR;Wissen -PREFERENCES_CACHECLEAR_ALL;Wis alle bestanden in de cache: -PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Wis alle bestanden in de cache behalve verwerkingsprofielen: -PREFERENCES_CACHECLEAR_ONLYPROFILES;Wis alleen verwerkingsprofielen in de cache: -PREFERENCES_CACHECLEAR_SAFETY;Alleen bestanden in de cache worden gewist. Verwerkingsprofielen van de oorspronkelijke afbeeldingen blijven ongemoeid. -PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in de cache -PREFERENCES_CACHEOPTS;Cache-opties -PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen -PREFERENCES_CHUNKSIZES;Tegels per thread -PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE-demozaïek -PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA-correctie -PREFERENCES_CHUNKSIZE_RAW_RCD;RCD-demozaïek -PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans-demozaïek -PREFERENCES_CHUNKSIZE_RGB;RGB-verwerking -PREFERENCES_CLIPPINGIND;Indicatie over-/onderbelichting -PREFERENCES_CLUTSCACHE;HaldCLUT-cache -PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cluts in de cache -PREFERENCES_CLUTSDIR;HaldCLUT-map -PREFERENCES_CMMBPC;Zwartpuntcompensatie -PREFERENCES_CROP;Uitsnijden -PREFERENCES_CROP_AUTO_FIT;Automatisch zoomen tot de uitsnede -PREFERENCES_CROP_GUIDES;Getoonde hulplijnen als uitsnede niet bewerkt wordt -PREFERENCES_CROP_GUIDES_FRAME;Frame -PREFERENCES_CROP_GUIDES_FULL;Origineel -PREFERENCES_CROP_GUIDES_NONE;Geen -PREFERENCES_CURVEBBOXPOS;Positie kopieer/plak-knoppen bij Curves -PREFERENCES_CURVEBBOXPOS_ABOVE;Boven -PREFERENCES_CURVEBBOXPOS_BELOW;Beneden -PREFERENCES_CURVEBBOXPOS_LEFT;Links -PREFERENCES_CURVEBBOXPOS_RIGHT;Rechts -PREFERENCES_CUSTPROFBUILD;Eigen/externe profielgenerator -PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor een foto te maken.\nOntvangt terminalparameters voor het genereren van pp3's gebaseerd op regels:\n[Pad RAW/JPG] [Pad standaardprofiel] [f-getal] [belichting in sec] [brandpuntsafstand in mm] [ISO] [lens] [Camerafabrikant] [cameramodel]\n\n Let op: Indien een pad spaties bevat moeten er dubbele quotes om het pad worden gezet. -PREFERENCES_CUSTPROFBUILDKEYFORMAT;'Keys'-formaat -PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Naam -PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID -PREFERENCES_CUSTPROFBUILDPATH;Pad naar programma of script -PREFERENCES_DARKFRAMEFOUND;Gevonden -PREFERENCES_DARKFRAMESHOTS;foto's -PREFERENCES_DARKFRAMETEMPLATES;sjablonen -PREFERENCES_DATEFORMAT;Datumformaat -PREFERENCES_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is \n%d/%m/%y -PREFERENCES_DIRDARKFRAMES;Map met donkerframes -PREFERENCES_DIRECTORIES;Mappen -PREFERENCES_DIRHOME;Standaardmap -PREFERENCES_DIRLAST;Laatst bezochte map -PREFERENCES_DIROTHER;Anders -PREFERENCES_DIRSELECTDLG;Selecteer standaardmap bij opstarten... -PREFERENCES_DIRSOFTWARE;Installatiemap -PREFERENCES_EDITORCMDLINE;Aangepaste opdrachtregel -PREFERENCES_EDITORLAYOUT;Bewerkingsvenster -PREFERENCES_EXTERNALEDITOR;Externe editor -PREFERENCES_FBROWSEROPTS;Opties bestandsnavigator -PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compacte gereedschapsbalken in bestandsnavigator -PREFERENCES_FLATFIELDFOUND;Gevonden -PREFERENCES_FLATFIELDSDIR;Vlakveldmap -PREFERENCES_FLATFIELDSHOTS;foto's -PREFERENCES_FLATFIELDTEMPLATES;sjablonen -PREFERENCES_FORIMAGE;Voor niet-RAW-bestanden -PREFERENCES_FORRAW;Voor RAW-bestanden -PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Zelfde hoogte miniaturen in Bewerkingsvenster en Bestandsnavigator -PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Verschillende hoogtes voor miniaturen vereist meer verwerkingstijd wanneer je wisselt tussen Bewerkingsvenster en Bestandsnavigator -PREFERENCES_GIMPPATH;Installatiemap GIMP -PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in linkerpaneel -PREFERENCES_HISTOGRAM_TOOLTIP;Het werkprofiel wordt gebruikt voor het Hoofdhistogram en de Navigator. In alle andere gevallen wordt het gamma-gecorrigeerde uitvoerprofiel gebruikt. -PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting -PREFERENCES_ICCDIR;Map met ICC-profielen -PREFERENCES_IMPROCPARAMS;Standaardprofiel -PREFERENCES_INSPECT_LABEL;Inspecteer -PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum aantal afbeeldingen in de cache -PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Het maximum aantal afbeeldingen in de cache wanneer je in de Bestandsnavigator met de cursor over de miniaturen beweegt. Op computers met erg weinig RAM-geheugen (2 GB) moet deze waarde op 1 of 2 worden gezet. -PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie -PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie -PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie -PREFERENCES_INTENT_SATURATION;Verzadiging -PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Toon interne JPEG-miniatuur indien onbewerkt -PREFERENCES_LANG;Taal -PREFERENCES_LANGAUTODETECT;Gebruik taalinstellingen pc -PREFERENCES_MAXRECENTFOLDERS;Maximum aantal recente mappen -PREFERENCES_MENUGROUPEXTPROGS;Groepeer open met -PREFERENCES_MENUGROUPFILEOPERATIONS;Groepeer bestandsbewerkingen -PREFERENCES_MENUGROUPLABEL;Groepeer labelen -PREFERENCES_MENUGROUPPROFILEOPERATIONS;Groepeer profielbewerkingen -PREFERENCES_MENUGROUPRANK;Groepeer markering -PREFERENCES_MENUOPTIONS;Menu-opties -PREFERENCES_MONINTENT;Standaard weergave-intentie monitor -PREFERENCES_MONITOR;Monitor -PREFERENCES_MONPROFILE;Standaard kleurprofiel -PREFERENCES_MONPROFILE_WARNOSX;Als gevolg van beperkingen van macOS wordt alleen sRGB ondersteund. -PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster -PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor -PREFERENCES_NAVIGATIONFRAME;Navigatie -PREFERENCES_OVERLAY_FILENAMES;Toon bestandsnamen over miniaturen -PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Toon bestandsnaam over miniaturen in het Bewerkingsvenster -PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande uitvoerbestanden -PREFERENCES_PANFACTORLABEL;Factor -PREFERENCES_PARSEDEXT;Extensies (verwerkingsvolgorde) -PREFERENCES_PARSEDEXTADD;Voeg extensie toe -PREFERENCES_PARSEDEXTADDHINT;Geef nieuwe extensie op en druk op de knop om aan de lijst toe te voegen -PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst -PREFERENCES_PARSEDEXTDOWNHINT;Verplaats extensie naar beneden -PREFERENCES_PARSEDEXTUPHINT;Verplaats extensie naar boven -PREFERENCES_PERFORMANCE_MEASURE;Meting -PREFERENCES_PERFORMANCE_MEASURE_HINT;Log de verwerkingstijden in de console -PREFERENCES_PERFORMANCE_THREADS;Threads -PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximaal aantal threads voor ruisvermindering en Wavelet-niveaus (0 = automatisch) -PREFERENCES_PREVDEMO;Voorbeeld demozaïekmethode -PREFERENCES_PREVDEMO_FAST;Snel -PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: -PREFERENCES_PREVDEMO_SIDECAR;Gelijk aan PP3 -PREFERENCES_PRINTER;Printer (soft-proof) -PREFERENCES_PROFILEHANDLING;Verwerking profielen -PREFERENCES_PROFILELOADPR;Laadprioriteit profielen -PREFERENCES_PROFILEPRCACHE;Profiel in cache -PREFERENCES_PROFILEPRFILE;Profiel bij RAW-bestand -PREFERENCES_PROFILESAVEBOTH;Bewaar verwerkingsprofielen zowel in de cache als naast het invoerbestand -PREFERENCES_PROFILESAVECACHE;Bewaar profiel in cache -PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand -PREFERENCES_PROFILESAVELOCATION;Opslaglocatie profielen -PREFERENCES_PROFILE_NONE;Geen -PREFERENCES_PROPERTY;Eigenschap -PREFERENCES_PRTINTENT;Weergave-intentie -PREFERENCES_PRTPROFILE;Kleurprofiel -PREFERENCES_PSPATH;Installatiemap Adobe Photoshop -PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom% en pan-startpunt -PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Onthoud het zoompercentage en pan-startpunt van de huidige afbeelding als er een nieuwe afbeelding wordt geopend.\n\nDeze optie werkt alleen in Enkeltab-modus en wanneer "Demozaïekmethode van het voorbeeld <100% zoom" hetzelfde is als "Gelijk aan PP3". -PREFERENCES_SAVE_TP_OPEN_NOW;Bewaar open/dicht-status van de gereedschappen nu -PREFERENCES_SELECTLANG;Selecteer taal -PREFERENCES_SERIALIZE_TIFF_READ;TIFF-leesinstellingen -PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serieel lezen van TIFF-bestanden -PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Als een map veel ongecomprimeerde TIFF-bestanden bevat dan versnelt deze optie het aanmaken van de miniaturen. -PREFERENCES_SET;Activeer -PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info -PREFERENCES_SHOWDATETIME;Toon datum en tijd -PREFERENCES_SHOWEXPOSURECOMPENSATION;Toon belichtingscompensatie -PREFERENCES_SHOWFILMSTRIPTOOLBAR;Toon filmstrip werkbalk -PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting -PREFERENCES_SINGLETAB;Enkel-tab: foto's openen in zelfde tabvenster -PREFERENCES_SINGLETABVERTAB;Enkel-tab ('filmstrip') modus met verticale tabs -PREFERENCES_SND_HELP;Typ bestandsnaam (of niets: geen geluid).\nWindows: gebruik 'SystemDefault', 'SystemAsterisk', etc. voor systeemgeluiden.\nLinux: gebruik "complete", "window-attention" etc. voor systeemgeluiden -PREFERENCES_SND_LNGEDITPROCDONE;Bewerking klaar -PREFERENCES_SND_QUEUEDONE;Verwerkingsrij klaar -PREFERENCES_SND_THRESHOLDSECS;na seconden -PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten -PREFERENCES_TAB_BROWSER;Bestandsnavigator -PREFERENCES_TAB_COLORMGR;Kleurbeheer -PREFERENCES_TAB_DYNAMICPROFILE;Dynamische Profielregel -PREFERENCES_TAB_GENERAL;Algemeen -PREFERENCES_TAB_IMPROC;Beeldverwerking -PREFERENCES_TAB_PERFORMANCE;Prestaties -PREFERENCES_TAB_SOUND;Geluiden -PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Ingesloten JPEG-voorbeeld -PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Te tonen foto -PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrale raw-rendering -PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Ingesloten JPEG indien vol formaat, anders neutrale raw -PREFERENCES_TP_LABEL;Gereedschapspaneel: -PREFERENCES_TP_VSCROLLBAR;Verberg de schuifbalk van het gereedschapspaneel -PREFERENCES_USEBUNDLEDPROFILES;Gebruik gebundelde profielen -PREFERENCES_WORKFLOW;Layout -PROFILEPANEL_COPYPPASTE;Te kopiëren parameters -PROFILEPANEL_GLOBALPROFILES;Gebundelde profielen -PROFILEPANEL_LABEL;Profielen -PROFILEPANEL_LOADDLGLABEL;Kies profiel... -PROFILEPANEL_LOADPPASTE;Te laden parameters -PROFILEPANEL_MODE_TOOLTIP;Profiel aanvullen.\n\nKnop ingedrukt: gedeeltelijke profielen worden omgezet naar volledige profielen. De ontbrekende waarden worden vervangen door standaardwaarden.\n\nKnop neutraal: profielen worden toegepast zoals ze zijn, alleen de aanwezige waarden worden gewijzigd. -PROFILEPANEL_MYPROFILES;Mijn profielen -PROFILEPANEL_PASTEPPASTE;Te plakken parameters -PROFILEPANEL_PCUSTOM;Handmatig -PROFILEPANEL_PDYNAMIC;Dynamisch -PROFILEPANEL_PFILE;Uit bestand -PROFILEPANEL_PINTERNAL;Neutraal -PROFILEPANEL_PLASTSAVED;Laatst opgeslagen -PROFILEPANEL_SAVEDLGLABEL;Bewaar profiel... -PROFILEPANEL_SAVEPPASTE;Te bewaren parameters -PROFILEPANEL_TOOLTIPCOPY;Kopieer huidig profiel naar klembord -PROFILEPANEL_TOOLTIPLOAD;Laad profiel uit bestand -PROFILEPANEL_TOOLTIPPASTE;Plak profiel van klembord -PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel.\nCtrl+klik voor het selecteren van de instellingen voor opslaan. -PROGRESSBAR_DECODING;Decoderen... -PROGRESSBAR_GREENEQUIL;Groenbalancering... -PROGRESSBAR_HLREC;Reconstructie hoge lichten... -PROGRESSBAR_HOTDEADPIXELFILTER;Hete/dodepixels-filter... -PROGRESSBAR_LINEDENOISE;Lijnruisfilter... -PROGRESSBAR_LOADING;Afbeelding laden... -PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... -PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... -PROGRESSBAR_LOADJXL;Laden JXL-bestand... -PROGRESSBAR_LOADPNG;Laden PNG-bestand... -PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... -PROGRESSBAR_NOIMAGES;Geen afbeeldingen -PROGRESSBAR_PROCESSING;Foto verwerken... -PROGRESSBAR_PROCESSING_PROFILESAVED;Uitvoeren 'Profiel opslaan' -PROGRESSBAR_RAWCACORR;Raw CA-correctie... -PROGRESSBAR_READY;Gereed -PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... -PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... -PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... -PROGRESSBAR_SNAPSHOT_ADDED;Snapshot toegevoegd -PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in Bestandsnavigator -QINFO_FRAMECOUNT;%2 frames -QINFO_HDR;HDR / %2 frame(s) -QINFO_ISO;ISO -QINFO_NOEXIF;Exif-gegevens niet beschikbaar. -QINFO_PIXELSHIFT;Pixel-Shift / %2 frame(s) -QUEUE_AUTOSTART;Autostart -QUEUE_AUTOSTART_TOOLTIP;Start verwerking automatisch wanneer nieuwe foto arriveert -QUEUE_DESTFILENAME;Pad en bestandsnaam -QUEUE_FORMAT_TITLE;Bestandstype -QUEUE_LOCATION_FOLDER;Sla op in map -QUEUE_LOCATION_TEMPLATE;Gebruik sjabloon -QUEUE_LOCATION_TEMPLATE_TOOLTIP;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2024/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2024, %d2=foto, ...\n%p1=/home/tom/image/02-09-2024, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de waardering van de foto. Als de foto geen waardering heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f -QUEUE_LOCATION_TITLE;Uitvoerlocatie -QUEUE_STARTSTOP_TOOLTIP;Start of stop de verwerking van foto's in de rij.\n\nSneltoets: Ctrl+S -SAMPLEFORMAT_0;onbekend dataformaat -SAMPLEFORMAT_1;8-bit unsigned -SAMPLEFORMAT_2;16-bit unsigned -SAMPLEFORMAT_4;24-bit LogLuv -SAMPLEFORMAT_8;32-bit LogLuv -SAMPLEFORMAT_16;16-bit drijvendekomma -SAMPLEFORMAT_32;24-bit drijvendekomma -SAMPLEFORMAT_64;32-bit drijvendekomma -SAVEDLG_AUTOSUFFIX;Voeg automatisch ophogend nummer (-1, -2..) toe als bestand al bestaat -SAVEDLG_FILEFORMAT;Bestandstype -SAVEDLG_FILEFORMAT_FLOAT; drijvendekomma -SAVEDLG_FORCEFORMATOPTS;Forceer opties voor opslaan -SAVEDLG_JPEGQUAL;JPEG-kwaliteit -SAVEDLG_PUTTOQUEUE;Plaats in verwerkingsrij -SAVEDLG_PUTTOQUEUEHEAD;Plaats vooraan in verwerkingsrij -SAVEDLG_PUTTOQUEUETAIL;Plaats achteraan in verwerkingsrij -SAVEDLG_SAVEIMMEDIATELY;Bewaar meteen -SAVEDLG_SAVESPP;Bewaar afbeelding met profiel -SAVEDLG_SUBSAMP;Subsampling -SAVEDLG_SUBSAMP_1;Beste compressie -SAVEDLG_SUBSAMP_2;Gebalanceerd -SAVEDLG_SUBSAMP_3;Beste kwaliteit -SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en verticaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma-subsampling. -SAVEDLG_TIFFUNCOMPRESSED;Geen compressie -SAVEDLG_WARNFILENAME;Bestandsnaam wordt -SHCSELECTOR_TOOLTIP;Klik op de rechtermuisknop om\nde 3 knoppen te verschuiven -SOFTPROOF_GAMUTCHECK_TOOLTIP;Markeer pixels waarvan de kleuren buiten het kleurgamma vallen, relatief aan:\n- het printerprofiel, indien opgegeven en soft-proofing is ingeschakeld,\n- het uitvoerprofiel, indien geen printerprofiel is gekozen en soft-proofing is ingeschakeld,\n- het beeldschermprofiel, indien soft-proofing is uitgeschakeld. -SOFTPROOF_TOOLTIP;Soft-proofing simuleert hoe een foto wordt getoond:\n- als deze wordt afgedrukt, indien een printerprofiel is opgegeven in Voorkeuren > Kleurbeheer,\n- als de foto getoond wordt op een beeldscherm dat het huidige uitvoerprofiel gebruikt en een printerprofiel niet is opgegeven. -THRESHOLDSELECTOR_B;Onderkant -THRESHOLDSELECTOR_BL;Onderkant-links -THRESHOLDSELECTOR_BR;Onderkant-rechts -THRESHOLDSELECTOR_HINT;Houd de Shift-toets ingedrukt om individuele controlepunten te verschuiven. -THRESHOLDSELECTOR_T;Bovenkant -THRESHOLDSELECTOR_TL;Bovenkant-links -THRESHOLDSELECTOR_TR;Bovenkant-rechts -TOOLBAR_TOOLTIP_COLORPICKER;Vergrendelbare kleurkiezer\n\nKlik met de linkermuisknop in het voorbeeld om een kleurkiezer toe te voegen\nBeweeg het punt door de linkermuisknop ingedrukt te houden\nVerwijder de kleurkiezer met rechts-klik\nVerwijder alle kleurkiezers met Shift+rechtsklik\nMet een rechtermuisklik naast een kleurkiezer komt het selectiehandje terug. -TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: C -TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: H -TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtzetten/Kleine rotaties.\nSneltoets: S\n\nBepaal de verticale of horizontale as door een hulplijn over de afbeelding te trekken. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. -TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: W -TP_BWMIX_ALGO;Algoritme OYCPM -TP_BWMIX_ALGO_LI;Lineair -TP_BWMIX_ALGO_SP;Speciale effecten -TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire respons.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen. -TP_BWMIX_AUTOCH;Auto -TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur -TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM-modus. -TP_BWMIX_CHANNEL;Luminantiebalans -TP_BWMIX_CURVEEDITOR1;'Voor'-curve -TP_BWMIX_CURVEEDITOR2;'Na'-curve -TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tooncurve wordt toegepast na de zwart-witconversie. -TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tooncurve wordt toegepast voor de zwart-witconversie.\nHoud rekening met de kleurcomponenten. -TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminantie als functie van tint (L=f(T).\nPas op met extreme waarden, deze kunnen onregelmatigheden veroorzaken. -TP_BWMIX_FILTER;Filterkleur -TP_BWMIX_FILTER_BLUE;Blauw -TP_BWMIX_FILTER_BLUEGREEN;Blauw-Groen -TP_BWMIX_FILTER_GREEN;Groen -TP_BWMIX_FILTER_GREENYELLOW;Groen-Geel -TP_BWMIX_FILTER_NONE;Geen -TP_BWMIX_FILTER_PURPLE;Paars -TP_BWMIX_FILTER_RED;Rood -TP_BWMIX_FILTER_REDYELLOW;Rood-Geel -TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beïnvloeden de helderheid. Zo maakt een rood filter een blauwe lucht donkerder. -TP_BWMIX_FILTER_YELLOW;Geel -TP_BWMIX_GAMMA;Gammacorrectie -TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB-kanaal -TP_BWMIX_LABEL;Zwart-wit -TP_BWMIX_MET;Methode -TP_BWMIX_MET_CHANMIX;Kanaalmixer -TP_BWMIX_MET_DESAT;Desatureren -TP_BWMIX_MET_LUMEQUAL;Luminantie-equalizer -TP_BWMIX_MIXC;Kanalenmixer -TP_BWMIX_NEUTRAL;Terugzetten -TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totaal: %4%% -TP_BWMIX_RGBLABEL_HINT;RGB-omrekeningsfactoren. Hierin zijn alle gekozen opties verwerkt.\nTotaal toont de som van de uit te voeren RGB-factoren:\n- dit is altijd 100% in relatieve modus\n- groter (lichter) of kleiner (donkerder) dan 100% in absolute modus. -TP_BWMIX_RGB_TOOLTIP;Mix de RGB-kanalen. Gebruik Voorinstellingen voor aanwijzingen.\nNegatieve waarden kunnen onregelmatigheden veroorzaken. -TP_BWMIX_SETTING;Voorinstellingen -TP_BWMIX_SETTING_TOOLTIP;Verschillende voorinstellingen (film, landschap, etc.) of handmatige instellingen van de kanaalmixer. -TP_BWMIX_SET_HIGHCONTAST;Hoog contrast -TP_BWMIX_SET_HIGHSENSIT;Hoge gevoeligheid -TP_BWMIX_SET_HYPERPANCHRO;Hyperpanchromatisch -TP_BWMIX_SET_INFRARED;Infrarood -TP_BWMIX_SET_LANDSCAPE;Landschap -TP_BWMIX_SET_LOWSENSIT;Lage gevoeligheid -TP_BWMIX_SET_LUMINANCE;Luminantie -TP_BWMIX_SET_NORMCONTAST;Normaal contrast -TP_BWMIX_SET_ORTHOCHRO;Orthochromatisch -TP_BWMIX_SET_PANCHRO;Panchromatisch -TP_BWMIX_SET_PORTRAIT;Portret -TP_BWMIX_SET_RGBABS;RGB-absoluut -TP_BWMIX_SET_RGBREL;RGB-relatief -TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM-absoluut -TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM-relatief -TP_BWMIX_TCMODE_FILMLIKE;Z-W Filmachtig -TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadiging en Waarde mengen -TP_BWMIX_TCMODE_STANDARD;Z-W Standaard -TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen standaard -TP_BWMIX_VAL;L -TP_CACORRECTION_BLUE;Blauw -TP_CACORRECTION_LABEL;Corrigeer chromatische afwijking -TP_CACORRECTION_RED;Rood -TP_CBDL_AFT;Na zwart-wit -TP_CBDL_BEF;Voor zwart-wit -TP_CBDL_METHOD;Uitvoeren -TP_CBDL_METHOD_TOOLTIP;Kies of Detailcontrast moet worden uitgevoerd ná de zwart-witbewerking waardoor het werkt in L*a*b*, of vòòr de zwart-witbewerking waardoor het werkt in RGB -TP_CHMIXER_BLUE;Blauw -TP_CHMIXER_GREEN;Groen -TP_CHMIXER_LABEL;Kleurkanaalmixer -TP_CHMIXER_RED;Rood -TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen -TP_COARSETRAF_TOOLTIP_ROTLEFT;Roteer links.\n\nSneltoets:\n[ - Multitab-modus,\nAlt+[ - Enkeltab-modus. -TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. -TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen -TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminantie -TP_COLORAPP_ALGO;Algoritme -TP_COLORAPP_ALGO_ALL;Alle -TP_COLORAPP_ALGO_JC;Lichtheid + Chroma (JC) -TP_COLORAPP_ALGO_JS;Lichtheid + Verzadiging (JS) -TP_COLORAPP_ALGO_QM;Helderheid + Kleurrijkheid (QM) -TP_COLORAPP_ALGO_TOOLTIP;Keuze uit parameters -TP_COLORAPP_BADPIXSL;Hete/dode-pixelsfilter -TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0 = geen effect 1 = mediaan 2 = gaussiaans.\n\nDeze onregelmatigheden zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. -TP_COLORAPP_BRIGHT;Helderheid (Q) -TP_COLORAPP_BRIGHT_TOOLTIP;Helderheid in CIECAM02 is verschillend van Lab en RGB, hou rekening met de luminositeit van wit -TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Bij handmatige aanpassing worden waarden boven 65 aanbevolen. -TP_COLORAPP_CHROMA;Chroma (C) -TP_COLORAPP_CHROMA_M;Kleurrijkheid (M) -TP_COLORAPP_CHROMA_M_TOOLTIP;Kleurrijkheid in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CHROMA_S;Verzadiging (S) -TP_COLORAPP_CHROMA_S_TOOLTIP;Verzadiging in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CIECAT_DEGREE;Chromatische aanpassing Scène -TP_COLORAPP_CONTRAST;Contrast (J) -TP_COLORAPP_CONTRAST_Q;Contrast (Q) -TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CONTRAST_TOOLTIP;Contrast (J) in CIECAM02 is verschillend van Lab en RGB -TP_COLORAPP_CURVEEDITOR1;Tooncurve 1 -TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM-wijzigingen.\n\nHet histogram toont J,Q na toepassing van CIECAM, indien het selectievakje 'Toon CIECAM-uitvoer' is aangezet.\n(J,Q) worden niet getoond in het hoofdhistogram. \n\nZie voor de definitieve uitvoer het Histogrampaneel. -TP_COLORAPP_CURVEEDITOR2;Tooncurve 2 -TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings-tooncurve 2. -TP_COLORAPP_CURVEEDITOR3;Chroma-curve -TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. -TP_COLORAPP_DATACIE;CIECAM02 uitvoerhistogram in de curven -TP_COLORAPP_DATACIE_TOOLTIP;Indien aangevinkt tonen de histogrammen van de CIECAM02-curven bij benadering de waarden/reeksen voor J of Q, en C, S of M na de CIECAM02-aanpassingen.\nDit heeft geen invloed op het hoofdhistogram.\n\nIndien uitgevinkt tonen de histogrammen van de CIECAM02-curven de Lab-waarden zoals deze waren voor de CIECAM02-aanpassingen -TP_COLORAPP_FREE;Vrije temp + groen + CAT02 + [uitvoer] -TP_COLORAPP_GAMUT;Beperk kleurbereik (Lab) -TP_COLORAPP_HUE;Tint (h) -TP_COLORAPP_HUE_TOOLTIP;Tint (h) - hoek tussen 0° en 360° -TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 -TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen -TP_COLORAPP_LABEL_SCENE;Scène-omstandigheden -TP_COLORAPP_LABEL_VIEWING;Weergaveomstandigheden -TP_COLORAPP_LIGHT;Lichtheid (J) -TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB -TP_COLORAPP_MEANLUMINANCE;Gemiddelde luminantie (Yb%) -TP_COLORAPP_MODEL;Witpuntmodel -TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. -TP_COLORAPP_NEUTRAL;Terugzetten -TP_COLORAPP_NEUTRAL_TOOLTIP;Zet alle regelaars, vinkjes en curves terug naar hun standaardwaarde -TP_COLORAPP_RSTPRO;Bescherming huid- en rode tinten -TP_COLORAPP_RSTPRO_TOOLTIP;Bescherm huid- en rode tinten (schuifbalk en curven) -TP_COLORAPP_SURROUND;Omgeving -TP_COLORAPP_SURROUND_AVER;Gemiddeld -TP_COLORAPP_SURROUND_DARK;Donker -TP_COLORAPP_SURROUND_DIM;Gedimd -TP_COLORAPP_SURROUND_EXDARK;Duister -TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden. -TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid -TP_COLORAPP_TCMODE_CHROMA;Chroma -TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid -TP_COLORAPP_TCMODE_LABEL1;Curve modus 1 -TP_COLORAPP_TCMODE_LABEL2;Curve modus 2 -TP_COLORAPP_TCMODE_LABEL3;Curve chroma-modus -TP_COLORAPP_TCMODE_LIGHTNESS;Lichtheid -TP_COLORAPP_TCMODE_SATUR;Verzadiging -TP_COLORAPP_TEMP_TOOLTIP;Zet altijd Tint=1 om een lichtbron te selecteren.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 -TP_COLORAPP_TONECIE;Tonemappen met CIECAM -TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgevinkt zal het toonmappen plaatsvinden in Lab.\nIndien aangevinkt zal toonmappen gebruikmaken van CIECAM02.\nVoorwaarde is dat Tonemappen (Lab/CIECAM02) actief is. -TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m²) -TP_COLORAPP_WBCAM;WB [RT+CAT02] + [uitvoer] -TP_COLORAPP_WBRT;WB [RT] + [uitvoer] -TP_COLORTONING_AB;o C/L -TP_COLORTONING_AUTOSAT;Automatisch -TP_COLORTONING_BALANCE;Balans -TP_COLORTONING_BY;o C/L -TP_COLORTONING_CHROMAC;Dekking -TP_COLORTONING_COLOR;Kleur -TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma-dekking als functie van Luminantie oC=f(L) -TP_COLORTONING_HIGHLIGHT;Hoge lichten -TP_COLORTONING_HUE;Kleurtint -TP_COLORTONING_LAB;L*a*b*-menging -TP_COLORTONING_LABEL;Kleurtinten -TP_COLORTONING_LABGRID;L*a*b* kleurcorrectieraster -TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 -TP_COLORTONING_LABREGIONS;Kleurcorrectiegebieden -TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 -TP_COLORTONING_LABREGION_CHANNEL;Kanaal -TP_COLORTONING_LABREGION_CHANNEL_ALL;Alle -TP_COLORTONING_LABREGION_CHANNEL_B;Blauw -TP_COLORTONING_LABREGION_CHANNEL_G;Groen -TP_COLORTONING_LABREGION_CHANNEL_R;Rood -TP_COLORTONING_LABREGION_CHROMATICITYMASK;C -TP_COLORTONING_LABREGION_HUEMASK;H -TP_COLORTONING_LABREGION_LIGHTNESS;Helderheid (L) -TP_COLORTONING_LABREGION_LIGHTNESSMASK;L -TP_COLORTONING_LABREGION_LIST_TITLE;Correctie -TP_COLORTONING_LABREGION_MASK;Masker -TP_COLORTONING_LABREGION_MASKBLUR;Verzachtingsmasker -TP_COLORTONING_LABREGION_OFFSET;Verschuiving -TP_COLORTONING_LABREGION_POWER;Kracht -TP_COLORTONING_LABREGION_SATURATION;Verzadiging -TP_COLORTONING_LABREGION_SHOWMASK;Toon masker -TP_COLORTONING_LABREGION_SLOPE;Helling -TP_COLORTONING_LUMA;Luminantie -TP_COLORTONING_LUMAMODE;Behoud luminantie -TP_COLORTONING_LUMAMODE_TOOLTIP;Wanneer de kleur wijzigt (rood, groen, cyaan, blauw, etc.) blijft de luminatie van elke pixel behouden. -TP_COLORTONING_METHOD;Methode -TP_COLORTONING_METHOD_TOOLTIP;L*a*b*-menging, RGB-schuifbalken en RGB-curven gebruiken geïnterpoleerde kleurmenging.\nKleurbalans SMH en Verzadiging twee kleuren gebruiken directe kleuren.\nAlle methodes werken ook met zwart-wit. -TP_COLORTONING_MIDTONES;Middentonen -TP_COLORTONING_NEUTRAL;Terug naar beginstand -TP_COLORTONING_NEUTRAL_TOOLTIP;Zet alle waarden (schaduwen, middentonen, hoge lichten) terug naar hun standaardwaarden. -TP_COLORTONING_OPACITY;Dekking -TP_COLORTONING_RGBCURVES;RGB - Curven -TP_COLORTONING_RGBSLIDERS;RGB - Schuifbalken -TP_COLORTONING_SA;Bescherm verzadiging -TP_COLORTONING_SATURATEDOPACITY;Sterkte -TP_COLORTONING_SATURATIONTHRESHOLD;Drempel -TP_COLORTONING_SHADOWS;Schaduwen -TP_COLORTONING_SPLITCO;Schaduwen/Middentonen/Hoge lichten -TP_COLORTONING_SPLITCOCO;Kleurbalans SMH -TP_COLORTONING_SPLITLR;Verzadiging twee kleuren -TP_COLORTONING_STR;Sterkte -TP_COLORTONING_STRENGTH;Sterkte -TP_COLORTONING_TWO2;Speciaal chroma twee kleuren -TP_COLORTONING_TWOALL;Speciaal chroma -TP_COLORTONING_TWOBY;Speciaal a* en b* -TP_COLORTONING_TWOCOLOR_TOOLTIP;Standaard chroma:\nLineaire respons, a* = b*.\n\nSpeciaal chroma:\nLineaire respons, a* = b*, maar ontbonden - gebruik de diagonaal hieronder.\n\nSpeciaal a* en b*:\nLineair ontbonden respons met aparte curves voor a* en b*. Bedoeld voor speciale effecten.\n\nSpeciaal chroma twee kleuren: beter voorspelbaar. -TP_COLORTONING_TWOSTD;Standaard chroma -TP_CROP_FIXRATIO;Verhouding: -TP_CROP_GTDIAGONALS;Diagonaalmethode -TP_CROP_GTEPASSPORT;Biometrisch paspoort -TP_CROP_GTFRAME;Frame -TP_CROP_GTGRID;Raster -TP_CROP_GTHARMMEANS;Gulden snede -TP_CROP_GTNONE;Geen -TP_CROP_GTRULETHIRDS;Regel van derden -TP_CROP_GTTRIANGLE1;Gouden Driehoek 1 -TP_CROP_GTTRIANGLE2;Gouden Driehoek 2 -TP_CROP_GUIDETYPE;Hulplijnen: -TP_CROP_H;Hoogte -TP_CROP_LABEL;Bijsnijden -TP_CROP_PPI;PPI -TP_CROP_RESETCROP;Terugzetten -TP_CROP_SELECTCROP;Selecteer -TP_CROP_W;Breedte -TP_CROP_X;X -TP_CROP_Y;Y -TP_DARKFRAME_AUTOSELECT;Automatische selectie -TP_DARKFRAME_LABEL;Donkerframe -TP_DEFRINGE_LABEL;Verzachten (Lab/CIECAM02) -TP_DEFRINGE_RADIUS;Straal -TP_DEFRINGE_THRESHOLD;Drempel -TP_DEHAZE_DEPTH;Diepte -TP_DEHAZE_LABEL;Nevelvermindering -TP_DEHAZE_SHOW_DEPTH_MAP;Toon dieptemap -TP_DEHAZE_STRENGTH;Sterkte -TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zone -TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatisch algemeen -TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Chrominantie Blauw & Geel -TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Chrominantie-curve -TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Verhoog (vermenigvuldig) de waarde van alle chrominantieschuiven.\nDeze curve regelt de sterkte van de chromatische ruisvermindering als een functie van de chromaticiteit, om bijvoorbeeld het effect te verhogen in gebieden met weinig verzadiging en te verlagen in gebieden met veel verzadiging. -TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominantie -TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Handmatig -TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Chrominantie (master) -TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Auto-methode -TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nVoorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. -TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de Voorbeeld-methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma-ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. -TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Voorbeeld multi-zone -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Voorbeeld -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Toont de overgebleven ruisniveaus van het zichtbare deel van de afbeelding in het voorbeeld na Wavelet.\n\n>300 Veel ruis\n100-300 Gemiddelde ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB- en L*a*b*-modus. De RGB-waarden zijn minder accuraat omdat de RGB-modus luminantie en chrominantie niet volledig scheidt. -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Voorbeeld grootte=%1, Centrum: Px=%2 Py=%3 -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Voorbeeld ruis: Gemiddeld=%1 Hoog=%2 -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Voorbeeld ruis: Gemiddeld= - Hoog= - -TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Tegelgrootte=%1, Centrum: Tx=%2 Ty=%3 -TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Chrominantie Rood & Groen -TP_DIRPYRDENOISE_LABEL;Ruisvermindering -TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Type gereedschap -TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminantie-curve -TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminantie-detail -TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminantie -TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminantie -TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compenseer lichtheid -TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Wijzig de kracht van de ruisvermindering gebaseerd op de lichtheid van de afbeelding. De kracht wordt minder bij donkere beelden en meer bij heldere beelden. -TP_DIRPYRDENOISE_MAIN_COLORSPACE;Kleurruimte -TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* -TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB -TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Voor RAW-afbeeldingen kan de RGB- of Lab-methode worden gebruikt.\n\nVoor niet-RAW-afbeeldingen zal altijd de Lab-methode worden gebruikt, ongeacht de geselecteerde methode. -TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma -TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten. -TP_DIRPYRDENOISE_MAIN_MODE;Kwaliteit -TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Hoog -TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Standaard -TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;De kwaliteit kan worden aangepast aan de hoeveelheid ruis. \nHoog verbetert de ruisonderdrukking, maar verlengt de verwerkingstijd -TP_DIRPYRDENOISE_MEDIAN_METHOD;Methode -TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Alleen Chroma -TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* -TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Mediaan-filter -TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Alleen Luminantie -TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB -TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;De Alleen Luminantie- en L*a*b*-methodes worden meteen na de Wavelet-stap uitgevoerd bij het onderdrukken van ruis.\nDe RGB-methode wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. -TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Gewogen L* (weinig) + a*b* (normaal) -TP_DIRPYRDENOISE_MEDIAN_PASSES;Mediaan-herhalingen -TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Het gebruik van drie mediaanfilter-herhalingen met een 3×3 venstergrootte geeft meestal een beter resultaat dan het gebruik van één mediaanfilter-herhaling met een 7×7 venstergrootte. -TP_DIRPYRDENOISE_MEDIAN_TYPE;Type -TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Gebruik een mediaanfilter van gewenste venstergrootte. Hoe groter het venster hoe langer het duurt.\n\n3×3 zacht: behandelt 5 pixels in een 3×3 pixelvenster.\n3×3: behandelt 9 pixels in een 3×3 pixelvenster.\n5×5 zacht: behandelt 13 pixels in een 5×5 pixelvenster.\n5×5: behandelt 25 pixels in een 5×5 pixelvenster.\n7×7: behandelt 49 pixels in een 7×7 pixelvenster.\n9×9: behandelt 81 pixels in een 9×9 pixelvenster.\n\nSoms is het mogelijk om een betere kwaliteit te krijgen door het uitvoeren van meerdere herhalingen met een kleiner venster dan één uitvoering met een groter venster. -TP_DIRPYRDENOISE_TYPE_3X3;3×3 -TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 zacht -TP_DIRPYRDENOISE_TYPE_5X5;5×5 -TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 zacht -TP_DIRPYRDENOISE_TYPE_7X7;7×7 -TP_DIRPYRDENOISE_TYPE_9X9;9×9 -TP_DIRPYREQUALIZER_ALGO;Huid-algoritme -TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de huidskleuren, minimaliseert de actie op andere kleuren\nGroot: vermijd onregelmatigheden -TP_DIRPYREQUALIZER_ARTIF;Verminder onregelmatigheden -TP_DIRPYREQUALIZER_HUESKIN;Huidtint -TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitiezone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigszins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. -TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) -TP_DIRPYREQUALIZER_LUMACOARSEST;grofste -TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;< Contrast -TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast > -TP_DIRPYREQUALIZER_LUMAFINEST;fijnste -TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutraal -TP_DIRPYREQUALIZER_SKIN;Huidtinten Wijzigen/Beschermen -TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Bij -100 worden huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd en alle andere tinten worden gewijzigd -TP_DIRPYREQUALIZER_THRESHOLD;Drempel -TP_DIRPYREQUALIZER_TOOLTIP;Probeer onregelmatigheden te verminderen die het gevolg zijn van een kleurverschuiving van de huidtinten (tint, chroma, luma) en de rest van de afbeelding -TP_DISTORTION_AMOUNT;Hoeveelheid -TP_DISTORTION_AUTO_TOOLTIP;Corrigeert automatisch lensafwijkingen in RAW-afbeeldingen op basis van de ingebedde JPEG indien deze is gecorrigeerd door de camera. -TP_DISTORTION_LABEL;Corrigeer lensvervorming -TP_EPD_EDGESTOPPING;Randen -TP_EPD_GAMMA;Gamma -TP_EPD_LABEL;Tonemapping (Lab/CIECAM02) -TP_EPD_REWEIGHTINGITERATES;Herhaling -TP_EPD_SCALE;Schaal -TP_EPD_STRENGTH;Sterkte -TP_EXPOSURE_AUTOLEVELS;Autom. niveaus -TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Activeer automatische niveaus\nActiveer Herstel Hoge lichten indien nodig. -TP_EXPOSURE_BLACKLEVEL;Schaduwen -TP_EXPOSURE_BRIGHTNESS;Helderheid -TP_EXPOSURE_CLAMPOOG;Kap kleuren die buiten het gamma vallen af -TP_EXPOSURE_CLIP;Afkap % -TP_EXPOSURE_CLIP_TOOLTIP;Het deel van de pixels dat moet worden hersteld bij gebruik van automatische niveaus. -TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten comprimeren -TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel compressie hoge lichten -TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie -TP_EXPOSURE_CONTRAST;Contrast -TP_EXPOSURE_CURVEEDITOR;Tooncurve -TP_EXPOSURE_CURVEEDITOR1;Tooncurve 1 -TP_EXPOSURE_CURVEEDITOR2;Tooncurve 2 -TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\n The Toolbox > Exposure Tab > Exposure Panel > Tone Curve -TP_EXPOSURE_EXPCOMP;Belichtingscompensatie -TP_EXPOSURE_HISTMATCHING;Automatische tooncurve -TP_EXPOSURE_HISTMATCHING_TOOLTIP;Pas automatisch de curves en schuifregelaars aan (behalve belichtingscompensatie) volgens de in de RAW ingebedde JPEG-afbeelding. -TP_EXPOSURE_LABEL;Belichting -TP_EXPOSURE_SATURATION;Verzadiging -TP_EXPOSURE_TCMODE_FILMLIKE;Filmachtig -TP_EXPOSURE_TCMODE_LABEL1;Curve modus 1 -TP_EXPOSURE_TCMODE_LABEL2;Curve modus 2 -TP_EXPOSURE_TCMODE_LUMINANCE;Luminantie -TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptueel -TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Verzadiging en Waarde mengen -TP_EXPOSURE_TCMODE_STANDARD;Standaard -TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen standaard -TP_EXPOS_BLACKPOINT_LABEL;Raw-zwartpunten -TP_EXPOS_WHITEPOINT_LABEL;Raw-witpunten -TP_FILMNEGATIVE_BLUE;Blauw-verhouding -TP_FILMNEGATIVE_GREEN;Referentie-exponent (contrast) -TP_FILMNEGATIVE_GUESS_TOOLTIP;Bepaal automatisch de rood/groen-verhouding door twee gebieden te kiezen met een neutrale tint (geen kleur) in het origineel. De gebieden moeten verschillen in helderheid. Kies de witbalans nadien. -TP_FILMNEGATIVE_LABEL;Filmnegatief -TP_FILMNEGATIVE_PICK;Kies neutrale punten -TP_FILMNEGATIVE_RED;Rood-verhouding -TP_FILMSIMULATION_LABEL;Filmsimulatie -TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee zoekt naar HaldCLUT-afbeeldingen om de Filmsimulatie uit te voeren, maar deze bevinden zich in een map die teveel tijd kost om te lezen.\n Kijk bij Voorkeuren > Beeldverwerking > Filmsimulatie om te zien welke map gebruikt wordt\nAanbevolen wordt om een map te gebruiken die alleen HaldCLUT-afbeeldingen bevat of kies een lege folder als u Filmsimulatie niet wilt gebruiken.\n\nMeer informatie is te vinden in het (Engelstalige) artikel over Filmsimulatie op RawPedia.\n\nWilt u de scan nu afbreken? -TP_FILMSIMULATION_STRENGTH;Sterkte -TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT-map in Voorkeuren -TP_FLATFIELD_AUTOSELECT;Automatische selectie -TP_FLATFIELD_BLURRADIUS;Verzachten: straal -TP_FLATFIELD_BLURTYPE;Verzachten: type -TP_FLATFIELD_BT_AREA;Gebied -TP_FLATFIELD_BT_HORIZONTAL;Horizontaal -TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. -TP_FLATFIELD_BT_VERTICAL;Verticaal -TP_FLATFIELD_CLIPCONTROL;Afkapcontrole -TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Afkapcontrole vermijdt uitgevreten hoge lichten veroorzaakt door het toepassen van een vlakveld. Als er al uitgevreten hoge lichten waren voor het toepassen van het vlakveld, dan kan afkapcontrole kleurzweem veroorzaken. -TP_FLATFIELD_LABEL;Vlakveld -TP_GENERAL_11SCALE_TOOLTIP;De werking is alleen zichtbaar op schaal 1:1 van het voorbeeld -TP_GRADIENT_CENTER;Centrum -TP_GRADIENT_CENTER_X;Centrum X -TP_GRADIENT_CENTER_X_TOOLTIP;Rotatiepunt X-as: \n-100=linkerkant \n0=centrum \n+100=rechterkant -TP_GRADIENT_CENTER_Y;Centrum Y -TP_GRADIENT_CENTER_Y_TOOLTIP;Rotatiepunt Y-as: \n-100=bovenkant \n0=centrum \n+100=onderkant -TP_GRADIENT_DEGREE;Hoek -TP_GRADIENT_DEGREE_TOOLTIP;Rotatiehoek in graden -TP_GRADIENT_FEATHER;Verloop -TP_GRADIENT_FEATHER_TOOLTIP;Verloop als percentage van de afbeeldingsdiagonaal -TP_GRADIENT_LABEL;Grijsverloopfilter -TP_GRADIENT_STRENGTH;Sterkte -TP_GRADIENT_STRENGTH_TOOLTIP;Filtersterkte in stops -TP_HLREC_BLEND;Mengen -TP_HLREC_CIELAB;CIELab-menging -TP_HLREC_COLOR;Kleurherstel -TP_HLREC_ENA_TOOLTIP;Kan worden geactiveerd door automatische niveaus -TP_HLREC_LABEL;Hoge lichten herstellen -TP_HLREC_LUMINANCE;Lichtherstel -TP_HLREC_METHOD;Methode: -TP_HSVEQUALIZER_CHANNEL;HSV-balans -TP_HSVEQUALIZER_HUE;Tint -TP_HSVEQUALIZER_LABEL;HSV-balans -TP_HSVEQUALIZER_SAT;Verzadiging -TP_HSVEQUALIZER_VAL;Waarde -TP_ICM_APPLYBASELINEEXPOSUREOFFSET;DCP-basisbelichting -TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebedde DCP-basisbelichting. De instelling is alleen actief als de DCP een basisbelichting heeft. -TP_ICM_APPLYHUESATMAP;DCP-basistabel -TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP-basistabel (HueSatMap). De instelling is alleen actief als de DCP een basistabel heeft. -TP_ICM_APPLYLOOKTABLE;DCP-look-tabel -TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP-look-tabel. De instelling is alleen actief als de DCP een look-tabel heeft. -TP_ICM_BPC;Zwartpuntcompensatie -TP_ICM_DCPILLUMINANT;Illuminant -TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren -TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. -TP_ICM_INPUTCAMERA;Camera standaard -TP_ICM_INPUTCAMERAICC;Camera-specifiek kleurprofiel -TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-invoerkleurprofielen. Deze zijn preciezer dan een eenvoudige matrix maar niet beschikbaar voor alle camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en /dccprofiles en worden automatisch geladen gebaseerd op een bestandsnaam die exact overeenkomt met de modelnaam van de camera. -TP_ICM_INPUTCAMERA_TOOLTIP;Gebruik een eenvoudige kleurenmatrix van dcraw, een uitgebreidere RawTherapee-versie (indien aanwezig voor het cameramodel), of gebruik het ingebedde profiel in de DNG. -TP_ICM_INPUTCUSTOM;Handmatig -TP_ICM_INPUTCUSTOM_TOOLTIP;Selecteer eigen DCP/ICC-kleurenprofiel voor uw camera. -TP_ICM_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... -TP_ICM_INPUTEMBEDDED;Gebruik ingebed profiel, indien mogelijk -TP_ICM_INPUTEMBEDDED_TOOLTIP;Gebruik ingebed profiel, indien mogelijk. -TP_ICM_INPUTNONE;Geen profiel -TP_ICM_INPUTNONE_TOOLTIP;Gebruik geen invoerprofiel. Alleen toepassen in speciale gevallen. -TP_ICM_INPUTPROFILE;Invoerprofiel -TP_ICM_LABEL;Kleurbeheer -TP_ICM_NOICM;Geen ICM: sRGB-uitvoer -TP_ICM_OUTPUTPROFILE;Uitvoerprofiel -TP_ICM_PROFILEINTENT;Weergave-intentie -TP_ICM_SAVEREFERENCE;Bewaar referentie-afbeelding -TP_ICM_SAVEREFERENCE_APPLYWB;Toepassen witbalans -TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Gebruik witbalans bij het opslaan van afbeeldingen voor het maken van ICC-profielen. Gebruik geen witbalans bij het maken van DCP-profielen. -TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF-afbeelding op voordat het invoerprofiel is toegepast. Het resultaat kan worden gebruikt voor kalibratie en het genereren van een cameraprofiel. -TP_ICM_TONECURVE;Gebruik DCP-tooncurve -TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP-tooncurve. De instelling is alleen actief als de geselecteerde DCP een tooncurve bevat. -TP_ICM_WORKINGPROFILE;Werkprofiel -TP_ICM_WORKING_TRC;Tooncurve: -TP_ICM_WORKING_TRC_CUSTOM;Door gebruiker gedefinieerd -TP_ICM_WORKING_TRC_GAMMA;Gamma -TP_ICM_WORKING_TRC_NONE;Geen -TP_ICM_WORKING_TRC_SLOPE;Helling -TP_ICM_WORKING_TRC_TOOLTIP;Enkel voor ingebouwde profielen. -TP_IMPULSEDENOISE_LABEL;Spot-ruisonderdrukking -TP_IMPULSEDENOISE_THRESH;Drempel -TP_LABCURVE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Plaats de kleuren in het bereik van de kleurruimte van het werkprofiel\nen pas Munsell-correctie toe -TP_LABCURVE_BRIGHTNESS;Helderheid -TP_LABCURVE_CHROMATICITY;Chromaticiteit -TP_LABCURVE_CHROMA_TOOLTIP;Voor zwartwit, zet Chromaticiteit op -100 -TP_LABCURVE_CONTRAST;Contrast -TP_LABCURVE_CURVEEDITOR;Luminantiecurve -TP_LABCURVE_CURVEEDITOR_A_RANGE1;Groen verzadigd -TP_LABCURVE_CURVEEDITOR_A_RANGE2;Groen pastel -TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rood pastel -TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rood verzadigd -TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blauw verzadigd -TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blauw pastel -TP_LABCURVE_CURVEEDITOR_B_RANGE3;Geel pastel -TP_LABCURVE_CURVEEDITOR_B_RANGE4;Geel verzadigd -TP_LABCURVE_CURVEEDITOR_CC;CC -TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutraal -TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Slap -TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel -TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Verzadigd -TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticiteit volgens Chromaticiteit C=f(C) -TP_LABCURVE_CURVEEDITOR_CH;CH -TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticiteit volgens Tint C=f(T) -TP_LABCURVE_CURVEEDITOR_CL;CL -TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticiteit volgens Luminantie C=f(L) -TP_LABCURVE_CURVEEDITOR_HH;HH -TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue volgens Tint H=f(T) -TP_LABCURVE_CURVEEDITOR_LC;LC -TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminantie volgens Chromaticiteit L=f(C) -TP_LABCURVE_CURVEEDITOR_LH;LH -TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens Tint L=f(H) -TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens Luminantie L=f(L) -TP_LABCURVE_LABEL;Lab -TP_LABCURVE_LCREDSK;Beperk LC tot huid- en rode tinten -TP_LABCURVE_LCREDSK_TOOLTIP;Indien ingeschakeld beïnvloedt de LC-curve alleen huid- en rode tinten.\nIndien uitgeschakeld is het van toepassing op alle tinten. -TP_LABCURVE_RSTPROTECTION;Bescherming huid- en rode tinten -TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits-schuifbalk en de CC-curve. -TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden -TP_LENSGEOM_FILL;Automatisch uitvullen -TP_LENSGEOM_LABEL;Objectief / Geometrie -TP_LENSGEOM_LIN;Lineair -TP_LENSGEOM_LOG;Logarithmisch -TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatische selectie -TP_LENSPROFILE_CORRECTION_LCPFILE;LCP-bestand -TP_LENSPROFILE_CORRECTION_MANUAL;Handmatige selectie -TP_LENSPROFILE_LABEL;Lenscorrectieprofielen -TP_LENSPROFILE_LENS_WARNING;Waarschuwing: de gebruikte bijsnijdfactor van het lensprofiel komt niet overeen met de bijsnijdfactor van de camera, de resultaten kunnen onjuist zijn. -TP_LENSPROFILE_MODE_HEADER;Lensprofiel -TP_LENSPROFILE_USE_CA;Chromatische afwijking -TP_LENSPROFILE_USE_GEOMETRIC;Geometrische vervorming -TP_LENSPROFILE_USE_HEADER;Lenscorrecties -TP_LENSPROFILE_USE_VIGNETTING;Vignettering -TP_LOCALCONTRAST_AMOUNT;Hoeveelheid -TP_LOCALCONTRAST_DARKNESS;Donkere delen -TP_LOCALCONTRAST_LABEL;Lokaal contrast -TP_LOCALCONTRAST_LIGHTNESS;Lichte delen -TP_LOCALCONTRAST_RADIUS;Straal -TP_METADATA_EDIT;Pas wijzigingen toe -TP_METADATA_MODE;Metadata kopieermodus -TP_METADATA_STRIP;Strip alle metadata -TP_METADATA_TUNNEL;Kopieer ongewijzigd -TP_NEUTRAL;Terugzetten -TP_NEUTRAL_TOOLTIP;Alle belichtingsinstellingen naar 0 -TP_PCVIGNETTE_FEATHER;Straal -TP_PCVIGNETTE_FEATHER_TOOLTIP;Straal: \n0=alleen hoeken \n50=halverwege tot het centrum \n100=tot aan het centrum -TP_PCVIGNETTE_LABEL;Vignetteringsfilter -TP_PCVIGNETTE_ROUNDNESS;Vorm -TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Vorm: \n0=rechthoek \n50=ellips \n100=circel -TP_PCVIGNETTE_STRENGTH;Sterkte -TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filtersterkte in stops (volledig in de hoeken). -TP_PDSHARPENING_LABEL;Verscherpen -TP_PERSPECTIVE_HORIZONTAL;Horizontaal -TP_PERSPECTIVE_LABEL;Perspectief -TP_PERSPECTIVE_VERTICAL;Verticaal -TP_PFCURVE_CURVEEDITOR_CH;Tint -TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Bepaalt de mate van verzachten per kleur. Hoger = meer, lager = minder. -TP_PREPROCESS_DEADPIXFILT;Dodepixels-filter -TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Onderdrukt dode pixels. -TP_PREPROCESS_GREENEQUIL;Groenbalans -TP_PREPROCESS_HOTPIXFILT;Hetepixels-filter -TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Onderdrukt hete pixels. -TP_PREPROCESS_LABEL;Voorbewerking -TP_PREPROCESS_LINEDENOISE;Lijnruisfilter -TP_PREPROCESS_LINEDENOISE_DIRECTION;Richting -TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Beide -TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontaal -TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontaal enkel op PDAF-rijen -TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Verticaal -TP_PREPROCESS_NO_FOUND;Niet gevonden -TP_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter -TP_PRSHARPENING_LABEL;Verscherp na verkleinen -TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen actief is en de methode 'Lanczos' is. Omdat verkleinen geen effect heeft op het voorbeeld, heeft 'post-verkleinen verscherping' ook geen effect op het voorbeeld. -TP_RAWCACORR_AUTO;Automatische CA-correctie -TP_RAWCACORR_AUTOIT;Herhalingen -TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische afwijkingen.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. -TP_RAWCACORR_AVOIDCOLORSHIFT;Vermijd kleurverschuiving -TP_RAWCACORR_CABLUE;Blauw -TP_RAWCACORR_CARED;Rood -TP_RAWCACORR_LABEL;Corrigeer chromatische afwijking -TP_RAWEXPOS_BLACK_0;Groen 1 (leidend) -TP_RAWEXPOS_BLACK_1;Rood -TP_RAWEXPOS_BLACK_2;Blauw -TP_RAWEXPOS_BLACK_3;Groen 2 -TP_RAWEXPOS_BLACK_BLUE;Blauw -TP_RAWEXPOS_BLACK_GREEN;Groen -TP_RAWEXPOS_BLACK_RED;Rood -TP_RAWEXPOS_LINEAR;Witpuntcorrectie -TP_RAWEXPOS_RGB;Rood, Groen, Blauw -TP_RAWEXPOS_TWOGREEN;Koppel Groen 1 en 2 -TP_RAW_1PASSMEDIUM;1 keer (Markesteijn) -TP_RAW_2PASS;1-gang+snel -TP_RAW_3PASSBEST;3 gangen (Markesteijn) -TP_RAW_4PASS;3-gangen+snel -TP_RAW_AHD;AHD -TP_RAW_AMAZE;AMaZE -TP_RAW_AMAZEVNG4;AMaZE+VNG4 -TP_RAW_BORDER;Rand -TP_RAW_DCB;DCB -TP_RAW_DCBENHANCE;DCB-verbetering -TP_RAW_DCBITERATIONS;Aantal DCB-herhalingen -TP_RAW_DCBVNG4;DCB+VNG4 -TP_RAW_DMETHOD;Methode -TP_RAW_DMETHOD_PROGRESSBAR;%1 Demozaïeken... -TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demozaïekverfijning... -TP_RAW_DMETHOD_TOOLTIP;IGV en LMMSE zijn speciaal bedoeld voor afbeeldingen met hoge ISO-waarden -TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto-drempel -TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Als checkbox is aangevinkt (aanbevolen), berekent RT een optimale waarde gebaseerd op vlakke gebieden in de foto.\nIndien die niet gevonden worden of de foto veel ruis bevat, wordt de waarde op 0 gezet.\nOm de waarde handmatig in te voeren moet u eerst de checkbox uitvinken (redelijke waarden zijn afhankelijk van het soort foto). -TP_RAW_DUALDEMOSAICCONTRAST;Contrastdrempel -TP_RAW_EAHD;EAHD -TP_RAW_FALSECOLOR;Stapgrootte kleurfoutonderdrukking -TP_RAW_FAST;Snel -TP_RAW_HD;Drempel -TP_RAW_HD_TOOLTIP;Lagere waarden maken hete/dodepixel-detectie agressiever, maar valse positieven kunnen leiden tot meer onregelmatigheden. Als er onregelmatigheden verschijnen bij het gebruik van de hete/dodepixel-filters, verminder dan geleidelijk de drempelwaarde tot ze verdwijnen. -TP_RAW_HPHD;HPHD -TP_RAW_IGV;IGV -TP_RAW_IMAGENUM;Sub-afbeelding -TP_RAW_IMAGENUM_SN;SN-modus -TP_RAW_IMAGENUM_TOOLTIP;Sommige RAW-bestanden bestaan uit verschillende sub-afbeeldingen (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\Als een andere demozaïekmethode dan Pixel Shift gebruikt wordt, selecteert deze de gebruikte sub-afbeelding.\n\nBij gebruik van de Pixel Shift demozaïekmethode op een Pixel Shift RAW worden alle sub-afbeeldingen gebruikt en dit selecteert de sub-afbeelding die gebruikt wordt voor bewegende gebieden. -TP_RAW_LABEL;Demozaïekproces -TP_RAW_LMMSE;LMMSE -TP_RAW_LMMSEITERATIONS;LMMSE-verbeterstappen -TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1), mediaan (stappen 2-4) en verfijnen (stappen 5-6) om onregelmatigheden te verwijderen en de signaal/ruis-ratio te verbeteren. -TP_RAW_MONO;Mono -TP_RAW_NONE;Geen (Toont sensorpatroon) -TP_RAW_PIXELSHIFT;Pixel Shift -TP_RAW_PIXELSHIFTBLUR;Vervaag bewegingsmasker -TP_RAW_PIXELSHIFTDMETHOD;Demozaïek voor beweging -TP_RAW_PIXELSHIFTEPERISO;Gevoeligheid -TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;De standaardwaarde 0 werkt goed voor lage ISO-waarden.\nHogere waarden vergroten de gevoeligheid van bewegingsdetectie.\nWijzig in kleine stappen en controleer het bewegingsmasker.\nVerhoog gevoeligheid voor onderbelichte foto's of foto's met hoge ISO-waarden. -TP_RAW_PIXELSHIFTEQUALBRIGHT;Balanceer de helderheid van de frames -TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Balanceer per kanaal -TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Ingeschakeld: balanceer elk RGB-kanaal afzonderlijk.\nUitgeschakeld: balanceer alle kanalen evenveel. -TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Balanceer de helderheid van de frames ten opzichte van de helderheid van het geselecteerde frame.\nAls er overbelichte gebieden zijn in de frames, selecteer dan het helderste frame om een magenta kleurzweem te vermijden of selecteer bewegingscorrectie. -TP_RAW_PIXELSHIFTGREEN;Controleer groene kanaal voor beweging -TP_RAW_PIXELSHIFTHOLEFILL;Vul holtes in verschuivingsmasker -TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Vul holtes in het verschuivingsmasker op -TP_RAW_PIXELSHIFTMEDIAN;Mediaan -TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Gebruik mediaan voor alle frames inplaats van alleen het geselecteerde frame voor gebieden met beweging.\nVerwijder objecten die voorkomen op verschillende plekken in alle frames.\nGeeft bewegingseffect voor langzaam bewegende (overlappende) objecten. -TP_RAW_PIXELSHIFTMM_AUTO;Automatisch -TP_RAW_PIXELSHIFTMM_CUSTOM;Eigen -TP_RAW_PIXELSHIFTMM_OFF;Uit -TP_RAW_PIXELSHIFTMOTION;Bewegingsdetectie-niveau (vervallen) -TP_RAW_PIXELSHIFTMOTIONMETHOD;Bewegingscorrectie -TP_RAW_PIXELSHIFTNONGREENCROSS;Controleer rood/blauw-kanaal voor beweging -TP_RAW_PIXELSHIFTSHOWMOTION;Toon beweging -TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Toon alleen masker -TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Toont het bewegingsmasker zonder de afbeelding -TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Toont de foto met een groen masker dat de bewegingsgebieden toont. -TP_RAW_PIXELSHIFTSIGMA;Vervagen straal -TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;De standaardstraal van 1,0 is goed voor normale ISO-waarden. Verhoog de waarde voor hogere ISO.\n5,0 is een goed startpunt voor afbeeldingen met hoge ISO-waarden.\nControleer het bewegingsmasker bij het veranderen van de waarde. -TP_RAW_PIXELSHIFTSMOOTH;Zachte overgang -TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Zachte overgang tussen gebieden met en zonder beweging.\nKies 0 om Zachte overgang uit te zetten\nKies 1 voor Amaze/lmmse of Mediaan -TP_RAW_RCD;RCD -TP_RAW_RCDVNG4;RCD+VNG4 -TP_RAW_SENSOR_BAYER_LABEL;Sensor met Bayer-matrix -TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-gang geeft het beste resultaat (aanbevolen voor lage ISO-waarden)\n1-gang geeft hetzelfde resultaat als 3-gang voor hoge ISO-afbeeldingen en is sneller. -TP_RAW_SENSOR_XTRANS_LABEL;Sensor met X-Transmatrix -TP_RAW_VNG4;VNG4 -TP_RAW_XTRANS;X-Trans -TP_RAW_XTRANSFAST;Snelle X-Trans -TP_RESIZE_ALLOW_UPSCALING;Sta opschalen toe -TP_RESIZE_APPLIESTO;Toepassen op: -TP_RESIZE_CROPPEDAREA;Uitsnede -TP_RESIZE_FITBOX;Breedte en hoogte -TP_RESIZE_FULLIMAGE;Hele foto -TP_RESIZE_H;H: -TP_RESIZE_HEIGHT;Hoogte -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_W;B: -TP_RESIZE_WIDTH;Breedte -TP_RETINEX_CONTEDIT_HSL;Histogrambalans HSL -TP_RETINEX_CONTEDIT_LAB;Histogrambalans L*a*b* -TP_RETINEX_CONTEDIT_LH;Tintbalans -TP_RETINEX_CONTEDIT_MAP;Equalizer -TP_RETINEX_CURVEEDITOR_CD;L=f(L) -TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminantie volgens luminantie L=f(L).\nCorrigeert ruwe data om halo's en onregelmatigheden te verminderen. -TP_RETINEX_CURVEEDITOR_LH;Sterkte=f(H) -TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Sterkte volgens tint, Sterkte=f(H).\nDeze curve wijzigt ook chroma wanneer de Retinex-methode Hoge lichten wordt gebruikt. -TP_RETINEX_CURVEEDITOR_MAP;L=f(L) -TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Deze curve kan zowel losstaand worden gebruikt of in combinatie met een Gaussiaans of wavelet-masker.\nHoud rekening met onregelmatigheden. -TP_RETINEX_EQUAL;Mixer -TP_RETINEX_FREEGAMMA;Vrij gamma -TP_RETINEX_GAIN;Verbeteren -TP_RETINEX_GAINOFFS;Versterking en verschuiving (helderheid) -TP_RETINEX_GAINTRANSMISSION;Transmissieversterking -TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Versterk of verzwak de transmissiemap om de gewenste luminantie te verkrijgen.\nDe x-as is de transmissie.\nDe y-as is de versterking. -TP_RETINEX_GAMMA;Gamma -TP_RETINEX_GAMMA_FREE;Vrij -TP_RETINEX_GAMMA_HIGH;Hoog -TP_RETINEX_GAMMA_LOW;Laag -TP_RETINEX_GAMMA_MID;Midden -TP_RETINEX_GAMMA_NONE;Geen -TP_RETINEX_GAMMA_TOOLTIP;Herstel tinten door gamma voor en na Retinex toe te passen. Verschilt van Retinex-curves en andere curves (Lab, Exposure, etc.). -TP_RETINEX_GRAD;Transmissieverloop -TP_RETINEX_GRADS;Sterkteverloop -TP_RETINEX_GRADS_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Sterkte verminderd en herhaling vergroot, en omgekeerd. -TP_RETINEX_GRAD_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Variantie en Drempel worden verkleind als herhaling toeneemt, en omgekeerd. -TP_RETINEX_HIGH;Hoog -TP_RETINEX_HIGHLIG;Hoge lichten -TP_RETINEX_HIGHLIGHT;Drempel hoge lichten -TP_RETINEX_HIGHLIGHT_TOOLTIP;Versterkt de werking van de Hoge lichten-methode.\nMogelijk moet Naburige pixels worden aangepast en moet de Witpuntcorrectie in de Raw-tab -> Raw Witpunten worden vergroot. -TP_RETINEX_HSLSPACE_LIN;HSL-Lineair -TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmisch -TP_RETINEX_ITER;Herhalingen (Toonmappen) -TP_RETINEX_ITERF;Toonmappen -TP_RETINEX_ITER_TOOLTIP;Simuleert toonmappen.\nHoge waarden verlengen de bewerkingstijd. -TP_RETINEX_LABEL;Retinex -TP_RETINEX_LABEL_MASK;Masker -TP_RETINEX_LABSPACE;L*a*b* -TP_RETINEX_LOW;Laag -TP_RETINEX_MAP;Methode -TP_RETINEX_MAP_GAUS;Gaussiaans masker -TP_RETINEX_MAP_MAPP;Scherptemasker (wavelet gedeeltelijk) -TP_RETINEX_MAP_MAPT;Scherptemasker (wavelet totaal) -TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en onregelmatigheden te verminderen.\n\nCurve: past een diagonale contrastcurve toe op het masker.\nHou rekening met onregelmatigheden!\n\n Gausiaans: genereert en gebruikt een Gausiaanse vervaging op het masker.\nVerscherpen: genereert en gebruikt een wavelet op het masker.\nLangzaam. -TP_RETINEX_MAP_NONE;Geen -TP_RETINEX_MEDIAN;Transmissiemediaan-filter -TP_RETINEX_METHOD;Methode -TP_RETINEX_METHOD_TOOLTIP;Laag: schaduwen ophelderen,\nUniform: gelijkmatig,\nHoog: versterk hoge lichten,\nHoge lichten: verwijder magenta in hoge lichten. -TP_RETINEX_MLABEL;Teruggeplaatst sluiervrij Min=%1 Max=%2 -TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. -TP_RETINEX_NEIGHBOR;Naburige pixels -TP_RETINEX_NEUTRAL;Beginwaarde -TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarde. -TP_RETINEX_OFFSET;Beginpunt -TP_RETINEX_SCALES;Gaussiaans verloop -TP_RETINEX_SCALES_TOOLTIP;Als schuifbalk = 0, dan zijn alle herhalingen gelijk.\nIndien > 0 dan worden schaal en straal verkleind als de herhaling toeneemt, en omgekeerd. -TP_RETINEX_SETTINGS;Instellingen -TP_RETINEX_SKAL;Schaal -TP_RETINEX_SLOPE;Helling vrij gamma -TP_RETINEX_STRENGTH;Sterkte -TP_RETINEX_THRESHOLD;Drempel -TP_RETINEX_THRESHOLD_TOOLTIP;Beperkt in/uit.\nIn = bron,\nUit = afbeeldings-gauss. -TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sigma=%4 -TP_RETINEX_TLABEL2;TM Tm=%1 TM=%2 -TP_RETINEX_TLABEL_TOOLTIP;Transmissieresultaat.\nMin en Max worden gebruikt door Variantie.\nMeeste en Sigma\nTm=Min TM=Max van de transmissie. -TP_RETINEX_TRANF;Transmissie -TP_RETINEX_TRANSMISSION;Transmissiemap -TP_RETINEX_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde, en positieve waarden (max).\nOrdinaat: versterking of vermindering. -TP_RETINEX_UNIFORM;Uniform -TP_RETINEX_VARIANCE;Variantie -TP_RETINEX_VARIANCE_TOOLTIP;Lage variantie versterkt lokaal contrast en verzadiging, maar dit kan artefacten veroorzaken. -TP_RETINEX_VIEW;Proces -TP_RETINEX_VIEW_MASK;Masker -TP_RETINEX_VIEW_METHOD_TOOLTIP;Standaard - Normale weergave.\nMasker - Toont het masker.\nOnscherp masker - Toont de afbeelding met een onscherptemasker met grote straal.\nTransmissie - Auto/Vast - Toont de transmissiemap, voordat actie wordt ondernomen op contrast en helderheid.\n\nLet op: het masker komt niet overeen met de werkelijkheid, maar is versterkt om het effect beter zichtbaar te maken. -TP_RETINEX_VIEW_NONE;Standaard -TP_RETINEX_VIEW_TRAN;Transmissie - Auto -TP_RETINEX_VIEW_TRAN2;Transmissie - Vast -TP_RETINEX_VIEW_UNSHARP;Onscherpmasker -TP_RGBCURVES_BLUE;B -TP_RGBCURVES_CHANNEL;Kanaal -TP_RGBCURVES_GREEN;G -TP_RGBCURVES_LABEL;RGB-curven -TP_RGBCURVES_LUMAMODE;Luminositeitsmodus -TP_RGBCURVES_LUMAMODE_TOOLTIP;LuminositeitsmodusVarieert de toewijzing van de R-, G- en B-kanalen aan de luminositeit van de afbeelding, zonder dat de kleur van de afbeelding wijzigt. -TP_RGBCURVES_RED;R -TP_ROTATE_DEGREE;Graden -TP_ROTATE_LABEL;Roteren -TP_ROTATE_SELECTLINE;Bepaal rechte lijn -TP_SAVEDIALOG_OK_TOOLTIP;Sneltoets: Ctrl+Enter -TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hoge lichten -TP_SHADOWSHLIGHTS_HLTONALW;Toonomvang -TP_SHADOWSHLIGHTS_LABEL;Schaduwen/hoge lichten -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_BLUR;Vervagen straal -TP_SHARPENING_CONTRAST;Contrastdrempel -TP_SHARPENING_EDRADIUS;Straal -TP_SHARPENING_EDTOLERANCE;Randtolerantie -TP_SHARPENING_HALOCONTROL;Halocontrole -TP_SHARPENING_HCAMOUNT;Hoeveelheid -TP_SHARPENING_ITERCHECK;Automatische limiet herhalingen -TP_SHARPENING_LABEL;Verscherpen (Lab/CIECAM02) -TP_SHARPENING_METHOD;Methode -TP_SHARPENING_ONLYEDGES;Alleen randen verscherpen -TP_SHARPENING_RADIUS;Straal -TP_SHARPENING_RADIUS_BOOST;Straalvergroting -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_CONTRAST;Contrastdrempel -TP_SHARPENMICRO_LABEL;Microcontrast (Lab/CIECAM02) -TP_SHARPENMICRO_MATRIX;3×3-matrix ipv. 5×5 -TP_SHARPENMICRO_UNIFORMITY;Uniformiteit -TP_SOFTLIGHT_LABEL;Zacht licht -TP_SOFTLIGHT_STRENGTH;Sterkte -TP_TM_FATTAL_AMOUNT;Hoeveelheid -TP_TM_FATTAL_ANCHOR;Anker -TP_TM_FATTAL_LABEL;Compressie dynamisch bereik -TP_TM_FATTAL_THRESHOLD;Detail -TP_VIBRANCE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving -TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH -TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Huidtinten -TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rood/Paars -TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rood -TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rood/Geel -TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Geel -TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tint volgens Tint -TP_VIBRANCE_LABEL;Levendigheid -TP_VIBRANCE_PASTELS;Pasteltinten -TP_VIBRANCE_PASTSATTOG;Koppel pastel- en verzadigde tinten -TP_VIBRANCE_PROTECTSKINS;Bescherm huidtinten -TP_VIBRANCE_PSTHRESHOLD;Drempel pastel/verzadiging -TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Drempel verzadiging -TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;De verticale as vertegenwoordigt pasteltinten aan de onderkant en verzadigde tinten aan de bovenkant.\nDe horizontale as vertegenwoordigt het verzadigingsbereik. -TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Gewicht pastel/verzadigingtransitie -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;Vignetteringscorrectie -TP_VIGNETTING_RADIUS;Straal -TP_VIGNETTING_STRENGTH;Sterkte -TP_WAVELET_1;Niveau 1 -TP_WAVELET_2;Niveau 2 -TP_WAVELET_3;Niveau 3 -TP_WAVELET_4;Niveau 4 -TP_WAVELET_5;Niveau 5 -TP_WAVELET_6;Niveau 6 -TP_WAVELET_7;Niveau 7 -TP_WAVELET_8;Niveau 8 -TP_WAVELET_9;Niveau 9 -TP_WAVELET_APPLYTO;Toepassen -TP_WAVELET_AVOID;Vermijd kleurverschuiving -TP_WAVELET_B0;Zwart -TP_WAVELET_B1;Grijs -TP_WAVELET_B2;Rest -TP_WAVELET_BACKGROUND;Achtergrond -TP_WAVELET_BACUR;Curve -TP_WAVELET_BALANCE;Contrastbalans d/v-h -TP_WAVELET_BALANCE_TOOLTIP;Wijzigt de balans tussen de wavelet-richtingen: vertikaal-horizontaal en diagonaal.\nAls tonemapping in contrast, chromaticiteit of residueel actief zijn, wordt het effect als gevolg van de balans versterkt. -TP_WAVELET_BALCHRO;Chroma-balans -TP_WAVELET_BALCHRO_TOOLTIP;De Contrastbalans-curve en schuifbalk wijzigen ook de chromaticiteit-balans. -TP_WAVELET_BANONE;Geen -TP_WAVELET_BASLI;Schuifbalk -TP_WAVELET_BATYPE;Balansmethode -TP_WAVELET_CBENAB;Kleurtint en kleurbalans -TP_WAVELET_CB_TOOLTIP;Met hoge waarden kun je speciale effecten creëren, gelijkend op wat je met de Chroma-module kunt bereiken, maar nu gericht op het residuele beeld. Met kleinere waarden kun je handmatig de witbalans corrigeren. -TP_WAVELET_CCURVE;Lokaal contrast -TP_WAVELET_CH1;Alle chroma's -TP_WAVELET_CH2;Pastel - Verzadigd -TP_WAVELET_CH3;Koppel contrastniveaus -TP_WAVELET_CHCU;Curve -TP_WAVELET_CHR;Koppel Chroma aan Contrast -TP_WAVELET_CHRO;Verzadigd - Pastel -TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel -TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met contrastniveaus -TP_WAVELET_CHSL;Schuifbalken -TP_WAVELET_CHTYPE;Chrominantiemethode -TP_WAVELET_COLORT;Dekking Rood-Groen niveau -TP_WAVELET_COMPCONT;Contrast -TP_WAVELET_COMPGAMMA;Compressie gamma -TP_WAVELET_COMPGAMMA_TOOLTIP;Door het gamma van het residuele beeld te wijzigen, kun je data en histogram in balans brengen. -TP_WAVELET_COMPTM;Toonmappen -TP_WAVELET_CONTEDIT;'Na'-contrastcurve -TP_WAVELET_CONTR;Kleurenscala - controle -TP_WAVELET_CONTRA;Contrast -TP_WAVELET_CONTRAST_MINUS;< Contrast -TP_WAVELET_CONTRAST_PLUS;Contrast > -TP_WAVELET_CONTRA_TOOLTIP;Wijzigt het contrast van de residuele afbeelding. -TP_WAVELET_CTYPE;Chrominantiesterkte -TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Wijzigt lokaal contrast als een functie van het oorspronkelijke lokale contrast (abscis).\nLage absciswaarden vertegenwoordigen weinig lokaal contrast (werkelijke waarden rond 10..20).\n50% abscis vertegenwoordigt gemiddeld lokaal contrast (werkelijke waarden rond 100..300).\n66% abscis vertegenwoordigt de standaarddeviatie van lokaal contrast (werkelijke waarden rond 300..800).\n100% abscis vertegenwoordigt maximaal lokaal contrast (werkelijke waarden rond 3000..8000). -TP_WAVELET_CURVEEDITOR_CH;Contrastniveau=f(Tint) -TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Wijzigt het contrast van elk niveau als een functie van tint.\nZorg er voor dat de wijzigingen die zijn gemaakt bij de Gamut Tint-toepassing niet worden overschreven.\nDe curve werkt alleen als de Wavelet contrastniveauschuifbalken groter zijn dan nul. -TP_WAVELET_CURVEEDITOR_CL;L -TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Contrast luminantiecurve. Wordt uitgevoerd aan het einde van de Wavelet niveaubehandeling. -TP_WAVELET_CURVEEDITOR_HH;HH -TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de tint van de residuele afbeelding als functie van tint. -TP_WAVELET_DALL;Alle richtingen -TP_WAVELET_DAUB;Randen -TP_WAVELET_DAUB2;D2 - laag -TP_WAVELET_DAUB4;D4 - standaard -TP_WAVELET_DAUB6;D6 - standaard plus -TP_WAVELET_DAUB10;D10 - medium -TP_WAVELET_DAUB14;D14 - hoog -TP_WAVELET_DAUB_TOOLTIP;Wijzigt de Daubechies-coëfficiënten:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere verwerkingstijd.\n\nBeïnvloed zowel randdetectie als het algemene resultaat van de eerste niveaus. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan variëren per afbeelding en toepassing. -TP_WAVELET_DONE;Verticaal -TP_WAVELET_DTHR;Diagonaal -TP_WAVELET_DTWO;Horizontaal -TP_WAVELET_EDCU;Curve -TP_WAVELET_EDGCONT;Lokaal contrast -TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen, naar rechts vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev en maximum. -TP_WAVELET_EDGE;Randen verscherpen (Luminantie) -TP_WAVELET_EDGEAMPLI;Basisversterking -TP_WAVELET_EDGEDETECT;Gradiëntgevoeligheid -TP_WAVELET_EDGEDETECTTHR;Drempel laag (ruis) -TP_WAVELET_EDGEDETECTTHR2;Drempel hoog (detectie) -TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Wijzigt de randdetectie. Bijvoorbeeld om randverscherping te voorkomen bij fijne details zoals ruis in de lucht. -TP_WAVELET_EDGEDETECT_TOOLTIP;Beweeg de schuifbalk naar rechts om de randgevoeligheid te vergroten. Dit wijzigt lokaal contrast, randscherpte en ruis. -TP_WAVELET_EDGESENSI;Randgevoeligheid -TP_WAVELET_EDGREINF_TOOLTIP;Versterk of verminder de actie van het eerste niveau en doe het tegenovergestelde voor het tweede niveau; laat de rest ongewijzigd. -TP_WAVELET_EDGTHRESH;Drempel -TP_WAVELET_EDGTHRESH_TOOLTIP;Wijzigt de interactie tussen de eerste niveaus en de andere niveaus. Hoe hoger de drempel hoe meer de actie is gecentreerd op de eerste niveaus. Wees voorzichtig met negatieve waarden. Deze versterken de hogere niveaus en kunnen artefacten veroorzaken. -TP_WAVELET_EDRAD;Straal -TP_WAVELET_EDRAD_TOOLTIP;Deze straalaanpassing verschilt erg van die in de andere verscherpingsgereedschappen. De waarde wordt vergeleken met elk niveau op basis van een complexe functie. In dit geval heeft zelfs een nulwaarde effect. -TP_WAVELET_EDSL;Drempel schuifbalk -TP_WAVELET_EDTYPE;Lokaal contrastmethode -TP_WAVELET_EDVAL;Waarde -TP_WAVELET_FINAL;Finale Bewerking -TP_WAVELET_FINEST;fijn -TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantiereeks (0..100) -TP_WAVELET_HS1;Alle luminanties -TP_WAVELET_HS2;Hoge lichten/schaduwen -TP_WAVELET_HUESKIN;Tint reeks (huid) -TP_WAVELET_HUESKIN_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. -TP_WAVELET_HUESKY;Tint Reeks (lucht) -TP_WAVELET_HUESKY_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. -TP_WAVELET_ITER;Balansniveau -TP_WAVELET_ITER_TOOLTIP;Links: verhoog lage niveaus en verlaag hoge niveaus.\nRechts: verlaag lage niveaus en verhoog hoge niveaus. -TP_WAVELET_LABEL;Wavelet-niveaus -TP_WAVELET_LARGEST;grof -TP_WAVELET_LEVCH;Chromaticiteit -TP_WAVELET_LEVDIR_ALL;Alle niveaus in alle richtingen -TP_WAVELET_LEVDIR_INF;Onder of gelijk aan het niveau -TP_WAVELET_LEVDIR_ONE;Eén niveau -TP_WAVELET_LEVDIR_SUP;Boven het niveau -TP_WAVELET_LEVELS;Wavelet-niveaus -TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detailniveaus. Meer niveaus vereisen meer RAM en de verwerking duurt langer. -TP_WAVELET_LEVF;Contrast -TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveaus=%1 -TP_WAVELET_LEVONE;Niveau 2 -TP_WAVELET_LEVTHRE;Niveau 4 -TP_WAVELET_LEVTWO;Niveau 3 -TP_WAVELET_LEVZERO;Niveau 1 -TP_WAVELET_LINKEDG;Koppel met Randscherptewaarde -TP_WAVELET_LIPST;Verbeterde methode -TP_WAVELET_LOWLIGHT;Grovere niveaus luminantiebereik (0..100) -TP_WAVELET_MEDGREINF;Eerste niveau -TP_WAVELET_MEDI;Verminder artefacten in blauwe lucht -TP_WAVELET_MEDILEV;Randdetectie -TP_WAVELET_MEDILEV_TOOLTIP;Bij gebruik van Randdetectie:\n- Maak geen gebruik van de lagecontrast-niveaus. Dit voorkomt artefacten.\n- Gebruik de hoge waarden van de Gradiënt-gevoeligheid.\n\nJe kunt de sterkte moduleren met 'verfijnen' van Ruisonderdrukking. -TP_WAVELET_NEUTRAL;Neutraal -TP_WAVELET_NOIS;Ruisonderdrukking -TP_WAVELET_NOISE;Ruisonderdrukking -TP_WAVELET_NPHIGH;Hoog -TP_WAVELET_NPLOW;Laag -TP_WAVELET_NPNONE;Geen -TP_WAVELET_NPTYPE;Naburige pixels -TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan worden randen verscherpt. -TP_WAVELET_OPACITY;Dekking Blauw-Geel niveau -TP_WAVELET_OPACITYW;Contrastbalans d/v-h curve -TP_WAVELET_OPACITYWL;Uiteindelijk lokaal contrast -TP_WAVELET_OPACITYWL_TOOLTIP;Wijzigt het lokaal contrast aan het einde van de wavelet-toepassing.\n\nHet lokaal contrast wordt sterker van links naar rechts. -TP_WAVELET_PASTEL;Pastel-chromaciteit -TP_WAVELET_PROC;Proces -TP_WAVELET_RE1;Versterkt -TP_WAVELET_RE2;Ongewijzigd -TP_WAVELET_RE3;Verminderd -TP_WAVELET_RESCHRO;Chromaticiteit -TP_WAVELET_RESCON;Schaduwen -TP_WAVELET_RESCONH;Hoge lichten -TP_WAVELET_RESID;Residuele afbeelding -TP_WAVELET_SAT;Verzadigd chromaciteit -TP_WAVELET_SETTINGS;Wavelet-instellingen -TP_WAVELET_SKIN;Huidtinten wijzigen/beschermen -TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. -TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen -TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in het tintbereik\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... -TP_WAVELET_STREN;Sterkte -TP_WAVELET_STRENGTH;Sterkte -TP_WAVELET_SUP;Boven het niveau + overblijvend -TP_WAVELET_SUPE;Extra -TP_WAVELET_THR;Drempel schaduwen -TP_WAVELET_THRES;Max. niveau -TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) -TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) -TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus van de gekozen waarde tot het gekozen aantal Wavelet-niveaus zullen worden beïnvloed door het Schaduwluminantiebereik. -TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus beneden en inclusief de gekozen waarde zullen worden beïnvloed door het luminantiebereik van de hoge lichten. -TP_WAVELET_THRH;Drempel hoge lichten -TP_WAVELET_TILES;Tegelgrootte (* 128) -TP_WAVELET_TILESBIG;Grote tegels -TP_WAVELET_TILESFULL;Volledige afbeelding -TP_WAVELET_TILESIZE;Tegelgrootte -TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer 'Grote tegels' als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugenaanbevelingen. -TP_WAVELET_TMSTRENGTH;Compressiesterkte -TP_WAVELET_TMSTRENGTH_TOOLTIP;Bepaalt de sterkte van het toonmappen of de contrastcompressie. Als de waarde anders is dan 0, dan worden de Sterkte- en Gamma-schuifbalken van Toonmappen in de Belichtingstab inactief. -TP_WAVELET_TMTYPE;Compressiemethode -TP_WAVELET_TON;Kleurtinten -TP_WBALANCE_AUTO;Automatisch -TP_WBALANCE_CAMERA;Camera -TP_WBALANCE_CLOUDY;Bewolkt -TP_WBALANCE_CUSTOM;Handmatig -TP_WBALANCE_DAYLIGHT;Daglicht (zonnig) -TP_WBALANCE_EQBLUERED;Blauw/Rood-balans -TP_WBALANCE_EQBLUERED_TOOLTIP;Wijzigt het normale gedrag van 'witbalans' door de blauw/rood-balans te veranderen.\nToepassen wanneer de opname-omstandigheden sterk afwijken van: \na) standaardbelichting (bv. onderwater)\nb) de condities waar de kalibraties zijn uitgevoerd\nc) de matrices of ICC-profielen. -TP_WBALANCE_FLASH55;Leica -TP_WBALANCE_FLASH60;Standaard, Canon, Pentax, Olympus -TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta -TP_WBALANCE_FLASH_HEADER;Flits -TP_WBALANCE_FLUO1;F1 - Daglicht -TP_WBALANCE_FLUO2;F2 - Koel wit -TP_WBALANCE_FLUO3;F3 - Wit -TP_WBALANCE_FLUO4;F4 - Warm wit -TP_WBALANCE_FLUO5;F5 - Daglicht -TP_WBALANCE_FLUO6;F6 - Licht wit -TP_WBALANCE_FLUO7;F7 - D65 Daglicht simuleren -TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design -TP_WBALANCE_FLUO9;F9 - Koel wit deluxe -TP_WBALANCE_FLUO10;F10 - Philips TL85 -TP_WBALANCE_FLUO11;F11 - Philips TL84 -TP_WBALANCE_FLUO12;F12 - Philips TL83 -TP_WBALANCE_FLUO_HEADER;Fluorescent(TL) -TP_WBALANCE_GREEN;Groentint -TP_WBALANCE_GTI;GTI -TP_WBALANCE_HMI;HMI -TP_WBALANCE_JUDGEIII;JudgeIII -TP_WBALANCE_LABEL;Witbalans -TP_WBALANCE_LAMP_HEADER;Lamp -TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 -TP_WBALANCE_LED_HEADER;LED -TP_WBALANCE_LED_LSI;LSI Lumelex 2040 -TP_WBALANCE_METHOD;Methode -TP_WBALANCE_PICKER;Kies -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_TEMPBIAS;AWB temperatuur-afwijking -TP_WBALANCE_TEMPBIAS_TOOLTIP;Wijzigt de berekening van auto-witbalans\ndoor een afwijking naar warmere of koelere temperatuur.\nDe afwijking wordt uitgedrukt als percentage van de berekende temperatuur,\nzodat het resultaat is: computedTemp + computedTemp * afwijking. -TP_WBALANCE_TEMPERATURE;Kleurtemperatuur -TP_WBALANCE_TUNGSTEN;Tungsten (wolfraam) -TP_WBALANCE_WATER1;Onderwater 1 -TP_WBALANCE_WATER2;Onderwater 2 -TP_WBALANCE_WATER_HEADER;Onderwater -ZOOMPANEL_100;(100%) -ZOOMPANEL_NEWCROPWINDOW;Open (nieuw) detailvenster -ZOOMPANEL_ZOOM100;Zoom naar 100%\nSneltoets: Z -ZOOMPANEL_ZOOMFITCROPSCREEN;Maak uitsnede passend in het scherm\nSneltoets: F -ZOOMPANEL_ZOOMFITSCREEN;Passend in venster\nSneltoets: Alt+F -ZOOMPANEL_ZOOMIN;Zoom in\nSneltoets: + -ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -ERROR_MSG_METADATA_VALUE;Metadata: fout bij omzetting %1 naar %2 -EXIFFILTER_PATH;Bestandspad -EXIFPANEL_ACTIVATE_ALL_HINT;Selecteer alle tags -EXIFPANEL_ACTIVATE_NONE_HINT;Deselecteer alle tags -EXIFPANEL_BASIC_GROUP;Basis -EXIFPANEL_VALUE_NOT_SHOWN;Niet getoond -FILEBROWSER_POPUPINSPECT;Inspecteer -FILEBROWSER_POPUPSORTBY;Sorteer bestanden -FILECHOOSER_FILTER_EXECUTABLE;Uitvoerbare bestanden -GENERAL_DELETE_ALL;Wis alles -GENERAL_EDIT;Bewerk -GENERAL_OTHER;Ander -HISTOGRAM_TOOLTIP_CROSSHAIR;Toon/verberg indicatorkruis -HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toon/verberg optieknoppen -HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Pas helderheid aan -HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram -HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw-histogram -HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-Parade -HISTOGRAM_TOOLTIP_TYPE_VECTORbereik_HC;Tint-Chroma vectorscope -HISTOGRAM_TOOLTIP_TYPE_VECTORbereik_HS;Tint-Verzadiging vectorscope -HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Golfvorm -!HISTORY_MSG_446;--unused-- -!HISTORY_MSG_447;--unused-- -!HISTORY_MSG_448;--unused-- -!HISTORY_MSG_450;--unused-- -!HISTORY_MSG_451;--unused-- -!HISTORY_MSG_454;--unused-- -!HISTORY_MSG_455;--unused-- -!HISTORY_MSG_456;--unused-- -!HISTORY_MSG_458;--unused-- -!HISTORY_MSG_459;--unused-- -!HISTORY_MSG_460;--unused-- -!HISTORY_MSG_461;--unused-- -!HISTORY_MSG_463;--unused-- -!HISTORY_MSG_466;--unused-- -!HISTORY_MSG_467;--unused-- -!HISTORY_MSG_470;--unused-- HISTORY_MSG_496;LA - Spot verwijderd HISTORY_MSG_497;LA - Spot geselecteerd -!HISTORY_MSG_498;--unused-- -!HISTORY_MSG_499;--unused-- HISTORY_MSG_500;LA - Spotvorm HISTORY_MSG_501;LA - Spotmethode HISTORY_MSG_502;LA - SC - Vorm method @@ -2426,7 +822,6 @@ HISTORY_MSG_576;LA - cbdl mult HISTORY_MSG_577;LA - cbdl chroma HISTORY_MSG_578;LA - cbdl drempel HISTORY_MSG_579;LA - cbdl bereik -!HISTORY_MSG_580;--unused-- HISTORY_MSG_581;LA - Ruisverm. lum f 1 HISTORY_MSG_582;LA - Ruisverm. lum c HISTORY_MSG_583;LA - Ruisverm. lum detail @@ -2509,7 +904,6 @@ HISTORY_MSG_660;LA - CBDL klaarheid HISTORY_MSG_661;LA - CBDL residueel contrast HISTORY_MSG_662;LA - Verminder ruis lum f 0 HISTORY_MSG_663;LA - Verminder ruis lum f 2 -!HISTORY_MSG_664;--unused-- HISTORY_MSG_665;LA - cbdl masker meng HISTORY_MSG_666;LA - cbdl masker straal HISTORY_MSG_667;LA - cbdl masker chroma @@ -2990,16 +1384,40 @@ HISTORY_MSG_BLUWAV;Versterkingsrespons HISTORY_MSG_CATCAT;CAL - Instellingen - Modus HISTORY_MSG_CATCOMPLEX;CAL - Instellingen - Complexiteit HISTORY_MSG_CATMODEL;CAL - Instellingen - CAM +HISTORY_MSG_CLAMPOOG;Kleuren afkappen die buiten het gamma vallen +HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Kleurcorrectie +HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Kleurcorrectie +HISTORY_MSG_COLORTONING_LABREGION_CHANNEL;CT - Kanaal +HISTORY_MSG_COLORTONING_LABREGION_CHROMATICITYMASK;CT - gebied C-masker +HISTORY_MSG_COLORTONING_LABREGION_HUEMASK;CT - H-masker +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESS;CT - Licht +HISTORY_MSG_COLORTONING_LABREGION_LIGHTNESSMASK;CT - L-masker +HISTORY_MSG_COLORTONING_LABREGION_LIST;CT - Lijst +HISTORY_MSG_COLORTONING_LABREGION_MASKBLUR;CT - verzachtingsmasker gebied +HISTORY_MSG_COLORTONING_LABREGION_OFFSET;CT - verschuiving gebied +HISTORY_MSG_COLORTONING_LABREGION_POWER;CT - sterkte gebied +HISTORY_MSG_COLORTONING_LABREGION_SATURATION;CT - Verzadiging +HISTORY_MSG_COLORTONING_LABREGION_SHOWMASK;CT - toon gebiedsmasker +HISTORY_MSG_COLORTONING_LABREGION_SLOPE;CT - hellingsgebied HISTORY_MSG_COMPLEX;Waveletcomplexiteit HISTORY_MSG_COMPLEXRETI;Retinexcomplexiteit +HISTORY_MSG_DEHAZE_DEPTH;Ontnevelen - Diepte +HISTORY_MSG_DEHAZE_ENABLED;Ontnevelen HISTORY_MSG_DEHAZE_SATURATION;Nevelvermindering - Verzadiging +HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Ontnevelen - Toon dieptemap +HISTORY_MSG_DEHAZE_STRENGTH;Ontnevelen - Sterkte HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compenseer lichtheid +HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual-demozaïek - auto-drempel +HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual-demozaïek - Contrastdrempel HISTORY_MSG_EDGEFFECT;Randversterking respons HISTORY_MSG_FF_FROMMETADATA;Flat-Field - Uit metadata HISTORY_MSG_FILMNEGATIVE_BALANCE;FN - Referentie-uitvoer HISTORY_MSG_FILMNEGATIVE_COLORSPACE;Filmnegatief kleurruimte +HISTORY_MSG_FILMNEGATIVE_ENABLED;Filmnegatief HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Referentie-invoer +HISTORY_MSG_FILMNEGATIVE_VALUES;Filmnegatief waarden HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell +HISTORY_MSG_HISTMATCHING;Auto-tooncurve HISTORY_MSG_HLBL;Kleurpropagatie - vervaging HISTORY_MSG_HLTH;Tegenovergestelde Inpainting - versterking drempel HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy @@ -3010,14 +1428,34 @@ HISTORY_MSG_ICM_FBW;Zwart en wit HISTORY_MSG_ICM_GAMUT;Beperk kleurbereik HISTORY_MSG_ICM_GREX;Primair groen X HISTORY_MSG_ICM_GREY;Primair groen Y +HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaire kleuren +HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 illuminant D +HISTORY_MSG_ICM_OUTPUT_TYPE;Uitvoer - Type HISTORY_MSG_ICM_PRESER;Behoud neutraal HISTORY_MSG_ICM_REDX;Primair rood X HISTORY_MSG_ICM_REDY;Primair rood Y +HISTORY_MSG_ICM_WORKING_GAMMA;Werkend - Gamma HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Methode lichtsterkte HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Methode primaire kleuren +HISTORY_MSG_ICM_WORKING_SLOPE;Werkend - Helling +HISTORY_MSG_ICM_WORKING_TRC_METHOD;Werkend - TRC-methode HISTORY_MSG_ILLUM;CAL - SC - Lichtsterkte +HISTORY_MSG_LOCALCONTRAST_AMOUNT;Lokaal Contrast - Hoeveelheid +HISTORY_MSG_LOCALCONTRAST_DARKNESS;Lokaal Contrast - Donker +HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokaal Contrast +HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokaal Contrast - Licht +HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokaal Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Lokaal - draaipunt Equalizer HISTORY_MSG_LOCAL_GAMUTMUNSEL;Lokaal - SC - Voorkom kleurverschuiving +HISTORY_MSG_METADATA_MODE;Metadata kopieermodus +HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrastdrempel +HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto-drempel +HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto-radius +HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto-limiet herhalingen +HISTORY_MSG_PDSHARPEN_CONTRAST;CS - Contrastdrempel +HISTORY_MSG_PDSHARPEN_ITERATIONS;CS - Herhalingen +HISTORY_MSG_PDSHARPEN_RADIUS;CS - Straal +HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Toename hoekstraal HISTORY_MSG_PERSP_CAM_ANGLE;Perspectief - Camera HISTORY_MSG_PERSP_CAM_FL;Perspectief - Camera HISTORY_MSG_PERSP_CAM_SHIFT;Perspectief - Camera @@ -3027,24 +1465,39 @@ HISTORY_MSG_PERSP_PROJ_ANGLE;Perspectief - Herstel HISTORY_MSG_PERSP_PROJ_ROTATE;Perspectief - PCA-rotatie HISTORY_MSG_PERSP_PROJ_SHIFT;Perspectief - PCA HISTORY_MSG_PIXELSHIFT_AVERAGE;PS - Gemiddeld +HISTORY_MSG_PIXELSHIFT_DEMOSAIC;PS - Demozaïekmethode voor beweging +HISTORY_MSG_PREPROCESS_LINEDENOISE_DIRECTION;Lijnruisfilter richting +HISTORY_MSG_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter HISTORY_MSG_PREPROCWB_MODE;Voorproces WB Modus HISTORY_MSG_PROTAB;Protectie +HISTORY_MSG_PRSHARPEN_CONTRAST;PRS - Contrastdrempel HISTORY_MSG_RANGEAB;Reeks ab +HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correctie - Herhalingen +HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correctie - Vermijd kleurverschuiving +HISTORY_MSG_RAW_BORDER;Raw rand +HISTORY_MSG_RESIZE_ALLOWUPSCALING;Schalen - sta vergroting toe HISTORY_MSG_RESIZE_LONGEDGE;Verander grootte - Lange zijde HISTORY_MSG_RESIZE_SHORTEDGE;Verander grootte - Korte zijde +HISTORY_MSG_SHARPENING_BLUR;Verscherpen - Vervagingsradius +HISTORY_MSG_SHARPENING_CONTRAST;Verscherpen - Contrastdrempel +HISTORY_MSG_SH_COLORSPACE;S/H - Kleurruimte HISTORY_MSG_SIGMACOL;Chroma-versterking respons HISTORY_MSG_SIGMADIR;Dir versterking respons HISTORY_MSG_SIGMAFIN;Finale contrastversterking respons HISTORY_MSG_SIGMATON;Toning versterking respons +HISTORY_MSG_SOFTLIGHT_ENABLED;Zacht licht +HISTORY_MSG_SOFTLIGHT_STRENGTH;Zacht licht - Sterkte HISTORY_MSG_SPOT;Verwijder vlekken HISTORY_MSG_SPOT_ENTRY;Vlekverwijdering - punt gewijzigd HISTORY_MSG_TEMPOUT;CAM02 automatische temperatuur HISTORY_MSG_THRESWAV;Balance drempel +HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anker HISTORY_MSG_TONE_EQUALIZER_BANDS;Toonequalizer - Banden HISTORY_MSG_TONE_EQUALIZER_ENABLED;Toonequalizer HISTORY_MSG_TONE_EQUALIZER_PIVOT;Toonequalizer - Draaipunt HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Toonequalizer - Regularisatie HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Toonequalizer - Tonale map +HISTORY_MSG_TRANS_METHOD;Geometrie - Methode HISTORY_MSG_WAVBALCHROM;Equalizer chrominantie HISTORY_MSG_WAVBALLUM;Equalizer luminantie HISTORY_MSG_WAVBL;Vervagingsniveaus @@ -3100,56 +1553,488 @@ HISTORY_MSG_WBITC_SAMPLING;Laag sampling HISTORY_MSG_WBITC_SIZE;Itcwb Grootte HISTORY_MSG_WBITC_SORTED;Itcwb gewogen HISTORY_MSG_WBITC_THRES;Itcwb drempel +HISTORY_NEWSNAPSHOT;Nieuw +HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt+S +HISTORY_SNAPSHOT;Nieuw +HISTORY_SNAPSHOTS;Snapshots +ICCPROFCREATOR_COPYRIGHT;Copyright: +ICCPROFCREATOR_COPYRIGHT_RESET_TOOLTIP;Zet terug naar standaard copyright, verleend aan "RawTherapee, CC0" +ICCPROFCREATOR_CUSTOM;Handmatig +ICCPROFCREATOR_DESCRIPTION;Beschriiving: +ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Voeg gamma- en hellingwaarden toe aan de beschrijving +ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Laat leeg voor de standaardbeschrijving. +ICCPROFCREATOR_GAMMA;Gamma +ICCPROFCREATOR_ICCVERSION;ICC-versie: +ICCPROFCREATOR_ILL;Illuminant: +ICCPROFCREATOR_ILL_41;D41 +ICCPROFCREATOR_ILL_50;D50 +ICCPROFCREATOR_ILL_55;D55 +ICCPROFCREATOR_ILL_60;D60 ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater +ICCPROFCREATOR_ILL_65;D65 +ICCPROFCREATOR_ILL_80;D80 +ICCPROFCREATOR_ILL_DEF;Standaard +ICCPROFCREATOR_ILL_INC;StdA 2856K +ICCPROFCREATOR_ILL_TOOLTIP;U kunt alleen de illuminant instellen voor ICC v4-profielen. +ICCPROFCREATOR_PRIMARIES;Primaire kleuren: +ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 +ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 +ICCPROFCREATOR_PRIM_ADOBE;Adobe RGB (1998) +ICCPROFCREATOR_PRIM_BEST;BestRGB +ICCPROFCREATOR_PRIM_BETA;BetaRGB +ICCPROFCREATOR_PRIM_BLUX;Blauw X +ICCPROFCREATOR_PRIM_BLUY;Blauw Y +ICCPROFCREATOR_PRIM_BRUCE;BruceRGB ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 +ICCPROFCREATOR_PRIM_GREX;Groen X +ICCPROFCREATOR_PRIM_GREY;Groen Y +ICCPROFCREATOR_PRIM_PROPH;Prophoto +ICCPROFCREATOR_PRIM_REC2020;Rec2020 +ICCPROFCREATOR_PRIM_REDX;Rood X +ICCPROFCREATOR_PRIM_REDY;Rood Y +ICCPROFCREATOR_PRIM_SRGB;sRGB +ICCPROFCREATOR_PRIM_TOOLTIP;U kunt alleen aangepaste primaries voor ICC v4-profielen instellen. +ICCPROFCREATOR_PRIM_WIDEG;Wijd kleurenscala +ICCPROFCREATOR_PROF_V2;ICC v2 +ICCPROFCREATOR_PROF_V4;ICC v4 +ICCPROFCREATOR_SAVEDIALOG_TITLE;Bewaar ICC-profiel als... +ICCPROFCREATOR_SLOPE;Helling +ICCPROFCREATOR_TRC_PRESET;Toonresponscurve: INSPECTOR_WINDOW_TITLE;Inspecteur +IPTCPANEL_CATEGORY;Categorie +IPTCPANEL_CATEGORYHINT;Het onderwerp van de afbeelding. +IPTCPANEL_CITY;Plaats +IPTCPANEL_CITYHINT;Plaats waar de afbeelding is genomen. +IPTCPANEL_COPYHINT;Kopieer IPTC-instellingen naar klembord +IPTCPANEL_COPYRIGHT;Copyright-melding +IPTCPANEL_COPYRIGHTHINT;Melding over de huidige copyright-houder van de afbeelding, bijvoorbeeld ©2008 Jane Doe. +IPTCPANEL_COUNTRY;Land +IPTCPANEL_COUNTRYHINT;Land waar de afbeelding is genomen. +IPTCPANEL_CREATOR;Maker +IPTCPANEL_CREATORHINT;Naam van de maker. +IPTCPANEL_CREATORJOBTITLE;Functie van de maker. +IPTCPANEL_CREATORJOBTITLEHINT;De functie van de maker. +IPTCPANEL_CREDIT;Credit +IPTCPANEL_CREDITHINT;Naam van de leverancier van de foto, niet noodzakelijkerwijs de eigenaar/maker (Credit) +IPTCPANEL_DATECREATED;Opnamedatum +IPTCPANEL_DATECREATEDHINT;Datum waarop de afbeelding is genomen. +IPTCPANEL_DESCRIPTION;Beschrijving +IPTCPANEL_DESCRIPTIONHINT;Bijschrift dat het wie, wat of waarom beschrijft van wat er gebeurt in de afbeelding. Dit kan inclusief de namen van de personen zijn en of hun rol in de actie die plaatsvindt in de afbeelding. +IPTCPANEL_DESCRIPTIONWRITER;Schrijver van de beschrijving. +IPTCPANEL_DESCRIPTIONWRITERHINT;De naam van de persoon die is betrokken bij het schrijven, wijzigen of corrigeren van de beschrijving van de afbeelding. +IPTCPANEL_EMBEDDED;Ingebed +IPTCPANEL_EMBEDDEDHINT;Keer terug naar IPTC-data die in de foto zijn opgeslagen +IPTCPANEL_HEADLINE;Titel +IPTCPANEL_HEADLINEHINT;Een korte samenvatting van de inhoud van de afbeelding. +IPTCPANEL_INSTRUCTIONS;Instructies +IPTCPANEL_INSTRUCTIONSHINT;Infomatie over embargo of andere beperkingen die buiten het Copyright vallen. +IPTCPANEL_KEYWORDS;Sleutelwoorden +IPTCPANEL_KEYWORDSHINT;Gebruik steekwoorden of zinnen om het onderwerp van de afbeelding te beschrijven. +IPTCPANEL_PASTEHINT;Plak IPTC-instellingen van klembord +IPTCPANEL_PROVINCE;Provincie +IPTCPANEL_PROVINCEHINT;Provincie waar de afbeelding is genomen. +IPTCPANEL_RESET;Standaardwaarden +IPTCPANEL_RESETHINT;Terug naar standaardwaarden +IPTCPANEL_SOURCE;Bron +IPTCPANEL_SOURCEHINT;De naam van de persoon of de partij die verantwoordelijk is voor de verspreiding van de afbeelding, zoals de persoon of partij van wie de afbeelding afkomstig is. +IPTCPANEL_SUPPCATEGORIES;Aanvullende categorieën. +IPTCPANEL_SUPPCATEGORIESHINT;Verfijnt het onderwerp van de afbeelding. +IPTCPANEL_TITLE;Titel +IPTCPANEL_TITLEHINT;De korte naam van de afbeelding. Dit kan de bestandsnaam zijn. +IPTCPANEL_TRANSREFERENCE;Referentienummer +IPTCPANEL_TRANSREFERENCEHINT;Het nummer dat wordt gebruikt voor de 'workflow control' of voor de tracking. +MAIN_BUTTON_FULLSCREEN;Volledig scherm +MAIN_BUTTON_ICCPROFCREATOR;ICC Profielmaker +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Fotobewerker\nSneltoets: Shift+F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Fotobewerker om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB. De miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) +MAIN_BUTTON_PREFERENCES;Voorkeuren +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij.\nSneltoets: Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto.\nSneltoets: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Bewerk afbeelding in externe fotobewerker +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma.\nSneltoets: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: M +MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm +MAIN_FRAME_EDITOR;Fotobewerker +MAIN_FRAME_EDITOR_TOOLTIP; Bewerking.\nSneltoets: Ctrl+F4 +MAIN_FRAME_FILEBROWSER;Bestandsnavigator +MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator.\nSneltoets: Ctrl+F2 +MAIN_FRAME_PLACES;Locaties +MAIN_FRAME_PLACES_ADD;Nieuw +MAIN_FRAME_PLACES_DEL;Verwijderen +MAIN_FRAME_QUEUE;Verwerkingsrij +MAIN_FRAME_QUEUE_TOOLTIP; Verwerkingsrij.\nSneltoets: Ctrl+F3 +MAIN_FRAME_RECENT;Recente mappen +MAIN_MSG_ALREADYEXISTS;Bestand bestaat al +MAIN_MSG_CANNOTLOAD;Fout bij laden +MAIN_MSG_CANNOTSAVE;Fout bij opslaan van de afbeelding +MAIN_MSG_CANNOTSTARTEDITOR;Kan fotoprogramma niet starten. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Geef juiste pad op in 'Voorkeuren'. +MAIN_MSG_EMPTYFILENAME;Geen bestandsnaam opgegeven! +MAIN_MSG_IMAGEUNPROCESSED;Deze opdracht vereist dat alle geselecteerde foto's eerst moeten zijn verwerkt. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_OPERATIONCANCELLED;Opdracht afgebroken +MAIN_MSG_PATHDOESNTEXIST;Het pad\n\n%1\n\nbestaat niet. Geef een correct pad op in Voorkeuren. +MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? +MAIN_MSG_SETPATHFIRST;Specificeer eerst een doelmap in Voorkeuren\nom deze functionaliteit te kunnen gebruiken! +MAIN_MSG_TOOMANYOPENEDITORS;Teveel open fotobewerkers.\nSluit er een om verder te kunnen. +MAIN_MSG_WRITEFAILED;Niet opgeslagen\n\n"%1"\n\nControleer of de map bestaat en dat u schrijfrechten heeft. +MAIN_TAB_ADVANCED;Geavanceerd +MAIN_TAB_ADVANCED_TOOLTIP;Sneltoets: Alt+A +MAIN_TAB_COLOR;Kleur +MAIN_TAB_COLOR_TOOLTIP;Sneltoets: Alt+C +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DETAIL_TOOLTIP;Sneltoets: Alt+D +MAIN_TAB_DEVELOP;Ontwikkel +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exporteren +MAIN_TAB_EXPOSURE;Belichting +MAIN_TAB_EXPOSURE_TOOLTIP;Sneltoets: Alt+E +MAIN_TAB_FAVORITES;Favorieten +MAIN_TAB_FAVORITES_TOOLTIP;Sneltoets: Alt+U +MAIN_TAB_FILTER;Filter +MAIN_TAB_INSPECT; Inspecteer +MAIN_TAB_IPTC;IPTC MAIN_TAB_LOCALLAB;Lokale aanpassingen MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt+O +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt+M +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Sneltoets: Alt+R +MAIN_TAB_TRANSFORM;Transformeer +MAIN_TAB_TRANSFORM_TOOLTIP;Sneltoets: Alt+T +MAIN_TOOLTIP_BACKCOLOR0;Achtergrond kleur van het voorbeeld: Gebaseerd op thema\nSneltoets: 8 +MAIN_TOOLTIP_BACKCOLOR1;Achtergrond kleur van het voorbeeld: Zwart\nSneltoets: 9 +MAIN_TOOLTIP_BACKCOLOR2;Achtergrond kleur van het voorbeeld: Wit\nSneltoets: 0 +MAIN_TOOLTIP_BACKCOLOR3;Achtergrondkleur van het voorbeeld: Middelgrijs\nSneltoets: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vergrendel/Ontgrendel de Voorafbeelding.\n\nVergrendeld: 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\nOntgrendeld: de Voorafbeelding volgt een stap achter de Naafbeelding en laat de afbeelding zien zonder het effect van het huidige gereedschap. +MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis).\nSneltoets: H +MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: > +MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: < +MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: B +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focusmasker.\nSneltoets: Shift+F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focusmasker aanstaat. +MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: G +MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSneltoets: V\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSneltoets: R +MAIN_TOOLTIP_PREVIEWSHARPMASK;Bekijk het Scherptecontrastmasker.\nSneltoets: P\nWerkt alleen als verscherping is geactiveerd en het zoomniveau >= 100%. +MAIN_TOOLTIP_QINFO;Beknopte fotogegevens +MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel.\nSneltoets: L +MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt+L +MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift+L +MAIN_TOOLTIP_THRESHOLD;Drempel +MAIN_TOOLTIP_TOGGLE;Vergelijk origineel en bewerking +MONITOR_PROFILE_SYSTEM;Systeem standaardwaarde +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Breedte: %1, Hoogte: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_BUNDLED_MISSING;Het gebundelde profiel "%1" werd niet gevonden!\n\nUw installatie kan beschadigd zijn.\n\nDaarom worden interne standaardwaarden gebruikt. +OPTIONS_DEFIMG_MISSING;Het standaardprofiel voor niet-RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. +OPTIONS_DEFRAW_MISSING;Het standaardprofiel voor RAW-afbeeldingen werd niet gevonden of is niet ingesteld.\n\nControleer de profielmap, het kan ontbreken of beschadigd zijn.\n\nDaarom wordt "%1" gebruikt. +PARTIALPASTE_ADVANCEDGROUP;Geavanceerd +PARTIALPASTE_BASICGROUP;Basisinstellingen +PARTIALPASTE_CACORRECTION;C/A-correctie +PARTIALPASTE_CHANNELMIXER;Kleurkanaalmixer +PARTIALPASTE_CHANNELMIXERBW;Zwart-wit +PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen +PARTIALPASTE_COLORTONING;Kleurtinten +PARTIALPASTE_COMMONTRANSFORMPARAMS;Automatisch uitvullen +PARTIALPASTE_COMPOSITIONGROUP;Compositie-instellingen +PARTIALPASTE_CROP;Bijsnijden +PARTIALPASTE_DARKFRAMEAUTOSELECT;Donkerframe autom. selectie +PARTIALPASTE_DARKFRAMEFILE;Donkerframe-opname +PARTIALPASTE_DEFRINGE;Verzachten +PARTIALPASTE_DEHAZE;Ontnevelen +PARTIALPASTE_DETAILGROUP;Detailinstellingen +PARTIALPASTE_DIALOGLABEL;Profiel gedeeltelijk plakken... +PARTIALPASTE_DIRPYRDENOISE;Ruisonderdrukking +PARTIALPASTE_DIRPYREQUALIZER;Detailcontrast +PARTIALPASTE_DISTORTION;Corrigeer lensvervorming +PARTIALPASTE_EPD;Toonmappen +PARTIALPASTE_EQUALIZER;Wavelet Balans +PARTIALPASTE_EVERYTHING;Alles +PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens +PARTIALPASTE_EXPOSURE;Belichting +PARTIALPASTE_FILMNEGATIVE;Filmnegatief +PARTIALPASTE_FILMSIMULATION;Filmsimulatie +PARTIALPASTE_FLATFIELDAUTOSELECT;Vlakveld autoselectie +PARTIALPASTE_FLATFIELDBLURRADIUS;Vlakveld verzachting straal +PARTIALPASTE_FLATFIELDBLURTYPE;Vlakveld verzachting type +PARTIALPASTE_FLATFIELDCLIPCONTROL;Vlakveld afkapcontrole +PARTIALPASTE_FLATFIELDFILE;Vlakveldopname PARTIALPASTE_FLATFIELDFROMMETADATA;Vlakveld uit metadata +PARTIALPASTE_GRADIENT;Grijsverloopfilter +PARTIALPASTE_HSVEQUALIZER;HSV-balans +PARTIALPASTE_ICMSETTINGS;ICM-instellingen +PARTIALPASTE_IMPULSEDENOISE;Spot-ruisonderdrukking +PARTIALPASTE_IPTCINFO;IPTC-informatie +PARTIALPASTE_LABCURVE;LAB-curve +PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen +PARTIALPASTE_LENSPROFILE;Lenscorrectieprofiel +PARTIALPASTE_LOCALCONTRAST;Lokaal contrast PARTIALPASTE_LOCALLAB;Lokale aanpassingen PARTIALPASTE_LOCALLABGROUP;Instellingen Lokale aanpassingen +PARTIALPASTE_METADATA;Metadata modus +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_PCVIGNETTE;Vignetteringsfilter +PARTIALPASTE_PERSPECTIVE;Perspectief +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dodepixels-filter +PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hetepixels-filter +PARTIALPASTE_PREPROCESS_LINEDENOISE;Lijnruisfilter +PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter PARTIALPASTE_PREPROCWB;Pre-proces witbalans +PARTIALPASTE_PRSHARPENING;Verscherp na verkleinen +PARTIALPASTE_RAWCACORR_AUTO;Autom. C/A-correctie +PARTIALPASTE_RAWCACORR_AVOIDCOLORSHIFT;CA vermijd kleurverschuiving +PARTIALPASTE_RAWCACORR_CAREDBLUE;CA rood & blauw +PARTIALPASTE_RAWEXPOS_BLACK;Zwartniveau +PARTIALPASTE_RAWEXPOS_LINEAR;Raw witpunt- lineaire corr. factor +PARTIALPASTE_RAWGROUP;Raw-instellingen +PARTIALPASTE_RAW_BORDER;Raw rand +PARTIALPASTE_RAW_DCBENHANCE;Pas DCB-verbetering toe +PARTIALPASTE_RAW_DCBITERATIONS;aantal DCB-herhalingen +PARTIALPASTE_RAW_DMETHOD;Demozaïekmethode +PARTIALPASTE_RAW_FALSECOLOR;Demozaïek stapgrootte kleurfoutonderdrukking +PARTIALPASTE_RAW_IMAGENUM;Sub-afbeelding +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE-verbetering +PARTIALPASTE_RAW_PIXELSHIFT;Pixelverschuiving +PARTIALPASTE_RESIZE;Wijzig grootte +PARTIALPASTE_RETINEX;Retinex +PARTIALPASTE_RGBCURVES;RGB-curven +PARTIALPASTE_ROTATION;Roteren +PARTIALPASTE_SHADOWSHIGHLIGHTS;Schaduwen/hoge lichten +PARTIALPASTE_SHARPENEDGE;Randen +PARTIALPASTE_SHARPENING;Verscherping +PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_SOFTLIGHT;Zacht licht PARTIALPASTE_SPOT;Spot verwijder +PARTIALPASTE_TM_FATTAL;Compressie dynamisch bereik PARTIALPASTE_TONE_EQUALIZER;Toonequalizer +PARTIALPASTE_VIBRANCE;Levendigheid +PARTIALPASTE_VIGNETTING;Vignetteringscorrectie +PARTIALPASTE_WHITEBALANCE;Witbalans +PREFERENCES_ADD;Toevoegen +PREFERENCES_APPEARANCE;Uiterlijk +PREFERENCES_APPEARANCE_COLORPICKERFONT;Lettertype kleurenkiezer +PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kleur bijsnijmasker +PREFERENCES_APPEARANCE_MAINFONT;Standaard lettertype +PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator randkleur +PREFERENCES_APPEARANCE_THEME;Thema +PREFERENCES_APPLNEXTSTARTUP;herstart vereist +PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingssysteem +PREFERENCES_AUTOSAVE_TP_OPEN;Bewaar positie gereedschappen (open/dicht) bij afsluiten +PREFERENCES_BATCH_PROCESSING;Groepsverwerking +PREFERENCES_BEHADDALL;Alles op 'Toevoegen' +PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen-modus.\nWijzigingen van de parameters voor groepsverwerking zijn deltas op de opgeslagen waarden. +PREFERENCES_BEHAVIOR;Gedrag +PREFERENCES_BEHSETALL;Alles op 'Activeer' +PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer-modus.\nWijzigingen van de parameters voor groepsverwerking zijn absoluut. De actuele waarden worden gebruikt. +PREFERENCES_CACHECLEAR;Wissen +PREFERENCES_CACHECLEAR_ALL;Wis alle bestanden in de cache: +PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Wis alle bestanden in de cache behalve verwerkingsprofielen: +PREFERENCES_CACHECLEAR_ONLYPROFILES;Wis alleen verwerkingsprofielen in de cache: +PREFERENCES_CACHECLEAR_SAFETY;Alleen bestanden in de cache worden gewist. Verwerkingsprofielen van de oorspronkelijke afbeeldingen blijven ongemoeid. +PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in de cache +PREFERENCES_CACHEOPTS;Cache-opties +PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen PREFERENCES_CAMERAPROFILESDIR;Map met cameraprofielen +PREFERENCES_CHUNKSIZES;Tegels per thread +PREFERENCES_CHUNKSIZE_RAW_AMAZE;AMaZE-demozaïek +PREFERENCES_CHUNKSIZE_RAW_CA;Raw CA-correctie +PREFERENCES_CHUNKSIZE_RAW_RCD;RCD-demozaïek +PREFERENCES_CHUNKSIZE_RAW_XT;Xtrans-demozaïek +PREFERENCES_CHUNKSIZE_RGB;RGB-verwerking PREFERENCES_CIE;Ciecam PREFERENCES_CIEARTIF;Vermijd onregelmatigheden +PREFERENCES_CLIPPINGIND;Indicatie over-/onderbelichting +PREFERENCES_CLUTSCACHE;HaldCLUT-cache +PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cluts in de cache +PREFERENCES_CLUTSDIR;HaldCLUT-map +PREFERENCES_CMMBPC;Zwartpuntcompensatie PREFERENCES_COMPLEXITYLOC;Standaard complexiteit voor Lokale Aanpassingen PREFERENCES_COMPLEXITY_EXP;Geavanceerd PREFERENCES_COMPLEXITY_NORM;Standaard PREFERENCES_COMPLEXITY_SIMP;Basis +PREFERENCES_CROP;Uitsnijden +PREFERENCES_CROP_AUTO_FIT;Automatisch zoomen tot de uitsnede +PREFERENCES_CROP_GUIDES;Getoonde hulplijnen als uitsnede niet bewerkt wordt +PREFERENCES_CROP_GUIDES_FRAME;Frame +PREFERENCES_CROP_GUIDES_FULL;Origineel +PREFERENCES_CROP_GUIDES_NONE;Geen +PREFERENCES_CURVEBBOXPOS;Positie kopieer/plak-knoppen bij Curves +PREFERENCES_CURVEBBOXPOS_ABOVE;Boven +PREFERENCES_CURVEBBOXPOS_BELOW;Beneden +PREFERENCES_CURVEBBOXPOS_LEFT;Links +PREFERENCES_CURVEBBOXPOS_RIGHT;Rechts +PREFERENCES_CUSTPROFBUILD;Eigen/externe profielgenerator +PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor een foto te maken.\nOntvangt terminalparameters voor het genereren van pp3's gebaseerd op regels:\n[Pad RAW/JPG] [Pad standaardprofiel] [f-getal] [belichting in sec] [brandpuntsafstand in mm] [ISO] [lens] [Camerafabrikant] [cameramodel]\n\n Let op: Indien een pad spaties bevat moeten er dubbele quotes om het pad worden gezet. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;'Keys'-formaat +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Naam +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Pad naar programma of script +PREFERENCES_DARKFRAMEFOUND;Gevonden +PREFERENCES_DARKFRAMESHOTS;foto's +PREFERENCES_DARKFRAMETEMPLATES;sjablonen +PREFERENCES_DATEFORMAT;Datumformaat +PREFERENCES_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is \n%d/%m/%y +PREFERENCES_DIRDARKFRAMES;Map met donkerframes +PREFERENCES_DIRECTORIES;Mappen +PREFERENCES_DIRHOME;Standaardmap +PREFERENCES_DIRLAST;Laatst bezochte map +PREFERENCES_DIROTHER;Anders +PREFERENCES_DIRSELECTDLG;Selecteer standaardmap bij opstarten... +PREFERENCES_DIRSOFTWARE;Installatiemap +PREFERENCES_EDITORCMDLINE;Aangepaste opdrachtregel +PREFERENCES_EDITORLAYOUT;Bewerkingsvenster PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Passeer uitvoerprofiel PREFERENCES_EXTEDITOR_DIR;Uitvoermap PREFERENCES_EXTEDITOR_DIR_CURRENT;Zelfde als invoerbeeld PREFERENCES_EXTEDITOR_DIR_CUSTOM;Aangepast PREFERENCES_EXTEDITOR_DIR_TEMP;temp map dir besturingssysteem PREFERENCES_EXTEDITOR_FLOAT32;32-bit decimale TIFF_uitvoer +PREFERENCES_EXTERNALEDITOR;Externe editor PREFERENCES_EXTERNALEDITOR_CHANGE;Verander applicatie PREFERENCES_EXTERNALEDITOR_CHANGE_FILE;Verander uitvoerbaar bestand PREFERENCES_EXTERNALEDITOR_COLUMN_COMMAND;Opdracht PREFERENCES_EXTERNALEDITOR_COLUMN_NAME;Naam PREFERENCES_EXTERNALEDITOR_COLUMN_NATIVE_COMMAND;Standaard opdracht +PREFERENCES_FBROWSEROPTS;Opties bestandsnavigator +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Compacte gereedschapsbalken in bestandsnavigator +PREFERENCES_FLATFIELDFOUND;Gevonden +PREFERENCES_FLATFIELDSDIR;Vlakveldmap +PREFERENCES_FLATFIELDSHOTS;foto's +PREFERENCES_FLATFIELDTEMPLATES;sjablonen +PREFERENCES_FORIMAGE;Voor niet-RAW-bestanden +PREFERENCES_FORRAW;Voor RAW-bestanden +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Zelfde hoogte miniaturen in Bewerkingsvenster en Bestandsnavigator +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Verschillende hoogtes voor miniaturen vereist meer verwerkingstijd wanneer je wisselt tussen Bewerkingsvenster en Bestandsnavigator +PREFERENCES_GIMPPATH;Installatiemap GIMP +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in linkerpaneel +PREFERENCES_HISTOGRAM_TOOLTIP;Het werkprofiel wordt gebruikt voor het Hoofdhistogram en de Navigator. In alle andere gevallen wordt het gamma-gecorrigeerde uitvoerprofiel gebruikt. +PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting +PREFERENCES_ICCDIR;Map met ICC-profielen +PREFERENCES_IMPROCPARAMS;Standaardprofiel PREFERENCES_INSPECTORWINDOW;Open de Inspecteur in eigen venster of volledig scherm +PREFERENCES_INSPECT_LABEL;Inspecteer +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum aantal afbeeldingen in de cache +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Het maximum aantal afbeeldingen in de cache wanneer je in de Bestandsnavigator met de cursor over de miniaturen beweegt. Op computers met erg weinig RAM-geheugen (2 GB) moet deze waarde op 1 of 2 worden gezet. +PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie +PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie +PREFERENCES_INTENT_SATURATION;Verzadiging +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Toon interne JPEG-miniatuur indien onbewerkt +PREFERENCES_LANG;Taal +PREFERENCES_LANGAUTODETECT;Gebruik taalinstellingen pc PREFERENCES_LENSFUNDBDIR;Map met Lensfun-database PREFERENCES_LENSFUNDBDIR_TOOLTIP;Map met de Lensfun-database. Laat leeg om de standaardmappen te gebruiken. PREFERENCES_LENSPROFILESDIR;Map met lensprofielen PREFERENCES_LENSPROFILESDIR_TOOLTIP;Map met Adobe Lens Correction Profiles (LCP's) +PREFERENCES_MAXRECENTFOLDERS;Maximum aantal recente mappen +PREFERENCES_MENUGROUPEXTPROGS;Groepeer open met +PREFERENCES_MENUGROUPFILEOPERATIONS;Groepeer bestandsbewerkingen +PREFERENCES_MENUGROUPLABEL;Groepeer labelen +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Groepeer profielbewerkingen +PREFERENCES_MENUGROUPRANK;Groepeer markering +PREFERENCES_MENUOPTIONS;Menu-opties PREFERENCES_METADATA;Metadata PREFERENCES_METADATA_SYNC;Synchronisatie metadata met XMP-zijspanbestanden PREFERENCES_METADATA_SYNC_NONE;Geen PREFERENCES_METADATA_SYNC_READ;Alleen lezen PREFERENCES_METADATA_SYNC_READWRITE;Bidirectioneel +PREFERENCES_MONINTENT;Standaard weergave-intentie monitor +PREFERENCES_MONITOR;Monitor +PREFERENCES_MONPROFILE;Standaard kleurprofiel +PREFERENCES_MONPROFILE_WARNOSX;Als gevolg van beperkingen van macOS wordt alleen sRGB ondersteund. +PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster +PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor +PREFERENCES_NAVIGATIONFRAME;Navigatie +PREFERENCES_OVERLAY_FILENAMES;Toon bestandsnamen over miniaturen +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Toon bestandsnaam over miniaturen in het Bewerkingsvenster +PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande uitvoerbestanden +PREFERENCES_PANFACTORLABEL;Factor +PREFERENCES_PARSEDEXT;Extensies (verwerkingsvolgorde) +PREFERENCES_PARSEDEXTADD;Voeg extensie toe +PREFERENCES_PARSEDEXTADDHINT;Geef nieuwe extensie op en druk op de knop om aan de lijst toe te voegen +PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst +PREFERENCES_PARSEDEXTDOWNHINT;Verplaats extensie naar beneden +PREFERENCES_PARSEDEXTUPHINT;Verplaats extensie naar boven +PREFERENCES_PERFORMANCE_MEASURE;Meting +PREFERENCES_PERFORMANCE_MEASURE_HINT;Log de verwerkingstijden in de console +PREFERENCES_PERFORMANCE_THREADS;Threads +PREFERENCES_PERFORMANCE_THREADS_LABEL;Maximaal aantal threads voor ruisvermindering en Wavelet-niveaus (0 = automatisch) +PREFERENCES_PREVDEMO;Voorbeeld demozaïekmethode +PREFERENCES_PREVDEMO_FAST;Snel +PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: +PREFERENCES_PREVDEMO_SIDECAR;Gelijk aan PP3 +PREFERENCES_PRINTER;Printer (soft-proof) +PREFERENCES_PROFILEHANDLING;Verwerking profielen +PREFERENCES_PROFILELOADPR;Laadprioriteit profielen +PREFERENCES_PROFILEPRCACHE;Profiel in cache +PREFERENCES_PROFILEPRFILE;Profiel bij RAW-bestand +PREFERENCES_PROFILESAVEBOTH;Bewaar verwerkingsprofielen zowel in de cache als naast het invoerbestand +PREFERENCES_PROFILESAVECACHE;Bewaar profiel in cache +PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand +PREFERENCES_PROFILESAVELOCATION;Opslaglocatie profielen +PREFERENCES_PROFILE_NONE;Geen +PREFERENCES_PROPERTY;Eigenschap +PREFERENCES_PRTINTENT;Weergave-intentie +PREFERENCES_PRTPROFILE;Kleurprofiel +PREFERENCES_PSPATH;Installatiemap Adobe Photoshop +PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom% en pan-startpunt +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Onthoud het zoompercentage en pan-startpunt van de huidige afbeelding als er een nieuwe afbeelding wordt geopend.\n\nDeze optie werkt alleen in Enkeltab-modus en wanneer "Demozaïekmethode van het voorbeeld <100% zoom" hetzelfde is als "Gelijk aan PP3". +PREFERENCES_SAVE_TP_OPEN_NOW;Bewaar open/dicht-status van de gereedschappen nu +PREFERENCES_SELECTLANG;Selecteer taal +PREFERENCES_SERIALIZE_TIFF_READ;TIFF-leesinstellingen +PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serieel lezen van TIFF-bestanden +PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Als een map veel ongecomprimeerde TIFF-bestanden bevat dan versnelt deze optie het aanmaken van de miniaturen. +PREFERENCES_SET;Activeer +PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info +PREFERENCES_SHOWDATETIME;Toon datum en tijd +PREFERENCES_SHOWEXPOSURECOMPENSATION;Toon belichtingscompensatie +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Toon filmstrip werkbalk PREFERENCES_SHOWTOOLTIP;Toon schermtips voor Lokale aanpassingen +PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting +PREFERENCES_SINGLETAB;Enkel-tab: foto's openen in zelfde tabvenster +PREFERENCES_SINGLETABVERTAB;Enkel-tab ('filmstrip') modus met verticale tabs +PREFERENCES_SND_HELP;Typ bestandsnaam (of niets: geen geluid).\nWindows: gebruik 'SystemDefault', 'SystemAsterisk', etc. voor systeemgeluiden.\nLinux: gebruik "complete", "window-attention" etc. voor systeemgeluiden +PREFERENCES_SND_LNGEDITPROCDONE;Bewerking klaar +PREFERENCES_SND_QUEUEDONE;Verwerkingsrij klaar +PREFERENCES_SND_THRESHOLDSECS;na seconden +PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten +PREFERENCES_TAB_BROWSER;Bestandsnavigator +PREFERENCES_TAB_COLORMGR;Kleurbeheer +PREFERENCES_TAB_DYNAMICPROFILE;Dynamische Profielregel PREFERENCES_TAB_FAVORITES;Favorieten +PREFERENCES_TAB_GENERAL;Algemeen +PREFERENCES_TAB_IMPROC;Beeldverwerking +PREFERENCES_TAB_PERFORMANCE;Prestaties +PREFERENCES_TAB_SOUND;Geluiden +PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Ingesloten JPEG-voorbeeld +PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Te tonen foto +PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrale raw-rendering +PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Ingesloten JPEG indien vol formaat, anders neutrale raw PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Beschikbare gereedschappen PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Toon favoriete gereedschappen ook op hun oorspronkelijke locatie PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Indien aangevinkt zullen de favoriete gereedschappen zowel in de Favorieten-tab als op hun oorspronkelijke locatie te vinden zijn.\n\nOpmerking: als deze optie is aangevinkt kunt u een lichte vertraging verwachten tijdens het wisselen van tabs. PREFERENCES_TOOLPANEL_FAVORITE;Favoriet PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorietenpaneel PREFERENCES_TOOLPANEL_TOOL;Gereedschap +PREFERENCES_TP_LABEL;Gereedschapspaneel: +PREFERENCES_TP_VSCROLLBAR;Verberg de schuifbalk van het gereedschapspaneel +PREFERENCES_USEBUNDLEDPROFILES;Gebruik gebundelde profielen PREFERENCES_WBA;Witbalans PREFERENCES_WBACORR;Witbalans - Automatische temperatuurcorrelatie -!PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. PREFERENCES_WBAENA;Witbalans - Toon instellingen automatische temperatuurcorrelatie PREFERENCES_WBAENACUSTOM;Gebruik aangepaste temperatuur & tint PREFERENCES_WBAFORC;Forceer extra algoritme @@ -3159,11 +2044,94 @@ PREFERENCES_WBAPATCH;Maximaal aantal kleuren gebruikt in afbeelding PREFERENCES_WBAPRECIS;Precisie-algoritme - schaal toegepast PREFERENCES_WBASIZEREF;Grootte referentiekleur vergelijken met grootte histogramkleur PREFERENCES_WBASORT;Sorteer in chroma-volgorde in plaats van histogram +PREFERENCES_WORKFLOW;Layout PREFERENCES_XMP_SIDECAR_MODE;XMP zijspanbestand stijl PREFERENCES_XMP_SIDECAR_MODE_EXT;Zoals darktable (FILENAME.ext.xmp voor FILENAME.ext) PREFERENCES_XMP_SIDECAR_MODE_STD;Standaard (FILENAME.xmp voor FILENAME.ext) PREFERENCES_ZOOMONSCROLL;Zoom afbeeldingen door te scrollen +PROFILEPANEL_COPYPPASTE;Te kopiëren parameters +PROFILEPANEL_GLOBALPROFILES;Gebundelde profielen +PROFILEPANEL_LABEL;Profielen +PROFILEPANEL_LOADDLGLABEL;Kies profiel... +PROFILEPANEL_LOADPPASTE;Te laden parameters +PROFILEPANEL_MODE_TOOLTIP;Profiel aanvullen.\n\nKnop ingedrukt: gedeeltelijke profielen worden omgezet naar volledige profielen. De ontbrekende waarden worden vervangen door standaardwaarden.\n\nKnop neutraal: profielen worden toegepast zoals ze zijn, alleen de aanwezige waarden worden gewijzigd. +PROFILEPANEL_MYPROFILES;Mijn profielen +PROFILEPANEL_PASTEPPASTE;Te plakken parameters +PROFILEPANEL_PCUSTOM;Handmatig +PROFILEPANEL_PDYNAMIC;Dynamisch +PROFILEPANEL_PFILE;Uit bestand +PROFILEPANEL_PINTERNAL;Neutraal +PROFILEPANEL_PLASTSAVED;Laatst opgeslagen +PROFILEPANEL_SAVEDLGLABEL;Bewaar profiel... +PROFILEPANEL_SAVEPPASTE;Te bewaren parameters +PROFILEPANEL_TOOLTIPCOPY;Kopieer huidig profiel naar klembord +PROFILEPANEL_TOOLTIPLOAD;Laad profiel uit bestand +PROFILEPANEL_TOOLTIPPASTE;Plak profiel van klembord +PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel.\nCtrl+klik voor het selecteren van de instellingen voor opslaan. +PROGRESSBAR_DECODING;Decoderen... +PROGRESSBAR_GREENEQUIL;Groenbalancering... +PROGRESSBAR_HLREC;Reconstructie hoge lichten... +PROGRESSBAR_HOTDEADPIXELFILTER;Hete/dodepixels-filter... +PROGRESSBAR_LINEDENOISE;Lijnruisfilter... +PROGRESSBAR_LOADING;Afbeelding laden... +PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... +PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... +PROGRESSBAR_LOADJXL;Laden JXL-bestand... +PROGRESSBAR_LOADPNG;Laden PNG-bestand... +PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... +PROGRESSBAR_NOIMAGES;Geen afbeeldingen +PROGRESSBAR_PROCESSING;Foto verwerken... +PROGRESSBAR_PROCESSING_PROFILESAVED;Uitvoeren 'Profiel opslaan' +PROGRESSBAR_RAWCACORR;Raw CA-correctie... +PROGRESSBAR_READY;Gereed +PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... +PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... +PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... +PROGRESSBAR_SNAPSHOT_ADDED;Snapshot toegevoegd +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in Bestandsnavigator +QINFO_FRAMECOUNT;%2 frames +QINFO_HDR;HDR / %2 frame(s) +QINFO_ISO;ISO +QINFO_NOEXIF;Exif-gegevens niet beschikbaar. +QINFO_PIXELSHIFT;Pixel-Shift / %2 frame(s) +QUEUE_AUTOSTART;Autostart +QUEUE_AUTOSTART_TOOLTIP;Start verwerking automatisch wanneer nieuwe foto arriveert +QUEUE_DESTFILENAME;Pad en bestandsnaam +QUEUE_FORMAT_TITLE;Bestandstype +QUEUE_LOCATION_FOLDER;Sla op in map +QUEUE_LOCATION_TEMPLATE;Gebruik sjabloon +QUEUE_LOCATION_TEMPLATE_TOOLTIP;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2024/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2024, %d2=foto, ...\n%p1=/home/tom/image/02-09-2024, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de waardering van de foto. Als de foto geen waardering heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f +QUEUE_LOCATION_TITLE;Uitvoerlocatie +QUEUE_STARTSTOP_TOOLTIP;Start of stop de verwerking van foto's in de rij.\n\nSneltoets: Ctrl+S +SAMPLEFORMAT_0;onbekend dataformaat +SAMPLEFORMAT_1;8-bit unsigned +SAMPLEFORMAT_2;16-bit unsigned +SAMPLEFORMAT_4;24-bit LogLuv +SAMPLEFORMAT_8;32-bit LogLuv +SAMPLEFORMAT_16;16-bit drijvendekomma +SAMPLEFORMAT_32;24-bit drijvendekomma +SAMPLEFORMAT_64;32-bit drijvendekomma +SAVEDLG_AUTOSUFFIX;Voeg automatisch ophogend nummer (-1, -2..) toe als bestand al bestaat SAVEDLG_BIGTIFF;BigTIFF (geen metadata-ondersteuning) +SAVEDLG_FILEFORMAT;Bestandstype +SAVEDLG_FILEFORMAT_FLOAT; drijvendekomma +SAVEDLG_FORCEFORMATOPTS;Forceer opties voor opslaan +SAVEDLG_JPEGQUAL;JPEG-kwaliteit +SAVEDLG_PUTTOQUEUE;Plaats in verwerkingsrij +SAVEDLG_PUTTOQUEUEHEAD;Plaats vooraan in verwerkingsrij +SAVEDLG_PUTTOQUEUETAIL;Plaats achteraan in verwerkingsrij +SAVEDLG_SAVEIMMEDIATELY;Bewaar meteen +SAVEDLG_SAVESPP;Bewaar afbeelding met profiel +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Beste compressie +SAVEDLG_SUBSAMP_2;Gebalanceerd +SAVEDLG_SUBSAMP_3;Beste kwaliteit +SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en verticaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma-subsampling. +SAVEDLG_TIFFUNCOMPRESSED;Geen compressie +SAVEDLG_WARNFILENAME;Bestandsnaam wordt +SHCSELECTOR_TOOLTIP;Klik op de rechtermuisknop om\nde 3 knoppen te verschuiven +SOFTPROOF_GAMUTCHECK_TOOLTIP;Markeer pixels waarvan de kleuren buiten het kleurgamma vallen, relatief aan:\n- het printerprofiel, indien opgegeven en soft-proofing is ingeschakeld,\n- het uitvoerprofiel, indien geen printerprofiel is gekozen en soft-proofing is ingeschakeld,\n- het beeldschermprofiel, indien soft-proofing is uitgeschakeld. +SOFTPROOF_TOOLTIP;Soft-proofing simuleert hoe een foto wordt getoond:\n- als deze wordt afgedrukt, indien een printerprofiel is opgegeven in Voorkeuren > Kleurbeheer,\n- als de foto getoond wordt op een beeldscherm dat het huidige uitvoerprofiel gebruikt en een printerprofiel niet is opgegeven. SORT_ASCENDING;Oplopend SORT_BY_DATE;Op datum SORT_BY_EXIF;Op EXIF @@ -3177,18 +2145,132 @@ TC_PRIM_GREX;Gx TC_PRIM_GREY;Gy TC_PRIM_REDX;Rx TC_PRIM_REDY;Ry -!TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. -!TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. +THRESHOLDSELECTOR_B;Onderkant +THRESHOLDSELECTOR_BL;Onderkant-links +THRESHOLDSELECTOR_BR;Onderkant-rechts +THRESHOLDSELECTOR_HINT;Houd de Shift-toets ingedrukt om individuele controlepunten te verschuiven. +THRESHOLDSELECTOR_T;Bovenkant +THRESHOLDSELECTOR_TL;Bovenkant-links +THRESHOLDSELECTOR_TR;Bovenkant-rechts +TOOLBAR_TOOLTIP_COLORPICKER;Vergrendelbare kleurkiezer\n\nKlik met de linkermuisknop in het voorbeeld om een kleurkiezer toe te voegen\nBeweeg het punt door de linkermuisknop ingedrukt te houden\nVerwijder de kleurkiezer met rechts-klik\nVerwijder alle kleurkiezers met Shift+rechtsklik\nMet een rechtermuisklik naast een kleurkiezer komt het selectiehandje terug. +TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: C +TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: H +TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtzetten/Kleine rotaties.\nSneltoets: S\n\nBepaal de verticale of horizontale as door een hulplijn over de afbeelding te trekken. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. +TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: W +TP_BWMIX_ALGO;Algoritme OYCPM +TP_BWMIX_ALGO_LI;Lineair +TP_BWMIX_ALGO_SP;Speciale effecten +TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire respons.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur +TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM-modus. +TP_BWMIX_CHANNEL;Luminantiebalans +TP_BWMIX_CURVEEDITOR1;'Voor'-curve +TP_BWMIX_CURVEEDITOR2;'Na'-curve +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tooncurve wordt toegepast na de zwart-witconversie. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tooncurve wordt toegepast voor de zwart-witconversie.\nHoud rekening met de kleurcomponenten. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminantie als functie van tint (L=f(T).\nPas op met extreme waarden, deze kunnen onregelmatigheden veroorzaken. +TP_BWMIX_FILTER;Filterkleur +TP_BWMIX_FILTER_BLUE;Blauw +TP_BWMIX_FILTER_BLUEGREEN;Blauw-Groen +TP_BWMIX_FILTER_GREEN;Groen +TP_BWMIX_FILTER_GREENYELLOW;Groen-Geel +TP_BWMIX_FILTER_NONE;Geen +TP_BWMIX_FILTER_PURPLE;Paars +TP_BWMIX_FILTER_RED;Rood +TP_BWMIX_FILTER_REDYELLOW;Rood-Geel +TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beïnvloeden de helderheid. Zo maakt een rood filter een blauwe lucht donkerder. +TP_BWMIX_FILTER_YELLOW;Geel +TP_BWMIX_GAMMA;Gammacorrectie +TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB-kanaal +TP_BWMIX_LABEL;Zwart-wit +TP_BWMIX_MET;Methode +TP_BWMIX_MET_CHANMIX;Kanaalmixer +TP_BWMIX_MET_DESAT;Desatureren +TP_BWMIX_MET_LUMEQUAL;Luminantie-equalizer +TP_BWMIX_MIXC;Kanalenmixer +TP_BWMIX_NEUTRAL;Terugzetten +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totaal: %4%% +TP_BWMIX_RGBLABEL_HINT;RGB-omrekeningsfactoren. Hierin zijn alle gekozen opties verwerkt.\nTotaal toont de som van de uit te voeren RGB-factoren:\n- dit is altijd 100% in relatieve modus\n- groter (lichter) of kleiner (donkerder) dan 100% in absolute modus. +TP_BWMIX_RGB_TOOLTIP;Mix de RGB-kanalen. Gebruik Voorinstellingen voor aanwijzingen.\nNegatieve waarden kunnen onregelmatigheden veroorzaken. +TP_BWMIX_SETTING;Voorinstellingen +TP_BWMIX_SETTING_TOOLTIP;Verschillende voorinstellingen (film, landschap, etc.) of handmatige instellingen van de kanaalmixer. +TP_BWMIX_SET_HIGHCONTAST;Hoog contrast +TP_BWMIX_SET_HIGHSENSIT;Hoge gevoeligheid +TP_BWMIX_SET_HYPERPANCHRO;Hyperpanchromatisch +TP_BWMIX_SET_INFRARED;Infrarood +TP_BWMIX_SET_LANDSCAPE;Landschap +TP_BWMIX_SET_LOWSENSIT;Lage gevoeligheid +TP_BWMIX_SET_LUMINANCE;Luminantie +TP_BWMIX_SET_NORMCONTAST;Normaal contrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatisch +TP_BWMIX_SET_PANCHRO;Panchromatisch +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;RGB-absoluut +TP_BWMIX_SET_RGBREL;RGB-relatief +TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM-absoluut +TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM-relatief +TP_BWMIX_TCMODE_FILMLIKE;Z-W Filmachtig +TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadiging en Waarde mengen +TP_BWMIX_TCMODE_STANDARD;Z-W Standaard +TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen standaard +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Blauw +TP_CACORRECTION_LABEL;Corrigeer chromatische afwijking +TP_CACORRECTION_RED;Rood +TP_CBDL_AFT;Na zwart-wit +TP_CBDL_BEF;Voor zwart-wit +TP_CBDL_METHOD;Uitvoeren +TP_CBDL_METHOD_TOOLTIP;Kies of Detailcontrast moet worden uitgevoerd ná de zwart-witbewerking waardoor het werkt in L*a*b*, of vòòr de zwart-witbewerking waardoor het werkt in RGB +TP_CHMIXER_BLUE;Blauw +TP_CHMIXER_GREEN;Groen +TP_CHMIXER_LABEL;Kleurkanaalmixer +TP_CHMIXER_RED;Rood +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen +TP_COARSETRAF_TOOLTIP_ROTLEFT;Roteer links.\n\nSneltoets:\n[ - Multitab-modus,\nAlt+[ - Enkeltab-modus. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. +TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen +TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminantie +TP_COLORAPP_ALGO;Algoritme +TP_COLORAPP_ALGO_ALL;Alle +TP_COLORAPP_ALGO_JC;Lichtheid + Chroma (JC) +TP_COLORAPP_ALGO_JS;Lichtheid + Verzadiging (JS) +TP_COLORAPP_ALGO_QM;Helderheid + Kleurrijkheid (QM) +TP_COLORAPP_ALGO_TOOLTIP;Keuze uit parameters +TP_COLORAPP_BADPIXSL;Hete/dode-pixelsfilter +TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0 = geen effect 1 = mediaan 2 = gaussiaans.\n\nDeze onregelmatigheden zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. +TP_COLORAPP_BRIGHT;Helderheid (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Helderheid in CIECAM02 is verschillend van Lab en RGB, hou rekening met de luminositeit van wit +TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Bij handmatige aanpassing worden waarden boven 65 aanbevolen. TP_COLORAPP_CATCLASSIC;Klassiek -!TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. TP_COLORAPP_CATMOD;Modus TP_COLORAPP_CATSYMGEN;Auto-symmetrisch TP_COLORAPP_CATSYMSPE;Gemengd +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Kleurrijkheid (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Kleurrijkheid in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CHROMA_S;Verzadiging (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Verzadiging in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CIECAT_DEGREE;Chromatische aanpassing Scène TP_COLORAPP_CIECAT_DEGREEOUT;Chromatische aanpassing weergave -!TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). -!TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D50) into new values whose white point is that of the new illuminant - see WP model (for example D75). +TP_COLORAPP_CONTRAST;Contrast (J) +TP_COLORAPP_CONTRAST_Q;Contrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q) in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CONTRAST_TOOLTIP;Contrast (J) in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CURVEEDITOR1;Tooncurve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM-wijzigingen.\n\nHet histogram toont J,Q na toepassing van CIECAM, indien het selectievakje 'Toon CIECAM-uitvoer' is aangezet.\n(J,Q) worden niet getoond in het hoofdhistogram. \n\nZie voor de definitieve uitvoer het Histogrampaneel. +TP_COLORAPP_CURVEEDITOR2;Tooncurve 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings-tooncurve 2. +TP_COLORAPP_CURVEEDITOR3;Chroma-curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. +TP_COLORAPP_DATACIE;CIECAM02 uitvoerhistogram in de curven +TP_COLORAPP_DATACIE_TOOLTIP;Indien aangevinkt tonen de histogrammen van de CIECAM02-curven bij benadering de waarden/reeksen voor J of Q, en C, S of M na de CIECAM02-aanpassingen.\nDit heeft geen invloed op het hoofdhistogram.\n\nIndien uitgevinkt tonen de histogrammen van de CIECAM02-curven de Lab-waarden zoals deze waren voor de CIECAM02-aanpassingen +TP_COLORAPP_FREE;Vrije temp + groen + CAT02 + [uitvoer] +TP_COLORAPP_GAMUT;Beperk kleurbereik (Lab) TP_COLORAPP_GEN;Instellingen -!TP_COLORAPP_GEN_TOOLTIP;This module is based on the CIECAM color appearance models, which were designed to better simulate how human vision perceives colors under different lighting conditions, e.g. against different backgrounds. It takes into account the environment of each color and modifies its appearance to get as close as possible to human perception. It also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic appearance is preserved across the scene and display environments. +TP_COLORAPP_HUE;Tint (h) +TP_COLORAPP_HUE_TOOLTIP;Tint (h) - hoek tussen 0° en 360° TP_COLORAPP_IL41;D41 TP_COLORAPP_IL50;D50 TP_COLORAPP_IL55;D55 @@ -3198,51 +2280,339 @@ TP_COLORAPP_IL75;D75 TP_COLORAPP_ILA;Incandescent StdA 2856K TP_COLORAPP_ILFREE;Vrij TP_COLORAPP_ILLUM;Illuminant -!TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and latitude. +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen +TP_COLORAPP_LABEL_SCENE;Scène-omstandigheden +TP_COLORAPP_LABEL_VIEWING;Weergaveomstandigheden +TP_COLORAPP_LIGHT;Lichtheid (J) +TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB +TP_COLORAPP_MEANLUMINANCE;Gemiddelde luminantie (Yb%) TP_COLORAPP_MOD02;CAM02 TP_COLORAPP_MOD16;CAM16 +TP_COLORAPP_MODEL;Witpuntmodel TP_COLORAPP_MODELCAT;CAM -!TP_COLORAPP_MODELCAT_TOOLTIP;Allows you to choose between CAM02 or CAM16.\nCAM02 will sometimes be more accurate.\nCAM16 should generate fewer artifacts. -!TP_COLORAPP_SOURCEF_TOOLTIP;Corresponds to the shooting conditions and how to bring the conditions and data back to a 'normal' area. Normal means average or standard conditions and data, i.e. without taking into account CIECAM corrections. +TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. +TP_COLORAPP_NEUTRAL;Terugzetten +TP_COLORAPP_NEUTRAL_TOOLTIP;Zet alle regelaars, vinkjes en curves terug naar hun standaardwaarde +TP_COLORAPP_RSTPRO;Bescherming huid- en rode tinten +TP_COLORAPP_RSTPRO_TOOLTIP;Bescherm huid- en rode tinten (schuifbalk en curven) +TP_COLORAPP_SURROUND;Omgeving TP_COLORAPP_SURROUNDSRC;Omgevingsverlichting -!TP_COLORAPP_SURSOURCE_TOOLTIP;Changes tones and colors to take into account the surround conditions of the scene lighting. The darker the surround conditions, the brighter the image will become. Image brightness will not be changed when the surround is set to average. -!TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 -!TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. -!TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. -!TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. +TP_COLORAPP_SURROUND_AVER;Gemiddeld +TP_COLORAPP_SURROUND_DARK;Donker +TP_COLORAPP_SURROUND_DIM;Gedimd +TP_COLORAPP_SURROUND_EXDARK;Duister +TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden. +TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid +TP_COLORAPP_TCMODE_LABEL1;Curve modus 1 +TP_COLORAPP_TCMODE_LABEL2;Curve modus 2 +TP_COLORAPP_TCMODE_LABEL3;Curve chroma-modus +TP_COLORAPP_TCMODE_LIGHTNESS;Lichtheid +TP_COLORAPP_TCMODE_SATUR;Verzadiging +TP_COLORAPP_TEMP_TOOLTIP;Zet altijd Tint=1 om een lichtbron te selecteren.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TONECIE;Tonemappen met CIECAM +TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgevinkt zal het toonmappen plaatsvinden in Lab.\nIndien aangevinkt zal toonmappen gebruikmaken van CIECAM02.\nVoorwaarde is dat Tonemappen (Lab/CIECAM02) actief is. +TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m²) +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [uitvoer] +TP_COLORAPP_WBRT;WB [RT] + [uitvoer] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatisch +TP_COLORTONING_BALANCE;Balans +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Dekking +TP_COLORTONING_COLOR;Kleur +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma-dekking als functie van Luminantie oC=f(L) +TP_COLORTONING_HIGHLIGHT;Hoge lichten +TP_COLORTONING_HUE;Kleurtint +TP_COLORTONING_LAB;L*a*b*-menging +TP_COLORTONING_LABEL;Kleurtinten +TP_COLORTONING_LABGRID;L*a*b* kleurcorrectieraster +TP_COLORTONING_LABGRID_VALUES;HL: a=%1 b=%2\nS: a=%3 b=%4 +TP_COLORTONING_LABREGIONS;Kleurcorrectiegebieden +TP_COLORTONING_LABREGION_ABVALUES;a=%1 b=%2 +TP_COLORTONING_LABREGION_CHANNEL;Kanaal +TP_COLORTONING_LABREGION_CHANNEL_ALL;Alle +TP_COLORTONING_LABREGION_CHANNEL_B;Blauw +TP_COLORTONING_LABREGION_CHANNEL_G;Groen +TP_COLORTONING_LABREGION_CHANNEL_R;Rood +TP_COLORTONING_LABREGION_CHROMATICITYMASK;C +TP_COLORTONING_LABREGION_HUEMASK;H +TP_COLORTONING_LABREGION_LIGHTNESS;Helderheid (L) +TP_COLORTONING_LABREGION_LIGHTNESSMASK;L +TP_COLORTONING_LABREGION_LIST_TITLE;Correctie +TP_COLORTONING_LABREGION_MASK;Masker +TP_COLORTONING_LABREGION_MASKBLUR;Verzachtingsmasker +TP_COLORTONING_LABREGION_OFFSET;Verschuiving +TP_COLORTONING_LABREGION_POWER;Kracht +TP_COLORTONING_LABREGION_SATURATION;Verzadiging +TP_COLORTONING_LABREGION_SHOWMASK;Toon masker +TP_COLORTONING_LABREGION_SLOPE;Helling +TP_COLORTONING_LUMA;Luminantie +TP_COLORTONING_LUMAMODE;Behoud luminantie +TP_COLORTONING_LUMAMODE_TOOLTIP;Wanneer de kleur wijzigt (rood, groen, cyaan, blauw, etc.) blijft de luminatie van elke pixel behouden. +TP_COLORTONING_METHOD;Methode +TP_COLORTONING_METHOD_TOOLTIP;L*a*b*-menging, RGB-schuifbalken en RGB-curven gebruiken geïnterpoleerde kleurmenging.\nKleurbalans SMH en Verzadiging twee kleuren gebruiken directe kleuren.\nAlle methodes werken ook met zwart-wit. +TP_COLORTONING_MIDTONES;Middentonen +TP_COLORTONING_NEUTRAL;Terug naar beginstand +TP_COLORTONING_NEUTRAL_TOOLTIP;Zet alle waarden (schaduwen, middentonen, hoge lichten) terug naar hun standaardwaarden. +TP_COLORTONING_OPACITY;Dekking +TP_COLORTONING_RGBCURVES;RGB - Curven +TP_COLORTONING_RGBSLIDERS;RGB - Schuifbalken +TP_COLORTONING_SA;Bescherm verzadiging +TP_COLORTONING_SATURATEDOPACITY;Sterkte +TP_COLORTONING_SATURATIONTHRESHOLD;Drempel +TP_COLORTONING_SHADOWS;Schaduwen +TP_COLORTONING_SPLITCO;Schaduwen/Middentonen/Hoge lichten +TP_COLORTONING_SPLITCOCO;Kleurbalans SMH +TP_COLORTONING_SPLITLR;Verzadiging twee kleuren +TP_COLORTONING_STR;Sterkte +TP_COLORTONING_STRENGTH;Sterkte +TP_COLORTONING_TWO2;Speciaal chroma twee kleuren +TP_COLORTONING_TWOALL;Speciaal chroma +TP_COLORTONING_TWOBY;Speciaal a* en b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standaard chroma:\nLineaire respons, a* = b*.\n\nSpeciaal chroma:\nLineaire respons, a* = b*, maar ontbonden - gebruik de diagonaal hieronder.\n\nSpeciaal a* en b*:\nLineair ontbonden respons met aparte curves voor a* en b*. Bedoeld voor speciale effecten.\n\nSpeciaal chroma twee kleuren: beter voorspelbaar. +TP_COLORTONING_TWOSTD;Standaard chroma +TP_CROP_FIXRATIO;Verhouding: TP_CROP_GTCENTEREDSQUARE;Vierkant gecentreerd +TP_CROP_GTDIAGONALS;Diagonaalmethode +TP_CROP_GTEPASSPORT;Biometrisch paspoort +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Raster +TP_CROP_GTHARMMEANS;Gulden snede +TP_CROP_GTNONE;Geen +TP_CROP_GTRULETHIRDS;Regel van derden +TP_CROP_GTTRIANGLE1;Gouden Driehoek 1 +TP_CROP_GTTRIANGLE2;Gouden Driehoek 2 +TP_CROP_GUIDETYPE;Hulplijnen: +TP_CROP_H;Hoogte +TP_CROP_LABEL;Bijsnijden +TP_CROP_PPI;PPI +TP_CROP_RESETCROP;Terugzetten +TP_CROP_SELECTCROP;Selecteer +TP_CROP_W;Breedte +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Automatische selectie +TP_DARKFRAME_LABEL;Donkerframe +TP_DEFRINGE_LABEL;Verzachten (Lab/CIECAM02) +TP_DEFRINGE_RADIUS;Straal +TP_DEFRINGE_THRESHOLD;Drempel +TP_DEHAZE_DEPTH;Diepte +TP_DEHAZE_LABEL;Nevelvermindering TP_DEHAZE_SATURATION;Verzadiging +TP_DEHAZE_SHOW_DEPTH_MAP;Toon dieptemap +TP_DEHAZE_STRENGTH;Sterkte +TP_DIRPYRDENOISE_CHROMINANCE_AMZ;Auto multi-zone +TP_DIRPYRDENOISE_CHROMINANCE_AUTOGLOBAL;Automatisch algemeen +TP_DIRPYRDENOISE_CHROMINANCE_BLUEYELLOW;Chrominantie Blauw & Geel +TP_DIRPYRDENOISE_CHROMINANCE_CURVE;Chrominantie-curve +TP_DIRPYRDENOISE_CHROMINANCE_CURVE_TOOLTIP;Verhoog (vermenigvuldig) de waarde van alle chrominantieschuiven.\nDeze curve regelt de sterkte van de chromatische ruisvermindering als een functie van de chromaticiteit, om bijvoorbeeld het effect te verhogen in gebieden met weinig verzadiging en te verlagen in gebieden met veel verzadiging. +TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominantie +TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Handmatig +TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Chrominantie (master) +TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Auto-methode +TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nVoorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\nNegen gebieden worden gebruikt om de chroma-ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de Voorbeeld-methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma-ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma-ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Voorbeeld multi-zone +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Voorbeeld +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEWRESIDUAL_INFO_TOOLTIP;Toont de overgebleven ruisniveaus van het zichtbare deel van de afbeelding in het voorbeeld na Wavelet.\n\n>300 Veel ruis\n100-300 Gemiddelde ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB- en L*a*b*-modus. De RGB-waarden zijn minder accuraat omdat de RGB-modus luminantie en chrominantie niet volledig scheidt. +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_INFO;Voorbeeld grootte=%1, Centrum: Px=%2 Py=%3 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO;Voorbeeld ruis: Gemiddeld=%1 Hoog=%2 +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_NOISEINFO_EMPTY;Voorbeeld ruis: Gemiddeld= - Hoog= - +TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW_TILEINFO;Tegelgrootte=%1, Centrum: Tx=%2 Ty=%3 +TP_DIRPYRDENOISE_CHROMINANCE_REDGREEN;Chrominantie Rood & Groen +TP_DIRPYRDENOISE_LABEL;Ruisvermindering +TP_DIRPYRDENOISE_LUMINANCE_CONTROL;Type gereedschap +TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminantie-curve +TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminantie-detail +TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminantie +TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminantie +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compenseer lichtheid +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Wijzig de kracht van de ruisvermindering gebaseerd op de lichtheid van de afbeelding. De kracht wordt minder bij donkere beelden en meer bij heldere beelden. +TP_DIRPYRDENOISE_MAIN_COLORSPACE;Kleurruimte +TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* +TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB +TP_DIRPYRDENOISE_MAIN_COLORSPACE_TOOLTIP;Voor RAW-afbeeldingen kan de RGB- of Lab-methode worden gebruikt.\n\nVoor niet-RAW-afbeeldingen zal altijd de Lab-methode worden gebruikt, ongeacht de geselecteerde methode. +TP_DIRPYRDENOISE_MAIN_GAMMA;Gamma +TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten. +TP_DIRPYRDENOISE_MAIN_MODE;Kwaliteit +TP_DIRPYRDENOISE_MAIN_MODE_AGGRESSIVE;Hoog +TP_DIRPYRDENOISE_MAIN_MODE_CONSERVATIVE;Standaard +TP_DIRPYRDENOISE_MAIN_MODE_TOOLTIP;De kwaliteit kan worden aangepast aan de hoeveelheid ruis. \nHoog verbetert de ruisonderdrukking, maar verlengt de verwerkingstijd +TP_DIRPYRDENOISE_MEDIAN_METHOD;Methode +TP_DIRPYRDENOISE_MEDIAN_METHOD_CHROMINANCE;Alleen Chroma +TP_DIRPYRDENOISE_MEDIAN_METHOD_LAB;L*a*b* +TP_DIRPYRDENOISE_MEDIAN_METHOD_LABEL;Mediaan-filter +TP_DIRPYRDENOISE_MEDIAN_METHOD_LUMINANCE;Alleen Luminantie +TP_DIRPYRDENOISE_MEDIAN_METHOD_RGB;RGB +TP_DIRPYRDENOISE_MEDIAN_METHOD_TOOLTIP;De Alleen Luminantie- en L*a*b*-methodes worden meteen na de Wavelet-stap uitgevoerd bij het onderdrukken van ruis.\nDe RGB-methode wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. +TP_DIRPYRDENOISE_MEDIAN_METHOD_WEIGHTED;Gewogen L* (weinig) + a*b* (normaal) +TP_DIRPYRDENOISE_MEDIAN_PASSES;Mediaan-herhalingen +TP_DIRPYRDENOISE_MEDIAN_PASSES_TOOLTIP;Het gebruik van drie mediaanfilter-herhalingen met een 3×3 venstergrootte geeft meestal een beter resultaat dan het gebruik van één mediaanfilter-herhaling met een 7×7 venstergrootte. +TP_DIRPYRDENOISE_MEDIAN_TYPE;Type +TP_DIRPYRDENOISE_MEDIAN_TYPE_TOOLTIP;Gebruik een mediaanfilter van gewenste venstergrootte. Hoe groter het venster hoe langer het duurt.\n\n3×3 zacht: behandelt 5 pixels in een 3×3 pixelvenster.\n3×3: behandelt 9 pixels in een 3×3 pixelvenster.\n5×5 zacht: behandelt 13 pixels in een 5×5 pixelvenster.\n5×5: behandelt 25 pixels in een 5×5 pixelvenster.\n7×7: behandelt 49 pixels in een 7×7 pixelvenster.\n9×9: behandelt 81 pixels in een 9×9 pixelvenster.\n\nSoms is het mogelijk om een betere kwaliteit te krijgen door het uitvoeren van meerdere herhalingen met een kleiner venster dan één uitvoering met een groter venster. +TP_DIRPYRDENOISE_TYPE_3X3;3×3 +TP_DIRPYRDENOISE_TYPE_3X3SOFT;3×3 zacht +TP_DIRPYRDENOISE_TYPE_5X5;5×5 +TP_DIRPYRDENOISE_TYPE_5X5SOFT;5×5 zacht +TP_DIRPYRDENOISE_TYPE_7X7;7×7 +TP_DIRPYRDENOISE_TYPE_9X9;9×9 +TP_DIRPYREQUALIZER_ALGO;Huid-algoritme +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de huidskleuren, minimaliseert de actie op andere kleuren\nGroot: vermijd onregelmatigheden +TP_DIRPYREQUALIZER_ARTIF;Verminder onregelmatigheden +TP_DIRPYREQUALIZER_HUESKIN;Huidtint +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitiezone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigszins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. +TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) +TP_DIRPYREQUALIZER_LUMACOARSEST;grofste +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;< Contrast +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast > +TP_DIRPYREQUALIZER_LUMAFINEST;fijnste +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutraal +TP_DIRPYREQUALIZER_SKIN;Huidtinten Wijzigen/Beschermen +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Bij -100 worden huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd en alle andere tinten worden gewijzigd +TP_DIRPYREQUALIZER_THRESHOLD;Drempel +TP_DIRPYREQUALIZER_TOOLTIP;Probeer onregelmatigheden te verminderen die het gevolg zijn van een kleurverschuiving van de huidtinten (tint, chroma, luma) en de rest van de afbeelding +TP_DISTORTION_AMOUNT;Hoeveelheid +TP_DISTORTION_AUTO_TOOLTIP;Corrigeert automatisch lensafwijkingen in RAW-afbeeldingen op basis van de ingebedde JPEG indien deze is gecorrigeerd door de camera. +TP_DISTORTION_LABEL;Corrigeer lensvervorming +TP_EPD_EDGESTOPPING;Randen +TP_EPD_GAMMA;Gamma +TP_EPD_LABEL;Tonemapping (Lab/CIECAM02) +TP_EPD_REWEIGHTINGITERATES;Herhaling +TP_EPD_SCALE;Schaal +TP_EPD_STRENGTH;Sterkte +TP_EXPOSURE_AUTOLEVELS;Autom. niveaus +TP_EXPOSURE_AUTOLEVELS_TOOLTIP;Activeer automatische niveaus\nActiveer Herstel Hoge lichten indien nodig. +TP_EXPOSURE_BLACKLEVEL;Schaduwen +TP_EXPOSURE_BRIGHTNESS;Helderheid +TP_EXPOSURE_CLAMPOOG;Kap kleuren die buiten het gamma vallen af +TP_EXPOSURE_CLIP;Afkap % +TP_EXPOSURE_CLIP_TOOLTIP;Het deel van de pixels dat moet worden hersteld bij gebruik van automatische niveaus. +TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten comprimeren +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel compressie hoge lichten +TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR1;Tooncurve 1 +TP_EXPOSURE_CURVEEDITOR2;Tooncurve 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\n The Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_EXPCOMP;Belichtingscompensatie +TP_EXPOSURE_HISTMATCHING;Automatische tooncurve +TP_EXPOSURE_HISTMATCHING_TOOLTIP;Pas automatisch de curves en schuifregelaars aan (behalve belichtingscompensatie) volgens de in de RAW ingebedde JPEG-afbeelding. +TP_EXPOSURE_LABEL;Belichting +TP_EXPOSURE_SATURATION;Verzadiging +TP_EXPOSURE_TCMODE_FILMLIKE;Filmachtig +TP_EXPOSURE_TCMODE_LABEL1;Curve modus 1 +TP_EXPOSURE_TCMODE_LABEL2;Curve modus 2 +TP_EXPOSURE_TCMODE_LUMINANCE;Luminantie +TP_EXPOSURE_TCMODE_PERCEPTUAL;Perceptueel +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Verzadiging en Waarde mengen +TP_EXPOSURE_TCMODE_STANDARD;Standaard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen standaard +TP_EXPOS_BLACKPOINT_LABEL;Raw-zwartpunten +TP_EXPOS_WHITEPOINT_LABEL;Raw-witpunten +TP_FILMNEGATIVE_BLUE;Blauw-verhouding TP_FILMNEGATIVE_BLUEBALANCE;Koel/Warm TP_FILMNEGATIVE_COLORSPACE;Omkeerkleurruimte: TP_FILMNEGATIVE_COLORSPACE_INPUT;Invoerkleurruimte TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;Kies de kleurruimte voor de negatieve omkering:\nInvoerkleurruimte: voer de omkering uit voordat het invoerprofiel wordt toegepast, zoals in eerdere versies van RT.\nWerkkleurruimte: voer de omkering uit na het invoerprofiel en gebruik het momenteel geselecteerde werkprofiel. TP_FILMNEGATIVE_COLORSPACE_WORKING;Werkkleurruimte +TP_FILMNEGATIVE_GREEN;Referentie-exponent (contrast) TP_FILMNEGATIVE_GREENBALANCE;Magenta/Groen +TP_FILMNEGATIVE_GUESS_TOOLTIP;Bepaal automatisch de rood/groen-verhouding door twee gebieden te kiezen met een neutrale tint (geen kleur) in het origineel. De gebieden moeten verschillen in helderheid. Kies de witbalans nadien. +TP_FILMNEGATIVE_LABEL;Filmnegatief TP_FILMNEGATIVE_OUT_LEVEL;Uitvoerniveau +TP_FILMNEGATIVE_PICK;Kies neutrale punten TP_FILMNEGATIVE_PICK_SIZE;Grootte: +TP_FILMNEGATIVE_RED;Rood-verhouding TP_FILMNEGATIVE_REF_LABEL;Invoer RGB: %1 TP_FILMNEGATIVE_REF_PICK;Kies witbalans TP_FILMNEGATIVE_REF_SIZE;Grootte: TP_FILMNEGATIVE_REF_TOOLTIP;Kies een grijspunt om de witbalans van het positieve beeld te bepalen. +TP_FILMSIMULATION_LABEL;Filmsimulatie +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee zoekt naar HaldCLUT-afbeeldingen om de Filmsimulatie uit te voeren, maar deze bevinden zich in een map die teveel tijd kost om te lezen.\n Kijk bij Voorkeuren > Beeldverwerking > Filmsimulatie om te zien welke map gebruikt wordt\nAanbevolen wordt om een map te gebruiken die alleen HaldCLUT-afbeeldingen bevat of kies een lege folder als u Filmsimulatie niet wilt gebruiken.\n\nMeer informatie is te vinden in het (Engelstalige) artikel over Filmsimulatie op RawPedia.\n\nWilt u de scan nu afbreken? +TP_FILMSIMULATION_STRENGTH;Sterkte +TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT-map in Voorkeuren +TP_FLATFIELD_AUTOSELECT;Automatische selectie +TP_FLATFIELD_BLURRADIUS;Verzachten: straal +TP_FLATFIELD_BLURTYPE;Verzachten: type +TP_FLATFIELD_BT_AREA;Gebied +TP_FLATFIELD_BT_HORIZONTAL;Horizontaal +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. +TP_FLATFIELD_BT_VERTICAL;Verticaal +TP_FLATFIELD_CLIPCONTROL;Afkapcontrole +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Afkapcontrole vermijdt uitgevreten hoge lichten veroorzaakt door het toepassen van een vlakveld. Als er al uitgevreten hoge lichten waren voor het toepassen van het vlakveld, dan kan afkapcontrole kleurzweem veroorzaken. TP_FLATFIELD_FROMMETADATA;Uit metadata +TP_FLATFIELD_LABEL;Vlakveld +TP_GENERAL_11SCALE_TOOLTIP;De werking is alleen zichtbaar op schaal 1:1 van het voorbeeld +TP_GRADIENT_CENTER;Centrum +TP_GRADIENT_CENTER_X;Centrum X +TP_GRADIENT_CENTER_X_TOOLTIP;Rotatiepunt X-as: \n-100=linkerkant \n0=centrum \n+100=rechterkant +TP_GRADIENT_CENTER_Y;Centrum Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Rotatiepunt Y-as: \n-100=bovenkant \n0=centrum \n+100=onderkant +TP_GRADIENT_DEGREE;Hoek +TP_GRADIENT_DEGREE_TOOLTIP;Rotatiehoek in graden +TP_GRADIENT_FEATHER;Verloop +TP_GRADIENT_FEATHER_TOOLTIP;Verloop als percentage van de afbeeldingsdiagonaal +TP_GRADIENT_LABEL;Grijsverloopfilter +TP_GRADIENT_STRENGTH;Sterkte +TP_GRADIENT_STRENGTH_TOOLTIP;Filtersterkte in stops +TP_HLREC_BLEND;Mengen +TP_HLREC_CIELAB;CIELab-menging +TP_HLREC_COLOR;Kleurherstel TP_HLREC_COLOROPP;Tegenovergestelde Inpainting +TP_HLREC_ENA_TOOLTIP;Kan worden geactiveerd door automatische niveaus TP_HLREC_HLBLUR;Vervaging TP_HLREC_HLTH;Versterking drempel +TP_HLREC_LABEL;Hoge lichten herstellen +TP_HLREC_LUMINANCE;Lichtherstel +TP_HLREC_METHOD;Methode: +TP_HSVEQUALIZER_CHANNEL;HSV-balans +TP_HSVEQUALIZER_HUE;Tint +TP_HSVEQUALIZER_LABEL;HSV-balans +TP_HSVEQUALIZER_SAT;Verzadiging +TP_HSVEQUALIZER_VAL;Waarde +TP_ICM_APPLYBASELINEEXPOSUREOFFSET;DCP-basisbelichting +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Gebruik de ingebedde DCP-basisbelichting. De instelling is alleen actief als de DCP een basisbelichting heeft. +TP_ICM_APPLYHUESATMAP;DCP-basistabel +TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP-basistabel (HueSatMap). De instelling is alleen actief als de DCP een basistabel heeft. +TP_ICM_APPLYLOOKTABLE;DCP-look-tabel +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP-look-tabel. De instelling is alleen actief als de DCP een look-tabel heeft. +TP_ICM_BPC;Zwartpuntcompensatie +TP_ICM_DCPILLUMINANT;Illuminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren +TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. TP_ICM_FBW;Zwart-wit TP_ICM_GAMUT;Begrens kleurruimte -!TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. +TP_ICM_INPUTCAMERA;Camera standaard +TP_ICM_INPUTCAMERAICC;Camera-specifiek kleurprofiel +TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-invoerkleurprofielen. Deze zijn preciezer dan een eenvoudige matrix maar niet beschikbaar voor alle camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en /dccprofiles en worden automatisch geladen gebaseerd op een bestandsnaam die exact overeenkomt met de modelnaam van de camera. +TP_ICM_INPUTCAMERA_TOOLTIP;Gebruik een eenvoudige kleurenmatrix van dcraw, een uitgebreidere RawTherapee-versie (indien aanwezig voor het cameramodel), of gebruik het ingebedde profiel in de DNG. +TP_ICM_INPUTCUSTOM;Handmatig +TP_ICM_INPUTCUSTOM_TOOLTIP;Selecteer eigen DCP/ICC-kleurenprofiel voor uw camera. +TP_ICM_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... +TP_ICM_INPUTEMBEDDED;Gebruik ingebed profiel, indien mogelijk +TP_ICM_INPUTEMBEDDED_TOOLTIP;Gebruik ingebed profiel, indien mogelijk. +TP_ICM_INPUTNONE;Geen profiel +TP_ICM_INPUTNONE_TOOLTIP;Gebruik geen invoerprofiel. Alleen toepassen in speciale gevallen. +TP_ICM_INPUTPROFILE;Invoerprofiel +TP_ICM_LABEL;Kleurbeheer TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 TP_ICM_NEUTRAL;Zet terug +TP_ICM_NOICM;Geen ICM: sRGB-uitvoer +TP_ICM_OUTPUTPROFILE;Uitvoerprofiel TP_ICM_OUTPUTPROFILE_TOOLTIP;Alle RTv4- of RTv2-profielen zijn met TRC - sRGB: g=2,4 s=12,92\n\nMet de ICC-profielmaker kunt u v4- of v2-profielen creëren met de volgende keuzen:\n-Primaire kleuren: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB en Aangepast\n-TRC: BT709, sRGB, lineair, standaard g=2,2, standaard g=1,8, Aangepast\n-Illuminant: D41, D50, D55, D60, D65, D80, stdA 2856K -!TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 -!TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 -!TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different color mode for an image, you permanently change the color values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic color adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). -!TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 +TP_ICM_PROFILEINTENT;Weergave-intentie TP_ICM_REDFRAME;Aangepaste primaire kleuren +TP_ICM_SAVEREFERENCE;Bewaar referentie-afbeelding +TP_ICM_SAVEREFERENCE_APPLYWB;Toepassen witbalans +TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Gebruik witbalans bij het opslaan van afbeeldingen voor het maken van ICC-profielen. Gebruik geen witbalans bij het maken van DCP-profielen. +TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF-afbeelding op voordat het invoerprofiel is toegepast. Het resultaat kan worden gebruikt voor kalibratie en het genereren van een cameraprofiel. +TP_ICM_TONECURVE;Gebruik DCP-tooncurve +TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP-tooncurve. De instelling is alleen actief als de geselecteerde DCP een tooncurve bevat. TP_ICM_TRCFRAME;Abstract Profiel -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. -!TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +TP_ICM_WORKINGPROFILE;Werkprofiel TP_ICM_WORKING_CIEDIAG;CIE xy diagram TP_ICM_WORKING_ILLU;Illuminant TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3258,7 +2628,6 @@ TP_ICM_WORKING_ILLU_NONE;Standaard TP_ICM_WORKING_ILLU_STDA;stdA 2875K TP_ICM_WORKING_PRESER;Beschermt pasteltinten TP_ICM_WORKING_PRIM;Bestemming primaire kleuren -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3273,28 +2642,87 @@ TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB TP_ICM_WORKING_PRIM_WID;WideGamut +TP_ICM_WORKING_TRC;Tooncurve: TP_ICM_WORKING_TRC_18;Prophoto g=1,8 TP_ICM_WORKING_TRC_22;Adobe g=2,2 TP_ICM_WORKING_TRC_BT709;BT709 g=2,22 s=4,5 +TP_ICM_WORKING_TRC_CUSTOM;Door gebruiker gedefinieerd +TP_ICM_WORKING_TRC_GAMMA;Gamma TP_ICM_WORKING_TRC_LIN;Linear g=1 +TP_ICM_WORKING_TRC_NONE;Geen +TP_ICM_WORKING_TRC_SLOPE;Helling TP_ICM_WORKING_TRC_SRGB;sRGB g=2,4 s=12,92 +TP_ICM_WORKING_TRC_TOOLTIP;Enkel voor ingebouwde profielen. +TP_IMPULSEDENOISE_LABEL;Spot-ruisonderdrukking +TP_IMPULSEDENOISE_THRESH;Drempel +TP_LABCURVE_BRIGHTNESS;Helderheid +TP_LABCURVE_CHROMATICITY;Chromaticiteit +TP_LABCURVE_CHROMA_TOOLTIP;Voor zwartwit, zet Chromaticiteit op -100 +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Luminantiecurve +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Groen verzadigd +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Groen pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rood pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rood verzadigd +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blauw verzadigd +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blauw pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Geel pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Geel verzadigd +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutraal +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Slap +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Verzadigd +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticiteit volgens Chromaticiteit C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticiteit volgens Tint C=f(T) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticiteit volgens Luminantie C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue volgens Tint H=f(T) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminantie volgens Chromaticiteit L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens Tint L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens Luminantie L=f(L) +TP_LABCURVE_LABEL;Lab +TP_LABCURVE_LCREDSK;Beperk LC tot huid- en rode tinten +TP_LABCURVE_LCREDSK_TOOLTIP;Indien ingeschakeld beïnvloedt de LC-curve alleen huid- en rode tinten.\nIndien uitgeschakeld is het van toepassing op alle tinten. +TP_LABCURVE_RSTPROTECTION;Bescherming huid- en rode tinten +TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits-schuifbalk en de CC-curve. +TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden +TP_LENSGEOM_FILL;Automatisch uitvullen +TP_LENSGEOM_LABEL;Objectief / Geometrie +TP_LENSGEOM_LIN;Lineair +TP_LENSGEOM_LOG;Logarithmisch +TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatische selectie +TP_LENSPROFILE_CORRECTION_LCPFILE;LCP-bestand +TP_LENSPROFILE_CORRECTION_MANUAL;Handmatige selectie +TP_LENSPROFILE_LABEL;Lenscorrectieprofielen +TP_LENSPROFILE_LENS_WARNING;Waarschuwing: de gebruikte bijsnijdfactor van het lensprofiel komt niet overeen met de bijsnijdfactor van de camera, de resultaten kunnen onjuist zijn. +TP_LENSPROFILE_MODE_HEADER;Lensprofiel +TP_LENSPROFILE_USE_CA;Chromatische afwijking +TP_LENSPROFILE_USE_GEOMETRIC;Geometrische vervorming +TP_LENSPROFILE_USE_HEADER;Lenscorrecties +TP_LENSPROFILE_USE_VIGNETTING;Vignettering +TP_LOCALCONTRAST_AMOUNT;Hoeveelheid +TP_LOCALCONTRAST_DARKNESS;Donkere delen +TP_LOCALCONTRAST_LABEL;Lokaal contrast +TP_LOCALCONTRAST_LIGHTNESS;Lichte delen +TP_LOCALCONTRAST_RADIUS;Straal TP_LOCALLAB_ACTIV;Alleen luminantie TP_LOCALLAB_ACTIVSPOT;Activeer spot TP_LOCALLAB_ADJ;Kleurequalizer TP_LOCALLAB_AMOUNT;Hoeveelheid TP_LOCALLAB_ARTIF;Vormdetectie -!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE bereik threshold increases the range of ΔE bereik. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the bereik. TP_LOCALLAB_AUTOGRAY;Autom. gemiddelde luminantie (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Auto TP_LOCALLAB_AVOID;Voorkom kleurverschuiving -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. TP_LOCALLAB_AVOIDMUN;Alleen Munsell-correctie -!TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. TP_LOCALLAB_AVOIDRAD;Verzachtingsstraal TP_LOCALLAB_BALAN;ab-L-balans (ΔE) TP_LOCALLAB_BALANEXP;Laplacian-balans TP_LOCALLAB_BALANH;C-H-balans (ΔE) -!TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. TP_LOCALLAB_BASELOG;Bereik schaduwen (logaritmische basis) TP_LOCALLAB_BILATERAL;Bilateraal filter TP_LOCALLAB_BLACK_EV;Zwart LW @@ -3302,29 +2730,21 @@ TP_LOCALLAB_BLCO;Alleen chrominantie TP_LOCALLAB_BLENDMASKCOL;Meng TP_LOCALLAB_BLENDMASKMASK;Voeg toe/trek af luma-masker TP_LOCALLAB_BLENDMASKMASKAB;Voeg toe/trek af chroma-masker -!TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;If this slider = 0 no action.\nAdd or subtract the mask from the original image. -!TP_LOCALLAB_BLENDMASK_TOOLTIP;If blend = 0 only shape detection is improved.\nIf blend > 0 the mask is added to the image. If blend < 0 the mask is subtracted from the image. TP_LOCALLAB_BLGUID;Begeleid filter TP_LOCALLAB_BLINV;Inverteer TP_LOCALLAB_BLLC;Luminantie & Chrominantie TP_LOCALLAB_BLLO;Alleen luminantie TP_LOCALLAB_BLMED;Mediaan -!TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal: direct blur and noise with all settings.\nInverse: blur and noise with all settings. Warning, some settings may give curious results. TP_LOCALLAB_BLNOI_EXP;Vervaging & Ruis TP_LOCALLAB_BLNORM;Normaal TP_LOCALLAB_BLUFR;Vervaging/Korrel & Ruisvermindering -!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for bereik and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the bereik.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. TP_LOCALLAB_BLUR;Gaussiaanse vervaging - Ruis - Korrel TP_LOCALLAB_BLURCOL;Straal -!TP_LOCALLAB_BLURCOLDE_TOOLTIP;The image used to calculate dE is blurred slightly to avoid taking isolated pixels into account. TP_LOCALLAB_BLURDE;Vormdetectie vervaging TP_LOCALLAB_BLURLC;Alleen luminantie TP_LOCALLAB_BLURLEVELFRA;Vervagingsniveaus -!TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. -!TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). TP_LOCALLAB_BLUR_TOOLNAME;Vervaging/Korrel & Ruisvermindering TP_LOCALLAB_BLWH;Alle veranderingen forceren in Zwart-wit -!TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. TP_LOCALLAB_BUTTON_ADD;Voeg toe TP_LOCALLAB_BUTTON_DEL;Wis TP_LOCALLAB_BUTTON_DUPL;Dupliceer @@ -3332,16 +2752,12 @@ TP_LOCALLAB_BUTTON_REN;Hernoem TP_LOCALLAB_BUTTON_VIS;Toon/verberg TP_LOCALLAB_BWFORCE;Gebruik Zwart LW & Wit LW TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Piekluminantie) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. TP_LOCALLAB_CAM16_FRA;Cam16 Beeldaanpassingen TP_LOCALLAB_CAMMODE;CAM-model TP_LOCALLAB_CAMMODE_CAM16;CAM 16 TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz TP_LOCALLAB_CATAD;Chromatische aanpassing/Cat16 TP_LOCALLAB_CBDL;Contrast per Detailniveaus -!TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. -!TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. -!TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. TP_LOCALLAB_CBDL_TOOLNAME;Contrast per Detailniveaus TP_LOCALLAB_CENTER_X;Centrum X TP_LOCALLAB_CENTER_Y;Centrum Y @@ -3350,17 +2766,13 @@ TP_LOCALLAB_CHRO46LABEL;Chroma-niveaus 456: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_CHROLABEL;Chroma-niveaus 0123: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_CHROMA;Chrominantie TP_LOCALLAB_CHROMABLU;Chroma-niveaus -!TP_LOCALLAB_CHROMABLU_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. TP_LOCALLAB_CHROMACBDL;Chroma -!TP_LOCALLAB_CHROMACB_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. TP_LOCALLAB_CHROMALEV;Chroma-niveaus TP_LOCALLAB_CHROMASKCOL;Chroma -!TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Kleurweergave (Cam16 & JzCzHz) TP_LOCALLAB_CIEC;Gebruik Ciecam omgevingsparameters -!TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIECOLORFRA;Kleur TP_LOCALLAB_CIECONTFRA;Contrast TP_LOCALLAB_CIELIGHTCONTFRA;Verlichting & Contrast @@ -3369,28 +2781,19 @@ TP_LOCALLAB_CIEMODE;Verander gereedschapspositie TP_LOCALLAB_CIEMODE_COM;Standaard TP_LOCALLAB_CIEMODE_DR;Dynamisch bereik TP_LOCALLAB_CIEMODE_TM;Toonmappen -!TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. TP_LOCALLAB_CIEMODE_WAV;Wavelet TP_LOCALLAB_CIETOOLEXP;Curven TP_LOCALLAB_CIE_TOOLNAME;Kleurweergave (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Spotgrootte -!TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. TP_LOCALLAB_CLARICRES;Meng chroma TP_LOCALLAB_CLARIFRA;Klaarheid (Clarity) & Scherptemasker/Meng & Verzacht beelden -!TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. TP_LOCALLAB_CLARILRES;Meng luma TP_LOCALLAB_CLARISOFT;Verzacht straal -!TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. -!TP_LOCALLAB_CLARISOFT_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and all wavelet pyramid processes. To deactivate, set slider to zero. TP_LOCALLAB_CLARITYML;Klaarheid (Clarity) -!TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. TP_LOCALLAB_CLIPTM;Kap herstelde data af (versterking) TP_LOCALLAB_COFR;Kleur & Licht TP_LOCALLAB_COLORDE;ΔE Voorbeeldkleur - intensiteit -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. -!TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. -TP_LOCALLAB_COLOR;Bereik (kleurgereedschappen) -!TP_LOCALLAB_COLOR_TOOLTIP;Common bereik slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own bereik controls. +TP_LOCALLAB_COLORSCOPE;Bereik (kleurgereedschappen) TP_LOCALLAB_COLOR_CIE;Kleurcurve TP_LOCALLAB_COLOR_TOOLNAME;Kleur & Licht TP_LOCALLAB_COL_NAME;Naam @@ -3400,47 +2803,27 @@ TP_LOCALLAB_COMPREFRA;Wavelet-niveau toonmappen TP_LOCALLAB_CONTCOL;Contrastdrempel TP_LOCALLAB_CONTFRA;Contrast per niveau TP_LOCALLAB_CONTRAST;Contrast -!TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. TP_LOCALLAB_CONTRESID;Contrast -!TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. TP_LOCALLAB_CONTTHR;Contrastdrempel TP_LOCALLAB_CONTWFRA;Lokaal contrast TP_LOCALLAB_CSTHRESHOLD;Wavelet-niveaus TP_LOCALLAB_CSTHRESHOLDBLUR;Selecteer Wavelet-niveau TP_LOCALLAB_CURV;Lichtheid - Contrast - Chrominantie 'Super' TP_LOCALLAB_CURVCURR;Normaal -!TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tooncurve -!TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. -!TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. TP_LOCALLAB_CURVES_CIE;Tooncurven TP_LOCALLAB_CURVNONE;De-activeer curven TP_LOCALLAB_DARKRETI;Donker TP_LOCALLAB_DEHAFRA;Ontnevelen TP_LOCALLAB_DEHAZ;Kracht -!TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. -!TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. TP_LOCALLAB_DELTAD;Delta-balans TP_LOCALLAB_DELTAEC;ΔE Beeldmasker TP_LOCALLAB_DENOI1_EXP;Ruisvermindering volgens luminantiemasker TP_LOCALLAB_DENOI2_EXP;Herstel volgens luminantiemasker -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. -!TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. -!TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. -!TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Allows you to direct the chroma noise reduction towards either the blue-yellow or red-green colors. -!TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Allows you to carry out more or less noise reduction in either the shadows or the highlights. -!TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). TP_LOCALLAB_DENOIMASK;Chroma-masker ruisvermindering -!TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. -!TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. -!TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominantie TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminantie TP_LOCALLAB_DENOI_EXP;Ruisvermindering -!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n bereik allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. TP_LOCALLAB_DEPTH;Diepte TP_LOCALLAB_DETAIL;Lokaal contrast TP_LOCALLAB_DETAILFRA;Randdetectie - DCT @@ -3454,12 +2837,10 @@ TP_LOCALLAB_ELI;Ellips TP_LOCALLAB_ENABLE_AFTER_MASK;Gebruik toonmappen TP_LOCALLAB_ENABLE_MASK;Activeer masker TP_LOCALLAB_ENABLE_MASKAFT;Gebruik alle algoritmen Belichting -!TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. TP_LOCALLAB_ENH;Verbeterd TP_LOCALLAB_ENHDEN;Verbeterd + chroma-ruisonderdrukking TP_LOCALLAB_EPSBL;Detail TP_LOCALLAB_EQUIL;Normaliseer luminantie -!TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. TP_LOCALLAB_ESTOP;Edge stopping TP_LOCALLAB_EV_DUPL;Kopie van TP_LOCALLAB_EV_NVIS;Verberg @@ -3467,59 +2848,34 @@ TP_LOCALLAB_EV_NVIS_ALL;Verberg allemaal TP_LOCALLAB_EV_VIS;Toon TP_LOCALLAB_EV_VIS_ALL;Toon alles TP_LOCALLAB_EXCLUF;Uitsluiting -!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'bereik' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. TP_LOCALLAB_EXCLUTYPE;Spotmethode -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. TP_LOCALLAB_EXECLU;Sluit spot uit TP_LOCALLAB_EXFULL;Volledige afbeelding TP_LOCALLAB_EXNORM;Normale spot -!TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). TP_LOCALLAB_EXPCHROMA;Chroma-compensatie -!TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. -!TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. TP_LOCALLAB_EXPCOMP;Belichtingscompensatie Æ’ TP_LOCALLAB_EXPCOMPINV;Belichtingscompensatie -!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE bereik threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. -!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'bereik' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. TP_LOCALLAB_EXPCURV;Curven TP_LOCALLAB_EXPGRAD;Verloopfilter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. -!TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. -!TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. -!TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. -!TP_LOCALLAB_EXPLAP_TOOLTIP;Moving the slider to the right progressively reduces the contrast. -!TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a color and luminance background (fewer possibilties). -!TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applies a median filter before the Laplace transform to prevent artifacts (noise).\nYou can also use the 'Denoise' tool. TP_LOCALLAB_EXPOSE;Dynamisch bereik & Belichting -!TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. TP_LOCALLAB_EXPRETITOOLS;Geavanceerde Retinex-gereedschappen -!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'bereik' values to simulate smaller spots. TP_LOCALLAB_EXPTOOL;Belichtingsgereedschappen TP_LOCALLAB_EXP_TOOLNAME;Dynamisch bereik & Belichting TP_LOCALLAB_FATAMOUNT;Hoeveelheid TP_LOCALLAB_FATANCHOR;Anker TP_LOCALLAB_FATDETAIL;Detail TP_LOCALLAB_FATFRA;Compressie dynamisch bereik Æ’ -!TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. TP_LOCALLAB_FATLEVEL;Sigma TP_LOCALLAB_FATSHFRA;Masker compressie dynamisch bereik Æ’ -!TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. TP_LOCALLAB_FEATVALUE;'Veer'verloop (Verloopfilters) TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ -!TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). TP_LOCALLAB_FFTW;Æ’ - Gebruik Fast Fourier-transformatie TP_LOCALLAB_FFTWBLUR;Æ’ - Gebruik altijd Fast Fourier-transformatie -!TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image -!TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. TP_LOCALLAB_GAM;Gamma TP_LOCALLAB_GAMC;Gamma -!TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. TP_LOCALLAB_GAMFRA;Toonresponscurve (TRC) TP_LOCALLAB_GAMM;Gamma TP_LOCALLAB_GAMMASKCOL;Gamma -!TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. TP_LOCALLAB_GAMSH;Gamma TP_LOCALLAB_GAMUTLABRELA;Lab TP_LOCALLAB_GAMUTMUNSELL;Alleen Munsell @@ -3528,47 +2884,31 @@ TP_LOCALLAB_GAMUTXYZABSO;XYZ absoluut TP_LOCALLAB_GAMUTXYZRELA;XYZ relatief TP_LOCALLAB_GAMW;Gamma (wavelet-pyramiden) TP_LOCALLAB_GRADANG;Hoek verloop -!TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. TP_LOCALLAB_GRADFRA;Masker Verloopfilter -!TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. TP_LOCALLAB_GRADLOGFRA;Verloopfilter - Luminantie TP_LOCALLAB_GRADSTR;Verloopsterkte -!TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. TP_LOCALLAB_GRADSTRCHRO;Chroma verloopsterkte TP_LOCALLAB_GRADSTRHUE;Tint verloopsterkte TP_LOCALLAB_GRADSTRHUE2;Tint verloopsterkte -!TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength. TP_LOCALLAB_GRADSTRLUM;Luma verloopsterkte TP_LOCALLAB_GRAINFRA;Filmkorrel 1:1 TP_LOCALLAB_GRAINFRA2;Grofheid -!TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. TP_LOCALLAB_GRALWFRA;Verloopfilter (lokaal contrast) -!TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). -!TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. TP_LOCALLAB_GRIDONE;Kleurtoning TP_LOCALLAB_GRIDTWO;Direct TP_LOCALLAB_GUIDBL;Verzachtingsstraal -!TP_LOCALLAB_GUIDBL_TOOLTIP;Applies a guided filter with adjustable radius. Allows you to reduce artifacts or blur the image. -!TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Changes the distribution function of the guided filter. Negative values simulate a Gaussian blur. TP_LOCALLAB_GUIDFILTER;Straal Begeleid filter -!TP_LOCALLAB_GUIDFILTER_TOOLTIP;Can reduce or increase artifacts. -!TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensity of the guided filter. -!TP_LOCALLAB_HHMASK_TOOLTIP;Fine hue adjustments for example for the skin. TP_LOCALLAB_HIGHMASKCOL;Hoge lichten TP_LOCALLAB_HLH;H TP_LOCALLAB_HUECIE;Tint TP_LOCALLAB_IND;Onafhankelijk (muis) TP_LOCALLAB_INDSL;Onafhankelijk (muis + schuiven) TP_LOCALLAB_INVBL;Inverteer -!TP_LOCALLAB_INVBL_TOOLTIP;Alternative to 'Inverse' mode: use two spots\nFirst Spot:\n Full Image\n\nSecond spot: Excluding spot. TP_LOCALLAB_INVERS;Inverteer -!TP_LOCALLAB_INVERS_TOOLTIP;Fewer possibilities if selected (Inverse).\n\nAlternative: use two spots\nFirst Spot:\n Full Image\n \nSecond spot: Excluding spot\n\n Inverse will enable this tool for the area outside the spot, while the area within the spot will remain unaffected by the tool. TP_LOCALLAB_INVMASK;Keer algoritme om TP_LOCALLAB_ISOGR;Distributie (ISO) TP_LOCALLAB_JAB;Gebruikt Zwart Ev & Wit Ev -!TP_LOCALLAB_JABADAP_TOOLTIP;Perceptual Uniform adaptation.\nAutomatically adjusts the relationship between Jz and saturation taking into account 'Absolute luminance'. TP_LOCALLAB_JZ100;Jz-referentie 100cd/m2 -!TP_LOCALLAB_JZ100_TOOLTIP;Automatically adjusts the reference Jz 100 cd/m2 level (image signal).\nChanges the saturation level and action of 'PU adaptation' (Perceptual Uniform adaptation). TP_LOCALLAB_JZADAP;PU-adaptatie TP_LOCALLAB_JZCH;Chroma TP_LOCALLAB_JZCHROM;Chroma @@ -3576,23 +2916,15 @@ TP_LOCALLAB_JZCLARICRES;Voeg samen met chroma Cz TP_LOCALLAB_JZCLARILRES;Voeg samen Jz TP_LOCALLAB_JZCONT;Contrast TP_LOCALLAB_JZFORCE;Forceer max Jz tot 1 -!TP_LOCALLAB_JZFORCE_TOOLTIP;Allows you to force the maximum Jz value to 1 for better slider and curve response. TP_LOCALLAB_JZFRA;Jz Cz Hz Beeldaanpassingen TP_LOCALLAB_JZHFRA;Curven Hz TP_LOCALLAB_JZHJZFRA;Curve Jz(Hz) TP_LOCALLAB_JZHUECIE;Tintrotatie TP_LOCALLAB_JZLIGHT;Helderheid TP_LOCALLAB_JZLOG;Log-codering Jz -!TP_LOCALLAB_JZLOGWBS_TOOLTIP;Black Ev and White Ev adjustments can be different depending on whether Log encoding or Sigmoid is used.\nFor Sigmoid, a change (increase in most cases) of White Ev may be necessary to obtain a better rendering of highlights, contrast and saturation. -!TP_LOCALLAB_JZLOGWB_TOOLTIP;If Auto is enabled, it will calculate and adjust the Ev levels and the 'Mean luminance Yb%' for the spot area. The resulting values will be used by all Jz operations including 'Log Encoding Jz'.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed as a percentage of gray. 18% gray corresponds to a background luminance of 50% when expressed in CIE L.\nThe data is based on the mean luminance of the image.\nWhen used with Log Encoding, the mean luminance is used to determine the amount of gain that needs to be applied to the signal prior to the log encoding. Lower values of mean luminance will result in increased gain. -!TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (only in 'Advanced' mode). Only operational if the output device (monitor) is HDR (peak luminance higher than 100 cd/m2 - ideally between 4000 and 10000 cd/m2. Black point luminance inferior to 0.005 cd/m2). This supposes a) the ICC-PCS for the screen uses Jzazbz (or XYZ), b) works in real precision, c) that the monitor is calibrated (if possible with a DCI-P3 or Rec-2020 gamut), d) that the usual gamma (sRGB or BT709) is replaced by a Perceptual Quantiser (PQ) function. TP_LOCALLAB_JZPQFRA;Jz herindeling -!TP_LOCALLAB_JZPQFRA_TOOLTIP;Allows you to adapt the Jz algorithm to an SDR environment or to the characteristics (performance) of an HDR environment as follows:\n a) for luminance values between 0 and 100 cd/m2, the system behaves as if it were in an SDR environment.\n b) for luminance values between 100 and 10000 cd/m2, you can adapt the algorithm to the HDR characteristics of the image and the monitor.\n\nIf 'PQ - Peak luminance' is set to 10000, 'Jz remappping' behaves in the same way as the original Jzazbz algorithm. TP_LOCALLAB_JZPQREMAP;PQ - Piekluminantie -!TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - allows you to change the internal PQ function (usually 10000 cd/m2 - default 120 cd/m2).\nCan be used to adapt to different images, processes and devices. TP_LOCALLAB_JZQTOJ;Relatieve luminantie -!TP_LOCALLAB_JZQTOJ_TOOLTIP;Allows you to use 'Relative luminance' instead of 'Absolute luminance' - Brightness becomes Lightness.\nThe changes affect: the Brightness slider, the Contrast slider and the Jz(Jz) curve. TP_LOCALLAB_JZSAT;Verzadiging TP_LOCALLAB_JZSHFRA;Schaduwen/Hoge lichten Jz TP_LOCALLAB_JZSOFTCIE;Verzachtingsstraal (Begeleid filter) @@ -3606,30 +2938,18 @@ TP_LOCALLAB_LABGRID;Kleurcorrectierooster TP_LOCALLAB_LABGRIDMERG;Achtergrond TP_LOCALLAB_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 TP_LOCALLAB_LABSTRUM;Structuurmasker -!TP_LOCALLAB_LAPLACC;ΔØ Mask Laplacian solve PDE TP_LOCALLAB_LAPLACE;Laplacian-drempel ΔE TP_LOCALLAB_LAPLACEXP;Laplacian-drempel TP_LOCALLAB_LAPMASKCOL;Laplacian-drempel -!TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the luminance values of the lighter areas. Can be used in conjunction with the L(L) and LC(H) curves. -!TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAPRAD_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAP_MASK_TOOLTIP;Solves PDEs for all Laplacian masks.\nIf enabled the Laplacian threshold mask reduces artifacts and smooths the result.\nIf disabled the response is linear. TP_LOCALLAB_LCLABELS;Residuele ruisniveaus -!TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. -!TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improves quality and allows the use of large radii, but increases processing time (depends on the area to be processed). Preferable to use only for large radii. The size of the area can be reduced by a few pixels to optimize the FFTW. This can reduce the processing time by a factor of 1.5 to 10. TP_LOCALLAB_LC_TOOLNAME;Lokaal Contrast & Wavelets TP_LOCALLAB_LEVELBLUR;Maximum vervagingsniveaus TP_LOCALLAB_LEVELWAV;Wavelet-niveaus -!TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4. TP_LOCALLAB_LEVFRA;Niveaus TP_LOCALLAB_LIGHTNESS;Lichtheid -!TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse mode: selection = -100 forces luminance to zero. TP_LOCALLAB_LIGHTRETI;Lichtheid TP_LOCALLAB_LINEAR;Lineariteit TP_LOCALLAB_LIST_NAME;Voeg gereedschap toe aan huidige spot... -!TP_LOCALLAB_LIST_TOOLTIP;You can select 3 levels of complexity for each tool: Basic, Standard and Advanced.\nThe default setting for all tools is Basic but this can be changed in the Preferences window.\nYou can also change the level of complexity on a per-tool basis while you are editing. -!TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Allows you to decrease or increase the effect on particular levels of detail in the mask by targeting certain luminance zones (in general the lightest). -!TP_LOCALLAB_LMASK_LL_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts). May create artifacts. TP_LOCALLAB_LOCCONT;Onscherptemasker TP_LOCALLAB_LOC_CONTRAST;Lokaal Contrast & Wavelets TP_LOCALLAB_LOC_CONTRASTPYR;Pyramide 1: @@ -3641,108 +2961,42 @@ TP_LOCALLAB_LOG;Log-codering TP_LOCALLAB_LOG1FRA;CAM16 Beeldaanpassingen TP_LOCALLAB_LOG2FRA;Kijkomstandigheden TP_LOCALLAB_LOGAUTO;Automatisch -!TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions. -!TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. -!TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. -!TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. -!TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. TP_LOCALLAB_LOGCIE;Log-codering ipv. Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. TP_LOCALLAB_LOGCOLORFL;Kleurrijkheid (M) -!TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. TP_LOCALLAB_LOGCONQL;Contrast (Q) TP_LOCALLAB_LOGCONTHRES;Contrastdrempel (J & Q) TP_LOCALLAB_LOGCONTL;Contrast (J) -!TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. -!TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. -!TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. -!TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. TP_LOCALLAB_LOGEXP;Alle gereedschappen TP_LOCALLAB_LOGFRA;Scène-omstandigheden -!TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). TP_LOCALLAB_LOGLIGHTL;Lichtheid (J) -!TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. TP_LOCALLAB_LOGLIGHTQ;Helderheid (Q) -!TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. TP_LOCALLAB_LOGLIN;Logaritmische modus TP_LOCALLAB_LOGPFRA;Relatieve Belichtingsniveaus TP_LOCALLAB_LOGREPART;Overall kracht -!TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. -!TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. -!TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. -!TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the Scene conditions.\n\nAverage: Average light conditions (standard). The image will not change.\n\nDim: Dim conditions. The image will become slightly brighter.\n\nDark: Dark conditions. The image will become more bright. -!TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. TP_LOCALLAB_LOG_TOOLNAME;Log-codering TP_LOCALLAB_LUM;LL - CC TP_LOCALLAB_LUM46LABEL;Luma-niveaus 456: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_LUMADARKEST;Donkerst TP_LOCALLAB_LUMASK;Achtergrondkleur/luma-masker -!TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). TP_LOCALLAB_LUMAWHITESEST;Lichtst TP_LOCALLAB_LUMFRA;L*a*b* standaard TP_LOCALLAB_LUMLABEL;Luma-niveaus 0123: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_MASFRAME;Masker en Combineer -!TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. TP_LOCALLAB_MASK;Curven TP_LOCALLAB_MASK2;Contrastcurve TP_LOCALLAB_MASKCOM;Gemeenschappelijk Kleurmasker -!TP_LOCALLAB_MASKCOM_TOOLNAME;Gemeenschappelijk Kleurmasker -!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of bereik. -!TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. TP_LOCALLAB_MASKDDECAY;Vervalsterkte -!TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. -!TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. -!TP_LOCALLAB_MASKDE_TOOLTIP;Used to target the denoise as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the Denoise will be applied progressively.\n iIf the mask is above the 'light' threshold, then the Denoise will be applied progressively.\n Between the two, the image settings without the Denoise will be maintained, unless you adjust the sliders 'Gray area luminance denoise' or 'Gray area chrominance denoise'. -!TP_LOCALLAB_MASKGF_TOOLTIP;Used to target the Guided Filter as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the GF will be applied progressively.\n If the mask is above the 'light' threshold, then the GF will be applied progressively.\n Between the two, the image settings without the GF will be maintained. TP_LOCALLAB_MASKH;Tintcurve -!TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lighter-tone limit above which CBDL (Luminance only) parameters will be restored progressively to their original values prior to being modified by the CBDL settings .\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\nUse a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable colorpicker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Lighter-tone limit above which Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. TP_LOCALLAB_MASKLCTHR;Lichte gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHR2;Lichte gebieden luma-drempel TP_LOCALLAB_MASKLCTHRLOW;Donkere gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHRLOW2;Donkere gebieden luma-drempel TP_LOCALLAB_MASKLCTHRMID;Grijze gebieden luma-ruisvermindering -!TP_LOCALLAB_MASKLCTHRMIDCH;Grijze gebieden chroma-ruisvermindering -!TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. TP_LOCALLAB_MASKLNOISELOW;Versterk donkere/lichte gebieden -!TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;The denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Dark-tone limit below which the Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;The Guided Filter is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKRECOL_TOOLTIP;Used to modulate the effect of the Color and Light settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Color and Light settings \n In between these two areas, the full value of the Color and Light settings will be applied. TP_LOCALLAB_MASKRECOTHRES;Hersteldrempel -!TP_LOCALLAB_MASKREEXP_TOOLTIP;Used to modulate the effect of the 'Dynamic range and Exposure' settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings \n In between these two areas, the full value of the 'Dynamic range and Exposure' settings will be applied. -!TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Log encoding settings - can be used to restore highlights reconstructed by Color propagation \n In between these two areas, the full value of the Log encoding settings will be applied. -!TP_LOCALLAB_MASKRESCB_TOOLTIP;Used to modulate the effect of the CBDL (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the CBDL settings \n In between these two areas, the full value of the CBDL settings will be applied. -!TP_LOCALLAB_MASKRESH_TOOLTIP;Used to modulate the effect of the Shadows Highlights settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Shadows Highlights settings \n In between these two areas, the full value of the Shadows Highlights settings will be applied. -!TP_LOCALLAB_MASKRESRETI_TOOLTIP;Used to modulate the effect of the Retinex (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Retinex settings \n In between these two areas, the full value of the Retinex settings will be applied. -!TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. -!TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. -!TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. TP_LOCALLAB_MASKUNUSABLE;Masker uitgeschakeld (Masker & modificaties) TP_LOCALLAB_MASKUSABLE;Masker ingeschakeld (Masker & modificaties) -!TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. TP_LOCALLAB_MEDIAN;Mediaan Laag -!TP_LOCALLAB_MEDIANITER_TOOLTIP;The number of successive iterations carried out by the median filter. -!TP_LOCALLAB_MEDIAN_TOOLTIP;You can choose a median value in the range 3x3 to 9x9 pixels. Higher values increase noise reduction and blur. TP_LOCALLAB_MEDNONE;Geen TP_LOCALLAB_MERCOL;Kleur TP_LOCALLAB_MERDCOL;Voeg samen met achtergrond (ΔE) @@ -3752,9 +3006,6 @@ TP_LOCALLAB_MERFOR;Kleur tegenhouden TP_LOCALLAB_MERFOU;Vermenigvuldig TP_LOCALLAB_MERGE1COLFRA;Voeg samen met Origineel/Vorige/Achtergrond TP_LOCALLAB_MERGECOLFRA;Masker: LCh & Structuur -!TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Allows you to create masks based on the 3 LCh curves and/or a structure-detection algorithm. -!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of bereik in this case). -!TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. TP_LOCALLAB_MERHEI;Overlap TP_LOCALLAB_MERHUE;Tint TP_LOCALLAB_MERLUCOL;Luminantie @@ -3772,9 +3023,7 @@ TP_LOCALLAB_MERTHI;Brand kleur TP_LOCALLAB_MERTHR;Verschil TP_LOCALLAB_MERTWE;Uitsluiting TP_LOCALLAB_MERTWO;Aftrekken -!TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. TP_LOCALLAB_MLABEL;Herstelde data Min=%1 Max=%2 -!TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. TP_LOCALLAB_MODE_EXPERT;Geavanceerd TP_LOCALLAB_MODE_NORMAL;Standaard TP_LOCALLAB_MODE_SIMPLE;Basis @@ -3782,25 +3031,17 @@ TP_LOCALLAB_MRFIV;Achtergrond TP_LOCALLAB_MRFOU;Voorgaande spot TP_LOCALLAB_MRONE;Geen TP_LOCALLAB_MRTHR;Originele afbeelding -!TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. TP_LOCALLAB_NEIGH;Radius -!TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. -!TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. -!TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. TP_LOCALLAB_NLDET;Detailherstel TP_LOCALLAB_NLFRA;Non-local Means: Luminantie -!TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. TP_LOCALLAB_NLGAM;Gamma TP_LOCALLAB_NLLUM;Kracht TP_LOCALLAB_NLPAT;Maximale patch-grootte TP_LOCALLAB_NLRAD;Maximale straalgrootte TP_LOCALLAB_NOISECHROCOARSE;Ruw chroma (Wav) -!TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=0.02. TP_LOCALLAB_NOISECHRODETAIL;Chroma detailherstel TP_LOCALLAB_NOISECHROFINE;Fijn chroma (Wav) TP_LOCALLAB_NOISEGAM;Gamma -!TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. TP_LOCALLAB_NOISELEQUAL;Equalizer wit-zwart TP_LOCALLAB_NOISELUMCOARSE;Luminantie grof coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luma detailherstel @@ -3815,12 +3056,9 @@ TP_LOCALLAB_OFFS;Verschuiving TP_LOCALLAB_OFFSETWAV;Verschuiving TP_LOCALLAB_OPACOL;Opaciteit TP_LOCALLAB_ORIGLC;Voeg alleen samen met originele afbeelding -!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'bereik'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). -!TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. TP_LOCALLAB_PASTELS2;Levendigheid TP_LOCALLAB_PDE;Contrastversterker - Compressie Dynamisch bereik TP_LOCALLAB_PDEFRA;Contrastversterker Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. TP_LOCALLAB_PREVHIDE;Verberg extra instellingen TP_LOCALLAB_PREVIEW;Voorbeeld ΔE TP_LOCALLAB_PREVSHOW;Toon extra instellingen @@ -3832,20 +3070,11 @@ TP_LOCALLAB_QUAL_METHOD;Globale kwaliteit TP_LOCALLAB_QUANONEALL;Uit TP_LOCALLAB_QUANONEWAV;Alleen Non-local means TP_LOCALLAB_RADIUS;Radius -!TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. TP_LOCALLAB_RADMASKCOL;Verzachtingsstraal -!TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). TP_LOCALLAB_RECT;Rechthoek TP_LOCALLAB_RECURS;Recursieve referenties -!TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. TP_LOCALLAB_REN_DIALOG_LAB;Geef de nieuwe Control Spot-naam TP_LOCALLAB_REN_DIALOG_NAME;Hernoem Control Spot -!TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Color and Light image with respect to the original image. -!TP_LOCALLAB_REPARDEN_TOOLTIP;Allows you to adjust the relative strength of the Denoise image with respect to the original image. -!TP_LOCALLAB_REPAREXP_TOOLTIP;Allows you to adjust the relative strength of the Dynamic Range and Exposure image with respect to the original image. -!TP_LOCALLAB_REPARSH_TOOLTIP;Allows you to adjust the relative strength of the Shadows/Highlights and Tone Equalizer image with respect to the original image. -!TP_LOCALLAB_REPARTM_TOOLTIP;Allows you to adjust the relative strength of the Tone mapping image with respect to the original image. -!TP_LOCALLAB_REPARW_TOOLTIP;Allows you to adjust the relative strength of the local contrast and wavelet image with respect to the original image. TP_LOCALLAB_RESID;Residuele afbeelding TP_LOCALLAB_RESIDBLUR;Vervaag residuele afbeelding TP_LOCALLAB_RESIDCHRO;Residuele afbeelding Chroma @@ -3857,45 +3086,28 @@ TP_LOCALLAB_RESIDSHA;Schaduwen TP_LOCALLAB_RESIDSHATHR;Drempel schaduwen TP_LOCALLAB_RETI;Ontnevel & Retinex TP_LOCALLAB_RETIFRA;Retinex -!TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex can be useful for processing images: \nthat are blurred, foggy or hazy (in addition to Dehaze).\nthat contain large differences in luminance.\nIt can also be used for special effects (tone mapping). TP_LOCALLAB_RETIM;Originele Retinex TP_LOCALLAB_RETITOOLFRA;Retinex-gereedschappen -!TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Has no effect when the value of 'Lightness = 1' or 'Darkness =2'.\nFor other values, the last step of a 'Multiple scale Retinex' algorithm (similar to 'local contrast') is applied. These 2 cursors, associated with 'Strength' allow you to make adjustments upstream of local contrast. -!TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Adjusts the internal parameters to optimize the response.\nPreferable to keep the 'Restored data' values close to Min=0 and Max=32768 (log mode), but other values are possible. -!TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logarithm mode introduces more contrast but will also generate more halos. -!TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. -!TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. TP_LOCALLAB_RET_TOOLNAME;Ontnevel & Retinex TP_LOCALLAB_REWEI;Herhaling herweging TP_LOCALLAB_RGB;RGB-tooncurve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. TP_LOCALLAB_ROW_NVIS;Niet zichtbaar TP_LOCALLAB_ROW_VIS;Zichtbaar -!TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. TP_LOCALLAB_SATUR;Verzadiging TP_LOCALLAB_SATURV;Verzadiging (s) TP_LOCALLAB_SCALEGR;Schaal TP_LOCALLAB_SCALERETI;Schaal TP_LOCALLAB_SCALTM;Schaal -TP_LOCALLAB_bereikMASK;Bereik (ΔE beeldmasker) -!TP_LOCALLAB_bereikMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. TP_LOCALLAB_SENSI;Bereik TP_LOCALLAB_SENSIEXCLU;Bereik -!TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. -!TP_LOCALLAB_SENSIMASK_TOOLTIP;bereik adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'bereik (ΔE image mask)' in 'Settings' > 'Mask and Merge'. -!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the bereik of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. TP_LOCALLAB_SETTINGS;Instellingen TP_LOCALLAB_SH1;Schaduwen Hoge lichten TP_LOCALLAB_SH2;Equalizer TP_LOCALLAB_SHADEX;Schaduwen TP_LOCALLAB_SHADEXCOMP;Schaduwcompressie TP_LOCALLAB_SHADHIGH;Schaduwen/hoge lichten & Toonequalizer -!TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. TP_LOCALLAB_SHAMASKCOL;Schaduwen TP_LOCALLAB_SHAPETYPE;Spot-vorm -!TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. TP_LOCALLAB_SHARAMOUNT;Hoeveelheid TP_LOCALLAB_SHARBLUR;Vervagingsradius TP_LOCALLAB_SHARDAMPING;Demping @@ -3905,7 +3117,6 @@ TP_LOCALLAB_SHARP;Schaduwen TP_LOCALLAB_SHARP_TOOLNAME;Schaduwen TP_LOCALLAB_SHARRADIUS;Straal TP_LOCALLAB_SHORTC;Korte curves L-masker -!TP_LOCALLAB_SHORTCMASK_TOOLTIP;Short circuit the 2 curves L(L) and L(H).\nAllows you to mix the current image with the original image modified by the mask job.\nUsable with masks 2, 3, 4, 6, 7. TP_LOCALLAB_SHOWC;Masker en modificaties TP_LOCALLAB_SHOWC1;Voeg bestand samen TP_LOCALLAB_SHOWCB;Masker en modificaties @@ -3915,12 +3126,9 @@ TP_LOCALLAB_SHOWFOURIER;Fourier Æ’(dct) TP_LOCALLAB_SHOWLAPLACE;∆ Laplacian (eerste) TP_LOCALLAB_SHOWLC;Masker en modificaties TP_LOCALLAB_SHOWMASK;Toon masker -!TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Displays masks and modifications.\nBeware, you can only view one tool mask at a time.\nShow modified image: shows the modified image including the effect of any adjustments and masks.\nShow modified areas without mask: shows the modifications before any masks are applied.\nShow modified areas with mask: shows the modifications after a mask has been applied.\nShow mask: shows the aspect of the mask including the effect of any curves and filters.\nShow spot structure: allows you to see the structure-detection mask when the 'Spot structure' cursor is activated (when available).\nNote: The mask is applied before the shape detection algorithm. -!TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. TP_LOCALLAB_SHOWMASKTYP1;Vervaging & Ruis TP_LOCALLAB_SHOWMASKTYP2;Ruisvermindering TP_LOCALLAB_SHOWMASKTYP3;Vervaging & Ruis + Ruisvermindering -!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the bereik sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. TP_LOCALLAB_SHOWMNONE;Toon gemodificeerde afbeelding TP_LOCALLAB_SHOWMODIF;Toon gemodificeerde gebieden zonder masker TP_LOCALLAB_SHOWMODIF2;Toon gemodificeerde gebieden @@ -3936,7 +3144,6 @@ TP_LOCALLAB_SHOWSTRUCEX;Toon spotstructuur (Geavanceerd) TP_LOCALLAB_SHOWT;Masker en modificaties TP_LOCALLAB_SHOWVI;Masker en modificaties TP_LOCALLAB_SHRESFRA;Schaduwen/Hoge lichten & TRC -!TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). TP_LOCALLAB_SH_TOOLNAME;Schaduwen/Hoge lichten & Toonequalizer TP_LOCALLAB_SIGFRA;Sigmoid Q & Log-codering Q TP_LOCALLAB_SIGJZFRA;Sigmoid Jz @@ -3945,22 +3152,17 @@ TP_LOCALLAB_SIGMOIDBL;Samenvoegen TP_LOCALLAB_SIGMOIDLAMBDA;Contrast TP_LOCALLAB_SIGMOIDQJ;Gebruikt Zwart Ev & Wit Ev TP_LOCALLAB_SIGMOIDTH;Drempel (Grijspunt) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. TP_LOCALLAB_SLOMASKCOL;Helling -!TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. TP_LOCALLAB_SLOSH;Helling TP_LOCALLAB_SOFT;Zacht licht & Originele Retinex TP_LOCALLAB_SOFTM;Zacht licht -!TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. TP_LOCALLAB_SOFTRADIUSCOL;Radius verzachting -!TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. TP_LOCALLAB_SOFTRETI;Verminder ΔE-onregelmatgheden TP_LOCALLAB_SOFT_TOOLNAME;Zacht licht & Originele Retinex TP_LOCALLAB_SOURCE_ABS;Absolute luminantie TP_LOCALLAB_SOURCE_GRAY;Gemiddelde luminantie (Yb%) TP_LOCALLAB_SPECCASE;Specifieke gevallen TP_LOCALLAB_SPECIAL;Speciaal gebruik van RGB-curven -!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'bereik', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. TP_LOCALLAB_SPOTNAME;Nieuwe spot TP_LOCALLAB_STD;Standaard TP_LOCALLAB_STR;Kracht @@ -3968,18 +3170,13 @@ TP_LOCALLAB_STRBL;Kracht TP_LOCALLAB_STREN;Compressiesterkte TP_LOCALLAB_STRENG;Kracht TP_LOCALLAB_STRENGR;Kracht -!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'bereik' function which allows you to delimit the action (e.g. to isolate a particular color). TP_LOCALLAB_STRENGTH;Ruis TP_LOCALLAB_STRGRID;Kracht TP_LOCALLAB_STRUC;Structuur TP_LOCALLAB_STRUCCOL;Spotstructuur TP_LOCALLAB_STRUCCOL1;Spotstructuur -!TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. TP_LOCALLAB_STRUMASKCOL;Kracht qstructuurmasker -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). -!TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! TP_LOCALLAB_STYPE;Vorm Shape methode -!TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. TP_LOCALLAB_SYM;Symmetrisch (muis) TP_LOCALLAB_SYMSL;Symmetrisch (muis + schuiven) TP_LOCALLAB_TARGET_GRAY;Gemiddelde luminantie (Yb%) @@ -3989,37 +3186,1181 @@ TP_LOCALLAB_THRESDELTAE;Drempel ΔE-bereik TP_LOCALLAB_THRESRETI;Drempel TP_LOCALLAB_THRESWAV;Balansdrempel TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sig=%4 -!TP_LOCALLAB_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. TP_LOCALLAB_TM;Toonmappen TP_LOCALLAB_TM_MASK;Gebruik transmissiemap +TP_LOCALLAB_TONE_TOOLNAME;Toonmappen +TP_LOCALLAB_TOOLCOL;Structuurmasker als gereedschap +TP_LOCALLAB_TOOLMASK;Maskergereedschappen +TP_LOCALLAB_TOOLMASK_2;Wavelets +TP_LOCALLAB_TRANSIT;Transitieverloop +TP_LOCALLAB_TRANSITGRAD;Transitie-differentiatie XY +TP_LOCALLAB_TRANSITVALUE;Transitiewaarde +TP_LOCALLAB_TRANSITWEAK;Transitieverval (lineair-log) +TP_LOCALLAB_TRANSMISSIONGAIN;Transmissieversterking +TP_LOCALLAB_TRANSMISSIONMAP;Transmissiemap +TP_LOCALLAB_USEMASK;Laplacian +TP_LOCALLAB_VART;Variantie (contrast) +TP_LOCALLAB_VIBRANCE;Levendigheid & Warm/Koel +TP_LOCALLAB_VIB_TOOLNAME;Levendigheid & Warm/Koel +TP_LOCALLAB_WARM;Warm/Koel & Kleuronregelmatigheden +TP_LOCALLAB_WAV;Lokaal contrast +TP_LOCALLAB_WAVCOMP;Compressie per niveau +TP_LOCALLAB_WAVCOMPRE;Compressie per niveau +TP_LOCALLAB_WAVCON;Contrast per niveau +TP_LOCALLAB_WAVDEN;Luminantie ruisvermindering +TP_LOCALLAB_WAVE;Wavelets +TP_LOCALLAB_WAVEDG;Lokaal contrast +TP_LOCALLAB_WAVLEV;Vervaag per niveau +TP_LOCALLAB_WAVMASK;Lokaal contrast +TP_LOCALLAB_WEDIANHI;Mediaan Hi +TP_LOCALLAB_WHITE_EV;Wit Ev +TP_LOCALLAB_ZCAMFRA;ZCAM Beeldaanpassingen +TP_LOCALLAB_ZCAMTHRES;Haal hoge data op +TP_LOCAL_HEIGHT;Onder +TP_LOCAL_HEIGHT_T;Boven +TP_LOCAL_WIDTH;Rechts +TP_LOCAL_WIDTH_L;Links +TP_METADATA_EDIT;Pas wijzigingen toe +TP_METADATA_MODE;Metadata kopieermodus +TP_METADATA_STRIP;Strip alle metadata +TP_METADATA_TUNNEL;Kopieer ongewijzigd +TP_NEUTRAL;Terugzetten +TP_NEUTRAL_TOOLTIP;Alle belichtingsinstellingen naar 0 +TP_PCVIGNETTE_FEATHER;Straal +TP_PCVIGNETTE_FEATHER_TOOLTIP;Straal: \n0=alleen hoeken \n50=halverwege tot het centrum \n100=tot aan het centrum +TP_PCVIGNETTE_LABEL;Vignetteringsfilter +TP_PCVIGNETTE_ROUNDNESS;Vorm +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Vorm: \n0=rechthoek \n50=ellips \n100=circel +TP_PCVIGNETTE_STRENGTH;Sterkte +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filtersterkte in stops (volledig in de hoeken). +TP_PDSHARPENING_LABEL;Verscherpen +TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Bijsnijdfactor +TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Brandpuntsafstand +TP_PERSPECTIVE_CAMERA_FRAME;Correctie +TP_PERSPECTIVE_CAMERA_PITCH;Verticaal +TP_PERSPECTIVE_CAMERA_ROLL;Rotatie +TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontale verschuiving +TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Verticale verschuiving +TP_PERSPECTIVE_CAMERA_YAW;Horizontaal +TP_PERSPECTIVE_CONTROL_LINES;Controlelijnen +TP_PERSPECTIVE_HORIZONTAL;Horizontaal +TP_PERSPECTIVE_LABEL;Perspectief +TP_PERSPECTIVE_METHOD;Methode +TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-gebaseerd +TP_PERSPECTIVE_METHOD_SIMPLE;Simpel +TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correctie aanpassingen +TP_PERSPECTIVE_PROJECTION_PITCH;Verticaal +TP_PERSPECTIVE_PROJECTION_ROTATE;Rotatie +TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontale verschuiving +TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Verticale verschuiving +TP_PERSPECTIVE_PROJECTION_YAW;Horizontaal +TP_PERSPECTIVE_RECOVERY_FRAME;Herstel +TP_PERSPECTIVE_VERTICAL;Verticaal +TP_PFCURVE_CURVEEDITOR_CH;Tint +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Bepaalt de mate van verzachten per kleur. Hoger = meer, lager = minder. +TP_PREPROCESS_DEADPIXFILT;Dodepixels-filter +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Onderdrukt dode pixels. +TP_PREPROCESS_GREENEQUIL;Groenbalans +TP_PREPROCESS_HOTPIXFILT;Hetepixels-filter +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Onderdrukt hete pixels. +TP_PREPROCESS_LABEL;Voorbewerking +TP_PREPROCESS_LINEDENOISE;Lijnruisfilter +TP_PREPROCESS_LINEDENOISE_DIRECTION;Richting +TP_PREPROCESS_LINEDENOISE_DIRECTION_BOTH;Beide +TP_PREPROCESS_LINEDENOISE_DIRECTION_HORIZONTAL;Horizontaal +TP_PREPROCESS_LINEDENOISE_DIRECTION_PDAF_LINES;Horizontaal enkel op PDAF-rijen +TP_PREPROCESS_LINEDENOISE_DIRECTION_VERTICAL;Verticaal +TP_PREPROCESS_NO_FOUND;Niet gevonden +TP_PREPROCESS_PDAFLINESFILTER;PDAF-lijnfilter +TP_PREPROCWB_LABEL;Pre-proces witbalans +TP_PREPROCWB_MODE;Modus +TP_PREPROCWB_MODE_AUTO;Auto +TP_PREPROCWB_MODE_CAMERA;Camera +TP_PRSHARPENING_LABEL;Verscherp na verkleinen +TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen actief is en de methode 'Lanczos' is. Omdat verkleinen geen effect heeft op het voorbeeld, heeft 'post-verkleinen verscherping' ook geen effect op het voorbeeld. +TP_RAWCACORR_AUTO;Automatische CA-correctie +TP_RAWCACORR_AUTOIT;Herhalingen +TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische afwijkingen.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. +TP_RAWCACORR_AVOIDCOLORSHIFT;Vermijd kleurverschuiving +TP_RAWCACORR_CABLUE;Blauw +TP_RAWCACORR_CARED;Rood +TP_RAWCACORR_LABEL;Corrigeer chromatische afwijking +TP_RAWEXPOS_BLACK_0;Groen 1 (leidend) +TP_RAWEXPOS_BLACK_1;Rood +TP_RAWEXPOS_BLACK_2;Blauw +TP_RAWEXPOS_BLACK_3;Groen 2 +TP_RAWEXPOS_BLACK_BLUE;Blauw +TP_RAWEXPOS_BLACK_GREEN;Groen +TP_RAWEXPOS_BLACK_RED;Rood +TP_RAWEXPOS_LINEAR;Witpuntcorrectie +TP_RAWEXPOS_RGB;Rood, Groen, Blauw +TP_RAWEXPOS_TWOGREEN;Koppel Groen 1 en 2 +TP_RAW_1PASSMEDIUM;1 keer (Markesteijn) +TP_RAW_2PASS;1-gang+snel +TP_RAW_3PASSBEST;3 gangen (Markesteijn) +TP_RAW_4PASS;3-gangen+snel +TP_RAW_AHD;AHD +TP_RAW_AMAZE;AMaZE +TP_RAW_AMAZEBILINEAR;AMaZE+Bilineair +TP_RAW_AMAZEVNG4;AMaZE+VNG4 +TP_RAW_BORDER;Rand +TP_RAW_DCB;DCB +TP_RAW_DCBBILINEAR;DCB+Bilineair +TP_RAW_DCBENHANCE;DCB-verbetering +TP_RAW_DCBITERATIONS;Aantal DCB-herhalingen +TP_RAW_DCBVNG4;DCB+VNG4 +TP_RAW_DMETHOD;Methode +TP_RAW_DMETHOD_PROGRESSBAR;%1 Demozaïeken... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demozaïekverfijning... +TP_RAW_DMETHOD_TOOLTIP;IGV en LMMSE zijn speciaal bedoeld voor afbeeldingen met hoge ISO-waarden +TP_RAW_DUALDEMOSAICAUTOCONTRAST;Auto-drempel +TP_RAW_DUALDEMOSAICAUTOCONTRAST_TOOLTIP;Als checkbox is aangevinkt (aanbevolen), berekent RT een optimale waarde gebaseerd op vlakke gebieden in de foto.\nIndien die niet gevonden worden of de foto veel ruis bevat, wordt de waarde op 0 gezet.\nOm de waarde handmatig in te voeren moet u eerst de checkbox uitvinken (redelijke waarden zijn afhankelijk van het soort foto). +TP_RAW_DUALDEMOSAICCONTRAST;Contrastdrempel +TP_RAW_EAHD;EAHD +TP_RAW_FALSECOLOR;Stapgrootte kleurfoutonderdrukking +TP_RAW_FAST;Snel +TP_RAW_HD;Drempel +TP_RAW_HD_TOOLTIP;Lagere waarden maken hete/dodepixel-detectie agressiever, maar valse positieven kunnen leiden tot meer onregelmatigheden. Als er onregelmatigheden verschijnen bij het gebruik van de hete/dodepixel-filters, verminder dan geleidelijk de drempelwaarde tot ze verdwijnen. +TP_RAW_HPHD;HPHD +TP_RAW_IGV;IGV +TP_RAW_IMAGENUM;Sub-afbeelding +TP_RAW_IMAGENUM_SN;SN-modus +TP_RAW_IMAGENUM_TOOLTIP;Sommige RAW-bestanden bestaan uit verschillende sub-afbeeldingen (Pentax/Sony Pixel Shift, Pentax 3-in-1 HDR, Canon Dual Pixel, Fuji EXR).\n\Als een andere demozaïekmethode dan Pixel Shift gebruikt wordt, selecteert deze de gebruikte sub-afbeelding.\n\nBij gebruik van de Pixel Shift demozaïekmethode op een Pixel Shift RAW worden alle sub-afbeeldingen gebruikt en dit selecteert de sub-afbeelding die gebruikt wordt voor bewegende gebieden. +TP_RAW_LABEL;Demozaïekproces +TP_RAW_LMMSE;LMMSE +TP_RAW_LMMSEITERATIONS;LMMSE-verbeterstappen +TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1), mediaan (stappen 2-4) en verfijnen (stappen 5-6) om onregelmatigheden te verwijderen en de signaal/ruis-ratio te verbeteren. +TP_RAW_MONO;Mono +TP_RAW_NONE;Geen (Toont sensorpatroon) +TP_RAW_PIXELSHIFT;Pixel Shift +TP_RAW_PIXELSHIFTAVERAGE;Gebruik gemiddelde voor bewegende delen +TP_RAW_PIXELSHIFTBLUR;Vervaag bewegingsmasker +TP_RAW_PIXELSHIFTDMETHOD;Demozaïek voor beweging +TP_RAW_PIXELSHIFTEPERISO;Gevoeligheid +TP_RAW_PIXELSHIFTEPERISO_TOOLTIP;De standaardwaarde 0 werkt goed voor lage ISO-waarden.\nHogere waarden vergroten de gevoeligheid van bewegingsdetectie.\nWijzig in kleine stappen en controleer het bewegingsmasker.\nVerhoog gevoeligheid voor onderbelichte foto's of foto's met hoge ISO-waarden. +TP_RAW_PIXELSHIFTEQUALBRIGHT;Balanceer de helderheid van de frames +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL;Balanceer per kanaal +TP_RAW_PIXELSHIFTEQUALBRIGHTCHANNEL_TOOLTIP;Ingeschakeld: balanceer elk RGB-kanaal afzonderlijk.\nUitgeschakeld: balanceer alle kanalen evenveel. +TP_RAW_PIXELSHIFTEQUALBRIGHT_TOOLTIP;Balanceer de helderheid van de frames ten opzichte van de helderheid van het geselecteerde frame.\nAls er overbelichte gebieden zijn in de frames, selecteer dan het helderste frame om een magenta kleurzweem te vermijden of selecteer bewegingscorrectie. +TP_RAW_PIXELSHIFTGREEN;Controleer groene kanaal voor beweging +TP_RAW_PIXELSHIFTHOLEFILL;Vul holtes in verschuivingsmasker +TP_RAW_PIXELSHIFTHOLEFILL_TOOLTIP;Vul holtes in het verschuivingsmasker op +TP_RAW_PIXELSHIFTMEDIAN;Mediaan +TP_RAW_PIXELSHIFTMEDIAN_TOOLTIP;Gebruik mediaan voor alle frames inplaats van alleen het geselecteerde frame voor gebieden met beweging.\nVerwijder objecten die voorkomen op verschillende plekken in alle frames.\nGeeft bewegingseffect voor langzaam bewegende (overlappende) objecten. +TP_RAW_PIXELSHIFTMM_AUTO;Automatisch +TP_RAW_PIXELSHIFTMM_CUSTOM;Eigen +TP_RAW_PIXELSHIFTMM_OFF;Uit +TP_RAW_PIXELSHIFTMOTIONMETHOD;Bewegingscorrectie +TP_RAW_PIXELSHIFTNONGREENCROSS;Controleer rood/blauw-kanaal voor beweging +TP_RAW_PIXELSHIFTSHOWMOTION;Toon beweging +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY;Toon alleen masker +TP_RAW_PIXELSHIFTSHOWMOTIONMASKONLY_TOOLTIP;Toont het bewegingsmasker zonder de afbeelding +TP_RAW_PIXELSHIFTSHOWMOTION_TOOLTIP;Toont de foto met een groen masker dat de bewegingsgebieden toont. +TP_RAW_PIXELSHIFTSIGMA;Vervagen straal +TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;De standaardstraal van 1,0 is goed voor normale ISO-waarden. Verhoog de waarde voor hogere ISO.\n5,0 is een goed startpunt voor afbeeldingen met hoge ISO-waarden.\nControleer het bewegingsmasker bij het veranderen van de waarde. +TP_RAW_PIXELSHIFTSMOOTH;Zachte overgang +TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Zachte overgang tussen gebieden met en zonder beweging.\nKies 0 om Zachte overgang uit te zetten\nKies 1 voor Amaze/lmmse of Mediaan +TP_RAW_RCD;RCD +TP_RAW_RCDBILINEAR;RCD+Bilineair +TP_RAW_RCDVNG4;RCD+VNG4 +TP_RAW_SENSOR_BAYER_LABEL;Sensor met Bayer-matrix +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-gang geeft het beste resultaat (aanbevolen voor lage ISO-waarden)\n1-gang geeft hetzelfde resultaat als 3-gang voor hoge ISO-afbeeldingen en is sneller. +TP_RAW_SENSOR_XTRANS_LABEL;Sensor met X-Transmatrix +TP_RAW_VNG4;VNG4 +TP_RAW_XTRANS;X-Trans +TP_RAW_XTRANSFAST;Snelle X-Trans +TP_RESIZE_ALLOW_UPSCALING;Sta opschalen toe +TP_RESIZE_APPLIESTO;Toepassen op: +TP_RESIZE_CROPPEDAREA;Uitsnede +TP_RESIZE_FITBOX;Breedte en hoogte +TP_RESIZE_FULLIMAGE;Hele foto +TP_RESIZE_H;H: +TP_RESIZE_HEIGHT;Hoogte +TP_RESIZE_LABEL;Grootte aanpassen +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_LE;Lange zijde: +TP_RESIZE_LONG;Korte zijde +TP_RESIZE_METHOD;Methode: +TP_RESIZE_NEAREST;Dichtstbij +TP_RESIZE_SCALE;Schaal +TP_RESIZE_SE;Korte zijde: +TP_RESIZE_SHORT;Korte zijde +TP_RESIZE_SPECIFY;Specificeer: +TP_RESIZE_W;B: +TP_RESIZE_WIDTH;Breedte +TP_RETINEX_CONTEDIT_HSL;Histogrambalans HSL +TP_RETINEX_CONTEDIT_LAB;Histogrambalans L*a*b* +TP_RETINEX_CONTEDIT_LH;Tintbalans +TP_RETINEX_CONTEDIT_MAP;Equalizer +TP_RETINEX_CURVEEDITOR_CD;L=f(L) +TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminantie volgens luminantie L=f(L).\nCorrigeert ruwe data om halo's en onregelmatigheden te verminderen. +TP_RETINEX_CURVEEDITOR_LH;Sterkte=f(H) +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Sterkte volgens tint, Sterkte=f(H).\nDeze curve wijzigt ook chroma wanneer de Retinex-methode Hoge lichten wordt gebruikt. +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;Deze curve kan zowel losstaand worden gebruikt of in combinatie met een Gaussiaans of wavelet-masker.\nHoud rekening met onregelmatigheden. +TP_RETINEX_EQUAL;Mixer +TP_RETINEX_FREEGAMMA;Vrij gamma +TP_RETINEX_GAIN;Verbeteren +TP_RETINEX_GAINOFFS;Versterking en verschuiving (helderheid) +TP_RETINEX_GAINTRANSMISSION;Transmissieversterking +TP_RETINEX_GAINTRANSMISSION_TOOLTIP;Versterk of verzwak de transmissiemap om de gewenste luminantie te verkrijgen.\nDe x-as is de transmissie.\nDe y-as is de versterking. +TP_RETINEX_GAMMA;Gamma +TP_RETINEX_GAMMA_FREE;Vrij +TP_RETINEX_GAMMA_HIGH;Hoog +TP_RETINEX_GAMMA_LOW;Laag +TP_RETINEX_GAMMA_MID;Midden +TP_RETINEX_GAMMA_NONE;Geen +TP_RETINEX_GAMMA_TOOLTIP;Herstel tinten door gamma voor en na Retinex toe te passen. Verschilt van Retinex-curves en andere curves (Lab, Exposure, etc.). +TP_RETINEX_GRAD;Transmissieverloop +TP_RETINEX_GRADS;Sterkteverloop +TP_RETINEX_GRADS_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Sterkte verminderd en herhaling vergroot, en omgekeerd. +TP_RETINEX_GRAD_TOOLTIP;Indien schuifbalk=0: alle herhalingen zijn gelijk.\nIndien > 0 Variantie en Drempel worden verkleind als herhaling toeneemt, en omgekeerd. +TP_RETINEX_HIGH;Hoog +TP_RETINEX_HIGHLIG;Hoge lichten +TP_RETINEX_HIGHLIGHT;Drempel hoge lichten +TP_RETINEX_HIGHLIGHT_TOOLTIP;Versterkt de werking van de Hoge lichten-methode.\nMogelijk moet Naburige pixels worden aangepast en moet de Witpuntcorrectie in de Raw-tab -> Raw Witpunten worden vergroot. +TP_RETINEX_HSLSPACE_LIN;HSL-Lineair +TP_RETINEX_HSLSPACE_LOG;HSL-Logaritmisch +TP_RETINEX_ITER;Herhalingen (Toonmappen) +TP_RETINEX_ITERF;Toonmappen +TP_RETINEX_ITER_TOOLTIP;Simuleert toonmappen.\nHoge waarden verlengen de bewerkingstijd. +TP_RETINEX_LABEL;Retinex +TP_RETINEX_LABEL_MASK;Masker +TP_RETINEX_LABSPACE;L*a*b* +TP_RETINEX_LOW;Laag +TP_RETINEX_MAP;Methode +TP_RETINEX_MAP_GAUS;Gaussiaans masker +TP_RETINEX_MAP_MAPP;Scherptemasker (wavelet gedeeltelijk) +TP_RETINEX_MAP_MAPT;Scherptemasker (wavelet totaal) +TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en onregelmatigheden te verminderen.\n\nCurve: past een diagonale contrastcurve toe op het masker.\nHou rekening met onregelmatigheden!\n\n Gausiaans: genereert en gebruikt een Gausiaanse vervaging op het masker.\nVerscherpen: genereert en gebruikt een wavelet op het masker.\nLangzaam. +TP_RETINEX_MAP_NONE;Geen +TP_RETINEX_MEDIAN;Transmissiemediaan-filter +TP_RETINEX_METHOD;Methode +TP_RETINEX_METHOD_TOOLTIP;Laag: schaduwen ophelderen,\nUniform: gelijkmatig,\nHoog: versterk hoge lichten,\nHoge lichten: verwijder magenta in hoge lichten. +TP_RETINEX_MLABEL;Teruggeplaatst sluiervrij Min=%1 Max=%2 +TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. +TP_RETINEX_NEIGHBOR;Naburige pixels +TP_RETINEX_NEUTRAL;Beginwaarde +TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarde. +TP_RETINEX_OFFSET;Beginpunt +TP_RETINEX_SCALES;Gaussiaans verloop +TP_RETINEX_SCALES_TOOLTIP;Als schuifbalk = 0, dan zijn alle herhalingen gelijk.\nIndien > 0 dan worden schaal en straal verkleind als de herhaling toeneemt, en omgekeerd. +TP_RETINEX_SETTINGS;Instellingen +TP_RETINEX_SKAL;Schaal +TP_RETINEX_SLOPE;Helling vrij gamma +TP_RETINEX_STRENGTH;Sterkte +TP_RETINEX_THRESHOLD;Drempel +TP_RETINEX_THRESHOLD_TOOLTIP;Beperkt in/uit.\nIn = bron,\nUit = afbeeldings-gauss. +TP_RETINEX_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sigma=%4 +TP_RETINEX_TLABEL2;TM Tm=%1 TM=%2 +TP_RETINEX_TLABEL_TOOLTIP;Transmissieresultaat.\nMin en Max worden gebruikt door Variantie.\nMeeste en Sigma\nTm=Min TM=Max van de transmissie. +TP_RETINEX_TRANF;Transmissie +TP_RETINEX_TRANSMISSION;Transmissiemap +TP_RETINEX_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde, en positieve waarden (max).\nOrdinaat: versterking of vermindering. +TP_RETINEX_UNIFORM;Uniform +TP_RETINEX_VARIANCE;Variantie +TP_RETINEX_VARIANCE_TOOLTIP;Lage variantie versterkt lokaal contrast en verzadiging, maar dit kan artefacten veroorzaken. +TP_RETINEX_VIEW;Proces +TP_RETINEX_VIEW_MASK;Masker +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standaard - Normale weergave.\nMasker - Toont het masker.\nOnscherp masker - Toont de afbeelding met een onscherptemasker met grote straal.\nTransmissie - Auto/Vast - Toont de transmissiemap, voordat actie wordt ondernomen op contrast en helderheid.\n\nLet op: het masker komt niet overeen met de werkelijkheid, maar is versterkt om het effect beter zichtbaar te maken. +TP_RETINEX_VIEW_NONE;Standaard +TP_RETINEX_VIEW_TRAN;Transmissie - Auto +TP_RETINEX_VIEW_TRAN2;Transmissie - Vast +TP_RETINEX_VIEW_UNSHARP;Onscherpmasker +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanaal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB-curven +TP_RGBCURVES_LUMAMODE;Luminositeitsmodus +TP_RGBCURVES_LUMAMODE_TOOLTIP;LuminositeitsmodusVarieert de toewijzing van de R-, G- en B-kanalen aan de luminositeit van de afbeelding, zonder dat de kleur van de afbeelding wijzigt. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Graden +TP_ROTATE_LABEL;Roteren +TP_ROTATE_SELECTLINE;Bepaal rechte lijn +TP_SAVEDIALOG_OK_TOOLTIP;Sneltoets: Ctrl+Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hoge lichten +TP_SHADOWSHLIGHTS_HLTONALW;Toonomvang +TP_SHADOWSHLIGHTS_LABEL;Schaduwen/hoge lichten +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_BLUR;Vervagen straal +TP_SHARPENING_CONTRAST;Contrastdrempel +TP_SHARPENING_EDRADIUS;Straal +TP_SHARPENING_EDTOLERANCE;Randtolerantie +TP_SHARPENING_HALOCONTROL;Halocontrole +TP_SHARPENING_HCAMOUNT;Hoeveelheid +TP_SHARPENING_ITERCHECK;Automatische limiet herhalingen +TP_SHARPENING_LABEL;Verscherpen (Lab/CIECAM02) +TP_SHARPENING_METHOD;Methode +TP_SHARPENING_ONLYEDGES;Alleen randen verscherpen +TP_SHARPENING_RADIUS;Straal +TP_SHARPENING_RADIUS_BOOST;Straalvergroting +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_CONTRAST;Contrastdrempel +TP_SHARPENMICRO_LABEL;Microcontrast (Lab/CIECAM02) +TP_SHARPENMICRO_MATRIX;3×3-matrix ipv. 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformiteit +TP_SOFTLIGHT_LABEL;Zacht licht +TP_SOFTLIGHT_STRENGTH;Sterkte +TP_SPOT_COUNTLABEL;%1 punt(en) +TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte +TP_SPOT_ENTRYCHANGED;Punt veranderd +TP_SPOT_HINT;Klik op deze button... Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. +TP_SPOT_LABEL;Verwijder vlekken +TP_TM_FATTAL_AMOUNT;Hoeveelheid +TP_TM_FATTAL_ANCHOR;Anker +TP_TM_FATTAL_LABEL;Compressie dynamisch bereik +TP_TM_FATTAL_THRESHOLD;Detail +TP_TONE_EQUALIZER_BANDS;Banden +TP_TONE_EQUALIZER_BAND_0;Zwarten +TP_TONE_EQUALIZER_BAND_1;Schaduwen +TP_TONE_EQUALIZER_BAND_2;Middentonen +TP_TONE_EQUALIZER_BAND_3;Hoge lichten +TP_TONE_EQUALIZER_BAND_4;Witten +TP_TONE_EQUALIZER_DETAIL;Fijnafstemming +TP_TONE_EQUALIZER_LABEL;Toonequalizer +TP_TONE_EQUALIZER_PIVOT;Draaipunt (LW) +TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Toon kleurenmap +TP_VIBRANCE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Huidtinten +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rood/Paars +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rood +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rood/Geel +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Geel +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tint volgens Tint +TP_VIBRANCE_LABEL;Levendigheid +TP_VIBRANCE_PASTELS;Pasteltinten +TP_VIBRANCE_PASTSATTOG;Koppel pastel- en verzadigde tinten +TP_VIBRANCE_PROTECTSKINS;Bescherm huidtinten +TP_VIBRANCE_PSTHRESHOLD;Drempel pastel/verzadiging +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Drempel verzadiging +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;De verticale as vertegenwoordigt pasteltinten aan de onderkant en verzadigde tinten aan de bovenkant.\nDe horizontale as vertegenwoordigt het verzadigingsbereik. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Gewicht pastel/verzadigingtransitie +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;Vignetteringscorrectie +TP_VIGNETTING_RADIUS;Straal +TP_VIGNETTING_STRENGTH;Sterkte +TP_WAVELET_1;Niveau 1 +TP_WAVELET_2;Niveau 2 +TP_WAVELET_3;Niveau 3 +TP_WAVELET_4;Niveau 4 +TP_WAVELET_5;Niveau 5 +TP_WAVELET_6;Niveau 6 +TP_WAVELET_7;Niveau 7 +TP_WAVELET_8;Niveau 8 +TP_WAVELET_9;Niveau 9 +TP_WAVELET_APPLYTO;Toepassen +TP_WAVELET_AVOID;Vermijd kleurverschuiving +TP_WAVELET_B0;Zwart +TP_WAVELET_B1;Grijs +TP_WAVELET_B2;Rest +TP_WAVELET_BACKGROUND;Achtergrond +TP_WAVELET_BACUR;Curve +TP_WAVELET_BALANCE;Contrastbalans d/v-h +TP_WAVELET_BALANCE_TOOLTIP;Wijzigt de balans tussen de wavelet-richtingen: vertikaal-horizontaal en diagonaal.\nAls tonemapping in contrast, chromaticiteit of residueel actief zijn, wordt het effect als gevolg van de balans versterkt. +TP_WAVELET_BALCHRO;Chroma-balans +TP_WAVELET_BALCHROM;Equalizer kleur +TP_WAVELET_BALCHRO_TOOLTIP;De Contrastbalans-curve en schuifbalk wijzigen ook de chromaticiteit-balans. +TP_WAVELET_BALLUM;Ruisonderdrukkings-equalizer wit-zwart +TP_WAVELET_BANONE;Geen +TP_WAVELET_BASLI;Schuifbalk +TP_WAVELET_BATYPE;Balansmethode +TP_WAVELET_BL;Vervagingsniveaus +TP_WAVELET_BLCURVE;Vervaag per niveau +TP_WAVELET_BLURFRAME;Vervaag +TP_WAVELET_BLUWAV;Versterkingsrespons +TP_WAVELET_CBENAB;Kleurtint en kleurbalans +TP_WAVELET_CB_TOOLTIP;Met hoge waarden kun je speciale effecten creëren, gelijkend op wat je met de Chroma-module kunt bereiken, maar nu gericht op het residuele beeld. Met kleinere waarden kun je handmatig de witbalans corrigeren. +TP_WAVELET_CCURVE;Lokaal contrast +TP_WAVELET_CH1;Alle chroma's +TP_WAVELET_CH2;Pastel - Verzadigd +TP_WAVELET_CH3;Koppel contrastniveaus +TP_WAVELET_CHCU;Curve +TP_WAVELET_CHR;Koppel Chroma aan Contrast +TP_WAVELET_CHRO;Verzadigd - Pastel +TP_WAVELET_CHROFRAME;Vervaag chrominantie +TP_WAVELET_CHROMAFRAME;Chroma +TP_WAVELET_CHROMCO;Chrominantie grof +TP_WAVELET_CHROMFI;Chrominantie fijn +TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel +TP_WAVELET_CHRWAV;Vervaging chroma +TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met contrastniveaus +TP_WAVELET_CHSL;Schuifbalken +TP_WAVELET_CHTYPE;Chrominantiemethode +TP_WAVELET_CLA;Klaarheid (Clarity) +TP_WAVELET_CLARI;Scherptemasker en Clarity +TP_WAVELET_COLORT;Dekking Rood-Groen niveau +TP_WAVELET_COMPCONT;Contrast +TP_WAVELET_COMPEXPERT;Geavanceerd +TP_WAVELET_COMPGAMMA;Compressie gamma +TP_WAVELET_COMPGAMMA_TOOLTIP;Door het gamma van het residuele beeld te wijzigen, kun je data en histogram in balans brengen. +TP_WAVELET_COMPLEXLAB;Complexiteit +TP_WAVELET_COMPLEX_TOOLTIP;Standaard: toont... shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. +TP_WAVELET_COMPNORMAL;Standaard +TP_WAVELET_COMPTM;Toonmappen +TP_WAVELET_CONTEDIT;'Na'-contrastcurve +TP_WAVELET_CONTFRAME;Contrast - Compressie +TP_WAVELET_CONTR;Kleurenscala - controle +TP_WAVELET_CONTRA;Contrast +TP_WAVELET_CONTRAST_MINUS;< Contrast +TP_WAVELET_CONTRAST_PLUS;Contrast > +TP_WAVELET_CONTRA_TOOLTIP;Wijzigt het contrast van de residuele afbeelding. +TP_WAVELET_CTYPE;Chrominantiesterkte +TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Uitgeschakeld als zoom > ~300% +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Wijzigt lokaal contrast als een functie van het oorspronkelijke lokale contrast (abscis).\nLage absciswaarden vertegenwoordigen weinig lokaal contrast (werkelijke waarden rond 10..20).\n50% abscis vertegenwoordigt gemiddeld lokaal contrast (werkelijke waarden rond 100..300).\n66% abscis vertegenwoordigt de standaarddeviatie van lokaal contrast (werkelijke waarden rond 300..800).\n100% abscis vertegenwoordigt maximaal lokaal contrast (werkelijke waarden rond 3000..8000). +TP_WAVELET_CURVEEDITOR_CH;Contrastniveau=f(Tint) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Wijzigt het contrast van elk niveau als een functie van tint.\nZorg er voor dat de wijzigingen die zijn gemaakt bij de Gamut Tint-toepassing niet worden overschreven.\nDe curve werkt alleen als de Wavelet contrastniveauschuifbalken groter zijn dan nul. +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Contrast luminantiecurve. Wordt uitgevoerd aan het einde van de Wavelet niveaubehandeling. +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Wijzigt de tint van de residuele afbeelding als functie van tint. +TP_WAVELET_DALL;Alle richtingen +TP_WAVELET_DAUB;Randen +TP_WAVELET_DAUB2;D2 - laag +TP_WAVELET_DAUB4;D4 - standaard +TP_WAVELET_DAUB6;D6 - standaard plus +TP_WAVELET_DAUB10;D10 - medium +TP_WAVELET_DAUB14;D14 - hoog +TP_WAVELET_DAUBLOCAL;Wavelet Rand-performance +TP_WAVELET_DAUB_TOOLTIP;Wijzigt de Daubechies-coëfficiënten:\nD4 = Standaard,\nD14 = Geeft meestal het beste resultaat met een iets langere verwerkingstijd.\n\nBeïnvloed zowel randdetectie als het algemene resultaat van de eerste niveaus. De kwaliteit is niet strikt gerelateerd aan deze coëfficiënt en kan variëren per afbeelding en toepassing. +TP_WAVELET_DEN5THR;Begeleid drempel +TP_WAVELET_DENCURV;Curve +TP_WAVELET_DENL;Correctie structuur +TP_WAVELET_DENLH;Begeleid drempel niveaus 1-4 +TP_WAVELET_DENOISE;Gids curve gebaseerd op Lokaal contrast +TP_WAVELET_DENOISEGUID;Begeleide drempel gebaseerd op tint +TP_WAVELET_DENOISEH;Hoge niveaus curve Lokaal contrast +TP_WAVELET_DENOISEHUE;Ruisonderdrukking Tint-equalizer +TP_WAVELET_DENQUA;Modus +TP_WAVELET_DENSIGMA_TOOLTIP;Wijzigt de vorm van de gids +TP_WAVELET_DENSLI;Schuif +TP_WAVELET_DENSLILAB;Methode +TP_WAVELET_DENWAVGUID_TOOLTIP;Gebruikt tint om de actie van het begeleid filter te verminderen of te vermeerderen +TP_WAVELET_DENWAVHUE_TOOLTIP;Versterk of verminder ruisvermindering afhankelijk van de kleur +TP_WAVELET_DETEND;Details +TP_WAVELET_DIRFRAME;Directioneel contrast +TP_WAVELET_DONE;Verticaal +TP_WAVELET_DTHR;Diagonaal +TP_WAVELET_DTWO;Horizontaal +TP_WAVELET_EDCU;Curve +TP_WAVELET_EDEFFECT;Versterkingsrespons +TP_WAVELET_EDGCONT;Lokaal contrast +TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen, naar rechts vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev en maximum. +TP_WAVELET_EDGE;Randen verscherpen (Luminantie) +TP_WAVELET_EDGEAMPLI;Basisversterking +TP_WAVELET_EDGEDETECT;Gradiëntgevoeligheid +TP_WAVELET_EDGEDETECTTHR;Drempel laag (ruis) +TP_WAVELET_EDGEDETECTTHR2;Drempel hoog (detectie) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;Wijzigt de randdetectie. Bijvoorbeeld om randverscherping te voorkomen bij fijne details zoals ruis in de lucht. +TP_WAVELET_EDGEDETECT_TOOLTIP;Beweeg de schuifbalk naar rechts om de randgevoeligheid te vergroten. Dit wijzigt lokaal contrast, randscherpte en ruis. +TP_WAVELET_EDGESENSI;Randgevoeligheid +TP_WAVELET_EDGREINF_TOOLTIP;Versterk of verminder de actie van het eerste niveau en doe het tegenovergestelde voor het tweede niveau; laat de rest ongewijzigd. +TP_WAVELET_EDGTHRESH;Drempel +TP_WAVELET_EDGTHRESH_TOOLTIP;Wijzigt de interactie tussen de eerste niveaus en de andere niveaus. Hoe hoger de drempel hoe meer de actie is gecentreerd op de eerste niveaus. Wees voorzichtig met negatieve waarden. Deze versterken de hogere niveaus en kunnen artefacten veroorzaken. +TP_WAVELET_EDRAD;Straal +TP_WAVELET_EDRAD_TOOLTIP;Deze straalaanpassing verschilt erg van die in de andere verscherpingsgereedschappen. De waarde wordt vergeleken met elk niveau op basis van een complexe functie. In dit geval heeft zelfs een nulwaarde effect. +TP_WAVELET_EDSL;Drempel schuifbalk +TP_WAVELET_EDTYPE;Lokaal contrastmethode +TP_WAVELET_EDVAL;Waarde +TP_WAVELET_FINAL;Finale Bewerking +TP_WAVELET_FINCFRAME;Finaal lokaal contrast +TP_WAVELET_FINEST;fijn +TP_WAVELET_GUIDFRAME;Uiteindelijke verzachting (begeleid filter) +TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantiereeks (0..100) +TP_WAVELET_HS1;Alle luminanties +TP_WAVELET_HS2;Hoge lichten/schaduwen +TP_WAVELET_HUESKIN;Tint reeks (huid) +TP_WAVELET_HUESKIN_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. +TP_WAVELET_HUESKY;Tint Reeks (lucht) +TP_WAVELET_HUESKY_TOOLTIP;De laagste punten vormen het begin van de transitiezone en de bovenste punten het einde. Boven is het effect maximaal.\n\nAls het gebied aanzienlijk moet worden gewijzigd, of als er artefacten ontstaan, dan is de witbalans incorrect. +TP_WAVELET_ITER;Balansniveau +TP_WAVELET_ITER_TOOLTIP;Links: verhoog lage niveaus en verlaag hoge niveaus.\nRechts: verlaag lage niveaus en verhoog hoge niveaus. +TP_WAVELET_LABEL;Wavelet-niveaus +TP_WAVELET_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 +TP_WAVELET_LARGEST;grof +TP_WAVELET_LEVCH;Chromaticiteit +TP_WAVELET_LEVDEN;Niveau 5-6 ruisvermindering +TP_WAVELET_LEVDIR_ALL;Alle niveaus in alle richtingen +TP_WAVELET_LEVDIR_INF;Onder of gelijk aan het niveau +TP_WAVELET_LEVDIR_ONE;Eén niveau +TP_WAVELET_LEVDIR_SUP;Boven het niveau +TP_WAVELET_LEVELHIGH;Straal 5-6 +TP_WAVELET_LEVELLOW;Straal 1-4 +TP_WAVELET_LEVELS;Wavelet-niveaus +TP_WAVELET_LEVELSIGM;Straal +TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detailniveaus. Meer niveaus vereisen meer RAM en de verwerking duurt langer. +TP_WAVELET_LEVF;Contrast +TP_WAVELET_LEVFOUR;Niveau 5-6 ruisvermindering en begeleide drempel +TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveaus=%1 +TP_WAVELET_LEVONE;Niveau 2 +TP_WAVELET_LEVTHRE;Niveau 4 +TP_WAVELET_LEVTWO;Niveau 3 +TP_WAVELET_LEVZERO;Niveau 1 +TP_WAVELET_LIMDEN;Interactie niveaus 5-6 op niveaus 1-4 +TP_WAVELET_LINKEDG;Koppel met Randscherptewaarde +TP_WAVELET_LIPST;Verbeterde methode +TP_WAVELET_LOWLIGHT;Grovere niveaus luminantiebereik (0..100) +TP_WAVELET_LOWTHR_TOOLTIP;Voorkomt versterking van fijne texturen en ruis +TP_WAVELET_MEDGREINF;Eerste niveau +TP_WAVELET_MEDI;Verminder artefacten in blauwe lucht +TP_WAVELET_MEDILEV;Randdetectie +TP_WAVELET_MEDILEV_TOOLTIP;Bij gebruik van Randdetectie:\n- Maak geen gebruik van de lagecontrast-niveaus. Dit voorkomt artefacten.\n- Gebruik de hoge waarden van de Gradiënt-gevoeligheid.\n\nJe kunt de sterkte moduleren met 'verfijnen' van Ruisonderdrukking. +TP_WAVELET_MERGEC;Meng chroma +TP_WAVELET_MERGEL;Meng luma +TP_WAVELET_MIXCONTRAST;Referentie +TP_WAVELET_MIXDENOISE;Ruisvermindering +TP_WAVELET_MIXMIX;Gemengd 50% ruis - 50% ruisvermindering +TP_WAVELET_MIXMIX70;Gemengd 30% ruis - 70% ruisvermindering +TP_WAVELET_MIXNOISE;Ruis +TP_WAVELET_NEUTRAL;Neutraal +TP_WAVELET_NOIS;Ruisonderdrukking +TP_WAVELET_NOISE;Ruisonderdrukking +TP_WAVELET_NPHIGH;Hoog +TP_WAVELET_NPLOW;Laag +TP_WAVELET_NPNONE;Geen +TP_WAVELET_NPTYPE;Naburige pixels +TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan worden randen verscherpt. +TP_WAVELET_OLDSH;Algoritme met negatieve waarden +TP_WAVELET_OPACITY;Dekking Blauw-Geel niveau +TP_WAVELET_OPACITYW;Contrastbalans d/v-h curve +TP_WAVELET_OPACITYWL;Uiteindelijk lokaal contrast +TP_WAVELET_OPACITYWL_TOOLTIP;Wijzigt het lokaal contrast aan het einde van de wavelet-toepassing.\n\nHet lokaal contrast wordt sterker van links naar rechts. +TP_WAVELET_PASTEL;Pastel-chromaciteit +TP_WAVELET_PROC;Proces +TP_WAVELET_PROTAB;Bescherming +TP_WAVELET_QUAAGRES;Agressief +TP_WAVELET_QUACONSER;Conservatief +TP_WAVELET_RADIUS;Straal schaduwen - hoge lichten +TP_WAVELET_RANGEAB;Reeks a en b % +TP_WAVELET_RE1;Versterkt +TP_WAVELET_RE2;Ongewijzigd +TP_WAVELET_RE3;Verminderd +TP_WAVELET_RESBLUR;Vervaging luminantie +TP_WAVELET_RESBLURC;Vervaging chroma +TP_WAVELET_RESBLUR_TOOLTIP;Uitgeschakeld als zoom > ~500% +TP_WAVELET_RESCHRO;Chromaticiteit +TP_WAVELET_RESCON;Schaduwen +TP_WAVELET_RESCONH;Hoge lichten +TP_WAVELET_RESID;Residuele afbeelding +TP_WAVELET_SAT;Verzadigd chromaciteit +TP_WAVELET_SETTINGS;Wavelet-instellingen +TP_WAVELET_SHA;Scherptemasker +TP_WAVELET_SHFRAME;Schaduwen/hoge lichten +TP_WAVELET_SHOWMASK;Toon wavelet-masker +TP_WAVELET_SIGM;Straal +TP_WAVELET_SIGMA;Verzwakkingsrespons +TP_WAVELET_SIGMAFIN;Verzwakkingsrespons +TP_WAVELET_SKIN;Huidtinten wijzigen/beschermen +TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. +TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen +TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in het tintbereik\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... +TP_WAVELET_SOFTRAD;Verzachtingsstraal +TP_WAVELET_STREN;Sterkte +TP_WAVELET_STREND;Kracht +TP_WAVELET_STRENGTH;Sterkte +TP_WAVELET_SUPE;Extra +TP_WAVELET_THR;Drempel schaduwen +TP_WAVELET_THREND;Drempel lokaal contrast +TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) +TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) +TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus van de gekozen waarde tot het gekozen aantal Wavelet-niveaus zullen worden beïnvloed door het Schaduwluminantiebereik. +TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus beneden en inclusief de gekozen waarde zullen worden beïnvloed door het luminantiebereik van de hoge lichten. +TP_WAVELET_THRH;Drempel hoge lichten +TP_WAVELET_TILESBIG;Grote tegels +TP_WAVELET_TILESFULL;Volledige afbeelding +TP_WAVELET_TILESIZE;Tegelgrootte +TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer 'Grote tegels' als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugenaanbevelingen. +TP_WAVELET_TMEDGS;Edge stopping +TP_WAVELET_TMSCALE;Schaal +TP_WAVELET_TMSTRENGTH;Compressiesterkte +TP_WAVELET_TMSTRENGTH_TOOLTIP;Bepaalt de sterkte van het toonmappen of de contrastcompressie. Als de waarde anders is dan 0, dan worden de Sterkte- en Gamma-schuifbalken van Toonmappen in de Belichtingstab inactief. +TP_WAVELET_TMTYPE;Compressiemethode +TP_WAVELET_TON;Kleurtinten +TP_WAVELET_TONFRAME;Uitgesloten kleuren +TP_WAVELET_USH;Geen +TP_WAVELET_USHARP;'Clarity'-methode +TP_WAVELET_WAVLOWTHR;Laag contrast drempel +TP_WAVELET_WAVOFFSET;Verschuiving +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_AUTOITCGREEN;Temperatuurcorrelatie +TP_WBALANCE_AUTOOLD;RGB grijs +TP_WBALANCE_AUTO_HEADER;Automatisch & Verfijning +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Bewolkt +TP_WBALANCE_CUSTOM;Handmatig +TP_WBALANCE_DAYLIGHT;Daglicht (zonnig) +TP_WBALANCE_EQBLUERED;Blauw/Rood-balans +TP_WBALANCE_EQBLUERED_TOOLTIP;Wijzigt het normale gedrag van 'witbalans' door de blauw/rood-balans te veranderen.\nToepassen wanneer de opname-omstandigheden sterk afwijken van: \na) standaardbelichting (bv. onderwater)\nb) de condities waar de kalibraties zijn uitgevoerd\nc) de matrices of ICC-profielen. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standaard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flits +TP_WBALANCE_FLUO1;F1 - Daglicht +TP_WBALANCE_FLUO2;F2 - Koel wit +TP_WBALANCE_FLUO3;F3 - Wit +TP_WBALANCE_FLUO4;F4 - Warm wit +TP_WBALANCE_FLUO5;F5 - Daglicht +TP_WBALANCE_FLUO6;F6 - Licht wit +TP_WBALANCE_FLUO7;F7 - D65 Daglicht simuleren +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Koel wit deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent(TL) +TP_WBALANCE_GREEN;Groentint +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_ITCWB_ALG;Verwijder 2-pas algoritme +TP_WBALANCE_ITCWB_CUSTOM;Gebruik aangepaste temperatuur & tint +TP_WBALANCE_ITCWB_DELTA;Delta temperatuur in groene lus +TP_WBALANCE_ITCWB_FGREEN;Vind groene student +TP_WBALANCE_ITCWB_FORCED;Dichtbij volledig CIE-diagram +TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie +TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimumgrootte +TP_WBALANCE_ITCWB_NOPURPLE;Filter op paars +TP_WBALANCE_ITCWB_PRECIS;Precisie-algoritme - schaal gebruikt +TP_WBALANCE_ITCWB_PRIM_ACE;Forceer gebruik van het gehele CIE-diagram +TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling +TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - nabij Pointer's kleurenscala +TP_WBALANCE_ITCWB_PRIM_JDCMAX;Nabij volledig CIE-diagram +TP_WBALANCE_ITCWB_PRIM_REC;Hoge sampling +TP_WBALANCE_ITCWB_PRIM_SRGB;Lage sampling & Gebruik geen camera-instellingen +TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ-matrix +TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax na camera XYZ-matrix +TP_WBALANCE_ITCWB_RGREEN;Groen bereik +TP_WBALANCE_ITCWB_SAMPLING;Lage sampling 5,9 +TP_WBALANCE_ITCWB_SIZE;Grootte ref.kleur vergelijk met histogram +TP_WBALANCE_ITCWB_SIZEPATCH;Grootte kleur-patch +TP_WBALANCE_ITCWB_THRES;Kleuren gebruikt in afbeelding (voorinstelling) +TP_WBALANCE_ITCWGREEN;Groen verfijning +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_MULLABEL;Vermenigvuldigers: r=%1 g=%2 b=%3 +TP_WBALANCE_OBSERVER10;Observer 10° in plaats van Observer 2° +TP_WBALANCE_PATCHLABEL;Lees kleuren:%1 Patch: Chroma:%2 Grootte=%3 +TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - data x 9 Min:%2 Max=%3 +TP_WBALANCE_PICKER;Kies +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_STUDLABEL;Correlatiefactor: %1 Doorgangen:%2 Slechtst=%3 +TP_WBALANCE_STUDLABEL0;Correlatiefactor: %1 Doorgangen:%2 Alt=%3 +TP_WBALANCE_STUDLABEL1;Correlatiefactor: %1 Doorgangen:%2 Best_alt=%3 +TP_WBALANCE_TEMPBIAS;AWB temperatuur-afwijking +TP_WBALANCE_TEMPBIAS_TOOLTIP;Wijzigt de berekening van auto-witbalans\ndoor een afwijking naar warmere of koelere temperatuur.\nDe afwijking wordt uitgedrukt als percentage van de berekende temperatuur,\nzodat het resultaat is: computedTemp + computedTemp * afwijking. +TP_WBALANCE_TEMPERATURE;Kleurtemperatuur +TP_WBALANCE_TUNGSTEN;Tungsten (wolfraam) +TP_WBALANCE_WATER1;Onderwater 1 +TP_WBALANCE_WATER2;Onderwater 2 +TP_WBALANCE_WATER_HEADER;Onderwater +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Open (nieuw) detailvenster +ZOOMPANEL_ZOOM100;Zoom naar 100%\nSneltoets: Z +ZOOMPANEL_ZOOMFITCROPSCREEN;Maak uitsnede passend in het scherm\nSneltoets: F +ZOOMPANEL_ZOOMFITSCREEN;Passend in venster\nSneltoets: Alt+F +ZOOMPANEL_ZOOMIN;Zoom in\nSneltoets: + +ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. +!HISTORY_MSG_446;--unused-- +!HISTORY_MSG_447;--unused-- +!HISTORY_MSG_448;--unused-- +!HISTORY_MSG_450;--unused-- +!HISTORY_MSG_451;--unused-- +!HISTORY_MSG_454;--unused-- +!HISTORY_MSG_455;--unused-- +!HISTORY_MSG_456;--unused-- +!HISTORY_MSG_458;--unused-- +!HISTORY_MSG_459;--unused-- +!HISTORY_MSG_460;--unused-- +!HISTORY_MSG_461;--unused-- +!HISTORY_MSG_463;--unused-- +!HISTORY_MSG_466;--unused-- +!HISTORY_MSG_467;--unused-- +!HISTORY_MSG_470;--unused-- +!HISTORY_MSG_498;Local - Spot name +!HISTORY_MSG_499;Local - Spot visibility +!HISTORY_MSG_580;--unused-- +!HISTORY_MSG_664;--unused-- +!HISTORY_MSG_ICM_CAT;Matrix adaptation +!HISTORY_MSG_ICM_MIDTCIE;Midtones +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution +!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars +!PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y +!TC_PRIM_REFI;Refine colors (white-point) +!TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. +!TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. +!TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. +!TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). +!TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D50) into new values whose white point is that of the new illuminant - see WP model (for example D75). +!TP_COLORAPP_GEN_TOOLTIP;This module is based on the CIECAM color appearance models, which were designed to better simulate how human vision perceives colors under different lighting conditions, e.g. against different backgrounds. It takes into account the environment of each color and modifies its appearance to get as close as possible to human perception. It also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic appearance is preserved across the scene and display environments. +!TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and latitude. +!TP_COLORAPP_MODELCAT_TOOLTIP;Allows you to choose between CAM02 or CAM16.\nCAM02 will sometimes be more accurate.\nCAM16 should generate fewer artifacts. +!TP_COLORAPP_SOURCEF_TOOLTIP;Corresponds to the shooting conditions and how to bring the conditions and data back to a 'normal' area. Normal means average or standard conditions and data, i.e. without taking into account CIECAM corrections. +!TP_COLORAPP_SURSOURCE_TOOLTIP;Changes tones and colors to take into account the surround conditions of the scene lighting. The darker the surround conditions, the brighter the image will become. Image brightness will not be changed when the surround is set to average. +!TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 +!TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. +!TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. +!TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. +!TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. +!TP_ICM_BW;Black and White +!TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. +!TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 +!TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 +!TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different color mode for an image, you permanently change the color values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic color adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). +!TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. +!TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale +!TP_ICM_WORKING_ILLU_E;E +!TP_ICM_WORKING_NON;None +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata +!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. +!TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. +!TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. +!TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;If this slider = 0 no action.\nAdd or subtract the mask from the original image. +!TP_LOCALLAB_BLENDMASK_TOOLTIP;If blend = 0 only shape detection is improved.\nIf blend > 0 the mask is added to the image. If blend < 0 the mask is subtracted from the image. +!TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal: direct blur and noise with all settings.\nInverse: blur and noise with all settings. Warning, some settings may give curious results. +!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for scope and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the scope.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. +!TP_LOCALLAB_BLURCOLDE_TOOLTIP;The image used to calculate dE is blurred slightly to avoid taking isolated pixels into account. +!TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. +!TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). +!TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. +!TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. +!TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. +!TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. +!TP_LOCALLAB_CHROMABLU_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. +!TP_LOCALLAB_CHROMACB_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. +!TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). +!TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. +!TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None +!TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. +!TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. +!TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. +!TP_LOCALLAB_CLARISOFT_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and all wavelet pyramid processes. To deactivate, set slider to zero. +!TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. +!TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color +!TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. +!TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. +!TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. +!TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. +!TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. +!TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. +!TP_LOCALLAB_DEHAZE_BLACK;Black +!TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. +!TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. +!TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). +!TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. +!TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Allows you to direct the chroma noise reduction towards either the blue-yellow or red-green colors. +!TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Allows you to carry out more or less noise reduction in either the shadows or the highlights. +!TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). +!TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. +!TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. +!TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. +!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools +!TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. +!TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. +!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. +!TP_LOCALLAB_EXMAIN;Global +!TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). +!TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. +!TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. +!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. +!TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. +!TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. +!TP_LOCALLAB_EXPLAP_TOOLTIP;Moving the slider to the right progressively reduces the contrast. +!TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a color and luminance background (fewer possibilties). +!TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applies a median filter before the Laplace transform to prevent artifacts (noise).\nYou can also use the 'Denoise' tool. +!TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. +!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'Scope' values to simulate smaller spots. +!TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. +!TP_LOCALLAB_FATSAT;Saturation control +!TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) +!TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). +!TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image +!TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. +!TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. +!TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. +!TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. +!TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. +!TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. +!TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength. +!TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. +!TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). +!TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. +!TP_LOCALLAB_GUIDBL_TOOLTIP;Applies a guided filter with adjustable radius. Allows you to reduce artifacts or blur the image. +!TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Changes the distribution function of the guided filter. Negative values simulate a Gaussian blur. +!TP_LOCALLAB_GUIDFILTER_TOOLTIP;Can reduce or increase artifacts. +!TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensity of the guided filter. +!TP_LOCALLAB_HHMASK_TOOLTIP;Fine hue adjustments for example for the skin. +!TP_LOCALLAB_INVBL_TOOLTIP;Alternative to 'Inverse' mode: use two spots\nFirst Spot:\n Full Image\n\nSecond spot: Excluding spot. +!TP_LOCALLAB_INVERS_TOOLTIP;Fewer possibilities if selected (Inverse).\n\nAlternative: use two spots\nFirst Spot:\n Full Image\n \nSecond spot: Excluding spot\n\n Inverse will enable this tool for the area outside the spot, while the area within the spot will remain unaffected by the tool. +!TP_LOCALLAB_JABADAP_TOOLTIP;Perceptual Uniform adaptation.\nAutomatically adjusts the relationship between Jz and saturation taking into account 'Absolute luminance'. +!TP_LOCALLAB_JZ100_TOOLTIP;Automatically adjusts the reference Jz 100 cd/m2 level (image signal).\nChanges the saturation level and action of 'PU adaptation' (Perceptual Uniform adaptation). +!TP_LOCALLAB_JZFORCE_TOOLTIP;Allows you to force the maximum Jz value to 1 for better slider and curve response. +!TP_LOCALLAB_JZLOGWBS_TOOLTIP;Black Ev and White Ev adjustments can be different depending on whether Log encoding or Sigmoid is used.\nFor Sigmoid, a change (increase in most cases) of White Ev may be necessary to obtain a better rendering of highlights, contrast and saturation. +!TP_LOCALLAB_JZLOGWB_TOOLTIP;If Auto is enabled, it will calculate and adjust the Ev levels and the 'Mean luminance Yb%' for the spot area. The resulting values will be used by all Jz operations including 'Log Encoding Jz'.\nAlso calculates the absolute luminance at the time of shooting. +!TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed as a percentage of gray. 18% gray corresponds to a background luminance of 50% when expressed in CIE L.\nThe data is based on the mean luminance of the image.\nWhen used with Log Encoding, the mean luminance is used to determine the amount of gain that needs to be applied to the signal prior to the log encoding. Lower values of mean luminance will result in increased gain. +!TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (only in 'Advanced' mode). Only operational if the output device (monitor) is HDR (peak luminance higher than 100 cd/m2 - ideally between 4000 and 10000 cd/m2. Black point luminance inferior to 0.005 cd/m2). This supposes a) the ICC-PCS for the screen uses Jzazbz (or XYZ), b) works in real precision, c) that the monitor is calibrated (if possible with a DCI-P3 or Rec-2020 gamut), d) that the usual gamma (sRGB or BT709) is replaced by a Perceptual Quantiser (PQ) function. +!TP_LOCALLAB_JZPQFRA_TOOLTIP;Allows you to adapt the Jz algorithm to an SDR environment or to the characteristics (performance) of an HDR environment as follows:\n a) for luminance values between 0 and 100 cd/m2, the system behaves as if it were in an SDR environment.\n b) for luminance values between 100 and 10000 cd/m2, you can adapt the algorithm to the HDR characteristics of the image and the monitor.\n\nIf 'PQ - Peak luminance' is set to 10000, 'Jz remappping' behaves in the same way as the original Jzazbz algorithm. +!TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - allows you to change the internal PQ function (usually 10000 cd/m2 - default 120 cd/m2).\nCan be used to adapt to different images, processes and devices. +!TP_LOCALLAB_JZQTOJ_TOOLTIP;Allows you to use 'Relative luminance' instead of 'Absolute luminance' - Brightness becomes Lightness.\nThe changes affect: the Brightness slider, the Contrast slider and the Jz(Jz) curve. +!TP_LOCALLAB_LAPLACC;ΔØ Mask Laplacian solve PDE +!TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the luminance values of the lighter areas. Can be used in conjunction with the L(L) and LC(H) curves. +!TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. +!TP_LOCALLAB_LAPRAD_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. +!TP_LOCALLAB_LAP_MASK_TOOLTIP;Solves PDEs for all Laplacian masks.\nIf enabled the Laplacian threshold mask reduces artifacts and smooths the result.\nIf disabled the response is linear. +!TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. +!TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improves quality and allows the use of large radii, but increases processing time (depends on the area to be processed). Preferable to use only for large radii. The size of the area can be reduced by a few pixels to optimize the FFTW. This can reduce the processing time by a factor of 1.5 to 10. +!TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4. +!TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse mode: selection = -100 forces luminance to zero. +!TP_LOCALLAB_LIST_TOOLTIP;You can select 3 levels of complexity for each tool: Basic, Standard and Advanced.\nThe default setting for all tools is Basic but this can be changed in the Preferences window.\nYou can also change the level of complexity on a per-tool basis while you are editing. +!TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Allows you to decrease or increase the effect on particular levels of detail in the mask by targeting certain luminance zones (in general the lightest). +!TP_LOCALLAB_LMASK_LL_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts). May create artifacts. +!TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions. +!TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. +!TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. +!TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. +!TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. +!TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. +!TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. +!TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. +!TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. +!TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. +!TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). +!TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. +!TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings +!TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. +!TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. +!TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. +!TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the Scene conditions.\n\nAverage: Average light conditions (standard). The image will not change.\n\nDim: Dim conditions. The image will become slightly brighter.\n\nDark: Dark conditions. The image will become more bright. +!TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. +!TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). +!TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. +!TP_LOCALLAB_MASKCOM_TOOLNAME;Common Color Mask +!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of Scope. +!TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. +!TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. +!TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. +!TP_LOCALLAB_MASKDE_TOOLTIP;Used to target the denoise as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the Denoise will be applied progressively.\n iIf the mask is above the 'light' threshold, then the Denoise will be applied progressively.\n Between the two, the image settings without the Denoise will be maintained, unless you adjust the sliders 'Gray area luminance denoise' or 'Gray area chrominance denoise'. +!TP_LOCALLAB_MASKGF_TOOLTIP;Used to target the Guided Filter as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the GF will be applied progressively.\n If the mask is above the 'light' threshold, then the GF will be applied progressively.\n Between the two, the image settings without the GF will be maintained. +!TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lighter-tone limit above which CBDL (Luminance only) parameters will be restored progressively to their original values prior to being modified by the CBDL settings .\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\nUse a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable colorpicker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Lighter-tone limit above which Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise +!TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. +!TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;The denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Dark-tone limit below which the Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;The Guided Filter is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. +!TP_LOCALLAB_MASKRECOL_TOOLTIP;Used to modulate the effect of the Color and Light settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Color and Light settings \n In between these two areas, the full value of the Color and Light settings will be applied. +!TP_LOCALLAB_MASKREEXP_TOOLTIP;Used to modulate the effect of the 'Dynamic range and Exposure' settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings \n In between these two areas, the full value of the 'Dynamic range and Exposure' settings will be applied. +!TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Log encoding settings - can be used to restore highlights reconstructed by Color propagation \n In between these two areas, the full value of the Log encoding settings will be applied. +!TP_LOCALLAB_MASKRESCB_TOOLTIP;Used to modulate the effect of the CBDL (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the CBDL settings \n In between these two areas, the full value of the CBDL settings will be applied. +!TP_LOCALLAB_MASKRESH_TOOLTIP;Used to modulate the effect of the Shadows Highlights settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Shadows Highlights settings \n In between these two areas, the full value of the Shadows Highlights settings will be applied. +!TP_LOCALLAB_MASKRESRETI_TOOLTIP;Used to modulate the effect of the Retinex (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Retinex settings \n In between these two areas, the full value of the Retinex settings will be applied. +!TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. +!TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. +!TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. +!TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. +!TP_LOCALLAB_MEDIANITER_TOOLTIP;The number of successive iterations carried out by the median filter. +!TP_LOCALLAB_MEDIAN_TOOLTIP;You can choose a median value in the range 3x3 to 9x9 pixels. Higher values increase noise reduction and blur. +!TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Allows you to create masks based on the 3 LCh curves and/or a structure-detection algorithm. +!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of scope in this case). +!TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. +!TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones +!TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. +!TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. +!TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. +!TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. +!TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. +!TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. +!TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. +!TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=0.02. +!TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. +!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). +!TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant +!TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. +!TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). +!TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. +!TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Color and Light image with respect to the original image. +!TP_LOCALLAB_REPARDEN_TOOLTIP;Allows you to adjust the relative strength of the Denoise image with respect to the original image. +!TP_LOCALLAB_REPAREXP_TOOLTIP;Allows you to adjust the relative strength of the Dynamic Range and Exposure image with respect to the original image. +!TP_LOCALLAB_REPARSH_TOOLTIP;Allows you to adjust the relative strength of the Shadows/Highlights and Tone Equalizer image with respect to the original image. +!TP_LOCALLAB_REPARTM_TOOLTIP;Allows you to adjust the relative strength of the Tone mapping image with respect to the original image. +!TP_LOCALLAB_REPARW_TOOLTIP;Allows you to adjust the relative strength of the local contrast and wavelet image with respect to the original image. +!TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex can be useful for processing images: \nthat are blurred, foggy or hazy (in addition to Dehaze).\nthat contain large differences in luminance.\nIt can also be used for special effects (tone mapping). +!TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Has no effect when the value of 'Lightness = 1' or 'Darkness =2'.\nFor other values, the last step of a 'Multiple scale Retinex' algorithm (similar to 'local contrast') is applied. These 2 cursors, associated with 'Strength' allow you to make adjustments upstream of local contrast. +!TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Adjusts the internal parameters to optimize the response.\nPreferable to keep the 'Restored data' values close to Min=0 and Max=32768 (log mode), but other values are possible. +!TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logarithm mode introduces more contrast but will also generate more halos. +!TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. +!TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control +!TP_LOCALLAB_SCOPEMASK;Scope (ΔE image mask) +!TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. +!TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. +!TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. +!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. +!TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. +!TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. +!TP_LOCALLAB_SHORTCMASK_TOOLTIP;Short circuit the 2 curves L(L) and L(H).\nAllows you to mix the current image with the original image modified by the mask job.\nUsable with masks 2, 3, 4, 6, 7. +!TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Displays masks and modifications.\nBeware, you can only view one tool mask at a time.\nShow modified image: shows the modified image including the effect of any adjustments and masks.\nShow modified areas without mask: shows the modifications before any masks are applied.\nShow modified areas with mask: shows the modifications after a mask has been applied.\nShow mask: shows the aspect of the mask including the effect of any curves and filters.\nShow spot structure: allows you to see the structure-detection mask when the 'Spot structure' cursor is activated (when available).\nNote: The mask is applied before the shape detection algorithm. +!TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. +!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the Scope sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. +!TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGGAMJCIE;Gamma +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution +!TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing +!TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. +!TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. +!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. +!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). +!TP_LOCALLAB_STRENGTHCIELOG;Strength +!TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! +!TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. +!TP_LOCALLAB_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. !TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;This slider affects edge sensitivity.\n The greater the value, the more likely a change in contrast will be interpreted as an 'edge'.\n If set to zero the tone mapping will have an effect similar to unsharp masking. !TP_LOCALLAB_TONEMAPGAM_TOOLTIP;The Gamma slider shifts the tone-mapping effect towards either the shadows or the highlights. !TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In some cases tone mapping may result in a cartoonish appearance, and in some rare cases soft but wide halos may appear.\n Increasing the number of reweighting iterates will help fight some of these problems. !TP_LOCALLAB_TONEMAP_TOOLTIP;Same as the tone mapping tool in the main menu.\nThe main-menu tool must be deactivated if this tool is used. !TP_LOCALLAB_TONEMASCALE_TOOLTIP;This slider allows you to adjust the transition between 'local' and 'global' contrast.\nThe greater the value, the larger a detail needs to be for it to be boosted. -TP_LOCALLAB_TONE_TOOLNAME;Toonmappen -TP_LOCALLAB_TOOLCOL;Structuurmasker als gereedschap !TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Allows you to modify the mask, if one exists. -TP_LOCALLAB_TOOLMASK;Maskergereedschappen -TP_LOCALLAB_TOOLMASK_2;Wavelets !TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. -TP_LOCALLAB_TRANSIT;Transitieverloop -TP_LOCALLAB_TRANSITGRAD;Transitie-differentiatie XY !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. -TP_LOCALLAB_TRANSITVALUE;Transitiewaarde -TP_LOCALLAB_TRANSITWEAK;Transitieverval (lineair-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. -TP_LOCALLAB_TRANSMISSIONGAIN;Transmissieversterking -TP_LOCALLAB_TRANSMISSIONMAP;Transmissiemap !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. -TP_LOCALLAB_USEMASK;Laplacian -TP_LOCALLAB_VART;Variantie (contrast) -TP_LOCALLAB_VIBRANCE;Levendigheid & Warm/Koel +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. -TP_LOCALLAB_VIB_TOOLNAME;Levendigheid & Warm/Koel !TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtrl+click to show/hide all Control Spot. -TP_LOCALLAB_WARM;Warm/Koel & Kleuronregelmatigheden !TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases. !TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve including the dark-gray/light-gray boundary corresponds to the first 3 levels 0, 1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3, 4, 5, 6). !TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balances the action within each level. @@ -4047,172 +4388,27 @@ TP_LOCALLAB_WARM;Warm/Koel & Kleuronregelmatigheden !TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Allows you to adjust the maximum effect of blurring on the levels. !TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Low to high local contrast from left to right on the x-axis\nIncrease or decrease local contrast on the y-axis. !TP_LOCALLAB_WAT_WAVTM_TOOLTIP;The lower (negative) part compresses each level of decomposition creating a tone mapping effect.\nThe upper (positive) part attenuates the contrast by level.\nThe finest to coarsest levels of decomposition are from left to right on the x-axis. -TP_LOCALLAB_WAV;Lokaal contrast !TP_LOCALLAB_WAVBLUR_TOOLTIP;Allows you to blur each level of the decomposition, as well as the residual image. -TP_LOCALLAB_WAVCOMP;Compressie per niveau -TP_LOCALLAB_WAVCOMPRE;Compressie per niveau !TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Allows you to apply tone mapping or reduce local contrast on individual levels.\nFine to coarse detail levels from left to right on the x-axis. !TP_LOCALLAB_WAVCOMP_TOOLTIP;Allows you to apply local contrast based on the direction of the wavelet decomposition : horizontal, vertical, diagonal. -TP_LOCALLAB_WAVCON;Contrast per niveau !TP_LOCALLAB_WAVCONTF_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -TP_LOCALLAB_WAVDEN;Luminantie ruisvermindering -TP_LOCALLAB_WAVE;Wavelets -TP_LOCALLAB_WAVEDG;Lokaal contrast !TP_LOCALLAB_WAVEEDG_TOOLTIP;Improves sharpness by targeting the action of local contrast on the edges. It has the same functions as the corresponding module in Wavelet Levels and uses the same settings. !TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Range of wavelet levels used in 'Local contrast' (by wavelet level). !TP_LOCALLAB_WAVGRAD_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. !TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. -TP_LOCALLAB_WAVLEV;Vervaag per niveau -TP_LOCALLAB_WAVMASK;Lokaal contrast !TP_LOCALLAB_WAVMASK_TOOLTIP;Uses wavelets to modify the local contrast of the mask and reinforce or reduce the structure (skin, buildings, etc.). -TP_LOCALLAB_WEDIANHI;Mediaan Hi -TP_LOCALLAB_WHITE_EV;Wit Ev -TP_LOCALLAB_ZCAMFRA;ZCAM Beeldaanpassingen -TP_LOCALLAB_ZCAMTHRES;Haal hoge data op -TP_LOCAL_HEIGHT;Onder -TP_LOCAL_HEIGHT_T;Boven -TP_LOCAL_WIDTH;Rechts -TP_LOCAL_WIDTH_L;Links !TP_LOCRETI_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Evenly distributed.\nHigh = Reinforce strong light. -TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Bijsnijdfactor -TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Brandpuntsafstand -TP_PERSPECTIVE_CAMERA_FRAME;Correctie -TP_PERSPECTIVE_CAMERA_PITCH;Verticaal -TP_PERSPECTIVE_CAMERA_ROLL;Rotatie -TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontale verschuiving -TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Verticale verschuiving -TP_PERSPECTIVE_CAMERA_YAW;Horizontaal -TP_PERSPECTIVE_CONTROL_LINES;Controlelijnen !TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+drag: Draw new line\nRight-click: Delete line !TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;At least two horizontal or two vertical control lines required. -TP_PERSPECTIVE_METHOD;Methode -TP_PERSPECTIVE_METHOD_CAMERA_BASED;Camera-gebaseerd -TP_PERSPECTIVE_METHOD_SIMPLE;Simpel -TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correctie aanpassingen -TP_PERSPECTIVE_PROJECTION_PITCH;Verticaal -TP_PERSPECTIVE_PROJECTION_ROTATE;Rotatie -TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontale verschuiving -TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Verticale verschuiving -TP_PERSPECTIVE_PROJECTION_YAW;Horizontaal -TP_PERSPECTIVE_RECOVERY_FRAME;Herstel -TP_PREPROCWB_LABEL;Pre-proces witbalans -TP_PREPROCWB_MODE;Modus -TP_PREPROCWB_MODE_AUTO;Auto -TP_PREPROCWB_MODE_CAMERA;Camera -TP_RAW_AMAZEBILINEAR;AMaZE+Bilineair -TP_RAW_DCBBILINEAR;DCB+Bilineair -TP_RAW_PIXELSHIFTAVERAGE;Gebruik gemiddelde voor bewegende delen !TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Use average of all frames instead of selected frame for regions with motion.\nGives motion effect on slow moving (overlapping) objects. -TP_RAW_RCDBILINEAR;RCD+Bilineair -TP_RESIZE_LE;Lange zijde: -TP_RESIZE_LONG;Korte zijde -TP_RESIZE_SE;Korte zijde: -TP_RESIZE_SHORT;Korte zijde -TP_SPOT_COUNTLABEL;%1 punt(en) -TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte -TP_SPOT_ENTRYCHANGED;Punt veranderd -TP_SPOT_HINT;Klik op deze button... Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. -TP_SPOT_LABEL;Verwijder vlekken -TP_TONE_EQUALIZER_BANDS;Banden -TP_TONE_EQUALIZER_BAND_0;Zwarten -TP_TONE_EQUALIZER_BAND_1;Schaduwen -TP_TONE_EQUALIZER_BAND_2;Middentonen -TP_TONE_EQUALIZER_BAND_3;Hoge lichten -TP_TONE_EQUALIZER_BAND_4;Witten -TP_TONE_EQUALIZER_DETAIL;Fijnafstemming -TP_TONE_EQUALIZER_LABEL;Toonequalizer -TP_TONE_EQUALIZER_PIVOT;Draaipunt (LW) -TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Toon kleurenmap -TP_WAVELET_BALCHROM;Equalizer kleur -TP_WAVELET_BALLUM;Ruisonderdrukkings-equalizer wit-zwart -TP_WAVELET_BL;Vervagingsniveaus -TP_WAVELET_BLCURVE;Vervaag per niveau -TP_WAVELET_BLURFRAME;Vervaag -TP_WAVELET_BLUWAV;Versterkingsrespons -TP_WAVELET_CHROFRAME;Vervaag chrominantie -TP_WAVELET_CHROMAFRAME;Chroma -TP_WAVELET_CHROMCO;Chrominantie grof -TP_WAVELET_CHROMFI;Chrominantie fijn -TP_WAVELET_CHRWAV;Vervaging chroma -TP_WAVELET_CLA;Klaarheid (Clarity) -TP_WAVELET_CLARI;Scherptemasker en Clarity -TP_WAVELET_COMPEXPERT;Geavanceerd -TP_WAVELET_COMPLEXLAB;Complexiteit -TP_WAVELET_COMPLEX_TOOLTIP;Standaard: toont... shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. -TP_WAVELET_COMPNORMAL;Standaard -TP_WAVELET_CONTFRAME;Contrast - Compressie -TP_WAVELET_CURVEEDITOR_BL_TOOLTIP;Uitgeschakeld als zoom > ~300% -TP_WAVELET_DAUBLOCAL;Wavelet Rand-performance -TP_WAVELET_DEN5THR;Begeleid drempel -TP_WAVELET_DENCURV;Curve -TP_WAVELET_DENL;Correctie structuur -TP_WAVELET_DENLH;Begeleid drempel niveaus 1-4 !TP_WAVELET_DENLOCAL_TOOLTIP;Use a curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained. !TP_WAVELET_DENMIX_TOOLTIP;The local-contrast reference value used by the guided filter.\nDepending on the image, results can vary depending on whether the noise is measured before or after the noise reduction. These four choices allow you to take into account various combinations of the original and modified (denoised) images to find the best compromise. -TP_WAVELET_DENOISE;Gids curve gebaseerd op Lokaal contrast -TP_WAVELET_DENOISEGUID;Begeleide drempel gebaseerd op tint -TP_WAVELET_DENOISEH;Hoge niveaus curve Lokaal contrast -TP_WAVELET_DENOISEHUE;Ruisonderdrukking Tint-equalizer -TP_WAVELET_DENQUA;Modus -TP_WAVELET_DENSIGMA_TOOLTIP;Wijzigt de vorm van de gids -TP_WAVELET_DENSLI;Schuif -TP_WAVELET_DENSLILAB;Methode -TP_WAVELET_DENWAVGUID_TOOLTIP;Gebruikt tint om de actie van het begeleid filter te verminderen of te vermeerderen -TP_WAVELET_DENWAVHUE_TOOLTIP;Versterk of verminder ruisvermindering afhankelijk van de kleur -TP_WAVELET_DETEND;Details -TP_WAVELET_DIRFRAME;Directioneel contrast -TP_WAVELET_EDEFFECT;Versterkingsrespons !TP_WAVELET_EDEFFECT_TOOLTIP;This slider selects the range of contrast values that will receive the full effect of any adjustment. -TP_WAVELET_FINCFRAME;Finaal lokaal contrast !TP_WAVELET_FINTHR_TOOLTIP;Uses local contrast to reduce or increase the action of the guided filter. -TP_WAVELET_GUIDFRAME;Uiteindelijke verzachting (begeleid filter) -TP_WAVELET_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 -TP_WAVELET_LEVDEN;Niveau 5-6 ruisvermindering -TP_WAVELET_LEVELHIGH;Straal 5-6 -TP_WAVELET_LEVELLOW;Straal 1-4 -TP_WAVELET_LEVELSIGM;Straal -TP_WAVELET_LEVFOUR;Niveau 5-6 ruisvermindering en begeleide drempel -TP_WAVELET_LIMDEN;Interactie niveaus 5-6 op niveaus 1-4 -TP_WAVELET_LOWTHR_TOOLTIP;Voorkomt versterking van fijne texturen en ruis -TP_WAVELET_MERGEC;Meng chroma -TP_WAVELET_MERGEL;Meng luma -TP_WAVELET_MIXCONTRAST;Referentie -TP_WAVELET_MIXDENOISE;Ruisvermindering -TP_WAVELET_MIXMIX;Gemengd 50% ruis - 50% ruisvermindering -TP_WAVELET_MIXMIX70;Gemengd 30% ruis - 70% ruisvermindering -TP_WAVELET_MIXNOISE;Ruis !TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between low contrast and high contrast details.\nHigh values will amplify contrast changes to the higher contrast details, whereas low values will amplify contrast changes to low contrast details.\nBy using a low Attenuation response value you can select which contrast values will be enhanced. -TP_WAVELET_OLDSH;Algoritme met negatieve waarden -TP_WAVELET_PROTAB;Bescherming -TP_WAVELET_QUAAGRES;Agressief -TP_WAVELET_QUACONSER;Conservatief -TP_WAVELET_RADIUS;Straal schaduwen - hoge lichten -TP_WAVELET_RANGEAB;Reeks a en b % -TP_WAVELET_RESBLUR;Vervaging luminantie -TP_WAVELET_RESBLURC;Vervaging chroma -TP_WAVELET_RESBLUR_TOOLTIP;Uitgeschakeld als zoom > ~500% -TP_WAVELET_SHA;Scherptemasker -TP_WAVELET_SHFRAME;Schaduwen/hoge lichten -TP_WAVELET_SHOWMASK;Toon wavelet-masker -TP_WAVELET_SIGM;Straal -TP_WAVELET_SIGMA;Verzwakkingsrespons -TP_WAVELET_SIGMAFIN;Verzwakkingsrespons !TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values. -TP_WAVELET_SOFTRAD;Verzachtingsstraal -TP_WAVELET_STREND;Kracht !TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. -TP_WAVELET_THREND;Drempel lokaal contrast -TP_WAVELET_TMEDGS;Edge stopping -TP_WAVELET_TMSCALE;Schaal -TP_WAVELET_TONFRAME;Uitgesloten kleuren -TP_WAVELET_USH;Geen -TP_WAVELET_USHARP;'Clarity'-methode !TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, you can choose any level (in Settings) from 1 to 4 for processing.\nIf you select Clarity, you can choose any level (in Settings) between 5 and Extra. -TP_WAVELET_WAVLOWTHR;Laag contrast drempel -TP_WAVELET_WAVOFFSET;Verschuiving -TP_WBALANCE_AUTOITCGREEN;Temperatuurcorrelatie -TP_WBALANCE_AUTOOLD;RGB grijs -TP_WBALANCE_AUTO_HEADER;Automatisch & Verfijning !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4223,46 +4419,16 @@ TP_WBALANCE_AUTO_HEADER;Automatisch & Verfijning !TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;This setting sets the size of color datas used by algorithm. !TP_WBALANCE_ITCWBSIZE_TOOLTIP;This setting sets the number of iterations to find the best correspondence between the reference spectral colors and those in xyY value of the image. A value of 3 seams a good compromise. !TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. -TP_WBALANCE_ITCWB_ALG;Verwijder 2-pas algoritme -TP_WBALANCE_ITCWB_CUSTOM;Gebruik aangepaste temperatuur & tint -TP_WBALANCE_ITCWB_DELTA;Delta temperatuur in groene lus -TP_WBALANCE_ITCWB_FGREEN;Vind groene student -TP_WBALANCE_ITCWB_FORCED;Dichtbij volledig CIE-diagram -TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie !TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. -TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimumgrootte -TP_WBALANCE_ITCWB_NOPURPLE;Filter op paars -TP_WBALANCE_ITCWB_PRECIS;Precisie-algoritme - schaal gebruikt -TP_WBALANCE_ITCWB_PRIM_ACE;Forceer gebruik van het gehele CIE-diagram -TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling -TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - nabij Pointer's kleurenscala -TP_WBALANCE_ITCWB_PRIM_JDCMAX;Nabij volledig CIE-diagram -TP_WBALANCE_ITCWB_PRIM_REC;Hoge sampling -TP_WBALANCE_ITCWB_PRIM_SRGB;Lage sampling & Gebruik geen camera-instellingen -TP_WBALANCE_ITCWB_PRIM_XYZCAM;Camera XYZ-matrix -TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax na camera XYZ-matrix -TP_WBALANCE_ITCWB_RGREEN;Groen bereik -TP_WBALANCE_ITCWB_SAMPLING;Lage sampling 5,9 -TP_WBALANCE_ITCWB_SIZE;Grootte ref.kleur vergelijk met histogram -TP_WBALANCE_ITCWB_SIZEPATCH;Grootte kleur-patch -TP_WBALANCE_ITCWB_THRES;Kleuren gebruikt in afbeelding (voorinstelling) !TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and Green (tint).\n\nUsage tips:\n1) start Itcwb , enable 'Use Custom temperature and tint'.\n2) Set 'Temperature and tint' to your liking :free, Pick,...(Custom)\n3) go back to 'Temperature correlation'.\n\nYou cannot use : 2 passes, AWB temperature bias, Green refinement. !TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. -TP_WBALANCE_ITCWGREEN;Groen verfijning !TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and No use camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) not to use camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. +!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. !TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). -TP_WBALANCE_MULLABEL;Vermenigvuldigers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. -TP_WBALANCE_OBSERVER10;Observer 10° in plaats van Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. -TP_WBALANCE_PATCHLABEL;Lees kleuren:%1 Patch: Chroma:%2 Grootte=%3 +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. -TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - data x 9 Min:%2 Max=%3 !TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Display ΔE patch (this assumes there is enough spectral data), between image and spectral datas.\n Display read datas found. The 2 values correspond to the minimum and maximum data values taken into account. The coefficient x9 must be taken into account to obtain the number of pixels concerned in the image. -TP_WBALANCE_STUDLABEL;Correlatiefactor: %1 Doorgangen:%2 Slechtst=%3 -TP_WBALANCE_STUDLABEL0;Correlatiefactor: %1 Doorgangen:%2 Alt=%3 -TP_WBALANCE_STUDLABEL1;Correlatiefactor: %1 Doorgangen:%2 Best_alt=%3 !TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. !//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. - +!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 7ad5c1792..38995f726 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -92,8 +92,6 @@ EXIFPANEL_RESET;Przywróć EXIFPANEL_RESETALL;Przywróć wszystkie EXIFPANEL_RESETALLHINT;Przywraca orginalne wartoÅ›ci etykiet EXIFPANEL_RESETHINT;Przywraca orginalne wartoÅ›ci wybranych etykiet -EXIFPANEL_SHOWALL;Pokaż wszystkie -EXIFPANEL_SUBDIRECTORY;Podkatalog EXIFPANEL_VALUE_NOT_SHOWN;Nie wyÅ›wietlane EXPORT_BYPASS;Kroki przetwarzania do pominiÄ™cia EXPORT_BYPASS_ALL;Zaznacz / Odznacz wszystkie @@ -1019,7 +1017,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Czcionka narzÄ™dzia do wybierania koloró PREFERENCES_APPEARANCE_CROPMASKCOLOR;Kolor maski kadrowania PREFERENCES_APPEARANCE_MAINFONT;Główny font PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Kolor ramki Nawigatora -PREFERENCES_APPEARANCE_PSEUDOHIDPI; Tryb pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Motyw graficzny PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia PREFERENCES_AUTOMONPROFILE;Automatycznie użyj systemowego profilu monitora @@ -1541,7 +1538,6 @@ TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja podÅ›wietleÅ„ TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Próg kompresji podÅ›wietleÅ„ TP_EXPOSURE_COMPRSHADOWS;Kompresja cieni TP_EXPOSURE_CONTRAST;Kontrast -TP_EXPOSURE_CURVEEDITOR;Krzywa tonalna TP_EXPOSURE_CURVEEDITOR1;Krzywa Tonalna 1 TP_EXPOSURE_CURVEEDITOR2;Krzywa Tonalna 2 TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;WiÄ™cej informacji na temat optymalnego wykorzystania obu krzywych jest dostÄ™pne w podrÄ™czniku (RawTherapee Manual) w dziale:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve\n(NarzÄ™dzie > ZakÅ‚adka Ekspozycji > Krzywe Tonalne) @@ -1632,8 +1628,6 @@ TP_ICM_WORKING_TRC_SLOPE;Nachylenie TP_ICM_WORKING_TRC_TOOLTIP;Tylko dla wbudowanych profili. TP_IMPULSEDENOISE_LABEL;Redukcja Szumów Impulsowych TP_IMPULSEDENOISE_THRESH;Próg -TP_LABCURVE_AVOIDCOLORSHIFT;Zapobiegaj zmianom koloru -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Umieszcza kolory w gamie roboczej przestrzeni kolorów i stosuje korektÄ™ Munsell'a TP_LABCURVE_BRIGHTNESS;ÅšwiatÅ‚ość TP_LABCURVE_CHROMATICITY;Chromatyczność TP_LABCURVE_CHROMA_TOOLTIP;Aby zastosować tonowanie zdjÄ™cia B&W, ustaw chromatyczność na -100. @@ -2073,6 +2067,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !HISTORY_MSG_500;Local - Spot shape !HISTORY_MSG_501;Local - Spot method !HISTORY_MSG_502;Local - SC - Shape method @@ -2088,7 +2083,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2398,7 +2393,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2641,7 +2636,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2748,16 +2743,23 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2765,7 +2767,72 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_PDSHARPEN_RADIUS_BOOST;CS - Corner radius boost @@ -2878,18 +2945,18 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !IPTCPANEL_SOURCEHINT;Enter or edit the name of a person or party who has a role in the content supply chain, such as a person or entity from whom you received this image from. !IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image. !IPTCPANEL_TITLEHINT;Enter a short verbal and human readable name for the image, this may be the file name. -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !OPTIONS_BUNDLED_MISSING;The bundled profile '%1' could not be found!\n\nYour installation could be damaged.\n\nDefault internal values will be used instead. !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\n'%1' will be used instead. !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\n'%1' will be used instead. !PARTIALPASTE_EQUALIZER;Wavelet levels !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter !PARTIALPASTE_PREPROCWB;Preprocess White Balance @@ -2902,13 +2969,16 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2931,6 +3001,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -2942,18 +3013,22 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_PRINTER;Printer (Soft-Proofing) !PREFERENCES_PROFILESAVEBOTH;Save processing profile both to the cache and next to the input file !PREFERENCES_PRTINTENT;Rendering intent +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Embedded JPEG preview !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2976,6 +3051,27 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. @@ -2988,12 +3084,16 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. @@ -3087,6 +3187,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only available if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3102,8 +3203,15 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_ICM_SAVEREFERENCE;Save Reference Image !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3115,11 +3223,13 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3128,17 +3238,21 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 !TP_ICM_WORKING_TRC_BT709;BT709 g=2.22 s=4.5 !TP_ICM_WORKING_TRC_LIN;Linear g=1 !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ACTIVSPOT;Enable Spot @@ -3147,9 +3261,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3192,9 +3306,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3234,6 +3351,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3249,8 +3372,9 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3258,7 +3382,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3273,7 +3400,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3282,13 +3409,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3308,6 +3436,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3316,6 +3445,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3331,9 +3461,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3342,11 +3473,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3368,7 +3499,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3464,7 +3596,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3509,8 +3641,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3518,7 +3652,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3531,6 +3665,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3600,7 +3735,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3636,6 +3771,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3683,10 +3819,15 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3731,10 +3872,11 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3755,7 +3897,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3801,17 +3943,41 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3833,13 +3999,14 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3871,11 +4038,12 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4203,7 +4371,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4246,7 +4414,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Portugues b/rtdata/languages/Portugues index e037c565c..2e07efdba 100644 --- a/rtdata/languages/Portugues +++ b/rtdata/languages/Portugues @@ -76,8 +76,6 @@ EXIFPANEL_RESET;Repor EXIFPANEL_RESETALL;Repor tudo EXIFPANEL_RESETALLHINT;Repor os valores originais de todas as etiquetas. EXIFPANEL_RESETHINT;Repor os valores originais das etiquetas selecionadas. -EXIFPANEL_SHOWALL;Mostrar tudo -EXIFPANEL_SUBDIRECTORY;Sub-pasta EXPORT_BYPASS;Etapas do processamento a ignorar EXPORT_BYPASS_ALL;Marcar / desmarcar tudo EXPORT_BYPASS_DEFRINGE;Ignorar o remover de orlas púrpuras @@ -1673,8 +1671,6 @@ TP_ICM_WORKING_TRC_SLOPE;Declive TP_ICM_WORKING_TRC_TOOLTIP;Apenas para perfis internos TP_IMPULSEDENOISE_LABEL;Redução de ruído por impulso TP_IMPULSEDENOISE_THRESH;Limite -TP_LABCURVE_AVOIDCOLORSHIFT;Evitar mudança de cor -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Encaixar as cores na gama do espaço de cores utilizado e aplicar a correção Munsell. TP_LABCURVE_BRIGHTNESS;Claridade TP_LABCURVE_CHROMATICITY;Cromaticidade TP_LABCURVE_CHROMA_TOOLTIP;Para aplicar a tonificação a preto e branco, configure a cromaticidade para -100. @@ -2248,6 +2244,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version !FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2298,7 +2295,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2608,7 +2605,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2851,7 +2848,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2945,18 +2942,90 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -3052,20 +3121,22 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector !MAIN_FRAME_PLACES_DEL;Remove -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3085,13 +3156,18 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3120,6 +3196,27 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending @@ -3129,12 +3226,16 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3196,6 +3297,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3208,8 +3310,15 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3221,11 +3330,13 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3234,11 +3345,14 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3249,6 +3363,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LENSGEOM_LOG;Logarithmic !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct @@ -3259,9 +3374,9 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3304,9 +3419,12 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3346,6 +3464,12 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3361,8 +3485,9 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3370,7 +3495,10 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3385,7 +3513,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3394,13 +3522,14 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3420,6 +3549,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3428,6 +3558,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3443,9 +3574,10 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3454,11 +3586,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3480,7 +3612,8 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3576,7 +3709,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3621,8 +3754,10 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3630,7 +3765,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3643,6 +3778,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3712,7 +3848,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3748,6 +3884,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3795,10 +3932,15 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3843,10 +3985,11 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3867,7 +4010,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3913,17 +4056,41 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3945,13 +4112,14 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3983,11 +4151,12 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4192,7 +4361,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4235,7 +4404,7 @@ ZOOMPANEL_ZOOMOUT;Afastar\nAtalho: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index 133205a09..77c22ff13 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -76,8 +76,6 @@ EXIFPANEL_RESET;Restaurar EXIFPANEL_RESETALL;Restaurar Tudo EXIFPANEL_RESETALLHINT;Restaurar todas as tags aos seus valores originais. EXIFPANEL_RESETHINT;Restaurar as tags selecionadas aos seus valores originais. -EXIFPANEL_SHOWALL;Mostrar tudo -EXIFPANEL_SUBDIRECTORY;Subdiretório EXPORT_BYPASS;Etapas de processamento para ignorar EXPORT_BYPASS_ALL;Selecionar / Desmarcar Tudo EXPORT_BYPASS_DEFRINGE;Ignorar Defringe @@ -835,7 +833,6 @@ IPTCPANEL_TITLE;Título IPTCPANEL_TITLEHINT;Digite um nome curto e legível para a imagem, pode ser o nome do arquivo. IPTCPANEL_TRANSREFERENCE;Identificador (ID) do trabalho IPTCPANEL_TRANSREFERENCEHINT;Digite um número ou identificador necessário para controle ou rastreamento do fluxo de trabalho. -LENSPROFILE_LENS_WARNING;Aviso: o fator de corte usado para o perfil da lente é maior que o fator de corte da câmera, os resultados podem estar errados. MAIN_BUTTON_FULLSCREEN;Tela cheia MAIN_BUTTON_ICCPROFCREATOR;Criador de Perfil ICC MAIN_BUTTON_NAVNEXT_TOOLTIP;Navegue até a próxima imagem relativa à imagem aberta no Editor.\nAtalho: Shift-F4\n\nPara navegar até a próxima imagem relativa à miniatura selecionada no Navegador de Arquivos ou no Diapositivo:\nAtalho: F4 @@ -1014,7 +1011,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Fonte do seletor de cor PREFERENCES_APPEARANCE_CROPMASKCOLOR;Cor da máscara de corte PREFERENCES_APPEARANCE_MAINFONT;Fonte principal PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Cor do guia do navegador -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Modo pseudo-HiDPI PREFERENCES_APPEARANCE_THEME;Tema PREFERENCES_APPLNEXTSTARTUP;é necessário reiniciar PREFERENCES_AUTOMONPROFILE;Usar o perfil de cores do monitor principal do sistema operacional @@ -1685,8 +1681,6 @@ TP_ICM_WORKING_TRC_SLOPE;Declive TP_ICM_WORKING_TRC_TOOLTIP;Apenas para perfis internos TP_IMPULSEDENOISE_LABEL;Redução de Ruído por Impulso TP_IMPULSEDENOISE_THRESH;Limite -TP_LABCURVE_AVOIDCOLORSHIFT;Evite mudança de cor -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Ajuste as cores na gama do espaço de cores de trabalho e aplique a correção Munsell. TP_LABCURVE_BRIGHTNESS;Claridade TP_LABCURVE_CHROMATICITY;Cromaticidade TP_LABCURVE_CHROMA_TOOLTIP;Para aplicar tonificação B&W, configure Cromaticidade para -100. @@ -2253,6 +2247,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2303,7 +2298,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2613,7 +2608,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2856,7 +2851,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2952,18 +2947,90 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold !HISTORY_MSG_PDSHARPEN_AUTO_RADIUS;CS - Auto radius @@ -3058,20 +3125,23 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FILMNEGATIVE;Film negative !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR_SAFETY;Only files in the cache are cleared. Processing profiles stored alongside the source images are not touched. !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3091,13 +3161,18 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3123,6 +3198,27 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !PROGRESSBAR_DECODING;Decoding... !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending !SORT_BY_DATE;By Date @@ -3131,12 +3227,16 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3197,6 +3297,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3209,8 +3310,15 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3222,11 +3330,13 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3235,11 +3345,14 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3248,6 +3361,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 !TP_LENSGEOM_LIN;Linear !TP_LENSGEOM_LOG;Logarithmic +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_USE_HEADER;Correct !TP_LOCALLAB_ACTIV;Luminance only @@ -3257,9 +3371,9 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3302,9 +3416,12 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3344,6 +3461,12 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3359,8 +3482,9 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3368,7 +3492,10 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3383,7 +3510,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3392,13 +3519,14 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3418,6 +3546,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3426,6 +3555,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3441,9 +3571,10 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3452,11 +3583,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3478,7 +3609,8 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3574,7 +3706,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3619,8 +3751,10 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3628,7 +3762,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3641,6 +3775,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3710,7 +3845,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3746,6 +3881,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3793,10 +3929,15 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3841,10 +3982,11 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3865,7 +4007,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3911,17 +4053,41 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3943,13 +4109,14 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3981,11 +4148,12 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4193,7 +4361,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4236,7 +4404,7 @@ ZOOMPANEL_ZOOMOUT;Menos Zoom\nAtalho: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index de0846e01..82f7a9718 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -77,8 +77,6 @@ EXIFPANEL_RESET;СброÑить EXIFPANEL_RESETALL;СброÑить вÑе EXIFPANEL_RESETALLHINT;СброÑить вÑе теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ EXIFPANEL_RESETHINT;СброÑить выбранные теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ -EXIFPANEL_SHOWALL;Показать вÑÑ‘ -EXIFPANEL_SUBDIRECTORY;Подкаталог EXPORT_BYPASS_ALL;Выделить вÑе / СнÑть выделение EXPORT_BYPASS_DEFRINGE;ПропуÑтить подавление ореолов EXPORT_BYPASS_DIRPYRDENOISE;ПропуÑтить подавление шума @@ -535,7 +533,6 @@ IPTCPANEL_RESET;СброÑить IPTCPANEL_RESETHINT;СброÑить профиль на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию IPTCPANEL_SOURCE;ИÑточник IPTCPANEL_TITLE;Ðазвание -LENSPROFILE_LENS_WARNING;Внимание: кроп-фактор иÑпользуемый Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð° объектива больше чем кроп-фактор камеры, результаты могут быть не верны. MAIN_BUTTON_FULLSCREEN;Полный Ñкран MAIN_BUTTON_NAVNEXT_TOOLTIP;Перейти к Ñледующему изображению отноÑительно открытого в редакторе\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: Shift+F4\n\nПерейти к Ñледущему изображению отноÑительно выбранного в файловом браузере\nгорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ° F4 MAIN_BUTTON_NAVPREV_TOOLTIP;Перейти к предыдущему изображению отноÑительно открытого в редакторе\nгорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: Shift+F4\n\nПерейти к предыдущему изображению отноÑительно выбранного в файловом браузере\nгорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ° F4 @@ -1159,8 +1156,6 @@ TP_ICM_TONECURVE_TOOLTIP;ИÑпользовать вÑтроенную тона TP_ICM_WORKINGPROFILE;Рабочий профиль TP_IMPULSEDENOISE_LABEL;Подавление импульÑного шума TP_IMPULSEDENOISE_THRESH;Порог -TP_LABCURVE_AVOIDCOLORSHIFT;Избегать Ñдвига цветов -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Умещать цвета в диапазон рабочего цветового проÑтранÑтва и применÑть коррекцию МанÑелла TP_LABCURVE_BRIGHTNESS;ЯркоÑть TP_LABCURVE_CHROMATICITY;ЦветноÑть TP_LABCURVE_CHROMA_TOOLTIP;Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð§&Б, выÑтавьте ЦветноÑть в -100 @@ -1462,6 +1457,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !FILECHOOSER_FILTER_PP;Processing profiles !FILECHOOSER_FILTER_SAME;Same format as current photo @@ -1725,7 +1721,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2035,7 +2031,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2278,7 +2274,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2388,16 +2384,23 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2405,7 +2408,72 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold !HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto threshold @@ -2557,10 +2625,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !MAIN_MSG_TOOMANYOPENEDITORS;Too many open editors.\nPlease close an editor to continue. !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !MONITOR_PROFILE_SYSTEM;System default !PARTIALPASTE_COLORTONING;Color toning !PARTIALPASTE_DEHAZE;Haze removal @@ -2569,8 +2637,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PARTIALPASTE_FILMSIMULATION;Film simulation !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_PRSHARPENING;Post-resize sharpening @@ -2582,7 +2650,9 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PARTIALPASTE_RETINEX;Retinex !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: !PREFERENCES_CACHECLEAR_ONLYPROFILES;Clear only cached processing profiles: @@ -2599,7 +2669,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PREFERENCES_CLUTSCACHE;HaldCLUT Cache !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2627,6 +2697,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -2645,13 +2716,17 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PREFERENCES_PROFILESAVELOCATION;Processing profile saving location !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2681,6 +2756,27 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !PROGRESSBAR_HOTDEADPIXELFILTER;Hot/dead pixel filter... !PROGRESSBAR_LINEDENOISE;Line noise filter... !PROGRESSBAR_RAWCACORR;Raw CA correction... +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !SAMPLEFORMAT_0;Unknown data format !SAMPLEFORMAT_1;8-bit unsigned @@ -2702,12 +2798,16 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_CBDL_AFT;After Black-and-White @@ -2906,6 +3006,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only available if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control @@ -2923,8 +3024,15 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2936,11 +3044,13 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2949,11 +3059,14 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2970,6 +3083,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LENSGEOM_LOG;Logarithmic !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_GEOMETRIC;Geometric distortion !TP_LENSPROFILE_USE_HEADER;Correct @@ -2980,9 +3094,9 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3025,9 +3139,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3067,6 +3184,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3082,8 +3205,9 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3091,7 +3215,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3106,7 +3233,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3115,13 +3242,14 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3141,6 +3269,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3149,6 +3278,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3164,9 +3294,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3175,11 +3306,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3201,7 +3332,8 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3297,7 +3429,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3342,8 +3474,10 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3351,7 +3485,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3364,6 +3498,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3433,7 +3568,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3469,6 +3604,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3516,10 +3652,15 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3564,10 +3705,11 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3588,7 +3730,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3634,17 +3776,41 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3666,13 +3832,14 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3704,11 +3871,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4198,7 +4366,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4241,7 +4409,7 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index 15bb90737..1cf459b82 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -50,7 +50,6 @@ EXIFPANEL_RESET;Врати EXIFPANEL_RESETALL;Врати Ñве EXIFPANEL_RESETALLHINT;Враћа Ñве ознаке на почетне вредноÑти EXIFPANEL_RESETHINT;Враћа изабрану ознаку на почетну вредноÑти -EXIFPANEL_SUBDIRECTORY;Поддиректоријум EXPORT_BYPASS_ALL;Изабери / поништи Ñве EXPORT_BYPASS_DEFRINGE;Занемари уклањање ореола EXPORT_BYPASS_DIRPYRDENOISE;Занемари уклањање шума @@ -407,7 +406,6 @@ HISTORY_NEWSNAPSHOT;Додај HISTORY_NEWSNAPSHOT_TOOLTIP;Пречица: Alt-s HISTORY_SNAPSHOT;Снимак HISTORY_SNAPSHOTS;Снимак -HRESHOLDSELECTOR_BL;Доле-лево IPTCPANEL_CATEGORY;Категорија IPTCPANEL_CITY;Град IPTCPANEL_COPYHINT;Коппирај ИПТЦ пшодешавања у оÑтаву @@ -430,9 +428,7 @@ MAIN_BUTTON_NAVNEXT_TOOLTIP;Шаље Ð²Ð°Ñ Ð½Ð° наредну Ñлику у о MAIN_BUTTON_NAVPREV_TOOLTIP;Шаље Ð²Ð°Ñ Ð½Ð° претходну Ñлику у одноÑу на отворену у прозору за уређивање.\nПречица: Shift-F3\n\nnТакође, омогућа вам да идете на наредну Ñлику у одноÑу на тренутно изабрану у разгледачу или филмÑкој траци.\nПречица: F3 MAIN_BUTTON_NAVSYNC_TOOLTIP;УÑаглашава разгледач датотека или филмÑку траку Ñа делом за уређивање ради умањеног приказа тренутно отворене Ñлике и чиÑти Ñве изабране филтере.\nПречица: x\n\nКао и претходна операција, али без чишћења изабраних филтера:\nПречица: y\n(Умањени приказ отворене Ñлике неће бити приказан уколико је изфилтриран). MAIN_BUTTON_PREFERENCES;ПоÑтавке -MAIN_BUTTON_PUTTOQUEUE;Закажи MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Додаје тренутну Ñлику у заказане Ctrl+B -MAIN_BUTTON_SAVE;Сачувај MAIN_BUTTON_SAVE_TOOLTIP;Чува тренутну Ñлику Ctrl+С MAIN_BUTTON_SENDTOEDITOR;Уреди MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Уређује тренутну Ñлику у Ñпољном програму Ctrl+Е @@ -670,7 +666,7 @@ PROFILEPANEL_TOOLTIPSAVE;Чува тренутни профил PROGRESSBAR_LOADING;Учитавам Ñлику... PROGRESSBAR_LOADINGTHUMBS;Учитавам приказе... PROGRESSBAR_LOADJPEG;Учитавам JPEG датотеку... -PROGRESSBAR_LOADJPEG;Учитавам JXL датотеку... +PROGRESSBAR_LOADJXL;Учитавам JXL датотеку... PROGRESSBAR_LOADPNG;Учитавам PNG датотеку... PROGRESSBAR_LOADTIFF;Учитавам TIFF датотеку... PROGRESSBAR_NOIMAGES;ÐиÑу пронађене Ñлике @@ -709,6 +705,7 @@ SAVEDLG_TIFFUNCOMPRESSED;Ðезапаковани TIFF SAVEDLG_WARNFILENAME;Датотека ће бити названа SHCSELECTOR_TOOLTIP;Кликните деÑно дугме миша да поново вратите позицију ова три клизача. THRESHOLDSELECTOR_B;Доле +THRESHOLDSELECTOR_BL;Доле-лево THRESHOLDSELECTOR_BR;Доле-деÑно THRESHOLDSELECTOR_HINT;ПритиÑните дугме Shift за померање појединачних тачака. THRESHOLDSELECTOR_T;Горе @@ -894,7 +891,6 @@ TP_EXPOSURE_COMPRHIGHLIGHTS;Сабијање Ñветлог TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Праг за чупање Ñветлих делова TP_EXPOSURE_COMPRSHADOWS;Сабијање Ñенки TP_EXPOSURE_CONTRAST;КонтраÑÑ‚ -TP_EXPOSURE_CURVEEDITOR;Крива нијанÑи TP_EXPOSURE_CURVEEDITOR1;Крива тонова 1 TP_EXPOSURE_CURVEEDITOR2;Крива тонова 2 TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Погледајте „ЕкÑпозиција > Криве тонова“ унутар чланка на Ñајту RawPedia како би научили како Ñе поÑтижу најбољи резучтати уÑпотребом две криве тонова. @@ -962,8 +958,6 @@ TP_ICM_TONECURVE_TOOLTIP;Употребљава уграђену DCP криву TP_ICM_WORKINGPROFILE;Радни профил TP_IMPULSEDENOISE_LABEL;ИмпулÑно уклањање шума TP_IMPULSEDENOISE_THRESH;Праг -TP_LABCURVE_AVOIDCOLORSHIFT;Избегни померање боја -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;ПоÑтавља боје у опÑег тренутног радног проÑтора боја и примењује МунÑелову корекцију. TP_LABCURVE_BRIGHTNESS;ОÑветљеноÑÑ‚ TP_LABCURVE_CHROMATICITY;Боје TP_LABCURVE_CHROMA_TOOLTIP;To apply ЦБ toning, set Chromaticity to -100. @@ -1236,6 +1230,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !FILEBROWSER_RESETDEFAULTPROFILE;Reset to default !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. !FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles (*.icc) !FILECHOOSER_FILTER_CURVE;Curve files @@ -1527,7 +1522,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -1837,7 +1832,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2080,7 +2075,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2196,16 +2191,23 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2218,7 +2220,72 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2403,10 +2470,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u !MAIN_TAB_INSPECT; Inspect -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !MONITOR_PROFILE_SYSTEM;System default !NAVIGATOR_B;B: !NAVIGATOR_G;G: @@ -2430,8 +2497,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_METAGROUP;Metadata settings !PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter @@ -2454,9 +2521,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color !PREFERENCES_APPEARANCE_MAINFONT;Main font !PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Navigator guide color -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_APPEARANCE_THEME;Theme !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR;Clear !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: @@ -2475,7 +2544,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs !PREFERENCES_CLUTSDIR;HaldCLUT directory !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2517,6 +2586,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) !PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -2544,6 +2614,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_PROFILE_NONE;None !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset !PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Remember the zoom % and pan offset of the current image when opening a new image.\n\nThis option only works in 'Single Editor Tab Mode' and when 'Demosaicing method used for the preview at <100% zoom' is set to 'As in PP3'. !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now @@ -2551,7 +2623,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_SERIALIZE_TIFF_READ_LABEL;Serialize reading of TIFF files !PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP;Enabling this option when working with folders containing uncompressed TIFF files can increase performance of thumbnail generation. !PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show Filmstrip toolbar -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_PERFORMANCE;Performance @@ -2559,6 +2632,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2591,6 +2665,27 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !QINFO_FRAMECOUNT;%2 frames !QINFO_HDR;HDR / %2 frame(s) !QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAMPLEFORMAT_0;Unknown data format @@ -2612,13 +2707,16 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry -!THRESHOLDSELECTOR_BL;Bottom-left +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_COLORPICKER;Lockable Color Picker\n\nWhen the tool is active:\n- Add a picker: left-click.\n- Drag a picker: left-click and drag.\n- Delete a picker: right-click.\n- Delete all pickers: Ctrl+Shift+right-click.\n- Revert to hand tool: right-click outside any picker. !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_BWMIX_FILTER_TOOLTIP;The color filter simulates shots taken with a colored filter placed in front of the lens. Colored filters reduce the transmission of specific color ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. @@ -2837,6 +2935,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_ICM_APPLYLOOKTABLE;Look table !TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only available if the selected DCP has one. !TP_ICM_BPC;Black Point Compensation +!TP_ICM_BW;Black and White !TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is 'interpolated' which is a mix between the two based on white balance. The setting is only available if a dual-illuminant DCP with interpolation support is selected. !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control @@ -2855,8 +2954,15 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance !TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2868,11 +2974,13 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2881,11 +2989,14 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2903,6 +3014,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_CA;Chromatic aberration @@ -2921,9 +3033,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -2966,9 +3078,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3008,6 +3123,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3023,8 +3144,9 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3032,7 +3154,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3047,7 +3172,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3056,13 +3181,14 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3082,6 +3208,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3090,6 +3217,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3105,9 +3233,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3116,11 +3245,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3142,7 +3271,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3238,7 +3368,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3283,8 +3413,10 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3292,7 +3424,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3305,6 +3437,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3374,7 +3507,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3410,6 +3543,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3457,10 +3591,15 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3505,10 +3644,11 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3529,7 +3669,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3575,17 +3715,41 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3607,13 +3771,14 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3645,11 +3810,12 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4190,7 +4356,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4233,7 +4399,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ Ñлике - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Slovenian b/rtdata/languages/Slovenian index 1ba151693..2ad1ed7d6 100644 --- a/rtdata/languages/Slovenian +++ b/rtdata/languages/Slovenian @@ -75,8 +75,6 @@ EXIFPANEL_RESET;Ponastavi EXIFPANEL_RESETALL;Ponastavi vse EXIFPANEL_RESETALLHINT;Ponastavi vse znaÄke na njihove izvirne vrednosti. EXIFPANEL_RESETHINT;Ponastavi izbrane znaÄke na njihove izvirne vrednosti. -EXIFPANEL_SHOWALL;Prikaži vse -EXIFPANEL_SUBDIRECTORY;Podmapa EXPORT_BYPASS;Koraki obdelave za obvoz EXPORT_BYPASS_ALL;Izberi / Odizberi vse EXPORT_BYPASS_DEFRINGE;Izpusti odstranjevanje napak robov @@ -1025,7 +1023,6 @@ PREFERENCES_APPEARANCE_COLORPICKERFONT;Pisava izbire barv PREFERENCES_APPEARANCE_CROPMASKCOLOR;Barve maske obrezovanja PREFERENCES_APPEARANCE_MAINFONT;Glavna pisava PREFERENCES_APPEARANCE_NAVGUIDECOLOR;Glavna barva navigacije -PREFERENCES_APPEARANCE_PSEUDOHIDPI;Psevdo naÄin HiDPI PREFERENCES_APPEARANCE_THEME;Tema PREFERENCES_APPLNEXTSTARTUP;potreben ponovni zagon PREFERENCES_AUTOMONPROFILE;Uporabi profil glavnega monitorja iz operacijskega sistema @@ -1706,8 +1703,6 @@ TP_ICM_WORKING_TRC_SLOPE;Strmina TP_ICM_WORKING_TRC_TOOLTIP;Samo za vgrajene profile. TP_IMPULSEDENOISE_LABEL;Impulzno zmanjÅ¡anje Å¡uma TP_IMPULSEDENOISE_THRESH;Prag -TP_LABCURVE_AVOIDCOLORSHIFT;Izogibaj se barvnega pomika -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Prilagodi barve barvnemu prostoru delovnega barvnega prostora in uporabi Munsellov popravek. TP_LABCURVE_BRIGHTNESS;Svetlost TP_LABCURVE_CHROMATICITY;KromatiÄnost TP_LABCURVE_CHROMA_TOOLTIP;Za uporabo Ärno-belega toniranja nastavi kromatiÄnost na -100. @@ -2282,6 +2277,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !EXIFPANEL_VALUE_NOT_SHOWN;Not shown !FILEBROWSER_POPUPINSPECT;Inspect !FILEBROWSER_POPUPSORTBY;Sort Files +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_DELETE_ALL;Delete all !GENERAL_EDIT;Edit @@ -2331,7 +2327,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2641,7 +2637,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2884,7 +2880,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2976,18 +2972,90 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method !HISTORY_MSG_ILLUM;CAL - SC - Illuminant !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_PDSHARPEN_CHECKITER;CS - Auto limit iterations !HISTORY_MSG_PERSP_CAM_ANGLE;Perspective - Camera @@ -3076,18 +3144,21 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater !ICCPROFCREATOR_PRIM_DCIP3;DCI-P3 !INSPECTOR_WINDOW_TITLE;Inspector -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_PREPROCWB;Preprocess White Balance !PARTIALPASTE_SPOT;Spot removal !PARTIALPASTE_TONE_EQUALIZER;Tone equalizer +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CAMERAPROFILESDIR;Camera profiles directory !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -3107,13 +3178,18 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off !PREFERENCES_METADATA_SYNC_READ;Read only !PREFERENCES_METADATA_SYNC_READWRITE;Bidirectional -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_FAVORITES;Favorites +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -3136,6 +3212,27 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !PREFERENCES_XMP_SIDECAR_MODE_EXT;darktable-like (FILENAME.ext.xmp for FILENAME.ext) !PREFERENCES_XMP_SIDECAR_MODE_STD;Standard (FILENAME.xmp for FILENAME.ext) !PREFERENCES_ZOOMONSCROLL;Zoom images by scrolling +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !SAVEDLG_BIGTIFF;BigTIFF (no metadata support) !SORT_ASCENDING;Ascending !SORT_BY_DATE;By Date @@ -3144,12 +3241,16 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATCLASSIC;Classic @@ -3204,6 +3305,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur !TP_HLREC_HLTH;Gain threshold +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3216,8 +3318,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3229,11 +3338,13 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3242,11 +3353,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 !TP_ICM_WORKING_TRC_22;Adobe g=2.2 @@ -3255,6 +3369,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_ICM_WORKING_TRC_SRGB;sRGB g=2.4 s=12.92 !TP_LENSGEOM_LIN;Linear !TP_LENSGEOM_LOG;Logarithmic +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LOCALLAB_ACTIV;Luminance only !TP_LOCALLAB_ACTIVSPOT;Enable Spot !TP_LOCALLAB_ADJ;Equalizer Color @@ -3262,9 +3377,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3307,9 +3422,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3349,6 +3467,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3364,8 +3488,9 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3373,7 +3498,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3388,7 +3516,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3397,13 +3525,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3423,6 +3552,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3431,6 +3561,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3446,9 +3577,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3457,11 +3589,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3483,7 +3615,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3579,7 +3712,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3624,8 +3757,10 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3633,7 +3768,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3646,6 +3781,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3715,7 +3851,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3751,6 +3887,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3798,10 +3935,15 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3846,10 +3988,11 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3870,7 +4013,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3916,17 +4059,41 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3948,13 +4115,14 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3986,11 +4154,12 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4191,7 +4360,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4234,7 +4403,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Out\nBližnjica: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index edbeb9e3a..baef111e5 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -58,7 +58,6 @@ EXIFPANEL_RESET;Ã…terställ EXIFPANEL_RESETALL;Ã…terställ alla EXIFPANEL_RESETALLHINT;Ã…terställ alla etiketter till deras originalvärden EXIFPANEL_RESETHINT;Ã…terställ de valda etiketterna till deras originalvärden -EXIFPANEL_SUBDIRECTORY;Underkatalog EXPORT_BYPASS_ALL;Markera/Avmarkera allt EXPORT_BYPASS_DEFRINGE;FörbigÃ¥ överstrÃ¥lning EXPORT_BYPASS_DIRPYRDENOISE;FörbigÃ¥ brusreducering @@ -618,14 +617,12 @@ IPTCPANEL_RESET;Ã…terställ IPTCPANEL_RESETHINT;Ã…terställ till standardprofilen IPTCPANEL_SOURCE;Källa IPTCPANEL_TITLE;Titel -ISTORY_MSG_372;PRS USM - Radie MAIN_BUTTON_FULLSCREEN;Helskärm MAIN_BUTTON_NAVNEXT_TOOLTIP;Flytta till nästa bild relativt den bild som är öppen i redigeringsvyn\nKortkommando: Shift-F4\n\nFlytta till nästa bild relativt den valda miniatyrbilden i filvyn\nKortkommando: F4 MAIN_BUTTON_NAVPREV_TOOLTIP;Flytta till föregÃ¥ende bild relativt den bild som är öppen i redigeringsvyn\nKortkommando: Shift-F3\n\nFlytta till föregÃ¥ende bild relativt den valda miniatyrbilden i filvyn\nKortkommando: F3 MAIN_BUTTON_NAVSYNC_TOOLTIP;Synkronisera filvyn med redigeringsvyn för att uppdatera förhandsgranskningen av den nu öppna bilden, och för att nollställa filtren i filvyn.\nKortkommando: x\n\nSom ovan, men utan att nollställa filtren i filvyn\nKortkommando: y\n(Notera att förhandsgranskningen av den öppna bildens miniatyrbilder ej visas om den är filtrerad.). MAIN_BUTTON_PREFERENCES;Inställningar MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Lägg till nuvarande bild i behandlingskön.\nKortkommando: Ctrl+b -MAIN_BUTTON_SAVE;Spara MAIN_BUTTON_SAVE_TOOLTIP;Spara nuvarande bild.\nKortkommando: Ctrl+s MAIN_BUTTON_SENDTOEDITOR;Redigera bilden i ett externt program MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Redigera nuvarande bild i externt bildredigeringsprogram.\nKortkommando: Ctrl+e @@ -1300,8 +1297,6 @@ TP_ICM_TONECURVE_TOOLTIP;Aktivera för att använda tonkurvor som kan finnas i D TP_ICM_WORKINGPROFILE;Färgrymd TP_IMPULSEDENOISE_LABEL;Brusreducering mha av stegsvar TP_IMPULSEDENOISE_THRESH;Tröskelvärde -TP_LABCURVE_AVOIDCOLORSHIFT;Undvik färgskift -TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Passa färger i färgrymden och applicera Munsell-korrigering TP_LABCURVE_BRIGHTNESS;Ljushet TP_LABCURVE_CHROMATICITY;Kroma TP_LABCURVE_CHROMA_TOOLTIP;För att Ã¥stadkomma en S/V-toning, sätt Kroma till -100 @@ -1755,6 +1750,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !FILEBROWSER_POPUPSORTBY;Sort Files !FILEBROWSER_RESETDEFAULTPROFILE;Reset to default !FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. +!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !FILECHOOSER_FILTER_EXECUTABLE;Executable files !GENERAL_CURRENT;Current !GENERAL_DELETE_ALL;Delete all @@ -1875,7 +1871,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_512;Local - SD - ΔE decay !HISTORY_MSG_513;Local - Spot - Excluding - Scope !HISTORY_MSG_514;Local - Spot structure -!HISTORY_MSG_515;Local Adjustments +!HISTORY_MSG_515;Selective Editing !HISTORY_MSG_516;Local - Color and light !HISTORY_MSG_517;Local - Enable super !HISTORY_MSG_518;Local - Lightness @@ -2185,7 +2181,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_830;Local - Color gradient strength L !HISTORY_MSG_831;Local - Color gradient angle !HISTORY_MSG_832;Local - Color gradient strength C -!HISTORY_MSG_833;Local - TG - Feather gradient +!HISTORY_MSG_833;Local - Mask gradient feather !HISTORY_MSG_834;Local - Color gradient strength H !HISTORY_MSG_835;Local - Vib gradient strength L !HISTORY_MSG_836;Local - Vib gradient angle @@ -2428,7 +2424,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_1079;Local - CIECAM Sigmoid strength J !HISTORY_MSG_1080;Local - CIECAM Sigmoid threshold !HISTORY_MSG_1081;Local - CIECAM Sigmoid blend -!HISTORY_MSG_1082;Local - CIECAM Sigmoid Q BlackEv WhiteEv +!HISTORY_MSG_1082;Local - CIECAM Auto threshold !HISTORY_MSG_1083;Local - CIECAM Hue !HISTORY_MSG_1084;Local - Uses Black Ev - White Ev !HISTORY_MSG_1085;Local - Jz lightness @@ -2544,16 +2540,23 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_ICM_AINTENT;Abstract profile intent !HISTORY_MSG_ICM_BLUX;Primaries Blue X !HISTORY_MSG_ICM_BLUY;Primaries Blue Y +!HISTORY_MSG_ICM_CAT;Matrix adaptation !HISTORY_MSG_ICM_FBW;Black and White !HISTORY_MSG_ICM_GAMUT;Gamut control !HISTORY_MSG_ICM_GREX;Primaries Green X !HISTORY_MSG_ICM_GREY;Primaries Green Y +!HISTORY_MSG_ICM_MIDTCIE;Midtones !HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries !HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D !HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type !HISTORY_MSG_ICM_PRESER;Preserve neutral !HISTORY_MSG_ICM_REDX;Primaries Red X !HISTORY_MSG_ICM_REDY;Primaries Red Y +!HISTORY_MSG_ICM_REFI;Refinement Colors +!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x +!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y +!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights +!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_ICM_WORKING_GAMMA;TRC - Gamma !HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Illuminant method !HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method @@ -2566,7 +2569,72 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness !HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius !HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot +!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast +!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW +!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius +!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) +!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights +!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows +!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure +!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool +!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) +!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather +!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather +!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather +!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather +!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift +!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution +!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness +!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control +!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation !HISTORY_MSG_METADATA_MODE;Metadata copy mode !HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2750,10 +2818,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !MAIN_TAB_ADVANCED_TOOLTIP;Shortcut: Alt-a !MAIN_TAB_FAVORITES;Favorites !MAIN_TAB_FAVORITES_TOOLTIP;Shortcut: Alt-u -!MAIN_TAB_LOCALLAB;Local +!MAIN_TAB_LOCALLAB;Selective Editing !MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt-o !MAIN_TOOLTIP_BACKCOLOR3;Background color of the preview: middle grey\nShortcut: 9 -!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%. +!MAIN_TOOLTIP_PREVIEWSHARPMASK;Preview the sharpening contrast mask.\nShortcut: p\n\nOnly works when sharpening is enabled and zoom >= 100%, or when capture sharpening is enabled. !OPTIONS_BUNDLED_MISSING;The bundled profile '%1' could not be found!\n\nYour installation could be damaged.\n\nDefault internal values will be used instead. !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\n'%1' will be used instead. !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\n'%1' will be used instead. @@ -2764,8 +2832,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control !PARTIALPASTE_FLATFIELDFROMMETADATA;Flat-field from Metadata !PARTIALPASTE_LOCALCONTRAST;Local contrast -!PARTIALPASTE_LOCALLAB;Local Adjustments -!PARTIALPASTE_LOCALLABGROUP;Local Adjustments Settings +!PARTIALPASTE_LOCALLAB;Selective Editing +!PARTIALPASTE_LOCALLABGROUP;Selective Editing Settings !PARTIALPASTE_METADATA;Metadata mode !PARTIALPASTE_PREPROCESS_PDAFLINESFILTER;PDAF lines filter !PARTIALPASTE_PREPROCWB;Preprocess White Balance @@ -2782,9 +2850,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_APPEARANCE_COLORPICKERFONT;Color picker font !PREFERENCES_APPEARANCE_CROPMASKCOLOR;Crop mask color !PREFERENCES_APPEARANCE_MAINFONT;Main font -!PREFERENCES_APPEARANCE_PSEUDOHIDPI;Pseudo-HiDPI mode !PREFERENCES_APPEARANCE_THEME;Theme !PREFERENCES_AUTOSAVE_TP_OPEN;Save tool collapsed/expanded state on exit +!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth +!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders +!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders !PREFERENCES_CACHECLEAR;Clear !PREFERENCES_CACHECLEAR_ALL;Clear all cached files: !PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Clear all cached files except for cached processing profiles: @@ -2800,7 +2870,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_CIE;Ciecam !PREFERENCES_CIEARTIF;Avoid artifacts !PREFERENCES_CMMBPC;Black point compensation -!PREFERENCES_COMPLEXITYLOC;Default complexity for Local Adjustments +!PREFERENCES_COMPLEXITYLOC;Default complexity for Selective Editing !PREFERENCES_COMPLEXITY_EXP;Advanced !PREFERENCES_COMPLEXITY_NORM;Standard !PREFERENCES_COMPLEXITY_SIMP;Basic @@ -2831,6 +2901,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. !PREFERENCES_LENSPROFILESDIR;Lens profiles directory !PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) +!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom !PREFERENCES_METADATA;Metadata !PREFERENCES_METADATA_SYNC;Metadata synchronization with XMP sidecars !PREFERENCES_METADATA_SYNC_NONE;Off @@ -2849,9 +2920,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_PROFILESAVELOCATION;Processing profile saving location !PREFERENCES_PRTINTENT;Rendering intent !PREFERENCES_PRTPROFILE;Color profile +!PREFERENCES_RAW_DECODER;Raw Decoder +!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_SAVE_TP_OPEN_NOW;Save tool collapsed/expanded state now !PREFERENCES_SERIALIZE_TIFF_READ;TIFF Read Settings -!PREFERENCES_SHOWTOOLTIP;Show Local Adjustments advice tooltips +!PREFERENCES_SHOWTOOLTIP;Show Selective Editing advice tooltips +!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing !PREFERENCES_TAB_DYNAMICPROFILE;Dynamic Profile Rules !PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_TAB_PERFORMANCE;Performance @@ -2859,6 +2933,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show !PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral raw rendering !PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral raw otherwise +!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. @@ -2891,6 +2966,27 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !QINFO_FRAMECOUNT;%2 frames !QINFO_HDR;HDR / %2 frame(s) !QINFO_PIXELSHIFT;Pixel Shift / %2 frame(s) +!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here +!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here +!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples +!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. +!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. +!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: +!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template !QUEUE_LOCATION_TITLE;Output Location !QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s !SAMPLEFORMAT_0;Unknown data format @@ -2912,12 +3008,16 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !SORT_BY_NAME;By Name !SORT_BY_RANK;By Rank !SORT_DESCENDING;Descending +!TC_LOCALLAB_PRIM_SHIFTX;Shift x +!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +!TC_LOCALLAB_PRIM_SHIFTY;Shift y !TC_PRIM_BLUX;Bx !TC_PRIM_BLUY;By !TC_PRIM_GREX;Gx !TC_PRIM_GREY;Gy !TC_PRIM_REDX;Rx !TC_PRIM_REDY;Ry +!TC_PRIM_REFI;Refine colors (white-point) !TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_BWMIX_MIXC;Channel Mixer !TP_BWMIX_NEUTRAL;Reset @@ -3043,6 +3143,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only available if the selected DCP has one. !TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only available if the selected DCP has one. !TP_ICM_APPLYLOOKTABLE;Look table +!TP_ICM_BW;Black and White !TP_ICM_FBW;Black-and-White !TP_ICM_GAMUT;Gamut control !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. @@ -3057,8 +3158,15 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_ICM_REDFRAME;Custom Primaries !TP_ICM_SAVEREFERENCE;Save Reference Image !TP_ICM_TRCFRAME;Abstract Profile -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to ciecam) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant' : which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries': which allows you to change the destination primaries with two main uses - channel mixer and calibration.\nNote: Abstract profiles take into account the built-in Working profiles without modifying them. They do not work with custom Working profiles. +!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. +!TP_ICM_WORKING_CAT;Matrix adaptation +!TP_ICM_WORKING_CAT_BRAD;Bradford +!TP_ICM_WORKING_CAT_CAT02;Cat02 +!TP_ICM_WORKING_CAT_CAT16;Cat16 +!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford +!TP_ICM_WORKING_CAT_VK;Von Kries +!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_CIEDIAG;CIE xy diagram !TP_ICM_WORKING_ILLU;Illuminant !TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -3070,11 +3178,13 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_ICM_WORKING_ILLU_D65;D65 !TP_ICM_WORKING_ILLU_D80;D80 !TP_ICM_WORKING_ILLU_D120;D120 +!TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_ILLU_NONE;Default !TP_ICM_WORKING_ILLU_STDA;stdA 2875K +!TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRESER;Preserves Pastel tones !TP_ICM_WORKING_PRIM;Destination primaries -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination- primaries'' combobox, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. +!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. !TP_ICM_WORKING_PRIM_AC0;ACESp0 !TP_ICM_WORKING_PRIM_ACE;ACESp1 !TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -3083,11 +3193,14 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_ICM_WORKING_PRIM_BST;BestRGB !TP_ICM_WORKING_PRIM_CUS;Custom (sliders) !TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy Diagram) +!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) !TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA !TP_ICM_WORKING_PRIM_NONE;Default !TP_ICM_WORKING_PRIM_PROP;ProPhoto !TP_ICM_WORKING_PRIM_REC;Rec2020 !TP_ICM_WORKING_PRIM_SRGB;sRGB +!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. !TP_ICM_WORKING_PRIM_WID;WideGamut !TP_ICM_WORKING_TRC;Tone response curve: !TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -3105,6 +3218,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected !TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file !TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata !TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. !TP_LENSPROFILE_MODE_HEADER;Lens Profile !TP_LENSPROFILE_USE_CA;Chromatic aberration @@ -3123,9 +3237,9 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_ARTIF;Shape detection !TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. !TP_LOCALLAB_AUTOGRAY;Auto mean luminance (Yb%) -!TP_LOCALLAB_AUTOGRAYCIE;Auto +!TP_LOCALLAB_AUTOGRAYCIE;Automatic !TP_LOCALLAB_AVOID;Avoid color shift -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab).\nMunsell correction always disabled when Jz or CAM16 or Color Appearance and Lighting is used.\n\nDefault: Munsell.\nMunsell correction: fixes Lab mode hue drifts due to non-linearity, when chromaticity is changed (Uniform Perceptual Lab).\nLab: applies a gamut control, in relative colorimetric, Munsell is then applied.\nXYZ Absolute, applies gamut control, in absolute colorimetric, Munsell is then applied.\nXYZ Relative, applies gamut control, in relative colorimetric, Munsell is then applied. +!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. !TP_LOCALLAB_AVOIDMUN;Munsell correction only !TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. !TP_LOCALLAB_AVOIDRAD;Soft radius @@ -3168,9 +3282,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_BUTTON_DUPL;Duplicate !TP_LOCALLAB_BUTTON_REN;Rename !TP_LOCALLAB_BUTTON_VIS;Show/Hide +!TP_LOCALLAB_BWEVNONE;None +!TP_LOCALLAB_BWEVSIG;Activated +!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_BWFORCE;Uses Black Ev & White Ev !TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Peak Luminance) -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16. Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images. +!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CAM16_FRA;Cam16 Image Adjustments !TP_LOCALLAB_CAMMODE;CAM model !TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -3210,6 +3327,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. !TP_LOCALLAB_CIEMODE_WAV;Wavelet !TP_LOCALLAB_CIETOOLEXP;Curves +!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) !TP_LOCALLAB_CIRCRADIUS;Spot size !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -3225,8 +3348,9 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_CLIPTM;Clip restored data (gain) !TP_LOCALLAB_COFR;Color & Light !TP_LOCALLAB_COLORDE;ΔE preview color - intensity -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button will only work if you have activated one (and only one) of the tools in 'Add tool to current spot' menu.\nTo be able to preview ΔE with several tools enabled, use Mask and modifications - Preview ΔE. +!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE;Scope (color tools) !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. !TP_LOCALLAB_COLOR_CIE;Color curve @@ -3234,7 +3358,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_COL_NAME;Name !TP_LOCALLAB_COL_VIS;Status !TP_LOCALLAB_COMPFRA;Directional contrast +!TP_LOCALLAB_COMPRCIE;Brightness compression +!TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping +!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTCOL;Contrast threshold !TP_LOCALLAB_CONTFRA;Contrast by level !TP_LOCALLAB_CONTRAST;Contrast @@ -3249,7 +3376,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_CURVCURR;Normal !TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. !TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combobox to 'Normal'. +!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tone curve !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. @@ -3258,13 +3385,14 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_DARKRETI;Darkness !TP_LOCALLAB_DEHAFRA;Dehaze !TP_LOCALLAB_DEHAZ;Strength +!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DELTAD;Delta balance !TP_LOCALLAB_DELTAEC;ΔE Image mask !TP_LOCALLAB_DENOI1_EXP;Denoise based on luminance mask !TP_LOCALLAB_DENOI2_EXP;Recovery based on luminance mask -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. +!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. !TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. !TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). !TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. @@ -3284,6 +3412,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_DETAILFRA;Edge detection - DCT !TP_LOCALLAB_DETAILSH;Details !TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold +!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround !TP_LOCALLAB_DIVGR;Gamma !TP_LOCALLAB_DUPLSPOTNAME;Copy !TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3292,6 +3421,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping !TP_LOCALLAB_ENABLE_MASK;Enable mask !TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_ENH;Enhanced !TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3307,9 +3437,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_EXCLUF;Excluding !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE;Spot method -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all local adjustment data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\n\n'Full image' allows you to use the local adjustment tools on the whole image.\n The RT Spot delimiters are set beyond the image preview boundaries.\n The transition is set to 100.\nNote, you may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nPlease note: using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems. +!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. !TP_LOCALLAB_EXECLU;Excluding spot !TP_LOCALLAB_EXFULL;Full image +!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXNORM;Normal spot !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA;Chroma compensation @@ -3318,11 +3449,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_EXPCOMP;Exposure compensation Æ’ !TP_LOCALLAB_EXPCOMPINV;Exposure compensation !TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Local Adjustments version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. +!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. !TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. !TP_LOCALLAB_EXPCURV;Curves !TP_LOCALLAB_EXPGRAD;Graduated Filter -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. +!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. !TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. !TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. !TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. @@ -3344,7 +3475,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FATSHFRA;Dynamic Range Compression Mask Æ’ !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE;Feather gradient (Grad. Filters) +!TP_LOCALLAB_FEATVALUE;Feather gradient +!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). !TP_LOCALLAB_FFTW;Æ’ - Use Fast Fourier Transform @@ -3440,7 +3572,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_JZTHRHCIE;Threshold Chroma for Jz(Hz) !TP_LOCALLAB_JZWAVEXP;Wavelet Jz !TP_LOCALLAB_LABBLURM;Blur Mask -!TP_LOCALLAB_LABEL;Local Adjustments +!TP_LOCALLAB_LABEL;Selective Editing !TP_LOCALLAB_LABGRID;Color correction grid !TP_LOCALLAB_LABGRIDMERG;Background !TP_LOCALLAB_LABGRID_VALUES;High(a)=%1 High(b)=%2\nLow(a)=%3 Low(b)=%4 @@ -3485,8 +3617,10 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIE;Log encoding instead of Sigmoid -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you tu use Black Ev, White Ev, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using Log encoding Q. +!TP_LOCALLAB_LOGCIE;Log encoding +!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) +!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. !TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3494,7 +3628,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_LOGCONTL;Contrast (J) !TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. !TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. +!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. !TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. !TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. !TP_LOCALLAB_LOGEXP;All tools @@ -3507,6 +3641,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. !TP_LOCALLAB_LOGLIN;Logarithm mode !TP_LOCALLAB_LOGPFRA;Relative Exposure Levels +!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART;Overall strength !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. @@ -3576,7 +3711,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. !TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. !TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Mask & modifications) +!TP_LOCALLAB_MASKUNUSABLE;Mask disabled (Enable in Mask & modifications) !TP_LOCALLAB_MASKUSABLE;Mask enabled (Mask & modifications) !TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. !TP_LOCALLAB_MEDIAN;Median Low @@ -3612,6 +3747,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_MERTWE;Exclusion !TP_LOCALLAB_MERTWO;Subtract !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3659,10 +3795,15 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_PASTELS2;Vibrance !TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression !TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for Rawtherapee : gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. !TP_LOCALLAB_PREVHIDE;Hide additional settings !TP_LOCALLAB_PREVIEW;Preview ΔE !TP_LOCALLAB_PREVSHOW;Show additional settings +!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_PROXI;ΔE decay !TP_LOCALLAB_QUAAGRES;Aggressive !TP_LOCALLAB_QUACONSER;Conservative @@ -3707,10 +3848,11 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_RET_TOOLNAME;Dehaze & Retinex !TP_LOCALLAB_REWEI;Reweighting iterates !TP_LOCALLAB_RGB;RGB Tone Curve -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. +!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_ROW_NVIS;Not visible !TP_LOCALLAB_ROW_VIS;Visible !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. +!TP_LOCALLAB_SATCIE;Saturation control !TP_LOCALLAB_SATUR;Saturation !TP_LOCALLAB_SATURV;Saturation (s) !TP_LOCALLAB_SCALEGR;Scale @@ -3731,7 +3873,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_SHADHIGH;Shadows/Highlights & Tone Equalizer !TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. !TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. +!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. !TP_LOCALLAB_SHAMASKCOL;Shadows !TP_LOCALLAB_SHAPETYPE;Spot shape !TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. @@ -3777,17 +3919,41 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). !TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer -!TP_LOCALLAB_SIGFRA;Sigmoid Q & Log encoding Q +!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution +!TP_LOCALLAB_SIGCIE;Sigmoid +!TP_LOCALLAB_SIGFRA;Sigmoid Q +!TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGJZFRA;Sigmoid Jz !TP_LOCALLAB_SIGMAWAV;Attenuation response +!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDBL;Blend !TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -!TP_LOCALLAB_SIGMOIDQJ;Uses Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold +!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. +!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance +!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +!TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev +!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a Tone-mapping appearance using both the'Ciecam' (or 'Jz') and 'Sigmoid' function.\nThree sliders: a) Contrast acts on the shape of the sigmoid curve and consequently on the strength; b) Threshold (Gray point) distributes the action according to the luminance; c)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. +!TP_LOCALLAB_SIGSLOPJCIE;Slope +!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments +!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASKCOL;Slope !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. +!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) !TP_LOCALLAB_SLOSH;Slope +!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation +!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode +!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene +!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFT;Soft Light & Original Retinex !TP_LOCALLAB_SOFTM;Soft Light !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. @@ -3809,13 +3975,14 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_STRENGR;Strength !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). !TP_LOCALLAB_STRENGTH;Noise +!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRGRID;Strength !TP_LOCALLAB_STRUC;Structure !TP_LOCALLAB_STRUCCOL;Spot structure !TP_LOCALLAB_STRUCCOL1;Spot structure !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASKCOL;Structure mask strength -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). +!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! !TP_LOCALLAB_STYPE;Shape method !TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. @@ -3847,11 +4014,12 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. !TP_LOCALLAB_TRANSITVALUE;Transition value !TP_LOCALLAB_TRANSITWEAK;Transition decay (linear-log) -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). +!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain !TP_LOCALLAB_TRANSMISSIONMAP;Transmission map !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. +!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_USEMASK;Laplacian !TP_LOCALLAB_VART;Variance (contrast) !TP_LOCALLAB_VIBRANCE;Vibrance & Warm/Cool @@ -4192,7 +4360,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_WAVELET_WAVOFFSET;Offset !TP_WBALANCE_AUTOITCGREEN;Temperature correlation !TP_WBALANCE_AUTOOLD;RGB grey -!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement +!TP_WBALANCE_AUTO_HEADER;Automatic & Refinement !TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. !TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. !TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. @@ -4235,7 +4403,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !TP_WBALANCE_MULLABEL;Multipliers: r=%1 g=%2 b=%3 !TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. !TP_WBALANCE_OBSERVER10;Observer 10° instead of Observer 2° -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in Rawtherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nTo avoid a (rare) drift of the colors due to the choice Observer 10° - probably due to the conversion matrix - Observer 2° must be selected.\nIn a majority of cases Observer 10° (default) will be a more relevant choice. +!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. !TP_WBALANCE_PATCHLABEL;Read colors:%1 Patch: Chroma:%2 Size=%3 !TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. !TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - datas x 9 Min:%2 Max=%3 diff --git a/rtdata/languages/default b/rtdata/languages/default index f38d51d7d..3eacc3429 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1450,48 +1450,12 @@ HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Primaries method HISTORY_MSG_ICM_WORKING_SLOPE;TRC - Slope HISTORY_MSG_ICM_WORKING_TRC_METHOD;TRC method HISTORY_MSG_ILLUM;CAL - SC - Illuminant -HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle -HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression -HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold -HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white -HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation -HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast -HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools -HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam -HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma -HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut -HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant -HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q -HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones -HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L -HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries -HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors -HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid -HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability -HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method -HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope -HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance -HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance -HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method -HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L -HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC -HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X -HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y -HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X -HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y -HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution -HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X -HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y -HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x -HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y -HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene -HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing -HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode -HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control -HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength -HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount +HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness +HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast +HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness +HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius +HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius @@ -1502,26 +1466,62 @@ HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels +HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle +HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution +HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X +HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y +HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold +HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white +HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation +HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam +HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut +HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X +HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y +HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q +HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones +HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L +HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries +HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X +HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y +HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors +HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control +HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y +HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid +HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability +HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method +HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope +HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance +HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode +HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L +HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength +HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC +HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black +HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather +HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather +HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather -HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather -HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather -HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather -HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather +HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution -HISTORY_MSG_LOCALCONTRAST_AMOUNT;Local Contrast - Amount -HISTORY_MSG_LOCALCONTRAST_DARKNESS;Local Contrast - Darkness -HISTORY_MSG_LOCALCONTRAST_ENABLED;Local Contrast -HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Local Contrast - Lightness -HISTORY_MSG_LOCALCONTRAST_RADIUS;Local Contrast - Radius -HISTORY_MSG_LOCALLAB_TE_PIVOT;Local - Equalizer pivot -HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black -HISTORY_MSG_LOCAL_GAMUTMUNSEL;Local - SC - Avoid Color Shift HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation HISTORY_MSG_METADATA_MODE;Metadata copy mode HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrast threshold @@ -2019,8 +2019,8 @@ PREFERENCES_LENSFUNDBDIR;Lensfun database directory PREFERENCES_LENSFUNDBDIR_TOOLTIP;Directory containing the Lensfun database. Leave empty to use the default directories. PREFERENCES_LENSPROFILESDIR;Lens profiles directory PREFERENCES_LENSPROFILESDIR_TOOLTIP;Directory containing Adobe Lens Correction Profiles (LCPs) -PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom PREFERENCES_MENUGROUPEXTPROGS;Group 'Open with' PREFERENCES_MENUGROUPFILEOPERATIONS;Group 'File operations' PREFERENCES_MENUGROUPLABEL;Group 'Color label' @@ -2187,26 +2187,26 @@ QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears QUEUE_FORMAT_TITLE;File Format QUEUE_LOCATION_FOLDER;Save to folder QUEUE_LOCATION_TEMPLATE;Use template -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates -QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw -QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: -QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: -QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. -QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue +QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank +QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. -QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: -QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples -QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time +QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Specify the output location based on characteristics such as the source photo's location, rank, trash status or position in the queue.\n\nThe output template field value can include specifiers beginning with %, which are replaced by those characteristics in the actual destination path.\n\nPress the ? button for full instructions. QUEUE_LOCATION_TITLE;Output Location QUEUE_STARTSTOP_TOOLTIP;Start or stop processing the images in the queue.\n\nShortcut: Ctrl+s SAMPLEFORMAT_0;Unknown data format @@ -2245,6 +2245,9 @@ SORT_BY_LABEL;By Color Label SORT_BY_NAME;By Name SORT_BY_RANK;By Rank SORT_DESCENDING;Descending +TC_LOCALLAB_PRIM_SHIFTX;Shift x +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. +TC_LOCALLAB_PRIM_SHIFTY;Shift y TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By TC_PRIM_GREX;Gx @@ -2745,8 +2748,8 @@ TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' i TP_ICM_WORKINGPROFILE;Working Profile TP_ICM_WORKING_CAT;Matrix adaptation TP_ICM_WORKING_CAT_BRAD;Bradford -TP_ICM_WORKING_CAT_CAT16;Cat16 TP_ICM_WORKING_CAT_CAT02;Cat02 +TP_ICM_WORKING_CAT_CAT16;Cat16 TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford TP_ICM_WORKING_CAT_VK;Von Kries TP_ICM_WORKING_CAT_XYZ;XYZ scale @@ -2767,7 +2770,6 @@ TP_ICM_WORKING_ILLU_STDA;stdA 2875K TP_ICM_WORKING_NON;None TP_ICM_WORKING_PRESER;Preserves Pastel tones TP_ICM_WORKING_PRIM;Destination primaries -TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 @@ -2784,6 +2786,7 @@ TP_ICM_WORKING_PRIM_NONE;Default TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. TP_ICM_WORKING_PRIM_WID;WideGamut TP_ICM_WORKING_TRC;Tone response curve: TP_ICM_WORKING_TRC_18;Prophoto g=1.8 @@ -2838,10 +2841,10 @@ TP_LENSGEOM_FILL;Auto-fill TP_LENSGEOM_LABEL;Lens / Geometry TP_LENSGEOM_LIN;Linear TP_LENSGEOM_LOG;Logarithmic -TP_LENSPROFILE_CORRECTION_METADATA;From file metadata TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected +TP_LENSPROFILE_CORRECTION_METADATA;From file metadata TP_LENSPROFILE_LABEL;Profiled Lens Correction TP_LENSPROFILE_LENS_WARNING;Warning: the crop factor used for lens profiling is larger than the crop factor of the camera, the results might be wrong. TP_LENSPROFILE_MODE_HEADER;Lens Profile @@ -2938,12 +2941,6 @@ TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Color appearance (Cam16 & JzCzHz) -TP_LOCALLAB_CIE_SMOOTH_NONE;None -TP_LOCALLAB_CIE_SMOOTH_EV;Ev based -TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels -TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based -TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based -TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels TP_LOCALLAB_CIEC;Use Ciecam environment parameters TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. TP_LOCALLAB_CIECOLORFRA;Color @@ -2957,6 +2954,12 @@ TP_LOCALLAB_CIEMODE_TM;Tone-Mapping TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. TP_LOCALLAB_CIEMODE_WAV;Wavelet TP_LOCALLAB_CIETOOLEXP;Curves +TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels +TP_LOCALLAB_CIE_SMOOTH_EV;Ev based +TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based +TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based +TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels +TP_LOCALLAB_CIE_SMOOTH_NONE;None TP_LOCALLAB_CIE_TOOLNAME;Color appearance (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Spot size TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. @@ -2974,17 +2977,17 @@ TP_LOCALLAB_COFR;Color & Light TP_LOCALLAB_COLORDE;ΔE preview color - intensity TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. +TP_LOCALLAB_COLORFRAME;Dominant color TP_LOCALLAB_COLORSCOPE;Scope (color tools) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. TP_LOCALLAB_COLOR_CIE;Color curve TP_LOCALLAB_COLOR_TOOLNAME;Color & Light -TP_LOCALLAB_COLORFRAME;Dominant color TP_LOCALLAB_COL_NAME;Name TP_LOCALLAB_COL_VIS;Status TP_LOCALLAB_COMPFRA;Directional contrast -TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping TP_LOCALLAB_COMPRCIE;Brightness compression TP_LOCALLAB_COMPRCIETH;Compression threshold +TP_LOCALLAB_COMPREFRA;Wavelet level tone mapping TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. TP_LOCALLAB_CONTCOL;Contrast threshold TP_LOCALLAB_CONTFRA;Contrast by level @@ -3009,8 +3012,8 @@ TP_LOCALLAB_CURVNONE;Disable curves TP_LOCALLAB_DARKRETI;Darkness TP_LOCALLAB_DEHAFRA;Dehaze TP_LOCALLAB_DEHAZ;Strength -TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. TP_LOCALLAB_DEHAZE_BLACK;Black +TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. TP_LOCALLAB_DELTAD;Delta balance TP_LOCALLAB_DELTAEC;ΔE Image mask @@ -3044,8 +3047,8 @@ TP_LOCALLAB_EDGSHOW;Show all tools TP_LOCALLAB_ELI;Ellipse TP_LOCALLAB_ENABLE_AFTER_MASK;Use Tone Mapping TP_LOCALLAB_ENABLE_MASK;Enable mask -TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools TP_LOCALLAB_ENABLE_MASKAFT;Use all algorithms Exposure +TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. TP_LOCALLAB_ENH;Enhanced TP_LOCALLAB_ENHDEN;Enhanced + chroma denoise @@ -3093,7 +3096,6 @@ TP_LOCALLAB_EXP_TOOLNAME;Dynamic Range & Exposure TP_LOCALLAB_FATAMOUNT;Amount TP_LOCALLAB_FATANCHOR;Anchor TP_LOCALLAB_FATDETAIL;Detail -TP_LOCALLAB_FATSAT;Saturation control TP_LOCALLAB_FATFRA;Dynamic Range Compression Æ’ TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. TP_LOCALLAB_FATLEVEL;Sigma @@ -3243,9 +3245,9 @@ TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic rang TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. TP_LOCALLAB_LOGCIE;Log encoding -TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. +TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. TP_LOCALLAB_LOGCOLORFL;Colorfulness (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. TP_LOCALLAB_LOGCONQL;Contrast (Q) @@ -3419,18 +3421,15 @@ TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. TP_LOCALLAB_PASTELS2;Vibrance TP_LOCALLAB_PDE;Contrast Attenuator - Dynamic Range compression -TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. -TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. -TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. -TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. TP_LOCALLAB_PDEFRA;Contrast Attenuator Æ’ TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. +TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. +TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. +TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. TP_LOCALLAB_PREVHIDE;Hide additional settings TP_LOCALLAB_PREVIEW;Preview ΔE TP_LOCALLAB_PREVSHOW;Show additional settings -TC_LOCALLAB_PRIM_SHIFTX;Shift x -TC_LOCALLAB_PRIM_SHIFTY;Shift y -TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant TP_LOCALLAB_PROXI;ΔE decay TP_LOCALLAB_QUAAGRES;Aggressive @@ -3547,41 +3546,41 @@ TP_LOCALLAB_SHOWVI;Mask and modifications TP_LOCALLAB_SHRESFRA;Shadows/Highlights & TRC TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). TP_LOCALLAB_SH_TOOLNAME;Shadows/Highlights & Tone Equalizer +TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution TP_LOCALLAB_SIGCIE;Sigmoid TP_LOCALLAB_SIGFRA;Sigmoid Q TP_LOCALLAB_SIGGAMJCIE;Gamma TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Attenuation response +TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. TP_LOCALLAB_SIGMOIDBL;Blend TP_LOCALLAB_SIGMOIDLAMBDA;Contrast TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold -TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev -TP_LOCALLAB_SIGMOIDSENSI;Adaptability -TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) -TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. -TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance -TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. +TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. +TP_LOCALLAB_SIGMOIDQJ;Black Ev & White Ev TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). +TP_LOCALLAB_SIGMOIDSENSI;Adaptability +TP_LOCALLAB_SIGMOIDTH;Threshold (Gray point) +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. +TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. TP_LOCALLAB_SIGSLOPJCIE;Slope TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments -TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution TP_LOCALLAB_SIGWHITESCIE;Whites distribution -TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. TP_LOCALLAB_SLOMASKCOL;Slope TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) -TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) -TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) +TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) +TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) TP_LOCALLAB_SLOSH;Slope TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene -TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. +TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing TP_LOCALLAB_SOFT;Soft Light & Original Retinex TP_LOCALLAB_SOFTM;Soft Light TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. From aaf91fff8f0722e826ab2fde9a6e5161a0fd33c7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:01:39 -0700 Subject: [PATCH 270/291] Add DCPs and camconst.json entries from ART --- rtdata/dcpprofiles/NIKON Z 8.dcp | Bin 0 -> 65350 bytes rtdata/dcpprofiles/NIKON Z 9.dcp | Bin 0 -> 65350 bytes rtdata/dcpprofiles/NIKON Z F.dcp | Bin 0 -> 65350 bytes rtdata/dcpprofiles/camera_model_aliases.json | 2 ++ rtengine/camconst.json | 13 ++++++++++--- 5 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 rtdata/dcpprofiles/NIKON Z 8.dcp create mode 100644 rtdata/dcpprofiles/NIKON Z 9.dcp create mode 100644 rtdata/dcpprofiles/NIKON Z F.dcp diff --git a/rtdata/dcpprofiles/NIKON Z 8.dcp b/rtdata/dcpprofiles/NIKON Z 8.dcp new file mode 100644 index 0000000000000000000000000000000000000000..cbd59f0510849314450ef4cc883d1a53725f65aa GIT binary patch literal 65350 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�@iNRGvo!lewk8h|Xa6_bC=%EE=Ayi27*2057EgaL54}Q` z+>9d8x>g1ZzeHi}@cm-!gA};s#2_lBKpZ}mh%4>lV3d?AzFvw$wQ2Dvv(6GrYct+h zCBWxon)tFj61V4sn7<4|dR!vC-0`BA{H~rq6XEwUN)#;(!aLTLh1bJG(9{3~ z)lb5e6G7tE0zXi>gu&PRM2I{2B%>3dZlM)xPWd1V>Qk@zAt!6&LBpaWP52_Nkl1OU^mxj`{nXx1}ct&5KM(R%Fv{P7q&K zW?)eOnX46vBHKS5H9sm~GayBLH%mu9&gc^~>0;6#_7TlIF)bilR4!v3J@qATry_BJXwz@04KVw$O{H zx$L{l55>|?WuhP~9#TjcI*%$9ojIeh)`jDWQIWVZB?<;JBhWUyP`KSAQ}JO0j?;&3 z6&;Fh6C>eSm?;{Oy`yoDM9USa;+2jwXKf@dzey06=^uZylJlu`G0gYKWo;0NJ)anh z9DK2gbEsAc!Q#vtAIvxw4)QETZ*L7+Jqp9KLs}6iQQ!VB6t!)=MZacVkS>ORek0~f z)K+y0$HuiDqTNAqM%zdH^_>4VKKDA5Bpj~9k^fD7`Wvyb* zAAeFrLr2cL$z`$D`Ra zZ;W|UCg!EYBW68onc6~_Oo+!7KJyDL4htLOIP6;IhfSe}#Of|FxSi;ai+g2}cqtN1 zHU;2xUb(2F49DfK0o1yciul=~xHcsaZSoEXugSrv>lBE_u?50+V<67DaxOJIN4(>C zUR@rD0-toTt)CyBb_hgPPLeoT!JS7r0jO3UD^9G@BDQe=Dz8U~YkhstXS_cebqNty zYm);r%a5!xe{uDz7yL)*a4=0vZi5$Av(CNH)LX<*AAb6x53(PsM2eRhN$jh)?yVG7 zt*Dti}5TOg0q@T=PduOCPLP?-Lg}Kb_lv`=o~CiRY($@w}MNpG&4_=&6Oh z75B-lPZ2}yeX!_&H-cKni<#7qJ^96VJ|j{zaAME19U116LWE_47aBIBr>L91I7+RS z6Lr!b7y5_~^izjMC~?S8E#`9XQ=L)F4ak=m)5H@GuJRnnIEti)=$54ys(*A9PS(_X zoma!yZjV4LYZmGc{`)*f&{O=�MQrT;aYoRCqeFuepSNgl3^)I~nOqBIv1~6efZj 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 KE|0o4JpX?OVLDj= literal 0 HcmV?d00001 diff --git a/rtdata/dcpprofiles/NIKON Z 9.dcp b/rtdata/dcpprofiles/NIKON Z 9.dcp new file mode 100644 index 0000000000000000000000000000000000000000..9f644ae4185d94fb8bb97bf4a2a788bb44df9155 GIT binary patch literal 65350 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 uI9R`JY&W27Jpa%8Z**yUeYktu=+nP#?8XoH_ Date: Sat, 20 Jul 2024 17:38:59 -0700 Subject: [PATCH 271/291] Upgrade exiv2 and libjxl for AppImage Upgrade exiv2 to v0.28.3. Upgrade libjxl to 0.10.3. --- .github/workflows/appimage.yml | 2 +- .github/workflows/codeql.yml | 2 +- tools/makedeb/PKGBUILD.libjxl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 3b2ed7b19..787b2822c 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -52,7 +52,7 @@ jobs: - name: Install Exiv2 run: | - EXIV2_VERSION='v0.28.1' + EXIV2_VERSION='v0.28.3' echo "Cloning Exiv2 $EXIV2_VERSION." git clone --depth 1 --branch "$EXIV2_VERSION" https://github.com/Exiv2/exiv2.git ext/exiv2 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c25acedff..38b66cb96 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -47,7 +47,7 @@ jobs: run: | echo "Downloading and installing libjxl..." VERSION_UBUNTU=22.04 - VERSION_JXL=0.10.2 + VERSION_JXL=0.10.3 curl -Ss -qgb "" -fLC - --retry 3 --retry-delay 3 -o libjxl-debs.tar.gz \ "https://github.com/libjxl/libjxl/releases/download/v${VERSION_JXL}/jxl-debs-amd64-ubuntu-${VERSION_UBUNTU}-v${VERSION_JXL}.tar.gz" tar xf libjxl-debs.tar.gz diff --git a/tools/makedeb/PKGBUILD.libjxl b/tools/makedeb/PKGBUILD.libjxl index b63801812..ed48f846b 100644 --- a/tools/makedeb/PKGBUILD.libjxl +++ b/tools/makedeb/PKGBUILD.libjxl @@ -2,7 +2,7 @@ _pkgname="libjxl" pkgname="$_pkgname" -pkgver='0.10.2' +pkgver='0.10.3' pkgrel='1' pkgdesc='JPEG XL image format reference implementation' url='https://github.com/libjxl/libjxl' From 61aa4ad76a5f34e2e35d50e0850802f0543dd4e5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:08:44 -0700 Subject: [PATCH 272/291] Update Russian translation Translation supplied by Iliya5digital in https://github.com/Beep6581/RawTherapee/pull/7049. --- rtdata/languages/Russian | 425 ++++++++++++++++++++------------------- 1 file changed, 213 insertions(+), 212 deletions(-) diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 82f7a9718..ed6fee6a4 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -7,6 +7,7 @@ #007 2014-02-12 Kostia (Kildor) Romanov #008 2018-02-10 Kostia (Kildor) Romanov #009 2018-12-13 Kostia (Kildor) Romanov +#010 2024-04-12 Ilya #100 #101 @LANGUAGE_DISPLAY_NAME=РуÑÑкий @@ -19,10 +20,12 @@ ADJUSTER_RESET_TO_DEFAULT;Click: СброÑить на значение BATCH_PROCESSING;ÐŸÐ°ÐºÐµÑ‚Ð½Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ° CURVEEDITOR_AXIS_IN;I: CURVEEDITOR_AXIS_OUT;O: +CURVEEDITOR_CATMULLROM;ГибкоÑть CURVEEDITOR_CURVE;ÐšÑ€Ð¸Ð²Ð°Ñ CURVEEDITOR_CURVES;Кривые CURVEEDITOR_CUSTOM;Произвольный CURVEEDITOR_DARKS;Темные тона +CURVEEDITOR_EDITPOINT_HINT;Включить редактирование значений входа/выхода значений.\n\nЩелкните правой кнопкой мыши узел, чтобы выбрать его.\nЩелкните правой кнопкой мыши пуÑтое меÑто, чтобы отменить выбор значениÑ. CURVEEDITOR_HIGHLIGHTS;Света CURVEEDITOR_LIGHTS;Светлые тона CURVEEDITOR_LINEAR;Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ @@ -54,6 +57,9 @@ DYNPROFILEEDITOR_NEW;Ðовый DYNPROFILEEDITOR_NEW_RULE;Создать правило подбора DYNPROFILEEDITOR_PROFILE;Профиль обработки EDITWINDOW_TITLE;Редактор +EDIT_OBJECT_TOOLTIP;Отображает виджет в окне предварительного проÑмотра, который позволÑет наÑтроить Ñтот инÑтрумент. +EDIT_PIPETTE_TOOLTIP;Чтобы добавить точку корректировки к кривой, удерживайте клавишу Ctrl, щелкнув левой кнопкой мыши нужное меÑто в предварительном проÑмотре изображениÑ.\nЧтобы отрегулировать точку, удерживайте клавишу Ctrl, щелкнув левой кнопкой мыши ÑоответÑтвующую облаÑть в предварительном проÑмотре, затем отпуÑтите кнопку Ctrl (еÑли вам не нужен точный контроль) и, ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ Ð»ÐµÐ²ÑƒÑŽ кнопку мыши, перемеÑтите мышь вверх или вниз, чтобы перемеÑтить Ñту точку вверх или вниз по кривой. +ERROR_MSG_METADATA_VALUE;Метаданные: ошибки наÑтройки %1 на %2 EXIFFILTER_APERTURE;Диафрагма EXIFFILTER_CAMERA;Камера EXIFFILTER_EXPOSURECOMPENSATION;КомпенÑÐ°Ñ†Ð¸Ñ ÑкÑпозиции (EV) @@ -63,12 +69,16 @@ EXIFFILTER_IMAGETYPE;Тип Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ EXIFFILTER_ISO;ISO EXIFFILTER_LENS;Объектив EXIFFILTER_METADATAFILTER;Включить фильтры метаданных +EXIFFILTER_PATH;Путь к файлу EXIFFILTER_SHUTTER;Выдержка +EXIFPANEL_ACTIVATE_ALL_HINT;Выбрать вÑе Ñ‚Ñги +EXIFPANEL_ACTIVATE_NONE_HINT;Отменить вÑе Ñ‚Ñги EXIFPANEL_ADDEDIT;Добавить EXIFPANEL_ADDEDITHINT;Добавить новый Ñ‚Ñг или редактировать ÑущеÑтвующий EXIFPANEL_ADDTAGDLG_ENTERVALUE;ВвеÑти значение EXIFPANEL_ADDTAGDLG_SELECTTAG;Выбрать тег EXIFPANEL_ADDTAGDLG_TITLE;Добавить/редактировать тег +EXIFPANEL_BASIC_GROUP;ОÑнова EXIFPANEL_KEEP;ЗапиÑать EXIFPANEL_KEEPHINT;СохранÑть выбранные теги при запиÑи файла EXIFPANEL_REMOVE;Удалить @@ -77,10 +87,13 @@ EXIFPANEL_RESET;СброÑить EXIFPANEL_RESETALL;СброÑить вÑе EXIFPANEL_RESETALLHINT;СброÑить вÑе теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ EXIFPANEL_RESETHINT;СброÑить выбранные теги в первоначальные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ +EXIFPANEL_VALUE_NOT_SHOWN;Ðе показывать +EXPORT_BYPASS;Этапы обработки Ð´Ð»Ñ Ð¾Ð±Ñ…Ð¾Ð´Ð° EXPORT_BYPASS_ALL;Выделить вÑе / СнÑть выделение EXPORT_BYPASS_DEFRINGE;ПропуÑтить подавление ореолов EXPORT_BYPASS_DIRPYRDENOISE;ПропуÑтить подавление шума EXPORT_BYPASS_DIRPYREQUALIZER;ПропуÑтить контраÑÑ‚ в завиÑимоÑти от детализации +EXPORT_BYPASS_EQUALIZER;Обход уровней вейвлета EXPORT_BYPASS_RAW_CA;ПропуÑтить [raw] коррекцию хроматичеÑких аберраций EXPORT_BYPASS_RAW_CCSTEPS;ПропуÑтить [raw] подавление ложных цветов EXPORT_BYPASS_RAW_DCB_ENHANCE;ПропуÑтить [raw] раÑширенный DCB @@ -97,23 +110,34 @@ EXPORT_FASTEXPORTOPTIONS;ÐаÑтройки быÑтрого ÑкÑпорта EXPORT_INSTRUCTIONS;ÐаÑтройки быÑтрого ÑкÑпорта помогают Ñкономить Ð²Ñ€ÐµÐ¼Ñ Ð¸ реÑурÑÑ‹, затрачиваемые на уÑтановку наÑтроек обработки и запуÑкать очередь обработки, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð²Ð¼ÐµÑто Ñтого наÑтройки быÑтрого ÑкÑпорта. Этот метод рекомендуетÑÑ Ð´Ð»Ñ Ð±Ñ‹Ñтрого ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ð¹ Ñ Ð½Ð¸Ð·ÐºÐ¸Ð¼ разрешением, когда ÑкороÑть обработки в приоритете или когда нужно отмаÑштабировать одно или неÑколько изображений без внеÑÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ в их Ñохранённые параметры обработки. EXPORT_MAXHEIGHT;МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота: EXPORT_MAXWIDTH;МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð°: +EXPORT_PIPELINE;Конвейер обработки EXPORT_PUTTOQUEUEFAST; ПоÑтавить в очередь Ð´Ð»Ñ Ð±Ñ‹Ñтрого ÑкÑпорта EXPORT_RAW_DMETHOD;Метод демозаика +EXPORT_USE_FAST_PIPELINE;Выделенный (Ð¿Ð¾Ð»Ð½Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð½Ñ‹Ð¼ размером) +EXPORT_USE_FAST_PIPELINE_TOOLTIP;ИÑпользуйте Ñпециальный конвейер обработки изображений в режиме быÑтрого ÑкÑпорта, в котором ÑкороÑть ÑочетаетÑÑ Ñ ÐºÐ°Ñ‡ÐµÑтвом. Изменение размера Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÑетÑÑ ÐºÐ°Ðº можно раньше, а не в конце, как в обычном конвейере. УÑкорение может быть значительным, но будьте готовы увидеть артефакты и общее ухудшение качеÑтва вывода. +EXPORT_USE_NORMAL_PIPELINE;Стандартный (пропуÑтить некоторые шаги, изменить размер в конце) EXTPROGTARGET_1;raw EXTPROGTARGET_2;в очереди обработки FILEBROWSER_APPLYPROFILE;Применить FILEBROWSER_APPLYPROFILE_PARTIAL;Применить - чаÑтично FILEBROWSER_AUTODARKFRAME;ÐвтоматичеÑкий темновой кадр FILEBROWSER_AUTOFLATFIELD;ÐвтоматичеÑкое плоÑкое поле +FILEBROWSER_BROWSEPATHBUTTONHINT;Ðажмите, чтобы открыть указанный путь, перезагрузить папку и применить ключевые Ñлова «найти». FILEBROWSER_BROWSEPATHHINT;Введите путь Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð°.\nCtrl-O Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° на диалог ввода текÑта.\nEnter / Ctrl-Enter (в обозревателе файлов) Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð°;\n\nЯрлыки путей:\n ~ - домашний каталог пользователÑ\n ! - каталог Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñми FILEBROWSER_CACHE;КÑш +FILEBROWSER_CACHECLEARFROMFULL;ОчиÑтить вÑе включенные кÑшированные профили +FILEBROWSER_CACHECLEARFROMPARTIAL;ОчиÑтить вÑе кроме кÑшированных профилей FILEBROWSER_CLEARPROFILE;Удалить профиль FILEBROWSER_COLORLABEL_TOOLTIP;Color label\n\nUse dropdown menu or Shortcuts:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Red\nShift-Ctrl-2 Yellow\nShift-Ctrl-3 Green\nShift-Ctrl-4 Blue\nShift-Ctrl-5 Purple FILEBROWSER_COPYPROFILE;Скопировать профиль FILEBROWSER_CURRENT_NAME;Текущее имÑ: FILEBROWSER_DARKFRAME;Темновой кадр +FILEBROWSER_DELETEDIALOG_ALL;Ð’Ñ‹ уверены, что хотите навÑегда удалить вÑе файлы %1 из корзины? FILEBROWSER_DELETEDIALOG_HEADER;Подтверждение ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° +FILEBROWSER_DELETEDIALOG_SELECTED;Ð’Ñ‹ уверены, что хотите навÑегда удалить выбранные файлы %1? +FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Ð’Ñ‹ уверены, что хотите навÑегда удалить выбранные файлы %1, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²ÐµÑ€Ñию, обработанную в очереди? FILEBROWSER_EMPTYTRASH;ОчиÑтить корзину +FILEBROWSER_EMPTYTRASHHINT;ÐавÑегда удалить вÑе файлы из корзины. FILEBROWSER_EXTPROGMENU;Открыть Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ FILEBROWSER_FLATFIELD;ПлоÑкое поле FILEBROWSER_MOVETODARKFDIR;ПеремеÑтить в каталог темновых кадров @@ -132,6 +156,7 @@ FILEBROWSER_POPUPCOLORLABEL4;Пометка: Синим FILEBROWSER_POPUPCOLORLABEL5;Пометка: Фиолетовым FILEBROWSER_POPUPCOPYTO;Скопировать в... FILEBROWSER_POPUPFILEOPERATIONS;ДейÑÑ‚Ð²Ð¸Ñ Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ +FILEBROWSER_POPUPINSPECT;ОÑмотреть FILEBROWSER_POPUPMOVEEND;ПеремеÑтить в конец очереди FILEBROWSER_POPUPMOVEHEAD;ПеремеÑтить в начало очереди FILEBROWSER_POPUPMOVETO;ПеремеÑтить в... @@ -147,8 +172,11 @@ FILEBROWSER_POPUPRANK2;Рейтинг 2 ** FILEBROWSER_POPUPRANK3;Рейтинг 3 *** FILEBROWSER_POPUPRANK4;Рейтинг 4 **** FILEBROWSER_POPUPRANK5;Рейтинг 5 ***** +FILEBROWSER_POPUPREMOVE;Удалить навÑегда +FILEBROWSER_POPUPREMOVEINCLPROC;Удалить навÑегда, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²ÐµÑ€Ñию, обработанную в очереди FILEBROWSER_POPUPRENAME;Переименовать FILEBROWSER_POPUPSELECTALL;Выбрать вÑе +FILEBROWSER_POPUPSORTBY;Сортировать файлы FILEBROWSER_POPUPTRASH;Удалить в корзину FILEBROWSER_POPUPUNRANK;СнÑть рейтинг FILEBROWSER_POPUPUNTRASH;Удалить из корзины @@ -173,6 +201,8 @@ FILEBROWSER_SHOWDIRHINT;СброÑить вÑе фильтры.\nГорÑÑ‡Ð°Ñ FILEBROWSER_SHOWEDITEDHINT;Показать измененные изображениÑ.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Показать не измененные изображениÑ.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: 6 FILEBROWSER_SHOWEXIFINFO;Показать информацию EXIF.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: i\n\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ° в режиме Одиночного редактора: Alt-I +FILEBROWSER_SHOWNOTTRASHHINT;Показывать только Ð¸Ð·Ð¾Ð±Ñ€Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ в корзине +FILEBROWSER_SHOWORIGINALHINT;Показывать только иÑходные изображениÑ.\n\nЕÑли ÑущеÑтвует неÑколько изображений Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼ именем файла, но Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ раÑширениÑми, оригинальным ÑчитаетÑÑ Ñ‚Ð¾, раÑширение которого находитÑÑ Ð±Ð»Ð¸Ð¶Ðµ вÑего к началу ÑпиÑка проанализированных раÑширений в разделе «ÐаÑтройки» > «Браузер файлов» > «Проанализированные раÑширениÑ». FILEBROWSER_SHOWRANK1HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 1.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: 1 FILEBROWSER_SHOWRANK2HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 2.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: 2 FILEBROWSER_SHOWRANK3HINT;Показать Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ¹Ñ‚Ð¸Ð½Ð³Ð¾Ð¼ 3.\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: 3 @@ -190,7 +220,10 @@ FILEBROWSER_ZOOMOUTHINT;Уменьшить размер ÑÑкиза\nГорÑч FILECHOOSER_FILTER_ANY;Ð’Ñе файлы FILECHOOSER_FILTER_COLPROF;Цветовые профили FILECHOOSER_FILTER_CURVE;Файлы кривых +FILECHOOSER_FILTER_EXECUTABLE;ИÑполнÑмые файлы FILECHOOSER_FILTER_LCP;Файлы коррекции объектива +FILECHOOSER_FILTER_PP;Обработка профилей +FILECHOOSER_FILTER_SAME;Тот же формат, как на Ñтом изоброжении FILECHOOSER_FILTER_TIFF;Файлы TIFF GENERAL_ABOUT;О программе GENERAL_AFTER;ПоÑле @@ -201,17 +234,21 @@ GENERAL_BEFORE;До GENERAL_CANCEL;Отмена GENERAL_CLOSE;Закрыть GENERAL_CURRENT;Текущий +GENERAL_DELETE_ALL;Удалить вÑе GENERAL_DISABLE;Выключить GENERAL_DISABLED;Выключено +GENERAL_EDIT;Редактировать GENERAL_ENABLE;Включить GENERAL_ENABLED;Включено GENERAL_FILE;Файл +GENERAL_HELP;Справка GENERAL_LANDSCAPE;Ðльбомный GENERAL_NA;Ð/Д GENERAL_NO;Ðет GENERAL_NONE;Ðет GENERAL_OK;OK GENERAL_OPEN;Открыть +GENERAL_OTHER;Прочее GENERAL_PORTRAIT;Портретный GENERAL_RESET;СброÑить GENERAL_SAVE;Сохранить @@ -219,12 +256,23 @@ GENERAL_SAVE_AS;Сохранить как... GENERAL_SLIDER;Ползунок GENERAL_UNCHANGED;(не менÑлоÑÑŒ) GENERAL_WARNING;Внимание +GIMP_PLUGIN_INFO;Добро пожаловать в плагин RawTherapee GIMP!\nПоÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñто закройте главное окно RawTherapee, и изображение будет автоматичеÑки импортировано в GIMP. HISTOGRAM_TOOLTIP_B;Показать/Ñкрыть Ñиний канал гиÑтограммы HISTOGRAM_TOOLTIP_BAR;Показать/Ñкрыть панель Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ RGB\nÐажмите правую кнопку мыши на предпроÑмотре изображениÑ, чтобы заблокировать/разблокировать его HISTOGRAM_TOOLTIP_CHRO;Показать/Ñкрыть хроматичеÑкую гиÑтограмму +HISTOGRAM_TOOLTIP_CROSSHAIR;Показать/Скрыть перекреÑтие индикатора. HISTOGRAM_TOOLTIP_G;Показать/Ñкрыть зелёный канал гиÑтограммы HISTOGRAM_TOOLTIP_L;Показать/Ñкрыть CIELAB гиÑтограмму +HISTOGRAM_TOOLTIP_MODE;Переключение между линейным, лог-линейным и лог-логарифмичеÑким маÑштабированием гиÑтограммы. HISTOGRAM_TOOLTIP_R;Показать/Ñкрыть краÑный канал гиÑтограммы +HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Переключить видимоÑть кнопок выбора облаÑти. +HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Отрегулируйте ÑркоÑть прицела. +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;ГиÑтограмма +HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;ÐÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð°Ñ Ð³Ð¸Ñтограмма +HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-парад +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;ВектороÑкоп Hue-Chroma +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;ВектороÑкоп Hue-Saturation +HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Волна HISTORY_CHANGED;Изменено HISTORY_CUSTOMCURVE;ПользовательÑÐºÐ°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ HISTORY_FROMCLIPBOARD;Из буфера обмена @@ -457,11 +505,176 @@ HISTORY_MSG_247;ÐšÑ€Ð¸Ð²Ð°Ñ 'LH' HISTORY_MSG_248;ÐšÑ€Ð¸Ð²Ð°Ñ 'HH' HISTORY_MSG_249;КпУД: Порог HISTORY_MSG_251;Ч&Б: Ðлгоритм +HISTORY_MSG_252;CbDL - Кожа Ñмола/защита +HISTORY_MSG_253;CbDL - УÑтранить дефекты +HISTORY_MSG_254;CbDL - Тон кожи +HISTORY_MSG_255;NR - Фильтр медианы +HISTORY_MSG_256;NR - Тип - Медиана +HISTORY_MSG_257;Цветное тонирование +HISTORY_MSG_258;CT - Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_MSG_259;CT - ÐšÑ€Ð¸Ð²Ð°Ñ Ð½ÐµÐ¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ð¾Ñти +HISTORY_MSG_260;CT - a*[b*] ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_MSG_261;CT - Метод +HISTORY_MSG_262;CT - b* ÐºÑ€Ð¸Ð²Ð°Ñ +HISTORY_MSG_263;CT - Тени - КраÑные +HISTORY_MSG_264;CT - Тени - Зеленые +HISTORY_MSG_265;CT - Тени - Синие +HISTORY_MSG_266;CT - Средний – КраÑный +HISTORY_MSG_267;CT - Средний – Зеленый +HISTORY_MSG_268;CT - Средний – Синий +HISTORY_MSG_269;CT - Ð’Ñ‹Ñокий - КраÑный +HISTORY_MSG_270;CT - Ð’Ñ‹Ñокий - Зеленый +HISTORY_MSG_271;CT - Ð’Ñ‹Ñокий - Синий +HISTORY_MSG_272;CT - Ð‘Ð°Ð»Ð°Ð½Ñ +HISTORY_MSG_273;CT - Цветовой Ð‘Ð°Ð»Ð°Ð½Ñ SMH +HISTORY_MSG_276;CT - ÐšÑ€Ð¸Ð²Ð°Ñ HISTORY_MSG_277;--неиÑпользуемый-- +HISTORY_MSG_278;CT - Сохранение ÑркоÑти +HISTORY_MSG_279;CT - Тени +HISTORY_MSG_280;CT - Ð’Ñ‹Ñокие +HISTORY_MSG_283;CT - Сила +HISTORY_MSG_284;CT - Ðвто sat. защита +HISTORY_MSG_285;NR - Медиана - Метод +HISTORY_MSG_286;NR - Медиана - Тип +HISTORY_MSG_287;NR - Медиана - Итерации +HISTORY_MSG_288;Flat-Field - управление клипом +HISTORY_MSG_289;Flat-Field - Управление клипом - Ðвто +HISTORY_MSG_290;Уровень Черного - КраÑный +HISTORY_MSG_291;Уровень Черного - Зеленый +HISTORY_MSG_292;Уровень Черного - Синий HISTORY_MSG_293;Ð˜Ð¼Ð¸Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð»Ñ‘Ð½ÐºÐ¸ HISTORY_MSG_294;Ð˜Ð¼Ð¸Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð»Ñ‘Ð½ÐºÐ¸: Сила HISTORY_MSG_295;Ð˜Ð¼Ð¸Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð»Ñ‘Ð½ÐºÐ¸: Плёнка +HISTORY_MSG_296;NR - ÐšÑ€Ð¸Ð²Ð°Ñ ÑркоÑти +HISTORY_MSG_297;NR - Режим HISTORY_MSG_298;Фильтр битых пикÑелей +HISTORY_MSG_299;NR - ÐšÑ€Ð¸Ð²Ð°Ñ Ñ†Ð²ÐµÑ‚Ð½Ð¾Ñти +HISTORY_MSG_301;NR - Управление ÑркоÑтью +HISTORY_MSG_302;NR - Метод цветноÑти +HISTORY_MSG_303;NR - Метод цветноÑти +HISTORY_MSG_304;W - Уровни контраÑтноÑти +HISTORY_MSG_305;Вейвлет-уровни +HISTORY_MSG_306;W - ПрогреÑÑ +HISTORY_MSG_307;W - ПрогреÑÑ +HISTORY_MSG_308;W - Ðаправление процеÑÑа +HISTORY_MSG_309;W - ES - Детали +HISTORY_MSG_310;W - ОÑтаток - ÐебеÑÐ½Ð°Ñ Ñмола/защита +HISTORY_MSG_311;W - Вейвлет-уровни +HISTORY_MSG_312;W - ОÑтаток - порог теней +HISTORY_MSG_313;W - ЦветноÑть - Sat/past +HISTORY_MSG_314;W - Гамма - уменьшение артефактов +HISTORY_MSG_315;W - ОÑтаток - КонтраÑÑ‚ +HISTORY_MSG_316;W - Гамма - кожи tar/prot +HISTORY_MSG_317;W - Гамма - Тон кожи +HISTORY_MSG_318;W - КонтраÑтноÑть - более тонкие уровни +HISTORY_MSG_319;W - КонтраÑтноÑть - более тонкий диапазон +HISTORY_MSG_320;W - КонтраÑтноÑть - более грубый диапазон +HISTORY_MSG_321;W - КонтраÑтноÑть - более грубые уровни +HISTORY_MSG_322;W - Гамма – Избегайте ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° +HISTORY_MSG_323;W - ES - Локальный контраÑÑ‚ +HISTORY_MSG_324;W - ЦветноÑть - ПаÑтель +HISTORY_MSG_325;W - ЦветноÑть – ÐаÑÑ‹Ñ‰ÐµÐ½Ð½Ð°Ñ +HISTORY_MSG_326;W - ЦветноÑть - Метод +HISTORY_MSG_327;W - КонтраÑÑ‚ – Применить к +HISTORY_MSG_328;W - ЦветноÑть – Ñила ÑвÑзи +HISTORY_MSG_329;W - Тонирование - ÐепрозрачноÑть RG +HISTORY_MSG_330;W - Тонирование - ÐепрозрачноÑть BY +HISTORY_MSG_331;W - Уровни контраÑтноÑти – ЭкÑтра +HISTORY_MSG_332;W - Метод укладки плитки +HISTORY_MSG_333;W - ОÑтаток – Тени +HISTORY_MSG_334;W - ОÑтаток – цветноÑть +HISTORY_MSG_335;W - ОÑтаток – Ð’Ñ‹Ñокие +HISTORY_MSG_336;W - ОÑтаток - порог выÑоких +HISTORY_MSG_337;W - ОÑтаток – ÐебеÑный оттенок +HISTORY_MSG_338;W - ES - Ð Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_339;W - ES - Длина +HISTORY_MSG_340;W - Длина +HISTORY_MSG_341;W - ÐŸÐ¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñть +HISTORY_MSG_342;W - ES - Первый уроень +HISTORY_MSG_343;W - Уровни цветноÑти +HISTORY_MSG_344;W - Мет цветноÑть sl/cur +HISTORY_MSG_345;W - ES - Локальный контраÑÑ‚ +HISTORY_MSG_346;W - ES - Локальный контраÑтный метод +HISTORY_MSG_347;W - Шумоподавление - Уровень 1 +HISTORY_MSG_348;W - Шумоподавление - Уровень 2 +HISTORY_MSG_349;W - Шумоподавление - Уровень 3 +HISTORY_MSG_350;W - ES - Обнаружение краёв +HISTORY_MSG_351;W - ОÑтаток - ÐºÑ€Ð¸Ð²Ð°Ñ HH +HISTORY_MSG_352;W - Фон +HISTORY_MSG_353;W - ES - Ð“Ñ€Ð°Ð´Ð¸ÐµÐ½Ñ‚Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑть +HISTORY_MSG_354;W - ES - ÐŸÐ¾Ð²Ñ‹ÑˆÐµÐ½Ð½Ð°Ñ +HISTORY_MSG_355;W - ES - Порг низких +HISTORY_MSG_356;W - ES - Порог выÑоких +HISTORY_MSG_357;W - Шумоподавление - СвÑзь Ñ ES +HISTORY_MSG_358;W - Гамма – CH +HISTORY_MSG_359;ГорÑчий/Мертвый – Порог +HISTORY_MSG_360;TM - Гамма +HISTORY_MSG_361;W - Финал – Ð±Ð°Ð»Ð°Ð½Ñ Ñ†Ð²ÐµÑ‚Ð½Ð¾Ñти +HISTORY_MSG_362;W - ОÑтаток - метод ÑÐ¶Ð°Ñ‚Ð¸Ñ +HISTORY_MSG_363;W - ОÑтаток - прочноÑть на Ñжатие +HISTORY_MSG_364;W - Финал - Ð‘Ð°Ð»Ð°Ð½Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð°Ñта +HISTORY_MSG_365;W - Финал - Ð‘Ð°Ð»Ð°Ð½Ñ Ð”ÐµÐ»ÑŒÑ‚Ñ‹ +HISTORY_MSG_366;W - ОÑтаток – Гамма ÑÐ¶Ð°Ñ‚Ð¸Ñ +HISTORY_MSG_367;W - Финал – ÐºÑ€Ð¸Ð²Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð°ÑтноÑти «ПоÑле» +HISTORY_MSG_368;W - Финал - контраÑтный Ð±Ð°Ð»Ð°Ð½Ñ +HISTORY_MSG_369;W - Финал - метод баланÑа +HISTORY_MSG_370;W - Финал – ÐºÑ€Ð¸Ð²Ð°Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ контраÑта +HISTORY_MSG_371;Повышение резкоÑти поÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° +HISTORY_MSG_372;PRS USM - Ð Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_373;PRS USM - КоличеÑво +HISTORY_MSG_374;PRS USM - Порг +HISTORY_MSG_375;PRS USM - Заточить только ÐºÑ€Ð°Ñ +HISTORY_MSG_376;PRS USM - Ð Ð°Ð´Ð¸ÑƒÑ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ ÐºÑ€Ð°Ñ +HISTORY_MSG_377;PRS USM - ДопуÑк кромки +HISTORY_MSG_378;PRS USM - Гало-контроль +HISTORY_MSG_379;PRS USM - ÐšÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма Halo +HISTORY_MSG_380;PRS - Метод +HISTORY_MSG_381;PRS RLD - Ð Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_382;PRS RLD - КоличеÑво +HISTORY_MSG_383;PRS RLD - Демпфирование +HISTORY_MSG_384;PRS RLD - Итерации +HISTORY_MSG_385;W - ОÑтаток - Цветовой Ð±Ð°Ð»Ð°Ð½Ñ +HISTORY_MSG_386;W - ОÑтаток - CB зеленый макÑимум +HISTORY_MSG_387;W - ОÑтаток - CB Ñиний макÑимум +HISTORY_MSG_388;W - ОÑтаток - CB зеленый Ñредний +HISTORY_MSG_389;W - ОÑтаток - CB Ñиний Ñредний +HISTORY_MSG_390;W - ОÑтаток – зеленый минимум CB +HISTORY_MSG_391;W - ОÑтаток - CB Ñиний низкий +HISTORY_MSG_392;W - ОÑтаток - Цветовой Ð±Ð°Ð»Ð°Ð½Ñ +HISTORY_MSG_393;DCP - ПроÑмотр таблицы +HISTORY_MSG_394;DCP - Базовое воздейÑтвие +HISTORY_MSG_395;DCP - Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° +HISTORY_MSG_396;W - Дополнительный инÑтрумент «КонтраÑт» +HISTORY_MSG_397;W - Дополнительный инÑтрумент «ЦветноÑть» +HISTORY_MSG_398;W - Дополнительный инÑтрумент ES +HISTORY_MSG_399;W - ОÑтаточный вÑпомогательный инÑтрумент +HISTORY_MSG_400;W - ПоÑледний подинÑтрумент +HISTORY_MSG_401;W - Дополнительный инÑтрумент Ð´Ð»Ñ Ñ‚Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ +HISTORY_MSG_402;W - Дополнительный инÑтрумент ÑˆÑƒÐ¼Ð¾Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ +HISTORY_MSG_403;W - ES - ÐšÑ€Ð°ÐµÐ²Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑть +HISTORY_MSG_404;W - ES - Базовое уÑиление +HISTORY_MSG_405;W - Шумоподавление - Уровень 4 +HISTORY_MSG_406;W - ES - СоÑедние пикÑели +HISTORY_MSG_407;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ â€“ Метод +HISTORY_MSG_408;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Ð Ð°Ð´Ð¸ÑƒÑ +HISTORY_MSG_410;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Смещение +HISTORY_MSG_411;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Сила +HISTORY_MSG_412;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - ГауÑÑов градиент +HISTORY_MSG_413;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - КонтраÑÑ‚ +HISTORY_MSG_414;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - ГиÑтограмма - Ð›Ð°Ð±Ð¾Ñ€Ð°Ñ‚Ð¾Ñ€Ð¸Ñ +HISTORY_MSG_415;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - ТранÑмиÑÑÐ¸Ñ +HISTORY_MSG_416;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ +HISTORY_MSG_417;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ â€“ Медиана передачи +HISTORY_MSG_418;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Порог +HISTORY_MSG_419;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Цветовое проÑтранÑтво +HISTORY_MSG_420;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - ГиÑтограмма - HSL +HISTORY_MSG_421;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Гамма +HISTORY_MSG_422;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Гамма +HISTORY_MSG_423;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Гамма-наклон +HISTORY_MSG_424;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - порог HL +HISTORY_MSG_426;Ð ÐµÑ‚Ð¸Ð½ÐµÐºÑ - Ñквалайзер оттенков +HISTORY_MSG_427;Цель рендеринга вывода +HISTORY_MSG_428;Мониторинг Ð½Ð°Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð° HISTORY_MSG_440;КпУД: Метод HISTORY_MSG_485;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¸Ð²Ð° HISTORY_MSG_486;ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¸Ð²Ð°: Камера @@ -1428,224 +1641,12 @@ ZOOMPANEL_ZOOMOUT;Отдалить\nГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°: - !CURVEEDITOR_AXIS_LEFT_TAN;LT: !CURVEEDITOR_AXIS_RIGHT_TAN;RT: -!CURVEEDITOR_CATMULLROM;Flexible -!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. -!EDIT_OBJECT_TOOLTIP;Displays a widget on the preview window which lets you adjust this tool. -!EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. -!ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!EXIFFILTER_PATH;File path -!EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags -!EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags -!EXIFPANEL_BASIC_GROUP;Basic -!EXIFPANEL_VALUE_NOT_SHOWN;Not shown -!EXPORT_BYPASS;Processing steps to bypass -!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels -!EXPORT_PIPELINE;Processing pipeline -!EXPORT_USE_FAST_PIPELINE;Dedicated (full processing on resized image) -!EXPORT_USE_FAST_PIPELINE_TOOLTIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality. -!EXPORT_USE_NORMAL_PIPELINE;Standard (bypass some steps, resize at the end) -!FILEBROWSER_BROWSEPATHBUTTONHINT;Click to open specified path, reload folder and apply 'find' keywords. -!FILEBROWSER_CACHECLEARFROMFULL;Clear all including cached profiles -!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear all except cached profiles -!FILEBROWSER_DELETEDIALOG_ALL;Are you sure you want to permanently delete all %1 files in trash? -!FILEBROWSER_DELETEDIALOG_SELECTED;Are you sure you want to permanently delete the selected %1 files? -!FILEBROWSER_DELETEDIALOG_SELECTEDINCLPROC;Are you sure you want to permanently delete the selected %1 files, including a queue-processed version? -!FILEBROWSER_EMPTYTRASHHINT;Permanently delete all files in trash. -!FILEBROWSER_POPUPINSPECT;Inspect -!FILEBROWSER_POPUPREMOVE;Delete permanently -!FILEBROWSER_POPUPREMOVEINCLPROC;Delete permanently, including queue-processed version -!FILEBROWSER_POPUPSORTBY;Sort Files -!FILEBROWSER_SHOWNOTTRASHHINT;Show only images not in trash. -!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. -!FILECHOOSER_FILTER_EXECUTABLE;Executable files -!FILECHOOSER_FILTER_PP;Processing profiles -!FILECHOOSER_FILTER_SAME;Same format as current photo -!GENERAL_DELETE_ALL;Delete all -!GENERAL_EDIT;Edit -!GENERAL_HELP;Help -!GENERAL_OTHER;Other -!GIMP_PLUGIN_INFO;Welcome to the RawTherapee GIMP plugin!\nOnce you are done editing, simply close the main RawTherapee window and the image will be automatically imported in GIMP. -!HISTOGRAM_TOOLTIP_CROSSHAIR;Show/Hide indicator crosshair. -!HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram. -!HISTOGRAM_TOOLTIP_SHOW_OPTIONS;Toggle visibility of the scope option buttons. -!HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Adjust scope brightness. -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram -!HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw Histogram -!HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB Parade -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Hue-Chroma Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Hue-Saturation Vectorscope -!HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Waveform !HISTORY_MSG_235;B&W - CM - Auto !HISTORY_MSG_237;B&W - CM -!HISTORY_MSG_252;CbDL - Skin tar/prot -!HISTORY_MSG_253;CbDL - Reduce artifacts -!HISTORY_MSG_254;CbDL - Skin hue -!HISTORY_MSG_255;NR - Median filter -!HISTORY_MSG_256;NR - Median - Type -!HISTORY_MSG_257;Color Toning -!HISTORY_MSG_258;CT - Color curve -!HISTORY_MSG_259;CT - Opacity curve -!HISTORY_MSG_260;CT - a*[b*] opacity -!HISTORY_MSG_261;CT - Method -!HISTORY_MSG_262;CT - b* opacity -!HISTORY_MSG_263;CT - Shadows - Red -!HISTORY_MSG_264;CT - Shadows - Green -!HISTORY_MSG_265;CT - Shadows - Blue -!HISTORY_MSG_266;CT - Mid - Red -!HISTORY_MSG_267;CT - Mid - Green -!HISTORY_MSG_268;CT - Mid - Blue -!HISTORY_MSG_269;CT - High - Red -!HISTORY_MSG_270;CT - High - Green -!HISTORY_MSG_271;CT - High - Blue -!HISTORY_MSG_272;CT - Balance -!HISTORY_MSG_273;CT - Color Balance SMH -!HISTORY_MSG_276;CT - Opacity -!HISTORY_MSG_278;CT - Preserve luminance -!HISTORY_MSG_279;CT - Shadows -!HISTORY_MSG_280;CT - Highlights !HISTORY_MSG_281;CT - Sat. strength !HISTORY_MSG_282;CT - Sat. threshold -!HISTORY_MSG_283;CT - Strength -!HISTORY_MSG_284;CT - Auto sat. protection -!HISTORY_MSG_285;NR - Median - Method -!HISTORY_MSG_286;NR - Median - Type -!HISTORY_MSG_287;NR - Median - Iterations -!HISTORY_MSG_288;Flat-Field - Clip control -!HISTORY_MSG_289;Flat-Field - Clip control - Auto -!HISTORY_MSG_290;Black Level - Red -!HISTORY_MSG_291;Black Level - Green -!HISTORY_MSG_292;Black Level - Blue -!HISTORY_MSG_296;NR - Luminance curve -!HISTORY_MSG_297;NR - Mode -!HISTORY_MSG_299;NR - Chrominance curve -!HISTORY_MSG_301;NR - Luma control -!HISTORY_MSG_302;NR - Chroma method -!HISTORY_MSG_303;NR - Chroma method -!HISTORY_MSG_304;W - Contrast levels -!HISTORY_MSG_305;Wavelet Levels -!HISTORY_MSG_306;W - Process -!HISTORY_MSG_307;W - Process -!HISTORY_MSG_308;W - Process direction -!HISTORY_MSG_309;W - ES - Detail -!HISTORY_MSG_310;W - Residual - Sky tar/prot -!HISTORY_MSG_311;W - Wavelet levels -!HISTORY_MSG_312;W - Residual - Shadows threshold -!HISTORY_MSG_313;W - Chroma - Sat/past -!HISTORY_MSG_314;W - Gamut - Reduce artifacts -!HISTORY_MSG_315;W - Residual - Contrast -!HISTORY_MSG_316;W - Gamut - Skin tar/prot -!HISTORY_MSG_317;W - Gamut - Skin hue -!HISTORY_MSG_318;W - Contrast - Finer levels -!HISTORY_MSG_319;W - Contrast - Finer range -!HISTORY_MSG_320;W - Contrast - Coarser range -!HISTORY_MSG_321;W - Contrast - Coarser levels -!HISTORY_MSG_322;W - Gamut - Avoid color shift -!HISTORY_MSG_323;W - ES - Local contrast -!HISTORY_MSG_324;W - Chroma - Pastel -!HISTORY_MSG_325;W - Chroma - Saturated -!HISTORY_MSG_326;W - Chroma - Method -!HISTORY_MSG_327;W - Contrast - Apply to -!HISTORY_MSG_328;W - Chroma - Link strength -!HISTORY_MSG_329;W - Toning - Opacity RG -!HISTORY_MSG_330;W - Toning - Opacity BY -!HISTORY_MSG_331;W - Contrast levels - Extra -!HISTORY_MSG_332;W - Tiling method -!HISTORY_MSG_333;W - Residual - Shadows -!HISTORY_MSG_334;W - Residual - Chroma -!HISTORY_MSG_335;W - Residual - Highlights -!HISTORY_MSG_336;W - Residual - Highlights threshold -!HISTORY_MSG_337;W - Residual - Sky hue -!HISTORY_MSG_338;W - ES - Radius -!HISTORY_MSG_339;W - ES - Strength -!HISTORY_MSG_340;W - Strength -!HISTORY_MSG_341;W - Edge performance -!HISTORY_MSG_342;W - ES - First level -!HISTORY_MSG_343;W - Chroma levels -!HISTORY_MSG_344;W - Meth chroma sl/cur -!HISTORY_MSG_345;W - ES - Local contrast -!HISTORY_MSG_346;W - ES - Local contrast method -!HISTORY_MSG_347;W - Denoise - Level 1 -!HISTORY_MSG_348;W - Denoise - Level 2 -!HISTORY_MSG_349;W - Denoise - Level 3 -!HISTORY_MSG_350;W - ES - Edge detection -!HISTORY_MSG_351;W - Residual - HH curve -!HISTORY_MSG_352;W - Background -!HISTORY_MSG_353;W - ES - Gradient sensitivity -!HISTORY_MSG_354;W - ES - Enhanced -!HISTORY_MSG_355;W - ES - Threshold low -!HISTORY_MSG_356;W - ES - Threshold high -!HISTORY_MSG_357;W - Denoise - Link with ES -!HISTORY_MSG_358;W - Gamut - CH -!HISTORY_MSG_359;Hot/Dead - Threshold -!HISTORY_MSG_360;TM - Gamma -!HISTORY_MSG_361;W - Final - Chroma balance -!HISTORY_MSG_362;W - Residual - Compression method -!HISTORY_MSG_363;W - Residual - Compression strength -!HISTORY_MSG_364;W - Final - Contrast balance -!HISTORY_MSG_365;W - Final - Delta balance -!HISTORY_MSG_366;W - Residual - Compression gamma -!HISTORY_MSG_367;W - Final - 'After' contrast curve -!HISTORY_MSG_368;W - Final - Contrast balance -!HISTORY_MSG_369;W - Final - Balance method -!HISTORY_MSG_370;W - Final - Local contrast curve -!HISTORY_MSG_371;Post-Resize Sharpening -!HISTORY_MSG_372;PRS USM - Radius -!HISTORY_MSG_373;PRS USM - Amount -!HISTORY_MSG_374;PRS USM - Threshold -!HISTORY_MSG_375;PRS USM - Sharpen only edges -!HISTORY_MSG_376;PRS USM - Edge detection radius -!HISTORY_MSG_377;PRS USM - Edge tolerance -!HISTORY_MSG_378;PRS USM - Halo control -!HISTORY_MSG_379;PRS USM - Halo control amount -!HISTORY_MSG_380;PRS - Method -!HISTORY_MSG_381;PRS RLD - Radius -!HISTORY_MSG_382;PRS RLD - Amount -!HISTORY_MSG_383;PRS RLD - Damping -!HISTORY_MSG_384;PRS RLD - Iterations -!HISTORY_MSG_385;W - Residual - Color balance -!HISTORY_MSG_386;W - Residual - CB green high -!HISTORY_MSG_387;W - Residual - CB blue high -!HISTORY_MSG_388;W - Residual - CB green mid -!HISTORY_MSG_389;W - Residual - CB blue mid -!HISTORY_MSG_390;W - Residual - CB green low -!HISTORY_MSG_391;W - Residual - CB blue low -!HISTORY_MSG_392;W - Residual - Color balance -!HISTORY_MSG_393;DCP - Look table -!HISTORY_MSG_394;DCP - Baseline exposure -!HISTORY_MSG_395;DCP - Base table -!HISTORY_MSG_396;W - Contrast sub-tool -!HISTORY_MSG_397;W - Chroma sub-tool -!HISTORY_MSG_398;W - ES sub-tool -!HISTORY_MSG_399;W - Residual sub-tool -!HISTORY_MSG_400;W - Final sub-tool -!HISTORY_MSG_401;W - Toning sub-tool -!HISTORY_MSG_402;W - Denoise sub-tool -!HISTORY_MSG_403;W - ES - Edge sensitivity -!HISTORY_MSG_404;W - ES - Base amplification -!HISTORY_MSG_405;W - Denoise - Level 4 -!HISTORY_MSG_406;W - ES - Neighboring pixels -!HISTORY_MSG_407;Retinex - Method -!HISTORY_MSG_408;Retinex - Radius -!HISTORY_MSG_410;Retinex - Offset -!HISTORY_MSG_411;Retinex - Strength -!HISTORY_MSG_412;Retinex - Gaussian gradient -!HISTORY_MSG_413;Retinex - Contrast -!HISTORY_MSG_414;Retinex - Histogram - Lab -!HISTORY_MSG_415;Retinex - Transmission -!HISTORY_MSG_416;Retinex -!HISTORY_MSG_417;Retinex - Transmission median -!HISTORY_MSG_418;Retinex - Threshold -!HISTORY_MSG_419;Retinex - Color space -!HISTORY_MSG_420;Retinex - Histogram - HSL -!HISTORY_MSG_421;Retinex - Gamma -!HISTORY_MSG_422;Retinex - Gamma -!HISTORY_MSG_423;Retinex - Gamma slope -!HISTORY_MSG_424;Retinex - HL threshold !HISTORY_MSG_425;--unused-- -!HISTORY_MSG_426;Retinex - Hue equalizer -!HISTORY_MSG_427;Output rendering intent -!HISTORY_MSG_428;Monitor rendering intent !HISTORY_MSG_429;Retinex - Iterations !HISTORY_MSG_430;Retinex - Transmission gradient !HISTORY_MSG_431;Retinex - Strength gradient From 749111f2ec36faeac8f3759b119032679305225c Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 21 Jul 2024 14:22:47 +0700 Subject: [PATCH 273/291] mac: further clarification of installation instructions --- tools/osx/INSTALL.readme.rtf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/osx/INSTALL.readme.rtf b/tools/osx/INSTALL.readme.rtf index 9a4183a0d..7d4aa060e 100644 --- a/tools/osx/INSTALL.readme.rtf +++ b/tools/osx/INSTALL.readme.rtf @@ -1,7 +1,9 @@ To install the RawTherapee application: 1. Open the RawTherapee .dmg Disk Image included alongside this document. -2. To install RT, drag icon onto /Applications (it will not start if in another location). +2. Drag the RawTherapee icon onto /Applications. + +Note: For security reasons, RawTherapee MUST be installed in /Applications. RawTherapee will refuse to start if installed elsewhere. To run the RawTherapee application: From 19eb07de260dd02a31388eeeed46d3679d6e3b76 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 27 Jul 2024 10:57:20 -0700 Subject: [PATCH 274/291] Update Chinese (Simplified) translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provided by syyrmb (å一元人民å¸) in https://github.com/Beep6581/RawTherapee/issues/7145. --- rtdata/languages/Chinese (Simplified) | 105 +++++++++++++------------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index 2ed7cf262..ee075d9b6 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -8,6 +8,7 @@ #007 2021-09-24 åä¸€å…ƒäººæ°‘å¸ #008 2022-07-26 åä¸€å…ƒäººæ°‘å¸ #009 2023-12-25 åä¸€å…ƒäººæ°‘å¸ +#010 2024-06-03 åä¸€å…ƒäººæ°‘å¸ #100 #101 @LANGUAGE_DISPLAY_NAME=简体中文 @@ -70,6 +71,7 @@ EXIFFILTER_IMAGETYPE;图åƒç±»åž‹ EXIFFILTER_ISO;感光度 EXIFFILTER_LENS;镜头 EXIFFILTER_METADATAFILTER;å¯ç”¨å…ƒæ•°æ®è¿‡æ»¤å™¨ +EXIFFILTER_PATH;文件路径 EXIFFILTER_SHUTTER;å¿«é—¨ EXIFPANEL_ADDEDIT;添加/编辑 EXIFPANEL_ADDEDITHINT;添加/编辑标签 @@ -396,12 +398,12 @@ HISTORY_MSG_148;å¾®åå·® HISTORY_MSG_149;å¾®åå·®-3×3阵列 HISTORY_MSG_150;去马赛克åŽé™å™ª/去æ‚点 HISTORY_MSG_151;鲜明度 -HISTORY_MSG_152;鲜明-欠饱和色 -HISTORY_MSG_153;鲜明-饱和色 +HISTORY_MSG_152;鲜明-低饱和色 +HISTORY_MSG_153;鲜明-高饱和色 HISTORY_MSG_154;鲜明-è‚¤è‰²ä¿æŠ¤ HISTORY_MSG_155;Vib-é¿å…色彩åç§» -HISTORY_MSG_156;鲜明-饱和/欠饱和挂钩 -HISTORY_MSG_157;鲜明-饱/欠阈值 +HISTORY_MSG_156;鲜明-高/低饱和挂钩 +HISTORY_MSG_157;鲜明-高/低饱和阈值 HISTORY_MSG_158;色调映射-力度 HISTORY_MSG_159;色调映射-边缘 HISTORY_MSG_160;色调映射-规模度 @@ -547,7 +549,7 @@ HISTORY_MSG_309;å°æ³¢-边缘é”度-细节 HISTORY_MSG_310;å°æ³¢-残差图-è‚¤è‰²ä¿æŠ¤ HISTORY_MSG_311;å°æ³¢-å°æ³¢å±‚级 HISTORY_MSG_312;å°æ³¢-残差图-阴影阈值 -HISTORY_MSG_313;å°æ³¢-色度-饱和/欠饱和 +HISTORY_MSG_313;å°æ³¢-色度-高/低饱和 HISTORY_MSG_314;å°æ³¢-色域-å‡å°‘æ‚点 HISTORY_MSG_315;å°æ³¢-残差图-åå·® HISTORY_MSG_316;å°æ³¢-色域-肤色针对 @@ -558,8 +560,8 @@ HISTORY_MSG_320;å°æ³¢-åå·®-粗糙范围 HISTORY_MSG_321;å°æ³¢-åå·®-粗糙等级 HISTORY_MSG_322;å°æ³¢-色域-é¿å…å色 HISTORY_MSG_323;å°æ³¢-边缘-局部åå·® -HISTORY_MSG_324;å°æ³¢-色度-欠饱和 -HISTORY_MSG_325;å°æ³¢-色度-饱和 +HISTORY_MSG_324;å°æ³¢-色度-低饱和 +HISTORY_MSG_325;å°æ³¢-色度-高饱和 HISTORY_MSG_326;å°æ³¢-色度-方法 HISTORY_MSG_327;å°æ³¢-åå·®-应用到 HISTORY_MSG_328;å°æ³¢-色度-力度挂钩 @@ -619,6 +621,7 @@ HISTORY_MSG_404;å°æ³¢-边缘-放大基数 HISTORY_MSG_405;å°æ³¢-去噪-第4级 HISTORY_MSG_406;å°æ³¢-边缘-边缘åƒç´  HISTORY_MSG_440;CbDL-方法 +HISTORY_MSG_444;白平衡-色温åå‘ HISTORY_MSG_445;Rawå­å›¾åƒ HISTORY_MSG_449;åƒç´ åç§»-ISO适应 HISTORY_MSG_452;åƒç´ åç§»-显示动体 @@ -680,8 +683,8 @@ HISTORY_MSG_534;局部-冷暖 HISTORY_MSG_535;局部-æ›è¡¥ 范围 HISTORY_MSG_536;局部-æ›å…‰å¯¹æ¯”度曲线 HISTORY_MSG_537;局部-鲜明度 -HISTORY_MSG_538;局部-鲜明 饱和色 -HISTORY_MSG_539;局部-鲜明 欠饱和色 +HISTORY_MSG_538;局部-鲜明 高饱和色 +HISTORY_MSG_539;局部-鲜明 低饱和色 HISTORY_MSG_540;局部-鲜明 阈值 HISTORY_MSG_541;局部-鲜明 è‚¤è‰²ä¿æŠ¤ HISTORY_MSG_542;局部-鲜明 é¿å…å色 @@ -990,7 +993,7 @@ PARTIALPASTE_HSVEQUALIZER;HSVå‡è¡¡å™¨ PARTIALPASTE_ICMSETTINGS;ICM设置 PARTIALPASTE_IMPULSEDENOISE;脉冲噪声é™ä½Ž PARTIALPASTE_IPTCINFO;IPTC ä¿¡æ¯ -PARTIALPASTE_LABCURVE;Lab调整 +PARTIALPASTE_LABCURVE;L*a*b*调整 PARTIALPASTE_LENSGROUP;镜头相关设置 PARTIALPASTE_LENSPROFILE;镜片修正档案 PARTIALPASTE_LOCALCONTRAST;局部åå·® @@ -1164,13 +1167,13 @@ PREFERENCES_PREVDEMO_LABEL;å°äºŽ100%缩放查看时使用的去马赛克算法 PREFERENCES_PREVDEMO_SIDECAR;与PP3ç›¸åŒ PREFERENCES_PRINTER;æ‰“å°æœº (软打样) PREFERENCES_PROFILEHANDLING;图片处ç†é…ç½®ç®¡ç† -PREFERENCES_PROFILELOADPR;é…置文件读å–优先级 +PREFERENCES_PROFILELOADPR;优先读å–çš„é…置文件 PREFERENCES_PROFILEPRCACHE;缓存中的é…置文件 PREFERENCES_PROFILEPRFILE;图片所在目录的é…置文件 -PREFERENCES_PROFILESAVEBOTH;å°†é…置文件存放到缓存和输入图片所在ä½ç½® -PREFERENCES_PROFILESAVECACHE;å°†é…置文件存放到缓存 -PREFERENCES_PROFILESAVEINPUT;å°†é…置文件与图片并列存放 -PREFERENCES_PROFILESAVELOCATION;å°†é…置文件存放到缓存和输入图片所在目录 +PREFERENCES_PROFILESAVEBOTH;å°†é…置文件å‘缓存和输入图片所在目录å„存放一份 +PREFERENCES_PROFILESAVECACHE;å°†é…置文件存放至缓存 +PREFERENCES_PROFILESAVEINPUT;å°†é…置文件存放至与图片相åŒçš„目录 +PREFERENCES_PROFILESAVELOCATION;é…置文件的ä¿å­˜ä½ç½® PREFERENCES_PROFILE_NONE;æ—  PREFERENCES_PROPERTY;属性 PREFERENCES_PRTINTENT;渲染æ„图 @@ -1200,6 +1203,7 @@ PREFERENCES_STARTUPIMDIR;å¯åŠ¨æ—¶è·¯å¾„ PREFERENCES_TAB_BROWSER;文件æµè§ˆå™¨ PREFERENCES_TAB_COLORMGR;è‰²å½©ç®¡ç† PREFERENCES_TAB_DYNAMICPROFILE;动æ€é¢„设规则 +PREFERENCES_TAB_FAVORITES;æ”¶è— PREFERENCES_TAB_GENERAL;通用 PREFERENCES_TAB_IMPROC;å›¾ç‰‡å¤„ç† PREFERENCES_TAB_PERFORMANCE;性能 @@ -1208,9 +1212,13 @@ PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;内嵌JPEG预览 PREFERENCES_THUMBNAIL_INSPECTOR_MODE;展示的图片 PREFERENCES_THUMBNAIL_INSPECTOR_RAW;中性Raw渲染图 PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;若内嵌JPEG为全尺寸,则预览它;å¦åˆ™é¢„览中性Raw +PREFERENCES_TOOLPANEL_FAVORITE;æ”¶è— +PREFERENCES_TOOLPANEL_FAVORITESPANEL;æ”¶è—æ  +PREFERENCES_TOOLPANEL_TOOL;工具 PREFERENCES_TP_LABEL;å·¥å…·æ  PREFERENCES_TP_VSCROLLBAR;éšè—åž‚ç›´æ»šåŠ¨æ¡ PREFERENCES_USEBUNDLEDPROFILES;å¯ç”¨å†…置预设 +PREFERENCES_WBA;白平衡 PREFERENCES_WORKFLOW;è½¯ä»¶ç•Œé¢ PREFERENCES_ZOOMONSCROLL;滚动鼠标滚轮控制图片缩放 PROFILEPANEL_COPYPPASTE;è¦å¤åˆ¶çš„傿•° @@ -1315,7 +1323,7 @@ TP_BWMIX_GAM_TOOLTIP;矫正红绿è“三色通é“(RGB)伽马 TP_BWMIX_LABEL;黑白 TP_BWMIX_MET;方法 TP_BWMIX_MET_CHANMIX;é€šé“æ··åˆå™¨ -TP_BWMIX_MET_DESAT;去饱和 +TP_BWMIX_MET_DESAT;é™ä½Žé¥±å’Œåº¦ TP_BWMIX_MET_LUMEQUAL;亮度å‡è¡¡å™¨ TP_BWMIX_MIXC;é€šé“æ··åˆå™¨ TP_BWMIX_NEUTRAL;é‡ç½® @@ -1402,7 +1410,7 @@ TP_COLORAPP_LABEL_CAM02;图åƒè°ƒæ•´ TP_COLORAPP_LABEL_SCENE;场景æ¡ä»¶ TP_COLORAPP_LABEL_VIEWING;观察æ¡ä»¶ TP_COLORAPP_LIGHT;明度 (J) -TP_COLORAPP_LIGHT_TOOLTIP; CIECAM02/16ä¸­çš„â€œæ˜Žåº¦â€æŒ‡ä¸€ä¸ªåˆºæ¿€ç‰©çš„æ¸…晰度与相似观察æ¡ä»¶ä¸‹çš„白色物体清晰度之相对值,与Labå’ŒRGBçš„â€œæ˜Žåº¦â€æ„义ä¸åŒ +TP_COLORAPP_LIGHT_TOOLTIP; CIECAM02/16ä¸­çš„â€œæ˜Žåº¦â€æŒ‡ä¸€ä¸ªåˆºæ¿€ç‰©çš„æ¸…晰度与相似观察æ¡ä»¶ä¸‹çš„白色物体清晰度之间的相对值,与Labå’ŒRGBçš„â€œæ˜Žåº¦â€æ„义ä¸åŒ TP_COLORAPP_MEANLUMINANCE;å¹³å‡äº®åº¦(Yb%) TP_COLORAPP_MODEL;白点模型 TP_COLORAPP_MODELCAT;色貌模型 @@ -1418,8 +1426,8 @@ TP_COLORAPP_SURROUND_AVER;一般 TP_COLORAPP_SURROUND_DARK;黑暗 TP_COLORAPP_SURROUND_DIM;æ˜æš— TP_COLORAPP_SURROUND_EXDARK;æžæš— -TP_COLORAPP_SURROUND_TOOLTIP;改å˜è‰²è°ƒå’Œè‰²å½©ä»¥è€ƒè™‘到输出设备的观察æ¡ä»¶ã€‚\n\n一般:一般的光照环境(标准)。图åƒä¸ä¼šå˜åŒ–。\n\næ˜æš—ï¼šæ˜æš—环境(如电视)。图åƒä¼šç•¥å¾®å˜æš—。\n\n黑暗:黑暗环境(如投影仪)。图åƒä¼šå˜å¾—更暗。\n\næžæš—:éžå¸¸æš—的环境(Cutsheet)。图åƒä¼šå˜å¾—很暗 -TP_COLORAPP_SURSOURCE_TOOLTIP;改å˜è‰²è°ƒä¸Žè‰²å½©ä»¥è®¡å…¥åœºæ™¯æ¡ä»¶\n\n一般:一般的亮度æ¡ä»¶ï¼ˆæ ‡å‡†ï¼‰ã€‚图åƒä¸è¢«æ”¹å˜\n\næ˜æš—:较暗的场景。图åƒä¼šè¢«ç•¥å¾®æäº®\n\n黑暗:黑暗的环境。图åƒä¼šè¢«æäº®\n\næžæš—:éžå¸¸æš—的环境。图片会å˜å¾—éžå¸¸äº® +TP_COLORAPP_SURROUND_TOOLTIP;改å˜è‰²è°ƒå’Œè‰²å½©ä»¥å°†è¾“出设备的观察æ¡ä»¶çº³å…¥è€ƒé‡ã€‚\n\n一般:一般的光照环境(标准)。图åƒä¸ä¼šå˜åŒ–。\n\næ˜æš—ï¼šæ˜æš—环境(如电视)。图åƒä¼šç•¥å¾®å˜æš—。\n\n黑暗:黑暗环境(如投影仪)。图åƒä¼šå˜å¾—更暗。\n\næžæš—:éžå¸¸æš—的环境(Cutsheet)。图åƒä¼šå˜å¾—很暗 +TP_COLORAPP_SURSOURCE_TOOLTIP;改å˜è‰²è°ƒä¸Žè‰²å½©ä»¥å°†åœºæ™¯æ¡ä»¶çº³å…¥è€ƒé‡\n\n一般:一般的亮度æ¡ä»¶ï¼ˆæ ‡å‡†ï¼‰ã€‚图åƒä¸è¢«æ”¹å˜\n\næ˜æš—:较暗的场景。图åƒä¼šè¢«ç•¥å¾®æäº®\n\n黑暗:黑暗的环境。图åƒä¼šè¢«æäº®\n\næžæš—:éžå¸¸æš—的环境。图片会å˜å¾—éžå¸¸äº® TP_COLORAPP_TCMODE_BRIGHTNESS;视明度 TP_COLORAPP_TCMODE_CHROMA;彩度 TP_COLORAPP_TCMODE_COLORF;视彩度 @@ -1618,15 +1626,17 @@ TP_FILMNEGATIVE_COLORSPACE;å转色彩空间: TP_FILMNEGATIVE_COLORSPACE_INPUT;输入色彩空间 TP_FILMNEGATIVE_COLORSPACE_TOOLTIP;选择用于负片å转的色彩空间:\n输入色彩空间: 在输入档案被应用之å‰è¿›è¡Œå转,与之å‰ç‰ˆæœ¬çš„RT相åŒ\n工作色彩空间: 在输入档案被应用之åŽè¿›è¡Œåè½¬ï¼Œä½¿ç”¨å½“å‰æ‰€é€‰çš„工作档案 TP_FILMNEGATIVE_COLORSPACE_WORKING;工作色彩空间 -TP_FILMNEGATIVE_GREEN;å‚照指数(å差) +TP_FILMNEGATIVE_GREEN;å‚照指数 TP_FILMNEGATIVE_GREENBALANCE;å“红/绿 TP_FILMNEGATIVE_GUESS_TOOLTIP;通过选å–åŽŸå›¾ä¸­çš„ä¸¤ä¸ªä¸­æ€§è‰²ï¼ˆæ²¡æœ‰è‰²å½©ï¼‰è‰²å—æ¥è‡ªåŠ¨ç¡®å®šçº¢ä¸Žè“色的比例。两个色å—的亮度应当有所差别。 TP_FILMNEGATIVE_LABEL;胶片负片 TP_FILMNEGATIVE_OUT_LEVEL;输出亮度 TP_FILMNEGATIVE_PICK;选择(两个)中ç°ç‚¹ +TP_FILMNEGATIVE_PICK_SIZE;大å°ï¼š TP_FILMNEGATIVE_RED;红色比例 TP_FILMNEGATIVE_REF_LABEL;输入RGB: %1 TP_FILMNEGATIVE_REF_PICK;选择白平衡点 +TP_FILMNEGATIVE_REF_SIZE;大å°ï¼š TP_FILMNEGATIVE_REF_TOOLTIP;为输出的正片选择一å—ç°è‰²åŒºåŸŸè¿›è¡Œç™½å¹³è¡¡ TP_FILMSIMULATION_LABEL;胶片模拟 TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee被设置寻找用于胶片模拟工具的Hald CLUT图åƒï¼Œä½†å›¾åƒæ‰€åœ¨çš„æ–‡ä»¶å¤¹åŠ è½½æ—¶é—´è¿‡é•¿ã€‚\nå‰å¾€å‚数设置-图片处ç†-Hald CLUT路径\n以寻找被使用的文件夹是哪个。你应该令该文件夹指å‘ä¸€ä¸ªåªæœ‰Hald CLUT图åƒè€Œæ²¡æœ‰å…¶ä»–å›¾ç‰‡çš„æ–‡ä»¶å¤¹ã€‚å¦‚æžœä½ ä¸æƒ³ç”¨èƒ¶ç‰‡æ¨¡æ‹ŸåŠŸèƒ½ï¼Œå°±å°†å®ƒæŒ‡å‘一个空文件夹。\n\n阅读RawPediaçš„Film Simulationè¯æ¡ä»¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚\n\nä½ æƒ³å–æ¶ˆæ‰«æå—? @@ -1672,8 +1682,8 @@ TP_ICM_INPUTCAMERAICC;自适应相机档案 TP_ICM_INPUTCUSTOM;自定义 TP_ICM_INPUTCUSTOM_TOOLTIP;选择你自己的DCP/ICC色彩档案 TP_ICM_INPUTDLGLABEL;选择输入ICCé…ç½®... -TP_ICM_INPUTEMBEDDED;如å¯èƒ½, 使用内置 -TP_ICM_INPUTEMBEDDED_TOOLTIP;使用éžraw文件内嵌的色彩档案 +TP_ICM_INPUTEMBEDDED;使用内置 +TP_ICM_INPUTEMBEDDED_TOOLTIP;使用éžraw文件内嵌的色彩档案,若无内嵌档案则会自动使用“相机缺çœâ€æ¨¡å¼ TP_ICM_INPUTNONE;无档案 TP_ICM_INPUTNONE_TOOLTIP;ä¸ä½¿ç”¨ä»»ä½•色彩档案。\n仅在特殊情况下使用此选项 TP_ICM_INPUTPROFILE;输入é…ç½® @@ -1846,6 +1856,10 @@ TP_LOCALLAB_GAMFRA;色调å“应曲线(TRC) TP_LOCALLAB_GAMM;伽马 TP_LOCALLAB_GAMMASKCOL;伽马 TP_LOCALLAB_GAMSH;伽马 +TP_LOCALLAB_GAMUTMUNSELL;仅孟塞尔矫正 +TP_LOCALLAB_GAMUTNON;æ—  +TP_LOCALLAB_GAMUTXYZABSO;ç»å¯¹XYZ +TP_LOCALLAB_GAMUTXYZRELA;相对XYZ TP_LOCALLAB_GRADANG;æ¸å˜è§’度 TP_LOCALLAB_GRADANG_TOOLTIP;旋转角度(å•ä½ä¸ºÂ°ï¼‰ï¼š-180 0 +180 TP_LOCALLAB_GRADFRA;æ¸å˜æ»¤é•œè’™ç‰ˆ @@ -2210,6 +2224,15 @@ TP_TM_FATTAL_AMOUNT;æ•°é‡ TP_TM_FATTAL_ANCHOR;锚点 TP_TM_FATTAL_LABEL;动æ€èŒƒå›´åŽ‹ç¼© TP_TM_FATTAL_THRESHOLD;细节 +TP_TONE_EQUALIZER_BAND_0;黑点 +TP_TONE_EQUALIZER_BAND_1;阴影 +TP_TONE_EQUALIZER_BAND_2;中间调 +TP_TONE_EQUALIZER_BAND_3;高光 +TP_TONE_EQUALIZER_BAND_4;白点 +TP_TONE_EQUALIZER_DETAIL;正则化 +TP_TONE_EQUALIZER_LABEL;色调å‡è¡¡å™¨ +TP_TONE_EQUALIZER_PIVOT;锚点(Ev) +TP_TONE_EQUALIZER_SHOW_COLOR_MAP;显示å„色调范围 TP_VIBRANCE_AVOIDCOLORSHIFT;é¿å…å色 TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;肤色 TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;红/ç´« @@ -2218,14 +2241,14 @@ TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;红/黄 TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;黄 TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;æ ¹æ®è‰²ç›¸(H)调整色相(H),H=f(H) TP_VIBRANCE_LABEL;鲜明度 -TP_VIBRANCE_PASTELS;欠饱和色调 -TP_VIBRANCE_PASTSATTOG;将饱和色与欠饱和色挂钩 +TP_VIBRANCE_PASTELS;低饱和色调 +TP_VIBRANCE_PASTSATTOG;将高饱和色与低饱和色挂钩 TP_VIBRANCE_PROTECTSKINS;ä¿æŠ¤è‚¤è‰² -TP_VIBRANCE_PSTHRESHOLD;欠饱和/饱和色阈值 +TP_VIBRANCE_PSTHRESHOLD;低饱和/高饱和阈值 TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;饱和度阈值 -TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;纵å‘底部代表欠饱和色,顶部代表饱和色\n横轴代表整个饱和度范围 -TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;欠饱和/饱和色过渡æƒé‡ -TP_VIBRANCE_SATURATED;饱和色调 +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;纵å‘底部代表低饱和色,顶部代表高饱和色\n横轴代表整个饱和度范围 +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;低饱和/高饱和过渡æƒé‡ +TP_VIBRANCE_SATURATED;高饱和色调 TP_VIGNETTING_AMOUNT;æ•°é‡ TP_VIGNETTING_CENTER;中心 TP_VIGNETTING_CENTER_X;中心 X @@ -2351,7 +2374,7 @@ TP_WAVELET_NPTYPE;临近åƒç´  TP_WAVELET_OPACITY;è“-黄ä¸é€æ˜Žåº¦ TP_WAVELET_OPACITYW;å差平衡 æ–œ/纵-横曲线 TP_WAVELET_OPACITYWL;局部åå·® -TP_WAVELET_PASTEL;欠饱和色 +TP_WAVELET_PASTEL;低饱和色 TP_WAVELET_PROC;å¤„ç† TP_WAVELET_QUAAGRES;激进 TP_WAVELET_QUACONSER;ä¿å®ˆ @@ -2416,7 +2439,7 @@ TP_WBALANCE_SOLUX35;Solux 3500K TP_WBALANCE_SOLUX41;Solux 4100K TP_WBALANCE_SPOTWB;白平衡采样 TP_WBALANCE_TEMPBIAS;自动白平衡色温åå‘ -TP_WBALANCE_TEMPBIAS_TOOLTIP;此功能å…许你将色温å‘冷/æš–å移,\n以调整计算出的“自动白平衡â€ã€‚这个å移被表达为已计\n算出的色温的一个百分比,故最终的调整结果为“色温+色温*å移†+TP_WBALANCE_TEMPBIAS_TOOLTIP;此功能å…许你将色温å‘冷/æš–å移,以调整计算出的“自动白平衡â€ã€‚\n这个å移被表达为计算出的色温的一个百分比,故最终的调整结果为“色温+色温*åç§»â€ã€‚\nä½ å¯ä»¥ä½¿ç”¨â€œè‡ªåŠ¨ç™½å¹³è¡¡è‰²æ¸©åå‘â€æ¥è°ƒæ•´â€œè‰²æ¸©å…³è”系数â€ã€‚å¯¹å…¶è¿›è¡Œä»»ä½•è°ƒæ•´éƒ½ä¼šè®©è½¯ä»¶é‡æ–°è®¡ç®—色温,色调和关è”系数 TP_WBALANCE_TEMPERATURE;色温 TP_WBALANCE_TUNGSTEN;ç™½ç‚½ç¯ TP_WBALANCE_WATER1;水下 1 @@ -2435,7 +2458,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !!!!!!!!!!!!!!!!!!!!!!!!! !ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!EXIFFILTER_PATH;File path !EXIFPANEL_ACTIVATE_ALL_HINT;Select all tags !EXIFPANEL_ACTIVATE_NONE_HINT;Unselect all tags !EXIFPANEL_BASIC_GROUP;Basic @@ -2513,7 +2535,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !HISTORY_MSG_441;Retinex - Gain transmission !HISTORY_MSG_442;Retinex - Scale !HISTORY_MSG_443;Output black point compensation -!HISTORY_MSG_444;WB - Temp bias !HISTORY_MSG_446;--unused-- !HISTORY_MSG_447;--unused-- !HISTORY_MSG_448;--unused-- @@ -3341,15 +3362,10 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !PREFERENCES_RAW_DECODER;Raw Decoder !PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw !PREFERENCES_SPOTLOC;Define Spot method for Selective Editing -!PREFERENCES_TAB_FAVORITES;Favorites !PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Available Tools !PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Keep favorite tools in original locations !PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;If set, favorite tools will appear in both the favorites tab and their original tabs.\n\nNote: Enabling this option may result in a slight delay when switching tabs. -!PREFERENCES_TOOLPANEL_FAVORITE;Favorite -!PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel -!PREFERENCES_TOOLPANEL_TOOL;Tool -!PREFERENCES_WBA;White Balance !PREFERENCES_WBACORR;White Balance - Automatic temperature correlation !PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. !PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings @@ -3468,8 +3484,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts. !TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected. !TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. -!TP_FILMNEGATIVE_PICK_SIZE;Size: -!TP_FILMNEGATIVE_REF_SIZE;Size: !TP_FLATFIELD_FROMMETADATA;From Metadata !TP_HLREC_COLOROPP;Inpaint Opposed !TP_HLREC_HLBLUR;Blur @@ -3717,10 +3731,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. !TP_LOCALLAB_GAMUTLABRELA;Lab -!TP_LOCALLAB_GAMUTMUNSELL;Munsell only -!TP_LOCALLAB_GAMUTNON;None -!TP_LOCALLAB_GAMUTXYZABSO;XYZ Absolute -!TP_LOCALLAB_GAMUTXYZRELA;XYZ Relative !TP_LOCALLAB_GAMW;Gamma (wavelet pyramids) !TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. !TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. @@ -4248,15 +4258,6 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\nå¿«æ·é”®ï¼š- !TP_RETINEX_VIEW_TRAN2;Transmission - Fixed !TP_SPOT_ENTRYCHANGED;Point changed !TP_TONE_EQUALIZER_BANDS;Bands -!TP_TONE_EQUALIZER_BAND_0;Blacks -!TP_TONE_EQUALIZER_BAND_1;Shadows -!TP_TONE_EQUALIZER_BAND_2;Midtones -!TP_TONE_EQUALIZER_BAND_3;Highlights -!TP_TONE_EQUALIZER_BAND_4;Whites -!TP_TONE_EQUALIZER_DETAIL;Regularization -!TP_TONE_EQUALIZER_LABEL;Tone Equalizer -!TP_TONE_EQUALIZER_PIVOT;Pivot (Ev) -!TP_TONE_EQUALIZER_SHOW_COLOR_MAP;Show tonal map !TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH !TP_WAVELET_BALCHROM;Equalizer Color !TP_WAVELET_BALLUM;Denoise equalizer White-Black From 19a77174355076f83d399912d4d6ac2f32118610 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 27 Jul 2024 11:56:26 -0700 Subject: [PATCH 275/291] Update Dutch translation Provided by paulmatthijsse in https://github.com/Beep6581/RawTherapee/issues/7156. --- rtdata/languages/Nederlands | 1505 ++++++++++++++++++----------------- 1 file changed, 753 insertions(+), 752 deletions(-) diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index b36284af5..9cec0212b 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -14,9 +14,10 @@ #014 2015-11-23 update by wim ter meer #015 2016-07-21 update by wim ter meer #016 2017-04-21 update by wim ter meer -#017 2020-06-05 update by dheijl +#017 2020-06-05 update by dheijl #018 2024-02-18 update to RawTherapee 5.10 by Paul Matthijsse #019 2024-03-08 update by Paul Matthijsse +#020 2024-07-27 update naar RawTherapee 5.11 door pm #100 #101 @LANGUAGE_DISPLAY_NAME=Nederlands @@ -213,7 +214,7 @@ FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's\nSneltoets: Shift+7 FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's\nSneltoets: Shift+6 FILEBROWSER_SHOWEXIFINFO;Toon Exif-info FILEBROWSER_SHOWNOTTRASHHINT;Toon alleen niet-verwijderde afbeeldingen. -FILEBROWSER_SHOWORIGINALHINT;Toon alleen originele afbeelding.\n\nAls er meerdere afbeeldingen zijn met dezelfde naam maar verschillende extensies, dan wordt de afbeelding gekozen waarvan de extensie het hoogst staat in de lijst met extensies in Voorkeuren > Bestandsnavigator > Extensies +FILEBROWSER_SHOWORIGINALHINT;Toon alleen originele afbeelding.\n\nAls er meerdere afbeeldingen zijn met dezelfde naam maar verschillende extensies, dan wordt de afbeelding gekozen waarvan de extensie het hoogst staat in de lijst met extensies in Voorkeuren > Bestandsnavigator > Extensies FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster.\nSneltoets: Shift+1 FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren.\nSneltoets: Shift+2 FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren.\nSneltoets: Shift+3 @@ -395,7 +396,7 @@ HISTORY_MSG_116;Verbeterd DCB HISTORY_MSG_117;RAW CA-correctie - Rood HISTORY_MSG_118;RAW CA-correctie - Blauw HISTORY_MSG_119;Lijnruis -HISTORY_MSG_120;Drempel groenbalans +HISTORY_MSG_120;Drempel groenbalans HISTORY_MSG_121;RAW CA-correctie - Auto HISTORY_MSG_122;Donkerframe - Autom. selectie HISTORY_MSG_123;Donkerframe - Bestand @@ -740,643 +741,645 @@ HISTORY_MSG_491;Witbalans HISTORY_MSG_492;RGB-curven HISTORY_MSG_493;L*a*b* aanpassingen HISTORY_MSG_494;verscherpen -HISTORY_MSG_496;LA - Spot verwijderd -HISTORY_MSG_497;LA - Spot geselecteerd -HISTORY_MSG_500;LA - Spotvorm -HISTORY_MSG_501;LA - Spotmethode -HISTORY_MSG_502;LA - SC - Vorm method -HISTORY_MSG_503;LA - Spot - Rechts -HISTORY_MSG_504;LA - Spot - Links -HISTORY_MSG_505;LA - Spot - Onder -HISTORY_MSG_506;LA - Spot - Boven -HISTORY_MSG_507;LA - Spot - Centrum -HISTORY_MSG_508;LA - Spot - Grootte -HISTORY_MSG_509;LA - Spot kwaliteitsmethode -HISTORY_MSG_510;LA - TG - Transitiewaarde -HISTORY_MSG_511;LA - SD - Drempel ΔE-bereik -HISTORY_MSG_512;LA - SD - ΔE-verval -HISTORY_MSG_513;LA - Spot - Uitsluiting - bereik -HISTORY_MSG_514;LA - Spotstructuur -HISTORY_MSG_515;LA - Aanpassingen -HISTORY_MSG_516;LA - Kleur en Licht -HISTORY_MSG_517;LA - Activeer super -HISTORY_MSG_518;LA - Lichtheid -HISTORY_MSG_519;LA - Contrast -HISTORY_MSG_520;LA - Chrominantie -HISTORY_MSG_521;LA - Bereik -HISTORY_MSG_522;LA - Curvemethode -HISTORY_MSG_523;LA - LL-curve -HISTORY_MSG_524;LA - CC-curve -HISTORY_MSG_525;LA - LH-curve -HISTORY_MSG_526;LA - H-curve -HISTORY_MSG_527;LA - Inverteer kleur -HISTORY_MSG_528;LA - Belichting -HISTORY_MSG_529;LA - Belichtingscompensatie -HISTORY_MSG_530;LA - Bel. Hlcompr -HISTORY_MSG_531;LA - Bel. hlcomprthresh -HISTORY_MSG_532;LA - Bel. zwart -HISTORY_MSG_533;LA - Bel. Shcompr -HISTORY_MSG_534;LA - Warm Koel -HISTORY_MSG_535;LA - Bel. Bereik -HISTORY_MSG_536;LA - Bel. Contrastcurve -HISTORY_MSG_537;LA - Levendigheid -HISTORY_MSG_538;LA - Lev. Verzadigd -HISTORY_MSG_539;LA - Lev. Pastel -HISTORY_MSG_540;LA - Lev. Drempel -HISTORY_MSG_541;LA - Lev. Bescherm huidtonen -HISTORY_MSG_542;LA - Lev. Vermijd kleurverschuiving -HISTORY_MSG_543;LA - Lev. Koppel -HISTORY_MSG_544;LA - Lev. Bereik -HISTORY_MSG_545;LA - Lev. H-curve -HISTORY_MSG_546;LA - Vervaging en Ruisvermindering -HISTORY_MSG_547;LA - Straal -HISTORY_MSG_548;LA - Ruis -HISTORY_MSG_549;LA - Bereik ruisvermindering -HISTORY_MSG_550;LA - Methode ruisvermindering -HISTORY_MSG_551;LA - Ruisvermindering alleen Luminantie -HISTORY_MSG_552;LA - Toonmappen -HISTORY_MSG_553;LA - TM compressiesterkte -HISTORY_MSG_554;LA - TM gamma -HISTORY_MSG_555;LA - TM edge stopping -HISTORY_MSG_556;LA - TM Schaal -HISTORY_MSG_557;LA - TM Herwogen -HISTORY_MSG_558;LA - TM Bereik -HISTORY_MSG_559;LA - Retinex -HISTORY_MSG_560;LA - Retinex methode -HISTORY_MSG_561;LA - Retinex kracht -HISTORY_MSG_562;LA - Retinex chroma -HISTORY_MSG_563;LA - Retinex straal -HISTORY_MSG_564;LA - Retinex contrast -HISTORY_MSG_565;LA - Bereik -HISTORY_MSG_566;LA - Retinex versterkingscurve -HISTORY_MSG_567;LA - Retinex Omgekeerd -HISTORY_MSG_568;LA - Verscherping -HISTORY_MSG_569;LA - Sh Straal -HISTORY_MSG_570;LA - Sh Hoeveelheid -HISTORY_MSG_571;LA - Sh Demping -HISTORY_MSG_572;LA - Sh Herhalingen -HISTORY_MSG_573;LA - Sh Bereik -HISTORY_MSG_574;LA - Sh Omgekeerd -HISTORY_MSG_575;LA - CBDL -HISTORY_MSG_576;LA - cbdl mult -HISTORY_MSG_577;LA - cbdl chroma -HISTORY_MSG_578;LA - cbdl drempel -HISTORY_MSG_579;LA - cbdl bereik -HISTORY_MSG_581;LA - Ruisverm. lum f 1 -HISTORY_MSG_582;LA - Ruisverm. lum c -HISTORY_MSG_583;LA - Ruisverm. lum detail -HISTORY_MSG_584;LA - Ruisverm. equalizer Wit-Zwart -HISTORY_MSG_585;LA - Ruisverm. chro f -HISTORY_MSG_586;LA - Ruisverm. chro c -HISTORY_MSG_587;LA - Ruisverm. chro detail -HISTORY_MSG_588;LA - Ruisverm. equalizer Blauw-Rood -HISTORY_MSG_589;LA - Ruisverm. bilateraal -HISTORY_MSG_590;LA - Ruisverm. bereik -HISTORY_MSG_591;LA - Voorkom kleurverschuiving -HISTORY_MSG_592;LA - Sh Contrast -HISTORY_MSG_593;LA - LA contrast -HISTORY_MSG_594;LA - Lokaal contrast straal -HISTORY_MSG_595;LA - Lokaal contrast hoeveelheid -HISTORY_MSG_596;LA - Lokaal contrast donkerte -HISTORY_MSG_597;LA - Lokaal contrast lichtheid -HISTORY_MSG_598;LA - Lokaal contrast bereik -HISTORY_MSG_599;LA - Retinex ontnevel -HISTORY_MSG_600;LA - Zacht licht activeer -HISTORY_MSG_601;LA - Zacht licht kracht -HISTORY_MSG_602;LA - Zacht licht bereik -HISTORY_MSG_603;LA - Sh Vervagingsradius -HISTORY_MSG_605;LA - Keuze maskervoorbeeld -HISTORY_MSG_606;LA - Spot geslecteerd -HISTORY_MSG_607;LA - Kleurmasker C -HISTORY_MSG_608;LA - Kleurmasker L -HISTORY_MSG_609;LA - Bel.masker C -HISTORY_MSG_610;LA - Bel.masker L -HISTORY_MSG_611;LA - Kleurmasker H -HISTORY_MSG_612;LA - Kleur structuur -HISTORY_MSG_613;LA - Bel. structuur -HISTORY_MSG_614;LA - Bel.masker H -HISTORY_MSG_615;LA - Meng kleur -HISTORY_MSG_616;LA - Meng bel. -HISTORY_MSG_617;LA - Vervaag Bel. -HISTORY_MSG_618;LA - Gebruik kleurmasker -HISTORY_MSG_619;LA - Gebruik bel.masker -HISTORY_MSG_620;LA - Meng col -HISTORY_MSG_621;LA - Bel. omgekeerd -HISTORY_MSG_622;LA - Spot - Uitsluiting - Spotstructuur -HISTORY_MSG_623;LA - Bel. Chroma-compensatie -HISTORY_MSG_624;LA - Kleurcorrectieraster -HISTORY_MSG_625;LA - Kleurcorrectie kracht -HISTORY_MSG_626;LA - Kleurcorrectie methode -HISTORY_MSG_627;LA - Schaduw Hoge lichten -HISTORY_MSG_628;LA - SH Hoge lichten -HISTORY_MSG_629;LA - SH H tonaalomvang -HISTORY_MSG_630;LA - SH Schaduwen -HISTORY_MSG_631;LA - SH S tonaalomvang -HISTORY_MSG_632;LA - SH straal -HISTORY_MSG_633;LA - SH bereik -HISTORY_MSG_634;LA - straal kleur -HISTORY_MSG_635;LA - straal Bel. -HISTORY_MSG_636;LA - Gereedschap toegevoegd -HISTORY_MSG_637;LA - SH Masker C -HISTORY_MSG_638;LA - SH Masker L -HISTORY_MSG_639;LA - SH Masker H -HISTORY_MSG_640;LA - SH meng -HISTORY_MSG_641;LA - Gebruik SH-masker -HISTORY_MSG_642;LA - Straal SH -HISTORY_MSG_643;LA - Vervaag SH -HISTORY_MSG_644;LA - Keer SH om -HISTORY_MSG_645;LA - SD - ab-L-balans -HISTORY_MSG_646;LA - Bel.masker chroma -HISTORY_MSG_647;LA - Bel.masker gamma -HISTORY_MSG_648;LA - Bel.masker helling -HISTORY_MSG_649;LA - Bel. verzachting straal -HISTORY_MSG_650;LA - Kleurmasker chroma -HISTORY_MSG_651;LA - Kleurmasker gamma -HISTORY_MSG_652;LA - Kleurmasker helling -HISTORY_MSG_653;LA - SH-masker chroma -HISTORY_MSG_654;LA - SH-masker gamma -HISTORY_MSG_655;LA - SH-masker helling -HISTORY_MSG_656;LA - Kleur zachte radius -HISTORY_MSG_657;LA - Retinex verminder onregelmatigheden -HISTORY_MSG_658;LA - CBDL zachte radius -HISTORY_MSG_659;LA - TG - Transitieverval -HISTORY_MSG_660;LA - CBDL klaarheid -HISTORY_MSG_661;LA - CBDL residueel contrast -HISTORY_MSG_662;LA - Verminder ruis lum f 0 -HISTORY_MSG_663;LA - Verminder ruis lum f 2 -HISTORY_MSG_665;LA - cbdl masker meng -HISTORY_MSG_666;LA - cbdl masker straal -HISTORY_MSG_667;LA - cbdl masker chroma -HISTORY_MSG_668;LA - cbdl masker gamma -HISTORY_MSG_669;LA - cbdl masker helling -HISTORY_MSG_670;LA - cbdl masker C -HISTORY_MSG_671;LA - cbdl masker L -HISTORY_MSG_672;LA - cbdl masker CL -HISTORY_MSG_673;LA - Gebruik cbdl masker -HISTORY_MSG_674;LA - Gereedschap verwijderd -HISTORY_MSG_675;LA - TM zacht straal -HISTORY_MSG_676;LA - TG - Transitiedifferentie -HISTORY_MSG_677;LA - TM hoeveelheid -HISTORY_MSG_678;LA - TM verzadiging -HISTORY_MSG_679;LA - Retinex masker C -HISTORY_MSG_680;LA - Retinex masker L -HISTORY_MSG_681;LA - Retinex masker CL -HISTORY_MSG_682;LA - Retinex masker -HISTORY_MSG_683;LA - Retinex masker meng -HISTORY_MSG_684;LA - Retinex masker straal -HISTORY_MSG_685;LA - Retinex masker chroma -HISTORY_MSG_686;LA - Retinex masker gamma -HISTORY_MSG_687;LA - Retinex masker helling -HISTORY_MSG_688;LA - Gereedschap verwijderd -HISTORY_MSG_689;LA - Retinex masker transmissiemap -HISTORY_MSG_690;LA - Retinex schaal -HISTORY_MSG_691;LA - Retinex donkerte -HISTORY_MSG_692;LA - Retinex lichtheid -HISTORY_MSG_693;LA - Retinex drempel -HISTORY_MSG_694;LA - Retinex Laplacian drempel -HISTORY_MSG_695;LA - Verzachting methode -HISTORY_MSG_696;LA - Retinex Normaliseer -HISTORY_MSG_697;LA - TM Normaliseer -HISTORY_MSG_698;LA - LA contrast Fast Fourier -HISTORY_MSG_699;LA - Retinex Fast Fourier -HISTORY_MSG_701;LA - Bel. Schaduwen -HISTORY_MSG_702;LA - Bel. Methode -HISTORY_MSG_703;LA - Bel. Laplacian drempel -HISTORY_MSG_704;LA - Bel. PDE-balans -HISTORY_MSG_705;LA - Bel. lineariteit -HISTORY_MSG_706;LA - TM masker C -HISTORY_MSG_707;LA - TM masker L -HISTORY_MSG_708;LA - TM masker CL -HISTORY_MSG_709;LA - gebruik TM-masker -HISTORY_MSG_710;LA - TM-masker meng -HISTORY_MSG_711;LA - TM-masker straal -HISTORY_MSG_712;LA - TM-masker chroma -HISTORY_MSG_713;LA - TM-masker gamma -HISTORY_MSG_714;LA - TM-masker helling -HISTORY_MSG_716;LA - LA methode -HISTORY_MSG_717;LA - LA contrast -HISTORY_MSG_718;LA - LA contrastniveaus -HISTORY_MSG_719;LA - LA contrast residueel L -HISTORY_MSG_720;LA - Vervagingsmasker C -HISTORY_MSG_721;LA - Vervagingsmasker L -HISTORY_MSG_722;LA - Vervagingsmasker CL -HISTORY_MSG_723;LA - Gebruik vervagingsmasker -HISTORY_MSG_725;LA - Vervagingsmasker meng -HISTORY_MSG_726;LA - Vervagingsmasker straal -HISTORY_MSG_727;LA - Vervagingsmasker chroma -HISTORY_MSG_728;LA - Vervagingsmasker gamma -HISTORY_MSG_729;LA - Vervagingsmasker helling -HISTORY_MSG_730;LA - Vervaging methode -HISTORY_MSG_731;LA - mediaanmethod -HISTORY_MSG_732;LA - mediaan herhalingen -HISTORY_MSG_733;LA - straal zacht -HISTORY_MSG_734;LA - detail -HISTORY_MSG_738;LA - Lokaal contrast meng L -HISTORY_MSG_739;LA - Lokaal contrast zacht straal -HISTORY_MSG_740;LA - Lokaal contrast Meng C -HISTORY_MSG_741;LA - Lokaal contrast Residueel C -HISTORY_MSG_742;LA - Exp Laplacian gamma -HISTORY_MSG_743;LA - Bel. Fattal Hoeveelheid -HISTORY_MSG_744;LA - Bel. Fattal Detail -HISTORY_MSG_745;LA - Bel. Fattal verschuiving -HISTORY_MSG_746;LA - Bel. Fattal Sigma -HISTORY_MSG_747;LA - Spot aangemaakt -HISTORY_MSG_748;LA - Bel. Ruisvermindering -HISTORY_MSG_749;LA - Reti Diepte -HISTORY_MSG_750;LA - Reti Modus log - lin -HISTORY_MSG_751;LA - Reti Ontnevel verzadiging -HISTORY_MSG_752;LA - Reti Verschuiving -HISTORY_MSG_753;LA - Reti Transmissiemap -HISTORY_MSG_754;LA - Reti Kap -HISTORY_MSG_755;LA - TM gebruik tm-masker -HISTORY_MSG_756;LA - Bel. gebruik algo belichtingsmasker -HISTORY_MSG_757;LA - Bel. Laplacian-masker -HISTORY_MSG_758;LA - Reti Laplacian-masker -HISTORY_MSG_759;LA - Bel. Laplacian-masker -HISTORY_MSG_760;LA - Kleur Laplacian masker -HISTORY_MSG_761;LA - SH Laplacian-masker -HISTORY_MSG_762;LA - cbdl Laplacian-masker -HISTORY_MSG_763;LA - Blur Laplacian-masker -HISTORY_MSG_764;LA - Solve PDE Laplacian-masker -HISTORY_MSG_765;LA - Ruisvermindering detaildrempel -HISTORY_MSG_766;LA - Vervaag Fast Fourier -HISTORY_MSG_767;LA - Korrel ISO -HISTORY_MSG_768;LA - Korrel Sterkte -HISTORY_MSG_769;LA - Korrel Schaal -HISTORY_MSG_770;LA - Kleurmasker contrastcurve -HISTORY_MSG_771;LA - Bel.masker contrastcurve -HISTORY_MSG_772;LA - SH-masker contrastcurve -HISTORY_MSG_773;LA - TM-Masker contrastcurve -HISTORY_MSG_774;LA - Reti masker contrastcurve -HISTORY_MSG_775;LA - CBDL masker contrastcurve -HISTORY_MSG_776;LA - Vervaag-Ruisverminderingmasker contrastcurve -HISTORY_MSG_777;LA - Vervaagmasker lokale contrastcurve -HISTORY_MSG_778;LA - Maskeer hoge lichten -HISTORY_MSG_779;LA - Kleurmasker lokale contrastcurve -HISTORY_MSG_780;LA - Kleurmasker schaduwen -HISTORY_MSG_781;LA - Contrastmasker Wavelet-niveau -HISTORY_MSG_782;LA - Vervaag-Ruisverminderingmasker Wavelet-niveaus -HISTORY_MSG_783;LA - Kleur Wavelet-niveaus -HISTORY_MSG_784;LA - masker - ΔE beeldmasker -HISTORY_MSG_785;LA - masker - bereik -HISTORY_MSG_786;LA - SH-methode -HISTORY_MSG_787;LA - Equalizer vermenigvuldiger -HISTORY_MSG_788;LA - Equalizer detail -HISTORY_MSG_789;LA - SH-masker hoeveelheid -HISTORY_MSG_790;LA - SH-masker anker -HISTORY_MSG_791;LA - masker Short L-curven -HISTORY_MSG_792;LA - masker - Achtergrond -HISTORY_MSG_793;LA - SH TRC gamma -HISTORY_MSG_794;LA - SH TRC helling -HISTORY_MSG_795;LA - masker bewaar herstel beeld -HISTORY_MSG_796;LA - SC - Recursieve referenties -HISTORY_MSG_797;LA - Meng Originele methode -HISTORY_MSG_798;LA - Opaciteit -HISTORY_MSG_799;LA - Kleur RGB Tooncurve -HISTORY_MSG_800;LA - Kleur Tooncurve Methode -HISTORY_MSG_801;LA - Kleur Tooncurve Speciaal -HISTORY_MSG_802;LA - Contrastdrempel -HISTORY_MSG_803;LA - Kleur Meng -HISTORY_MSG_804;LA - Kleur masker structuur -HISTORY_MSG_805;LA - Vervaging Ruisonderdrukking maskerstructuur -HISTORY_MSG_806;LA - Kleur masker structuur als gereedschap -HISTORY_MSG_807;LA - Vervaging Ruisonderdrukkingsmasker structuur als gereedschap -HISTORY_MSG_808;LA - Kleur masker curve H(H) -HISTORY_MSG_809;LA - Lev. maskercurve C(C) -HISTORY_MSG_810;LA - Lev. maskercurve L(L) -HISTORY_MSG_811;LA - Lev. maskercurve LC(H) -HISTORY_MSG_813;LA - Gebruik Levendigheid masker -HISTORY_MSG_814;LA - Lev. masker Meng -HISTORY_MSG_815;LA - Lev. masker straal -HISTORY_MSG_816;LA - Lev. masker chroma -HISTORY_MSG_817;LA - Lev. masker gamma -HISTORY_MSG_818;LA - Lev. masker helling -HISTORY_MSG_819;LA - Lev. masker laplacian -HISTORY_MSG_820;LA - Lev. masker contrastcurve -HISTORY_MSG_821;LA - kleurenraster achtergrond -HISTORY_MSG_822;LA - kleur achtergrond meng -HISTORY_MSG_823;LA - kleur achtergrond luminantie -HISTORY_MSG_824;LA - Bel. verloopmasker kracht -HISTORY_MSG_825;LA - Bel. verloopmasker hoek -HISTORY_MSG_826;LA - Bel. verloop kracht -HISTORY_MSG_827;LA - Bel. verloop hoek -HISTORY_MSG_828;LA - SH verloop kracht -HISTORY_MSG_829;LA - SH verloop hoek -HISTORY_MSG_830;LA - Keurverloop kracht L -HISTORY_MSG_831;LA - Keurverloop hoek -HISTORY_MSG_832;LA - Keurverloop kracht C -HISTORY_MSG_833;LA - TG - Veer verloop -HISTORY_MSG_834;LA - Keurverloop kracht H -HISTORY_MSG_835;LA - Lev. verloop kracht L -HISTORY_MSG_836;LA - Lev. verloop hoek -HISTORY_MSG_837;LA - Lev. verloop kracht C -HISTORY_MSG_838;LA - Lev. verloop kracht H -HISTORY_MSG_839;LA - Softwarecomplexiteit -HISTORY_MSG_840;LA - CL-curve -HISTORY_MSG_841;LA - LC-curve -HISTORY_MSG_842;LA - Vervagingsmasker Straal -HISTORY_MSG_843;LA - Vervagingsmasker Contrastdrempel -HISTORY_MSG_844;LA - Vervagingsmasker FFTW -HISTORY_MSG_845;LA - Log-codering -HISTORY_MSG_846;LA - Log-codering auto -HISTORY_MSG_847;LA - Log-codering Bron -HISTORY_MSG_849;LA - Log-codering Bron auto -HISTORY_MSG_850;LA - Log-codering B_Ev -HISTORY_MSG_851;LA - Log-codering W_Ev -HISTORY_MSG_852;LA - Log-codering Doel -HISTORY_MSG_853;LA - Log encodind lokaal contrast -HISTORY_MSG_854;LA - Log encodind bereik -HISTORY_MSG_855;LA - Log-codering gehele beeld -HISTORY_MSG_856;LA - Log-codering Schaduwen bereik -HISTORY_MSG_857;LA - Wavelet vervaging residueel -HISTORY_MSG_858;LA - Wavelet vervaging alleen luminantie -HISTORY_MSG_859;LA - Wavelet max. vervaging -HISTORY_MSG_860;LA - Wavelet vervaging niveaus -HISTORY_MSG_861;LA - Wavelet contrastniveaus -HISTORY_MSG_862;LA - Wavelet contrastversterking -HISTORY_MSG_863;LA - Wavelet meng met originele afbeelding -HISTORY_MSG_864;LA - Wavelet dir contrastversterking -HISTORY_MSG_865;LA - Wavelet dir contrast delta -HISTORY_MSG_866;LA - Wavelet dir compressie -HISTORY_MSG_868;LA - SD - C-H balans -HISTORY_MSG_869;LA - Ruisonderdrukking per niveau -HISTORY_MSG_870;LA - Wavelet masker curve H -HISTORY_MSG_871;LA - Wavelet masker curve C -HISTORY_MSG_872;LA - Wavelet masker curve L -HISTORY_MSG_873;LA - Wavelet masker -HISTORY_MSG_875;LA - Wavelet masker voeg samen -HISTORY_MSG_876;LA - Wavelet masker zacht -HISTORY_MSG_877;LA - Wavelet masker chroma -HISTORY_MSG_878;LA - Wavelet masker contrastcurve -HISTORY_MSG_879;LA - Wavelet contrast chroma -HISTORY_MSG_880;LA - Wavelet vervaging chroma -HISTORY_MSG_881;LA - Wavelet contrast verschuiving -HISTORY_MSG_882;LA - Wavelet vervaging -HISTORY_MSG_883;LA - Wavelet contrast per niveau -HISTORY_MSG_884;LA - Wavelet dir contrast -HISTORY_MSG_885;LA - Wavelet toonmapping -HISTORY_MSG_886;LA - Wavelet toonmapping comprimeer -HISTORY_MSG_887;LA - Wavelet toonmapping comprimeer residueel -HISTORY_MSG_888;LA - Contrast Wavelet Balans Drempel -HISTORY_MSG_889;LA - Contrast Wavelet Verloop Sterkte -HISTORY_MSG_890;LA - Contrast Wavelet Verloop hoek -HISTORY_MSG_891;LA - Contrast Wavelet Verloop -HISTORY_MSG_892;LA - Log Encoding Verloop kracht -HISTORY_MSG_893;LA - Log Encoding Verloop hoek -HISTORY_MSG_894;LA - SD - ΔE voorbeeld kleurintensiteit -HISTORY_MSG_897;LA - Contrast Wavelet ES kracht -HISTORY_MSG_898;LA - Contrast Wavelet ES straal -HISTORY_MSG_899;LA - Contrast Wavelet ES detail -HISTORY_MSG_900;LA - Contrast Wavelet ES verloop -HISTORY_MSG_901;LA - Contrast Wavelet ES drempel laag -HISTORY_MSG_902;LA - Contrast Wavelet ES drempel hoog -HISTORY_MSG_903;LA - Contrast Wavelet ES LA contrast -HISTORY_MSG_904;LA - Contrast Wavelet ES eerste niveau -HISTORY_MSG_905;LA - Contrast Wavelet Randscherpte -HISTORY_MSG_906;LA - Contrast Wavelet ES gevoeligheid -HISTORY_MSG_907;LA - Contrast Wavelet ES versterking -HISTORY_MSG_908;LA - Contrast Wavelet ES nabuur -HISTORY_MSG_909;LA - Contrast Wavelet ES toon -HISTORY_MSG_910;LA - SC - Wavelet Randprestaties -HISTORY_MSG_911;LA - Vervaging Chroma Luma -HISTORY_MSG_912;LA - Vervaging Gids filterkracht -HISTORY_MSG_913;LA - Contrast Wavelet Sigma DR -HISTORY_MSG_914;LA - Vervaging Wavelet Sigma BL -HISTORY_MSG_915;LA - Rand Wavelet Sigma ED -HISTORY_MSG_916;LA - Residueel wavelet schaduwen -HISTORY_MSG_917;LA - Residueel wavelet schaduwen drempel -HISTORY_MSG_918;LA - Residueel wavelet hoge lichten -HISTORY_MSG_919;LA - Residueel wavelet hoge lichten drempel -HISTORY_MSG_920;LA - Wavelet sigma LC -HISTORY_MSG_921;LA - Wavelet Gradueel sigma LC2 -HISTORY_MSG_922;LA - SC - Veranderingen in Z-W -HISTORY_MSG_923;LA - Gereedschapscomplexiteit modus +HISTORY_MSG_496;SB - Spot verwijderd +HISTORY_MSG_497;SB - Spot geselecteerd +HISTORY_MSG_498;Lokaal - Spotnaam +HISTORY_MSG_499;Lokaal - Zichtbaarheid spot +HISTORY_MSG_500;SB - Spotvorm +HISTORY_MSG_501;SB - Spotmethode +HISTORY_MSG_502;SB - SC - Vorm method +HISTORY_MSG_503;SB - Spot - Rechts +HISTORY_MSG_504;SB - Spot - Links +HISTORY_MSG_505;SB - Spot - Onder +HISTORY_MSG_506;SB - Spot - Boven +HISTORY_MSG_507;SB - Spot - Centrum +HISTORY_MSG_508;SB - Spot - Grootte +HISTORY_MSG_509;SB - Spot kwaliteitsmethode +HISTORY_MSG_510;SB - TG - Transitiewaarde +HISTORY_MSG_511;SB - SD - Drempel ΔE-bereik +HISTORY_MSG_512;SB - SD - ΔE-verval +HISTORY_MSG_513;SB - Spot - Uitsluiting - bereik +HISTORY_MSG_514;SB - Spotstructuur +HISTORY_MSG_515;SB - Aanpassingen +HISTORY_MSG_516;SB - Kleur en Licht +HISTORY_MSG_517;SB - Activeer super +HISTORY_MSG_518;SB - Lichtheid +HISTORY_MSG_519;SB - Contrast +HISTORY_MSG_520;SB - Chrominantie +HISTORY_MSG_521;SB - Bereik +HISTORY_MSG_522;SB - Curvemethode +HISTORY_MSG_523;SB - LL-curve +HISTORY_MSG_524;SB - CC-curve +HISTORY_MSG_525;SB - LH-curve +HISTORY_MSG_526;SB - H-curve +HISTORY_MSG_527;SB - Inverteer kleur +HISTORY_MSG_528;SB - Belichting +HISTORY_MSG_529;SB - Belichtingscompensatie +HISTORY_MSG_530;SB - Bel. Hlcompr +HISTORY_MSG_531;SB - Bel. hlcomprthresh +HISTORY_MSG_532;SB - Bel. zwart +HISTORY_MSG_533;SB - Bel. Shcompr +HISTORY_MSG_534;SB - Warm Koel +HISTORY_MSG_535;SB - Bel. Bereik +HISTORY_MSG_536;SB - Bel. Contrastcurve +HISTORY_MSG_537;SB - Levendigheid +HISTORY_MSG_538;SB - Lev. Verzadigd +HISTORY_MSG_539;SB - Lev. Pastel +HISTORY_MSG_540;SB - Lev. Drempel +HISTORY_MSG_541;SB - Lev. Bescherm huidtonen +HISTORY_MSG_542;SB - Lev. Vermijd kleurverschuiving +HISTORY_MSG_543;SB - Lev. Koppel +HISTORY_MSG_544;SB - Lev. Bereik +HISTORY_MSG_545;SB - Lev. H-curve +HISTORY_MSG_546;SB - Vervaging en Ruisvermindering +HISTORY_MSG_547;SB - Straal +HISTORY_MSG_548;SB - Ruis +HISTORY_MSG_549;SB - Bereik ruisvermindering +HISTORY_MSG_550;SB - Methode ruisvermindering +HISTORY_MSG_551;SB - Ruisvermindering alleen Luminantie +HISTORY_MSG_552;SB - Toonmappen +HISTORY_MSG_553;SB - TM compressiesterkte +HISTORY_MSG_554;SB - TM gamma +HISTORY_MSG_555;SB - TM Randbehoud +HISTORY_MSG_556;SB - TM Schaal +HISTORY_MSG_557;SB - TM Herwogen +HISTORY_MSG_558;SB - TM Bereik +HISTORY_MSG_559;SB - Retinex +HISTORY_MSG_560;SB - Retinex methode +HISTORY_MSG_561;SB - Retinex kracht +HISTORY_MSG_562;SB - Retinex chroma +HISTORY_MSG_563;SB - Retinex straal +HISTORY_MSG_564;SB - Retinex contrast +HISTORY_MSG_565;SB - Bereik +HISTORY_MSG_566;SB - Retinex versterkingscurve +HISTORY_MSG_567;SB - Retinex Omgekeerd +HISTORY_MSG_568;SB - Verscherping +HISTORY_MSG_569;SB - Sh Straal +HISTORY_MSG_570;SB - Sh Hoeveelheid +HISTORY_MSG_571;SB - Sh Demping +HISTORY_MSG_572;SB - Sh Herhalingen +HISTORY_MSG_573;SB - Sh Bereik +HISTORY_MSG_574;SB - Sh Omgekeerd +HISTORY_MSG_575;SB - CBDL +HISTORY_MSG_576;SB - cbdl mult +HISTORY_MSG_577;SB - cbdl chroma +HISTORY_MSG_578;SB - cbdl drempel +HISTORY_MSG_579;SB - cbdl bereik +HISTORY_MSG_581;SB - Ruisverm. lum f 1 +HISTORY_MSG_582;SB - Ruisverm. lum c +HISTORY_MSG_583;SB - Ruisverm. lum detail +HISTORY_MSG_584;SB - Ruisverm. equalizer Wit-Zwart +HISTORY_MSG_585;SB - Ruisverm. chro f +HISTORY_MSG_586;SB - Ruisverm. chro c +HISTORY_MSG_587;SB - Ruisverm. chro detail +HISTORY_MSG_588;SB - Ruisverm. equalizer Blauw-Rood +HISTORY_MSG_589;SB - Ruisverm. bilateraal +HISTORY_MSG_590;SB - Ruisverm. bereik +HISTORY_MSG_591;SB - Voorkom kleurverschuiving +HISTORY_MSG_592;SB - Sh Contrast +HISTORY_MSG_593;SB - LA contrast +HISTORY_MSG_594;SB - Lokaal contrast straal +HISTORY_MSG_595;SB - Lokaal contrast hoeveelheid +HISTORY_MSG_596;SB - Lokaal contrast donkerte +HISTORY_MSG_597;SB - Lokaal contrast lichtheid +HISTORY_MSG_598;SB - Lokaal contrast bereik +HISTORY_MSG_599;SB - Retinex ontnevel +HISTORY_MSG_600;SB - Zacht licht activeer +HISTORY_MSG_601;SB - Zacht licht kracht +HISTORY_MSG_602;SB - Zacht licht bereik +HISTORY_MSG_603;SB - Sh Vervagingsradius +HISTORY_MSG_605;SB - Keuze maskervoorbeeld +HISTORY_MSG_606;SB - Spot geslecteerd +HISTORY_MSG_607;SB - Kleurmasker C +HISTORY_MSG_608;SB - Kleurmasker L +HISTORY_MSG_609;SB - Bel.masker C +HISTORY_MSG_610;SB - Bel.masker L +HISTORY_MSG_611;SB - Kleurmasker H +HISTORY_MSG_612;SB - Kleur structuur +HISTORY_MSG_613;SB - Bel. structuur +HISTORY_MSG_614;SB - Bel.masker H +HISTORY_MSG_615;SB - Meng kleur +HISTORY_MSG_616;SB - Meng bel. +HISTORY_MSG_617;SB - Vervaag Bel. +HISTORY_MSG_618;SB - Gebruik kleurmasker +HISTORY_MSG_619;SB - Gebruik bel.masker +HISTORY_MSG_620;SB - Meng col +HISTORY_MSG_621;SB - Bel. omgekeerd +HISTORY_MSG_622;SB - Spot - Uitsluiting - Spotstructuur +HISTORY_MSG_623;SB - Bel. Chroma-compensatie +HISTORY_MSG_624;SB - Kleurcorrectieraster +HISTORY_MSG_625;SB - Kleurcorrectie kracht +HISTORY_MSG_626;SB - Kleurcorrectie methode +HISTORY_MSG_627;SB - Schaduw Hoge lichten +HISTORY_MSG_628;SB - SH Hoge lichten +HISTORY_MSG_629;SB - SH H tonaalomvang +HISTORY_MSG_630;SB - SH Schaduwen +HISTORY_MSG_631;SB - SH S tonaalomvang +HISTORY_MSG_632;SB - SH straal +HISTORY_MSG_633;SB - SH bereik +HISTORY_MSG_634;SB - straal kleur +HISTORY_MSG_635;SB - straal Bel. +HISTORY_MSG_636;SB - Gereedschap toegevoegd +HISTORY_MSG_637;SB - SH Masker C +HISTORY_MSG_638;SB - SH Masker L +HISTORY_MSG_639;SB - SH Masker H +HISTORY_MSG_640;SB - SH meng +HISTORY_MSG_641;SB - Gebruik SH-masker +HISTORY_MSG_642;SB - Straal SH +HISTORY_MSG_643;SB - Vervaag SH +HISTORY_MSG_644;SB - Keer SH om +HISTORY_MSG_645;SB - SD - ab-L-balans +HISTORY_MSG_646;SB - Bel.masker chroma +HISTORY_MSG_647;SB - Bel.masker gamma +HISTORY_MSG_648;SB - Bel.masker helling +HISTORY_MSG_649;SB - Bel. verzachting straal +HISTORY_MSG_650;SB - Kleurmasker chroma +HISTORY_MSG_651;SB - Kleurmasker gamma +HISTORY_MSG_652;SB - Kleurmasker helling +HISTORY_MSG_653;SB - SH-masker chroma +HISTORY_MSG_654;SB - SH-masker gamma +HISTORY_MSG_655;SB - SH-masker helling +HISTORY_MSG_656;SB - Kleur zachte radius +HISTORY_MSG_657;SB - Retinex verminder onregelmatigheden +HISTORY_MSG_658;SB - CBDL zachte radius +HISTORY_MSG_659;SB - TG - Transitieverval +HISTORY_MSG_660;SB - CBDL klaarheid +HISTORY_MSG_661;SB - CBDL residueel contrast +HISTORY_MSG_662;SB - Verminder ruis lum f 0 +HISTORY_MSG_663;SB - Verminder ruis lum f 2 +HISTORY_MSG_665;SB - cbdl masker meng +HISTORY_MSG_666;SB - cbdl masker straal +HISTORY_MSG_667;SB - cbdl masker chroma +HISTORY_MSG_668;SB - cbdl masker gamma +HISTORY_MSG_669;SB - cbdl masker helling +HISTORY_MSG_670;SB - cbdl masker C +HISTORY_MSG_671;SB - cbdl masker L +HISTORY_MSG_672;SB - cbdl masker CL +HISTORY_MSG_673;SB - Gebruik cbdl masker +HISTORY_MSG_674;SB - Gereedschap verwijderd +HISTORY_MSG_675;SB - TM zacht straal +HISTORY_MSG_676;SB - TG - Transitiedifferentie +HISTORY_MSG_677;SB - TM hoeveelheid +HISTORY_MSG_678;SB - TM verzadiging +HISTORY_MSG_679;SB - Retinex masker C +HISTORY_MSG_680;SB - Retinex masker L +HISTORY_MSG_681;SB - Retinex masker CL +HISTORY_MSG_682;SB - Retinex masker +HISTORY_MSG_683;SB - Retinex masker meng +HISTORY_MSG_684;SB - Retinex masker straal +HISTORY_MSG_685;SB - Retinex masker chroma +HISTORY_MSG_686;SB - Retinex masker gamma +HISTORY_MSG_687;SB - Retinex masker helling +HISTORY_MSG_688;SB - Gereedschap verwijderd +HISTORY_MSG_689;SB - Retinex masker transmissiemap +HISTORY_MSG_690;SB - Retinex schaal +HISTORY_MSG_691;SB - Retinex donkerte +HISTORY_MSG_692;SB - Retinex lichtheid +HISTORY_MSG_693;SB - Retinex drempel +HISTORY_MSG_694;SB - Retinex Laplacian drempel +HISTORY_MSG_695;SB - Verzachting methode +HISTORY_MSG_696;SB - Retinex Normaliseer +HISTORY_MSG_697;SB - TM Normaliseer +HISTORY_MSG_698;SB - LA contrast Fast Fourier +HISTORY_MSG_699;SB - Retinex Fast Fourier +HISTORY_MSG_701;SB - Bel. Schaduwen +HISTORY_MSG_702;SB - Bel. Methode +HISTORY_MSG_703;SB - Bel. Laplacian drempel +HISTORY_MSG_704;SB - Bel. PDE-balans +HISTORY_MSG_705;SB - Bel. lineariteit +HISTORY_MSG_706;SB - TM masker C +HISTORY_MSG_707;SB - TM masker L +HISTORY_MSG_708;SB - TM masker CL +HISTORY_MSG_709;SB - gebruik TM-masker +HISTORY_MSG_710;SB - TM-masker meng +HISTORY_MSG_711;SB - TM-masker straal +HISTORY_MSG_712;SB - TM-masker chroma +HISTORY_MSG_713;SB - TM-masker gamma +HISTORY_MSG_714;SB - TM-masker helling +HISTORY_MSG_716;SB - LA methode +HISTORY_MSG_717;SB - LA contrast +HISTORY_MSG_718;SB - LA contrastniveaus +HISTORY_MSG_719;SB - LA contrast residueel L +HISTORY_MSG_720;SB - Vervagingsmasker C +HISTORY_MSG_721;SB - Vervagingsmasker L +HISTORY_MSG_722;SB - Vervagingsmasker CL +HISTORY_MSG_723;SB - Gebruik vervagingsmasker +HISTORY_MSG_725;SB - Vervagingsmasker meng +HISTORY_MSG_726;SB - Vervagingsmasker straal +HISTORY_MSG_727;SB - Vervagingsmasker chroma +HISTORY_MSG_728;SB - Vervagingsmasker gamma +HISTORY_MSG_729;SB - Vervagingsmasker helling +HISTORY_MSG_730;SB - Vervaging methode +HISTORY_MSG_731;SB - mediaanmethod +HISTORY_MSG_732;SB - mediaan herhalingen +HISTORY_MSG_733;SB - straal zacht +HISTORY_MSG_734;SB - detail +HISTORY_MSG_738;SB - Lokaal contrast meng L +HISTORY_MSG_739;SB - Lokaal contrast zacht straal +HISTORY_MSG_740;SB - Lokaal contrast Meng C +HISTORY_MSG_741;SB - Lokaal contrast Residueel C +HISTORY_MSG_742;SB - Exp Laplacian gamma +HISTORY_MSG_743;SB - Bel. Fattal Hoeveelheid +HISTORY_MSG_744;SB - Bel. Fattal Detail +HISTORY_MSG_745;SB - Bel. Fattal verschuiving +HISTORY_MSG_746;SB - Bel. Fattal Sigma +HISTORY_MSG_747;SB - Spot aangemaakt +HISTORY_MSG_748;SB - Bel. Ruisvermindering +HISTORY_MSG_749;SB - Reti Diepte +HISTORY_MSG_750;SB - Reti Modus log - lin +HISTORY_MSG_751;SB - Reti Ontnevel verzadiging +HISTORY_MSG_752;SB - Reti Verschuiving +HISTORY_MSG_753;SB - Reti Transmissiemap +HISTORY_MSG_754;SB - Reti Kap +HISTORY_MSG_755;SB - TM gebruik tm-masker +HISTORY_MSG_756;SB - Bel. gebruik algo belichtingsmasker +HISTORY_MSG_757;SB - Bel. Laplacian-masker +HISTORY_MSG_758;SB - Reti Laplacian-masker +HISTORY_MSG_759;SB - Bel. Laplacian-masker +HISTORY_MSG_760;SB - Kleur Laplacian masker +HISTORY_MSG_761;SB - SH Laplacian-masker +HISTORY_MSG_762;SB - cbdl Laplacian-masker +HISTORY_MSG_763;SB - Blur Laplacian-masker +HISTORY_MSG_764;SB - Solve PDE Laplacian-masker +HISTORY_MSG_765;SB - Ruisvermindering detaildrempel +HISTORY_MSG_766;SB - Vervaag Fast Fourier +HISTORY_MSG_767;SB - Korrel ISO +HISTORY_MSG_768;SB - Korrel Sterkte +HISTORY_MSG_769;SB - Korrel Schaal +HISTORY_MSG_770;SB - Kleurmasker contrastcurve +HISTORY_MSG_771;SB - Bel.masker contrastcurve +HISTORY_MSG_772;SB - SH-masker contrastcurve +HISTORY_MSG_773;SB - TM-Masker contrastcurve +HISTORY_MSG_774;SB - Reti masker contrastcurve +HISTORY_MSG_775;SB - CBDL masker contrastcurve +HISTORY_MSG_776;SB - Vervaag-Ruisverminderingmasker contrastcurve +HISTORY_MSG_777;SB - Vervaagmasker lokale contrastcurve +HISTORY_MSG_778;SB - Maskeer hoge lichten +HISTORY_MSG_779;SB - Kleurmasker lokale contrastcurve +HISTORY_MSG_780;SB - Kleurmasker schaduwen +HISTORY_MSG_781;SB - Contrastmasker Wavelet-niveau +HISTORY_MSG_782;SB - Vervaag-Ruisverminderingmasker Wavelet-niveaus +HISTORY_MSG_783;SB - Kleur Wavelet-niveaus +HISTORY_MSG_784;SB - masker - ΔE beeldmasker +HISTORY_MSG_785;SB - masker - bereik +HISTORY_MSG_786;SB - SH-methode +HISTORY_MSG_787;SB - Equalizer vermenigvuldiger +HISTORY_MSG_788;SB - Equalizer detail +HISTORY_MSG_789;SB - SH-masker hoeveelheid +HISTORY_MSG_790;SB - SH-masker anker +HISTORY_MSG_791;SB - masker Short L-curven +HISTORY_MSG_792;SB - masker - Achtergrond +HISTORY_MSG_793;SB - SH TRC gamma +HISTORY_MSG_794;SB - SH TRC helling +HISTORY_MSG_795;SB - masker bewaar herstel beeld +HISTORY_MSG_796;SB - SC - Recursieve referenties +HISTORY_MSG_797;SB - Meng Originele methode +HISTORY_MSG_798;SB - Opaciteit +HISTORY_MSG_799;SB - Kleur RGB Tooncurve +HISTORY_MSG_800;SB - Kleur Tooncurve Methode +HISTORY_MSG_801;SB - Kleur Tooncurve Speciaal +HISTORY_MSG_802;SB - Contrastdrempel +HISTORY_MSG_803;SB - Kleur Meng +HISTORY_MSG_804;SB - Kleur masker structuur +HISTORY_MSG_805;SB - Vervaging Ruisonderdrukking maskerstructuur +HISTORY_MSG_806;SB - Kleur masker structuur als gereedschap +HISTORY_MSG_807;SB - Vervaging Ruisonderdrukkingsmasker structuur als gereedschap +HISTORY_MSG_808;SB - Kleur masker curve H(H) +HISTORY_MSG_809;SB - Lev. maskercurve C(C) +HISTORY_MSG_810;SB - Lev. maskercurve L(L) +HISTORY_MSG_811;SB - Lev. maskercurve LC(H) +HISTORY_MSG_813;SB - Gebruik Levendigheid masker +HISTORY_MSG_814;SB - Lev. masker Meng +HISTORY_MSG_815;SB - Lev. masker straal +HISTORY_MSG_816;SB - Lev. masker chroma +HISTORY_MSG_817;SB - Lev. masker gamma +HISTORY_MSG_818;SB - Lev. masker helling +HISTORY_MSG_819;SB - Lev. masker laplacian +HISTORY_MSG_820;SB - Lev. masker contrastcurve +HISTORY_MSG_821;SB - kleurenraster achtergrond +HISTORY_MSG_822;SB - kleur achtergrond meng +HISTORY_MSG_823;SB - kleur achtergrond luminantie +HISTORY_MSG_824;SB - Bel. verloopmasker kracht +HISTORY_MSG_825;SB - Bel. verloopmasker hoek +HISTORY_MSG_826;SB - Bel. verloop kracht +HISTORY_MSG_827;SB - Bel. verloop hoek +HISTORY_MSG_828;SB - SH verloop kracht +HISTORY_MSG_829;SB - SH verloop hoek +HISTORY_MSG_830;SB - Keurverloop kracht L +HISTORY_MSG_831;SB - Keurverloop hoek +HISTORY_MSG_832;SB - Keurverloop kracht C +HISTORY_MSG_833;SB - TG - Veer verloop +HISTORY_MSG_834;SB - Keurverloop kracht H +HISTORY_MSG_835;SB - Lev. verloop kracht L +HISTORY_MSG_836;SB - Lev. verloop hoek +HISTORY_MSG_837;SB - Lev. verloop kracht C +HISTORY_MSG_838;SB - Lev. verloop kracht H +HISTORY_MSG_839;SB - Softwarecomplexiteit +HISTORY_MSG_840;SB - CL-curve +HISTORY_MSG_841;SB - LC-curve +HISTORY_MSG_842;SB - Vervagingsmasker Straal +HISTORY_MSG_843;SB - Vervagingsmasker Contrastdrempel +HISTORY_MSG_844;SB - Vervagingsmasker FFTW +HISTORY_MSG_845;SB - Log-codering +HISTORY_MSG_846;SB - Log-codering auto +HISTORY_MSG_847;SB - Log-codering Bron +HISTORY_MSG_849;SB - Log-codering Bron auto +HISTORY_MSG_850;SB - Log-codering B_Ev +HISTORY_MSG_851;SB - Log-codering W_Ev +HISTORY_MSG_852;SB - Log-codering Doel +HISTORY_MSG_853;SB - Log encodind lokaal contrast +HISTORY_MSG_854;SB - Log encodind bereik +HISTORY_MSG_855;SB - Log-codering gehele beeld +HISTORY_MSG_856;SB - Log-codering Schaduwen bereik +HISTORY_MSG_857;SB - Wavelet vervaging residueel +HISTORY_MSG_858;SB - Wavelet vervaging alleen luminantie +HISTORY_MSG_859;SB - Wavelet max. vervaging +HISTORY_MSG_860;SB - Wavelet vervaging niveaus +HISTORY_MSG_861;SB - Wavelet contrastniveaus +HISTORY_MSG_862;SB - Wavelet contrastversterking +HISTORY_MSG_863;SB - Wavelet meng met originele afbeelding +HISTORY_MSG_864;SB - Wavelet dir contrastversterking +HISTORY_MSG_865;SB - Wavelet dir contrast delta +HISTORY_MSG_866;SB - Wavelet dir compressie +HISTORY_MSG_868;SB - SD - C-H balans +HISTORY_MSG_869;SB - Ruisonderdrukking per niveau +HISTORY_MSG_870;SB - Wavelet masker curve H +HISTORY_MSG_871;SB - Wavelet masker curve C +HISTORY_MSG_872;SB - Wavelet masker curve L +HISTORY_MSG_873;SB - Wavelet masker +HISTORY_MSG_875;SB - Wavelet masker voeg samen +HISTORY_MSG_876;SB - Wavelet masker zacht +HISTORY_MSG_877;SB - Wavelet masker chroma +HISTORY_MSG_878;SB - Wavelet masker contrastcurve +HISTORY_MSG_879;SB - Wavelet contrast chroma +HISTORY_MSG_880;SB - Wavelet vervaging chroma +HISTORY_MSG_881;SB - Wavelet contrast verschuiving +HISTORY_MSG_882;SB - Wavelet vervaging +HISTORY_MSG_883;SB - Wavelet contrast per niveau +HISTORY_MSG_884;SB - Wavelet dir contrast +HISTORY_MSG_885;SB - Wavelet toonmapping +HISTORY_MSG_886;SB - Wavelet toonmapping comprimeer +HISTORY_MSG_887;SB - Wavelet toonmapping comprimeer residueel +HISTORY_MSG_888;SB - Contrast Wavelet Balans Drempel +HISTORY_MSG_889;SB - Contrast Wavelet Verloop Sterkte +HISTORY_MSG_890;SB - Contrast Wavelet Verloop hoek +HISTORY_MSG_891;SB - Contrast Wavelet Verloop +HISTORY_MSG_892;SB - Log Encoding Verloop kracht +HISTORY_MSG_893;SB - Log Encoding Verloop hoek +HISTORY_MSG_894;SB - SD - ΔE voorbeeld kleurintensiteit +HISTORY_MSG_897;SB - Contrast Wavelet ES kracht +HISTORY_MSG_898;SB - Contrast Wavelet ES straal +HISTORY_MSG_899;SB - Contrast Wavelet ES detail +HISTORY_MSG_900;SB - Contrast Wavelet ES verloop +HISTORY_MSG_901;SB - Contrast Wavelet ES drempel laag +HISTORY_MSG_902;SB - Contrast Wavelet ES drempel hoog +HISTORY_MSG_903;SB - Contrast Wavelet ES LA contrast +HISTORY_MSG_904;SB - Contrast Wavelet ES eerste niveau +HISTORY_MSG_905;SB - Contrast Wavelet Randscherpte +HISTORY_MSG_906;SB - Contrast Wavelet ES gevoeligheid +HISTORY_MSG_907;SB - Contrast Wavelet ES versterking +HISTORY_MSG_908;SB - Contrast Wavelet ES nabuur +HISTORY_MSG_909;SB - Contrast Wavelet ES toon +HISTORY_MSG_910;SB - SC - Wavelet Randprestaties +HISTORY_MSG_911;SB - Vervaging Chroma Luma +HISTORY_MSG_912;SB - Vervaging Gids filterkracht +HISTORY_MSG_913;SB - Contrast Wavelet Sigma DR +HISTORY_MSG_914;SB - Vervaging Wavelet Sigma BL +HISTORY_MSG_915;SB - Rand Wavelet Sigma ED +HISTORY_MSG_916;SB - Residueel wavelet schaduwen +HISTORY_MSG_917;SB - Residueel wavelet schaduwen drempel +HISTORY_MSG_918;SB - Residueel wavelet hoge lichten +HISTORY_MSG_919;SB - Residueel wavelet hoge lichten drempel +HISTORY_MSG_920;SB - Wavelet sigma LC +HISTORY_MSG_921;SB - Wavelet Gradueel sigma LC2 +HISTORY_MSG_922;SB - SC - Veranderingen in Z-W +HISTORY_MSG_923;SB - Gereedschapscomplexiteit modus HISTORY_MSG_924;--unused-- -HISTORY_MSG_925;LA - bereik (kleurgereedschappen) -HISTORY_MSG_926;LA - Toon maskertype -HISTORY_MSG_927;LA - Schaduw -HISTORY_MSG_928;LA - Algemeen kleurenmasker -HISTORY_MSG_929;LA - Masker Algemeen Bereik -HISTORY_MSG_930;LA - Masker Algemeen Meng luma -HISTORY_MSG_931;LA - Masker Algemeen activeer -HISTORY_MSG_932;LA - Masker Algemeen straal zacht -HISTORY_MSG_933;LA - Masker Algemeen laplacian -HISTORY_MSG_934;LA - Masker Algemeen chroma -HISTORY_MSG_935;LA - Masker Algemeen gamma -HISTORY_MSG_936;LA - Masker Algemeen helling -HISTORY_MSG_937;LA - Masker Algemeen curve C(C) -HISTORY_MSG_938;LA - Masker Algemeen curve L(L) -HISTORY_MSG_939;LA - Masker Algemeen curve LC(H) -HISTORY_MSG_940;LA - Masker Algemeen structuur als gereedschap -HISTORY_MSG_941;LA - Masker Algemeen structuurkracht -HISTORY_MSG_942;LA - Masker Algemeen H(H) curve -HISTORY_MSG_943;LA - Masker Algemeen FFT -HISTORY_MSG_944;LA - Masker Algemeen Vervaging straal -HISTORY_MSG_945;LA - Masker Algemeen contrastdrempel -HISTORY_MSG_946;LA - Masker Algemeen schaduwen -HISTORY_MSG_947;LA - Masker Algemeen Contrastcurve -HISTORY_MSG_948;LA - Masker Algemeen Wavelet-curve -HISTORY_MSG_949;LA - Masker Algemeen Drempel niveaus -HISTORY_MSG_950;LA - Masker Algemeen GF kracht -HISTORY_MSG_951;LA - Masker Algemeen GF hoek -HISTORY_MSG_952;LA - Masker Algemeen zacht straal -HISTORY_MSG_953;LA - Masker Algemeen meng chroma -HISTORY_MSG_954;LA - Toon/verberg gereedschappen -HISTORY_MSG_955;LA - Activeer Spot -HISTORY_MSG_956;LA - CH-curve -HISTORY_MSG_957;LA - Ruisonderdrukking modus -HISTORY_MSG_958;LA - Toon/verberg instellingen -HISTORY_MSG_959;LA - Inverteer vervaging -HISTORY_MSG_960;LA - Log-codering - cat16 -HISTORY_MSG_961;LA - Log-codering Ciecam -HISTORY_MSG_962;LA - Log-codering Absolute luminantie bron -HISTORY_MSG_963;LA - Log-codering Absolute luminantie doel -HISTORY_MSG_964;LA - Log-codering Omgeving -HISTORY_MSG_965;LA - Log-codering Verzadiging s -HISTORY_MSG_966;LA - Log-codering Contrast J -HISTORY_MSG_967;LA - Log-codering masker curve C -HISTORY_MSG_968;LA - Log-codering masker curve L -HISTORY_MSG_969;LA - Log-codering masker curve H -HISTORY_MSG_970;LA - Log-codering masker geactiveerd -HISTORY_MSG_971;LA - Log-codering masker meng -HISTORY_MSG_972;LA - Log-codering masker straal -HISTORY_MSG_973;LA - Log-codering masker chroma -HISTORY_MSG_974;LA - Log-codering masker contrast -HISTORY_MSG_975;LA - Log-codering Lichtheid J -HISTORY_MSG_977;LA - Log-codering Contrast Q -HISTORY_MSG_978;LA - Log-codering Sursource -HISTORY_MSG_979;LA - Log-codering Helderheid Q -HISTORY_MSG_980;LA - Log-codering Kleurrijkheid M -HISTORY_MSG_981;LA - Log-codering Kracht -HISTORY_MSG_982;LA - Equalizer tint -HISTORY_MSG_983;LA - Ruisonderdrukking drempel masker hoog -HISTORY_MSG_984;LA - Ruisonderdrukking drempel masker laag -HISTORY_MSG_985;LA - Ruisonderdrukking Laplacian -HISTORY_MSG_986;LA - Ruisonderdrukking versterk -HISTORY_MSG_987;LA - GF herstel drempel -HISTORY_MSG_988;LA - GF drempel masker laag -HISTORY_MSG_989;LA - GF drempel masker hoog -HISTORY_MSG_990;LA - Ruisonderdrukking herstel drempel -HISTORY_MSG_991;LA - Ruisonderdrukking drempel masker laag -HISTORY_MSG_992;LA - Ruisonderdrukking drempel masker hoog -HISTORY_MSG_993;LA - Ruisonderdrukking Omgekeerd algo -HISTORY_MSG_994;LA - GF Omgekeerd algo -HISTORY_MSG_995;LA - Ruisonderdrukking verval -HISTORY_MSG_996;LA - Kleurherstel drempel -HISTORY_MSG_997;LA - Kleurherstel masker laag -HISTORY_MSG_998;LA - Kleur drempel masker hoog -HISTORY_MSG_999;LA - Kleur verval -HISTORY_MSG_1000;LA - Ruisonderdrukking luminantie grijs -HISTORY_MSG_1001;LA - Log herstel drempel -HISTORY_MSG_1002;LA - Log drempel masker laag -HISTORY_MSG_1003;LA - Log drempel masker hoog -HISTORY_MSG_1004;LA - Log verval -HISTORY_MSG_1005;LA - Bel. herstel drempel -HISTORY_MSG_1006;LA - Bel. drempel masker laag -HISTORY_MSG_1007;LA - Bel. drempel masker hoog -HISTORY_MSG_1008;LA - Bel. verval -HISTORY_MSG_1009;LA - SH herstel drempel -HISTORY_MSG_1010;LA - SH drempel masker laag -HISTORY_MSG_1011;LA - SH drempel masker hoog -HISTORY_MSG_1012;LA - SH verval -HISTORY_MSG_1013;LA - lev. herstel drempel -HISTORY_MSG_1014;LA - lev. drempel masker laag -HISTORY_MSG_1015;LA - lev. drempel masker hoog -HISTORY_MSG_1016;LA - lev. verval -HISTORY_MSG_1017;LA - lc herstel drempel -HISTORY_MSG_1018;LA - lc drempel masker laag -HISTORY_MSG_1019;LA - lc drempel masker hoog -HISTORY_MSG_1020;LA - lc verval -HISTORY_MSG_1021;LA - Ruisonderdrukking chrominantie grijs -HISTORY_MSG_1022;LA - TM herstel drempel -HISTORY_MSG_1023;LA - TM drempel masker laag -HISTORY_MSG_1024;LA - TM drempel masker hoog -HISTORY_MSG_1025;LA - TM verval -HISTORY_MSG_1026;LA - cbdl herstel drempel -HISTORY_MSG_1027;LA - cbdl drempel masker laag -HISTORY_MSG_1028;LA - cbdl drempel masker hoog -HISTORY_MSG_1029;LA - cbdl verval -HISTORY_MSG_1030;LA - reti herstel drempel -HISTORY_MSG_1031;LA - reti drempel masker laag -HISTORY_MSG_1032;LA - reti drempel masker hoog -HISTORY_MSG_1033;LA - reti verval -HISTORY_MSG_1034;LA - Nlmeans - kracht -HISTORY_MSG_1035;LA - Nlmeans - detail -HISTORY_MSG_1036;LA - Nlmeans - patch -HISTORY_MSG_1037;LA - Nlmeans - straal -HISTORY_MSG_1038;LA - Nlmeans - gamma -HISTORY_MSG_1039;LA - Korrel - gamma -HISTORY_MSG_1040;LA - SC - Verzachtingsstraal -HISTORY_MSG_1041;LA - Spot - Munsell -HISTORY_MSG_1042;LA - Log-codring - drempel -HISTORY_MSG_1043;LA - Bel. - normaliseer -HISTORY_MSG_1044;LA - LA contrast kracht -HISTORY_MSG_1045;LA - Kleur en Licht kracht -HISTORY_MSG_1046;LA - Ruisonderdrukking kracht -HISTORY_MSG_1047;LA - SH en Toonequalizer kracht -HISTORY_MSG_1048;LA - DR en Belichting kracht -HISTORY_MSG_1049;LA - TM kracht -HISTORY_MSG_1050;LA - Log-codering chroma -HISTORY_MSG_1051;LA - residueel wavelet gamma -HISTORY_MSG_1052;LA - residueel wavelet helling -HISTORY_MSG_1053;LA - ruisonderdrukking gamma -HISTORY_MSG_1054;LA - Wavelet gamma -HISTORY_MSG_1055;LA - Kleur en Licht gamma -HISTORY_MSG_1056;LA - DR en Belichting gamma -HISTORY_MSG_1057;LA - CIECAM Geactiveerd -HISTORY_MSG_1058;LA - CIECAM Overall kracht -HISTORY_MSG_1059;LA - CIECAM Autogrijs -HISTORY_MSG_1060;LA - CIECAM Gemiddelde luminantie bron -HISTORY_MSG_1061;LA - CIECAM bron absoluut -HISTORY_MSG_1062;LA - CIECAM omgeving bron -HISTORY_MSG_1063;LA - CIECAM verzadiging -HISTORY_MSG_1064;LA - CIECAM Chroma -HISTORY_MSG_1065;LA - CIECAM lichtheid J -HISTORY_MSG_1066;LA - CIECAM helderheid -HISTORY_MSG_1067;LA - CIECAM Contrast J -HISTORY_MSG_1068;LA - CIECAM drempel -HISTORY_MSG_1069;LA - CIECAM contrast Q -HISTORY_MSG_1070;LA - CIECAM kleurrijkheid -HISTORY_MSG_1071;LA - CIECAM Absolute luminantie -HISTORY_MSG_1072;LA - CIECAM Gemiddelde luminantie -HISTORY_MSG_1073;LA - CIECAM Cat16 -HISTORY_MSG_1074;LA - CIECAM LA contrast -HISTORY_MSG_1075;LA - CIECAM kijkomgeving -HISTORY_MSG_1076;LA - CIECAM bereik -HISTORY_MSG_1077;LA - CIECAM modus -HISTORY_MSG_1078;LA - Rood/huidbescherming -HISTORY_MSG_1079;LA - CIECAM Sigmoid kracht J -HISTORY_MSG_1080;LA - CIECAM Sigmoid drempel -HISTORY_MSG_1081;LA - CIECAM Sigmoid meng -HISTORY_MSG_1082;LA - CIECAM Sigmoid Q BlackEv WhiteEv -HISTORY_MSG_1083;LA - CIECAM tint -HISTORY_MSG_1084;LA - Gebruikt Black Ev - White Ev -HISTORY_MSG_1085;LA - Jz lichtheid -HISTORY_MSG_1086;LA - Jz contrast -HISTORY_MSG_1087;LA - Jz chroma -HISTORY_MSG_1088;LA - Jz tint -HISTORY_MSG_1089;LA - Jz Sigmoid kracht -HISTORY_MSG_1090;LA - Jz Sigmoid drempel -HISTORY_MSG_1091;LA - Jz Sigmoid meng -HISTORY_MSG_1092;LA - Jz aanpassing -HISTORY_MSG_1093;LA - CAM model -HISTORY_MSG_1094;LA - Jz hoge lichten -HISTORY_MSG_1095;LA - Jz hoge lichten thr -HISTORY_MSG_1096;LA - Jz schaduwen -HISTORY_MSG_1097;LA - Jz schaduwen thr -HISTORY_MSG_1098;LA - Jz straal SH -HISTORY_MSG_1099;LA - Cz(Hz) Curve -HISTORY_MSG_1100;LA - Jz referentie 100 -HISTORY_MSG_1101;LA - Jz PQ remap -HISTORY_MSG_1102;LA - Jz(Hz) Curve -HISTORY_MSG_1103;LA - Levendigheid gamma -HISTORY_MSG_1104;LA - Scherp gamma -HISTORY_MSG_1105;LA - CIECAM Toon methode -HISTORY_MSG_1106;LA - CIECAM Toon curve -HISTORY_MSG_1107;LA - CIECAM Kleur methode -HISTORY_MSG_1108;LA - CIECAM Kleur curve -HISTORY_MSG_1109;LA - Jz(Jz) curve -HISTORY_MSG_1110;LA - Cz(Cz) curve -HISTORY_MSG_1111;LA - Cz(Jz) curve -HISTORY_MSG_1112;LA - forcejz -HISTORY_MSG_1113;LA - HDR PQ -HISTORY_MSG_1114;LA - Cie masker activeer -HISTORY_MSG_1115;LA - Cie masker curve C -HISTORY_MSG_1116;LA - Cie masker curve L -HISTORY_MSG_1117;LA - Cie masker curve H -HISTORY_MSG_1118;LA - Cie masker meng -HISTORY_MSG_1119;LA - Cie masker straal -HISTORY_MSG_1120;LA - Cie masker chroma -HISTORY_MSG_1121;LA - Cie masker contrast curve -HISTORY_MSG_1122;LA - Cie masker herstel drempel -HISTORY_MSG_1123;LA - Cie masker herstel donker -HISTORY_MSG_1124;LA - Cie masker herstel licht -HISTORY_MSG_1125;LA - Cie masker herstel verval -HISTORY_MSG_1126;LA - Cie masker laplacian -HISTORY_MSG_1127;LA - Cie masker gamma -HISTORY_MSG_1128;LA - Cie masker helling -HISTORY_MSG_1129;LA - Cie Relatieve luminantie -HISTORY_MSG_1130;LA - Cie Verzadiging Jz -HISTORY_MSG_1131;LA - masker - Ruisvermindering -HISTORY_MSG_1132;LA - Cie Wav sigma Jz -HISTORY_MSG_1133;LA - Cie Wav level Jz -HISTORY_MSG_1134;LA - Cie Wav LA contrast Jz -HISTORY_MSG_1135;LA - Cie Wav klaarheid Jz -HISTORY_MSG_1136;LA - Cie Wav klaarheid Cz -HISTORY_MSG_1137;LA - Cie Wav klaarheid Zacht -HISTORY_MSG_1138;LA - LA - Hz(Hz) Curve -HISTORY_MSG_1139;LA - Jz zacht Curven H -HISTORY_MSG_1140;LA - Jz Drempel chroma -HISTORY_MSG_1141;LA - chroma curve Jz(Hz) -HISTORY_MSG_1142;LA - kracht zacht -HISTORY_MSG_1143;LA - Jz blackev -HISTORY_MSG_1144;LA - Jz whiteev -HISTORY_MSG_1145;LA - Jz Log-codering -HISTORY_MSG_1146;LA - Jz Log-codering doel grijs -HISTORY_MSG_1147;LA - Jz BlackEv WhiteEv -HISTORY_MSG_1148;LA - Jz Sigmoid -HISTORY_MSG_1149;LA - Q Sigmoid -HISTORY_MSG_1150;LA - Log-codering Q in plaats van Sigmoid Q +HISTORY_MSG_925;SB - bereik (kleurgereedschappen) +HISTORY_MSG_926;SB - Toon maskertype +HISTORY_MSG_927;SB - Schaduw +HISTORY_MSG_928;SB - Algemeen kleurenmasker +HISTORY_MSG_929;SB - Masker Algemeen Bereik +HISTORY_MSG_930;SB - Masker Algemeen Meng luma +HISTORY_MSG_931;SB - Masker Algemeen activeer +HISTORY_MSG_932;SB - Masker Algemeen straal zacht +HISTORY_MSG_933;SB - Masker Algemeen laplacian +HISTORY_MSG_934;SB - Masker Algemeen chroma +HISTORY_MSG_935;SB - Masker Algemeen gamma +HISTORY_MSG_936;SB - Masker Algemeen helling +HISTORY_MSG_937;SB - Masker Algemeen curve C(C) +HISTORY_MSG_938;SB - Masker Algemeen curve L(L) +HISTORY_MSG_939;SB - Masker Algemeen curve LC(H) +HISTORY_MSG_940;SB - Masker Algemeen structuur als gereedschap +HISTORY_MSG_941;SB - Masker Algemeen structuurkracht +HISTORY_MSG_942;SB - Masker Algemeen H(H) curve +HISTORY_MSG_943;SB - Masker Algemeen FFT +HISTORY_MSG_944;SB - Masker Algemeen Vervaging straal +HISTORY_MSG_945;SB - Masker Algemeen contrastdrempel +HISTORY_MSG_946;SB - Masker Algemeen schaduwen +HISTORY_MSG_947;SB - Masker Algemeen Contrastcurve +HISTORY_MSG_948;SB - Masker Algemeen Wavelet-curve +HISTORY_MSG_949;SB - Masker Algemeen Drempel niveaus +HISTORY_MSG_950;SB - Masker Algemeen GF kracht +HISTORY_MSG_951;SB - Masker Algemeen GF hoek +HISTORY_MSG_952;SB - Masker Algemeen zacht straal +HISTORY_MSG_953;SB - Masker Algemeen meng chroma +HISTORY_MSG_954;SB - Toon/verberg gereedschappen +HISTORY_MSG_955;SB - Activeer Spot +HISTORY_MSG_956;SB - CH-curve +HISTORY_MSG_957;SB - Ruisonderdrukking modus +HISTORY_MSG_958;SB - Toon/verberg instellingen +HISTORY_MSG_959;SB - Inverteer vervaging +HISTORY_MSG_960;SB - Log-codering - cat16 +HISTORY_MSG_961;SB - Log-codering Ciecam +HISTORY_MSG_962;SB - Log-codering Absolute luminantie bron +HISTORY_MSG_963;SB - Log-codering Absolute luminantie doel +HISTORY_MSG_964;SB - Log-codering Omgeving +HISTORY_MSG_965;SB - Log-codering Verzadiging s +HISTORY_MSG_966;SB - Log-codering Contrast J +HISTORY_MSG_967;SB - Log-codering masker curve C +HISTORY_MSG_968;SB - Log-codering masker curve L +HISTORY_MSG_969;SB - Log-codering masker curve H +HISTORY_MSG_970;SB - Log-codering masker geactiveerd +HISTORY_MSG_971;SB - Log-codering masker meng +HISTORY_MSG_972;SB - Log-codering masker straal +HISTORY_MSG_973;SB - Log-codering masker chroma +HISTORY_MSG_974;SB - Log-codering masker contrast +HISTORY_MSG_975;SB - Log-codering Lichtheid J +HISTORY_MSG_977;SB - Log-codering Contrast Q +HISTORY_MSG_978;SB - Log-codering Sursource +HISTORY_MSG_979;SB - Log-codering Helderheid Q +HISTORY_MSG_980;SB - Log-codering Kleurrijkheid M +HISTORY_MSG_981;SB - Log-codering Kracht +HISTORY_MSG_982;SB - Equalizer tint +HISTORY_MSG_983;SB - Ruisonderdrukking drempel masker hoog +HISTORY_MSG_984;SB - Ruisonderdrukking drempel masker laag +HISTORY_MSG_985;SB - Ruisonderdrukking Laplacian +HISTORY_MSG_986;SB - Ruisonderdrukking versterk +HISTORY_MSG_987;SB - GF herstel drempel +HISTORY_MSG_988;SB - GF drempel masker laag +HISTORY_MSG_989;SB - GF drempel masker hoog +HISTORY_MSG_990;SB - Ruisonderdrukking herstel drempel +HISTORY_MSG_991;SB - Ruisonderdrukking drempel masker laag +HISTORY_MSG_992;SB - Ruisonderdrukking drempel masker hoog +HISTORY_MSG_993;SB - Ruisonderdrukking Omgekeerd algo +HISTORY_MSG_994;SB - GF Omgekeerd algo +HISTORY_MSG_995;SB - Ruisonderdrukking verval +HISTORY_MSG_996;SB - Kleurherstel drempel +HISTORY_MSG_997;SB - Kleurherstel masker laag +HISTORY_MSG_998;SB - Kleur drempel masker hoog +HISTORY_MSG_999;SB - Kleur verval +HISTORY_MSG_1000;SB - Ruisonderdrukking luminantie grijs +HISTORY_MSG_1001;SB - Log herstel drempel +HISTORY_MSG_1002;SB - Log drempel masker laag +HISTORY_MSG_1003;SB - Log drempel masker hoog +HISTORY_MSG_1004;SB - Log verval +HISTORY_MSG_1005;SB - Bel. herstel drempel +HISTORY_MSG_1006;SB - Bel. drempel masker laag +HISTORY_MSG_1007;SB - Bel. drempel masker hoog +HISTORY_MSG_1008;SB - Bel. verval +HISTORY_MSG_1009;SB - SH herstel drempel +HISTORY_MSG_1010;SB - SH drempel masker laag +HISTORY_MSG_1011;SB - SH drempel masker hoog +HISTORY_MSG_1012;SB - SH verval +HISTORY_MSG_1013;SB - lev. herstel drempel +HISTORY_MSG_1014;SB - lev. drempel masker laag +HISTORY_MSG_1015;SB - lev. drempel masker hoog +HISTORY_MSG_1016;SB - lev. verval +HISTORY_MSG_1017;SB - lc herstel drempel +HISTORY_MSG_1018;SB - lc drempel masker laag +HISTORY_MSG_1019;SB - lc drempel masker hoog +HISTORY_MSG_1020;SB - lc verval +HISTORY_MSG_1021;SB - Ruisonderdrukking chrominantie grijs +HISTORY_MSG_1022;SB - TM herstel drempel +HISTORY_MSG_1023;SB - TM drempel masker laag +HISTORY_MSG_1024;SB - TM drempel masker hoog +HISTORY_MSG_1025;SB - TM verval +HISTORY_MSG_1026;SB - cbdl herstel drempel +HISTORY_MSG_1027;SB - cbdl drempel masker laag +HISTORY_MSG_1028;SB - cbdl drempel masker hoog +HISTORY_MSG_1029;SB - cbdl verval +HISTORY_MSG_1030;SB - reti herstel drempel +HISTORY_MSG_1031;SB - reti drempel masker laag +HISTORY_MSG_1032;SB - reti drempel masker hoog +HISTORY_MSG_1033;SB - reti verval +HISTORY_MSG_1034;SB - Nlmeans - kracht +HISTORY_MSG_1035;SB - Nlmeans - detail +HISTORY_MSG_1036;SB - Nlmeans - patch +HISTORY_MSG_1037;SB - Nlmeans - straal +HISTORY_MSG_1038;SB - Nlmeans - gamma +HISTORY_MSG_1039;SB - Korrel - gamma +HISTORY_MSG_1040;SB - SC - Verzachtingsstraal +HISTORY_MSG_1041;SB - Spot - Munsell +HISTORY_MSG_1042;SB - Log-codring - drempel +HISTORY_MSG_1043;SB - Bel. - normaliseer +HISTORY_MSG_1044;SB - LA contrast kracht +HISTORY_MSG_1045;SB - Kleur en Licht kracht +HISTORY_MSG_1046;SB - Ruisonderdrukking kracht +HISTORY_MSG_1047;SB - SH en Toonequalizer kracht +HISTORY_MSG_1048;SB - DR en Belichting kracht +HISTORY_MSG_1049;SB - TM kracht +HISTORY_MSG_1050;SB - Log-codering chroma +HISTORY_MSG_1051;SB - residueel wavelet gamma +HISTORY_MSG_1052;SB - residueel wavelet helling +HISTORY_MSG_1053;SB - ruisonderdrukking gamma +HISTORY_MSG_1054;SB - Wavelet gamma +HISTORY_MSG_1055;SB - Kleur en Licht gamma +HISTORY_MSG_1056;SB - DR en Belichting gamma +HISTORY_MSG_1057;SB - CIECAM Geactiveerd +HISTORY_MSG_1058;SB - CIECAM Overall kracht +HISTORY_MSG_1059;SB - CIECAM Autogrijs +HISTORY_MSG_1060;SB - CIECAM Gemiddelde luminantie bron +HISTORY_MSG_1061;SB - CIECAM bron absoluut +HISTORY_MSG_1062;SB - CIECAM omgeving bron +HISTORY_MSG_1063;SB - CIECAM verzadiging +HISTORY_MSG_1064;SB - CIECAM Chroma +HISTORY_MSG_1065;SB - CIECAM lichtheid J +HISTORY_MSG_1066;SB - CIECAM helderheid +HISTORY_MSG_1067;SB - CIECAM Contrast J +HISTORY_MSG_1068;SB - CIECAM drempel +HISTORY_MSG_1069;SB - CIECAM contrast Q +HISTORY_MSG_1070;SB - CIECAM kleurrijkheid +HISTORY_MSG_1071;SB - CIECAM Absolute luminantie +HISTORY_MSG_1072;SB - CIECAM Gemiddelde luminantie +HISTORY_MSG_1073;SB - CIECAM Cat16 +HISTORY_MSG_1074;SB - CIECAM LA contrast +HISTORY_MSG_1075;SB - CIECAM kijkomgeving +HISTORY_MSG_1076;SB - CIECAM bereik +HISTORY_MSG_1077;SB - CIECAM modus +HISTORY_MSG_1078;SB - Rood/huidbescherming +HISTORY_MSG_1079;SB - CIECAM Sigmoid kracht J +HISTORY_MSG_1080;SB - CIECAM Sigmoid drempel +HISTORY_MSG_1081;SB - CIECAM Sigmoid meng +HISTORY_MSG_1082;SB - CIECAM Sigmoid Q BlackEv WhiteEv +HISTORY_MSG_1083;SB - CIECAM tint +HISTORY_MSG_1084;SB - Gebruikt Zwart LW - Wit LW +HISTORY_MSG_1085;SB - Jz lichtheid +HISTORY_MSG_1086;SB - Jz contrast +HISTORY_MSG_1087;SB - Jz chroma +HISTORY_MSG_1088;SB - Jz tint +HISTORY_MSG_1089;SB - Jz Sigmoid kracht +HISTORY_MSG_1090;SB - Jz Sigmoid drempel +HISTORY_MSG_1091;SB - Jz Sigmoid meng +HISTORY_MSG_1092;SB - Jz aanpassing +HISTORY_MSG_1093;SB - CAM model +HISTORY_MSG_1094;SB - Jz hoge lichten +HISTORY_MSG_1095;SB - Jz hoge lichten thr +HISTORY_MSG_1096;SB - Jz schaduwen +HISTORY_MSG_1097;SB - Jz schaduwen thr +HISTORY_MSG_1098;SB - Jz straal SH +HISTORY_MSG_1099;SB - Cz(Hz) Curve +HISTORY_MSG_1100;SB - Jz referentie 100 +HISTORY_MSG_1101;SB - Jz PQ remap +HISTORY_MSG_1102;SB - Jz(Hz) Curve +HISTORY_MSG_1103;SB - Levendigheid gamma +HISTORY_MSG_1104;SB - Scherp gamma +HISTORY_MSG_1105;SB - CIECAM Toon methode +HISTORY_MSG_1106;SB - CIECAM Toon curve +HISTORY_MSG_1107;SB - CIECAM Kleur methode +HISTORY_MSG_1108;SB - CIECAM Kleur curve +HISTORY_MSG_1109;SB - Jz(Jz) curve +HISTORY_MSG_1110;SB - Cz(Cz) curve +HISTORY_MSG_1111;SB - Cz(Jz) curve +HISTORY_MSG_1112;SB - forcejz +HISTORY_MSG_1113;SB - HDR PQ +HISTORY_MSG_1114;SB - Cie masker activeer +HISTORY_MSG_1115;SB - Cie masker curve C +HISTORY_MSG_1116;SB - Cie masker curve L +HISTORY_MSG_1117;SB - Cie masker curve H +HISTORY_MSG_1118;SB - Cie masker meng +HISTORY_MSG_1119;SB - Cie masker straal +HISTORY_MSG_1120;SB - Cie masker chroma +HISTORY_MSG_1121;SB - Cie masker contrast curve +HISTORY_MSG_1122;SB - Cie masker herstel drempel +HISTORY_MSG_1123;SB - Cie masker herstel donker +HISTORY_MSG_1124;SB - Cie masker herstel licht +HISTORY_MSG_1125;SB - Cie masker herstel verval +HISTORY_MSG_1126;SB - Cie masker laplacian +HISTORY_MSG_1127;SB - Cie masker gamma +HISTORY_MSG_1128;SB - Cie masker helling +HISTORY_MSG_1129;SB - Cie Relatieve luminantie +HISTORY_MSG_1130;SB - Cie Verzadiging Jz +HISTORY_MSG_1131;SB - masker - Ruisvermindering +HISTORY_MSG_1132;SB - Cie Wav sigma Jz +HISTORY_MSG_1133;SB - Cie Wav level Jz +HISTORY_MSG_1134;SB - Cie Wav LA contrast Jz +HISTORY_MSG_1135;SB - Cie Wav klaarheid Jz +HISTORY_MSG_1136;SB - Cie Wav klaarheid Cz +HISTORY_MSG_1137;SB - Cie Wav klaarheid Zacht +HISTORY_MSG_1138;SB - SB - Hz(Hz) Curve +HISTORY_MSG_1139;SB - Jz zacht Curven H +HISTORY_MSG_1140;SB - Jz Drempel chroma +HISTORY_MSG_1141;SB - chroma curve Jz(Hz) +HISTORY_MSG_1142;SB - kracht zacht +HISTORY_MSG_1143;SB - Jz blackev +HISTORY_MSG_1144;SB - Jz whiteev +HISTORY_MSG_1145;SB - Jz Log-codering +HISTORY_MSG_1146;SB - Jz Log-codering doel grijs +HISTORY_MSG_1147;SB - Jz BlackEv WhiteEv +HISTORY_MSG_1148;SB - Jz Sigmoid +HISTORY_MSG_1149;SB - Q Sigmoid +HISTORY_MSG_1150;SB - Log-codering Q in plaats van Sigmoid Q HISTORY_MSG_BLSHAPE;Vervaag per niveau HISTORY_MSG_BLURCWAV;Vervaging chroma HISTORY_MSG_BLURWAV;Vervaging luminantie @@ -1424,16 +1427,23 @@ HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy HISTORY_MSG_ICM_AINTENT;Abstract profiel - weergave-intentie HISTORY_MSG_ICM_BLUX;Primair blauw X HISTORY_MSG_ICM_BLUY;Primair blauw Y +HISTORY_MSG_ICM_CAT;Matrix-aanpassing HISTORY_MSG_ICM_FBW;Zwart en wit HISTORY_MSG_ICM_GAMUT;Beperk kleurbereik HISTORY_MSG_ICM_GREX;Primair groen X HISTORY_MSG_ICM_GREY;Primair groen Y +HISTORY_MSG_ICM_MIDTCIE;Middentonen HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaire kleuren HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 illuminant D HISTORY_MSG_ICM_OUTPUT_TYPE;Uitvoer - Type HISTORY_MSG_ICM_PRESER;Behoud neutraal HISTORY_MSG_ICM_REDX;Primair rood X HISTORY_MSG_ICM_REDY;Primair rood Y +HISTORY_MSG_ICM_REFI;Kleurverfijning +HISTORY_MSG_ICM_SHIFTX;Kleurverfijning - Verschuif x +HISTORY_MSG_ICM_SHIFTY;Kleurverfijning - Verschuif y +HISTORY_MSG_ICM_SMOOTHCIE;Vloeiende hoge lichten +HISTORY_MSG_ICM_TRCEXP;Abstract Profiel HISTORY_MSG_ICM_WORKING_GAMMA;Werkend - Gamma HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;Methode lichtsterkte HISTORY_MSG_ICM_WORKING_PRIM_METHOD;Methode primaire kleuren @@ -1446,7 +1456,9 @@ HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokaal Contrast HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokaal Contrast - Licht HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokaal Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Lokaal - draaipunt Equalizer +HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Beperk verzadiging HISTORY_MSG_LOCAL_GAMUTMUNSEL;Lokaal - SC - Voorkom kleurverschuiving +HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Beperk verzadiging HISTORY_MSG_METADATA_MODE;Metadata kopieermodus HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrastdrempel HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto-drempel @@ -1695,8 +1707,8 @@ MAIN_TAB_FAVORITES_TOOLTIP;Sneltoets: Alt+U MAIN_TAB_FILTER;Filter MAIN_TAB_INSPECT; Inspecteer MAIN_TAB_IPTC;IPTC -MAIN_TAB_LOCALLAB;Lokale aanpassingen -MAIN_TAB_LOCALLAB_TOOLTIP;Shortcut: Alt+O +MAIN_TAB_LOCALLAB;Selectief bewerken +MAIN_TAB_LOCALLAB_TOOLTIP;Sneltoets: Alt+O MAIN_TAB_METADATA;Metadata MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt+M MAIN_TAB_RAW;RAW @@ -1782,8 +1794,8 @@ PARTIALPASTE_LABCURVE;LAB-curve PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen PARTIALPASTE_LENSPROFILE;Lenscorrectieprofiel PARTIALPASTE_LOCALCONTRAST;Lokaal contrast -PARTIALPASTE_LOCALLAB;Lokale aanpassingen -PARTIALPASTE_LOCALLABGROUP;Instellingen Lokale aanpassingen +PARTIALPASTE_LOCALLAB;Selectief bewerken +PARTIALPASTE_LOCALLABGROUP;Instellingen Selectief bewerken PARTIALPASTE_METADATA;Metadata modus PARTIALPASTE_METAGROUP;Metadata PARTIALPASTE_PCVIGNETTE;Vignetteringsfilter @@ -1840,6 +1852,9 @@ PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen-modus.\nWij PREFERENCES_BEHAVIOR;Gedrag PREFERENCES_BEHSETALL;Alles op 'Activeer' PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer-modus.\nWijzigingen van de parameters voor groepsverwerking zijn absoluut. De actuele waarden worden gebruikt. +PREFERENCES_BROWSERECURSIVEDEPTH;Diepte sub-folders +PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Volg symbolische links in sub-folders +PREFERENCES_BROWSERECURSIVEMAXDIRS;Max. aantal sub-folders PREFERENCES_CACHECLEAR;Wissen PREFERENCES_CACHECLEAR_ALL;Wis alle bestanden in de cache: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Wis alle bestanden in de cache behalve verwerkingsprofielen: @@ -1862,7 +1877,7 @@ PREFERENCES_CLUTSCACHE;HaldCLUT-cache PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cluts in de cache PREFERENCES_CLUTSDIR;HaldCLUT-map PREFERENCES_CMMBPC;Zwartpuntcompensatie -PREFERENCES_COMPLEXITYLOC;Standaard complexiteit voor Lokale Aanpassingen +PREFERENCES_COMPLEXITYLOC;Standaard complexiteit voor Selectief bewerken PREFERENCES_COMPLEXITY_EXP;Geavanceerd PREFERENCES_COMPLEXITY_NORM;Standaard PREFERENCES_COMPLEXITY_SIMP;Basis @@ -1901,7 +1916,7 @@ PREFERENCES_EXTEDITOR_BYPASS_OUTPUT_PROFILE;Passeer uitvoerprofiel PREFERENCES_EXTEDITOR_DIR;Uitvoermap PREFERENCES_EXTEDITOR_DIR_CURRENT;Zelfde als invoerbeeld PREFERENCES_EXTEDITOR_DIR_CUSTOM;Aangepast -PREFERENCES_EXTEDITOR_DIR_TEMP;temp map dir besturingssysteem +PREFERENCES_EXTEDITOR_DIR_TEMP;Tmp-map besturingssysteem PREFERENCES_EXTEDITOR_FLOAT32;32-bit decimale TIFF_uitvoer PREFERENCES_EXTERNALEDITOR;Externe editor PREFERENCES_EXTERNALEDITOR_CHANGE;Verander applicatie @@ -1941,6 +1956,7 @@ PREFERENCES_LENSFUNDBDIR_TOOLTIP;Map met de Lensfun-database. Laat leeg om de st PREFERENCES_LENSPROFILESDIR;Map met lensprofielen PREFERENCES_LENSPROFILESDIR_TOOLTIP;Map met Adobe Lens Correction Profiles (LCP's) PREFERENCES_MAXRECENTFOLDERS;Maximum aantal recente mappen +PREFERENCES_MAX_ZOOM_TITLE;Maximale zoom PREFERENCES_MENUGROUPEXTPROGS;Groepeer open met PREFERENCES_MENUGROUPFILEOPERATIONS;Groepeer bestandsbewerkingen PREFERENCES_MENUGROUPLABEL;Groepeer labelen @@ -1977,7 +1993,7 @@ PREFERENCES_PREVDEMO;Voorbeeld demozaïekmethode PREFERENCES_PREVDEMO_FAST;Snel PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: PREFERENCES_PREVDEMO_SIDECAR;Gelijk aan PP3 -PREFERENCES_PRINTER;Printer (soft-proof) +PREFERENCES_PRINTER;Printer (soft-proofing) PREFERENCES_PROFILEHANDLING;Verwerking profielen PREFERENCES_PROFILELOADPR;Laadprioriteit profielen PREFERENCES_PROFILEPRCACHE;Profiel in cache @@ -1991,6 +2007,8 @@ PREFERENCES_PROPERTY;Eigenschap PREFERENCES_PRTINTENT;Weergave-intentie PREFERENCES_PRTPROFILE;Kleurprofiel PREFERENCES_PSPATH;Installatiemap Adobe Photoshop +PREFERENCES_RAW_DECODER;Raw-decoder +PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Gebruik LibRaw PREFERENCES_REMEMBERZOOMPAN;Onthoud zoom% en pan-startpunt PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Onthoud het zoompercentage en pan-startpunt van de huidige afbeelding als er een nieuwe afbeelding wordt geopend.\n\nDeze optie werkt alleen in Enkeltab-modus en wanneer "Demozaïekmethode van het voorbeeld <100% zoom" hetzelfde is als "Gelijk aan PP3". PREFERENCES_SAVE_TP_OPEN_NOW;Bewaar open/dicht-status van de gereedschappen nu @@ -2003,7 +2021,7 @@ PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info PREFERENCES_SHOWDATETIME;Toon datum en tijd PREFERENCES_SHOWEXPOSURECOMPENSATION;Toon belichtingscompensatie PREFERENCES_SHOWFILMSTRIPTOOLBAR;Toon filmstrip werkbalk -PREFERENCES_SHOWTOOLTIP;Toon schermtips voor Lokale aanpassingen +PREFERENCES_SHOWTOOLTIP;Toon schermtips voor Selectief bewerken PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting PREFERENCES_SINGLETAB;Enkel-tab: foto's openen in zelfde tabvenster PREFERENCES_SINGLETABVERTAB;Enkel-tab ('filmstrip') modus met verticale tabs @@ -2011,6 +2029,7 @@ PREFERENCES_SND_HELP;Typ bestandsnaam (of niets: geen geluid).\nWindows: gebruik PREFERENCES_SND_LNGEDITPROCDONE;Bewerking klaar PREFERENCES_SND_QUEUEDONE;Verwerkingsrij klaar PREFERENCES_SND_THRESHOLDSECS;na seconden +PREFERENCES_SPOTLOC;Bepaal spotmethode voor Selectief bewerken PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten PREFERENCES_TAB_BROWSER;Bestandsnavigator PREFERENCES_TAB_COLORMGR;Kleurbeheer @@ -2024,6 +2043,7 @@ PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Ingesloten JPEG-voorbeeld PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Te tonen foto PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrale raw-rendering PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Ingesloten JPEG indien vol formaat, anders neutrale raw +PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Laad/bewaar waardering en kleurcodes van miniaturen van/naar XMP-zijspanbestanden PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Beschikbare gereedschappen PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Toon favoriete gereedschappen ook op hun oorspronkelijke locatie PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Indien aangevinkt zullen de favoriete gereedschappen zowel in de Favorieten-tab als op hun oorspronkelijke locatie te vinden zijn.\n\nOpmerking: als deze optie is aangevinkt kunt u een lichte vertraging verwachten tijdens het wisselen van tabs. @@ -2097,6 +2117,8 @@ QINFO_PIXELSHIFT;Pixel-Shift / %2 frame(s) QUEUE_AUTOSTART;Autostart QUEUE_AUTOSTART_TOOLTIP;Start verwerking automatisch wanneer nieuwe foto arriveert QUEUE_DESTFILENAME;Pad en bestandsnaam +QUEUE_DESTPREVIEW_TITLE;Selecteer een miniatuur om het bestemmingspad te zien +QUEUE_DESTPREVIEW_TOOLTIP;Bestemmingspad van de eerst geselecteerde foto verschijnt hier QUEUE_FORMAT_TITLE;Bestandstype QUEUE_LOCATION_FOLDER;Sla op in map QUEUE_LOCATION_TEMPLATE;Gebruik sjabloon @@ -2139,12 +2161,15 @@ SORT_BY_LABEL;Op kleurlabel SORT_BY_NAME;Op naam SORT_BY_RANK;Volgens sterwaardering SORT_DESCENDING;Aflopend +TC_LOCALLAB_PRIM_SHIFTX;Verschuif x +TC_LOCALLAB_PRIM_SHIFTY;Verschuif y TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By TC_PRIM_GREX;Gx TC_PRIM_GREY;Gy TC_PRIM_REDX;Rx TC_PRIM_REDY;Ry +TC_PRIM_REFI;Verfijn kleuren (witpunt) THRESHOLDSELECTOR_B;Onderkant THRESHOLDSELECTOR_BL;Onderkant-links THRESHOLDSELECTOR_BR;Onderkant-rechts @@ -2155,6 +2180,7 @@ THRESHOLDSELECTOR_TR;Bovenkant-rechts TOOLBAR_TOOLTIP_COLORPICKER;Vergrendelbare kleurkiezer\n\nKlik met de linkermuisknop in het voorbeeld om een kleurkiezer toe te voegen\nBeweeg het punt door de linkermuisknop ingedrukt te houden\nVerwijder de kleurkiezer met rechts-klik\nVerwijder alle kleurkiezers met Shift+rechtsklik\nMet een rechtermuisklik naast een kleurkiezer komt het selectiehandje terug. TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: C TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: H +TOOLBAR_TOOLTIP_PERSPECTIVE;Perspectiefcorrectie\n\nVerplaats de controlelijnen om perspectivische vervorming te corrigeren. Klik opnieuw op deze knop om de correctie toe te passen. TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtzetten/Kleine rotaties.\nSneltoets: S\n\nBepaal de verticale of horizontale as door een hulplijn over de afbeelding te trekken. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: W TP_BWMIX_ALGO;Algoritme OYCPM @@ -2228,7 +2254,7 @@ TP_CHMIXER_LABEL;Kleurkanaalmixer TP_CHMIXER_RED;Rood TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen TP_COARSETRAF_TOOLTIP_ROTLEFT;Roteer links.\n\nSneltoets:\n[ - Multitab-modus,\nAlt+[ - Enkeltab-modus. -TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Roteer rechts.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminantie TP_COLORAPP_ALGO;Algoritme @@ -2263,7 +2289,7 @@ TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM-wij TP_COLORAPP_CURVEEDITOR2;Tooncurve 2 TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings-tooncurve 2. TP_COLORAPP_CURVEEDITOR3;Chroma-curve -TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. TP_COLORAPP_DATACIE;CIECAM02 uitvoerhistogram in de curven TP_COLORAPP_DATACIE_TOOLTIP;Indien aangevinkt tonen de histogrammen van de CIECAM02-curven bij benadering de waarden/reeksen voor J of Q, en C, S of M na de CIECAM02-aanpassingen.\nDit heeft geen invloed op het hoofdhistogram.\n\nIndien uitgevinkt tonen de histogrammen van de CIECAM02-curven de Lab-waarden zoals deze waren voor de CIECAM02-aanpassingen TP_COLORAPP_FREE;Vrije temp + groen + CAT02 + [uitvoer] @@ -2282,16 +2308,16 @@ TP_COLORAPP_ILFREE;Vrij TP_COLORAPP_ILLUM;Illuminant TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen -TP_COLORAPP_LABEL_SCENE;Scène-omstandigheden +TP_COLORAPP_LABEL_SCENE;Opname-omstandigheden TP_COLORAPP_LABEL_VIEWING;Weergaveomstandigheden TP_COLORAPP_LIGHT;Lichtheid (J) -TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB +TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB TP_COLORAPP_MEANLUMINANCE;Gemiddelde luminantie (Yb%) TP_COLORAPP_MOD02;CAM02 TP_COLORAPP_MOD16;CAM16 TP_COLORAPP_MODEL;Witpuntmodel TP_COLORAPP_MODELCAT;CAM -TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. +TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. TP_COLORAPP_NEUTRAL;Terugzetten TP_COLORAPP_NEUTRAL_TOOLTIP;Zet alle regelaars, vinkjes en curves terug naar hun standaardwaarde TP_COLORAPP_RSTPRO;Bescherming huid- en rode tinten @@ -2580,6 +2606,7 @@ TP_ICM_APPLYHUESATMAP_TOOLTIP;Gebruik de ingebedde DCP-basistabel (HueSatMap). D TP_ICM_APPLYLOOKTABLE;DCP-look-tabel TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP-look-tabel. De instelling is alleen actief als de DCP een look-tabel heeft. TP_ICM_BPC;Zwartpuntcompensatie +TP_ICM_BW;Zwart en Wit TP_ICM_DCPILLUMINANT;Illuminant TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. @@ -2613,6 +2640,12 @@ TP_ICM_TONECURVE;Gebruik DCP-tooncurve TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP-tooncurve. De instelling is alleen actief als de geselecteerde DCP een tooncurve bevat. TP_ICM_TRCFRAME;Abstract Profiel TP_ICM_WORKINGPROFILE;Werkprofiel +TP_ICM_WORKING_CAT;Aanpassing matrix +TP_ICM_WORKING_CAT_BRAD;Bradford +TP_ICM_WORKING_CAT_CAT02;Cat02 +TP_ICM_WORKING_CAT_CAT16;Cat16 +TP_ICM_WORKING_CAT_VK;Von Kries +TP_ICM_WORKING_CAT_XYZ;XYZ-schaal TP_ICM_WORKING_CIEDIAG;CIE xy diagram TP_ICM_WORKING_ILLU;Illuminant TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2688,7 +2721,7 @@ TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens Luminantie L=f(L) TP_LABCURVE_LABEL;Lab TP_LABCURVE_LCREDSK;Beperk LC tot huid- en rode tinten TP_LABCURVE_LCREDSK_TOOLTIP;Indien ingeschakeld beïnvloedt de LC-curve alleen huid- en rode tinten.\nIndien uitgeschakeld is het van toepassing op alle tinten. -TP_LABCURVE_RSTPROTECTION;Bescherming huid- en rode tinten +TP_LABCURVE_RSTPROTECTION;Bescherming huid- en rode tinten TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits-schuifbalk en de CC-curve. TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden TP_LENSGEOM_FILL;Automatisch uitvullen @@ -2744,12 +2777,14 @@ TP_LOCALLAB_BLURDE;Vormdetectie vervaging TP_LOCALLAB_BLURLC;Alleen luminantie TP_LOCALLAB_BLURLEVELFRA;Vervagingsniveaus TP_LOCALLAB_BLUR_TOOLNAME;Vervaging/Korrel & Ruisvermindering -TP_LOCALLAB_BLWH;Alle veranderingen forceren in Zwart-wit +TP_LOCALLAB_BLWH;Alle veranderingen forceren in zwart-wit TP_LOCALLAB_BUTTON_ADD;Voeg toe TP_LOCALLAB_BUTTON_DEL;Wis TP_LOCALLAB_BUTTON_DUPL;Dupliceer TP_LOCALLAB_BUTTON_REN;Hernoem TP_LOCALLAB_BUTTON_VIS;Toon/verberg +TP_LOCALLAB_BWEVNONE;Geen +TP_LOCALLAB_BWEVSIG;Geactiveerd TP_LOCALLAB_BWFORCE;Gebruik Zwart LW & Wit LW TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Piekluminantie) TP_LOCALLAB_CAM16_FRA;Cam16 Beeldaanpassingen @@ -2783,6 +2818,12 @@ TP_LOCALLAB_CIEMODE_DR;Dynamisch bereik TP_LOCALLAB_CIEMODE_TM;Toonmappen TP_LOCALLAB_CIEMODE_WAV;Wavelet TP_LOCALLAB_CIETOOLEXP;Curven +TP_LOCALLAB_CIE_SMOOTHFRAME;Versterking hoge lichten & Niveaus +TP_LOCALLAB_CIE_SMOOTH_EV;Gebaseerd op LW +TP_LOCALLAB_CIE_SMOOTH_GAMMA;Gebaseerd op helling +TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gebaseerd op gamma +TP_LOCALLAB_CIE_SMOOTH_LEVELS;Niveaus +TP_LOCALLAB_CIE_SMOOTH_NONE;Geen TP_LOCALLAB_CIE_TOOLNAME;Kleurweergave (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Spotgrootte TP_LOCALLAB_CLARICRES;Meng chroma @@ -2793,12 +2834,14 @@ TP_LOCALLAB_CLARITYML;Klaarheid (Clarity) TP_LOCALLAB_CLIPTM;Kap herstelde data af (versterking) TP_LOCALLAB_COFR;Kleur & Licht TP_LOCALLAB_COLORDE;ΔE Voorbeeldkleur - intensiteit +TP_LOCALLAB_COLORFRAME;Dominante kleur TP_LOCALLAB_COLORSCOPE;Bereik (kleurgereedschappen) TP_LOCALLAB_COLOR_CIE;Kleurcurve TP_LOCALLAB_COLOR_TOOLNAME;Kleur & Licht TP_LOCALLAB_COL_NAME;Naam TP_LOCALLAB_COL_VIS;Status TP_LOCALLAB_COMPFRA;Directioneel contrast +TP_LOCALLAB_COMPRCIE;Helderheidscompressie TP_LOCALLAB_COMPREFRA;Wavelet-niveau toonmappen TP_LOCALLAB_CONTCOL;Contrastdrempel TP_LOCALLAB_CONTFRA;Contrast per niveau @@ -2816,6 +2859,7 @@ TP_LOCALLAB_CURVNONE;De-activeer curven TP_LOCALLAB_DARKRETI;Donker TP_LOCALLAB_DEHAFRA;Ontnevelen TP_LOCALLAB_DEHAZ;Kracht +TP_LOCALLAB_DEHAZE_BLACK;Zwart TP_LOCALLAB_DELTAD;Delta-balans TP_LOCALLAB_DELTAEC;ΔE Beeldmasker TP_LOCALLAB_DENOI1_EXP;Ruisvermindering volgens luminantiemasker @@ -2829,6 +2873,7 @@ TP_LOCALLAB_DETAIL;Lokaal contrast TP_LOCALLAB_DETAILFRA;Randdetectie - DCT TP_LOCALLAB_DETAILSH;Details TP_LOCALLAB_DETAILTHR;Detaildrempel Lum/chrom +TP_LOCALLAB_DISAB_CIECAM;Schakel Ciecam of geringe Jz-omgeving uit TP_LOCALLAB_DIVGR;Gamma TP_LOCALLAB_DUPLSPOTNAME;Kopieer TP_LOCALLAB_EDGFRA;Randscherpte @@ -2837,11 +2882,12 @@ TP_LOCALLAB_ELI;Ellips TP_LOCALLAB_ENABLE_AFTER_MASK;Gebruik toonmappen TP_LOCALLAB_ENABLE_MASK;Activeer masker TP_LOCALLAB_ENABLE_MASKAFT;Gebruik alle algoritmen Belichting +TP_LOCALLAB_ENABLE_MASKALL;Gebruik alle maskergereedschappen TP_LOCALLAB_ENH;Verbeterd TP_LOCALLAB_ENHDEN;Verbeterd + chroma-ruisonderdrukking TP_LOCALLAB_EPSBL;Detail TP_LOCALLAB_EQUIL;Normaliseer luminantie -TP_LOCALLAB_ESTOP;Edge stopping +TP_LOCALLAB_ESTOP;Randbehoud TP_LOCALLAB_EV_DUPL;Kopie van TP_LOCALLAB_EV_NVIS;Verberg TP_LOCALLAB_EV_NVIS_ALL;Verberg allemaal @@ -2851,6 +2897,7 @@ TP_LOCALLAB_EXCLUF;Uitsluiting TP_LOCALLAB_EXCLUTYPE;Spotmethode TP_LOCALLAB_EXECLU;Sluit spot uit TP_LOCALLAB_EXFULL;Volledige afbeelding +TP_LOCALLAB_EXMAIN;Globaal TP_LOCALLAB_EXNORM;Normale spot TP_LOCALLAB_EXPCHROMA;Chroma-compensatie TP_LOCALLAB_EXPCOMP;Belichtingscompensatie Æ’ @@ -2866,11 +2913,14 @@ TP_LOCALLAB_FATANCHOR;Anker TP_LOCALLAB_FATDETAIL;Detail TP_LOCALLAB_FATFRA;Compressie dynamisch bereik Æ’ TP_LOCALLAB_FATLEVEL;Sigma +TP_LOCALLAB_FATSAT;Beperk verzadiging TP_LOCALLAB_FATSHFRA;Masker compressie dynamisch bereik Æ’ -TP_LOCALLAB_FEATVALUE;'Veer'verloop (Verloopfilters) +TP_LOCALLAB_FEATVALUE;Veerverloop (Verloopfilters) +TP_LOCALLAB_FEATVALUE_MASK;Veerverloop (Grad. Filters Masker) TP_LOCALLAB_FFTCOL_MASK;FFTW Æ’ TP_LOCALLAB_FFTW;Æ’ - Gebruik Fast Fourier-transformatie -TP_LOCALLAB_FFTWBLUR;Æ’ - Gebruik altijd Fast Fourier-transformatie +TP_LOCALLAB_FFTWBLUR;Æ’ - Gebruik altijd Fast Fourier-transformatie +TP_LOCALLAB_FULLIMAGE;Zwart LW en Wit LW voor volledige afbeelding TP_LOCALLAB_GAM;Gamma TP_LOCALLAB_GAMC;Gamma TP_LOCALLAB_GAMFRA;Toonresponscurve (TRC) @@ -2883,7 +2933,7 @@ TP_LOCALLAB_GAMUTNON;Geen TP_LOCALLAB_GAMUTXYZABSO;XYZ absoluut TP_LOCALLAB_GAMUTXYZRELA;XYZ relatief TP_LOCALLAB_GAMW;Gamma (wavelet-pyramiden) -TP_LOCALLAB_GRADANG;Hoek verloop +TP_LOCALLAB_GRADANG;Verloophoek TP_LOCALLAB_GRADFRA;Masker Verloopfilter TP_LOCALLAB_GRADLOGFRA;Verloopfilter - Luminantie TP_LOCALLAB_GRADSTR;Verloopsterkte @@ -2907,7 +2957,7 @@ TP_LOCALLAB_INVBL;Inverteer TP_LOCALLAB_INVERS;Inverteer TP_LOCALLAB_INVMASK;Keer algoritme om TP_LOCALLAB_ISOGR;Distributie (ISO) -TP_LOCALLAB_JAB;Gebruikt Zwart Ev & Wit Ev +TP_LOCALLAB_JAB;Gebruik Zwart LW & Wit LW TP_LOCALLAB_JZ100;Jz-referentie 100cd/m2 TP_LOCALLAB_JZADAP;PU-adaptatie TP_LOCALLAB_JZCH;Chroma @@ -2929,11 +2979,11 @@ TP_LOCALLAB_JZSAT;Verzadiging TP_LOCALLAB_JZSHFRA;Schaduwen/Hoge lichten Jz TP_LOCALLAB_JZSOFTCIE;Verzachtingsstraal (Begeleid filter) TP_LOCALLAB_JZSTRSOFTCIE;Kracht Begeleid filter -TP_LOCALLAB_JZTARGET_EV;Bezie gemiddelde luminantie (Yb%) +TP_LOCALLAB_JZTARGET_EV;Bekijk gemiddelde luminantie (Yb%) TP_LOCALLAB_JZTHRHCIE;Chroma-drempel voor Jz(Hz) TP_LOCALLAB_JZWAVEXP;Wavelet Jz TP_LOCALLAB_LABBLURM;Vervagingsmasker -TP_LOCALLAB_LABEL;Lokale aanpassingen +TP_LOCALLAB_LABEL;Selectief bewerken TP_LOCALLAB_LABGRID;Kleurcorrectierooster TP_LOCALLAB_LABGRIDMERG;Achtergrond TP_LOCALLAB_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 @@ -2962,16 +3012,18 @@ TP_LOCALLAB_LOG1FRA;CAM16 Beeldaanpassingen TP_LOCALLAB_LOG2FRA;Kijkomstandigheden TP_LOCALLAB_LOGAUTO;Automatisch TP_LOCALLAB_LOGCIE;Log-codering ipv. Sigmoid +TP_LOCALLAB_LOGCIEQ;Log-codering Q (met Ciecam) TP_LOCALLAB_LOGCOLORFL;Kleurrijkheid (M) TP_LOCALLAB_LOGCONQL;Contrast (Q) TP_LOCALLAB_LOGCONTHRES;Contrastdrempel (J & Q) TP_LOCALLAB_LOGCONTL;Contrast (J) TP_LOCALLAB_LOGEXP;Alle gereedschappen -TP_LOCALLAB_LOGFRA;Scène-omstandigheden +TP_LOCALLAB_LOGFRA;Opname-omstandigheden TP_LOCALLAB_LOGLIGHTL;Lichtheid (J) TP_LOCALLAB_LOGLIGHTQ;Helderheid (Q) TP_LOCALLAB_LOGLIN;Logaritmische modus TP_LOCALLAB_LOGPFRA;Relatieve Belichtingsniveaus +TP_LOCALLAB_LOGPFRA2;Log-codering - instellingen TP_LOCALLAB_LOGREPART;Overall kracht TP_LOCALLAB_LOG_TOOLNAME;Log-codering TP_LOCALLAB_LUM;LL - CC @@ -2985,16 +3037,18 @@ TP_LOCALLAB_MASFRAME;Masker en Combineer TP_LOCALLAB_MASK;Curven TP_LOCALLAB_MASK2;Contrastcurve TP_LOCALLAB_MASKCOM;Gemeenschappelijk Kleurmasker +TP_LOCALLAB_MASKCOM_TOOLNAME;Gemeenschappelijk kleurmasker TP_LOCALLAB_MASKDDECAY;Vervalsterkte TP_LOCALLAB_MASKH;Tintcurve -TP_LOCALLAB_MASKLCTHR;Lichte gebieden luminantiedrempel +TP_LOCALLAB_MASKLCTHR;Lichte gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHR2;Lichte gebieden luma-drempel TP_LOCALLAB_MASKLCTHRLOW;Donkere gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHRLOW2;Donkere gebieden luma-drempel TP_LOCALLAB_MASKLCTHRMID;Grijze gebieden luma-ruisvermindering +TP_LOCALLAB_MASKLCTHRMIDCH;Grijze gebieden chroma-ruisvermindering TP_LOCALLAB_MASKLNOISELOW;Versterk donkere/lichte gebieden TP_LOCALLAB_MASKRECOTHRES;Hersteldrempel -TP_LOCALLAB_MASKUNUSABLE;Masker uitgeschakeld (Masker & modificaties) +TP_LOCALLAB_MASKUNUSABLE;Masker uitgeschakeld (zie Masker & modificaties) TP_LOCALLAB_MASKUSABLE;Masker ingeschakeld (Masker & modificaties) TP_LOCALLAB_MEDIAN;Mediaan Laag TP_LOCALLAB_MEDNONE;Geen @@ -3023,6 +3077,7 @@ TP_LOCALLAB_MERTHI;Brand kleur TP_LOCALLAB_MERTHR;Verschil TP_LOCALLAB_MERTWE;Uitsluiting TP_LOCALLAB_MERTWO;Aftrekken +TP_LOCALLAB_MIDTCIE;Middentonen TP_LOCALLAB_MLABEL;Herstelde data Min=%1 Max=%2 TP_LOCALLAB_MODE_EXPERT;Geavanceerd TP_LOCALLAB_MODE_NORMAL;Standaard @@ -3062,6 +3117,7 @@ TP_LOCALLAB_PDEFRA;Contrastversterker Æ’ TP_LOCALLAB_PREVHIDE;Verberg extra instellingen TP_LOCALLAB_PREVIEW;Voorbeeld ΔE TP_LOCALLAB_PREVSHOW;Toon extra instellingen +TP_LOCALLAB_PRIMILLFRAME;Primaire kleuren & Illuminant TP_LOCALLAB_PROXI;ΔE-verval TP_LOCALLAB_QUAAGRES;Aggressief TP_LOCALLAB_QUACONSER;Conservatief @@ -3093,11 +3149,13 @@ TP_LOCALLAB_REWEI;Herhaling herweging TP_LOCALLAB_RGB;RGB-tooncurve TP_LOCALLAB_ROW_NVIS;Niet zichtbaar TP_LOCALLAB_ROW_VIS;Zichtbaar +TP_LOCALLAB_SATCIE;Beperk verzadiging TP_LOCALLAB_SATUR;Verzadiging TP_LOCALLAB_SATURV;Verzadiging (s) TP_LOCALLAB_SCALEGR;Schaal TP_LOCALLAB_SCALERETI;Schaal TP_LOCALLAB_SCALTM;Schaal +TP_LOCALLAB_SCOPEMASK;Bereik (ΔE beeldmasker) TP_LOCALLAB_SENSI;Bereik TP_LOCALLAB_SENSIEXCLU;Bereik TP_LOCALLAB_SETTINGS;Instellingen @@ -3107,7 +3165,7 @@ TP_LOCALLAB_SHADEX;Schaduwen TP_LOCALLAB_SHADEXCOMP;Schaduwcompressie TP_LOCALLAB_SHADHIGH;Schaduwen/hoge lichten & Toonequalizer TP_LOCALLAB_SHAMASKCOL;Schaduwen -TP_LOCALLAB_SHAPETYPE;Spot-vorm +TP_LOCALLAB_SHAPETYPE;Spotvorm TP_LOCALLAB_SHARAMOUNT;Hoeveelheid TP_LOCALLAB_SHARBLUR;Vervagingsradius TP_LOCALLAB_SHARDAMPING;Demping @@ -3117,7 +3175,7 @@ TP_LOCALLAB_SHARP;Schaduwen TP_LOCALLAB_SHARP_TOOLNAME;Schaduwen TP_LOCALLAB_SHARRADIUS;Straal TP_LOCALLAB_SHORTC;Korte curves L-masker -TP_LOCALLAB_SHOWC;Masker en modificaties +TP_LOCALLAB_SHOWC;Masker & modificaties TP_LOCALLAB_SHOWC1;Voeg bestand samen TP_LOCALLAB_SHOWCB;Masker en modificaties TP_LOCALLAB_SHOWDCT;Toon Fourier (Æ’) proces @@ -3145,15 +3203,29 @@ TP_LOCALLAB_SHOWT;Masker en modificaties TP_LOCALLAB_SHOWVI;Masker en modificaties TP_LOCALLAB_SHRESFRA;Schaduwen/Hoge lichten & TRC TP_LOCALLAB_SH_TOOLNAME;Schaduwen/Hoge lichten & Toonequalizer +TP_LOCALLAB_SIGBLACKSSCIE;Zwartdistributie TP_LOCALLAB_SIGFRA;Sigmoid Q & Log-codering Q TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Versterkingsrespons TP_LOCALLAB_SIGMOIDBL;Samenvoegen TP_LOCALLAB_SIGMOIDLAMBDA;Contrast -TP_LOCALLAB_SIGMOIDQJ;Gebruikt Zwart Ev & Wit Ev +TP_LOCALLAB_SIGMOIDNORMCIE;Normaliseer Luminantie +TP_LOCALLAB_SIGMOIDQJ;Gebruikt Zwart LW & Wit LW +TP_LOCALLAB_SIGMOIDSENSI;Aanpasbaarheid TP_LOCALLAB_SIGMOIDTH;Drempel (Grijspunt) +TP_LOCALLAB_SIGSLOPJCIE;Helling +TP_LOCALLAB_SIGTRCCIE;Aanpassingen brondata +TP_LOCALLAB_SIGWHITESCIE;Witdistributie TP_LOCALLAB_SLOMASKCOL;Helling +TP_LOCALLAB_SLOPESMOOTH;Grijsbalans (Helling) +TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Helling) +TP_LOCALLAB_SLOPESMOOTHG;Green balance (Helling) +TP_LOCALLAB_SLOPESMOOTHR;Roodbalans (Helling) TP_LOCALLAB_SLOSH;Helling +TP_LOCALLAB_SMOOTHCIE;Versterking hoge lichten +TP_LOCALLAB_SMOOTHCIE_LUM;Luminositeitsmodus +TP_LOCALLAB_SMOOTHCIE_SCA;Schaal Yb-Scène +TP_LOCALLAB_SMOOTHCIE_YB;Schaal Yb-Viewing TP_LOCALLAB_SOFT;Zacht licht & Originele Retinex TP_LOCALLAB_SOFTM;Zacht licht TP_LOCALLAB_SOFTRADIUSCOL;Radius verzachting @@ -3171,12 +3243,13 @@ TP_LOCALLAB_STREN;Compressiesterkte TP_LOCALLAB_STRENG;Kracht TP_LOCALLAB_STRENGR;Kracht TP_LOCALLAB_STRENGTH;Ruis +TP_LOCALLAB_STRENGTHCIELOG;Kracht TP_LOCALLAB_STRGRID;Kracht TP_LOCALLAB_STRUC;Structuur TP_LOCALLAB_STRUCCOL;Spotstructuur TP_LOCALLAB_STRUCCOL1;Spotstructuur -TP_LOCALLAB_STRUMASKCOL;Kracht qstructuurmasker -TP_LOCALLAB_STYPE;Vorm Shape methode +TP_LOCALLAB_STRUMASKCOL;Kracht structuurmasker +TP_LOCALLAB_STYPE;Vorm - methode TP_LOCALLAB_SYM;Symmetrisch (muis) TP_LOCALLAB_SYMSL;Symmetrisch (muis + schuiven) TP_LOCALLAB_TARGET_GRAY;Gemiddelde luminantie (Yb%) @@ -3198,6 +3271,7 @@ TP_LOCALLAB_TRANSITVALUE;Transitiewaarde TP_LOCALLAB_TRANSITWEAK;Transitieverval (lineair-log) TP_LOCALLAB_TRANSMISSIONGAIN;Transmissieversterking TP_LOCALLAB_TRANSMISSIONMAP;Transmissiemap +TP_LOCALLAB_TRCFRAME;Toonresponscurve (TRC) & Middentonen TP_LOCALLAB_USEMASK;Laplacian TP_LOCALLAB_VART;Variantie (contrast) TP_LOCALLAB_VIBRANCE;Levendigheid & Warm/Koel @@ -3213,7 +3287,7 @@ TP_LOCALLAB_WAVEDG;Lokaal contrast TP_LOCALLAB_WAVLEV;Vervaag per niveau TP_LOCALLAB_WAVMASK;Lokaal contrast TP_LOCALLAB_WEDIANHI;Mediaan Hi -TP_LOCALLAB_WHITE_EV;Wit Ev +TP_LOCALLAB_WHITE_EV;Wit LW TP_LOCALLAB_ZCAMFRA;ZCAM Beeldaanpassingen TP_LOCALLAB_ZCAMTHRES;Haal hoge data op TP_LOCAL_HEIGHT;Onder @@ -3280,7 +3354,7 @@ TP_PRSHARPENING_LABEL;Verscherp na verkleinen TP_PRSHARPENING_TOOLTIP;Verscherp na verkleinen. Werkt alleen als verkleinen actief is en de methode 'Lanczos' is. Omdat verkleinen geen effect heeft op het voorbeeld, heeft 'post-verkleinen verscherping' ook geen effect op het voorbeeld. TP_RAWCACORR_AUTO;Automatische CA-correctie TP_RAWCACORR_AUTOIT;Herhalingen -TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische afwijkingen.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. +TP_RAWCACORR_AUTOIT_TOOLTIP;Deze schuif is alleen actief als Automatische CA-correctie is aangevinkt.\nAuto-correctie werkt conservatief en corrigeert meestal niet alle chromatische afwijkingen.\nOm de resterende CA te corrigeren, kunt u dit proces tot vijf keer herhalen.\nElke herhaling vermindert de CA van de vorige herhaling, maar gaat wel ten koste van extra rekentijd. TP_RAWCACORR_AVOIDCOLORSHIFT;Vermijd kleurverschuiving TP_RAWCACORR_CABLUE;Blauw TP_RAWCACORR_CARED;Rood @@ -3438,7 +3512,7 @@ TP_RETINEX_MEDIAN;Transmissiemediaan-filter TP_RETINEX_METHOD;Methode TP_RETINEX_METHOD_TOOLTIP;Laag: schaduwen ophelderen,\nUniform: gelijkmatig,\nHoog: versterk hoge lichten,\nHoge lichten: verwijder magenta in hoge lichten. TP_RETINEX_MLABEL;Teruggeplaatst sluiervrij Min=%1 Max=%2 -TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. +TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. TP_RETINEX_NEIGHBOR;Naburige pixels TP_RETINEX_NEUTRAL;Beginwaarde TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarde. @@ -3515,13 +3589,13 @@ TP_SHARPENMICRO_UNIFORMITY;Uniformiteit TP_SOFTLIGHT_LABEL;Zacht licht TP_SOFTLIGHT_STRENGTH;Sterkte TP_SPOT_COUNTLABEL;%1 punt(en) -TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte +TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte TP_SPOT_ENTRYCHANGED;Punt veranderd TP_SPOT_HINT;Klik op deze button... Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. TP_SPOT_LABEL;Verwijder vlekken TP_TM_FATTAL_AMOUNT;Hoeveelheid TP_TM_FATTAL_ANCHOR;Anker -TP_TM_FATTAL_LABEL;Compressie dynamisch bereik +TP_TM_FATTAL_LABEL;Compressie dynamisch bereik TP_TM_FATTAL_THRESHOLD;Detail TP_TONE_EQUALIZER_BANDS;Banden TP_TONE_EQUALIZER_BAND_0;Zwarten @@ -3587,7 +3661,7 @@ TP_WAVELET_BLCURVE;Vervaag per niveau TP_WAVELET_BLURFRAME;Vervaag TP_WAVELET_BLUWAV;Versterkingsrespons TP_WAVELET_CBENAB;Kleurtint en kleurbalans -TP_WAVELET_CB_TOOLTIP;Met hoge waarden kun je speciale effecten creëren, gelijkend op wat je met de Chroma-module kunt bereiken, maar nu gericht op het residuele beeld. Met kleinere waarden kun je handmatig de witbalans corrigeren. +TP_WAVELET_CB_TOOLTIP;Met hoge waarden kun je speciale effecten creëren, gelijkend op wat je met de Chroma-module kunt bereiken, maar nu gericht op het residuele beeld. Met kleinere waarden kun je handmatig de witbalans corrigeren. TP_WAVELET_CCURVE;Lokaal contrast TP_WAVELET_CH1;Alle chroma's TP_WAVELET_CH2;Pastel - Verzadigd @@ -3612,7 +3686,7 @@ TP_WAVELET_COMPEXPERT;Geavanceerd TP_WAVELET_COMPGAMMA;Compressie gamma TP_WAVELET_COMPGAMMA_TOOLTIP;Door het gamma van het residuele beeld te wijzigen, kun je data en histogram in balans brengen. TP_WAVELET_COMPLEXLAB;Complexiteit -TP_WAVELET_COMPLEX_TOOLTIP;Standaard: toont... shows a reduced set of tools suitable for most processing operations.\nAdvanced: shows the complete set of tools for advanced processing operations. +TP_WAVELET_COMPLEX_TOOLTIP;Standaard: toont minder gereedschappen maar voldoende voor de meeste bewerkingen.\nGeavanceerd: toont alle gereedschappen voor geavanceerde bewerkingen. TP_WAVELET_COMPNORMAL;Standaard TP_WAVELET_COMPTM;Toonmappen TP_WAVELET_CONTEDIT;'Na'-contrastcurve @@ -3780,14 +3854,14 @@ TP_WAVELET_THR;Drempel schaduwen TP_WAVELET_THREND;Drempel lokaal contrast TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) -TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus van de gekozen waarde tot het gekozen aantal Wavelet-niveaus zullen worden beïnvloed door het Schaduwluminantiebereik. +TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveaus van de gekozen waarde tot het gekozen aantal Wavelet-niveaus zullen worden beïnvloed door het Schaduwluminantiebereik. TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveaus beneden en inclusief de gekozen waarde zullen worden beïnvloed door het luminantiebereik van de hoge lichten. TP_WAVELET_THRH;Drempel hoge lichten TP_WAVELET_TILESBIG;Grote tegels TP_WAVELET_TILESFULL;Volledige afbeelding TP_WAVELET_TILESIZE;Tegelgrootte TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer 'Grote tegels' als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugenaanbevelingen. -TP_WAVELET_TMEDGS;Edge stopping +TP_WAVELET_TMEDGS;Randbehoud TP_WAVELET_TMSCALE;Schaal TP_WAVELET_TMSTRENGTH;Compressiesterkte TP_WAVELET_TMSTRENGTH_TOOLTIP;Bepaalt de sterkte van het toonmappen of de contrastcompressie. Als de waarde anders is dan 0, dan worden de Sterkte- en Gamma-schuifbalken van Toonmappen in de Belichtingstab inactief. @@ -3833,7 +3907,7 @@ TP_WBALANCE_ITCWB_CUSTOM;Gebruik aangepaste temperatuur & tint TP_WBALANCE_ITCWB_DELTA;Delta temperatuur in groene lus TP_WBALANCE_ITCWB_FGREEN;Vind groene student TP_WBALANCE_ITCWB_FORCED;Dichtbij volledig CIE-diagram -TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie +TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimumgrootte TP_WBALANCE_ITCWB_NOPURPLE;Filter op paars TP_WBALANCE_ITCWB_PRECIS;Precisie-algoritme - schaal gebruikt @@ -3909,17 +3983,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_466;--unused-- !HISTORY_MSG_467;--unused-- !HISTORY_MSG_470;--unused-- -!HISTORY_MSG_498;Local - Spot name -!HISTORY_MSG_499;Local - Spot visibility !HISTORY_MSG_580;--unused-- !HISTORY_MSG_664;--unused-- -!HISTORY_MSG_ICM_CAT;Matrix adaptation -!HISTORY_MSG_ICM_MIDTCIE;Midtones -!HISTORY_MSG_ICM_REFI;Refinement Colors -!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x -!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y -!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights -!HISTORY_MSG_ICM_TRCEXP;Abstract Profile !HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast !HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW !HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius @@ -3953,7 +4018,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X !HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y !HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors -!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control !HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x !HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y !HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid @@ -3983,20 +4047,9 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather !HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution !HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness -!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control !HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution !HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth -!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders -!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders -!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom -!PREFERENCES_RAW_DECODER;Raw Decoder -!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw -!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing -!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars !PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here -!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here !QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates !QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f !QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples @@ -4016,11 +4069,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: !QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time !QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template -!TC_LOCALLAB_PRIM_SHIFTX;Shift x !TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. -!TC_LOCALLAB_PRIM_SHIFTY;Shift y -!TC_PRIM_REFI;Refine colors (white-point) -!TOOLBAR_TOOLTIP_PERSPECTIVE;Perspective Correction\n\nEdit control lines to correct perspective distortion. Click this button again to apply correction. !TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. !TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. !TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). @@ -4035,7 +4084,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. !TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. !TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_ICM_BW;Black and White !TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. !TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 !TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 @@ -4043,13 +4091,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 !TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. !TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. -!TP_ICM_WORKING_CAT;Matrix adaptation -!TP_ICM_WORKING_CAT_BRAD;Bradford -!TP_ICM_WORKING_CAT_CAT02;Cat02 -!TP_ICM_WORKING_CAT_CAT16;Cat16 !TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford -!TP_ICM_WORKING_CAT_VK;Von Kries -!TP_ICM_WORKING_CAT_XYZ;XYZ scale !TP_ICM_WORKING_ILLU_E;E !TP_ICM_WORKING_NON;None !TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. @@ -4069,8 +4111,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. !TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). !TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. -!TP_LOCALLAB_BWEVNONE;None -!TP_LOCALLAB_BWEVSIG;Activated !TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding !TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. !TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. @@ -4081,12 +4121,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). !TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. !TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. -!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels -!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based -!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based -!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based -!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels -!TP_LOCALLAB_CIE_SMOOTH_NONE;None !TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. !TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. !TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. @@ -4094,9 +4128,7 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. !TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. !TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. -!TP_LOCALLAB_COLORFRAME;Dominant color !TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. -!TP_LOCALLAB_COMPRCIE;Brightness compression !TP_LOCALLAB_COMPRCIETH;Compression threshold !TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. !TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. @@ -4106,7 +4138,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. !TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. !TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. -!TP_LOCALLAB_DEHAZE_BLACK;Black !TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. !TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. !TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. @@ -4120,13 +4151,10 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. !TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. !TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. -!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround -!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools !TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. !TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. !TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. !TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. -!TP_LOCALLAB_EXMAIN;Global !TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). !TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. !TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. @@ -4143,11 +4171,8 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. !TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'Scope' values to simulate smaller spots. !TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. -!TP_LOCALLAB_FATSAT;Saturation control !TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) !TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). -!TP_LOCALLAB_FULLIMAGE;Black-Ev and White-Ev for whole image !TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. !TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. !TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. @@ -4193,7 +4218,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. !TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. !TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) !TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. !TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. !TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. @@ -4206,7 +4230,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). !TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. !TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. -!TP_LOCALLAB_LOGPFRA2;Log Encoding settings !TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. !TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. !TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. @@ -4214,7 +4237,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. !TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). !TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. -!TP_LOCALLAB_MASKCOM_TOOLNAME;Common Color Mask !TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of Scope. !TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. !TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. @@ -4232,7 +4254,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise !TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. !TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. !TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. @@ -4261,7 +4282,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of scope in this case). !TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. !TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. -!TP_LOCALLAB_MIDTCIE;Midtones !TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. !TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. !TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. @@ -4278,7 +4298,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. !TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. !TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. -!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant !TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. !TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). !TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. @@ -4296,8 +4315,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. !TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. !TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. -!TP_LOCALLAB_SATCIE;Saturation control -!TP_LOCALLAB_SCOPEMASK;Scope (ΔE image mask) !TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. !TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. !TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. @@ -4311,37 +4328,22 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. !TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the Scope sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. !TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution !TP_LOCALLAB_SIGCIE;Sigmoid !TP_LOCALLAB_SIGGAMJCIE;Gamma !TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. !TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold !TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. -!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance !TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. !TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. !TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). -!TP_LOCALLAB_SIGMOIDSENSI;Adaptability !TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. !TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. -!TP_LOCALLAB_SIGSLOPJCIE;Slope -!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments -!TP_LOCALLAB_SIGWHITESCIE;Whites distribution !TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) -!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation -!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode -!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene !TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. -!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing !TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. !TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. !TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. !TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). -!TP_LOCALLAB_STRENGTHCIELOG;Strength !TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. !TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). !TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! @@ -4358,7 +4360,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). !TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. !TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. -!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones !TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. !TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtrl+click to show/hide all Control Spot. !TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases. From cee888386fbd4c0cd45e9bec2e3ebce39a6a0e22 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 28 Jul 2024 07:18:05 +0700 Subject: [PATCH 276/291] macOS CI: build for arm64 (#7132) * macOS CI: add build for arm64 Additionally builds an arm64 macOS app as well as x86_64 for testing purposes. * macOS: add architecture to continuous package name * macOS CI: remove an incorrect processor type directive * macOS CI: remove a downgraded dependency * macOS CI: add automake dependency to arm64 config * macOS CI: try system libraw = ON * macOS CI: have brew install libra * macOS: try brew cleanup for libraw uninstall * macOS CI: don't uninstall libraw first * macOS CI: test-launch the app * macOS CI: fix indentation * macOS CI: list running apps after launch test * macOS CI: copy app to /Applications for launch test * macOS CI: add libtool * macos CI: tst arm64 cli --- .github/workflows/macos.yml | 122 +++++++++++++++++++++++++++++++++--- tools/osx/macosx_bundle.sh | 2 +- 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 52869e981..824d87d1d 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -25,7 +25,7 @@ jobs: mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake | tee -a depslog + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring @@ -34,23 +34,21 @@ jobs: env: CMAKE_CXX_STANDARD: 11 PKG_CONFIG_PATH: /usr/local/opt/libtiff/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/expat/lib/pkgconfig - RAW_THERAPEE_MAJOR: '5' - RAW_THERAPEE_MINOR: '10' C_FLAGS: > -arch x86_64 -mtune=generic -Xpreprocessor -fopenmp /usr/local/opt/libomp/lib/libomp.dylib -I/usr/local/opt/libomp/include -I/usr/local/include -I/usr/local/opt/gdk-pixbuf/include -I/usr/local/opt/libiconv/include -I/usr/local/opt/libxml2/include -I/usr/local/opt/expat/include -I/usr/local/opt/libtiff/include run: | # GITHUB_REF is the ref that triggered the build, like # refs/heads/new-feature - the next line parses that to REF: the branch # name only (new-feature) + export RAW_THERAPEE_VERSION=$(git describe --tags | cut -f1,2 -d'.') export REF=${GITHUB_REF##*/} export C_FLAGS=$(echo -e $C_FLAGS | tr -d '\n') cd build && date -u && date +%s > configstamp - curl -L https://github.com/Homebrew/homebrew-core/raw/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -o libomp.rb && brew install --formula libomp.rb cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libomp/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ - -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_MAJOR}.${RAW_THERAPEE_MINOR}-${REF}" \ + -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_VERSION}-${REF}" \ -DPROC_TARGET_NUMBER="1" \ -DPROC_LABEL="generic processor" \ -DCMAKE_OSX_ARCHITECTURES=$(uname -m) \ @@ -67,8 +65,9 @@ jobs: -DOpenMP_libomp_LIBRARY=/usr/local/opt/libomp/lib/libomp.dylib \ -DCMAKE_AR=/usr/bin/ar \ -DCMAKE_RANLIB=/usr/bin/ranlib \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ - -DOSX_CONTINUOUS=ON \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 \ + -DCONTINUOUS=ON \ + -DCODESIGNID:STRING="-" \ .. zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' - name: Compile RawTherapee @@ -105,7 +104,114 @@ jobs: run: | date -u zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' - + - name: Test-launch the app + run: | + cd build + sudo cp -R RawTherapee.app /Applications + open -a RawTherapee + sleep 5 + osascript -e 'tell application "Finder"' -e 'get the name of every process whose visible is true' -e 'end tell' + osascript -e 'tell application "RawTherapee" to if it is running then quit' + - name: Publish artifacts + uses: softprops/action-gh-release@v2 + if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} + with: + tag_name: nightly-github-actions + files: | + ${{env.ARTIFACT_PATH}} + + armbuild: + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: | + date -u + mkdir build + date +%s > build/stamp + brew uninstall --ignore-dependencies libtiff + brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog + date -u + echo "----====Pourage====----" + cat depslog | grep Pouring + zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + - name: Configure build system + env: + CMAKE_CXX_STANDARD: 11 + PKG_CONFIG_PATH: /opt/homebrew/opt/libtiff/lib/pkgconfig:opt/homebrew/opt/libffi/lib/pkgconfig:/ope/homebrew/opt/expat/lib/pkgconfig + C_FLAGS: > + -arch arm64 -Xpreprocessor -fopenmp /opt/homebrew/opt/libomp/lib/libomp.dylib -I/opt/homebrew/opt/libomp/include -I/opt/homebrew/include -I/opt/homebrew/opt/gdk-pixbuf/include -I/opt/homebrew/opt/libiconv/include -I/opt/homebrew/opt/libxml2/include -I/opt/homebrew/opt/expat/include -I/opt/homebrew/opt/libtiff/include + run: | + # GITHUB_REF is the ref that triggered the build, like + # refs/heads/new-feature - the next line parses that to REF: the branch + # name only (new-feature) + export RAW_THERAPEE_VERSION=$(git describe --tags | cut -f1,2 -d'.') + export REF=${GITHUB_REF##*/} + export C_FLAGS=$(echo -e $C_FLAGS | tr -d '\n') + cd build && date -u && date +%s > configstamp + cmake \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -DCMAKE_EXE_LINKER_FLAGS="-L. -L/opt/homebrew/lib -Wl,-rpath -Wl,/opt/homebrew/lib -L/opt/homebrew/opt/gdk-pixbuf/lib -L/opt/homebrew/opt/libiconv/lib -L/opt/homebrew/opt/libomp/lib -L/opt/homebrew/opt/libffi/lib -L/opt/homebrew/opt/libffi/lib -L/opt/homebrew/opt/libxml2/lib -L/opt/homebrew/opt/expat/lib" \ + -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_VERSION}-${REF}" \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DWITH_LTO="ON" \ + -DLENSFUNDBDIR="/Applications/RawTherapee.app/Contents/Resources/share/lensfun" \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_C_FLAGS="-arch arm64 -Wno-pass-failed -Wno-deprecated-register -Wno-unused-command-line-argument" \ + -DCMAKE_CXX_FLAGS="-arch arm64 -Wno-pass-failed -Wno-deprecated-register -Wno-unused-command-line-argument" \ + -DOpenMP_C_FLAGS="${C_FLAGS}" \ + -DOpenMP_CXX_FLAGS="${C_FLAGS}" \ + -DOpenMP_C_LIB_NAMES=libomp \ + -DOpenMP_CXX_LIB_NAMES=libomp \ + -DOpenMP_libomp_LIBRARY=/opt/homebrew/opt/libomp/lib/libomp.dylib \ + -DCMAKE_AR=/usr/bin/ar \ + -DCMAKE_RANLIB=/usr/bin/ranlib \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \ + -DCONTINUOUS=ON \ + -DCODESIGNID:STRING="-" \ + .. + zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' + - name: Compile RawTherapee + run: | + date -u && date +%s > build/compilestamp + cd build + export REF=${GITHUB_REF##*/} + make -j$(sysctl -a | grep machdep.cpu.thread_count | tail -c 2) install + zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' + - name: Create application bundle + run: | + zsh + date +%s > build/bundlestamp && date -u && cd build + export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle + export ARTIFACT=(RawTherapee*${CMAKE_BUILD_TYPE}.zip) + echo "=== artifact: ${ARTIFACT}" + # defining environment variables for next step as per + # https://github.com/actions/starter-workflows/issues/68 + echo "ARTIFACT_PATH=${GITHUB_WORKSPACE}/build/${ARTIFACT}" >> $GITHUB_ENV + echo "ARTIFACT_FILE=${ARTIFACT}" >> $GITHUB_ENV + zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' + printf '%s\n' \ + "REF: ${REF}" \ + "ARTIFACT: ${ARTIFACT}" \ + "ARTIFACT_PATH: ${ARTIFACT_PATH}" \ + "ARTIFACT_FILE: ${ARTIFACT_FILE}" \ + "PUBLISH_NAME: ${PUBLISH_NAME}" + exit + - uses: actions/upload-artifact@v4 + with: + name: ${{env.ARTIFACT_FILE}} + path: ${{env.ARTIFACT_PATH}} + - name: Finish build + run: | + date -u + zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + - name: Test-launch the app + run: | + cd build + sudo cp -R RawTherapee.app /Applications + time RawTherapee_*/rawtherapee-cli - name: Publish artifacts uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index 83689d45b..aaceb27be 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -484,7 +484,7 @@ function CreateDmg { if test -z "${BRANCH}"; then BRANCH=$(git rev-parse --short HEAD) fi - mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_${BRANCH}_macOS_${CMAKE_BUILD_TYPE}.zip" + mv "${PROJECT_NAME}_macOS_${arch}_latest.zip" "${PROJECT_NAME}_${BRANCH}_macOS_${arch}_${CMAKE_BUILD_TYPE}.zip" fi } From cc0e941652b7d0057411ad04299a21203fc3e2bb Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 28 Jul 2024 07:13:58 +0200 Subject: [PATCH 277/291] Selective editing - modifies the activation of the Laplacian according to the spots with Dehaze (#7122) * Disable Laplace when others Spot with dehaze * Disable Laplace when others Spot with dehaze * appimage and widows yml with drexpos * Compatibility 5.10 contrast attenuator * Change control out of boud when using Contrast attenuator * Comment code * Comment code * Comment code and fixed * Clip original retinex to avoid crash in some cases * Change tooltip * Clip only Lapalacian if expose or soft enabled * Various improvment to avoid crash * Tonecurve hsv colortoning chmixer not allow negative RGB * Fattal and black need clip issue 7151 * Disable Fattal * Clean code * Disable appimage and windows yml --- rtengine/iplocallab.cc | 71 +++++++++++++++++++++++++++++++++++++++--- rtengine/procparams.cc | 8 ++++- rtgui/locallabtools.cc | 12 +++++-- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 9cf83d9cb..13f974d1a 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -85,6 +85,12 @@ constexpr float clipDE(float x) return rtengine::LIM(x, 0.3f, 1.f); } +constexpr float clipR(float x) +{ + return rtengine::LIM(x, 0.f, 65535.f);//used when Laplacian Contrast attenuator +} + + constexpr float clipC(float x) { return rtengine::LIM(x, -100000.f, 100000.f);//increase LIM from 42000 to 1000000 to avoid clip and also imaginaries colors @@ -18000,8 +18006,6 @@ void ImProcFunctions::Lab_Local( } } - - if (exlocalcurve && localexutili) {// L=f(L) curve enhanced #ifdef _OPENMP @@ -18104,8 +18108,8 @@ void ImProcFunctions::Lab_Local( } - if (lp.laplacexp > 0.1f) { - + if (lp.laplacexp > 0.1f) {//don't use if an other spot use Dehaze. + //printf("EXEC ATTENUATOR\n"); MyMutex::MyLock lock(*fftwMutex); std::unique_ptr datain(new float[bfwr * bfhr]); std::unique_ptr dataout(new float[bfwr * bfhr]); @@ -20521,6 +20525,65 @@ void ImProcFunctions::Lab_Local( } } } + int bw = transformed->W; + int bh = transformed->H; + bool notzero = false; //verify that RGB values are > 0.f issue 7121 to avoid crash. Could perhaps be used in other cases as RGB curves (main) + bool notlaplacian = false;//no use of strong Laplacian + + float epsi = 0.000001f; + + + if((lp.laplacexp > 1.f && lp.exposena) || (lp.strng > 2.f && lp.sfena)){//strong Laplacian + notlaplacian = true; + } + + if(((lp.laplacexp > 0.f && lp.laplacexp <= 1.f) && lp.exposena && lp.blac == 0.f)) { // use Laplacian with very small values + notzero = true; + } else if ((lp.laplacexp > 0.f && lp.laplacexp <= 1.f) && lp.exposena && lp.blac != 0.f) {//for curvelocal simplebasecurve with black + notlaplacian = true; + } + + ToneCurveMode curveMode = params->toneCurve.curveMode;//Tone curve does not allow negative values + if((curveMode == ToneCurveMode::PERCEPTUAL) || (curveMode == ToneCurveMode::STD) || (curveMode == ToneCurveMode::WEIGHTEDSTD) || (curveMode == ToneCurveMode::FILMLIKE) || (curveMode == ToneCurveMode::SATANDVALBLENDING) || (curveMode == ToneCurveMode::LUMINANCE)) { + notzero = true; + } + + ToneCurveMode curveMode2 = params->toneCurve.curveMode2;//Tone curve does not allow negative values + if((curveMode2 == ToneCurveMode::PERCEPTUAL) || (curveMode2 == ToneCurveMode::STD) || (curveMode2 == ToneCurveMode::WEIGHTEDSTD) || (curveMode2 == ToneCurveMode::FILMLIKE) || (curveMode2 == ToneCurveMode::SATANDVALBLENDING) || (curveMode2 == ToneCurveMode::LUMINANCE)) { + notzero = true; + } + + if(params->rgbCurves.enabled || params->hsvequalizer.enabled || params->chmixer.enabled || params->colorToning.enabled ) {//rgb curves, HSV, Channel mixer, Color Toning does not allow negative values. Perhaps others cases ? + notzero = true; + } + + if(notlaplacian || notzero) {//allows memory and conversion labrgb only in these cases + const std::unique_ptr prov1(new Imagefloat(bw, bh)); + lab2rgb(*transformed, *prov1, params->icm.workingProfile); + + if(notlaplacian) {//clip value above 65535.f and > epsilon when Contrast attenuator with high values Laplacian or Original Retinex +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < bh; ++i) + for (int j = 0; j < bw; ++j) { + prov1->r(i, j) = clipR(rtengine::max(prov1->r(i, j), epsi)); + prov1->g(i, j) = clipR(rtengine::max(prov1->g(i, j), epsi)); + prov1->b(i, j) = clipR(rtengine::max(prov1->b(i, j), epsi)); + } + } else if(notzero) {//standard case only with small values Laplace no clip +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < bh; ++i) + for (int j = 0; j < bw; ++j) { + prov1->r(i, j) = rtengine::max(prov1->r(i, j), epsi); + prov1->g(i, j) = rtengine::max(prov1->g(i, j), epsi); + prov1->b(i, j) = rtengine::max(prov1->b(i, j), epsi); + } + } + rgb2lab(*prov1, *transformed, params->icm.workingProfile); + } // Gamut and Munsell control - very important do not deactivated to avoid crash diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e1a56a533..8041ab298 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -9235,7 +9235,13 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) spotEdited.visiexpose = true; } + assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); assignFromKeyfile(keyFile, "Locallab", "Complexexpose_" + index_str, spot.complexexpose, spotEdited.complexexpose); + if (ppVersion <= 350 && spot.laplacexp > 0.f) { // Contrast attenuator moved to "advanced" after 5.10. Set complexity to "advanced" if Contrast attenuator is in use. + spot.complexexpose = 0; + spotEdited.complexexpose = true; + } + assignFromKeyfile(keyFile, "Locallab", "Expcomp_" + index_str, spot.expcomp, spotEdited.expcomp); assignFromKeyfile(keyFile, "Locallab", "Hlcompr_" + index_str, spot.hlcompr, spotEdited.hlcompr); assignFromKeyfile(keyFile, "Locallab", "Hlcomprthresh_" + index_str, spot.hlcomprthresh, spotEdited.hlcomprthresh); @@ -9277,7 +9283,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "LmaskexpCurve_" + index_str, spot.Lmaskexpcurve, spotEdited.Lmaskexpcurve); assignFromKeyfile(keyFile, "Locallab", "ExpMethod_" + index_str, spot.expMethod, spotEdited.expMethod); assignFromKeyfile(keyFile, "Locallab", "ExnoiseMethod_" + index_str, spot.exnoiseMethod, spotEdited.exnoiseMethod); - assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); + // assignFromKeyfile(keyFile, "Locallab", "Laplacexp_" + index_str, spot.laplacexp, spotEdited.laplacexp); assignFromKeyfile(keyFile, "Locallab", "Reparexp_" + index_str, spot.reparexp, spotEdited.reparexp); assignFromKeyfile(keyFile, "Locallab", "Balanexp_" + index_str, spot.balanexp, spotEdited.balanexp); assignFromKeyfile(keyFile, "Locallab", "Linearexp_" + index_str, spot.linear, spotEdited.linear); diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index 4c68b004e..7fa0b608c 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -3796,7 +3796,7 @@ void LocallabExposure::convertParamToNormal() // Disable all listeners disableListener(); gamex->setValue(defSpot.gamex); - + laplacexp->setValue(defSpot.laplacexp); // Set hidden GUI widgets in Normal mode to default spot values structexp->setValue((double)defSpot.structexp); blurexpde->setValue((double)defSpot.blurexpde); @@ -3819,6 +3819,7 @@ void LocallabExposure::convertParamToSimple() // Disable all listeners disableListener(); + laplacexp->setValue(defSpot.laplacexp); fatlevel->setValue(defSpot.fatlevel); fatanchor->setValue(defSpot.fatanchor); norm->set_active(false); @@ -3865,7 +3866,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) fatlevel->hide(); fatanchor->hide(); gamex->hide(); - + exppde->hide(); break; case Normal: @@ -3893,6 +3894,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) // Specific Simple mode widgets are shown in Normal mode softradiusexp->hide(); blurexpde->hide(); + exppde->hide(); if (!inversex->get_active()) { // Keep widget hidden when invers is toggled expgradexp->show(); @@ -3937,6 +3939,7 @@ void LocallabExposure::updateGUIToMode(const modeType new_type) maskusablee->hide(); maskunusablee->show(); } + exppde->show(); expmaskexp->show(); lapmaskexp->show(); @@ -4192,13 +4195,15 @@ void LocallabExposure::updateExposureGUI3() expcomp->setLabel(M("TP_LOCALLAB_EXPCOMP")); gamex->hide(); expfat->show(); - exppde->show(); + exppde->hide(); if (mode == Normal) { // Keep widgets hidden in Simple mode softradiusexp->show(); expgradexp->show(); exprecove->show(); blurexpde->show(); + exppde->hide(); + } if (mode == Expert) { // Keep widgets hidden in Simple mode softradiusexp->show(); @@ -4207,6 +4212,7 @@ void LocallabExposure::updateExposureGUI3() structexp->show(); blurexpde->show(); gamex->show(); + exppde->show(); } From 8734ddc95f29dc2a57b0395e390495dd1632d87b Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 30 Jul 2024 18:33:57 +0700 Subject: [PATCH 278/291] Delete tools/osx/rtdmg-bkgd.png --- tools/osx/rtdmg-bkgd.png | Bin 317127 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/osx/rtdmg-bkgd.png diff --git a/tools/osx/rtdmg-bkgd.png b/tools/osx/rtdmg-bkgd.png deleted file mode 100644 index a8be0cec68b0f859c18f62e4f0aeda7ba2d02ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 317127 zcmeFYbyQr<@-95M6A13Z;O;g+aCZ$JWCnMa;BFy6Ah^3jaDoPnL2wQ3!8L@yHzeglSdtE#*A+C;0X%3-0Cq5}W`ECqRKO#lF42LOQ2M1_a7 z>;eR=0RZ|gUu`{iO*1c`v#XP(jXf0T?&AyvLcMJ)0RZp$;w(E)NM%Fz{RFx|@KvFZ zcn|SmaOROyQc^`@r~mUK=c&0Q=9D%<9NaV9x);Lt`++7`V%Iz&N9?bs_sgcv7!pL* zHX;wj0>AlVJ?XAJ8r^;3-+8m|A&{DIR64BW`(fK5;B#%PvB`|^-gfT({^p8UZRD*- z{>4Sav48&YcJ|T2M(OGH@{fIFv!4M=b5>y0f(8 zUqQRw9jWoh;6$#P$6^wf0Us&5i57PUzK9i)UTza{AU!#{;<~(Z!i_%|-9Oyl+vRZ& zIGO1i%$==gR5`oDW;~O>WyZRvX!FYd&Ii(5xThFz>Na`AI&kZTaJH-<5}@|!&S+-_ zJ5xw@(kRPqv8y*^s2}{PTZ!gs%FC1|(e>GftgPn}>;YUtjp% zUd`x;b<3Um+ojxf>-gUMyiv=~{q7fkc$IZ@%NKscg(w!N@_m1aRO3z*bk9?8>-4=Z z>h9;oO<PgIo=G#fg&f_!q79$FKl`z`?9}M7oa^-Q#jaIM_x*FLYl9;Jm!Z|J$}=zI zkW9$ZjjHx?%h!o{wd!Jl_SAM~se8}3;=6?b$=mIL`?K!+LZiZz{zZS@u1nh#xG7Sn z_dy1$Q+-$H^zo6e%Qx(w(fqi}l#suhp6n`gPPk7Q2#jALO89wuKHzkS(!Zs~7H@V;8rc}oEOF5=)M?{0o~%W*xCDAuiA?rTOV01YsRF0 zW=vk;zbmz_WyAgQLvPb*y}NJp;3tyjwa*QfYsT`%&$Vq_&`BFL3I>l6(dQp#D1sPC zf{8})iTFxKO{#}4TA#^U{lpUBmw!K;m&X4^`7P;@$1@AGqptNOr^wIQY{%2Yt$Hgo z_oLm1-KQn@=T}c0AFXO!W;yi|Kh=K1gDIo>%!ds3J9_A(-1YuZt=J(;-3W$D{MnMQBT6bq&l)no|U z_69!Bb!G))q6FcVGij(87Yl_5Xe`fX3(2(^_ zJh`z++f35UXaCEdM#WboV>b(6#P9)m8 z+-Lh6u5&MTKr%0swezrMgNYHOGkGJ}oLy?(A?%!jX+Dm7hEr+kW6H%Q?tzZVdWA?6 zn@ETEygf}%m`!XOCT;2}@;jEUa6{n-_(}~GF4(o-++4-eRhGXK2Nv3pJb&f0o zmU2VX56QO1!>f|Mbfm^QGY{&;i8&mvLUbeR@1ou@H8X1~uywgC3}Ah?X2_@>ZKIg- z@?&Ap#?!2#)O*W4_|@tSh-EtgkHg!KA*l9eD2q(ux7>65|_p%tA zI!$!?=tpGAp>FFHXVT&o9!R zQ?JKUnMaRdOx82)uZJ8)N#8j#lais~KlY;`dB&c-UJ%ev(t}R(%ti`tX1+??=&!i&&Q~{unb(Pr$gA1vk@knGEAKpL z)=iI_nO8zf0LJ80JN>sC?z{uC5Yoiu?Go9+q}OF6J&*+bWp%3xozMC3A`$#>3r|TW zmQb%y9(qcFpx|g&ZfLCzLgN$L0uRuW(=~r zvN{Qqyugy&#MoL&RJcvGPnH_@sy`F!bbIzylAXwSr<3`}&`XR>{jew=g~C%I5}$H_ z*hnooL#J{1^-RMd)rOzUE8dCo zJDUaLam4Y_0W@>vqGAn+X_bvuIB3%08fJ^8L2=TbjMgWfmchrJS06j2qYg{7ZdV?t zogr;un?9zZBT#!3NqT}YNbR*JKP2PSgskVKCm0UR*8l7y{rpHS{=g-Xhb;~-3M$%< zCZSHL6Z8Y4ZutkeWIpPPG&vOgQ<`QM2KY&o<72d$w(x2!cSIWmh-a$;XBc8oWNiF) zp37peCaQteSM^2Ca$~NDsDwv`ndaAsW5xkk%gV;^_e)Zn7ZTjG#Nc+pyw!kJ3s-K0 zky%dNXl-f>Tix6@<%&J1&S<8+Y$T-2mlpN#U*p`hzBzu1^9`=?-^C<<>pcuG8hYAc ziNFs>=t5usgup3Bm&{JEtk}e?a0Vz)(^54+K10Zb@<3w+@)fhF7I3pTMsI!Uz9GUp z*ZF=4$j+qpmvOFcQ$ow?#Cj`}x8Xa9=1U#7(KrG|RO)8J4uAHa@A&P1?rW2q8vvI;o&c zAR4<)1j@|Vg>ifd2F>>d>@1%z`39?n1>wi80*yHuU1W11%p}7IWrULqgPf$_ak%dp z6^En=9LRu=KlItZE0_<>S|GuAfw;Q@k@`SWp$D|3ys8gc z;@!@xQ2b0IwDktawBvE9On71W`rM=+hdN04eJ?r!aKl<)2O;p?fEJfL9cuu86q%_O z^dK}s9z}QKbOWOq`7_ZDB@oBVi{B#=me+VlN#p1xz@mqG^g1CxL3|(Kb&V@Eh@HDBatc^5oC@%QH z1PsZ1W6GQb;BADg+2>Uhw$95tK}Hu}}Z+Q-9esn30HN9I4W1kG+xcEx0D$iAL0 zQVcpCyNwavZhPusuvZVT8OsfS%8UaO%hD|(q7DfNQe~Gs>WEKQC@en^;pqLUs3!5lhxPQ zmOir@yT}XDW2X0f-HA2LI$U}hG;dUPn{ka1+dKUn2}whOLU9x9!ZAIPU+z3+BKxYud4#P*1qn0=M^GH(AkE9dg!t(3atatJSfBQLm8`5Ap7fXYI)b-jBY-Ae z^`V~yf)cDa_TQrPB`XhP`XoLZ?|St1c5Rfdh$^$rDuAI4#7rTw=D0Wp8~Cr5x# zX{NVApi8+yGFs8NX`93M&Z|txeXg%0QLWYHRVXV-08dEE>?2G$far)xUPwx?KjVkz zU#yf$kbjy4?SnN=Cq1<0Tu`8*Hjz;b&(_g_h+AZdvzADTE-KkcG67tsd>wC;`pyi! z5wuIUydsD=btDchKHbNE(bz?r6);ZUuYq{H+aBZ~2>pkDh)!Em&lU1Ol+JWs{q zK$E&3eTlWCvETV@O?g5{75xq6jZ_4;oa;!E_6lhTiR>qH z%qOGUq&;bzDvZkrX_D{#a^lMsn1Y4;=v*ljdG?TYB|ha2u|o#8W&--7#$h;w6d z2g78U;nQrNl9>UqjnLx~ORT?V-68}A@mY)T%UNeH+&$Y?0@)p)(OoqRA|S<; zb~AfX-lo2-o3Qn*hVA8ZPYKluq(}4C3^|f!;hv#^Otx`^v%0TuvMGq$_R<8SQY*rN zh{EI9jJx5;nzCd@s;Z44-%2<1n^%x7EPP6&PJzO>P`Y5LVT(F4IYdXyS;{H|)<-E4 z2J75-Vv0*N&52AZ2)!;g)rrCL>%sSo=5fykKT3$eUBe5PYdZrpLoP>nluSSOC_?t= z`}h(4AZwwDdDo_OH3@kqF9V|Xbco4zT&IpCGO3L)X-87}g?V^%d68Y2-chK~AYc=& zHBfpR&#D@?mDemt)SGkb$vkF^IheYNXu$Rel3`yHd{zJ2HXN6+Xi2mfn`&`%n4%Ji zlrmEz!&f?$d`3D1lTV_4szrlovpl?M}!=oF$0IP$x*(#cqc@NU6RA8U*QKNUy>s%K|(Jqf0dDsv0b9R+d$&RRYC z%y9s{Nw}Z`naxNb-yGXo)l@sP9<{81rsPP3JFN6kPT4dJQGA` zoztL-*+n;0p*YNEM|~}m-cyn%v8(e4tdoRd&Ic3>y2rW`5Q);_E8K1W2jOv8CH~8Qr{R0*?x@ z5~chg8pE09?ijA6QlYtyuk&;?$h3Rx+@Lig=QE^ejlT{}?(?2TtL@r4#}^NX-Ovez zqOeUjH2KoTE`t#sg{PMZ-0XIi`dryo6RP#DMKN&pOHMF9`M3ljAZ3fsKqLRFOhbKKG~j_B~BNYL{cc6;nSJZq2Q zE1uYRUx`x9;WEk%(PB`q(hcK)PB5#1mCX+oijZ)WAN%9qEf=GyCAFptSR{3u+KZ~o zcH#M=kD0>H2*qk1q0&UEjyW1VPNaYoc#61})G>79;^OBMR>6lzSTTWD(dHN4&b{kc z_rbJ}YbKox*sAzaFoR6s>X$q=JY%T}h;V~Ta0g?Z%Vk*;wBGJExe2{}hN+S{Dz%G( z5sF*hZDE^7e}u~`ycI0DFN;2WyE1xw5YA`rk=!ibjU!vAwf%OA>0C2$mE_A2Vpgl= z(A)e*y{2by>cw%fkxyUqA5Wfr#;gB8;c*+!nio@YC(#V#UO$!;S)eGxdLCid*Ptmi zKLf8=)_kh!U>=82Oq&AF{;K@vV0?n8{Dkk6>GFoCw!Z4yMdrhdbEMxE*$Qlr(ml}OHy{46KYrD`&&7Nf9)#M80T zGwtzkj45B!Cc8Y^tj;%;5wyP3jc0fXtr2J>J+T?|=)f7~rFV~sQD*D;6<9`e5BOyC zu$6FGNYhgy>9?eH)(P4zdRxbLJ73lpnE;G}V?qgOOy=9DpL$T!SEZ(sMmud2U4$O$ zJIsh1#lF)e;U*ppF&j)9CVF>+^(>{STO7Zm3U@AYI|A+Cpp|$knYJ;;AoJZ+8@4Xvdij@{WWHt zm{j^qNcJdH2R-x|;dZFyFe1ouQtSZth$U3&>L&& zr2&tk;jO#~$BXxv0D|6SHIk7Z!c49c(?#pB0Jg$R7@Hk7wa>PYH8AnHA&8rN`kG#^ z+a0M#b?F2{_5T;_*20{p0*h*z%qg zK8i>jMgc*J9ytgE_F$?+^e58bkCGC_TlKEE-FZt5EYz#mSa?iCs$YFZAcLA=Dh*gt zQF)(UJXuez`Z(K1R@~|~koia-c^VaK7z4GLsb}ntmF350xhVJ}LIGP1ZcC^dA{!xH zxpOQ18YWkn%7@q!mNN2_cUrzGm#!8k8xte13bi=-S$v8D9HU#|c-d?l#5Ly?#nQBR z(bKW~w00?=Rd^Cg!nAvewB9E>X_~?P!?wHyymqsMp(`F@q&e2y33F&Q9|6c-*Wt54 zljEUgK(a(nWqa&{cVEj@7J~w!TC6B~0W&=cc;M~etgMYMHP;>&epMqU4Vs;_FpN@U*olB*My2Y85RO>G5aN4UvDsG zU_f!@Cc~-rj1;R=;CnT)47zGqcqx)3T(7PQ+wG;c37U|EFJw&-gV5xE9LqOljWHW( zod3u{ETHX^fY>|iU}_31dzojvMqk0--Z1F^Gw1G8nqmsJf>na#GvFvRo4$t@%_nWy zh|xrNPOLdxI7+l9t^)WfuiWMPbm)Rr;$lG5-7GlY{dGf5;5d6QKX3)S&_Q&;AX?)& z$qM$$xBlL2Pku_M!y}Uel^1tfBb_8;!NGYYdxLU+X;AUvyT*EJWw@9!8UGi0Z6c1$ zX-7^Gb>xtZ8?utQl2p_)i>v|0zyQwd=wKxGtdBGmTpLjVL>}k>BShrcH>yk( zkKNIi%3Ne;?diXp@QQL!r=(5wb#9z{`Wy9F_aG^-`DVdRN};YzkqK|L1&G!1PFxOJ z3gd*E$9dPW6mI4hs{k2T}vch3_))+I?DYREdx%s^NPT z@)!r7co%xKNqxb7v|a>}n{x)YlXe^OJ(g??7ofDe`HY5`t>KEF9cHH?xH3@GU_Bq1 z3!Z_?B5NnrdlC5@aKCC)Pq6WM?HLCV!h)yGjC(fr=tuYf_Ktdut`BFj4K8L1U^3Hw{RyUpHx??6Ypv-^BZOFKMF^zX@uQ z9U8vpPRLT1=06`MdVbe%YRhr1+>6Rf^?W)w=aBY9!@WcoL7S&NGE5zNo^Qq_qPjC% zt=oi*0?Ps}jf%jN8o^W~IyyajrcKYGHhad<;=4OC$(fMH%CtK`3-&mRp*SyA-I#+0(f%E$bUUnN(8G zQ79^6ydtD(l1eeS#5YNy!_XV3eAhYu6v?%v9pdysaq^(a1@zJ9$0YWS;Yh70#s?B!DP+z*rL^|0MKn7ffS!)8itNAY??{LdzF z_XjwcGJq_CX6I$}1h`KliALnU@Hjl97%q<#OQY_UD`k>|fC5U*JAu%s+V>_tfJ zWjJBGsaMT@O+R_K{;DiT;L8@||Fjwh*FPJ+$zo)0BEEPh_}#6ey_WA#;}!O?Yr z7HW@Yg7VZSoI)kT&PbKdAHEb#b8c1!muvKWyRmz@!z9Tq(V2>K=@-yX0r*}=yO*;w zMhO;bcxfaRAGLeI!xE>{KWa|5kvlb_Jg+aCPmS8hC6Yb!q?|HkEL!5@)%15b;MH5? zSW3wI`7PesPdnHWbCWdTEq&`wwGx?N@hYV~jDZ%hkJrghw^a>S2Tt?T(tW52~3<5ns}u>@t1 zijA8@ZuJg_8Q&xW;q>r@0& z8d3IG!hF@yy!=pG`BUf0wew=+fUbA9IO=o=NOwCo;ezz$+q`Uyi)4 zFi2G3C>rNxIMzid-)noT7V|LFLmGJRk;}JG(cZ_bC^FC_M;T1 zh55RG^JN|EkKqDB+Zw%e@IGkP;nX6z-WH<3!K(|aHz7KC;nRmH_K5^=CLs@z@JUfD zY`sTH$$DE874>72u&hhU?zU} z<*`t3KWy_Svm%)NNSd*MR7y0zd}1CYrPBnDlz1|`=FmjUK9#|&;C8KXRAz`Q!cJ#< zj7FsJOwXd{(-Zd^u=6! zAvDueu7e-)c`y(CiQQ)HzBxFe+Z{13B_nsLt`g6s6~y;L*?=Rv?A|TN@2dqhSggoD zoJ;*37QUN!+7uB&iSvThsKgHx!}K4~FHBF|UZIox>dITZC<7$$Ht9nkpBqq~P zN_rVhuL) zOFQ?)0V@IU(~mbfK9IV%--t?@fiueG)ZAZzrdYSj3T5T(Jz~#S2(w~~HkUN$k>P5S z<-yzcp7oQ0V{^I`g){n!9~uO_UHWb9!S;C^^*bZEg*>eOJ*^)}-<9V?`l+$xxn9J* zxD0Oeb5cjJ+`>_X#Ge!QA@3`(C8q7=l(#*iQS!ykmNt$;P5#=dVJJOKg;w^7@&W?) zCXFi@A7AcH#a73UW{=~o9BQM+m5=eOk^|oZA1%da*2eBz6u3jaX*rPq41l;UCk0ZN8UbQ+m8vY&A$Z^pODMX0ce>9QMC3GGGL zFdWIei%QOkcMiFB?t6gpJzdG1ct3+8gF)^UsK?2Vxw2&u=X*d&>AhM%=Tr1;FAB;V zedtqqlA6oUwCpsUdinxJjocqi`6wtDg3Z0hw@DNn7KNW@?utYcv*paNnvxJv0WtKE zMRDQzMWngqS8T|=lVx@|6GQ{Bc!bbHzp=tQP7y8EOqfll;6%Ch(?3Zr(&t#vQ!Pkr z+SIfiMQ%r60}pKjizfyo0^B4{wIfYUajH%h zByxz^$3?o81cMLld;>H}@eh8u=il(X8P>Ca)T^npYj|7dDk>o*>aVxTU91 zC!^|PaJq0GTJS;B#;Rm)FR~uC)3kYBL7cw;P- z8tlflde1vZRUa&D;Ops*yA-uWQrvydgL81Blg-_2qR3OD$*=-8Q|ICeTX=*$jB4De zO%^A0J>{m89FZ?`tojInnt7_m(f3xId+ybux3ZSuLUQlkc)3OG*)v-92qY8*myqJe zMlT(ns!5OHYtqk3StLnOn%its76qE`qRAiFs^03IkcQT+ z>OOzPfpC?LvF z6GfWkORwQ!)7t(JSHzQT5n6K|<+xOC=CqPfP!jBk-4RpmlDK3v1{-tBgWk=`r1km(#yM2oY~VIYEX-3&0i2`~=; zz=hjLNvSJHN&V|hHrV@XS^kNl^6%8~!_^FxWSG%))m?_wv%eL9UNoW0l;PNh>ryD2 z+@PqCCgBsw^){`njG9mN4(LBcc`AW(3+LkLtm&Tk_(%zz&HU}LH`Vr%oA=R^p5-#m zsc$g|6_zBs5Xs>!-S9D%=cwj5KZ#S*%15Kk(Q__5)RwfpxNK-;lu}|O!VXKImgEd zf&qy}+->hoH}u2_m}!R|-Jx__*%6k|FBLh%qjt?+4iV$bBV~9j+&yVN*h0hcMy_dW z?w$u&iYe5#H0|JywO|<;wea~oYF&hj$Z;QeNzNqx;Ta>~$m(20$aIBpN8fFG8a%X% z@G@V&*fA(n%Ji-L+&<;e;bGQ7w`leEp8z=@*A#)h)OY{@Ki3BKYN4KrGT6e&f!z$^ zWDaHbc5sHhdI$iBh^s3RB@JqTHDC`x`ty$99%*| zLL8jj9NgS&FbOs{A4hjHZ#G9ang@vA7}8KT3s)OwcN-^1-~*WMKmV|GG5ew&WJH6oRnvLpg=mc)6flZ07ue+-zKye4MgD6PF%mS#U^;eI!jRRE6-RyxiE&)zn0U;qiP60k%9$x;x zsp~>r-C%hm3gTuL5@P4#|D_HKHn6OXtAm%BD^wKpuPfjmvOrk2u>ZE{m!Q3wo3)ga zgEQ38&FmouMM0b#Tz}#y!fUd_UwSey5(T67$3VC?+6{x2cD zzoZ_Jc=!c5VJr*&&9+}-{gT!HyDYyD7c4?KxVU~N%rCQ4%)I}NZ(ac&ZXOOUPCnkh zQKSNOhq~H0TK%TzZ_a92Kpmk{X3h^2_E2E|F(X>m9_}zbEoUec@(1l~JOY28PAv~} zH>kyL4*7ZhqU5i3X;?D4+xR}r^?w%lSGxYQ|EaZ&J5=2S)xEa?RC(Smtn zX8*5=;^g7x6o9eF3Cp%WZGcHW#PNg2_M)KwYcf2r`G?BCfx~cN`7FTyyT<%o&KYW9 zV`*dYM;>xc{Iri`SFGEkex<}Vr8e8Ecn zzkL3y{jW&~L8`%M$@j}-{W_r#T*WfdBGZ zgyVnZMFh51SUd!(lk5M9rze^=FbZ5DKpA@oZ0VAe(3F(X6#0d2Z}XqW`Zr*a-&Oiy zdHhBC?^~N+i;S$9y&LqmgTI?S9RHY#fA9HSAAgtaU;hmR)`VrF5A=8Yze{UEVP*4S z1qS`*jz7-~ zzsHBg!vE9HAA$b=bPV8s2l*fI`(L{LOV|I1f&Y>4f1~Tabp4MQ_#X-XH@g0RqYM47 zr;f10g(%1i_Dr!5Zut@Hc_f;%yuKR%fPwe$g#%<{5yKi$+!a)0P1{ zT}dj{zEm%|Y6h|cHSv)!V#;<5x)`eh2zzzJWu8K1kT4iSKv8vNQK(^$eUF0i$Njj= zd6LtYskU3TJuVyl4zm?{j7O>7Mr5WNeiq&QDKh%QM~t-GB2%`|=155}`}2!7bve(B ziCx-UR1v0qyE>}6M{BjA7yf&nT2H&?*BiU9600V5=jZ2*$a&TRb+|;dmx)^my_X!@ z7=4)CXOlzIJ@$uf~3YM}fR4{vX8D71LW7J7j! z#96mqMKilpK}=>)%?||Tm6QywIv=Cded`dXit&93-s|z`eEXJOInDX|>E_w?XlU@> zntIWpO4Z4z!P)B77qR@>%qHD8ChRwqO$Kb2DxD@r?%)x+C^4e4*Ae&OULW?T&fmOS zbrvMA8*&Fzc%q%t>RFk;c|_j0aBv(YTlmGcX{S6(mEmpHzEYNIDZ*6(C1N%v)w9Z} zK0niVI_IY=xGSQC6N|=Iw{k!H`IZ8yoM)_gsi~>+^YcACJl49$_b=#^M;u$0bIK?T ztyYyIgz0YKZ=UJ*_XJXG=x9sf+h7DCUCYY2S@G3#zuQPIFS$CU)jEoUqB$) zst17Rff@BtYuo_mo8hcQb#*o4;;Ip@|G;xpdH2*nwwpR}dbedWGD77-Bv_-+-tO{0`fluztpA|r&|G1|&`@#J>$G$I@^M!WzI_i>zLW9I1d-L;16X2m#UhGWi;__}n&Q|}n{ zH%qY|Qk!42x$=-_u{nOrr%BGj1s%V*c$R9RHZ~*Am#?Gz{LLKsY6j|63i6Ar-B)@SFKb>i9U^f05LP9t5{DEg;3vyQ8N({0$f0H{J;D5$)$Q%1 z*iR>qUk=n3v5=mPS*SqF_uRq9?MSPLfnjg9vd5QJyQ7Vcy!^qy_fv>{JAWa+J_uDoBQN3ecb0LWZhG?O?s@RxNd^vSXfxBL8wpUBo!aEz)T!tqUr`N&04XhWxhtqr=vcSf}{`xm~gUQvi}*YtQ( zG*YD6YicN62>OJq9|+0nA<9AT4)T%J8V#zaY-JSm8+HhD!#rmizbB!KW^IFL)X@N&Gn@T|yTXYg_dL+E>V&5a=U%>r^ajU{Ci^`P!}jS-8Y1!ddFYwmV0 z^9}M|Tp3vrc_;Yj8uh#VB86m0Ny!?MPQ{DnB=t0>@T6uG$!(2>F7gwS4~^s{y5C)t~C z`X`94{y|loap#g0jkGnurGqt0cFs(3DGlLWCO0LT^+yfQ=mU$_Qq{FK5-w4ki43y! zzrOM;Kv{IPE@RYHt@+G4san%l6_C2vyYM|5WWfBQ=x`b2f8nQ4K!>JHUNr2(F7rav zUb7?dxcZCrxvwbly55_h?z0nxcQu%tL=2>SZCQLtBZ5h#rB(_G3Q#EBvJp`n^Rduk zl3o|bbH*oODa3~klQ!=YGEbZoQpwo37{65+%DfT!o)*0++iSE7xp)33mgsKSdtr1* z_nxu{n?ZssC6Em><$Z({9kN+=u6k^abmf%f6HEm|c)|>_x#J2pxZ)NG*LWkN_55v(BnAdg6<MeN{=kxo_oo&X; ztRLkarKTv}sKwWcjU6AA?ao_3T2HfIjNIZqCx5BGta?L9F2Fw({ldo@($-gnBu^n+ zV7wfqTS;K#Ec_AK!o|w?8_LxS2M?E=%VB1-?DRKN(d78bIPM=7G%EPty+?g|f}e$N zIK}D^jjLj=V8YyhRp#zf>=cY>)_|A1v8Vnc9rH)4i>eEL`YUYC;uz2dF0PAgl@yT0 zpmf3|O15FNfc>S?RAjyk==b|G_w>9o{aXYiDB0ZZ-2tg z-OmJfY;ap_cw#J?YE~(}W+--!q1|=8ebHb@KMHYar)AlB0WCu6}5PS(85Bi z4sUyzw#FP6&`$|DR03rEy5^%JE(s!0xzPsd(~NHF4?`=h#E?J`_Rdm{a$mg|RHBYH z?|bMC>p=2Sd4N$sBrzuPxNKh>qYN+Q-Ae#AQWtdXYYgEedqItSLueLVewllV=1JVz zx~@8XFxax6&#dk$ytq((22Pn(b8U|zp98yLwOkC6UOP#`+#2$;SL>e2o}G?Hi@F5N zFmxbvtxZ#O-kQC8=IPm>r%QqzLvm*-9 z#yta~(`%??0Vrbx^3jf|#mwcOUU`7C>64iR1&KpM=GwIn=dB?YNHNyM5GIfddSujj zzHVi>?33K&ch78!?^(m7`DNycfjI!uOZ=kkoWiw`ub2^UzCZCOmP{V+UI*ym@wN}2 z&xy?kdUde5FW%1}lSj%8mj@{NrU+U&E7f`y+57y+_e}L4mJ=gSy*!X|d)>Ns_gEk} ztabs_ySM_&yH|7}9*U=DkN26^?5Dz-?~shq>Dnr*=96cLUYfzE80HNTk;5vmB_=54 zJMW{pi{O}QA^8`3ayV6@{Wr?;Rpx_gjRk~ zrJ8&0H6CWUi={50KLtifGRgfiibb=$lBG{oz}%}d&FC)h z>-e-xQA#Y>>2IBZcQrmivbPXwgMyEJJCEj5mC_tPhs`b)KAkv?@aipvUM<`NilQ`&c+F> z-nOTZi?t*M`fBQi%@Es{Ws_& zHn`8`kC0kpot(7Q&{8miIzuigb8AXFV~TS7M#Zm{`HgBCnXwqUM&X9mykAHyyp&1y z?WCOG=)*LfE2vP64Rwtftu#a)U;>lNzFcu$6Rs||TAvZu;l(vDG<4w4v`-C@mX_4B z%x~u-rwe!amY}}%-RHjv^q9Jw3aJ%r%vG)L?onL z_x80la{_^*)MABxt$jrTwTiVE+QH40Dq_X&n2!@z87f`aF;M6{=YR?|&IATuqXv>S zARVV8lnoTayEwS=4Au-$nRwb3X*Zhkwj@)SgE>fswt9W5v;#8zU}(PQDeY~e)3l4~ zUTKw8wvK3fwqSer)z6#mJR9DO8siRGIl0J)h`kHn(g~Y-Jy=6(a`KrU{GnnbE~kP6 z{{j__c)`?#I`#Y%9M5;%V)UpV7|`S_h?4G71(JpcItTl^Z9-v*$Bg9@HT?N`SV5O+ zIywXym8BrzRGsm(P}Bi7tDQjvGdR`dn9BDrk;YS!cBHGGoucaO7^kX8KqZrrzFeo} z;3Y#&R)qMI>_2ft8w;vIjQd#0d)pLrIDomYHZhW?RLtX*6_Q|E{uPeI9Q!AwSv&=% zbr}BaX~&8U3nNSskAdH{1zh~Cyp<-Ij~W_Iispj05@Rbrv%nt)s(*D-h>eXU*}^4Ai! zL9H5|h3iz^G#{9w-(s|AYre%2es;`6OV{M8vy7%7{xpARh$(V+Onf!z|3qlLF{hUtW3LhhDDR$8z6{< zg?n8V_Af^)UL^dW;S!6yM_c3s=gqDlnGhKeLA4Ty-8psn^^LxUT>fam#4d=2=EM8< z!^AX011y;cD>W(c?RRBQ-pGgKT{jM_u*%IO#2LmY`?xj^mq?$nQBBj-b%{SA^_Vh` z9zCwsz5CivV$sm2o)$r~dn>!zYCnjoOR00CW<$ivK?tcb7mFmrN$u?uh*Kz2Id#*k zBWsw|2o26i=^Yh6;G91mFIFm5%e@m0aoF74gdLY#ZX+&yJ7JsQlarIvQ(H$zb~ZMc zt9#)XL@&sNTvz+TZ*Om5Cy032iE^z{I0WR6Xcc3~v$?!r#!F)=YPx{^{J zJ|1_sKCXkC+Yg_kxi{NyMxT(0`kwbk<2jKyzounkWZbE4`MNh=9J_M0Fh6f#V8BYK z1cgE+Bzpfpnyxyksx{ct-AD)`Eh%+rlu$rQT0)TqDU~j1P`bNYx*MdVOF9K+>`~_HkGyeK<-xTlmlyj15dy)c!?kz4)LiyCyIk~$( z^&F0(y2@D-V)63j`NmC(<$%zpmuXBM!tgv)D+*7r@E}F(dK49x(bT#WTPfJUhP|5Z z`dz42E^5@mPaB;gqA&adX?8A1?2s?rRh|K-1i2KfP^Hx92?> zREoCkBKwIrqPNA*-e(e?Pmac(9rKwsW@>(UKBWH37vZa+#`i~pUb`KQboXR%dk?81 zh@Nl8Tuzn0&`(q)mtKB%A7;&wU~>I%np)Ef9o#Rmk+R*SGQ{z_jIvSClX20WySq0t z5R{N8VaL5}UVrfn#X!KV0l*l|;yw4#2`d!Ed{VYB@B1oRGsIY#ZY54R-!_zN}8- zu=J4{TTS)%hxo4b4_kIeqg|Lo0~W~1v zJYS+d{bEd^JVc%wD-x?ntxZLe+edk|gx^Xmm`PbUWW+@dn%Fsi$&M&}>e0(Ym%yc%Gh5J~To(1MUK8@)KSRxm_2v|ma1(l){vWkmTCqy~< zHjm1zj?pHs>T4b|GIk9N?3`6@{oMPjmZ#`|W7B3>0gB$l)YK#Rq21j8_w&ZJU%zfN z>Is7?ySlpgBd0`8L}bWC4q_U-bXuF=6s+#=?1&hA_sh@EC)0By6b^}9L7V1|2tp+* z)yV%OTPx_&qdb*!JK1gPYEwP@A$@9Z9cphVThK< z%GHQ|ggE0R^npUbGa`4IMfbP3xiIH#^T}oa|&H8-R-zt zHNlCt?LIApk!Wd`2NVAb4Gmo>Rg>uEmzG%?s6F)N!S=G1+kB>+Tg~r-@j~On-J{TM}6iBX)eC1HJr?+c1u&u9}aSdYgpx+(Sa(v80;*U*sQ($30I zY|>o4mzT$OpbIWjVb4RxYLR72+9qTQs!BZ#^NE(6m!9hb--GW3b zF4ucO^~L_b6=DV`M}B_Nn>sjg#l^*ig>rs-UnecDudm^l4VnHYIZ4K;oAY%}&7WED zxw?8xU7Y~A-{x>Sdi<0{4Sdg%;2h|YKT?EwrVL*v72^6Mb(Uvu(CZrD)8iE1J1pP zehML<3M5(C?W&*cysnC=ikr*JqZ1RIt%$zu`Zcc?cKp7R-}5=XDo!ycT}S&z>zC#e zmCc~|3^9KxuH<|A_ozI{yvM?x-XD|G=cUkuWlC6MYM!Ne?>=Q8zxR1dy^8ej!$c$2 zKEk7gb!vN)V8ZkexMYA)m+?MWn70=N@&bcWp__mxC1jK#&h7-XSc z;ftQruz`2j<{6Vw?$eKa3M#;f~_-{#=k{A5TZoT>PJ| zx%ijpCE9u{17h@lkC~Q9NY*m@{{<*(YYB@Lb6R_Fyul|Q&^ItJ;c-C*dHgu6@}zuG zMNKkQNmdphWF$jDO^pLgV3^b~41H$2qQ|}TOM(NBulMQ}H8eHJNJ%|TCpE|Ol+fFr z3J8!1=Nx?dqo_O)h^pCgd-E?VE6c~nhqLv{cCOmo!^1;LN(y=ksz7>7j3m!Ns^U9c z-L#HnW)6-I=H|55M}==(TrPmeS@Hk$!zBLR(J^{ty+7X|u;^y@@9*APISvjEFGXl> zZf<3l*4LNG{N`f}!CjR$tI|&974_8hnwpxNud6YFOa7goE2Ija&b~{BBba+rXgOU9 z^~R)>W?b@eq0u2YFmP+4Kn?D(vU0?%6+cC28|viToJEBeD=X`VU*BB70{idX4{>RV zf^QviZjqh#XU0+tTEEDgjk|(KiZsjO$oc;2x^CrerhBI0AkSLWp8fjt5iU~kdRc9) z#;7F^IS##aNN;cN?}>uwy1KfB4`rpLEzmJFG^T1Sr`2}_pauW_)%dqMs1STd-(75|pyn-24c_g{M<^# zpf}gV$jFGuAJAneWV3=II8*m=5pIvDpkTsj5diFmPn-#U&pdkc=^+po_1 zH((f|twL+1lDVzBSm_=S^wz>={zuH=vZ_7?tJa<(ZkZ%*?%~ z56#}cf9igDQr3DSY}gqvIH)iYd|)l8nD(T>xG(DZ-&u#RgoMO%f4n_76moKM*4E{U zd2Gzg=RIOK?X+zSOiW_eC*#Y@%ZncW_LBH4=TG;A={ON{THP+U@?4uep!VRPtT}ya zZls^JPlqzIrYG`Qa>@27}a&ma+wLZR-g8oTWUS9s?%OR+zzxxYKE`K(lFr#+n zDoqBY!yd@$=GWJs7v!a}GBeXm7bO1oPV{0eI^qyz?}y1i+}?ac^vNsu^zUF`t@W~T za_W`qw*y7gqDjW*d4T6%925}{-L20x2y?4Hh6Tz80|R4Z=d_$i($4M=v{}#dW&g89 z&(@qA$+dMfbabU;{`bHlx3;$6!y{04pw2B@&+It{cd05XmqV?DQVOIAI|MltGNrrO zP8Dk#v#-Ff2gZqf)RdExqmnIcVr*=`Gd0xH)AOP30J?Fgz%K;+w1^0K!+xrC3rt#^AlJ+0@78;I_M_sPO5S?=+wv0GFP1EV9KvqGDq>Kj&hDJx0C z{~Xmn?Mr$1nEyKJA^Ix9Vdzz`gZ|?Uf%b0{SrIpVZe(sgkXUhJ*_aHmwm1ZyrQA~{dTbmG+z@o8iGga&{laHD2 zm$tSNBO(w!e9g*QnQyQg!KEf3(B~r85-ZNnuXnrPk<4uqSe&27!SC+uwBMVHwfh2W zBbbcy`#|E5DNQimTlqB&Y`1vmzzBt}G&O_C2v=tC7d>y?EiHGTDF9TeIJ3Px*=oJs z`$!N8UFKhD(>?{il~z2*TQ@hi3`;%^j(uoV>`VIx2e-!qoQpO+Q~<25;BYL*RZoN= z@0Y)Tse5|$XIRZ!gl00L2OaOhc^fjm^|`{*ns6$fGA*>LCi^WOvyluIwXemx&6m+i zqU|lSV`EWqania)aPvX$`0gc=ph^ECZ1-m!XRX`J-rvmU{xC_R{iuA=aJR?v@EiK6 zg=|qus4{$VS6vO)p*wCuS=+A35d3=fQ95rtacE<0&6wa?tKOP6Yb8>F>Z=l-uV5{?xm%rlamvh)$S7QstrIU*=be4JOCgYS7$afXctX7ZjG71ul2n7 zlMe5BWorxb6DJcB`d?3J>275FCkSo`DTv4!;qCfd$wMkCD$rIEpST=1I_$)8>M05r zwZ%tAMKwAdD1NzuNvi9-{23Z=Pgj?Ld@L}fM3`|7jqtue-Z`Cm^U?jNi|p#D1Dw}z z(Mz**QFk|YcWrL_>`^mb3SS=|RW-GqP|7n<3S0jC5aAjnAl65th5|h~8COzD;$;yQ zPO4@y@J|>rt(u+Bm5+xj7WVMzB}f~>?w7m{bjb2bD4z-<9LP4W0`5hBmvokV6b8*w zF|Vk!l$4eVQCnOQ)BeUS{;?Y8n_ykiq>MgC9|lv>O_UvJi|$OUPhJX&G%9>G_?bBQ z?5=T>Rq^EJEtML6Y(?C!R3RVY_vH(m=1ie%;{Y#SsdG#sIu!CyY2=u56B1{w1CG`Yw?Cg}po3|BC zg_Hkzw&-vmg9l%bxd=BsIvV+H1STft!-o$+JB6b35%VAXR1K#U0m&UEv5k$5sp;44 zcXhK?n?F*2mK$_L&_2Iwrwd{sn5M0EakduvO`ad)P>yBkE6g!w1p<6HJ+-;Vp~ z!=Lyh7P={UT3BpnNd+SzBg3&P?)}N@adn=T?r|9=vd@*Ma8;B~{us>{kU3&P46wWy zKVo4%ilLbbqw(?af?8%*`M$nB_sB6GAfu8y<|!2Wf}~+kThu&k38zR*`~JlP?iXYOrkHpQIe_3M{96_c%LpmRXM5!;j;>ap~>*-v90?`nrx zHdVGXTXqGa0K0qRvdN^UJJ}yK2+O1+MToj>+gqLosi+?4jQlXy^mKdun&QxUcF$2J z41ytnfq^OQRyD6_8KujnpQi(8!j$|4*W2BfV5Eq!Y~BF<#)HQ$4x3xKL)$B?t=+r#rS$_QJkWeo$}4ljwT3PxauzAnV(n zZBo^vz&U?2ES4>~yvqh!hd8(CpuZa1^vFhNR!!yJx8Hr4DMMGc{J(x~v?4yM&BOEvwA?}wN5kWvgg1T@x!bC|;J-plpidN0|UN+CG7EH%0(#Y zc6N4?n2GmDNJ?JUZ1=~qaeg~QnlS4b^o6GW;ow)Z=f9teHy6X6qK9qB(CZB||AKV_ zya!ZjgPuEm_2%Efa1vipL&JqHzNqt`A%TUPOW}L<;Z!1|O9&SJ&!ULmbs;|4-QL~? z;GQ8gH#5`AeQjiD_*F4ANE-v%NbU^-MC@Q@&a{ILQO;BB>+6e-L+(X2*xQ?-$_GLt z{sTd;J%yk_ODS92(ofkSh`&n`xgA3W+77SKbzm zn!$|-oqKjz4VW!S#EByj9~3+d9i5ca)MhwFdQdE&NKIr}0@B16yW%o+w5XYDYiomw zJKY-h|0WyUWqY*J1^>=D>Xc&GQC$%yZCQ=L(lVJ9 zH2zNgw|quv*RhGtqcwn&m<>Zon5@fW1H~Xwa>S3pku`0M*Zs(YAYG2RewlKZ_53KO z!Hg#n5W0ztP))Y}>j1VvtSJl$bIoEMyIC(xv@k|#K0{Ua&z!iJq;c@(2?#P8yDOgJ zNljL2>CgqJK2RmyFzk6okU<_ToU3`S4B5VPdWX9lk4?b5<~0D^ZlcYs!w+4UCwokD zUq{VAOh`q7WxCA>Xyvn3Be(~9dsI+pLdeqAXJ=6$*tWGGhfaOD{g$ey=k3Lx&8lw|clwn5))?>*K(=JW#2p2S zCN-~tJK_0Bb9L4Ovbg`BDO~@%=~pwYYZ)#uW22tfp2o!uA1Dv50TX zfokjO{({NKsZ$@3p01~+hP*-uFL>8r*U2g=G2!xou?W@?kg4NiTfsMYRKmQLQ|v@e zU;O>w85?K(jZRNrq;i^XudEA^HUa=seh~qf&Q*X4ujgpBCpajmGuXtsJALN>#BD^g ztm&PnPo8LDOM>HKVZo}g0ISOvpzJU7c{te4 z4}l8-tnH1YUkUySydF4vX(@ynj}H$quEEE=P39r?$s)~xVXGb5wrox0sfDbpHgC-V3ydhF(St&v^UX2o+@)S^yAxs zs8N%W4>4?3T;v(teerv%UaWCbImP3V?EP#Q^e7DtDReI?h1b9+{4v~MX;8KdG6ZW0zt>sJn_d^4k|3uPhHC$ z_U1?~nW4334#yOB1l0ES%Fw(=C*>&jM-m_qoN4~#L`0df2UQut8l8~vduuDO@yf`^ zNW^J>(Dv{10B5i;po6fIq@g-P9i8kq9sIHzewwc!(y*zat`3NY?dk=BXbtqEQmqQ4 zPsuRdJpRtU8y_3n-q~6FbkGc9UNv!wqnP#dmOVgrFK=UB3g8w%x?TV73Rz4r$Hhh` zCu29Xu37%*?*|Ng(&GLPIJ-a`{Ot*RkgIVbaWozRLVqEd*0rF)DYE1 zH8S6Nd-KWJcqBstif~mS0cgU^%nW!lUgoR7!Jw*3z2Lw=ce*N(Qq7|Iswlm%Wsfu) zk^LfkV`HPXrbbFq5(h*Ju(Hz9($>z9k&sqaSGkuwpssUsaw3S0R=Y!$o*bc2IKa(# zTWK6PYXub}8ixy`Oge9#GtlU?wCWAJu%Q0Qbe$3Z!-M1b1)mxW6>Jm3)z#HJg~Vs2 z%Amk{Uhn96ULC!dh(7u=EEW$I>(&^fkWgZXb|`q%Q1o@>BkYOMOu=LYcA*p55xKvj zUOg!&l^|sHBFS#oSyId+Hk+=TLZ6r(DBGp~kQG2?6orz|Q!J|KYK}7lN5Y(!qW(BI zCV>!B4q=noJ}F7z5y8XG%JBS)db))HLS-^;eJvk;_M?}Y41WtqXu0rttKIZlkD6sF zKa*8hnNKBn2fZ8fJT6ccA#HM*X0!H1_fyK7v=}u+GNuUcGBkK^tR;#(YqVcjSlW9X z9~XzVcCVcj?LAQ;9{rq`7ouZ%VIh`7mfHR8!(6>4N8DfUo;~w{H?3gx-rU?fRYz6T zcC{PVw$AYSu!q{y4YUhD;9I~WZB##oO0VXtWD7o_KEDU^+5P%-8Zn#b^yQss1f^8< za}Q1vfGNv-OPTA3_!pjnWhpF{LjlFGd2g#G=cARy+nY1MDR^&9L~qVlK}b0n_PqJeMKOCc z;Pjof_2KW)?7mDr9i1zXVO0)12jU(>+huBEfs~X<| zZ5O!b;v)6#@1-&DOMvW#@6IMACu^3x<^!GrIBQo4*a;|`om3e67SJip*o(h?yNcKI zm~C<@V~~ZO%5c38R|xDDl(x6oqh3$+$1GSu-vaq`(t`2bJTw%5)v|NZZ<`#41_$Ts zK2i(*IX_wjP$VPP4gg$v0*|shl$e;f!ex7JZvpte)JSLZOFs<7E@pM^`#j~P<6Gq~ zt~6N?MA*u%2egqiF~k^f~rTbqQ;_-gB-g~BCRQv z@gc0wE2zzIicw}erqB5J^z=ROz94j!%*QoaplWVQb^(82XLud-x!x zA*ACKc91`K@PLxCD645?Ox{g};=~pvvA#bmgh8yAkpz2Xt-30aIP_YcIPPk-BqHh# zfq``&ctbv$6y9kT3etKG|S{l>%?kW|825`(Ni9@T4b3tL+~p_-&aDfpZZm+p8Y zT)OS zacUz{v*zstZ=|HUz!dPkhEeJW8ag!1M@%6aMO}EHeS7)&MlmeZ+aPOL)0BJ$+)GrC zyvUC=uU(g#oZMv4@ny9qT(8l-06=SIX8W?W^QTY$E-tz{JIgy0Mo7U1CjH+R{0}+# z?}G!S$u}sR7}$7+(`vR7=zM8+y%Xg5=v++5n=_ojd-J%yRJresii)aV8+|VzB_#zy zaYXe%0>O6PU2LUxYk;}1#%pD6j#w7hh_2J(28l$&7Pk@&N-{EZ$rWS&`{_S2e+V(O z&{g;_OkALbd8vMYF3BFiPL8YpesCqt%1c?>4U@>%w%@pthN>Kyu~ay;cq2r(RpeDx za!sCo`Y1c^SSgJVmm8;GjjEQseDI{j0P(F7M0WM)umU^7TmR5aszSi3#~=4W;u;f5q* z6O-7On1}=xsJj3DBStubd&BtXkzv~zuq&V_{x9r>-vVeJH2v@J-`BjnXq2LK=)Z*~Rp}90>SdP>bOW(b0V$9>%A7oIrp$`FyKiP|WSz+QUQiv^_g3OT0^u zOFv&;NnL#c%oZ)Cyh;R^k>Z|6RAz;R@rrrLQ0K+kRrz_ST~)oS?d|RG^Jt1X_l$;P zt1^q7EHGuayT2G>5VT1gVI|h}S7ON!un$Zwixt#+JsptmkLQtm$$9enYEFxNY2eHl z`TTSDeZg&iy0T>UZOmgk_*eyWu|#hSq95=hltDD)>(@tG4#|x)<@Xl*hEsfs)dhsK zRbw28%3ZDVMTkV|yw#+=h=*x0jn;lLS&At4;7m3?YTnX6R93?)$2OR7^q@6h-z3+a zFyjTl0!CWhJq4-RTOWDvrQPTowS$0Le(j;*VNOt!+)9g!B_ny|{e8y)tt)>K4#vYJ zyl4E&XXT}tAq4k0#VSbNgBi}j$+?Me29cH1o#|F^)du1@sh_%5@8mZZ6l~qiO7I2X z1{t>krF6SGKLXNPuglzz`_ReBWdOA5yP*O4F{Fb6-8?}Fg|_Ad3IoV%`bSinb3jc2 zXv4AdPsJL6-oJ>4QqG+j4rdmO8(_Kw4*l@m4sBkDO^$m=C{9FpfF+@*Y6Jpoa)A|8 zoXk}?Ei~A@+eZ04RYJ*h--`rOr9vT~dbz`22?$GX1g*G-`sX<|jc%C*jCc1*Osj;z zKsY=AP^C~JGF70)bc5A+r~_52rR94phq`)%I}4;LXGnUq9f|0t-JJ!m41j#@8OMB0xFmy*|e z$pPs5&i1xoVm(1@(0RCcftBK8-7tIn*$PlRA%~Qo+s=~EW!Pwkg%;J1ku`+h z`j9$SsKX`M?Z|_~1WQZP;3e+yp4Z0eDls*+=igoJ3>U9%Et(&uUH6q$sE(=HeWkN2 za&u81H8f_ypZ*AgKjwF?B6rLZBi%MK1+e|M_AqE1iiRQUEB3EhUgbOb`2Fs2ux80CMt{TTu@q#~d#RZ>}L zJO1@0pa)-VV>)_7!L5(n)=u=+uto(Jk62<4x&Zjg$1yBw;1@3h>x2V>+)Q;c#IqH* zLr1QLrt(`5vg|$K)MCzu`VJ0!+pKsP7{3==Z(-PvfvQk32ELzC8F@)mp4dzWE?tz07-tNid22)Tv<|$43+a}XlY4n)cWM?+-5@p z6u&eGrKbG`JnDOSMSc9r|1?Iw49zK?n_E{B`-u^05oqMJvG#bZUd7uHX@9Bki{KVF zwSdnH9Z5xnFgAvh5J_a>oqw-1ia@?&d-*vnEC>p`1~_*ToP`k;=VfFapJ*IPBg98X* z4n_$VBcoODy{@;5%34mw@AtM7e6)Ax* z7RD&gd2~IWLY6a^VS;Ej6_%ln=}(bO5KhFv$ms2kK4}mV7}#D;AbuwzAXANvjFh|o zbF_{HjBT;SC}9%-hAZ^j2WH>bHa6m7VwB(B!9r7*ch12ab3Y= zi_m8ApB#Dxt6W0}>W3T6a&i*>3$UNQXr_D) z(lUTx6^MwSy8~sP&6OupP|htcKRjIS09FAEqpNcPGV@@d0fkolWdVnOB-&ulXXT5i zXV0rHJ9iZ_^w7p?;=g(Il2M_J|HdH}+?%@>E^J zv+6pCf@@xvT~l+tQ3#EptqbTAf_bb#pj~Vi;vfokqHcSdlOLc!;QVT4M_>sa)qk|=Y0X}8LAuEZ#{ z>`E7LQY2zal+1m1XtGdXxO^p&w{OY7l&l~|AS5PzMs)wr19|b!RlX*F1M(-HHw9BW zE~(|gS~X;dNrH}~yvv*BTHHl?&7vY$Ro1W#U&*g$*o8fb+9Phazv@Zhfj`#h zxaSHjJ?chGS>`Um9{%(%d4Vz-5^gk;($}nXIQsCN;Pf7VXd&=n9x6A#q~xWnEMjf~ zYWn<#IzSNiGvx+a#yzkT03J0rH(`xHisB}akhc7%;EHIpvhecS!zwZ)T-M5)JfiXQ z_x?W%a4k$yKTs$zPjs7ag`D>Am$77Hffc z0Dw5C#fv4l9kDr28R&o1h>p56?7F_sap!R`ogjk@}BjW*JB) zaDgG|mI2X$QFEB$y@fyMXk;rvZ^4Ws_mE*>NQ^FXXOLaLYSzolc<^9oC< z(3164*}r(?iy7zY9}_;gw39JjY5Js{4S6%4g2!36L-(s0vXMoeIXnoM7?Nt$QB!-4 zi+VU5GS&iOEV#p5$3%(ZIP&?1v-A|9XvEkn^}kHIwsLP{g3Xy0@JKB-B{B2Ysq!I} ziz+z4D9g&i;{DL6@+3;5NNQA5N(yzt%}?)xnVDA>F9=L``My`--lwG`jI~Jg1i1-y zwY3k$Je~lAZ-bt5*KwfHOioRS9(58YR0gQ(P2ODpyHj}KlI5kj7DAE(ZXMudNPjTL zKz*t&-PyEaw->{pj=|Ae7uonpSl@(%3$dzSAmSw?kcT)TCAI4(a2b3DKlJ8ux;4s^ zO3<1nmgm>}{8b-Q`Zu7$6U{m*A~1YkzQiT9I66GM%WT1@yG&>s#S^6#w9d%S$3WeO zUkVbjS8gxYPlSn60tqy^qM&lg{W<(5kcNaG;1xc(08yFt;huAJHlRdfZRYZ8kPl7T zeNYKX3iIb#JdCWXwnnqj`BLY%?0r~smQp}_b8JdwKusFj0BC|xui#L9h_0lf64_-) zdyOmpc@_K~Ya2gh1Alhh)RW++8}C6MW;Yx{uJN+X`%*VyvB6~_=BG1D@0!-gJ#KpCufZrad9)={9tQB zef}q-Ia2st-};~TlKr~~zmeoPCA1)N(k3hPeD;t?HLn1aF@tpQz*zQO^7%0hUo6U0wVosLfJW)0uFmJU&> ze1^oRs3_o-kkf3$Q^KbbmfX7pdDpOU6}&ajI*`&qnN~^>^xm@u^O`R88V1mkW@V{_ zgVo2`#_&>l(_JggQXOwh9J8JIhCgqe78pIc+StnGRJ@Z7?irGsz#0RjzmQfsY|6vaeUra zv1OWT_4JgG@Me&OIS%&m1qhVU(a{IZXS#}~8XiRj1>jIyhd+Eu%BlMVq7)o&8_OSV zfB%dORm5x+A777YY^jf@qzSXr??9sM7cXTRb+$?hPfqIwx;2PwHWtgotd3P)kF zB<*Gg>#Lw%s%L#}ZM}uyL{wxX?J)+hke}7&;}Bp&nlyg(amLyjYEm^gA9(MC^g+U; zBgBKw7M!RZzH6$hKY+O5kFO9wYCEUrKL@=NH;2+hZwJ!#t)L&>W%hoLB0oUHl2O+j z2gmDZ-flQhYn7Xu8=z=6Xq1q_m#qsCZZS;{V0%0Dv0q52M_-xHkM?Oz@d{3kB<5oJ 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%0A5($XR$hwxMQ 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

    !*Nz)&H{`q@v|I5p-eQ#&~MIsLX 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≫sv#1&Abm_|rflIt3j>oxrYWmr zA?R?mn){(iAv1yW>Dm37SECr8_$XfROYq>a8*b}$^t|q0`Bct+MBeP;e97|tlSs8u z31|6fV@`CK!gxYEdDMyFY;f)kNZs{nBMPv>Ea`wE$ojQK+^s>H=qF_a82j3UI2dNl zY!Lu%!eq~(a|9Xo=e+BP4wtV*A>G!8c5^5H4ZtIIrT9$6Zr5`_<-MG>uQ;3&ceX_Q zB^xgkB4`pM@iV@ALV+5)7Nswl1l0Wl#KV?8@v==CGyunt5~{!o&-80BlTsEzWqPslKKR6)k`I`MnRcW|6>wHaU)-yg2-Y z^o=%mzLmMCBUOp3&pjAXnahi(^;UVJz>?Ti)46X?ve;J{@JHwB+l;yDAR05;zm_S zF4v~@%jO)w((x1;ZCe}$o0sjTgaHZPGz?9sq(*)kf8F|If;pxVzN@jI994h|C0xG@ zWnvQEc-W*+>s8`&pk*(DQ)w__x5-;g`x;(jmqtUpx&G9WB? znYeVOLZpovn^X|?M7|PZO}>xcF(2_P2`jV7{k&H)a`qa}Yf=|=IHIAsBl)n(^uf=G zzb9?d<(^_nl*?W4r0VWj;sp+Sf6+bQHAmoR5B?n)Pep#0O7Ie7aCn0&6+rPwk!5lz zz#`b(m?2^li@|2tos75J^Sg&0vAJ~DB^oAk58L?iGR8jXb-

    +62J>tfq6!zB^bP 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

    4U`&WQU@M1>(ykrdix*bUmjKAY! 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 KMNUMnLSTX*eSXmZ From bbeaccfe95e8e2cef478a157f56c6c40347c7a6a Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Tue, 30 Jul 2024 18:34:50 +0700 Subject: [PATCH 279/291] Mac: update fancy dmg background with instructions --- tools/osx/rtdmg-bkgd.png | Bin 0 -> 399285 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/osx/rtdmg-bkgd.png diff --git a/tools/osx/rtdmg-bkgd.png b/tools/osx/rtdmg-bkgd.png new file mode 100644 index 0000000000000000000000000000000000000000..23d4342905dd9619bacab54e8a0763c5bc411794 GIT binary patch literal 399285 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ⓈuDbA7kQ^wvKA-4EaOFgO1!L{G%#b0M+vTL(K!-9 za-RR2f?aQoux-OuIq>u5XL6aWnd{` z2KL`0M*|SeD06=iun*rj(i;+BmnVV(i0AeI-4`)YdOD%Lnc~{1Q}(%fp@ItC7rnW_ zq>$;^Ux>PM7d?5PC^YEjNMt0g=q>)U%USO#5OLglQd)s3)7VkO%qVIC%k55;$_oqp zR7t*u;0QNS&F#PH7{7_$B)X7IB29=wf}#JL`;HN~auBY=}fX<7Su8bvGI zbm4$6^GxGCNs<)Ou{y)ko2Jqo*M04}dWogS7)-cTMilSXv_LabwNJ*6r#R}J-dZ`8 zdeDD9M(>8c@6?T4G>8&U8f1%=KT1WE8(VikxJ0{hdt1<%)Uj2!y3v`-#)nq)ytE*m zj#@vY0ua+mnaoyxvhnS1R<;3akIH`Khq1>X91^usMZo=IkVe#=n2E&hC;-W+} zRN8vW=P_z)Yq%-}$fQ=55rNFp|e23u`fLXny@l$Sdr4lIn>jqal$-Ji*w zk+9J49DX_0qq_5!zVMT1GQO9j`PyW^B*CY3aCAl$zr`lHX#=oRU zN8IQ7nXk}Vm^KL*p5GeUeTdqPmw4#^F)i?yYngGMTpp&%-Sf;oDt;UD+TS?0d_Ttm+o1mW!MV4TRuM#K8rqvk_qsw?~*OL%SN1ZRE1Ezg>v9hg))a-ec2 zV3{`AJUqPmuTe?dQ*nSOfsXp2<0^6rU<7{AVROaWBosTyzYsf~V68&(JZ)s181O4( zi%xCxN7_}J0ZKx{arrJ_A4{K>j*K(8fkO?^KHk82SNfoqoK0H=dj%T*aXDmgVX8U1 zy5h4xxXiz8JEe}0>&CZ#_59&65`7c`Eb~NrR6Y&RGGo7V+{o~Z17o`s9lGKr9*h1D ziJpzI(RRcAkuRGH1gM34=-fx(2-IkLoIb`Jj1s#!y1atnpbapBum@QIZ}cBRbI+*; zww!GTEEe>UGWDaFeb(i&xEps@!1GTdZoam|j!NwF(&*pJ;u8%cHE-(4JIsDG1qnX* zAK1!)U5-ac92*liun;6kaZ} zyQ6mml!6wO zvQjp{;W=ZIljyl^WFOTp(^U_O3(?==47oK^J1O8XQG`tK+|+onli>&j7d9e#SpkNg z$mmm6U7#T|Vvl@hOv292<7|%6u4@X5*H7P5Q@V1e*hCFi;6a93ljy~Udd^34#nwNn zV5hVcckcg0@@KmkHz^aK55LNTU`0lNR+R6vgaG}ef(R9p)gn>yUBuwsRlx{y#P2y3 z`j3O2aM2`rXn8^w@2t3j)17QU4q`4-xM6WyU$j8zDFwSaZiq|H-$M#EcmKinhV%TBy)F-uf;?T#4rr#sv&FE#7Jz*2efZTxo zl$Pxw=LApDE2nX&^$d${3(? zr%zjfvHY!a4Rx3yFJqF68!w5jZ!z`qO?+pEf|Z1!!{_bLc%b85fjL4Pc&e2 zl);?1yKuYDvv}kWTnG^LzpahqbD_Gno3V#=6yaNP-)QMRmnNV~UK;4DF#c410<~F~ zCHg$dH%T=?#Wu9Pl%v1}N$`2c{w?e94Qs|t?Z7tM2KDs7OVt+dq%Ri;OtbmJ-?$#% zB!+8yl;|OH629N%u9?co3tq+W49%Jb8@rS8Pa|VtTRyQs8SGPy!W!CZs(d$k`l^TI6iP?9{;1jQanh>D}X!zWe|G z&#tz-c2&A^~_dH8WIHWV^bi+bms~qNtd6xjrN{;`@F{6@!GzoW^vlRz$3IX?T((HtC`!=RP1}tQ9=m)U+a0S3Yr{2zzMM z;jgsFX6nhUL@!MUR&&LcM$9&B<1yKzHR&JkmQ6l97gZd#keVeopA@D{nN&BsW|zG3 zCmEd8D48dIL>AzU<>hfd)mZtjAT#r`9G{&1s@!PGh*Jvo8N1u=?0GTFc)U}WkbH5Z zkFNj*cG)eD`CJ|JIvP0Bw_HnYG-S~Vl-F0zC_YoD-v52~kCoN72*@OwnfU7wVnJ|t zG3#A$-~{j`k~Iaa$p7khs;GEC|@ZwdCZRo`Ks z#v%`1IjnvkKQ~44I<)H}Y3%pu6#N^rtx8u_C!8=b za%-B~^SRUZ3%hBv0t0~*^GzoE0d48m9Os1IKTUlNaq}Kh)!V0ooUu=XKm8kBaG+Z+ z|6YE0_MyRt(aT!)f&MmVp35QV;{l25K%dN=TP3oMpZVv`w#HMLos3yhPfL%xuOI2t zJZCTyQ2yKdt`CX{kH*Qx$83Ml2Dghsy4s64dxy(x|6i9U!w#arcJ^|7Ab-XD+pG5t zAK&kP|Kq;d$N%~Bh>NkcvOCY?VNhqDU5$gs;MI>mhJW`_;UE9wOT_EA)lrd`a+ zw3(Yta)Z_2is|!R}@!+t1Zpc>)$b`!V1eJwdp}3 zdQTQCeCO@EGZ0m%is;YkIy;k`v2b=aL-YRr4fYD_PlZMBatL8}YymRu=#=67a>;(w zTM7zumsSNLPgFbKI9UsX8Uh>2Ia|+i%{c47RHG;o%~Sa=iF)m~NNZJUanD%2>14Gx zeo-8X=WS|8$fg^9C;tAL4macyIZ+PTFPdF^Gg&RN7|Si+X>*T~y}*4Dz)^tea!hlc zw@Dy@R2z@I0?9}D&xEEw9vHQb)vH8^m^#|NuVvoZXz_F5T3b4IEx?f}tB1DQ`2>EJ z@n40h^<~jYi|6Q>B4BIWAe#jSLR(|vJR=>msO3QBqGwJ>ee?VxT3YEfIVU+PqF?yi zVuc&T}QA zbnVJm+ZPSeb`M~fdy;L;e)lwTmbE;1#MJg;Raa&}WmmSYeHNF|>ot?I{kK9_g7<@g zG^$GRPIqzr9@|@k{l3r3rXd#Hl2xwCY`52W{KZ$6GXDIWTph$Qzp(FzQHG(U{CgCn zziEf1Llr$!LM<{G<81SsZNfX5xqF^hBy^1>IZk>b>Y568MJjvoAxDboyk|Ce@Hb!i zS-F))7rN8mn5}JIUG51*P1M)SPtJ}Ly37UqCDJf8^MaI%~UT`4dem_ zSI@z038GQAFA%LDIvju%&QbsQ%-MdoYS7GrPZQq5!w_iP8=J+ItPhbU!jrQZ&sS_- zzl)9Bro;*e(hl$Xhzn+@4dV_vUPFac#XN@W8(%59eK3X)BrhK%FAM9o~ic4l>ViF0Ip_g1+og?KxOJ4=Tm*QN@Tg4Yiz_`n69pfW}kmcic z+K=;{Os008$J2v;4Dl!*rh9g4u-(6{DW^NE8wSx+)xW8ar^f9i7H(RHL?ZO~M{4W} zr6Gl!&P^3Y?6#BnB@3l@Z7Md;{4g3HwaQjvd=YnerjVkFCZ$J?!Gu-h8KIqniN9NA z;aB}=PH+JzhtlfLhX7XE5hZK&6Lr_s{j@PlNCR4J=eQa3);#+_O#*)xO2w*Ei{6IY z_Ce~I2rmLqljk+-18w3}QlUv%laobB3x>ax8gf3>H+Qa+)!HN+N_l;K?V{9^2;BXs zc5a{p7_a?yf6FxcVPNsw}G z0w(c;6c9WWHjf~QzXfkd$f7So68EjYQHQ4`ksR4!I4PA%lfQ!ZKJgi_*FE3iF9WI* zkV#VZVV&e|acZjM#)4;p7P?P(fx@pKqrA3*zCohp%U23p^7Oad8c&y}=u=-s(ay%U zv%?_ACKq4fA9DX>-M7&A2UDozJh-uO_@rINuCad4HBxX^Qk&Ax<2xuG)@a zGJPI)+S}_~hd)?@1-YZYIFF1n#G{*#^kQ<6^F>PRv`1D+Z9`nlvh!>xzP#mmQCsTb z9f4P_i&R|~il7AYZybS1Yo3g-1Rd(@gT0(VQnXQ9?320O zPulD6viI4@qneq`#jn`!rX+SypB}gjJDz}hjkcMgQ{50u-ehCDomzyybX9Na5{7{MJo%C+_NudC@z&Z zSMxjpfF^676e*}(cH5W~#mii7>|OO#bf>o|A^A2_18d2$*CLK_FszUP(VuQP?d7b_ z=Pdf)E3Ubwn_}fkH+&5P4QjV?y*N3;K!L-j#Mii!?N#FDm)3{k2rVc$*0812 za)sGdr2ol!>2;;VQ{c!hLRqsUuAw}ag?AUkee8UIz1&kfaW^gs{;d^@@cDjsWniI` zkx>EoNrPqoXz!nk;r{BVoG??QNW6mG2venoMQsGx!9O8wJe2!Rfy`-#Zpi?_xp_4?S!w$HZzbm5oGW zlHa{@@=?oP6(tpvmiS;@5a$xhRIT#VGk})}6+8*&(sK(0M?_j*b#ke-56|O~&A7Gv zz*>mSacUI0ueMY(Wt8Dk8XlWW+Tp_|NUM-|vo3{6C1({)_xd}VuJyin{8yy$MV6-* zM)~!-#~8)U{9~tGD|$N599h zo6XoCJ#BbJY_%xe-jsb~RJ{6X_oE|&15++3CO&Ua;@PUKXu?T1Ll`?~SGm={F>AE# zsVk*ppAAIutaWv*Z`U;+pFp4ato`3aMM2a3Zx8+{ve6RStNN=qOpVfii~~kV7-dlJ z^?{a?`6(QP#7aZYm@jfw*})tYG?3)Y1hwnBs|lI9#hZcchYz2Dz_^G<_Uog zB0PEPn|&oUTn%WZX9d9YrGCeA=>qS!|6h&Of<73-kET4F+>8-hX+R0sG6oA zm9B@5^^7-W;03}t-Iv5Mz`{=!5`+CJHM@WJc-G>;;)PIpJxQ5m1N|}e3>xHjVV^11 z@ln$7DeD`m%mxIZFTTcXFI>QRZks3&=&zE&s)9s?=XLQ;` z?G7A-OelW7FT3fe6n-Hkj5Rp<8tdl;!GoA|sPK85ghH@{+ajkF85ekgPl9HFu159? z0nVsxr5M}u&NEPZ5dt_>;<=srQnHr1sq(5`29A7G`{0Z*6MO3RHLrOnJ>;5Nc)I{V z7EBo8*g9Un4nOSQmF11ILhY)VcFDa)@YnKZ|D$FJRhHoGGmAF))9ba0knqg8BC%lrkOl*WV>d)&2k*D32N`k#JcXWVKWK)S(P~&C-0J%F zLUBur#(Jx34g;I6R)|_F=C}`ya__c; zl>{g0uSY0<8o-4PT4*r;?LCr?CQi%=_mp*z#&L$Uzz^qJwRt1!Yr74^Er(Igd|^or zmi19GlimU49*+%=RDABm-c6xASG)iif=W6uF4gim0*Qpp*c?aFT(PG=Iy#1_%w}|ZVV_1QuIUh*6u1huc<0{pzyOQSN~TlH~O~c3r>b_RgdQ#eProl%#$O#kqIQUp9 z(HXl^sCoza`62+5hRi`xo(Z}S7xk^7r-oD%B=R= z?9^d$RL?fKzDVIc5zw+AAz(M9O$aCzqe7U+@(_&Y;DvK>&p$DC2#8D~bsJn5Yv`hY zUhAdDI*uIA@82;d7^TpJ?1z(CM{RB~DJ4w)LimWtlQ}*gP=#%r!4$5QFJ@bBn*Lth z;TZw6BbZB7wwW&RL|1=wQk#!iPZ!0If zXWbxfhGm%>6bq^wJmo=fVlK)Jv6Rn@ssX8eQn;mAtuyn&^X*qQlARKkT9~OsLeekQ z6Yu)UkxnVP5k-+kXz-kGk1Pb@H%oM=-=ED87ygMI5w=vj>fUyYMZ_R{T$XZX|Ei;$ zrUQx-AGF8&r7c`XLA z*@tfQMy57KlIm5|=&3Lb&oZCJ=Epj?A#0L~>nSAQegJpmBYJ81goF1^mgBy!o-t7$ zC^Sy=?>$&$cZHjJ4VO;Nq2!*i(k<$lon?{-vcJ)*hh))Ol->6$o`yJwa>pNSHp7{Z-9wPWDql=1SPYBjOH1Z6zLn z>HDdz23ucj2M9Ie6c0Or}87R6c)Z?LFPit zy!RreeHg@jS*A^%tNnSTBv1gg3$X(j*4;6E6Ppm=RznJQRFXl(a*iD8zDxhtv4EPe zfwD3*%{yVb1w%v6By{0@*S`Fy*jjTcNToHGxE7nt{8BcEHKg0Y24nxvhmO4;%Yk0* zt86LWDG)@fPUT+X&i~3AD~Zr|UqC1NrDt17`V{!pxap#9@x*6QDLrp-@sWyI>N#7R zL33nLM_Z-cEKODiNl|{<9P_Ie2e=xmw@wc%!gRdZI%uz(!@u@21^RFsJO21far7`o zs4q*KUp<)I3g;UcI97JihS$DRdjAZD>;chv#<9DP=x8|1Q9j+IcmFrF<=s5V{hX4N z#T$yVs&~$xi&}$KZS$U2rb`t6XozWvyI+0GN0HL+Ttz94%983sI+(pQ{Z*24_w4@k zEN*XbKTj2>o#I*0wFVqGJSZG#vT!;dKYFC0MQu1blzgiu<#J9aEn}WPNA{Jz{c*S6 zoayJL88M4ODbv|r#vVXvBgJ5*`OWAb=wPQtNKB9jyO@T#Xk8vr9*7lo?xDxIBa|^i zd4`}oBVqOu{14Pwel=Dr&a#$HfXm9yOV{X zl%sxtakaNNgzI3M;hrNKV=hKu!JAo+Sw-bl%+-?5H_7#Nk$^a~4g!oUFrH2KVmpoA zt)MFI)}PK@NevqfjLKk&Pbu<3fC>;XgY20u9kbUyXW$G+|fZ?WcqAk zG4UF$axJb(5RUdd$RVn<9$xgRBv3m$1+kQ_4sE~NyxLOjtSdQqSJ0nt8auTF?gQ#d zvl@2ai)G_W>c=d}947x+GpIWnbjU|@JefUf^J)j1ZY;=rgPAhUonnHxbXp<2p9t;?_y zL+*JISb2`S5Xx}gxN4u0y2#(+-M=2y(P*9!Be>hrI!|aBxpCz}NQW!BquX%%y`~hd z8T9EU;fHRDSFnT{`-QENa!?yqzFt!;g23LXr|&6mV$G=6k$0XJ;RRV|)_D~pApzP` zIRXclEF7T5$OqnCB}je$0`_hF&<0Zb>t9yDD|$QO1(R9!J!&HmuuPIdnT+vQ_THMh zqbZV4i6#Ebzu^vqC5mrJg8Rc#}sjtd_FVW}9jQ;3Y znX!KtMvXxD+~S#0eNs{p?CNkQ!xIwMGfDB&Sc%K*T>V|-VbK-g%(#D|^b2WdWP;Ko z-%Z2M6SeC5{bz|XrFU?b$Bw+Ye&X#i#n9hWk5%I5;U2p${0Xc9W|>~z)c+nt-7_Zs zmWY=wK3bSZ+8rZRp_kt|ij_t6mP{fl^lUV3@I7+i2~z%E*#js!G^qEjY(|qpmS!>(er)Myu zbw%5!2eDLFIftmvk8+q^Jreh0g)aK{X#b@5-vbCc@NCzQvhMYtRej}gM2Du=D;CB- zQhDXH>k;fK;q{Qg?IF6#vHW|B?HQSDve6bkc zGg0dL(;&XW+G}_KtH+%EttBL@I^B(iS=WnY#aoN%Zs>Zd-_;ri)cniwl3DIT@xuB~ zeH|SWx%3bBbSALn7XTnLuxGrz3v!_m_gZCNH1(N@)9$BkIL#>}x2`5dUy3Y{q!VRm zwjfXBu`d>M=)>0J-w65T)tPo3Y)X#qUi0?p6OChH*ER1Rhvt!`j5|4+QzL>CJy>Nr z@JD4>-_XOk-PLc7T%FHzW-k{yamsN8BO&zwV5mYG=aiBhxm4X%cTaOE$#FwsyA%?E zbNOEaZQHUsiU~CFfgqmK<5Kz0rn?%+dj&gqf!CXeFxT93A{;iYu$6Ko`-5_VzkZq} z*s`s#e@8vLuuey=u%mggm0;bi!my3@4`!g`p%kZ@L7+1Y_c=)P4cprtCCMa4a^yB! zW0T)!4d6F9?L6I{YULlrMsKm#<>cq+&dCw-rt?Yl|L$df;#S=SNpsnyud8;)W?XgbXfw`(2cjDGFST|sPdzBK2ks~^BfbFm#_uT zO8uRf1zzz8sRhqIu8i?qfZ+@3aZR^2SW&ckSsq<+3;%=K=lJuH-&F^%Z$=a@#@~fP zCe5pXF&y7bEqXH&ylK!Z-%K!W)GE_GV`S0n*D46|+BGHPHp!yLGIY1{?08-E#y3}R zm;F%1o3+5W9S{`At?CzzQ-ak0c|LRZdqXC+Pm7ATBmRYilo~|{xwt&5)&^92DEmJVo^wZyE_qF&wV{%@vhf4j zU9U*M<}y!^5i^`-88&L>*U^$|={}zMT<9@jhk*eO=FPYn8s|9Kt;M?xx6SF_(eDPQYqSAKUvEKC-`^~@si*%hN z!786~c_hJ4#)`j8_YDc4+1`79kNV1{a8w0xWY+SV3(a1~R5e9}`aIo1G{Jn2zp(3E z`b9weyjKBh>If;lY#_qwmj&F?MmCJaAbJnl;aelW@jo}Shf2lwI{NnOALIyzVjchRM+!v@jpV`4=blQ z`>%3AjZ)Fl;>r_WNt3QVDs>oQN;UQ|-$nGR|2#>R7Wdn$w^QTTuSk1M$?T-xTF9JG zbdx-gsl7%`N{VrYV=oCLzz{J}dyN~ZkTiS1Oa02l0maz21 zTGv6G=px1m6Q}PFc130FFWa|h+x}Dr5R!e1ib}TIe zPcCfX?-qhpt0Rp5i85|_k0VIMsC@O@BS^~5odPnGvq*^3TQ zm_6>O!CZZqinbNvUMw9S8#)zRQ?dJtmB=L}k}g{)zNoyj7`<{=Xh=8)A=X<7S-+IC z9~aNCs9MM@Xl!x}-xD@!6dUR7rrN&Mn!)e(y1lK*9&UWR8%UoMS^FgLm)=6TSO=S0r# z+pFFEEe}qUDhwqlp##b_Yjk}>tj2~<*Z_c}^6K1pDEp19asUiE(ZAMn(cz*}j))1RaRf9D(; z5^dM3xjWUlq+J%tYj0+4e`YSncJJ+63trVy1TOs}*DQ4H-@(+LTkXt;s#e{9THrn} z!?zoR7->h#;=?%N70Hw5XE^AjD~?S6`sHUtP@(hfc9?5|B6KdH<`^_4WGfD}LSq%P zJ5IvbZT33*zz9M3DAX(oAGdh3V5crPHsees z{jDx97YaOU*)t)Q&;c=9mx>P!e?q$LpGB}uuVZmPQ}yG1w1JwX{?7YqlXn&n$BpsP zN~P(SfZ>7JR}^Q1KodB>P1w63+D`Iwg$kSJp}LkEkE6dUG6#WtFiPkgb6 zo5w>_3}sl!lo|Wo*SUsi${+-A@RzrV_KSlGb8K>8Eew%Ib=j#uF%hxy3(jNVpOcGo zixwWvKwLsEoh7?ooxf zG_=aD+(iX;TiG|*#;Po(OMfL{8eONm(>+uZ#wdEK@O9Wzu!=Nx(wNp=h~18iLIvAe z1GVPSZ5^l=K`zvkMXCe0M^3d~F(p{WAVlI*B`kwCSn9blv=g!lbivh7s^43=en8+T z(-a{n;+3)7g~LDEpZMFntir|~4%zMxEvyL-{@$6p(fq2|Jn75W`eTMkYQs+4UnS@R z^V5gWcV}m}AG{%l?uLGE51^sbPLHP8HWAq;LCD{d z1c8zIm|so(d}5W6Mc9_@wx0VXAkTR1_+M$*RLUdsO+*au87Tw1k-GS))6P7j$eF7L zgm4i>o12Z)K?~G#*~B0rBbL@mkW?8Urtsc6x(yJ1Hsy7FgIECDo^s#u95C&O5O-Il zpI;D8_$MxguC>ZN8$1nm==O+WFktTJ;@I)1m+dEtHyswTdgt>6WFHNsiwxdhYQGZ+ z22Qm9v*jQ7fvzL(!&rvZHsFKb?G?c#9?qICgji@?Xy-Y_jRW)+t*U1tQ!Z}@2@uwJ zK@i(1ac(c@M>s0Y z^|lFiJ7OEQd1_K~vgI}-cdV|Q-ThS1hC-OOC`V=$Il`6!_Qyp#EL%nC?$ct$maM?! zAn=WPeTu+p!>Gy7tsq7ZMRj4m&>^>tDI?P#upB#D$vHFyaDw3>N?e@sgUW;KaH{fG zKoogtrfp)zuoLYwu3uE4EJDG$ZBUikd#B8RG5Gtvhq*oQJlXo|a!HHJg^RQ3jej2`9mtc2sXgMz?VX=4A%%efQ8sRk-9C@z9N7&; z@Dt&Hko8*x%4Se_l=lXo+yE0s2l$kg?o3vC*)od50A57EOKD@I4+?=~ov^`e4K3s^ zVTqBcL!;wwXd5re)xy?1px>w~qr6QR!ekJwaF}i^@fPc`{c~ue_g9LqpZ3~jcl@_Z zwElT__=k!<(4z(37qB-%QCCr*6H9T+cZ#+*bAVZ0E-eM_V%&P}((W>vdu=yrjHskg z6qWt>Sgyy4ORMII^5Me4YaZP{-Vqp#%x{7EjoOsPimtQgb=`=;Cw}raA|p&PR9EV0 zz^|k-Brn?GJU1|ZHn!4HQGyIyXqvVPE$*P#$P09B+w01MN`TGa;3BqQ`cB>wSJmYZ0NNU_*dh z`Q>z$VYy#%YExMFMosXAMmBhF&LnET-3hhz$vI#0|DOdwLH*!}?yjqJeeP_uJEP<1 zw!7atAIv*9$X^n1$iNs?aC=YcP-$1m@OX|{ity5_Jb&;;rHEykLu#!zuyFReI^Xgu zBi<(6nCLi7r-wI-Ve#$}!@hU?F-apk=eFPdlvE+Kjb2&{`;&LIv43NK)f|7WMpb@>^j#snvNrak3VWrwl5ia0;RpzNEfe^{B*f0$|0$KF)G z1SKcE^j@bC(26pDj`n5o7<_r}ePx(%sD(=0{a4z9{u$S)&zUN*&uyY(kvefM5dl)H z`9!r7vKk-wvXdu7&eIPhp_m6 z5!DwStLo*OSUzp6E^u#Rl%w5t@Q>0Dm#=!7Y6yiMIMv-6)a9rZ($p5CxJvA|_wZZ1 zQdzqY7}B3Gw|JL_6r`v9Ou@uRr8bnL=$cy9^|iwoc(d|TX;@!joSCy*%2GJQVPOlD zgN=FQsSR&L^c!3}c{IxC;){FKHMhq>G#nEDF=KT67}U-N)9RcxK4@GF(vC@RejU5C zEWZB5(dV0>v+7%(cxmU4{=}+Vb%9PP-K_dYR1l?dp$?B z8A^1+{EZ_8R?7pYbl>k8>jxefOeRTR#+Y~@>+ON%AeijJ9W9}XGz8@{K3IYP3LP=gDju-kODeY!fBI#kt8RlT zs=^6jlt)0_Z$KOXCETLrk9x-T+%jAY(okcmB_2XIpC9_p@!~toIkMIO+*xwW)%|OR zsRQH)HR(h(u3prnib|%3&Wrgl*KAcki}CCzuJw@pH!{|-hFkOMkezb|YK4^qdkpcH zs)_EmC4rpA3}mqn+hiZm^M&FTtm5@^vU%IIx0{wPlv0 zqO{$fIZUzYvahSyJ9AUgoWxtrlYAf4fXS)~v;xfY4GM4st;!lw5OSPU4hz?(iW;@A zhusx@5i6e*VTn(&&Lmyv!7{@FZKoKC=X}2ZP}IHuVRA&j9i{Gcvs zp&==z4JJcydfruyNMT@YEI4g@oU}jQ1wK@RXEnJMkHdiuF8kYibM}25rP<=_uaOU) z7$Kh~!6I@`UvUI0@^lU2`_&r{lfW-wa?k3jFndzgDk7DcNAWRFsdZIuri!U4srAt; z<(^bB{IJB%iP?F+$eb{?g)Gcy!v3^s3evn*O+pI!3!}irhb5z7OkNta6yid85(Vrj zMRK69t%XCPT39*InCprhdI3PUtC{C}w?7Vt|IZGM^2H_Y{tYhY8a7!SdOo|IW$X9N z{>SIs2OtrMAFVdTsm1-Kt_(_{fmDeDWIY@@4~ExkEC=mK6MAVNQ+Xb&7~BKmSFXg{ zA}2t&H|86@J7Tli6@)Mhne1uPDtikjc#bX>XA-@PcE7gM5fAQwr-4jvj?bx92*wDc z`@;#eHsGDN;Tu!L_cGhPyhbz)-%VAC!pTIfuP)nE@ju? zE|cLee-XJ_L<`8zJ0_y83Zguliy5?cgYUKTChJD=)0hfX)2j!w(Fl{6#=WLda0t09 zBlfa}_Dn!j#%LJC4%Gh8RXH5z#}Ig+VE}#?vqcJpo02$Vv@qGzQvYoD3r{&S^`&*l ze)ltyMrq%mAD`t^`eT)Guqe(MYn%(BxakWRjJe69hNtuhAA8{H(HqndBC3A#HOmOl z_bf2NOjG)c_T4B{{4!g4ebC~RoryQ5Y&&*cmMi-KFE#%Z4wh-Ue7a?fd! zi`7PDZ_D#U8vKHE>Q0EV1}6NH9V2$9Gi{p@KhX5n+!!Z|QG7QrNpHZW)OQ^M0|Z_D zgjVq|_m_6H*E{t0Ux~&vrf=V>?q$Wwb{cNI`yybvNfiXj*?Qj_92-C5Q`u71@*Xg@ zakG%#wK)L7A=gyzp2ekyH~?J2wJ^e@^f*}zSKNoKQfFYUiM^8phTd|1m>go}fp0M# z54`;s*apf6}Qa1n0Suq7`JcRuN4sb3*G&U zh~wRkNI6|g#Ki1u%On?*iZWY#p?2}g`;?T;`rAUhnBbUzIBx=Gg$;HubgOoSn8%&+#u2pe6mAtxs6;hhE&)X6t!TD-edJH0f&l*5HSNya?oAQ|eZk$okC6``{RC{r*DutL<-Z zq{sf`LW(H9q>{gkaU~aN3QP^Xhlio<4w$J6K7vKiH*L>Etb#;OCv8Jr^!;ld?w^ke zl=#(NLM?{xT79rzkrWuH;Hy6^-?*Ceb1g(369wsV4<+e0H9Y27sgJ6P(Yam11zd8%Sj>ru^Fc<0l-^H9Y2pCe_(BIR)o|RW*>&00 zjqs;v-*_i=W%bTHRak&3K@k1iNA3is)|)DTKSXjz!1i#iW8re~8k5)lzZwg5L28-* zyV`qrpRdS9fx<>@k7adzIH$3JZ{g_Rk=r(Exi;;; zIpRm|3Eut6b0pE(0R4>aujb9_r7bovO&uiCV5o1mxDj-`EG$m_BDit0i9+IdAKc$% zkoK1^SmQLL8)J_u1l<2D*xcx4@zLf@or?ga5f^b^fL)xJ#O4ME6)-*;g-VXZ8dq~7 zH1(Ynf1MEfO@faEG(n zJQ(%`cw?z}ODA7p{~77h4QOdO{1?#zH@v*#p*sWK(BGlB&yTXlodLd6PT4%hi$7en zFsnFidm>oZci6b6HdG*8vj;1)K8xuePq#D+OFfzL699v55lrq`_e>O|SJZvoVUVCr zt_Uad*co0~=evniRxVn!3eu$ui9yc$-iqZ?ytXu761aSAon0IeQ#Njc`D?eVrDJh@ zvz&`%oc82PYQl+0{|b&@^^dCVP^zyjf9;$(H228QhVm?b>H+X@xkLLl&XbkrU3;?E zJMBkU-jK*gFYf4@tGye*ozFuZN|DCaWtq^_TMjec(o%EHizOrv?ucS^cx2t}CzDM6 zxKvC^Sq)04XWW;x1k@K9tPRy>aM+0$pIpQ2DEnZ&YP3WC9euu=niOFGn$`90o zrvn3VO5q=+M;=7*!s!`}(mA;8 zrUlvAC>(vM?20i-^x>Wa&=p4tW(Qj_Ja>O}t@9d<*FKUH_t5Vc_6j;9)NWRz^=`AY zQpWrWk^T!WPV&z#?LEH3#QM9d`gx*#u?J>JK`0H1#q@t-AK)MiMH&=ZqIWJ?6g~y| z)p78>Hsuq;gsjLv@p*}6i{Yn?JFqzHFzr)o3s^MI*?=(j^pb?tjq`&32#gR|4X+nW z*c?XqunoX9AuHJ_6NY#q;FWCs&29A3?U+%cgBIPH#uEdSZD>^C5?T6%0yeJ|j?T4P zWnC;5EMh9$0}24Ck&*QtE`X!(0OK)!Ka=Q|QaMT{a-;lwfWcl!#LWVXBcc20QA{k( z5sMJo7a4h805s}lyl6qJ>ru$)iw4+y<=kmQqd1pfFnP^gvDLqsGf1XAjS%ui&FoH1 z@66uUTLBK}nsUMzKaUyb{ffG4v(c|0icLw3bHcX0f(^+dZX2nt_Ke#um5g6JmljBi z$s4*M!ktUJoMX;H82ZK<1Y_3bL`FS2g3&l(o|HccGW=< zDB#aJ%pQc&8{D&&wUv8CegTQS_VB2cZ~SP`^rOsIGn%8|s&g!d1IL;{@K?4cS}(oX zf1O+*tVbKqqe3LBP2Jyjfzu@*0yTYP2ZPUoM}pQ?@&DHSuJ-wbk)Gsku{K^9*CE~^ z)E+4}8r-8j{M(+?U}Onw$!avy-tbS*EPr)1LF&-B2@mN=d%*rtfZLRPcQ_0R(QHQ4 zoD;F6j5rg_-WR72%a&AziD~3)?CWO%o1UPJ`Ij>R^DC9+DWR%)hlZH$d^@?`unCb% z<~zAD+anNpr~L$k)}}nysEu2DA09`&lHI!oUJ#p>0QZ~TE|Uo2Yqkxod}?$}`jg)l zkivM%lhf6i@}_YTA*&Co&l~DpjhrsfHbBRtqOPveq_2Ol#R0AH-7dwy80fJhjC7#C zuy0>#Rxb9BkS`moPiPbwy4%&Fpg>s=MZkUlB!ULa$1)w97EWKC*Z8@9Pm;*!p*p*e z=_y-4?A}!I9@Hq^^o$x9tLOLdVd#*k2t((&KkI;xku7p))eMqUUsg);(A^RqbX#-e zbH&Ms=j>nD`|snNUB0f%{+3q9cGq51cCJcTi5;jS{nS%eYr*!v_8@l3V6T#%I{{_*usM7k7#z+EuOyXRrCQOZfbSI zYEN3CiS40&xd!)#mX%|pnemK zN1=_X(0c?kaBO3w5Gv`zYN$nxEmwG6+*T;q-9`g~=+3WWzU=3X3xr9kURC#&D<%{QIirH7C?n;I`SCW2{t}aLp$H=V( z-V3n0Lkg&((qh|t5KukHmebG0uS~ZY=*#q@C~Hnkx3nV#J``N-soTLO2djd+GPMDq z^`42k_aK}Kewb@-K?h)pm(Vl&zrM+U`ilQY)4RtdefR(W+q#PGE3f4# zBUBW0T`jFyx^jwVN=p<{Q$j^NthHsPY2`eFw7D|nlp!h}D^XJsG6B;(Byvbl5fD`H z@O^vzZohx^=I!Q9koW8Ld_L~?2TW*wG&fWDHq8gpdnxlx#p<#oPGW)fG-g%WS;s#* zeJ@{=0gT=;S|b}t2(ME&99A3?fpj6c%J$KB=EnA>;4UBOGWu;MOkNR0V3< z`d(PEP8d*rKh|9>ZNxSu-iEy!Kzbo5%#H?+@j`Dhc9k>KB2+s(Y?F`%4$cL46jTUs zzL}a2536wNK~^|HqN-V52XA0UBZ+_|zHsB;Oj_K-S}vq2;ZM)_CMk?XnVA#T-5=y6(Yy4;kNGKqAfr=P2ri zCBaC{7AkHgd@!mGZCwaW5G^v5`Bzt3l@t>4%h($}xN49i3izevac$X=#?Up>g>g`f z;h{o*hZ!KEUiQVg*lXGD`N38W5N8P4eRaKO8L{4jfNs|Rq=s8BkC|Bk7ZZ9INa#V2 z(8ME|>>!&2maaddXJ0<>d3@b9DZTrku`+w5&18EOve#8B`1k{}7L;m<5;0K&`*x7> z?V39SPa6Y-!)>qN2&vOdO;vtNRA}FHWlu-Y)Km-iNSD-EV6su45U?;66`mnS^(Yr? zbBdUwce-~+UD9z+ytSj3rk>cb_P`jtW?O)LhTor|{VmA`+kjh`dk_LfIn5?kQ^+^3 zn%h0m^rV3?APysOkM7f(CeJ0muEp=nArie`JV(Bi+SdAhU>cd=sJa(Ab3ZUvE z%5sU5Dwut;`Z$Tj4cMU6oSZ*Qi=M~QB%hj^{G2Es$dbuI^&Bq`JD$r*S!G4n?+BUv z#DbD@iIZn1?I~u5gf}d8>_r%EfN^;OeiOfe6V=#wgsIx*xet1nWy{NZk3t<(pq5(-qC2{7tAPGoMEps%&me5rzHR=9-Y z$bTZR6iv&PS}RFgh3=B)W(Q}I9J;bxae0H_R{-JOYX>iMKzSum+#uvtn@q13n`?U8 z1T25yI;zgdr#gL2dXHLr-U^t#ug%r^>$hKsPrW}$|NQUGZylz_d&y5%Vz4q_ZhNY0 zc+Yj@Q^*>CLLujg`v8c;yf3p4#K!{P7BHmQR4`)E8xziSmenG;3X{m%i8D z>)qGcC(tQJn>`imUxp};X)Tm0KXjy@;|4nw_})}|@WLXexlzG-=f)J|j15MmW*(An z2R2k^-x#L1HoLdS-T#A`+s0o9DQKeNn+KRZu~Ac$Be8>pH+-S0u zy|*{xFyP@G?N&pRr!$W~yRH3+)>=~4ezz`D0a2WB)^KC!l({q}2Wuhazeo{IxaBMv z|~}@4nOqW6&2nZ&(?$nF>qu(NOV?6~#bXVFfu>M`2ow zcJMtK46o#AEtOT5sqr%zg|=>(0{xinOiUeRUdrNM$CThppqavqTn?$jdDT~Yw{#b^!oVC)p zc;2A_iypm9obza;hhtpZWFO6=+rZtAv-Lr~_c%yz);PQ0G>K5oO+)bOojVo2L)K$~ zT`A<-5y@&)bt||5PszeP7-)W`@&7t{p1027S#EA$rdI#?50)77xH)9iG%3f0KXlWr zi1$3(Q|^7-E$3y66N`Jv2G5Z*Z#T7%*XE;nrkyZkM&$VfyhRN83G#l(br$>n$mkK8 z#&aULFe6f&{*Y^Pe|dT#Z*G|q`Bpk6FxRY8t}Z^r+z7+-zFm1cCm^J6qg2&@AVIH^ z=Ey*qG>1;O1%=dv>ckAXehCSCIHG+RzEGN2E07QZH_Uw~P0@lEa`^Iq^tvimXA zM?0mZHT*m-eyl&6wHEwq< zuuaoNUdgl4{*1Wh_TIrLrjME@&y^fSn6~E^m_~57*jw@C==QKin0ar(FKXJHKuz&!fMSE!)a*fJ?7&o> z>};#^cX?;6Fr!y1{>a(UpZ~8S@6FYqgHhi^yH4E;Tfyzjczg2HIqE_lW_sCYlu_>? zMNjje5-f^N9Ce!I=OPStsp3J#))&50*<-b8Hs^*@=wS97FT))ZwjpNmXu-*2_+2LO z1WIRR-DCQb;A>&nMj_yrpnc>>Iy!6xFsxlp~f`}Plq`0p9 z11=hxxMT0+m`yWxOLiObmbE)~m?2fE=kRk;bx0e`WJ3JH<>$C*UKY-?d{EOO4t-4P zpuHD%j3xcqT;0U&u;69ZN={IQ^{=Cs*XTc@I}&_vfpYWl4%GX~`ZZVM|b?#sG)*v4D63f@n`r8qGgrM|0` zyaRi9L0MW)ygfW>m7U zK{x*DwF-LAlf0j~yl;?F6DC^fxjTAsB!C=1yjmbw$vaN+jrPG8WB%o}c8C{-*!5%A zY$}T{MD*nKjk{s=A5~?_4V#f@$gZx!`yglMh3`R!5#IRp@DMT#VEeBT!C=AOGF3e( zBXY~s3b%N&D#AraHhdQD(%lc6%8qx3m3UmyS%vMq9@!#<2KCsrlg}Jilqi!cu=vS)j%ZqJst_=a;I_ z!^j1&gP7%FI3D1rKD2G-ot>_(c&|{-HN(R*buW+-^DB{D?0a9EtmReh)^ygaWge zYgw_9?>_G=3-|)}>21<~wzl)e0-MO4BdTEw!E1)t+@?4n`;pI-1&FiX-CZ3Uf)cHK z2!@1Lx;^g92)5VM|8W)9R)HA)q&S^<6rP|FwP#VP%tk{YOjlqp(>vBYn+934X9UmB zV}7I0IyL(0IpPVyfO7tf$u%k<{sA74WG}>7TK2I2u;q)1`VZ%OS!EN`b(+6RJR&Jg zE#oA2#LI6;!HLrPLa?THd;DKcj7&TD6e@c8*Ar7jjHY({LQ$YLIDHX!!->m}4-MSG zdCdDqf$zdBddfbggifm^ql`aCC6ZqoqLTVJ3NouNmJVz8izZGR%JCiCv0&y)mGDN? zBT1eOntgcMaYZ0#B^Z<_uv^t(EIWRf$5rX2{UGg@p1|9*XIqHbI4!T z>g$Rll2NbEw=)|{%9s^C>XbsUf*b>7faWQ}cHxJ-^s4o!wxjD54AYwpT=c#bPdczT~% z*-SG+u@S7qF?~K)yS&SPaAhzd*icVl$dEqpS`7P=JG;wED z7QOn>=x<_}C?&DpYGD|Mq2tbkuDqbqQ{J4RRD#fS_B-IFil%3ypv3h+u6@$3q+3uW zrHFeRXTSP@>!6&9Ee}N3#*KphPLsBVQZ$$H?3}BsLSmAo>$xaYvtd~kEM&65{=7%%ua)a-|vHmZI$yHt4 z3rxupGaON%i2)XKRDgVKlr~=zkdxJc2W_rN_l9p68?5e|KHYzF>=^Uqt-Wo$v38u3 z2)fG=m+71w4^Xl8+3J^`@UUa{_^`Q^Z)2dv9rz_385xOXKk$~cV>$y@vDHqgCZm7R zQ%BSOEUvlglsQ{yBt4&$F*37l5;SSw*|PXY`svz{PBYd7f?JK39=sp$ZTa`fHRitM zeCmWp{<{aIjF7T``5-)DpW(kffCKY+=I4u-$#nOXzp(-RW>qY|HJx_7@uR}-h=D5| z2m>|<8T^cU#M3k_!8Au0=+8u<1urTYNxh=uW#dw2X!puy5cY+gT^3U0b=1T$%aIjP z_W+j(*apC^^wS`h$Rf(1B1Py?g(!ZQkC+uBsa1{*wX1PY67Mm(yn+c4=*ivD6v4ao zyN?4FuKKtAjXC;6=OZI*5Ip+ops|w3(@=;^`C0qSo+Nj#P&)qgJB;8WS@vzG6bQ9l z>OuElU0IPG()w7*Xoh6;!1|q-&hh%>pD0Hn)(gnMskSTScvp{Exa^EIkQ;7Q#M4GD z@+yN1g9$3mZ&b!4&UUMqo(tU z>yXVUUZ@!OQuV=fmh^2Z6Q-}jez}#cTa@xNeqG(i4L~z<@@j6*YHs&-x^HfQPi$iu zu%9m$ZASD?Mh#Ipt#=!0$B8>ZZyC~wcV9P+OjVugGE7d@@8H@kGhOqu3@wJr%e*=l zMC2GK>$iI+u%P{DIDjdw&pb_`Y+5QT%tz?Z0*w6JN(X*jT_2X+~CLH`ROm09lKTUoEtIbZhaY14nNJ=U7Gkq-x--yDTym&eF4Y|kAWeBsd~E*bO#7PAaEK>6ks*ET^+|!|Fcw zHd1|IBjMDp#3pC#UIZkxn-}6G%+w7=NcR;@3w$~_=$W?pvW98TI)Rr+_ilX0Vre3E zUs@T4-x1W=@_@Q-QIyVTw+JZ>p4K;ncoj(DH7Q9wX`5#vhFj@}roUNJv`~hhIKdv} z{^R75!vyEp^@lMzUvyS6<*5-VrnSLkbXNV^xy+R>uSZS!1f#BH4;H3_5wnhy_zNqR z{&V2jjGQaH$%po|?)jm~e>B*f`9muo3*uK686v?7<=)GyHX6~>;=yuDdyP5~zPQ!r z5l)I&h(YeS)i9xRt60MPA3p;syfVm^S~VdhB4t?YUob za#~&5Y`IlS-cpM$b~N93$1r=>42%+UZPp&xK%iS|yreqp=5U3e9oEQTe6$$tw2Cby zYdFtFLp{@M@UbyG`;GSVvEv`_XdKAdQe@a@B!)MR(X;GMT%_yG^Qkfn*V1IK8}Hvd zB?0!RIBf2HfMRVlot%S8yxf+d9#KA%NhhjOgOqPEb$ynT4#Ece04~|MogXq;+aj*2 z3f05?7YElkkg7`X)Ihk+n8&V$j+uYxy>YkM!IS22Sc3dDsFsS0Mloqm(q((mFkCdH zzbDq%rkch74jGj_B&Zh62d-&riRzb+r{_X=VKO9dnRqrFE%h7{MAWhdtQJg$9yk#S zM(AIW%-J>T zMUA1g0Sh~6w7YfK82rSm>2}g1%nnVPUBpTZ?v8W%%Uy-Jn}DB5@_o#mP~0Q!H|pr$ ztS5ffjsLyyGBF-@4a+^Y6`h@}7Oz$E2uK%?X<$LM?jJB&g{pw8JWKOmi(f(ANKZ0K z$UW2?gy<<)_QkFE!8X`M>by|ZaA@RI=~y@-oLRs51spdy22Z>vxQ|YfH8}+k)&l3B z8YLx2(S~Zel8YU%lwF_bF7-((OhFB0G8bJO%S|`0aRDP%G%5*sB55M@1mHk?R$)gA zNx}B>ru6d1{-WW5ap1Ea7bZKtUlH)UPGi)(jxAy zW#{5DDva!0@u}IlpxP*AT_D;VPJ}_9Ex{qY)}8A=xORQ%6~GDD_*Vyeee-ux*SACO z=M|U3=x%&Un&2xxFSI@$p7b*W1s5*(p}3uk?3c}=GTP5PtR z3(qPrO)5DV#@1Ihy?qvJ<5? z{wZ;gp0lBN6*f4U#QKB)!#Fma9Z2{o0p%R^AP`qO-(PLNKP#5OtHaQiKP%R+M$xkt z&_#PEXBSNquX}F(5%W^TYbDaI%bOpQUy3{@~p9FnYl4RAE^;ur$AuqRyfqQB4 z7RyRA3w_w)uWMJ5n7og-e{e(3@fwN9+qkb#WJ3o#${n=dM4Zk{Lgy*3Yg2dFc9O9c zD=EszEyX~Cvorn%-b&&lJ2SN_GV5CHRb>UN1P*q7T-<73IZu>?e&>yu%b!~wsQ-!&%NeyB}hER(!5f@O&2~mF5yQek#{9rNH#o~BLOytthQH$V(dZWHD5!u-p z$?bE{3CBU$H&1a`5XnN_MqoCY=57Kb(Vp3oj)%7b99MkiD^=_`i2y>Ohhbw^O*sWQ zd12fa)g5oVR(AVW@HWS{+dFfCME3fBuv}Nt7f4M1oabl`namyHgX?5!<5ENd6b9jKQjm$m()eW9rfMNGsQ*=4Hu^rfw{& z(D1DU>Zx-L&l@pPR@_)OE+d3?j|-LQ z{V&a`WDhF&_loU{B53T`s4n%jQYSJ-s*2uS?{gN1obV8+Y4BsqS`fuMTaJ z{N$`A9pRmyp4&fqDH~S4#V%&t=!8)5FXf)L2a=`FfDinU<|Cw#oZEjLp^e=4eBR#! zKQ&q4d2c4*P4gYs#UJUOX~d2dl=5Xh)s>fz;W5mr4rFTb4hKN%FDQcrpNvR67O~P; z(9cx@qP@!`>uIrjOSE9Pk~G68?X(Cm8w|xo&Erz{^Vw*a-RuB;TqI5yt8e}TL9MA8 zpQEEFqIV4a8rK>VGWCB0KRGlUK)>r41dZ0`X)lg!ih&#o(ni)#`YrE$%H)9SOyghfS+tq41RnWo zVnqyQy7&4;Zx{L1NkFbxzQfrLJ$K90t~8?OtEwG+`&`RN`TfnMkW42mn{!RwBOp}P zk?DVsO*&Cev$__95s{Nwk$v+zP5;_YMKH}ZAmYAz+10fc>$HsGhJ{_%`L7?fF^0<@ z(Mw(N!QS}Ch-6uBoMvrc*Zno|C@hY*fH^wN5GlUUG?Z6dT{yrtk}vvETrW}Wn;jFs z^VR$i*j!!PfPDt!NG^p)M`-h!{nD3)FZBzK-tIQ6L+zJSP)XmSMVwnhVJXzZO+r#$ zQqJ=s?lE56@3tgaL^9ZasFtDJ7z4cqohTDxbWou7LyMYx=OwQQXsa&)=B@yrw}Hy#?q4X z^w!xu(ZTZfAdT;v52tG3f61$O*3xHE&+}mR4Ji1THsX1#RTUYPhWV8j+O&##HS=i~ zMv@Ti#C+R~kk*qJi8K4EJj58MWIzanTg|Hj$F!J^O4w=pH{)&_BQUxVVTPHf29ial zRf^#^Fw?e)xhLP-Cxy$-7P0~pxY+vJ(Adt=3>~|bV~$8U0_HV9>^->fg{Qs}JO6u} znId;B#e-6bI*?Cw!Igmxadovx1gN1xF;6TD@MGQ$OfCPc!+B;v>T`?OZ52-w&!LkX zWc^oZo(ME?lOmiU6|$g#JWt+BOQGhRafn7;AgKh3Kd#Y69lI)Z8D-jUQoJeM09X04I?QY{s13coHnr7kE@R9E--aWz?r=8Qgvcj*Oi<-@v& zC9c?^w>|%lt@0Rar*w!ujF}hO&uEG+uBFFHij6?88gkGnf%Yun$Prf!etkU0dDOho zew~_ywFt-5=Mjhg>!{GH8ELxZCZPRGw~dn*b&(?=OkbhO1}A<{*_u92SUj|H7Ni-s zd_izU>*eM=itMkQKxj-asO}AG7>y_HQONbh3U$h}P%}h=NLyT62$7N3EN&IoI0>^L zxnNCRLuu0pr*(7bOOIcVUW_@tm^*aq-TN)eL|wg`zi?SmG5kJ4t);%~;uE;)f)31Q zxTb0r%cA@5(ow6&Q~Tb-Z5AEyvfT|>Eacc^h25xzA9ipql)fKovWgS6mW4BeXZ>{M z@egEbOL(lJksmr^ce`^+8Z=r#+1j@6&J=BaEGlgN)FLI2&b=@T&}}-pwm@*c3Y&%C zA4&xV%9CD{%PX9c_6uF?rwd-spE%zJV2<%|davji(U>K^Gkm0LWAPgf7$x2(V3gbbx$|xM~C*4iZwyYtlg8TH^N4% zt%`}&f5}-xz=bKQM6qy+7*R%_$OY4ou>_>ZTw;!#WPI&=4F(Yb!=LH_#0=3xIW-1F zBIVKG2BvY+pKwg+($GZU+T0vlWwLqZv^fPPB=Vcbnsd-CnI7H{O*H zkiW(*prP`3uVmc`WWf+?VI|O88~+6Y^6`LPyME2(Gvf^FT>~jf1xY8Knu4y;84~u4Rax$5KjF zrGM~#a|;jGdi0$ev@k4d{>zDEQZY#j46a>N6~JsIZUfOdD&L%CUo&71Ji0ekrq3Vz zH)K(nIqnH?jm&){+{)t;yW1^lL4ReY!-TmVGf?qY&dR^kP+#O61a%p&vyvT8i4$&e zPI?&*bIp4WdnfbTcE;+{-h7&__?J$)`Wf5NXp)>9s3O>sJ$dc-7wO$s&pTpF7B=@S zRer~iwj0NLW=alAp8)d>jFK#0WB%H{Wx|ewZKvodF+Epk`gT|$dX{q;+mu?L zWi?C9Dv(#Kj8hg(64f*2F}QE#;mV<+Mylb5tlz`?YaUPiU({~HN+&9D(E7dKBn)#T z*gHZ0aUYPeDqY{+rE~|hq<_mHby!dz_~aVBC;nwIE`F#9*04bxcYTf8v+8#yIkDyf z>E#x7otl?2OVdE@owlm>#obTqy0;EyI;K~z0t&>g)%>oO)n$ONeLk(>uJMPTG=a(o zy+TK77ta@hXDQxW>l(8Ozz<{R9Fxi0=^rVch(Q%Tv+9zz0(#15PJG>v7kdw(na{fB zEn}1+krY$%VMIeObXe+jX1?CwXO%Vmsh#iOuFkIY!LCfzYulm-=*IF$F5}`sTGmj1 zc*FYijH}4wVA!U2_%OAcU&kCQgpmg4XE&eenF#7(e*}=OT0`|vLwF~L23(wJLQrZU zX9h@7v#0u^UM<_~En}CQ+?z9!Y5eL`#n9qkcLjy+fbMO8ajsMQAXvSZ;cJUC*?7No z7TVPwOt{xDdYFeOY=O%|Gkg}ep>pjxbZ4~+xXa^XIv;2PZLPmecZ4IS-z(}>ee>NI z8uD`I;vsq<_3JdP(`a)4*eH&pdXZ~{tbo^yC~u@+{=~t9=Fb~{{dd;xq<=;wZPtrl zw&VTZ&&~JO6-oY}m_?;uu888Dq7s}j-=B-h?m2MF=JLf|h{9FMd%ttSx5^g2BtOU~ zQ^>i+IAX`_sQ~SNKgRcq(yL#u{d3Y9w(9Y*cFMs1xwD1;Ys_S3m`s;%k}mC zY*Y}!5&!gRrwAiletDH*jblFd&*nV@P8*H01I9|0uIpk!>(ur5-Qf66v5 z*ka%k&w#Mbiq&5g<&f45zUCx60$!!1LXiQ5<(vf-G5*Pp*x>1rBvVBclidC_O)kz( z$*DH-u=S5-Uk=Q5hYS9G;?Irt!qkxqn{>zMsY2guU46N!75){~i^T^FwVlsb0XVSp zE&?DKuS6eJD=zt5HckJzl$$vqO z#kI6rCw!8Yxp9~Ng(W13Xpfd( z)1L8{_wypOz7fgTBxyq=b?~t4_<9Fy46~uf3`A5P!pw)N#bPfH$EAugXJ>TWk*I5< z_89f?+CqzFeF5pwuHX+R8J5S>ti6KVw`d=xvi_dEd8Ao-uYn>i_uD+Rl|lF+s;WH} z5*dBGOWti0U)u{v`v!-MBKs#5HM8TDLz^Pcs*FgYWmfQY+f6L5tr>8oP5Q#pv@`F! z2`r!qoE?#^^3a5srNZTniGn&?JRJyq*eTGNz_EGBuqvq;NK zepixhdyfib6ztDJZyb-UlU)ulq&0DO`x4ptfg|n-&34Saxd;vLY^*4ojR>-90D!dg zx(6XB*6PVy&Z4_DPKYYYEEV^@=I{|s3I)j2=A2s>+sxn5P|QhE#tr3 zqZ@&p$SKV#wlJ^^h)ypD%OK2^J0wQIv5K^)mFR>&n>(+raQ~`?CP-DpKm`HXlmpZ+ z;M1Qk(gP2ht)B@bRQ93{qCFka@4j|+A(C40C&buFJf^N>Gm2=)<1u1P0H}iT#59Id z5;Ixu0f|PJ#5g#`WU@v~@&<4JA2hBs=^_udGBIeJqV$50GorMj188{0{7c$L7~3-E zvof4xFw@sv^9}=rto-?ARyf(!b7`Rnv1M~VrtWYszAa;AnxjA~{}#5JC!LU0s*|6N zLGj-ZBVjRM)KrV`p69MwwTESgX9SlIP~f;|WmkKTzOJ^~gPln{;_OA;jBDb+DGja- zb97_l$!jWM4bjJIn}Q2e^?%6r`0I7HN=w1T z!NW$1i~9!Oiqclu{}|)U*7z<()C~%*iv|?|WOj#{w`!mFq2)`&g=(?iNz^|96?P8d z_6M`sB`wQsFhHCje1om64%JxqwkKqOL(JbNHzsoQov$>$P&wgEt zp>+M1k?UEBJE1)1xsscRszrd=(G2B(Nb9gxb&5a6c9+mPtf6j}B5Wb465(EF-W>ME z2|etmEZT#d2p#E$xCJ`6>*|UKnK6HpzK?>Db2Ap}sDy?C+uTb`5q>2UJM4FF9uTFv z%YW`BWuLM9UGY5SmaKa2n*s-irXWPt36OJ|u zL0Q*X-ng)gnS79cei!m_s$^ryWNYaV*pMYj+<&Hm-fFY<+Se(2VKjR|1hgjEIBoxd zCN+DU8yI73>ZQV$17|(u;DK(U;HgHuo@ZCx0=#yeCtFytfa*ve^h}C&$o>;S%~v># zPw*ny;T!DWa2%MHE;2pWr}^?J_{RDcircctYwy54xNGuOBy>#Xi;p-d@;*f;B?yai zNe8Zr*>OYYnHv#u2XJFWx6E=aXR9CZn=IX|)?F~;3_LX2KizQ!fgwhzkyx*g2h+E* zbz?}AXY&G8Ys6v#IZ4uHWH@5uJv%TIrq5HT#VJy@XAz5?8YbeCOEc7OYmZoyPIHPe z6mkk`Vut-sVN0WkV;)0JBD||)G@&H$wt)aki_Y|15@O^IPIT?X$N%32a7a$zotHB) z`!&@acm~Z%LRB`P;ysJt^!CZL%-qzy=wGS6?9#^7w*L}x+SmMxGVii6uY5wu-amOclU!af{O{Xjz@jn|LR%YX zFpfGWvCtTl>ph=t%1^87pR58j2P8Qjh~AeGVzRJI`B#jlSks)lk9~C`-aa5^Z01VP zN+g8oRq3dG^NDOFIfmI|G5uH+@m~ogV-M*ql+eD|sG+gY*z+`~_Rc~8_o{z;W;Nyh?7<3s zykz=EMKwHD_NjNe&GMkC{SFL-wyh$tU#HO;KTu}FyODy`)YJ{cDs4W7HXhm)x`#+X zB2b-Y?kU46d?~?^4l9xKMeDDNEWLi!^%LC@I6H)|Qe^Ag zQZ2VErmOLTf_XL)JCJ)=-2^|0B*9nt~qi`c1ADnD!f7G*U8|l+LxPqqq#pg$h}~eL?VIFxZHwpv zdS*1(2MqSXs&(hjNiW`NXU-=$foW|dL$r_z`>q;+Rd=_45Hh}XEo;>aKL~doQKam( z^YPnLnB4ck8DOXaTGT^%=Ani#x8S~ZAQp~gMT4y8@~BO^v(#1n%G&Sr1??hWrpyiomdg859ul;5puuvCPI3Kd1X}q zT@`H#?G&%hun}h%Y{h`gN}kq`5lZ(K<#Zn6uwJXzqh4Ovf+9U2ztP0|(#HbGLieO-Ol5+sz=x2m+zLYMgn*Z1-Ts&@^o-+zjoQ zAfaD+`CU=kLA8OCZSu@@WWb#EDlOI#HZl#mWr!x}OGscqiV_VMg_2COd))I|Loj(% zoQh?K=_hxtR=O=_1cna>&wkSeo<3KlH1As4)pcDZ0K5jGeWX?P?u@6b+6fS=An?jB ziW@*b8-HxjD!%R%@NOQizL?~9iW0UsyR`ZEyIq-aGP@TiGs-dIRDlK_5MJ?tjq>FD zM2n`yKs}6*ll2%MX!*NWbw<_>LQM(TG<Fzn{VoF@<+At7KhPtWD4W9r~*507O(C4(MTyQO| zVO?Cg53}zYw+k7C3u~EB%FVyp5+-d3d$tn`lZfdL>dV3FVvvCkX#<*!I@L|b7}dmJ zDN1Q!7o4*zQ1&%K^Rc2^{@%_Je1rYVE}_?4@nATr(${Z;LK4+16v*$##DjRdJSUui zNz9h&w=|<)&P8h*Aci}(QyJXT+;I8apy0^pMCtjgXWR?k*C-;NR)#s>IvM1hVcAXk zB70rcrzAL9;_K<>JAh!c1>kaN2hXxU*31oAHVr-qI3GRw1qquqzdOLutRV|ByRG)i zHTeNld){Ami##rBI`K5=GC!=rwqrQczLKy<`PFK3j-lCf^|Ci!cj8qgf*85}_WqtP zIxXIfH}~HAvFf55c%k@T%L_L*vhP~`y!TOPo z5PcDge^v2XU0tNBpo2W9hV$1iyq6)@)YJ;U0xnQ**k_+vs#%xQ=6f-2$nd+G|dygf=I_sIdUU) zt+I*m0%JJFyeN}bvq)9YKNprjHK^ZaYR#uNb_byy}oo9deJS z==Dwp@-Pp=low=#1%x;B#?|}L^devkK*8epZ_Ru=X?JU?A(>i9Dg;do3b0y}7LQ1t zd#OFEvpfpZ9S_J9OVxj+H$<9XQr>{z%;p>H!M?)MFk#O_I@rY)-4)s)^dVeO0-`$` z*!q>}fWm-|2f@+78xMk|st(m>h2Z&t=%VQ6mgqLjg&HA8<^Y`YZdu|!{b_^EU8j{n z95XYnoTK%M{X=EKnEg?Y^Z;Nh>!y5cD}r{-SFHu=K3fTKL`Ezmk%qmFBfzlYN>UH8 z8uYr&)H^f3E%&D6*H!?Hk9NLWYUIBuYpQNH?TUIN=CcUQ+3%XjwTW8Eq9lk&z5}~8 zP997%B-8up?#HBilZ zM0RxrQkKmn)0sx9Ym!j>`Jw7alM%E^${@PFz(RGarh7$?=OAv z(e{3FUruQ8J$C8m9X-E%uYuScnA+1_JfJ`HuwQwjEh5EdbAJ&8C@vRLAKYFO*GV=7 zif4SEbX?e)eD7%IC19(*b)c%_q4$8D^Z+8VWpT%rCH|zdw#{1Xgig@bCJ~damM&g< z4zG?83}%b?gOyO1-gkFxa(+ZUPrN^E#jaMhow`*-YpzG~GE<^l$SxbcprviU;p`u`d43D&g}S%$1PEnzY@65}1oVmzAoeS_LFTz0Wm zea}8>sB-#Mk^X7z&fKO9si%FD@B{e)rqYOK^o8(nt<+cbv}=_=2$?v@S{yz68V~et zul0s>-cE_ZV%2elC_d(Dj{C&xhQ>MG4T;U`{H-fnray6iL7Ho2`?`H?#=)Xr7CgfH z$SnSK()e~r%M9=o;gyh>j27<%l>4cnuk+1{g%*HwHYg6pHQ$r=4ELiY)2sa-V z6h4GfOc7=*H~96iN%&Bj3L-rdi7$%vn}2OHBn~Z17yFhAa4*IXRHMZ&TMtr1b^o!=5;o&Y*j z)XSMs2B-A^#qFQ9TJ)qDf`H|iTVGmG=!cxDk0_;K2_S4YPD(q}U zEWCJH;NK6ivsnJ9FCQEmdg-@E)cTwo^O@IoMW?;6ufMLs522$ls^OySZVrCsF#oQ1bb6+J$gUc(QsK!&|z?46hXKDDDCp1V`8MCLd%QN*}{{8YSd2=1N)Z8|6?+fy;f7< zvo=ilASqb?dWD}E^)oVLc;eRij`^~+L0u8Cc@_(irX_`~{Hr=*XwZD_f=qb{=m%Cp z*00zmuTITl>VupOgum;Ir+?J0#SYrfWNO^|E;f%?5Zyx1HHv@7KAF}+k%btt&38A9 zH^!<1hF8uZE$qt&c(^vjgUY-ipjct5K8;`~QRo&N!VTrgXln2B#}qLdkqoAPj&l*q z<>^*OlJ#Lrwp}QR!|K#gr}kSVKKn{<2Tip0iwX^DRpaD z3fURhjx-8ZPWR6jd$s%5NRRqvtwFUakz(T%B@YM8IYOI!LH&zl-MQqjCXYlD_&foJ1yQgS}RXY z24X5FW|FI@^MEQ!GK4b4o2yV;R2b-Bm^Ra={X#an$hO+>=81pG5)R7C{k-~lYe)U) z(4{?wy(=@yN3y>ttI*3c36bs0*Gc~2Q0MH9|A>e3PLc-`wD-$A>F=`f)wr=5A?@E@k8`TKr(mxo_^-TA z9+vhNgRjX2?=bzDdSQcfBo=14;>DV)DJIY6*MX5|yu1QFe{q+diHo1f>!bTQ;Iv1d z^nN@XoW*Pe_Uo_9>}ZUX=SQX^?hVB(T)-anB}5>P&?1!hXmUw-LeD**Ju8A6Av28$ z5b?hzL5`t>tu6=3#=|u69vvb<-8K>GmUn_V z3ZEUfR_XROa&CqokFN;L4pa2K%kZhYAbXY*O)FMb6vPf>=xw2E>={NZGWC-Qy&Vpy z!fY2rabCqByb8e6b&V@wEIUKuP?$EUhu&`YQTtVsF;zIDIsF>`3~tgj5<2r%ITPl6 zb5Sn@SrYL*0@_m3v67ew7I=SJ*R{n#&7s;HPDFnIf;t~>T!k#oj`qnGjo8f4k4`Ua zJ;%Qv!APMYy^&k&^z4d*$sXr%DSKn6(&MFN!q#=lf_C`lBxg8u9me=ow&OJJkTafq zGEw(WZbnaw37D|(iytYlai)!L-Xn&~=orB}YhYMi(T%*PziXQINuM{XcKMHABDGJ+ z-#a(t1=>?5I6$_NO!MGA@)4oA?v5TPpnA#b1m;P>LTxrmkv~Ui<+D98%uAdgQaW#- zvqWYI4sb~N-31{7Dtm;Sv{os*fC8h!s~g;rU*+5#vile`dO)!&Z7hHNnt=7PvKUZT z#VF!?%42jU*-N)_y@Pby-ILr6o}T59g~Slayao?QILsCWs9K8jb%EG@pn7ap5hT2m zr|FoG-6bXtT_yS9^6?4jlhMv^8Za+;aJ8EI48AY1&qgxrjos`3O`XWBE<#qZT5Vh^ zNHhDIC2(RvTW5GiStQackz1;<9>KGHfe>S&@Ga@GV*XNd3vueI#0Qzo&7N;wtZ?T& z5jN}ToS|EPQ%f-aJYl>Zp6$0)#5c9H%-XuC+il*s;20cnG-Ai3J_^&<6>ycT1=63H*^BmuF zQ_aDTfbr;_pUD%Pn`Jd6`Btzm&R-J*oIkO*$_s3^R)5M-HJ1jKN4L@=h4U4qhz-$~ zaMTqTYwlKZA`h(iA3N?mQFplaK-KCpwJwQ51$sS#)rm-b&ag_T^6{wXH0$$J;SF0-2D8_&G?A_qo`acFf-}R92XznJlPgC@3>NlyiOs>uy=ikgP}u6lF>pd zhwHc!nT&JA9htN9&6GlAv?3;(4D=ng2H7RoY2I|L0C|B6+Ib%tI&!|_ZnMp=-!%*K z+R%g++LQ#aisW^-Z(mn#RvRjY9tDdQl$+vwrWZrrzwiuH08Zx)$Mf|RQYLdB+Mn|} zl|Ws)NS+Oc+qnoEIibl|U07LFYHvfZ?3tT~X>migu3PqHOHzVqj0tKj`uDZ^lZ1)o zo`<)JqybyY0fdbP<^f66k^QKfukLv2OF!Ku}FEU@O-J=l5VjfG_or z1`sRgn+;GILHm@sV1xgqm;3Jg!au~FUJ4j_sB*Ad4$qAGAv4BtRa|M7Ka?T2bJggD z_lg>1Z`_|KArM@4=4G*9kTWxyj-F;FMosnS>=K`FwpJyUHfqwvReyn!P5<=d*yB`30SKU zzWe|GZQa`K>cKi!tJLA@$68mbWtu8M;@Z{ESf^#JNr+&jq)i-31QB9euT`C==A6TN zSt&`RL=cCl5sDnDa&U}uLgE|=BKW@h`Q3hhfty?2dFB0lJs*$zy=ox!{K2&!(!cKF zsxrD1g5-Hw@X#`$&M5|z3P*g~RJq{4MX8;Y_VB3L(b-|=-Bn5Rrp*H3NXsR+ z^aTF1;&cj8vKgA#b`s{zsJM4K(4iuQCz!!Lh}ZWntjzzUEJE=LTHdFy((~I+d`zZt zTGFFWuj_7mr;A+n|5h0n9l8Vs+ouG7HGM*LBTnK? z7F(=KOeHkRwpd8o&xUh;w523nGu~+%!A87?dH=ZcuS;R7iNMu)T!Q!p9V9y=e>ye~ zg71+gq3{0~$bEOsW-`UiY4-k=ol+ln2XG9~?{Tl`tI7?D@k7P5NfN&imBL>2{^)k7 zSuc!=(fC=Bh7sx+vF{La24o{_VV5y+VM`R#f+p4EyN>auX6A`Fi&*phg;0TlVRHMp zrln2n}_=)XYI5=Z9x$SNo;0cK?6|tOk<6;lE z)x;eubg%9gSA=f%lXJnhhBXC6`3eWTa-q3GQ?1N*j&~bt@asT}Tk1x^%1iL$beDbc zRgA=>9KUNdk}pQQqwm&NCoVu@@1vj2&&)Ph^AhaB-BcCwyjxOq8jAIXi&T z8j9_x92by1bi?uWJ_3A7bW71)HZVNGGkfe{Ln%26_`2#8&uqAg#x)?FarYo0ek+8H zDrsFPCJ47T`X~5*Q`qTOMo@N2cMtoWYS#@7^7XK<#q7zn^La(7??R>%N@}L*p^Lcw z@wTVgl`a1JT$dt~YjOG5m{J+MD`}ucvRHZAxkJ7U35nKy>#YEkc$D$SsK1V$Pa$h$ zUwaVpm7F(L(_3>Ac^BB^`WEONvh#;pQlPGI@8gNb!!2*7y5FpSFE|T`oE3eG1Ar7R zph_CcGsoE9&32qC>^r!?&|H6D}^OY6f4d>uyZZ|mXgz1=2dQnpL_`d z-jLHp#_`;HgZ6M;p8>qb*dbqxbwnYR-+430Ukt7Ou) z01C|CnHtHN;Nr83WY^XGCY?X(_g=S0EQ+J@cD9y5iDT2b*e7_*_n!DjNuR z-Oq{^G_!P%s1^~wtDQ%N@Jl~?&p$P(n7^69ZF5P-IZA4p?;HzRd6|x^>#;5e{k%96 zEzI=VTOt!fVTRh?i^%|Iv(lRX9Td00A3tI?Vdzuq*ZvLP3m#pJN5+8%KD|NwvsCkV z0N>Q$DzHmm*+X)wB;a9y2>5^KZh$Nl(*FOYNB%l$-?r4&3aUZ1yu)4#tD+`r+b{sD zmK^Kl4zNr+G(6$vG~`uG?AG^gPxG}uMQqm|7L9#dZkYZpW-qub%{nl0J^|8=CbQ!h zR$&siCxi)bMSHAt0$=VGoPMfz-X0^ZI5^c7qei?b*$kV` zG{PDIl|svh%mt|Fkov~I)L)Tdsu}pL99s%h+Xs9LqMbq{*H_{jx5ciMG6e2*rij#x z?tH37t8%_71Z4s;3u`&0ZTAVb2AbmN_E^j=(u4zh_{2#sSKuIW@mvn$&R|G{`WVF} z%5dn`1bWc%QXe|YNrrH1Hr;M(f2ib@Myz=tpFVl)W!@lv%CR|&&25PFIl2l_f zbT~H-&EK8gr*_FgdopW(EJ(CS-I}6!fPNYKD;}w3CD2cs;hu<9$>EcwlZ(PNqwfSD z+Ab;$-?#$Eyi8c3dqLap`98L5n5;ff$??x}=fP)1&NN3y9z06rXaie$X}3~|(9K&m z>3&1K>c4~S5tt>hFm3S;Y!-st)wDeclDFEqEUDdozchWD zE4tt;tATj5Od*5S{f<4ER(qr02AgQ#78iqe6JT!anwwX!p)MBKxTlg@vru*ROf|sx z2{Ll5#`#bfRSCL*WGyR3cY$iwGb1?}#_gGbEj{%jirsO%Qd%q8g2j`r^uCu4q;^pnhNPw&@_p91`k50QiftRb!NW7E)QLvX`|v6ha(U}0U1 zV?&Vr>VnwCT=qu&LsV5$;eaKY*2+u$UWGr*vDv6#z1+$7P)$Fc?HRMAdGO@_Ny1GQ zvrTrfMU*NOiMM&ge|u-U+UHHPU@r9~T81uI^cGskI9)t3p$wU6Lm1wsbD?`2)>DZ62_ zC%&B{^l9JpJv50B1eQx|tAs86jJ6u!w7;5MCz7<+n{X|$XJcDT`*1rekzXjoK72&b z<64632skZP;h{;~+22dCzkTSrHRITTk2~=_E$6$*@0za4{C?cvN0?ARdcmYYkd+72 zH%;=O`UOY@UWdps6*chStuBG{kZ)rtUjwr$9T&zhU+=L#ntPV{0Yy^;9HI= z>kf*^Hp8UCMc`f4m48-yftg#9-{Y|3%^HY$Xp`RbKL=u;Juz=K&z<{CU@hVB7Yji7 z5n!c1>jgTz?9Ge-fbZ$J5&EiUrVbZQ-Lw^2min~MRZ^2um5bMSkt0it+|)Wfh+K20 z4v^0`_7oD(OO~W_+IlCb6W7x4)@bkh)|hMC?o-czo5v!<1F#8hFS_R>HKocY`p;QX zb#>3vg5mBr1IdcliYu|!Rz%%z_FP&i%jtT|BV%hj$7O3F0##t|Lt=|hhTXmlBS{hI z=K(SUl08wzYuTMFi#g@=Zv7a0=4t5*MRlODn%}(`2%v*E>mCq5_8sLs1R_cPhGtW# zDwEyyIkA7*b0yeyNMP#G(kBaz4@;~sl4jr3maU$Up=KkYI4IOMOZ(P>`CApdMNrQsiakMoVMw30Kpd?I? zp8=M#WFFYERY5^HsM0!ggbsaNS^&7%joA%%cXzIqoA_Gqkrn&01{hUb?KKs8zZ8JXIr1_=z`b}zHEt7y3%*t=Vfc|rfwz{)_%*+ZnGD{a zM6It=YOEr=722zCwvV1ro-n5c;8~oB!1>R8y`qE1Ok=#fYGH2e^&#*?yUYGx#d#!Y zhx*S~dCX_|&^f1E-<^%!n(=hm0<8uJBi51yUj?Yw@Gz;s6ys~VhbX3&_@x;Yb3tv` zpGW?>8Zv_owhW)p)U#fH4EdIr=pVFVPN+pKej+fuY#L^O?_!Pys_{zjH&rU=!n!m7 zUrTx{i_OBGLiHRIvfddP7L5DgKu*BTB!zhVCzCCHSSeW9Sj1ThpD=gE@n0~K&~aZ> z8BwtJgaiIyj6Sek_oGDRJm;@X0l9DZCRUzXK}yvx*iG1I?exSg02rXWBB!{p{@jNF zkDnL%2mU{W!PaTr6a7{4W40&Me{CJSdk~Ugbx(XY!13ASyoaHzxO~TnyPjk6zD{Wm z1=`Y+ShDeXfYtVyJfhsbdJExy-33 z#y;3Em6H15$H>r2B7a)$deQtu-lHUkhxUnH<(xq`*}t>K7G&SRc9STl+{*x4C?9^i z0i8>%Xk(LZa6KS-_!yoQW^3Wg)71IkHI_FLK7W6F zr_iS@PT)%6xG;Cn%M~x|WC8PE_L%E-&)@$dm#C>%hy_< zb6?Qxr6v0c(ys_Xz*zkTkncFcUfI`>CTNafk%@}9P8;BqY_{TpRu;(}yPz3PFGL?F z{(ZpbTzv!-8}~+_5HO{ZPT zSKPOStePv8L+ZFG$;}*o$NTYm8&Iw!Rxz6gp`NL85AnaORLu_DJSqg4LcTT=MCS>m zoE*u!3o`Ik*-jsWsH;v6#cP3NmR9(!BE^@`}S`On=xU9Kanxit`Q^=bNrmp3Wp4vyHkdXK%Y{o(C4qWJg( zilcVZ*u5;E?K&7fpBHg20cpacKMKhw24 zYGA3?0(FPNR!}zyUq~xQq`P}6}_e*8BH-8eh zJsKVC%xzSE^EUTU#Zg~PbpcU$-qTfuAJX6s;2bNVG?3B`@>fUv3DeB^BXGLWnpU2O z*e5U)^@K~wH_O{wkka+7r9*V5=7rViu4?resLuy>>H-5?m<^c&&r#4&(NnWnBJp4I z5!sVuA4R>DQKP2o_1!G)3Q&n6-0|AWEamlXM3eCbQu}d-lHZ|a#8^PLle~y07a@(Es+{x(o)+CI?hc0Cj5Yw~yA$9#_ zQ;YRwyu*X1z^JC^gwDd1VkK#-e)o50-q80aiy)Jw~opezV1COq9C>~K<|rg|LM}Q(~#A}(%$+O z(3de5)OqW7i0GWm!#zTaMc0^ zW52<1E-o8zA%?nn0;D4@`ixC*)a6MLoOt|u@<2V9N?@DF4xEUyPIl1kPNQJM`^*h* za&KaCLX-NBtzZrsS^47NrM*w%&P9lQgpvf#L#hnaUkmKt<|I|e1`ve_xAIn7&#&$F zejf8b>0KNDbJcwvFd)mb0M_;-u!Rpf&~{Nf^?#Xg*Xmt=Nxy6}8z%gaYxWQ$cZDgI zZA7JfxUF}f8UTJzB3e&4Xyyf_uq_*61iazW6A%rY9M4(0J#pltQunIWV~B&y#TZ1rpRHdjPsJSH_(w1a`=CM^DrYhbZw`ylL5VnAm2oeF5O$DClcr1 zSWil7JSaIy3`8O8lubxvFba!Ulk?BZ5sL1IC`X4;F{tXrlOkG=f-Me+6E|{uYy7|! zhPvi{*Xs#PVR4<(;hp!1k}GX4y07H*fCur8iEG)fZ6#=wKGgO}3ge_~_1s7kIy-{V zvetr>SPO}9uY$OWRZ=z5WSS`H;dY5EeR(_i|eZEj!UfI`To5kCx+ zuBijElPU}b+wP~h8ydX7x%@qvEbBdz)udy?wj*x+J+ppIncd?0IPukZLgGmv7qU4x z5Ri=lc=K1rVH2EJxF__WBa=IBAXH5qkcx*)Rk{z2Vtc9|?^lO>f0wCQ>`WQm>Nwal zG2pFdb6Ga&-nC((e^X8iYND(*D#}Xo8ExKKrg6FAs|Qb<+NNjT%S)f%&;3^_13a^W zKrzMOPdhgAb{g~<1C*eNfchuYwtNaw{irSfMwKd)2b5=}=;*(@Vk86dI6hm5G1+VruA2c_ zYQp@am|F+F+(bH`y8F}#W;3hm>f0@Ck3eYEndU^jm{If168^#TBF*XDcM$L?FYeII z==uA%?TR#=xydhb%|h$+8Ra|Z_>y)6+I*m(qj&TuZE~H#35iMI!*Z>#p{?6=(TUTQG3Ieee{(?KHjv-sk{l-e-(~zX;U$X!nUq}0Pm%E`W z3&?4?$E3BSspSPhGdV-# zE5P5&|F-_zD0N}2$T!$;qaX$Ry%93X2>-iD6MC=@s_J4w8n5}HjuM8{0Irakoi|Z2 z3S4DMm}lx_6E0gm`*S|QDVr5m?c3#mEI7-3Z^*q}nY94c{b<$T#;Q4b0n>LgSO6!t z#|Deqk?X?T)UDRZ)TA*zfXcc!a3gT*nG1hD5^r}AwiBQ>i0k0#)^PUp#s?)wwumk? z%?pp^dyKBT#v!{vv##1fRgvpIyVS}n^kta&wa%a~=NW>dC5RkW6)7NQjpbsNVY;KM zk>VSZe+ceD->+4H;fS@Vxhg7R24IWi+H^_zevmLa=7p30{_5b3S~uLQx$Qzz%ak!& zwH|%4D!A97$}fzUU>--0CT>XA)z7SZ&L9P*v~xvm#EmbCk*^$2W4NL8kU|E*C2?|G z`G5(2OhiP~C@HbzfM`V@<1!Au{-D3J*i#7R1FVM7Y8yGCR~;vOW@ZuXbK>^?B&&t# zH<5);xiX!x7QTloTZvQ$m=Z2jKw`*+hFayf1qONtgvXCZFAw8`%N9F{zd&8S-;k>; zq*-^2Mw2Q(i^yVnBOL4OR(~{|wdonP2z=8FIjUUCl9LE(pKk50sG$OKN6=o3=N^u||C+ zteV0k9LO`zhMKam2BZlJ5fgWORMoTDM`k`d$c}%*S_%jYj3EAbURNJQ#<8v3pi_%u zKwR+mkA!<4@rjE*-yHsiExB0&VVGt)#2}eBcv(Y0C4!U93q?7qGknOS1J3Kc+nd9* zc_d)NBffsM^&y+}CsBY?UK>k9XZZRu^k=+~?3JdWk1>{3^wf8EX+SJt?+!q8!C_Ri za6rVmJE`i(EMF9ZK350C1Crdh26XgvcNhyG)>Boq4o{TPk;^`R?y&NJq1|bf6SKM) zP`6O8Vqf<@n#;6yvopM3-E0TN#Ieq&Jt>u3qL$2$fDekEma6k%gPx8SWj!Yk?@iRBlHO`gl|J;N@2ax*8NYI56s`Dx-x8!EPx0Fm)i9A*>I zP@q0Op@ET0xhR*e?=|L)kDS<)-SQx{MAMJ`HcA6H>wT^9XxwR%x!NM}KQyG{D+?QS z9B;(QVKGaDjC)D@q!QqA&R$P`Wak4(S~PCGnz#Dz$5e{ukI{}hw{J(qN-8}VQM?Dt z4eW}TVHOx0*JM}%)|_UEh>V*ZT@krQ9=*RpA|LU7gq?T11H`wJ(C9aS+fm^fwG&!5 zF;Wl`q!R-8drFA3rKyO?nhJf2@?rZP7i4&eU%HI{6T=*gf(G zKW-i?T<=h2o>`Cc8S%7iL+ z>w2bK@0JGk6=1VNw&qBqVm_xYFXG77`z)#npz9d31CE{jxwU|!eTBu>cYko_NJ(Re z9@Q^^$M;dUzfDI=^!nH z4a67Tm_YJi5S0&Lt_I%2*%ZP{L{I2)K53=%mn8ZykX7Y{HR&pA%~96Sg!iJZVIZv5 zpd!9*-H7Brv=ybW1NS;nqJEnd#T%sX?ryc<=-;+`;=TyM2t(z=rP(Y>O9m~K6hbS4 zS%gIa?&}bZY1SRP|?K#;DxP*5*vCcEoS_o1WIs(*ltw^t4dfM zj^J)K0QMfGQis>sTLU5c8-s|z_C^&zgkbaf^wkD2VjaHw^8lnTaM7VFX}SBpQJhj$ zK^z@*#ps1BRPNl=n2qTB_RLc(Uj8acS+8SW*D}Iu_56b{zz&$c`M&<#w&bEPtgz9a z6QDr?B)YE}Tqmsq-I{SdkRrEMKTCFc8?MkHKdvL3F!AQWEyA`&rdvtd=?Rmc#ml}t zMVG0cm8h_(x+&X(79Qn8?2EL15+17EcN=2t`Bu%&vtNl$R}EEj#DcO>cJyjDETk6i z_zvL}h!<~vKakk24oXja*0w#9l{jUK{nSGye-8r6aX;jQuuf%9fme^YzU#QSGae&s zdj_<|;Q;VsD`lF6CJobNZLz}VlL712YI8C6I@_a-pH=8{JV?_mMR%MsPk~jTyvbv4 z*lF_*YzNvJrJ%#Jam=1TDdg$cyLw9MHsWpSgW9r(YNAVfx4%zLDHZ!7*F28veE&q? zZjzlUz==ApvWb|33(=%x8fnEG#+kYVtVkGs;};=wietT`lLkLa=hM5c;S7~?@pgOr zyelS0KmankjFRzIX9ofu;wt=(Ask#R(HuZX-ho$iUH$%TK%V7-+$>=}682T~$WGI> zV6e|y$Ok8K3r${FR+ePCejc;O@;g#|2LDh4e6RaY7PR>t{Cx$Tr_LPEY`Rc2krP|r zj_K=kSD9p#FABtDXbXoy2}IG6mCR_~%cgg(gprtEi_a*9<6y&hI<^dCsr|6`Hpy*G zF()l)Lo)oMBm@50jYCb>>s5Zy3azJ^>)XQEZt++j>d2jU+-~b#DnG=_7>@-2%78pNUO@Q@ku*6xqB8k0l+5P8YCN9^k z+(!+)R5Tp!KGW{=R`Pn(R$I@6@XjYHvV4Np4b;t`zo`Pd`Yq<`YpJPshmz4aA}>7K z64ZKka=fOnTvHpzdwwo0FL*;diot|z3;%#o$eb%<2@hmiG2F*t1ZrM27;J`%VW?f!M*%K>!!P<;DW zl9iDo$RZP8hWCv~MozPJ%6!MWFi{_N&J8V05(Ug3n6UE(M}{=@b^KNC_)r}LlGW}4 z?y75FUOZ-P5i4$bWt~HNqxnbfj=`dCgbr*UN8Ubm8uC-0N#%@=RsjZ%fz{sF!zuqL z!n0q^`TK4C*7j%GQh3bh0*JN`9tGB5WZDt^gOMt|jvY;Mj_dI^K}{E2z)EV$-M&)r zXp=mt_&3bu-nKezS(7~A)yB(NRCFG!Dg-++P`1}Fhe{c8oQd7m=KkM*MD4xQiHvX&#eQJycKB5f^#kGzAg37(J;xS2geB*{UB(JvjpNTY? zVCOSE_{8DkQhC;cPQTEsI;INj&0Iuh5Edp0AK~STHfZ%N{G+~^jKR~_aVV%v zgG8{PTdbm8&Aw~dkx1T`Y2B^a1{FJ&>#`Nj|1*N(yG)JM$8GuV^nsO7*S)0|R0#f; z6C#s;c4sfCaOUgq4SoSY(}{um4(-8fwGE-5^cX9REh2Qt#iqz+(4SCq@o=!ThPu7< zbH`m8DVwwZV9t1N$sQ1w4P`nAM>ZMfPj^Up`95^~GAwBPjg+hVF3176=*#8^YiH(i z_5Y_oYb+}dO83iYZyp^2K@;5l^6=i0@z$!7atK)TsciY)f6i041M&bNB#9rjW6iiC zr*r?y`K46bykv&z%jN(VKU;dBNiy=KB^9@n4O~D)$kcCN89-(1*C$r5%@7JEZ?Hmm zD>4`fA}9|K?iJFX!w8TD;7-2!{~QOcuxX}G(tgv^Ry2gfH>!DzS5 z80zbVNVnM$@XyuCAT8Q$h=vG-N1P-~FbLD4>Gj1jmV`_;)INa~7lYJ=>`eF&aAmlS z?6|`S#T-kF-vbssLKHMCm5n*pTV^mTFLuooSYafx-1rjF*$`Lw0qO587413676nzJ z2SzN@2w+n`96;?q7d+9?;t$r{3SvG6%k@joP?tlZG{ZGvwW0hhr9Lq^!z<^CJ1U+S zr?;3~on#laksMNSp!7*zX$8Eex&Z%349NVxpe>^oLiJe=@_45@PU6;|ZkuElQy>nhr2X>V!7?zk&0sbQxx9iozVOWM|-q96>!Bh_tE z@+jaI$vjoTX0Gow;w%-baV+rk_P=+IdESl!$R?#;7N}pRT${N@60*h z7<%=v+Gqm?K9%0H5Lrz9LpcSW+FOIX#%{te^PyjQ1Uub;*w*y{i{6wN@pSmD+-Ab7 zAC0~;lIhayL|$X$k)@x{$$oxO2+W>=MPSwCUi4tr!P?HhM)!lPFv|MPse)+t&F4lz zZ9otkKf;YjB{3>E)}R)w)o;LNUgL?A2N0@^}On2Fd|9n0{tS~f#<1YC&?+`mYm zkNRO&v!^s?A4=RW)Plm>P*A*eu9oCb7c?>crt);j;FaAs>*QnTf@1qh)&pEq_gzmf zb4No<3qWB@#DWvq=rSj1jn9%`JQH_XYunofsJZCp(~-jbq}U&u+w~GAH%USZ*4DG= zEr8YrM$1h>^$nATYaB8qZ(7WPuEh507shV1*392pF`+=Ovq2p-X{Vf(Zi)8s6B^4X zX6N7FbbZ`X)UBWp+au*JQeX&%q^D)ufi`RolG+>*oV=4yfT70>ls)>RCc@Ir38SE~ z?GnVs<8&A%CSTNh=&>CH3RW!FQNPieg++{>?#kD3hxb$#eqNYDH}hl45TOYNhj+dbfwc ztaR?_C_~FqxWGBq?+_ptE5Mc#b?%iuz_+PYWAff0ELAFozE^&qy;vNusJC77N#o2lZ z|E4R*pX_wTklY1+tBjMyD(JP5rpRVjE zsgvDG&Wk)~9rN-G)>TXLFaX(lDnTU_`P5scZVq;3845<>1eECx8pdtV954lI7z$ZIQ2 zxcj=VuMO~kb86v=OP0$JnJarrT7nE(c?f(^Eju-pXEeg!lJ#8Q|GkVSelz!8VP_QL z!>fLN-64&;eh9ceoBmZ|(By>9*F;%jqUI8Dall~%A*!aZAw&Q@6T7|~leSCQMb1R% zd-)AD5OwR_0rhz~o;^2Y;xte(_K>OY7%g1=y5(#3|IY$IN)*{~uW)@d{4ArT`3Nt1 zPhX7cBMw#KkcV z4RGyp&oFQ^SB}?JAyDh(}J;b6k$EJGk@+=2*nv16@Dp zcV{7fmK(bm@8wCFJ=b7=}L>kM&3FjY!bpmii|~P_`|_84R3+a=GD$!KTfa*ya4|%I}E!j8y|Hc z`45kRz@Vu%93WnCCPc>aqNne6g!)!UpV`=9$$34W()M4<7bpH4k6fLAy5-eI*g1M` zr!)cG9aIr!aIuWZUKyRw25#jSZA7LRca7wN(_VKtlW(P-RI&C^(leRx^HzkVx~zlk zyo2U?>IZ|xxD|mF;Q`G}3B@JgRQm#^5PR8fH`q@UhAQkOft&DAQWU`@{RzbC%W`EC zDujYdtYsl&U8ZvxUyqq_5P&~}6SRy3D;I@RNXSZ+FfvUV$8|fRRy@@fSPRY1)IDTS zyArT}VBGg0?ay3i{g64RaiI2(R4MRxna**id}Ar_IKj^rjLgK!Zks15s)VGk+P?k3 zu5J$NR~tLpt**KNHM_BGUN87Wfj74Ig6sCL)g8y zrwOMC%G(rW393oC|L@iAsz&U{jmVx*x@qE>_YN}E)4tT4uS%H)yV`Bq(;c&=qyK2q zZBFf<(EFJy=;?`PmXEdi(agFpuadSEYfYy+D)@na;LmPY%8OQTwMtW1+O@mqWx3N5A$ff{x|Xs;kF9Iv_x=RWB0U(w{5oh6kGq*; z^lP8{DeC%v8fkM#{K{tadeKYs$$VWYfZeq`zB2=x$((=uKLNy->PSJZTMRBMe#g6N;CcRz zx9#q*Yiyqhp=R%W1G3AAy`vo(oC$I_l;w8-AKk?j>rORg>uoC-<+v88tpRj}wksvW zu6O3&pH;)aAUns6lj+D{Ne64_x_?-boftxcb@< zM`NGkBrx4+!#YR&aYyEDxu1Rl+JYoM{G`BKl#c|YrSLIL;Pji@S-FTnvx%cEeQ?k6 zR1c{C)<5j8aATb&7f5KiziS!Fhr-#`@9Sk9`@e*=mtNt9Xy!;v2>(&m?$qALo$_@f;b#X+r4m!`2Tm^(^2*m3ggN=ePBKxRH|)(|MBdqV7(cbw z-JH&6=&K&V2|u~M@QGUwsMrmIY}vtP|Ix56dMSEZ#LE53QM8)2@r_}ziVFRm1djD< z>H(MukHc{-p{}+a(yLT%^QgUpUIMGFOTZ)$GDGUnxy{1n7r*8Xi@!^CK(E_|y}wd5 z>d<(3Q_N!}nbz)qZTzbm+V=n0YM3-Jw(#LJrtFWjTB$ zNK3k1uD8C$`+}+SO2xej1SPV5xZ=PHKwE+Ne^4}QKUeISTB|C7_rXq7HEKCQH-7-j zDYjmTsNb4ciel1moPJP3@N5IitQo;1B;=tlKvUHZJ#iXI|M?Jrz63gqs+}F~8a)jg z$FT@2M*QHdR6Y@Q%|rRHqs?0Zi&_qu6_1oz*MSS%usu`2D0tBQ5(5cKUCy>wobih3 zuu5d*T#H$^1X^Sjf|Wj57AL*jKi;2U_ua;N(>0PGa^5{VhWe9|r9>n(YL7{3b_$2> zKeAqerFOSo+!-v57KDh#)eq#@ffOw-T3dr-WA;f7KEjZ#7MTU~Ct!a~)egH1F!V(U z!skUOe|=r;dxus}p`b2^pQ5f8$FlzX8bG(A=J>zS2q6 zC*07vyV#sK@w{g0<4OOOqHkPH40cB<%dI*34Ki=oMOwzmjLk*!n8UeaS^;vUPQQ7J z4*Jp#tB+GzR?Euj#v4XF8T|7wD~Ll}izNVHt8NWn=KRWvwhvX(%p8jd*;-@-(t*v? z^x+aTJyKVi?oEO@5L>0$SB|JLrBg%}wE$MZNz@{ZCJAVK03;csShjBxq>92&}I6%jXfyw2@3hV1B0VW3fDdvJzpF?E-*yO{h{ z9*M;6dgkjJ%zIIk1U{AZB!)_3XM1AvnFHf5ZMM7lkI0S4$a#b{GsN*~ZOZHxFqfq_ zS^f78uG^ngdpmV6^E^;S1>=DP`cDq0sbz}Sk1C3iuv7F>Yj4I}xTPIC0Km;REk!YO z*JJWV(~jDAu>5FU_wCkK%1y|mED>7Bzl<>B{*o*j6^X0?V+GGI@+kO z(>=7H7!(oo8K63CLpE z4z&4Wx;N-QOPDZ9vT2sU46F%tJ=(*~aFWG(aF*Qvx}Vpby^&G6v)2BzS6Yv2V^45< zb^fkTTKMU8gmW!FT%ODZ@##;z;Z>5U5c>u{^E9my!>y3hPLvsw79A+_oH+U^$S zj{#M=$xeMTKfc}fhgM$S(H}U{H|h${rKn1G+H+Kg>57ZkyA-P>ML=>Hu?dCcv3l7w zN#uB=$v#fO)(w<#@)_fPFQA(hC2TZB)r>as*eG zb5<^QCM4lUyT2NG&nP|$ZEqHS2(8-~ik29=Y6cf|zmt{q%DH17fgfs*{9Z7$KyVFM%Kpe` z4v=$!e$>K6k@22q=3OV2KC_=aK?U#rZ~~7Roy!5p+_B=V1;2g2-oV|FGSsj35%G2k z;0!F3?TG0EAb=x>%os4-UPG~zBOH@83!6Hr;`iqEdMx*7bAZ~fOVrqGCJbX~g$z?|Hh z*fMm-NpA~P5i1Sa9`6Ifqt&Mor1uynPwJ6NQNsFKRXA2j`WBmH?UHD z7_49wL7g`OXoL@McvF(+0y0bzTjO>^*4n0ej-Jy!|1a~lFnkA$SsoMwJD4V76FGBB z>#YHUPBF~E@tMZtnnQMA!)I>}cGC`4A@OQN7P>@sH!%WuCx?xPl?nO#$sqV&SUPTJ+K zgKkNxlT<;q8@Uq;{DYVW_(K(k!G>(#E>rY`+i*VBzgvfi!Lue*G3!p)h(RYVD zZ;<=J7hp0=HWSZCig?+PXm^+pFt8U!4yVa3ogkmoy{8%TfCAB@D!<@EsQRZK3>s}Y z`3?;i2K}m#I=&JF?tSW&m&sz914sO5rc;{x6;PDmeC3SCE`M*$H{LRx?$%hUeGZq| zqv~q~;5FkwOht2?$EfwbpR(hi<}BqM(=xgWxAZeD_3~uE6s-_!s5zdCR1{!>YS~NY zWMz<$J}C%1e@tbn+{xY4B%hb7s{{y1zjJIA!0M|Z@41X$1Siu~%$brSkyVT*j*3z$W0PbhgLxtMA0 zpafz@kS6KhJOtfkWACga5F^LIA*)!AoiL6ra3l)?d&OVekBivNr@2U7C}yGAo*=)R zOqy0a)H|AIlW*8GyoY-l{#0|66vD{C(9(10^}TV{Xz2j33XnpD#VM)lI@mzldfj!@ znTJpNOqW(kKtJTdjK^s8#U4!eQD${aJKBYci|id}fo^@$kyt`&6n;A{_&{W!AH0O^ zzJ#xL?{n^;&ZA=D01Y*$9C-8$OT~CY03(!nN$zTln);54q~w)^T?SRRUkzEdEtdEB z9F%ZsUDH!1TObAyCitHx?#B%@$LqxYxIA#j@IbvTt_U#X3c+K(8|#3#K9l#5 zoMmHmIn2SumxG?cf%sq?cyvvblW^# zNln}TARQCLO-8a(Hb$o3WB|Z}eg|eDX8fVQYq14Dei4@nB~7Zg>FyOf6F^yN?S3hz zdA`)u7@4X(yIi5WS?k!WDjABPj&_y#(>VUn`EsqmB=I8DvZ1F&*lQZYlV~!w2x8Cb~YKSY+AccW%-!Nx=&};%4%GX zzLEmg!Lwns1csk?&a&(w4x1gPyA8pP(&r0+)kbu(`uAiEn+t z|7j~QufSe%C)5-sx~b+EFMu(?tcr_pO!N)aHL^R#2Tsdbw}eIZN1{@l7ppuJT^Dkxhs)Odu1b@+`ag{2isY9Z)H8tsQsBvBl04wYM z!R`#!n&dK*T~O|5$nFe30H%c9a=7OSJQj3}J@+}>5)9{+DSy3qkW#=o2}`})bkduQ z?j*1(E7!vV^m9i}Mp$i4bL$)DV+10by1cJ+YE_T`+**3qnp2vNx_w;!^>4C2XF5lk zqejcL(;F z(&xx3fm{^eT*Yt=kmsxEkFZe_BN2#dti>J!TLW6#94`sCy-st2YJPvc?&}C*?(;}PS-@7h;X4`T;SSaKykw40)=9&SoNn-KeQ6XB! z*#XDX_LD8C*~a$3Y*jbP7RrtiJ)s0Ke*UNDMNSw3!)ye89MeOHs>(RrLXdrn@e&2M zS=&r{q}@tGy}{lIQM;Lr9p&QL^m~GP?fJ!z)A+wkJ{*quhBYfnA~c{}0>)^4Sy#0f z@vW}1>x7t{N6(b_hqjX`z173n^Wo70?oU`R@DlCrM&etJv(aDE%kBOvoYDMTXVtc; z4eECv{*APhkCbli?2V(pkr}4D2mjD4X0_Hfj?Ho+CS20*kPY?M@ymoqu zI=gfiE4obc-}HpI*=(J&18=jVW7fMv>tR@F#C1pB3vc)lPp&k(fEmFEr`sp+{wiJf zaEzGs*z2>Qwr#JayQgdu-RoWK3=w>SU%miBAWy=ygodveYg0?{mH*B3%U8PAg{?ZS zo|BFeJpc3PaA8xY{lllLgQ%gIEp167zhXe|reJtEMN)s&thLNLwqG`hxY+eY1pbP* zRghFE+!~KBPb+qeq`DqJmFEE$!O)VXzKt1U+rgl(uewZrGg}+Ccy#DGAk|b0JC@t# z*!@qeZx!d^$txNcVoqyq3P0o>A~^3=9dWZ3Zx=OW-V`t9||bSip9JIx|O_U@=et`ByXpw??LHW&Y0|q@9cHKddrY~vL#;bG0T0_G`Q_o zJkjz?ZC&xp|;!^3A3w*T3TBUr5zs{jkoC zem8hb(Ih{ma5Kb)A-mU9CzSTt@!t?m3H`ab!jg{69{+uN$M)X|h4SOGBO6>x+|{&G zE1$BuG08cyYx>L4#g61Ux+dDye*OOebwG;0Z-c#WnKYNW+=kn*eZCFWGU?y7`XViV zOMA4w&1+qG!?i3;tFP~SZayQtv{&ViFs7HXb>0Xko&I%sU$+kT;Wg46(@kT{yDKd} zgGUrb;5%2z(3bJwA;_dQ-jo>jD0+4gzuvu?%RUiZZpZj|jd+GE)g$FkRXG{3v_Y8e{d>$`AX1h#RSw%484GK}Z3Y{cnw!`?-w z;ntm-p68M0I`}dFdEv!fg|jMec$eUh?Vu zb$Z-ZzN&t2gI~vEnSWmz!Y%b#()zfs?<;%DwcScI;%L-Xu3;LmbEc=&~ZoOWG zOn1?`Z@D(}C;VMFqudSK=drBQmVMlH()!%>DUX)%*ZJJ`?>g#wZk@ZlukWg>yULr6 zXP-M-ZWnAh8t!@MHO|L%9&Ocfw)}lP!n9mn*05v#nAhn(3%8^oH-8g*xy8{pMvu5lK4V$a zz3aTBaTok3=Ll=QwC*cI(`o*V*ViNMRp}+%@>-l_-YDZpv-8KiWqO2Z*&9YaV_v6k z%WvGKJK}Vi=hk5?H~mL{^heV#e({Tse7Z`U5!UPRu&im0`KCL6DR;w-xMO+=-*g&p zq&?;>(<9Ag*?q28@ol`@${ME6OIWX!?Rk!o#u8szO>cx-MSsL?`!sH!8*h1S{*wL( z(`B94yu9wRrrqadS>rBwHC)qNmN&iUIgc`p>F1&Gal($axewoU@NG+JwBAeDh8gX> zif6;EDtno{k#5V@vc3%6CGP8>x#aOY*RAV)akfWlHLgay6Ud^`+^q(bGQ9{c9aE1`;Tc$UsrwjCfqN6@r!ZF`%Tbe zeY`Hd&ErdN98Q1wUwnP~@|WJ6_IB!x)K{0Rz+PR_Knu#5UDxn7xi(7|W@Ez_ip_SJ z`^PzO7vODf-mF?`NAcC8e^T89pB`m0hh<(}+9vrmBl8U^!4ACi%*!#SFXowN^P1nq zeMmlH6Dvb8J zykG`AG6)MGN9pBN@wouzT7IBPpG|b!ik&W?#X29dI-4F6`OoBtcXrm>b)`{yYj&fD~Cht5YWLfRm2;s-rekKIQaZROM`W+j28>TK`!- z@;v0Vfvlp|szK$ajQ?`Qe^(g2Z6NKGD+9kGHPf3Bt)mjD>}|Gi!30Oy%<#k&ZJI)_ z1DrVXQ`NChr(j=l`N$XN8vZywf(N7?CW`rrQ7|0Ooq0cdY`XFAy1 zovzMK0xwLr`ylb3*B+&RlJhnBz^j`eMW6I2X9+PNRZ@!AZ3`G}BYxQ`838PG|Cd3E zi@^MUmDfdR3ONXBdFv#Ue4ahTB9DKz53l-=jy07w+?kx4{ES)GGudl=5^Z-4Wbrd{ z#c0Y_gsaRp2G3@YvdW8X1{r2FazeQXiN~cM+p#Zrc}hZ zx2B^H-kZL7uoD7BN#Oho&G7e{g!HTaZ09K{z!D}fUIUTDIiX@XF<{ANv^b8)n2EX?FSYyo4F?m$1)s-Lfs|KM#%91v|>ra<1bg>BseoS|{=MhJk@p?=zVOL$7*T;z4yvMwT`*k?0SKF?2y{}$1g3ZuN&_N zJ#N?r52&AjoHG5J4#;pdut^0f_*ua6n{V>+P|h*MsS{VX`PMhp*(b%%EP^&a{6dXxB_UT^UsBylt69y0(yAJAUCM zURg_PVhqAFh za!X6N%d48Kh>Wpm^MxJp~*HJmQnYNN`>E|7N&P*y8ndJ-}S zmyUY*3Nv4_WssV{+{pv-&Zxf{Kg!8ho|G$>I>9({S=Z3no$EPyTg6AdPD-dlB2mY?)&^Xls%<<`GaW>lRz`DMHEe~-M20*EMaI~*|DYisM zY7>~sKSOVi^d;)O`&)3q(-s@x*5sUauzk-#K-$+Vqhk!bcb}JB$}dG zcWDQtmDD5Vg^!9kS=d3@)#Z8B0RR@;HmrB~nAVosU3!i+ut@th&q>9yvAC2`$La(~ z>=8P44f)OEnzF>W=@Z2xc>sl$@YhF8SbC|R+wk87&%S?7AGTj@Gd`ss!9)2nrl9rN z*=hQt@;i@yI@du0>e&t(+u)*y0$w4z^pqj}1DMpQrNVP;0lI^2(l(}Zbaw1e9VZB- zvoY<^4mG;tP#isYqz~{31!+QvMAl$8>oNurtAW|bNK)8y_4xb{NHa+ zkB(1^4*yp@tI5sLd7eGe=5C5#IMsCi?9cve`jbETlj*Pi>aVg3LO#u_dCR2pOgC=l zc|F1kvpgDhnLpAR(>=b}K9;n{>veRS&q%ZLR-IdiRb}_dds+PZ@MxIUxpnLO=Q-bp z#t74Cc`W&M*)qT7v3yz9I1TeU&du{>cuC`B@Lz{sFG5p2d{kH;#<6^R6_Hl74c9Pj zgk^r0-*$cxoZINVXj$vF3cvMRRrWG@BhThB<~8ju>+9uNoK<#gyj5jO8ZUa?wENuh zA0HpTD9KM8UfaKQUn(%>k7?n$jz*l(mYp8UpEtea`Mmfq3jaI5`PTGbe)Bh`2b+B3 z^#aEQ&q;lB;u5Gp7?+;3&WoAlurZ|SQSif~($At)M+_e+`I|VO20+0wz!bnA8D}_8 z=ipx8mFXPlcgJD96GDGd|_p|`RC_2fPwXz9AI=f^_@NByAki5GXCkv5n7S( z!g7OmDb%4FImkCi)bsDvQeorZ#>v;I#hHl{E5X=-vkw;dSMTe$LRpGJr?}hX193nm1bb+MXygFqMw0bH+)wT-&0Dc=Adh z2z}da>XJP3tNxIyub~q=LErk^*r*%3K@|Tu3a``Vcu32(-uw*0JftCF>PlT~#Lxb!E4VZAf?_6uoj6C`dE*a6P(hL1MzcL>lnzwp1>!3MK^ zXj|r42TmXzmGNF>ZC$uXkc7(D1`be;6y9UnM^#AZ8ptY@eY$zYN28E7; zvAMh;OhDqBmlv^7q&&4@?QkkS_9Z(mx`QVTr zIX0Dn{^qCt;AK1YNZ>u&UUf?WGB^j>ilv#g6?I; zRP;wK?U}x|u@gBm?x`zwuxw{@FOw(THr2Amu~I|6SJ1w263q6G-aB4nQ^)Y#J^B(b zw$U8uZay^~n`DgBCR}e>Ny-ForW&Rb>t&bvMaj25_xb4uzdV}$&%gU&(HZ_vJ#wv$ zt8G-F>9if~{gOx1afjRwfB3^^R?sEgGAz^0c3D2k*)V+`VLQ)r<8-;_F|YGGuW`p~ z(+xM4cV3^nY~A_3aIXu09o<#=qyEZ$+x05^B~HVP`E8Gp_7ZM{@3K|rC5@)N3f8=a zzYA_1e&@d|zI0v%jh5$S&&txaS<>qKb@E#780J0F!x4o0`OSc`MC`Hvzk&frI-i!K zD?@#|(nkBXZI^Jj*{5MgI>I-tPJ3>ira#Gty0v~wy+0{>wfvrMJ6>0vy$-sE2m904 zf9H3m|KY#;x6}XhZ+^Q1bbK})O7+y~)Y){H=|E@$N77Y_95{7X1~3jr!cw-2vweDU zO#WG%N}Wgpx(Wh-*OB6P%GPY@>KKB|KZ6uqU=BUaoGNf{+iL^i%NAnc6yx0KHX|^L z^$x6xQckfKMPHJxt_xO99Uyg(=xy-DTwkvoW5vn=PC51J*=Qw8_>y%!5dp3;>9AG+ zErRkPH_O!Be&nAt&Lys=Li$ql`tsqM6-l(2=Okluu*b?1%AtYixzFKGx*rt(zX zNwwrrBk{CV2U=wpgDBt-RXVmK4;_AKL^gRRpTJ|jDH>Q@F*6{Hx;wEX5j9qKgAmJ{ zjK~BIX;2do$=C2dypVT}dn2j&>S&oO#0ERA_({3j%LW0chcLo6U+pSSR0W!o#^3_e zB%O8-xU1IM3Z=mJSN1Z`G7o8MQ-fgZTDscARYe1KgFofT1PDP}+HI~0U7&Ye2c-Kj z_%=w2U8H9_Q&0};#(+`DrF%|*Uh*S5lTzYn(~J+KOEaxftKZhCL8J2R>{Q>Arjug^ z-aD)|gf8QVX9IG`fN$V7w+n3^+m%rD$b)IyMYXZILOT-K{UHUAl+SYqtV&jz(`HdC z^2W~8J^V{IZJ@oOhumq`5kTu1yt4XD@R~_6uhAoQ3~l)dN>aek6yEZl5IH05jtN(~ zH`1r!1XAp7v!UDo{+cgb&6AG1E20BDdcs0nAfk-*U3%Aes;!!i3*oLRr=F>^v~$FC zQUKKh=lrY_6_)L7YfmTtsCVdV3)`hOchx_W1n}+&#w+A=QbDaLN$lA|!f&PyqhVr7~a2FJnC!W@G2?e7G_F z@Bi=H)8GF6_onyW{~-FOkpHT_3byk+ugf1{mg!YEowvWgpU;|l?XQn9-FfTI>fZE( z>2%X5+uY;}(>P1`hBbdYnx=Wn^ay9VX*B<3`RlsYmOch}AHJjhFC$OeV&vKSk951d z`HnDM*6{a%X;{xqt7RF>mgyz0W%;YPZuwsYt(T!O+T~^FH12KoeO_LUEH}NqIoxt? z21}6Jgj&LWcKz(Y*EW68PSN;FyLO%Qd0GBxzSd@Kmlw7BeeKu0gzxmaI=e5;j~nj6 zgTp+>__eQnZTiO7zdn8a_kL&k#_xW0`r221d-|;}yg6+>dS~JxM-zlK_6b_Y6 z1x}ZNK|Ekrra27GudZr~bpm;^^`ESdIEjOj;-(BYOGmuxF0LgGn9iz)j%I>NXuy(d z{;X^N%a3u&D2J|{}2~eONUBkhAbvM|>$y9d! znrG1{9syKe9c_ShP614iAbcEioX%=DGkf&`UR*_pT#828Ls)rMhPdVmD}WdL0?U8N zGk7wi99Yw_Avre(_+Ic|$pZcGG~d6HKlSK!$ayYXhqrb|E}`RndlrskCPk{?i--6j zRCSJAUb!>FauxGzdywIE+B_#Tf(wjGdNU&f2xTZcSAAPgwXIz`{*#M1q+{n~gI9G} z?QfnCk{-@}Scw4dYP%)7GFYZ;{1bq7<~4fqr)YBXP_Nd-ep2#VQh`KWSD-D>m!cCs-i$i|ZPfRPx4GncvuGmnSE#;rr@)1^~oJqP( zTV|FSDCQ(Hj%RTC8ccC5%ONf7LaQRb+8ks6C=MBKP0sXzAc-C^p*;Op?Wzb%mHZS* zkzD-xL7L*P=bK=o6P4JTH3)ImXQyO%o$)5EX+;dH+D z#`KeS-krYt!=Fq)`0-DsxBu}Ur+@hFcloU0PcqSxdIZ1EZ5y&)+0itchlI!UeHbli zEU!lz>&iNRgf*=!UDk4W-RUL#UDq#zyNPg zUXKPc{n>Fp3)IcRfxex^XYp>c>uCRHv2L!qE*iG4Zy;88PT?E2amDGpyYR>IPhwg< zN4;;;;dx+J(HU(z@*MM5;r%M}c6rIvm%sew>6^d*_301(vu{k_`2F8cK>pR={;k~H z-rx<<`>aS9XSq zvamYh-uU>9ZPYw*DTKDpp6wS$O}g-j18;ghvKk#4W(aVN9f+|`m2oC+D&PU)zpk%1 zwmP@-*w^{jbmcV%5jV7}ja7iB9j?Wg$t#l_(FJ_Bc6v1Jh8Mr`B3;rqZAUu=EB3hI z9a7g0M0{G;c0)@h(5ipoD~XcR?Be68`L-h;{7h)*s9OgmvyQUYWrH%)tPU{ht}UQ9 z2e<|iOnHzYEY!iTz=!-f&-`)R45tve3DAXsK;V?yRkQ>qQYS#S+`lW9sy+M9t>)5A zN$RX*U`O^x4rNj^d4z6+nC$``Cu9_%ng$7u$TU#8sn05}>k0_HKgd_I%Ck$o7--h2 zq4sTh@CT^ts4-k|6j}VL+oZUf`-UlC%1*$bj}TrP#CkT6$zuW*P+B^vH5v2dN=oS0 z23(d`A2c9UMr9LPc>WI^lNHojmMz2*;m8EZtXBo~v~TEO$>0kkO@AKa6okQ6w+Y7x zK_U;leg0p^Ib)LdTX6k9w6MXpE6%gL%CEf5BaHa3IQG?Sdze&vLA<$0xa28-KV;F) zz0w@88PEK}gbo~1|Du883V+EUOhH+0fAHur&Hy=lW?q3oSC6X4S~<2~DU0RG8eW{M z{}ylCe@)1c3y`bV1+1luuUpZp2}vu2!ryXCIICPbM}Bn;SdCSY54t`xUhM@W2-VJn zYBw^~hC8&W2p|Xox%0qaTABToF4PyI)ylr`wL3)K3Ba{WsMN}R#yh~$_M_9>t~Y%_ zo-$D=3VKSzohz=C+dk4Zx~*g5jlIL^t*`#Uw8vI=?{$~Joucg1qoe7)ci)?S^y7b? z-v0g%rtg05?diL3zs)xEf1G~y^PgYaK7!rypZZlBxCLlMQR8{O>uCCoBYfkHWlhJt zF7G_gBW$O&rS<4B(oe?x-zr*T`CaMe^|Ey2BQ1X|^OCn^>-e-Bjk6A}%Wpf2yNcdj zd5zcSRXo*S{u9n=n~05RUVZ!ocZRHO}m0U1JtjuPpht=P$hV z#`HB-!~fu4{j2F4-}naU-w?g~8?mT$I(qK{_PDjZVz;m8F zJjY>~j!q(xyb}y414pEs5|S@B-&ikOxQuYTBBx#}8}S?7{_rfI4Ck+Xui zk}FO>`O2@eE)DC4eGQ=#IS9}#gJoVONR^6(gW%0rbh^Mo;onJ=VV?b<9H zQ|0uRb{v`_Rbb#bsL+s31t$W@rdD7QDDaH6fro+e29sE)zHpNuJ#7H+V9dJ#w9zKP zgmh!0L?T=iivar^^VL;7M=V@;%Ream28awP)*gI&r9VXF;rkrm+}TP)p@`Px=$%)fwGKFg&H)??cz{FF<5 zWg}0HmoF0;FxC%ryy-K7nxR zR<;#ClsOx?3M()9laIc6%)tTP{8`_|03>kQt@HyR*+e+v0sGULLnf zI}<`a@}Mp7f8>VGCIR{ve(QIqEuI1Q1%xo6_u8IHH=l!dTmH%M$@JmlC(|!^%leOg z^kahc?@!tVFxST^P_ZPd12MW@UD+kf-5 z>A(N4{`K^mU;I)WV4tHrXQkO~%6~=qnMTRZZIi8M#YGQTv8@Oc}S(MO9Wm1lqFBv z>K|T0mL1IQdbU1ve#<7NuAhLTEVW7&{I#ZvrY2lbwmus2hAkPYj4()P~Z&ofMe?W?+ za#t|Gga`7FOVA2c@~s1Dv>hwxs6ecBQ2y|UxXKblu2jT+OfpoH@ZwsRq=D;zDZz)= zsrwsv1XLJBEd!EnnXc{9k91I`JOwTPs*}{cbRN;M0ea}!rraJcU;biqX$lU!Fb3$7 zla4yoisM{AvL`R?a)uXOgwO*g$k5ASTdHDsluZH>{$#=L!p{H#czu<80fHJw1b#Pj?Et^L)5hW!eiIRgL6S=JJ=u1$ZdIiEspo}T- z&)BHA%B(#6s_obYih2=Im(oX>V^8f{3L-%9UV^}5}5z&KmBZa`v*UmzRwD~ zf&1V8!}rMh#q{*#v~1i;v;aA`Mpan0wcy4U4PI?MYDbu0YHJS5Dw*0ZevLSs3$E-I z`^%7HRl4iF(Hqz6mZi(a^GIt|{Kq={V9@!Y=8Iuw&VM(oOqCX>|L#53l>c+=rgM_&PvuqN5SVbeI1s&o67_S1EfN zxMjKz?Xht@51zDNv@TwT=Y4egb%W`8S=w!Rz0~`za^Zz(`d<6lnE&}N{_E-A{oz-c zt$&DfeVUgc>7WQ32Rcp|&I;GQ$Vq2spWxbiwE?_A9l5M7)XI}@r#7fJ;5a?sW>wA| z<`;aH2mge%MV-J}W%Rkit?A^HJpbThd~wMNoW##r4LN7^@s!W>=ma`RU~r@lWI*Ps z-!3bFzVt_$J6lW;fT@g;9XRRi!5DuBy=%4El?`p+%e&OYKhHWfp4~d_HhW>tSYemu z4g@?0PuSVHH&Z87p1z&f0B0LH0MuMqMQ0CLIs4{n5B0PRgI>SoTX>k0MG%b~hlfmH z_y%eIVuzStIhiz}+ygP9gS2+h@o=BF7F!88rfwb8#;z#!bJ*fu=tRqlvIKD8`nKwA z-=Yjbaddw3JUnt*Z)ayE!-iWwu|s`!s%)K04g$R*T7(as~-Q;pIubtm&57_v8{tQv%3HEGf^>5k)qUcoi*UlAuY0hp3 zzM;LI@q?Y)Gvw+CF}0U}PB1l1K@t!~yJ{oaPbB3O&Nfi(3f!z-R~rBm80|rO@?8l0 zX?NR-0gz(*R{GdUKCU8jj;u174OO-%UYk5fUO|?9uJ~9Uk>++My|fc@Be6tDT{0<` z_BFrNU0a2rI>i273ac!0J5~rU=EKw(*NP`(-ii%wCPczt2yG|=a@p?ekCZ8Qp5dNp z-cYqF=3o&REf(E5Re)agLDeBj1q4n+1uTMsqb?FeuxlNt#~zD(?l*RWel+AiQSG^A zm|O2@FrWS)t<+tL1FLDS=><3c6@G}`v>Rn>IqXy7$x+PWKm( zGLD$#5xShM<46#F9gFKRlk}^!cg6+ecDuLsj$X74M-JP3WJqr5sS?^SkGeoOb(Ge@ z1;}85BV*O_zEiRU4m|DYVSDN^!G0&rlDYT_Lss&XA$n8>I>ShK%Kg-ucs?rS`0L9F zHEARv4{c>ce%)JugjPwde#+Tf-MyFC-?y2NB9f0xv4{j`-jWW#`K&f+OWIjDpu^ow7-!>anDx_?uaFA{{VXr+fcX_U$TdPj+6rgz){0A9Bdb@cC& zaejl&5xJq~JzLv*&)w!8#pQIwYQJY+QuyfU@${V^zd!w7|KCr+p7qh50CfLQg5|Y& zecV>oFntzw-EmXznz-9QrNy}ox5nVI-8%Z8ru?O?#=2bE;o-xFEY!R?{p2Sx((;`2;1eI*Viv{9%-zS^+jlY8gNFtsjt^#eXX+P z5=XodZdty|jrP&;*7Wy3;<>erpW>+bCTtuwy!(D>)HZL!^&80sa;M(3IlLheE=)%R z*Jr02`KGeL-5JjP88h>^+i?zdeZG!+qI^&BVvY%lbYzYR>vqCc9HY=AU_a$1 z@1ZlAm3#2F4Z`DXRj|CnwT{jXLT=&hOUJ-(pEoVwZaci$m5{I8+ii3~5S3abRIEVY23G`!2VCp$ZK8eF1@8^CDz7uSP1bD#6 zqa5$JE?ie#7{p6Qd$u#=Hhy;`P(&FF2}rh)*>6&wow9YGJa--FUnsNqo{zD=4$}!X z_mfa>z4ZXj=hMN?ex6elUt#2Rd~$?M>+RD3rOvWDfx6zO&L2ErCDS-2QuGmk002M$ zNkl-GtK9ZV1PjQzYOUH{eOfbeZMOOzv@Jkxkkt`$uuEp{^5VOszM+2D$T zPG%rxcv~qX6WC}A<&&>Jg;1Z+q|I6`FTek6J2yX#iIfvII@z{E-w^FqZ*@2DIU%j? zYG!aB8p!5Z{`Q+A-s&rjY~gm*mOS4OZJ?C)0-id1Y*WwD0wksprtKlk$j{lfmwb@` zb`q&&+eWt7J=#-0_CM_dXiYvjiBxqce-H6JS`OQt?ZN7a13$|nUga@4M_bWIw(oN% zQP9J`?LEehBgO)<4h{`KXtmgBlYl)z8ugwwi`|?^*(Xp@&wQc_*zk}EN4Cqu(|)Mq zhS9pd1E<~tk#?3PrW#giB`rj``13(wLLDSg)W&; zRVLd8G}Sq@;o+Ot{iLO336AG7w{_b$h4ZIu*5MxQ#P6}EKB((_@(nuHUnWuE`S|J4 zw71V^)T~#&FK(Z;eR>bLp{JdcqxxLrwGYY*dfHSwdaWE3anCtU8?|l$DSRYp*{oMg z%$xsdk4`K{Q%#Q^(uUqC5188~h1~;=T<&Vr4FtXCArbWI6NTz4oO=1gf@#aCNAkVz z?lFqV5AH4HH+LgA> z_-leAZDBZ%WtK0m%^MH#moR&oww-@NYw`@Ar(LcVo8 z>yE#obd~Yi&?~@yrCG1jK+mgK+ihv9RSjg6dxT#FyH1Ygx31j$`@r0W|7j`fI%s=! z{fzmeEjqvR#_JJx%x~B}yLI!oe)BhR@E%Q%pYREnb8f0Q&aN(aqc<>qN@V6N_{GIB zHzI;HZpvO8u$}6>akJ$X%%9GR0T(dfU-4k=5uYn_#rG6v?HC8qpjbyDp+NZ?T$95f z8;6JcoKB%>Z}4%5aA3B!e4$S{)qdO7ut}%HJf9OaC|4!}92aSIgt9eV$5RIgSv{Qf z&nl^oDm=3qO`eXWFuihYT0Q(kkEpIL>KLoDhYrb3GhC(gb4I0? zP6ENe>{Lk~_QeyOU2#w+Kl7#@)|oa`KI@WCUgK1<{hzaX831Rc&Z>edN|J#1rL9^%A$*74fgXFDdN zHP&QOz`E4ot(CW@#{~ZVp~pGSSO=p9n0}J!l$-Ax5B9MK0Ui3+s&@q=*1NV)CU2bL z~=s$+;j2`aA^l|GTDW|XZQ?Mj6WU{6YTBcjB*&L z7)-mf0__R7b;f<1LkHcO)3L<1RuKQ>XB7)$ojTcLu%V+&>rWeXg2d;-eW!v!VSmoc zdNOcoC;AlI*{5u$$3~|d1_#P>Dh;mt`}S$y=w|&pNux0P)Pqj6pZ_wL6-OC$qW$F8 zCVj%dD3e8Vz5&8Ma@lWHN&3?C`{xwRve|D9wsg*IThgLxswz7Vm-sYw@>|& zpNTmPqu$!*92*)G>EvI~FQu7rhj|1jam|F=rDIJwVY~FZgFV_J{eezUKu|*3)Qw0r z5#_j4hu1|*+R#H6`-ygSJh|{WdjPa8W{HgUeZPy2$Z1Okie%6}Icqo&tS8UfR$N+h z+K=N-w$ameYJ!4s!**;rV~~AD-oAX${_vRX%L!POfj(kz?|9(&A~Vm*Aqm@s?bdqJ zPL93mbV2>Ar;|0>%Km0wijkwdV`a5_$GVg$Px@vBv$kXVg0}EyAIVq%kMvt?um`W2 zVAb|l)00Qb{Ozkr|M^&pVD6)`B4;_PGZvjV%M^f_Xx6!H~MPJ zOhj?say*d^IO<{@ZFqx#LM9O4r5xJD2^Hz2jCydA&3t9dSceU4v*{P9567YE3u0;T z*cW>8!4#3#cIvoyNPzl~iPJMCRgWGYO%IrG&5jr7I>y?k+u*AC0pruVMP!uzl_ME*>q{NWb&MAM?F_ z(PN~!q|tJZyw=IR#J%rz^H{>K%OBxZ$u;7Q=@IYg)2EX^4`FOm>yD9z>E^jiH-49U z-D$_URY#YPu&dzilQ+uqD(KyZ=Up)BH`?zmc+1xY=+8^&KFmHTFw4rlkKCj2yP>rW z`}#II4bwQc!H#7P;vTnks)iqB?7UCfd0pMC%U`A6DjT=`8~(0q;qJ2MDn3oW&)&EX z-}?NtpVh5>h?Ya{_hz56{p>@W3Ado11Gm4ok2B+-h(oipH|=v{-P`463$Y6VGXq-N z0dYWZh!YZEx?+B&^ADsq=xQ-HgRyuzJ|4N{I!MFh5}D$}a&z~d?Hia4a&=q{M06GK zGjJ9->kyGXVL~9^zeP52boh2y;dOhev<<#=s{A~eIj)8!ut2T^6gV9l2ICQ=baG|g zYn?+^fW$ch&U|sVSRLCVXgk0ragw2}ldWU(SiVW?7`rl3PKx~|P8@{Y#((uxX>e-c zqdj%Fbqp_XlyuyoI6Zm#eq^^UbY2UloI=I*zIKAcNf0=0 z*}o2MFOZqlOXY_Z_!YQ4!Kfz$Bk!Tl1$B_sCmb{#xhpEct&fL?u9#Qws6*^(wf57I z-J@qszof51AuYF8gR|x`fewk*8eOz_j#kM=HfI`b)FssbS za^mZZV>JS59NAjAlP7JBdeNbD#|QDvbikcP$5BVqK=tV9$@K7zL*VrL2^47)+SFkE zoGtwZ1@2(54`~-)j;1XS2>RWzQIiL*5SPttA5WZ!;L!wn2#zy5IFNaZAllEYX%{D_ zj&O)|zFqZn@+GUWI?~j4#t`+vZnp9C33im2&p!fO@}YI=u8CbT!1M6~bpj3hABT>U z0^*!qw|OfUJ*+ zzxvO-f(XnpGTU#I$B7Vik}7dN^>rLO?4c9!1Gd91R``5iO=M&uhI(+-GWJIwZEXPS zwRIqW`}I?TVv4a*)mK&$kpZ)SZ-7IB{%U)1@}s`5P2Wo0O4A7p%h~xtUD@va9=!o| zwR@Q0ksz8*}xaF_U(f$q#iCj=yS`!!h6iL8hj(4JhZSkJ!+O9k;Z-b(pcrYXD<*(#pe#onO)f z#wR`=Wf?$unIDEVcz?oV=JApDFY!xG?PnnGVSlBGrd`_4HlSeu&%fLYwN)l9`5L8 z(bkTG6Jx@MjIZi=hCrK4RJyesMW;>rnRS;jo_9N3K>Qq7t?xw4F7#{Sqj(v>YagnF zIs}T(ls|xMg1Rkmi_f9!vPn?{o8Bh1)Q< zl{L(GZumZrWp|}t1m`ZAWBI7>n7=N)y~^n8fIltyZN%r*_b$BqRQ|F)#%uAHhvofS zRW5wzH~+p~()uJ^tLv&`UH&@Qr49O8I;+xS-bl0I`(50hS)kOH93G=Go2CyxGHoC zt&=UC@^aF2o~$#~(Gl^`F*HchdGaP(9Ssl(}lD17*4TxQc9GVEvxs9QyWOSjYZUbyk24R`;^< zi30|1c1UOoWH_OX=tMtZ^5$q0=NH^lgApBR9Df}zZRsurpH+48#6V)7mm)!e?X5V3 zl>4V_K6}kKsNz%`2pT+71Je^^Y-dD$F5s6oPK6r$rUAlR=NKvkrnV1Oo3N2WS+@qS z2KQ-y28_s|qwgaa;vGGG0x$BZr&`&BEOn3ivG3*)0#mjPO;=1k&Ir;Vl)A&iu6_ZG zb!o6=+q2wNM(Y{tfKRJIFYS{TFrvS4fRB762tk8$gGc^sQ}K&|v5u(a(AE|PG?7!O zPnjG^U@R@R&%+;d+C$Zmfm8>hwsC);AyYZ z9ysA)`(f+2P5F#Afi9TU@Yah0NndeHK2e7838 z>($j`OVT$5Fi@8=mUu1RGIAiR<|~R7BruVPl50Om~ovDASZ`AOB@3e>}xS_h4-0h z+qiVxZR1vIx0X9`WqYWJ01{p(2jvFYXXnS&j^~Ng=%7r{(cZNyN!rv~6gJO*6B>-9 z@{?rQt0rGE_UQwdUn;<2PAY5>ROh?)*ulQ!%jc@jy=O2UK*-06+{Kp1!Wcs{9;iJyJM4Z@FS>c)VT8!) ztHptFoU%W0j zW8bv(o#egDf8AHdv-GNcJxkd<;kvxj&qCEz!}fWEXuaPt%0{?fxAa|&pewuK`uZ+Atbzp1=(_tD)Q=3=ADp<0w-|OcMtIUnT*hj;ao1J{`r`Ai$N0Y-{8u zof{4AN3EP!z^cO>M+(B0?*gZzorwXQG@YT1I0_KNX>bL}pxI~nwpm%wSuhaY!r|~+ zyK(xFU5DrbWF2aQmd6Bo1{~UUgB92c(se${sWRUn9?ZzAbE&SD$C;%>I*5c!FeMPD zM3LeI#rfi5lc3erhFyYy1Gk-HSM_rXw(w_jz$dC(1Een_?Vbq<&dQ>*tb=U8v0(rO z9}js0!Zl72VZHeYa%MViU-ji`RvxB|bF|MkUtc75#R_n?9pY@cMS2^V9^(+|h&_Jv zG^^*-O7wM-#jW5v%s%_P_1;KmMnFu>ragGox|^B(AP%cOCi-bTm*huCxwpkG>=@{fM-?3v}qq z)XHPqFlefFksTAzJ(~j;NX5amuU%jt14+ZCny68K+lO0*X@@qp90n-VInKY^UlUN$ zu3Uw)FFM)di~S5SdqaJ-sL!0O*&!DFd zcL+ERNhFU6P={qt>&-Txe%e@h;AL~Qju5tM24koIi*x039a9`=1FkJMRv!y$N%fYT+DX!P$ZgH$J85GFE!n~57_^2q0rth~ZR4Sa6xdR`x#Py?%kvlx`d;#VKgVfb8fv|7 zBL4O` zipuPhGbfBQwgBP17u)Bx+f(vt`@MC<#D(`*##b~29wlS*vZ3{r9VDE^bv#jz8oRG} zvDfFO58i)2dFPBp>TjJM@Ho@^@4d%1cky_UE0eai7bg@q83UZ`bP~ho+1&~E?t4em zkALwVFmx_xnBFTtjimw^M&g&&wY$(^G5iFS)Q9t=QppuUY?gcmgTSe`Y!pJ z{|GmxyWI0S-A5f);g01^Zwc45SHbo+cX3C&#%Y>;UPWUpYZ@cmm=<;kvn&^;^MoDK ztMD7X>3aPtj*)lMTb0*kuj-rty_IgF%WLy*Q~0*Brupl5US+5I==q`*+jf?3r|-*e z9o+NKSx4iOoWH6r*468nzqDJ^X_&s&He-6URm1+%kA61&!8bl1IGsBWgVDHnI4yaO z7>CL2$=d_~j8cJ3KpbaDNN$My)5$Qf@vX4p`5bS2SMYS6vZWFFt~R)u<84%Dsd4hk<=n*9 zR)Rse0X(Q2wp%ABigpF#$c2s7#|ID8Um0q5M%6EuX(P59-yPv~+LiqueJhy7DJQMY zvdScYWwc3Yd&KGYOx_NTy7}(Vu}vj_qs(q=yOGIR+ML{|Q)pRF(ocX$He}egO`&~( zi*o{yjg9JuPGr@@99ZBQph?szi=1i02B-3uriVIVOny}lNW!FA3>Te!tN?jHhQB5U zv^H7obb`Ql5bPpn1m^!;1CP1B4Zx&qUr+yKOt4M+XoCGTE3!2q46MYy2?PA?1 zs`Y6*2qCVug1So2i82xFD{@L3a~z5*kdC1icaZxb4vfZqRt(=y>p>18%GH2 z;eCAhlsZ0~o;-O(9n)T7c3R@G30BW}9|N0v@`y#BPzb>Ow1 zvM=q{`Q!OMwrJWTzmdke^awwu8{WJz|30#aE6#Y_hBv~Fyu=spi(mX=`r^Cqz8jLa z(HeQ)Cq43R_*HpbcH6mS@AGZ23D8GH?t^q6nA@0sn##1TN1wG_Uw1kgxBNH4NvCPu zf^uE-SzTS5;v?rp_Q7b@Y|IS3qJ=Dcg_vmw<-=8S`N_Rxk_( zC@aUcR(9NmpXU#u?bh`Q^m)esFC)rCgi32)h#Vdsz>DXkSru1jx2*55mHkcV>Qo7% zZ+nVU=SuR^_a6~}`Ur$US;7jOFavTNXPnA>j!(;HrvZo@dpx78{7&%rR$&#<7DqUb zwjt}yCLk|gVuS&zEy380pIJdwW@yM)2Q;f>1kSpozRBMxFtwGy_E8J8)^a!R68kL4kk=8>2^Tlmr@i+dj|HDe(Pk8he4Su=-SQ+g$jnS8*LAEut0lgs*7}-#0fue_9!Uc z3Q|E-iBfIbb||9tly=r~l9!~<@j|t>MTZ%%_TA#8J=Iwru0u*p`K%1{t>DNu)4$>Z z%Y}CIuoZ%vF#>E~FnR9e3AW2)F6eB3wl2~}pjXdq1A-8jmpleQ@RHpEKsatxfTuk6 z)9Qz+8C~JAxmmj`BDamK8V&)O?MPkug%54SK{;)y>M)-=1m=o%wWUn(maZhS@^5?N z+IDK6S69cSOzoF_s7^gPd11dSZoU^np5Et}Dvb>G zpABTAD}<(&-e4@R>L*Qmce10#{TK!sC985^$>^A8;(1ak_bTL3X6wsVupFUP|NgwdOp?+7iGp)Dn zE}%1D(BC`EG3~&1m@x%vHcL&nWwv%Tl<-gpcw7ZWnVGrz{`hn;4 z!F$y6E?bkIz~6}!w!I^VyO(UczT@#g(j3yuv;Lgjp_2B2vA1a_58rq*HYiAW!g$4z z`WwoY*P@s=o;$sYrg;q?B>ro-F@H=qT%Si8W4g;fDd$n|PLHy8-YQ#ko-iX^r$;)S zzO76cX*Nus$GkDUie{I4ex9S@o2R(TyuM!2&BP&nYQ$Z_{3@@NTiIH^KHnx26Nn$} zj7_M|O9HEKmN1`Pmj${pwaxl$sp&4ikG)3RyWpGd^WfY?^VhMw?ewa3Yr4xi?)vDn zeBbkVVx0CXo{5WxM4tHN<9TCeki#k9zRGqxX4kp&4dMEEI+hm%LT3cKb5NtsfRBqLy0&+`WtS!^F><*uDh%jxWeiBKn0mj1k6szUOB@L zap-lTd`X-u7OvhL^L#E|3o?qwGm$7LOIKOst8;UO6XbSVU(EA>7wlzwXrB4@IY*pY z972t$Q{%1y(6h3VI>W8fox?NC>IXv2{S_B0L5!`_>Ls<<*mCyPy(AOz; zYwF1p_~MMZS}KT6q4jK_q%4ov;;x)mmplr9&3E}6)-F5_@w99Q4|&tq29DYjo-^Ly z&1-J81UrE~waGKfd`gM=4+C`V`snBheBgn8P@RKh>l=DB7^*V*X!~6Z=vHGVQG5a2 zDGuyDPM=##cdS435hvSUF|a;FyvM;H!Ug#e-SncX} z%nkNwgF5O4Y2w*d)Wg-sZQ7ZESq{qVM+ShlrA!i#XK9*?^no?FaJ4TJXsLH!)?`h9 zj}%T$)K*)&v~Aak3;T2hQ<#f7I_13yZGZZ4+K~3d!KZ)4u5+8uB#7-4-7-OkMAl2S z)zZl}=&lyOlwf{-$X)tk8S=HO?P$Yo`O-i!cjcrVf@6f_Dcf*oy@faM0v)>{IEe(1 z=qa$lhJlEEFykKZ_CEtOX#o`(A_utkw>%DjwFJlx1FMF5msd$fnu_qHleP!x`GtZc z_#Y!@Wzl-+yb5X@XS5$WVIQC(vvA6v2@-=YZ9pa1?UXBUob0dJ{!F<+v6DdB$#P|= z&{92TT`3ViFF+IDKNvY#VlQ(XR2EB|JgmcUl|SmsmH*&lU+v(kul&?SZ8uZLWk+#$ zGZ|5<+D;+>h-mCcpl$m|P3nREmOvI*X`c`r(gdS|n#BI}+oz6&R}2=&YkeS2;FYNl zC{U&y?GLbXVh5g%*P7S5al%ep`gIQy`~ypRz`1iKjDfSQWt%oRicK@f1aHiXjj()Z zJ9bEqQ|inySQ_eQ|8}K3b)7f%JN7bh$h#WyC*OGtPtwz{11HJ08*((fLifOjR7{^!7EOcWfWWzqqAdoRmmi`7n8LvQ?G2Do+~CV->y6@>W}5Ssy};d0sE= z+I7=sVLZm`kw)W>_4XdmAD`%4;{jP7Cz_6%)iP-LvK^fP$L?B1@eSGp09+rj;>Zhe zSy}O=Ih0&RknT`rhOSa47 zsQA|0&$0UYfL{eVWgm5klZ_+8a088Ub~fEgYH$J_SBWkN_;mEMg&qOxEzAb?I)L8v zap-V>Tz&DZtnq3%IqPrGVwS-zJ`7HopOUE;rRDp+I@36-ett?vslJV_EI3oBqYLP& zzkCh6HVO6&oOHr4dT6^stD~i3lvQEu>z3$!mVA{-2T2)p<`hmi?H*?tCr-O%t3UeG zHd^uH4vB;k!{N#{R93H^V%JC6*2r__$2`Y=xR-i6 zg#RJICtZ0}*4*1=C7pq;}keaAj$;Gr{JX(>y~?aaLRkF*lH zs#p^m;GvxD%|6?(jvZbY#LL4#z_G*7!+=x%)I2XfbixB!@?*>?0`yhKAIj0KgAfBu zdB~rl^qKlkc_L(Na6&ujLy6QQE6?zNEco_u^0Eb({uYIhQ~8|afR=5=zA0ICbNtFA z9E@4)D>}e$(sqb#G>woPHqIs4}uxP7a?xQ-LJ3LWian=D=i=(Y%D({7cn5|x+vVpi;XkUN<#xNe!SA68^3LRRH^e5>$?m=6ch{L#9pHCx+I(5Iaer-F-_4o-Bf~4tYjCj2+ef>3&+@)u-}k=Y*8DsI0i^wWf3L

    lta(dZ@t66lV4g$dJ3(7E0bhofxFfAqj9a%6c1*9r8RZ)3H{N&_R+tfP9nH=c z-=k&g{B`FgzjbiWlfR_7N{8FzYy4F_TfbFh_sLsDdsW^#TIGcdrAvWsBX(QaK=Mho=lW-M!X4cYX@@=vvaU$OE_yN=hU`xxt?^GDb&Z}^5;b^VBEi+6bzY>V%p z>r{!G@6F;=IQ(7VjOk#U;MDld>mzRJ#3@;w&;fEgv@5WR=gZIBLg;6pToH8(bG91d zD*5d1Q=DV|CD=`{i6fBbD&>`r#vI9(@SI%n{qoR>UBn?80aaC z+b4Yv_LA+JThv26H|b5C6>r`UuT9)`?iR{@R>O6MHT?$d$L~=)A)=${mj8OAvMbqc z{X}NkmyWviZ(Z$EKg^G?8ck42kZ`b%Ez!-lGy9ES>FrUm$0&L1OYoEjTWj~!6MSt@ zu4Za~onKdmFPsp7k4|`Y0MxE;p>wzbs&gyO1$@=uQW*$9mE9dC?m|g04XmGf%NAz% z`+Tb_S74+q0a}hW73lV4w^~z$(4qxmaP{_|(V@@dT8Gw?}L4TT28@b^pG-xkdv_!ZuFl_4QqJM%-oE>!xRV zJj`zy*6~`GKhk-X>5*T{cOUw~`m6EzS)H4v<;!CokH!&x6-?6_;X3WP%bQ>4^||vs zH{LR@`Sy7%@AQ&S=X)OU*6|qOJ3Zo=w@T*byNYg?HN97PUeaF0f0ewg$Mt8{8nKn_ z^KHT|ncoKcS=qA|SXRn-ZMy42th?%>VPB>`M*h!A`pLU$JG5P%SA!*fUq26>`{F3$ z`#cwYd2q<5lL$}|-r(G=zdAd+Y`1;jCuCf4&Q`g)`56Sbf)z&_Ps0G{OiR$@2pREz^1Wj1 z>&mrTuMrvTalmw1$k)z$Y%9+*sy-L1vx*$YI&|p&)EDr8w6#S*%1#1TJ$$zC09zWE z84T)_`AlsBe{6KjN|(W0wkYcKf|F;Rk!hQs4x^JHI+d=x*(PEm=xKt-d^6m-%?qBC zmABmQ>pxz(jnY+Ww{SCQBc59|wF{1>-xJqnSplE<*od_EHj_Hq&d=!imSSJXhFCb5 zv+K5}debHOCp~J^->bC6LXE>bDuYO={p{rZaacU0^ z2oMb7t#k6NJ8N1fikZ;x^M0-q8muwtfUOM_h0*!nVr#$8-N`Wj2N)$ z?DM|%zXSvZbOs!h32z&dru-6Aa77cMepSYHCIKBV@Hp%TeJGCgWBZA`(xD!GE;Wv$ z9fl)qkEE-bsZU_kBmpj|1VdcAGHrC?b&~SOMoKGPk9@9+da#{T+bkZLoIvLAM<)L~ ztRe$6uU)|vFM87Ul*P7cn{;I|Q3U55gsGM1>f6AK1QH7TG@ zB_Haf@2Qt{QoA#>sn?b{eyaxp(fCP4F5&mk$B6<9#dXZl5V1XSpfT5sH-e}SO=pAq zg%{b}*>!N?I6;Qny|}*D*rLqve=FhSRh1L*2h{TcVb!V z@`~jl*ZMQ3kiM$?9@@xBLEDw^+Sds?gKtnp3m;2I?R zNK(dM@nbV&VGOs+*cY@<4q2doChL%0S&52Sd9H~>FTJTiwvtTdsYf4}CbBshnKpo3 zocOf=Ya(AJXy3Ly)Z=BKfzW%`uTgQ zme)6s&zEX`qa4dTug7vZtjc>n&MyYtvc37{o73<9?(a^2_jiAHZ$j#@)MG?$+GC#S z5vTR;yvFJ45qDLdZyp)%AV(EOA%iE%Ury<}K;G&TDzMt(P`h zUbh_P+s8j5_!40xJ|cJeb)3Dq=v4hGjrywf(ymK=*5%222|LQuWy`u6VVcGgX2c!S zOWg5VxFwyj{B@^S*=ZfmS0(FRJXhIc#Od-ruaeiYBerS(Gqc#=+&^S%?jwTCvjpW& z2nJns(`j=x%bD{du0MF{3c4$s1jrE80VRWbv4fD#6=&$;GbYf}Dbcz2`SpA@3`eG( zlQal&kgm37PLCC;J4%I$^F9`g1lx zzXJaP_d$oXg0~Z#HRX4kvoH9H-^WUfquG>9Ba{;Kb>L z`sY~1HPAM2@r6i_c@AHP&F}8+@OEKWLHzU6JH$p=q0EXBI6h-Y53S$^J4;@t*7meZ z;H6`zFLb>gn~m>_Z_!fb*2Wur(VF#YCc9bxb&^p*#?UvXoTn|dz^eQ zK-9@L81V&vzVJu;x+7u3m1pQ1DCBu&==+F+<^K8;QrY%xUE@SLcDf3)f!8TbS9$$j zx@|=|m$WgfrrL~?K)n8K_Do$Z#qCu2IEDtKuH+aj5W6A24kpGyrU!?PX|yvwvlQnY zqZ(XF%Q}&_hw{Jwq{efflgzeMCZ2R?4FWp26gJK%%%3>vKs`E-T9<|-ikAe2WI_yp7DgK8%Rsa22I0aC8?`iAKPV6{b7#(CCM<4Uu(k*h!b+f_G> znWH8|gz-~sKAPcb?1^Cx0Xo$??eKm2EcwkC;@U3l?@lqTD4_T$j*~v!7C}q=bPVxw@zVcKa54TRk0y5-K z586i<<@P>fR`iQ~=AfJU9s9iS2H*TEyugM@_+)#!!Xw848>aa#MO77)btVm$%`E!qN;bJk<-3y$CF z3@>SByvwA)P5bsyt80A#GOe7-<`J7Xq3*cDwX$dvA6;NLi?H?|#|$BComL42xxYW< z3nf>ye{m9^bKmfu(zgy4l%D=}7 zxuh+S=V6&gm-jiDLw;YsigWXn)+k%&w+wwAd5-X7{(aKYYaX}3H{2ip@gGlr_=kTu zegFI4&*NJo?kd@qG@DN6kNBPEc}c7B#{4lo;;u@Md`vgJ5w`QkyiRvnpUr*J)gY$Uf`k2YAsJ&(+*=$I$X zC0(ya_~+sCx?xAzmU6G+-7u}|DwzA^t+U6vd}-cRw&W?SGxSHBd(#Ko`_m8K|7W(~ z@^UV=zrA_rb~c|4^m8s}yn*~|`spKHj&|@c&QPriS3qE(=XUY4Q$C$yfb6zvoR@ch z_LDp_j-SHl>DF!q^xls{87B>g5{JMb#~b}2j*QQ%JEL!4j!U6J`b9ZBY1^zSaW?4C zKQ}h| zSG+LlDU&g_C7Joyh%y>fCg4X$+p;;8yxxq z=L*U(J<(+BCTa9@mw;PrZ6}%7%Y=qSw0XDJ3Lm-TTDXdJg?(BcVg0GYC9no)9_K9W z((3}}Hf;07Ar^`alP1qUY3Ka|=pn65+MMO;r7lIY;1pe%{BAub4Mcs||LjjS9(rLP zyrA94Z;P=RD%Wik6j`#Hr5-6U7&gOhVGt|N4rH~Bbyw{a+W?eWMn)Sm%_C#2Ez={r zmYAGKok|BAbP$;_7kK%ro9E;~r(S?YeIbJrKCv$Vn$xuM8jL&9c1EQd#C81})cU6$ zH6GiJog_7YCT*~eUXD+(jY2zK@Mqho@mKod)Azk!&Gnd3c}@o&5?(qvYCpE0*#AnO z2$^*5P3f<*{EQV&j;hNU_d$0z**3)ot8nNG&d6zVx1-yqePm{jNz+WuLPOg-S};Wy zUDdb7zG{OIf*$3_BrnHIWs^_Znlmb-v`yKE0ZIPBLe~1uS#?o?Y$3VVB8&Hg^atc;H-2n&f*hJ&d2C1GMmA*JW71e4Cjkw>KhOI|4)^yn-e_lK zclF-;i=XB5T75mNx9yFc>6gEJH2wUS?_Sqg3i(f1kFLwUPUgq(pK^Zv>tCOK_`@GY zU-|oMdF~S7zHlQQahlJVe^>f%|MqXE?|tukd`6Y8Kg`GT@V~EZ*TIeXWBM)`y1a4v z-1&WOotEb=@AIg~6u&mZt&Hy$R=wpSdP$83@Pkfp-M zJe$m8$J}HI7`geonx|88>9%J2s@s(>SS3Aq%1xX=-4%qdeC_}j04EJ+z%%!EZsy?O ze0g~7v&MVKp|j+Qm99))2qcEi83C_P3mV3_%{$Mg>yVPpiWG1LiqcXq9U9yy;GOZu zX(Dixr}SNsaV06Mi8xjMWy@|H3Z0{JB=8@gRSthUCC4~tK7a1Yjw|%LOkw~H7j@xh z;De(hZP4q7!1 z%k?g_5@N!`mD*E-D$=e{sJ!-8e@^pfbzE61XZL`&utO?3ylNW(znKXA8&{w%<8P4)AI(A6?O2d9xyZfwYZZT$MAjRhkX+)){3cBaZ(4S-&EdjJ4H07*naRLAORTQrbL@Xa}^aPZUi%4UFjPP@LKop111 zK?3~PSv*#9=_3YSc8NVwQcE+ZxxcVnw zgHCO0nRfTE?oX&6ZLdRI!3g%E*j*uj=lSMLlweyOZ+RsU0NZlghxD|uKl>I~NdqE8 z*E3B;wt2@)C#9t4WLQmP zNmsjZX)pA}o>F1_VtbvePPTuPs|O5bww(!+fFOwyEd zMV=JO9vO!z47mCH@@z2Y*aO;#oc#XchA?@oNE+c;Qp>lSq)SgMePx$e;TH^z9Vb)XcJj_Al^L zzBFOm4-Re3u_2EJLBoD7FY7gvAK=#{T_M|dcGwM-7plU;u{ZD(rye+aFNAFLadqE! zm017w4#z~{jkS9`CKVpaY>;ewvmM*!^O-a8x%NJpgR?u^E?K?K%kGf7UhrAA#Hz@` z#3|#WW2oa+`i;B4XrFGQ_pt2?tNm&1;MC(q`UJ|TjXYqT_i-FBacgr@H|2B^IJ*gW zmfm}r`WTEm=4%UA%1>BjmyY(dezc!$^&B2MTW8bTKYa%|>HBva(tF)U)nE0~uYUEb z)1UwOpHF}N*MB{I``h2XH|y#*)#gm!=V+X};9I_trg=a5(T~#B+D3hDx+DC{q?>=A z?~=E9-6coM+wgsE`s>OY?z8jl7I;zn&Gnqy!!sP3U{}yHg^P>lfnA_}cDb;?*pb@y zZQljxM=l$FESM{J%u4z;nycu1gut&T<2QceH>PiX^PAImzVn^w{rBI0ZBn!iJZr1A zW1m+sUY4!9UgrDk(zm|#t?8Y2-kE-Hj~AW&{KwPLfBFgATF-cP`6Mg9+0KVU;MU0_ zJW3rvpIt5o6laF}kgLTy-M!kRb0aTb)>aN3ZU}%ntZ{g`N&8%@KX3AJ5uoo2YO*B` zr@=tiRUI7{!$#k>Zs39dhD{0rR|%vUBxDga`KVQt=?|4^|^9C zMdxDxh?o@-oi?BG_eDziYz;WFca=@IMtOv;?X4gp?+KG49V|;%_-t_}_)Ktu9y|ALvt#fHPYDQ@7D{oi9tIb-jiQ0v>SBR;fwbt=^$xiCl7r4I|$^NFa4~-B9noUMD_|c@?`gj0&&#mwq~0c;Q1%6WmYtYHp>nGoPX`3e!^@rVUV2%TvWTf zDGNY}8QCC9kU#sK83$^5{%-Y&EZaOwlX8!!{x4g`E zym93;kHuxz&m2fnUUgcNJkbfd9;VYLl^q_+WdBc-42X4NLP<-NI?sLC3uMSdqcYNu z#nqk}Z>6u!)sbJ35?;Qw z?Z4U^`x>yX_N+sFwH3`<(DcdJ2HB*Y31rJjD|aSXIQuw21(`B~Cv}jqgmK=9Oxwf% z&)%EuSe9gGdfR7@IWi)0swpc~WUECMAQf3G0^*H;z99sG0B;EBnh&5?;0x#p$V)kHuo_0(q;U7_^J`o4m zV6_nkzm0K&7Cps-_5*)PTP7LmLY+V+ZqniVf}bM9xgicb>afinMjf18>?6Z!4&uD2 zdc@uwvUd2j{iTT#?DN$wzCMaTK%2IdT3_Kx&+jf=0{?Ebg^ z@Q>a9{(t?)u-p0*eu_c8eY9xiEi2{war5TQ?z7K6i|>hTf}ed^)E;=o$@zKlz{tK0 z>DTsJdReB0mHCU<26L#s_Q`fyKKzO{Uj*hkPeyk9bv{z7IpZd#75EbHS(RzK^pv{b*_@uOd6 zJk@#Dk9h1(&X2xEy4*e2Nv8)Pjq>BVttHy(PfNCRUU(f4@2d?N@+aa&J_d2pXOPbl z_LxbMkbd987k)%tck(i=&WHHwIf0EK>Kq%nVN)_?DKGeRo{NiYW=H3YXQ-o-rdaH1 z**(kq(J8Z;!d0d5ok3IVKrFvvDY7iG1d@Ygx2qa>(HXgM{fanc#tuK}OdiAxn+$8v zNuIb-aR$Y^>gW*TGJ7a6HH|D0q*EA6b`^a#2V>xiBk+h(In)`_fS17~scIgN4p37% z;HBeQI#9%i7&1dc=P;H`s%~^784Rfk(pJY)gN`z*!;ER^0K#EL>5g8F!>mnoy2A%z z4f5%sXhtChIl?E7bPhLk9dJoRM^-7ZK{p0-oJ27__=!P$TuaEaDIC7jIj3gjgFf}( zd1gA&8Um{x%zn#`bhrlM`jGAD)XQJuM8}fOEU^ij&~^QUpE~!4((`eo&N4W}h}%Wc z>85^ke&sWwd^n%cVb{5Z4HmYM!8U$z%DF+q=6-aJTmOs^H{N86^TU`Y>Y)P9yCcJFf2?Ad`6F|xOSyVg zYXznFQ8siVoEn6v4ZweD%gs322K<+2qEQ#sYj$Id-;Fp2k_Q)k1h^)+mbhLRDErh? z2jY$_2X-j)p$+7F!1t2XDnN0>fJ}L=F-Y9BBGx(uA&;xY-jxz)ENYP;D~p2D@6($T>o4vTv_;LxrnoPsM+U01V#kvj(x1gK_Wb&ihmq4 zPRLQhCNzx`!*;|czIJ7h%HJFA1)pZ44X{(u`=gls$rvN(CQNK;Ng-_UFuNHns`Q2i*3%*5t)Q>vYxX}Ht|Hpsq z{_em07_Wowm<3_>C$0+un~oMOv6qs~Hpp|d{9B5#1wrhO{TqWpKFeC)dgj$~=96+g zyA93sR^B+Zoh*w@%RwKK&3a$7e2&pj-7j3Y5a-C_ls>&7y79Sj{nW{!>=QbLphB}H2BCuC>;-zg-he*rtSeDN}o`2m` z$3becBYRqI$3SmOKSInD(%EEoU}r}g=PWCS0+_jR|&_XBL$Whmsw>#GyQQy({4ZEs3WS_dvZ+ zb%C@@ltD##=I>ZOv58M~^d-YA>Fz$8t!bk;;jHQzzZjs&wyG0xVlW}=!XW;fTW+i{ z6R&QiW@jZDaiCKc14=F9r}M{a!}K_1_{Ou+D{OKneU^`NV}rPHK3J&`0|Pp15n=hH zYblnQ>%!U50A^(;y2^^HI&z9RKltU;TVoP&Q!Vh6;n1Exkp6W%g{)L`-6*V|teA*v95cf~E6K z-FeqNF~vUL6*{G>+O3~X3fBQa;UAq|J~2qAZaVJ_{^*x-9ddoG==o;qD=qmaRmFtP zIJ2Iy+&pMysVQF-OmI!aO(bb?V}WZjcHQSx5+Ct*dHX^v<;Rx3YdW8?5Q6JhVs!jt zr+o&3ify?;KqtP$jdo#OooK#md}8x6`H2rKw~gs$} zCKQ#|;8Xss3Xs7&oqNQ};6n)Fa~(4C2pp(dJuJTLa~|NQeSQk;0N)I%b4#T zK_u?PR7R->0|i#afX(@1Vle7qTcVXgmExrM#KwMdfK?pP`P4fA`3{pW^(ys6PVmCT zS9E9RUqrq`#dfI+6(TGJPj8oyPx!?FjeNAl!s5UW0)Wp^Mn?H!qsVi;aSg@IfCzwO z@kN!3fgCu}iSM?23a`b-EFY@l?@m15EkgJ#oj858ZIa{qBF2QawDThBWOMzC6twVB zdffcu`k+4XEs#?AE);COL!N_)rTFd)_u zgJ)97P*+wCVI3bdRMmGHJ>iJQ3Yxfq7MjwZ;Y(5Y@?F;;-+5h{N_76E%Z)i^sEGp# z+`!`|aeUv!S7gFBzOVegaZaQd*Q(Dk*Bv)z#FeAvrXB5!G@=&q`^QFpoF``4eND=5 zt~1VO_$Uv+5;@u_$Z?K^%swc@mz(6rTAC2w8QF?!OLn%{=u`jL=0JCVR4;z_ID@lu zBRjG0g(#BJKiW8M@|6uvdDJ9U0EKn6<9bvl-X5WPu?ssl&DmTut_j6}^A)dO(|L?o zY4E?USMRYuN9^;WpO^Rz=VCkF>V9(jVfTageEy=_`)=8~j#KolOX_@|9(=BU_bpp;$l!;4bJ~)9S!p@W&#Ml! z7d}Tr_8ouxBF|CFi>_ug8q22zYFcQgKL$*sg|gYsLI5wB5^t)q^qW78*ZjEtG{ znNQw$IiIm>`_`YDX8fr-Lvpo0#?L<2`mOrcGV_*Oe$*I!cC)ViuXSB!aPgb(e64%y z=8gDqr(2-Di@v-XH0ehbtQbtFlg}l@tI2ql`ZAls>FY};f@k=2rb{POorQR&E*fEV z9Q1=8Gl(ktxwG&|9YydWFKs$J?D);Af*1@iSi?TEmhqz$eux$wOw5U=JVRIp!fKzw z*VwR!(Gk8WDKh~|*^BycSD5OY$wxX9@ys%vIRu4|4)x{3bJE^Oj++elK-Vqa)vJ__ z;32CFG}zMcN4tN^p6YYuk~(CPXZavY`Ag@Ru0KcFEtd`yH#K75sQL;z%o7isASPsY z6%z*RPt+m8y3U4dXlGo#<|dv~R40vH_F3}GdGNU+mS8flVGt;_atKtcup1p!Ar@Qw z@D~vhZby~bYR(JvB3EjmSj+eF%(os{(129^*EqON81HhFS!8wnbYfya1x;Wvc;*y@ z6!9#6vjNz)I*(=6SzO_SE`quq%B*maWz_-K2SJPTh`0u-)SCe~v8B$`l|goSzFFQ& zKCU-)nicjq;=C%3F^i;i54sPv?_IFc?g6o!|~nk#mG=N&`c>YwEl+AjUSc z-1x$vnCm|}^fL_xSK!60oIuLiW&l8y7^KN>72@U?d|@+i0Ea<8OK1g9u5Eo6%O+L~ zZ1L|{n>O*C;F)X<7Ni@?(}l?%HGfLFeA+`L1m;BYMz{eq|Ol59|a+5qg9S?XdhZc>S6I;PQ<*}&sF z4Ug-J`o`dnlO`L~j}*Snn0)nW1GTKPSccc)mwJ(wK_@Zi{Bf-7nh&ff>5t?~+vhsV zhg2stxyHaMgHRr|psWjBE}*&IA`SyP(745 zbNHmlMiOmLoDImucj8NYc)cOtS6ymxu0pk(ImN$xf6(y}kNR-^=^rN5D? z#=)^@Tq9~2;s#P_--H+6&vN~-x`B3*b0o1i_7w-5<2>=*FRLs>;>2rZ2d`4&_lwtp zmRWYbQ)OUHoxs5s?J&>0M_Zvv5toRGczg#r&r#>FTdoOiXV4ZhSms)fwn@5#gx@(n z;0KoC!;*Vl4c%kyMH4%Xzj*6 z|MUCZfB4?dfQloZcL;nZd_ut&UX~lmXAJvcT6{P0zsLR%?s@X;*AyG}-F32# z>*}&o%Tw-?v20GQhYr^R-TDCV&9zT|WGmp*BL)P)0QdeXwZ(pqk zo$s~!O63cWfEApYM(QKWn?`D#Y{0ZE=ll@QGGDYb$JX(2JRJ+m)O7gpOwV%88^dWW zYx;|l;y3T{te-iz-}aMbCExkZcVfeipZw$}CowSptf}K?yLEXU{H*JI)`!LqY4B!0 z>_rY*k)+HH-*f_?1zBHq`xhO9nJ}_Nh9CNJ+3t36@8*kIq-C5)%lSwvng1k zt4cla5#ORSr&)pMT&R-^@8sRM;UO4wY^13U*2POVx{H^u3P-c!GR_1!?{klV?7d0r5{kGI*;5uL6gpA%vu(M;X{dq{7|f7vo!VO z{QRymng!-ZnC1OzsxO11GH{QL&xFl+EGrqPjAm_gZrI!|I;lFvG2oVMRv0i?le!Lh zBVX}QQ2# z&Z;`4BBiZ!;m z`9ysjvyj90&{Z6D-IsGsOhwmGTq!Y#x(h%26q{#>!Z5klH=pKp@7n3tV^jh0pOQisbQ&_-*Mi zGvcQ8R(kE&`PqFVF*R(P=E224V(BAztbX@eF4f1W{kGMv#vE&0>j&hw5yQj-bHn$KQzPbMPuMf!e=;K2-#yq$g&w8fi zvh8DoYk;GCPl|Nr=X~Lwo(IY_eP=+@>-+xc^gY=r$EnkBo2OG|uGHKLm8q4hGAE7_ z5w|%|an`Z4a*$a#5x1FJ#4Tnf4pdYU#D$88iW^12_2>8E|B|;K?&p4<`?{|Cx+*d7 ziaN_;M2_mm*=m`LU8BB+W#U}c>BQLiKw+~5NI0q?+iFjTCg(zG?}1pHS0%`mDTCY< zE$}_O9q!8}eLYb0zuhml) zhx>zc|4pTP!b>=vY8g46hI{0@M{a*-Zi77}kQ0ni(C7;g*5{h0!+jb~Jm{I{f8W~= zwjVV_?b$Kq@qdimK#4nT3@`neb$3(-cUCUFZ=i24=qYgL;-d1qLSfpYR@b$dgV5v3 z2zsCOKyj&Iu|RnZo{i~jdt!Cj6J*TfXb+i%z_?N zcLBu&#U^L*onJsM%Yf)s+999taLK2iHjrUx#V12_HdM1O#0tO2zsXX2_AeAw@xems zEV?dRrq51(^W&W-A`XH8H*e#6^2>jd|8t(FA6#t(%v>&4N6&3IMVo*VSZY zJARs^-06Vdo(4jy6>m-cb!)6I4uMzt#5;@ry(YW&yp$6_wX+N)-8^{X^>2@LF5i5k z3~65d^*;7Ogyirh`l3bU&X3IAzo#;ipH7(EcZvP@V&k0F+bd@x-HZ1map)X9m(=ua zxQOlEN$2N_h(0RuO2T)YyJt4vk<3c6Cmx@L^lgBj|0{KBM(`*2z4rHeGYj{hKTMXm zBk1=^<)re8dYDS=MZru9X<7%g+B)vdTjRr_lTCu?&l%Q=2iBfe>xk>^>nG~xtrKg$ z>=>HF{r>Pd1Q{7paPzMw*`Ke@^_~~;`7hS#nw-Fa+H>R^AKCxWjPY9tvtNYsjETbWE-~9TgK@eSiWg10Ar=4hW3CFQvBSUnqSuJ-#0yd z#A|c$a7l`vlAu(Dthd6;B6cepnzgF@OMS_|WoOm$N=nk^b`RTjflGkqlDl=z-q@1v z#J=z866a=be7Onh5_9b{p@`NjxZmJ5T73K`XA8y07CS+gThP<+LamZTSTTlvTeDa{ z>mNEl>PYDV!K}luGmIRIgw3{OLn^$b8N8lmjVkNPO^_P22olpfv0xvNRtj85<8llr zz0v8+S`wg{i!XMhlOfe+^!*gr3d$wOVELdBB0t#@+ zsPO^P-}VAO`Yu&+*`GVSX19m;tC?TcJK-ry$$Ef=NKR9+UcH6^%kDa}$g%rDq9=|a?ffn}`jJes~^F`t@xmO_ zr6L0q*ss~s#x8c%uH*0h_tm!X&WsZBc?s17!jyiLkUiP_YV$YRiBnx^D$dJ(F(J93 z0krpb_uINHn`I8>t}20Js`kgT{DY52C;VaStw#=_tZ^fQt^5!t;xiZW0Ogpue|!@z zGzlv>B~df}&z2=R6vsW{n3nTnft;L-pFo$T0Lu+;O(MwHTDhFod(T7c+=pv-0$cN% zvcV!1_0XsiWT|SRfC1Qn=tz(QMhc{*QPUZbe@*?}C^lj&}dhRQtpR{V<;Fc6T3gNcpv z?4H+t>Ubilo9H=JZp&6wf3sW5b~K^1RRMaEdbgK^hr4erJ%~Ek>?V%Y(+tO$9hi1K zJ-sQ~!2s>epCkuPT$mD9)j`HN*+eOopyLl3ii}PoeKG`)DpGe+dPR|{LeT);qJ8lo zRK{yMAL4#PbLYj<(g)4zS$G$9U@Dd8=5sJ8rO0+grV1nf>>GaQ7At#dkp;TkjE>^u z?q?kz5T}5LGu>0|aFzrA&l|?f1qcr*G=5dT+kMJ+?}wtU#FalP-E`i?0`CsV1S>m^ zAqPx|*$RaDJ*D$8^pF4j5og6-=)eLkl2kPY!t1j<@t(u|S1Y)cwn)$34EG7FJ_Df0 za=4z>ONoz?thHt}CRXkQM)zp3I7MP5mhR`853|3q8r|Ug?&W2+RUt83axo)^Y~XRw zE;NP%wcq}i_Cx1|rW&@@SL1%{|Ik@2&R)Xj9PqtxI-kjknwG~2jkYi%5*ETm32Mrn zS_8F($ue5np*t;+)yLX4iZ$=Ws(wo_R=-|O5V8o)zxIW;B3oN}c=dLsuve?Nd6SaC z*3Z8GadfE(kY$fAvF4&Ndu*3rAa5pZs%W)hO~QrybeDECuGQR7={z+3&jinLF=YGt zSq-XqaG8P1Is(Ic*tZ^U8~->y%;(N+$n4k3=08m>a8+JG-R6hNP9xvS_NOQRaWfQs zs~uQ=WxkgEbBLR7J(uZOp-s7+hWgJ4_m&T1Vpp@1H@n?R#(T91{S!ye%qUvjKHvP1 z1fC8W;sBqB*Fres`@;D@0s#}{bnCPViV514C|YrQe`F5m@8DuU>_qqw0=|-bDEb~h z4UmmiJ%W9br+;lb`k}Ph-qPD5^~1^8(r$ z2v$e!cK19d%B z6$Zi`VV@6p>D3oe*J(|V;s{Qsjq#w-o4fVPgKWgiX8HUdO7X2lhi7s;Y?!oT+VRjK zNhIb%ZRnc8VhC+W{r&m-a_;ygz!^l+NZ6XB#7gr(*|MExA88}9Z);>kx#rE^QaMkY z4Mx0Y(l3q-e~`M}4R|vmgU-6|<(lpvSyCM1?CH{moV7gLQalP-srTTNbP;OapozAF z5(O$6A$W`r|L`KqNDj%hQRR^RK4ho^f$CqP5#vS0=^k<#+NBWxwpC@=2$M?YgnD&^ z4b>Ll)~{fL4wm#B6WxU@@VjhQ&?TT+PC%l06GBE`1CGF!w@yS!B6!s%ov%;PR-iS- zrOc@Dpz(FN@YZ(=PXL(I?NNox*3XF|&DlOf_MDiZd%J6col_pr4t^gFE1V)6Z^rX4 z+@{^?eVL<{MFx*H;yvwMnRrY?rQWIECH1%9X6IqB#GY`<*z0P zels^9FQjZXwrN5W2af6@Q4OA78HqxrVX?opu)t7Tp_LS8)A~G4Do1Nj#CQG3d3R$t zCm4@#iQam+o5Q&Ur)RZKJGFha4|ZnX@_t*B*T9BF@T&8i`!k8-;dtgRZ!0YkyK5I$ zLk?1^conl+r+`$%8;Lg1kMSX>f5_puy3gJQw?{R2fz9N_GgINAv`B`r4zo;bX^Bp z;r(|@)OIQ0oVv&$#v)lk(}CgBeldatabERThQgVcq!n5|cO^m9hfum?=xOkBpmt`j zy3I_z%0j7=8~xROKtM!V|Jv^~wTve@=F08N44lU_02(y`%Y>_#PUEbATgvFJ7_g{1 zI3vw-&_u7CgOJGfI%Aq8TJbe9HKtYd?(Soah|2X6XUO;KfgsRCIQtJ`LP81j{dXF4 z!NLDYuCKd{$T`zaKSP5hB7j#HvCVR!lo>TNQ|d+S)D@~Y4*tb6hqJA<$)TBSo0B1a zY1HqGKKI{ns{3szmpAu2les>U4L1|RPC4P&EtrZ?yNK2gdCU#$!rl`(QuwnRSwydd zL|5WEJ9WpLV9eXb^y|a-pMxwqdbsdgC4J+ZXI!Q%bMF(+Q9EXHuFFp6lfWXfLyIY; z)i+4NfiCerCc^QxIac)gc{9UeWJ68>rW{UG=n6r{5DD?{6>Xb@y+l93A)yiI*xlYh zYVJ}7Io_HC(p7RGOVFXzG@bQE;n5c#%*a5*7)rpM!-X@umrur|G*WbQ2*x zi|_RzE)X$nMCjIt>V@FY!~dq86vk04y9&G4N`DV5`Sg{bl{%#6A^c~1{h@wea;)ztgv2!O z=(WR5n|l`_WnnoP!pNDeGuX&nME~cj1hM@s24Ske1d)?@SL{a}5NqZ%cr;c?>L+mf ziBfpQSSextOjYaXG9A94{*f(oAqrd$_K`?2z+%b z%glkTm};eg@RHHEWeaM(TqQ=z1^Fs79l+ybk{^W(goQ`XvzlJUb?is9Od;3)!zVU} zL_$X|oD8zj=rVU$V*Re83PxL;mJeE=El5t9uUr<}F1ze@6<6X#xEA!J>UiGxxAwnT z;)Owfr(fHfeDH_*G*~%duj!j@TY&%WgDS%0$DC-Xxl>A%)o&h`wM3ftPo50!?!zqv z&3Sj$%}28%o=2NTzk|y75NnHDR_YLb08jjKDp8G$U60a5f^KUZY(3AGx|6=0xR)XjmAkN!(;X3Ua4`y(TZ_gr>4f>`6LixMv=K{oEn zQ{Ryk(-aank!DDsDZqA3e>Jv>-e$TOs4H&ls)O~5;6;#lgO>Ha7%%?^Q z?(DXpWU=34c{VZ zvJBYGe^v+d=#6omhNJ&6>n~Gvd4V{07+38|w_Eo|6s`5KtHWF85W1yP%!V7vvM+pC zswKFq-DR9nNQs8=dr)cU!p^W#s&6LJY6X(foDGTJ5-Yd{jZX3pH-#qJfRlQ`XHk)L z9vQ&T=xLGYZ67-@C-jHqy%bkm%xGEoQ8M1FT;BRt)gO_16!AqLUYs` zU)ZqVQjS)*H6mS~;jPImbs^+nGlyQ7##Q5aXz{0S313r zmjzZzjQ^Q_ZGPFTRLe+ifG|qII&R(}UdQV-aLnQ(L2@77r(B5>Gw@JU&Nzb!MU*+NQ5$MdtPenun(fA3rEa7TVwq}cC(VMi9r z$_`>#z^RAdPla*CT)L-Js|b6Z4jlM!>uTbX9f_ zhiV2y)%y})p;6uQ`+FKwdm5;%zpAd$^2K6p%WC6e35Am2oz3LMx|miqrR_o%%hO1r z%c(gG80KKa5v&+vUYh?T!sMX1Dxr zv)R6s^(DZ2>g`1NSL&ZQ@X7y~I4S=sITq%k!P#tM(Gjc}s{W-{1_YVr=`UtyHTa&j zzNc$MffKY>3$kL!bqp;{?yq=HC6prnIdpYBoE+STwICQPk$%9>d2reoD!1805=D}g z?a#eE->rUfTm1Ws##HWt)pcTk^W9s~qTEq*)77C5G&riP36=T-ijKO3#(Ddm>o3*) zS=>M3MXl3KBW%fbH(WfHJzg;+6S(D|i2$l-4~PHdajh^Erx(H_)wir=YI2(38N#59 znlb7Wg0Tb=|4aQ2jiF<7;+8~UShY0qk{bA4$xCl5$j(>0+OWcot=Hk9@dqD`Xci}Z zgmAmI^%|)K*H{sjDz@%R`mw>fZiPOA-DWz(dT-0Cv*jV^>6o#omo9{>8Z6As6$$U< z>Qd&ZwUm$$rsw@-i?a>+{Kfi1gVIX+4|YScf!Shmtkoia%ALU`%Vzjg73~|9Fzgy! zzkp41Vn2&i3AMx=2OGt4b&AFKO-EAS%@dl9=wCs=@R9wxR%{MGwBoFcB!g2L#Cj$wzV*QR(MTw(t)4x~wQsc|5n4m`d8hunWim@VtxID>+0p(>% zW?F<5|1Qy(R}!6cyZCY367JXnBl;+I36qo1eAZ2TWwmB`qU ziQMRTYR1)ftH$Y)nR%AVU?E15ZHW>(?j=5KW|!+gg0HV4Pkql~1v_iZPmRpjVWbu1 ze#sB1&v>iK{OAu0ZI#AM_E)~bToYTkJ65`DXK)9Gb*&zFg*tJ-Suoz+d#RptnK{+U zy@QS^shJVG@AD0OeY(I&sfyM*TuK;UHJD!FU?ub;y1ob(ZO>1^5Y$8DiB7aj#Pxlwr8L4MF%{&tcP)7g3ZVg^VgP-hs@zM_!)7a#FaszI3 zQ<3X(yyKGf%WSwJ%Hzz3cZ#v|%&0M7iPC=ZYZ9`*wQkFRblKxa3jH0Ly_W)0)p$l6 z{{naOcIx|81EUvkN{jTqgxJW`fCb%&y%DrOwsgpYAi#bPW{NSSGy1Br?v)W5GA}70 ze#ga1f_Gn`Slau~!yx*~SBPHUEVVixCv=F=%+U4aiiY{{o2g+J#U{eRpRU!sqq3zz{H5^DERGQ%>q9 z!uMcQUD$G%?pri_<`+Y}0CE;(Rz(miK*mB_$U!?f=GrCSSe)SGA2#5csfKsqy<2)FW36c$^0gEJ61G;5b ze;|OE!Kqy+JzKT^!e+Kp1gKB(()P3P24~BJMK0(R_gQ|)@|vKK{^dL549#}B`;JuyXOElqmw9brsgUt?9Jnfpn^k9Q)D$SR8!f z-(A09s^xEJ2U-qZD@z@?9)zBP|Ga=Wbr62tNoq)qBpbET^U!_wnm8&@cY*r~xKq9I zncbo01Bj~S&vLjcX{swAG!D`|&)X(GYH%vikPhCrV>>VaT=cSal=RQKZ8HK7JJpXl zu*+1MA7BAZ2o0Sno>^=z*1Arkwyag#n!X)LTe}QJ1 z>L)?<>d#sXN`yYj^lf;_?3xk(R#h1%vSeH$+< z^g&B&G-oS0ShPp=og6Vstx%F@j7HYh0j7V;WmtlEFP?uK?31sE8d=d&sH{7ey>|7d zvz&OHj9PeF-q~i)S27Ab)X-iVXc%3Qq$D&>*_m+B-7B9RpS;m7L~6}YHcFHRMoZR& zwho1qOWAtpSW-=7rXs;j`u@6w{^)qO;&Js$TZ0WR2MmRyl?@}N1vnTq76^lXAli42 zDH*W6WC8`f3<$adwK}vp3g_eIiyVT=Jsv|PrfI)|#;X|1MMRY&0~!Zmj;ugmLU^&B zGdYNQfD7gqjsiJuHp{(08S12m^sMrl-XX#UYXWk3SM@C6H{9#>{>2DNhwQy}+xQga za-k);BVQXj45pZ`x7yRSD-B^4tmi0kf~dtnXj73ul~F?_Nmh^$8C`mczI^cWx#LNf zxO&xuN(+hTG{(EP#ByEA21z|$TR-ya*29OghnfGc$dCf~Y zl1y>A{hHItx<^x|T3~|I8EU}MW|+vbv%&XI?6I;~Ex#M>fvptZVSu#$68ZM61#9=Z zG}Z5EPfiVcuW$whLkaIsIQX2FD^KuBYuM%`TMy)RtMnbE_?`Z0n&32b;k%ae`zDq0 zg2vZnE&^2WOI)!@`d{Gp`}k{Z?&ey~84Q|jCvE^=zr#mxKJ0QiFe)T)@{-M+Dp{ZD zpV`<+JNViOUA(q~aJ>goCTQMzj;YJkhZUM-n}uewT)KxD0DCZ>&e`2m1eH+Z0vy!P z%-lQgY0T)tym(X$pJ98O+NkyaJo3Rs%XG;4| zy*z`)PdhABUR&wUts=b#=a!#n;RPd=$|6a|l^uTGB$?!9*R(bR~_ zhi|0DGAF>hFM8uD&---wZT>ewes%0k!Fr;Q`1Nl=A$L)@kw26$2YEn41*H6MFL_Zp zHFDQfw&33sZY?N8q9+_ea{`lIv}m-6khT^IC??)7nx)C5I|EwL3L2HFiliTERVo7< zejvce;UVq#aO4z|gCT|#Q(ys2l~!c?f6*+xc^86Tg3bQ-#G0roxK$rN;!`CJ6?&!~ zraqt<)P^bN+RG6ZS|RaIMGBLkXfG+cdo(%EDX!tivaDa-O>1Sp&m+Zw1z$QEGudkk z)&`x0uQ$8Kg5G466*(~%6k>x;u@+4X9rV;5FW{GFJDfuUKzhS0r$t^d%l&4%RNcg$ zCfiapKHPddQ#!_#bM)gDQu z8-J)Cm7(dq;zNN?7?J_$lr(Z+Js5sV2^`6GD20Gp%}yq)|FZ>$C9S4d)Cep*Yx0Tl z!X=w1V^kH&rk&q(MyG6*ijX7~2v8l5RDs1){lC3xShUAS>V1M&1?Ge^bsPGAwIjto zya#(`lzTf^C?T@h88rT#<-Mf*NTRGezcDHt3|nD$hwJ1ZHTYXfO+LVKf3c@bOrk1= zubGB@>)5@X)m9oCTrPYLBW>dIdx`L6iH0Zs$O`pjcO5--sc!K|_0gIlXEEZX+ENMK z#H|c!G5unEFy&Y2xC`wU`|Yyma#R!G=LfL0lwpoWp=8bFFIj)oUir_*^<&8lc5~>A zIsouPYv(t5LsI*_iUPGd@F1{&a(+rC;VP5OjNJA#M* zgst$Fq0~fwlvx>@Q(;;E76jh@;_br3c9g?e)s`0fFDoQaVH(K7c=5=q{!)jTUCvh| z!YSNhzwp}gAL=8GOnV-t7#0iu&poNOuQ^>1m^sJv9&bDR@6?o5r89ZIPeUO(GB0B9 zK0>S1mo|zouvPZ=UTWrCeKDHqS1;`W{M)@-#p8|&xMuq>KL-K5c7ZVC@7VtBL^E=h zy`P(8Y};_V0Jk~(Rpkl#&(&1=$>)P2VtfExEvh+VdPMz{zA%BW&I_W}7Bhn1L4ko@ zQ?dqxY>ffU!00EAU~PBhh7Cp1T%OiX6FD%YR#|VLRw<%*6E*Qm=*FoUeho%xsSb2s zho>b)NtgPHP3#OXn6vS#N}tF8V#3|S9I;%=YtEpK`x4aN$&x#v}LQNK4E=;oqL9FY03&^Pwjw;QYfo@KZl8 z-#%BH_nJ+Ya-RK}`A9crIoRVjA|~lFRzJ!GRjZJBj>}k`gJkPLGQyyK_jli6^;4a% z9-NnnV@&?_oO+#@-}&jGRJctLxkgdz_ig$cMWRNW*=bpAN{9P(eXIVUrv!bP_PL!= zI65$UXFR>zhJdbVCdSHZ94!BTFMxILDR~Zl0|dCMXX@zCTxnwA+j0%fdag5K#7b3N zF)ZF;c+JN$nz&Q5GwCYM z>@-gHru@ofe=tY>@UQe=!ml^GlQjyeC>=F1y|1UUaMMeN8+s*G@YMu?!G*>o9pJwS zNs)FTJt4@@>2PJ{uU4P4eD(rY4@y&_q>bC4>gSnVn#Sn$4W|-WF}h%p63tO=TMfrn zk|GFG)rdF>giefw2#(;gf;W6fu!2cjk$K{NwG38@#HvF^*!Lx??riFO52dVUoM;xS zIOCpU`P{U!7}BY+Zmqz)(=rX4{EG2JdUoX@dl}g#p{GmUI+4Dg?DQOn`O=sC1-#hY zw5B12gY|U!_kL%;Q0&w3$8BaO&)Qe1RQP6JtRfDIqIkD%`HxdpINw47X}Rk8cPj<@ zC#Re!f=!?7zBRUY>v>)??Y6u<{Ti2-Oy$%&=hgE!DR<}{xzUh<3G0&O$5l{J%1X{O zwgneuesX)YWb)V28MNpy-DO*qB&vxd5e83adl*}umk^I5ST4^=eV}rk{t%j6N{tF@3|1_@7=W6mFd>KC~Yx}3LjPS=fJro`Um-K~q+14-N8i$`J=LAKv? zNr@x5BbDlZ0Y_xUhcEWx)t5fKmR4V-mcBkP8pw8O`x@HF65E}UYtAc^qG$BR9Hdh! zJTcm{G8HnxmeMkKyW=H3L6pl}Uh}Hz^AF%$&xS!KtEvJNNj2wXP z^T{EJpa=NcD0xw8iK75h9p_n(3INshhXN+llWtF_+Ms>Ngj#r&AVE|M+$6m)%E9>I zwGLZH#!Xh-#?@Avoe4iBJNq=H_WAGt_zD0H4m6CEkog3+535X2xsbNnzND;I!7w9w zDj8D4G*nnhpR{sFvWbzhLcMJs`ji2Q$)=Tb_n2AiqQ*cVSk-gWyWA&cx|QW>u+P|H zKPt6yXS)NG1%&?H^=jqm7isU)r|NJ(!&2lDo;{~sH1K~~izJ)$uw!5?T= z0ZDI(O6{OJafw9PCRu5_1*l7|$_MZ4L~|T~f28d%!z0!GAJAacf(+3x1x>GT&wSWn zt;uP=De8v?_pi2Cfd}RJBah_AJ)-@=NGW)4#ZNZV3rIKiYs&MM051)AD|)9@9HQ1R zmH-=rZRs7uif<#iyvOocAEc$X#C4)Ujk38Y5*(GOnKVHgE)L%EG^8BI`JGk|VVyp2k_>;^ z$5K^u!dP*NyHj690kXFq6X|=E-9ypVh?x#7t7N;n!Ra~!N6mgc&}ap;DhSR>Ppip; zwDc_0!qnRE1W0fa8kVRYm*i+l5l2HU!`=w2)9>=8h08<7Q~j{ zRnFpKA3gGs^f@5H`;Zmzigb?BMdJq8Sad?eX?I>l&M0S5F%eE5Pn4 zO#-s8E04KG04VTyBP8^A_3Tt7$ANOmV0m&0g;~~DrQ-&94`7w)@h>uXuifu0e(xFy z62fQ5(xUov?NB$3S9m$9L(`OEzlh8L=nGz7O%Ct^zQWtq0vG!8WdB~7X4>SLvHYOZ zHW$I^=JjW@%yz|cN z|GCCxQNA#OR#0eHmHlOjybMjG%P$+eMjUIdnWEO@$V{5O0O0bz`i|L{l5ex>s&nlt z7h3eYjPXmI-rQli2v^YRcFkIx+AUx*PFNxD5xaLL67p8I>Qr}p>!nW@O$9SeB_t#| zhjV2whnG`$1uI&GFq$jO3 znMvNtGcqIsMnyR_mMZ&TF>sS3_^GB}Lc@&;d_Tu~`lArR{ZN(*VOO^cP6P=J0oNa? z=)Gglob#aoS&&T2cM|k|g6_Q1M0|oE?>VCY8A=UX)JE@I>fPnbM=#fG>cawkzIKjr z#pWjb35w@aR}4A6=X_XDGkWWdrFeeR4ZW=%V5l&(o1_0U{*j^6smW%%*bPjuT4iX` zWkFN^Ea5WoV_jNbXg@W z2_@BL>DYeGY!G9H%BpMpjt%}ELBS>-zCX44oRke5I=^QiG^Aw&92z*e0{C^FYi`gL zT=>O7g2f1hm}rRr8e38aI12^N2b$K=`On2YY5h&a*QD|^7MhJ!x4-P{G`MA`jdfJk zTi4y8-U0;9D=}*WvNJ84Eb+C32i*rmO~*9;c!F0qV7WODg2Sc*tuEm zI&3FRny6B!|EAX8~l?=9vLwUg!j$`7pR zS|HYntWgXlQH?&fytkh|xNP9d&1RiJBRmbc&6VWRCAgIUov+Tq*Jcw8bzSb~&`IA~ zz{cU5b4F7Ev^Bu~3I@5@%k@(;+J={Lseq6`sxGI1?E3}dGuYsk_OL8U=0|jH(W1+fH<_U&rTnt1m9UsTn2$ zOhrdeOhV#a-Dj}<0hTSFr(1W7cX{5F77>7QR`nOE|KJ}$_pQe=x`F59@N=$1?-QJ2 zzSyRz>Anm;ZDQ9#GKcoPPmHBZSACkOIC{xhxs8R6P^hk zc7#VaZmpUoYXr+slwDT*mKKma?JeP}{U$M>W!Kr$K2ziN}&7o=`^>98bZaFA@W8WQy>-#Z)9(@>p@jr1AD zM|v!6&q@$r{mmSbd@Yhs-=(t2>I0C8ax21UaM~>5g&i_jnp#dtbJ2A6g--KEc`&h< zj{e5^sPy%%$GR+E;rH2FzlBuSp3_T3X^$?ueq>kpN0mi@i1D~b@$}jB#v_=%SryB# zEpz&q$>lHuLY=fB(E!RI=<10)kp1aghvGfIA9Ew7VULFsTpwT4I>gs1=!n3_Nc z{}OvzqIfDHbJM-VsZDS74yycQg^An4f7It7vxU<}5kCcg1~e2D#V-eSNq-j*oZkUV zT-~&(dm_nZ#w&!URk)LOLqeO&KoV27v_|+-p&<_$u;Eqr;AhFZ-v~ChU%5(qmj2tg zT-lY=shH-b`_AGT&uo)bJA5;ed;07YNmHw`l-#5j;QFtXi@?=6xfOZMloRN|I)S@# zzd?J(>Phh2jS{kV*LNH-)`>7~kt8zJ>JVScwE(FxjW8}1+AlDbrZTIo2ZTl?7e3?1 z7w}bd-#Kcb9s2Dq4lk9RQ;JUn7N?NMU^)cyR=u9lb%JXw!V~L)OK}ZHmiaOQS6f!E zSb-t-VNKbp%z+7tszKX3vt4U={M+%zhf3x%OOJqkoA24hHjYBq5Eq6Q@`JvcTW4B5 zsw=@rOQ|(Xj2=67Ph;lX{pz3C>QH45z`s;*?B3V77Y>L!DS>^TCmC3xqXO z21y^UfEQw^8L<66 zs};_Ya%{BCad+f~j`%0Th1t${ODB2{9hBSzX8cNT60T2!nG?e8yR{4LuahqKs+=t& zQe@G9h7H?QVTOr-{0OkP@iU}Y1+5Zp?__A{`>ru5I$!L&CvBn@sEt<7o$o}#oJJu%)@{)&V$ec zKsa)V!1N9lEJ2`Ec`J#-NvmT|L#9h1_-fvsQq+X!W@3=de$?0uXS3Q@+7lP>^O2tW zjQRl1!n`B6t#&Zo(w+?8r{09>2@Y*iZ?kl;M|KYT51K9}045z`dU7E9)m~0E%9~#w zH|dm$UcCb|=TnRzZKevEzOA(aRHyG4N-9rst-5O3n-y`+I&rUK~Ez zMmlgcJ1F#%`;)j&ymoK5|v=O06(dsf~ zfpE7E6SY~aa7M|?==?8%R^ZoJD~Fr$d;{Ytmm`Kth)nd}ta^?f&ixmJ6!hWHMsZDGlI2jZoCWx-oNq;^0x2Dk`D`tsXVUP^0=<7}-NfJtt>`2u z&WcYY7DJ;5xv6|af($3v(Mne{&;+!}G(gYkmjFeDLbFrKgcHnaz`)`;3+de5*OsM{ zD8G=JgM1lSdE_wGB9lHfcg}>(Y6WNeG9qPicCszLsB@md>4^VZQqdE^`7(7=v{1hw zBZ|-%MN{flM%s?oVO}79AW+9&PiNqO52>*iyj=pDL|7z~abH_?Nf1j>=^67O@vPbd zm(g6iykB|Rq~1}WGoirQy7dy2{U6ez_U>>>j?A+I%BW#sC$@ko2q!;&l6);qAbeC@ zUD3ZS+Nx@B*n6z**>wD`MWZ*0AzSCFj%OV|JbPiWs~FY$4TrKBnQ2i2`uh%G zPA_z-Ch}}2hZj5m^iJe$l+3y7M24?oDRcJ0ev3h4mJ_7}dm!QCI!Ibjg|01fiJM8g zIZ+8i?w~Z4HG5lpWP-fJMwkJ&B$5tm9bSdh*una9NxHSr)4n%--NowoOkt_&9p;zJ zx+=j;`Wo{qi-K)EtN>}3bbfHV5o#rDxFxq#Hh8Q zB|>M=fg=4jJ90XY>%rfy%&f_MV(kB*fvjp{F}(Y_6_&`Vg~W~UWoOKeUd{6L&ome_ z<)l{Hz6ZV>V&33v(F^6`bbkTdq;74g#=USNGzl6P>(G7->du2|?fs_@^3$O^Cl4JP z;D>;ONM8!9bV*5qkLTZjK4*e*qi(az0?I`?gR7CR!L3G5DJA5tsudTsql}b3SleYH zmp@yP)fd$0?)^SY>z)?psG4s?6w%0B?vhw%pp~mzc{!RLC8{K$R1P>aTExqc4!375 zLTyhjSCs}~aRdF2#a^n9Eo}NVhc;J_7Ci-;5e1*lW4#rYML*;TXCUQ25Z#S}Tgl{6 z;d0OKWx@`vJ9mh3Ye4v9Tfpk-nvg;K(UA%Ijp@^roHrKZNn27~!ks?N@0UxuO7^bY ztXwofCI9>M`9?NR+*G0H-1_~?-J2nT4$L04{mdHAfw(^xCJ{&%g4%Mk%2}c|xDgyl ze;mqZc({i0;W{B=axCnk>hly|k!hcaFnqmVQW|5XDVq^Ey*HG&beoXjKP~DB?IKWSoLX?*d_{JyITD)~i6LplB4aw{Aw85v`ul*ND3BwuniRVJz7mXyTx z>8bqwX=Fv;rj`eI7I3RWPh&>TTt5bH2%X}pEs!Kj5oE$g!oSYN=3EkX8 zc;}?;;C@X?Iw4<*@~zCSC@(aRWgqNL-DJ67btXHf4rlbFi!6MPH&_C|y}P?d`|I70 z^!fmjwrL>G`r%JnK-N7Fez;b^&)lE;d>^a0Eq{c)1>*N1U(1KX{?yt^IET8mFoEN0 zO!57X)RKOME$9rW4Q-|Pau_LEL`}7Uunb%FYC-`2#RlQ&!|4=Vr3n5NOH@F^SO;n~ z4r5%$g-9jV)`ghGw81E|6MnDfwl8#pnl*gwwKe>lLIlc+8~T2B$?PRtt$I88y|`alN`-WmG%^Z>EgSQr(Bk+%K=gA8KK@qYS0w-6<)f5Gkp9y4DQ% z){f|BfA4DIr!Zu1Dj<3*yds8p|RSl607cV%bK?xe<2Ng z*oT*{>B2uJ{8RIX{|)?xwrK9vmLjn%(=_Ejd~<+u(Zqu7^L_QM52u(F?R0*J*7AQ8 zRvzn9A)vy>2nLIAd`ie#1|>aVA?E~Hbv~mUwPZFnrpd>LuyC9I1s~%q1$688j)bLt zo^8UE->wlUJbF&rwn3Q_)CLQ@aaJCH+H6lNl0$=X!%Huj8~d?1HrDa1x3oCn*XVC? zkH+MiO6EQce2qQGjkWg+8?1a$nxK$5m@ue*(rX$&th=JOy4m92Hn`^B%ni5nWg0hB za8gaO-4UJMmz>JJzB>^rux&r=-@Blx6|`xMFk9Na*8dWEgZ1;&!_EeyF}29hjI%H`G!4_bvtHA%*qq#^udAOu{Jl;G!-UKoZKHztON`ZOaNNN6Pgg+ z5O%9b+gs=)F4$RW-Ys0l3V$m>N{!m#CA~|Ww(D)lW`ouI5sh&L6Au!G@K1?Tse==78J{YGd zLZdBugT`D+-s&Fub6zx)OWi75(k!p-2f>{7|7}w3W2s&&|Ee|Me4B#Fx+$>PrzUb? z=Ck1iY{!tsElt&@Sl*9iy$#j?r4qL8q0v<{9g1ttM~zXGe>SB`dJb zzle%U$x$AgiCUlC9l^5x`h1}>xeN|#Li+CHd829qlXR}PpQdfT6ugn8`34Fn)I~~t z>TS)|az@p=<^DgK&c&bU{{R19Wlg`9`VC5foyd@3`_d6*g7T&2iq zLdeXB z)w0$05br-Zq_3`LkDvcCSfzX*acUpEW#7r!1#CXASsaBtmH_YZaI~i|aJAyRM;w{_}lNrJ|boE#TFc z0@|ASDu&Py$D&YY7Pr<=OQVHmobJc;aool(JXB8NdgPSgFKV9~8i!;tXz=cS7#pY6 zqZ;%tfncv`S%+o=>-g-(^ATi?hxep|U)@I0vrEcTm$$FTerJtzgN%D{x_qWW9!GL z6QD4{4Rc@V1PM*yPJO$fM_f(Xd=3Lhq1IkFan>U@9o7^7z?7y(0h{|tTru0C5&8fK zV@FJ%xrr_+-0raN){;3plwgm3xNhFYDy|zU9{NO9AVYCioQ8_}E_w0J1HbsnkT3et zoPvHkhF&xBFk*jiNBM#B*c(+37e{+HbL!XPGxB0E5Z<@8;-dPwWKhv^O`v+B>~gzl z=of)kc5Igk$IvecgQbDPTRoK}Fv!FfiSMg%>#tTCSC%F=e_d*Z_~%9$CS>Iim2+$p zeli6Q&Kh_W_0+B)@@{EC_GlE-<-D|YEy%}UaWHjHRt}~UAFFTwW9c0%&^)FTe(Oci zQ1^XDneQX#S`;|Ug0=26B87~dd1rY+rY-1#-6_0B3@H2A&6C!`0*gT=;X8JEMF6_J zz{+3iOTk*!37`3OL>ly4>%nN!-gV9`FP!xQ?sLDN{6o~5reqZ04KKFdq&i!j{?HF- zQ0|!&qZwKd^)zK!wU#RK0aF(BNK3-be+qz?Qzq0EMwV``w@~yn4o5VfFIM3!ff^w> zp00yQ%xWdrnC6hvE%q!InB_Mb!e)dVlXIX34yB0f)LOdKCGukoAj{cVLKV6%1Ya7; z7i)!#em4H`uN|lsU3ud8-D6+NQPF%B6gG{2?3((jQ-jdB%-&LMxhQk$0J;u!x-s<9 zBzxwsJWW*%_Gib@3aP5!)d#)i%uJW!fh5A04{JUPxg+L_*caaqdJFc~TH%3vopmJA z@%-dFS0k(5kpyetDn-9Xb-H^(=xtI>z51cZ0fpQ#qrKT-`wwj_0{jV4XQ25ycLg|= zkUWDhO<(0JX6da99Ub%)s3NJrM-BGOq%d9Mp1Xl)FmZJ0k&99`_+jt~>>$00Z~o2r zu@{yOn_hZkA+}YBMIknQ`Tlug&)w1`h%PYi<-d8aa-cs}dftPHjvSDM)0WT3NynlB z&RWxYck$cDgiDO}QerItL`~UET~f|f)f)g`!ViwAy>gXHFSnjoFCPuYrAz9!ZYW2s z5kvXU=30-PIGHC!h(!8kuJ(YF1~2R@jc9t_zNOKAC-Mix6Xy$v)L}@TxTCQeK2|QU zh}Ir!gieoE$NzlwkHRo@f{>zL*w#<~7rt}JnIDkNYl|(`Z!;9POtkXO`p+B%+u2rS zh|pYOE@qm*w#hHMb>m$ab%A^U6W$#-%^!u0-b9I5^Lm2P3DNBF9`2-Py!Hs;Jdt*B zzn=&Tal%Vfr+qTADXvRn{>G*1pHpQd(fr8QS-M6=0eD342?M$lh@od9ORifV=3SRa zM=;9k=W5+lr0To-X_Ib@x+j|wH?c3%QUU2C(4z$3nvu_!Qs_~>{VxL17z z#?RfF!xD=^gm0x%pnT7xH)k}FLHXHMQRg*tY7c)WUU)3li@8 zv(Yo}?LVpNdVfDqi1^AUXz^qU!dXjkpt9GHrb7d$TZgEpvlqEQN5$0+(q@ieRFLmy z^mfFHUVE*vl5{CnZ`J2#JE=?aE_E$pp7H7XeejKG87- ztBNY?C2BD7fo=>>=LcEFsaVoV-9b~$`hVW<%y{*KGf2N27==-R#0 z%(4bH3LQ!}=`B1PL-vc-OKJOuL~aO1{%F}-YqG-Wirn*?F|1v*lH^LC1mY1N=|AME z`f^cD{m>s^U}%olnXLq^+`7e=x!p6>e+l(0z0(z5Vbxu9d6)-P{N+{5p~y_f;KvXT zu?uZzpn-P9fpMj_&z6p0CF@BDa{U(EGQ{qV8WkW3cuGy5@b=lyqlV>-OKl z25j9^z7t!I*&mG=sl7}Rv5RVw^_Lylk}aW_ z{(VVz8o~C2!kn;AhS+qcaG+pm&giX0z=s1hZD=9k)I`|jxQ6B0Tpw^=*O-XePRRoA z5e#X!Q|kbl{dIG%p!n$dFNzZd9Ms*C@0@9%M_kOa{#!LF53>o>u9Rr^=VMc6wBr&g7Z z78!N-h9;z1`+_okrF7YjVRaxOv~u>Ah6;>0yy=#ZE){^nq-t$bM!@>6ZsY0YM=vM<};(j7fcpR?yq`n(*SURA&vh{ zh;8rphOidrtp=c(mba>#L^Fr9sEK zFRo`>BTqvcLzQ0U40QjPxS%qXAH6OCqi+of&t~a)#8B4OQr8sEe{`Fi7I;*>QB1m@ z7oDWyEEyN`JRGjKb6f@T@881r1lJ!O$i7(eY!26kD z-W12WvXgaeWn7k4l5e>an(%GIFZrm!wAA_$2h>c)0Cy#AU3m4DX-%(CgxAbb0Y=~Q z$J44JYHf zg_(=n&z)gpYHukIm{HQ_l(#&5X{ zs$;{E4|0>i&ZIL*Z=qnq7prSa8ACu`_0u_)?zr zQ};R4z*9=4PCI>PRwPnl{eetsJ>@$6N0qAa@~)2T&PwnOK6C)VSpfO*I;tsgXipsR z882k1>5b+PGi0y*f0QUlAT>?*ypDeN+c8Mers3w8%FHr;bC>aYB0jLq7*%cE_|^(& z+|fEmT@idL^HA^e+oCI(S;-S4-FIWc<@9RcXETG=G+G9o`1!AJ^lY&G^k&KR-6?5x z%knY$`loGgUUj-p>mE<0TH~{qRODWLBpJbJnps_&!ikRMFLf8?P=B@GnrW;>RR&GA zmvC`H{6ew=b_3H(pKlYb3s?YCyI1pI$^c?gA#h7#D8`MTxEE{-AJZfsF(UUEj&A;+ zt8(#S?E0sjx?C!iKbIS31W?RMvh_w{jwXE1`B{($ZW5JMOz)F7>uIN2Pd=WsrkqVR zd_+c9g!<@1F_OLr?&#LqfR9}bot|fFyz0$?tPWSy$zAy-@rHfF(zEl(S;zWbjnxf_ zG7?f@Ln}{v?7JcS1Esdsk0#P62M<#99Ao}ug0o(ZM%}|hHhVn)jJv_IWlF%61g}hf ziqEesSH>k{0KZ`+;Qt~V3KFAik^(%Sx8}vO zjOk+Z>V<5eHM-h2U4x?4A3PZYoGF`m;6vdr>uOiUM%7=`8WFz(tb{O8)ss3yLc0!$ zm>48JEIk$j?%e}QWd>voUCaYHzBE@I3c?r8d{X{2)XoLGaNfkF)>_DY4+S1o0iTZ> z`CFAC1rGqCq z-zV}JKD_KqJ zP4#TZn;NfLpd=ed1r^!Xf`@DPs`_1Ykg^B@3gu)TIkh?Zc<+T|`aAXe+IVaJ%zPT@ zf;nH!&plw3-FDZE@@rCYsOS!yP}i-+gZPWlOn>qZN1l@Y6{9z5ol+fx$U2YNq+Y(8 zreFd9%X2Q5(|)>Ts_XZy#OrO%F2KLYyHhGjs*Pd0IR%}9+eGyCYp&LMNah5*Kto)s zaRolOEySMYs$9@xpJfrv2;|G)7V`MBqZOx=!Cnw^m{^`9TRvUmr!3IaP&!c5_AJs^ zcz*N1mp1%U3ACY7vX+-ux%)~hCi{%&pm}<*Qa(NDUyN>*tLJvE&rt5CRJLS68X=Fi zsu0u}fIdL$^fS|q(P5&;@=dRb0R>AgiLC`9k~>yb1th#tcf zs4mfBtK3RqsQOgk>?vk43BLD)nt?B?0R=mZ6TkN!aC3AGP9FRcSkze*5eCJO=6*Lf zjvFM!Ul}W>4Lw2(bg0suBz{EiSa0qH7XPR;@Q6IoO;j=7XQ-xQ`GF;t<)vH2eVBS_ z;;@QyL*TS$I1`bG_?$asglH%*?a}<(5=>$$%V;CNNYwazTeE!iWA>uCmy!TiXb||X zrRfu*G<3^w(;vH+JF^qc*=5wXW7IcHqeObkC|SyOc4iGfo(-lycTdfmSy5dQSP#?| z_>|bO6*&1f_uR|7e>yVRnomnPKa+_wen7o)@WS;mEk+P-q5Jetwt~582O+_3k8i}` z4=wbqqulEawKC|RAZ%rp2aqa>br<`H!6j6R>6!l)|8iPDPVu4n!WW`fCIx(rP#PxNjsfTMn z*e{o9`!NQruQpM(iIbOOdgqM+_x9Jz!W+EP)DrKZB}Jk}e1L+zm6?IdF{yKdLuYb5 z-_-!vcBcP)SA#V6f0NL_q~?(7)MX6%_zzqvq|9H$ITF35hXF{XAbZl%B?+Kjg&XD+ zn-KV0gSft~6~@&tk;^nRsyaB!A4&Sgw!W&(vhxiJ1{@b2lb1X4Zj23MPF2lzjff8f zyo}24y5IoOPdqwvuKeC7<&hN#&OJYE{a@hsgnAJMzMzepSc(n_zDFb{ZEsozpQ0Mrl?EIK^V5 zG6zBP6GTY)E`&L#7H7`H#rl05B9PQ2$*`UA${cHU@FYvnvB-;?53jS{d)CrS`m3f4 zC|NuaV}ej0Wn08757Py=j8z#6aLlyCzO%q$=&-P!Oz?so@5~Xm@hy{F>I=zRLC8D_ z&t}-B>$!=_hSQi`>72qf;P&8a7sht3lU`Fuc+1J~a!xaGogw+1A`huqd|GLYO}{?4 z`}ikc@}YSgFLYG&oaERDhVrShD_gM*zi#)zFsjQW&)ZftZ=jI@ZY*+^+0Ry>pKPbm zQuxP2)L=;F{$spS+u664av$3-bqFPoKQC~WDy96#EJ9lk_gZJ9wB~mQO>Eswjw(v& zAh zxM#Gw5xGAgHCgKtwMP-8Y~Qng5>fuDVdJ*vcYJ=fH0sLsocQfZ7rM4_$s5QQK$GMj zhxT<7#}B+5Tehn8IUV0f=4Uqv^iStVVguob63BPW(DZU{4{tl*FchFFtNqEVJ)PL7 z8-OGVH)r{C6MptNC4Gp3B1DJO5R81F3(HIQn}h6Qdm-BLNGa1^MDh4w`26lGTGdcO z(hS@YFyCLF0J(0Z>y1l@dMHc|J#k8x;V7&ZvsC!>U{G|g472Ldtmn4(h`rZ0VTutladve>v+n8cJiV4so zCbVTxvM?mSg+v!S;wJ3GXbeXd3dOuImV-2)G{Y7q0?!v(8!a7+yE?Z5y(gn5FbUc| zFU5QFlR0>!|=GL`ljS-bGnnlF@n4ysMy>w!x#s z2^ZtNo|lg|1k%El&`pS@{!R(IzZJB4_Il`@w~7JQD|VMb(rlxoke(U#wgTbbW^9ZF z79qhBZwY_@hceY+=2r1|3CPEF`wB6Il$+HkTbH?&Tc3DQl4$vmFOUc5`f?`fExPa4 znUK`^i{AwRO`e)e0ugHi`+W+Ph2|Y~>R!5H{D~+&@0Y&xjHNcS+34G7&AsC-p z!|=(zQv%~tXV0Z-jUx55ZY6EJP>}p){!FXd)wQXpNORJz)yieX3uS)(f5_M|pezHD zt}o)Q)x08%C8WQREN%Vta&-M)_{Kv=c&wBh@7Rm8r1j1_0E{aJsxY#-xew{6vXAM8Xrz`@MHTUZu>UF)hC{}L<^38|64Y2~}nGOD~@Lu)&`huFm%Cd}4==t?z)d&U_NdxDM& zNNj{%luK>c#lGKUd$sY=gi|14qtp+-@WZpRuSW$8w2nODjLxHjjuIcKvq!r)5~7L0@DY@*lKwUTWRLVU8g| zABKGMwG57VwTsv)bz3#u`5pC3a^N-nJ%NxOpgh^U(8dp=S#~relei^1%DRCosjK!X zTILYlSy~B2?V)(%BGNW8J*Qz`?6FZz(NaAK{U-_Y6Z_r(2tZpAvyZR1jZ}d!`&IIRTZURu|#h{mq|JCg2Vy{M8P8Kq~M&xApwy4yh zQN%jyb1yjUa4dwgIi=a?Af~nRI`Ow)hWYRB0%Ct2af^{Z7GR%o^W-rxrRQx~hp(@k z_8q_dr_#G;ZLg1Y#9c^udrEjV{_(R($VKs~DQ(c+efxK($WN8Yy;2^z%rqI;TY>A^Oz|G?b zd=NB%Tkg2dq|YL0<)su`=cV6Mau}}UDP{QKkt_pdHL$PhRWcuPAqkF>rv3pLg&Kk3R#Ft zf=rdIZ*N{T?AumM#l&Hs_~O4Rznc=&6WC>~Iz%5D9_&zMNEa5|hGSa9>X+HoIvw5y zBVMKMBWgd@K2}J0H+i70=P)#EA!gs=u1A_NuL+LCcx=nGyR!k&-})YBlpx!adi#x{ zu@fVqW?NEEKr&-lhi7vqmGRdNiO<3~Jj}roCe(-%Yy{oW?S=PUXO!^o@0fKwAGtw~ ztoAyP-zVKvc3_(n%NX4)FYoFRkJ7NKl0@yvSyN|3TN9)6Erum6+St~fA2`%mu?f!OJr;?1XJ-3_KFtE@3RWogcDP?tfM5gpu^Uz0@Cz>qdi~hZnv?-ITwbWuM*+Nvbs|ayB+#Ms9*2FzW8O>#N z(C+6?AJ_=??dx`~!{!b9wl2#04$|z$6t%~2Soae#5B0!b^K`3RAiZL)p`Qu4ud&=~ zM$C4q^F$tlC6zK*Ed2&*s7gehxdID{Uo}^48E)aRh{1(l@Xz+&i@S#9^K=>(J%A6M zb?JZ5Q5(ujZ1Mq}+d9Yy-qIWX-&}Rqj|r-~t+Za=KO(wPCzy(&yA$@k_7$rvZZ*XU zuw@TzjIWGPntZ}F$-UlOfMzx&8()X_kWz1I?FCt*r;9h+E_@>+74AYuT z)aim&6kMY>$jZ|{B9mPq9LXE{uF}6J`F7(f8jcd7w8!!v`YIy4Y9FcR#os6 zHfZfIAF$9CM?eH&78>DVX{N|{eZi#9XoGj9zwK*MQDjv)kFD7c0LT5ygK+5}7qy+a znYeS`*rV-UIm_%hnnFpljoUqy4jYCYvm|lYr@?lR1#RMW#Xi(ox?G5E-5kCiuV}u) zg2-)hfKBJ>mGPl`03V2+!*yhUQbpguSalAl0<%JhAdL}i zAk&FW^^j`v%*48iz~RV-ZbP-HU{|d4__gkegO9E|$8CjP?3Qny3uj$>eYdqlE_p7+ zG9&A(SoTJFs{bTG(LLjPy%xA;Md7hk(>R-Qtj`AVwGM_ku3@6GT)Y!^Bq=Ca*ntXl zSpW-zPb3Yjt|_*Jd{vCelFg<*wRK(rX2ZWjqr@w&w0WW~9wzuPKM5+TsETl< z3s<>xjH;+_&||}%5;DJB)afI8$HTuX&2?YZatpn3Kg6P9qJe_I$f*L4jr^0*lo{54 zt#h{W4OZ#5SZhYQ8GL86N^XXGr!JxRZ7suaKUoA~q&2bjetQ z+W^Z_pt66_PSf(?y`_K%SzSMW|L#A&Km%ST$-BwEb+<66MgC~nSsPfRL9yZ(haTf( za#`c&-Gv{|ZQtj9MZZn0SdWiL($Jf@LPHm>tR0OuA?Lway=x&_Eb)o}*=h_{_-|u2J%%uyv;*GzbFcLGzx0kxIj}~Oy5Sh(24hxwu%|SsE zf`TJTbM`xxCs?IRggMlNPYzITUE!On-2^C}w3q+(^x^v!PkF=a-KSO2E^jO3{OsCp znV-M0enIno(9cJMxN8J6mUYDCn4qDUs_5PWoGUxolF(V$*PdXu!QM>(%f8*$34W@C zzA>bwT3Wt14&g~hS%%O0Jdsw;W)ufCk{+iYuIEZI`*&8B1-*Q8js>}&zEc}q_%?gc zs*4>Rk?--mffcUhv55P2ruC5Ew)wPrb-X$rg>QrUv?++8`JDUW4Nl6HP_paA3j+AcA&vIfSXUZ%smi})%!Z?x>VHp*yxy|LwvL{nF-BB`$#M22FX^9 z&7GX7DnYcv@Nw6V-wPw;({%zr8P)Z=HT0)4+E1CmS?Sas!+=9lyj@O7ReA)`4ig;U zG|-w}4G$}FG@2U;EFWK#af^3ipF?$N=sx!dvdo-KOVmnhO8fE#r3Y>CPqa>=KjpvFrPE7tD5?aw!ZFFW4xb? zYV4G>Tl`2|l&kavwvgnETU+%8hbcY3OsVt5r8_AL>x8=M?);aGPSM~CSa-+1u^0Y~ z*@hu}!f2NrI{Hh2%`V}@#Lvdn{!14K|2*3JEe%>MVLIw;8fyii4I%@BWPBgS;A>?F zU_;)V-<8Ts`}X7(Z1J3xPPTM+PiY5Pz zo2w$Q-@@zUudgZ{RG-F9Ul(1}p;9j=)diaCEBu?I6J%DL^H2B8mQK^j;1zICJwo1< zD2ff%kJSCfG&!NA<^IFXqVc3z@;?dH_-o=1?z=0}njPSE|33@hQ%km;+PIvIT*dtV zU7HE)c|DcyA-?^zqb3C4{CvFEFI+oZ-c`zu`p7w%|E;t8N&u*WslK1!zPBbZVNaj= zcGw+g9$bvvV9B(PxX;^Lhef*&`x>hS0Z5OXafk_1oy}*p=1KD!)Lq!o)&s7#%h}gf&1vu&vxUgbHf>X zpQ0fY3G7NAdkAw7LO{;8zg=i`V-op6$$u8NyzLFAU1=e(s#b`7g$j$h&(8$qqR|hx zb$I*}*S(DOY;@^I~6=!Xrq2XV?xa@u_? zPSrPAGO^11M)b|E{260@uO8ZHhnToJ8cvkZZI88c2lN1SX>=% zTul)*8C=-;_4@=Vb10j3W6xjda!rJyzfZzY^T}%Z5AG$9m*Rf=agWX);=;7W{S;$e zfz!nVF*QXFp?)VupoFEm|4TK^4WWD5%`+uI3nemtA{0LyD0q}xEux`Hgb-uJ8h zm}!KRM(_cTYshC&PCOPQ*Hdn*K^@r^l;Ua z^{U;D2(ksJ_le^<Vb~&REzA0M<$@S9(R5K5FH(yK}jpQ8U!MTRKnuwNIfWruwZmL>ce zn>%A0%1K_;DP&!^iW_Ey^k2gD8U@!ks1NSbs$aCWrIDAM;|g`|)2KT2B56KwNwIn#FM z1GV*L@R3#?dH(zWa$~g%k1fmR)ii=*c;#sj9CVI=0TS|7nF zd>nCD#`{;L z!qQ?25}nYrxsWK#owV2eP&r=Y%EZv;rB7O zzGAA@CWhBDL|NEHLK)p#{;9{|@4ubk`6tXcYtAIdIdhY@wk;zKecUGV|xJ1c! zA-E~{U-ZLpa6>=bUmsN!M8rK<*F6>`+%zUb=a;JxN|lgiOUas+A+<iv_oWK2-( z&G_A0bd?rjPAU26AOI)4_I%tGNq1~Mxa!&aQ&s>u*=xBM)?KOe=h;)MkjKXi6at!< z(()iN>B;y~1zKOYQ7TFlABNXGAjguwa66R^SZr8I-*sTintd9@ur>j^zEiu?W1bxplIyGR zSk^AD^W~P@e$_I-yV6ljx-@92wC#eVu^d!+03Ym`!b~(44yA?&<$&fMDtZD%kZOih zQqpzaj}s){o>fCxtnJpoRCpzkvWC%wm`ODqYT|3#NCK$xxg1 zvf-%XyLCvNfE&zZ3#4zN;&OAeav#=}vWyI*T|KU;9c1Tpk|-Zzlukaqq# zpYrRZ!V)Z25om+{fNf||$^Go>fSS-imKmn0)*qQ(Iaw5al>7_m6k^R&$`#38S+u#A zk~&tYXfbS zWcgB88ro?4W#PIn<9F`d_KeAx;^?JXrCzce*S0^v%FIN7?bhAS@8&$OwhG3|+o$HVUH)M}U&_xtUvByg1C zLT^;$RZsGQu`aok<6CVcpPARLR+6$>?mG(*RsC+Fa>8buyxgWk%&8Xmmy_}>pTG5t zMyoclYrmC_Dh4pag>QHX+57f2d5X_`z0CZOq!TlD0;Be|>2q0Qu$SapR&d%WdU#AdQ9B^ zk{+h~I7D;*{uj~bwrhQELCN#OQ1;HCRFZ_ODVHS5zS9-nME5f;$2h?qk^)9yE!_{1 z$}K@q;W5y@L=xO8>+(8!8m79NZ#2OQeY|k@gqy*A%U^vXD?iq|Q`VGD5%dF&oR!qE zT(l&39QpzTkqVY4p!L)1T5}Kj-x7d@-eT$TinBa|d(f0EHqm}~G|ER_2N(3&kQNH9 z_%m5hZ~HaDt1dpqY)g*UCKuwi(=IMtSruyqL2tnSQ|OTUW0Cuh%I#y~&YgW%;CD^# zx$PALm7L`c8zwfzbpKKbFo*W2f65gb;UGO%RMAj%kye1Trl{S}7uSQ=oU~4j%P#yj zm`!ZIKwFonkC03Vz^&C4+@J$ucKg`Y`aUq-3Qs6SLM#HMxj^L^gTkU4bo3HRKr7Uk zUkKHF^DMYq$It<=oi^bhvb5FS5AN8eH=UomGzqw{;L0qdP;U` zvGb2l>#j2l*Rb+PP0(7CVP(YO3HewX1pi8F2D6r1HsaeQ?bL%UXdT#eE0j%#?t%_+ zS}UNH{##fS82%++ zHh;;GC6ihMN|;%7m8DipFx}D%x|@upe&hn#v(+_Ex-%$g?B??WVo69VZTjz#|g zHRtS;uh%zns0s)BE-}qRIhwcUn4jNc4qhk;Ll1nRf2T6{DGje(E8zTSidU);zwMu* zz!(?_M%gt|*fuiu1lw516P!#Cp!iOhy7#~H zk4!}-a@e2IBcs&*)C|*~k%LP#sxKK#_>^l*2<*w*f0I^LTNt{c?wZk$VQidqiq|wj z1Fe|4C;IiZ>zlN(loeUT@?9m`Xe2Dn=^}OK+hdiJchh3^*GZmdNU`Ug4#WPCu$*kr z6ZLwTk4ml8flZ<8U=(}{Kcpo>%{6%QetpDVu1>CyP<2S%0ibFVv_yJT`6W4EQgwKiP$K5dgLlIBqtW=Z49P?Zbn_Bmpgd^$fjPj}tUDs10p+crcRj&c1 zmesMX-SuDAcw9D!^6&NdJ1Ogr=YRCMAUq|9-YT`LIMPD92$6*A)_SB#pX z*j3+H5b|(P`Fhc=N}RmgTzao=>Tii_dv=ACeE?_s-~_B*P3pex!DlgayS=!d$Gp}AuNt9h3sxbhQS7oR;;aO!@5DGYSDp%pf9O{A;S zkS{X@3ANscK#h5eHYntUeS!ygU~K09P>^EUgu0SWB2Go&7u<$kfr4GZC)Vp^5!w|u z7b#YTRlrnBX_0tmlcr&#`)TW5he`%_?Bw5DYat#aGCelnl^aDFq!)g#6*U z8*apaJzT(i*rA-tsrYSG@vI@MO052AUgBS|!gDuzT|a2wRew(JJSA;6ni&~fm{YpQ zH?yueRT_oQ{#=_XBmhAi=$uFDxe1(2RqF}4TeGCQ_j1a%Du2(l{;I#zn+CH*(Z9G4 zMY~At0)AdQ&}ioU*eAE{J3;q%xA+`ra2LYIr<6*m8&sH9JHDQQx!L#pov6yg!I;4K z$(~n=7n`RUeBD&0P|}Bdtxf1-otNR(z|*{yBuq$3MX+nVxsj$J-aBfCrr7ei;fjXk zZpkn9HtXr3qiceZw*S=5_f|=r*xA)pg*fP8`NPDBvpQQed!w*}KI8r0cvPy(j*WSe zW@kB1V#)qvuH3ED32h0l6L3N``(eEvjdFV#oxz}%8u^cLcHL_`(8wDV2}bP7BxsWl zy(1FK*VpR_iOaN~g&QaGGI9v#w%c8={ytp`Uo*RCD4I`xCnqvX&o3~zy3*x_TZLks zanmi5j4bK8i{E_v{<`j@)_-tcu)fb9n|61x z4+rTqnf8bX>6q#IN_>cKY1zTuuR^vEv@$AdI{0k|L$jF>+O(On@kPiIp)4+{N(j8uob7NzdyrnfM z>Ud4O&GN7(cy!mc4p!K3nZD(A7DN63Tgxj15l;`dFmWrfdGjK@!~XfF;%hqg3dPKu zm$7Q_#16#MXf*4R?wC8^o!*uS|G;iNh6T<&kw(4T!t&;$o&w--Xn%(za&Wy8?viZUC6mek6q+jP8 zn0CWzh5!eDozblXoRiM^^U_3!67jkxFXD)5F7L$6{UfPKY7p*;!Q+B%Q|)y+FXdL{ zCe`b|kpOH9&VRA+Q?iR0wn|)?w96_+kKV`AgP$_Jo6E=bgf%g+kYy+4^}OXw;$9n3 zk`Cz#bSVeCwURIkyQU}rTJ?_d)h*K5skbN3j~#v=mG{n(mD7jlq?sm?A$=VXV-W3s z_jFm;x-&Jrgc<%s=eT0tQ$adyMZ3$D-K$4a+PAlu^;WOXk6h#9iMa@23B|pz5AJia z)JsMo_l&u6@{ykPPA#p9pLJwV5L@1rUZdlzBJofPfTMU)P;99HUTwA zjT(2>lUh*LlJOl;VQ=K=Q2&*XnTUPw7eBXfX?-h6a2Hct^to=o>EaKRt335zTtK?c z&yme4tF+SJU%FU4pY1G5zm$Fn@B`1LWq-T9_Z7t}5RMI;+gH@M=P5jLg{Ig`37SeP zl346A$I)UQX5U;>$TpvKHpLZ^8e&>1khj08UJ-w(kDn~w5w+7D-q;ElI3ILdyY`N5 z@`?f-+VqI%QTci= zcjfi<#51&yLOx24{~Q@uk?`(MQM$L6x>ZXR=5@#&1QO2q*NH`EG*X{WQ{nn~9f#P% zT`UV8ar{i=?~E8hUqx;3pknd-Z?)pz#S0fyb_}|o9+v1Z74vvcO{>fn)VFdl@XAwu z?Xmi754YJLL_4m&Eg;38t!`w<%!IhE0Fmu(4T1T4eRlX?`{POb;|7MngT6a}ud0`H zD;NAlYJu;pwLbU7cjgehu8mgd{ErBDq^bD)OKlLg?G-T5sS2r1Fl79oI zKs8EK#iWxa+^6@a<0}Uv27of}qiP4fbfv9_mC@l-`GHyB+Sb(ljbMT@bEO$s9U$L) zlOuJqw=(Pt^4swjH}lr=A~n`JAH;Xm8mj&>AN&&EqldfzvW^706-8=9Uc~Yq13tTd zb$(@KtDG94c#Qkd&o0qe_o9seJ*NT-Zt(BNcGD_B=#VvMTcyt%DbGM8q^qDtbX2N~ zPS+y}x4X}JE)ndpcM0Z!%5R+1e^W9s9I)I}&=dS~DhRKb`O(Vkp4|TkPi$SPMjfhj z4YlW=e;J!}9V#iGR{ixbnI&pVh;E#F_1K}IM4fH574dhV_3q_*BMvrLXLPF^|2O*E zj=mtWs#Zt#&;64Du8hz=4Vv?*b){w;$=vP6$zD*z z5$s};dw4}0p|uJ53#MIv?kztK0|3XZe^8LVQ7ZGbX#j{bV4om_5q3=FzQu+A6N`H0 zJ0Au%(Z4zk(4J0eu2x*AX6hO0JKJ~(c~K4MUV|=kiN0Xdp-||JHE%r`0!;ZPtrq?G zsxVAVWt|{FT4gZ65&BTGd?l=-qVCUWS+|P17-ox~SPTQ3N3To!b1sQdD3uBq!-OxF zgn4*Z@2Iw`i5+cXKN+Pz(ZWW+PC&cEl1_J5tHOSq zVh+RA>v_4>pyzMzd{wgGkId<;E2<;|YIB8L^=Bf}(eEsOws!@Nmo)TOf0Z`C?>>L* z&!szymuvLN5*K1ijThfcovwmCX*X*ux6O+yKL*PSOjhRDBpUC_mmr}IY-0tvG#WLWW3sN5c133ILR#eCr2JL{ zP}^U19heB_`!-bsA!+SPVo5}-A+{tUyqWj?ynjNT=gED} zea`j0F4Oa|1Co=Ie>gB!n`hh9C1Cnpwz6N{i4y26|3-lcEvT?W9v}u!y%&hYz>NHwA2h=h@oN;Ps-5#%}mpIp}pO&@;^Xy^|?8v&^ zoRP}_7r{cFZz$)+p6wXavQo`;b8lxj&c<)sVC|-%@LH<2p{HDJ*fEXot@V{!LES)P ziO%F+GR1s9?NGWX2}r8Xsw8R19~x;vEeF1f=l2uu>VKSEZ|;|5`mzU&}>q7^V(FAMJN+9yPjH|l`WdCl){Z=z=vZTj0} zqznS5zG?ODN@eW)1^DX00zF{_Zgq$6=I9wND8hnOSdXGy?3C%!FLQM{hO|mW~KCM@ckdps6yg)IcFFgcsa&clG^&a$7Mzqg?4Rd%- zpddLo)j0u=5Lb-aj3V9or2za>JRuMg*MO1rd`_wYjZE3ZpFzb zpgO(7?gOXpiD(AA&}jxtQ1o}am7qgv3-x8FPdf@7;hY=Z=Z*5mAshPY%@oV;)`QUV zM3{S%=a=`G1(Z!R)ypFKU0q_+yCQ-))@m8}T+z;v;v?AX@$>DI{+Xw%dgavf-*W9$ z7z9FffOK~~ZXxpBT6Gxc1(@~Ma~Q%F$Qh%2?wlzvU##q=Djn9DB(=z+>v={x#cT>TAP|6u(|{6-|=;@28vO$*qX+NYLdz&qp-!s)qam z$bO@XHA}X8vU2zkW5tV_?jMKMx4)$)es6z(Rv9(544c{X-w+PT0&JH`dj8w&(6v@#yP~n?eGON__)jB1 zmw8`8^-hBkSpa$D>~Jn7HcG)YPd5Dbk^UfC&xJPtZA2-yJzru$GB6jpS23(PBm68v zaw?p{y-u?5N^gPt6h&c3w9=iU?fXreOJ$U{J>O62LdG7Q{^GVFJX3lf*k}NNPIQ9$oxZ*{?HU(_w7tDj z^9nTSSW zfJ%0gtOAk_Kn(wU$Zo!Jdheal1Q6|&H*xrA@%GEWWF8Z63S*U9 zN3ZYvS;`l+j+<=m|0vj5?E#6cdExsARW$IN_(d}>_``yY$>XWIcQw%k_PaP!!(0DpvC>?}OB?U4eE=NRQd&F+3!AKmyh->+)b*VyMR~T`(^= zz3VoeEhiiPH>|a5g)ZHC;bg0MfiWMsQLTA5kRx)&$wAd?D_2k|C675ONhR0U_vt6LSe|E$(c!tHPUWJ_abn}-YpI0-)nV|<3M?w&xQr?Y@9LOI|KPR|z#8z_ya@Gh5_u?999^dsWaGPl3poNz5Z z`VyLAO(*0VbV!7N=W03zmKY!P($lVL|Bw4m?o-6xSyHKlHULLP@4{AkRi_ttjBtGW zb2q+`mM}Jz?%VSG`TMbGLnpCaxVG)F1D}TUhVB-x^DfPmW+z(9y86?!7bd_Y>Z2X+cCiQGC)Oi4ibfF4*BG`( zvDNW+FQEL5y2kSjrpP+k^c)vwy~NEjX=#OploBCAo%RKNpr&4@((jY+l~HrmT%1Hfn9AY8Pq@1a>Mo6G!yu%cLdh# z16np2rp35=-q1-h&hwbD?M|^}?-+9bB=yTu*+QN?k!C7JamwSBwT6vpQ*eL3zGXL4s{3x;@${|O-)%gBNDly2=v~M{j_#7EmBoftqk6SjE+E>ZjVPQ_Id(!Lgb3M-^Gb(@tJYvuHDD z*J!sMmUYYaile8^`@xqRMB8^s#y{YWy z0=T;61@bU>-OzIzZ+^4cJy^%#B=3!d@zx?LBbI}SRXnY6hgG3&`F}G?{;m1a)D_%4 z55zpggQPzE0kIA*?n--Nu(IaHF?*e-4{|l7hpKyyWzS9YoKsf>FXB5MNfx#~En5ZAOv8gMo3$WNs2zl8|hFyhep0?@Lj zFKcNtyO^$(Gl0m25`5j_ceRc?>921oc3Kd>BAkWi{r_8Q15*;a_YAtnqM6BVAm@K| z_MU?o{<+fQP0-+#7s7Lz2o;g;6@$NDxLQcKJm@wvU6KRSGp&-Qf+XcO&C};g-*@-` z8?80D7UgC{SsdYdSDYYEV3Q*v~$6c>BL*)ktnbW$BUXxwx$XTwn(Bbyk+a| z?e1MhBV(v~j%Sl?f78q#6#yi$d)%kYe^7|c{PK@_wCy*LfTTCf-5xzQ(3$ftupo)G zQ}Bkx{D1;u|JwEZUHT0raoaFj7KBYb%!sg{+{ud)gdDl~rm`zN{0 zGK>vq#CW3FmiEb}-B&X@sOs*{pmj{W<<)#+33Cq0dDv+Vx*!z^Rm2!dkO!tQD#O_7Erflj^t!_#{@l;KF)0LS{Vvm z3cgS)$X_JYPnX_Fd7e^+ys+lEZ#mrF@}aXCcUJ%BiD{vpCNUk?>ZY(GB#AZ-e$gYP z+|qvADCs9Vc2DBHg-L{E$&QA+Ru?N=_irq{HB4u{SI?e4#CygfHyg1x^$;ABb|fx) zZg#ZQ)hL`>gr<^u7Ii~2tO;{GXhz7KxnhRY!dLY!wnsQW;InRW8dZO>x@$j2-&L>k ztt%3hC1f>Zwzb%sQ4*XwjP1e1hJP`D?zO0bIu?#5o7-ZKaj_~J=Fg3B3Ee~YU@5UE z<(ea>$6JS`LncGnn2$5KBOFggS#8Qtg|^{jKvv%F zS6U6H+#lMscp0;3d&o9@TvPKc=HQ~;-&VLmm)QT|{=`-q@strmNwOG^mKR-NWpk*B zINdmUPYM720{SE9k3n8$-T9zc=tpp*eR+6Mj?JxZ1b79JzZfYaz6iM&5 z!u5P;m1*6Ym*>wVc-Nh>dv4f>ndtMCY>?ecF~8(_4$)hdJD6Mm-W!m5D_#1vlR>~S zd#_i-nzScr$G$3?hkLhqfV2#DA!)CHDE=G^^}=>>*#w2;-97f|XA2_wZ#VAjR9kH< zZ{yxAa9_rile-vNhdM#9vAokvMsVgPnJ;ss222k5S*;CLE~&oG?(AENq+j882-8I> z%4n#^$BXHd4>d0OgDF`B$Z2SyLO0@5FT4ZyL=BuCE)aEu<67WMNBtXP&M5f(zvd(A z(!P2p+|YL84gIzE;HcY$w(sTlaH^?o_ic}^|3kZPy@;^Fn(H@v9@<6aU=!s@;eoil zErE72bRL3I+o3g$M0}_Rc}pIjy^Tw3xT~{X2f2NE&rb$yUbW}v8RLl)JJqnb#JMyJQi>oyF!>{D%WX-3sW{yf{KJMCI5KEQlsxBmZmR6LEUuC4+~ni1le^- ziiFBr=~9OD3gaZoyp#2_J8tNT9V*k(<*pwg71wM$`@C(vox3iFI~uZh&HqRT%*(3- z{`cV@SA)pL_+Y$%RGw$l$j(9vF%)4@NG%GaDJ^K^>V4Vk9GqC8lEzI2-%msCXvZ2+ z5if)=Z0GyxxtvwqnPr8P{R+WKPuk<0>xwbQ)2Y&O`zl`j*%}q%)J-(yJ{>taaqK1H zdXS;!#L<*}z#-VUU2}5Akp*!2cLVu*T)Fmj&-|O%W7%gjKFUYgTkZ_B?VQ+_pgi50 zpS-!*S=pe4woUyp`egWsIoJwS`Mg?eIt1oUKF$$v+5?xju>$$5H%2zbU2?1CI}%)= zu1oosfMAO-W_)0NJ?6u(bquFO9O3aFL?*7)UN+c*F##6b#7|gP_9Hlz!vLEde zPOM0u#{q(q7m~g~w{cJUr&{D?GtwW#{DzZFYk~Oa_CE`=4M$5YdR}r>Ul3I9)HBZu5M2n_D}( z4`mm9oJX(Q5J1%uDDTT#2g7$evy4~D820kH3#TWn_Wb<(%f_&mkSb@)e90X%9oV^y zjnP7{@?)%~Lo~Bf^-A3R+d9lYh3Lvqys3{NkQbRBF40->$)~ZSY z*II{|vX1knh6Y_urHhYp`W7h_R-2^V7LjIMMz0NAeo6{HMlPTLb_EAHPL!B(%tcU&gQFNk7*@4)wP_PIM9z zXDf1A3rhkyO2Xzigi)?(=wLP=(mi#yVV>s;rIlfO*QVdrJR>@fH`G!Vx1n_3tau`p zlHN({PU#YZzY5HXXc^ZTBt3KgBv>T<5fhve_vn073KArDMIoVga6qr`s)~Q ztnu9&eZTdMtcscU^P^1t@B;z3w(%ZD_Zn!o3%IfJSHL#~d10d%q)nH%J%;4wxwp3=}xt2*AM#?@yKJPglZ4d12C954$QeTLV{?2s|JSR1V zq_}86)s23dnTy9@b6=;bi*n5M)i9#U8#ak?U3v`v+qKu{9xbm$S5D722PkySWulLt z@Sj9{_x3KvDiougx4|E&w_dP9cu9paukqI@dZqn_eK@@i(8|X2d(Ewh`JRgh=6G*e zLx1;SN1HsyI=I0rOep)AOAQ@_`0aMOFfK}NPw_|m-eS8uw^rPB)I+V>vd*-^e(J2cb@}MzWry4EjI9m+rxJb; z#@-pTGHh0zlCh997}X7#u?};03R`k+`lQ;)tpEwz8hNH~k3k8-{cJm^+r7C^(!d~I z4=0`67RK7EM;2!c*Ezc-R|3uY(cq&Z@cPLy@w9{6t6&7PCcL(zrV?6xB0`KgujqHP zKi5v0gsh8fmvLt%v#h@PzOki_2d%qi8{)6mq!=n5C~jTF+iZ!6r^|Hu5z-E{Q>eaB zCcZSM0{lyQn0iJyquCieWOOZXVO%I!0x!qa7pA>E9kT|L|666Qvu}loI;r+6MdVY5 z_~h?_FCXX6tGX;*yRxQE>P(Lyu!~~X;7yn*pGd6Ih?G%mBowkEk*im<%OwA?HK@z85s)>f7lKU z2fMp8Th8p+C*YzJfpsHu2?%C^MfD~!(^o_hm%8^b@5&hf|2YA%I6UR|A@w=Vm!Yi^ z&98V<{lVeuh7o@Cl`3n%EZ=(3<^-A13DlQMu1z+5|EbBh^kPqrm+GpR729~W2+s4b zF<2Vog2?AaQCP?j6THcCd}5 zuOFMRwgAqG%^jFOH-!61ENE$w_*$~uo@?4u>Z8!?T+)rgAN;N^y8J2 zo!`7F58^jERAM<53{7fz!yt}^GdisM4}b1dx0?si-`DQ~dQxUI6OVrA_LHK%opPlT z^@-jofCaIWH2X#@D?QlaG_L-8f%rn(BySh(hMM|V9Xe5ihCNvhsO7da^2U**ZcCAQqni`t8pj-S&M1iF_A@QfIVge?6%&=53-Dx3b2_ zw(u)ItNoRfntHO6e&2rNgG7Lo$Q9SQe)?UbPAI#!*?WKp^VqL^J9>Sod?{YCL6Dvv z|F3P`MOx$elXB_LiLmgG#HAZlMhjAXxtiKUTF-#IV#>PNr<6*Nlx&U0zR5k$ z#~<;_ow2KB+;I`{_QHr|%W%ecK)AlEcWaX@TFT!qOd!gD{Kj{?FR*|~ieO`tV94l0 z>BuApe)QX$uXg*s%#V*#mg)wisUd^ma+`H+QNv6NfD3tkql@Qw>eFZ&wOHABt}~D= zyi~6`)u-JrCp`)eVCu!pYhrtI6cnNlLCpxNtoHm|kxr9Gg{EiI3rF~Fdt@rzNC`j1se4c!2gA~D32nZ9pOaoClppN{*ZYae z<}2||K{1dz2wN{DL=iW^cq^xVU2h8Lo_^;1VTFTF(<3Hiw|qpt*TE{zl004?ltL ze%V3L_4cbH;-!+m=AY*(+s$vx$DBSZ9N!FNprcam5ZK=UO>dT~t!B6{>bdUT8L@8M zr!Gfthr6_gl|q(l%vtqF&**lQ(?^`Kse<;Q^xl#x|Mj}^rDCeTA}{}XL+o!i0IBRF zp(ltWR{tBR3ApZwVGMtLz7cci9orNXF}JL&m)cX8Gu~hHOX{UArUsi#%R+0G#&@E4_a9*TIcQA)zDD`8C1W0dv`{ zUV=@Y!2r6w@8y8#?3Dich#w#y@9kEoSQXL1dkNqUUeY+^Yn=&I_>@w_$Wu z?-)+)4T2IdQ@9>575N4}_H$t3I_g(GXEG`mj|s8D(Sk1&LJdSKp|ZVR2=$m2ukSjp zML*-hR8E@2!{NPVQl258Kdz)#GWcSily^*LcnZ;*TA^p`Etz4Q-Ja?3@ZLI)uYBFm zpsX){PN6=(_-B$s=_8Gp1(M-vLG0F+gBA35H7M^9_X%d-h}k4)9bgPrc|OKC*)iZ7 z$rpc0S0z>K`z&Z8eVT!`S=^4+U&Ghs188b)YfE=c$#Zg894wz}U_$$k1gXj`inP#2 zLr^~YqiCpLdeH~7!mehgnd_)lmrC4=S=Qy>iUB)nvO)d?7@WQTes6emS?!p8n zt&-wFs__5(W$wKuOwod(TvfcG*&I_z=HL|6Oo$TT)(<1X@87@D_|4=y+r5Dl zg}SkuRH!{gIXsM@T}|A*7CJOSkiz4Y9+W2D(%HVo};MAvp6I<9rw zUf7kMD}CC#WPfDI%P!g3yH78qRJLfV6h87_TznS0lIz{JaLQXyw|ggQt+RB?H*yMb z>?|haFqa7#$qq$qQei1qYlDA3V(=$*v1>9L(BJ`)kY;ODdJBY?-Pbr&P+y|Vk=;wxl@+)WcMm;w5vmwp(|3dwm9WngysB{2a;ih`w+ogZ-fZ6)5vt@ zoye4m=VzocLQEdLX*M&otISx_6cXt6*zDJ2eyhJkP7ZWY6=9{D(i#lL3rHuUIWvX- zML$;&|JM&wvS=eJ;j23mDMQ}BK=8kIAbk(B1MXw5&nuo(Piyl)NIiAV4Vy!W9*edI zP>!CdtMQrGuseiXoh^=!Niz$~X|^t8?o%CN^D4vrTX}VQn{kZ*6fWgr8fRBqx#Wof`H z_=PflS{?Uq1=Bzli~4#{YI{4pjC1cd!njr69wmz|MF^;M9wqA?Zkyh%7?k@nB)df2(96Djo+VJm4!O;~^L5 z?=~aU`L0pgvMAQpT(jVx87fOIlSs0a9zAtKvbHTI6B7N%9MrcToNPUv9bM5ip-aKM z6t0>|^Z*j@jJSDfl%D0UpOkBjsY($SGNp@CdA{GzTYr?W-tPS&>QZxKpld|cQz1%d zHV`-9?5yK4tX9B8xceFMkBJ||T>geAY8)nL^oKDDD0RgK0-&g_?=IbSn~n~0*zKq6JA5Fn*(lkKPik+1#mHj-nxvRTk8)B4Lk0a<(oLq6gM znQ<26ahcoaxH2qnBD{w$C*?$1qBLq}JSsV_gawd49{Cf9-yj0iD-^8~6RU9*scj%FQw1?Wlhu_K{4}jJ) z&hJm#3|%a*PfxWvLS85qw~9%xhlrPgtgeXAWNaVN1@J8yNdTkVbQU;<@#u9DLS;2! zVJ*4tcjuH6n0B}~Vky?J9pp7%%-pT+-#I$s=|{s;&?iebe5LTmnk66(ub zJzH2}FM3kaTpMZ^cnCflPrG9})b(X-w&P9DD*JxLRz0}t@se!hDE zWiNe~H!@#qsOqaZDBsNlhx#KA8_;v{+%)O!A7#Eep3*$;5W-F`;f~%mzJIoUh9Tp$ zLAs6-AW!<#8a+(^41sb!o^}{b0@gP)Na)S6sNZoVv@hxieG}CxR0;g}4nVolg?E_W z61?k6M7Fd`C?G9+^h}o%(PwHBaObWq)b73)wm=;IWF;Bp(Al|4v9;*BIYqT)&*`>l zVLb0PSfIn4n&+ti$$98ig3s4Xu7lw%tDm24>-Nc+(iHRXewc;HN!$MzO55l@g{pOe zK}m|+!pX^>KLcPw9DLv}d+%n(8IEpEA-nIZU1fdRSu%FndIW}gyS)7LHy-~J31o@K zGR0|<0e(nAD0FtONCowWU#zr(Ho{`tKdAGQ8O)-M0Bf~0;7#)UYH6t&dy^BgbXy1K z>aZc#49bYk8hpWvuM?fzgoJpuDktEIs*b(v3eC>P4d)?W8yOk2Yb4FTNjiwMY%|Ub zgUTYOiQwJ8NGT!uE8DQBs7+)7$2|j3(BsUf_(x=1>PBiD#k)M{IJg<(qT5^yZUV5sYZb9HYGhOK}xhZ#i)U4Q`(9I$E!!**dv$4o3oG8am94vAb}!nQs%DJwv6)<+4~2 z?O5c?z4{P}Z9Xgr;- z3rLEmw2d^-h7jQE+t!!$94@SAI?(?VJvq6uH!t>K%Jz;erb|AQ}VU7oF0OFuOHVqLkAZxP*B&3CV4{>edJvhG4v)2?IvdgSy5p^%iTr9V)FBRC&2 z(EHkX$avH93TrvGGjl(fgqnx!AY^2u+TM0GAI8S#DwK&e!}S&(3Uy@tqx`}W^b!*F z(L&t_7h$lX`jy^(ENU8B9OPhEsSIvz96C-N>^Fs}$9y8895`W?qv0M;y);Lv*UKXE z9T#=@SA(%Ux&*L24|?&nMC=*jL*(18WZ384XQQ&kzG1YS~~%awN4P>zGjB@Ahe)g{f=88$7#&t6>z#C#mP zzoLDgqc&@MJVQf2nW46Ji9#ZeHBD;_nuoMc-?}|0%cxc9=)bmvuH z37oo$`7w$7XuZN5*5)Tgw(z zOk#xQp?ggwF=2Lq`Occpbi_7tmlePc?^a2eqfDxN3U|^&kgl_qs+4T1zsAgXP~UIU z@Ek6?zW8!PXU3&M1)$ic5??!`sV+eeE=)Pl7eVFe2Fe~?9&61!Gs<)BHgn)y z@2mp)B;)pj`^$~o)Ko_MRo67E`sWBO+PrIGBczKzHFs`jM$L1+XwA#TEPb!fnG5&< zaq(Gf6xUT!6>*^)v@Uu^N$-%@gnMbw|I{|#ZvLd`ivGG?;C9$T^j3bQoxZ55Zko0Riz<4pCc8*fqlZ7sIF*SbRNt^$6d;wrdyx;1#u1Vn9-6K3TIIj9N3E>>XPh}0iWTS|bOjHh;-u`Lk*D_dKz_uVXsy4&m`jUvWjU@F zOwh*v?1t4(0E6mqNj?j)hG_aWv@e!V1q})R!u|^wJdl)4+RVzOpA-9h10D zIZFi+2jQV9$eU#P&8$J|t^JN~dtXy@8jT~?Fj+f)^XozKefo#0$N**V(_Oh+fn86B z`QK>PetvMCfquW~wGA>K6nNoXJ@i(9hKc`i@Pg>q+rPWhARTc!y zBj)$j!0-7^ZIPNT&ZVdp;;p&-W)2mTr>0VF@wa4u~1ka{+i&vzcl5Z^DL?orzqqjJ{0s@WP# z>hz=rCpBZY*S*EBy!Uh8fow*sG_TWf`tdEMNE8 z*?;UFFmN|u9rxcT(=A6^wa!Twt(K38w~c6db3{MS&2>oUk~O%v-&x1%l+iq z)NEB(d7~lgUJX^*ig|4Um+2d}uMk?<$ShvD?>awK4GO(5-jt2r%=I=C7H_{ZAQrn) zA~ess`fNg9USCBsOP4l+AcfDj{7MA(C%HP;T?Zp?+B_ToLp)Z9`%h%|YlDo#n9Ht5 zw}*TM3}EH-u<*6fKHy-7ea$XOQ6!kGMpTslzM&xG&i>cL;J3f=CNko|N{FlPmVYw{ z`xu}0#BJbNP024-(zmZzKw0WS3j4$lh{(Clzgr8*w#v#UsfDO>CyVh}wRbUUVq zx2yBFsEM^-_Hrb*n;d7D^NCN(J*QmvOchX@=n-z^Gl8OuTx;IAb!g$qei>f)BB^>D zu5~g(`BMY6zch^(&KH-BQj%ZurmV9AEPKN#>#RtJCp9WRh{teYeVsefC`5E#$VPkc z*{}K5;~f8k16DxjDa*DSDBWa)NgrAQG@46Gbf`QXnF?j_0ci<}q0*Y(XMW4tvVAFL zU`0APQ>&TPxc4052C3l;PWiir8D;gwU+Io`nRaDzLrKo54r|T#!iFIF=>#$2);Wil3aMTqESpUB^FKkBGk>#0d*=sl@j`qb(QHQ$8j>~vZ412KQy=4Uaw zTKz+|)-m^+k0s(JGL>Ps@>z_8>sBJ$0Y`rDTlr(=E{`zF*%mdcLE4GufX3IGYj6t@ z%HP7m8Jo|-nY$v--L;q4b=ShIt_cS2q(Nq$jqa^q3_l%`2Q-?7rq)0>YH@w=k}O}N zoC#q)0XXmX?|Vo8z+Swt#|KB`+~bTNLgBd>fet<*hA9CU^aU$+wD@eLJ($i8aZ~s1 z@H5+bdK=yMm_cwDa}QVRyXymQ4^hKyqDoX4*TH@>T~c;|jY@_(wELVsaktHrmB5oy zEV%togp) ztwcp;!mM6jtPLVU1&DrOr;#uV(hlfnXdZmVtByJtuG%_o=8TIEVRm&23J>Wla*$jH=Ov%f$!{H1D6tjWH+pW zLxrky38#~vU&)XIaLml@{OzJ{!ky;ZV%npa>tg8Fm<)HTA7=FGddsk93B?$__bLim z!yD8msTrn*;BvaWF2#stDjU_2ya9$uDJZ0}|Gj)VPwC#(J=wCH8JGQ}6qQ$;*K-T? z*81;;;Hu;HY_g~I8$DqZ$yUbmRqdpBLEvF%2Zmf`D<=GycGU`NmL;<=I@R(mspy&b z_NCHiaI$^Wl_?n88|7Go!b6$&D^$n-8-_L(BOMPFBPpC^N33)4(~Ji|u~OvWjCcEg zyI9pGIGrHVm2hzZ3)Y8O4GLHaZb#BXJ3R)hjE2e+;2{5)|8Tzlwh7Ds=BXV<{C0aj z>`^~aLWtw8rS=LlM?!4P&LpF8f_Dggh7aCTIeQSPx>wHo#?Jqv2i&p(t{KNj--}h4 z@AwrQmCX!Ccbzk+eLVN-r@Q|$3-%8V-Y{%Q)BByeHCdqGdDk*au5+1=c?EAkIC|As zCeUS(@r%w(aIQYK%YtsSYBg)Sk$f-MwYO|SymIk{aXao&lwm^1qO&@9O3yY7gUaeE z&A4c^wTdmQN4luHnY%v$E9qr^1!-VLrnu087Gry$-9*=WpsG`~^*G_}#e(nWB9*5f zt!Gu~Lmq3uT_OiH+JkV4Wh=dy8?_}tAl`cyy-M^G(`SI@NBw09cQKrX?XQnnhm{Ys zWtvF1R<%==PIayD8oo6Hg!)Qw&}hOMX7%D`pzXbr*{Lquc`kNt(SMlZ5v5@Z_okjr z7SZR((eSUo%(7WFwwHv=9in1GRZxf@Sj~YUWfZ0FMQB4Y1+)}wcfjS(W9|zP`J;BQ zyLhcdU#N?kGO?-*)qVKZMWR_zzQZSK@*MbzQ;tes)&b7NjtgRBk~&5pI|S<)>TAJ* z;agHh^?aK{il}X9U$C0r>|*MJ$4%KG0Cx~ZLzX3Odoo@UH@ETh<=4{s{Tbm4c^mOt zs(@oXlNnK>q3 zcQZ%Jk$IWRMJ|Yk#5|U0lcN8KwCN)vqC6HZRcyx?k53z!Th>87aVx$^Xn%Ej!>HA5 z(Z2Lz^71F8LPsZTRPKok^$=L8W^E`tq+xOVU60sbk%7fno4?^8DD(ep>U!a)iz=-B zA*x;SB9x$Wt^yNt=uk022Kr{lGMJ?^!0Us zG^fhukX1AsQt;mrh7|`mUc5thEd0D1$$V2uZrnnL@da(7ZzUF6?u&>&rFf|axS=f! zNSbTWU(B!7?zu;fcmxeMZx35NZAt&C%J*_t+vi0H@s9fh$+^ksP+h8k7D2tWjnMz6 z4Dnq+fKMDQ;Dx}2b-Bb>PW(d7wY6<2wVrSi3(ScLme#I|O<}MRD&45N)8$D#zD_$Bxn0QgGQ;TNQITk8zh}G)|aB zG*^{fG5CJW`(|Fw(?I7SR-|bGj+l$aY2wKa>9|yH)q)|ePv}yUi!(fKv z(;FL?sX~}l{9nk5_D=Y>Xx2fvFzy3?964@P{;E7IlWDYGBO>&FG2gk_S*38*;Njiu z*186XYhZon_DQhtwuHKO4fW#&(CSSIGR<#YVJ+V}r<|0$2r?nu<4kxdXU|@Dv>-~H^Uyr9R zhBM^?d0-j7$ZMFl0N$!ci0;e3LdkO^leBh8Pc#d4D*`fCk^Q_4WOGA^KIZSLBL(0` z=j&s1981`$7en%*OzSv@Fl}aqD&L%48Q~QXvf}C*m2gAh;&8`(5VE>8G+69HLPXU? zZzX7QHf^w#@`ITlY4^^Fi=0D-|AqZ%cY#l&pvJny7p1*L3clKLg2XItFXd1J_Y6sJ z%-D&=d@V^i>7Al~2n>y%Cwl%QM9WX~Jjhyw9zD&yUAFnEA+F8nyy>3sz?8yHUGtli z<%%NE>DDESUUIO*Ohh~VP2g8;@Z=%K%?Bln+gF;R*B6F)&N$I6;eWV37En3?jA&T* zZ*al?@UDduJpYPwMtoTaZ_Pe=Sb6(MJo81yEqU5UXOH``w{09n0$18{l%-nQ@k++% z7B!=v)M6)EtD_uaM(>4GSJ!!QbdZI!Wd;%JwC6zEVG+>$XNYw@u2bl`7~=C=ce2dS z$YiYsuPI8||A_NyJqs&FCIe-lq4H}LcObuHp>(b3i{zAU88N9nNAWFDE91C#=Isub zbD@uiLlsh-l}&<1dTjM%xIoW_#ENRzsHf0vOQ?%uO($;KJj|ZoeQVRX@>SpFS-f?Dh5I`2G>T_j)&~%T4^ByM z#Mt?`k|Rngww1g+4I8Y(irKNg*klh)2y)d=2m_K2m8}lzrOj9Tx;_fKb0l25FU(QO zu4->aFUc*jSQ3L{zMs4tPpdDxTde-5QdAUFh8Tz@)11P_6N*%gcbyy4ek8_g$B&h;C>OC zTnNdr?rk&f*X*}ceBPF-x z5ANQ(>(LI|qHDIM-HY0E34Snqu?}hy!u#0y`Xnk?IMsm?rzje;FK6$irH5J-7LWV+ zkFLxiVy|j4YtBl;7PN0KWf|jzuAKvez2bmH*J$en>+lP`^Jh2xIwg$D>`^wu%OO72 z_#YMyT&>b@X?sE0@`rybd3D_4A&IS7WSv^Y@e8bbvlHi%{bBnSN+(WG|I|5X2a#xy>9x^WL~;qL3Zp3ft5MtUg_YFoO#mC7)_ zo_1!~xInqR?r;Vn<2=HG3|VhUc~8gYB=lvp!${3L7S*YjG{#p zttiKMI$*pT6)M#4y%HrYHQOtP6DK|HzzpyU;A(mIBe#nd3pPJfflcC}mjw?~C$aig z*+Z4M4Y$Vrd|KJP>3P$u&ES~?wDBa4Jy$RD)mvu7WAH&YFk&q+^QYM3XQbNGqKF#H z8=5n+@D=f(YF&(LS(ry@t^%rdTo_@Y3L0GX?T(;1TGm@84LrLamPa@a6MuB)+Y#>t z-DfmqpZvK-EsZe%xSeuad#Mozdr%@aQIOoyl4@j-kz^P9>09iRPVA^0)^rqnnP1Yf$t-AN| z#)^8JcjJ2Jh3>E@#n%6THt2!Co|@jTlKdk=S98Wq$>4KKu_-B_<+pM6E^T>ucNes@ zIyyfBrH%AF$jJB@bzGd#=hU*)&6!*L*$}cgKmWa#*1x28JAUBo=_6j&M+;q0mumcI z8HJ5yO#1dRFa9D}z0F+NbBVKSCL$Ob+}2yggSW0`jzx?Ptq*OvS8JKx$EF6`8b?^b zo|M8X-dwn;-%ppQP+GMEx_GtkFVMOoL~Q!jg5HZZeS_fjmy8F~Pnh1{EP=r@p6*8X z?4iJwHhrU?t_oNiUWU&!K^BpmE0)cm^~DfsmmGTxcL47OUOawF&21kA7f#%Yr-CD{ zv5Q)jI&L%_2vHce&(>k}BCQD27RApmU|v|8fIE;5x$JxwpC(zLYaMhVjkT5nWS%Z0 zY&fu`>y7Vttm*+t&}c9M0!~Tl7%{s9juNCgYq#TT5yG8Qa_M=27N!U~J8syJpwIf8$qauypr{?^r-)}U1gSV>V1`X~* zG8zs?+cK|XxztbV%afp}Q?M)JQ<B-*M~>zj2P-FObwlx8j)wnhKTU zqQZuK?I1{i+N@-1^nHFjt<;58DxG}kOG)FuY>9=VX*pTN+Orb$O>tIvhhETY44?bQ zmLIU@D}UbCs>TfX5$oJ##n0bRw^0iVhDfWUxhn%cUz0*wonQR(t}{2bWnb`MG%i9b zVlW4Us@bN*b_dxdx01-Lq&k`CVoV-SEHu@c7~b=`=^Wu3+zxT(GxkAl{1Lx;cd7j( ziK)U(iYFgSt1NfUC?X@|L#=3|cAxyGoD)kMR7G=LGOq>auU5H7ZLzuscsmaG_V1z} zbHewjq!b{(y}_G1ZD59f(I#16yN8gL8KV*C&~8L-B;-5~<5=-l*&>CR9HF&D2x&to z#A82{?DP@V9o8I*iCVG~5@9wJG2afW9`ZY0bBDG ze`9y;#0X|XJ!D(bxO;ZtOK~l;cKxeuY1~k)8aa->o35{+Fky$r#*dJfJcq}jQEI=k z_ea~Nw335U77>3K$M8=nIF=ly4<|~g} zC~VOLPWW%tiLTU$Ko`)ZLYiNt;OA%u-a zayxzw?3@tnZu5hbpvuwyy13ik#gb5Px{lrAZD0%NP8ks?S;Dm}je*S_r$)s|SLRPE2zCM5cM8$S^Us_%Q9ryDo9iKh4AK&4V84iloW*P!QRsP zGrfm@I5~l`{evp#6M_5#YcSo(zrkBSiKpNjp`+<~pu3~4M%4t;DbEd)jFDLnm7os3 z>~r5<{f|Y$a*7f4Nq24K!K27Q9fOU9%LRuWSMtE8EMv-(a;dlbIJkmk4aYgezaHDF zRsmI#(mBGo1&o)#Yg@(8DBT=|{0$#=IaSqss1%}Py*H49<8dRV^AT<*^1%lIVtKa7 zC2+r2O=x9IR5U##py5{80_8$RfY;{+SIwDrEIIqa!Llwhi$opWkV#WMTI8f zx%Y%w4Z@~UL77eyrZo||_Z6!Eo7Pxq;D<0#>+C1|($oTNc{Q|E(ai^a9he%2%vv07$$t6Pp?fI|#!!zz|vbHM%5!{p~F&jm2avh3nC7 z3#>v`P`;~s3ZVFlX`{DV(Zk<5et+)+V3gDoc582yDCn&G3qJR5vw_8BYgFAdwzT~8(lJG;i3+Qx8_jjPIDuWEd%-=OPHan06fx*G^dMR40RVt@CLml+_$v#=@x zQDIqKMtL2kVF9Y-lTp(B-K|c~d>WLUf*VvDz~Cd06soRK`uBCs8Ge)@#lEN^?QZmi z8|rWYLlX>ag_z)hANHNqgY5N#ZVArb!B7TOt%o z;<=AzkeQVwN7a<;q51IX4Px~~=S>h4I`CxVsM-(f)}F7s-^)Gsj`i)zWGzI~?OSvl zzWTfsm|_)93i9tLocw|jN12Pum<-^C!%A7!_~)&nRVDO%bHq8|+$ zMebinDtc%GY4&OeCq;AF#OjsM67coG-@YmABI3u$9_D`yKAWC5FlXM6d8%rY7v&^k zWsz!}`QqL}_FSjr6UuQm+|YIucBCwa%0Urf^l&1GTzZ-WEnBe9P+Ptp@I3( z{km@2*c#GaobO?fq2<~1+&8Olqvsv<>sI^%=!(xwqILx$OIIu1an!I4Vhb$Ve zH}zcZct=^+#|E0UT7Pst|s`*C~3uw{z~3S z*$572m&RIHGjyFAfL?9U5-}1G8OeU(u_PGK<$M3b8%^GMJ?CHAJ`v%y69jHhWADgVJ&B-*k%*oo8F0M z{d+gB1LM^c&0TI_X11+irCMt$G9Jf~a@V)LEBh=Hc zqD~>P;Pz-i^^o1#nF;%9$yaA7LS8!Ielpl+(!`m(Ds$Ps>ZW}QQY$s#j(i!Yu?Vh> zE~3EKT(Te0^k~o&v9*CnRF|(SD)BBn?X~4&5HwI5ExcaqSNcj(3|CF_CLPI?8v08T zqO-rz#65uVI+o?y6x`W5OC#_-ke<2{7gZin2rNO@^vN(is!7^>jxc`rv3*4;g5TR+((!G zOZN&^hTL)4Zn9Qbo``3m`l%^c*(FnVABpQ8X!7z#R^UO)g9@TlsLwMRPzy5rSvRR} zl9_0oeS1{qwhj3Q>jsR}YCXJa74qt5Ww*sZ4hZpy0yL+~9LvfpeNxv3D_5{IVVhL{ z=RlUx<>NI{GSCbGD8aJP*EA*k1K$^iTpM8O^Jm9P3ubaF;|*qRe4Xi?TO=uY$A-gV z?Nh7fX9Cv}WRYTe3)$8duDHD<|?<}N^3Z)ZW(yi{MhEQ9kR;Rd_{UT1q~pF|9Pgwufrtl zx@t^13D0h6L)0qfco?qkRJECzt)@Ay_2eb9 zEm>#$Mn~7;liWN=Du@@LN$MSc{sBk3<)JxT^LtrrXq%#@V?;LybwU(R@n>*mtZSyu z9Jv=hko|IqDH&Q?7mp21ix|Z(bIYtZW@kB}7WR{1>1wjn_jl}0DeQh=k~2BI-Pdlk zAXJ!%P-%IBD$>c}PL#~aYBK`u?!U=zyOp+&7#q!8c1>%^W;=5}6uSmsmKMp`vJrs9 z_q0zIzarjq9lmX&n=;Y}Q03Tf8RD2P;v&soq_&BMrr=`Q&5Jg>lIPPDtp2aUWVSODNPdO%+ zWH!l}|F*K^G!ovV#t8YO?E37ahpl8?|IqRr>2*lvFhr*zV$Ck{q_?s_(AT|p2za^O zcFBvu4sUEQ&W|Z4Z>?lBjMgnT?Pn4FL!MIBl9E9U$_Ax<`jOEj^oA{ zOWQPY0`Z`_4JUnFYJX$V|7G7&yA{a*KYWAItr2ief;Qt_kK(d5S*=d^+_7{k za`4WhLEqRng-0Ixnc0Wx9LpjogwPw?G{r>nx{&ld0g(dz!w~YXsoMZlkB?zYNt+E18md;gimN9T9h(dfwIk@jX>;&gi_H^)w-= zD@)(LSB?Fa22(ron?d zSZ6;fR_!Q^xmE=NhL}GH;7Ok4qm_rZ>n%X$**)MMTTyNvYf+iO8SJp)pU>aANJ@kga>shcZ>LGu|qV@^ru%@r&SI6r-d**}Ix zfy(M)qNshQ>E(XrDx(SQ9dLZLhWMfx@#q3gkWr#M`rbJTQi<||kQqLWh7Xa)^6J;M z@UBepvb}mtg#Z`+=w@t=-J+7KHpPeo58`=YbI)4Uc~EI2f7o|G6~z3m__jkckH zTPrXB$Wqa0>k2Q3&=L~rHR|wQKusWfjUDjE2vfn8yKf zqFr7)dw(hY9Vn7_v%W0%Frlfb;oB)j0sL5TKFNNoKVIc~MmZ*oqkYlRUkzlO5>iKc zc@MAB5EgxAsen`3A>>UJ^UcE~M+~rI=-}}1&oKs10>rta`1g3;6GJb6PVY0e#N=-O zC$m*L#BzDgv37eaNaZc)FV|P}Z1Zu*0W%fX7i>5Y^11(C)3^Pf;_c>gKC&;yFZ|}Q zeRU?pPU(_rEO_XI0WsJTeT)-9)OXx@^fDRW9~AOb z)4LQLzZ3uA+!O|X>VgyfShN-+>F}PM5e?vmil!=R;YX+bZq1UJU4??7o_D9}f7vSy zyS?b%97|RmE9&!QpR%l9w}_~S=C{VoJ7O({y^=MDfCm_PAwKx{7CxnaV2SPuNt(}B zL&L?91;Hp6A~>ZzJf0|*g`$nm8D<)`4N4t{(qHLUK}3_^Y6)y$%PXJZTUzg z@Z#}Hbe5Q03NqVh<%-<1Kd3?OAJDW6?=bC&gp}j+a`NG0&LeQMs1uPnW zhu6Gzm0ou7anKiVN%ZZ=?&NjvssHJ?uQ-mf#p?zBA+MDHFZX}M_s)$=J-cFamA0%J6c3kMKACxSsC6UcVW|NH*L&7tsJpvCo|2w z=iSOK0fHk0eS9GX$-o+~m-44H!41_wF>A<7T~nV%HwlRUy%-`dk;?kT9w7!0ccgs9 z4BEk!?fyUGTV?J^7C^&nL4m%)1piX{a(fQ(zTVsqN~_0;_T0DN=W=rb4D8Ec2b=>$j?w$HC` zZ#8O45=i*?@d3KNBLz6SLthl4TG-%l!FyhDq}uBOb`YPoCe61DC}xzt^bHV7`hM+H z9AlN5?6p(`Sc`h?_13D=3cGh#)rnO;C{CwzdmI2buHVcujfk;4oTd2BW_1^{<%rzq zvW|x3m=ZmFnmloD5ECE%x8lC=1$`9RGcTl1hvyNEoq?*((!H>dZsg1m3&t zbqK|^UR=r(@D*7yo(-=456dH9iRtkrOJVVJvASHK6Jg!;N1L@cZvd{)iYCX@x$lxr zigI{>7)YIXbhT&34N&0B^WI5in+cg^fm04VqDuUNVM8hwuKSX+$_Cx_BqdbQZg{-n zPScAp`^E^H9SoQfSGd=>^!LuvZl|Kf8m+%tV%RMSTDq0x0eYbiul;#1%X|-f#3u9O zIzjOJ7l+)}LB2{uvoYBFYFWa^>O~o%Zyv<&WiQ|RDQedKC{m$38-F#5WEME~<_fcG z>w+wQK{9;Hw#Jc5c~Z-os7__4xXQ9jev%(yoQE0JEf|8-q79y&!<^y2BF6MIy&?kQ~(c=HIL%* z9$mAezV64(B|7^bfb_-0J<4yQ{aQ>lC#Y(wM%`cEtqvA;Ro?`|&?=FCv8ux<;t_j2 zs=sD;D^n+k+9w1jF-M&OELoQLL~26yR#*kSZwy1-X@nV~biZGfx@^E_JtHUKksBLD zJiVi35!)M&*2+7x0c3lF)8~g~!Kvojzt-AeHHvq5WB~C>x@8=(00q;cpYL;gvEsve zJUqPm;qINtYs(8S1tW_QTc+WwqUdPW=(|_zmcI1t$I`%KiJUb-M3)}pZ=pZhN;G7S zu0Qfe?73w81MLYwBAr%{Y= zhR*}KhFG?V@Pc96O&PKUe6)4oNsd2lDtqIMAbI0a$r06GL6Y@1a&7y*jOY6&#VfQf z^)}ymEhh|$aK$70b5Np}yoPP=_PopEh&FC~QT0z%5hegt9KtW`rNB);Am)fRr#gfVr8hU1qs>rZC+o4>&M0olGu zox^ThZ!NO>n1%|WO+0ckpXM|)E?p-{msJ%fPCfutt&Z9VXc$ z`SE6>%}M13e#IHg10_by`dW#c#P^27E)K3UsCnjF$6nMCweU9RunhtF;_f@Yz23}Wi+R#v7u%z1zJS%{1b9(bD$Gm0<9r)$u1-Nd|IsGz^% z|A<$WZk?dkLrx*+T{g;zu%4qpsLjD<{a%^mWQbh<&G^c+Cw0T(n$iH|Rks$WyM|0` z0o3B;a<=GxUo%ZL#X^S zpWZ2F_Ea92^NB0(Rih1z>CZvT?`MH!fJ)XlsCslRF;%Z0kRuWqxrR^fNE>;6&wGxW zYu^nL2SjoQOL_lw5plN{bSw4vQ-!UIL;0F=q~ZfqW)tSls2o-wZSP|tM+C;bB=@`3 zc^wxA_1{0U$Mj_5;r?BM9Xk&8*j~PLs~C3_Wm~YjWJITSp_bEW-Gt(>r$ee zd|<#;%+yfH(Xqv`h;xC%EE=;(ezUm}mtO^)sv8gOhS@I0`;pp0Cc7zqw4?8!Y_lu0 zAVkt}<;>c^1If{eUQ0(r5NDP3gC1vlN0EM>XQR4|j0e3pAFH@~Kv$AGX*sB0Ki$5+ z3j?`4!AJLdu#DsN-Yhkr}>PavAKGwQ+H&clM2`Wn<#M7PqS-C zG-7=~oVNPfth(RP6JRz!KBY{8;MEL{mhG5#5>R;8EY3LU2G>QB#pBz;?KQcNpcHK1 zA+two%*_hcN0jpr1|<3tQ$smq1(!M9U>Cmal`9i}3$x0u;4Cp|N(~zNljWyo(Cpp~ zw|7U0>2#)Z=-A~h*^fJ^k;8p_VGngr{b_#ju$NP(7HAk(Kckf+ayN+N2|o$|^|oFM z=^O55s7qhQSGXz1>-_6q=gnZZFUA8sE^^ z9i6Y^9b3zK3z(@t8-QFHN|9sU>&(h|O*TPGO< zvyC&&BS(&_hu__bN#-}=6I5J#3iAvcg7bW1)c=#pj-M_m22hI3*g==;F)&n`PTswwM+ z3GD0dPG5!dyHEm(PT}NlMz~X{u$UVY8+@r|;9bJv=UWRSO-8Z1jE%+#CVWwZjmn$} z{(r_U=^IoL{+0Q4%~@h&)gPIGrO98Y4X#lr=;wm%W}|Z0;S_@YLnA*yQ~A?eT)~1) z%*4bQzWMlT76AauiW>C$j;zi>r0Oz`AqOd7qx%VR7MrFnM%}+HsAzfnbn?4F!7ahZ zw-+H&`$*o_9Pc_Zo!46Wj?J*qqElQ0E$dO-%J5U@{lmC;8rZC-e_J!``f$t<7eEFD zp&7JT8$%MWDaW);REdcp*Gd)PZM`>p89o_X?`>vsb><>QG_ZskEpnr++Da=DIsU;53Sx~Y{%vY)@R z4?9I3oG$)M3r_NU9&6H%m441&KP?xtAA4QZ=ykgN*dzBLhvBz{ z-a4OxX@Y237s05!_Qd9fKXSulkoKOt695-&d@O8uAyCTt1vyD${kppV((K>EJiWT? z_U*6}!Lm>Tmf0j;EJGEE2kjvXbdaA_5s zmM-b6N2-M#-vDx8KmL%-CTT$fS2yU;Mg}|1VJ@xHiavDzysp}401oiik^DJ>CWtd1 z>E$r3V9)7sgs|U?TMGeGicS_kaoLc%sPNFtL4}VGoc}I6tc>MejRPD*odO9o?4?2A zy^Fau$*RpaEfQUei@SeQ!j*AC?B52x4;>xaihrW!yO+XTA3!{uyWh9HvG^_c(-lzA zv`tO8Px3JS-*+=V#FIOKAna%4U7~af`2V?fS{*#S9-ngQ03i2U z;qOjZ>p{Ynf24;8X>Z=`PBk$EEt@`U1E_*@=m(8xPc=I}ls!pI$k|x_)Q#Mbb+rmW zAPtW}hsKBF;o|6Hvch``H*=kHY226%47-Ctf$ggtruUI=(bqCw>mI&$8sju_Em1Y- z(7^}1ym7soG1vaP>o+`n=&0k)Nh@vDGB2LL(Ojceo3ED=B00FI;=hl6Jf2GEcT4Y# z{>j)e* z7J{pOgCDZe55#0Nk&yTME@%nUath?GGT69wIqc{h>HYz2RM#N8d2of1 z8BVb37~;pqH=JtSjmw{TT0a?2=lgMDy(@@&G2MSEMC&Mc{%~JN9SbKK@$FOfJNd10 zTIdZs!t{K0jIND#S$bf?5Dezsq=#|fv_b!uv1VFd?N%9REG|H{sgiGj#Ou3IbIGbBwFLk`kPA|G?@);e4Tm0S0RHlgH-$q`{@b2&DknihByDtTr5yMryH@{nsOO@s?k0%qkgNuOy}3BJN~l5vA!kQ z@uvSP67>!Aryl<=K$1N_BYh!Ftbx<7akmh9olS@FZbvI}4r>-ui5_bwPxt!Q%&7?W z=>!*HTW7wMKL6UIdkiaZH}VQ&59HT3N@SBs3`n48vpZ&NYiF~`k1Tx?64VpiujVYr z{%fZ#$Vy+$#hlp1Jh_(besp6}&NqS6lAxI5*t1rdU`nXKbQ|+6j)uwIFi5eOcEG%> zPE3R9-4347P%{%HReq*9Vut~gb>FBD6?ir2T3JkB5N_jJ{z_4+-{xXu7WHzeJ=tLT z$mdCtM~#aVOX1WyU^P^$v{Ew-fo1A$jDfB69z`e5#G>xKkR5u4=#~C`BAMe@#GKDi z!-Wpm@mgf;W|P{utdxw+BB+*Jcj=2}?}`Jhjm8{56fN3fWTgZ815}Z*Y^aJHn$vcf zP7mr#g+0NgAMm9AR%d^Ha|^D4G1)OAMv@IXvPXd4GO zb0*?PNv=J%Pad~jxk%9X`Iolv=Tcn%i+R$F=!j4j?-YQ|)&_PDFtPr!q@!SMS*&34 z)DF#U8~eK7zbX>jD|kc^be{MCKPqQl8`Sr#pXkr1f>HwgvP`hCBL&sY)r>XV!Qz*< z)uP|*53wiMn^B+Qgpcig;$t^q*NPTbU#TjHbaVq@G9)~ZXGN)DOMbQTpH*H;S=XgqdGASk4(*vS-ZrbSRrHusftx(oKMp8;%tAv9qt zODMC@*5TW?m*c?;x}MeL&BV7fg^Rg)dIxX4((h1_>eo7-FHrd>vX?R4v)1%LVffCw zSJ3?K4Xw?G=R7B0Twa2ATSb+p6Y2R$lr_TOhreg%d-)oP^=9sFD%_N;xV19<&BSu3Ty z=|PET`CqUQ)>$A*%p1pY>vBvB3w*x8zt~VG-S5kEYSz~~^r?^QMIlA$h--H%y(J$S z1T~4nD_zJYGo09N2^DPaL?xH@R2DK;3IhE1c{Pi9Qz^ ze^ggQUovAfzd@)j1yVWaZ}tYO)97`+n}|}>O|G(GP-O8J3rz=M@`L2Zr0T{1_p@>< z5VLelaDcp!Ulp1+hV`}8G_N0e!=qgG2x+l=c%o2$s3DZQ>pUf6->KL4LsuSM!yRN7C39^t^RnQpQb(Ow6F? zJ@J3c&>V0~{ePp?B)~Vn?2WezR%W69n{PpOW_VlGIxi$zK9rx#Bu|;Yg!+}}Z)7W? zR!&BGZ3g8Wnuu?~NtH}#zIq5)z;xf*of!#XwOQr62RrkodAXtY%I`L#C*Jb~Z#FVS z6@MM|v~73At>)^nm%9l0dUM~wsT}RsB&&hj_Jj5rfrg!#ffteXx~3VdF%XsI^lkEA zp=rkHrw8^Fy{(f0$ICV6h#(6cCiWBs@I1Y$&^^a}C zwy}2)Q=DFvz4hPU;89hu`k~#pfPNPyKS#8~95@%A4>(e1zxg~(O_%oNz~|Q8S2hk} zn5vwiq`!h5-IM2W7t^=hJYO{jw!a)$Gb`^;pa10eZa0m7#BD{k>a z)8dwT$mxe=9dE$rzS=*AT0603qoo>P5;!Sv-tghVG5h53>)Y&Cdh1U2w_Ekl1c!Gs zj(d<*m!f-?Rcho*rCk`6glFE}?pppQm^gJacG>XGoZ0ar@o7@`pT zFO}E3x>g0HRwZa#Aa3|FlBblL5EitQWAVt_K#77xw8pJ7C#O Date: Tue, 30 Jul 2024 18:37:13 +0700 Subject: [PATCH 280/291] mac: add replace, move, rename instructions --- tools/osx/INSTALL.readme.rtf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/osx/INSTALL.readme.rtf b/tools/osx/INSTALL.readme.rtf index 7d4aa060e..bffc9bae5 100644 --- a/tools/osx/INSTALL.readme.rtf +++ b/tools/osx/INSTALL.readme.rtf @@ -2,6 +2,8 @@ To install the RawTherapee application: 1. Open the RawTherapee .dmg Disk Image included alongside this document. 2. Drag the RawTherapee icon onto /Applications. +3. If RawTherapee.app exists, click Replace in the dialog. +4. Do not move or rename RawTherapee.app Note: For security reasons, RawTherapee MUST be installed in /Applications. RawTherapee will refuse to start if installed elsewhere. From 4b78e16130e2ab40a4eef39aca40d564af23727f Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 29 Jul 2024 13:09:43 +0200 Subject: [PATCH 281/291] FramesData: add missing isDNG initialization. FramesData isDNG wasn't initialized. This will randomly cause images to be considered as dng files when the underlying value is different than 0 since the metadata parsing could exit before the code that checks for the Exif.Image.DNGVersion tag. --- rtengine/imagedata.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 77be8c1a3..e9458f3ce 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -274,6 +274,7 @@ FramesData::FramesData(const Glib::ustring &fname, time_t ts) : sampleFormat(IIOSF_UNKNOWN), isPixelShift(false), isHDR(false), + isDNG(false), w_(-1), h_(-1) { From 23ec7f324eaac4d75a3f453275cb4a77f7a9dd95 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:50:54 -0700 Subject: [PATCH 282/291] Add new icon for Selective Editing The icon is a rectangular RT spot. Switch the hand tool icon back to the normal open hand instead of the high-contrast version. --- .../rawtherapee/scalable/apps/rt-spot.svg | 98 +++++++++++++++++++ rtgui/toolbar.cc | 3 +- rtgui/toolpanelcoord.cc | 2 +- 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 rtdata/icons/rawtherapee/scalable/apps/rt-spot.svg diff --git a/rtdata/icons/rawtherapee/scalable/apps/rt-spot.svg b/rtdata/icons/rawtherapee/scalable/apps/rt-spot.svg new file mode 100644 index 000000000..240a8de35 --- /dev/null +++ b/rtdata/icons/rawtherapee/scalable/apps/rt-spot.svg @@ -0,0 +1,98 @@ + + + + + + + + + image/svg+xml + + + + Lawrence37 + + + + + + + + + RawTherapee icon: RT spot. + + + + + + + + + + + + + + + + + + + + diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index 1b59b8b24..158d2518d 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -27,8 +27,7 @@ ToolBar::ToolBar () : showColPickers(true), listener (nullptr), pickerListener(n { editingMode = false; - //handimg.reset(new RTImage("hand-open", Gtk::ICON_SIZE_LARGE_TOOLBAR)); - handimg.reset(new RTImage("hand-open-hicontrast", Gtk::ICON_SIZE_LARGE_TOOLBAR)); + handimg.reset(new RTImage("hand-open", Gtk::ICON_SIZE_LARGE_TOOLBAR)); editinghandimg.reset(new RTImage("crosshair-adjust", Gtk::ICON_SIZE_LARGE_TOOLBAR)); handTool = Gtk::manage (new Gtk::ToggleButton ()); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index efad8f0a6..354d3e47e 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -465,7 +465,7 @@ ToolPanelCoordinator::ToolPanelCoordinator (bool batch) : ipc (nullptr), favorit toiD = Gtk::manage (new TextOrIcon ("detail", M ("MAIN_TAB_DETAIL"), M ("MAIN_TAB_DETAIL_TOOLTIP"))); toiC = Gtk::manage (new TextOrIcon ("color-circles", M ("MAIN_TAB_COLOR"), M ("MAIN_TAB_COLOR_TOOLTIP"))); toiW = Gtk::manage (new TextOrIcon ("atom", M ("MAIN_TAB_ADVANCED"), M ("MAIN_TAB_ADVANCED_TOOLTIP"))); - toiL = Gtk::manage(new TextOrIcon("hand-open", M("MAIN_TAB_LOCALLAB"), M("MAIN_TAB_LOCALLAB_TOOLTIP"))); + toiL = Gtk::manage(new TextOrIcon("rt-spot", M("MAIN_TAB_LOCALLAB"), M("MAIN_TAB_LOCALLAB_TOOLTIP"))); toiT = Gtk::manage (new TextOrIcon ("transform", M ("MAIN_TAB_TRANSFORM"), M ("MAIN_TAB_TRANSFORM_TOOLTIP"))); toiR = Gtk::manage (new TextOrIcon ("bayer", M ("MAIN_TAB_RAW"), M ("MAIN_TAB_RAW_TOOLTIP"))); From 79279bc42c7a85aaa463e51d6950e9bee3a19eae Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 4 Aug 2024 20:07:54 +0200 Subject: [PATCH 283/291] Temperature corellation - crash with some 5D mark III - issue 7162 (#7164) * Bad behavior with blackwhite and gamma - after change avoid color shift * Fixed crash in itcwb issue 7162 * Appimage and windows yml * Clean code * Various suggested changes * Remove unused code * Remove appimage and windows yml --- rtengine/rawimagesource.cc | 41 ++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 6d9d6fd6c..ab2ee58e6 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -59,6 +59,16 @@ namespace { +float clipitc(float x) +{ + if (std::isnan(x)) { + x = 0.1f; + } else { + x = rtengine::LIM(x, 0.1f, 65534.9f);//White balance Itcwb - limit values + } + return x; +} + void rotateLine(const float* const line, rtengine::PlanarPtr &channel, const int tran, const int i, const int w, const int h) { switch (tran & TR_ROT) { @@ -6221,12 +6231,20 @@ void RawImageSource::ItcWB(bool extra, double &tempref, double &greenref, double } if (oldsampling == false) { + if (settings->verbose) { + printf("size rgb loc - bfh=%i bfw=%i repref=%i\n", bfh, bfw, repref); + } + #ifdef _OPENMP #pragma omp parallel for #endif for (int y = 0; y < bfh ; ++y) { for (int x = 0; x < bfw ; ++x) { + redloc[y][x] = clipitc(redloc[y][x]); + greenloc[y][x] = clipitc(greenloc[y][x]); + blueloc[y][x] = clipitc(blueloc[y][x]); + const float RR = rmm[repref] * redloc[y][x]; const float GG = gmm[repref] * greenloc[y][x]; const float BB = bmm[repref] * blueloc[y][x]; @@ -7451,17 +7469,11 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int const int bfw = W / precision + ((W % precision) > 0 ? 1 : 0);// 5 arbitrary value can be change to 3 or 9 ; const int bfh = H / precision + ((H % precision) > 0 ? 1 : 0); - if (! greenloc) { - greenloc(bfw, bfh); - } + greenloc(bfw, bfh); - if (! redloc) { - redloc(bfw, bfh); - } + redloc(bfw, bfh); - if (! blueloc) { - blueloc(bfw, bfh); - } + blueloc(bfw, bfh); double avgL = 0.0; //center data on normal values @@ -7496,8 +7508,10 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int } const float sig = std::sqrt(vari / mm); - const float multip = 60000.f / (avgL + 2.f * sig); - //multip to put red, blue, green in a good range + float multip = 60000.f / (avgL + 2.f * sig); + if(std::isnan(multip)) {//if very bad datas with avgl and sig + multip = 1.f; + } #ifdef _OPENMP #pragma omp parallel for #endif @@ -7506,7 +7520,7 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int const int ii = i * precision; if (ii < H) { - for (int j = 0, jj = 0; j < bfw; ++j, jj += precision) { + for (int j = 0, jj = 0; j < bfw; ++j, jj += precision) {//isnan and <0 and > 65535 in case of redloc[i][j] = red[ii][jj] * multip; greenloc[i][j] = green[ii][jj] * multip; blueloc[i][j] = blue[ii][jj] * multip; @@ -7722,9 +7736,6 @@ void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, doubl WBauto(extra, tempref, greenref, redloc, greenloc, blueloc, bfw, bfh, avg_rm, avg_gm, avg_bm, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, twotimes, wbpar, begx, begy, yEn, xEn, cx, cy, cmp, raw, hrp); } - redloc(0, 0); - greenloc(0, 0); - blueloc(0, 0); if (settings->verbose && wbpar.method != "autitcgreen") { printf("RGB grey AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); From ff15de216f0533d790b898dc62d8695829f19fe7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 10 Aug 2024 16:11:21 -0700 Subject: [PATCH 284/291] Update Dutch translation Translation provided in https://github.com/Beep6581/RawTherapee/issues/7173. --- rtdata/languages/Nederlands | 1018 +++++++++++++++++------------------ 1 file changed, 509 insertions(+), 509 deletions(-) diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 9cec0212b..404cc2c18 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -17,7 +17,7 @@ #017 2020-06-05 update by dheijl #018 2024-02-18 update to RawTherapee 5.10 by Paul Matthijsse #019 2024-03-08 update by Paul Matthijsse -#020 2024-07-27 update naar RawTherapee 5.11 door pm +#020 2024-08-09 update naar RawTherapee 5.11 door pm #100 #101 @LANGUAGE_DISPLAY_NAME=Nederlands @@ -58,7 +58,7 @@ DONT_SHOW_AGAIN;Dit bericht niet meer tonen DYNPROFILEEDITOR_DELETE;Verwijder DYNPROFILEEDITOR_EDIT;Wijzig DYNPROFILEEDITOR_EDIT_RULE;Wijzig dynamische profielregel -DYNPROFILEEDITOR_ENTRY_TOOLTIP;Het zoeken is niet hoofdlettergevoelig.\nGebruik het "re:" voorvoegsel om\n een reguliere expressie in te voeren +DYNPROFILEEDITOR_ENTRY_TOOLTIP;Het zoeken is niet hoofdlettergevoelig.\nGebruik het "re:" voorvoegsel om\neen reguliere expressie in te voeren DYNPROFILEEDITOR_IMGTYPE_ANY;Alles DYNPROFILEEDITOR_IMGTYPE_HDR;HDR DYNPROFILEEDITOR_IMGTYPE_PS;Pixel-shift @@ -70,7 +70,7 @@ DYNPROFILEEDITOR_NEW_RULE;Nieuwe dynamische profielregel DYNPROFILEEDITOR_PROFILE;Profiel verwerken EDITWINDOW_TITLE;Bewerk afbeelding EDIT_OBJECT_TOOLTIP;Toont een widget in het voorbeeldscherm waarmee de werking van het gereedschap kan worden aangepast. -EDIT_PIPETTE_TOOLTIP;Voeg een punt aan de curve toe met Ctrl+muisklik op de gewenste plek in het voorbeeld.\nKlik op een punt in de tooncurve om deze te selecteren (wordt rood), verplaats 'm vervolgens met de linkermuisknop ingedrukt.\n Hou de Ctrl-toets ingedrukt voor fijnmazige controle. +EDIT_PIPETTE_TOOLTIP;Voeg een punt aan de curve toe met Ctrl+muisklik op de gewenste plek in het voorbeeld.\nKlik op een punt in de tooncurve om deze te selecteren (wordt rood), verplaats 'm vervolgens met de linkermuisknop ingedrukt.\nHou de Ctrl-toets ingedrukt voor fijnmazige controle. ERROR_MSG_METADATA_VALUE;Metadata: fout bij omzetting %1 naar %2 EXIFFILTER_APERTURE;Diafragma EXIFFILTER_CAMERA;Camera @@ -135,7 +135,7 @@ FILEBROWSER_APPLYPROFILE_PARTIAL;Pas profiel toe (gedeeltelijk) FILEBROWSER_AUTODARKFRAME;Automatisch donkerframe FILEBROWSER_AUTOFLATFIELD;Selecteer automatisch vlakveldopname FILEBROWSER_BROWSEPATHBUTTONHINT;Klik om de opgegeven map te laden en het zoekfilter opnieuw toe te passen. -FILEBROWSER_BROWSEPATHHINT;Typ het pad naar de doelmap.\nCtrl+O markeer het pad in het tekstveld.\nEnter / Ctrl+Enter open de map.\nEsc maak het tekstveld leeg.\nShift+Esc verwijder markering.\n\nsneltoetsen:\n ~ - thuismap van de gebruiker\n ! - afbeeldingenmap van de gebruiker +FILEBROWSER_BROWSEPATHHINT;Typ het pad naar de doelmap.\nCtrl+O markeer het pad in het tekstveld.\nEnter / Ctrl+Enter open de map.\nEsc maak het tekstveld leeg.\nShift+Esc verwijder markering.\n\nsneltoetsen:\n ~ - thuismap van de gebruiker\n ! - afbeeldingenmap van de gebruiker FILEBROWSER_CACHE;Cache FILEBROWSER_CACHECLEARFROMFULL;Wis alles inclusief opgeslagen profielen FILEBROWSER_CACHECLEARFROMPARTIAL;Wis alles behalve opgeslagen profielen @@ -222,6 +222,7 @@ FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren.\nSneltoets: Shift+4 FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren.\nSneltoets: Shift+5 FILEBROWSER_SHOWRECENTLYSAVEDHINT;Toon recent opgeslagen/verwerkte foto's.\nSneltoets: Alt+7 FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte foto's.\nSneltoets: Alt+6 +FILEBROWSER_SHOWRECURSIVE;Toon afbeeldingen in subfolders recursief FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak\nSneltoets: Ctrl+T FILEBROWSER_SHOWUNCOLORHINT;Toon foto's zonder kleurlabel.\nSneltoets: Alt+0 FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering.\nSneltoets: Shift+0 @@ -329,7 +330,7 @@ HISTORY_MSG_41;Tooncurve Mode 1 HISTORY_MSG_42;Tooncurve 2 HISTORY_MSG_43;Tooncurve Mode 2 HISTORY_MSG_48;Gebruik DCP-tooncurve -HISTORY_MSG_49;DCP-illuminant +HISTORY_MSG_49;DCP-lichtbron HISTORY_MSG_50;Schaduwen/hoge lichten HISTORY_MSG_51;S/HL - Hoge lichten HISTORY_MSG_52;S/HL - Schaduwen @@ -675,7 +676,7 @@ HISTORY_MSG_407;Retinex - Methode HISTORY_MSG_408;Retinex - Naburig HISTORY_MSG_410;Retinex - Beginpunt HISTORY_MSG_411;Retinex - Sterkte -HISTORY_MSG_412;Retinex - Gaussiaans Verloop +HISTORY_MSG_412;Retinex - Gaussiaans verloop HISTORY_MSG_413;Retinex - Variantie HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmissie @@ -727,10 +728,10 @@ HISTORY_MSG_477;CAM02 - Groen uit HISTORY_MSG_478;CAM02 - Yb uit HISTORY_MSG_479;CAM02 - CAT02 aanpassing uit HISTORY_MSG_480;CAM02 - Automatische CAT02 uit -HISTORY_MSG_481;CAM02 - Temp. scène -HISTORY_MSG_482;CAM02 - Groen scène -HISTORY_MSG_483;CAM02 - Yb scène -HISTORY_MSG_484;CAM02 - Auto Yb scène +HISTORY_MSG_481;CAM02 - Temp. opname +HISTORY_MSG_482;CAM02 - Groen opname +HISTORY_MSG_483;CAM02 - Yb opname +HISTORY_MSG_484;CAM02 - Auto Yb opname HISTORY_MSG_485;Lenscorrectie HISTORY_MSG_486;Lenscorrectie - Camera HISTORY_MSG_487;Lenscorrectie - Lens @@ -843,7 +844,7 @@ HISTORY_MSG_595;SB - Lokaal contrast hoeveelheid HISTORY_MSG_596;SB - Lokaal contrast donkerte HISTORY_MSG_597;SB - Lokaal contrast lichtheid HISTORY_MSG_598;SB - Lokaal contrast bereik -HISTORY_MSG_599;SB - Retinex ontnevel +HISTORY_MSG_599;SB - Retinex nevelvermindering HISTORY_MSG_600;SB - Zacht licht activeer HISTORY_MSG_601;SB - Zacht licht kracht HISTORY_MSG_602;SB - Zacht licht bereik @@ -915,9 +916,9 @@ HISTORY_MSG_669;SB - cbdl masker helling HISTORY_MSG_670;SB - cbdl masker C HISTORY_MSG_671;SB - cbdl masker L HISTORY_MSG_672;SB - cbdl masker CL -HISTORY_MSG_673;SB - Gebruik cbdl masker +HISTORY_MSG_673;SB - Gebruik cbdl-masker HISTORY_MSG_674;SB - Gereedschap verwijderd -HISTORY_MSG_675;SB - TM zacht straal +HISTORY_MSG_675;SB - TM verzacht straal HISTORY_MSG_676;SB - TG - Transitiedifferentie HISTORY_MSG_677;SB - TM hoeveelheid HISTORY_MSG_678;SB - TM verzadiging @@ -987,7 +988,7 @@ HISTORY_MSG_747;SB - Spot aangemaakt HISTORY_MSG_748;SB - Bel. Ruisvermindering HISTORY_MSG_749;SB - Reti Diepte HISTORY_MSG_750;SB - Reti Modus log - lin -HISTORY_MSG_751;SB - Reti Ontnevel verzadiging +HISTORY_MSG_751;SB - Reti nevelvermindering verzadiging HISTORY_MSG_752;SB - Reti Verschuiving HISTORY_MSG_753;SB - Reti Transmissiemap HISTORY_MSG_754;SB - Reti Kap @@ -1039,12 +1040,12 @@ HISTORY_MSG_799;SB - Kleur RGB Tooncurve HISTORY_MSG_800;SB - Kleur Tooncurve Methode HISTORY_MSG_801;SB - Kleur Tooncurve Speciaal HISTORY_MSG_802;SB - Contrastdrempel -HISTORY_MSG_803;SB - Kleur Meng -HISTORY_MSG_804;SB - Kleur masker structuur +HISTORY_MSG_803;SB - Kleurmengen +HISTORY_MSG_804;SB - Kleurmaskerstructuur HISTORY_MSG_805;SB - Vervaging Ruisonderdrukking maskerstructuur -HISTORY_MSG_806;SB - Kleur masker structuur als gereedschap +HISTORY_MSG_806;SB - Kleurmaskerstructuur als gereedschap HISTORY_MSG_807;SB - Vervaging Ruisonderdrukkingsmasker structuur als gereedschap -HISTORY_MSG_808;SB - Kleur masker curve H(H) +HISTORY_MSG_808;SB - Kleurmasker curve H(H) HISTORY_MSG_809;SB - Lev. maskercurve C(C) HISTORY_MSG_810;SB - Lev. maskercurve L(L) HISTORY_MSG_811;SB - Lev. maskercurve LC(H) @@ -1422,7 +1423,7 @@ HISTORY_MSG_FILMNEGATIVE_VALUES;Filmnegatief waarden HISTORY_MSG_GAMUTMUNSEL;Gamut-Munsell HISTORY_MSG_HISTMATCHING;Auto-tooncurve HISTORY_MSG_HLBL;Kleurpropagatie - vervaging -HISTORY_MSG_HLTH;Tegenovergestelde Inpainting - versterking drempel +HISTORY_MSG_HLTH;Inpaint opposed - versterking drempel HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy HISTORY_MSG_ICM_AINTENT;Abstract profiel - weergave-intentie HISTORY_MSG_ICM_BLUX;Primair blauw X @@ -1434,7 +1435,7 @@ HISTORY_MSG_ICM_GREX;Primair groen X HISTORY_MSG_ICM_GREY;Primair groen Y HISTORY_MSG_ICM_MIDTCIE;Middentonen HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Uitvoer - Primaire kleuren -HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 illuminant D +HISTORY_MSG_ICM_OUTPUT_TEMP;Uitvoer - ICC-v4 Lichtbron D HISTORY_MSG_ICM_OUTPUT_TYPE;Uitvoer - Type HISTORY_MSG_ICM_PRESER;Behoud neutraal HISTORY_MSG_ICM_REDX;Primair rood X @@ -1456,9 +1457,73 @@ HISTORY_MSG_LOCALCONTRAST_ENABLED;Lokaal Contrast HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;Lokaal Contrast - Licht HISTORY_MSG_LOCALCONTRAST_RADIUS;Lokaal Contrast - Radius HISTORY_MSG_LOCALLAB_TE_PIVOT;Lokaal - draaipunt Equalizer -HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Beperk verzadiging +HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Lokaal - CIECAM masker vervaging contrast +HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Lokaal - CIECAM masker vervaging FFTW +HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Lokaal - CIECAM masker vervaging straal +HISTORY_MSG_LOCAL_CIEMASK_CHH;Lokaal - CIECAM masker curve h(h) +HISTORY_MSG_LOCAL_CIEMASK_HIGH;Lokaal - CIECAM masker hoge lichten +HISTORY_MSG_LOCAL_CIEMASK_SHAD;Lokaal - CIECAM masker schaduwen +HISTORY_MSG_LOCAL_CIEMASK_STRU;Lokaal - CIECAM masker structuur +HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Lokaal - CIECAM structuurmasker als gereedschap +HISTORY_MSG_LOCAL_CIEMASK_WLC;Lokaal - CIECAM masker wavelet L(L) +HISTORY_MSG_LOCAL_CIEMASK_WLEV;Lokaal - CIECAM masker wavelet niveaus +HISTORY_MSG_LOCAL_CIE_ANGGRAD;Lokaal - CIECAM verloop hoek +HISTORY_MSG_LOCAL_CIE_BLACKS;Lokaal - CIECAM Spreiding zwarten +HISTORY_MSG_LOCAL_CIE_BLUXL;Lokaal - CIECAM blauw X +HISTORY_MSG_LOCAL_CIE_BLUYL;Lokaal - CIECAM blauw Y +HISTORY_MSG_LOCAL_CIE_BRICOMP;Lokaal - CIECAM helderheidscompressie +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Lokaal - CIECAM drempel helderheidscompressie +HISTORY_MSG_LOCAL_CIE_BWCIE;Lokaal - CIECAM Zwart en Wit +HISTORY_MSG_LOCAL_CIE_CAT;Lokaal - Matrixaanpassing +HISTORY_MSG_LOCAL_CIE_DETAILJZ;Lokaal - JzCzHz Lokaal contrast +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Lokaal - CIECAM Alle maskergereedschappen +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Lokaal - CIECAM Pre-Cam +HISTORY_MSG_LOCAL_CIE_GAM;Lokaal - CIECAM Gamma +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Lokaal - CIECAM Kleuromvang +HISTORY_MSG_LOCAL_CIE_GREXL;Lokaal - CIECAM groen X +HISTORY_MSG_LOCAL_CIE_GREYL;Lokaal - CIECAM groen Y +HISTORY_MSG_LOCAL_CIE_ILL;Lokaal - CIECAM TRC Lichtbron +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Lokaal - CIECAM Log-codering Q +HISTORY_MSG_LOCAL_CIE_MIDT;Lokaal - CIECAM Middentonen +HISTORY_MSG_LOCAL_CIE_NORM;Lokaal - CIECAM Normaliseer L +HISTORY_MSG_LOCAL_CIE_PRIM;Lokaal - CIECAM TRC primaire kleuren +HISTORY_MSG_LOCAL_CIE_REDXL;Lokaal - CIECAM rood X +HISTORY_MSG_LOCAL_CIE_REDYL;Lokaal - CIECAM rood Y +HISTORY_MSG_LOCAL_CIE_REFI;Lokaal - CIECAM Verfijn kleuren +HISTORY_MSG_LOCAL_CIE_SATCIE;Lokaal - CIECAM Beperk verzadiging +HISTORY_MSG_LOCAL_CIE_SHIFTXL;Lokaal - CIECAM verschuif x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;Lokaal - CIECAM verschuif y +HISTORY_MSG_LOCAL_CIE_SIG;Lokaal - Sigmoid +HISTORY_MSG_LOCAL_CIE_SIGADAP;Lokaal - CIECAM Sigmoid aanpasbaarheid +HISTORY_MSG_LOCAL_CIE_SIGMET;Lokaal - CIECAM Sigmoid methode +HISTORY_MSG_LOCAL_CIE_SLOP;Lokaal - CIECAM helling +HISTORY_MSG_LOCAL_CIE_SLOPESMO;Lokaal - CIECAM grijsbalans +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Lokaal - CIECAM blauwbalans +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Lokaal - CIECAM groenbalans +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Lokaal - CIECAM roodbalans +HISTORY_MSG_LOCAL_CIE_SMOOTH;Lokaal - CIECAM Schaal Yb opname +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Lokaal - CIECAM Zachte lichten methode +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Lokaal - CIECAM Schaal Yb weergave +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Lokaal - CIECAM Niveaus - Luminositeitsmodus +HISTORY_MSG_LOCAL_CIE_STRGRAD;Lokaal - CIECAM verloop kracht L +HISTORY_MSG_LOCAL_CIE_STRLOG;Lokaal - CIECAM Log-codering kracht +HISTORY_MSG_LOCAL_CIE_TRC;Lokaal - CIECAM TRC +HISTORY_MSG_LOCAL_CIE_WHITES;Lokaal - CIECAM Spreiding witten +HISTORY_MSG_LOCAL_DEHAZE_BLACK;Lokaal - Nevelvermindering Zwart +HISTORY_MSG_LOCAL_FEATHERCIE;Lokaal - CIECAM verloop verzachting +HISTORY_MSG_LOCAL_FEATHERCOL;Lokaal - kleur verloop verzachting +HISTORY_MSG_LOCAL_FEATHEREXE;Lokaal - Bel. verloop verzachting +HISTORY_MSG_LOCAL_FEATHERLOG;Lokaal - Log verloop verzachting +HISTORY_MSG_LOCAL_FEATHERMAS;Lokaal - masker algemeen verloop verzachting +HISTORY_MSG_LOCAL_FEATHERSH;Lokaal - SH verloop verzachting +HISTORY_MSG_LOCAL_FEATHERVIB;Lokaal - Vib verloop verzachting +HISTORY_MSG_LOCAL_FEATHERWAV;Lokaal - Wav verloop verzachting HISTORY_MSG_LOCAL_GAMUTMUNSEL;Lokaal - SC - Voorkom kleurverschuiving -HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Beperk verzadiging +HISTORY_MSG_LOCAL_LOG_BLACKS;Lokaal - Log Zwartdistributie +HISTORY_MSG_LOCAL_LOG_COMPR;Lokaal - Log Comprimeer helderheid +HISTORY_MSG_LOCAL_LOG_SAT;Lokaal - Log Beperk verzadiging +HISTORY_MSG_LOCAL_LOG_WHITES;Lokaal - Log Witdistributie +HISTORY_MSG_LOCAL_TMO_SATUR;Lokaal Bel. Fattal-verzadiging HISTORY_MSG_METADATA_MODE;Metadata kopieermodus HISTORY_MSG_MICROCONTRAST_CONTRAST;Microcontrast - Contrastdrempel HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;CS - Auto-drempel @@ -1577,7 +1642,7 @@ ICCPROFCREATOR_DESCRIPTION_ADDPARAM;Voeg gamma- en hellingwaarden toe aan de bes ICCPROFCREATOR_DESCRIPTION_TOOLTIP;Laat leeg voor de standaardbeschrijving. ICCPROFCREATOR_GAMMA;Gamma ICCPROFCREATOR_ICCVERSION;ICC-versie: -ICCPROFCREATOR_ILL;Illuminant: +ICCPROFCREATOR_ILL;Lichtbron: ICCPROFCREATOR_ILL_41;D41 ICCPROFCREATOR_ILL_50;D50 ICCPROFCREATOR_ILL_55;D55 @@ -1587,7 +1652,7 @@ ICCPROFCREATOR_ILL_65;D65 ICCPROFCREATOR_ILL_80;D80 ICCPROFCREATOR_ILL_DEF;Standaard ICCPROFCREATOR_ILL_INC;StdA 2856K -ICCPROFCREATOR_ILL_TOOLTIP;U kunt alleen de illuminant instellen voor ICC v4-profielen. +ICCPROFCREATOR_ILL_TOOLTIP;U kunt alleen de lichtbron instellen voor ICC v4-profielen. ICCPROFCREATOR_PRIMARIES;Primaire kleuren: ICCPROFCREATOR_PRIM_ACESP0;ACES AP0 ICCPROFCREATOR_PRIM_ACESP1;ACES AP1 @@ -2055,6 +2120,7 @@ PREFERENCES_TP_VSCROLLBAR;Verberg de schuifbalk van het gereedschapspaneel PREFERENCES_USEBUNDLEDPROFILES;Gebruik gebundelde profielen PREFERENCES_WBA;Witbalans PREFERENCES_WBACORR;Witbalans - Automatische temperatuurcorrelatie +PREFERENCES_WBACORR_TOOLTIP;Deze instellingen maken het mogelijk om, afhankelijk van de afbeelding (type raw-bestand, kleurmeting, etc.), het Temperatuurcorrelatie-algoritme aan te passen om de beste resultaten te krijgen. Er is geen absolute regel die deze parameters verbindt met de verkregen resultaten.\n\nDe instellingen zijn van drie types:\n* Die voor de gebruiker toegankelijk zijn vanuit de GUI.\n* Die alleen toegankelijk zijn door het lezen van elk pp3-bestand: Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (Zie Rawpedia)\n* Die voor de gebruiker toegankelijk zijn in Voorkeuren (zie Rawpedia).\nU kunt 'AWB-temperatuurnadruk' en 'Groenverfijning' gebruiken om de resultaten aan te passen. Elke verandering in deze opdrachten resulteert in een nieuwe berekening van temperatuur, tint en correlatie.\n\nLet op dat de drie indicatoren 'Correlatiefactor', 'Patchkleur' en ΔE alleen dienen ter informatie. Het is niet omdat een van deze indicatoren beter is dat het resultaat noodzakelijkerwijs beter zal zijn. PREFERENCES_WBAENA;Witbalans - Toon instellingen automatische temperatuurcorrelatie PREFERENCES_WBAENACUSTOM;Gebruik aangepaste temperatuur & tint PREFERENCES_WBAFORC;Forceer extra algoritme @@ -2122,6 +2188,25 @@ QUEUE_DESTPREVIEW_TOOLTIP;Bestemmingspad van de eerst geselecteerde foto verschi QUEUE_FORMAT_TITLE;Bestandstype QUEUE_LOCATION_FOLDER;Sla op in map QUEUE_LOCATION_TEMPLATE;Gebruik sjabloon +QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Toon of verberg een helpvenster met instructies voor het maken van locatie-sjablonen +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;Als u de uitvoerafbeelding naast de bronafbeelding wilt opslaan, schrijf dan:\n%p1/%f\n\nAls u de uitvoerafbeelding wilt opslaan in een map genaamd 'geconverteerd' in de map van de bronfoto, schrijf dan:\n%p1/geconverteerd/%f\n\nAls u de uitvoerafbeelding wilt opslaan in\n'/home/tom/photos/geconverteerd/2010-10-31', schrijf dan:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Voorbeelden +QUEUE_LOCATION_TEMPLATE_HELP_INTRO;Het uitvoersjabloonveld stelt u in staat om dynamisch de bestemmingsmap en bestandsnaam aan te passen. Wanneer u bepaalde specificaties opneemt, die beginnen met %, worden deze door het programma vervangen wanneer elk bestand wordt opgeslagen.\n\nDe onderstaande secties beschrijven elk type specificatie. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;We gebruik dit pad als voorbeeld: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;De betekenissen van de opmaakstrings zijn: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;De specificaties %dN, %d-N, %pN, %p-N, %PN en %P-N (N = 1..9) worden vervangen door elementen van het folderpad van het afbeeldingsbestand.\nDe opmaakspecificaties werken als volgt:\n %dN = Nde folder vanaf het einde van het pad\n %d-N = Nde folder vanaf het begin van het pad\n %pN = alle folders tot de Nde vanaf het einde van het pad\n %p-N = de eerste N folders in het pad\n %PN = de laatste N folders in het pad\n %P-N = alle folders vanaf de Nde tot het einde van het pad\n %f = basis bestandsnaam (zonder extensie) +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;Voor Windows-paden is %d-1 de stationsletter en dubbele punt, en %d-2 de basismap op dat station. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Mappen en gedeeltelijke paden +QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r wordt vervangen door de waardering van de foto. Als de foto geen waardering heeft, wordt '0' gebruikt. Als de foto in de prullenbak zit, wordt 'x' gebruikt. +QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Waardering +QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;FOUT: tweede resultaat is anders: +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 worden vervangen door de oorspronkelijke positie van de foto in de wachtrij op het moment dat de wachtrij wordt gestart. Het nummer specificeert de opvulling, bijvoorbeeld %s3 resulteert in '001'. +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Positie/volgorde in de wachtrij +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Drie verschillende datum/tijd-waarden kunnen in sjablonen worden gebruikt:\n %tE"%Y-%m-%d" = wanneer export is gestart\n %tF"%Y-%m-%d" = wanneer bestand voor het laatst is opgeslagen\n %tP"%Y-%m-%d" = wanneer foto is genomen\nDe geciteerde string definieert het formaat van de resulterende datum en/of tijd. De opmaakstring %tF"%Y-%m-%d" is slechts een voorbeeld. De string kan alle conversiespecificaties gebruiken die zijn gedefinieerd voor de g_date_time_format functie (zie https://docs.gtk.org/glib/method.DateTime.format.html).\n\nVoorbeeld opmaakstrings: +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Datum en tijd +QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Een uitvoersjabloon maken QUEUE_LOCATION_TEMPLATE_TOOLTIP;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2024/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2024, %d2=foto, ...\n%p1=/home/tom/image/02-09-2024, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de waardering van de foto. Als de foto geen waardering heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f QUEUE_LOCATION_TITLE;Uitvoerlocatie QUEUE_STARTSTOP_TOOLTIP;Start of stop de verwerking van foto's in de rij.\n\nSneltoets: Ctrl+S @@ -2148,7 +2233,7 @@ SAVEDLG_SUBSAMP;Subsampling SAVEDLG_SUBSAMP_1;Beste compressie SAVEDLG_SUBSAMP_2;Gebalanceerd SAVEDLG_SUBSAMP_3;Beste kwaliteit -SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en verticaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma-subsampling. +SAVEDLG_SUBSAMP_TOOLTIP;Beste compressie:\nJ:a:b 4:2:0\nh/v 2/2\nChroma gehalveerd horizontaal en verticaal\n\nGebalanceerd:\nJ:a:b 4:2:2\nh/v 2/1\nChroma gehalveerd horizontaal.\n\nBeste kwaliteit:\nJ:a:b 4:4:4\nh/v 1/1\nGeen chroma-subsampling. SAVEDLG_TIFFUNCOMPRESSED;Geen compressie SAVEDLG_WARNFILENAME;Bestandsnaam wordt SHCSELECTOR_TOOLTIP;Klik op de rechtermuisknop om\nde 3 knoppen te verschuiven @@ -2162,6 +2247,7 @@ SORT_BY_NAME;Op naam SORT_BY_RANK;Volgens sterwaardering SORT_DESCENDING;Aflopend TC_LOCALLAB_PRIM_SHIFTX;Verschuif x +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combinatie met Kleuren verfijnen kunt u:\n1) voor lage waarden, de zuiverheid (purity) van het beeld aanpassen.\n2) voor hogere waarden een gematigde kleurtoning uitvoeren.\nLet op dat u niet buiten het CIE xy-diagram gaat. TC_LOCALLAB_PRIM_SHIFTY;Verschuif y TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By @@ -2186,7 +2272,7 @@ TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: W TP_BWMIX_ALGO;Algoritme OYCPM TP_BWMIX_ALGO_LI;Lineair TP_BWMIX_ALGO_SP;Speciale effecten -TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire respons.\n Speciale effecten: creëert speciale effecten door kanalen non-lineair te mixen. +TP_BWMIX_ALGO_TOOLTIP;Lineair: creëert een normale lineaire respons.\nSpeciale effecten: creëert speciale effecten door kanalen non-lineair te mixen. TP_BWMIX_AUTOCH;Auto TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM-modus. @@ -2257,6 +2343,7 @@ TP_COARSETRAF_TOOLTIP_ROTLEFT;Roteer links.\n\nSneltoets:\n[ - Multitab-m TP_COARSETRAF_TOOLTIP_ROTRIGHT;Roteer rechts.\n\nSneltoets:\n] - Multitab-modus,\nAlt+] - Enkeltab-modus. TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen TP_COLORAPP_ABSOLUTELUMINANCE;Absolute luminantie +TP_COLORAPP_ADAPSCEN_TOOLTIP;Komt overeen met de luminantie in candela per vierkante meter op het moment van opname, automatisch berekend op basis van de exif-gegevens. TP_COLORAPP_ALGO;Algoritme TP_COLORAPP_ALGO_ALL;Alle TP_COLORAPP_ALGO_JC;Lichtheid + Chroma (JC) @@ -2264,11 +2351,12 @@ TP_COLORAPP_ALGO_JS;Lichtheid + Verzadiging (JS) TP_COLORAPP_ALGO_QM;Helderheid + Kleurrijkheid (QM) TP_COLORAPP_ALGO_TOOLTIP;Keuze uit parameters TP_COLORAPP_BADPIXSL;Hete/dode-pixelsfilter -TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0 = geen effect 1 = mediaan 2 = gaussiaans.\n\nDeze onregelmatigheden zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. +TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n0 = geen effect 1 = mediaan 2 = gaussiaans.\n\nDeze onregelmatigheden zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. TP_COLORAPP_BRIGHT;Helderheid (Q) TP_COLORAPP_BRIGHT_TOOLTIP;Helderheid in CIECAM02 is verschillend van Lab en RGB, hou rekening met de luminositeit van wit TP_COLORAPP_CAT02ADAPTATION_TOOLTIP;Bij handmatige aanpassing worden waarden boven 65 aanbevolen. TP_COLORAPP_CATCLASSIC;Klassiek +TP_COLORAPP_CATMET_TOOLTIP;Klassiek - traditionele CIECAM-bewerking. De kleuradaptatie-transformaties worden afzonderlijk toegepast op 'Opname-omstandigheden' en basisverlichting aan de ene kant, en op basisverlichting en 'Weergave-omstandigheden' aan de andere kant.\n\nSymmetrisch - De kleuradaptatie is gebaseerd op de witbalans. De instellingen 'Opname-omstandigheden', 'Afbeeldingsaanpassingen' en 'Weergave-omstandigheden' worden geneutraliseerd.\n\nGemengd - Hetzelfde als de 'Klassieke' optie, maar in dit geval is de kleuradaptatie gebaseerd op de witbalans. TP_COLORAPP_CATMOD;Modus TP_COLORAPP_CATSYMGEN;Auto-symmetrisch TP_COLORAPP_CATSYMSPE;Gemengd @@ -2289,12 +2377,15 @@ TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM-wij TP_COLORAPP_CURVEEDITOR2;Tooncurve 2 TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings-tooncurve 2. TP_COLORAPP_CURVEEDITOR3;Chroma-curve -TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\nHet histogram toont chromaticiteit (Lab) voor CIECAM-aanpassingen.\nHet histogram toont C, S en M na toepassing van CIECAM indien de optie 'Toon CIECAM-uitvoer' is aangevinkt.\nC, S en M worden niet getoond in het hoofdhistogram. \nDe definitieve uitvoer is te zien in het histogrampaneel. TP_COLORAPP_DATACIE;CIECAM02 uitvoerhistogram in de curven TP_COLORAPP_DATACIE_TOOLTIP;Indien aangevinkt tonen de histogrammen van de CIECAM02-curven bij benadering de waarden/reeksen voor J of Q, en C, S of M na de CIECAM02-aanpassingen.\nDit heeft geen invloed op het hoofdhistogram.\n\nIndien uitgevinkt tonen de histogrammen van de CIECAM02-curven de Lab-waarden zoals deze waren voor de CIECAM02-aanpassingen +TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is een chromatische aanpassing. Het converteert de waarden van een afbeelding met een witpunt van een gegeven Lichtbron (bijvoorbeeld D65) naar nieuwe waarden met het witpunt van de nieuwe Lichtbron - zie WP-model (bijvoorbeeld D50 of D55). +TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is een chromatische aanpassing. Het converteert de waarden van een afbeelding met een witpunt van een gegeven Lichtbron (bijvoorbeeld D50) naar nieuwe waarden met het witpunt van de nieuwe Lichtbron - zie WP-model (bijvoorbeeld D75). TP_COLORAPP_FREE;Vrije temp + groen + CAT02 + [uitvoer] TP_COLORAPP_GAMUT;Beperk kleurbereik (Lab) TP_COLORAPP_GEN;Instellingen +TP_COLORAPP_GEN_TOOLTIP;Deze module is gebaseerd op de CIECAM-kleurweergavemodellen, die zijn ontworpen om beter te simuleren hoe het menselijke oog kleuren waarneemt onder verschillende verlichtingsomstandigheden, bijvoorbeeld tegen verschillende achtergronden. Het analyseert de omgeving van elke kleur en wijzigt die om zo dicht mogelijk bij de menselijke waarneming te komen. Het past de uitvoer ook aan aan de gekozen weergave-omstandigheden (monitor, tv, projector, printer, etc.), zodat de kleurweergave behouden blijft tussen de opname- en weergave-omgevingen. TP_COLORAPP_HUE;Tint (h) TP_COLORAPP_HUE_TOOLTIP;Tint (h) - hoek tussen 0° en 360° TP_COLORAPP_IL41;D41 @@ -2305,7 +2396,8 @@ TP_COLORAPP_IL65;D65 TP_COLORAPP_IL75;D75 TP_COLORAPP_ILA;Incandescent StdA 2856K TP_COLORAPP_ILFREE;Vrij -TP_COLORAPP_ILLUM;Illuminant +TP_COLORAPP_ILLUM;Lichtbron +TP_COLORAPP_ILLUM_TOOLTIP;Kiest de verlichting die het dichtst bij de opname-omstandigheden ligt. In het algemeen D50, maar dit kan veranderen afhankelijk van de tijd en de breedtegraad. TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen TP_COLORAPP_LABEL_SCENE;Opname-omstandigheden @@ -2317,11 +2409,13 @@ TP_COLORAPP_MOD02;CAM02 TP_COLORAPP_MOD16;CAM16 TP_COLORAPP_MODEL;Witpuntmodel TP_COLORAPP_MODELCAT;CAM +TP_COLORAPP_MODELCAT_TOOLTIP;U kunt kiezen tussen CAM02 of CAM16. CAM02 zal soms nauwkeuriger zijn, maar CAM16 zal minder onregelmatigheden genereren. TP_COLORAPP_MODEL_TOOLTIP;WitpuntmodelWB [RT] + [uitvoer]:\nRT's witbalans wordt gebruikt voor de scène (opname), CIECAM02 gebruikt D50. De witbalans van het uitvoerapparaat (beeldscherm bv.) wordt opgegeven in Weergaveomstandigheden. wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02/16] + [uitvoer]:\nDe witbalansinstellingen van RT worden gebruikt door CAT02 en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden.\n\nFree temp + tint + CAT02/16 + [uitvoer]: kleurtemperatuur en tint worden opgegeven door de gebruiker en de witbalans van het uitvoerapparaat wordt opgegeven in Weergaveomstandigheden. TP_COLORAPP_NEUTRAL;Terugzetten TP_COLORAPP_NEUTRAL_TOOLTIP;Zet alle regelaars, vinkjes en curves terug naar hun standaardwaarde TP_COLORAPP_RSTPRO;Bescherming huid- en rode tinten TP_COLORAPP_RSTPRO_TOOLTIP;Bescherm huid- en rode tinten (schuifbalk en curven) +TP_COLORAPP_SOURCEF_TOOLTIP;Dit gaat over de opname-omstandigheden en hoe deze omstandigheden en data teruggebracht kunnen worden naar een 'normaal' gebied. Normaal betekent gemiddelde of standaardomstandigheden en -data, dat wil zeggen zonder rekening te houden met CIECAM-correcties. TP_COLORAPP_SURROUND;Omgeving TP_COLORAPP_SURROUNDSRC;Omgevingsverlichting TP_COLORAPP_SURROUND_AVER;Gemiddeld @@ -2329,6 +2423,7 @@ TP_COLORAPP_SURROUND_DARK;Donker TP_COLORAPP_SURROUND_DIM;Gedimd TP_COLORAPP_SURROUND_EXDARK;Duister TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden. +TP_COLORAPP_SURSOURCE_TOOLTIP;Verandert tonen en kleuren op basis van de omgevingsomstandigheden van de opnameverlichting. Hoe donkerder de omgevingsomstandigheden, hoe helderder het beeld zal worden. De helderheid van het beeld zal niet worden gewijzigd wanneer de omgeving op gemiddeld is ingesteld. TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid TP_COLORAPP_TCMODE_CHROMA;Chroma TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid @@ -2337,12 +2432,17 @@ TP_COLORAPP_TCMODE_LABEL2;Curve modus 2 TP_COLORAPP_TCMODE_LABEL3;Curve chroma-modus TP_COLORAPP_TCMODE_LIGHTNESS;Lichtheid TP_COLORAPP_TCMODE_SATUR;Verzadiging +TP_COLORAPP_TEMP2_TOOLTIP;Of symmetrische modus temp = Witbalans.\nOf selecteer Lichtbron en stel altijd Tint=1 in.\n\ntemp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 +TP_COLORAPP_TEMPOUT_TOOLTIP;Temperatuur en Tint.\nAfhankelijk van eerder gemaakte keuzes, is de geselecteerde temperatuur:\nWitbalans\ntemp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nVrij. TP_COLORAPP_TEMP_TOOLTIP;Zet altijd Tint=1 om een lichtbron te selecteren.\n\nA temp=2856\nD50 temp=5003\nD55 temp=5503\nD65 temp=6504\nD75 temp=7504 TP_COLORAPP_TONECIE;Tonemappen met CIECAM TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgevinkt zal het toonmappen plaatsvinden in Lab.\nIndien aangevinkt zal toonmappen gebruikmaken van CIECAM02.\nVoorwaarde is dat Tonemappen (Lab/CIECAM02) actief is. +TP_COLORAPP_VIEWINGF_TOOLTIP;Houd rekening met het apparaat waarop het uiteindelijke beeld zal worden bekeken (monitor, tv, projector, printer, enz.) en de omgeving hiervan. Dit proces gebruikt de gegevens van het proces 'Beeldaanpassingen' en past deze aan het apparaat aan, rekening houdend met de weergave-omstandigheden en de omgeving. TP_COLORAPP_VIEWING_ABSOLUTELUMINANCE_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m²) TP_COLORAPP_WBCAM;WB [RT+CAT02] + [uitvoer] TP_COLORAPP_WBRT;WB [RT] + [uitvoer] +TP_COLORAPP_YBOUT_TOOLTIP;Yb is de relatieve luminantie van de achtergrond, uitgedrukt in een grijspercentage. 18% grijs komt overeen met een achtergrondluminantie van 50% uitgedrukt in CIE L.\nDe gegevens zijn gebaseerd op de gemiddelde luminantie van het beeld. +TP_COLORAPP_YBSCEN_TOOLTIP;Yb is de relatieve luminantie van de achtergrond, uitgedrukt in een grijspercentage. 18% grijs komt overeen met een achtergrondluminantie van 50% uitgedrukt in CIE L.\nDe gegevens zijn gebaseerd op de gemiddelde luminantie van het beeld. TP_COLORTONING_AB;o C/L TP_COLORTONING_AUTOSAT;Automatisch TP_COLORTONING_BALANCE;Balans @@ -2490,7 +2590,7 @@ TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de huidskleuren, minimaliseert de a TP_DIRPYREQUALIZER_ARTIF;Verminder onregelmatigheden TP_DIRPYREQUALIZER_HUESKIN;Huidtint TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;De onderste punten zetten het begin van de transitiezone, en de bovenste punten het einde. Daar is het effect het sterkst.\n\nAls je de zone sterk moet verschuiven of als er sprake is van artefacten, dan is de witbalans incorrect.\nJe kunt de zone enigszins wijzigen om te voorkomen dat de rest van de afbeelding wordt beïnvloed. -TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) +TP_DIRPYREQUALIZER_LABEL;Contrast per Detailniveaus (Lab/CIECAM02) TP_DIRPYREQUALIZER_LUMACOARSEST;grofste TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;< Contrast TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast > @@ -2522,7 +2622,7 @@ TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie TP_EXPOSURE_CONTRAST;Contrast TP_EXPOSURE_CURVEEDITOR1;Tooncurve 1 TP_EXPOSURE_CURVEEDITOR2;Tooncurve 2 -TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\n The Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve TP_EXPOSURE_EXPCOMP;Belichtingscompensatie TP_EXPOSURE_HISTMATCHING;Automatische tooncurve TP_EXPOSURE_HISTMATCHING_TOOLTIP;Pas automatisch de curves en schuifregelaars aan (behalve belichtingscompensatie) volgens de in de RAW ingebedde JPEG-afbeelding. @@ -2557,7 +2657,7 @@ TP_FILMNEGATIVE_REF_PICK;Kies witbalans TP_FILMNEGATIVE_REF_SIZE;Grootte: TP_FILMNEGATIVE_REF_TOOLTIP;Kies een grijspunt om de witbalans van het positieve beeld te bepalen. TP_FILMSIMULATION_LABEL;Filmsimulatie -TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee zoekt naar HaldCLUT-afbeeldingen om de Filmsimulatie uit te voeren, maar deze bevinden zich in een map die teveel tijd kost om te lezen.\n Kijk bij Voorkeuren > Beeldverwerking > Filmsimulatie om te zien welke map gebruikt wordt\nAanbevolen wordt om een map te gebruiken die alleen HaldCLUT-afbeeldingen bevat of kies een lege folder als u Filmsimulatie niet wilt gebruiken.\n\nMeer informatie is te vinden in het (Engelstalige) artikel over Filmsimulatie op RawPedia.\n\nWilt u de scan nu afbreken? +TP_FILMSIMULATION_SLOWPARSEDIR;RawTherapee zoekt naar HaldCLUT-afbeeldingen om de Filmsimulatie uit te voeren, maar deze bevinden zich in een map die teveel tijd kost om te lezen.\nKijk bij Voorkeuren > Beeldverwerking > Filmsimulatie om te zien welke map gebruikt wordt\nAanbevolen wordt om een map te gebruiken die alleen HaldCLUT-afbeeldingen bevat of kies een lege folder als u Filmsimulatie niet wilt gebruiken.\n\nMeer informatie is te vinden in het (Engelstalige) artikel over Filmsimulatie op RawPedia.\n\nWilt u de scan nu afbreken? TP_FILMSIMULATION_STRENGTH;Sterkte TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT-map in Voorkeuren TP_FLATFIELD_AUTOSELECT;Automatische selectie @@ -2587,7 +2687,7 @@ TP_GRADIENT_STRENGTH_TOOLTIP;Filtersterkte in stops TP_HLREC_BLEND;Mengen TP_HLREC_CIELAB;CIELab-menging TP_HLREC_COLOR;Kleurherstel -TP_HLREC_COLOROPP;Tegenovergestelde Inpainting +TP_HLREC_COLOROPP;Inpaint opposed TP_HLREC_ENA_TOOLTIP;Kan worden geactiveerd door automatische niveaus TP_HLREC_HLBLUR;Vervaging TP_HLREC_HLTH;Versterking drempel @@ -2607,11 +2707,12 @@ TP_ICM_APPLYLOOKTABLE;DCP-look-tabel TP_ICM_APPLYLOOKTABLE_TOOLTIP;Gebruik de ingebedde DCP-look-tabel. De instelling is alleen actief als de DCP een look-tabel heeft. TP_ICM_BPC;Zwartpuntcompensatie TP_ICM_BW;Zwart en Wit -TP_ICM_DCPILLUMINANT;Illuminant +TP_ICM_DCPILLUMINANT;Lichtbron TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren -TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. +TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP-illuminant moet worden gebruikt. Standaard is dit 'interpoleren'. Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-lichtbron DCP met interpolatie is geselecteerd. TP_ICM_FBW;Zwart-wit TP_ICM_GAMUT;Begrens kleurruimte +TP_ICM_ILLUMPRIM_TOOLTIP;Kies de verlichting die het dichtst bij de opname-omstandigheden ligt.\nWijzigingen kunnen alleen worden aangebracht wanneer de selectie 'Bestemming primaire kleuren' is ingesteld op 'Aangepast (schuifregelaars)'. TP_ICM_INPUTCAMERA;Camera standaard TP_ICM_INPUTCAMERAICC;Camera-specifiek kleurprofiel TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-invoerkleurprofielen. Deze zijn preciezer dan een eenvoudige matrix maar niet beschikbaar voor alle camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en /dccprofiles en worden automatisch geladen gebaseerd op een bestandsnaam die exact overeenkomt met de modelnaam van de camera. @@ -2629,7 +2730,11 @@ TP_ICM_LABGRID_CIEXY;R(x)=%1 R(y)=%2\nG(x)=%3 G(y)=%4\nB(x)=%5 B(y)=%6 TP_ICM_NEUTRAL;Zet terug TP_ICM_NOICM;Geen ICM: sRGB-uitvoer TP_ICM_OUTPUTPROFILE;Uitvoerprofiel -TP_ICM_OUTPUTPROFILE_TOOLTIP;Alle RTv4- of RTv2-profielen zijn met TRC - sRGB: g=2,4 s=12,92\n\nMet de ICC-profielmaker kunt u v4- of v2-profielen creëren met de volgende keuzen:\n-Primaire kleuren: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB en Aangepast\n-TRC: BT709, sRGB, lineair, standaard g=2,2, standaard g=1,8, Aangepast\n-Illuminant: D41, D50, D55, D60, D65, D80, stdA 2856K +TP_ICM_OUTPUTPROFILE_TOOLTIP;Alle RTv4- of RTv2-profielen zijn met TRC - sRGB: g=2,4 s=12,92\n\nMet de ICC-profielmaker kunt u v4- of v2-profielen creëren met de volgende keuzen:\n-Primaire kleuren: Aces AP0, Aces AP1, AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB en Aangepast\n-TRC: BT709, sRGB, lineair, standaard g=2,2, standaard g=1,8, Aangepast\n-Lichtbron: D41, D50, D55, D60, D65, D80, stdA 2856K +TP_ICM_PRIMBLU_TOOLTIP;Primair Blauw:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y=0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 +TP_ICM_PRIMGRE_TOOLTIP;Primair Groen:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y=0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 y=0.7750 +TP_ICM_PRIMILLUM_TOOLTIP;U kunt een afbeelding wijzigen van de oorspronkelijke modus ('werkprofiel') naar een andere modus ('Bestemming primaire kleuren'). Wanneer u een andere kleurmodus voor een afbeelding kiest, veranderen de kleurwaarden in de afbeelding permanent.\n\nHet wijzigen van de 'primaire kleuren' is vrij complex en moeilijk te gebruiken en vereist veel experimenteren.\nHiermee kunnen exotische kleurcorrecties worden gemaakt, zoals bij de kanaalmixer primaire kleuren.\nPas de camerakalibratie aan met 'Aangepast (schuifregelaars)'. +TP_ICM_PRIMRED_TOOLTIP;Primair Rood:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y=0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 TP_ICM_PROFILEINTENT;Weergave-intentie TP_ICM_REDFRAME;Aangepaste primaire kleuren TP_ICM_SAVEREFERENCE;Bewaar referentie-afbeelding @@ -2639,15 +2744,18 @@ TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineaire TIFF-afbeelding op voordat het invo TP_ICM_TONECURVE;Gebruik DCP-tooncurve TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP-tooncurve. De instelling is alleen actief als de geselecteerde DCP een tooncurve bevat. TP_ICM_TRCFRAME;Abstract Profiel +TP_ICM_TRCFRAME_TOOLTIP;Ook bekend als 'synthetische' of 'virtuele' profielen. Deze worden toegepast aan het eind van de verwerkingspijplijn (voor ciecam), waardoor speciale beeldeffecten kunnen worden gecreëerd.\nU kunt wijzigingen aanbrengen in:\n'Toonresponscurve', die de tonen van het beeld aanpast\n'Verlichting', waarmee de primaire kleuren van het profiel worden aangepast aan de opnamemstandigheden.\n'Primaire kleuren Bestemming': waarmee u de Primaire kleuren Bestemming kunt wijzigen met drie hoofdtoepassingen - kanalenmixer, herstel beeldkleur (verzadiging) en kalibratie.\nOpmerking: Abstracte profielen maken gebruik van de ingebouwde werkprofielen zonder deze te wijzigen. Ze werken niet met aangepaste werkprofielen. +TP_ICM_TRC_TOOLTIP;Hiermee kunt u de standaard sRGB Toonresponscurve in RT wijzigen (g=2.4 s=12.92).\nDeze TRC wijzigt de tonen van het beeld. De RGB- en Lab-waarden, het histogram en de uitvoer (scherm, TIF, JPG) worden gewijzigd:\n-Gamma werkt voornamelijk op lichte tonen \n-Hellingshoek werkt voornamelijk op donkere tonen.\nU kunt willekeurige gamma en hellingshoek-paren (waarden >1) kiezen en het algoritme zorgt ervoor dat er continuïteit is tussen de lineaire en parabolische delen van de curve.\nEen andere selectie dan 'Geen' activeert de menu's 'Verlichting' en 'Primaire kleuren Bestemming'. TP_ICM_WORKINGPROFILE;Werkprofiel -TP_ICM_WORKING_CAT;Aanpassing matrix +TP_ICM_WORKING_CAT;Matrixaanpassing TP_ICM_WORKING_CAT_BRAD;Bradford TP_ICM_WORKING_CAT_CAT02;Cat02 TP_ICM_WORKING_CAT_CAT16;Cat16 +TP_ICM_WORKING_CAT_TOOLTIP;Voert de chromatische aanpassing van de XYZ-conversiematrix uit. Standaard: Bradford TP_ICM_WORKING_CAT_VK;Von Kries TP_ICM_WORKING_CAT_XYZ;XYZ-schaal TP_ICM_WORKING_CIEDIAG;CIE xy diagram -TP_ICM_WORKING_ILLU;Illuminant +TP_ICM_WORKING_ILLU;Lichtbron TP_ICM_WORKING_ILLU_1500;Tungsten 1500K TP_ICM_WORKING_ILLU_2000;Tungsten 2000K TP_ICM_WORKING_ILLU_D41;D41 @@ -2657,10 +2765,13 @@ TP_ICM_WORKING_ILLU_D60;D60 TP_ICM_WORKING_ILLU_D65;D65 TP_ICM_WORKING_ILLU_D80;D80 TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_E;E TP_ICM_WORKING_ILLU_NONE;Standaard TP_ICM_WORKING_ILLU_STDA;stdA 2875K -TP_ICM_WORKING_PRESER;Beschermt pasteltinten +TP_ICM_WORKING_NON;Geen +TP_ICM_WORKING_PRESER;Bescherm pasteltinten TP_ICM_WORKING_PRIM;Bestemming primaire kleuren +TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Wanneer 'Aangepast CIE xy-diagram' is geselecteerd in de combobox Primaire kleuren Bestemming, kunt u de waarden van de drie primaire kleuren direct op de grafiek wijzigen.\nMerk op dat in dit geval de positie van het witpunt op de grafiek niet wordt bijgewerkt. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2668,12 +2779,15 @@ TP_ICM_WORKING_PRIM_BET;Beta RGB TP_ICM_WORKING_PRIM_BRU;BruceRGB TP_ICM_WORKING_PRIM_BST;BestRGB TP_ICM_WORKING_PRIM_CUS;Aangepast (schuiven) -TP_ICM_WORKING_PRIM_CUSGR;Custom (CIE xy diagram) +TP_ICM_WORKING_PRIM_CUSGR;Aangepast (CIE xy-diagram) +TP_ICM_WORKING_PRIM_FREE;Aangepast LA (schuiven) TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA TP_ICM_WORKING_PRIM_NONE;Standaard TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_TOOLTIP;Controleert de kleuromvang (gamut). Primaire kleuren Bestemming (Geavanceerd) stelt u in staat om de primaire kleuren van de bestemming te wijzigen, om de kleur van het beeld (verzadiging) te herstellen of te veranderen. De kleurbalans blijft behouden wanneer het 'Werkprofiel' en de 'Primaire kleuren Bestemming' gelijk zijn. Het 'Werkprofiel' wordt niet gewijzigd.\nWanneer 'Aangepast LA (schuiven)' is geselecteerd, kunt u de waarden van de drie primaire kleuren (Rood, Groen en Blauw) voor x en y wijzigen. TP_ICM_WORKING_PRIM_WID;WideGamut TP_ICM_WORKING_TRC;Tooncurve: TP_ICM_WORKING_TRC_18;Prophoto g=1,8 @@ -2681,7 +2795,7 @@ TP_ICM_WORKING_TRC_22;Adobe g=2,2 TP_ICM_WORKING_TRC_BT709;BT709 g=2,22 s=4,5 TP_ICM_WORKING_TRC_CUSTOM;Door gebruiker gedefinieerd TP_ICM_WORKING_TRC_GAMMA;Gamma -TP_ICM_WORKING_TRC_LIN;Linear g=1 +TP_ICM_WORKING_TRC_LIN;Lineair g=1 TP_ICM_WORKING_TRC_NONE;Geen TP_ICM_WORKING_TRC_SLOPE;Helling TP_ICM_WORKING_TRC_SRGB;sRGB g=2,4 s=12,92 @@ -2731,6 +2845,7 @@ TP_LENSGEOM_LOG;Logarithmisch TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatische selectie TP_LENSPROFILE_CORRECTION_LCPFILE;LCP-bestand TP_LENSPROFILE_CORRECTION_MANUAL;Handmatige selectie +TP_LENSPROFILE_CORRECTION_METADATA;Uit metadata bestand TP_LENSPROFILE_LABEL;Lenscorrectieprofielen TP_LENSPROFILE_LENS_WARNING;Waarschuwing: de gebruikte bijsnijdfactor van het lensprofiel komt niet overeen met de bijsnijdfactor van de camera, de resultaten kunnen onjuist zijn. TP_LENSPROFILE_MODE_HEADER;Lensprofiel @@ -2748,14 +2863,18 @@ TP_LOCALLAB_ACTIVSPOT;Activeer spot TP_LOCALLAB_ADJ;Kleurequalizer TP_LOCALLAB_AMOUNT;Hoeveelheid TP_LOCALLAB_ARTIF;Vormdetectie +TP_LOCALLAB_ARTIF_TOOLTIP;De ΔE-bereikdrempel vergroot het ΔE-bereik. Hoge waarden zijn voor beelden met een zeer groot kleurbereik.\nDoor het ΔE-verval te vergroten kan de vormdetectie verbeterd worden maar ook het bereik gereduceerd. TP_LOCALLAB_AUTOGRAY;Autom. gemiddelde luminantie (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Auto TP_LOCALLAB_AVOID;Voorkom kleurverschuiving +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Pas kleuren aan tot ze binnen het bereik van de werkkleurruimte vallen en pas Munsell-correctie toe (Uniform Perceptual Lab). Standaard: Alleen Munsell.\n\nAlleen Munsell: Corrigeert tintafwijkingen in de Lab-modus als gevolg van non-lineariteit wanneer de chromaticiteit wordt gewijzigd (Uniform Perceptual Lab).\nLab: Past een gamutcontrole toe in relatieve colorimetrie. Vervolgens wordt Munsell toegepast.\nXYZ Absoluut: Past gamutcontrole toe in absolute colorimetrie. Vervolgens wordt Munsell toegepast.\nXYZ Relatief: Past gamutcontrole toe in relatieve colorimetrie. Vervolgens wordt Munsell toegepast. Het resultaat is niet hetzelfde als bij Lab. TP_LOCALLAB_AVOIDMUN;Alleen Munsell-correctie +TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell-correctie is altijd uitgeschakeld wanneer Jz of CAM16 wordt gebruikt. TP_LOCALLAB_AVOIDRAD;Verzachtingsstraal TP_LOCALLAB_BALAN;ab-L-balans (ΔE) TP_LOCALLAB_BALANEXP;Laplacian-balans TP_LOCALLAB_BALANH;C-H-balans (ΔE) +TP_LOCALLAB_BALAN_TOOLTIP;Wijzigt de parameters van het ΔE-algoritme.\nHoudt meer of minder rekening met a*b* of L*, of meer of minder C of H.\nNiet voor ruisonderdrukking. TP_LOCALLAB_BASELOG;Bereik schaduwen (logaritmische basis) TP_LOCALLAB_BILATERAL;Bilateraal filter TP_LOCALLAB_BLACK_EV;Zwart LW @@ -2763,21 +2882,29 @@ TP_LOCALLAB_BLCO;Alleen chrominantie TP_LOCALLAB_BLENDMASKCOL;Meng TP_LOCALLAB_BLENDMASKMASK;Voeg toe/trek af luma-masker TP_LOCALLAB_BLENDMASKMASKAB;Voeg toe/trek af chroma-masker +TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;Schuifregelaar op 0, geen actie.\nVoeg het masker toe aan of trek het af van de originele afbeelding. +TP_LOCALLAB_BLENDMASK_TOOLTIP;Als mengen = 0 wordt alleen de vormdetectie verbeterd.\nAls mengen > 0 wordt het masker aan de afbeelding toegevoegd. Als mengen < 0 wordt het masker van de afbeelding afgetrokken. TP_LOCALLAB_BLGUID;Begeleid filter TP_LOCALLAB_BLINV;Inverteer TP_LOCALLAB_BLLC;Luminantie & Chrominantie TP_LOCALLAB_BLLO;Alleen luminantie TP_LOCALLAB_BLMED;Mediaan +TP_LOCALLAB_BLMETHOD_TOOLTIP;Normaal: direct vervagen en ruis met alle instellingen.\nInvers: vervagen en ruis met alle instellingen. Waarschuwing, sommige instellingen kunnen vreemde resultaten geven. TP_LOCALLAB_BLNOI_EXP;Vervaging & Ruis TP_LOCALLAB_BLNORM;Normaal TP_LOCALLAB_BLUFR;Vervaging/Korrel & Ruisvermindering +TP_LOCALLAB_BLUMETHOD_TOOLTIP;Om de achtergrond te vervagen en de voorgrond te isoleren:\n-vervaging van de achtergrond door de afbeelding volledig te bedekken met een spot (hoge waarden voor bereik en overgang en 'Normaal' of 'Invers' in het selectievakje).\n-Isoleren van de voorgrond door een of meer 'Uitsluitende' spots te gebruiken en het bereik te vergroten.\n\nDeze module (inclusief Mediaan en Guided filter) kan worden gebruikt als aanvulling op de ruisonderdrukking in het hoofdmenu. TP_LOCALLAB_BLUR;Gaussiaanse vervaging - Ruis - Korrel TP_LOCALLAB_BLURCOL;Straal +TP_LOCALLAB_BLURCOLDE_TOOLTIP;De afbeelding die wordt gebruikt om ΔE te berekenen, wordt lichtelijk vervaagd om te voorkomen dat geïsoleerde pixels in de berekening worden meegenomen. TP_LOCALLAB_BLURDE;Vormdetectie vervaging TP_LOCALLAB_BLURLC;Alleen luminantie TP_LOCALLAB_BLURLEVELFRA;Vervagingsniveaus +TP_LOCALLAB_BLURMASK_TOOLTIP;Gebruikt een vervaging met een grote straal om een masker te creëren waarmee het contrast van de afbeelding gevarieerd kan worden en/of delen ervan donkerder of lichter te maken. +TP_LOCALLAB_BLURRMASK_TOOLTIP;Hiermee wordt de straal van de Gaussische vervaging gewijzigd (0 tot 1000). TP_LOCALLAB_BLUR_TOOLNAME;Vervaging/Korrel & Ruisvermindering TP_LOCALLAB_BLWH;Alle veranderingen forceren in zwart-wit +TP_LOCALLAB_BLWH_TOOLTIP;Dwingt de kleurcomponenten 'a' en 'b' naar nul.\nHandig voor zwart-witverwerking of filmsimulatie. TP_LOCALLAB_BUTTON_ADD;Voeg toe TP_LOCALLAB_BUTTON_DEL;Wis TP_LOCALLAB_BUTTON_DUPL;Dupliceer @@ -2785,14 +2912,19 @@ TP_LOCALLAB_BUTTON_REN;Hernoem TP_LOCALLAB_BUTTON_VIS;Toon/verberg TP_LOCALLAB_BWEVNONE;Geen TP_LOCALLAB_BWEVSIG;Geactiveerd +TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-codering TP_LOCALLAB_BWFORCE;Gebruik Zwart LW & Wit LW TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Piekluminantie) +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) aangepast aan CAM16 (experimenteel). Hiermee kunt u de interne PQ-functie wijzigen (meestal 10000 cd/m2 - standaard 100 cd/m2 - uitgeschakeld voor 100 cd/m2).\nKan bijvoorbeeld worden gebruikt om CAM16-verwerking af te stemmen op de maximale monitorhelderheid van 400 cd/m2. TP_LOCALLAB_CAM16_FRA;Cam16 Beeldaanpassingen TP_LOCALLAB_CAMMODE;CAM-model TP_LOCALLAB_CAMMODE_CAM16;CAM 16 TP_LOCALLAB_CAMMODE_JZ;Jz Cz Hz TP_LOCALLAB_CATAD;Chromatische aanpassing/Cat16 TP_LOCALLAB_CBDL;Contrast per Detailniveaus +TP_LOCALLAB_CBDLCLARI_TOOLTIP;Verbetert het lokale contrast van de middentonen. +TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Zelfde als wavelets.\nHet eerste niveau (0) werkt op details van 2x2 pixels.\nHet laatste niveau (5) werkt op details van 64x64 pixels. +TP_LOCALLAB_CBDL_THRES_TOOLTIP;Voorkomt het verscherpen van ruis. TP_LOCALLAB_CBDL_TOOLNAME;Contrast per Detailniveaus TP_LOCALLAB_CENTER_X;Centrum X TP_LOCALLAB_CENTER_Y;Centrum Y @@ -2801,13 +2933,17 @@ TP_LOCALLAB_CHRO46LABEL;Chroma-niveaus 456: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_CHROLABEL;Chroma-niveaus 0123: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_CHROMA;Chrominantie TP_LOCALLAB_CHROMABLU;Chroma-niveaus +TP_LOCALLAB_CHROMABLU_TOOLTIP;Vergroot of vermindert het effect afhankelijk van de luma-instellingen.\nWaarden onder 1 verminderen het effect. Waarden boven 1 vergroten het effect. TP_LOCALLAB_CHROMACBDL;Chroma +TP_LOCALLAB_CHROMACB_TOOLTIP;Vergroot of vermindert het effect afhankelijk van de luma-instellingen.\nWaarden onder 1 verminderen het effect. Waarden boven 1 vergroten het effect. TP_LOCALLAB_CHROMALEV;Chroma-niveaus TP_LOCALLAB_CHROMASKCOL;Chroma +TP_LOCALLAB_CHROMASK_TOOLTIP;Wijzigt de chroma van het masker als er een bestaat (d.w.z. C(C) of LC(H) is geactiveerd). TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chroma TP_LOCALLAB_CIE;Kleurweergave (Cam16 & JzCzHz) TP_LOCALLAB_CIEC;Gebruik Ciecam omgevingsparameters +TP_LOCALLAB_CIECAMLOG_TOOLTIP;Deze module is gebaseerd op het CIECAM-kleurverschijningsmodel, dat is ontworpen om beter te simuleren hoe het menselijk oog kleuren waarneemt onder verschillende lichtomstandigheden.\nHet eerste Ciecam-proces 'Opname-omstandigheden' wordt uitgevoerd met log-codering en maakt gebruik van 'Absolute luminantie' op het moment van opname.\nHet tweede Ciecam-proces 'Beeldaanpassingen' is vereenvoudigd en gebruikt slechts drie variabelen (lokaal contrast, contrast J, verzadiging s).\nHet derde Ciecam-proces 'Weergaveomstandigheden' past de uitvoer aan de beoogde weergaveomstandigheden aan (monitor, tv, projector, printer, enz.), zodanig dat de kleuren en het contrast behouden blijven in de weergaveomgeving. TP_LOCALLAB_CIECOLORFRA;Kleur TP_LOCALLAB_CIECONTFRA;Contrast TP_LOCALLAB_CIELIGHTCONTFRA;Verlichting & Contrast @@ -2816,6 +2952,7 @@ TP_LOCALLAB_CIEMODE;Verander gereedschapspositie TP_LOCALLAB_CIEMODE_COM;Standaard TP_LOCALLAB_CIEMODE_DR;Dynamisch bereik TP_LOCALLAB_CIEMODE_TM;Toonmappen +TP_LOCALLAB_CIEMODE_TOOLTIP;In de standaardmodus wordt Ciecam aan het einde van het proces toegevoegd. 'Masker en modificaties' en 'Herstel volgens luminantiemasker' zijn beschikbaar voor 'Cam16 en JzCzHz'.\nU kunt Ciecam ook integreren met andere gereedschappen (TM, Wavelet, Dynamisch Bereik, Log-codering). De resultaten met deze gereedschappen zullen anders zijn dan zonder Ciecam. In deze modus kunt u ook 'Masker en modificaties' en 'Herstel volgens luminantiemasker' gebruiken. TP_LOCALLAB_CIEMODE_WAV;Wavelet TP_LOCALLAB_CIETOOLEXP;Curven TP_LOCALLAB_CIE_SMOOTHFRAME;Versterking hoge lichten & Niveaus @@ -2826,48 +2963,78 @@ TP_LOCALLAB_CIE_SMOOTH_LEVELS;Niveaus TP_LOCALLAB_CIE_SMOOTH_NONE;Geen TP_LOCALLAB_CIE_TOOLNAME;Kleurweergave (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Spotgrootte +TP_LOCALLAB_CIRCRAD_TOOLTIP;Bevat de referenties van de spot, nuttig voor vormdetectie (tint, luma, chroma, Sobel).\nLage waarden kunnen nuttig zijn bij het verwerken van gebladerte.\nGebruik hoge waarden voor huidtinten. TP_LOCALLAB_CLARICRES;Meng chroma TP_LOCALLAB_CLARIFRA;Klaarheid (Clarity) & Scherptemasker/Meng & Verzacht beelden +TP_LOCALLAB_CLARIJZ_TOOLTIP;Niveaus 0 tot en met 4: Scherptemasker is ingeschakeld\nNiveaus 5 en hoger: Klaarheid (Clarity) is ingeschakeld. TP_LOCALLAB_CLARILRES;Meng luma TP_LOCALLAB_CLARISOFT;Verzacht straal +TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;De schuifregelaar Verzachtingsstraal (Begeleid filter) vermindert halo's en onregelmatigheden voor Klaarheid (Clarity), Scherptemasker en Lokaal contrast wavelets Jz. +TP_LOCALLAB_CLARISOFT_TOOLTIP;De schuifregelaar Verzachtingsstraal (Begeleid filter) vermindert halo's en onregelmatigheden voor Klaarheid (Clarity), Scherptemasker en alle wavelet-piramideprocessen. Zet de schuif op 0 om dit te deactiveren. TP_LOCALLAB_CLARITYML;Klaarheid (Clarity) +TP_LOCALLAB_CLARI_TOOLTIP;Niveaus 0 tot en met 4: Scherptemasker is ingeschakeld.\nNiveaus 5 en hoger: Helderheid is ingeschakeld.\nNuttig bij toonmappen met wavelet-niveaus. TP_LOCALLAB_CLIPTM;Kap herstelde data af (versterking) TP_LOCALLAB_COFR;Kleur & Licht TP_LOCALLAB_COLORDE;ΔE Voorbeeldkleur - intensiteit +TP_LOCALLAB_COLORDEPREV_TOOLTIP;De voorvertoningsknop voor ΔE in Instellingen werkt alleen als Verscherping, Zacht Licht en Originele Retinex, Vervagen/Korrel en Ruisvermindering, Nevel Verwijderen en Retinex of Contrast per Detailniveaus zijn geactiveerd in het menu 'Voeg gereedschap toe aan huidige spot'.\nVoor andere gereedschappen bevindt de Voorvertoningsknop ΔE zich in de tool, waarmee ΔE wordt voorvertoond met meerdere ingeschakelde gereedschappen. Geef de voorkeur aan Masker en modificaties. +TP_LOCALLAB_COLORDE_TOOLTIP;Toont een blauwe kleurvoorvertoning van de ΔE-selectie indien negatief en groen indien positief.\n\nMasker en modificaties (toon gemodificeerde gebieden zonder masker): toon daadwerkelijke modificaties als positief, toon verbeterde modificaties (alleen luminantie) met blauw en geel indien negatief. TP_LOCALLAB_COLORFRAME;Dominante kleur TP_LOCALLAB_COLORSCOPE;Bereik (kleurgereedschappen) +TP_LOCALLAB_COLORSCOPE_TOOLTIP;Gemeenschappelijke bereikschuif voor Kleur en Licht, Schaduwen/Hoge lichten, Levendigheid.\nAndere hulpmiddelen hebben hun eigen bereikregelaars. TP_LOCALLAB_COLOR_CIE;Kleurcurve TP_LOCALLAB_COLOR_TOOLNAME;Kleur & Licht TP_LOCALLAB_COL_NAME;Naam TP_LOCALLAB_COL_VIS;Status TP_LOCALLAB_COMPFRA;Directioneel contrast TP_LOCALLAB_COMPRCIE;Helderheidscompressie +TP_LOCALLAB_COMPRCIETH;Compressiedrempel TP_LOCALLAB_COMPREFRA;Wavelet-niveau toonmappen +TP_LOCALLAB_COMPRLOG_TOOLTIP;Dit algoritme comprimeert de gegevens vòòr de logconversie, boven de drempelwaarde van de schuif. Te gebruiken in combinatie met Witdistributie. TP_LOCALLAB_CONTCOL;Contrastdrempel TP_LOCALLAB_CONTFRA;Contrast per niveau TP_LOCALLAB_CONTRAST;Contrast +TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Hiermee kunt u het contrast van het masker vrij aanpassen.\nHet heeft een vergelijkbare functie als de Gamma- en Helling-schuiven.\nHiermee kunt u bepaalde delen van het beeld bewerken (meestal de lichtste delen van het masker door de curve te gebruiken om de donkere delen uit te sluiten). Dit kan artefacten veroorzaken. TP_LOCALLAB_CONTRESID;Contrast +TP_LOCALLAB_CONTTHMASK_TOOLTIP;Hiermee kunt u bepalen welke delen van het beeld worden beïnvloed op basis van de textuur. TP_LOCALLAB_CONTTHR;Contrastdrempel TP_LOCALLAB_CONTWFRA;Lokaal contrast TP_LOCALLAB_CSTHRESHOLD;Wavelet-niveaus TP_LOCALLAB_CSTHRESHOLDBLUR;Selecteer Wavelet-niveau TP_LOCALLAB_CURV;Lichtheid - Contrast - Chrominantie 'Super' TP_LOCALLAB_CURVCURR;Normaal +TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;Als de curven bovenaan staan, is het masker volledig zwart en worden er geen wijzigingen aangebracht in het beeld.\nAls de curve naar beneden wordt geplaatst, wordt het masker geleidelijk kleurrijker en helderder, waardoor het beeld progressief verandert.\n\nHet wordt aanbevolen (maar is niet verplicht) om de bovenkant van de curven op de grijze grenslijn te plaatsen die de referentiewaarden van chroma, luma en tint voor de spot weergeeft. +TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;Als de curven bovenaan staan, is het masker volledig zwart en worden er geen wijzigingen aangebracht in het beeld.\nAls de curve naar beneden wordt geplaatst, wordt het masker geleidelijk kleurrijker en helderder, waardoor het beeld progressief verandert.\n\nHet wordt aanbevolen (maar is niet verplicht) om de bovenkant van de curven op de grijze grenslijn te plaatsen die de referentiewaarden van chroma, luma en tint voor de spot weergeeft. +TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;Om de curves te activeren, stelt u het Curvetype in de combobox in op 'Normaal'. TP_LOCALLAB_CURVEEDITOR_TONES_LABEL;Tooncurve +TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), kan worden gebruikt met L(H) in Kleur en Licht. +TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normaal', de curve L=f(L) gebruikt hetzelfde algoritme als de helderheidsschuif. TP_LOCALLAB_CURVES_CIE;Tooncurven TP_LOCALLAB_CURVNONE;De-activeer curven TP_LOCALLAB_DARKRETI;Donker TP_LOCALLAB_DEHAFRA;Ontnevelen TP_LOCALLAB_DEHAZ;Kracht TP_LOCALLAB_DEHAZE_BLACK;Zwart +TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Verwijdert atmosferische nevel. Verhoogt de algehele verzadiging en detail.\nKan kleurzweem verwijderen, maar kan ook een blauwzweem introduceren die met andere hulpmiddelen kan worden gecorrigeerd. +TP_LOCALLAB_DEHAZ_TOOLTIP;Negatieve waarden voegen nevel toe. TP_LOCALLAB_DELTAD;Delta-balans TP_LOCALLAB_DELTAEC;ΔE Beeldmasker TP_LOCALLAB_DENOI1_EXP;Ruisvermindering volgens luminantiemasker TP_LOCALLAB_DENOI2_EXP;Herstel volgens luminantiemasker +TP_LOCALLAB_DENOIBILAT_TOOLTIP;Hiermee kunt u impuls- of 'zout en peper'-ruis verminderen. +TP_LOCALLAB_DENOICHROC_TOOLTIP;Hiermee kunt u ruisvlekken aanpakken. +TP_LOCALLAB_DENOICHRODET_TOOLTIP;Hiermee kunt u chrominantiedetails herstellen door geleidelijk een Fourier-transformatie (DCT) toe te passen. +TP_LOCALLAB_DENOICHROF_TOOLTIP;Hiermee kunt u chrominantieruis in fijne details aanpassen. +TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Hiermee kunt u de chromaruisreductie of op blauw-gele of op rood-groene kleuren richten. +TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Hiermee kunt u meer of minder ruisreductie uitvoeren in de schaduwen of de hoge lichten. +TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Hiermee kunt u luminantiedetails herstellen door geleidelijk een Fourier-transformatie (DCT) toe te passen. TP_LOCALLAB_DENOIMASK;Chroma-masker ruisvermindering +TP_LOCALLAB_DENOIMASK_TOOLTIP;Voor alle hulpmiddelen is hiermee het chromatische ruisniveau van het masker te regelen.\nHandig voor een betere controle van de chrominantie en om onregelmatigheden te vermijden bij gebruik van de LC(h)-curve. +TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservatieve modus behoudt lage frequentiedetails. Agressieve modus verwijdert lage frequentiedetails.\nConservatieve en agressieve modi gebruiken wavelets en DCT en kunnen worden gebruikt in combinatie met 'Non-local Means – Luminance'. +TP_LOCALLAB_DENOITHR_TOOLTIP;Past randdetectie aan om te helpen ruis in uniforme, laag-contrastgebieden te verminderen. TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominantie TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminantie TP_LOCALLAB_DENOI_EXP;Ruisvermindering +TP_LOCALLAB_DENOI_TOOLTIP;Deze module kan worden gebruikt voor ruisreductie, hetzij op zichzelf (aan het einde van de verwerkingspijplijn) of in aanvulling op de module Ruisreductie in het Detailtabblad (die aan het begin van de pijplijn werkt).\nMet Bereik kunt u de actie differentiëren op basis van kleur (ΔE).\nMinimale spotgrootte: 128x128. TP_LOCALLAB_DEPTH;Diepte TP_LOCALLAB_DETAIL;Lokaal contrast TP_LOCALLAB_DETAILFRA;Randdetectie - DCT @@ -2883,10 +3050,12 @@ TP_LOCALLAB_ENABLE_AFTER_MASK;Gebruik toonmappen TP_LOCALLAB_ENABLE_MASK;Activeer masker TP_LOCALLAB_ENABLE_MASKAFT;Gebruik alle algoritmen Belichting TP_LOCALLAB_ENABLE_MASKALL;Gebruik alle maskergereedschappen +TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;Indien ingeschakeld, gebruikt het masker Herstelde Data na de Transmissiekaart in plaats van Originele Data. TP_LOCALLAB_ENH;Verbeterd TP_LOCALLAB_ENHDEN;Verbeterd + chroma-ruisonderdrukking TP_LOCALLAB_EPSBL;Detail TP_LOCALLAB_EQUIL;Normaliseer luminantie +TP_LOCALLAB_EQUILTM_TOOLTIP;Herstel luminantie zodat het gemiddelde en de variantie van de uitvoerafbeelding identiek zijn aan die van het origineel. TP_LOCALLAB_ESTOP;Randbehoud TP_LOCALLAB_EV_DUPL;Kopie van TP_LOCALLAB_EV_NVIS;Verberg @@ -2894,38 +3063,62 @@ TP_LOCALLAB_EV_NVIS_ALL;Verberg allemaal TP_LOCALLAB_EV_VIS;Toon TP_LOCALLAB_EV_VIS_ALL;Toon alles TP_LOCALLAB_EXCLUF;Uitsluiting +TP_LOCALLAB_EXCLUF_TOOLTIP;De modus 'Uitsluiten' voorkomt dat aangrenzende spots bepaalde delen van het beeld beïnvloeden. Door 'Bereik' aan te passen, wordt het kleurbereik vergroot.\nU kunt ook gereedschappen toevoegen aan een Uitgesloten spot en deze op dezelfde manier gebruiken als bij een normale spot. TP_LOCALLAB_EXCLUTYPE;Spotmethode +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Een normale spot gebruikt recursieve data.\n\nEen uitsluitspot initialiseert alle selectieve bewerkingsdata opnieuw.\nKan worden gebruikt om een vorige actie geheel of gedeeltelijk te annuleren of om bewerkingen in de omgekeerde modus uit te voeren.\nGebruik 'Bereik' (Uitsluiten) om de uitsluitingsintensiteit in te stellen.\n\n'Volledige afbeelding' stelt u in staat om de selectieve bewerkingsgereedschappen op de hele afbeelding te gebruiken.\nDe RT Spot-begrenzers worden buiten de preview-grenzen van de afbeelding geplaatst.\nDe overgang is ingesteld op 100.\nOpmerking: Mogelijk moet u de RT Spot iets verplaatsen en de spotgrootte aanpassen om het gewenste effect te bereiken.\nOpmerking2: Het gebruik van Ruisonderdrukking, Wavelets of FFTW in volledige afbeeldingsmodus gebruikt grote hoeveelheden geheugen en kan ervoor zorgen dat de applicatie crasht op systemen met een lagere capaciteit.\n\n'Globaal' stelt u in staat om de selectieve bewerkingsgereedschappen op de hele afbeelding te gebruiken, zonder Delta E of transities. TP_LOCALLAB_EXECLU;Sluit spot uit TP_LOCALLAB_EXFULL;Volledige afbeelding TP_LOCALLAB_EXMAIN;Globaal TP_LOCALLAB_EXNORM;Normale spot +TP_LOCALLAB_EXPCBDL_TOOLTIP;Kan worden gebruikt om vlekken op de sensor of lens te verwijderen door het contrast op de juiste detailniveau te verminderen. TP_LOCALLAB_EXPCHROMA;Chroma-compensatie +TP_LOCALLAB_EXPCHROMA_TOOLTIP;Gebruik in combinatie met 'Belichtingscompensatie f' en 'Contrastverzwakker f' om de kleurverzadiging te behouden. +TP_LOCALLAB_EXPCOLOR_TOOLTIP;Pas kleur, helderheid en contrast aan en corrigeer kleine gebreken zoals rode ogen, stof op de sensor, enz. TP_LOCALLAB_EXPCOMP;Belichtingscompensatie ƒ TP_LOCALLAB_EXPCOMPINV;Belichtingscompensatie +TP_LOCALLAB_EXPCOMP_TOOLTIP;Voor portretten of afbeeldingen met een gering kleurverloop. U kunt 'Vormdetectie' wijzigen in 'Instellingen':\n\nVerhoog 'ΔE-bereikdrempel'\nVerlaag 'ΔE-verval'\nVerhoog 'ab-L balans (ΔE)' +TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Zie de documentatie voor Wavelet-niveaus.\nEr zijn enkele verschillen in de Selectieve bewerkingsversie, die meer gereedschappen en mogelijkheden heeft om aan afzonderlijke detailniveaus te werken.\nBijvoorbeeld toonmapping met Wavelet-niveaus. +TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Vermijd spots die te klein zijn (< 32x32 pixels).\nGebruik een lage 'Transitiewaarde' en een hoge waarde voor 'Transitieverval' en 'Bereik' om kleine spots te simuleren en defecten aan te pakken.\nGebruik 'Helderheid en scherptemasker' en 'Meng en verzacht beelden' indien nodig door 'Zachte straal' aan te passen om artefacten te verminderen. TP_LOCALLAB_EXPCURV;Curven TP_LOCALLAB_EXPGRAD;Verloopfilter +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Een verloopfilter is beschikbaar in Kleur en Licht (luminantie, chrominantie & tintverlopen en 'Voeg bestand samen'), Belichting (luminantieverloop), Belichtingsmasker (luminantieverloop), Schaduwen/Hoge lichten (luminantieverloop), Levendigheid (luminantie, chrominantie & tintverlopen), Lokaal contrast & wavelet-piramide (lokaal contrastverloop).\nVervaging bevindt zich in Instellingen. +TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Wijzigt de menging van de getransformeerde/originele afbeelding. +TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Wijzigt het gedrag voor afbeeldingen met te veel of te weinig contrast door een gammacurve toe te voegen vóór en na de Laplace-transformatie. +TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Wijzigt het gedrag voor onderbelichte foto's door een lineaire component toe te voegen vóór het toepassen van de Laplace-transformatie. +TP_LOCALLAB_EXPLAP_TOOLTIP;Door de schuif naar rechts te verplaatsen, wordt het contrast geleidelijk verminderd. +TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Stelt u in staat om GIMP- of Photoshop-laagmengmodi (verschil, vermenigvuldigen, zacht licht, overlay, enz.) met ondoorzichtigheidsregeling te gebruiken.\nOriginele afbeelding: huidige spot mengen met origineel.\nVorige spot: huidige spot mengen met vorige (als er slechts één spot is, is vorige = origineel).\nAchtergrond: huidige spot mengen met een kleur- en luminantie-achtergrond (minder mogelijkheden). +TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Past een mediaanfilter toe vóór de Laplace-transformatie om artefacten (ruis) te voorkomen.\nU kunt ook het gereedschap 'Ruisonderdrukking' gebruiken. TP_LOCALLAB_EXPOSE;Dynamisch bereik & Belichting +TP_LOCALLAB_EXPOSURE_TOOLTIP;Wijzig belichting in L*a*b-ruimte met behulp van Laplacian PDE-algoritmen op basis van dE en minimaliseer onregelmatigheden. TP_LOCALLAB_EXPRETITOOLS;Geavanceerde Retinex-gereedschappen +TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimaal 39x39.\nGebruik lage overgangswaarden en hoge 'Transitieverval' en 'Bereik'-waarden om kleinere spots te simuleren. TP_LOCALLAB_EXPTOOL;Belichtingsgereedschappen TP_LOCALLAB_EXP_TOOLNAME;Dynamisch bereik & Belichting TP_LOCALLAB_FATAMOUNT;Hoeveelheid TP_LOCALLAB_FATANCHOR;Anker TP_LOCALLAB_FATDETAIL;Detail TP_LOCALLAB_FATFRA;Compressie dynamisch bereik ƒ +TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – gebruik het Fattal Toonmapping algoritme. TP_LOCALLAB_FATLEVEL;Sigma TP_LOCALLAB_FATSAT;Beperk verzadiging TP_LOCALLAB_FATSHFRA;Masker compressie dynamisch bereik ƒ -TP_LOCALLAB_FEATVALUE;Veerverloop (Verloopfilters) -TP_LOCALLAB_FEATVALUE_MASK;Veerverloop (Grad. Filters Masker) +TP_LOCALLAB_FEATH_TOOLTIP;Verloopbreedte als percentage van de spotdiagonaal\nWordt gebruikt door alle verloopfilters in alle gereedschappen.\nGeen actie als er geen gradiëntfilter is geactiveerd. +TP_LOCALLAB_FEATVALUE;Veerverzachting +TP_LOCALLAB_FEATVALUE_MASK;Veerverzachting (Verloopfilters-masker) TP_LOCALLAB_FFTCOL_MASK;FFTW ƒ +TP_LOCALLAB_FFTMASK_TOOLTIP;Gebruik een Fourier-transformatie voor betere kwaliteit (langere verwerkingstijd en meer geheugengebruik). TP_LOCALLAB_FFTW;ƒ - Gebruik Fast Fourier-transformatie TP_LOCALLAB_FFTWBLUR;ƒ - Gebruik altijd Fast Fourier-transformatie TP_LOCALLAB_FULLIMAGE;Zwart LW en Wit LW voor volledige afbeelding +TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Berekent de LW-niveaus voor de hele afbeelding. TP_LOCALLAB_GAM;Gamma TP_LOCALLAB_GAMC;Gamma +TP_LOCALLAB_GAMCOL_TOOLTIP;Pas een gamma toe op Luminantie L*a*b*-data.\nAls gamma = 3.0 wordt Luminantie 'lineair' gebruikt. +TP_LOCALLAB_GAMC_TOOLTIP;Pas een gamma toe op Luminantie L*a*b*-data voor en na behandeling Piramide 1 en Piramide 2.\nAls gamma = 3.0 wordt Luminantie 'lineair' gebruikt. TP_LOCALLAB_GAMFRA;Toonresponscurve (TRC) TP_LOCALLAB_GAMM;Gamma TP_LOCALLAB_GAMMASKCOL;Gamma +TP_LOCALLAB_GAMMASK_TOOLTIP;Het aanpassen van Gamma en Helling kan zorgen voor een zachte en artefactvrije transformatie van het masker, door 'L' geleidelijk te wijzigen om discontinuïteiten te vermijden. TP_LOCALLAB_GAMSH;Gamma TP_LOCALLAB_GAMUTLABRELA;Lab TP_LOCALLAB_GAMUTMUNSELL;Alleen Munsell @@ -2934,31 +3127,47 @@ TP_LOCALLAB_GAMUTXYZABSO;XYZ absoluut TP_LOCALLAB_GAMUTXYZRELA;XYZ relatief TP_LOCALLAB_GAMW;Gamma (wavelet-pyramiden) TP_LOCALLAB_GRADANG;Verloophoek +TP_LOCALLAB_GRADANG_TOOLTIP;Rotatiehoek in graden: -180, 0, +180. TP_LOCALLAB_GRADFRA;Masker Verloopfilter +TP_LOCALLAB_GRADGEN_TOOLTIP;Past de sterkte van het luminantieverloop aan. TP_LOCALLAB_GRADLOGFRA;Verloopfilter - Luminantie TP_LOCALLAB_GRADSTR;Verloopsterkte +TP_LOCALLAB_GRADSTRAB_TOOLTIP;Past de sterkte van het chromaverloop aan. TP_LOCALLAB_GRADSTRCHRO;Chroma verloopsterkte TP_LOCALLAB_GRADSTRHUE;Tint verloopsterkte TP_LOCALLAB_GRADSTRHUE2;Tint verloopsterkte +TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Past de sterkte van het tintverloop aan. TP_LOCALLAB_GRADSTRLUM;Luma verloopsterkte TP_LOCALLAB_GRAINFRA;Filmkorrel 1:1 TP_LOCALLAB_GRAINFRA2;Grofheid +TP_LOCALLAB_GRAIN_TOOLTIP;Voegt filmachtige korrel toe aan het beeld. TP_LOCALLAB_GRALWFRA;Verloopfilter (lokaal contrast) +TP_LOCALLAB_GRIDFRAME_TOOLTIP;U kunt dit gereedschap als penseel gebruiken. Gebruik een kleine spot en pas 'Transitiewaarde' en 'Transitieverval' aan.\nAlleen de modus 'Normaal' en mogelijk ook Tint, Verzadiging, Kleur en Helderheid hebben invloed op Achtergrond samenvoegen (ΔE). +TP_LOCALLAB_GRIDMETH_TOOLTIP;Kleurtonen: de luminantie wordt in aanmerking genomen bij het variëren van chroma. Equivalent aan H=f(H) als de 'witte stip' op het raster op nul blijft en alleen de 'zwarte stip' wordt gewijzigd. Equivalent aan 'Kleurtonen' als beide stippen worden gewijzigd.\n\nDirect: werkt rechtstreeks op chroma. TP_LOCALLAB_GRIDONE;Kleurtoning TP_LOCALLAB_GRIDTWO;Direct TP_LOCALLAB_GUIDBL;Verzachtingsstraal +TP_LOCALLAB_GUIDBL_TOOLTIP;Past een Begeleid filter met verstelbare straal toe. Hiermee kunnen onregelmatigheden verminderd worden of het beeld vervaagd. +TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Wijzigt de distributiefunctie van het Begeleid filter. Negatieve waarden simuleren een Gaussiaanse vervaging. TP_LOCALLAB_GUIDFILTER;Straal Begeleid filter +TP_LOCALLAB_GUIDFILTER_TOOLTIP;Kan onregelmatigheden verminderen of vermeerderen. +TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensiteit van het Begeleide filter. +TP_LOCALLAB_HHMASK_TOOLTIP;Fijne tintaanpassingen, bijvoorbeeld voor de huid. TP_LOCALLAB_HIGHMASKCOL;Hoge lichten TP_LOCALLAB_HLH;H TP_LOCALLAB_HUECIE;Tint TP_LOCALLAB_IND;Onafhankelijk (muis) TP_LOCALLAB_INDSL;Onafhankelijk (muis + schuiven) TP_LOCALLAB_INVBL;Inverteer +TP_LOCALLAB_INVBL_TOOLTIP;Alternatief voor de 'Omkeer'-modus: gebruik twee spots.\nEerste spot:\nVolledige afbeelding.\n\nTweede spot: Sluit spot uit. TP_LOCALLAB_INVERS;Inverteer +TP_LOCALLAB_INVERS_TOOLTIP;Minder mogelijkheden indien (Omkeren) is geselecteerd.\n\nAlternatief: gebruik twee spots\nEerste spot:\nVolledige afbeelding.\n\nTweede spot: Uitgesloten spot.\n\nOmkeren zal dit gereedschap inschakelen voor het gebied buiten de spot, terwijl het gebied binnen de spot onaangetast blijft. TP_LOCALLAB_INVMASK;Keer algoritme om TP_LOCALLAB_ISOGR;Distributie (ISO) TP_LOCALLAB_JAB;Gebruik Zwart LW & Wit LW +TP_LOCALLAB_JABADAP_TOOLTIP;Perceptuele Uniforme aanpassing.\nPast automatisch de relatie tussen Jz en verzadiging aan, rekening houdend met 'Absolute luminantie'. TP_LOCALLAB_JZ100;Jz-referentie 100cd/m2 +TP_LOCALLAB_JZ100_TOOLTIP;Past automatisch het referentieniveau Jz 100 cd/m2 aan (beeldsignaal).\nWijzigt het verzadigingsniveau en de werking van 'PU-aanpassing' (Perceptuele Uniforme aanpassing). TP_LOCALLAB_JZADAP;PU-adaptatie TP_LOCALLAB_JZCH;Chroma TP_LOCALLAB_JZCHROM;Chroma @@ -2966,15 +3175,23 @@ TP_LOCALLAB_JZCLARICRES;Voeg samen met chroma Cz TP_LOCALLAB_JZCLARILRES;Voeg samen Jz TP_LOCALLAB_JZCONT;Contrast TP_LOCALLAB_JZFORCE;Forceer max Jz tot 1 +TP_LOCALLAB_JZFORCE_TOOLTIP;Hiermee kan de maximale Jz-waarde naar 1 geforceerd worden voor een betere respons van schuiven en curven. TP_LOCALLAB_JZFRA;Jz Cz Hz Beeldaanpassingen TP_LOCALLAB_JZHFRA;Curven Hz TP_LOCALLAB_JZHJZFRA;Curve Jz(Hz) TP_LOCALLAB_JZHUECIE;Tintrotatie TP_LOCALLAB_JZLIGHT;Helderheid TP_LOCALLAB_JZLOG;Log-codering Jz +TP_LOCALLAB_JZLOGWBS_TOOLTIP;Aanpassingen van Zwart LW en Wit LW kunnen verschillen afhankelijk van of Log-codering of Sigmoid wordt gebruikt.\nVoor Sigmoid kan een verandering (meestal een toename) van Wit LW nodig zijn voor een betere weergave van de hoge lichten, contrast en verzadiging. +TP_LOCALLAB_JZLOGWB_TOOLTIP;Als Auto is ingeschakeld, worden de LW-niveaus en de 'Gemiddelde luminantie Yb%' voor het spotgebied berekend en aangepast. De resulterende waarden worden gebruikt door alle Jz-bewerkingen, inclusief 'Log Encoding Jz'.\nHet berekent ook de absolute luminantie op het moment van opname. +TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is de relatieve luminantie van de achtergrond, uitgedrukt als een percentage grijs. 18% grijs komt overeen met een achtergrondluminantie van 50% wanneer uitgedrukt in CIE L.\nDe gegevens zijn gebaseerd op de gemiddelde luminantie van het beeld.\nIndien toegepast met Log-codering, wordt de gemiddelde luminantie gebruikt om de hoeveelheid versterking te bepalen die op het signaal moet worden toegepast voor de log-codering. Lagere waarden van gemiddelde luminantie resulteren in grotere versterking. +TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (alleen in 'Geavanceerde' modus). Alleen operationeel als het uitvoerapparaat (monitor) HDR is (piekluminantie hoger dan 100 cd/m2 - idealiter tussen 4000 en 10000 cd/m2. Zwartpuntluminantie lager dan 0.005 cd/m2). Dit veronderstelt a) dat de ICC-PCS voor het scherm Jzazbz (of XYZ) gebruikt, b) werkt in echte precisie, c) dat de monitor is gekalibreerd (bij voorkeur met een DCI-P3 of Rec-2020 kleurbereik), d) dat het gebruikelijke gamma (sRGB of BT709) wordt vervangen door een Perceptual Quantiser (PQ)-functie. TP_LOCALLAB_JZPQFRA;Jz herindeling +TP_LOCALLAB_JZPQFRA_TOOLTIP;Hiermee kunt u het Jz-algoritme aanpassen aan een SDR-omgeving of aan de kenmerken (prestaties) van een HDR-omgeving als volgt:\na) voor luminantiewaarden tussen 0 en 100 cd/m2 gedraagt het systeem zich alsof het zich in een SDR-omgeving bevindt.\nb) voor luminantiewaarden tussen 100 en 10000 cd/m2 kunt u het algoritme aanpassen aan de HDR-kenmerken van de afbeelding en de monitor.\n\nAls 'PQ - Piekluminantie' is ingesteld op 10000, gedraagt 'Jz-hermapping' zich op dezelfde manier als het originele Jzazbz-algoritme. TP_LOCALLAB_JZPQREMAP;PQ - Piekluminantie +TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - hiermee kunt u de interne PQ-functie wijzigen (meestal 10000 cd/m2 - standaard 120 cd/m2).\nKan worden gebruikt voor verschillende afbeeldingen, processen en apparaten. TP_LOCALLAB_JZQTOJ;Relatieve luminantie +TP_LOCALLAB_JZQTOJ_TOOLTIP;Hiermee kunt u 'Relatieve luminantie' in plaats van 'Absolute luminantie' gebruiken - Helderheid wordt Lichtheid.\nDe wijzigingen hebben invloed op: de Helderheidsschuif, de Contrastschuif en de Jz(Jz)-curve. TP_LOCALLAB_JZSAT;Verzadiging TP_LOCALLAB_JZSHFRA;Schaduwen/Hoge lichten Jz TP_LOCALLAB_JZSOFTCIE;Verzachtingsstraal (Begeleid filter) @@ -2988,18 +3205,30 @@ TP_LOCALLAB_LABGRID;Kleurcorrectierooster TP_LOCALLAB_LABGRIDMERG;Achtergrond TP_LOCALLAB_LABGRID_VALUES;Hoog(a)=%1 Hoog(b)=%2\nLaag(a)=%3 Laag(b)=%4 TP_LOCALLAB_LABSTRUM;Structuurmasker +TP_LOCALLAB_LAPLACC;ΔØ Masker Laplacian lost PDE op TP_LOCALLAB_LAPLACE;Laplacian-drempel ΔE TP_LOCALLAB_LAPLACEXP;Laplacian-drempel TP_LOCALLAB_LAPMASKCOL;Laplacian-drempel +TP_LOCALLAB_LAPRAD1_TOOLTIP;Verhoogt het contrast van het masker door de luminantiewaarden van de lichtere gebieden te verhogen. Kan worden gebruikt in combinatie met de L(L)- en LC(H)-curves. +TP_LOCALLAB_LAPRAD2_TOOLTIP;De verzachtingsstraal gebruikt een Begeleid filter om onregelmatigheden te verminderen en de overgang te verzachten. +TP_LOCALLAB_LAPRAD_TOOLTIP;De verzachtingsstraal gebruikt een Begeleid filter om onregelmatigheden te verminderen en de overgang te verzachten. +TP_LOCALLAB_LAP_MASK_TOOLTIP;Lost PDE's op voor alle Laplacian-maskers.\nIndien ingeschakeld, vermindert het Laplacian-drempelmasker onregelmatigheden en verzacht het resultaat.\nIndien uitgeschakeld is de respons lineair. TP_LOCALLAB_LCLABELS;Residuele ruisniveaus +TP_LOCALLAB_LCLABELS_TOOLTIP;Geeft de gemiddelde en high-end ruiswaarden weer voor het gebied dat wordt weergegeven in het Voorbeeldpaneel (bij 100% zoom). De ruiswaarden zijn gegroepeerd op wavelet-niveaus 0,1,2,3 en 4,5,6.\nDe weergegeven waarden zijn alleen indicatief en zijn bedoeld om te helpen bij het aanpassen van ruisonderdrukking. Ze mogen niet worden geïnterpreteerd als absolute ruisniveaus.\n\n300: Veel ruis\n100-300: Ruis\n50-100: Matige ruis\n< 50: Weinig ruis\n\nZe tonen het volgende:\n*De impact van Ruisonderdrukking in het hoofdmenu Detail-tabblad.\n*De invloed van Non-local Means, Wavelets en DCT op de luminantieruis.\n*De invloed van Wavelets en DCT op de chroma-ruis.\n*De invloed van Opnameverscherping en Demozaïeken. +TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT verbetert de kwaliteit en maakt het gebruik van grote stralen (radius) mogelijk, maar verhoogt de verwerkingstijd (afhankelijk van het te verwerken gebied). Bij voorkeur alleen gebruiken voor grote stralen. De grootte van het gebied kan met enkele pixels worden verminderd om de FFTW te optimaliseren. Dit kan de verwerkingstijd met een factor 1,5 tot 10 verminderen. TP_LOCALLAB_LC_TOOLNAME;Lokaal Contrast & Wavelets TP_LOCALLAB_LEVELBLUR;Maximum vervagingsniveaus TP_LOCALLAB_LEVELWAV;Wavelet-niveaus +TP_LOCALLAB_LEVELWAV_TOOLTIP;Het niveau wordt automatisch aangepast aan de grootte van de spot en het voorbeeld.\nVan niveau 9 grootte max 512 tot niveau 1 grootte max = 4. TP_LOCALLAB_LEVFRA;Niveaus TP_LOCALLAB_LIGHTNESS;Lichtheid +TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse modus: selectie = -100 dwingt luminantie naar nul. TP_LOCALLAB_LIGHTRETI;Lichtheid TP_LOCALLAB_LINEAR;Lineariteit TP_LOCALLAB_LIST_NAME;Voeg gereedschap toe aan huidige spot... +TP_LOCALLAB_LIST_TOOLTIP;U kunt drie complexiteitsniveaus selecteren voor elk gereedschap: Basis, Standaard en Geavanceerd.\nDe standaardinstelling voor alle hulpmiddelen is Basis, maar dit kan worden gewijzigd in het venster Voorkeuren.\nU kunt ook het complexiteitsniveau per gereedschap wijzigen tijdens het bewerken. +TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Hiermee kunt u het effect op specifieke detailniveaus in het masker verminderen of vergroten door op bepaalde luminantiezones te werken (over het algemeen de lichtste). +TP_LOCALLAB_LMASK_LL_TOOLTIP;Hiermee past u het contrast van het masker vrijelijk aan.\nHeeft een vergelijkbare functie als de Gamma- en Hellingschuiven.\nHiermee kunnen bepaalde delen van het beeld worden bewerkt (meestal de lichtste delen van het masker door de curve te gebruiken om de donkere delen uit te sluiten). Kan onregelmatigheden creëren. TP_LOCALLAB_LOCCONT;Onscherptemasker TP_LOCALLAB_LOC_CONTRAST;Lokaal Contrast & Wavelets TP_LOCALLAB_LOC_CONTRASTPYR;Pyramide 1: @@ -3009,48 +3238,113 @@ TP_LOCALLAB_LOC_CONTRASTPYRLAB;Verloopfilter/Randscherpte/Vervaging TP_LOCALLAB_LOC_RESIDPYR;Residueel beeld (Main) TP_LOCALLAB_LOG;Log-codering TP_LOCALLAB_LOG1FRA;CAM16 Beeldaanpassingen -TP_LOCALLAB_LOG2FRA;Kijkomstandigheden +TP_LOCALLAB_LOG2FRA;Weergave-omstandigheden TP_LOCALLAB_LOGAUTO;Automatisch +TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Berekent automatisch de 'Gemiddelde luminantie' voor de opnameomstandigheden. +TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Berekent automatisch de 'Gemiddelde luminantie' voor de opnameomstandigheden wanneer de Auto-knop in Relatieve belichtingsniveaus is ingedrukt. +TP_LOCALLAB_LOGAUTO_TOOLTIP;Door op deze knop te drukken, worden het dynamisch bereik en de 'Gemiddelde luminantie' voor de opnameomstandigheden berekend als de optie 'Auto gemiddelde luminantie (Yb%)' is aangevinkt).\nBerekent ook de absolute luminantie op het moment van opname.\nDruk nogmaals op de knop om de automatisch berekende waarden aan te passen. +TP_LOCALLAB_LOGBASE_TOOLTIP;Standaard = 2.\nWaarden kleiner dan 2 verminderen de werking van het algoritme, waardoor de schaduwen donkerder en de hoge lichten helderder worden.\nMet waarden groter dan 2 worden de schaduwen grijzer en worden de hoge lichten meer uitgebleekt. +TP_LOCALLAB_LOGCATAD_TOOLTIP;Met Chromatische aanpassing wordt een kleur geïnterpreteerd volgens zijn ruimtelijk-tijdelijke omgeving.\nHandig wanneer de witbalans aanzienlijk afwijkt van de D50-referentie.\nPast kleuren aan de lichtbron van het uitvoerapparaat aan. TP_LOCALLAB_LOGCIE;Log-codering ipv. Sigmoid TP_LOCALLAB_LOGCIEQ;Log-codering Q (met Ciecam) +TP_LOCALLAB_LOGCIEQ_TOOLTIP;Door het selectievakje aan te vinken kunt u schakelen tussen log-codering op basis van de drie RGB-kanalen en log-codering die uitsluitend is gebaseerd op het helderheidskanaal (Q) van Ciecam.\nHet gebruik van het Q-kanaal in plaats van de RGB-kanalen helpt ongewenste randeffecten zoals tint- en verzadigingsverschuivingen te vermijden.\nDe instellingen zijn echter moeilijker te optimaliseren omdat Q onbegrensd is en Ciecam de gegevens wijzigt om rekening te houden met de omgevingsomstandigheden, gelijktijdig contrast, enz.\nU moet mogelijk het volgende aanpassen:\nOpnameomstandigheden: Gemiddelde luminantie (Yb), wit- en zwartdistributie, Zwart LW, Wit LW.\n Bronaanpassingen: Helderheidscompressie, Sterkte.\n\nOpmerking: als u log-codering (Q) gebruikt, wees dan voorzichtig om de optie 'Ciecam uitschakelen' niet te activeren onder Opnameomstandigheden, menu Weergave-omstandigheden. +TP_LOCALLAB_LOGCIE_TOOLTIP;Hiermee kunt u Zwart LW, Wit LW, Wit- en zwartdistributie, Gemiddelde luminantie opname-omstandigheden en Gemiddelde luminantie weergave-omstandigheden (Yb%) gebruiken voor toonmappen met behulp van 'Log-codering' met Helderheidscompressie. TP_LOCALLAB_LOGCOLORFL;Kleurrijkheid (M) +TP_LOCALLAB_LOGCOLORF_TOOLTIP;Waargenomen hoeveelheid tint in verhouding tot grijs.\nIndicator dat een stimulus meer of minder gekleurd lijkt. TP_LOCALLAB_LOGCONQL;Contrast (Q) TP_LOCALLAB_LOGCONTHRES;Contrastdrempel (J & Q) TP_LOCALLAB_LOGCONTL;Contrast (J) +TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 houdt rekening met de toename in waargenomen kleuring bij luminantie. +TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 houdt rekening met de toename in waargenomen kleuring bij helderheid. +TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Past het contrastbereik van de middentonen aan (J & Q).\nPositieve waarden verminderen geleidelijk het effect van de Contrastschuiven (J & Q). Negatieve waarden verhogen geleidelijk het effect van de Contrastschuiven. +TP_LOCALLAB_LOGDETAIL_TOOLTIP;Werkt voornamelijk op hoge frequenties. +TP_LOCALLAB_LOGENCOD_TOOLTIP;Toonmappen met Logaritmische codering (ACES).\nNuttig voor onderbelichte afbeeldingen of afbeeldingen met een hoog dynamisch bereik.\n\nTweestaps-proces: 1) Berekening van Dynamisch Bereik 2) Handmatige aanpassing. TP_LOCALLAB_LOGEXP;Alle gereedschappen TP_LOCALLAB_LOGFRA;Opname-omstandigheden +TP_LOCALLAB_LOGFRAME_TOOLTIP;Hiermee kunt u de LW-niveaus en de 'Gemiddelde luminantie Yb%' (grijspunt bron) voor het spotgebied berekenen en aanpassen. De resulterende waarden zullen worden gebruikt door alle Lab-bewerkingen en de meeste RGB-bewerkingen in de pijplijn.\nBerekent ook de absolute luminantie op het moment van opname. +TP_LOCALLAB_LOGIMAGE_TOOLTIP;Houdt rekening met de overeenkomstige Ciecam-variabelen: Contrast (J) en Verzadiging (s), evenals Contrast (Q), Helderheid (Q), Lichtheid (J) en Kleurrijkheid (M) (in Geavanceerde modus). TP_LOCALLAB_LOGLIGHTL;Lichtheid (J) +TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Dicht bij lichtheid (L*a*b*). Houdt rekening met de toename in waargenomen kleuring. TP_LOCALLAB_LOGLIGHTQ;Helderheid (Q) +TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Waargenomen hoeveelheid licht die uit een stimulus komt.\nIndicator dat een stimulus meer of minder licht, helder lijkt. TP_LOCALLAB_LOGLIN;Logaritmische modus TP_LOCALLAB_LOGPFRA;Relatieve Belichtingsniveaus -TP_LOCALLAB_LOGPFRA2;Log-codering - instellingen +TP_LOCALLAB_LOGPFRA2;log-codering - instellingen TP_LOCALLAB_LOGREPART;Overall kracht +TP_LOCALLAB_LOGREPART_TOOLTIP;Hiermee kunt u de relatieve sterkte van de log-gecodeerde afbeelding aanpassen ten opzichte van de originele afbeelding.\nHeeft geen invloed op de Ciecam-component. +TP_LOCALLAB_LOGSATURL_TOOLTIP;Verzadiging (s) in CIECAM16 komt overeen met de kleur van een stimulus in verhouding tot zijn eigen helderheid.\nWerkt voornamelijk op middentonen en op de hoge lichten. +TP_LOCALLAB_LOGSCENE_TOOLTIP;Komt overeen met de opnameomstandigheden. +TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Verandert tinten en kleuren op basis van de opname-omstandigheden.\n\nGemiddeld: Gemiddelde lichtomstandigheden (standaard). Het beeld zal niet veranderen.\n\nGedimd: Gedimde omstandigheden. Het beeld zal iets helderder worden.\n\nDonker: Donkere omstandigheden. Het beeld zal helderder worden. +TP_LOCALLAB_LOGVIEWING_TOOLTIP;Komt overeen met het medium waarop de uiteindelijke afbeelding zal worden bekeken (monitor, TV, projector, printer, enz.), evenals de omgevingsomstandigheden. TP_LOCALLAB_LOG_TOOLNAME;Log-codering TP_LOCALLAB_LUM;LL - CC TP_LOCALLAB_LUM46LABEL;Luma-niveaus 456: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_LUMADARKEST;Donkerst TP_LOCALLAB_LUMASK;Achtergrondkleur/luma-masker +TP_LOCALLAB_LUMASK_TOOLTIP;Past de grijstint of kleur van de achtergrond van het masker aan in Toon Masker (Masker en Modificaties). TP_LOCALLAB_LUMAWHITESEST;Lichtst TP_LOCALLAB_LUMFRA;L*a*b* standaard TP_LOCALLAB_LUMLABEL;Luma-niveaus 0123: Gemiddeld=%1 Hoog=%2 TP_LOCALLAB_MASFRAME;Masker en Combineer +TP_LOCALLAB_MASFRAME_TOOLTIP;Voor alle maskers.\nHoudt rekening met de ΔE-afbeelding om te voorkomen dat het selectiegebied wordt gewijzigd wanneer de volgende maskergereedschappen worden gebruikt: Gamma, Helling, Chroma, Contrastcurve, Lokaal contrast (op wavelet-niveau), Vervagingsmasker en Structuurmasker (indien ingeschakeld).\nUitgeschakeld als de Inverteermodus wordt gebruikt. TP_LOCALLAB_MASK;Curven TP_LOCALLAB_MASK2;Contrastcurve TP_LOCALLAB_MASKCOM;Gemeenschappelijk Kleurmasker TP_LOCALLAB_MASKCOM_TOOLNAME;Gemeenschappelijk kleurmasker +TP_LOCALLAB_MASKCOM_TOOLTIP;Een gereedschap op zichzelf.\nKan worden gebruikt om het uiterlijk van de afbeelding aan te passen (chrominantie, luminantie, contrast) en de textuur als een functie van Bereik. +TP_LOCALLAB_MASKCURVE_TOOLTIP;De 3 curven staan standaard op 1 (maximum):\nC=f(C) de chroma varieert afhankelijk van de chrominantie. U kunt de chroma verlagen om de selectie te verbeteren. Door deze curve dichtbij nul in te stellen (met een lage waarde van C om de curve te activeren) kunt u de achtergrond desatureren in Inverteermodus.\nL=f(L) de luminantie varieert afhankelijk van de luminantie, dus u kunt de helderheid verminderen om de selectie te verbeteren.\nL en C = f(H) luminantie en chroma variëren met tint, dus u kunt de luminantie en chroma verlagen om de selectie te verbeteren. TP_LOCALLAB_MASKDDECAY;Vervalsterkte +TP_LOCALLAB_MASKDECAY_TOOLTIP;Beheert de vervalsnelheid voor de grijswaarden in het masker.\nVerval = 1 lineair, Verval > 1 scherpere parabolische overgangen, Verval < 1 geleidelijkere overgangen. +TP_LOCALLAB_MASKDEINV_TOOLTIP;Keert de manier om waarop het algoritme het masker interpreteert.\nIndien aangevinkt, zullen zwarte en zeer lichte gebieden worden verminderd. +TP_LOCALLAB_MASKDE_TOOLTIP;Wordt gebruikt voor ruisvermindering als een functie van de luminantie-informatie van de afbeelding die is opgenomen in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet zijn ingeschakeld om deze functie te gebruiken.\nAls het masker onder de 'donkere' drempel ligt, zal de ruisvermindering progressief worden toegepast.\nAls het masker boven de 'lichte' drempel ligt, zal de ruisvermindering progressief worden toegepast.\nTussen de twee zullen de afbeeldingsinstellingen zonder de ruisvermindering worden behouden, tenzij u de schuiven 'Grijsgebied luminantie ruisvermindering' of 'Grijsgebied chrominantie ruisvermindering' aanpast. +TP_LOCALLAB_MASKGF_TOOLTIP;Hier wordt het Begeleid Filter gebruikt als een functie van de luminantie-informatie van de afbeelding die is opgenomen in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet zijn ingeschakeld om deze functie te gebruiken.\nAls het masker onder de 'donkere' drempel ligt, zal het Begeleid Filter progressief worden toegepast.\nAls het masker boven de 'lichte' drempel ligt, zal het Begeleid Filter progressief worden toegepast.\nTussen de twee zullen de afbeeldingsinstellingen zonder het Begeleid Filter worden behouden. TP_LOCALLAB_MASKH;Tintcurve +TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lichtere-tint limiet waarboven CBDL-parameters (alleen Luminantie) geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de CBDL-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Kleur en Licht-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Vervagingsmasker', 'Verzachtingsstraal', 'Gamma en Helling', 'Contrast curve' en 'Lokaal contrast' (wavelets).\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; De ruisvermindering wordt geleidelijk verminderd van 100% bij de drempelinstelling tot 0% bij de maximale witte waarde (zoals bepaald door het masker).\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Verzachtingsstraal', 'Gamma en Helling', 'Contrastcurve', 'Lokaal contrast' (wavelets).\nGebruik een vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de 'Dynamisch bereik en Belichting'-instellingen werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Log-coderingsinstellingen werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Lichtere-tint limiet waarboven Retinex-parameters (alleen Luminantie) geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Retinex-instellingen werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de instellingen in Schaduwen/Hoge lichten werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Toonmap-instellingen werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Levendigheid en Warm/Koel-instellingen werden gewijzigd.\nU kunt bepaalde hulpmiddelen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lichtere-tint limiet waarboven de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Lokaal contrast en Wavelet-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKHIGTHRES_TOOLTIP;Het Begeleid filter wordt geleidelijk verminderd van 100% bij de drempelinstelling tot 0% bij de maximale witte waarde (zoals bepaald door het masker).\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Verzachtingsstraal', 'Gamma en Helling', 'Contrastcurve', 'Lokaal contrast wavelet'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. TP_LOCALLAB_MASKLCTHR;Lichte gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHR2;Lichte gebieden luma-drempel TP_LOCALLAB_MASKLCTHRLOW;Donkere gebieden luminantiedrempel TP_LOCALLAB_MASKLCTHRLOW2;Donkere gebieden luma-drempel TP_LOCALLAB_MASKLCTHRMID;Grijze gebieden luma-ruisvermindering TP_LOCALLAB_MASKLCTHRMIDCH;Grijze gebieden chroma-ruisvermindering +TP_LOCALLAB_MASKLC_TOOLTIP;Gebruikt door wavelet-luminantie. \nHiermee kunt u de ruisonderdrukking afstemmen op basis van de luminantie-informatie van de afbeelding in het L(L)- of LC(H)-masker (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\n'Donkere gebieden luminantiedrempel'. Als 'Versterk ruisonderdrukking in donkere en lichte gebieden' > 1, dan wordt de ruisonderdrukking geleidelijk verhoogd van 0% bij de drempelinstelling tot 100% bij de maximale zwarte waarde (bepaald door het masker).\n'Lichte gebieden luminantiedrempel'. De ruisonderdrukking wordt geleidelijk verminderd van 100% bij de drempelinstelling tot 0% bij de maximale witte waarde (bepaald door het masker).\nIn het gebied tussen de twee drempels worden de ruisonderdrukkingsinstellingen niet beïnvloed door het masker. TP_LOCALLAB_MASKLNOISELOW;Versterk donkere/lichte gebieden +TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Donkere-tint limiet waaronder de CBDL-parameters (alleen Luminantie) geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de CBDL-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Kleur en Licht-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Vervagingsmasker', 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve', 'Lokaal contrast' (wavelets).\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;De ruisonderdrukking wordt geleidelijk verhoogd van 0% bij de drempelinstelling tot 100% bij de maximale zwarte waarde (zoals bepaald door het masker).\nU kunt bepaalde gereedschappen in Masker en Modificaties gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve', 'Lokaal contrast' (wavelets).\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de 'Dynamisch bereik en Belichting'-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Log-coderingsinstellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Donkere-tint limiet waaronder de Retinex-parameters (alleen Luminantie) geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Retinex-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de instellingen in Schaduwen/Hoge lichten werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Toonmap-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de instellingen in Levendigheid en Warm/koel werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Donkere-tint limiet waaronder de parameters geleidelijk zullen worden hersteld naar hun oorspronkelijke waarden voordat ze door de Lokaal contrast en Wavelet-instellingen werden gewijzigd.\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve'.\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;Het Begeleid Filter wordt geleidelijk verhoogd van 0% bij de drempelinstelling tot 100% bij de maximale zwarte waarde (zoals bepaald door het masker).\nU kunt sommige gereedschappen in 'Masker en Modificaties' gebruiken om de grijstinten te veranderen: 'Structuurmasker', 'Verzachtingsstraal', Gamma en Helling, 'Contrastcurve', 'Lokaal contrast' (wavelets).\nGebruik een 'vergrendelbaar kleurpipet' op het masker om te zien welke gebieden zullen worden beïnvloed. Zorg ervoor dat u 'Achtergrond kleurmasker' = 0 instelt in Instellingen. +TP_LOCALLAB_MASKRECOL_TOOLTIP;Gebruikt om het effect van de Kleur en Licht-instellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Kleur en Licht-instellingen werden gewijzigd.\nTussen deze twee gebieden in, zal de volledige waarde van de Kleur en Licht-instellingen worden toegepast. TP_LOCALLAB_MASKRECOTHRES;Hersteldrempel +TP_LOCALLAB_MASKREEXP_TOOLTIP;Gebruikt om het effect van de 'Dynamisch bereik en Belichting'-instellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de 'Dynamisch bereik en Belichting'-instellingen werden gewijzigd.\nTussen deze twee gebieden in, zal de volledige waarde van de 'Dynamisch bereik en Belichting'-instellingen worden toegepast. +TP_LOCALLAB_MASKRELOG_TOOLTIP;Wordt gebruikt om het effect van de Log-coderingsinstellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Log-coderingsinstellingen werden gewijzigd - kan worden gebruikt om de hoge lichten die door Kleurherstel zijn gereconstrueerd te herstellen.\nTussen deze twee gebieden zal de volledige waarde van de Log-coderingsinstellingen worden toegepast. +TP_LOCALLAB_MASKRESCB_TOOLTIP;Wordt gebruikt om het effect van de CBDL-instellingen (alleen luminantie) te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de CBDL-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de CBDL-instellingen worden toegepast. +TP_LOCALLAB_MASKRESH_TOOLTIP;Wordt gebruikt om het effect van de instellingen in Schaduwen/Hoge lichten te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Schaduwen/Hoge lichten-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de Schaduwen/Hoge lichten-instellingen worden toegepast. +TP_LOCALLAB_MASKRESRETI_TOOLTIP;Wordt gebruikt om het effect van de Retinex-instellingen (alleen luminantie) te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Retinex-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de Retinex-instellingen worden toegepast. +TP_LOCALLAB_MASKRESTM_TOOLTIP;Wordt gebruikt om het effect van de Toonmap-instellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Toonmap-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de Toonmap-instellingen worden toegepast. +TP_LOCALLAB_MASKRESVIB_TOOLTIP;Wordt gebruikt om het effect van de Levendigheid en Warm/Koel-instellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Levendigheid en Warm/Koel-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de Levendigheid en Warm/Koel-instellingen worden toegepast. +TP_LOCALLAB_MASKRESWAV_TOOLTIP;Wordt gebruikt om het effect van de Lokaal contrast en Wavelet-instellingen te moduleren op basis van de luminantie-informatie van de afbeelding in de L(L)- of LC(H)-maskers (Masker en Modificaties).\nHet L(L)-masker of het LC(H)-masker moet worden ingeschakeld om deze functie te gebruiken.\nDe 'donkere' en 'lichte' gebieden onder de donkere drempel en boven de lichte drempel zullen geleidelijk worden hersteld naar hun oorspronkelijke waarden voordat ze door de Lokaal contrast en Wavelet-instellingen werden gewijzigd.\nTussen deze twee gebieden zal de volledige waarde van de Lokaal contrast en Wavelet-instellingen worden toegepast. TP_LOCALLAB_MASKUNUSABLE;Masker uitgeschakeld (zie Masker & modificaties) TP_LOCALLAB_MASKUSABLE;Masker ingeschakeld (Masker & modificaties) +TP_LOCALLAB_MASK_TOOLTIP;U kunt meerdere maskers voor een gereedschap inschakelen door een ander gereedschap te activeren en alleen het masker te gebruiken (stel de gereedschapsschuiven in op 0).\n\nU kunt ook de spot dupliceren en deze dicht bij de eerste spot plaatsen. De kleine variaties in de spotreferenties stellen u in staat om fijne aanpassingen te maken. TP_LOCALLAB_MEDIAN;Mediaan Laag +TP_LOCALLAB_MEDIANITER_TOOLTIP;Het aantal opeenvolgende iteraties dat wordt uitgevoerd door het mediaanfilter. +TP_LOCALLAB_MEDIAN_TOOLTIP;U kunt een mediaanwaarde kiezen in het bereik van 3x3 tot 9x9 pixels. Hogere waarden versterken de ruisonderdrukking en vervaging. TP_LOCALLAB_MEDNONE;Geen TP_LOCALLAB_MERCOL;Kleur TP_LOCALLAB_MERDCOL;Voeg samen met achtergrond (ΔE) @@ -3060,6 +3354,9 @@ TP_LOCALLAB_MERFOR;Kleur tegenhouden TP_LOCALLAB_MERFOU;Vermenigvuldig TP_LOCALLAB_MERGE1COLFRA;Voeg samen met Origineel/Vorige/Achtergrond TP_LOCALLAB_MERGECOLFRA;Masker: LCh & Structuur +TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Maakt het mogelijk om maskers te maken op basis van de drie LCh-curves en/of een structuurdetectie-algoritme. +TP_LOCALLAB_MERGEMER_TOOLTIP;Houdt rekening met ΔE bij het samenvoegen van bestanden (equivalent van Bereik in dit geval). +TP_LOCALLAB_MERGEOPA_TOOLTIP;Opaciteit = % van de huidige Spot die moet worden samengevoegd met de originele of vorige Spot.\nContrastdrempel: past het resultaat aan als een functie van het contrast in de originele afbeelding. TP_LOCALLAB_MERHEI;Overlap TP_LOCALLAB_MERHUE;Tint TP_LOCALLAB_MERLUCOL;Luminantie @@ -3077,8 +3374,10 @@ TP_LOCALLAB_MERTHI;Brand kleur TP_LOCALLAB_MERTHR;Verschil TP_LOCALLAB_MERTWE;Uitsluiting TP_LOCALLAB_MERTWO;Aftrekken +TP_LOCALLAB_METHOD_TOOLTIP;'Verbeterd + chromaruisvermindering' verhoogt de verwerkingstijd aanzienlijk maar vermindert onregelmatigheden. TP_LOCALLAB_MIDTCIE;Middentonen TP_LOCALLAB_MLABEL;Herstelde data Min=%1 Max=%2 +TP_LOCALLAB_MLABEL_TOOLTIP;De waarden moeten dicht bij Min=0 Max=32768 (logmodus) liggen, maar andere waarden zijn mogelijk. U kunt 'Kap herstelde data (versterking)' en 'Verschuiving' aanpassen om te normaliseren.\nHerstelt afbeeldingsdata zonder samenvoegen. TP_LOCALLAB_MODE_EXPERT;Geavanceerd TP_LOCALLAB_MODE_NORMAL;Standaard TP_LOCALLAB_MODE_SIMPLE;Basis @@ -3086,17 +3385,25 @@ TP_LOCALLAB_MRFIV;Achtergrond TP_LOCALLAB_MRFOU;Voorgaande spot TP_LOCALLAB_MRONE;Geen TP_LOCALLAB_MRTHR;Originele afbeelding +TP_LOCALLAB_MULTIPL_TOOLTIP;Breedbereik-tintaanpassing: -18EV tot +4EV. De eerste schuifregelaar werkt op zeer donkere tinten tussen -18EV en -6EV. De laatste schuifregelaar werkt op lichte tinten tot 4EV. TP_LOCALLAB_NEIGH;Radius +TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lagere waarden behouden details en textuur, hogere waarden versterken de ruisonderdrukking.\nAls gamma = 3.0 wordt luminantie 'lineair' gebruikt. +TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Gebruik deze schuif om de hoeveelheid ruisonderdrukking aan te passen aan de grootte van de te verwerken objecten. +TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Hogere waarden verbeteren de ruisonderdrukking ten koste van de verwerkingstijd. +TP_LOCALLAB_NLDENOISE_TOOLTIP;Detailherstel werkt op een Laplace-transformatie op uniforme gebieden in plaats van gebieden met details. TP_LOCALLAB_NLDET;Detailherstel TP_LOCALLAB_NLFRA;Non-local Means: Luminantie +TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means ruisonderdrukking neemt een gemiddelde van alle pixels in de afbeelding, gewogen naar hoe gelijkend ze zijn met de doelpixel.\nVermindert verlies van details vergeleken met local-mean algoritmen.\nAlleen luminantieruis wordt in aanmerking genomen. Chrominantieruis wordt het beste aangepakt met wavelets en Fourier-transformaties (DCT).\nKan in combinatie met 'Luminantieruisvermindering per niveau' of op zichzelf worden gebruikt. TP_LOCALLAB_NLGAM;Gamma TP_LOCALLAB_NLLUM;Kracht TP_LOCALLAB_NLPAT;Maximale patch-grootte TP_LOCALLAB_NLRAD;Maximale straalgrootte TP_LOCALLAB_NOISECHROCOARSE;Ruw chroma (Wav) +TP_LOCALLAB_NOISECHROC_TOOLTIP;Indien groter dan nul wordt een hoogwaardig algoritme ingeschakeld.\nGrof is voor schuif >=0,02. TP_LOCALLAB_NOISECHRODETAIL;Chroma detailherstel TP_LOCALLAB_NOISECHROFINE;Fijn chroma (Wav) TP_LOCALLAB_NOISEGAM;Gamma +TP_LOCALLAB_NOISEGAM_TOOLTIP;Als gamma = 1 wordt Luminantie 'Lab' gebruikt. Als gamma = 3.0 wordt Luminantie 'lineair' gebruikt.\nLagere waarden behouden details en textuur, hogere waarden versterken de ruisonderdrukking. TP_LOCALLAB_NOISELEQUAL;Equalizer wit-zwart TP_LOCALLAB_NOISELUMCOARSE;Luminantie grof coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luma detailherstel @@ -3111,13 +3418,20 @@ TP_LOCALLAB_OFFS;Verschuiving TP_LOCALLAB_OFFSETWAV;Verschuiving TP_LOCALLAB_OPACOL;Opaciteit TP_LOCALLAB_ORIGLC;Voeg alleen samen met originele afbeelding +TP_LOCALLAB_ORRETILAP_TOOLTIP;Wijzigt ΔE voorafgaand aan wijzigingen aangebracht door 'Bereik'. Dit stelt u in staat om de actie voor verschillende delen van de afbeelding te differentiëren (met betrekking tot de achtergrond bijvoorbeeld). +TP_LOCALLAB_ORRETISTREN_TOOLTIP;Werkt op de Laplaciaanse drempel, hoe groter de actie, hoe meer de verschillen in contrast worden verminderd. TP_LOCALLAB_PASTELS2;Levendigheid TP_LOCALLAB_PDE;Contrastversterker - Compressie Dynamisch bereik TP_LOCALLAB_PDEFRA;Contrastversterker ƒ +TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL-algoritme aangepast voor RawTherapee: geeft verschillende resultaten en vereist andere instellingen vergeleken met hoofdmenu 'Belichting'.\nKan nuttig zijn bij onderbelichting of voor afbeeldingen met een hoog dynamisch bereik. +TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;Indien aangevinkt, zorgt dit voor een kleuromvangcontrole direct na de primaire conversie naar XYZ. +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Stelt u in staat om het witpunt zodanig te verplaatsen dat het de dominante kleur nadert. Deze actie wijzigt de zuiverheid. In combinatie met 'Verschuif x' en 'Verschuif y, kunt u een beperkte kleurtoning uitvoeren. +TP_LOCALLAB_PRECAMREFI_TOOLTIP;Stelt u in staat om het witpunt zodanig te verplaatsen dat het de dominante kleur nadert. Deze actie wijzigt de zuiverheid. +TP_LOCALLAB_PRECAM_TOOLTIP;'Brondata-aanpassingen' wijzigt het dynamisch bereik met behulp van Log-codering, de tonen van de afbeelding en primaire kleuren (vereenvoudigd Abstract Profiel), en de middentonen, net voor het Ciecam-proces. Deze waarden zijn aanpasbaar:\nGamma: Werkt voornamelijk op lichte tonen\nHelling: Werkt voornamelijk op donkere tonen. U kunt elke gamma- en hellingcombinatie kiezen (waarden >1) en het algoritme zorgt ervoor dat er continuïteit is tussen de lineaire en paraboolvormige delen van de curve.\nPrimaire kleuren doel: Stelt u in staat om de Primaire kleuren van het doel te wijzigen om de kleur van de afbeelding te herstellen of te wijzigen (verzadiging). De kleurbalans wordt behouden wanneer het 'Werkprofiel' en de 'Primaire kleuren doel' vergelijkbaar zijn. Het 'Werkprofiel' wordt niet gewijzigd. U kunt ook de primaire kleuren en de lichtbron (witpunt) fijn aanpassen. Het verplaatsen van een primaire kleur verder weg van het witpunt vermindert de verzadiging en vice versa. Let op de kleuromvang (gamut). TP_LOCALLAB_PREVHIDE;Verberg extra instellingen TP_LOCALLAB_PREVIEW;Voorbeeld ΔE TP_LOCALLAB_PREVSHOW;Toon extra instellingen -TP_LOCALLAB_PRIMILLFRAME;Primaire kleuren & Illuminant +TP_LOCALLAB_PRIMILLFRAME;Primaire kleuren & Lichtbron TP_LOCALLAB_PROXI;ΔE-verval TP_LOCALLAB_QUAAGRES;Aggressief TP_LOCALLAB_QUACONSER;Conservatief @@ -3126,11 +3440,20 @@ TP_LOCALLAB_QUAL_METHOD;Globale kwaliteit TP_LOCALLAB_QUANONEALL;Uit TP_LOCALLAB_QUANONEWAV;Alleen Non-local means TP_LOCALLAB_RADIUS;Radius +TP_LOCALLAB_RADIUS_TOOLTIP;Gebruikt een snelle Fourier-transformatie voor straal > 30. TP_LOCALLAB_RADMASKCOL;Verzachtingsstraal +TP_LOCALLAB_RECOTHRES02_TOOLTIP;Als de waarde van de 'Hersteldrempel' groter is dan 1, houdt het masker in Masker en Modificaties rekening met eerdere wijzigingen van de afbeelding maar niet met die van het huidige gereedschap (bijv. Kleur en Licht, Wavelet, Cam16, enz.)\nAls de waarde van de 'Hersteldrempel' kleiner is dan 1, houdt het masker in Masker en Modificaties geen rekening met eerdere wijzigingen van de afbeelding.\n\nIn beide gevallen werkt de 'Hersteldrempel' op de gemaskerde afbeelding zoals gewijzigd door het huidige gereedschap (Kleur en Licht, Wavelet, Cam16, enz.). TP_LOCALLAB_RECT;Rechthoek TP_LOCALLAB_RECURS;Recursieve referenties +TP_LOCALLAB_RECURS_TOOLTIP;Dwingt het algoritme om de referenties opnieuw te berekenen na elke toepassing van een gereedschap.\nOok handig bij het werken met maskers. TP_LOCALLAB_REN_DIALOG_LAB;Geef de nieuwe Control Spot-naam TP_LOCALLAB_REN_DIALOG_NAME;Hernoem Control Spot +TP_LOCALLAB_REPARCOL_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Kleur en Licht-afbeelding aanpassen ten opzichte van de originele afbeelding. +TP_LOCALLAB_REPARDEN_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Ruisonderdrukking-afbeelding aanpassen ten opzichte van de originele afbeelding. +TP_LOCALLAB_REPAREXP_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Dynamisch Bereik en Belichting-afbeelding aanpassen ten opzichte van de originele afbeelding. +TP_LOCALLAB_REPARSH_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Schaduwen/Hoge lichten en Toonequalizer-afbeelding aanpassen ten opzichte van de originele afbeelding. +TP_LOCALLAB_REPARTM_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Toonmap-afbeelding aanpassen ten opzichte van de originele afbeelding. +TP_LOCALLAB_REPARW_TOOLTIP;Hiermee kunt u de relatieve sterkte van de Lokaal contrast en Wavelet-afbeelding aanpassen ten opzichte van de originele afbeelding. TP_LOCALLAB_RESID;Residuele afbeelding TP_LOCALLAB_RESIDBLUR;Vervaag residuele afbeelding TP_LOCALLAB_RESIDCHRO;Residuele afbeelding Chroma @@ -3140,15 +3463,23 @@ TP_LOCALLAB_RESIDHI;Hoge lichten TP_LOCALLAB_RESIDHITHR;Drempel hoge lichten TP_LOCALLAB_RESIDSHA;Schaduwen TP_LOCALLAB_RESIDSHATHR;Drempel schaduwen -TP_LOCALLAB_RETI;Ontnevel & Retinex +TP_LOCALLAB_RETI;Nevelvermindering & Retinex TP_LOCALLAB_RETIFRA;Retinex +TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex kan nuttig zijn voor het verwerken van afbeeldingen: \ndie wazig, mistig of nevelig zijn (naast Nevelvermindering).\ndie grote verschillen in luminantie bevatten.\nHet kan ook worden gebruikt voor speciale effecten (toonmapping). TP_LOCALLAB_RETIM;Originele Retinex TP_LOCALLAB_RETITOOLFRA;Retinex-gereedschappen -TP_LOCALLAB_RET_TOOLNAME;Ontnevel & Retinex +TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Heeft geen effect wanneer de waarde van 'Helderheid = 1' of 'Duisternis = 2'.\nVoor andere waarden wordt de laatste stap van een 'Multiple-scale Retinex'- algoritme (vergelijkbaar met 'lokaal contrast') toegepast. Deze twee schuiven, geassocieerd met 'Sterkte', stellen u in staat om aanpassingen voorafgaand aan lokaal contrast te maken. +TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Past de interne parameters aan voor een optimale respons.\nHet wordt aangeraden om de waarden van 'Herstelde data' dicht bij Min=0 en Max=32768 (log-modus) te houden, maar andere waarden zijn mogelijk. +TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logaritmische modus introduceert meer contrast maar zal ook meer halo's genereren. +TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;Met de schuiven voor Straal en Variantie kunt u de nevel aanpassen voor de voorgrond of de achtergrond. +TP_LOCALLAB_RETI_SCALE_TOOLTIP;Als Schaal = 1, gedraagt Retinex zich als lokaal contrast met extra mogelijkheden.\nHet verhogen van de waarde van Schaal verhoogt de intensiteit van de recursieve actie ten koste van de verwerkingstijd. +TP_LOCALLAB_RET_TOOLNAME;Nevelvermindering & Retinex TP_LOCALLAB_REWEI;Herhaling herweging TP_LOCALLAB_RGB;RGB-tooncurve +TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB-modus heeft u vier keuzes: Standaard, Gewogen standaard, Luminantie en Filmachtig. TP_LOCALLAB_ROW_NVIS;Niet zichtbaar TP_LOCALLAB_ROW_VIS;Zichtbaar +TP_LOCALLAB_RSTPROTECT_TOOLTIP;Rood- en huidskleurbescherming beïnvloedt de schuiven voor Verzadiging, Chroma en Kleurrijkheid. TP_LOCALLAB_SATCIE;Beperk verzadiging TP_LOCALLAB_SATUR;Verzadiging TP_LOCALLAB_SATURV;Verzadiging (s) @@ -3156,16 +3487,24 @@ TP_LOCALLAB_SCALEGR;Schaal TP_LOCALLAB_SCALERETI;Schaal TP_LOCALLAB_SCALTM;Schaal TP_LOCALLAB_SCOPEMASK;Bereik (ΔE beeldmasker) +TP_LOCALLAB_SCOPEMASK_TOOLTIP;Ingeschakeld als het ΔE-beeldmasker is ingeschakeld.\nLage waarden voorkomen een retouche van het geselecteerde gebied. TP_LOCALLAB_SENSI;Bereik TP_LOCALLAB_SENSIEXCLU;Bereik +TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Pas de kleuren aan die moeten worden uitgesloten. +TP_LOCALLAB_SENSIMASK_TOOLTIP;Bereikaanpassing specifiek voor het algemene maskergereedschap.\nWerkt op het verschil tussen de originele afbeelding en het masker.\nGebruikt de luma-, chroma- en tintreferenties van het midden van de spot.\n\nU kunt ook de ΔE van het masker zelf aanpassen met 'Bereik (ΔE beeldmasker)' in 'Instellingen' > 'Masker en Samenvoegen'. +TP_LOCALLAB_SENSI_TOOLTIP;Past het bereik van de actie aan:\nKleine waarden beperken de actie tot kleuren die vergelijkbaar zijn met die in het midden van de spot.\nHoge waarden laten het gereedschap werken op een breder scala aan kleuren. TP_LOCALLAB_SETTINGS;Instellingen -TP_LOCALLAB_SH1;Schaduwen Hoge lichten +TP_LOCALLAB_SH1;Schaduwen/Hoge lichten TP_LOCALLAB_SH2;Equalizer TP_LOCALLAB_SHADEX;Schaduwen TP_LOCALLAB_SHADEXCOMP;Schaduwcompressie TP_LOCALLAB_SHADHIGH;Schaduwen/hoge lichten & Toonequalizer +TP_LOCALLAB_SHADHMASK_TOOLTIP;Vermindert de hoge lichten van het masker op dezelfde manier als het Schaduwen/hoge lichten-algoritme. +TP_LOCALLAB_SHADMASK_TOOLTIP;Verheldert de schaduwen van het masker op dezelfde manier als het Schaduwen/hoge lichten-algoritme. +TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Pas schaduwen en hoge lichten aan met de schuiven voor schaduwen en hoge lichten of met een toonequalizer.\nKan worden gebruikt in plaats van of in combinatie met de Belichtingsmodule.\nKan ook worden gebruikt als een verloopfilter. TP_LOCALLAB_SHAMASKCOL;Schaduwen TP_LOCALLAB_SHAPETYPE;Spotvorm +TP_LOCALLAB_SHAPE_TOOLTIP;'Ellips' is de normale modus.\n'Rechthoek' kan in bepaalde gevallen worden gebruikt, bijvoorbeeld om in de volledige afbeeldingsmodus te werken door de begrenzingen buiten het voorbeeldgebied te plaatsen. Stel in dit geval de overgang in op 100.\n\nToekomstige ontwikkelingen zullen polygoonvormen en een Bézier-curve bevatten. TP_LOCALLAB_SHARAMOUNT;Hoeveelheid TP_LOCALLAB_SHARBLUR;Vervagingsradius TP_LOCALLAB_SHARDAMPING;Demping @@ -3175,6 +3514,7 @@ TP_LOCALLAB_SHARP;Schaduwen TP_LOCALLAB_SHARP_TOOLNAME;Schaduwen TP_LOCALLAB_SHARRADIUS;Straal TP_LOCALLAB_SHORTC;Korte curves L-masker +TP_LOCALLAB_SHORTCMASK_TOOLTIP;Kortsluit de 2 curves L(L) en L(H).\nHiermee kunt u de huidige afbeelding mengen met de originele afbeelding die is gewijzigd door de maskerbewerking.\nTe gebruiken met maskers 2, 3, 4, 6, 7. TP_LOCALLAB_SHOWC;Masker & modificaties TP_LOCALLAB_SHOWC1;Voeg bestand samen TP_LOCALLAB_SHOWCB;Masker en modificaties @@ -3184,9 +3524,12 @@ TP_LOCALLAB_SHOWFOURIER;Fourier ƒ(dct) TP_LOCALLAB_SHOWLAPLACE;∆ Laplacian (eerste) TP_LOCALLAB_SHOWLC;Masker en modificaties TP_LOCALLAB_SHOWMASK;Toon masker +TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Toont Maskers en Modificaties.\nLet op, u kunt slechts één gereedschapsmasker tegelijk bekijken.\nToon gewijzigde afbeelding: toont de gewijzigde afbeelding inclusief het effect van modificaties en maskers.\nToon gewijzigde gebieden zonder masker: toont de wijzigingen voordat maskers worden toegepast.\nToon gewijzigde gebieden met masker: toont de wijzigingen nadat een masker is toegepast.\nToon masker: toont het uiterlijk van het masker inclusief het effect van curves en filters.\nToon spotstructuur: hiermee kunt u het structuurdetectiemasker zien wanneer de 'Spotstructuur'-cursor is geactiveerd (indien beschikbaar).\nOpmerking: Het masker wordt toegepast vóór het vormdetectie-algoritme. +TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Stelt u in staat om de verschillende stadia van het Fourier-proces te visualiseren.\nLaplace - berekent de tweede afgeleide van de Laplace-transformatie als functie van de drempel.\nFourier - toont de Laplace-transformatie met DCT.\nPoisson - toont de oplossing van Poisson DCE.\nGeen luminantienormalisatie - toont resultaat zonder enige normalisatie van de luminantie. TP_LOCALLAB_SHOWMASKTYP1;Vervaging & Ruis TP_LOCALLAB_SHOWMASKTYP2;Ruisvermindering TP_LOCALLAB_SHOWMASKTYP3;Vervaging & Ruis + Ruisvermindering +TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Kan worden gebruikt met 'Masker en Modificaties'.\nAls 'Vervagen en ruis' is geselecteerd, kan het masker niet worden gebruikt voor ruisonderdrukking.\nAls ruisonderdrukking is geselecteerd, kan het masker niet worden gebruikt voor 'Vervagen en ruis'.\nAls 'Vervagen en ruis + ruisonderdrukking' is geselecteerd, wordt het masker gedeeld. Houd er rekening mee dat in dit geval de bereikschuiven voor zowel 'Vervagen en ruis' als ruisonderdrukking actief zullen zijn, dus het is raadzaam om de optie 'Toon wijzigingen met masker' te gebruiken bij het maken van aanpassingen. TP_LOCALLAB_SHOWMNONE;Toon gemodificeerde afbeelding TP_LOCALLAB_SHOWMODIF;Toon gemodificeerde gebieden zonder masker TP_LOCALLAB_SHOWMODIF2;Toon gemodificeerde gebieden @@ -3202,39 +3545,55 @@ TP_LOCALLAB_SHOWSTRUCEX;Toon spotstructuur (Geavanceerd) TP_LOCALLAB_SHOWT;Masker en modificaties TP_LOCALLAB_SHOWVI;Masker en modificaties TP_LOCALLAB_SHRESFRA;Schaduwen/Hoge lichten & TRC +TP_LOCALLAB_SHTRC_TOOLTIP;Gebaseerd op 'werkprofiel' (alleen degene die zijn geleverd), wijzigt de tonen van de afbeelding door te werken op een TRC (ToonResponsCurve).\nGamma werkt voornamelijk op de lichte tonen.\nHelling voornamelijk op donkere tonen.\nHet wordt aanbevolen dat de TRC van beide apparaten (monitor en uitvoerprofiel) sRGB is (standaard). TP_LOCALLAB_SH_TOOLNAME;Schaduwen/Hoge lichten & Toonequalizer TP_LOCALLAB_SIGBLACKSSCIE;Zwartdistributie +TP_LOCALLAB_SIGCIE;Sigmoid TP_LOCALLAB_SIGFRA;Sigmoid Q & Log-codering Q +TP_LOCALLAB_SIGGAMJCIE;Gamma TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Versterkingsrespons +TP_LOCALLAB_SIGMOID16_TOOLTIP;Hiermee kunt u een toonmapping-uiterlijk simuleren met zowel 'Ciecam' als 'Sigmoid Q'. Sigmoid Q heeft drie schuiven:\na) Contrast werkt op de vorm van de sigmoïde-curve en daarmee de sterkte\nb) Drempel (Grijspunt) verdeelt de actie volgens de luminantie\nc) Aanpasbaarheid weegt de actie van de sigmoïde met de interne exponentiële functie. TP_LOCALLAB_SIGMOIDBL;Samenvoegen TP_LOCALLAB_SIGMOIDLAMBDA;Contrast +TP_LOCALLAB_SIGMOIDLOGAUTO;Auto-drempel +TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;Als in de combobox 'Zwart LW en Wit LW' en 'Sigmoid en Log-codering' zijn aangevinkt in plaats van 'Alleen Sigmoid', worden de twee algoritmes 'Log-codering' en 'Sigmoid' samen gebruikt. TP_LOCALLAB_SIGMOIDNORMCIE;Normaliseer Luminantie +TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Mengen beïnvloedt het uiteindelijke aspect van het beeld, het contrast en de luminantie. Verhouding tussen origineel en uitvoerbeeld. +TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstructie van de luminantie zodat het gemiddelde en de variantie van het uitvoerbeeld rekening houden met die van het origineel.\nAlle aanpassingen die invloed hebben op J of Q worden meegenomen, inclusief die welke niet gerelateerd zijn aan Sigmoid Q. TP_LOCALLAB_SIGMOIDQJ;Gebruikt Zwart LW & Wit LW +TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;Wanneer in de combobox-selectie 'Zwart LW en Wit LW', 'Sigmoid en Log encoding Q' of 'Log-codering in plaats van Sigmoid' is aangevinkt. Dit algoritme comprimeert de data boven de waarde van de drempelschuif. De laatste waarde staat voor helderheid (Q) en moet zo dicht mogelijk bij de waarde 'Compressiedrempel' liggen (berekend wanneer 'Auto-drempel' is aangevinkt, vaak > 1). TP_LOCALLAB_SIGMOIDSENSI;Aanpasbaarheid TP_LOCALLAB_SIGMOIDTH;Drempel (Grijspunt) +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Hiermee kunt u, in Automatische modus, wanneer het dynamisch bereik van het beeld groot is, de distributie van lichten in witten en diepe zwarten wijzigen.\nKan worden gebruikt met Log-codering of Sigmoid met Zwart LW en Wit LW ingeschakeld.\n\nHet algoritme verandert de basisgegevens niet, maar werkt op de componenten die nodig zijn om het dynamisch bereik, Zwart LW, Wit LW en het Grijspunt te berekenen. +TP_LOCALLAB_SIGMOID_TOOLTIP;Hiermee kunt u een toonmap-uiterlijk simuleren met zowel de 'Jz'- als de 'Sigmoid'-functie. Drie schuifregelaars:\na) Contrast beïnvloedt de vorm van de sigmoïde-curve en daarmee de sterkte\nb) Drempel (Grijspunt) verdeelt de actie op basis van de luminantie\nc) Samenvoegen beïnvloedt het uiteindelijke beeld, het contrast en de luminantie. TP_LOCALLAB_SIGSLOPJCIE;Helling TP_LOCALLAB_SIGTRCCIE;Aanpassingen brondata TP_LOCALLAB_SIGWHITESCIE;Witdistributie TP_LOCALLAB_SLOMASKCOL;Helling +TP_LOCALLAB_SLOMASK_TOOLTIP;Door Gamma en Helling aan te passen kunt u een zachte transformatie van het masker bewerkstelligen (zonder onregelmatigheden) door geleidelijk 'L' te wijzigen om discontinuïteiten te vermijden. TP_LOCALLAB_SLOPESMOOTH;Grijsbalans (Helling) -TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Helling) -TP_LOCALLAB_SLOPESMOOTHG;Green balance (Helling) +TP_LOCALLAB_SLOPESMOOTHB;Blauwbalans (Helling) +TP_LOCALLAB_SLOPESMOOTHG;Groenbalans (Helling) TP_LOCALLAB_SLOPESMOOTHR;Roodbalans (Helling) TP_LOCALLAB_SLOSH;Helling TP_LOCALLAB_SMOOTHCIE;Versterking hoge lichten TP_LOCALLAB_SMOOTHCIE_LUM;Luminositeitsmodus -TP_LOCALLAB_SMOOTHCIE_SCA;Schaal Yb-Scène -TP_LOCALLAB_SMOOTHCIE_YB;Schaal Yb-Viewing +TP_LOCALLAB_SMOOTHCIE_SCA;Schaal Yb Opname +TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Voltooit de bewerkingen uitgevoerd door gamma, helling en middentonen door de lichten iets te verzwakken. Let op, dit is geen vervanging van 'Reconstructie Hoge lichten'.\n\nGamma-gebaseerd en Helling-gebaseerd (Standaard en Geavanceerd) stelt u in staat toonmapping te simuleren met behulp van:\na) Opname-omstandigheden: Zwart LW, Wit LW, Gemiddelde luminantie (Yb%)\nb) Weergaveomstandigheden: Gemiddelde luminantie (Yb%).\n\nSchaal Yb Opname is een functie van Wit LW. +TP_LOCALLAB_SMOOTHCIE_YB;Schaal Yb Weergave TP_LOCALLAB_SOFT;Zacht licht & Originele Retinex TP_LOCALLAB_SOFTM;Zacht licht +TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Pas een Zacht-licht mengmodus toe (identiek aan de globale aanpassing). Voer doordrukken en tegenhouden uit met het originele Retinex-algoritme. TP_LOCALLAB_SOFTRADIUSCOL;Radius verzachting +TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Past een Begeleid filter toe op het uitvoerbeeld om mogelijke onregelmatigheden te verminderen. TP_LOCALLAB_SOFTRETI;Verminder ΔE-onregelmatgheden TP_LOCALLAB_SOFT_TOOLNAME;Zacht licht & Originele Retinex TP_LOCALLAB_SOURCE_ABS;Absolute luminantie TP_LOCALLAB_SOURCE_GRAY;Gemiddelde luminantie (Yb%) TP_LOCALLAB_SPECCASE;Specifieke gevallen TP_LOCALLAB_SPECIAL;Speciaal gebruik van RGB-curven +TP_LOCALLAB_SPECIAL_TOOLTIP;Het selectievakje stelt u in staat om alle andere acties te verwijderen: 'Bereik', maskers, schuiven, enz., (behalve overgangen) en alleen het effect van de RGB-tooncurve te gebruiken. TP_LOCALLAB_SPOTNAME;Nieuwe spot TP_LOCALLAB_STD;Standaard TP_LOCALLAB_STR;Kracht @@ -3242,14 +3601,19 @@ TP_LOCALLAB_STRBL;Kracht TP_LOCALLAB_STREN;Compressiesterkte TP_LOCALLAB_STRENG;Kracht TP_LOCALLAB_STRENGR;Kracht +TP_LOCALLAB_STRENGRID_TOOLTIP;U kunt het gewenste effect aanpassen met 'kracht', maar u kunt ook de 'bereik'-functie gebruiken om de actie te begrenzen (bijvoorbeeld om een specifieke kleur te isoleren). TP_LOCALLAB_STRENGTH;Ruis TP_LOCALLAB_STRENGTHCIELOG;Kracht TP_LOCALLAB_STRGRID;Kracht TP_LOCALLAB_STRUC;Structuur TP_LOCALLAB_STRUCCOL;Spotstructuur TP_LOCALLAB_STRUCCOL1;Spotstructuur +TP_LOCALLAB_STRUCT_TOOLTIP;Gebruikt het Sobel-algoritme om structuur voor vormdetectie te gebruiken.\nActiveer 'Masker en Modificaties' > 'Toon spotstructuur' (Geavanceerde modus) om een voorbeeld van het masker te zien (zonder wijzigingen).\n\nKan worden gebruikt in combinatie met het Structuurmasker, Vervagingsmasker en Lokaal contrast (op wavelet-niveau) om de randdetectie te verbeteren.\n\nEffecten van aanpassingen met behulp van Helderheid, Contrast, Chrominantie, Belichting of andere niet-masker-gerelateerde hulpmiddelen zijn zichtbaar met 'Toon gewijzigde afbeelding' of 'Toon gewijzigde gebieden met masker'. TP_LOCALLAB_STRUMASKCOL;Kracht structuurmasker +TP_LOCALLAB_STRUMASK_TOOLTIP;Structuurmasker (schuif) met 'Structuurmasker als hulpmiddel' niet aangevinkt: In dit geval wordt een masker gegenereerd dat de structuur toont, zelfs als geen van de drie curves is geactiveerd. Structuurmaskers zijn beschikbaar voor Masker (Vervaag en Ruisonderdrukking) en masker (Kleur & Licht). +TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Matig gebruik van deze schuif wordt aanbevolen! TP_LOCALLAB_STYPE;Vorm - methode +TP_LOCALLAB_STYPE_TOOLTIP;U kunt kiezen tussen:\nSymmetrisch - linkerhendel gekoppeld aan rechterhendel, bovenhendel gekoppeld aan onderhendel.\nOnafhankelijk - alle hendels zijn onafhankelijk. TP_LOCALLAB_SYM;Symmetrisch (muis) TP_LOCALLAB_SYMSL;Symmetrisch (muis + schuiven) TP_LOCALLAB_TARGET_GRAY;Gemiddelde luminantie (Yb%) @@ -3259,33 +3623,83 @@ TP_LOCALLAB_THRESDELTAE;Drempel ΔE-bereik TP_LOCALLAB_THRESRETI;Drempel TP_LOCALLAB_THRESWAV;Balansdrempel TP_LOCALLAB_TLABEL;TM Min=%1 Max=%2 Gemiddeld=%3 Sig=%4 +TP_LOCALLAB_TLABEL_TOOLTIP;Resultaat transmissiekaart.\nMin en Max worden gebruikt door Variantie.\nTm=Min TM=Max van de transmissiekaart.\nU kunt de resultaten normaliseren met de drempelschuif. TP_LOCALLAB_TM;Toonmappen TP_LOCALLAB_TM_MASK;Gebruik transmissiemap +TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;Deze schuif beïnvloedt de randgevoeligheid.\nHoe groter de waarde, hoe waarschijnlijker een verandering in contrast als een rand wordt geïnterpreteerd.\nAls deze op nul is ingesteld, heeft de toonmapping een soortgelijk effect als een onscherptemasker. +TP_LOCALLAB_TONEMAPGAM_TOOLTIP;De Gamma-schuif verschuift het toonmapping-effect of naar de schaduwen of naar de hoge lichten. +TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In sommige gevallen kan toonmapping resulteren in een cartooneske uitstraling, en in zeldzame gevallen kunnen zachte maar brede halo's verschijnen.\nHet verhogen van het aantal herwegingsiteraties helpt sommige van deze problemen te bestrijden. +TP_LOCALLAB_TONEMAP_TOOLTIP;Zelfde als het toonmapgereedschap in het hoofdmenu.\nHet gereedschap in het hoofdmenu moet worden gedeactiveerd als dit gereedschap wordt gebruikt. +TP_LOCALLAB_TONEMASCALE_TOOLTIP;Met deze schuif kunt u de overgang tussen 'lokaal' en 'globaal' contrast aanpassen.\nHoe hoger de waarde, hoe groter een detail moet zijn om te worden versterkt. TP_LOCALLAB_TONE_TOOLNAME;Toonmappen TP_LOCALLAB_TOOLCOL;Structuurmasker als gereedschap +TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Hiermee kunt u het masker wijzigen, indien aanwezig. TP_LOCALLAB_TOOLMASK;Maskergereedschappen TP_LOCALLAB_TOOLMASK_2;Wavelets +TP_LOCALLAB_TOOLMASK_TOOLTIP;Structuurmasker (schuif) met het selectievakje 'Structuurmasker als hulpmiddel' aangevinkt: in dit geval wordt een masker gegenereerd dat de structuur toont nadat een of meer van de twee curves L(L) of LC(H) is gewijzigd.\nHier gedraagt het Structuurmasker zich als de andere Maskerhulpmiddelen: Gamma, Helling, enz.\nHet stelt u in staat de actie op het masker te variëren volgens de structuur van het beeld. TP_LOCALLAB_TRANSIT;Transitieverloop TP_LOCALLAB_TRANSITGRAD;Transitie-differentiatie XY +TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Hiermee kunt u de transitie op de y-as variëren. TP_LOCALLAB_TRANSITVALUE;Transitiewaarde TP_LOCALLAB_TRANSITWEAK;Transitieverval (lineair-log) +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Past de transitievervalfunctie aan: 1. lineair, 2. parabolisch, 3. kubiek tot ^25.\nKan worden gebruikt in combinatie met zeer lage transitiewaarden om defecten te verminderen (CBDL, Wavelets, Kleur & Licht). +TP_LOCALLAB_TRANSIT_TOOLTIP;Pas de gladheid van de transitie tussen betrokken en niet-betrokken gebieden aan als een percentage van de straal. TP_LOCALLAB_TRANSMISSIONGAIN;Transmissieversterking TP_LOCALLAB_TRANSMISSIONMAP;Transmissiemap +TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmissie volgens transmissie.\nAbscis: transmissie van negatieve waarden (min), gemiddelde en positieve waarden (max).\nOrdinaat: versterking of vermindering.\nU kunt deze curve aanpassen om de Transmissie te wijzigen en onregelmatigheden te verminderen. TP_LOCALLAB_TRCFRAME;Toonresponscurve (TRC) & Middentonen TP_LOCALLAB_USEMASK;Laplacian TP_LOCALLAB_VART;Variantie (contrast) TP_LOCALLAB_VIBRANCE;Levendigheid & Warm/Koel +TP_LOCALLAB_VIBRA_TOOLTIP;Past de levendigheid aan (in feite hetzelfde als de globale aanpassing).\nVoert het equivalent van een witbalansaanpassing uit met behulp van een CIECAM-algoritme. TP_LOCALLAB_VIB_TOOLNAME;Levendigheid & Warm/Koel +TP_LOCALLAB_VIS_TOOLTIP;Klik om geselecteerde Controlespot te tonen/verbergen.\nCtrl+klik om alle Controlespots te tonen/verbergen. TP_LOCALLAB_WARM;Warm/Koel & Kleuronregelmatigheden +TP_LOCALLAB_WARM_TOOLTIP;Deze schuif gebruikt het CIECAM-algoritme en werkt als een witbalansregeling om de kleurtemperatuur van het geselecteerde gebied warmer of koeler te maken.\nIn sommige gevallen kan het ook kleuronregelmatigheden verminderen. +TP_LOCALLAB_WASDEN_TOOLTIP;Luminantieruisonderdrukking: de linkerkant van de curve inclusief de donkergrijs/lichtgrijs grens komt overeen met de eerste drie niveaus 0, 1, 2 (fijne details). De rechterkant van de curve komt overeen met de grovere details (niveaus 3, 4, 5, 6). +TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balanceert de actie binnen elk niveau. +TP_LOCALLAB_WAT_BLURLC_TOOLTIP;De standaard vervagingsinstelling beïnvloedt alle drie L*a*b*-componenten (luminantie en kleur).\nIndien aangevinkt wordt alleen luminantie vervaagd. +TP_LOCALLAB_WAT_CLARIC_TOOLTIP;'Chroma samenvoegen' wordt gebruikt om de intensiteit van het gewenste effect op chrominantie te selecteren. +TP_LOCALLAB_WAT_CLARIL_TOOLTIP;'Luma samenvoegen' wordt gebruikt om de intensiteit van het gewenste effect op luminantie te selecteren. +TP_LOCALLAB_WAT_CONTCHROMALEV_TOOLTIP;'Chroma-niveaus': past de 'a'- en 'b'-componenten van Lab* aan als een verhouding van de luminantiewaarde. +TP_LOCALLAB_WAT_CONTOFFSET_TOOLTIP;Verschuiving wijzigt de balans tussen laag-contrast en hoog-contrast details.\nHoge waarden versterken contrastveranderingen voor de details met meer contrast, terwijl lage waarden contrastveranderingen voor details met weinig contrast versterken.\nDoor een lage 'Verzwakkingsrespons'-waarde te gebruiken kunt u selecteren welke contrastwaarden worden versterkt. +TP_LOCALLAB_WAT_DELTABAL_TOOLTIP;Door de schuif naar links te bewegen, worden de lagere niveaus geaccentueerd. Naar rechts worden de lagere niveaus verminderd en de hogere niveaus geaccentueerd. +TP_LOCALLAB_WAT_EXPRESID_TOOLTIP;Het residuele beeld gedraagt zich op dezelfde manier als het hoofdbeeld bij het aanpassen van contrast, chroma, enz. +TP_LOCALLAB_WAT_GRADW_TOOLTIP;Hoe meer u de schuif naar rechts beweegt, hoe effectiever het detectie-algoritme zal zijn en hoe minder merkbaar de effecten van lokaal contrast. +TP_LOCALLAB_WAT_LEVELLOCCONTRAST_TOOLTIP;Laag tot hoog lokaal contrast van links naar rechts op de x-as.\nVerhoogt of verlaagt lokaal contrast op de y-as. +TP_LOCALLAB_WAT_LOCCONTRASTEDG_TOOLTIP;U kunt de verdeling van lokaal contrast aanpassen per wavelet-niveau op basis van de initiële intensiteit van het contrast. Dit zal de effecten van perspectief en reliëf in de afbeelding wijzigen, en/of de contrastwaarden voor zeer lage initiële contrastniveaus verminderen. +TP_LOCALLAB_WAT_ORIGLC_TOOLTIP;'Alleen samenvoegen met origineel beeld', voorkomt dat de 'Wavelet Pyramide'-instellingen interfereren met 'Klaarheid (Clarity)' en 'Scherptemasker'. +TP_LOCALLAB_WAT_RESIDBLUR_TOOLTIP;Vervaagt het residuele beeld, onafhankelijk van de niveaus. +TP_LOCALLAB_WAT_RESIDCOMP_TOOLTIP;Comprimeert het residuele beeld om het contrast te verhogen of te verlagen. +TP_LOCALLAB_WAT_SIGMALC_TOOLTIP;Het effect van de lokale contrastaanpassing is sterker voor details met middelmatig contrast en zwakker voor hoge en lage contrastdetails.\nDeze schuif regelt hoe snel het effect vermindert naar de extreme contrasten.\nHoe hoger de waarde van de schuif, des te breder het contrastbereik dat het volledige effect van de lokale contrastaanpassing ontvangt en hoe hoger het risico op het genereren van onregelmatigheden.\nHoe lager de waarde, hoe gerichter het effect zal zijn op een smal bereik van contrastwaarden. +TP_LOCALLAB_WAT_STRENGTHW_TOOLTIP;Intensiteit van rand-effect detectie. +TP_LOCALLAB_WAT_STRWAV_TOOLTIP;Staat toe om het lokale contrast te variëren volgens een gekozen verloop en hoek. De variatie van het luminantiesignaal wordt in acht genomen, en niet de luminantie. +TP_LOCALLAB_WAT_THRESHOLDWAV_TOOLTIP;Bereik van wavelet-niveaus gebruikt door het hele Wavelets-module. +TP_LOCALLAB_WAT_WAVBLURCURV_TOOLTIP;Hiermee kunt u elk niveau van decompositie vervagen.\nDe fijnste tot grofste niveaus van decompositie zijn van links naar rechts. +TP_LOCALLAB_WAT_WAVCBDL_TOOLTIP;Vergelijkbaar met Contrast per Detailniveaus. Fijne tot grove detailniveaus van links naar rechts op de x-as. +TP_LOCALLAB_WAT_WAVDELTABAL_TOOLTIP;Werkt op de balans van de drie richtingen (horizontaal, verticaal en diagonaal), gebaseerd op de luminantie van de afbeelding.\nStandaard worden de schaduwen of hoge lichten verminderd om onregelmatigheden te vermijden. +TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Toont alle 'Randscherpte'-gereedschappen. Het is raadzaam de documentatie van Wavelet-niveaus te lezen. +TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Pas het maximale effect van vervaging op de niveaus aan. +TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Laag tot hoog lokaal contrast van links naar rechts op de x-as\nVerhoog of verlaag lokaal contrast op de y-as. +TP_LOCALLAB_WAT_WAVTM_TOOLTIP;Het lagere (negatieve) deel comprimeert elk niveau van decompositie, waardoor een toonmap-effect ontstaat.\nHet bovenste (positieve) deel verzwakt het contrast per niveau.\nDe fijnste tot grofste niveaus van decompositie zijn van links naar rechts op de x-as. TP_LOCALLAB_WAV;Lokaal contrast +TP_LOCALLAB_WAVBLUR_TOOLTIP;Hiermee kunt u elk niveau van decompositie vervagen, evenals het residuele beeld. TP_LOCALLAB_WAVCOMP;Compressie per niveau TP_LOCALLAB_WAVCOMPRE;Compressie per niveau +TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Pas toon-mapping toe of verminder lokaal contrast op individuele niveaus.\nFijne tot grove detailniveaus van links naar rechts op de x-as. +TP_LOCALLAB_WAVCOMP_TOOLTIP;Pas lokaal contrast toe gebaseerd op de richting van de wavelet-decompositie: horizontaal, verticaal, diagonaal. TP_LOCALLAB_WAVCON;Contrast per niveau +TP_LOCALLAB_WAVCONTF_TOOLTIP;Vergelijkbaar met Contrast per Detailniveaus. Fijne tot grove detailniveaus van links naar rechts op de x-as. TP_LOCALLAB_WAVDEN;Luminantie ruisvermindering TP_LOCALLAB_WAVE;Wavelets TP_LOCALLAB_WAVEDG;Lokaal contrast +TP_LOCALLAB_WAVEEDG_TOOLTIP;Verbetert de scherpte door de actie van lokaal contrast op de randen te richten. Het heeft dezelfde functies als de corresponderende module in Wavelet-niveaus en gebruikt dezelfde instellingen. +TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Bereik van wavelet-niveaus gebruikt in 'Lokaal contrast' (per wavelet-niveau). +TP_LOCALLAB_WAVGRAD_TOOLTIP;Varieer het lokale contrast volgens een gekozen verloop en hoek. De variatie van het luminantiesignaal wordt in acht genomen, en niet de luminantie. +TP_LOCALLAB_WAVHUE_TOOLTIP;Versterk of verminder de ruisonderdrukking op basis van tint. TP_LOCALLAB_WAVLEV;Vervaag per niveau TP_LOCALLAB_WAVMASK;Lokaal contrast +TP_LOCALLAB_WAVMASK_TOOLTIP;Gebruikt wavelets om het lokale contrast van het masker te wijzigen en de structuur (huid, gebouwen, etc.) te versterken of te verzwakken. TP_LOCALLAB_WEDIANHI;Mediaan Hi TP_LOCALLAB_WHITE_EV;Wit LW TP_LOCALLAB_ZCAMFRA;ZCAM Beeldaanpassingen @@ -3294,6 +3708,7 @@ TP_LOCAL_HEIGHT;Onder TP_LOCAL_HEIGHT_T;Boven TP_LOCAL_WIDTH;Rechts TP_LOCAL_WIDTH_L;Links +TP_LOCRETI_METHOD_TOOLTIP;Laag = Versterk weinig licht.\nUniform = Gelijkmatig verdeeld.\nHoog = Versterk sterk licht. TP_METADATA_EDIT;Pas wijzigingen toe TP_METADATA_MODE;Metadata kopieermodus TP_METADATA_STRIP;Strip alle metadata @@ -3317,6 +3732,8 @@ TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontale verschuiving TP_PERSPECTIVE_CAMERA_SHIFT_VERTICAL;Verticale verschuiving TP_PERSPECTIVE_CAMERA_YAW;Horizontaal TP_PERSPECTIVE_CONTROL_LINES;Controlelijnen +TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+slepen: Teken nieuwe lijn\nRechtsklik: Verwijder lijn +TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;Minimaal twee horizontale of twee verticale controlelijnen zijn vereist. TP_PERSPECTIVE_HORIZONTAL;Horizontaal TP_PERSPECTIVE_LABEL;Perspectief TP_PERSPECTIVE_METHOD;Methode @@ -3408,6 +3825,7 @@ TP_RAW_MONO;Mono TP_RAW_NONE;Geen (Toont sensorpatroon) TP_RAW_PIXELSHIFT;Pixel Shift TP_RAW_PIXELSHIFTAVERAGE;Gebruik gemiddelde voor bewegende delen +TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Gebruik het gemiddelde van alle frames in plaats van het geselecteerde frame voor gebieden met beweging.\nGeeft een bewegend effect op langzaam bewegende (overlappende) objecten. TP_RAW_PIXELSHIFTBLUR;Vervaag bewegingsmasker TP_RAW_PIXELSHIFTDMETHOD;Demozaïek voor beweging TP_RAW_PIXELSHIFTEPERISO;Gevoeligheid @@ -3506,7 +3924,7 @@ TP_RETINEX_MAP;Methode TP_RETINEX_MAP_GAUS;Gaussiaans masker TP_RETINEX_MAP_MAPP;Scherptemasker (wavelet gedeeltelijk) TP_RETINEX_MAP_MAPT;Scherptemasker (wavelet totaal) -TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en onregelmatigheden te verminderen.\n\nCurve: past een diagonale contrastcurve toe op het masker.\nHou rekening met onregelmatigheden!\n\n Gausiaans: genereert en gebruikt een Gausiaanse vervaging op het masker.\nVerscherpen: genereert en gebruikt een wavelet op het masker.\nLangzaam. +TP_RETINEX_MAP_METHOD_TOOLTIP;Gebruik het masker dat is aangemaakt door de bovenstaande Gausiaanse functie (Straal, Methode) om halo’s en onregelmatigheden te verminderen.\n\nCurve: past een diagonale contrastcurve toe op het masker.\nHou rekening met onregelmatigheden!\n\nGausiaans: genereert en gebruikt een Gausiaanse vervaging op het masker.\nVerscherpen: genereert en gebruikt een wavelet op het masker.\nLangzaam. TP_RETINEX_MAP_NONE;Geen TP_RETINEX_MEDIAN;Transmissiemediaan-filter TP_RETINEX_METHOD;Methode @@ -3514,8 +3932,8 @@ TP_RETINEX_METHOD_TOOLTIP;Laag: schaduwen ophelderen,\nUniform: gelijkmatig,\nHo TP_RETINEX_MLABEL;Teruggeplaatst sluiervrij Min=%1 Max=%2 TP_RETINEX_MLABEL_TOOLTIP;De waarden zouden dichtbij Min=0 en Max=32768 (log-modus) moeten liggen, maar andere waarden zijn mogelijk. Pas 'Kap herstelde data (versterking)' en 'Verschuiving' aan om te normaliseren. \nHerstelt beeldgegevens zonder menging. TP_RETINEX_NEIGHBOR;Naburige pixels -TP_RETINEX_NEUTRAL;Beginwaarde -TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarde. +TP_RETINEX_NEUTRAL;Beginwaarden +TP_RETINEX_NEUTRAL_TOOLTIP;Zet alles terug naar de beginwaarden. TP_RETINEX_OFFSET;Beginpunt TP_RETINEX_SCALES;Gaussiaans verloop TP_RETINEX_SCALES_TOOLTIP;Als schuifbalk = 0, dan zijn alle herhalingen gelijk.\nIndien > 0 dan worden schaal en straal verkleind als de herhaling toeneemt, en omgekeerd. @@ -3591,7 +4009,7 @@ TP_SOFTLIGHT_STRENGTH;Sterkte TP_SPOT_COUNTLABEL;%1 punt(en) TP_SPOT_DEFAULT_SIZE;Standaard spot-grootte TP_SPOT_ENTRYCHANGED;Punt veranderd -TP_SPOT_HINT;Klik op deze button... Click on this button to be able to operate on the preview area.\n\nTo edit a spot, hover the white mark locating an edited area, making the editing geometry appear.\n\nTo add a spot, press Ctrl and left mouse button, drag the circle (Ctrl key can be released) to a source location, then release the mouse button.\n\nTo move the source or destination spot, hover its center then drag it.\n\nThe inner circle (maximum effect area) and the 'feather' circle can be resized by hovering them (the circle becomes orange) and dragging it (the circle becomes red).\n\nWhen the changes are done, right click outside any spot to end the Spot editing mode, or click on this button again. +TP_SPOT_HINT;Druk op deze knop om in de voorbeeldweergave te werken.\n\nOm een plek te bewerken, beweeg de muis over de witte markering die het bewerkte gebied aangeeft, zodat de bewerkingsgeometrie zichtbaar wordt.\n\nOm een plek toe te voegen, houd Ctrl ingedrukt en klik met de linkermuisknop, sleep de cirkel (de Ctrl-toets kan nu worden losgelaten) naar een bronlocatie en laat de muisknop los.\n\nOm de bron- of bestemmingsplek te verplaatsen, beweeg de muis naar het midden en sleep deze.\n\nDe binnencirkel (maximaal effectgebied) en de vervagingscirkel kunnen worden vergroot of verkleind door er met de muis overheen te bewegen (de cirkel wordt oranje) en deze te slepen (de cirkel wordt rood).\n\nWanneer de wijzigingen zijn voltooid, klikt u met de rechtermuisknop buiten een plek om de plekbewerkingsmodus te beëindigen, of klik opnieuw op deze knop. TP_SPOT_LABEL;Verwijder vlekken TP_TM_FATTAL_AMOUNT;Hoeveelheid TP_TM_FATTAL_ANCHOR;Anker @@ -3673,13 +4091,13 @@ TP_WAVELET_CHROFRAME;Vervaag chrominantie TP_WAVELET_CHROMAFRAME;Chroma TP_WAVELET_CHROMCO;Chrominantie grof TP_WAVELET_CHROMFI;Chrominantie fijn -TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel +TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n1-x niveau verzadigd\nx-9 niveau pastel TP_WAVELET_CHRWAV;Vervaging chroma TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met contrastniveaus TP_WAVELET_CHSL;Schuifbalken TP_WAVELET_CHTYPE;Chrominantiemethode TP_WAVELET_CLA;Klaarheid (Clarity) -TP_WAVELET_CLARI;Scherptemasker en Clarity +TP_WAVELET_CLARI;Scherptemasker en Klaarheid (Clarity) TP_WAVELET_COLORT;Dekking Rood-Groen niveau TP_WAVELET_COMPCONT;Contrast TP_WAVELET_COMPEXPERT;Geavanceerd @@ -3718,6 +4136,8 @@ TP_WAVELET_DEN5THR;Begeleid drempel TP_WAVELET_DENCURV;Curve TP_WAVELET_DENL;Correctie structuur TP_WAVELET_DENLH;Begeleid drempel niveaus 1-4 +TP_WAVELET_DENLOCAL_TOOLTIP;Gebruik een curve om de ruisonderdrukking te sturen volgens het lokale contrast.\nDe gebieden worden ontdaan van ruis, de structuren blijven behouden. +TP_WAVELET_DENMIX_TOOLTIP;De referentiewaarde van het lokale contrast die door het Begeleid filter wordt gebruikt.\nAfhankelijk van de afbeelding kunnen de resultaten variëren. Dit hangt af van of de ruis wordt gemeten voor of na de ruisonderdrukking. Deze vier keuzes stellen u in staat om verschillende combinaties van de originele en gewijzigde (gereduceerde ruis) afbeeldingen te beoordelen om het beste compromis te vinden. TP_WAVELET_DENOISE;Gids curve gebaseerd op Lokaal contrast TP_WAVELET_DENOISEGUID;Begeleide drempel gebaseerd op tint TP_WAVELET_DENOISEH;Hoge niveaus curve Lokaal contrast @@ -3735,6 +4155,7 @@ TP_WAVELET_DTHR;Diagonaal TP_WAVELET_DTWO;Horizontaal TP_WAVELET_EDCU;Curve TP_WAVELET_EDEFFECT;Versterkingsrespons +TP_WAVELET_EDEFFECT_TOOLTIP;Deze schuif selecteert het bereik van contrastwaarden waarop het volledige effect van elke aanpassing zal worden toegepast. TP_WAVELET_EDGCONT;Lokaal contrast TP_WAVELET_EDGCONT_TOOLTIP;Schuif de punten naar links om het contrast te verminderen, naar rechts vergroot het contrast.\nLinksonder, Linksboven, Rechtsboven, Rechtsonder vertegenwoordigen respectievelijk lokaal contast voor lage waarden, gemiddeld, gemiddeld+stdev en maximum. TP_WAVELET_EDGE;Randen verscherpen (Luminantie) @@ -3756,6 +4177,7 @@ TP_WAVELET_EDVAL;Waarde TP_WAVELET_FINAL;Finale Bewerking TP_WAVELET_FINCFRAME;Finaal lokaal contrast TP_WAVELET_FINEST;fijn +TP_WAVELET_FINTHR_TOOLTIP;Gebruikt lokaal contrast om de werking van het Begeleid filter te verminderen of te versterken. TP_WAVELET_GUIDFRAME;Uiteindelijke verzachting (begeleid filter) TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantiereeks (0..100) TP_WAVELET_HS1;Alle luminanties @@ -3811,6 +4233,7 @@ TP_WAVELET_NPLOW;Laag TP_WAVELET_NPNONE;Geen TP_WAVELET_NPTYPE;Naburige pixels TP_WAVELET_NPTYPE_TOOLTIP;Gebruikt de nabijheid van een pixel en acht naburige pixels. Indien weinig verschil, dan worden randen verscherpt. +TP_WAVELET_OFFSET_TOOLTIP;De verschuiving wijzigt de balans tussen details met laag contrast en met hoog contrast.\nHoge waarden versterken de contrastveranderingen in de details met hoog contrast, terwijl lage waarden de contrastveranderingen in details met laag contrast versterken.\nDoor een lage verzwakkingsresponswaarde te gebruiken, kunt u selecteren welke contrastwaarden worden versterkt. TP_WAVELET_OLDSH;Algoritme met negatieve waarden TP_WAVELET_OPACITY;Dekking Blauw-Geel niveau TP_WAVELET_OPACITYW;Contrastbalans d/v-h curve @@ -3841,6 +4264,7 @@ TP_WAVELET_SHOWMASK;Toon wavelet-masker TP_WAVELET_SIGM;Straal TP_WAVELET_SIGMA;Verzwakkingsrespons TP_WAVELET_SIGMAFIN;Verzwakkingsrespons +TP_WAVELET_SIGMA_TOOLTIP;Het effect van de contrastschuiven is sterker in details met gemiddeld contrast en zwakker in details met hoog en laag contrast.\nMet deze schuif kunt u regelen hoe snel het effect afneemt naar de extreme contrasten.\nHoe hoger de schuif is ingesteld, hoe breder het bereik van contrasten dat een sterke verandering zal ondergaan, en hoe groter het risico op onregelmatigheden.\nHoe lager het is, hoe meer het effect wordt gericht op een nauwer bereik van contrastwaarden. TP_WAVELET_SKIN;Huidtinten wijzigen/beschermen TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen @@ -3851,6 +4275,7 @@ TP_WAVELET_STREND;Kracht TP_WAVELET_STRENGTH;Sterkte TP_WAVELET_SUPE;Extra TP_WAVELET_THR;Drempel schaduwen +TP_WAVELET_THRDEN_TOOLTIP;Genereert een getrapte curve die wordt gebruikt om de ruisonderdrukking aan te sturen als functie van lokaal contrast. De ruisonderdrukking zal worden toegepast op uniforme gebieden met laag lokaal contrast. Gebieden met details (hoger lokaal contrast) worden behouden. TP_WAVELET_THREND;Drempel lokaal contrast TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveaus (fijn naar grof - leidend) TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveaus (grof naar fijn) @@ -3869,7 +4294,8 @@ TP_WAVELET_TMTYPE;Compressiemethode TP_WAVELET_TON;Kleurtinten TP_WAVELET_TONFRAME;Uitgesloten kleuren TP_WAVELET_USH;Geen -TP_WAVELET_USHARP;'Clarity'-methode +TP_WAVELET_USHARP;Klaarheidmethode (Clarity) +TP_WAVELET_USH_TOOLTIP;Als u het scherptemasker selecteert, kunt u elk niveau (in Instellingen) van 1 tot 4 kiezen voor verwerking.\nAls u Klaarheid (Clarity) selecteert, kunt u elk niveau (in Instellingen) tussen 5 en Extra kiezen. TP_WAVELET_WAVLOWTHR;Laag contrast drempel TP_WAVELET_WAVOFFSET;Verschuiving TP_WBALANCE_AUTO;Automatisch @@ -3902,18 +4328,29 @@ TP_WBALANCE_FLUO_HEADER;Fluorescent(TL) TP_WBALANCE_GREEN;Groentint TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI +TP_WBALANCE_ITCWALG_TOOLTIP;Hiermee kunt u overschakelen naar de andere Alternatieve temperatuur (Alt_temp), indien mogelijk.\nInactief in het geval van 'enkele keuze'. +TP_WBALANCE_ITCWBDELTA_TOOLTIP;Het temperatuurverschil dat in aanmerking moet worden genomen voor elke 'groene' iteratie die geprobeerd is. +TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Vind het beste compromis tussen Student en groen. +TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Hiermee kunt u de minimale patchwaarde instellen. Te lage waarden kunnen leiden tot een gebrek aan correlatie. +TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Hiermee kunt u magenta/paarse gegevens uit de afbeelding filteren. Als het vakje is aangevinkt, wordt een filter toegepast dat de waarde van Y beperkt. Standaard is deze waarde 0,4. U kunt dit wijzigen in 'opties' Itcwb_Ypurple (Maximaal 1) +TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Hoe lager de waarde, hoe relevanter de data, maar dit verlengt de verwerkingstijd. Aangezien de verwerkingstijd laag is, zou deze parameter over het algemeen op de standaardwaarde moeten blijven staan. +TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Stelt de beoordelingsamplitude van de groene waarde in herhalingen in, van lage amplitude 0,82 tot 1,25 tot maximale amplitude 0,4 tot 4. +TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Deze instelling bepaalt de grootte van kleurdata die door het algoritme worden gebruikt. +TP_WBALANCE_ITCWBSIZE_TOOLTIP;Deze instelling bepaalt het aantal iteraties om de beste overeenkomst te vinden tussen de referentie-spectrale kleuren en die in xyY-waarde van de afbeelding. Een waarde van 3 lijkt een goed compromis. +TP_WBALANCE_ITCWBTHRES_TOOLTIP;Beperkt vergelijkings-sampling tussen spectrale data en beelddata. TP_WBALANCE_ITCWB_ALG;Verwijder 2-pas algoritme TP_WBALANCE_ITCWB_CUSTOM;Gebruik aangepaste temperatuur & tint TP_WBALANCE_ITCWB_DELTA;Delta temperatuur in groene lus TP_WBALANCE_ITCWB_FGREEN;Vind groene student -TP_WBALANCE_ITCWB_FORCED;Dichtbij volledig CIE-diagram +TP_WBALANCE_ITCWB_FORCED;Dwingt het gebruik van het volledige CIE-diagram af. TP_WBALANCE_ITCWB_FRA;Autom. instellingen temperatuurcorrelatie +TP_WBALANCE_ITCWB_FRA_TOOLTIP;Deze instellingen maken, afhankelijk van de afbeeldingen (raw-type, kleurmeting, etc.), een aanpassing van het 'Temperatuurcorrelatie'-algoritme mogelijk. Er is geen absolute regel die deze parameters koppelt aan de verkregen resultaten. TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimumgrootte TP_WBALANCE_ITCWB_NOPURPLE;Filter op paars TP_WBALANCE_ITCWB_PRECIS;Precisie-algoritme - schaal gebruikt TP_WBALANCE_ITCWB_PRIM_ACE;Forceer gebruik van het gehele CIE-diagram TP_WBALANCE_ITCWB_PRIM_ADOB;Medium sampling -TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - nabij Pointer's kleurenscala +TP_WBALANCE_ITCWB_PRIM_BETA;Medium sampling - nabij Pointers kleuromvang TP_WBALANCE_ITCWB_PRIM_JDCMAX;Nabij volledig CIE-diagram TP_WBALANCE_ITCWB_PRIM_REC;Hoge sampling TP_WBALANCE_ITCWB_PRIM_SRGB;Lage sampling & Gebruik geen camera-instellingen @@ -3924,7 +4361,12 @@ TP_WBALANCE_ITCWB_SAMPLING;Lage sampling 5,9 TP_WBALANCE_ITCWB_SIZE;Grootte ref.kleur vergelijk met histogram TP_WBALANCE_ITCWB_SIZEPATCH;Grootte kleur-patch TP_WBALANCE_ITCWB_THRES;Kleuren gebruikt in afbeelding (voorinstelling) +TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Hiermee kunt u Aangepaste instellingen voor Temperatuur en Groen (tint) gebruiken.\n\nGebruiksaanwijzing:\n1) start Itcwb, schakel 'Gebruik Aangepaste temperatuur en tint' in.\n2) Stel 'Temperatuur en tint' in naar wens: vrij, Kies,...(Aangepast)\n3) ga terug naar 'Temperatuurcorrelatie'.\n\nU kunt niet gebruiken: 2-gangen, AWB temperatuurnadruk, Groenverfijning. +TP_WBALANCE_ITCWFORCED_TOOLTIP;Standaard (vakje niet aangevinkt) worden de gegevens die tijdens het scannen worden gesampled, teruggebracht naar het sRGB-profiel, dat het meest verspreid is, zowel voor het kalibreren van DCP- of ICC-profielen met de Colorchecker24, of voor webgebruik.\nAls u afbeeldingen met een zeer hoge kleuromvang hebt (sommige bloemen, kunstmatige kleuren), kan het nodig zijn om het hele CIExy-diagram te gebruiken, het profiel dat wordt gebruikt zal ACESP0 zijn. In dit tweede geval zal het aantal kleuren dat intern aan het algoritme kan worden aangeboden, groter zijn. TP_WBALANCE_ITCWGREEN;Groen verfijning +TP_WBALANCE_ITCWGREEN_TOOLTIP;Hiermee kunt u de 'tint' (groen) wijzigen die als referentie zal dienen bij het starten van het algoritme. Het heeft in wezen dezelfde rol voor groen als 'AWB temperatuurnadruk' voor temperatuur.\nHet hele algoritme wordt opnieuw berekend. +TP_WBALANCE_ITCWPRIM_TOOLTIP;Hiermee kunt u de beeldsampling selecteren.\n'Dicht bij volledig CIE-diagram' gebruikt bijna alle gegevens die op de sensor aanwezig zijn, inclusief mogelijke imaginaire kleuren.\n'Camera XYZ-matrix' - gebruikt de matrix die rechtstreeks is afgeleid van de Kleurenmatrix.\n'Medium sampling' (standaard) - dicht bij Pointers kleuromvang (gamut): komt grotendeels overeen met de meest voorkomende gevallen van menselijke waarneming.\nDe andere keuze, 'Lage sampling en negeer camera-instellingen', stelt u in staat om hoge gamut-onderdelen van het beeld te isoleren en dwingt in sommige gevallen het algoritme (tint > 0,8, ...) om de camera-instellingen te negeren. Dit zal uiteraard invloed hebben op het resultaat.\n\nDeze sampling heeft alleen invloed op de kanaalvermenigvuldigers, het heeft niets te maken met het 'werkprofiel' en wijzigt de kleuromvang van de afbeelding niet. +TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Hiermee kunt u het oude sampling-algoritme gebruiken om betere compatibiliteit met versie 5.9 te garanderen. U moet Observer 10° (standaard) inschakelen. TP_WBALANCE_JUDGEIII;JudgeIII TP_WBALANCE_LABEL;Witbalans TP_WBALANCE_LAMP_HEADER;Lamp @@ -3933,9 +4375,13 @@ TP_WBALANCE_LED_HEADER;LED TP_WBALANCE_LED_LSI;LSI Lumelex 2040 TP_WBALANCE_METHOD;Methode TP_WBALANCE_MULLABEL;Vermenigvuldigers: r=%1 g=%2 b=%3 +TP_WBALANCE_MULLABEL_TOOLTIP;Waarden worden ter informatie verstrekt. U kunt ze niet wijzigen. TP_WBALANCE_OBSERVER10;Observer 10° in plaats van Observer 2° +TP_WBALANCE_OBSERVER10_TOOLTIP;Het kleurbeheer in RawTherapee (Witbalans, kanaalvermenigvuldigers, herstel hoge lichten, ...) gebruikt de spectrale gegevens van de lichtbron en kleuren. Observer is een belangrijke parameter van dit beheer, die rekening houdt met de kijkhoek van het oog. In 1931 werd deze vastgelegd op 2° (bevoorrecht het gebruik van de kegeltjes). In 1964 werd deze vastgelegd op 10° (bevoorrecht het gebruik van de kegeltjes, maar houdt gedeeltelijk rekening met de staafjes).\nIn het zeldzame geval van een kleurverschuiving met Observer 2° (waarschijnlijk door de conversiematrix) moet Observer 10° worden geselecteerd. TP_WBALANCE_PATCHLABEL;Lees kleuren:%1 Patch: Chroma:%2 Grootte=%3 +TP_WBALANCE_PATCHLABEL_TOOLTIP;Toont het aantal gelezen kleuren (max=237).\nToont de berekende Patch Chroma.\nAWB-temperatuurnadruk probeert deze waarde te verminderen, een minimum lijkt het algoritme te optimaliseren.\n\nPatchgrootte die overeenkomt met chroma-optimalisatie. TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE=%1 - data x 9 Min:%2 Max=%3 +TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Toont ΔE-patch (ervan uitgaande dat er voldoende spectrale data zijn), tussen beeld en spectrale gegevens.\nToont gelezen data die zijn gevonden. De twee waarden komen overeen met de minimale en maximale datawaarden die in aanmerking zijn genomen. De coëfficiënt x9 moet worden meegenomen om het aantal betrokken pixels in het beeld te verkrijgen. TP_WBALANCE_PICKER;Kies TP_WBALANCE_SHADE;Schaduw TP_WBALANCE_SIZE;Grootte: @@ -3947,6 +4393,7 @@ TP_WBALANCE_SPOTWB;Wijs WB aan TP_WBALANCE_STUDLABEL;Correlatiefactor: %1 Doorgangen:%2 Slechtst=%3 TP_WBALANCE_STUDLABEL0;Correlatiefactor: %1 Doorgangen:%2 Alt=%3 TP_WBALANCE_STUDLABEL1;Correlatiefactor: %1 Doorgangen:%2 Best_alt=%3 +TP_WBALANCE_STUDLABEL_TOOLTIP;Toont berekende Student-correlatie.\nLagere waarden zijn beter, waarbij <0,005 uitstekend is,\n<0,01 goed is, en >0,5 slecht is.\nLage waarden betekenen niet dat de witbalans goed is:\nals de lichtbron niet-standaard is, kunnen de resultaten grillig zijn.\nEen waarde van 1000 betekent dat eerdere berekeningen zijn gebruikt en\nde resultaten waarschijnlijk goed zijn.\n\nGangen: aantal gemaakte gangen.\nAlt_temp: Alternatieve temperatuur. TP_WBALANCE_TEMPBIAS;AWB temperatuur-afwijking TP_WBALANCE_TEMPBIAS_TOOLTIP;Wijzigt de berekening van auto-witbalans\ndoor een afwijking naar warmere of koelere temperatuur.\nDe afwijking wordt uitgedrukt als percentage van de berekende temperatuur,\nzodat het resultaat is: computedTemp + computedTemp * afwijking. TP_WBALANCE_TEMPERATURE;Kleurtemperatuur @@ -3966,7 +4413,6 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! -!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. !HISTORY_MSG_446;--unused-- !HISTORY_MSG_447;--unused-- !HISTORY_MSG_448;--unused-- @@ -3985,451 +4431,5 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - !HISTORY_MSG_470;--unused-- !HISTORY_MSG_580;--unused-- !HISTORY_MSG_664;--unused-- -!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast -!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW -!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius -!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) -!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights -!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows -!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure -!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool -!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) -!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels -!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle -!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution -!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X -!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y -!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression -!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold -!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white -!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation -!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast -!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools -!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam -!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma -!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut -!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X -!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y -!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant -!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q -!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones -!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L -!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries -!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X -!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y -!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors -!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x -!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y -!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid -!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability -!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method -!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope -!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance -!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene -!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method -!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing -!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode -!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L -!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength -!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC -!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution -!HISTORY_MSG_LOCAL_DEHAZE_BLACK;Local - Dehaze Black -!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather -!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather -!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather -!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather -!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather -!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather -!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather -!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather -!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution -!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness -!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution -!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates -!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f -!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples -!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths -!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. -!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank -!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: -!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. -!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue -!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: -!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time -!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template -!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. -!TP_COLORAPP_ADAPSCEN_TOOLTIP;Corresponds to the luminance in candelas per m2 at the time of shooting, calculated automatically from the exif data. -!TP_COLORAPP_CATMET_TOOLTIP;Classic - traditional CIECAM operation. The chromatic adaptation transforms are applied separately on 'Scene conditions' and basic illuminant on the one hand, and on basic illuminant and 'Viewing conditions' on the other.\n\nSymmetric – The chromatic adaptation is based on the white balance. The 'Scene conditions', 'Image adjustments' and 'Viewing conditions' settings are neutralized.\n\nMixed – Same as the 'Classic' option but in this case, the chromatic adaptation is based on the white balance. -!TP_COLORAPP_DEGREE_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D65) into new values whose white point is that of the new illuminant - see WP model (for example D50 or D55). -!TP_COLORAPP_DEGREOUT_TOOLTIP;CAT02/16 is a chromatic adaptation. It converts the values of an image whose white point is that of a given illuminant (for example D50) into new values whose white point is that of the new illuminant - see WP model (for example D75). -!TP_COLORAPP_GEN_TOOLTIP;This module is based on the CIECAM color appearance models, which were designed to better simulate how human vision perceives colors under different lighting conditions, e.g. against different backgrounds. It takes into account the environment of each color and modifies its appearance to get as close as possible to human perception. It also adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic appearance is preserved across the scene and display environments. -!TP_COLORAPP_ILLUM_TOOLTIP;Select the illuminant closest to the shooting conditions.\nIn general D50, but it can change depending on the time and latitude. -!TP_COLORAPP_MODELCAT_TOOLTIP;Allows you to choose between CAM02 or CAM16.\nCAM02 will sometimes be more accurate.\nCAM16 should generate fewer artifacts. -!TP_COLORAPP_SOURCEF_TOOLTIP;Corresponds to the shooting conditions and how to bring the conditions and data back to a 'normal' area. Normal means average or standard conditions and data, i.e. without taking into account CIECAM corrections. -!TP_COLORAPP_SURSOURCE_TOOLTIP;Changes tones and colors to take into account the surround conditions of the scene lighting. The darker the surround conditions, the brighter the image will become. Image brightness will not be changed when the surround is set to average. -!TP_COLORAPP_TEMP2_TOOLTIP;Either symmetrical mode temp = White balance.\nEither select illuminant always set Tint=1.\n\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504 -!TP_COLORAPP_TEMPOUT_TOOLTIP;Temperature and Tint.\nDepending on the choices made previously, the selected temperature is:\nWhite balance\nA temp=2856\nD41 temp=4100\nD50 temp=5003\nD55 temp=5503\nD60 temp=6000\nD65 temp=6504\nD75 temp=7504\nFree. -!TP_COLORAPP_VIEWINGF_TOOLTIP;Takes into account the support on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as its environment. This process will take the data coming from process 'Image Adjustments' and 'bring' it to the support in such a way that the viewing conditions and its environment are taken into account. -!TP_COLORAPP_YBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_COLORAPP_YBSCEN_TOOLTIP;Yb is the relative luminance of the background, expressed in % of gray. 18% gray corresponds to a background luminance of 50% expressed in CIE L.\nThe data is based on the mean luminance of the image. -!TP_ICM_ILLUMPRIM_TOOLTIP;Choose the illuminant closest to the shooting conditions.\nChanges can only be made when the 'Destination primaries' selection is set to 'Custom (sliders)'. -!TP_ICM_PRIMBLU_TOOLTIP;Primaries Blue:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 -!TP_ICM_PRIMGRE_TOOLTIP;Primaries Green:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 -!TP_ICM_PRIMILLUM_TOOLTIP;You can change an image from its original mode ('working profile') to a different mode ('destination primaries'). When you choose a different color mode for an image, you permanently change the color values in the image.\n\nChanging the 'primaries' is quite complex and difficult to use. It requires a lot of experimenting.\n It is capable of making exotic color adjustments as Channel Mixer primaries.\n Allows you to modify the camera calibration with Custom (sliders). -!TP_ICM_PRIMRED_TOOLTIP;Primaries Red:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 -!TP_ICM_TRCFRAME_TOOLTIP;Also known as 'synthetic' or 'virtual' profiles, which are applied at the end of the processing pipeline (prior to CIECAM) allowing you to create custom image effects.\nYou can make changes to the:\n 'Tone response curve', which modifies the tones of the image.\n 'Illuminant', which allows you to change the profile primaries to adapt them to the shooting conditions.\n 'Destination primaries', which allows you to change the destination primaries with three main uses - channel mixer, restore image color (saturation), and calibration.\nNote: Abstract profiles take into account the built-in working profiles without modifying them. They do not work with custom working profiles. -!TP_ICM_TRC_TOOLTIP;Allows you to change the default sRGB 'Tone response curve' in RT (g=2.4 s=12.92).\nThis TRC modifies the tones of the image. The RGB and Lab values, histogram and output (screen, TIF, JPG) are changed:\n-Gamma acts mainly on light tones -Slope acts mainly on dark tones.\nYou can choose any pair of 'gamma and slope' (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nA selection other than 'none' activates the 'Illuminant' and 'Destination primaries' menus. -!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford -!TP_ICM_WORKING_ILLU_E;E -!TP_ICM_WORKING_NON;None -!TP_ICM_WORKING_PRIMFRAME_TOOLTIP;When 'Custom CIE xy diagram' is selected in 'Destination primaries' combo box, you can modify the values of the 3 primaries directly on the graph.\nNote that in this case, the white point position on the graph will not be updated. -!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) -!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA -!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. -!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata -!TP_LOCALLAB_ARTIF_TOOLTIP;ΔE scope threshold increases the range of ΔE scope. High values are for very wide gamut images.\nIncreasing ΔE decay can improve shape detection, but can also reduce the scope. -!TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction (Uniform Perceptual Lab). Default: Munsell only.\n\nMunsell only: Fixes Lab mode hue drifts due to non-linearity when chromaticity is changed (Uniform Perceptual Lab).\nLab: Applies a gamut control in relative colorimetric. Munsell is then applied.\nXYZ Absolute: Applies gamut control in absolute colorimetric. Munsell is then applied.\nXYZ Relative: Applies gamut control in relative colorimetric. Munsell is then applied. The result is not the same as Lab. -!TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell correction always disabled when Jz or CAM16 is used. -!TP_LOCALLAB_BALAN_TOOLTIP;Changes the ΔE algorithm parameters.\nTakes into account more or less a*b* or L*, or more or less C or H.\nNot for Denoise. -!TP_LOCALLAB_BLENDMASKMASK_TOOLTIP;If this slider = 0 no action.\nAdd or subtract the mask from the original image. -!TP_LOCALLAB_BLENDMASK_TOOLTIP;If blend = 0 only shape detection is improved.\nIf blend > 0 the mask is added to the image. If blend < 0 the mask is subtracted from the image. -!TP_LOCALLAB_BLMETHOD_TOOLTIP;Normal: direct blur and noise with all settings.\nInverse: blur and noise with all settings. Warning, some settings may give curious results. -!TP_LOCALLAB_BLUMETHOD_TOOLTIP;To blur the background and isolate the foreground:\n-blur the background by completely covering the image with a spot (high values for scope and transition and 'Normal' or 'Inverse' in checkbox).\n-Isolate the foreground by using one or more 'Excluding' spots and increase the scope.\n\nThis module (including the 'median' and 'Guided filter') can be used in addition to the main-menu noise reduction. -!TP_LOCALLAB_BLURCOLDE_TOOLTIP;The image used to calculate dE is blurred slightly to avoid taking isolated pixels into account. -!TP_LOCALLAB_BLURMASK_TOOLTIP;Uses a large-radius blur to create a mask that allows you to vary the contrast of the image and/or darken/lighten parts of it. -!TP_LOCALLAB_BLURRMASK_TOOLTIP;Allows you to vary the 'radius' of the Gaussian blur (0 to 1000). -!TP_LOCALLAB_BLWH_TOOLTIP;Force color components 'a' and 'b' to zero.\nUseful for black and white processing, or film simulation. -!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding -!TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) adapted to CAM16 (experimental). Allows you to change the internal PQ function (usually 10000 cd/m2 - default 100 cd/m2 - disabled for 100 cd/m2).\nCan be used to adapt to different devices and images, for example, to match CAM16 processing with the maximum monitor brightness of 400cd/m2. -!TP_LOCALLAB_CBDLCLARI_TOOLTIP;Enhances local contrast of the midtones. -!TP_LOCALLAB_CBDL_ADJ_TOOLTIP;Same as wavelets.\nThe first level (0) acts on 2x2 pixel details.\nThe last level (5) acts on 64x64 pixel details. -!TP_LOCALLAB_CBDL_THRES_TOOLTIP;Prevents the sharpening of noise. -!TP_LOCALLAB_CHROMABLU_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMACB_TOOLTIP;Increases or reduces the effect depending on the luma settings.\nValues under 1 reduce the effect. Values greater than 1 increase the effect. -!TP_LOCALLAB_CHROMASK_TOOLTIP;Changes the chroma of the mask if one exists (i.e. C(C) or LC(H) is activated). -!TP_LOCALLAB_CIECAMLOG_TOOLTIP;This module is based on the CIECAM color appearance model which was designed to better simulate how human vision perceives colors under different lighting conditions.\nThe first Ciecam process 'Scene conditions' is carried out by Log encoding, it also uses 'Absolute luminance' at the time of shooting.\nThe second Ciecam process 'Image adjustments' is simplified and uses only 3 variables (local contrast, contrast J, saturation s).\nThe third Ciecam process 'Viewing conditions' adapts the output to the intended viewing conditions (monitor, TV, projector, printer, etc.) so that the chromatic and contrast appearance is preserved across the display environment. -!TP_LOCALLAB_CIEMODE_TOOLTIP;In Default mode, Ciecam is added at the end of the process. 'Mask and modifications' and 'Recovery based on luminance mask' are available for'Cam16 and JzCzHz' at your disposal .\nYou can also integrate Ciecam into other tools if you wish (TM, Wavelet, Dynamic Range, Log Encoding). The results for these tools will be different to those without Ciecam. In this mode, you can also use 'Mask and modifications' and 'Recovery based on luminance mask'. -!TP_LOCALLAB_CIRCRAD_TOOLTIP;Contains the references of the spot, useful for shape detection (hue, luma, chroma, Sobel).\nLow values may be useful for processing foliage.\nHigh values may be useful for processing skin. -!TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled. -!TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and Local contrast wavelets Jz. -!TP_LOCALLAB_CLARISOFT_TOOLTIP;The 'Soft radius' slider (guided filter algorithm) reduces halos and irregularities for Clarity, Sharp Mask and all wavelet pyramid processes. To deactivate, set slider to zero. -!TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 to 4 (included): 'Sharp mask' is enabled\nLevels 5 and above: 'Clarity' is enabled.\nUseful if you use 'Wavelet level tone mapping'. -!TP_LOCALLAB_COLORDEPREV_TOOLTIP;Preview ΔE button in Settings will only work if you have activated 'Sharpening', 'Soft Light and Original Retinex', 'Blur/Grain and Denoise', 'Dehaze and Retinex', or 'Contrast by Detail Levels' in the 'Add tool to current spot' menu.\nFor others tools, the Preview ΔE button is in the tool, which allows previewing ΔE with several tools enabled. Prefer using Mask and modifications. -!TP_LOCALLAB_COLORDE_TOOLTIP;Show a blue color preview for ΔE selection if negative and green if positive.\n\nMask and modifications (show modified areas without mask): show actual modifications if positive, show enhanced modifications (luminance only) with blue and yellow if negative. -!TP_LOCALLAB_COLORSCOPE_TOOLTIP;Common Scope slider for Color and Light, Shadows/Highlights, Vibrance.\nOther tools have their own scope controls. -!TP_LOCALLAB_COMPRCIETH;Compression threshold -!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. -!TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts).May create artifacts. -!TP_LOCALLAB_CONTTHMASK_TOOLTIP;Allows you to determine which parts of the image will be impacted based on the texture. -!TP_LOCALLAB_CURVEEDITORM_CC_TOOLTIP;If the curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_CC_TOOLTIP;If curves are at the top, the mask is completely black and no changes are made to the image.\nAs you lower the curve, the mask gradually becomes more colorful and bright, progressively changing the image.\n\nIt is recommended (but not mandatory) to position the top of the curves on the gray boundary line which represents the reference values of chroma, luma, hue for the spot. -!TP_LOCALLAB_CURVEEDITOR_LL_TOOLTIP;To activate the curves, set the 'Curve type' combo box to 'Normal'. -!TP_LOCALLAB_CURVEEDITOR_TONES_TOOLTIP;L=f(L), can be used with L(H) in Color and Light. -!TP_LOCALLAB_CURVEMETHOD_TOOLTIP;'Normal', the curve L=f(L) uses the same algorithm as the lightness slider. -!TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Removes atmospheric haze. Increases overall saturation and detail.\nCan remove color casts, but may also introduce a blue cast which can be corrected with other tools. -!TP_LOCALLAB_DEHAZ_TOOLTIP;Negative values add haze. -!TP_LOCALLAB_DENOIBILAT_TOOLTIP;Allows you to reduce impulse or 'salt & pepper' noise. -!TP_LOCALLAB_DENOICHROC_TOOLTIP;Allows you to deal with blotches and packets of noise. -!TP_LOCALLAB_DENOICHRODET_TOOLTIP;Allows you to recover chrominance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOICHROF_TOOLTIP;Allows you to adjust fine-detail chrominance noise. -!TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP;Allows you to direct the chroma noise reduction towards either the blue-yellow or red-green colors. -!TP_LOCALLAB_DENOIEQUAL_TOOLTIP;Allows you to carry out more or less noise reduction in either the shadows or the highlights. -!TP_LOCALLAB_DENOILUMDETAIL_TOOLTIP;Allows you to recover luminance detail by progressively applying a Fourier transform (DCT). -!TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. -!TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. -!TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. -!TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum spot size: 128x128. -!TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;If enabled the Mask uses Restored Data after Transmission Map instead of Original data. -!TP_LOCALLAB_EQUILTM_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image are identical to those of the original. -!TP_LOCALLAB_EXCLUF_TOOLTIP;'Excluding' mode prevents adjacent spots from influencing certain parts of the image. Adjusting 'Scope' will extend the range of colors.\n You can also add tools to an Excluding spot and use them in the same way as for a normal spot. -!TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot uses recursive data.\n\nExcluding spot reinitializes all selective editing data.\nCan be used to totally or partially cancel a previous action or to carry out operations in Inverse mode.\nUse 'Scope' (Excluding) to set the exclusion intensity.\n\n'Full image' allows you to use the selective editing tools on the whole image.\nThe RT Spot delimiters are set beyond the image preview boundaries.\nThe transition is set to 100.\nNote: You may have to reposition the RT Spot slightly and adjust the Spot size to get the desired effect.\nNote: Using Denoise or Wavelet or FFTW in full-image mode uses large amounts of memory and may cause the application to crash on lower capacity systems.\n\n'Global' allows you to use the selective editing tools on the whole image, without using Delta E or transitions. -!TP_LOCALLAB_EXPCBDL_TOOLTIP;Can be used to remove marks on the sensor or lens by reducing the contrast on the appropriate detail level(s). -!TP_LOCALLAB_EXPCHROMA_TOOLTIP;Use in association with 'Exposure compensation f' and 'Contrast Attenuator f' to avoid desaturating colors. -!TP_LOCALLAB_EXPCOLOR_TOOLTIP;Adjust color, lightness, contrast and correct small defects such as red-eye, sensor dust etc. -!TP_LOCALLAB_EXPCOMP_TOOLTIP;For portraits or images with a low color gradient. You can change 'Shape detection' in 'Settings':\n\nIncrease 'ΔE scope threshold'\nReduce 'ΔE decay'\nIncrease 'ab-L balance (ΔE)' -!TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;See the documentation for Wavelet Levels.\nThere are some differences in the Selective Editing version, which has more tools and more possibilities for working on individual detail levels.\nE.g. wavelet-level tone mapping. -!TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Avoid spots that are too small ( < 32x32 pixels).\nUse low 'Transition value' and high 'Transition decay' and 'Scope' to simulate small spots and deal with defects.\nUse 'Clarity and Sharp mask and Blend and Soften Images' if necessary by adjusting 'Soft radius' to reduce artifacts. -!TP_LOCALLAB_EXPGRADCOL_TOOLTIP;A graduated filter is available in Color and Light (luminance, chrominance & hue gradients, and 'Merge file'), Exposure (luminance grad.), Exposure Mask (luminance grad.), Shadows/Highlights (luminance grad.), Vibrance (luminance, chrominance & hue gradients), Local contrast & wavelet pyramid (local contrast grad.).\nFeather is located in Settings. -!TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Changes the transformed/original image blend. -!TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Changes the behaviour for images with too much or too little contrast by adding a gamma curve before and after the Laplace transform. -!TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Changes the behaviour for underexposed images by adding a linear component prior to applying the Laplace transform. -!TP_LOCALLAB_EXPLAP_TOOLTIP;Moving the slider to the right progressively reduces the contrast. -!TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Allows you to use GIMP or Photoshop layer blend modes (difference, multiply, soft light, overlay, etc.) with opacity control.\nOriginal image: merge current spot with original.\nPrevious spot: merge current spot with previous (if there is only one spot, previous = original).\nBackground: merge current spot with a color and luminance background (fewer possibilties). -!TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Applies a median filter before the Laplace transform to prevent artifacts (noise).\nYou can also use the 'Denoise' tool. -!TP_LOCALLAB_EXPOSURE_TOOLTIP;Modify exposure in L*a*b space using Laplacian PDE algorithms to take into account dE and minimize artifacts. -!TP_LOCALLAB_EXPSHARP_TOOLTIP;Spot minimum 39*39.\nUse low transition values and high 'Transition decay' and 'Scope' values to simulate smaller spots. -!TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal – uses the Fattal Tone-mapping algorithm. -!TP_LOCALLAB_FEATH_TOOLTIP;Gradient width as a percentage of the Spot diagonal\nUsed by all graduated filters in all tools.\nNo action if a graduated filter hasn't been activated. -!TP_LOCALLAB_FFTMASK_TOOLTIP;Use a Fourier transform for better quality (increased processing time and memory requirements). -!TP_LOCALLAB_FULLIMAGELOG_TOOLTIP;Calculates the Ev levels for the whole image. -!TP_LOCALLAB_GAMCOL_TOOLTIP;Apply a gamma on Luminance L*a*b* datas.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMC_TOOLTIP;Apply a gamma on Luminance L*a*b* datas before and after treatment Pyramid 1 and Pyramid 2.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_GAMMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_GRADANG_TOOLTIP;Rotation angle in degrees: -180 0 +180. -!TP_LOCALLAB_GRADGEN_TOOLTIP;Adjusts luminance gradient strength. -!TP_LOCALLAB_GRADSTRAB_TOOLTIP;Adjusts chroma gradient strength. -!TP_LOCALLAB_GRADSTRHUE_TOOLTIP;Adjusts hue gradient strength. -!TP_LOCALLAB_GRAIN_TOOLTIP;Adds film-like grain to the image. -!TP_LOCALLAB_GRIDFRAME_TOOLTIP;You can use this tool as a brush. Use a small spot and adapt the 'Transition value' and 'Transition decay'\nOnly 'Normal' mode and possibly Hue, Saturation, Color, Luminosity are concerned by Merge background (ΔE). -!TP_LOCALLAB_GRIDMETH_TOOLTIP;Color toning: the luminance is taken into account when varying chroma. Equivalent to H=f(H) if the 'white dot' on the grid remains at zero and you only vary the 'black dot'. Equivalent to 'Color toning' if you vary the 2 dots.\n\nDirect: acts directly on the chroma. -!TP_LOCALLAB_GUIDBL_TOOLTIP;Applies a guided filter with adjustable radius. Allows you to reduce artifacts or blur the image. -!TP_LOCALLAB_GUIDEPSBL_TOOLTIP;Changes the distribution function of the guided filter. Negative values simulate a Gaussian blur. -!TP_LOCALLAB_GUIDFILTER_TOOLTIP;Can reduce or increase artifacts. -!TP_LOCALLAB_GUIDSTRBL_TOOLTIP;Intensity of the guided filter. -!TP_LOCALLAB_HHMASK_TOOLTIP;Fine hue adjustments for example for the skin. -!TP_LOCALLAB_INVBL_TOOLTIP;Alternative to 'Inverse' mode: use two spots\nFirst Spot:\n Full Image\n\nSecond spot: Excluding spot. -!TP_LOCALLAB_INVERS_TOOLTIP;Fewer possibilities if selected (Inverse).\n\nAlternative: use two spots\nFirst Spot:\n Full Image\n \nSecond spot: Excluding spot\n\n Inverse will enable this tool for the area outside the spot, while the area within the spot will remain unaffected by the tool. -!TP_LOCALLAB_JABADAP_TOOLTIP;Perceptual Uniform adaptation.\nAutomatically adjusts the relationship between Jz and saturation taking into account 'Absolute luminance'. -!TP_LOCALLAB_JZ100_TOOLTIP;Automatically adjusts the reference Jz 100 cd/m2 level (image signal).\nChanges the saturation level and action of 'PU adaptation' (Perceptual Uniform adaptation). -!TP_LOCALLAB_JZFORCE_TOOLTIP;Allows you to force the maximum Jz value to 1 for better slider and curve response. -!TP_LOCALLAB_JZLOGWBS_TOOLTIP;Black Ev and White Ev adjustments can be different depending on whether Log encoding or Sigmoid is used.\nFor Sigmoid, a change (increase in most cases) of White Ev may be necessary to obtain a better rendering of highlights, contrast and saturation. -!TP_LOCALLAB_JZLOGWB_TOOLTIP;If Auto is enabled, it will calculate and adjust the Ev levels and the 'Mean luminance Yb%' for the spot area. The resulting values will be used by all Jz operations including 'Log Encoding Jz'.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb is the relative luminance of the background, expressed as a percentage of gray. 18% gray corresponds to a background luminance of 50% when expressed in CIE L.\nThe data is based on the mean luminance of the image.\nWhen used with Log Encoding, the mean luminance is used to determine the amount of gain that needs to be applied to the signal prior to the log encoding. Lower values of mean luminance will result in increased gain. -!TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (only in 'Advanced' mode). Only operational if the output device (monitor) is HDR (peak luminance higher than 100 cd/m2 - ideally between 4000 and 10000 cd/m2. Black point luminance inferior to 0.005 cd/m2). This supposes a) the ICC-PCS for the screen uses Jzazbz (or XYZ), b) works in real precision, c) that the monitor is calibrated (if possible with a DCI-P3 or Rec-2020 gamut), d) that the usual gamma (sRGB or BT709) is replaced by a Perceptual Quantiser (PQ) function. -!TP_LOCALLAB_JZPQFRA_TOOLTIP;Allows you to adapt the Jz algorithm to an SDR environment or to the characteristics (performance) of an HDR environment as follows:\n a) for luminance values between 0 and 100 cd/m2, the system behaves as if it were in an SDR environment.\n b) for luminance values between 100 and 10000 cd/m2, you can adapt the algorithm to the HDR characteristics of the image and the monitor.\n\nIf 'PQ - Peak luminance' is set to 10000, 'Jz remappping' behaves in the same way as the original Jzazbz algorithm. -!TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - allows you to change the internal PQ function (usually 10000 cd/m2 - default 120 cd/m2).\nCan be used to adapt to different images, processes and devices. -!TP_LOCALLAB_JZQTOJ_TOOLTIP;Allows you to use 'Relative luminance' instead of 'Absolute luminance' - Brightness becomes Lightness.\nThe changes affect: the Brightness slider, the Contrast slider and the Jz(Jz) curve. -!TP_LOCALLAB_LAPLACC;ΔØ Mask Laplacian solve PDE -!TP_LOCALLAB_LAPRAD1_TOOLTIP;Increases the contrast of the mask by increasing the luminance values of the lighter areas. Can be used in conjunction with the L(L) and LC(H) curves. -!TP_LOCALLAB_LAPRAD2_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAPRAD_TOOLTIP;Smooth radius uses a guided filter to decrease artifacts and smooth out the transition. -!TP_LOCALLAB_LAP_MASK_TOOLTIP;Solves PDEs for all Laplacian masks.\nIf enabled the Laplacian threshold mask reduces artifacts and smooths the result.\nIf disabled the response is linear. -!TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. -!TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improves quality and allows the use of large radii, but increases processing time (depends on the area to be processed). Preferable to use only for large radii. The size of the area can be reduced by a few pixels to optimize the FFTW. This can reduce the processing time by a factor of 1.5 to 10. -!TP_LOCALLAB_LEVELWAV_TOOLTIP;The Level is automatically adapted to the size of the spot and the preview.\nFrom level 9 size max 512 to level 1 size max = 4. -!TP_LOCALLAB_LIGHTN_TOOLTIP;In inverse mode: selection = -100 forces luminance to zero. -!TP_LOCALLAB_LIST_TOOLTIP;You can select 3 levels of complexity for each tool: Basic, Standard and Advanced.\nThe default setting for all tools is Basic but this can be changed in the Preferences window.\nYou can also change the level of complexity on a per-tool basis while you are editing. -!TP_LOCALLAB_LMASK_LEVEL_TOOLTIP;Allows you to decrease or increase the effect on particular levels of detail in the mask by targeting certain luminance zones (in general the lightest). -!TP_LOCALLAB_LMASK_LL_TOOLTIP;Allows you to freely change the contrast of the mask.\n Has a similar function to the Gamma and Slope sliders.\n It allows you to target certain parts of the image (usually the lightest parts of the mask by using the curve to exclude the darker parts). May create artifacts. -!TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions. -!TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Automatically calculates the 'Mean luminance' for the scene conditions when the 'Automatic' button in Relative Exposure Levels is pressed. -!TP_LOCALLAB_LOGAUTO_TOOLTIP;Pressing this button will calculate the dynamic range and 'Mean luminance' for the scene conditions if the 'Auto mean luminance (Yb%)' is checked).\nAlso calculates the absolute luminance at the time of shooting.\nPress the button again to adjust the automatically calculated values. -!TP_LOCALLAB_LOGBASE_TOOLTIP;Default = 2.\nValues less than 2 reduce the action of the algorithm making the shadows darker and the highlights brighter.\nWith values greater than 2, the shadows are grayer and the highlights become more washed out. -!TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatic adaptation allows us to interpret a color according to its spatio-temporal environment.\nUseful when the white balance deviates significantly from the D50 reference.\nAdapts colors to the illuminant of the output device. -!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. -!TP_LOCALLAB_LOGCIE_TOOLTIP;Allows you to use Black Ev, White Ev, White and Black distribution, Scene Mean luminance(Yb%) and Viewing Mean luminance(Yb%) for tone-mapping using 'Log encoding' with Brightness compression. -!TP_LOCALLAB_LOGCOLORF_TOOLTIP;Perceived amount of hue in relation to gray.\nIndicator that a stimulus appears more or less colored. -!TP_LOCALLAB_LOGCONTL_TOOLTIP;Contrast (J) in CIECAM16 takes into account the increase in perceived coloration with luminance. -!TP_LOCALLAB_LOGCONTQ_TOOLTIP;Contrast (Q) in CIECAM16 takes into account the increase in perceived coloration with brightness. -!TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Adjusts the mid-tone contrast range (J & Q).\nPositive values progressively reduce the effect of the Contrast sliders (J & Q). Negative values progressively increase the effect of the Contrast sliders. -!TP_LOCALLAB_LOGDETAIL_TOOLTIP;Acts mainly on high frequencies. -!TP_LOCALLAB_LOGENCOD_TOOLTIP;Tone Mapping with Logarithmic encoding (ACES).\nUseful for underexposed images or images with high dynamic range.\n\nTwo-step process: 1) Dynamic Range calculation 2) Manual adjustment. -!TP_LOCALLAB_LOGFRAME_TOOLTIP;Allows you to calculate and adjust the Ev levels and the 'Mean luminance Yb%' (source gray point) for the spot area. The resulting values will be used by all Lab operations and most RGB operations in the pipeline.\nAlso calculates the absolute luminance at the time of shooting. -!TP_LOCALLAB_LOGIMAGE_TOOLTIP;Takes into account corresponding Ciecam variables: i.e. Contrast (J) and Saturation (s), as well as Contrast (Q), Brightness (Q), Lightness (J) and Colorfulness (M) (in Advanced mode). -!TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Close to lightness (L*a*b*). Takes into account the increase in perceived coloration. -!TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Perceived amount of light emanating from a stimulus.\nIndicator that a stimulus appears to be more or less bright, clear. -!TP_LOCALLAB_LOGREPART_TOOLTIP;Allows you to adjust the relative strength of the log-encoded image with respect to the original image.\nDoes not affect the Ciecam component. -!TP_LOCALLAB_LOGSATURL_TOOLTIP;Saturation (s) in CIECAM16 corresponds to the color of a stimulus in relation to its own brightness.\nActs mainly on medium tones and on the highlights. -!TP_LOCALLAB_LOGSCENE_TOOLTIP;Corresponds to the shooting conditions. -!TP_LOCALLAB_LOGSURSOUR_TOOLTIP;Changes tones and colors to take into account the Scene conditions.\n\nAverage: Average light conditions (standard). The image will not change.\n\nDim: Dim conditions. The image will become slightly brighter.\n\nDark: Dark conditions. The image will become more bright. -!TP_LOCALLAB_LOGVIEWING_TOOLTIP;Corresponds to the medium on which the final image will be viewed (monitor, TV, projector, printer, etc.), as well as the surrounding conditions. -!TP_LOCALLAB_LUMASK_TOOLTIP;Adjusts the shade of gray or color of the mask background in Show Mask (Mask and modifications). -!TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTakes into account the ΔE image to avoid modifying the selection area when the following Mask Tools are used: Gamma, Slope, Chroma, Contrast curve, Local contrast (by wavelet level), Blur Mask and Structure Mask (if enabled ).\nDisabled when Inverse mode is used. -!TP_LOCALLAB_MASKCOM_TOOLTIP;A tool in its own right.\nCan be used to adjust the image appearance (chrominance, luminance, contrast) and texture as a function of Scope. -!TP_LOCALLAB_MASKCURVE_TOOLTIP;The 3 curves are set to 1 (maximum) by default:\nC=f(C) the chroma varies according to the chrominance. You can decrease the chroma to improve the selection. By setting this curve close to zero (with a low value of C to activate the curve) you can desaturate the background in Inverse mode.\nL=f(L) the luminance varies according to the luminance, so you can decrease the brightness to improve the selection.\nL and C = f(H) luminance and chroma vary with hue, so you can decrease luminance and chroma to improve selection. -!TP_LOCALLAB_MASKDECAY_TOOLTIP;Manages the rate of decay for the gray levels in the mask.\n Decay = 1 linear, Decay > 1 sharper parabolic transitions, Decay < 1 more gradual transitions. -!TP_LOCALLAB_MASKDEINV_TOOLTIP;Reverses the way the algorithm interprets the mask.\nIf checked black and very light areas will be decreased. -!TP_LOCALLAB_MASKDE_TOOLTIP;Used to target the denoise as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the Denoise will be applied progressively.\n iIf the mask is above the 'light' threshold, then the Denoise will be applied progressively.\n Between the two, the image settings without the Denoise will be maintained, unless you adjust the sliders 'Gray area luminance denoise' or 'Gray area chrominance denoise'. -!TP_LOCALLAB_MASKGF_TOOLTIP;Used to target the Guided Filter as a function of the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n If the mask is below the 'dark' threshold, then the GF will be applied progressively.\n If the mask is above the 'light' threshold, then the GF will be applied progressively.\n Between the two, the image settings without the GF will be maintained. -!TP_LOCALLAB_MASKHIGTHRESCB_TOOLTIP;Lighter-tone limit above which CBDL (Luminance only) parameters will be restored progressively to their original values prior to being modified by the CBDL settings .\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\nUse a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESC_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP; The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESE_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable colorpicker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESL_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESRETI_TOOLTIP;Lighter-tone limit above which Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESS_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESTM_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESVIB_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRESWAV_TOOLTIP;Lighter-tone limit above which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKHIGTHRES_TOOLTIP; The Guided Filter is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'structure mask', 'Smooth radius', 'Gamma and slope', 'Contrast curve', 'Local contrast wavelet'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. -!TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESD_TOOLTIP;The denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESE_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESL_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Log encoding settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels:'Smooth radius', 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESRETI_TOOLTIP;Dark-tone limit below which the Retinex (Luminance only) parameters will be restored progressively to their original values prior to being modified by the Retinex settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESS_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Shadows Highlights settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESTM_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Tone Mapping settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESVIB_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRESWAV_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKLOWTHRES_TOOLTIP;The Guided Filter is progressively increased from 0% at the threshold setting to 100% at the maximum black value (as determined by the mask).\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. -!TP_LOCALLAB_MASKRECOL_TOOLTIP;Used to modulate the effect of the Color and Light settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Color and Light settings \n In between these two areas, the full value of the Color and Light settings will be applied. -!TP_LOCALLAB_MASKREEXP_TOOLTIP;Used to modulate the effect of the 'Dynamic range and Exposure' settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the 'Dynamic range and Exposure' settings \n In between these two areas, the full value of the 'Dynamic range and Exposure' settings will be applied. -!TP_LOCALLAB_MASKRELOG_TOOLTIP;Used to modulate the effect of the Log encoding settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Log encoding settings - can be used to restore highlights reconstructed by Color propagation \n In between these two areas, the full value of the Log encoding settings will be applied. -!TP_LOCALLAB_MASKRESCB_TOOLTIP;Used to modulate the effect of the CBDL (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the CBDL settings \n In between these two areas, the full value of the CBDL settings will be applied. -!TP_LOCALLAB_MASKRESH_TOOLTIP;Used to modulate the effect of the Shadows Highlights settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Shadows Highlights settings \n In between these two areas, the full value of the Shadows Highlights settings will be applied. -!TP_LOCALLAB_MASKRESRETI_TOOLTIP;Used to modulate the effect of the Retinex (Luminance only) settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Retinex settings \n In between these two areas, the full value of the Retinex settings will be applied. -!TP_LOCALLAB_MASKRESTM_TOOLTIP;Used to modulate the effect of the Tone Mapping settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Tone Mapping settings \n In between these two areas, the full value of the Tone Mapping settings will be applied. -!TP_LOCALLAB_MASKRESVIB_TOOLTIP;Used to modulate the effect of the Vibrance and Warm Cool settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Vibrance and Warm Cool settings \n In between these two areas, the full value of the Vibrance and Warm Cool settings will be applied. -!TP_LOCALLAB_MASKRESWAV_TOOLTIP;Used to modulate the effect of the Local contrast and Wavelet settings based on the image luminance information contained in the L(L) or LC(H) masks (Mask and modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n The 'dark' and 'light' areas below the dark threshold and above the light threshold will be restored progressively to their original values prior to being modified by the Local contrast and Wavelet settings \n In between these two areas, the full value of the Local contrast and Wavelet settings will be applied. -!TP_LOCALLAB_MASK_TOOLTIP;You can enable multiple masks for a tool by activating another tool and using only the mask (set the tool sliders to 0 ).\n\nYou can also duplicate the spot and place it close to the first spot. The small variations in the spot references allow you to make fine adjustments. -!TP_LOCALLAB_MEDIANITER_TOOLTIP;The number of successive iterations carried out by the median filter. -!TP_LOCALLAB_MEDIAN_TOOLTIP;You can choose a median value in the range 3x3 to 9x9 pixels. Higher values increase noise reduction and blur. -!TP_LOCALLAB_MERGECOLFRMASK_TOOLTIP;Allows you to create masks based on the 3 LCh curves and/or a structure-detection algorithm. -!TP_LOCALLAB_MERGEMER_TOOLTIP;Takes ΔE into account when merging files (equivalent of scope in this case). -!TP_LOCALLAB_MERGEOPA_TOOLTIP;Opacity = % of current spot to be merged with original or previous Spot.\nContrast threshold : adjusts result as a function of contrast in original image. -!TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. -!TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. -!TP_LOCALLAB_MULTIPL_TOOLTIP;Wide-range tone adjustment: -18EV to +4EV. The first slider acts on very dark tones between -18EV and -6EV. The last slider acts on light tones up to 4EV. -!TP_LOCALLAB_NLDENOISENLGAM_TOOLTIP;Lower values preserve details and texture, higher values increase denoise.\nIf gamma = 3.0 Luminance 'linear' is used. -!TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denoise to the size of the objects to be processed. -!TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. -!TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. -!TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. -!TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=0.02. -!TP_LOCALLAB_NOISEGAM_TOOLTIP;If gamma = 1 Luminance 'Lab' is used. If gamma = 3.0 Luminance 'linear' is used.\nLower values preserve details and texture, higher values increase denoise. -!TP_LOCALLAB_ORRETILAP_TOOLTIP;Modifies ΔE prior to any changes made by 'Scope'. This allows you to differentiate the action for different parts of the image (with respect to the background for example). -!TP_LOCALLAB_ORRETISTREN_TOOLTIP;Acts on the Laplacian threshold, the greater the action, the more the differences in contrast will be reduced. -!TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL algorithm adapted for RawTherapee: gives different results and requires different settings compared to main-menu 'Exposure'.\nMay be useful for under-exposed or high dynamic range images. -!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. -!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. -!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. -!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. -!TP_LOCALLAB_RADIUS_TOOLTIP;Uses a Fast Fourier Transform for radius > 30. -!TP_LOCALLAB_RECOTHRES02_TOOLTIP;If the 'Recovery threshold' value is greater than 1, the mask in Mask and Modifications takes into account any previous modifications made to the image but not those made with the current tool (e.g. Color and Light, Wavelet, Cam16, etc.)\nIf the value of the 'Recovery threshold' is less than 1, the mask in Mask and Modifications does not take into account any previous modifications to the image.\n\nIn both cases, the 'Recovery threshold' acts on the masked image as modified by the current tool (Color and Light, Wavelet, Cam16, etc.). -!TP_LOCALLAB_RECURS_TOOLTIP;Forces the algorithm to recalculate the references after each tool is applied.\nAlso useful for working with masks. -!TP_LOCALLAB_REPARCOL_TOOLTIP;Allows you to adjust the relative strength of the Color and Light image with respect to the original image. -!TP_LOCALLAB_REPARDEN_TOOLTIP;Allows you to adjust the relative strength of the Denoise image with respect to the original image. -!TP_LOCALLAB_REPAREXP_TOOLTIP;Allows you to adjust the relative strength of the Dynamic Range and Exposure image with respect to the original image. -!TP_LOCALLAB_REPARSH_TOOLTIP;Allows you to adjust the relative strength of the Shadows/Highlights and Tone Equalizer image with respect to the original image. -!TP_LOCALLAB_REPARTM_TOOLTIP;Allows you to adjust the relative strength of the Tone mapping image with respect to the original image. -!TP_LOCALLAB_REPARW_TOOLTIP;Allows you to adjust the relative strength of the local contrast and wavelet image with respect to the original image. -!TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex can be useful for processing images: \nthat are blurred, foggy or hazy (in addition to Dehaze).\nthat contain large differences in luminance.\nIt can also be used for special effects (tone mapping). -!TP_LOCALLAB_RETI_LIGHTDARK_TOOLTIP;Has no effect when the value of 'Lightness = 1' or 'Darkness =2'.\nFor other values, the last step of a 'Multiple scale Retinex' algorithm (similar to 'local contrast') is applied. These 2 cursors, associated with 'Strength' allow you to make adjustments upstream of local contrast. -!TP_LOCALLAB_RETI_LIMDOFFS_TOOLTIP;Adjusts the internal parameters to optimize the response.\nPreferable to keep the 'Restored data' values close to Min=0 and Max=32768 (log mode), but other values are possible. -!TP_LOCALLAB_RETI_LOGLIN_TOOLTIP;Logarithm mode introduces more contrast but will also generate more halos. -!TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;The radius and variance sliders allow you adjust haze and target either the foreground or the background. -!TP_LOCALLAB_RETI_SCALE_TOOLTIP;If Scale=1, Retinex behaves like local contrast with additional possibilities.\nIncreasing the value of Scale increases the intensity of the recursive action at the expense of processing time. -!TP_LOCALLAB_RGBCURVE_TOOLTIP;In RGB mode you have 4 choices : Standard, Weighted standard, Luminance & Film-like. -!TP_LOCALLAB_RSTPROTECT_TOOLTIP;Red and skin-tone protection affects the Saturation, Chroma and Colorfulness sliders. -!TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if ΔE Image Mask is enabled.\nLow values avoid retouching selected area. -!TP_LOCALLAB_SENSIEXCLU_TOOLTIP;Adjust the colors to be excluded. -!TP_LOCALLAB_SENSIMASK_TOOLTIP;Scope adjustment specific to common mask tool.\nActs on the difference between the original image and the mask.\nUses the luma, chroma and hue references from the center of the spot\n\nYou can also adjust the ΔE of the mask itself by using 'Scope (ΔE image mask)' in 'Settings' > 'Mask and Merge'. -!TP_LOCALLAB_SENSI_TOOLTIP;Adjusts the scope of the action:\nSmall values limit the action to colors similar to those in the center of the spot.\nHigh values let the tool act on a wider range of colors. -!TP_LOCALLAB_SHADHMASK_TOOLTIP;Lowers the highlights of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADMASK_TOOLTIP;Lifts the shadows of the mask in the same way as the shadows/highlights algorithm. -!TP_LOCALLAB_SHADOWHIGHLIGHT_TOOLTIP;Adjust shadows and highlights either with shadows & highlights sliders or with a tone equalizer.\nCan be used instead of, or in conjunction with the Exposure module.\nCan also be used as a graduated filter. -!TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' is the normal mode.\n 'Rectangle' can be used in certain cases, for example to work in full-image mode by placing the delimiters outside the preview area. In this case, set transition = 100.\n\nFuture developments will include polygon shapes and Bezier curves. -!TP_LOCALLAB_SHORTCMASK_TOOLTIP;Short circuit the 2 curves L(L) and L(H).\nAllows you to mix the current image with the original image modified by the mask job.\nUsable with masks 2, 3, 4, 6, 7. -!TP_LOCALLAB_SHOWMASKCOL_TOOLTIP;Displays masks and modifications.\nBeware, you can only view one tool mask at a time.\nShow modified image: shows the modified image including the effect of any adjustments and masks.\nShow modified areas without mask: shows the modifications before any masks are applied.\nShow modified areas with mask: shows the modifications after a mask has been applied.\nShow mask: shows the aspect of the mask including the effect of any curves and filters.\nShow spot structure: allows you to see the structure-detection mask when the 'Spot structure' cursor is activated (when available).\nNote: The mask is applied before the shape detection algorithm. -!TP_LOCALLAB_SHOWMASKSOFT_TOOLTIP;Allows you to visualize the different stages of the Fourier process.\n Laplace - calculates the second derivative of the Laplace transform as a function of the threshold.\nFourier - shows the Laplacian transform with DCT.\nPoisson - shows the solution of the Poisson DCE.\nNo luminance normalization - shows result without any luminance normalization. -!TP_LOCALLAB_SHOWMASKTYP_TOOLTIP;Can be used with 'Mask and modifications'.\nIf 'Blur and noise' is selected, the mask cannot be used for Denoise.\nIf Denoise is selected, the mask cannot be used for 'Blur and noise'.\nIf 'Blur and noise + Denoise' is selected, the mask is shared. Note that in this case, the Scope sliders for both 'Blur and noise' and Denoise will be active so it is advisable to use the option 'Show modifications with mask' when making any adjustments. -!TP_LOCALLAB_SHTRC_TOOLTIP;Based on 'working profile' (only those provided), modifies the tones of the image by acting on a TRC (Tone Response Curve).\nGamma acts mainly on light tones.\nSlope acts mainly on dark tones.\nIt is recommended that the TRC of both devices (monitor and output profile) be sRGB (default). -!TP_LOCALLAB_SIGCIE;Sigmoid -!TP_LOCALLAB_SIGGAMJCIE;Gamma -!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. -!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold -!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. -!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. -!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. -!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). -!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. -!TP_LOCALLAB_SIGMOID_TOOLTIP;Allows you to simulate a tone mapping appearance using both the 'Jz' and 'Sigmoid' function. Three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc)Blend acts on the final aspect of the image, contrast and luminance. -!TP_LOCALLAB_SLOMASK_TOOLTIP;Adjusting Gamma and Slope can provide a soft and artifact-free transformation of the mask by progressively modifying 'L' to avoid any discontinuities. -!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. -!TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Apply a Soft-light blend (identical to the global adjustment). Carry out dodge and burn using the original Retinex algorithm. -!TP_LOCALLAB_SOFTRADIUSCOL_TOOLTIP;Applies a guided filter to the output image to reduce possible artifacts. -!TP_LOCALLAB_SPECIAL_TOOLTIP;The checkbox allows you to remove all other actions i.e. 'Scope', masks, sliders etc., (except for transitions) and use just the effect of the RGB tone-curve. -!TP_LOCALLAB_STRENGRID_TOOLTIP;You can adjust the desired effect with 'strength', but you can also use the 'scope' function which allows you to delimit the action (e.g. to isolate a particular color). -!TP_LOCALLAB_STRUCT_TOOLTIP;Uses the Sobel algorithm to take into account structure for shape detection.\nActivate 'Mask and modifications' > 'Show spot structure' (Advanced mode) to see a preview of the mask (without modifications).\n\nCan be used in conjunction with the Structure Mask, Blur Mask and 'Local contrast' (by wavelet level) to improve edge detection.\n\nEffects of adjustments using Lightness, Contrast, Chrominance, Exposure or other non-mask-related tools visible using either 'Show modified image' or 'Show modified areas with mask'. -!TP_LOCALLAB_STRUMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' unchecked: In this case a mask showing the structure will be generated even if none of the 3 curves is activated. Structure masks are available for mask (Blur and denoise') and mask(Color & Light). -!TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Moderate use of this slider is recommended! -!TP_LOCALLAB_STYPE_TOOLTIP;You can choose between:\nSymmetrical - left handle linked to right, top handle linked to bottom.\nIndependent - all handles are independent. -!TP_LOCALLAB_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Variance.\nTm=Min TM=Max of Transmission Map.\nYou can normalize the results with the threshold slider. -!TP_LOCALLAB_TONEMAPESTOP_TOOLTIP;This slider affects edge sensitivity.\n The greater the value, the more likely a change in contrast will be interpreted as an 'edge'.\n If set to zero the tone mapping will have an effect similar to unsharp masking. -!TP_LOCALLAB_TONEMAPGAM_TOOLTIP;The Gamma slider shifts the tone-mapping effect towards either the shadows or the highlights. -!TP_LOCALLAB_TONEMAPREWEI_TOOLTIP;In some cases tone mapping may result in a cartoonish appearance, and in some rare cases soft but wide halos may appear.\n Increasing the number of reweighting iterates will help fight some of these problems. -!TP_LOCALLAB_TONEMAP_TOOLTIP;Same as the tone mapping tool in the main menu.\nThe main-menu tool must be deactivated if this tool is used. -!TP_LOCALLAB_TONEMASCALE_TOOLTIP;This slider allows you to adjust the transition between 'local' and 'global' contrast.\nThe greater the value, the larger a detail needs to be for it to be boosted. -!TP_LOCALLAB_TOOLCOLFRMASK_TOOLTIP;Allows you to modify the mask, if one exists. -!TP_LOCALLAB_TOOLMASK_TOOLTIP;Structure mask (slider) with the checkbox 'Structure mask as tool' checked: in this case a mask showing the structure will be generated after one or more of the 2 curves L(L) or LC(H) has been modified.\n Here, the 'Structure mask' behaves like the other Mask tools : Gamma, Slope, etc.\n It allows you to vary the action on the mask according to the structure of the image. -!TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Allows you to vary the y-axis transition. -!TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Adjust transition decay function: 1 linear , 2 parabolic, 3 cubic up to ^25.\nCan be used in conjunction with very low transition values to reduce defects (CBDL, Wavelets, Color & Light). -!TP_LOCALLAB_TRANSIT_TOOLTIP;Adjust smoothness of transition between affected and unaffected areas as a percentage of the 'radius'. -!TP_LOCALLAB_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positive values (max).\nOrdinate: amplification or reduction.\nYou can adjust this curve to change the Transmission and reduce artifacts. -!TP_LOCALLAB_VIBRA_TOOLTIP;Adjusts vibrance (essentially the same as the global adjustment).\nCarries out the equivalent of a white-balance adjustment using a CIECAM algorithm. -!TP_LOCALLAB_VIS_TOOLTIP;Click to show/hide selected Control Spot.\nCtrl+click to show/hide all Control Spot. -!TP_LOCALLAB_WARM_TOOLTIP;This slider uses the CIECAM algorithm and acts as a White Balance control to make the color temperature of the selected area warmer or cooler.\nIt can also reduce color artifacts in some cases. -!TP_LOCALLAB_WASDEN_TOOLTIP;Luminance noise reduction: the left-hand side of the curve including the dark-gray/light-gray boundary corresponds to the first 3 levels 0, 1, 2 (fine detail). The right hand side of the curve corresponds to the coarser details (level 3, 4, 5, 6). -!TP_LOCALLAB_WAT_BALTHRES_TOOLTIP;Balances the action within each level. -!TP_LOCALLAB_WAT_BLURLC_TOOLTIP;The default blur setting affects all 3 L*a* b* components (luminance and colour).\nWhen checked, only luminance is blurred. -!TP_LOCALLAB_WAT_CLARIC_TOOLTIP;'Merge chroma' is used to select the intensity of the desired effect on chrominance. -!TP_LOCALLAB_WAT_CLARIL_TOOLTIP;'Merge luma' is used to select the intensity of the desired effect on luminance. -!TP_LOCALLAB_WAT_CONTCHROMALEV_TOOLTIP;'Chroma levels': adjusts the 'a' and 'b' components of Lab* as a proportion of the luminance value. -!TP_LOCALLAB_WAT_CONTOFFSET_TOOLTIP;Offset modifies the balance between low-contrast and high-contrast details.\nHigh values will amplify contrast changes to the higher-contrast details, whereas low values will amplify contrast changes to low-contrast details.\nBy using a low 'Attenuation response' value you can select which contrast values will be enhanced. -!TP_LOCALLAB_WAT_DELTABAL_TOOLTIP;By moving the slider to the left, the lower levels are accentuated. To the right, the lower levels are reduced and the higher levels accentuated. -!TP_LOCALLAB_WAT_EXPRESID_TOOLTIP;The residual image behaves in the same way as the main image when making adjustments to contrast, chroma etc. -!TP_LOCALLAB_WAT_GRADW_TOOLTIP;The more you move the slider to the right, the more effective the detection algorithm will be and the less noticeable the effects of local contrast. -!TP_LOCALLAB_WAT_LEVELLOCCONTRAST_TOOLTIP;Low to high local contrast from left to right on the x-axis.\nIncreases or decreases local contrast on the y-axis. -!TP_LOCALLAB_WAT_LOCCONTRASTEDG_TOOLTIP;You can adjust the distribution of local contrast by wavelet level based on the initial intensity of the contrast. This will modify the effects of perspective and relief in the image, and/or reduce the contrast values for very low initial contrast levels. -!TP_LOCALLAB_WAT_ORIGLC_TOOLTIP;'Merge only with original image', prevents the 'Wavelet Pyramid' settings from interfering with 'Clarity' and 'Sharp mask'. -!TP_LOCALLAB_WAT_RESIDBLUR_TOOLTIP;Blurs the residual image, independent of the levels. -!TP_LOCALLAB_WAT_RESIDCOMP_TOOLTIP;Compresses the residual image to increase or reduce contrast. -!TP_LOCALLAB_WAT_SIGMALC_TOOLTIP;The effect of the local contrast adjustment is stronger for medium-contrast details and weaker for high and low-contrast details.\n This slider controls how quickly the effect dampens towards the extreme contrasts.\nThe higher the value of the slider, the wider the range of contrasts that will receive the full effect of the local contrast adjustment and the higher the risk of generating artifacts.\nThe lower the value, the more the effect will be pinpointed towards a narrow range of contrast values. -!TP_LOCALLAB_WAT_STRENGTHW_TOOLTIP;Intensity of edge-effect detection. -!TP_LOCALLAB_WAT_STRWAV_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. -!TP_LOCALLAB_WAT_THRESHOLDWAV_TOOLTIP;Range of wavelet levels used throughout the Wavelets module. -!TP_LOCALLAB_WAT_WAVBLURCURV_TOOLTIP;Allows you to blur each level of decomposition.\nThe finest to coarsest levels of decomposition are from left to right. -!TP_LOCALLAB_WAT_WAVCBDL_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAT_WAVDELTABAL_TOOLTIP;Acts on the balance of the three directions (horizontal, vertical and diagonal) based on the luminance of the image.\nBy default the shadows or highlights are reduced to avoid artifacts. -!TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Shows all of the 'Edge sharpness' tools. It is advisable to read the Wavelet Levels documentation. -!TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Allows you to adjust the maximum effect of blurring on the levels. -!TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Low to high local contrast from left to right on the x-axis\nIncrease or decrease local contrast on the y-axis. -!TP_LOCALLAB_WAT_WAVTM_TOOLTIP;The lower (negative) part compresses each level of decomposition creating a tone mapping effect.\nThe upper (positive) part attenuates the contrast by level.\nThe finest to coarsest levels of decomposition are from left to right on the x-axis. -!TP_LOCALLAB_WAVBLUR_TOOLTIP;Allows you to blur each level of the decomposition, as well as the residual image. -!TP_LOCALLAB_WAVCOMPRE_TOOLTIP;Allows you to apply tone mapping or reduce local contrast on individual levels.\nFine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAVCOMP_TOOLTIP;Allows you to apply local contrast based on the direction of the wavelet decomposition : horizontal, vertical, diagonal. -!TP_LOCALLAB_WAVCONTF_TOOLTIP;Similar to Contrast By Detail Levels. Fine to coarse detail levels from left to right on the x-axis. -!TP_LOCALLAB_WAVEEDG_TOOLTIP;Improves sharpness by targeting the action of local contrast on the edges. It has the same functions as the corresponding module in Wavelet Levels and uses the same settings. -!TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Range of wavelet levels used in 'Local contrast' (by wavelet level). -!TP_LOCALLAB_WAVGRAD_TOOLTIP;Allows the local contrast to be varied according to a chosen gradient and angle. The variation of the luminance signal is taken into account and not the luminance. -!TP_LOCALLAB_WAVHUE_TOOLTIP;Allows you to reduce or increase the denoise based on hue. -!TP_LOCALLAB_WAVMASK_TOOLTIP;Uses wavelets to modify the local contrast of the mask and reinforce or reduce the structure (skin, buildings, etc.). -!TP_LOCRETI_METHOD_TOOLTIP;Low = Reinforce low light.\nUniform = Evenly distributed.\nHigh = Reinforce strong light. -!TP_PERSPECTIVE_CONTROL_LINES_TOOLTIP;Ctrl+drag: Draw new line\nRight-click: Delete line -!TP_PERSPECTIVE_CONTROL_LINE_APPLY_INVALID_TOOLTIP;At least two horizontal or two vertical control lines required. -!TP_RAW_PIXELSHIFTAVERAGE_TOOLTIP;Use average of all frames instead of selected frame for regions with motion.\nGives motion effect on slow moving (overlapping) objects. -!TP_WAVELET_DENLOCAL_TOOLTIP;Use a curve in order to guide the denoising according to the local contrast.\nThe areas are denoised, the structures are maintained. -!TP_WAVELET_DENMIX_TOOLTIP;The local-contrast reference value used by the guided filter.\nDepending on the image, results can vary depending on whether the noise is measured before or after the noise reduction. These four choices allow you to take into account various combinations of the original and modified (denoised) images to find the best compromise. -!TP_WAVELET_EDEFFECT_TOOLTIP;This slider selects the range of contrast values that will receive the full effect of any adjustment. -!TP_WAVELET_FINTHR_TOOLTIP;Uses local contrast to reduce or increase the action of the guided filter. -!TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between low contrast and high contrast details.\nHigh values will amplify contrast changes to the higher contrast details, whereas low values will amplify contrast changes to low contrast details.\nBy using a low Attenuation response value you can select which contrast values will be enhanced. -!TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n .The lower it is, the more the effect will be pinpointed towards a narrow range of contrast values. -!TP_WAVELET_THRDEN_TOOLTIP;Generates a stepped curve used to guide the noise reduction as a function of local contrast. The denoise will be applied to uniform low local-contrast areas. Areas with detail (higher local contrast) will be preserved. -!TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, you can choose any level (in Settings) from 1 to 4 for processing.\nIf you select Clarity, you can choose any level (in Settings) between 5 and Extra. -!TP_WBALANCE_ITCWALG_TOOLTIP;Allows you to switch to the other Alternative temperature (Alt_temp), when possible.\nInactive in the "single choice" case. -!TP_WBALANCE_ITCWBDELTA_TOOLTIP;Fixed for each "green" iteration tried, the temperature difference to be taken into account. -!TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Find the best compromise between Student and green. -!TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Allows you to set the minimum patch value. values that are too low can lead to a lack of correlation. -!TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Allows you to filter magenta/purple data from the image. If the box is checked a filter limiting the value of Y is applied. By default this value is 0.4. You can change it in 'options' Itcwb_Ypurple (Maximum 1) -!TP_WBALANCE_ITCWBPRECIS_TOOLTIP;The lower the value, the more relevant the data, but increases the processing time. Since the processing time is low, this parameter should generally be able to remain at the default value -!TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Sets the green value review amplitude in iterations, from low amplitude 0.82 to 1.25 to maximum amplitude 0.4 to 4. -!TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;This setting sets the size of color datas used by algorithm. -!TP_WBALANCE_ITCWBSIZE_TOOLTIP;This setting sets the number of iterations to find the best correspondence between the reference spectral colors and those in xyY value of the image. A value of 3 seams a good compromise. -!TP_WBALANCE_ITCWBTHRES_TOOLTIP;Limits comparison sampling between spectral data and image data. -!TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. -!TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Allows you to use Custom settings Temperature and Green (tint).\n\nUsage tips:\n1) start Itcwb , enable 'Use Custom temperature and tint'.\n2) Set 'Temperature and tint' to your liking :free, Pick,...(Custom)\n3) go back to 'Temperature correlation'.\n\nYou cannot use : 2 passes, AWB temperature bias, Green refinement. -!TP_WBALANCE_ITCWFORCED_TOOLTIP;By default (box not checked) the data scanned during sampling is brought back to the sRGB profile, which is the most widespread, both for calibrating DCP or ICC profiles with the Colorchecker24, or used on the web.\n If you have very high gamut images (some flowers, artificial colors), then it may be necessary to use the entire CIExy diagram, the profile used will be ACESP0. In this second case, the number of colors that can be used in internal to the algorithm will be more important. -!TP_WBALANCE_ITCWGREEN_TOOLTIP;Allows you to change the "tint" (green) which will serve as a reference when starting the algorithm. It has substantially the same role for greens as "AWB temperature bias" for temperature.\nThe whole algorithm is recalculated. -!TP_WBALANCE_ITCWPRIM_TOOLTIP;Allows you to select the image sampling.\n'Close to full CIE diagram' almost uses the data present on the sensor, possibly including the imaginary colors.\n'Camera XYZ matrix' - uses the matrix directly derived from Color Matrix.\n'Medium sampling' (default) - near Pointer's gamut: corresponds substantially to the most common cases of human vision.\nThe other choice 'Low sampling and Ignore camera settings' allow you to isolate high gamut parts of the image and forces the algorithm in some cases (tint > 0.8,...) to ignore camera settings. This will obviously have an impact on the result.\n\nThis sampling only has an influence on the channel multipliers, it has nothing to do with the "working profile" and does not modify the gamut of the image. -!TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Allows you to use the old sampling algorithm to ensure better compatibility with 5.9. You must enable Observer 10° (default). -!TP_WBALANCE_MULLABEL_TOOLTIP;Values given for information purposes. You cannot change them. -!TP_WBALANCE_OBSERVER10_TOOLTIP;The color management in RawTherapee (White balance, channel multipliers, highlight recovery,...) uses the spectral data of the illuminants and colors. Observer is an important parameter of this management which takes into account the angle of perception of the eye. In 1931 it was fixed at 2° (privileges the use of the cones). In 1964 it was fixed at 10° (privileges the use of the cones, but partially takes into account the rods).\nIn the rare case of a color drift with "Observer 2°" (probably due to the conversion matrix) "Observer 10°" must be selected. -!TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colors (max=237).\nDisplay calculated Patch Chroma.\nAWB temperature bias, lets try to reduce this value, a minimum may seem to optimize the algorithm.\n\nPatch size matching chroma optimization. -!TP_WBALANCE_PATCHLEVELLABEL_TOOLTIP;Display ΔE patch (this assumes there is enough spectral data), between image and spectral datas.\n Display read datas found. The 2 values correspond to the minimum and maximum data values taken into account. The coefficient x9 must be taken into account to obtain the number of pixels concerned in the image. -!TP_WBALANCE_STUDLABEL_TOOLTIP;Display calculated Student correlation.\nLower values are better, where <0.005 is excellent,\n<0.01 is good, and >0.5 is poor.\nLow values do not mean that the white balance is good:\nif the illuminant is non-standard the results can be erratic.\nA value of 1000 means previous calculations are used and\nthe resultsare probably good.\n\nPasses : number of passes made.\nAlt_temp : Alternative temperature. !//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. !//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram From 919bd635b17cdbf51a4fc86d67ac1e83dca48abf Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:26:12 -0700 Subject: [PATCH 285/291] Preparing for release 5.11-rc1 --- RELEASE_NOTES.txt | 57 ++++++++-- com.rawtherapee.RawTherapee.appdata.xml | 1 + rtdata/images/splash.svg | 133 +++++++++++------------- 3 files changed, 109 insertions(+), 82 deletions(-) diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index b4d4a3523..ca4beb576 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,6 +1,6 @@ -RAWTHERAPEE 5.10-dev RELEASE NOTES +RAWTHERAPEE 5.11-rc1 RELEASE NOTES -This is a development version of RawTherapee. We update the code almost daily. Every few months, once enough changes have accumulated and the code is stabilized, we make a new official release. Every code change between these releases is known as a "development" version, and this is one of them. +This is Release Candidate 1 of RawTherapee 5.11, released on 2025-08-11. This is not the final release yet. @@ -24,21 +24,60 @@ In order to use RawTherapee efficiently you should know that: NEW FEATURES SINCE 5.10 -- TODO -- Added or improved support for cameras, raw formats and color profiles: - - TODO +- The path template for queue export supports more format specifiers, including dates and new path types. Additionally, there is a preview to show the path for the selected image. +- The maximum zoom for the editor is now configurable. +- Pseudo HiDPI is replaced by real HiDPI. +- The file browser has an option to show all images within subfolders too. +- The Use embedded option for the Input Profile is available for DNGs that have an embedded DCP. +- The Color appearance sub-tool in Selective Editing (formerly Local Adjustments) received various improvements, including simplification of the basic mode, addition of new tone mappers for Cam16, a black and white mode, and a highlight attenuation feature. +- The White balance Tint range is expanded. +- It is now possible to use Contrast by Detail Levels in Before Black-and-White mode while Color Appearance & Lighting is activated with CAM16. +- Ratings and color labels can be synchronized with XMPs. +- The Selective Editing tool received various improvements, such as a global mode for applying edits to the entire image uniformly, ΔE preview buttons for most sub-tools, and adjustable graduated filter feathering for each sub-tool. +- The EXIF modified date-time is now added to saved images. +- RawTherapee can now read 12-bit Panasonic raw files encoded in the v6 format, such as those from the DC-GH5M2. +- RawTherapee can now read Panasonic raw files encoded in the v8 format, such as those from the DC-GH6, DC-S5M2, and DC-S5M2X. +- RawTherapee can now read Fujifilm lossy-compressed raw files. +- JPEG XL images can now be opened. +- There is a new option to use lens corrections from the file metadata. It works for compatible raw images from Fujifilm, Olympus / OM Digital Solutions (distortion and chromatic aberration corrections only), and Sony. Corrections embedded in DNGs can also be used. +- RawTherapee can leverage LibRaw (enabled by default) to read raw images. It adds the ability to read additional raw formats, such as Sony lossless compression, and improved support for some cameras. +- Added or improved support for cameras, raw formats and color profiles (not including LibRaw and color matrices for dcraw): + - FUJIFILM GFX 100 (PDAF lines filter) + - FUJIFILM GFX 100S (DCP, PDAF lines filter) + - FUJIFILM GFX 100 II (PDAF lines filter) + - Fujifilm X-H2S + - Nikon Z 8 (DCP) + - Nikon Z 9 (DCP) + - Nikon Z f (DCP) + - OM Digital Solutions TG-7 + - Panasonic DC-G9M2 + - Panasonic DC-GH5M2 + - Panasonic DC-GH6 + - Panasonic DC-S5M2 + - Panasonic DC-S5M2X + - Sony ILCE-1 (Pixel shift) + - Sony ILCE-6700 + - Sony ILCE-7CR (PDAF lines filter) + - Sony ILCE-7RM4 (PDAF lines filter) + - Sony ILCE-7RM5 (PDAF lines filter) + - SONY ILCE-9M3 NEWS RELEVANT TO PACKAGE MAINTAINERS New since 5.10: -- TODO +- Requires GTK+ >= 3.24.3 (was >= 3.22.24 in Windows, or >= 3.16 in other operating systems). +- Requires librsvg-2.0 >= 2.52 (was >= 2.40). +- Optional dependency on libjxl. +- Optional dependency on LibRaw >= 0.21. In general: -- To get the source code, either clone from git or use the tarball from https://rawtherapee.com/shared/source/ . Do not use the auto-generated GitHub release tarballs. -- Requires GTK+ version >=3.22.24 in Windows, else >=3.16 (though >=3.22.24 is recommended). -- GTK+ versions 3.24.2 - 3.24.6 have an issue where combobox menu scroll-arrows are missing when the combobox list does not fit vertically on the screen. As a result, users would not be able to scroll in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction. +- To get the source code, either clone from git or use the tarball from https://rawtherapee.com/shared/source/. Do not use the auto-generated GitHub release tarballs. +- Requires GTK+ version >= 3.24.3. +- GTK+ versions 3.24.3 - 3.24.6 have an issue where combobox menu scroll-arrows are missing when the combobox list does not fit vertically on the screen. As a result, users would not be able to scroll in the following comboboxes: Processing Profiles, Film Simulation, and the camera and lens profiles in Profiled Lens Correction. +- JPEG XL read support depends on libjxl. By default, RawTherapee builds with JPEG XL support if and only if libjxl is present. Use -DWITH_JXL="ON" or DWITH_JXL="OFF" to explicitly enable or disable, respectively, JPEG XL support. +- RawTherapee builds with a custom version of LibRaw by default. To use the system LibRaw, use -DWITH_SYSTEM_LIBRAW="ON". Requires LibRaw >= 0.21. - RawTherapee 5 requires GCC-4.9 or higher, or Clang. - Do not use -ffast-math, it will not make RawTherapee faster but will introduce artifacts. - Use -O3, it will make RawTherapee faster with no known side-effects. diff --git a/com.rawtherapee.RawTherapee.appdata.xml b/com.rawtherapee.RawTherapee.appdata.xml index 7e30dc2f8..585d265ff 100644 --- a/com.rawtherapee.RawTherapee.appdata.xml +++ b/com.rawtherapee.RawTherapee.appdata.xml @@ -22,6 +22,7 @@ https://rawpedia.rawtherapee.com/Main_Page#Localization rawtherapee.desktop + diff --git a/rtdata/images/splash.svg b/rtdata/images/splash.svg index 9e91d054e..0fcfdea25 100644 --- a/rtdata/images/splash.svg +++ b/rtdata/images/splash.svg @@ -7,7 +7,7 @@ viewBox="0 0 160 99.999999" version="1.1" id="svg783" - inkscape:version="1.3.1 (91b66b0783, 2023-11-16, custom)" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)" sodipodi:docname="splash.svg" inkscape:export-filename="/tmp/splash.png" inkscape:export-xdpi="96" @@ -26,15 +26,15 @@ + + + + + + - + - - - - - - - - - - - - - + style="font-size:4.93889px;line-height:1.25;font-family:'Eras Bold ITC';-inkscape-font-specification:'Eras Bold ITC';text-align:end;letter-spacing:-0.243417px;text-anchor:end;display:inline;fill:#ffffff;stroke-width:0.211231;filter:url(#filter4749-3-2-3)" + transform="matrix(1,0,0.05240778,1,-5.5835665,-177.49225)" + aria-label="Release Candidate 1" /> From ac185128d3c9cf0b644a4c65236138ae52b1e6c7 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 11 Aug 2024 07:18:36 +0200 Subject: [PATCH 286/291] Wavelet denoise limit window size to avoid crash issue 7146 (#7169) * Wavelet denoise limit window * Change limit minimum windows to 128 --- rtengine/ipwavelet.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index f0b6afaaf..536b89295 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -345,6 +345,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.BAmet = 2; } } + int minwinnoise = rtengine::min(imwidth, imheight); cp.sigm = params->wavelet.sigma; @@ -355,7 +356,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.resena = params->wavelet.expresid; cp.finena = params->wavelet.expfinal; cp.toningena = params->wavelet.exptoning; - cp.noiseena = params->wavelet.expnoise; + cp.noiseena = params->wavelet.expnoise && minwinnoise > 128;//128 limit for 6 levels wavelet denoise issue 7146 cp.blena = params->wavelet.expbl; cp.chrwav = 0.01f * params->wavelet.chrwav; From 53694b494ff6818e9718fdf2f4861bd9ff71417a Mon Sep 17 00:00:00 2001 From: Martin <78749513+marter001@users.noreply.github.com> Date: Sun, 11 Aug 2024 07:47:42 +0200 Subject: [PATCH 287/291] localisation deutsch for RT 5.11 --- rtdata/languages/Deutsch | 1992 +++++++++++++++++++------------------- 1 file changed, 993 insertions(+), 999 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 9283ce0e2..ebec02af0 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -1,92 +1,93 @@ -#001 keenonkites; Aktualisierte Version für 2.3 beta2 -#002 phberlin; basiert auf keenonkites' Erstübersetzung -#003 2007-12-20 -#004 2007-12-22 -#005 2008-01-08 -#006 2008-01-15 -#007 2008-02-20 -#008 2008-12-19 keenonkites, Anpassungen für 2.4beta4 -#009 2008-09-20 keenonkites, Anpassungen für 2.4m2 -#010 2008-04-04 Anpassungen für 2.4 -#011 Leichte Anpassungen (keenonkites/klonk) -#012 Erweiterung (oduis) -#013 Erweiterung (oduis) -#014 Erweiterung (oduis) -#015 Erweiterung (oduis) -#016 2012-12-05 3.0 alpha: Erweiterung und Korrekturen (Metex) -#017 2012-04-29 Erweiterungen und Korrekturen (MaWe) -#018 Erweiterung (oduis) -#019 Erweiterung (oduis) -#020 2013-02-27 Erweiterung (cytrinox) -#021 2013-12-31 Erweiterung (Ingo) -#022 2015-09-04 komplette Überarbeitung (TooWaBoo) -#023 2015-10-24 Retinexübersetzung und Korrekturen (TooWaBoo) -#024 2015-11-01 Korrekturen (TooWaBoo) RT4.2.450 -#025 2015-11-30 Korrekturen (TooWaBoo) RT4.2.507 -#026 2015-12-13 Korrekturen (TooWaBoo) RT4.2.514 -#026 2015-12-22 Korrekturen (TooWaBoo) RT4.2.536 -#027 2016-02-12 Retinexübersetzung (TooWaBoo) RT4.2.730 -#028 2016-03-19 Erweiterung/Korrekturen (TooWaBoo) RT4.2.880 -#029 2016-05-24 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1005 -#030 2016-09-30 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1234 -#031 2016-12-01 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1408 -#032 2016-12-29 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1464 -#033 2017-01-04 Erweiterung/Korrekturen/Soft-Proofing (TooWaBoo) RT4.2.1477 -#034 2017-01-07 IPTC (TooWaBoo) RT4.2.1492 -#035 2017-02-18 AWB bias (TooWaBoo) RT 5.0 r1 -#036 2017-02-23 Korrekturen (TooWaBoo) RT 5.0 r1 -#037 2017-03-06 Dynamisches Profil (TooWaBoo) RT 5.0 r1 -#038 2017-03-26 Pixel-Shift (TooWaBoo) RT 5.0 r1 -#039 06.04.2017 Fast Export (TooWaBoo) RT 5.0 r1 -#040 30.04.2017 Erweiterung/Korrekturen (TooWaBoo) RT 5.0 r1 -#041 03.05.2017 Erweiterung/Korrekturen (TooWaBoo) RT 5.0 r1 -#042 13.05.2017 Erweiterung (TooWaBoo) RT 5.0 r1 -#043 21.07.2017 Erweiterung (TooWaBoo) RT 5.1 -#044 21.09.2017 Erweiterung (TooWaBoo) RT 5.2 -#045 15.10.2017 Erweiterung (TooWaBoo) RT 5.3 -#046 18.10.2017 Erweiterung (TooWaBoo) RT 5.3 -#047 19.11.2017 HDR-Dynamikkompression (TooWaBoo) RT 5.3 -#048 13.12.2017 Erweiterung (TooWaBoo) RT 5.3 -#049 21.12.2017 Lokaler Kontrast (TooWaBoo) RT 5.3 -#050 07.01.2018 Crop Settings (TooWaBoo) RT 5.3 -#051 10.02.2018 Erweiterung (TooWaBoo) RT 5.3 -#052 10.02.2018 Korrektur (TooWaBoo) RT 5.3 -#053 26.02.2018 Erweiterung (TooWaBoo) RT 5.3 -#054 30.03.2018 Erweiterung (TooWaBoo) RT 5.4 -#055 06.04.2018 Erweiterung (TooWaBoo) RT 5.4 -#056 27.04.2018 Erweiterung (TooWaBoo) RT 5.4 -#057 17.05.2018 Erweiterung (TooWaBoo) RT 5.4 -#058 19.05.2018 Erweiterung (TooWaBoo) RT 5.4 -#059 29.05.2018 Erweiterung (TooWaBoo) RT 5.4 -#060 14.06.2018 Erweiterung (TooWaBoo) RT 5.4 -#061 14.06.2018 Korrektur (TooWaBoo) RT 5.4 -#062 22.06.2018 Korrektur (TooWaBoo) RT 5.4 -#063 24.06.2018 DCB/RCD+VNG4 (TooWaBoo) RT 5.4 -#064 24.06.2018 Erweiterung/Korrektur (TooWaBoo) RT 5.4 -#065 25.06.2018 Korrekturen (TooWaBoo) RT 5.4 -#066 04.07.2018 Erweiterung (TooWaBoo) RT 5.4 -#067 05.07.2018 Erweiterung (TooWaBoo) RT 5.4 -#068 05.07.2018 Erweiterung (TooWaBoo) RT 5.4 -#069 25.07.2018 Erweiterung (TooWaBoo) RT 5.4 -#070 25.07.2018 Korrekturen (TooWaBoo) RT 5.4 -#071 28.09.2018 Korrekturen (TooWaBoo) RT 5.5 -#072 05.10.2018 Korrekturen (TooWaBoo) RT 5.5 -#073 21.11.2018 Erweiterung (TooWaBoo) RT 5.5 -#074 24.11.2018 Erweiterung (TooWaBoo) RT 5.5 -#075 02.12.2018 Erweiterung (TooWaBoo) RT 5.5 -#076 11.12.2018 Erweiterung (TooWaBoo) RT 5.5 -#077 16.12.2018 Korrektur Farbwähler-Tooltip (TooWaBoo) RT 5.5 -#078 19.01.2019 Erweiterung (TooWaBoo) RT 5.5 -#079 24.02.2019 Erweiterung (TooWaBoo) RT 5.5 -#080 25.03.2019 Erweiterung (TooWaBoo) RT 5.6 -#081 15.04.2019 Erweiterung (TooWaBoo) RT 5.6 -#082 25.05.2019 Erweiterung (TooWaBoo) RT 5.6 -#083 06.07.2019 Erweiterung (TooWaBoo) RT 5.6 -#084 06.10.2019 Erweiterung (TooWaBoo) RT 5.7 -#084 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 -#085 29.07.2022 Erweiterung (marter, mozzihh) RT 5.9 -#086 2023-09, Version RT 5.10 (marter) - +#01 keenonkites; Aktualisierte Version für 2.3 beta2 +#02 phberlin; basiert auf keenonkites' Erstübersetzung +#03 2007-12-20 +#04 2007-12-22 +#05 2008-01-08 +#06 2008-01-15 +#07 2008-02-20 +#08 2008-12-19 keenonkites, Anpassungen für 2.4beta4 +#09 2008-09-20 keenonkites, Anpassungen für 2.4m2 +#10 2008-04-04 Anpassungen für 2.4 +#11 Leichte Anpassungen (keenonkites/klonk) +#12 Erweiterung (oduis) +#13 Erweiterung (oduis) +#14 Erweiterung (oduis) +#15 Erweiterung (oduis) +#16 2012-12-05 3.0 alpha: Erweiterung und Korrekturen (Metex) +#17 2012-04-29 Erweiterungen und Korrekturen (MaWe) +#18 Erweiterung (oduis) +#19 Erweiterung (oduis) +#20 2013-02-27 Erweiterung (cytrinox) +#21 2013-12-31 Erweiterung (Ingo) +#22 2015-09-04 komplette Überarbeitung (TooWaBoo) +#23 2015-10-24 Retinexübersetzung und Korrekturen (TooWaBoo) +#24 2015-11-01 Korrekturen (TooWaBoo) RT4.2.450 +#25 2015-11-30 Korrekturen (TooWaBoo) RT4.2.507 +#26 2015-12-13 Korrekturen (TooWaBoo) RT4.2.514 +#26 2015-12-22 Korrekturen (TooWaBoo) RT4.2.536 +#27 2016-02-12 Retinexübersetzung (TooWaBoo) RT4.2.730 +#28 2016-03-19 Erweiterung/Korrekturen (TooWaBoo) RT4.2.880 +#29 2016-05-24 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1005 +#30 2016-09-30 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1234 +#31 2016-12-01 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1408 +#32 2016-12-29 Erweiterung/Korrekturen (TooWaBoo) RT4.2.1464 +#33 2017-01-04 Erweiterung/Korrekturen/Soft-Proofing (TooWaBoo) RT4.2.1477 +#34 2017-01-07 IPTC (TooWaBoo) RT4.2.1492 +#35 2017-02-18 AWB bias (TooWaBoo) RT 5.0 r1 +#36 2017-02-23 Korrekturen (TooWaBoo) RT 5.0 r1 +#37 2017-03-06 Dynamisches Profil (TooWaBoo) RT 5.0 r1 +#38 2017-03-26 Pixel-Shift (TooWaBoo) RT 5.0 r1 +#39 06.04.2017 Fast Export (TooWaBoo) RT 5.0 r1 +#40 30.04.2017 Erweiterung/Korrekturen (TooWaBoo) RT 5.0 r1 +#41 03.05.2017 Erweiterung/Korrekturen (TooWaBoo) RT 5.0 r1 +#42 13.05.2017 Erweiterung (TooWaBoo) RT 5.0 r1 +#43 21.07.2017 Erweiterung (TooWaBoo) RT 5.1 +#44 21.09.2017 Erweiterung (TooWaBoo) RT 5.2 +#45 15.10.2017 Erweiterung (TooWaBoo) RT 5.3 +#46 18.10.2017 Erweiterung (TooWaBoo) RT 5.3 +#47 19.11.2017 HDR-Dynamikkompression (TooWaBoo) RT 5.3 +#48 13.12.2017 Erweiterung (TooWaBoo) RT 5.3 +#49 21.12.2017 Lokaler Kontrast (TooWaBoo) RT 5.3 +#50 07.01.2018 Crop Settings (TooWaBoo) RT 5.3 +#51 10.02.2018 Erweiterung (TooWaBoo) RT 5.3 +#52 10.02.2018 Korrektur (TooWaBoo) RT 5.3 +#53 26.02.2018 Erweiterung (TooWaBoo) RT 5.3 +#54 30.03.2018 Erweiterung (TooWaBoo) RT 5.4 +#55 06.04.2018 Erweiterung (TooWaBoo) RT 5.4 +#56 27.04.2018 Erweiterung (TooWaBoo) RT 5.4 +#57 17.05.2018 Erweiterung (TooWaBoo) RT 5.4 +#58 19.05.2018 Erweiterung (TooWaBoo) RT 5.4 +#59 29.05.2018 Erweiterung (TooWaBoo) RT 5.4 +#60 14.06.2018 Erweiterung (TooWaBoo) RT 5.4 +#61 14.06.2018 Korrektur (TooWaBoo) RT 5.4 +#62 22.06.2018 Korrektur (TooWaBoo) RT 5.4 +#63 24.06.2018 DCB/RCD+VNG4 (TooWaBoo) RT 5.4 +#64 24.06.2018 Erweiterung/Korrektur (TooWaBoo) RT 5.4 +#65 25.06.2018 Korrekturen (TooWaBoo) RT 5.4 +#66 04.07.2018 Erweiterung (TooWaBoo) RT 5.4 +#67 05.07.2018 Erweiterung (TooWaBoo) RT 5.4 +#68 05.07.2018 Erweiterung (TooWaBoo) RT 5.4 +#69 25.07.2018 Erweiterung (TooWaBoo) RT 5.4 +#70 25.07.2018 Korrekturen (TooWaBoo) RT 5.4 +#71 28.09.2018 Korrekturen (TooWaBoo) RT 5.5 +#72 05.10.2018 Korrekturen (TooWaBoo) RT 5.5 +#73 21.11.2018 Erweiterung (TooWaBoo) RT 5.5 +#74 24.11.2018 Erweiterung (TooWaBoo) RT 5.5 +#75 02.12.2018 Erweiterung (TooWaBoo) RT 5.5 +#76 11.12.2018 Erweiterung (TooWaBoo) RT 5.5 +#77 16.12.2018 Korrektur Farbwähler-Tooltip (TooWaBoo) RT 5.5 +#78 19.01.2019 Erweiterung (TooWaBoo) RT 5.5 +#79 24.02.2019 Erweiterung (TooWaBoo) RT 5.5 +#80 25.03.2019 Erweiterung (TooWaBoo) RT 5.6 +#81 15.04.2019 Erweiterung (TooWaBoo) RT 5.6 +#82 25.05.2019 Erweiterung (TooWaBoo) RT 5.6 +#83 06.07.2019 Erweiterung (TooWaBoo) RT 5.6 +#84 06.10.2019 Erweiterung (TooWaBoo) RT 5.7 +#84 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 +#85 29.07.2022 Erweiterung (marter, mozzihh) RT 5.9 +#86 29.08.2024 (marter) RT 5.11 +#100 +#101 @LANGUAGE_DISPLAY_NAME=Deutsch ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen ABOUT_TAB_LICENSE;Lizenz @@ -137,6 +138,7 @@ DYNPROFILEEDITOR_PROFILE;Profil EDITWINDOW_TITLE;Bildbearbeitung EDIT_OBJECT_TOOLTIP;Schaltet das Einstellungswerkzeug im Vorschaubild ein/aus. EDIT_PIPETTE_TOOLTIP;Um einen Punkt der Kurve hinzuzufügen, halten Sie die Strg-Taste gedrückt und klicken mit der linke Maustaste auf die gewünschte Stelle in der Vorschau.\nUm den Punkt anzupassen, halten Sie die Strg-Taste gedrückt und klicken Sie mit der linken Maustaste auf den entsprechenden Bereich in der Vorschau. Dann lassen Sie die Strg-Taste los (es sei denn, Sie möchten eine Feineinstellung vornehmen) und bewegen die Maus bei gedrückter linker Maustaste nach oben oder unten, um den Punkt auf der Kurve zu bewegen. +ERROR_MSG_METADATA_VALUE;Metadaten: Fehler Einstellung %1 nach %2 EXIFFILTER_APERTURE;Blende EXIFFILTER_CAMERA;Kamera EXIFFILTER_EXPOSURECOMPENSATION;Belichtungskorrektur (EV) @@ -287,6 +289,7 @@ FILEBROWSER_SHOWRANK4HINT;Nur mit 4 Sternen bewertete Bilder anzeigen.\nTaste: < FILEBROWSER_SHOWRANK5HINT;Nur mit 5 Sternen bewertete Bilder anzeigen.\nTaste: Umschalt-5 FILEBROWSER_SHOWRECENTLYSAVEDHINT;Nur gespeicherte Bilder anzeigen.\nTaste: Alt + 7 FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Nur nicht gespeicherte Bilder anzeigen.\nTaste: Alt + 6 +FILEBROWSER_SHOWRECURSIVE;Bilder in Unterordnern rekursiv anzeigen. FILEBROWSER_SHOWTRASHHINT;Inhalt des Papierkorbs anzeigen.\nTaste: Strg + t FILEBROWSER_SHOWUNCOLORHINT;Nur unmarkierte Bilder anzeigen.\nTaste: Alt + 0 FILEBROWSER_SHOWUNRANKHINT;Nur unbewertete Bilder anzeigen.\nTaste: Umschalt-0 @@ -348,7 +351,7 @@ HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogramm HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw-Histogramm HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-Parade HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Vektorskop Farbton-Chroma -HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS; Vektorskop Farbton-Sättigung +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Vektorskop Farbton-Sättigung HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Wellenform HISTORY_CHANGED;Geändert HISTORY_CUSTOMCURVE;Benutzerdefiniert @@ -822,647 +825,647 @@ HISTORY_MSG_491;(Farbe - Weißabgleich) HISTORY_MSG_492;(Farbe - RGB-Kurven) HISTORY_MSG_493;(Belichtung - L*a*b*) HISTORY_MSG_494;(RAW - Eingangsschärfung) -HISTORY_MSG_496;(Lokal - Spot)\nGelöscht -HISTORY_MSG_497;(Lokal - Spot)\nAusgewählt -HISTORY_MSG_498;--nicht verwendet-- -HISTORY_MSG_499;--nicht verwendet-- -HISTORY_MSG_500;(Lokal - Spot)\nForm -HISTORY_MSG_501;(Lokal - Spot)\nMethode -HISTORY_MSG_502;(Lokal - Spot)\nForm-Methode -HISTORY_MSG_503;(Lokal - Spot)\nRechts -HISTORY_MSG_504;(Lokal - Spot)\nLinks -HISTORY_MSG_505;(Lokal - Spot)\nUnten -HISTORY_MSG_506;(Lokal - Spot)\nOben -HISTORY_MSG_507;(Lokal - Spot)\nMitte -HISTORY_MSG_508;(Lokal - Spot)\nSpotgröße -HISTORY_MSG_509;(Lokal - Spot)\nQualitäts-Methode -HISTORY_MSG_510;(Lokal - Spot)\nÜbergangsgradient\nIntensität -HISTORY_MSG_511;(Lokal - Spot)\nKantenerkennung\nSchwellenwert -HISTORY_MSG_512;(Lokal - Spot)\nKantenerkennung\nΔE Zerfall -HISTORY_MSG_513;(Lokal - Spot)\nausschließender Bereich -HISTORY_MSG_514;(Lokal - Spot)\nStruktur -HISTORY_MSG_515;(Lokal - Lokale Anpassungen) -HISTORY_MSG_516;(Lokal - Farbe-Licht) -HISTORY_MSG_517;(Lokal) - Super aktivieren -HISTORY_MSG_518;(Lokal - Farbe-Licht)\nHelligkeit -HISTORY_MSG_519;(Lokal - Farbe-Licht)\nKontrast -HISTORY_MSG_520;(Lokal - Farbe-Licht)\nChrominanz -HISTORY_MSG_521;(Lokal) - Umfang -HISTORY_MSG_522;(Lokal - Farbe-Licht)\nKurventyp -HISTORY_MSG_523;(Lokal - Farbe-Licht)\nLL-Kurve -HISTORY_MSG_524;(Lokal - Farbe-Licht)\nCC-Kurve -HISTORY_MSG_525;(Lokal - Farbe-Licht)\nLH-Kurve -HISTORY_MSG_526;(Lokal - Farbe-Licht)\nHH-Kurve -HISTORY_MSG_527;(Lokal - Farbe-Licht)\nInvertieren -HISTORY_MSG_528;(Lokal - Dynamik u. Belichtung) -HISTORY_MSG_529;(Lokal - Dynamik u. Belichtung)\nKompression -HISTORY_MSG_530;(Lokal - Dynamik u. Belichtung)\nLichterkompression -HISTORY_MSG_531;(Lokal - Dynamik u. Belichtung)\nLichterkompression\nSchwellenwert -HISTORY_MSG_532;(Lokal - Dynamik u. Belichtung)\nSchwarzwert -HISTORY_MSG_533;(Lokal - Dynamik u. Belichtung)\nSchattenkompression -HISTORY_MSG_534;(Lokal - Farbtemperatur)\nTönung -HISTORY_MSG_535;(Lokal - Dynamik u. Belichtung)\nIntensität -HISTORY_MSG_536;(Lokal - Dynamik u. Belichtung)\nKontrastkurve -HISTORY_MSG_537;(Lokal - Farbtemperatur) -HISTORY_MSG_538;(Lokal - Farbtemperatur)\nGesättigte Töne -HISTORY_MSG_539;(Lokal - Farbtemperatur)\nPastelltöne -HISTORY_MSG_540;(Lokal - Farbtemperatur)\nSchwellenwert -HISTORY_MSG_541;(Lokal - Farbtemperatur)\nHauttöne schützen -HISTORY_MSG_542;(Lokal - Farbtemperatur)\nFarbverschiebung vermeiden -HISTORY_MSG_543;(Lokal - Farbtemperatur)\nPastell- und gesättigte Farbtöne koppeln -HISTORY_MSG_544;(Lokal - Farbtemperatur)\nBereich -HISTORY_MSG_545;(Lokal - Farbtemperatur)\nH-Kurve -HISTORY_MSG_546;(Lokal - Unschärfe)\nUnschärfe und Rauschen -HISTORY_MSG_547;(Lokal - Unschärfe)\nRadius -HISTORY_MSG_548;(Lokal - Unschärfe)\nRauschen -HISTORY_MSG_549;(Lokal - Unschärfe)\nIntensität -HISTORY_MSG_550;(Lokal - Unschärfe)\nMethode -HISTORY_MSG_551;(Lokal - Unschärfe)\nNur Luminanz -HISTORY_MSG_552;(Lokal - Tonwert) -HISTORY_MSG_553;(Lokal - Tonwert)\nKompressionsintensität -HISTORY_MSG_554;(Lokal - Tonwert)\nGamma -HISTORY_MSG_555;(Lokal - Tonwert)\nKantenempfindlichkeit -HISTORY_MSG_556;(Lokal - Tonwert)\nSkalieren -HISTORY_MSG_557;(Lokal - Tonwert)\nGewichtung -HISTORY_MSG_558;(Lokal - Tonwert)\nIntensität -HISTORY_MSG_559;(Lokal - Retinex) -HISTORY_MSG_560;(Lokal - Retinex)\nMethode -HISTORY_MSG_561;(Lokal - Retinex)\nIntensität -HISTORY_MSG_562;(Lokal - Retinex)\nChroma -HISTORY_MSG_563;(Lokal - Retinex)\nRadius -HISTORY_MSG_564;(Lokal - Retinex)\nKontrast -HISTORY_MSG_565;(Lokal) - Umfang -HISTORY_MSG_566;(Lokal - Retinex)\nVerstärkungskurve -HISTORY_MSG_567;(Lokal - Retinex)\nInvertieren -HISTORY_MSG_568;(Lokal - Schärfen) -HISTORY_MSG_569;(Lokal - Schärfen)\nRadius -HISTORY_MSG_570;(Lokal - Schärfen)\nIntensität -HISTORY_MSG_571;(Lokal - Schärfen)\nDämpfung -HISTORY_MSG_572;(Lokal - Schärfen)\nIterationen -HISTORY_MSG_573;(Lokal - Schärfen)\nUmfang -HISTORY_MSG_574;(Lokal - Schärfen)\nInvertieren -HISTORY_MSG_575;(Lokal - Detailebenen) -HISTORY_MSG_576;(Lokal - Detailebenen)\nMulti -HISTORY_MSG_577;(Lokal - Detailebenen)\nChroma -HISTORY_MSG_578;(Lokal - Detailebenen)\nSchwelle -HISTORY_MSG_579;(Lokal - Detailebenen)\nUmfang +HISTORY_MSG_496;(sel. Editieren - Spot)\nGelöscht +HISTORY_MSG_497;(sel. Editieren - Spot)\nAusgewählt +HISTORY_MSG_498;(sel. Editieren - Spot)\nName +HISTORY_MSG_499;(sel. Editieren - Spot)\nSichtbarkeit +HISTORY_MSG_500;(sel. Editieren - Spot)\nForm +HISTORY_MSG_501;(sel. Editieren - Spot)\nMethode +HISTORY_MSG_502;(sel. Editieren - Spot)\nForm-Methode +HISTORY_MSG_503;(sel. Editieren - Spot)\nRechts +HISTORY_MSG_504;(sel. Editieren - Spot)\nLinks +HISTORY_MSG_505;(sel. Editieren - Spot)\nUnten +HISTORY_MSG_506;(sel. Editieren - Spot)\nOben +HISTORY_MSG_507;(sel. Editieren - Spot)\nMitte +HISTORY_MSG_508;(sel. Editieren - Spot)\nSpotgröße +HISTORY_MSG_509;(sel. Editieren - Spot)\nQualitäts-Methode +HISTORY_MSG_510;(sel. Editieren - Spot)\nÜbergangsgradient\nIntensität +HISTORY_MSG_511;(sel. Editieren - Spot)\nKantenerkennung\nSchwellenwert +HISTORY_MSG_512;(sel. Editieren - Spot)\nKantenerkennung\nΔE Zerfall +HISTORY_MSG_513;(sel. Editieren - Spot)\nausschließender Bereich +HISTORY_MSG_514;(sel. Editieren - Spot)\nStruktur +HISTORY_MSG_515;(Selektives Editieren) +HISTORY_MSG_516;(sel. Editieren - Farbe-Licht) +HISTORY_MSG_517;(sel. Editieren) - Super aktivieren +HISTORY_MSG_518;(sel. Editieren - Farbe-Licht)\nHelligkeit +HISTORY_MSG_519;(sel. Editieren - Farbe-Licht)\nKontrast +HISTORY_MSG_520;(sel. Editieren - Farbe-Licht)\nChrominanz +HISTORY_MSG_521;(sel. Editieren) - Umfang +HISTORY_MSG_522;(sel. Editieren - Farbe-Licht)\nKurventyp +HISTORY_MSG_523;(sel. Editieren - Farbe-Licht)\nLL-Kurve +HISTORY_MSG_524;(sel. Editieren - Farbe-Licht)\nCC-Kurve +HISTORY_MSG_525;(sel. Editieren - Farbe-Licht)\nLH-Kurve +HISTORY_MSG_526;(sel. Editieren - Farbe-Licht)\nHH-Kurve +HISTORY_MSG_527;(sel. Editieren - Farbe-Licht)\nInvertieren +HISTORY_MSG_528;(sel. Editieren - Dynamik u. Belichtung) +HISTORY_MSG_529;(sel. Editieren - Dynamik u. Belichtung)\nKompression +HISTORY_MSG_530;(sel. Editieren - Dynamik u. Belichtung)\nLichterkompression +HISTORY_MSG_531;(sel. Editieren - Dynamik u. Belichtung)\nLichterkompression\nSchwellenwert +HISTORY_MSG_532;(sel. Editieren - Dynamik u. Belichtung)\nSchwarzwert +HISTORY_MSG_533;(sel. Editieren - Dynamik u. Belichtung)\nSchattenkompression +HISTORY_MSG_534;(sel. Editieren - Farbtemperatur)\nTönung +HISTORY_MSG_535;(sel. Editieren - Dynamik u. Belichtung)\nIntensität +HISTORY_MSG_536;(sel. Editieren - Dynamik u. Belichtung)\nKontrastkurve +HISTORY_MSG_537;(sel. Editieren - Farbtemperatur) +HISTORY_MSG_538;(sel. Editieren - Farbtemperatur)\nGesättigte Töne +HISTORY_MSG_539;(sel. Editieren - Farbtemperatur)\nPastelltöne +HISTORY_MSG_540;(sel. Editieren - Farbtemperatur)\nSchwellenwert +HISTORY_MSG_541;(sel. Editieren - Farbtemperatur)\nHauttöne schützen +HISTORY_MSG_542;(sel. Editieren - Farbtemperatur)\nFarbverschiebung vermeiden +HISTORY_MSG_543;(sel. Editieren - Farbtemperatur)\nPastell- und gesättigte Farbtöne koppeln +HISTORY_MSG_544;(sel. Editieren - Farbtemperatur)\nBereich +HISTORY_MSG_545;(sel. Editieren - Farbtemperatur)\nH-Kurve +HISTORY_MSG_546;(sel. Editieren - Unschärfe)\nUnschärfe und Rauschen +HISTORY_MSG_547;(sel. Editieren - Unschärfe)\nRadius +HISTORY_MSG_548;(sel. Editieren - Unschärfe)\nRauschen +HISTORY_MSG_549;(sel. Editieren - Unschärfe)\nIntensität +HISTORY_MSG_550;(sel. Editieren - Unschärfe)\nMethode +HISTORY_MSG_551;(sel. Editieren - Unschärfe)\nNur Luminanz +HISTORY_MSG_552;(sel. Editieren - Tonwert) +HISTORY_MSG_553;(sel. Editieren - Tonwert)\nKompressionsintensität +HISTORY_MSG_554;(sel. Editieren - Tonwert)\nGamma +HISTORY_MSG_555;(sel. Editieren - Tonwert)\nKantenempfindlichkeit +HISTORY_MSG_556;(sel. Editieren - Tonwert)\nSkalieren +HISTORY_MSG_557;(sel. Editieren - Tonwert)\nGewichtung +HISTORY_MSG_558;(sel. Editieren - Tonwert)\nIntensität +HISTORY_MSG_559;(sel. Editieren - Retinex) +HISTORY_MSG_560;(sel. Editieren - Retinex)\nMethode +HISTORY_MSG_561;(sel. Editieren - Retinex)\nIntensität +HISTORY_MSG_562;(sel. Editieren - Retinex)\nChroma +HISTORY_MSG_563;(sel. Editieren - Retinex)\nRadius +HISTORY_MSG_564;(sel. Editieren - Retinex)\nKontrast +HISTORY_MSG_565;(sel. Editieren) - Umfang +HISTORY_MSG_566;(sel. Editieren - Retinex)\nVerstärkungskurve +HISTORY_MSG_567;(sel. Editieren - Retinex)\nInvertieren +HISTORY_MSG_568;(sel. Editieren - Schärfen) +HISTORY_MSG_569;(sel. Editieren - Schärfen)\nRadius +HISTORY_MSG_570;(sel. Editieren - Schärfen)\nIntensität +HISTORY_MSG_571;(sel. Editieren - Schärfen)\nDämpfung +HISTORY_MSG_572;(sel. Editieren - Schärfen)\nIterationen +HISTORY_MSG_573;(sel. Editieren - Schärfen)\nUmfang +HISTORY_MSG_574;(sel. Editieren - Schärfen)\nInvertieren +HISTORY_MSG_575;(sel. Editieren - Detailebenen) +HISTORY_MSG_576;(sel. Editieren - Detailebenen)\nMulti +HISTORY_MSG_577;(sel. Editieren - Detailebenen)\nChroma +HISTORY_MSG_578;(sel. Editieren - Detailebenen)\nSchwelle +HISTORY_MSG_579;(sel. Editieren - Detailebenen)\nUmfang HISTORY_MSG_580;--nicht verwendet-- -HISTORY_MSG_581;(Lokal - Rauschminderung)\nLuminanz f 1 -HISTORY_MSG_582;(Lokal - Rauschminderung)\nLuminanz c -HISTORY_MSG_583;(Lokal - Rauschminderung)\nLuminanz Detailwiederherstellung -HISTORY_MSG_584;(Lokal - Rauschminderung)\nEqualizer Weiß -Schwarz -HISTORY_MSG_585;(Lokal - Rauschminderung)\nFeine Chrominanz -HISTORY_MSG_586;(Lokal - Rauschminderung)\nGrobe Chrominanz -HISTORY_MSG_587;(Lokal - Rauschminderung)\nFarbintensität Detailwiederherstellung -HISTORY_MSG_588;(Lokal - Rauschminderung)\nEqualizer Blau/Rot -HISTORY_MSG_589;(Lokal - Rauschminderung)\nImpulsrauschen -HISTORY_MSG_590;(Lokal - Rauschminderung)\nIntensität -HISTORY_MSG_591;(Lokal - Spot)\nSpeziell\nFarbverschiebungen vermeiden -HISTORY_MSG_592;(Lokal - Schärfen)\nKontrastschwelle -HISTORY_MSG_593;(Lokal - Lokaler Kontrast) -HISTORY_MSG_594;(Lokal - Lokaler Kontrast)\nRadius -HISTORY_MSG_595;(Lokal - Lokaler Kontrast)\nIntensität -HISTORY_MSG_596;(Lokal - Lokaler Kontrast)\nDunkel -HISTORY_MSG_597;(Lokal - Lokaler Kontrast)\nHell -HISTORY_MSG_598;(Lokal - Lokaler Kontrast)\nUmfang -HISTORY_MSG_599;(Lokal - Dunst entfernen)\nIntensität -HISTORY_MSG_600;(Lokal - weiches Licht)\nAktiviert -HISTORY_MSG_601;(Lokal - weiches Licht)\nIntensität -HISTORY_MSG_602;(Lokal - weiches Licht)\nBereich -HISTORY_MSG_603;(Lokal - Schärfen)\nUnschärferadius -HISTORY_MSG_605;(Lokal) - Auswahl Maskenvorschau +HISTORY_MSG_581;(sel. Editieren - Rauschminderung)\nLuminanz f 1 +HISTORY_MSG_582;(sel. Editieren - Rauschminderung)\nLuminanz c +HISTORY_MSG_583;(sel. Editieren - Rauschminderung)\nLuminanz Detailwiederherstellung +HISTORY_MSG_584;(sel. Editieren - Rauschminderung)\nEqualizer Weiß -Schwarz +HISTORY_MSG_585;(sel. Editieren - Rauschminderung)\nFeine Chrominanz +HISTORY_MSG_586;(sel. Editieren - Rauschminderung)\nGrobe Chrominanz +HISTORY_MSG_587;(sel. Editieren - Rauschminderung)\nFarbintensität Detailwiederherstellung +HISTORY_MSG_588;(sel. Editieren - Rauschminderung)\nEqualizer Blau/Rot +HISTORY_MSG_589;(sel. Editieren - Rauschminderung)\nImpulsrauschen +HISTORY_MSG_590;(sel. Editieren - Rauschminderung)\nIntensität +HISTORY_MSG_591;(sel. Editieren - Spot)\nSpeziell\nFarbverschiebungen vermeiden +HISTORY_MSG_592;(sel. Editieren - Schärfen)\nKontrastschwelle +HISTORY_MSG_593;(sel. Editieren - Lokaler Kontrast) +HISTORY_MSG_594;(sel. Editieren - Lokaler Kontrast)\nRadius +HISTORY_MSG_595;(sel. Editieren - Lokaler Kontrast)\nIntensität +HISTORY_MSG_596;(sel. Editieren - Lokaler Kontrast)\nDunkel +HISTORY_MSG_597;(sel. Editieren - Lokaler Kontrast)\nHell +HISTORY_MSG_598;(sel. Editieren - Lokaler Kontrast)\nUmfang +HISTORY_MSG_599;(sel. Editieren - Dunst entfernen)\nIntensität +HISTORY_MSG_600;(sel. Editieren - weiches Licht)\nAktiviert +HISTORY_MSG_601;(sel. Editieren - weiches Licht)\nIntensität +HISTORY_MSG_602;(sel. Editieren - weiches Licht)\nBereich +HISTORY_MSG_603;(sel. Editieren - Schärfen)\nUnschärferadius +HISTORY_MSG_605;(sel. Editieren) - Auswahl Maskenvorschau HISTORY_MSG_606;Lokalen Spot ausgewählt -HISTORY_MSG_607;(Lokal - Farbe-Licht)\nMaske\nKurve C -HISTORY_MSG_608;(Lokal - Farbe-Licht)\nMaske\nKurve L -HISTORY_MSG_609;(Lokal - Dynamik u. Belichtung)\nMaske\nKurve C -HISTORY_MSG_610;(Lokal - Dynamik u. Belichtung)\nMaske\nKurve L -HISTORY_MSG_611;(Lokal - Farbe-Licht)\nMaske\nKurve LC(H) -HISTORY_MSG_612;(Lokal - Farbe-Licht)\nSpot-Struktur -HISTORY_MSG_613;(Lokal - Dynamik u. Belichtung)\nSpot-Struktur -HISTORY_MSG_614;(Lokal - Dynamik u. Belichtung)\nMaske\nKurve LC(H) -HISTORY_MSG_615;(Lokal - Farbe-Licht)\nMaske\nÜberlagerung -HISTORY_MSG_616;(Lokal - Dynamik u. Belichtung)\nMaske\nÜberlagerung -HISTORY_MSG_617;(Lokal - Dynamik u. Belichtung)\nUnschärfe Kantenerkennung -HISTORY_MSG_618;(Lokal - Farbe-Licht)\nMaske -HISTORY_MSG_619;(Lokal - Dynamik u. Belichtung)\nMaske -HISTORY_MSG_620;(Lokal - Farbe-Licht)\nUnschärfe Kantenerkennung -HISTORY_MSG_621;(Lokal - Dynamik u. Belichtung)\nInvertieren -HISTORY_MSG_622;(Lokal - Spot)\nAusschließende Spot-Struktur -HISTORY_MSG_623;(Lokal - Dynamik u. Belichtung)\nKompensation Farbsättigung -HISTORY_MSG_624;(Lokal - Farbe-Licht)\nFarbkorrektur -HISTORY_MSG_625;(Lokal - Farbe-Licht)\nIntensität Farbkorrektur -HISTORY_MSG_626;(Lokal - Farbe-Licht)\nMethode -HISTORY_MSG_627;(Lokal - Schatten/Lichter) -HISTORY_MSG_628;(Lokal - Schatten/Lichter)\nLichter -HISTORY_MSG_629;(Lokal - Schatten/Lichter)\nTonwertbreite Lichter -HISTORY_MSG_630;(Lokal - Schatten/Lichter)\nSchatten -HISTORY_MSG_631;(Lokal - Schatten/Lichter)\nTonwertbreite Schatten -HISTORY_MSG_632;(Lokal - Schatten/Lichter)\nRadius -HISTORY_MSG_633;(Lokal - Schatten/Lichter)\nUmfang -HISTORY_MSG_634;(Lokal - Farbe-Licht)\nMaske\nRadius -HISTORY_MSG_635;(Lokal - Dynamik u. Belichtung)\nMaske\nRadius -HISTORY_MSG_636;(Lokal)\nWerkzeug hinzugefügt -HISTORY_MSG_637;(Lokal - Schatten/Lichter)\nMaske\nKurve C -HISTORY_MSG_638;(Lokal - Schatten/Lichter)\nMaske\nKurve L -HISTORY_MSG_639;(Lokal - Schatten/Lichter)\nMaske\nKurve LC(H) -HISTORY_MSG_640;(Lokal - Schatten/Lichter)\nMaske\nÜberlagerung -HISTORY_MSG_641;(Lokal - Schatten/Lichter)\nMaske -HISTORY_MSG_642;(Lokal - Schatten/Lichter)\nMaske\nRadius -HISTORY_MSG_643;(Lokal - Schatten/Lichter)\nUnschärfe Kantenerkennung -HISTORY_MSG_644;(Lokal - Schatten/Lichter)\nInvertieren -HISTORY_MSG_645;(Lokal - Spot)\nKantenerkennung\nBalance ab-L -HISTORY_MSG_646;(Lokal - Dynamik u. Belichtung)\nMaske\nFarbintensität -HISTORY_MSG_647;(Lokal - Dynamik u. Belichtung)\nMaske\nGamma -HISTORY_MSG_648;(Lokal - Dynamik u. Belichtung)\nMaske\nSteigung -HISTORY_MSG_649;(Lokal - Dynamik u. Belichtung)\nVerlaufsfilter\nRadius -HISTORY_MSG_650;(Lokal - Farbe-Licht)\nMaske\nFarbintensität -HISTORY_MSG_651;(Lokal - Farbe-Licht)\nMaske\nGamma -HISTORY_MSG_652;(Lokal - Farbe-Licht)\nMaske\nSteigung -HISTORY_MSG_653;(Lokal - Schatten/Lichter)\nMaske\nFarbintensität -HISTORY_MSG_654;(Lokal - Schatten/Lichter)\nMaske\nGamma -HISTORY_MSG_655;(Lokal - Schatten/Lichter)\nMaske\nSteigung -HISTORY_MSG_656;(Lokal - Farbe-Licht)\nRadius -HISTORY_MSG_657;(Lokal - Retinex)\nArtefakte reduzieren -HISTORY_MSG_658;(Lokal - Detailebenen)\nRadius -HISTORY_MSG_659;(Lokal - Spot)\nÜbergangsgradient\nÜbergangszerfall -HISTORY_MSG_660;(Lokal - Detailebenen)\nKlarheit -HISTORY_MSG_661;(Lokal - Detailebenen)\nVerbleibend -HISTORY_MSG_662;(Lokal - Rauschminderung)\nLuminanz f 0 -HISTORY_MSG_663;(Lokal - Rauschminderung)\nLuminanz f 2 +HISTORY_MSG_607;(sel. Editieren - Farbe-Licht)\nMaske\nKurve C +HISTORY_MSG_608;(sel. Editieren - Farbe-Licht)\nMaske\nKurve L +HISTORY_MSG_609;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nKurve C +HISTORY_MSG_610;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nKurve L +HISTORY_MSG_611;(sel. Editieren - Farbe-Licht)\nMaske\nKurve LC(H) +HISTORY_MSG_612;(sel. Editieren - Farbe-Licht)\nSpot-Struktur +HISTORY_MSG_613;(sel. Editieren - Dynamik u. Belichtung)\nSpot-Struktur +HISTORY_MSG_614;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nKurve LC(H) +HISTORY_MSG_615;(sel. Editieren - Farbe-Licht)\nMaske\nÜberlagerung +HISTORY_MSG_616;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nÜberlagerung +HISTORY_MSG_617;(sel. Editieren - Dynamik u. Belichtung)\nUnschärfe Kantenerkennung +HISTORY_MSG_618;(sel. Editieren - Farbe-Licht)\nMaske +HISTORY_MSG_619;(sel. Editieren - Dynamik u. Belichtung)\nMaske +HISTORY_MSG_620;(sel. Editieren - Farbe-Licht)\nUnschärfe Kantenerkennung +HISTORY_MSG_621;(sel. Editieren - Dynamik u. Belichtung)\nInvertieren +HISTORY_MSG_622;(sel. Editieren - Spot)\nAusschließende Spot-Struktur +HISTORY_MSG_623;(sel. Editieren - Dynamik u. Belichtung)\nKompensation Farbsättigung +HISTORY_MSG_624;(sel. Editieren - Farbe-Licht)\nFarbkorrektur +HISTORY_MSG_625;(sel. Editieren - Farbe-Licht)\nIntensität Farbkorrektur +HISTORY_MSG_626;(sel. Editieren - Farbe-Licht)\nMethode +HISTORY_MSG_627;(sel. Editieren - Schatten/Lichter) +HISTORY_MSG_628;(sel. Editieren - Schatten/Lichter)\nLichter +HISTORY_MSG_629;(sel. Editieren - Schatten/Lichter)\nTonwertbreite Lichter +HISTORY_MSG_630;(sel. Editieren - Schatten/Lichter)\nSchatten +HISTORY_MSG_631;(sel. Editieren - Schatten/Lichter)\nTonwertbreite Schatten +HISTORY_MSG_632;(sel. Editieren - Schatten/Lichter)\nRadius +HISTORY_MSG_633;(sel. Editieren - Schatten/Lichter)\nUmfang +HISTORY_MSG_634;(sel. Editieren - Farbe-Licht)\nMaske\nRadius +HISTORY_MSG_635;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nRadius +HISTORY_MSG_636;(sel. Editieren)\nWerkzeug hinzugefügt +HISTORY_MSG_637;(sel. Editieren - Schatten/Lichter)\nMaske\nKurve C +HISTORY_MSG_638;(sel. Editieren - Schatten/Lichter)\nMaske\nKurve L +HISTORY_MSG_639;(sel. Editieren - Schatten/Lichter)\nMaske\nKurve LC(H) +HISTORY_MSG_640;(sel. Editieren - Schatten/Lichter)\nMaske\nÜberlagerung +HISTORY_MSG_641;(sel. Editieren - Schatten/Lichter)\nMaske +HISTORY_MSG_642;(sel. Editieren - Schatten/Lichter)\nMaske\nRadius +HISTORY_MSG_643;(sel. Editieren - Schatten/Lichter)\nUnschärfe Kantenerkennung +HISTORY_MSG_644;(sel. Editieren - Schatten/Lichter)\nInvertieren +HISTORY_MSG_645;(sel. Editieren - Spot)\nKantenerkennung\nBalance ab-L +HISTORY_MSG_646;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nFarbintensität +HISTORY_MSG_647;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nGamma +HISTORY_MSG_648;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nSteigung +HISTORY_MSG_649;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nRadius +HISTORY_MSG_650;(sel. Editieren - Farbe-Licht)\nMaske\nFarbintensität +HISTORY_MSG_651;(sel. Editieren - Farbe-Licht)\nMaske\nGamma +HISTORY_MSG_652;(sel. Editieren - Farbe-Licht)\nMaske\nSteigung +HISTORY_MSG_653;(sel. Editieren - Schatten/Lichter)\nMaske\nFarbintensität +HISTORY_MSG_654;(sel. Editieren - Schatten/Lichter)\nMaske\nGamma +HISTORY_MSG_655;(sel. Editieren - Schatten/Lichter)\nMaske\nSteigung +HISTORY_MSG_656;(sel. Editieren - Farbe-Licht)\nRadius +HISTORY_MSG_657;(sel. Editieren - Retinex)\nArtefakte reduzieren +HISTORY_MSG_658;(sel. Editieren - Detailebenen)\nRadius +HISTORY_MSG_659;(sel. Editieren - Spot)\nÜbergangsgradient\nÜbergangszerfall +HISTORY_MSG_660;(sel. Editieren - Detailebenen)\nKlarheit +HISTORY_MSG_661;(sel. Editieren - Detailebenen)\nVerbleibend +HISTORY_MSG_662;(sel. Editieren - Rauschminderung)\nLuminanz f 0 +HISTORY_MSG_663;(sel. Editieren - Rauschminderung)\nLuminanz f 2 HISTORY_MSG_664;--nicht verwendet-- -HISTORY_MSG_665;(Lokal - Detailebenen)\nMaske\nÜberlagerung -HISTORY_MSG_666;(Lokal - Detailebenen)\nMaske\nRadius -HISTORY_MSG_667;(Lokal - Detailebenen)\nMaske\nFarbintensität -HISTORY_MSG_668;(Lokal - Detailebenen)\nMaske\nGamma -HISTORY_MSG_669;(Lokal - Detailebenen)\nMaske\nSteigung -HISTORY_MSG_670;(Lokal - Detailebenen)\nMaske C -HISTORY_MSG_671;(Lokal - Detailebenen)\nMaske L -HISTORY_MSG_672;(Lokal - Detailebenen)\nMaske CL -HISTORY_MSG_673;(Lokal - Detailebenen)\nMaske anwenden -HISTORY_MSG_674;(Lokal)\nWerkzeug entfernt -HISTORY_MSG_675;(Lokal - Tonwert)\nRadius -HISTORY_MSG_676;(Lokal - Spot)\nÜbergangsgradient\nUnterschied -HISTORY_MSG_677;(Lokal - Tonwert)\nIntensität -HISTORY_MSG_678;(Lokal - Tonwert)\nSättigung -HISTORY_MSG_679;(Lokal - Retinex)\nMaske C -HISTORY_MSG_680;(Lokal - Retinex)\nMaske L -HISTORY_MSG_681;(Lokal - Retinex)\nMaske CL -HISTORY_MSG_682;(Lokal - Retinex) Maske -HISTORY_MSG_683;(Lokal - Retinex)\nMaske\nÜberlagerung -HISTORY_MSG_684;(Lokal - Retinex)\nMaske\nRadius -HISTORY_MSG_685;(Lokal - Retinex)\nMaske\nFarbintensität -HISTORY_MSG_686;(Lokal - Retinex)\nMaske\nGamma -HISTORY_MSG_687;(Lokal - Retinex)\nMaske\nSteigung -HISTORY_MSG_688;(Lokal)\nWerkzeug entfernt -HISTORY_MSG_689;(Lokal - Retinex) Maske\nÜbertragungszuordnung -HISTORY_MSG_690;(Lokal - Retinex)\nSkalieren -HISTORY_MSG_691;(Lokal - Retinex)\nDunkel -HISTORY_MSG_692;(Lokal - Retinex)\nHell -HISTORY_MSG_693;(Lokal - Retinex)\nSchwelle -HISTORY_MSG_694;(Lokal - Retinex)\nSchwelle Laplace -HISTORY_MSG_695;(Lokal - weiches Licht)\nMethode -HISTORY_MSG_696;(Lokal - Retinex)\nLuminanz normalisieren -HISTORY_MSG_697;(Lokal - Tonwert)\nLuminanz normalisieren -HISTORY_MSG_698;(Lokal - Lokaler Kontrast)\nSchnelle Fouriertransformation -HISTORY_MSG_699;(Lokal - Retinex)\nSchnelle Fouriertransformation -HISTORY_MSG_701;(Lokal - Dynamik u. Belichtung)\nSchatten -HISTORY_MSG_702;(Lokal - Dynamik u. Belichtung)\nMethode -HISTORY_MSG_703;(Lokal - Dynamik u. Belichtung)\nSchwellenwert Laplace -HISTORY_MSG_704;(Lokal - Dynamik u. Belichtung)\nLaplace Balance -HISTORY_MSG_705;(Lokal - Dynamik u. Belichtung)\nLinearität -HISTORY_MSG_706;(Lokal - Tonwert)\nMaske\nKurve C -HISTORY_MSG_707;(Lokal - Tonwert)\nMaske\nKurve L -HISTORY_MSG_708;(Lokal - Tonwert)\nMaske\nKurve LC(h) -HISTORY_MSG_709;(Lokal - Tonwert)\nMaske -HISTORY_MSG_710;(Lokal - Tonwert)\nMaske überlagern -HISTORY_MSG_711;(Lokal - Tonwert)\nMaske Radius -HISTORY_MSG_712;(Lokal - Tonwert)\nMaske Farbintensität -HISTORY_MSG_713;(Lokal - Tonwert)\nMaske Gamma -HISTORY_MSG_714;(Lokal - Tonwert)\nMaske Steigung -HISTORY_MSG_716;(Lokal) - lokale Methode -HISTORY_MSG_717;(Lokal - Wavelet)\nKontrastkurve -HISTORY_MSG_718;(Lokal) - lokale Kontrastebenen -HISTORY_MSG_719;(Lokal - Wavelet)\nVerbleibende L -HISTORY_MSG_720;(Lokal - Unschärfe)\nLuminanzmaske\nKurve C -HISTORY_MSG_721;(Lokal - Unschärfe)\nLuminanzmaske\nKurve L -HISTORY_MSG_722;(Lokal - Unschärfe)\nLuminanzmaske\nKurve LC(h) -HISTORY_MSG_723;(Lokal - Unschärfe)\nMaske -HISTORY_MSG_725;(Lokal - Unschärfe)\nMaske\nÜberlagerung -HISTORY_MSG_726;(Lokal - Unschärfe)\nMaske\nRadius -HISTORY_MSG_727;(Lokal - Unschärfe)\nMaske\nFarbintensität -HISTORY_MSG_728;(Lokal - Unschärfe)\nMaske\nGamma -HISTORY_MSG_729;(Lokal - Unschärfe)\nMaske\nSteigung -HISTORY_MSG_730;(Lokal - Unschärfe)\nMethode -HISTORY_MSG_731;(Lokal - Unschärfe)\nMethode Median\nMedianwert -HISTORY_MSG_732;(Lokal - Unschärfe)\nMethode Median\nIterationen -HISTORY_MSG_733;(Lokal - Unschärfe)\nAnpassbarer Filter\nRadius -HISTORY_MSG_734;(Lokal - Unschärfe)\nAnpassbarer Filter\nDetail -HISTORY_MSG_738;(Lokal - Wavelet)\nRestbild\nLuma zusammenführen -HISTORY_MSG_739;(Lokal - Wavelet)\nRestbild\nRadius -HISTORY_MSG_740;(Lokal - Wavelet)\nRestbild\nChroma zusammenführen -HISTORY_MSG_741;(Lokal - Wavelet)\nVerbleibende C -HISTORY_MSG_742;(Lokal - Dynamik u. Belichtung)\nKontrastdämpfung\nGamma -HISTORY_MSG_743;(Lokal - Dynamik u. Belichtung)\nDynamikkompression\nIntensität -HISTORY_MSG_744;(Lokal - Dynamik u. Belichtung)\nDynamikkompression\nDetail -HISTORY_MSG_745;(Lokal - Dynamik u. Belichtung)\nDynamikkompression\nVersatz -HISTORY_MSG_746;(Lokal - Dynamik u. Belichtung)\nDynamikkompression\nSigma -HISTORY_MSG_747;(Lokal - Einstellungen)\nSpot erstellt -HISTORY_MSG_748;(Lokal - Dynamik u. Belichtung)\nMethode Rauschreduzierung -HISTORY_MSG_749;(Lokal - Dunst entfernen)\nTiefe -HISTORY_MSG_750;(Lokal - Retinex)\nModus logarithmisch -HISTORY_MSG_751;(Lokal - Dunst entfernen)\nSättigung -HISTORY_MSG_752;(Lokal - Retinex)\nVersatz -HISTORY_MSG_753;(Lokal - Retinex)\nÜbertragungszuordnung -HISTORY_MSG_754;(Lokal - Retinex)\nBeschneiden -HISTORY_MSG_755;(Lokal - Tonwert)\nTonwertkorrektur maskieren -HISTORY_MSG_756;(Lokal - Dynamik u. Belichtung)\nVerwende Algo-Belichtungsmaske -HISTORY_MSG_757;(Lokal - Dynamik u. Belichtung)\nMaske\nSchwelle Laplace -HISTORY_MSG_758;(Lokal - Retinex)\nMaske\nSchwelle Laplace -HISTORY_MSG_759;(Lokal - Dynamik u. Belichtung)\nMaske\nSchwelle Laplace -HISTORY_MSG_760;(Lokal - Farbe-Licht)\nMaske\nSchwelle Laplace -HISTORY_MSG_761;(Lokal - Schatten/Lichter)\nMaske\nSchwelle Laplace -HISTORY_MSG_762;(Lokal - Kontrastebenen)\nMaske\nSchwelle Laplace -HISTORY_MSG_763;(Lokal - Unschärfe)\nMaske\nSchwelle Laplace -HISTORY_MSG_764;(Lokal) - Auflösung PDE Laplace-Maske -HISTORY_MSG_765;(Lokal - Rauschminderung)\nLuminanzmaske\nSchwellenwert -HISTORY_MSG_766;(Lokal - Unschärfe)\nSchnelle Fouriertransformation -HISTORY_MSG_767;(Lokal - Unschärfe)\nISO Körnung Verteilung -HISTORY_MSG_768;(Lokal - Unschärfe)\nISO Körnung Intensität -HISTORY_MSG_769;(Lokal - Unschärfe)\nISO Korngröße -HISTORY_MSG_770;(Lokal - Farbe-Licht)\nMaske\nKontrastkurve -HISTORY_MSG_771;(Lokal - Dynamik u. Belichtung)\nMaske\nKontrastkurve -HISTORY_MSG_772;(Lokal - Schärfen)\nMaske\nKontrastkurve -HISTORY_MSG_773;(Lokal - Tonwert)\nMaske\nKontrastkurve -HISTORY_MSG_774;(Lokal - Retinex)\nMaske\nKontrastkurve -HISTORY_MSG_775;(Lokal - Detailebenen)\nMaske\nKontrastkurve -HISTORY_MSG_776;(Lokal - Unschärfe)\nMaske\nKontrastkurve -HISTORY_MSG_777;(Lokal - Unschärfe)\nMaske\nWavelet\nKontrastkurve -HISTORY_MSG_778;(Lokal - Unschärfe)\nMaske\nLichter -HISTORY_MSG_779;(Lokal - Farbe-Licht)\nMaske\nLokale Kontrastkurve -HISTORY_MSG_780;(Lokal - Farbe-Licht)\nMaske\nSchatten -HISTORY_MSG_781;(Lokal - Wavelet)\nWavelet Ebenen -HISTORY_MSG_782;(Lokal - Unschärfe)\nMaske\nWavelet Ebenen -HISTORY_MSG_783;(Lokal - Farbe-Licht)\nWavelet Ebenenauswahl -HISTORY_MSG_784;(Lokal - Spot)\nMaskieren\nΔE Bildmaske -HISTORY_MSG_785;(Lokal - Spot)\nMaskieren\nBereich Bildmaske -HISTORY_MSG_786;(Lokal - Schatten/Lichter)\nMethode -HISTORY_MSG_787;(Lokal - Schatten/Lichter)\nTonwert-Equalizer\nWerte -HISTORY_MSG_788;(Lokal - Schatten/Lichter)\nTonwert-Equalizer\nDetails -HISTORY_MSG_789;(Lokal - Schatten/Lichter)\nMaske\nIntensität -HISTORY_MSG_790;(Lokal - Schatten/Lichter)\nMaske Ankerpunkt -HISTORY_MSG_791;(Lokal - Maske)\nShort L-Kurve -HISTORY_MSG_792;(Lokal - Spot)\nMaskieren\nHintergrund Maske -HISTORY_MSG_793;(Lokal - Schatten/Lichter)\nGamma Farbtonkennlinie -HISTORY_MSG_794;(Lokal - Schatten/Lichter)\nSteigung Farbtonkennlinie -HISTORY_MSG_795;(Lokal - Maske)\nSichern wiederhergestelltes Bild -HISTORY_MSG_796;(Lokal - Spot)\nSpeziell\nReferenzen rekursiv -HISTORY_MSG_797;(Lokal - Farbe-Licht)\nZusammenführen\nMethode -HISTORY_MSG_798;(Lokal - Farbe-Licht)\nZusammenführen\nDeckkraft -HISTORY_MSG_799;(Lokal - Farbe-Licht)\nRGB-Kurve -HISTORY_MSG_800;(Lokal - Farbe-Licht)\nMethode RGB-Kurven -HISTORY_MSG_801;(Lokal - Farbe-Licht)\nSpezielle Verwendung RGB-Kurven -HISTORY_MSG_802;(Lokal - Farbe-Licht)\nZusammenführen\nSchwellenwert Kontrast -HISTORY_MSG_803;(Lokal - Farbe-Licht)\nZusammenführen -HISTORY_MSG_804;(Lokal - Farbe-Licht)\nIntensität Strukturmaske -HISTORY_MSG_805;(Lokal - Unschärfe)\nIntensität Strukturmaske -HISTORY_MSG_806;(Lokal - Farbe-Licht)\nStrukturmaske als Werkzeug -HISTORY_MSG_807;(Lokal - Unschärfe)\nStrukturmaske als Werkzeug -HISTORY_MSG_808;(Lokal - Farbe-Licht)\nMaske\nKurve H(H) -HISTORY_MSG_809;(Lokal - Farbtemperatur)\nMaske\nKurve C -HISTORY_MSG_810;(Lokal - Farbtemperatur)\nMaske\nKurve L -HISTORY_MSG_811;(Lokal - Farbtemperatur)\nMaske\nKurve LC(h) -HISTORY_MSG_813;(Lokal - Farbtemperatur)\nMaske -HISTORY_MSG_814;(Lokal - Farbtemperatur)\nMaske\nÜberlagerung -HISTORY_MSG_815;(Lokal - Farbtemperatur)\nMaske\nRadius -HISTORY_MSG_816;(Lokal - Farbtemperatur)\nMaske\nFarbintensität -HISTORY_MSG_817;(Lokal - Farbtemperatur)\nMaske\nGamma -HISTORY_MSG_818;(Lokal - Farbtemperatur)\nMaske\nSteigung -HISTORY_MSG_819;(Lokal - Farbtemperatur)\nMaske\nSchwellenwert Laplace -HISTORY_MSG_820;(Lokal - Farbtemperatur)\nMaske\nKontrastkurve -HISTORY_MSG_821;(Lokal - Farbe-Licht)\nHintergrundgitter -HISTORY_MSG_822;(Lokal - Farbe-Licht)\nHintergrund zusammenführen -HISTORY_MSG_823;(Lokal - Farbe-Licht)\nLuminanz Hintergrund -HISTORY_MSG_824;(Lokal - Dynamik u. Belichtung)\nVerlaufsfilter\nVerlaufsintensität -HISTORY_MSG_825;(Lokal - Dynamik u. Belichtung)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_826;(Lokal - Dynamik u. Belichtung)\nVerlaufsfilter\nIntensität -HISTORY_MSG_827;(Lokal - Dynamik u. Belichtung)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_828;(Lokal - Schatten/Lichter)\nVerlaufsfilter\nVerlaufsintensität -HISTORY_MSG_829;(Lokal - Schatten/Lichter)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_830;(Lokal - Farbe-Licht)\nVerlaufsfilter\nIntensität Luminanz -HISTORY_MSG_831;(Lokal - Farbe-Licht)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_832;(Lokal - Farbe-Licht)\nVerlaufsfilter\nIntensität Chrominanz -HISTORY_MSG_833;(Lokal - Spot)\nÜbergangsgradient\nVerlaufsbreite -HISTORY_MSG_834;(Lokal - Farbe-Licht)\nVerlaufsfilter\nIntensität Farbton -HISTORY_MSG_835;(Lokal - Farbtemperatur)\nVerlaufsfilter\nIntensität Luminanz -HISTORY_MSG_836;(Lokal - Farbtemperatur)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_837;(Lokal - Farbtemperatur)\nVerlaufsfilter\nIntensität Chrominanz -HISTORY_MSG_838;(Lokal - Farbtemperatur)\nVerlaufsfilter\nIntensität Farbton -HISTORY_MSG_839;(Lokal) - Softwarekomplexität -HISTORY_MSG_840;(Lokal - Farbe-Licht)\nCL-Kurve -HISTORY_MSG_841;(Lokal - Farbe-Licht)\nLC-Kurve -HISTORY_MSG_842;(Lokal - Farbe-Licht)\nUnschärfemaske\nRadius -HISTORY_MSG_843;(Lokal - Farbe-Licht)\nUnschärfemaske\nSchwellenwert Kontrast -HISTORY_MSG_844;(Lokal - Farbe-Licht)\nUnschärfemaske\nSchnelle Fouriertransformation -HISTORY_MSG_845;(Lokal - LOG-Kodierung) -HISTORY_MSG_846;(Lokal - LOG-Kodierung)\nAutomatisch -HISTORY_MSG_847;(Lokal - LOG-Kodierung)\nQuelle -HISTORY_MSG_849;(Lokal - LOG-Kodierung)\nQuelle Automatisch -HISTORY_MSG_850;(Lokal - LOG-Kodierung)\nSchwarz-Ev -HISTORY_MSG_851;(Lokal - LOG-Kodierung)\nWeiß-Ev -HISTORY_MSG_852;(Lokal - LOG-Kodierung)\nZiel -HISTORY_MSG_853;(Lokal - LOG-Kodierung)\nLokaler Kontrast -HISTORY_MSG_854;(Lokal - LOG-Kodierung)\nBereich -HISTORY_MSG_855;(Lokal - LOG-Kodierung)\nGesamtes Bild -HISTORY_MSG_856;(Lokal - LOG-Kodierung)\nBereich Schatten -HISTORY_MSG_857;(Lokal - Wavelet)\nUnschärfeebenen\nVerbleibende Unschärfe -HISTORY_MSG_858;(Lokal - Wavelet)\nUnschärfeebenen\nNur Luminanz -HISTORY_MSG_859;(Lokal - Wavelet)\nUnschärfeebenen\nMaximum -HISTORY_MSG_860;(Lokal - Wavelet)\nUnschärfeebenen -HISTORY_MSG_861;(Lokal - Wavelet)\nKontrastebenen -HISTORY_MSG_862;(Lokal - Wavelet)\nKontrastebenen\nDämpfungsreaktion -HISTORY_MSG_863;(Lokal - Wavelet)\nOriginal zusammenführen -HISTORY_MSG_864;(Lokal - Wavelet)\nDirektionaler Kontrast\nDämpfungsreaktion -HISTORY_MSG_865;(Lokal - Wavelet)\nDirektionaler Kontrast\nEbenenbalance -HISTORY_MSG_866;(Lokal - Wavelet)\nDirektionaler Kontrast\nKompression -HISTORY_MSG_868;(Lokal - Spot)\nKantenerkennung\nC-H Balance -HISTORY_MSG_869;(Lokal - Rauschminderung)\nLuminanzkurve -HISTORY_MSG_870;(Lokal - Lokaler Kontrast)\nMaske\nKurve H -HISTORY_MSG_871;(Lokal - Lokaler Kontrast)\nMaske\nKurve C -HISTORY_MSG_872;(Lokal - Lokaler Kontrast)\nMaske\nKurve L -HISTORY_MSG_873;(Lokal - Lokaler Kontrast)\nMaske -HISTORY_MSG_875;(Lokal - Lokaler Kontrast)\nMaske überlagern -HISTORY_MSG_876;(Lokal - Lokaler Kontrast)\nMaske glätten -HISTORY_MSG_877;(Lokal - Lokaler Kontrast)\nMaske Farbintensität -HISTORY_MSG_878;(Lokal - Lokaler Kontrast)\nMaske Kontrastkurve -HISTORY_MSG_879;(Lokal - Wavelet)\nKontrastebene\nFarbintensität -HISTORY_MSG_880;(Lokal - Wavelet)\nUnschärfeebenen\nChrominanz Ebenen -HISTORY_MSG_881;(Lokal - Wavelet)\nKontrastebene\nVersatz -HISTORY_MSG_882;(Lokal - Wavelet)\nUnschärfeebenen -HISTORY_MSG_883;(Lokal - Wavelet)\nKontrast nach Ebenen -HISTORY_MSG_884;(Lokal - Wavelet)\nDirektionaler Kontrast -HISTORY_MSG_885;(Lokal - Wavelet)\nTonwertkorrektur -HISTORY_MSG_886;(Lokal - Wavelet)\nTonwertkorrektur Kompression -HISTORY_MSG_887;(Lokal - Wavelet)\nTonwertkorrektur\nKompression Restbild -HISTORY_MSG_888;(Lokal - Wavelet)\nTonwertkorrektur\nSchwellenwert Balance -HISTORY_MSG_889;(Lokal - Wavelet)\nVerlaufsfilter\nIntensität -HISTORY_MSG_890;(Lokal - Wavelet)\nVerlaufsfilter\nRotationswinkel -HISTORY_MSG_891;(Lokal - Wavelet)\nVerlaufsfilter -HISTORY_MSG_892;(Lokal - LOG-Kodierung)\nVerlaufsintensität -HISTORY_MSG_893;(Lokal - LOG-Kodierung)\nVerlaufswinkel -HISTORY_MSG_894;(Lokal - Spot)\nKantenerkennung\nVorschau Farbe Intensität (ΔE) -HISTORY_MSG_897;(Lokal - Wavelet)\nKantenschärfe\nIntensität -HISTORY_MSG_898;(Lokal - Wavelet)\nKantenschärfe\nRadius -HISTORY_MSG_899;(Lokal - Wavelet(\nKantenschärfe\nDetails -HISTORY_MSG_900;(Lokal - Wavelet)\nKantenschärfe\nVerlaufsempfindlichkeit -HISTORY_MSG_901;(Lokal - Wavelet)\nKantenschärfe\nUnterer Schwellenwert -HISTORY_MSG_902;(Lokal - Wavelet)\nKantenschärfe\nOberer Schwellenwert -HISTORY_MSG_903;(Lokal - Wavelet)\nKantenschärfe\nKontrastkurve -HISTORY_MSG_904;(Lokal - Wavelet)\nKantenschärfe\nErste Ebene -HISTORY_MSG_905;(Lokal - Wavelet)\nKantenschärfe -HISTORY_MSG_906;(Lokal - Wavelet)\nKantenschärfe\nKantenempfindlichkeit -HISTORY_MSG_907;(Lokal - Wavelet)\nKantenschärfe\nGrundverstärkung -HISTORY_MSG_908;(Lokal - Wavelet)\nKantenschärfe\nBenachbarte Pixel -HISTORY_MSG_909;(Lokal - Wavelet\nKantenschärfe\nAlle Werkzeuge anzeigen -HISTORY_MSG_910;(Lokal - Wavelet)\nKantenperformance -HISTORY_MSG_911;(Lokal - Unschärfe)\nChrominanz Luminanz -HISTORY_MSG_912;(Lokal - Unschärfe)\nAnpassbarer Filter Intensität -HISTORY_MSG_913;(Lokal - Wavelet)\nTonwertkorrektur\nDämpfungsreaktion -HISTORY_MSG_914;(Lokal - Wavelet)\nUnschärfeebenen\nDämpfungsreaktion -HISTORY_MSG_915;(Lokal - Wavelet)\nKantenschärfe\nDämpfungsreaktion -HISTORY_MSG_916;(Lokal - Wavelet)\nRestbild Schatten -HISTORY_MSG_917;(Lokal - Wavelet)\nRestbild\nSchwellenwert Schatten -HISTORY_MSG_918;(Lokal - Wavelet)\nRestbild Lichter -HISTORY_MSG_919;(Lokal - Wavelet)\nRestbild\nSchwellenwert Lichter -HISTORY_MSG_920;(Lokal - Wavelet)\nKontrast\nDämpfungsreaktion -HISTORY_MSG_921;(Lokal - Wavelet)\nVerlaufsfilter\nDämpfungsreaktion -HISTORY_MSG_922;(Lokal - Spot)\nSpeziell\nÄnderungen in Schwarz-Weiß erzwingen -HISTORY_MSG_923;(Lokal - Werkzeug)\nKomplexität +HISTORY_MSG_665;(sel. Editieren - Detailebenen)\nMaske\nÜberlagerung +HISTORY_MSG_666;(sel. Editieren - Detailebenen)\nMaske\nRadius +HISTORY_MSG_667;(sel. Editieren - Detailebenen)\nMaske\nFarbintensität +HISTORY_MSG_668;(sel. Editieren - Detailebenen)\nMaske\nGamma +HISTORY_MSG_669;(sel. Editieren - Detailebenen)\nMaske\nSteigung +HISTORY_MSG_670;(sel. Editieren - Detailebenen)\nMaske C +HISTORY_MSG_671;(sel. Editieren - Detailebenen)\nMaske L +HISTORY_MSG_672;(sel. Editieren - Detailebenen)\nMaske CL +HISTORY_MSG_673;(sel. Editieren - Detailebenen)\nMaske anwenden +HISTORY_MSG_674;(sel. Editieren)\nWerkzeug entfernt +HISTORY_MSG_675;(sel. Editieren - Tonwert)\nRadius +HISTORY_MSG_676;(sel. Editieren - Spot)\nÜbergangsgradient\nUnterschied +HISTORY_MSG_677;(sel. Editieren - Tonwert)\nIntensität +HISTORY_MSG_678;(sel. Editieren - Tonwert)\nSättigung +HISTORY_MSG_679;(sel. Editieren - Retinex)\nMaske C +HISTORY_MSG_680;(sel. Editieren - Retinex)\nMaske L +HISTORY_MSG_681;(sel. Editieren - Retinex)\nMaske CL +HISTORY_MSG_682;(sel. Editieren - Retinex) Maske +HISTORY_MSG_683;(sel. Editieren - Retinex)\nMaske\nÜberlagerung +HISTORY_MSG_684;(sel. Editieren - Retinex)\nMaske\nRadius +HISTORY_MSG_685;(sel. Editieren - Retinex)\nMaske\nFarbintensität +HISTORY_MSG_686;(sel. Editieren - Retinex)\nMaske\nGamma +HISTORY_MSG_687;(sel. Editieren - Retinex)\nMaske\nSteigung +HISTORY_MSG_688;(sel. Editieren)\nWerkzeug entfernt +HISTORY_MSG_689;(sel. Editieren - Retinex) Maske\nÜbertragungszuordnung +HISTORY_MSG_690;(sel. Editieren - Retinex)\nSkalieren +HISTORY_MSG_691;(sel. Editieren - Retinex)\nDunkel +HISTORY_MSG_692;(sel. Editieren - Retinex)\nHell +HISTORY_MSG_693;(sel. Editieren - Retinex)\nSchwelle +HISTORY_MSG_694;(sel. Editieren - Retinex)\nSchwelle Laplace +HISTORY_MSG_695;(sel. Editieren - weiches Licht)\nMethode +HISTORY_MSG_696;(sel. Editieren - Retinex)\nLuminanz normalisieren +HISTORY_MSG_697;(sel. Editieren - Tonwert)\nLuminanz normalisieren +HISTORY_MSG_698;(sel. Editieren - Lokaler Kontrast)\nSchnelle Fouriertransformation +HISTORY_MSG_699;(sel. Editieren - Retinex)\nSchnelle Fouriertransformation +HISTORY_MSG_701;(sel. Editieren - Dynamik u. Belichtung)\nSchatten +HISTORY_MSG_702;(sel. Editieren - Dynamik u. Belichtung)\nMethode +HISTORY_MSG_703;(sel. Editieren - Dynamik u. Belichtung)\nSchwellenwert Laplace +HISTORY_MSG_704;(sel. Editieren - Dynamik u. Belichtung)\nLaplace Balance +HISTORY_MSG_705;(sel. Editieren - Dynamik u. Belichtung)\nLinearität +HISTORY_MSG_706;(sel. Editieren - Tonwert)\nMaske\nKurve C +HISTORY_MSG_707;(sel. Editieren - Tonwert)\nMaske\nKurve L +HISTORY_MSG_708;(sel. Editieren - Tonwert)\nMaske\nKurve LC(h) +HISTORY_MSG_709;(sel. Editieren - Tonwert)\nMaske +HISTORY_MSG_710;(sel. Editieren - Tonwert)\nMaske überlagern +HISTORY_MSG_711;(sel. Editieren - Tonwert)\nMaske Radius +HISTORY_MSG_712;(sel. Editieren - Tonwert)\nMaske Farbintensität +HISTORY_MSG_713;(sel. Editieren - Tonwert)\nMaske Gamma +HISTORY_MSG_714;(sel. Editieren - Tonwert)\nMaske Steigung +HISTORY_MSG_716;(sel. Editieren) - lokale Methode +HISTORY_MSG_717;(sel. Editieren - Wavelet)\nKontrastkurve +HISTORY_MSG_718;(sel. Editieren) - lokale Kontrastebenen +HISTORY_MSG_719;(sel. Editieren - Wavelet)\nVerbleibende L +HISTORY_MSG_720;(sel. Editieren - Unschärfe)\nLuminanzmaske\nKurve C +HISTORY_MSG_721;(sel. Editieren - Unschärfe)\nLuminanzmaske\nKurve L +HISTORY_MSG_722;(sel. Editieren - Unschärfe)\nLuminanzmaske\nKurve LC(h) +HISTORY_MSG_723;(sel. Editieren - Unschärfe)\nMaske +HISTORY_MSG_725;(sel. Editieren - Unschärfe)\nMaske\nÜberlagerung +HISTORY_MSG_726;(sel. Editieren - Unschärfe)\nMaske\nRadius +HISTORY_MSG_727;(sel. Editieren - Unschärfe)\nMaske\nFarbintensität +HISTORY_MSG_728;(sel. Editieren - Unschärfe)\nMaske\nGamma +HISTORY_MSG_729;(sel. Editieren - Unschärfe)\nMaske\nSteigung +HISTORY_MSG_730;(sel. Editieren - Unschärfe)\nMethode +HISTORY_MSG_731;(sel. Editieren - Unschärfe)\nMethode Median\nMedianwert +HISTORY_MSG_732;(sel. Editieren - Unschärfe)\nMethode Median\nIterationen +HISTORY_MSG_733;(sel. Editieren - Unschärfe)\nAnpassbarer Filter\nRadius +HISTORY_MSG_734;(sel. Editieren - Unschärfe)\nAnpassbarer Filter\nDetail +HISTORY_MSG_738;(sel. Editieren - Wavelet)\nRestbild\nLuma zusammenführen +HISTORY_MSG_739;(sel. Editieren - Wavelet)\nRestbild\nRadius +HISTORY_MSG_740;(sel. Editieren - Wavelet)\nRestbild\nChroma zusammenführen +HISTORY_MSG_741;(sel. Editieren - Wavelet)\nVerbleibende C +HISTORY_MSG_742;(sel. Editieren - Dynamik u. Belichtung)\nKontrastdämpfung\nGamma +HISTORY_MSG_743;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nIntensität +HISTORY_MSG_744;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nDetail +HISTORY_MSG_745;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nVersatz +HISTORY_MSG_746;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nSigma +HISTORY_MSG_747;(sel. Editieren - Einstellungen)\nSpot erstellt +HISTORY_MSG_748;(sel. Editieren - Dynamik u. Belichtung)\nMethode Rauschreduzierung +HISTORY_MSG_749;(sel. Editieren - Dunst entfernen)\nTiefe +HISTORY_MSG_750;(sel. Editieren - Retinex)\nModus logarithmisch +HISTORY_MSG_751;(sel. Editieren - Dunst entfernen)\nSättigung +HISTORY_MSG_752;(sel. Editieren - Retinex)\nVersatz +HISTORY_MSG_753;(sel. Editieren - Retinex)\nÜbertragungszuordnung +HISTORY_MSG_754;(sel. Editieren - Retinex)\nBeschneiden +HISTORY_MSG_755;(sel. Editieren - Tonwert)\nTonwertkorrektur maskieren +HISTORY_MSG_756;(sel. Editieren - Dynamik u. Belichtung)\nVerwende Algo-Belichtungsmaske +HISTORY_MSG_757;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nSchwelle Laplace +HISTORY_MSG_758;(sel. Editieren - Retinex)\nMaske\nSchwelle Laplace +HISTORY_MSG_759;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nSchwelle Laplace +HISTORY_MSG_760;(sel. Editieren - Farbe-Licht)\nMaske\nSchwelle Laplace +HISTORY_MSG_761;(sel. Editieren - Schatten/Lichter)\nMaske\nSchwelle Laplace +HISTORY_MSG_762;(sel. Editieren - Kontrastebenen)\nMaske\nSchwelle Laplace +HISTORY_MSG_763;(sel. Editieren - Unschärfe)\nMaske\nSchwelle Laplace +HISTORY_MSG_764;(sel. Editieren) - Auflösung PDE Laplace-Maske +HISTORY_MSG_765;(sel. Editieren - Rauschminderung)\nLuminanzmaske\nSchwellenwert +HISTORY_MSG_766;(sel. Editieren - Unschärfe)\nSchnelle Fouriertransformation +HISTORY_MSG_767;(sel. Editieren - Unschärfe)\nISO Körnung Verteilung +HISTORY_MSG_768;(sel. Editieren - Unschärfe)\nISO Körnung Intensität +HISTORY_MSG_769;(sel. Editieren - Unschärfe)\nISO Korngröße +HISTORY_MSG_770;(sel. Editieren - Farbe-Licht)\nMaske\nKontrastkurve +HISTORY_MSG_771;(sel. Editieren - Dynamik u. Belichtung)\nMaske\nKontrastkurve +HISTORY_MSG_772;(sel. Editieren - Schärfen)\nMaske\nKontrastkurve +HISTORY_MSG_773;(sel. Editieren - Tonwert)\nMaske\nKontrastkurve +HISTORY_MSG_774;(sel. Editieren - Retinex)\nMaske\nKontrastkurve +HISTORY_MSG_775;(sel. Editieren - Detailebenen)\nMaske\nKontrastkurve +HISTORY_MSG_776;(sel. Editieren - Unschärfe)\nMaske\nKontrastkurve +HISTORY_MSG_777;(sel. Editieren - Unschärfe)\nMaske\nWavelet\nKontrastkurve +HISTORY_MSG_778;(sel. Editieren - Unschärfe)\nMaske\nLichter +HISTORY_MSG_779;(sel. Editieren - Farbe-Licht)\nMaske\nLokale Kontrastkurve +HISTORY_MSG_780;(sel. Editieren - Farbe-Licht)\nMaske\nSchatten +HISTORY_MSG_781;(sel. Editieren - Wavelet)\nWavelet Ebenen +HISTORY_MSG_782;(sel. Editieren - Unschärfe)\nMaske\nWavelet Ebenen +HISTORY_MSG_783;(sel. Editieren - Farbe-Licht)\nWavelet Ebenenauswahl +HISTORY_MSG_784;(sel. Editieren - Spot)\nMaskieren\nΔE Bildmaske +HISTORY_MSG_785;(sel. Editieren - Spot)\nMaskieren\nBereich Bildmaske +HISTORY_MSG_786;(sel. Editieren - Schatten/Lichter)\nMethode +HISTORY_MSG_787;(sel. Editieren - Schatten/Lichter)\nTonwert-Equalizer\nWerte +HISTORY_MSG_788;(sel. Editieren - Schatten/Lichter)\nTonwert-Equalizer\nDetails +HISTORY_MSG_789;(sel. Editieren - Schatten/Lichter)\nMaske\nIntensität +HISTORY_MSG_790;(sel. Editieren - Schatten/Lichter)\nMaske Ankerpunkt +HISTORY_MSG_791;(sel. Editieren - Maske)\nShort L-Kurve +HISTORY_MSG_792;(sel. Editieren - Spot)\nMaskieren\nHintergrund Maske +HISTORY_MSG_793;(sel. Editieren - Schatten/Lichter)\nGamma Farbtonkennlinie +HISTORY_MSG_794;(sel. Editieren - Schatten/Lichter)\nSteigung Farbtonkennlinie +HISTORY_MSG_795;(sel. Editieren - Maske)\nSichern wiederhergestelltes Bild +HISTORY_MSG_796;(sel. Editieren - Spot)\nSpeziell\nReferenzen rekursiv +HISTORY_MSG_797;(sel. Editieren - Farbe-Licht)\nZusammenführen\nMethode +HISTORY_MSG_798;(sel. Editieren - Farbe-Licht)\nZusammenführen\nDeckkraft +HISTORY_MSG_799;(sel. Editieren - Farbe-Licht)\nRGB-Kurve +HISTORY_MSG_800;(sel. Editieren - Farbe-Licht)\nMethode RGB-Kurven +HISTORY_MSG_801;(sel. Editieren - Farbe-Licht)\nSpezielle Verwendung RGB-Kurven +HISTORY_MSG_802;(sel. Editieren - Farbe-Licht)\nZusammenführen\nSchwellenwert Kontrast +HISTORY_MSG_803;(sel. Editieren - Farbe-Licht)\nZusammenführen +HISTORY_MSG_804;(sel. Editieren - Farbe-Licht)\nIntensität Strukturmaske +HISTORY_MSG_805;(sel. Editieren - Unschärfe)\nIntensität Strukturmaske +HISTORY_MSG_806;(sel. Editieren - Farbe-Licht)\nStrukturmaske als Werkzeug +HISTORY_MSG_807;(sel. Editieren - Unschärfe)\nStrukturmaske als Werkzeug +HISTORY_MSG_808;(sel. Editieren - Farbe-Licht)\nMaske\nKurve H(H) +HISTORY_MSG_809;(sel. Editieren - Farbtemperatur)\nMaske\nKurve C +HISTORY_MSG_810;(sel. Editieren - Farbtemperatur)\nMaske\nKurve L +HISTORY_MSG_811;(sel. Editieren - Farbtemperatur)\nMaske\nKurve LC(h) +HISTORY_MSG_813;(sel. Editieren - Farbtemperatur)\nMaske +HISTORY_MSG_814;(sel. Editieren - Farbtemperatur)\nMaske\nÜberlagerung +HISTORY_MSG_815;(sel. Editieren - Farbtemperatur)\nMaske\nRadius +HISTORY_MSG_816;(sel. Editieren - Farbtemperatur)\nMaske\nFarbintensität +HISTORY_MSG_817;(sel. Editieren - Farbtemperatur)\nMaske\nGamma +HISTORY_MSG_818;(sel. Editieren - Farbtemperatur)\nMaske\nSteigung +HISTORY_MSG_819;(sel. Editieren - Farbtemperatur)\nMaske\nSchwellenwert Laplace +HISTORY_MSG_820;(sel. Editieren - Farbtemperatur)\nMaske\nKontrastkurve +HISTORY_MSG_821;(sel. Editieren - Farbe-Licht)\nHintergrundgitter +HISTORY_MSG_822;(sel. Editieren - Farbe-Licht)\nHintergrund zusammenführen +HISTORY_MSG_823;(sel. Editieren - Farbe-Licht)\nLuminanz Hintergrund +HISTORY_MSG_824;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nVerlaufsintensität +HISTORY_MSG_825;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_826;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nIntensität +HISTORY_MSG_827;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_828;(sel. Editieren - Schatten/Lichter)\nVerlaufsfilter\nVerlaufsintensität +HISTORY_MSG_829;(sel. Editieren - Schatten/Lichter)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_830;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nIntensität Luminanz +HISTORY_MSG_831;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_832;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nIntensität Chrominanz +HISTORY_MSG_833;(sel. Editieren - Spot)\nÜbergangsgradient\nVerlaufsbreite +HISTORY_MSG_834;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nIntensität Farbton +HISTORY_MSG_835;(sel. Editieren - Farbtemperatur)\nVerlaufsfilter\nIntensität Luminanz +HISTORY_MSG_836;(sel. Editieren - Farbtemperatur)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_837;(sel. Editieren - Farbtemperatur)\nVerlaufsfilter\nIntensität Chrominanz +HISTORY_MSG_838;(sel. Editieren - Farbtemperatur)\nVerlaufsfilter\nIntensität Farbton +HISTORY_MSG_839;(sel. Editieren) - Softwarekomplexität +HISTORY_MSG_840;(sel. Editieren - Farbe-Licht)\nCL-Kurve +HISTORY_MSG_841;(sel. Editieren - Farbe-Licht)\nLC-Kurve +HISTORY_MSG_842;(sel. Editieren - Farbe-Licht)\nUnschärfemaske\nRadius +HISTORY_MSG_843;(sel. Editieren - Farbe-Licht)\nUnschärfemaske\nSchwellenwert Kontrast +HISTORY_MSG_844;(sel. Editieren - Farbe-Licht)\nUnschärfemaske\nSchnelle Fouriertransformation +HISTORY_MSG_845;(sel. Editieren - LOG-Kodierung) +HISTORY_MSG_846;(sel. Editieren - LOG-Kodierung)\nAutomatisch +HISTORY_MSG_847;(sel. Editieren - LOG-Kodierung)\nQuelle +HISTORY_MSG_849;(sel. Editieren - LOG-Kodierung)\nQuelle Automatisch +HISTORY_MSG_850;(sel. Editieren - LOG-Kodierung)\nSchwarz-Ev +HISTORY_MSG_851;(sel. Editieren - LOG-Kodierung)\nWeiß-Ev +HISTORY_MSG_852;(sel. Editieren - LOG-Kodierung)\nZiel +HISTORY_MSG_853;(sel. Editieren - LOG-Kodierung)\nLokaler Kontrast +HISTORY_MSG_854;(sel. Editieren - LOG-Kodierung)\nBereich +HISTORY_MSG_855;(sel. Editieren - LOG-Kodierung)\nGesamtes Bild +HISTORY_MSG_856;(sel. Editieren - LOG-Kodierung)\nBereich Schatten +HISTORY_MSG_857;(sel. Editieren - Wavelet)\nUnschärfeebenen\nVerbleibende Unschärfe +HISTORY_MSG_858;(sel. Editieren - Wavelet)\nUnschärfeebenen\nNur Luminanz +HISTORY_MSG_859;(sel. Editieren - Wavelet)\nUnschärfeebenen\nMaximum +HISTORY_MSG_860;(sel. Editieren - Wavelet)\nUnschärfeebenen +HISTORY_MSG_861;(sel. Editieren - Wavelet)\nKontrastebenen +HISTORY_MSG_862;(sel. Editieren - Wavelet)\nKontrastebenen\nDämpfungsreaktion +HISTORY_MSG_863;(sel. Editieren - Wavelet)\nOriginal zusammenführen +HISTORY_MSG_864;(sel. Editieren - Wavelet)\nDirektionaler Kontrast\nDämpfungsreaktion +HISTORY_MSG_865;(sel. Editieren - Wavelet)\nDirektionaler Kontrast\nEbenenbalance +HISTORY_MSG_866;(sel. Editieren - Wavelet)\nDirektionaler Kontrast\nKompression +HISTORY_MSG_868;(sel. Editieren - Spot)\nKantenerkennung\nC-H Balance +HISTORY_MSG_869;(sel. Editieren - Rauschminderung)\nLuminanzkurve +HISTORY_MSG_870;(sel. Editieren - Lokaler Kontrast)\nMaske\nKurve H +HISTORY_MSG_871;(sel. Editieren - Lokaler Kontrast)\nMaske\nKurve C +HISTORY_MSG_872;(sel. Editieren - Lokaler Kontrast)\nMaske\nKurve L +HISTORY_MSG_873;(sel. Editieren - Lokaler Kontrast)\nMaske +HISTORY_MSG_875;(sel. Editieren - Lokaler Kontrast)\nMaske überlagern +HISTORY_MSG_876;(sel. Editieren - Lokaler Kontrast)\nMaske glätten +HISTORY_MSG_877;(sel. Editieren - Lokaler Kontrast)\nMaske Farbintensität +HISTORY_MSG_878;(sel. Editieren - Lokaler Kontrast)\nMaske Kontrastkurve +HISTORY_MSG_879;(sel. Editieren - Wavelet)\nKontrastebene\nFarbintensität +HISTORY_MSG_880;(sel. Editieren - Wavelet)\nUnschärfeebenen\nChrominanz Ebenen +HISTORY_MSG_881;(sel. Editieren - Wavelet)\nKontrastebene\nVersatz +HISTORY_MSG_882;(sel. Editieren - Wavelet)\nUnschärfeebenen +HISTORY_MSG_883;(sel. Editieren - Wavelet)\nKontrast nach Ebenen +HISTORY_MSG_884;(sel. Editieren - Wavelet)\nDirektionaler Kontrast +HISTORY_MSG_885;(sel. Editieren - Wavelet)\nTonwertkorrektur +HISTORY_MSG_886;(sel. Editieren - Wavelet)\nTonwertkorrektur Kompression +HISTORY_MSG_887;(sel. Editieren - Wavelet)\nTonwertkorrektur\nKompression Restbild +HISTORY_MSG_888;(sel. Editieren - Wavelet)\nTonwertkorrektur\nSchwellenwert Balance +HISTORY_MSG_889;(sel. Editieren - Wavelet)\nVerlaufsfilter\nIntensität +HISTORY_MSG_890;(sel. Editieren - Wavelet)\nVerlaufsfilter\nRotationswinkel +HISTORY_MSG_891;(sel. Editieren - Wavelet)\nVerlaufsfilter +HISTORY_MSG_892;(sel. Editieren - LOG-Kodierung)\nVerlaufsintensität +HISTORY_MSG_893;(sel. Editieren - LOG-Kodierung)\nVerlaufswinkel +HISTORY_MSG_894;(sel. Editieren - Spot)\nKantenerkennung\nVorschau Farbe Intensität (ΔE) +HISTORY_MSG_897;(sel. Editieren - Wavelet)\nKantenschärfe\nIntensität +HISTORY_MSG_898;(sel. Editieren - Wavelet)\nKantenschärfe\nRadius +HISTORY_MSG_899;(sel. Editieren - Wavelet(\nKantenschärfe\nDetails +HISTORY_MSG_900;(sel. Editieren - Wavelet)\nKantenschärfe\nVerlaufsempfindlichkeit +HISTORY_MSG_901;(sel. Editieren - Wavelet)\nKantenschärfe\nUnterer Schwellenwert +HISTORY_MSG_902;(sel. Editieren - Wavelet)\nKantenschärfe\nOberer Schwellenwert +HISTORY_MSG_903;(sel. Editieren - Wavelet)\nKantenschärfe\nKontrastkurve +HISTORY_MSG_904;(sel. Editieren - Wavelet)\nKantenschärfe\nErste Ebene +HISTORY_MSG_905;(sel. Editieren - Wavelet)\nKantenschärfe +HISTORY_MSG_906;(sel. Editieren - Wavelet)\nKantenschärfe\nKantenempfindlichkeit +HISTORY_MSG_907;(sel. Editieren - Wavelet)\nKantenschärfe\nGrundverstärkung +HISTORY_MSG_908;(sel. Editieren - Wavelet)\nKantenschärfe\nBenachbarte Pixel +HISTORY_MSG_909;(sel. Editieren - Wavelet\nKantenschärfe\nAlle Werkzeuge anzeigen +HISTORY_MSG_910;(sel. Editieren - Wavelet)\nKantenperformance +HISTORY_MSG_911;(sel. Editieren - Unschärfe)\nChrominanz Luminanz +HISTORY_MSG_912;(sel. Editieren - Unschärfe)\nAnpassbarer Filter Intensität +HISTORY_MSG_913;(sel. Editieren - Wavelet)\nTonwertkorrektur\nDämpfungsreaktion +HISTORY_MSG_914;(sel. Editieren - Wavelet)\nUnschärfeebenen\nDämpfungsreaktion +HISTORY_MSG_915;(sel. Editieren - Wavelet)\nKantenschärfe\nDämpfungsreaktion +HISTORY_MSG_916;(sel. Editieren - Wavelet)\nRestbild Schatten +HISTORY_MSG_917;(sel. Editieren - Wavelet)\nRestbild\nSchwellenwert Schatten +HISTORY_MSG_918;(sel. Editieren - Wavelet)\nRestbild Lichter +HISTORY_MSG_919;(sel. Editieren - Wavelet)\nRestbild\nSchwellenwert Lichter +HISTORY_MSG_920;(sel. Editieren - Wavelet)\nKontrast\nDämpfungsreaktion +HISTORY_MSG_921;(sel. Editieren - Wavelet)\nVerlaufsfilter\nDämpfungsreaktion +HISTORY_MSG_922;(sel. Editieren - Spot)\nSpeziell\nÄnderungen in Schwarz-Weiß erzwingen +HISTORY_MSG_923;(sel. Editieren - Werkzeug)\nKomplexität HISTORY_MSG_924;--nicht verwendet-- -HISTORY_MSG_925;(Lokal - Spot)\nAnwendungsbereich\nFarbwerkzeuge -HISTORY_MSG_926;(Lokal - Unschärfe) Rauschreduzierung\nMaskenauswahl -HISTORY_MSG_927;(Lokal - Unschärfe)\nMaske\nSchatten -HISTORY_MSG_928;(Lokal - Normale Farbmaske) -HISTORY_MSG_929;(Lokal - Normale Farbmaske)\nIntensität -HISTORY_MSG_930;(Lokal - Normale Farbmaske)\nÜberlagerung Luminanzmaske -HISTORY_MSG_931;(Lokal - Normale Farbmaske)\nMaske -HISTORY_MSG_932;(Lokal - Normale Farbmaske)\nRadius -HISTORY_MSG_933;(Lokal - Normale Farbmaske)\nSchwellenwert Laplace -HISTORY_MSG_934;(Lokal - Normale Farbmaske)\nFarbintensität -HISTORY_MSG_935;(Lokal - Normale Farbmaske)\nGamma -HISTORY_MSG_936;(Lokal - Normale Farbmaske)\nSteigung -HISTORY_MSG_937;(Lokal - Normale Farbmaske)\nKurve C(C) -HISTORY_MSG_938;(Lokal - Normale Farbmaske)\nKurve L(L) -HISTORY_MSG_939;(Lokal - Normale Farbmaske)\nKurve LC(H) -HISTORY_MSG_940;(Lokal - Normale Farbmaske)\nStrukturmaske als Werkzeug -HISTORY_MSG_941;(Lokal - Normale Farbmaske)\nIntensität Strukturmaske -HISTORY_MSG_942;(Lokal - Normale Farbmaske)\nKurve H(H) -HISTORY_MSG_943;(Lokal - Normale Farbmaske)\nSchnelle Fouriertransformation -HISTORY_MSG_944;(Lokal - Normale Farbmaske)\nUnschärfemaske\nUnschärferadius -HISTORY_MSG_945;(Lokal - Normale Farbmaske)\nUnschärfemaske\nSchwellenwert Kontrast -HISTORY_MSG_946;(Lokal - Normale Farbmaske)\nSchatten -HISTORY_MSG_947;(Lokal - Normale Farbmaske)\nKontrastkurve -HISTORY_MSG_948;(Lokal - Normale Farbmaske)\nWavelet-Kurve -HISTORY_MSG_949;(Lokal - Normale Farbmaske)\nWavelet-Ebenen -HISTORY_MSG_950;(Lokal - Normale Farbmaske)\nVerlaufsfiltermaske\nIntensität -HISTORY_MSG_951;(Lokal - Normale Farbmaske)\nVerlaufsfiltermaske\nRotationswinkel -HISTORY_MSG_952;(Lokal - Normale Farbmaske)\nRadius -HISTORY_MSG_953;(Lokal - Normale Farbmaske)\nÜberlagerung Chrominanzmaske -HISTORY_MSG_954;(Lokal)\nWerkzeuge einblenden/ausblenden -HISTORY_MSG_955;(Lokal) - Spot aktivieren -HISTORY_MSG_956;(Lokal - Farbe-Licht)\nCH-Kurve -HISTORY_MSG_957;(Lokal - Rauschminderung)\nModus -HISTORY_MSG_958;(Lokal) - Zus. Einstellungen -HISTORY_MSG_959;(Lokal - Unschärfe)\nInvertieren -HISTORY_MSG_960;(Lokal - LOG-Kodierung)\nCAT16 -HISTORY_MSG_961;(Lokal - LOG-Kodierung)\nCIECAM -HISTORY_MSG_962;(Lokal - LOG-Kodierung)\nAbsolute Luminanzquelle -HISTORY_MSG_963;(Lokal - LOG-Kodierung)\nAbsolutes Luminanzziel -HISTORY_MSG_964;(Lokal - LOG-Kodierung)\nUmgebung -HISTORY_MSG_965;(Lokal - LOG-Kodierung)\nSättigung s -HISTORY_MSG_966;(Lokal - LOG-Kodierung)\nKontrast J -HISTORY_MSG_967;(Lokal - LOG-Kodierung)\nMaske Kurve C -HISTORY_MSG_968;(Lokal - LOG-Kodierung)\nMaske Kurve L -HISTORY_MSG_969;(Lokal - LOG-Kodierung)\nMaske Kurve H -HISTORY_MSG_970;(Lokal - LOG-Kodierung)\nMaske -HISTORY_MSG_971;(Lokal - LOG-Kodierung)\nMaske überlagern -HISTORY_MSG_972;(Lokal - LOG-Kodierung)\nMaske Radius -HISTORY_MSG_973;(Lokal - LOG-Kodierung)\nMaske Chroma -HISTORY_MSG_974;(Lokal - LOG-Kodierung)\nMaske Kontrast -HISTORY_MSG_975;(Lokal - LOG-Kodierung)\nHelligkeit J -HISTORY_MSG_977;(Lokal - LOG-Kodierung)\nKontrast Q -HISTORY_MSG_978;(Lokal - LOG-Kodierung)\nSichere Quelle -HISTORY_MSG_979;(Lokal - LOG-Kodierung)\nHelligkeit Q -HISTORY_MSG_980;(Lokal - LOG-Kodierung)\nFarbigkeit M -HISTORY_MSG_981;(Lokal - LOG-Kodierung)\nIntensität -HISTORY_MSG_982;(Lokal - Rauschminderung)\nEqualizer Farbton -HISTORY_MSG_983;(Lokal - Rauschminderung)\nWiederherstellung\nSchwellenwert Maske hell -HISTORY_MSG_984;(Lokal - Rauschminderung)\nWiederherstellung\nSchwellenwert Maske dunkel -HISTORY_MSG_985;(Lokal - Rauschminderung)\nLuminanzmaske\nLaplace -HISTORY_MSG_986;(Lokal - Rauschminderung)\nDunkle und helle Bereiche verstärken -HISTORY_MSG_987;(Lokal - Verlaufsfilter)\nSchwellenwert Wiederherstellung -HISTORY_MSG_988;(Lokal - Verlaufsfilter)\nSchwellenwert Maske dunkel -HISTORY_MSG_989;(Lokal - Verlaufsfilter)\nSchwellenwert Maske hell -HISTORY_MSG_990;(Lokal - Rauschminderung)\nWiederherstellung\nSchwelle -HISTORY_MSG_991;(Lokal - Rauschminderung)\nSchwellenwert Maske dunkel -HISTORY_MSG_992;(Lokal - Rauschminderung)\nSchwellenwert Maske hell -HISTORY_MSG_993;(Lokal - Rauschminderung)\nInvertieren -HISTORY_MSG_994;(Lokal - Verlaufsfilter)\nInvertieren -HISTORY_MSG_995;(Lokal - Rauschminderung)\nZerfallrate -HISTORY_MSG_996;(Lokal - Farbe-Licht)\nWiederherstellung\nSchwelle -HISTORY_MSG_997;(Lokal - Farbe-Licht)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_998;(Lokal - Farbe-Licht)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_999;(Lokal - Farbe-Licht)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1000;(Lokal - Rauschminderung)\nLuminanz Graubereiche -HISTORY_MSG_1001;(Lokal - LOG-Kodierung)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1002;(Lokal - LOG-Kodierung)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1003;(Lokal - LOG-Kodierung)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1004;(Lokal - LOG-Kodierung)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1005;(Lokal - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1006;(Lokal - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1007;(Lokal - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1008;(Lokal - Dynamik u. Belichtung)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1009;(Lokal - Schatten/Lichter)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1010;(Lokal - Schatten/Lichter)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1011;(Lokal - Schatten/Lichter)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1012;(Lokal - Schatten/Lichter)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1013;(Lokal - Farbtemperatur)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1014;(Lokal - Farbtemperatur)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1015;(Lokal - Farbtemperatur)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1016;(Lokal - Farbtemperatur)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1017;(Lokal - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1018;(Lokal - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1019;(Lokal - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1020;(Lokal - Lokaler Kontrast)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1021;(Lokal - Rauschminderung)\nChrominanz Graubereiche -HISTORY_MSG_1022;(Lokal - Tonwert)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1023;(Lokal - Tonwert)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1024;(Lokal - Tonwert)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1025;(Lokal - Tonwert)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1026;(Lokal - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1027;(Lokal - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1028;(Lokal - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1029;(Lokal - Detailebenen-Kontrast)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1030;(Lokal - Retinex)\nWiederherstellung\nSchwellenwert -HISTORY_MSG_1031;(Lokal - Retinex)\nWiederherstellung\nSchwellenwert dunkel -HISTORY_MSG_1032;(Lokal - Retinex)\nWiederherstellung\nSchwellenwert hell -HISTORY_MSG_1033;(Lokal - Retinex)\nWiederherstellung\nZerfallrate -HISTORY_MSG_1034;(Lokal - Rauschminderung)\nNicht-lokales Mittel\nIntensität -HISTORY_MSG_1035;(Lokal - Rauschminderung)\nNicht-lokales Mittel\nDetailwiederherstellung -HISTORY_MSG_1036;(Lokal - Rauschminderung)\nNicht-lokales Mittel\nObjektgröße -HISTORY_MSG_1037;(Lokal - Rauschminderung)\nNicht-lokales Mittel\nRadius -HISTORY_MSG_1038;(Lokal - Rauschminderung)\nNicht-lokales Mittel\nGamma -HISTORY_MSG_1039;(Lokal - Unschärfe)\nKörnung Gamma -HISTORY_MSG_1040;(Lokal - Spot)\nSpeziell\nRadius -HISTORY_MSG_1041;(Lokal - Spot)\nSpeziell\nNur Munsell -HISTORY_MSG_1042;(Lokal - LOG-Kodierung)\nSchwellenwert -HISTORY_MSG_1043;(Lokal - Dynamik u. Belichtung)\nNormalisieren -HISTORY_MSG_1044;(Lokal - Lokaler Kontrast)\nGesamtintensität -HISTORY_MSG_1045;(Lokal - Farbe-Licht)\nGesamtintensität -HISTORY_MSG_1046;(Lokal - Rauschminderung)\nGesamtintensität -HISTORY_MSG_1047;(Lokal - Schatten/Lichter)\nGesamtintensität -HISTORY_MSG_1048;(Lokal - Dynamik u. Belichtung)\nGesamtintensität -HISTORY_MSG_1049;(Lokal - Tonwert)\nGesamtintensität -HISTORY_MSG_1050;(Lokal - LOG-Kodierung)\nChroma -HISTORY_MSG_1051;(Lokal - Lokaler Kontrast)\nRestbild\nGamma -HISTORY_MSG_1052;(Lokal - Lokaler Kontrast\nRestbild\nSteigung -HISTORY_MSG_1053;(Lokal - Rauschminderung)\nRauschreduzierung\nGamma -HISTORY_MSG_1054;(Lokal - Lokaler Kontrast)\nWavelet\nGamma -HISTORY_MSG_1055;(Lokal - Farbe u. Licht)\nGamma -HISTORY_MSG_1056;(Lokal - Dynamik u. Belichtung)\nDynamikkompression\nGamma -HISTORY_MSG_1057;(Lokal - CIECAM) -HISTORY_MSG_1058;(Lokal - CIECAM)\nGesamtintensität -HISTORY_MSG_1059;(Lokal - CIECAM)\nSzenebasierte Bedingungen\nAutomatisch -HISTORY_MSG_1060;(Lokal - CIECAM)\nSzenebasierte Bedingungen\nMittlere Luminanz -HISTORY_MSG_1061;(Lokal - CIECAM)\nSzenebasierte Bedingungen\nAbsolute Luminanz -HISTORY_MSG_1062;(Lokal - CIECAM)\nSzenebasierte Bedingungen\nUmgebung -HISTORY_MSG_1063;(Lokal - CIECAM)\nCAM16 - Farbe\nSättigung -HISTORY_MSG_1064;(Lokal - CIECAM)\nCAM16 - Farbe\nChroma -HISTORY_MSG_1065;(Lokal - CIECAM)\nHelligkeit J -HISTORY_MSG_1066;(Lokal - CIECAM)\nHelligkeit -HISTORY_MSG_1067;(Lokal - CIECAM)\nKontrast J -HISTORY_MSG_1068;(Lokal - CIECAM)\nCAM16 - Kontrast\nSchwellenwert Kontrast -HISTORY_MSG_1069;(Lokal - CIECAM)\nCAM16 - Kontrast\nKontrast (Q) -HISTORY_MSG_1070;(Lokal - CIECAM)\nCAM16 - Farbe\nBuntheit -HISTORY_MSG_1071;(Lokal - CIECAM)\nBetrachtungsbedingungen\nAbsolute Luminanz -HISTORY_MSG_1072;(Lokal - CIECAM)\nBetrachtungsbedingungen\nMittlere Luminanz -HISTORY_MSG_1073;(Lokal - CIECAM)\nBetrachtungsbedingungen\nChromatische Adaption/Cat16 -HISTORY_MSG_1074;(Lokal - CIECAM)\nCAM16 - Kontrast\nLokaler Kontrast -HISTORY_MSG_1075;(Lokal - CIECAM)\nBetrachtungsbedingungen\nUmgebung -HISTORY_MSG_1076;(Lokal - CIECAM)\nBereich -HISTORY_MSG_1077;(Lokal - CIECAM)\nWerkzeugmodus -HISTORY_MSG_1078;(Lokal - CIECAM)\nCAM16 - Farbe\nHautfarbtöne schützen -HISTORY_MSG_1079;(Lokal - CIECAM)\nSigmoid\nKontraststärke -HISTORY_MSG_1080;(Lokal - CIECAM)\nSigmoid\nSchwellenwert -HISTORY_MSG_1081;(Lokal - CIECAM)\nSigmoid\nÜberlagern -HISTORY_MSG_1082;(Lokal - CIECAM)\nSigmoid\nSchwarz-Ev Weiß-Ev verwenden -HISTORY_MSG_1083;(Lokal - CIECAM)\nCAM16 - Farbe\nFarbtonverschiebung -HISTORY_MSG_1084;(Lokal - CIECAM)\nSchwarz-Ev Weiß-Ev verwenden -HISTORY_MSG_1085;(Lokal - CIECAM)\nJz Cz Hz\nHelligkeit -HISTORY_MSG_1086;(Lokal - CIECAM)\nJz Cz Hz\nKontrast -HISTORY_MSG_1087;(Lokal - CIECAM)\nJz Cz Hz\nChroma -HISTORY_MSG_1088;(Lokal - CIECAM)\nJz Cz Hz\nFarbton -HISTORY_MSG_1089;(Lokal - CIECAM)\nSigmoid Jz\nKontraststärke -HISTORY_MSG_1090;(Lokal - CIECAM)\nSigmoid Jz\nSchwellenwert -HISTORY_MSG_1091;(Lokal - CIECAM)\nSigmoid Jz\nÜberlagern -HISTORY_MSG_1092;(Lokal - CIECAM)\nJz Zuordnung\nAnpassung -HISTORY_MSG_1093;(Lokal - CIECAM)\nCAM Modell -HISTORY_MSG_1094;(Lokal - CIECAM)\nJz Lichter -HISTORY_MSG_1095;(Lokal - CIECAM)\nTonwertbreite Jz Lichter -HISTORY_MSG_1096;(Lokal - CIECAM)\nJz Schatten -HISTORY_MSG_1097;(Lokal - CIECAM)\nTonwertbreite Jz Schatten -HISTORY_MSG_1098;(Lokal - CIECAM)\nJz Radius -HISTORY_MSG_1099;(Lokal - CIECAM)\nJz Cz Hz\nKurve Cz(Hz) -HISTORY_MSG_1100;(Lokal - CIECAM)\nJz Zuordnung\nReferenz 100 -HISTORY_MSG_1101;(Lokal - CIECAM)\nJz Zuordnung\nPQ Peak Luminanz -HISTORY_MSG_1102;(Lokal - CIECAM)\nKurve Jz(Hz) -HISTORY_MSG_1103;(Lokal - CIECAM)\nGamma Lebendigkeit -HISTORY_MSG_1104;(Lokal - CIECAM)\nGamma Schärfe -HISTORY_MSG_1105;(Lokal - CIECAM)\nTonmethode -HISTORY_MSG_1106;(Lokal - CIECAM)\nTonkurve -HISTORY_MSG_1107;(Lokal - CIECAM)\nFarbmethode -HISTORY_MSG_1108;(Lokal - CIECAM)\nFarbkurve -HISTORY_MSG_1109;(Lokal - CIECAM)\nKurve Jz(Jz) -HISTORY_MSG_1110;(Lokal - CIECAM)\nKurve Cz(Cz) -HISTORY_MSG_1111;(Lokal - CIECAM)\nKurve Cz(Jz) -HISTORY_MSG_1112;(Lokal - CIECAM)\nErzwinge jz -HISTORY_MSG_1113;(Lokal - CIECAM)\nCAM16\nHDR PQ -HISTORY_MSG_1114;(Lokal - CIECAM)\nMaske aktivieren -HISTORY_MSG_1115;(Lokal - CIECAM)\nMaske\nKurve C -HISTORY_MSG_1116;(Lokal - CIECAM)\nMaske\nKurve L -HISTORY_MSG_1117;(Lokal - CIECAM)\nMaske\nKurve LC(h) -HISTORY_MSG_1118;(Lokal - CIECAM)\nMaske\nÜberlagerung -HISTORY_MSG_1119;(Lokal - CIECAM)\nMaske\nGlättradius -HISTORY_MSG_1120;(Lokal - CIECAM)\nMaske\nFarbintensität -HISTORY_MSG_1121;(Lokal - CIECAM)\nMaske\nKontrastkurve -HISTORY_MSG_1122;(Lokal - CIECAM)\nMaske\nSchwelle Wiederherstellung -HISTORY_MSG_1123;(Lokal - CIECAM)\nMaske\nSchwelle dunkel -HISTORY_MSG_1124;(Lokal - CIECAM)\nMaske\nSchwelle hell -HISTORY_MSG_1125;(Lokal - CIECAM)\nMaske\nZerfallrate -HISTORY_MSG_1126;(Lokal - CIECAM)\nMaske\nSchwelle Laplace -HISTORY_MSG_1127;(Lokal - CIECAM)\nMaske\nGamma -HISTORY_MSG_1128;(Lokal - CIECAM)\nMaske\nSteigung -HISTORY_MSG_1129;(Lokal - CIECAM)\nJz Cz Hz\nRelative Helligkeit -HISTORY_MSG_1130;(Lokal - CIECAM)\nJz Cz Hz\nSättigung -HISTORY_MSG_1131;(Lokal - Maske)\nRauschminderung -HISTORY_MSG_1132;(Lokal - CIECAM)\nWavelet Jz\nDämpfungsreaktion -HISTORY_MSG_1133;(Lokal - CIECAM)\nWavelet Jz\nEbenen -HISTORY_MSG_1134;(Lokal - CIECAM)\nWavelet Jz\nLokaler Kontrast -HISTORY_MSG_1135;(Lokal - CIECAM)\nWavelet Jz\nLuma zusammenführen -HISTORY_MSG_1136;(Lokal - CIECAM)\nWavelet Jz\nChroma zusammenführen -HISTORY_MSG_1137;(Lokal - CIECAM)\nWavelet Jz\nGlättradius -HISTORY_MSG_1138;(Lokal - CIECAM)\nJz Cz Hz\nKurve Hz(Hz) -HISTORY_MSG_1139;(Lokal - CIECAM)\nJz Cz Hz\nKurven H\nGlättradius -HISTORY_MSG_1140;(Lokal - CIECAM)\nJz Cz Hz\nKurve Jz(Hz)\nSchwelle Chroma -HISTORY_MSG_1141;(Lokal - CIECAM)\nChroma-Kurve Jz(Hz) -HISTORY_MSG_1142;(Lokal) - Stärke Glätten -HISTORY_MSG_1143;(Lokal - CIECAM)\nSchwarz-Ev -HISTORY_MSG_1144;(Lokal - CIECAM)\nWeiß-Ev -HISTORY_MSG_1145;(Lokal - CIECAM)\nLOG-Kodierung Jz -HISTORY_MSG_1146;(Lokal - CIECAM)\nLOG-Kodierung Jz\nMittlere Helligkeit -HISTORY_MSG_1147;(Lokal - CIECAM)\nSigmoid Jz\nVerwendet Schwarz-Ev Weiß-Ev -HISTORY_MSG_1148;(Lokal - CIECAM)\nSigmoid Jz -HISTORY_MSG_1149;(Lokal - CIECAM)\nSigmoid Q -HISTORY_MSG_1150;(Lokal - CIECAM)\nSigmoid\nLOG-Kodierung anstatt Sigmoid +HISTORY_MSG_925;(sel. Editieren - Spot)\nAnwendungsbereich\nFarbwerkzeuge +HISTORY_MSG_926;(sel. Editieren - Unschärfe) Rauschreduzierung\nMaskenauswahl +HISTORY_MSG_927;(sel. Editieren - Unschärfe)\nMaske\nSchatten +HISTORY_MSG_928;(sel. Editieren - Normale Farbmaske) +HISTORY_MSG_929;(sel. Editieren - Normale Farbmaske)\nIntensität +HISTORY_MSG_930;(sel. Editieren - Normale Farbmaske)\nÜberlagerung Luminanzmaske +HISTORY_MSG_931;(sel. Editieren - Normale Farbmaske)\nMaske +HISTORY_MSG_932;(sel. Editieren - Normale Farbmaske)\nRadius +HISTORY_MSG_933;(sel. Editieren - Normale Farbmaske)\nSchwellenwert Laplace +HISTORY_MSG_934;(sel. Editieren - Normale Farbmaske)\nFarbintensität +HISTORY_MSG_935;(sel. Editieren - Normale Farbmaske)\nGamma +HISTORY_MSG_936;(sel. Editieren - Normale Farbmaske)\nSteigung +HISTORY_MSG_937;(sel. Editieren - Normale Farbmaske)\nKurve C(C) +HISTORY_MSG_938;(sel. Editieren - Normale Farbmaske)\nKurve L(L) +HISTORY_MSG_939;(sel. Editieren - Normale Farbmaske)\nKurve LC(H) +HISTORY_MSG_940;(sel. Editieren - Normale Farbmaske)\nStrukturmaske als Werkzeug +HISTORY_MSG_941;(sel. Editieren - Normale Farbmaske)\nIntensität Strukturmaske +HISTORY_MSG_942;(sel. Editieren - Normale Farbmaske)\nKurve H(H) +HISTORY_MSG_943;(sel. Editieren - Normale Farbmaske)\nSchnelle Fouriertransformation +HISTORY_MSG_944;(sel. Editieren - Normale Farbmaske)\nUnschärfemaske\nUnschärferadius +HISTORY_MSG_945;(sel. Editieren - Normale Farbmaske)\nUnschärfemaske\nSchwellenwert Kontrast +HISTORY_MSG_946;(sel. Editieren - Normale Farbmaske)\nSchatten +HISTORY_MSG_947;(sel. Editieren - Normale Farbmaske)\nKontrastkurve +HISTORY_MSG_948;(sel. Editieren - Normale Farbmaske)\nWavelet-Kurve +HISTORY_MSG_949;(sel. Editieren - Normale Farbmaske)\nWavelet-Ebenen +HISTORY_MSG_950;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nIntensität +HISTORY_MSG_951;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nRotationswinkel +HISTORY_MSG_952;(sel. Editieren - Normale Farbmaske)\nRadius +HISTORY_MSG_953;(sel. Editieren - Normale Farbmaske)\nÜberlagerung Chrominanzmaske +HISTORY_MSG_954;(sel. Editieren)\nWerkzeuge einblenden/ausblenden +HISTORY_MSG_955;(sel. Editieren) - Spot aktivieren +HISTORY_MSG_956;(sel. Editieren - Farbe-Licht)\nCH-Kurve +HISTORY_MSG_957;(sel. Editieren - Rauschminderung)\nModus +HISTORY_MSG_958;(sel. Editieren) - Zus. Einstellungen +HISTORY_MSG_959;(sel. Editieren - Unschärfe)\nInvertieren +HISTORY_MSG_960;(sel. Editieren - LOG-Kodierung)\nCAT16 +HISTORY_MSG_961;(sel. Editieren - LOG-Kodierung)\nCIECAM +HISTORY_MSG_962;(sel. Editieren - LOG-Kodierung)\nAbsolute Luminanzquelle +HISTORY_MSG_963;(sel. Editieren - LOG-Kodierung)\nAbsolutes Luminanzziel +HISTORY_MSG_964;(sel. Editieren - LOG-Kodierung)\nUmgebung +HISTORY_MSG_965;(sel. Editieren - LOG-Kodierung)\nSättigung s +HISTORY_MSG_966;(sel. Editieren - LOG-Kodierung)\nKontrast J +HISTORY_MSG_967;(sel. Editieren - LOG-Kodierung)\nMaske Kurve C +HISTORY_MSG_968;(sel. Editieren - LOG-Kodierung)\nMaske Kurve L +HISTORY_MSG_969;(sel. Editieren - LOG-Kodierung)\nMaske Kurve H +HISTORY_MSG_970;(sel. Editieren - LOG-Kodierung)\nMaske +HISTORY_MSG_971;(sel. Editieren - LOG-Kodierung)\nMaske überlagern +HISTORY_MSG_972;(sel. Editieren - LOG-Kodierung)\nMaske Radius +HISTORY_MSG_973;(sel. Editieren - LOG-Kodierung)\nMaske Chroma +HISTORY_MSG_974;(sel. Editieren - LOG-Kodierung)\nMaske Kontrast +HISTORY_MSG_975;(sel. Editieren - LOG-Kodierung)\nHelligkeit J +HISTORY_MSG_977;(sel. Editieren - LOG-Kodierung)\nKontrast Q +HISTORY_MSG_978;(sel. Editieren - LOG-Kodierung)\nSichere Quelle +HISTORY_MSG_979;(sel. Editieren - LOG-Kodierung)\nHelligkeit Q +HISTORY_MSG_980;(sel. Editieren - LOG-Kodierung)\nFarbigkeit M +HISTORY_MSG_981;(sel. Editieren - LOG-Kodierung)\nIntensität +HISTORY_MSG_982;(sel. Editieren - Rauschminderung)\nEqualizer Farbton +HISTORY_MSG_983;(sel. Editieren - Rauschminderung)\nWiederherstellung\nSchwellenwert Maske hell +HISTORY_MSG_984;(sel. Editieren - Rauschminderung)\nWiederherstellung\nSchwellenwert Maske dunkel +HISTORY_MSG_985;(sel. Editieren - Rauschminderung)\nLuminanzmaske\nLaplace +HISTORY_MSG_986;(sel. Editieren - Rauschminderung)\nDunkle und helle Bereiche verstärken +HISTORY_MSG_987;(sel. Editieren - Verlaufsfilter)\nSchwellenwert Wiederherstellung +HISTORY_MSG_988;(sel. Editieren - Verlaufsfilter)\nSchwellenwert Maske dunkel +HISTORY_MSG_989;(sel. Editieren - Verlaufsfilter)\nSchwellenwert Maske hell +HISTORY_MSG_990;(sel. Editieren - Rauschminderung)\nWiederherstellung\nSchwelle +HISTORY_MSG_991;(sel. Editieren - Rauschminderung)\nSchwellenwert Maske dunkel +HISTORY_MSG_992;(sel. Editieren - Rauschminderung)\nSchwellenwert Maske hell +HISTORY_MSG_993;(sel. Editieren - Rauschminderung)\nInvertieren +HISTORY_MSG_994;(sel. Editieren - Verlaufsfilter)\nInvertieren +HISTORY_MSG_995;(sel. Editieren - Rauschminderung)\nZerfallrate +HISTORY_MSG_996;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwelle +HISTORY_MSG_997;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_998;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_999;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1000;(sel. Editieren - Rauschminderung)\nLuminanz Graubereiche +HISTORY_MSG_1001;(sel. Editieren - LOG-Kodierung)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1002;(sel. Editieren - LOG-Kodierung)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1003;(sel. Editieren - LOG-Kodierung)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1004;(sel. Editieren - LOG-Kodierung)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1005;(sel. Editieren - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1006;(sel. Editieren - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1007;(sel. Editieren - Dynamik u. Belichtung)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1008;(sel. Editieren - Dynamik u. Belichtung)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1009;(sel. Editieren - Schatten/Lichter)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1010;(sel. Editieren - Schatten/Lichter)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1011;(sel. Editieren - Schatten/Lichter)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1012;(sel. Editieren - Schatten/Lichter)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1013;(sel. Editieren - Farbtemperatur)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1014;(sel. Editieren - Farbtemperatur)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1015;(sel. Editieren - Farbtemperatur)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1016;(sel. Editieren - Farbtemperatur)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1017;(sel. Editieren - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1018;(sel. Editieren - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1019;(sel. Editieren - Lokaler Kontrast)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1020;(sel. Editieren - Lokaler Kontrast)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1021;(sel. Editieren - Rauschminderung)\nChrominanz Graubereiche +HISTORY_MSG_1022;(sel. Editieren - Tonwert)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1023;(sel. Editieren - Tonwert)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1024;(sel. Editieren - Tonwert)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1025;(sel. Editieren - Tonwert)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1026;(sel. Editieren - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1027;(sel. Editieren - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1028;(sel. Editieren - Detailebenen-Kontrast)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1029;(sel. Editieren - Detailebenen-Kontrast)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1030;(sel. Editieren - Retinex)\nWiederherstellung\nSchwellenwert +HISTORY_MSG_1031;(sel. Editieren - Retinex)\nWiederherstellung\nSchwellenwert dunkel +HISTORY_MSG_1032;(sel. Editieren - Retinex)\nWiederherstellung\nSchwellenwert hell +HISTORY_MSG_1033;(sel. Editieren - Retinex)\nWiederherstellung\nZerfallrate +HISTORY_MSG_1034;(sel. Editieren - Rauschminderung)\nNicht-lokales Mittel\nIntensität +HISTORY_MSG_1035;(sel. Editieren - Rauschminderung)\nNicht-lokales Mittel\nDetailwiederherstellung +HISTORY_MSG_1036;(sel. Editieren - Rauschminderung)\nNicht-lokales Mittel\nObjektgröße +HISTORY_MSG_1037;(sel. Editieren - Rauschminderung)\nNicht-lokales Mittel\nRadius +HISTORY_MSG_1038;(sel. Editieren - Rauschminderung)\nNicht-lokales Mittel\nGamma +HISTORY_MSG_1039;(sel. Editieren - Unschärfe)\nKörnung Gamma +HISTORY_MSG_1040;(sel. Editieren - Spot)\nSpeziell\nRadius +HISTORY_MSG_1041;(sel. Editieren - Spot)\nSpeziell\nNur Munsell +HISTORY_MSG_1042;(sel. Editieren - LOG-Kodierung)\nSchwellenwert +HISTORY_MSG_1043;(sel. Editieren - Dynamik u. Belichtung)\nNormalisieren +HISTORY_MSG_1044;(sel. Editieren - Lokaler Kontrast)\nGesamtintensität +HISTORY_MSG_1045;(sel. Editieren - Farbe-Licht)\nGesamtintensität +HISTORY_MSG_1046;(sel. Editieren - Rauschminderung)\nGesamtintensität +HISTORY_MSG_1047;(sel. Editieren - Schatten/Lichter)\nGesamtintensität +HISTORY_MSG_1048;(sel. Editieren - Dynamik u. Belichtung)\nGesamtintensität +HISTORY_MSG_1049;(sel. Editieren - Tonwert)\nGesamtintensität +HISTORY_MSG_1050;(sel. Editieren - LOG-Kodierung)\nChroma +HISTORY_MSG_1051;(sel. Editieren - Lokaler Kontrast)\nRestbild\nGamma +HISTORY_MSG_1052;(sel. Editieren - Lokaler Kontrast\nRestbild\nSteigung +HISTORY_MSG_1053;(sel. Editieren - Rauschminderung)\nRauschreduzierung\nGamma +HISTORY_MSG_1054;(sel. Editieren - Lokaler Kontrast)\nWavelet\nGamma +HISTORY_MSG_1055;(sel. Editieren - Farbe u. Licht)\nGamma +HISTORY_MSG_1056;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nGamma +HISTORY_MSG_1057;(sel. Editieren - CIECAM) +HISTORY_MSG_1058;(sel. Editieren - CIECAM)\nGesamtintensität +HISTORY_MSG_1059;(sel. Editieren - CIECAM)\nSzenebasierte Bedingungen\nAutomatisch +HISTORY_MSG_1060;(sel. Editieren - CIECAM)\nSzenebasierte Bedingungen\nMittlere Luminanz +HISTORY_MSG_1061;(sel. Editieren - CIECAM)\nSzenebasierte Bedingungen\nAbsolute Luminanz +HISTORY_MSG_1062;(sel. Editieren - CIECAM)\nSzenebasierte Bedingungen\nUmgebung +HISTORY_MSG_1063;(sel. Editieren - CIECAM)\nCAM16 - Farbe\nSättigung +HISTORY_MSG_1064;(sel. Editieren - CIECAM)\nCAM16 - Farbe\nChroma +HISTORY_MSG_1065;(sel. Editieren - CIECAM)\nHelligkeit J +HISTORY_MSG_1066;(sel. Editieren - CIECAM)\nHelligkeit +HISTORY_MSG_1067;(sel. Editieren - CIECAM)\nKontrast J +HISTORY_MSG_1068;(sel. Editieren - CIECAM)\nCAM16 - Kontrast\nSchwellenwert Kontrast +HISTORY_MSG_1069;(sel. Editieren - CIECAM)\nCAM16 - Kontrast\nKontrast (Q) +HISTORY_MSG_1070;(sel. Editieren - CIECAM)\nCAM16 - Farbe\nBuntheit +HISTORY_MSG_1071;(sel. Editieren - CIECAM)\nBetrachtungsbedingungen\nAbsolute Luminanz +HISTORY_MSG_1072;(sel. Editieren - CIECAM)\nBetrachtungsbedingungen\nMittlere Luminanz +HISTORY_MSG_1073;(sel. Editieren - CIECAM)\nBetrachtungsbedingungen\nChromatische Adaption/Cat16 +HISTORY_MSG_1074;(sel. Editieren - CIECAM)\nCAM16 - Kontrast\nLokaler Kontrast +HISTORY_MSG_1075;(sel. Editieren - CIECAM)\nBetrachtungsbedingungen\nUmgebung +HISTORY_MSG_1076;(sel. Editieren - CIECAM)\nBereich +HISTORY_MSG_1077;(sel. Editieren - CIECAM)\nWerkzeugmodus +HISTORY_MSG_1078;(sel. Editieren - CIECAM)\nCAM16 - Farbe\nHautfarbtöne schützen +HISTORY_MSG_1079;(sel. Editieren - CIECAM)\nSigmoid\nKontraststärke +HISTORY_MSG_1080;(sel. Editieren - CIECAM)\nSigmoid\nSchwellenwert +HISTORY_MSG_1081;(sel. Editieren - CIECAM)\nSigmoid\nLuminanz normalisieren\nÜberlagern +HISTORY_MSG_1082;(sel. Editieren - CIECAM)\nSchwellenwert automatisch +HISTORY_MSG_1083;(sel. Editieren - CIECAM)\nCAM16 - Farbe\nFarbtonverschiebung +HISTORY_MSG_1084;(sel. Editieren - CIECAM)\nSchwarz-Ev Weiß-Ev verwenden +HISTORY_MSG_1085;(sel. Editieren - CIECAM)\nJz Cz Hz\nHelligkeit +HISTORY_MSG_1086;(sel. Editieren - CIECAM)\nJz Cz Hz\nKontrast +HISTORY_MSG_1087;(sel. Editieren - CIECAM)\nJz Cz Hz\nChroma +HISTORY_MSG_1088;(sel. Editieren - CIECAM)\nJz Cz Hz\nFarbton +HISTORY_MSG_1089;(sel. Editieren - CIECAM)\nSigmoid Jz\nKontraststärke +HISTORY_MSG_1090;(sel. Editieren - CIECAM)\nSigmoid Jz\nSchwellenwert +HISTORY_MSG_1091;(sel. Editieren - CIECAM)\nSigmoid Jz\nÜberlagern +HISTORY_MSG_1092;(sel. Editieren - CIECAM)\nJz Zuordnung\nAnpassung +HISTORY_MSG_1093;(sel. Editieren - CIECAM)\nCAM Modell +HISTORY_MSG_1094;(sel. Editieren - CIECAM)\nJz Lichter +HISTORY_MSG_1095;(sel. Editieren - CIECAM)\nTonwertbreite Jz Lichter +HISTORY_MSG_1096;(sel. Editieren - CIECAM)\nJz Schatten +HISTORY_MSG_1097;(sel. Editieren - CIECAM)\nTonwertbreite Jz Schatten +HISTORY_MSG_1098;(sel. Editieren - CIECAM)\nJz Radius +HISTORY_MSG_1099;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurve Cz(Hz) +HISTORY_MSG_1100;(sel. Editieren - CIECAM)\nJz Zuordnung\nReferenz 100 +HISTORY_MSG_1101;(sel. Editieren - CIECAM)\nJz Zuordnung\nPQ Peak Luminanz +HISTORY_MSG_1102;(sel. Editieren - CIECAM)\nKurve Jz(Hz) +HISTORY_MSG_1103;(sel. Editieren - CIECAM)\nGamma Lebendigkeit +HISTORY_MSG_1104;(sel. Editieren - CIECAM)\nGamma Schärfe +HISTORY_MSG_1105;(sel. Editieren - CIECAM)\nTonmethode +HISTORY_MSG_1106;(sel. Editieren - CIECAM)\nTonkurve +HISTORY_MSG_1107;(sel. Editieren - CIECAM)\nFarbmethode +HISTORY_MSG_1108;(sel. Editieren - CIECAM)\nFarbkurve +HISTORY_MSG_1109;(sel. Editieren - CIECAM)\nKurve Jz(Jz) +HISTORY_MSG_1110;(sel. Editieren - CIECAM)\nKurve Cz(Cz) +HISTORY_MSG_1111;(sel. Editieren - CIECAM)\nKurve Cz(Jz) +HISTORY_MSG_1112;(sel. Editieren - CIECAM)\nErzwinge Jz +HISTORY_MSG_1113;(sel. Editieren - CIECAM)\nCAM16\nHDR PQ +HISTORY_MSG_1114;(sel. Editieren - CIECAM)\nMaske aktivieren +HISTORY_MSG_1115;(sel. Editieren - CIECAM)\nMaske\nKurve C +HISTORY_MSG_1116;(sel. Editieren - CIECAM)\nMaske\nKurve L +HISTORY_MSG_1117;(sel. Editieren - CIECAM)\nMaske\nKurve LC(h) +HISTORY_MSG_1118;(sel. Editieren - CIECAM)\nMaske\nÜberlagerung +HISTORY_MSG_1119;(sel. Editieren - CIECAM)\nMaske\nGlättradius +HISTORY_MSG_1120;(sel. Editieren - CIECAM)\nMaske\nFarbintensität +HISTORY_MSG_1121;(sel. Editieren - CIECAM)\nMaske\nKontrastkurve +HISTORY_MSG_1122;(sel. Editieren - CIECAM)\nMaske\nSchwelle Wiederherstellung +HISTORY_MSG_1123;(sel. Editieren - CIECAM)\nMaske\nSchwelle dunkel +HISTORY_MSG_1124;(sel. Editieren - CIECAM)\nMaske\nSchwelle hell +HISTORY_MSG_1125;(sel. Editieren - CIECAM)\nMaske\nZerfallrate +HISTORY_MSG_1126;(sel. Editieren - CIECAM)\nMaske\nSchwelle Laplace +HISTORY_MSG_1127;(sel. Editieren - CIECAM)\nMaske\nGamma +HISTORY_MSG_1128;(sel. Editieren - CIECAM)\nMaske\nSteigung +HISTORY_MSG_1129;(sel. Editieren - CIECAM)\nJz Cz Hz\nRelative Helligkeit +HISTORY_MSG_1130;(sel. Editieren - CIECAM)\nJz Cz Hz\nSättigung +HISTORY_MSG_1131;(sel. Editieren - Spot)\nMaske Farbrauschen +HISTORY_MSG_1132;(sel. Editieren - CIECAM)\nWavelet Jz\nDämpfungsreaktion +HISTORY_MSG_1133;(sel. Editieren - CIECAM)\nWavelet Jz\nEbenen +HISTORY_MSG_1134;(sel. Editieren - CIECAM)\nWavelet Jz\nLokaler Kontrast +HISTORY_MSG_1135;(sel. Editieren - CIECAM)\nWavelet Jz\nLuma zusammenführen +HISTORY_MSG_1136;(sel. Editieren - CIECAM)\nWavelet Jz\nChroma zusammenführen +HISTORY_MSG_1137;(sel. Editieren - CIECAM)\nWavelet Jz\nGlättradius +HISTORY_MSG_1138;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurve Hz(Hz) +HISTORY_MSG_1139;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurven H\nGlättradius +HISTORY_MSG_1140;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurve Jz(Hz)\nSchwelle Chroma +HISTORY_MSG_1141;(sel. Editieren - CIECAM)\nChroma-Kurve Jz(Hz) +HISTORY_MSG_1142;(sel. Editieren) - Stärke Glätten +HISTORY_MSG_1143;(sel. Editieren - CIECAM)\nSchwarz-Ev +HISTORY_MSG_1144;(sel. Editieren - CIECAM)\nWeiß-Ev +HISTORY_MSG_1145;(sel. Editieren - CIECAM)\nLOG-Kodierung Jz +HISTORY_MSG_1146;(sel. Editieren - CIECAM)\nLOG-Kodierung Jz\nMittlere Helligkeit +HISTORY_MSG_1147;(sel. Editieren - CIECAM)\nSigmoid Jz\nVerwendet Schwarz-Ev Weiß-Ev +HISTORY_MSG_1148;(sel. Editieren - CIECAM)\nSigmoid Jz +HISTORY_MSG_1149;(sel. Editieren - CIECAM)\nSigmoid Q +HISTORY_MSG_1150;(sel. Editieren - CIECAM)\nSigmoid\nQuellen-Daten\nLOG-Kodierung HISTORY_MSG_BLSHAPE;(Erweitert - Wavelet)\nUnschärfeebenen\nUnschärfe nach Ebenen HISTORY_MSG_BLURCWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Buntheit HISTORY_MSG_BLURWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Helligkeit @@ -1492,8 +1495,8 @@ HISTORY_MSG_DEHAZE_ENABLED;(Details - Bildschleier entfernen) HISTORY_MSG_DEHAZE_SATURATION;(Details - Bildschleier entfernen)\nSättigung HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;(Details - Bildschleier entfernen)\nMaske anzeigen HISTORY_MSG_DEHAZE_STRENGTH;(Details - Bildschleier entfernen)\nIntensität -HISTORY_MSG_DIRPYRDENOISE_GAIN;(Details - Rauschreduzierung)\nHelligkeitskompensation -HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;(Sensor—Matrix)\nFarbinterpolation\nAuto-Kontrastschwelle +HISTORY_MSG_DIRPYRDENOISE_GAIN;Details - Rauschminderung)\nKompensation nach Bildhelligkeit +HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;(RAW - Sensor-Matrix)\nFarbinterpolation\nAuto-Kontrastschwelle HISTORY_MSG_DUALDEMOSAIC_CONTRAST;(RAW - Sensor-Matrix)\nFarbinterpolation\nKontrastschwelle HISTORY_MSG_EDGEFFECT;(Erweitert - Wavelet)\nKantenschärfung\nDämpfungsreaktion HISTORY_MSG_FF_FROMMETADATA;(RAW- Weißbild)\nFlat-Field - aus den Metadaten @@ -1510,16 +1513,23 @@ HISTORY_MSG_ICL_LABGRIDCIEXY;Cie xy-Diagramm HISTORY_MSG_ICM_AINTENT;Absicht Abstraktes Profil HISTORY_MSG_ICM_BLUX;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Blau X HISTORY_MSG_ICM_BLUY;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Blau Y +HISTORY_MSG_ICM_CAT;Matrixanpassung HISTORY_MSG_ICM_FBW;(Farbe - Farbmanagement)\nAbstraktes Profil\nSchwarz-Weiß HISTORY_MSG_ICM_GAMUT;(Farbe - Farbmanagement)\nAbstraktes Profil\nGamut-Kontrolle HISTORY_MSG_ICM_GREX;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Grün X HISTORY_MSG_ICM_GREY;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Grün Y +HISTORY_MSG_ICM_MIDTCIE;(Farbe - Farbmanagement)\nAbstraktes Profil\nMitteltöne HISTORY_MSG_ICM_OUTPUT_PRIMARIES;(Farbe - Farbmanagement)\nAbstraktes Profil\nAusgabeprofil Vorgaben HISTORY_MSG_ICM_OUTPUT_TEMP;(Farbe - Farbmanagement)\nAusgabeprofil\nIccV4-Illuminant D HISTORY_MSG_ICM_OUTPUT_TYPE;(Farbe - Farbmanagement)\nAusgabeprofil\nTyp HISTORY_MSG_ICM_PRESER;(Farbe - Farbmanagement)\nAbstraktes Profil\nPastelltöne erhalten HISTORY_MSG_ICM_REDX;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Rot X HISTORY_MSG_ICM_REDY;(Farbe - Farbmanagement)\nAbstraktes Profil\nVorgabe Rot Y +HISTORY_MSG_ICM_REFI;(Farbe - Farbmanagement)\nAbstraktes Profil\nFarbverfeinerung +HISTORY_MSG_ICM_SHIFTX;(Farbe - Farbmanagement)\nAbstraktes Profil\nFarbverfeinerung - Shift x +HISTORY_MSG_ICM_SHIFTY;(Farbe - Farbmanagement)\nAbstraktes Profil\nFarbverfeinerung - Shift y +HISTORY_MSG_ICM_SMOOTHCIE;(Farbe - Farbmanagement)\nAbstraktes Profil\nLichter glätten +HISTORY_MSG_ICM_TRCEXP;(Farbe - Farbmanagement) - Abstraktes Profil HISTORY_MSG_ICM_WORKING_GAMMA;(Farbe - Farbmanagement)\nAbstraktes Profil\nGamma Farbtonkennlinie HISTORY_MSG_ICM_WORKING_ILLUM_METHOD;(Farbe - Farbmanagement)\nAbstraktes Profil\nBelechtungsmethode HISTORY_MSG_ICM_WORKING_PRIM_METHOD;(Farbe - Farbmanagement)\nAbstraktes Profil\nZielvorwahl @@ -1531,9 +1541,74 @@ HISTORY_MSG_LOCALCONTRAST_DARKNESS;(Details - Lokaler Kontrast)\nDunkle Bereiche HISTORY_MSG_LOCALCONTRAST_ENABLED;(Details - Lokaler Kontrast) HISTORY_MSG_LOCALCONTRAST_LIGHTNESS;(Details - Lokaler Kontrast)\nHelle Bereiche HISTORY_MSG_LOCALCONTRAST_RADIUS;(Details - Lokaler Kontrast)\nRadius -HISTORY_MSG_LOCALLAB_TE_PIVOT;(Lokal - Schatten/Lichter)\nTonwert-Equalizer\nWichtung -HISTORY_MSG_LOCAL_DEHAZE_BLACK;(Lokal - Dunst entfernen)\nSchwarzpunkt -HISTORY_MSG_LOCAL_GAMUTMUNSEL;(Lokal - Spot)\nSpeziell\nFarbverschiebung vermeiden +HISTORY_MSG_LOCALLAB_TE_PIVOT;(sel. Editieren - Schatten/Lichter)\nTonwert-Equalizer\nWichtung +HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;(sel. Editieren - CIECAM)\nUnschärfemaske\nKontrast +HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;(sel. Editieren - CIECAM)\nUnschärfemaske\nFouriertransformation +HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;(sel. Editieren - CIECAM)\nUnschärfemaske\nRadius +HISTORY_MSG_LOCAL_CIEMASK_CHH;(sel. Editieren - CIECAM)\nUnschärfemaske\nKurve h(h) +HISTORY_MSG_LOCAL_CIEMASK_HIGH;(sel. Editieren - CIECAM)\nUnschärfemaske\nLichter +HISTORY_MSG_LOCAL_CIEMASK_SHAD;(sel. Editieren - CIECAM)\nUnschärfemaske\nSchatten +HISTORY_MSG_LOCAL_CIEMASK_STRU;(sel. Editieren - CIECAM)\nMaske\nIntensität Struktur +HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;(sel. Editieren - CIECAM)\nMaske\nStrukturmaske als Werkzeug +HISTORY_MSG_LOCAL_CIEMASK_WLC;(sel. Editieren - CIECAM)\nMaske\nWavelets L(L) +HISTORY_MSG_LOCAL_CIEMASK_WLEV;(sel. Editieren - CIECAM)\nMaske\nWavelets Ebenen +HISTORY_MSG_LOCAL_CIE_ANGGRAD;(sel. Editieren - CIECAM)\nVerlaufsfilter \nVerlaufswinkel +HISTORY_MSG_LOCAL_CIE_BLACKS;(sel. Editieren - CIECAM)\nSchwarz-Verteilung +HISTORY_MSG_LOCAL_CIE_BLUXL;(sel. Editieren - CIECAM)\Primärfarben und Lichtquelle\nBlau X +HISTORY_MSG_LOCAL_CIE_BLUYL;(sel. Editieren - CIECAM)\Primärfarben und Lichtquelle\nBlau Y +HISTORY_MSG_LOCAL_CIE_BRICOMP;(sel. Editieren - CIECAM)\nQuellen-Daten\nHelligkeitskompression +HISTORY_MSG_LOCAL_CIE_BRICOMPTH;(sel. Editieren - CIECAM)\nSchwellenwert Helligkeitskompression +HISTORY_MSG_LOCAL_CIE_BWCIE;(sel. Editieren - CIECAM)\nSchwarz-Weiß +HISTORY_MSG_LOCAL_CIE_CAT;(sel. Editieren - CIECAM)\nMatrix-Adaption +HISTORY_MSG_LOCAL_CIE_DETAILJZ;(sel. Editieren - JzCzHz)\nLokaler Kontrast +HISTORY_MSG_LOCAL_CIE_ENAMASKALL;(sel. Editieren - CIECAM)\nAlle Masken +HISTORY_MSG_LOCAL_CIE_EXPPRECAM;(sel. Editieren - CIECAM)\nQuell-Daten +HISTORY_MSG_LOCAL_CIE_GAM;(sel. Editieren - CIECAM)\nGamma +HISTORY_MSG_LOCAL_CIE_GAMUTCIE;(sel. Editieren - CIECAM)\nGamut +HISTORY_MSG_LOCAL_CIE_GREXL;(sel. Editieren - CIECAM)\nGrün X +HISTORY_MSG_LOCAL_CIE_GREYL;(sel. Editieren - CIECAM)\nGrün Y +HISTORY_MSG_LOCAL_CIE_ILL;(sel. Editieren - CIECAM)\nPrimärfarben und Lichtquelle\nBeleuchtung +HISTORY_MSG_LOCAL_CIE_LOGCIEQ;(sel. Editieren - CIECAM)\nLOG-Kodierung Q +HISTORY_MSG_LOCAL_CIE_MIDT;(sel. Editieren - CIECAM)\nMitteltöne +HISTORY_MSG_LOCAL_CIE_NORM;(sel. Editieren - CIECAM)\nSigmoid\nLuminanz normalisieren +HISTORY_MSG_LOCAL_CIE_PRIM;(sel. Editieren - CIECAM)\nTonwertkurve Primärfarben +HISTORY_MSG_LOCAL_CIE_REDXL;(sel. Editieren - CIECAM)\nRot X +HISTORY_MSG_LOCAL_CIE_REDYL;(sel. Editieren - CIECAM)\nRot Y +HISTORY_MSG_LOCAL_CIE_REFI;(sel. Editieren - CIECAM)\nFarben verfeinern +HISTORY_MSG_LOCAL_CIE_SATCIE;(sel. Editieren - CIECAM)\nSättigungskontrolle +HISTORY_MSG_LOCAL_CIE_SHIFTXL;(sel. Editieren - CIECAM)\nShift x +HISTORY_MSG_LOCAL_CIE_SHIFTYL;(sel. Editieren - CIECAM)\nShift y +HISTORY_MSG_LOCAL_CIE_SIG;(sel. Editieren - CIECAM)\nSigmoid +HISTORY_MSG_LOCAL_CIE_SIGADAP;(sel. Editieren - CIECAM)\nSigmoid Anpassung +HISTORY_MSG_LOCAL_CIE_SIGMET;(sel. Editieren - CIECAM)\nSigmoid Methode +HISTORY_MSG_LOCAL_CIE_SLOP;(sel. Editieren - CIECAM)\nSteigung +HISTORY_MSG_LOCAL_CIE_SLOPESMO;(sel. Editieren - CIECAM)\nQuelldaten\nGraubalance +HISTORY_MSG_LOCAL_CIE_SLOPESMOB;(sel. Editieren - CIECAM)\nQuelldaten\nBlaubalance +HISTORY_MSG_LOCAL_CIE_SLOPESMOG;(sel. Editieren - CIECAM)\nQuelldaten\nGrünbalance +HISTORY_MSG_LOCAL_CIE_SLOPESMOR;(sel. Editieren - CIECAM)\nQuelldaten\nRotbalance +HISTORY_MSG_LOCAL_CIE_SMOOTH;(sel. Editieren - CIECAM)\nQuelldaten\nSkalierung Yb Szene +HISTORY_MSG_LOCAL_CIE_SMOOTHMET;(sel. Editieren - CIECAM)\nMethode Lichtdämpfung +HISTORY_MSG_LOCAL_CIE_SMOOTHYB;(sel. Editieren - CIECAM)\nQuelldaten\nSkalierung Yb Ansicht +HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;(sel. Editieren - CIECAM)\nEbenen - Helligkeitsmodus +HISTORY_MSG_LOCAL_CIE_STRGRAD;(sel. Editieren - CIECAM)\nVerlaufsfilter\nVerlaufsstärke L +HISTORY_MSG_LOCAL_CIE_STRLOG;(sel. Editieren - CIECAM)\nQuellen-Daten\nLOG-Kodierung Stärke +HISTORY_MSG_LOCAL_CIE_TRC;(sel. Editieren - CIECAM)\Farbtonkennlinie +HISTORY_MSG_LOCAL_CIE_WHITES;(sel. Editieren - CIECAM)\nWeiß-Verteilung +HISTORY_MSG_LOCAL_DEHAZE_BLACK;(sel. Editieren - Dunst entfernen\nSchwarzpunkt +HISTORY_MSG_LOCAL_FEATHERCIE;(sel. Editieren - CIECAM)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERCOL;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHEREXE;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERLOG;(sel. Editieren - LOG-Kodierung)\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERMAS;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERSH;(sel. Editieren - Schatten/Lichter)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERVIB;(sel. Editieren - Farbtemperatur)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_FEATHERWAV;(sel. Editieren - Wavelet)\nVerlaufsfilter\nVerlaufsbreite +HISTORY_MSG_LOCAL_GAMUTMUNSEL;(sel. Editieren - Spot)\nSpeziell\nFarbverschiebung vermeiden +HISTORY_MSG_LOCAL_LOG_BLACKS;(sel. Editieren - LOG-Kodierung)\nSchwarz-Verteilung +HISTORY_MSG_LOCAL_LOG_COMPR;(sel. Editieren - LOG-Kodierung)\nHelligkeitskompression +HISTORY_MSG_LOCAL_LOG_SAT;(sel. Editieren - LOG-Kodierung)\nSättigungskontrolle +HISTORY_MSG_LOCAL_LOG_WHITES;(sel. Editieren - LOG-Kodierung)\nWeissverteilung +HISTORY_MSG_LOCAL_TMO_SATUR;(sel. Editieren - Dynamik u. Belichtung)\nDynamikkompression\nSättigungskontrolle HISTORY_MSG_METADATA_MODE;(Metadaten)\nKopiermodus HISTORY_MSG_MICROCONTRAST_CONTRAST;(Details - Mikrokontrast)\nKontrastschwelle HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST;(RAW - Eingangsschärfung)\nAuto-Schwelle @@ -1625,10 +1700,21 @@ HISTORY_MSG_WAVTHREND;(Erweitert - Wavelet)\nEndretusche - finales Glätten\nSch HISTORY_MSG_WAVUSHAMET;(Erweitert - Wavelet)\nSchärfemaske und Klarheit\nMethode HISTORY_MSG_WBALANCE_OBSERVER10;(Farbe - Weißabgleich)\nBeobachter 10° HISTORY_MSG_WBITC_CUSTOM;(Farbe - Weißabgleich)\nTemperaturbezogen - Benutzerdefiniert +HISTORY_MSG_WBITC_DELTA;(Farbe - Weißabgleich)\nDelta grün +HISTORY_MSG_WBITC_FGREEN;(Farbe - Weißabgleich)\nGrün - Kandidat +HISTORY_MSG_WBITC_FORCE;(Farbe - Weißabgleich)\nerzwingen HISTORY_MSG_WBITC_GREEN;(Farbe - Weißabgleich)\nGrün-Verfeinerung -HISTORY_MSG_WBITC_MINSIZE;(Farbe-Weißabgleich)\nPatch Mindestgröße -HISTORY_MSG_WBITC_OBS;(Farbe - Weißabgleich)\n2-Wege-Algorithmus entfernt +HISTORY_MSG_WBITC_MINSIZE;(Farbe - Weißabgleich)\nPatch Mindestgröße +HISTORY_MSG_WBITC_NOPURPLE;(Farbe - Weißabgleich)\n Kein Violett +HISTORY_MSG_WBITC_OBS;(Farbe - Weißabgleich)\n2-Wege-Algorithmus entfernen +HISTORY_MSG_WBITC_PONDER;(Farbe - Weißabgleich)\ngemäßigt +HISTORY_MSG_WBITC_PRECIS;(Farbe - Weißabgleich)\nPräzision HISTORY_MSG_WBITC_PRIM;(Farbe - Weißabgleich)\nWahl der Abtastung +HISTORY_MSG_WBITC_RGREEN;(Farbe - Weißabgleich)\nGrünbereich +!HISTORY_MSG_WBITC_SAMPLING;Low sampling +HISTORY_MSG_WBITC_SIZE;(Farbe - Weißabgleich)\nGröße +HISTORY_MSG_WBITC_SORTED;(Farbe - Weißabgleich)\ngemäßigt +HISTORY_MSG_WBITC_THRES;(Farbe - Weißabgleich)\nSchwellenwert HISTORY_NEWSNAPSHOT;Hinzufügen HISTORY_NEWSNAPSHOT_TOOLTIP;Taste: Alt + s HISTORY_SNAPSHOT;Schnappschuss @@ -1771,7 +1857,7 @@ MAIN_TAB_FAVORITES_TOOLTIP;Taste: Alt + u MAIN_TAB_FILTER;Filter MAIN_TAB_INSPECT;Inspektor MAIN_TAB_IPTC;IPTC -MAIN_TAB_LOCALLAB;Lokal +MAIN_TAB_LOCALLAB;Selektives Editieren MAIN_TAB_LOCALLAB_TOOLTIP;Taste: Alt-o MAIN_TAB_METADATA;Metadaten MAIN_TAB_METADATA_TOOLTIP;Taste: Alt + m @@ -1792,7 +1878,7 @@ MAIN_TOOLTIP_PREVIEWFOCUSMASK;Vorschau Fokusmaske\nTaste: Umschalt + f MAIN_TOOLTIP_PREVIEWG;Vorschau Grün-Kanal\nTaste: g MAIN_TOOLTIP_PREVIEWL;Vorschau Helligkeit\nTaste: v\n\n0.299·R + 0.587·G + 0.114·B MAIN_TOOLTIP_PREVIEWR;Vorschau Rot-Kanal\nTaste: r -MAIN_TOOLTIP_PREVIEWSHARPMASK;Schärfungs-Kontroll-Maske ein-/ausschalten.\n\nFunktioniert nur bei aktivierter Schärfung und Zoom >= 100%.\nTaste: p +MAIN_TOOLTIP_PREVIEWSHARPMASK;Schärfungs-Kontroll-Maske ein-/ausschalten.\n\nFunktioniert nur bei aktivierter Schärfung und Zoom >= 100%.\nTaste: p oder wenn Eingangsschärfung aktiviert ist. MAIN_TOOLTIP_QINFO;Bildinformationen ein-/ausblenden.\nTaste: i MAIN_TOOLTIP_SHOWHIDELP1;Linkes Bedienfeld ein-/ausblenden.\nTaste: l MAIN_TOOLTIP_SHOWHIDERP1;Rechtes Bedienfeld ein-/ausblenden.\nTaste: Alt + l @@ -1858,8 +1944,8 @@ PARTIALPASTE_LABCURVE;L*a*b* - Einstellungen PARTIALPASTE_LENSGROUP;Objektivkorrekturen PARTIALPASTE_LENSPROFILE;Objektivkorrekturprofil PARTIALPASTE_LOCALCONTRAST;Lokaler Kontrast -PARTIALPASTE_LOCALLAB;Lokale Anpassungen -PARTIALPASTE_LOCALLABGROUP;Lokale Anpassungen +PARTIALPASTE_LOCALLAB;Selektives Editieren +PARTIALPASTE_LOCALLABGROUP; Einstellungen f. Selektives Editieren PARTIALPASTE_METADATA;Kopiermodus PARTIALPASTE_METAGROUP;Metadaten PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter @@ -1916,6 +2002,9 @@ PREFERENCES_BEHADDALLHINT;Setzt alle Parameter auf Hinzufügen.\nAnpassun PREFERENCES_BEHAVIOR;Verhalten PREFERENCES_BEHSETALL;Alle setzen PREFERENCES_BEHSETALLHINT;Setzt alle Parameter auf Setzen.\nAnpassungen der Parameter in der Hintergrundstapelverarbeitung werden als Absolut zu den gespeicherten Werten interpretiert. +PREFERENCES_BROWSERECURSIVEDEPTH;Unterordner durchsuchen +PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Verknüfungen in Unterordnern durchsuchen +PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximale Anzahl Unterordner PREFERENCES_CACHECLEAR;Löschen PREFERENCES_CACHECLEAR_ALL;Alle Dateien im Zwischenspeicher löschen: PREFERENCES_CACHECLEAR_ALLBUTPROFILES;Alle Dateien im Zwischenspeicher löschen mit Ausnahme der Bearbeitungsprofile: @@ -1938,13 +2027,13 @@ PREFERENCES_CLUTSCACHE;HaldCLUT-Zwischenspeicher PREFERENCES_CLUTSCACHE_LABEL;Maximale Anzahl CLUTs im Zwischenspeicher PREFERENCES_CLUTSDIR;HaldCLUT-Verzeichnis PREFERENCES_CMMBPC;Schwarzpunkt-Kompensation -PREFERENCES_COMPLEXITYLOC;Vorgabe Komplexität für Lokale Anpassungen +PREFERENCES_COMPLEXITYLOC;Vorgabe Komplexität für Selektives Editieren PREFERENCES_COMPLEXITY_EXP;Erweitert PREFERENCES_COMPLEXITY_NORM;Standard PREFERENCES_COMPLEXITY_SIMP;Basis -PREFERENCES_CROP;Einstellung des Ausschnittswerkzeuges +PREFERENCES_CROP;Einstellung des Ausschnittwerkzeuges PREFERENCES_CROP_AUTO_FIT;Automatischer Zoom des Ausschnitts -PREFERENCES_CROP_GUIDES;Hilfslinien anzeigen wenn Ausschnitt nicht verändert wird +PREFERENCES_CROP_GUIDES;Hilfslinien anzeigen, wenn Ausschnitt nicht verändert wird PREFERENCES_CROP_GUIDES_FRAME;Rahmen PREFERENCES_CROP_GUIDES_FULL;Vorgabe des Ausschnittswerkzeuges PREFERENCES_CROP_GUIDES_NONE;Keine @@ -2001,7 +2090,7 @@ PREFERENCES_HISTOGRAM_TOOLTIP;Wenn aktiviert, wird das Arbeitsprofil für die Da PREFERENCES_HLTHRESHOLD;Lichter - Schwelle PREFERENCES_ICCDIR;ICC-Profile-Verzeichnis PREFERENCES_IMPROCPARAMS;Standard-Bearbeitungsprofile -PREFERENCES_INSPECTORWINDOW;Inspektor in eigenem Fullscreen-Fenster öffnen +PREFERENCES_INSPECTORWINDOW;Inspektor in eigenem Fullscreen-Fenster öffnen PREFERENCES_INSPECT_LABEL;Bildzwischenspeicher PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximale Anzahl Bilder im Zwischenspeicher PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Legt die maximale Anzahl Bilder fest, die im Zwischenspeicher gehalten werden, wenn man in der Dateiverwaltung mit der Maus über ein Bild fährt.\n\nAuf Systemen mit nicht mehr als 2GB RAM sollte der Wert nicht größer als 2 gewählt werden. @@ -2017,6 +2106,7 @@ PREFERENCES_LENSFUNDBDIR_TOOLTIP;Verzeichnis, in dem sich die Lensfun Datenbank PREFERENCES_LENSPROFILESDIR;Verzeichnis der Objektivprofile PREFERENCES_LENSPROFILESDIR_TOOLTIP;Verzeichnis, das die Adobe Lens Correction Profiles (LCPs) enthält PREFERENCES_MAXRECENTFOLDERS;Maximale Anzahl der letzten Dateien +PREFERENCES_MAX_ZOOM_TITLE;Maximale Vergrößerung PREFERENCES_MENUGROUPEXTPROGS;Untermenü 'Öffnen mit' PREFERENCES_MENUGROUPFILEOPERATIONS;Untermenü Dateioperationen PREFERENCES_MENUGROUPLABEL;Untermenü Farbmarkierung @@ -2042,7 +2132,7 @@ PREFERENCES_PANFACTORLABEL;Mausgeschwindigkeit beim Bewegen von Bildern PREFERENCES_PARSEDEXT;Dateitypen anzeigen PREFERENCES_PARSEDEXTADD;Dateityp PREFERENCES_PARSEDEXTADDHINT;Dateityp zur Liste hinzufügen -PREFERENCES_PARSEDEXTDELHINT;Ausgewählten Dateityp aus Liste entfernen +PREFERENCES_PARSEDEXTDELHINT;Ausgewählten Dateityp aus der Liste entfernen.\nVordefinierte Dateitypen können nicht gelöscht werden. PREFERENCES_PARSEDEXTDOWNHINT;Ausgewählten Dateityp nach unten verschieben. PREFERENCES_PARSEDEXTUPHINT;Ausgewählten Dateityp nach oben verschieben. PREFERENCES_PERFORMANCE_MEASURE;Messung aktivieren @@ -2067,6 +2157,8 @@ PREFERENCES_PROPERTY;Eigenschaft PREFERENCES_PRTINTENT;Wiedergabe PREFERENCES_PRTPROFILE;Farbprofil PREFERENCES_PSPATH;Adobe Photoshop Installationsverzeichnis +PREFERENCES_RAW_DECODER;Raw Decoder +PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;LibRaw verwenden PREFERENCES_REMEMBERZOOMPAN;Zoom und Bildposition merken PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;Öffnen eines neuen Bildes mit den Zoom- und Positionswerten des vorangegangenen Bildes.\n\nFunktioniert nur unter folgenden Bedingungen:\nEin-Reitermodus aktiv\n'Demosaikmethode für 100%-Ansicht' muss auf 'Wie im Bildverarbeitungsprofil vorgegeben' eingestellt sein. PREFERENCES_SAVE_TP_OPEN_NOW;Werkzeugstatus jetzt speichern @@ -2079,7 +2171,7 @@ PREFERENCES_SHOWBASICEXIF;Exif-Daten anzeigen PREFERENCES_SHOWDATETIME;Datum und Uhrzeit anzeigen PREFERENCES_SHOWEXPOSURECOMPENSATION;Belichtungskorrektur anfügen PREFERENCES_SHOWFILMSTRIPTOOLBAR;Toolbar oberhalb des Filmstreifens anzeigen -PREFERENCES_SHOWTOOLTIP;Anzeigen der Tooltips für Lokale Anpassungen +PREFERENCES_SHOWTOOLTIP;Anzeigen der Tooltips für selektives Editieren PREFERENCES_SHTHRESHOLD;Schatten - Schwelle PREFERENCES_SINGLETAB;Ein-Reitermodus PREFERENCES_SINGLETABVERTAB;Ein-Reitermodus (vertikale Reiter) @@ -2087,6 +2179,7 @@ PREFERENCES_SND_HELP;Geben Sie einen Pfad zu einer Sound-Datei ein, oder geben S PREFERENCES_SND_LNGEDITPROCDONE;Bearbeitung abgeschlossen PREFERENCES_SND_QUEUEDONE;Warteschlange abgearbeitet PREFERENCES_SND_THRESHOLDSECS;Verzögerung in Sekunden +PREFERENCES_SPOTLOC;Vorgabe der Spot-Methode für das selektive Editieren PREFERENCES_STARTUPIMDIR;Bildverzeichnis beim Programmstart PREFERENCES_TAB_BROWSER;Dateiverwaltung PREFERENCES_TAB_COLORMGR;Farbmanagement @@ -2100,20 +2193,28 @@ PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Eingebundenes JPEG PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Bildanzeige PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrales RAW-Bild PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Eingebundenes JPEG wenn in Originalgröße, sonst neutrales RAW-Bild +PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Laden/Speichern Miniaturbilder Bewertung und Farbe von/nach XMP Bearbeitungsprofil (sidecar) PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Verfügbare Werkzeuge PREFERENCES_TOOLPANEL_CLONE_FAVORITES;Belasse favorisierte Werkzeuge auch im Original-Tab PREFERENCES_TOOLPANEL_CLONE_FAVORITES_TOOLTIP;Wenn aktiviert, werden favorisierte Werkzeuge in beiden Tabs erscheinen, in den Favoriten und im ursprünglichen Tab.\n\nMerke: Die Aktivierung dieser Option könnte zu geringfügigen Verzögerungen während des Tab-Wechsels führen. PREFERENCES_TOOLPANEL_FAVORITE;Favorit -PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favorites Panel +PREFERENCES_TOOLPANEL_FAVORITESPANEL;Favoriten Panel PREFERENCES_TOOLPANEL_TOOL;Tool PREFERENCES_TP_LABEL;Werkzeugbereich: PREFERENCES_TP_VSCROLLBAR;Keine vertikale Scrollbar PREFERENCES_USEBUNDLEDPROFILES;Standardprofile verwenden PREFERENCES_WBA;Weißabgleich -PREFERENCES_WBACORR;Weissabgleich - automatische Temperaturkorrelation -PREFERENCES_WBACORR_TOOLTIP;Diese Einstellungen ermöglichen, abhängig von den Bildern (Art der Rohdatei, Farbmetrik usw.), eine Anpassung des Algorithmus "Temperaturkorrelation", um die besten Gesamtergebnisse zu erzielen. Es gibt keine absolute Regel, diese Parameter mit den erhaltenen Ergebnissen zu verknüpfen.\n\nEs gibt drei Arten von Einstellungen: \n* solche, die für den Benutzer über die GUI zugänglich sind.\n* solche, die nur beim Lesen aus jeder pp3-Datei zugänglich sind\n* diejenigen, auf die der Benutzer in "Optionen" zugreifen kann (siehe Rawpedia)\n Sie können "AWB-Temperatur-Bias" und "Grün-Verfeinerung" verwenden, um die Ergebnisse anzupassen. Jede Veränderung führt zu einer Neuberechnung von Temperatur, Farbton und Bezug.\n\nBitte beachten Sie, dass die drei Indikatoren "Bezugsfaktor", "Patch-Chroma" und ΔE nur zur Information dienen. Nur weil einer dieser Indikatoren besser ist, ist das Ergebnis nicht zwangsläufig besser. +PREFERENCES_WBACORR;Weißabgleich - automatische Temperaturkorrelation +PREFERENCES_WBACORR_TOOLTIP;Diese Einstellungen ermöglichen, abhängig von den Bildern (Art der Rohdatei, Farbmetrik usw.), eine Anpassung des Algorithmus 'Temperaturkorrelation', um die besten Gesamtergebnisse zu erzielen. Es gibt keine absolute Regel, diese Parameter mit den erhaltenen Ergebnissen zu verknüpfen.\n\nEs gibt drei Arten von Einstellungen: \n* solche, die für den Benutzer über die GUI zugänglich sind.\n* solche, die nur beim Lesen aus jeder pp3-Datei zugänglich sind\n* diejenigen, auf die der Benutzer in 'Optionen' zugreifen kann (siehe Rawpedia)\n Sie können 'AWB-Temperatur-Bias' und 'Grün-Verfeinerung' verwenden, um die Ergebnisse anzupassen. Jede Veränderung führt zu einer Neuberechnung von Temperatur, Farbton und Bezug.\n\nBitte beachten Sie, dass die drei Indikatoren 'Bezugsfaktor', 'Patch-Chroma' und ΔE nur zur Information dienen. Nur weil einer dieser Indikatoren besser ist, ist das Ergebnis nicht zwangsläufig besser. PREFERENCES_WBAENA;Zeige Einstellungen der Temperaturkorrelation bei automatischem Weißabgleich PREFERENCES_WBAENACUSTOM;Benutzerdefinierte Temperatur und Tönung +PREFERENCES_WBAFORC;Erzwingt extra Algorithmus +!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) +PREFERENCES_WBANOPURP;Keine lila Farben verwendet +!PREFERENCES_WBAPATCH;Number maximum of colors used in picture +PREFERENCES_WBAPRECIS;Präzision Algorithmus - skaliert +!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color +PREFERENCES_WBASORT;Chromatische Sortierung anstatt nach Histogramm PREFERENCES_WORKFLOW;Layout PREFERENCES_XMP_SIDECAR_MODE;Datei-Endung für XMP (Sidecar) PREFERENCES_XMP_SIDECAR_MODE_EXT;wie Darktable (DATEINAME.ext.xmp für DATEINAME.ext) @@ -2146,7 +2247,7 @@ PROGRESSBAR_LINEDENOISE;Linienrauschfilter... PROGRESSBAR_LOADING;Lade Bild... PROGRESSBAR_LOADINGTHUMBS;Lade Miniaturbilder... PROGRESSBAR_LOADJPEG;Lade JPEG... -PROGRESSBAR_LOADJXL;Lade JXL... +PROGRESSBAR_LOADJXL;Lade JXL ... PROGRESSBAR_LOADPNG;Lade PNG... PROGRESSBAR_LOADTIFF;Lade TIFF... PROGRESSBAR_NOIMAGES;Keine Bilder gefunden @@ -2167,10 +2268,31 @@ QINFO_PIXELSHIFT;Pixel-Shift / %2 Frame(s) QUEUE_AUTOSTART;Automatisch starten QUEUE_AUTOSTART_TOOLTIP;Bei neuem Job die Verarbeitung automatisch starten QUEUE_DESTFILENAME;Pfad und Dateiname +QUEUE_DESTPREVIEW_TITLE;Wähle ein Vorschaubild aus um den Zielpfad hier anzuzeigen +QUEUE_DESTPREVIEW_TOOLTIP;Der Zielpfad für das zuerst ausgewählte Bild erscheint hier QUEUE_FORMAT_TITLE;Dateiformat QUEUE_LOCATION_FOLDER;In dieses Verzeichnis speichern QUEUE_LOCATION_TEMPLATE;Dynamisches Verzeichnis verwenden -QUEUE_LOCATION_TEMPLATE_TOOLTIP;Die folgenden Variablen können verwendet werden:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nDiese Variablen beinhalten bestimmte Teile des Verzeichnispfades, in welchem sich das 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. +QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Anzeigen oder Ausblenden eines Hilfe-Fenster mit der Anleitung zur Erstellung von Ausgabe-Templates +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;Wenn Sie das Ausgabebild zusammen mit dem Quellbild speichern möchten, schreiben Sie:\n%p1/%f\n\nWenn Sie das Ausgabebild in einem Ordner mit dem Namen „converted“ im Ordner des Quellfotos speichern möchten, schreiben Sie:\n%p1/converted/%f\n\nWenn Sie das Ausgabebild in\n„/home/tom/photos/converted/2010-10-31“ speichern möchten, schreiben Sie:\n%p-3/converted/%P-4/%f +QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Beispiele +QUEUE_LOCATION_TEMPLATE_HELP_INTRO;Mit dem Feld „Ausgabevorlage“ können Sie den Zielordner und den Dateinamen dynamisch anpassen. Wenn Sie bestimmte Platzhalter einfügen, die mit % beginnen, werden diese beim Speichern jeder Datei vom Programm ersetzt.\n\nDie folgenden Abschnitte beschreiben die einzelnen Platzhaltertypen. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Zum Beispiel dieser Pfad: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The Bedeutungen der Formatierungs-Platzhalter sind: +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;Die Platzhalter %dN, %d-N, %pN, %p-N, %PN und %P-N (N = 1..9) werden durch Elemente des Verzeichnispfads der Bilddatei ersetzt.\nDie Formatplatzhalter funktionieren wie folgt:\n %dN = N-tes Verzeichnis vom Ende des Pfads\n %d-N = N-tes Verzeichnis vom Anfang des Pfads\n %pN = alle Verzeichnisse bis zum N-ten vom Ende des Pfads\n %p-N = die ersten N Verzeichnisse im Pfad\n %PN = die letzten N Verzeichnisse im Pfad\n %P-N = alle Verzeichnisse vom N-ten bis zum Ende des Pfads\n %f = Basis Dateiname (keine Erweiterung) +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;Bei Windows-Pfaden ist %d-1 der Laufwerksbuchstabe und der Doppelpunkt und %d-2 das Basisverzeichnis auf diesem Laufwerk. +QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Verzeichnisse und Teilpfade +QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r wird durch den Rang des Fotos ersetzt. Wenn das Foto keinen Rang hat, wird „0“ verwendet. Wenn das Foto im Papierkorb liegt, wird „x“ verwendet. +QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rang +QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2tes Ergebnis ist anders: +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 werden durch die Anfangsposition des Fotos in der zum Zeitpunkt des Starts der Warteschlange ersetzt. Die Zahl gibt die Auffüllung an, z. B. ergibt %s3 „001“. +QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position in der Warteschlange +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;In Vorlagen können drei verschiedene Datums-/Zeitwerte verwendet werden:\n %tE"%Y-%m-%d" = wann der Export gestartet wurde\n %tF"%Y-%m-%d" = wann die Datei zuletzt gespeichert wurde\n %tP"%Y-%m-%d" = wann das Foto aufgenommen wurde\nDie in Anführungszeichen gesetzte Zeichenfolge definiert das Format des resultierenden Datums und/oder der resultierenden Uhrzeit. Die Formatzeichenfolge %tF"%Y-%m-%d" ist nur ein Beispiel. Die Zeichenfolge kann alle für die Funktion g_date_time_format definierten Konvertierungsplatzhalter verwenden (siehe https://docs.gtk.org/glib/method.DateTime.format.html).\n\nBeispielformatzeichenfolgen: +QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Datum und Uhrzeit +QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Erstellen einer Ausgabevorlage +QUEUE_LOCATION_TEMPLATE_TOOLTIP;Geben Sie den Ausgabeort basierend auf Merkmalen wie dem Speicherort, Rang, Papierkorbstatus oder der Position in der Warteschlange des Quellfotos an.\n\nDer Feldwert der Ausgabevorlage kann Platzhalter enthalten, die mit % beginnen und im tatsächlichen Zielpfad durch diese Merkmale ersetzt werden.\n\nDrücken Sie die Taste ?, um vollständige Anweisungen zu erhalten. QUEUE_LOCATION_TITLE;Ausgabeverzeichnis QUEUE_STARTSTOP_TOOLTIP;Startet/Stoppt die Verarbeitung der Warteschlange.\n\nTaste: Strg + s SAMPLEFORMAT_0;Unbekanntes Datenformat @@ -2209,12 +2331,16 @@ SORT_BY_LABEL;Nach Farbmarkierung SORT_BY_NAME;Nach Name SORT_BY_RANK;Nach Bewertung SORT_DESCENDING;Absteigend +TC_LOCALLAB_PRIM_SHIFTX;Shift x +TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In Kombination mit „Farben verfeinern“ können Sie:\n 1) bei niedrigen Werten die Bildreinheit anpassen.\n 2) bei höheren Werten eine moderate Farbtönung durchführen.\nAchten Sie darauf, das CIE-XY-Diagramm nicht zu verlassen. +TC_LOCALLAB_PRIM_SHIFTY;Shift y TC_PRIM_BLUX;Bx TC_PRIM_BLUY;By TC_PRIM_GREX;Gx TC_PRIM_GREY;Gy TC_PRIM_REDX;Rx TC_PRIM_REDY;Ry +TC_PRIM_REFI;Farben verfeinern (Weißpunkt) THRESHOLDSELECTOR_B;Unten THRESHOLDSELECTOR_BL;Unten-Links THRESHOLDSELECTOR_BR;Unten-Rechts @@ -2498,7 +2624,7 @@ TP_DIRPYRDENOISE_CHROMINANCE_FRAME;Chrominanz TP_DIRPYRDENOISE_CHROMINANCE_MANUAL;Benutzerdefiniert TP_DIRPYRDENOISE_CHROMINANCE_MASTER;Chrominanz (Master) TP_DIRPYRDENOISE_CHROMINANCE_METHOD;Methode -TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Benutzerdefiniert:\nManuelle Anpassung der Chrominanz-Rauschreduzierung.\n\nAutomatisch Global:\nEs werden 9 Zonen für die Berechnung der Chrominanz-Rauschreduzierung verwendet.\n\nVorschau:\nNur der sichbare Teil des Bildes wird für die Berechnung der Chrominanz-Rauschreduzierung verwendet. +TP_DIRPYRDENOISE_CHROMINANCE_METHODADVANCED_TOOLTIP;Benutzerdefiniert:\nManuelle Anpassung der Chrominanz-Rauschreduzierung.\n\nAutomatisch Global:\nEs werden 9 Zonen für die Berechnung der Chrominanz-Rauschreduzierung verwendet.\n\nVorschau:\nNur der sichtbare Teil des Bildes wird für die Berechnung der Chrominanz-Rauschreduzierung verwendet. TP_DIRPYRDENOISE_CHROMINANCE_METHOD_TOOLTIP;Benutzerdefiniert:\nManuelle Anpassung der Chrominanz-Rauschreduzierung.\n\nAutomatisch Global:\nEs werden 9 Zonen für die Berechnung der Chrominanz-Rauschreduzierung verwendet.\n\nAuto-Multizonen:\nKeine Voransicht - wird erst beim Speichern angewendet.\nIn Abhängigkeit von der Bildgröße, wird das Bild in ca. 10 bis 70 Kacheln aufgeteilt. Für jede Kachel wird die Chrominanz-Rauschreduzierung individuell berechnet.\n\nVorschau:\nNur der sichtbare Teil des Bildes wird für die Berechnung der Chrominanz-Rauschreduzierung verwendet. TP_DIRPYRDENOISE_CHROMINANCE_PMZ;Vorschau TP_DIRPYRDENOISE_CHROMINANCE_PREVIEW;Vorschau @@ -2514,8 +2640,8 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminanzkurve TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Luminanzdetails TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminanz TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminanz -TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Helligkeitskompensation -TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Stärke der Rauschreduzierung basierend auf der Bildhelligkeit. Bei dunklen Bildern wird die Stärke verringert und bei hellen Bildern erhöht. +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Kompensation nach Bildhelligkeit +TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Ändern Sie die Stärke der Rauschunterdrückung basierend auf der Bildhelligkeit. Bei dunklen Bildern wird die Stärke verringert und bei hellen Bildern erhöht. TP_DIRPYRDENOISE_MAIN_COLORSPACE;Farbraum TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB @@ -2661,10 +2787,11 @@ TP_HSVEQUALIZER_VAL;V TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Basisbelichtung TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Die eingebettete DCP-Basisbelichtung verwenden.\nDie Einstellung ist nur verfügbar wenn sie vom Eingangsfarbprofil unterstützt wird. TP_ICM_APPLYHUESATMAP;Basistabelle -TP_ICM_APPLYHUESATMAP_TOOLTIP;Die eingebettete DCP-Basistabelle verwenden.\nDie Einstellung ist nur verfügbar wenn sie vom Eingangsfarbprofil unterstützt wird. +TP_ICM_APPLYHUESATMAP_TOOLTIP;Die eingebettete DCP-Basistabelle verwenden.\nDie Einstellung ist nur verfügbar, wenn sie vom Eingangsfarbprofil unterstützt wird. TP_ICM_APPLYLOOKTABLE;'Look'-Tabelle -TP_ICM_APPLYLOOKTABLE_TOOLTIP;Die eingebettete DCP-'Look'-Tabelle verwenden.\nDie Einstellung ist nur verfügbar wenn sie vom Eingangsfarbprofil unterstützt wird. +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Die eingebettete DCP-'Look'-Tabelle verwenden.\nDie Einstellung ist nur verfügbar, wenn sie vom Eingangsfarbprofil unterstützt wird. TP_ICM_BPC;Schwarzpunkt-Kompensation +TP_ICM_BW;Schwarz-Weiß TP_ICM_DCPILLUMINANT;Illumination TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoliert TP_ICM_DCPILLUMINANT_TOOLTIP;DCP-Illumination auswählen. Vorgabe ist 'Interpoliert'.\nDie Einstellung ist nur verfügbar, wenn sie vom Eingangsfarbprofil unterstützt wird. @@ -2679,7 +2806,7 @@ TP_ICM_INPUTCUSTOM;DCP/ICC-Profil TP_ICM_INPUTCUSTOM_TOOLTIP;Eigenes DCP/ICC-Farbprofil verwenden. TP_ICM_INPUTDLGLABEL;DCP/ICC-Profil wählen... TP_ICM_INPUTEMBEDDED;Eingebettetes Profil verwenden -TP_ICM_INPUTEMBEDDED_TOOLTIP;Farbprofil verwenden, das in Nicht-RAW-Bildern eingebettet ist. +TP_ICM_INPUTEMBEDDED_TOOLTIP;In der Datei eingebettetes Farbprofil verwenden. Falls nicht vorhanden, Kamera-Standard verwenden. TP_ICM_INPUTNONE;Kein Profil TP_ICM_INPUTNONE_TOOLTIP;Kein Eingangsfarbprofil verwenden. TP_ICM_INPUTPROFILE;Eingangsfarbprofil @@ -2702,9 +2829,16 @@ TP_ICM_SAVEREFERENCE_TOOLTIP;Speichern Sie das lineare TIFF-Bild bevor das Einga TP_ICM_TONECURVE;Tonwertkurve TP_ICM_TONECURVE_TOOLTIP;Eingebettete DCP-Tonwertkurve verwenden.\nDie Einstellung ist nur verfügbar, wenn sie vom Eingangsfarbprofil unterstützt wird. TP_ICM_TRCFRAME;Abstraktes Profil -TP_ICM_TRCFRAME_TOOLTIP;Auch bekannt als 'synthetisches' oder 'virtuelles' Profil, das am Ende der Verarbeitungspipeline (vor CIECAM) angewendet wird, sodass Sie benutzerdefinierte Bildeffekte erstellen können.\nSie können Änderungen vornehmen an:\n'Farbtonkennlinie': Ändert die Farbtöne des Bildes.\n'Beleuchtungsart': Ermöglicht Ihnen, die Profil-Primärfarben zu ändern, um sie an die Aufnahmebedingungen anzupassen.\n'Ziel-Primärfarben': Ermöglicht Ihnen, die Ziel-Primärfarben mit zwei Hauptanwendungen zu ändern - Kanalmischer und -kalibrierung.\nHinweis: Abstrakte Profile berücksichtigen die integrierten Arbeitsprofile, ohne sie zu ändern. Sie funktionieren nicht mit benutzerdefinierten Arbeitsprofilen. +TP_ICM_TRCFRAME_TOOLTIP;Auch bekannt als 'synthetisches' oder 'virtuelles' Profil, das am Ende der Verarbeitungspipeline (vor CIECAM) angewandt wird, sodass Sie benutzerdefinierte Bildeffekte erstellen können.\nSie können Änderungen vornehmen an:\n'Farbtonkennlinie': Ändert die Farbtöne des Bildes.\n'Beleuchtungsart': Ermöglicht Ihnen, die Profil-Primärfarben zu ändern, um sie an die Aufnahmebedingungen anzupassen.\n'Ziel-Primärfarben': Ermöglicht Ihnen, die Ziel-Primärfarben mit drei Hauptanwendungen zu ändern – Kanalmischer, Farbwiederherstellung (Sättigung) und Kalibrierung.\nHinweis: Abstrakte Profile berücksichtigen die integrierten Arbeitsprofile, ohne sie zu ändern. Sie funktionieren nicht mit benutzerdefinierten Arbeitsprofilen. TP_ICM_TRC_TOOLTIP;Ermöglicht Ihnen, die standardmäßige sRGB-'Farbtonkennlinie' in RT (g=2,4 s=12,92) zu ändern.\nDiese Farbtonkennlinie modifiziert die Farbtöne des Bildes. Die RGB- und Lab-Werte, das Histogramm und die Ausgabe (Bildschirm, TIF, JPG) werden geändert:\nGamma wirkt hauptsächlich auf helle Töne, Steigung wirkt hauptsächlich auf dunkle Töne.\nSie können ein beliebiges Paar von 'Gamma' und 'Steigung' (Werte >1) wählen, und der Algorithmus stellt sicher, dass zwischen den linearen und parabolischen Teilen der Kurve Kontinuität besteht.\nEine andere Auswahl als 'Keine' aktiviert die Menüs 'Lichtart' und 'Ziel-Primärfarben'. TP_ICM_WORKINGPROFILE;Arbeitsfarbraum +TP_ICM_WORKING_CAT;Matrix-Adaptation +TP_ICM_WORKING_CAT_BRAD;Bradford +TP_ICM_WORKING_CAT_CAT02;Cat02 +TP_ICM_WORKING_CAT_CAT16;Cat16 +TP_ICM_WORKING_CAT_TOOLTIP;Führt die chromatische Adaptation der XYZ-Konvertierungs-Matrix durch. Vorgabe Bradford +TP_ICM_WORKING_CAT_VK;Von Kries +TP_ICM_WORKING_CAT_XYZ;XYZ Skala TP_ICM_WORKING_CIEDIAG;CIE xy-Diagramm TP_ICM_WORKING_ILLU;Beleuchtung TP_ICM_WORKING_ILLU_1500;Tungsten 1500K @@ -2716,11 +2850,13 @@ TP_ICM_WORKING_ILLU_D60;D60 TP_ICM_WORKING_ILLU_D65;D65 TP_ICM_WORKING_ILLU_D80;D80 TP_ICM_WORKING_ILLU_D120;D120 +TP_ICM_WORKING_ILLU_E;E TP_ICM_WORKING_ILLU_NONE;Standard TP_ICM_WORKING_ILLU_STDA;Glühbirne Normlicht A 2875K +TP_ICM_WORKING_NON;Keine TP_ICM_WORKING_PRESER;Pastelltöne erhalten TP_ICM_WORKING_PRIM;Zielvorwahl -TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Wenn 'Benutzerdefiniert CIE xy-Diagramm' in der Combobox 'Zielvorwahl' ausgewählt ist, können die Werte der 3 Primärfarben direkt im Diagramm geändert werden.\nBeachten Sie, dass in diesem Fall die Weißpunktposition im Diagramm nicht aktualisiert wird. +TP_ICM_WORKING_PRIMFRAME_TOOLTIP;Wenn 'Benutzerdefiniertes CIE xy Diagramm' im Kombinationsfeld 'Zielvorwahl' ausgewählt ist, können Sie die Werte der 3 Primärfarben direkt im Diagramm ändern.\nBeachten Sie, dass in diesem Fall die Position des Weißpunkts im Diagramm nicht aktualisiert wird. TP_ICM_WORKING_PRIM_AC0;ACESp0 TP_ICM_WORKING_PRIM_ACE;ACESp1 TP_ICM_WORKING_PRIM_ADOB;Adobe RGB @@ -2729,11 +2865,14 @@ TP_ICM_WORKING_PRIM_BRU;BruceRGB TP_ICM_WORKING_PRIM_BST;BestRGB TP_ICM_WORKING_PRIM_CUS;Benutzerdefiniert (Regler) TP_ICM_WORKING_PRIM_CUSGR;Benutzerdefiniert (CIE xy-Diagramm) +TP_ICM_WORKING_PRIM_FREE;Benutzerdefiniert (Schieberegler) TP_ICM_WORKING_PRIM_JDCMAX;JDC Max +TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA TP_ICM_WORKING_PRIM_NONE;Standard TP_ICM_WORKING_PRIM_PROP;ProPhoto TP_ICM_WORKING_PRIM_REC;Rec2020 TP_ICM_WORKING_PRIM_SRGB;sRGB +TP_ICM_WORKING_PRIM_TOOLTIP;Führt eine Gamut-Kontrolle durch. Mit Ziel-Primärfarben (Erweitert) können Sie die Ziel-Primärfarben ändern, um die Bildfarbe (Sättigung) wiederherzustellen oder zu ändern. Die Farbbalance bleibt erhalten, wenn das 'Arbeitsprofil' und die 'Ziel-Primärfarben' ähnlich sind. 'Arbeitsprofile' werden nicht geändert. \nWenn 'Benutzerdefinierte Lokale Anpassungen (Schieberegler)' ausgewählt ist, können Sie die Werte der drei Primärfarben Rot, Grün, Blau für x und y ändern. TP_ICM_WORKING_PRIM_WID;WideGamut TP_ICM_WORKING_TRC;Farbtonkennlinie: TP_ICM_WORKING_TRC_18;ProPhoto g=1.8 @@ -2791,6 +2930,7 @@ TP_LENSGEOM_LOG;Logarithmisch TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatisch (Lensfun) TP_LENSPROFILE_CORRECTION_LCPFILE;LCP-Datei TP_LENSPROFILE_CORRECTION_MANUAL;Benutzerdefiniert (Lensfun) +TP_LENSPROFILE_CORRECTION_METADATA;aus den Meta-Daten TP_LENSPROFILE_LABEL;Objektivkorrekturprofil TP_LENSPROFILE_LENS_WARNING;Achtung: Der Crop-Faktor des Profils entspricht nicht dem der Kamera.\nDie Ergebnisse sind möglicherweise falsch. TP_LENSPROFILE_MODE_HEADER;Profilauswahl @@ -2812,7 +2952,7 @@ TP_LOCALLAB_ARTIF_TOOLTIP;Schwellenwert Bereich ΔE erhöht den Anwendungsbereic TP_LOCALLAB_AUTOGRAY;Automatisch mittlere Luminanz (Yb%) TP_LOCALLAB_AUTOGRAYCIE;Automatisch TP_LOCALLAB_AVOID;vermeide Farbverschiebungen -TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Passt Farben an den Arbeitsfarbraum an und wendet die Munsell-Korrektur an (Uniform Perceptual Lab).\nMunsell-Korrektur ist deaktiviert wenn Jz oder CAM16 oder 'Farberscheinung und Beleuchtung' angewendet wird.\n\nDefault: Munsell.\nMunsell-Korrektur: behebt Farbabweichungen im Lab-Modus aufgrund von Nichtlinearität, wenn die Chromatizität geändert wird (Uniform Perceptual Lab).\nLab: Wendet eine Gamut-Steuerung an, bei relativer Farbmetrik wird dann Munsell angewendet.\nXYZ +TP_LOCALLAB_AVOIDCOLORSHIFT_TOOLTIP;Passt Farben an den Arbeitsfarbraum an und wendet die Munsell-Korrektur an (Uniform Perceptual Lab). Voreinstellung: nur Munsell.\n\nnur Munsell: behebt Farbabweichungen im Lab-Modus aufgrund von Nichtlinearität, wenn die Chromatizität geändert wird (Uniform Perceptual Lab).\nLab: Wendet eine Gamut-Steuerung bei relativer Farbmetrik an, danach wird Munsell angewandt.\nXYZ absolut: Wendet eine Gamut-Steuerung bei absoluter Farbmetrik an, danach Munsell wird angewandt.\nXYZ relativ: Wendet eine Gamut-Steuerung bei relativer Farbmetrik an, danach Munsell wird angewandt. Das Ergebnis ist nicht das gleiche wie Lab. TP_LOCALLAB_AVOIDMUN;Nur Munsell-Korrektur TP_LOCALLAB_AVOIDMUN_TOOLTIP;Munsell-Korrektur ist deaktiviert, wenn Jz or CAM16 angewendet wird. TP_LOCALLAB_AVOIDRAD;Radius @@ -2855,9 +2995,12 @@ TP_LOCALLAB_BUTTON_DEL;Löschen TP_LOCALLAB_BUTTON_DUPL;Duplizieren TP_LOCALLAB_BUTTON_REN;Umbenennen TP_LOCALLAB_BUTTON_VIS;Ein-/Ausblenden +TP_LOCALLAB_BWEVNONE;Keine +TP_LOCALLAB_BWEVSIG;Aktiviert +TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Kodierung TP_LOCALLAB_BWFORCE;Schwarz-Ev & Weiß-Ev verwenden TP_LOCALLAB_CAM16PQREMAP;HDR PQ (Spitzenleuchtdichte) -TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) angepasst an CAM16. Ermöglicht die Änderung der internen PQ-Funktion (normalerweise 10000 cd/m2 - Standard 100 cd/m2 - deaktiviert für 100 cd/m2).\nKann zur Anpassung an verschiedene Geräte und Bilder verwendet werden. +TP_LOCALLAB_CAM16PQREMAP_TOOLTIP;PQ (Perceptual Quantizer) angepasst an CAM16(experimentell). Ermöglicht die Änderung der internen PQ-Funktion (normalerweise 10000 cd/m2 - Standard 100 cd/m2 - deaktiviert für 100 cd/m2).\nKann zur Anpassung an verschiedene Geräte und Bilder verwendet werden, z. Bsp. um die Cam16-Verarbeitung mit der maximalen Monitorhelligkeit von 400cd/m² abzustimmen. TP_LOCALLAB_CAM16_FRA;CAM16 Bildanpassungen TP_LOCALLAB_CAMMODE;CAM-Modell TP_LOCALLAB_CAMMODE_CAM16;CAM 16 @@ -2871,8 +3014,8 @@ TP_LOCALLAB_CBDL_TOOLNAME;Detailebenen-Kontrast TP_LOCALLAB_CENTER_X;Mitte X TP_LOCALLAB_CENTER_Y;Mitte Y TP_LOCALLAB_CH;Kurven CL - LC -TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mittel=%1 Hoch=%2 -TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mittel=%1 Hoch=%2 +TP_LOCALLAB_CHRO46LABEL;Chrominanz Ebenen 456: Mittel=%1 Hoch=%2 +TP_LOCALLAB_CHROLABEL;Chrominanz Ebenen 0123: Mittel=%1 Hoch=%2 TP_LOCALLAB_CHROMA;Chrominanz TP_LOCALLAB_CHROMABLU;Chrominanz-Ebenen TP_LOCALLAB_CHROMABLU_TOOLTIP;Erhöht oder verringert den Effekt abhängig von den Luma-Einstellungen.\nWerte kleiner 1 verringern den Effekt. Werte größer 1 erhöhen den Effekt. @@ -2884,7 +3027,7 @@ TP_LOCALLAB_CHROMASK_TOOLTIP;Ändert die Chrominanz der Maske, wenn eine existie TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chrominanz TP_LOCALLAB_CIE;CIECAM (CAM16 & JzCzHz) -TP_LOCALLAB_CIEC;CIECAM-Umgebungsparameter +TP_LOCALLAB_CIEC;Ciecam Umgebungs Parameter verwenden TP_LOCALLAB_CIECAMLOG_TOOLTIP;Dieses Modul basiert auf dem CIECAM-Farberscheinungsmodell, das entwickelt wurde, um das Sehen der menschlichen Farbwahrnehmung unter verschiedenen Lichtbedingungen zu simulieren.\nDer erste CIECAM-Prozess 'Szenebasierte Bedingungen' wird per LOG-Kodierung durchgeführt und verwendet 'Absolute Luminanz' zum Zeitpunkt der Aufnahme.\nDer zweite CIECAM-Prozess 'Bildkorrektur' wurde vereinfacht und nutzt nur 3 Variablen ('Lokaler Kontrast', 'Kontrast J', 'Sättigung s').\nDer dritte CIECAM-Prozess 'Anzeigebedingungen' passt die Ausgabe an das beabsichtigte Anzeigegerät (Monitor, TV, Projektor, Drucker, etc.) an, damit das chromatische und kontrastreiche Erscheinungsbild in der gesamten Anzeigeumgebung erhalten bleibt. TP_LOCALLAB_CIECOLORFRA;Farbe TP_LOCALLAB_CIECONTFRA;Kontrast @@ -2897,23 +3040,30 @@ TP_LOCALLAB_CIEMODE_TM;Tone-Mapping TP_LOCALLAB_CIEMODE_TOOLTIP;Im Standardmodus wird CIECAM am Ende des Prozesses hinzugefügt. 'Maske und Anpassungen' und 'Wiederherstellung auf Luminanzmaske' stehen für 'CAM16 und JzCzHz' zur Verfügung.\nAuf Wunsch kann CIECAM in andere Werkzeuge (TM, Wavelet, Dynamik, LOG-Kodierung) integriert werden. Das Ergebnis dieser Werkzeuge wird sich von denen ohne CIECAM unterscheiden. In diesem Modus können auch 'Maske und Anpassungen' und 'Wiederherstellung auf Luminanzmaske' angewendet werden. TP_LOCALLAB_CIEMODE_WAV;Wavelet TP_LOCALLAB_CIETOOLEXP;Kurven +TP_LOCALLAB_CIE_SMOOTHFRAME;Lichtdämpfung +TP_LOCALLAB_CIE_SMOOTH_EV;Ev basiert +TP_LOCALLAB_CIE_SMOOTH_GAMMA;Steigungs basiert +TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma basiert +TP_LOCALLAB_CIE_SMOOTH_LEVELS;Ebenen +TP_LOCALLAB_CIE_SMOOTH_NONE;Keine TP_LOCALLAB_CIE_TOOLNAME;Farberscheinung (Cam16 & JzCzHz) TP_LOCALLAB_CIRCRADIUS;Spot-Größe TP_LOCALLAB_CIRCRAD_TOOLTIP;Die Spot-Größe bestimmt die Referenzen des Spots, die für die Formerkennung nützlich sind (Farbton, Luma, Chroma, Sobel).\nNiedrige Werte können für die Bearbeitung kleiner Flächen und Strukturen nützlich sein.\nHohe Werte können für die Behandlung von größeren Flächen oder auch Haut nützlich sein. TP_LOCALLAB_CLARICRES;Chroma zusammenführen TP_LOCALLAB_CLARIFRA;Klarheit u. Schärfemaske - Überlagern u. Abschwächen -TP_LOCALLAB_CLARIJZ_TOOLTIP;Levels 0 bis 4 (einschließlich): ‘Schärfemaske’ ist aktiviert\nLevel 5 und darüber: 'Klarheit' ist aktiviert. +TP_LOCALLAB_CLARIJZ_TOOLTIP;Ebenen 0 bis 4 (einschließlich): 'Schärfemaske' ist aktiviert\nEbene 5 und darüber: 'Klarheit' ist aktiviert. TP_LOCALLAB_CLARILRES;Luma zusammenführen TP_LOCALLAB_CLARISOFT;Radius -TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;Der Regler ‘Radius’ (Algorithmus des anpassbaren Filters) reduziert Lichthöfe und Unregelmäßigkeiten für Klarheit, Schärfemaske und Wavelets Jz des lokalen Kontrastes. +TP_LOCALLAB_CLARISOFTJZ_TOOLTIP;Der Regler 'Radius' (Algorithmus des anpassbaren Filters) reduziert Lichthöfe und Unregelmäßigkeiten für Klarheit, Schärfemaske und Wavelets Jz des lokalen Kontrastes. TP_LOCALLAB_CLARISOFT_TOOLTIP;Der Regler 'Radius' (Algorithmus des anpassbaren Filters) reduziert Lichthöfe und Unregelmäßigkeiten für die Klarheit, die Schärfemaske und für alle Pyramiden-Wavelet-Prozesse. Zum Deaktivieren setzen Sie den Schieberegler auf Null. TP_LOCALLAB_CLARITYML;Klarheit -TP_LOCALLAB_CLARI_TOOLTIP;Levels 0 bis 4 (einschließlich): 'Schärfemaske' ist aktiviert\nLevel 5 und darüber: 'Klarheit' ist aktiviert.\nHilfreich bei 'Wavelet - Tonwertkorrektur' +TP_LOCALLAB_CLARI_TOOLTIP;Ebenen 0 bis 4 (einschließlich): 'Schärfemaske' ist aktiviert\nEbene 5 und darüber: 'Klarheit' ist aktiviert.\nHilfreich bei 'Wavelet - Tonwertkorrektur' TP_LOCALLAB_CLIPTM;Wiederhergestellte Daten beschneiden TP_LOCALLAB_COFR;Farbe und Licht TP_LOCALLAB_COLORDE;Vorschau Farbe - Intensität (ΔE) -TP_LOCALLAB_COLORDEPREV_TOOLTIP;Die Schaltfläche 'Vorschau ΔE' funktioniert nur, wenn Sie eines (und nur eines) der Werkzeuge im Menü 'Werkzeug zum aktuellen Spot hinzufügen' aktiviert haben.\nUm eine Vorschau von ΔE mit mehreren aktivierten Werkzeugen anzuzeigen, verwenden Sie 'Maske und Anpassungen' - Vorschau ΔE. +TP_LOCALLAB_COLORDEPREV_TOOLTIP;Die Schaltfläche 'ΔE-Vorschau' in den Einstellungen funktioniert nur, wenn Sie im Menü 'Werkzeug zum aktuellen Punkt hinzufügen' 'Schärfen', 'Weiches Licht und Original-Retinex', 'Weichzeichnen/Körnung und Rauschunterdrückung', 'Dunst entfernen und Retinex' oder 'Kontrast nach Detailstufen' aktiviert haben.\nBei anderen Werkzeugen befindet sich die Schaltfläche 'ΔE-Vorschau' im Werkzeug, die eine Vorschau von ΔE mit mehreren aktivierten Werkzeugen ermöglicht. Verwenden Sie vorzugsweise Maske und Modifikationen. TP_LOCALLAB_COLORDE_TOOLTIP;Zeigt eine blaue Farbvorschau für die ΔE-Auswahl an, wenn negativ, und grün, wenn positiv.\n\nMaske und Anpassungen (geänderte Bereiche ohne Maske anzeigen): Zeigt tatsächliche Änderungen an, wenn sie positiv sind, erweiterte Änderungen (nur Luminanz) mit Blau und Gelb, wenn sie negativ sind. +TP_LOCALLAB_COLORFRAME;Dominierende Farbe TP_LOCALLAB_COLORSCOPE;Bereich (Farbwerkzeuge) TP_LOCALLAB_COLORSCOPE_TOOLTIP;Regler für Farbe, Licht, Schatten, Highlights und Dynamik.\nAndere Werkzeuge haben ihre eigenen Kontrollregler für den Anwendungsbereich. TP_LOCALLAB_COLOR_CIE;Farbkurve @@ -2921,7 +3071,10 @@ TP_LOCALLAB_COLOR_TOOLNAME;Farbe und Licht TP_LOCALLAB_COL_NAME;Name TP_LOCALLAB_COL_VIS;Status TP_LOCALLAB_COMPFRA;Direktionaler Kontrast +TP_LOCALLAB_COMPRCIE;Helligkeits-Kompression +TP_LOCALLAB_COMPRCIETH;Kompression Schwellenwert TP_LOCALLAB_COMPREFRA;Tonwertkorrektur +TP_LOCALLAB_COMPRLOG_TOOLTIP;Dieser Algorithmus komprimiert die Daten vor der Log-Konvertierung über den Schwellenwert des Schiebereglers. Zu verwenden in Verbindung mit der Weiß-Verteilung. TP_LOCALLAB_CONTCOL;Schwellenwert Kontrast TP_LOCALLAB_CONTFRA;Ebenenkontrast TP_LOCALLAB_CONTRAST;Kontrast @@ -2945,13 +3098,14 @@ TP_LOCALLAB_CURVNONE;Kurven deaktivieren TP_LOCALLAB_DARKRETI;Dunkelheit TP_LOCALLAB_DEHAFRA;Dunst entfernen TP_LOCALLAB_DEHAZ;Intensität +TP_LOCALLAB_DEHAZE_BLACK;Schwarzpunkt TP_LOCALLAB_DEHAZFRAME_TOOLTIP;Entfernt atmosphärischen Dunst. Erhöht Sättigung und Details.\nKann einen Farbstich entfernen, aber auch einen Blaustich hinzufügen, der wiederum mit anderen Werkzeugen wieder entfernt werden kann. TP_LOCALLAB_DEHAZ_TOOLTIP;Negative Werte fügen Dunst hinzu. TP_LOCALLAB_DELTAD;Ebenenbalance TP_LOCALLAB_DELTAEC;ΔE-Bildmaske TP_LOCALLAB_DENOI1_EXP;Rauschreduzierung auf Luminanz-Maske TP_LOCALLAB_DENOI2_EXP;Wiederherstellung auf Luminanz-Maske -TP_LOCALLAB_DENOIBILAT_TOOLTIP;Ermöglicht Impulsrauschen zu reduzieren oder auch 'Salz-& Pfefferrauschen'. +TP_LOCALLAB_DENOIBILAT_TOOLTIP;Ermöglicht Impulsrauschen zu reduzieren oder auch 'Salz- u. Pfefferrauschen'. TP_LOCALLAB_DENOICHROC_TOOLTIP;Ermöglicht den Umgang mit Flecken und Rauschen. TP_LOCALLAB_DENOICHRODET_TOOLTIP;Ermöglicht die Wiederherstellung von Chrominanz-Details durch schrittweise Anwendung einer Fourier-Transformation (DCT). TP_LOCALLAB_DENOICHROF_TOOLTIP;Ermöglicht die Detailjustierung von Chrominanz-Rauschen @@ -2971,6 +3125,7 @@ TP_LOCALLAB_DETAIL;Lokaler Kontrast TP_LOCALLAB_DETAILFRA;Kantenerkennung DCT TP_LOCALLAB_DETAILSH;Details TP_LOCALLAB_DETAILTHR;Schwelle Luminanz-Chrominanz-Detail +TP_LOCALLAB_DISAB_CIECAM;Deaktiviere Ciecam oder Jz-Umgebung TP_LOCALLAB_DIVGR;Gamma TP_LOCALLAB_DUPLSPOTNAME;Kopie TP_LOCALLAB_EDGFRA;Kantenschärfe @@ -2979,6 +3134,7 @@ TP_LOCALLAB_ELI;Ellipse TP_LOCALLAB_ENABLE_AFTER_MASK;Tonwertkorrektur anwenden TP_LOCALLAB_ENABLE_MASK;Maske aktivieren TP_LOCALLAB_ENABLE_MASKAFT;alle Belichtungs-Algorithmen verwenden +TP_LOCALLAB_ENABLE_MASKALL;alle Maskierungswerkzeuge aktivieren TP_LOCALLAB_ENARETIMASKTMAP_TOOLTIP;Wenn aktiviert, verwendet die Maske 'Wiederhergestellte Daten' nach Übertragungszuordnung anstelle von Originaldaten. TP_LOCALLAB_ENH;Erweitert TP_LOCALLAB_ENHDEN;Erweitert + chromatische Rauschreduzierung @@ -2994,9 +3150,10 @@ TP_LOCALLAB_EV_VIS_ALL;Alle zeigen TP_LOCALLAB_EXCLUF;Ausschließend TP_LOCALLAB_EXCLUF_TOOLTIP;Der 'Ausschlussmodus' verhindert, dass benachbarte Punkte bestimmte Teile des Bildes beeinflussen. Durch Anpassen von 'Bereich' wird der Farbbereich erweitert.\nSie können einem Ausschluss-Spot auch Werkzeuge hinzufügen und diese auf die gleiche Weise wie für einen normalen Punkt verwenden. TP_LOCALLAB_EXCLUTYPE;Art des Spots -TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Der normale Spot verwendet rekursive Daten.\n\nDer ausschließende Spot reinitialisiert alle lokalen Anpassungen.\nEr kann ganz oder partiell angewendet werden, um vorherige lokale Anpassungen zu relativieren oder zurückzusetzen.\n\n'Ganzes Bild' erlaubt lokale Anpassungen auf das gesamte Bild.\nDie RT Spot-Begrenzung wird außerhalb der Vorschau gesetzt.\nDer Übergangswert wird auf 100 gesetzt.\nMöglicherweise muss der RT-Spot neu positioniert oder in der Größe angepasst werden, um das erwünschte Ergebnis zu erzielen.\nAchtung: Die Anwendung von Rauschreduzierung, Wavelet oder schnelle Fouriertransformation im 'Ganzes Bild-Modus' benötigt viel Speicher und Rechenleistung und könnte bei schwachen Systemen zu unerwünschtem Abbruch oder Abstürzen führen. +TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normaler Spot verwendet rekursive Daten.\n\nDurch Ausschließen des Spots werden alle selektiven Bearbeitungen neu initialisiert.\nKann verwendet werden, um eine vorherige Aktion ganz oder teilweise abzubrechen oder um Vorgänge im umgekehrten Modus auszuführen.\nVerwenden Sie 'Bereich' (Ausschließen), um die Ausschlussintensität festzulegen.\n\n'Vollbild' ermöglicht Ihnen, die selektiven Bearbeitungstools auf das gesamte Bild anzuwenden.\nDie RT-Spot-Begrenzer werden über die Bildvorschaugrenzen hinaus gesetzt.\nDer Übergang wird auf 100 eingestellt.\nHinweis: Möglicherweise muss der RT-Spot neu positioniert oder in der Größe angepasst werden, um das erwünschte Ergebnis zu erzielen.\nAchtung: Die Anwendung von Rauschreduzierung, Wavelet oder schnelle Fouriertransformation im 'Ganzes Bild-Modus' benötigt viel Speicher und Rechenleistung und könnte bei schwachen Systemen zu unerwünschtem Abbruch oder Abstürzen führen.\n\n'Global' ermöglicht Ihnen, die selektiven Bearbeitungstools auf das gesamte Bild anzuwenden, ohne Delta E oder Übergänge zu verwenden. TP_LOCALLAB_EXECLU;Ausschließender Spot TP_LOCALLAB_EXFULL;Gesamtes Bild +TP_LOCALLAB_EXMAIN;Global TP_LOCALLAB_EXNORM;Normaler Spot TP_LOCALLAB_EXPCBDL_TOOLTIP;Kann zur Entfernung von Sensorflecken oder Objektivfehlern verwendet werden, indem Kontrast auf der entsprechenden Detailebene verringert wird. TP_LOCALLAB_EXPCHROMA;Kompensation Farbsättigung @@ -3005,11 +3162,11 @@ TP_LOCALLAB_EXPCOLOR_TOOLTIP;Passt Farbe, Luminanz, Kontrast an und korrigiert k TP_LOCALLAB_EXPCOMP;Belichtungsausgleich ƒ TP_LOCALLAB_EXPCOMPINV;Belichtungsausgleich TP_LOCALLAB_EXPCOMP_TOOLTIP;Für Porträts oder Bilder mit geringem Farbverlauf. Sie können 'Formerkennung' unter 'Einstellungen' ändern:\n\nErhöhen Sie den 'ΔE-Bereichsschwellenwert'\nReduzieren Sie 'ΔE-Zerfallrate'\nErhöhen Sie 'ab-L-Balance (ΔE)'. -TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Siehe Dokumentation für Wavelet Levels.\nEs gibt einige Unterschiede in der Version der lokalen Einstellungen: mehr Werkzeuge und mehr Möglichkeiten an individuellen Detailebenen zu arbeiten.\nz.B. Wavelet-Level-Tonwertkorrektur. +TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Siehe Dokumentation für Wavelet-Ebenen.\nEs gibt einige Unterschiede in der Version des selektiven Editierens, welche mehr Werkzeuge und mehr Möglichkeiten an individuellen Detailebenen zu arbeiten anbietet.\nz.B. Wavelet-Ebenen-Tonwertkorrektur. TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Vermeiden Sie zu kleine Spots (<32 x 32 Pixel).\nVerwenden Sie niedrige 'Übergangswerte' und hohe Werte für 'Übergangszerfallrate' und 'Bereich,' um kleine Spots zu simulieren und Fehler zu beheben.\nVerwenden Sie 'Klarheit & Schärfemaske und Überlagern & Abschwächen' wenn nötig, indem Sie den 'Radius' anpassen, um Artefakte zu reduzieren. TP_LOCALLAB_EXPCURV;Kurven TP_LOCALLAB_EXPGRAD;Verlaufsfilter -TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Verlaufsfilter stehen in den folgenden Werkzeugen zur Verfügung: 'Farbe und Licht (Luminanz, Chrominanz, Farbtonverlauf, und Zusammenführen)', 'Belichtung (Luminanz grad.)', 'Belichtungsmaske (Luminanz grad.)', 'Schatten/Lichter (Luminanz grad.)', 'Dynamik (Luminanz, Chrominanz & Farbton)', 'Lokaler Kontrast & Wavelet Pyramide (lokaler Kontrast grad.)'.\nDer Zerfall wird in den Einstellungen definiert. +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Verlaufsfilter stehen in den folgenden Werkzeugen zur Verfügung: 'Farbe und Licht (Luminanz, Chrominanz, Farbtonverlauf, und Zusammenführen)', 'Belichtung (Luminanz grad.)', 'Belichtungsmaske (Luminanz grad.)', 'Schatten/Lichter (Luminanz grad.)', 'Dynamik (Luminanz, Chrominanz & Farbton)', 'Lokaler Kontrast & Wavelet Pyramide (lokaler Kontrast grad.)'.\nDer Zerfall wird in den Einstellungen definiert. TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Ändert die Mischung von geändertem/ursprünglichem Bild. TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Verändert das Verhalten des Bildes mit wenig oder zu wenig Kontrast, indem vorher eine Gammakurve und nachher eine Laplace-Transformation hinzugefügt werden. TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Verändert das Verhalten unterbelichteter Bilder indem eine lineare Komponente vor Anwendung der Laplace-Transformation hinzugefügt wird. @@ -3028,9 +3185,11 @@ TP_LOCALLAB_FATDETAIL;Detail TP_LOCALLAB_FATFRA;Dynamikkompression TP_LOCALLAB_FATFRAME_TOOLTIP;PDE Fattal - es wird der Fattal-Algorithmus zur Tonwertkorrektur angewendet. TP_LOCALLAB_FATLEVEL;Sigma +TP_LOCALLAB_FATSAT;Sättigungskontrolle TP_LOCALLAB_FATSHFRA;Maske für den Bereich der Dynamikkompression TP_LOCALLAB_FEATH_TOOLTIP;Verlaufsbreite als Prozentsatz der Spot-Diagonalen.\nWird von allen Verlaufsfiltern in allen Werkzeugen verwendet.\nKeine Aktion, wenn kein Verlaufsfilter aktiviert wurde. TP_LOCALLAB_FEATVALUE;Verlaufsbreite +TP_LOCALLAB_FEATVALUE_MASK;Verlaufsbreite (Maske Verlaufsfilter ) TP_LOCALLAB_FFTCOL_MASK;Schnelle Fouriertransformation TP_LOCALLAB_FFTMASK_TOOLTIP;Nutzt eine Fourier-Transformation für eine bessere Qualität (auf Kosten einer erhöhten Verarbeitungszeit und Speicheranforderungen). TP_LOCALLAB_FFTW;Schnelle Fouriertransformation @@ -3113,7 +3272,7 @@ TP_LOCALLAB_JZLOGWB_TOOLTIP;Wenn Auto aktiviert ist, werden die Ev-Werte und die TP_LOCALLAB_JZLOGYBOUT_TOOLTIP;Yb ist die relative Helligkeit des Hintergrunds, ausgedrückt als Prozentsatz von Grau. 18 % Grau entspricht einer Hintergrundhelligkeit von 50 %, ausgedrückt in CIE L.\nDie Daten basieren auf der mittleren Helligkeit des Bildes.\nBei Verwendung mit LOG-Kodierung wird die mittlere Helligkeit verwendet, um die erforderliche Verstärkung zu bestimmen, die dem Signal vor der LOG-Kodierung hinzugefügt werden muss. Niedrigere Werte der mittleren Helligkeit führen zu einer erhöhten Verstärkung. TP_LOCALLAB_JZMODECAM_TOOLTIP;Jz (Modus 'Erweitert'). Nur funktionsfähig, wenn das Ausgabegerät (Monitor) HDR ist (Spitzenleuchtdichte höher als 100 cd/m2 - idealerweise zwischen 4000 und 10000 cd/m2. Schwarzpunktleuchtdichte unter 0,005 cd/m2). Dies setzt voraus, dass\na) das ICC-PCS für den Bildschirm Jzazbz (oder XYZ) verwendet,\nb) mit echter Präzision arbeitet,\nc) dass der Monitor kalibriert ist (möglichst mit einem DCI-P3- oder Rec-2020-Farbraum),\nd) dass das übliche Gamma (sRGB oder BT709) durch eine Perceptual Quantiser (PQ)-Funktion ersetzt wird. TP_LOCALLAB_JZPQFRA;Jz Zuordnung -TP_LOCALLAB_JZPQFRA_TOOLTIP;Ermöglicht, den Jz-Algorithmus wie folgt an eine SDR-Umgebung oder an die Eigenschaften (Leistung) einer HDR-Umgebung anzupassen:\na) Bei Luminanzwerten zwischen 0 und 100 cd/m2 verhält sich das System so, als ob es sich in einer SDR-Umgebung befände .\nb) für Luminanzwerte zwischen 100 und 10000 cd/m2 können Sie den Algorithmus an die HDR-Eigenschaften des Bildes und des Monitors anpassen.\n\nWenn 'PQ - Peak Luminance' auf 10000 eingestellt ist, verhält sich 'Jz Zuordnung' genauso wie der ursprüngliche Jzazbz-Algorithmus. +TP_LOCALLAB_JZPQFRA_TOOLTIP;Ermöglicht, den Jz-Algorithmus wie folgt an eine SDR-Umgebung oder an die Eigenschaften (Leistung) einer HDR-Umgebung anzupassen:\na) Bei Luminanzwerten zwischen 0 und 100 cd/m2 verhält sich das System so, als ob es sich in einer SDR-Umgebung befände .\nb) für Luminanzwerte zwischen 100 und 10000 cd/m2 können Sie den Algorithmus an die HDR-Eigenschaften des Bildes und des Monitors anpassen.\n\nWenn 'PQ - Peak Luminanz' auf 10000 eingestellt ist, verhält sich 'Jz Zuordnung' genauso wie der ursprüngliche Jzazbz-Algorithmus. TP_LOCALLAB_JZPQREMAP;PQ - Peak Luminanz TP_LOCALLAB_JZPQREMAP_TOOLTIP;PQ (Perceptual Quantizer) - ermöglicht die Änderung der internen PQ-Funktion (normalerweise 10000 cd/m2 - Standard 120 cd/m2).\nKann zur Anpassung an verschiedene Bilder, Prozesse und Geräte verwendet werden. TP_LOCALLAB_JZQTOJ;Relative Helligkeit @@ -3126,7 +3285,7 @@ TP_LOCALLAB_JZTARGET_EV;Ansicht mittlere Helligkeit (Yb%) TP_LOCALLAB_JZTHRHCIE;Schwellenwert Chroma für Jz(Hz) TP_LOCALLAB_JZWAVEXP;Wavelet Jz TP_LOCALLAB_LABBLURM;Unschärfemaske -TP_LOCALLAB_LABEL;Lokale Anpassungen +TP_LOCALLAB_LABEL;Selektives Editieren TP_LOCALLAB_LABGRID;Farbkorrektur TP_LOCALLAB_LABGRIDMERG;Hintergrund TP_LOCALLAB_LABGRID_VALUES;oben(a)=%1\noben(b)=%2\nunten(a)=%3\nunten(b)=%4 @@ -3170,9 +3329,11 @@ TP_LOCALLAB_LOGAUTOGRAYJZ_TOOLTIP;Berechnet automatisch die 'Mittlere Luminanz' TP_LOCALLAB_LOGAUTOGRAY_TOOLTIP;Berechnet automatisch die 'Mittlere Luminanz' für die Szenenbedingungen, wenn die Schaltfläche 'Automatisch' in 'Relative Belichtungsebenen' gedrückt wird. TP_LOCALLAB_LOGAUTO_TOOLTIP;Mit Drücken dieser Taste werden der 'Dynamikbereich' und die 'Mittlere Luminanz' für die Szenenbedingungen berechnet, wenn die Option 'Automatische mittlere Luminanz (Yb%)' aktiviert ist.\nBerechnet auch die absolute Luminanz zum Zeitpunkt der Aufnahme.\nDrücken Sie die Taste erneut, um die automatisch berechneten Werte anzupassen. TP_LOCALLAB_LOGBASE_TOOLTIP;Standard = 2.\nWerte unter 2 reduzieren die Wirkung des Algorithmus, wodurch die Schatten dunkler und die Glanzlichter heller werden.\nMit Werten über 2 sind die Schatten grauer und die Glanzlichter werden verwaschener. -TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatische Anpassung ermöglicht, eine Farbe entsprechend ihrer räumlich-zeitlichen Umgebung zu interpretieren.\nNützlich, wenn der Weißabgleich weit von Referenz D50 entfernt ist.\nPasst Farben an das Leuchtmittel des Ausgabegeräts an. -TP_LOCALLAB_LOGCIE;LOG-Kodierung statt Sigmoid -TP_LOCALLAB_LOGCIE_TOOLTIP;Ermöglicht die Verwendung von 'Schwarz-Ev', 'Weiß-Ev', 'Szenen-Mittlere-Leuchtdichte (Yb%)' und 'sichtbare mittlere Leuchtdichte (Yb%)' für die Tonzuordnung mit 'LOG-Kodierung Q'. +TP_LOCALLAB_LOGCATAD_TOOLTIP;Chromatische Anpassung ermöglicht, eine Farbe entsprechend ihrer räumlich-zeitlichen Umgebung zu interpretieren.\nNützlich, wenn der Weißabgleich weit von Referenz D50 entfernt ist.\nPasst Farben an die Lichtquelle des Ausgabegeräts an. +TP_LOCALLAB_LOGCIE;LOG-Kodierung +TP_LOCALLAB_LOGCIEQ;LOG-Kodierung Q (mit Ciecam) +TP_LOCALLAB_LOGCIEQ_TOOLTIP;Aktivierung der Checkbox erlaubt die Wahl zwischen LOG-Kodierung basierend auf den 3 RGB Kanälen, und LOG-Kodierung basierend auf dem Ciecam’s Helligkeit (Q) Kanal.\nDie Verwendung des Q Kanals anstatt der RGB Kanäle hilft, unerwünschte Kanteneffekte, wie Farbton- und Sättigungsverschiebungen zu vermeiden.\nJedoch sind die Einstellungen schwieriger zu optimieren, weil Q unbeschränkt ist und Ciecam die Daten unter Berücksichtigung der Umgebungsbedingungen, gleichzeitig Kontrast, etc. anpasst.\nEs könnten folgende Anpassungen erforderlich werden:\n Szene-Bedingungen: Mittlere Helligkeit (Yb), Weiß- & Schwarzverteilung, Schwarz Ev, Weiß Ev.\n Quelldaten Anpassungen: Helligkeitskompression, Stärke.\n\nHinweis: Wenn LOG-Kodierung (Q) verwendet wird, sollte die Option 'Ciecam deaktivieren' unter Szene Bedingungen, Menu Umgebung nicht aktiviert werden. +TP_LOCALLAB_LOGCIE_TOOLTIP;Ermöglicht die Verwendung von 'Schwarz-Ev', 'Weiß-Ev', 'Weiß- und Schwarz-Verteilung', 'Szenen-Mittlere-Leuchtdichte (Yb%)' und 'sichtbare mittlere Leuchtdichte (Yb%)' für die Tonzuordnung mit 'LOG-Kodierung' mit Helligkeitskompression. TP_LOCALLAB_LOGCOLORFL;Buntheit (M) TP_LOCALLAB_LOGCOLORF_TOOLTIP;Wahrgenommene Intensität des Farbtones im Vergleich zu Grau.\nAnzeige, dass ein Reiz mehr oder weniger farbig erscheint. TP_LOCALLAB_LOGCONQL;Kontrast (Q) @@ -3180,7 +3341,7 @@ TP_LOCALLAB_LOGCONTHRES;Schwellenwert Kontrast (J & Q) TP_LOCALLAB_LOGCONTL;Kontrast (J) TP_LOCALLAB_LOGCONTL_TOOLTIP;Der Kontrast (J) in CIECAM16 berücksichtigt die Zunahme der wahrgenommenen Färbung mit der Luminanz. TP_LOCALLAB_LOGCONTQ_TOOLTIP;Der Kontrast (Q) in CIECAM16 berücksichtigt die Zunahme der wahrgenommenen Färbung mit der Helligkeit. -TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Passt den Kontrastbereich (J & Q) der Mitteltöne an.\nPositive Werte verringern den Effekt der Kontrastregler (J & Q) schrittweise. Negative Werte erhöhen den Effekt der Kontrastregler zunehmend. +TP_LOCALLAB_LOGCONTTHRES_TOOLTIP;Passt den Kontrastbereich (J & Q) der Mitteltöne an.\nPositive Werte verringern den Effekt der Kontrastregler (J & Q) schrittweise. Negative Werte erhöhen den Effekt der Kontrastregler zunehmend. TP_LOCALLAB_LOGDETAIL_TOOLTIP;Wirkt hauptsächlich auf hohe Frequenzen. TP_LOCALLAB_LOGENCOD_TOOLTIP;Tonwertkorrektur mit logarithmischer Kodierung (ACES).\nNützlich für unterbelichtete Bilder oder Bilder mit hohem Dynamikbereich.\n\nZweistufiger Prozess:\n1) Dynamikbereichsberechnung\n2) Manuelle Anpassung. TP_LOCALLAB_LOGEXP;Alle Werkzeuge @@ -3193,6 +3354,7 @@ TP_LOCALLAB_LOGLIGHTQ;Helligkeit (Q) TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Wahrgenommene Lichtmenge, die von einer Quelle ausgeht.\nIndikator dafür, dass eine Quelle mehr oder weniger hell und klar zu sein scheint. TP_LOCALLAB_LOGLIN;Logarithmischer Modus TP_LOCALLAB_LOGPFRA;Relative Belichtungsebenen +TP_LOCALLAB_LOGPFRA2;Einstellungen Log-Kodierung TP_LOCALLAB_LOGREPART;Gesamtintensität TP_LOCALLAB_LOGREPART_TOOLTIP;Ermöglicht das Anpassen der relativen Intensität des LOG-kodierten Bildes in Bezug auf das Originalbild.\nKein Effekt auf die CIECAM-Komponente. TP_LOCALLAB_LOGSATURL_TOOLTIP;Die Sättigung(en) in CIECAM16 entsprechen der Farbe einer Quelle in Bezug auf ihre eigene Helligkeit.\nWirkt hauptsächlich auf mittlere Töne und Lichter. @@ -3239,7 +3401,7 @@ TP_LOCALLAB_MASKLCTHRLOW;Schwellenwert dunkle Bereiche TP_LOCALLAB_MASKLCTHRLOW2;Schwelle dunkle Bereiche TP_LOCALLAB_MASKLCTHRMID;Luminanz Graubereiche TP_LOCALLAB_MASKLCTHRMIDCH;Chrominanz Graubereiche -TP_LOCALLAB_MASKLC_TOOLTIP;Wird von der Wavelet-Luminanz verwendet.\nDamit können Sie die Rauschunterdrückung basierend auf den Bildluminanzinformationen festlegen, die in der L(L)- oder LC(H)-Maske (Maske und Modifikationen) enthalten sind.\nDie L(L)-Maske oder die LC(H)-Maske muss aktiviert sein, m diese Funktion nutzen zu können.\n„Schwellenwert für die Luminanz dunkler Bereiche“. Ist „Rauschunterdrückung in dunklen und hellen Bereichen verstärken“ > 1, wird die Rauschunterdrückung schrittweise von 0 % auf 100 % beim maximalen Schwarzwert (bestimmt durch die Maske) erhöht.\n„Schwellenwert für die Luminanz für helle Bereiche“. Die Rauschunterdrückung wird schrittweise von 100 % auf 0 % beim maximalen Weißwert (bestimmt durch die Maske) verringert.\n Im Bereich zwischen den beiden Schwellenwerten werden die Rauschunterdrückungseinstellungen von der Maske nicht beeinflusst. +TP_LOCALLAB_MASKLC_TOOLTIP;Wird von der Wavelet-Luminanz verwendet.\nDamit können Sie die Rauschunterdrückung basierend auf den Bildluminanzinformationen festlegen, die in der L(L)- oder LC(H)-Maske (Maske und Modifikationen) enthalten sind.\nDie L(L)-Maske oder die LC(H)-Maske muss aktiviert sein, m diese Funktion nutzen zu können.\n'Schwellenwert für die Luminanz dunkler Bereiche'. Ist 'Rauschunterdrückung in dunklen und hellen Bereichen verstärken' > 1, wird die Rauschunterdrückung schrittweise von 0 % auf 100 % beim maximalen Schwarzwert (bestimmt durch die Maske) erhöht.\n'Schwellenwert für die Luminanz für helle Bereiche'. Die Rauschunterdrückung wird schrittweise von 100 % auf 0 % beim maximalen Weißwert (bestimmt durch die Maske) verringert.\n Im Bereich zwischen den beiden Schwellenwerten werden die Rauschunterdrückungseinstellungen von der Maske nicht beeinflusst. TP_LOCALLAB_MASKLNOISELOW;In dunklen und hellen Bereichen verstärken TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dunklere Tonwertgrenze, unterhalb derer die Parameter der Detailebenenkontraste (nur Luminanz) nach und nach auf ihre ursprünglichen Werte zurückgesetzt werden, bevor sie durch die Einstellungen des Detailebenenkontrastes geändert werden.\nSie können bestimmte Werkzeuge in 'Maske und Anpassungen' verwenden, um die Graustufen zu ändern: 'Glättradius', 'Gamma', 'Steigung' und 'Kontrastkurve'.\nVerwenden Sie einen 'feststellbaren Farbwähler' auf der Maske, um zu sehen, welche Bereiche betroffen sind. Stellen Sie sicher, dass Sie in den Einstellungen 'Hintergrundfarbmaske' = 0 festlegen. TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dunklere Tonwertgrenze, unterhalb derer die Parameter nach und nach auf ihre ursprünglichen Werte zurückgesetzt werden, bevor sie durch 'Farbe- und Licht'-Einstellungen geändert werden.\nSie können bestimmte Werkzeuge in 'Maske und Anpassungen' verwenden, um die Graustufen zu ändern: 'Strukturmaske' , 'Unschärfemaske', 'Glättradius', 'Gamma', 'Steigung', 'Kontrastkurve', 'Lokaler Kontrast (Wavelets)'.\nVerwenden Sie einen 'feststellbaren Farbwähler' auf der Maske, um zu sehen, welche Bereiche betroffen sind. Stellen Sie sicher, dass Sie in den Einstellungen 'Hintergrundfarbmaske' = 0 festlegen. @@ -3262,7 +3424,7 @@ TP_LOCALLAB_MASKRESRETI_TOOLTIP;Wird verwendet, um den Effekt der Retinex-Einste TP_LOCALLAB_MASKRESTM_TOOLTIP;Wird verwendet, um den Effekt der Tonwertkorrektur-Einstellungen basierend auf den in den L(L)- oder LC(H)-Masken (Maske und Anpassungen) enthaltenen Luminanz-Informationen zu modulieren.\nDie L(L)-Maske oder die LC(H)-Maske müssen aktiviert sein, um diese Funktion zu verwenden.\nDie Bereiche 'dunkel' und 'hell' unterhalb des Dunkelschwellenwertes und oberhalb des Helligkeitsschwellenwertes werden schrittweise auf ihre ursprünglichen Werte zurückgesetzt, bevor sie durch die Einstellungen der Tonwertkorrektur geändert werden.\nZwischen diesen beiden Bereichen wird der volle Einstellungswert der Tonwertkorrektur angewendet. TP_LOCALLAB_MASKRESVIB_TOOLTIP;Wird verwendet, um den Effekt der Einstellungen für Lebhaftigkeit und Warm/Kalt basierend auf den in den L(L)- oder LC(H)-Masken (Maske und Anpassungen) enthaltenen Luminanz-Informationen zu modulieren.\nDie L(L)-Maske oder die LC(H)-Maske muss aktiviert sein, um diese Funktion verwenden zu können.\nDie Bereiche 'dunkel' und 'hell' unterhalb und oberhalb des entsprechenden Schwellenwertes werden schrittweise auf ihre ursprünglichen Werte zurückgesetzt, bevor sie durch die Einstellungen Lebhaftigkeit und Farbtemperatur geändert werden.\nZwischen diesen beiden Bereichen wird der volle Wert der Einstellungen für Lebhaftigkeit und Warm/Kalt angewendet. TP_LOCALLAB_MASKRESWAV_TOOLTIP;Wird verwendet, um den Effekt der Einstellungen für lokalen Kontrast und Wavelet basierend auf den in den L(L)- oder LC(H)-Masken (Maske und Anpassungen) enthaltenen Luminanz-Informationen zu modulieren.\nDie L(L)-Maske oder die LC(H)-Maske muss aktiviert sein, um diese Funktion verwenden zu können.\nDie Bereiche 'dunkel' und 'hell' unterhalb und oberhalb der entsprechenden Schwellenwerte werden schrittweise auf ihre ursprünglichen Werte zurückgesetzt, bevor sie durch die Einstellungen für lokalen Kontrast und Wavelet geändert werden. Zwischen diesen beiden Bereichen wird der volle Wert der Einstellungen für lokalen Kontrast und Wavelet angewendet. -TP_LOCALLAB_MASKUNUSABLE;Maske deaktiviert (siehe Maske u. Anpassungen) +TP_LOCALLAB_MASKUNUSABLE;Maske deaktiviert (aktivieren unter Maske u. Anpassungen) TP_LOCALLAB_MASKUSABLE;Maske aktiviert (siehe Maske u. Anpassungen) TP_LOCALLAB_MASK_TOOLTIP;Sie können mehrere Masken für ein Werkzeug aktivieren, indem Sie ein anderes Werkzeug aktivieren und nur die Maske verwenden (setzen Sie die Werkzeugregler auf 0).\n\nSie können den Spot auch duplizieren und nahe am ersten Punkt platzieren. Die kleinen Abweichungen in den Punktreferenzen ermöglichen Feineinstellungen. TP_LOCALLAB_MEDIAN;Median niedrig @@ -3298,6 +3460,7 @@ TP_LOCALLAB_MERTHR;Differenz TP_LOCALLAB_MERTWE;Ausschluss TP_LOCALLAB_MERTWO;Subtraktion TP_LOCALLAB_METHOD_TOOLTIP;'Verbessert + Chroma Rauschreduzierung' verlängern die Verarbeitungszeiten erheblich.\nAber sie reduzieren auch Artefakte. +TP_LOCALLAB_MIDTCIE;Mitteltöne TP_LOCALLAB_MLABEL;Wiederhergestellte Daten Min=%1 Max=%2 TP_LOCALLAB_MLABEL_TOOLTIP;Die Werte sollten in der Nähe von Min=0 Max=32768 (Log-Modus) liegen, es sind jedoch auch andere Werte möglich. Sie können 'Wiederhergestellte Daten' beschneiden und 'Versatz' anpassen, um sie zu normalisieren.\nStellt Bilddaten ohne Überlagerung wieder her. TP_LOCALLAB_MODE_EXPERT;Erweitert @@ -3345,10 +3508,15 @@ TP_LOCALLAB_ORRETISTREN_TOOLTIP;Wirkt basierend auf dem Laplace-Schwellwert. Je TP_LOCALLAB_PASTELS2;Lebhaftigkeit TP_LOCALLAB_PDE;Kontrastdämpfung - Dynamikbereich Kompression TP_LOCALLAB_PDEFRA;Kontrastdämpfung -TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL Algorithmus an Rawtherapee angepasst: Liefert unterschiedliche Ergebnisse und erfordert andere Einstellungen als das Hauptmenü 'Belichtung'.\nKann nützlich für Bilder mit geringer Belichtung oder hohem Dynamikbereich sein. +TP_LOCALLAB_PDEFRAME_TOOLTIP;PDE IPOL Algorithmus an RawTherapee angepasst: Liefert unterschiedliche Ergebnisse und erfordert andere Einstellungen als das Hauptmenü 'Belichtung'.\nKann nützlich für Bilder mit geringer Belichtung oder hohem Dynamikbereich sein. +TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;Wenn aktiviert, wird eine Gamut-Kontrolle nach der Konvertierung nach XYZ durchgeführt. +TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Ermöglicht, den Weiß-Punkt so zu bewegen, dass er sich der Dominanzfarbe annähert. Diese Aktion modifiziert die Reinheit. In Kombination mit 'Shift x' und 'Shift y' kann eine moderate Farbtönung vorgenommen werden. +TP_LOCALLAB_PRECAMREFI_TOOLTIP;Ermöglicht, den Weiß-Punkt so zu bewegen, dass er sich der Dominanzfarbe annähert. Diese Aktion modifiziert die Reinheit. +TP_LOCALLAB_PRECAM_TOOLTIP; „Quelldatenanpassungen“ ändert den Dynamikbereich mithilfe der Log-Kodierung, der Töne des Bildes und der Primärfarben (vereinfachtes abstraktes Profil) und der Mitteltöne direkt vor dem Ciecam-Prozess. Diese Werte sind anpassbar:\nGamma: Wirkt hauptsächlich auf helle Töne\nSteigung: Wirkt hauptsächlich auf dunkle Töne. Sie können jedes beliebige Paar aus Gamma und Steigung wählen (Werte >1) und der Algorithmus stellt sicher, dass zwischen den linearen und parabolischen Teilen der Kurve Kontinuität besteht.\nZielprimärfarben: Ermöglicht Ihnen, die Zielprimärfarben zu ändern, um die Bildfarbe (Sättigung) wiederherzustellen oder zu ändern. Die Farbbalance bleibt weitgehend erhalten, wenn das „Arbeitsprofil“ und die „Zielprimärfarben“ ähnlich sind. Das „Arbeitsprofil“ wird nicht geändert. Sie können auch die Primärfarben und die Lichtquelle (Weißpunkt) fein anpassen. Wenn Sie eine Primärfarbe vom Weißpunkt weg verschieben, wird die Sättigung reduziert und umgekehrt. Achten Sie auf den Farbumfang. TP_LOCALLAB_PREVHIDE;Mehr Einstellungen ausblenden TP_LOCALLAB_PREVIEW;Vorschau ΔE TP_LOCALLAB_PREVSHOW;Mehr Einstellungen einblenden +TP_LOCALLAB_PRIMILLFRAME;Primärfarben und Lichtquelle TP_LOCALLAB_PROXI;Zerfallrate (ΔE) TP_LOCALLAB_QUAAGRES;Aggressiv TP_LOCALLAB_QUACONSER;Konservativ @@ -3367,7 +3535,7 @@ TP_LOCALLAB_REN_DIALOG_LAB;Neuer Spot Name TP_LOCALLAB_REN_DIALOG_NAME;Spot umbenennen TP_LOCALLAB_REPARCOL_TOOLTIP;Ermöglicht, die relative Stärke von 'Farbe und Licht' in Bezug auf das Originalbild anzupassen. TP_LOCALLAB_REPARDEN_TOOLTIP;Ermöglicht, die relative Stärke der 'Rauschreduzierung' in Bezug auf das Originalbild anzupassen. -TP_LOCALLAB_REPAREXP_TOOLTIP;Ermöglicht, die relative Stärke von 'Dynamik und und Belichtung' in Bezug auf das Originalbild anzupassen. +TP_LOCALLAB_REPAREXP_TOOLTIP;Ermöglicht, die relative Stärke von 'Dynamik und Belichtung' in Bezug auf das Originalbild anzupassen. TP_LOCALLAB_REPARSH_TOOLTIP;Ermöglicht, die relative Stärke von 'Schatten/Lichter' und 'Tonwert' in Bezug auf das Originalbild anzupassen. TP_LOCALLAB_REPARTM_TOOLTIP;Ermöglicht, die relative Stärke des 'Tone-Mappings' in Bezug auf das Originalbild anzupassen. TP_LOCALLAB_REPARW_TOOLTIP;Ermöglicht, die relative Stärke des'Lokalen Kontrasts' und der 'Wavelets' in Bezug auf das Originalbild anzupassen. @@ -3397,6 +3565,7 @@ TP_LOCALLAB_RGBCURVE_TOOLTIP;Im RGB-Modus gibt es 4 Möglichkeiten: 'Standard', TP_LOCALLAB_ROW_NVIS;Nicht sichtbar TP_LOCALLAB_ROW_VIS;Sichtbar TP_LOCALLAB_RSTPROTECT_TOOLTIP;'Rot- und Hauttöne schützen' beeinflusst die Schieberegler von Sättigung , Chromatizität und Buntheit. +TP_LOCALLAB_SATCIE;Kontrolle Sättigung TP_LOCALLAB_SATUR;Sättigung TP_LOCALLAB_SATURV;Sättigung (s) TP_LOCALLAB_SCALEGR;Korngröße @@ -3463,17 +3632,41 @@ TP_LOCALLAB_SHOWVI;Maske und Anpassungen TP_LOCALLAB_SHRESFRA;Schatten/Lichter & TRC TP_LOCALLAB_SHTRC_TOOLTIP;Basierend auf den (bereitgestellten) 'Arbeitsprofil'(en) werden die Farbtöne des Bildes geändert, indem das Arbeitsprofil auf eine Farbtonkennlinie einwirkt. \n'Gamma' wirkt hauptsächlich auf helle Töne.\n'Steigung' wirkt hauptsächlich auf dunkle Töne.\nEs wird empfohlen, die Farbtonkennlinie beider Geräte (Monitor- und Ausgabeprofil) auf sRGB (Standard) zu setzen. TP_LOCALLAB_SH_TOOLNAME;Schatten/Lichter - Equalizer -TP_LOCALLAB_SIGFRA;Sigmoid Q & LOG-Kodierung Q +TP_LOCALLAB_SIGBLACKSSCIE;Schwarz-Verteilung +TP_LOCALLAB_SIGCIE;Sigmoid +TP_LOCALLAB_SIGFRA;Sigmoid Q +TP_LOCALLAB_SIGGAMJCIE;Gamma TP_LOCALLAB_SIGJZFRA;Sigmoid Jz TP_LOCALLAB_SIGMAWAV;Dämpfungsreaktion +TP_LOCALLAB_SIGMOID16_TOOLTIP;Erlaubt mit 'Ciecam' und 'Sigmoid Q' den Anschein einer Tonwertkorrektur zu simulieren. Sigmoid Q hat 3 Schieber:\na) Kontrast wirkt sich auf die Form der Sigmoid Kurve und in der Konsequenz auf dei Stärke aus\nb) Schwellenwert (Graupunkt) verteilt die Action hinsichtlich der Helligkeit\nc) Wichtung: Anpassung der Wirkung der Sigmoidfunktion auf die interne Exponentialfunktion. TP_LOCALLAB_SIGMOIDBL;Überlagern TP_LOCALLAB_SIGMOIDLAMBDA;Kontrast -TP_LOCALLAB_SIGMOIDQJ;Schwarz-Ev und Weiß-Ev verwenden +TP_LOCALLAB_SIGMOIDLOGAUTO;Auto Schwellenwert +TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;Wenn in der Combo-Box 'Schwarz-Ev und Weiß-Ev' 'Sigmoid und Log Kodierung' aktiviert ist, anstatt 'nur Sigmoid', werden beide Algorithmen gemeinsam verarbeitet. +TP_LOCALLAB_SIGMOIDNORMCIE;Luminanz normalisieren +TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Überlagern wirkt sich auf das endgültige Aussehen des Bildes, Kontrast und Leuchtdichte aus. Verhältnis zwischen Original- und Ausgabebild. +TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Rekonstruiert die Luminanz, sodass Mittelwert und Varianz des Ausgabebildes denen des Originals entsprechen.\nAlle auf J oder Q einwirkenden Anpassungen werden berücksichtigt, einschließlich derjenigen, die nicht relativ zu Sigmoid Q sind. +TP_LOCALLAB_SIGMOIDQJ;Schwarz-Ev und Weiß-Ev +TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;Wenn in der Combobox-Auswahl 'Schwarz-Ev und Weiß-Ev‘ die Option 'Sigmoid- und LOG-Kodierung Q' oder 'LOG-Kodierung statt Sigmoid' aktiviert ist, komprimiert dieser Algorithmus die Daten über den Schwellenwert-Schiebereglerwert. Der letzte Wert steht für die Helligkeit (Q) und sollte so nahe wie möglich am Wert „Komprimierungsschwelle“ liegen (berechnet, wenn ‚Automatischer Schwellenwert‘ aktiviert ist, oft > 1). +TP_LOCALLAB_SIGMOIDSENSI;Anpassungsfähigkeit TP_LOCALLAB_SIGMOIDTH;Schwellenwert (Graupunkt) +TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Ermöglicht Ihnen im Automatikmodus, wenn der Dynamikbereich des Bildes hoch ist, die Lichtverteilung in Weiß und tiefem Schwarz zu ändern.\nKann mit LOG-Kodierung oder Sigmoid mit aktiviertem Schwarz- und Weiß-Ev verwendet werden.\n\nDer Algorithmus ändert die Basisdaten nicht, sondern wirkt auf die Komponenten ein, die zur Berechnung des Dynamikbereichs, des Schwarz-Ev, des Weiß-Ev und des Graupunkts erforderlich sind. TP_LOCALLAB_SIGMOID_TOOLTIP;Ermöglicht, ein Tone-Mapping-Erscheinungsbild zu simulieren, indem sowohl die 'CIECAM' (oder 'Jz') als auch die 'Sigmoid'-Funktion verwendet werden. Drei Schieberegler:\na) 'Kontrast' wirkt sich auf die Form der Sigmoidkurve und folglich auf die Stärke aus;\nb) 'Schwellenwert' (Graupunkt) verteilt die Aktion entsprechend der Leuchtdichte;\nc) 'Überlagern' wirkt sich auf den endgültigen Aspekt des Bildes, Kontrast und Leuchtdichte aus. +TP_LOCALLAB_SIGSLOPJCIE;Steigung +TP_LOCALLAB_SIGTRCCIE;Quellen-Daten-Anpassung +TP_LOCALLAB_SIGWHITESCIE;Weiß-Verteilung TP_LOCALLAB_SLOMASKCOL;Steigung TP_LOCALLAB_SLOMASK_TOOLTIP;Gamma und Steigung ermöglichen eine weiche und artefaktfreie Transformation der Maske, indem 'L' schrittweise geändert wird, um Diskontinuitäten zu vermeiden. +TP_LOCALLAB_SLOPESMOOTH;Grau-Balance (Steigung) +TP_LOCALLAB_SLOPESMOOTHB;Blau-Balance (Steigung) +TP_LOCALLAB_SLOPESMOOTHG;Grün-Balance (Steigung) +TP_LOCALLAB_SLOPESMOOTHR;Rot-Balance (Steigung) TP_LOCALLAB_SLOSH;Steigung +TP_LOCALLAB_SMOOTHCIE;Glanzlichtdämpfung +TP_LOCALLAB_SMOOTHCIE_LUM;Helligkeitsmodus +TP_LOCALLAB_SMOOTHCIE_SCA;Skalierung Yb Szene +TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Schließt die Verarbeitung durch Gamma, Neigung und Mitteltöne ab, indem eine leichte Abschwächung der Lichter bewirkt wird. Bitte beachten Sie, dass dies die Rekonstruktion von Glanzlichtern nicht ersetzt.\n\nGamma-basiert und Neigungsbasiert (Standard und Erweitert) ermöglichen Ihnen die Simulation einer Tonwertzuordnung mithilfe von:\na) Szenenbedingungen: Schwarz-Ev, Weiß-Ev, mittlere Leuchtdichte (Yb%)\nb) Betrachtungsbedingungen: mittlere Leuchtdichte (Yb%).\n\nDie Yb-Szenenskala ist eine Funktion von Weiß-Ev. +TP_LOCALLAB_SMOOTHCIE_YB;Skalierung Yb Ansicht TP_LOCALLAB_SOFT;Weiches Licht u. Original Retinex TP_LOCALLAB_SOFTM;Weiches Licht TP_LOCALLAB_SOFTMETHOD_TOOLTIP;Weiches-Licht-Mischung (identisch mit der globalen Anpassung). Führen Sie Abwedeln und Aufhellen (Dodge & Burn) mit dem ursprünglichen Retinex-Algorithmus durch. @@ -3495,13 +3688,14 @@ TP_LOCALLAB_STRENG;Intensität TP_LOCALLAB_STRENGR;Intensität TP_LOCALLAB_STRENGRID_TOOLTIP;Der gewünschte Effekt kann mit 'Intensität' eingestellt werden, aber es kann auch die Funktion 'Bereich' verwendet werden, um die Aktion zu begrenzen (z.B. um eine bestimmte Farbe zu isolieren). TP_LOCALLAB_STRENGTH;Rauschen +TP_LOCALLAB_STRENGTHCIELOG;Stärke TP_LOCALLAB_STRGRID;Intensität TP_LOCALLAB_STRUC;Struktur TP_LOCALLAB_STRUCCOL;Spot-Struktur TP_LOCALLAB_STRUCCOL1;Spot-Struktur TP_LOCALLAB_STRUCT_TOOLTIP;Verwendet den Sobel-Algorithmus, um die Struktur für die Formerkennung zu berücksichtigen.\nAktivieren Sie 'Maske und Anpassungen' > 'Spot-Struktur anzeigen' (erweiterter Modus), um eine Vorschau der Maske anzuzeigen (ohne Änderungen).\n\nKann in Verbindung verwendet werden mit der Strukturmaske, der Unschärfemaske und 'Lokaler Kontrast' (nach Wavelet-Ebene) zur Verbesserung der Kantenerkennung.\n\nEinflüsse von Anpassungen mit Helligkeit, Kontrast, Chrominanz, Belichtung oder anderen nicht maskenbezogenen Werkzeugen, entweder mit 'Modifiziert anzeigen' oder 'Geänderte Bereiche mit Maske anzeigen' überprüfen. TP_LOCALLAB_STRUMASKCOL;Intensität der Strukturmaske -TP_LOCALLAB_STRUMASK_TOOLTIP;Strukturmaske (Regler) mit deaktiviertem Kontrollkästchen 'Strukturmaske als Werkzeug':\nIn diesem Fall wird eine Maske mit der Struktur generiert, auch wenn keine der 3 Kurven aktiviert ist. Strukturmasken stehen für Maske 'Unschärfe und Rauschreduzierung' und Maske 'Farbe & Licht' zur Verfügung. +TP_LOCALLAB_STRUMASK_TOOLTIP;Strukturmaske (Regler) mit deaktiviertem Kontrollkästchen 'Strukturmaske als Werkzeug':\nIn diesem Fall wird eine Maske mit der Struktur generiert, auch wenn keine der 3 Kurven aktiviert ist. Strukturmasken stehen für Maske 'Unschärfe und Rauschreduzierung' und Maske 'Farbe & Licht' zur Verfügung. TP_LOCALLAB_STRUSTRMASK_TOOLTIP;Ein moderater Gebrauch dieses Reglers wird wärmstens empfohlen! TP_LOCALLAB_STYPE;Form TP_LOCALLAB_STYPE_TOOLTIP;Sie können wählen zwischen:\nSymmetrisch - linkes Handle mit rechts verknüpft, oberes Handle mit unten verbunden.\nUnabhängig - alle Handles sind unabhängig. @@ -3533,11 +3727,12 @@ TP_LOCALLAB_TRANSITGRAD;Übergangsunterschied XY TP_LOCALLAB_TRANSITGRAD_TOOLTIP;Verändert den Übergang der x-Achse TP_LOCALLAB_TRANSITVALUE;Übergangsintensität TP_LOCALLAB_TRANSITWEAK;Zerfall des Überganges (linear-log) -TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Anpassen der Zerfallrate: 1 linear, 2 parabolisch, 3 kubisch bis zu ^ 25.\nKann in Verbindung mit sehr niedrigen Übergangswerten verwendet werden, um Defekte (CBDL, Wavelets, Farbe & Licht) zu reduzieren +TP_LOCALLAB_TRANSITWEAK_TOOLTIP;Anpassen der Zerfallrate: 1 linear, 2 parabolisch, 3 kubisch bis zu ^ 25.\nKann in Verbindung mit sehr niedrigen Übergangswerten verwendet werden, um Defekte (CBDL, Wavelets, Farbe & Licht) zu reduzieren TP_LOCALLAB_TRANSIT_TOOLTIP;Passen Sie die Übergangshärte zwischen betroffenen und nicht betroffenen Bereichen als Prozentsatz des 'Radius' an. TP_LOCALLAB_TRANSMISSIONGAIN;Übertragungsverstärkung TP_LOCALLAB_TRANSMISSIONMAP;Übertragungszuordnung TP_LOCALLAB_TRANSMISSION_TOOLTIP;Übertragung gemäß Übertragung.\nAbszisse: Übertragung von negativen Werten (min), Mittelwert und positiven Werten (max).\nOrdinate: Verstärkung oder Reduzierung.\nSie können diese Kurve anpassen, um die Übertragung zu ändern und Artefakte zu reduzieren. +TP_LOCALLAB_TRCFRAME;Farbtonkennlinie & Mitteltöne TP_LOCALLAB_USEMASK;Laplace TP_LOCALLAB_VART;Varianz (Kontrast) TP_LOCALLAB_VIBRANCE;Farbtemperatur @@ -3568,7 +3763,7 @@ TP_LOCALLAB_WAT_THRESHOLDWAV_TOOLTIP;Bereich der Wavelet-Ebenen, die im gesamten TP_LOCALLAB_WAT_WAVBLURCURV_TOOLTIP;Ermöglicht es, Unschärfe auf jeden Zersetzungsgrad anzuwenden.\nDie feinsten bis gröbsten Zersetzungsstufen sind von links nach rechts. TP_LOCALLAB_WAT_WAVCBDL_TOOLTIP;Ähnlich wie bei Kontrast nach Detailebenen. Feine bis grobe Detailebenen von links nach rechts auf der x-Achse. TP_LOCALLAB_WAT_WAVDELTABAL_TOOLTIP;Wirkt auf das Gleichgewicht der drei Richtungen (horizontal, vertikal und diagonal) basierend auf der Luminanz des Bildes.\nStandardmäßig werden die Schatten oder Lichter reduziert, um Artefakte zu vermeiden. -TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Zeigt alle Werkzeuge zum 'Kantenschärfen' an. Es wird empfohlen, die Dokumentation zu Wavelet Levels zu lesen. +TP_LOCALLAB_WAT_WAVESHOW_TOOLTIP;Zeigt alle Werkzeuge zum 'Kantenschärfen' an. Es wird empfohlen, die Dokumentation zu Wavelet-Ebenen zu lesen. TP_LOCALLAB_WAT_WAVLEVELBLUR_TOOLTIP;Ermöglicht den maximalen Effekt der Unschärfe auf den Ebenen einzustellen. TP_LOCALLAB_WAT_WAVSHAPE_TOOLTIP;Niedriger bis hoher lokaler Kontrast von links nach rechts auf der x-Achse.\nErhöhen oder verringern Sie den lokalen Kontrast auf der y-Achse. TP_LOCALLAB_WAT_WAVTM_TOOLTIP;Der untere (negative) Teil komprimiert jede Ebene und erzeugt einen Tonwert-Effekt.\nDer obere (positive) Teil dämpft den Kontrast nach Ebene.\nFeine bis grobe Detailebenen von links nach rechts auf der x-Achse. @@ -3583,7 +3778,7 @@ TP_LOCALLAB_WAVCONTF_TOOLTIP;Ähnlich wie bei Kontrast nach Detailebenen. Feine TP_LOCALLAB_WAVDEN;Luminanzkurve TP_LOCALLAB_WAVE;Wavelets TP_LOCALLAB_WAVEDG;Lokaler Kontrast -TP_LOCALLAB_WAVEEDG_TOOLTIP;Verbessert die Schärfe durch gezielte lokale Kontrastwirkung an den Kanten. Es hat die gleichen Funktionen wie das entsprechende Modul in Wavelet Levels und verwendet die gleichen Einstellungen. +TP_LOCALLAB_WAVEEDG_TOOLTIP;Verbessert die Schärfe durch gezielte lokale Kontrastwirkung an den Kanten. Es hat die gleichen Funktionen wie das entsprechende Modul in Wavelet-Ebenen und verwendet die gleichen Einstellungen. TP_LOCALLAB_WAVEMASK_LEVEL_TOOLTIP;Bereich der Wavelet-Ebenen, die in 'Lokaler Kontrast' (nach Wavelet-Ebene) verwendet werden. TP_LOCALLAB_WAVGRAD_TOOLTIP;Anpassen des lokalen Kontrasts entsprechend einem gewählten Gradienten und Winkel. Die Änderung des Luminanz-Signals wird berücksichtigt und nicht die Luminanz. TP_LOCALLAB_WAVHUE_TOOLTIP;Ermöglicht das Verringern oder Erhöhen der Rauschreduzierung basierend auf dem Farbton. @@ -3837,7 +4032,7 @@ TP_RETINEX_TLABEL;T: Min = %1, Max = %2\nT: Mittel = %3, Sigma = %4 TP_RETINEX_TLABEL2;T: Tmin = %1, Tmax = %2 TP_RETINEX_TLABEL_TOOLTIP;Ergebnis der Übertragungszuordnung: Min, Max, Mittel und Sigma\nMin und Max hat Einfluss auf die Abweichung.\n\nTmin = Kleinster Wert der Übertragungszuordnung\nTmax = Größter Wert der Übertragungszuordnung. TP_RETINEX_TRANF;Übertragung -TP_RETINEX_TRANSMISSION;Übertragungzuordnung +TP_RETINEX_TRANSMISSION;Übertragungszuordnung TP_RETINEX_TRANSMISSION_TOOLTIP;Übertragung in Abhängigkeit der Übertragung.\n\nx-Achse: Übertragung negativer Werte (Min),\nMittel und positiver Werte (Max).\n\ny-Achse: Verstärkung oder Abschwächung. TP_RETINEX_UNIFORM;Schatten/Lichter TP_RETINEX_VARIANCE;Kontrast @@ -4191,7 +4386,7 @@ TP_WAVELET_WAVOFFSET;Versatz TP_WBALANCE_AUTO;Automatisch TP_WBALANCE_AUTOITCGREEN;Temperaturbezogen TP_WBALANCE_AUTOOLD;RGB grau -TP_WBALANCE_AUTO_HEADER;Automatisch & Verfeinern +TP_WBALANCE_AUTO_HEADER;Automatisch & Verfeinern TP_WBALANCE_CAMERA;Kamera TP_WBALANCE_CLOUDY;Bewölkt TP_WBALANCE_CUSTOM;Benutzerdefiniert @@ -4218,11 +4413,11 @@ TP_WBALANCE_FLUO_HEADER;Leuchtstofflampe TP_WBALANCE_GREEN;Tönung TP_WBALANCE_GTI;GTI TP_WBALANCE_HMI;HMI -TP_WBALANCE_ITCWALG_TOOLTIP;Ermöglicht Ihnen, wenn möglich, zur anderen alternativen Temperatur (Alt_temp) zu wechseln.\nInaktiv im Fall der "Einzelauswahl". +TP_WBALANCE_ITCWALG_TOOLTIP;Ermöglicht Ihnen, wenn möglich, zur anderen alternativen Temperatur (Alt_temp) zu wechseln.\nInaktiv im Fall der 'Einzelauswahl'. TP_WBALANCE_ITCWBDELTA_TOOLTIP;Für jede versuchte "grüne" Iteration wurde der zu berücksichtigende Temperaturunterschied festgelegt. TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Finden Sie den besten Kompromiss zwischen Kandidat und Grün. TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Ermöglicht Ihnen, den minimalen Patch-Wert festzulegen. Zu niedrige Werte können zu einer fehlenden Korrelation führen. -TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Ermöglicht das Filtern von Magenta-/Lila-Daten aus dem Bild. Wenn das Kontrollkästchen aktiviert ist, wird ein Filter angewendet, der den Wert von Y begrenzt. Standardmäßig beträgt dieser Wert 0,4. Sie können es in "Optionen" Itcwb_Ypurple ändern (maximal 1). +!TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Ermöglicht das Filtern von Magenta-/Lila-Daten aus dem Bild. Wenn das Kontrollkästchen aktiviert ist, wird ein Filter angewandt, der den Wert von Y begrenzt. Standardmäßig beträgt dieser Wert 0,4. Sie können es in 'Optionen' Iterativer temperaturbezogener Weißabgleich Y lila ändern (maximal 1). TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Je niedriger der Wert, desto relevanter sind die Daten, aber desto länger dauert die Verarbeitung. Da die Verarbeitungszeit gering ist, sollte dieser Parameter grundsätzlich auf dem Standardwert bleiben können. TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Legt die Amplitude der Grünwertüberprüfung in Iterationen fest, von der niedrigen Amplitude 0,82 bis 1,25 bis zur maximalen Amplitude 0,4 bis 4. TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Definiert die Anzahl der Farben die vom Algorithmus verwendet werden. @@ -4234,11 +4429,12 @@ TP_WBALANCE_ITCWB_DELTA;Delta-Temperatur in der Grün-Schleife TP_WBALANCE_ITCWB_FGREEN;Ermittle den Grün-Kandidaten TP_WBALANCE_ITCWB_FORCED;Annähernd vollständiges CIE-Diagramm TP_WBALANCE_ITCWB_FRA;Einstellungen Auto-Temperatur-Korrelation -TP_WBALANCE_ITCWB_FRA_TOOLTIP;Diese Einstellungen ermöglichen je nach Bildart (Rohtyp, Farbmetrik usw.) eine Anpassung des Algorithmus "Temperaturkorrelation". Es gibt keine absolute Regel, die diese Parameter mit den erzielten Ergebnissen verknüpft. +TP_WBALANCE_ITCWB_FRA_TOOLTIP;Diese Einstellungen ermöglichen je nach Bildart (Rohtyp, Farbmetrik usw.) eine Anpassung des Algorithmus 'Temperaturkorrelation'. Es gibt keine absolute Regel, die diese Parameter mit den erzielten Ergebnissen verknüpft. TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch Minimalgröße TP_WBALANCE_ITCWB_NOPURPLE;Filter auf Violett -TP_WBALANCE_ITCWB_PRIM_ACE;Erzwingt die Verwendung des vollständiigen CIE-Diagrammes -TP_WBALANCE_ITCWB_PRIM_ADOB;Mittlere Abttastung +TP_WBALANCE_ITCWB_PRECIS;Präzisions-Algorithm - skaliert +TP_WBALANCE_ITCWB_PRIM_ACE;Erzwingt die Verwendung des vollständigen CIE-Diagrammes +TP_WBALANCE_ITCWB_PRIM_ADOB;Mittlere Abtastung TP_WBALANCE_ITCWB_PRIM_BETA;Mittlere Abtastung (Standard) - nahe der Farbskala des Zeigers TP_WBALANCE_ITCWB_PRIM_JDCMAX;Annähernd vollständiges CIE-Diagramm TP_WBALANCE_ITCWB_PRIM_REC;Hohe Abtastung @@ -4247,12 +4443,13 @@ TP_WBALANCE_ITCWB_PRIM_XYZCAM;Kamera-XYZ-Matrix TP_WBALANCE_ITCWB_PRIM_XYZCAM2;JDCmax nach Kamera XYZ-Matrix TP_WBALANCE_ITCWB_RGREEN;Grün-Bereich TP_WBALANCE_ITCWB_SAMPLING;Niedrige Abtastung 5.9 +TP_WBALANCE_ITCWB_SIZE;Größe der Referenzfarbe im Vergleich zum Histogramm TP_WBALANCE_ITCWB_SIZEPATCH;Größe des Farb-Patches TP_WBALANCE_ITCWB_THRES;Verwendete Farben (Voreingestellt) -TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Ermöglicht Ihnen die Verwendung benutzerdefinierter Einstellungen für Temperatur und Grün (Tönung).\n\nNutzungstipps:\n1) Starten Sie Itcwb und aktivieren Sie "Benutzerdefinierte Temperatur und Tönung verwenden".\n2) Stellen Sie "Temperatur und Tönung" nach Ihren Wünschen ein: frei, auswählen ,...(Benutzerdefiniert)\n3) Gehen Sie zurück zu "Temperaturkorrelation".\n\nSie können nicht verwenden: 2 Durchgänge, AWB-Temperatur-Bias, Grün-Verfeinerung. +TP_WBALANCE_ITCWCUSTOM_TOOLTIP;Ermöglicht Ihnen die Verwendung benutzerdefinierter Einstellungen für Temperatur und Grün (Tönung)\n\nnicht zur Verfügung stehen: 2 Durchgänge, AWB-Temperatur-Bias, Grün-Verfeinerung. TP_WBALANCE_ITCWFORCED_TOOLTIP;Standardmäßig (Kontrollkästchen nicht aktiviert) werden die während der Abtastung gescannten Daten auf das sRGB-Profil zurückgeführt, das am weitesten verbreitet ist, sowohl für die Kalibrierung von DCP- oder ICC-Profilen mit dem Colorchecker24 als auch für die Verwendung im Internet.\nWenn Sie Bilder mit sehr hohem Farbumfang haben (einige Blumen, künstliche Farben), kann es erforderlich sein, das gesamte CIExy-Diagramm zu verwenden. Das verwendete Profil ist ACESP0. In diesem zweiten Fall ist die Anzahl der Farben, die innerhalb des Algorithmus verwendet werden können, wichtiger. TP_WBALANCE_ITCWGREEN;Grün-Verfeinerung -TP_WBALANCE_ITCWGREEN_TOOLTIP;Verändert die Grün-Tönung als Referenz für den Algorithmus. Es hat im Wesentlichen die gleiche Rolle für Grün wie die "AWB-Temperaturabweichung" für die Temperatur.\nDer gesamte Algorithmus wird neu berechnet. +TP_WBALANCE_ITCWGREEN_TOOLTIP;Verändert die Grün-Tönung als Referenz für den Algorithmus. Es hat im Wesentlichen die gleiche Rolle für Grün wie die 'AWB-Temperaturabweichung' für die Temperatur.\nDer gesamte Algorithmus wird neu berechnet. TP_WBALANCE_ITCWPRIM_TOOLTIP;Ermöglicht die Auswahl der Bildabtastung.\n'Annähernd vollständiges CIE-Diagramm' verwendet fast die auf dem Sensor vorhandenen Daten, möglicherweise einschließlich der imaginären Farben.\n'Kamera-XYZ-Matrix' – verwendet die direkt von der Farbmatrix abgeleitete Matrix.\n'Mittlere Abtastung (Standard) - nahe der Farbskala des Zeigers' entspricht im Wesentlichen den häufigsten Fällen des menschlichen Sehens.\nMit 'Geringe Abtastung und keine Kameraeinstellungen verwenden' können Sie Teile des Bildes mit hoher Farbskala isolieren und den Algorithmus zwingen, die Kameraeinstellungen in einigen Fällen (Tönung > 0,8,...) zu ignorieren. Dies wird sich natürlich auf das Ergebnis auswirken.\n\nDieses Sampling hat nur einen Einfluss auf die Kanalmultiplikatoren, es hat nichts mit dem "Arbeitsprofil" zu tun und verändert nicht die Farbskala des Bildes. TP_WBALANCE_ITCWSAMPLING_TOOLTIP;Ermöglicht die Verwendung des alten Sampling-Algorithmus, um eine bessere Kompatibilität mit 5.9 sicherzustellen. Dazu muss Beobachter 10° (Standard) aktiviert sein. TP_WBALANCE_JUDGEIII;JudgeIII @@ -4265,7 +4462,7 @@ TP_WBALANCE_METHOD;Methode TP_WBALANCE_MULLABEL;Multiplikatoren: r=%1 g=%2 b=%3 TP_WBALANCE_MULLABEL_TOOLTIP;Die Werte dienen der Information, sie können nicht geändert werden. TP_WBALANCE_OBSERVER10;Beobachter 10° anstatt Beobachter 2° -TP_WBALANCE_OBSERVER10_TOOLTIP;Das Farbmanagement in Rawtherapee (Weißabgleich, Kanalmultiplikatoren, Lichter-Rekonstruktion,...) nutzt die Spektraldaten der Leuchtmittel und Farben. Der Beobachter ist ein wichtiger Parameter dieses Managements, der den Wahrnehmungswinkel des Auges berücksichtigt. Im Jahr 1931 wurde er auf 2° festgelegt (privilegiert die Verwendung der Kegel). Im Jahr 1964 wurde er auf 10° festgelegt (privilegiert die Verwendung der Zapfen, berücksichtigt jedoch teilweise die Stäbchen).\nIm Falle einer (seltenen) Drift der Farben aufgrund des Beobachters 10° – wahrscheinlich aufgrund der Konvertierungsmatrix – muss Beobachter 2° ausgewählt werden.\nIn den meisten Fällen ist Beobachter 10° (Standard) die bessere Wahl. +TP_WBALANCE_OBSERVER10_TOOLTIP;Das Farbmanagement in RawTherapee (Weißabgleich, Kanalmultiplikatoren, Lichter-Rekonstruktion,...) verwendet die Spektraldaten der Lichtquellen und Farben. Der Beobachter ist ein wichtiger Parameter dieses Managements, der den Wahrnehmungswinkel des Auges berücksichtigt. Im Jahr 1931 wurde er auf 2° festgelegt (privilegiert die Verwendung der Zapfen). Im Jahre 1964 wurde er auf 10° festgelegt (privilegiert die Verwendung der Zapfen, berücksichtigt aber teilweise die Stäbchen). \nIm seltenen Fall einer Farbdrift mit 'Beobachter 2°' (wahrscheinlich aufgrund der Konvertierungsmatrix) muss 'Beobachter 10°' ausgewählt werden. TP_WBALANCE_PATCHLABEL;Gelesene Farben: %1 Patch Chroma: %2 Größe= %3 TP_WBALANCE_PATCHLABEL_TOOLTIP;Zeigt die Anzahl der gelesenen Farben an (max. = 237).\nZeigt die berechnete Patch-Chroma an.\nAWB-Temperaturabweichung. Versuchen Sie, diesen Wert zu reduzieren. Ein Minimum scheint den Algorithmus zu optimieren.\n\nPatch-Größe passt zur Chroma-Optimierung. TP_WBALANCE_PATCHLEVELLABEL;Patch: ΔE= %1 - Daten x 9 Min: %2 Max= %3 @@ -4296,206 +4493,3 @@ ZOOMPANEL_ZOOMFITCROPSCREEN;Ausschnitt an Bildschirm anpassen.\nTaste: f ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: Alt + f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - -//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. -//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!ERROR_MSG_METADATA_VALUE;Metadata: error setting %1 to %2 -!FILEBROWSER_SHOWRECURSIVE;Show images in sub-folders recursively. -!HISTORY_MSG_ICM_CAT;Matrix adaptation -!HISTORY_MSG_ICM_MIDTCIE;Midtones -!HISTORY_MSG_ICM_REFI;Refinement Colors -!HISTORY_MSG_ICM_SHIFTX;Refinement Colors - Shift x -!HISTORY_MSG_ICM_SHIFTY;Refinement Colors - Shift y -!HISTORY_MSG_ICM_SMOOTHCIE;Smooth highlights -!HISTORY_MSG_ICM_TRCEXP;Abstract Profile -!HISTORY_MSG_LOCAL_CIEMASK_BLURCONT;Local - CIECAM Mask blur contrast -!HISTORY_MSG_LOCAL_CIEMASK_BLURFFT;Local - CIECAM Mask blur FFTW -!HISTORY_MSG_LOCAL_CIEMASK_BLURRAD;Local - CIECAM Mask blur radius -!HISTORY_MSG_LOCAL_CIEMASK_CHH;Local - CIECAM Mask curve h(h) -!HISTORY_MSG_LOCAL_CIEMASK_HIGH;Local - CIECAM Mask highlights -!HISTORY_MSG_LOCAL_CIEMASK_SHAD;Local - CIECAM Mask shadows -!HISTORY_MSG_LOCAL_CIEMASK_STRU;Local - CIECAM Mask structure -!HISTORY_MSG_LOCAL_CIEMASK_STRU_TOOL;Local - CIECAM Mask structure as tool -!HISTORY_MSG_LOCAL_CIEMASK_WLC;Local - CIECAM Mask wavelet L(L) -!HISTORY_MSG_LOCAL_CIEMASK_WLEV;Local - CIECAM Mask wavelet levels -!HISTORY_MSG_LOCAL_CIE_ANGGRAD;Local - CIECAM Gradient angle -!HISTORY_MSG_LOCAL_CIE_BLACKS;Local - CIECAM Blacks distribution -!HISTORY_MSG_LOCAL_CIE_BLUXL;Local - CIECAM Blue X -!HISTORY_MSG_LOCAL_CIE_BLUYL;Local - CIECAM Blue Y -!HISTORY_MSG_LOCAL_CIE_BRICOMP;Local - CIECAM Brightness compression -!HISTORY_MSG_LOCAL_CIE_BRICOMPTH;Local - CIECAM Brightness compression threshold -!HISTORY_MSG_LOCAL_CIE_BWCIE;Local - CIECAM Black and white -!HISTORY_MSG_LOCAL_CIE_CAT;Local - Matrix adaptation -!HISTORY_MSG_LOCAL_CIE_DETAILJZ;Local - JzCzHz Local contrast -!HISTORY_MSG_LOCAL_CIE_ENAMASKALL;Local - CIECAM All mask tools -!HISTORY_MSG_LOCAL_CIE_EXPPRECAM;Local - CIECAM Pre-Cam -!HISTORY_MSG_LOCAL_CIE_GAM;Local - CIECAM Gamma -!HISTORY_MSG_LOCAL_CIE_GAMUTCIE;Local - CIECAM Gamut -!HISTORY_MSG_LOCAL_CIE_GREXL;Local - CIECAM Green X -!HISTORY_MSG_LOCAL_CIE_GREYL;Local - CIECAM Green Y -!HISTORY_MSG_LOCAL_CIE_ILL;Local - CIECAM TRC Illuminant -!HISTORY_MSG_LOCAL_CIE_LOGCIEQ;Local - CIECAM Log encoding Q -!HISTORY_MSG_LOCAL_CIE_MIDT;Local - CIECAM Mid Tones -!HISTORY_MSG_LOCAL_CIE_NORM;Local - CIECAM Normalize L -!HISTORY_MSG_LOCAL_CIE_PRIM;Local - CIECAM TRC primaries -!HISTORY_MSG_LOCAL_CIE_REDXL;Local - CIECAM Red X -!HISTORY_MSG_LOCAL_CIE_REDYL;Local - CIECAM Red Y -!HISTORY_MSG_LOCAL_CIE_REFI;Local - CIECAM Refinement colors -!HISTORY_MSG_LOCAL_CIE_SATCIE;Local - CIECAM Saturation control -!HISTORY_MSG_LOCAL_CIE_SHIFTXL;Local - CIECAM Shift x -!HISTORY_MSG_LOCAL_CIE_SHIFTYL;Local - CIECAM Shift y -!HISTORY_MSG_LOCAL_CIE_SIG;Local - Sigmoid -!HISTORY_MSG_LOCAL_CIE_SIGADAP;Local - CIECAM Sigmoid adaptability -!HISTORY_MSG_LOCAL_CIE_SIGMET;Local - CIECAM Sigmoid method -!HISTORY_MSG_LOCAL_CIE_SLOP;Local - CIECAM Slope -!HISTORY_MSG_LOCAL_CIE_SLOPESMO;Local - CIECAM Gray balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOB;Local - CIECAM Blue balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOG;Local - CIECAM Green balance -!HISTORY_MSG_LOCAL_CIE_SLOPESMOR;Local - CIECAM Red balance -!HISTORY_MSG_LOCAL_CIE_SMOOTH;Local - CIECAM Scale Yb scene -!HISTORY_MSG_LOCAL_CIE_SMOOTHMET;Local - CIECAM Smooth lights method -!HISTORY_MSG_LOCAL_CIE_SMOOTHYB;Local - CIECAM Scale Yb viewing -!HISTORY_MSG_LOCAL_CIE_SMOOTH_LUM;Local - CIECAM Levels - Luminosity mode -!HISTORY_MSG_LOCAL_CIE_STRGRAD;Local - CIECAM Gradient strength L -!HISTORY_MSG_LOCAL_CIE_STRLOG;Local - CIECAM Log encoding strength -!HISTORY_MSG_LOCAL_CIE_TRC;Local - CIECAM TRC -!HISTORY_MSG_LOCAL_CIE_WHITES;Local - CIECAM Whites distribution -!HISTORY_MSG_LOCAL_FEATHERCIE;Local - CIECAM Gradient feather -!HISTORY_MSG_LOCAL_FEATHERCOL;Local - Color Gradient feather -!HISTORY_MSG_LOCAL_FEATHEREXE;Local - Exp Gradient feather -!HISTORY_MSG_LOCAL_FEATHERLOG;Local - Log Gradient feather -!HISTORY_MSG_LOCAL_FEATHERMAS;Local - Mask Common gradient feather -!HISTORY_MSG_LOCAL_FEATHERSH;Local - SH Gradient feather -!HISTORY_MSG_LOCAL_FEATHERVIB;Local - Vib Gradient feather -!HISTORY_MSG_LOCAL_FEATHERWAV;Local - Wav Gradient feather -!HISTORY_MSG_LOCAL_LOG_BLACKS;Local - Log Blacks distribution -!HISTORY_MSG_LOCAL_LOG_COMPR;Local - Log Compress brightness -!HISTORY_MSG_LOCAL_LOG_SAT;Local - Log Saturation control -!HISTORY_MSG_LOCAL_LOG_WHITES;Local - Log Whites distribution -!HISTORY_MSG_LOCAL_TMO_SATUR;Local Exp Fattal Saturation -!HISTORY_MSG_WBITC_DELTA;Itcwb Delta green -!HISTORY_MSG_WBITC_FGREEN;Itcwb Green - student -!HISTORY_MSG_WBITC_FORCE;Itcwb Force -!HISTORY_MSG_WBITC_NOPURPLE;Itcwb Nopurple -!HISTORY_MSG_WBITC_PONDER;Itcwb ponderated -!HISTORY_MSG_WBITC_PRECIS;Itcwb Precision -!HISTORY_MSG_WBITC_RGREEN;Itcwb Green range -!HISTORY_MSG_WBITC_SAMPLING;Low sampling -!HISTORY_MSG_WBITC_SIZE;Itcwb Size -!HISTORY_MSG_WBITC_SORTED;Itcwb ponderated -!HISTORY_MSG_WBITC_THRES;Itcwb Threshold -!PREFERENCES_BROWSERECURSIVEDEPTH;Browse sub-folders depth -!PREFERENCES_BROWSERECURSIVEFOLLOWLINKS;Follow symbolic links when browsing sub-folders -!PREFERENCES_BROWSERECURSIVEMAXDIRS;Maximum sub-folders -!PREFERENCES_MAX_ZOOM_TITLE;Maximum zoom -!PREFERENCES_RAW_DECODER;Raw Decoder -!PREFERENCES_RAW_DECODER_ENABLE_LIBRAW;Use LibRaw -!PREFERENCES_SPOTLOC;Define Spot method for Selective Editing -!PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Load/Save thumbnail rank and color from/to XMP sidecars -!PREFERENCES_WBAFORC;Forces Extra algoritm -!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) -!PREFERENCES_WBANOPURP;No purple color used -!PREFERENCES_WBAPATCH;Number maximum of colors used in picture -!PREFERENCES_WBAPRECIS;Precision algorithm - scale used -!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color -!PREFERENCES_WBASORT;Sort in chroma order instead of histogram -!QUEUE_DESTPREVIEW_TITLE;Select a thumbnail to preview its destination path here -!QUEUE_DESTPREVIEW_TOOLTIP;Destination path for the first selected image appears here -!QUEUE_LOCATION_TEMPLATE_HELP_BUTTON_TOOLTIP;Show or hide a help panel with instructions for creating location templates -!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_BODY;If you want to save the output image alongside the source image, write:\n%p1/%f\n\nIf you want to save the output image in a folder named 'converted' located in the source photo's folder, write:\n%p1/converted/%f\n\nIf you want to save the output image in\n'/home/tom/photos/converted/2010-10-31', write:\n%p-3/converted/%P-4/%f -!QUEUE_LOCATION_TEMPLATE_HELP_EXAMPLES_TITLE;Common examples -!QUEUE_LOCATION_TEMPLATE_HELP_INTRO;The output template field allows you to to dynamically customize the destination folder and filename. When you include certain specifiers, which begin with %, they are replaced by the program when each file is being saved.\n\nThe sections below describe each type of specifier. -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_1;Using this pathname as an example: -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_BODY_2;The meanings of the formatting strings are: -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_LINUX;/home/tom/photos/2010-10-31/photo1.raw -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_EXAMPLE_WINDOWS;D:\tom\photos\2010-10-31\photo1.raw -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO;The %dN, %d-N, %pN, %p-N, %PN and %P-N (N = 1..9) specifiers will be replaced by elements of the image file's directory path.\nThe format specifiers operate as follows:\n %dN = Nth directory from the end of the path\n %d-N = Nth directory from the start of the path\n %pN = all directories up to the Nth from the end of the path\n %p-N = the first N directories in the path\n %PN = the last N directories in the path\n %P-N = all directories from the Nth to the end of the path\n %f = base filename (no extension) -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_INTRO_WINDOWS;For Windows paths, %d-1 is the drive letter and colon, and %d-2 is the base directory on that drive. -!QUEUE_LOCATION_TEMPLATE_HELP_PATHS_TITLE;Directories and partial paths -!QUEUE_LOCATION_TEMPLATE_HELP_RANK_BODY;%r will be replaced by the photo's rank. If the photo is unranked, '0' is used. If the photo is in the trash, 'x' is used. -!QUEUE_LOCATION_TEMPLATE_HELP_RANK_TITLE;Rank -!QUEUE_LOCATION_TEMPLATE_HELP_RESULT_MISMATCH;ERROR: 2nd result is different: -!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_BODY;%s1, ..., %s9 will be replaced by the photo's initial position in the queue at the time the queue is started. The number specifies the padding, e.g. %s3 results in '001'. -!QUEUE_LOCATION_TEMPLATE_HELP_SEQUENCE_TITLE;Position/sequence in queue -!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_BODY;Three different date/time values may be used in templates:\n %tE"%Y-%m-%d" = when export started\n %tF"%Y-%m-%d" = when file was last saved\n %tP"%Y-%m-%d" = when photo was taken\nThe quoted string defines the format of the resulting date and/or time. The format string %tF"%Y-%m-%d" is just one example. The string can use all conversion specifiers defined for the g_date_time_format function (see https://docs.gtk.org/glib/method.DateTime.format.html).\n\nExample format strings: -!QUEUE_LOCATION_TEMPLATE_HELP_TIMESTAMP_TITLE;Date and time -!QUEUE_LOCATION_TEMPLATE_HELP_TITLE;Creating an output template -!TC_LOCALLAB_PRIM_SHIFTX;Shift x -!TC_LOCALLAB_PRIM_SHIFTX_TOOLTIP;In combination with "Refine colors", allows you to:\n 1) for low values, adjust the image purity.\n 2) for higher values, carry out moderate color toning.\nBe careful not to go outside the CIE xy diagram. -!TC_LOCALLAB_PRIM_SHIFTY;Shift y -!TC_PRIM_REFI;Refine colors (white-point) -!TP_ICM_BW;Black and White -!TP_ICM_WORKING_CAT;Matrix adaptation -!TP_ICM_WORKING_CAT_BRAD;Bradford -!TP_ICM_WORKING_CAT_CAT02;Cat02 -!TP_ICM_WORKING_CAT_CAT16;Cat16 -!TP_ICM_WORKING_CAT_TOOLTIP;Performs the chromatic adaptation of the XYZ conversion matrix. Default: Bradford -!TP_ICM_WORKING_CAT_VK;Von Kries -!TP_ICM_WORKING_CAT_XYZ;XYZ scale -!TP_ICM_WORKING_ILLU_E;E -!TP_ICM_WORKING_NON;None -!TP_ICM_WORKING_PRIM_FREE;Custom LA (sliders) -!TP_ICM_WORKING_PRIM_JDCMAXSTDA;JDC Max stdA -!TP_ICM_WORKING_PRIM_TOOLTIP;Performs a gamut control. Destination primaries (Advanced) allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified.\nWhen 'Custom LA (sliders)' is selected, you can modify the values of the 3 primaries (Red, Green, and Blue) for x and y. -!TP_LENSPROFILE_CORRECTION_METADATA;From file metadata -!TP_LOCALLAB_BWEVNONE;None -!TP_LOCALLAB_BWEVSIG;Activated -!TP_LOCALLAB_BWEVSIGLOG;Sigmoid & Log-Encoding -!TP_LOCALLAB_CIE_SMOOTHFRAME;Highlight Attenuation & Levels -!TP_LOCALLAB_CIE_SMOOTH_EV;Ev based -!TP_LOCALLAB_CIE_SMOOTH_GAMMA;Slope based -!TP_LOCALLAB_CIE_SMOOTH_GAMMA ROLLOFF;Gamma based -!TP_LOCALLAB_CIE_SMOOTH_LEVELS;Levels -!TP_LOCALLAB_CIE_SMOOTH_NONE;None -!TP_LOCALLAB_COLORFRAME;Dominant color -!TP_LOCALLAB_COMPRCIE;Brightness compression -!TP_LOCALLAB_COMPRCIETH;Compression threshold -!TP_LOCALLAB_COMPRLOG_TOOLTIP;This algorithm compress the data before log conversion, above the threshold slider value. To use in conjunction with Whites distribution. -!TP_LOCALLAB_DEHAZE_BLACK;Black -!TP_LOCALLAB_DISAB_CIECAM;Disable Ciecam or Weak Jz surround -!TP_LOCALLAB_ENABLE_MASKALL;Enable all mask tools -!TP_LOCALLAB_EXMAIN;Global -!TP_LOCALLAB_FATSAT;Saturation control -!TP_LOCALLAB_FEATVALUE_MASK;Feather gradient (Grad. Filters Mask) -!TP_LOCALLAB_LOGCIEQ;Log Encoding Q (with Ciecam) -!TP_LOCALLAB_LOGCIEQ_TOOLTIP;Activating the checkbox allows you to switch between log encoding based on the 3 RGB channels, and log encoding based solely on Ciecam’s brightness (Q) channel.\nUsing the Q channel instead of the RGB channels helps avoid undesirable edge effects such as hue and saturation shifts.\nHowever, the settings are more difficult to optimise because Q is unbounded and Ciecam alters the data to take into account the surround conditions, simultaneous contrast, etc.\nYou may have to adjust the following:\n Scene conditions: Mean luminance (Yb), Whites & Blacks distribution, Black Ev, White Ev.\n Source Data Adjustments : Brightness compression, Strength.\n\nNote: when using Log Encoding (Q), be careful not to activate the Disable Ciecam option in the Scene Conditions, Surround menu. -!TP_LOCALLAB_LOGPFRA2;Log Encoding settings -!TP_LOCALLAB_MIDTCIE;Midtones -!TP_LOCALLAB_PRECAMGAMUT_TOOLTIP;If checked, ensures a gamut control just after primary conversion to XYZ. -!TP_LOCALLAB_PRECAMREFIMAIN_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. In combination with "Shift x" and "Shift y", allows you to carry out moderate color toning. -!TP_LOCALLAB_PRECAMREFI_TOOLTIP;Allows you to move the white-point in such a way that it approaches the dominant color. This action modifies the purity. -!TP_LOCALLAB_PRECAM_TOOLTIP;'Source Data Adjustments' modifies the Dynamic Range using Log encoding, the tones of the image and primaries (simplified Abstract Profile), and midtones, just before the Ciecam process. These values are adjustable:\nGamma: Acts mainly on light tones\nSlope: Acts mainly on dark tones. You can choose any pair of gamma and slope (values >1) and the algorithm will ensure that there is continuity between the linear and parabolic parts of the curve.\nDestination primaries: Allows you to change the destination primaries to restore or change image color (saturation). The color balance is significantly preserved when the 'Working Profile' and the 'Destination primaries' are similar. 'Working Profile' is not modified. You can also finely adapt the primaries and the illuminant (white-point). Moving a primary away from the white point reduces saturation and vice versa. Pay attention to the gamut. -!TP_LOCALLAB_PRIMILLFRAME;Primaries & Illuminant -!TP_LOCALLAB_SATCIE;Saturation control -!TP_LOCALLAB_SIGBLACKSSCIE;Blacks distribution -!TP_LOCALLAB_SIGCIE;Sigmoid -!TP_LOCALLAB_SIGGAMJCIE;Gamma -!TP_LOCALLAB_SIGMOID16_TOOLTIP;Allows you to simulate a tone mapping appearance using both 'Ciecam' and 'Sigmoid Q'. Sigmoid Q has three sliders:\na) Contrast acts on the shape of the sigmoid curve and consequently on the strength\nb) Threshold (Gray point) distributes the action according to the luminance\nc) Adaptability weights the action of the sigmoid by action on the internal exponential function. -!TP_LOCALLAB_SIGMOIDLOGAUTO;Auto threshold -!TP_LOCALLAB_SIGMOIDLOGEV_TOOLTIP;If the combo box selection 'Black Ev and White Ev' is 'Sigmoid and Log encoding' instead of 'Sigmoid only', the two algorithms 'Log encoding' and 'Sigmoid' are used together. -!TP_LOCALLAB_SIGMOIDNORMCIE;Normalize Luminance -!TP_LOCALLAB_SIGMOIDNORMCIEBLEND_TOOLTIP;Blend acts on the final aspect of the image, contrast and luminance. Ratio between original and output image. -!TP_LOCALLAB_SIGMOIDNORMCIE_TOOLTIP;Reconstruct luminance so that the mean and variance of the output image take into account those of the original.\nAll the adjustments acting on J or Q are taken into account, including those which are not relative to Sigmoid Q. -!TP_LOCALLAB_SIGMOIDQJCOMPRCIE_TOOLTIP;When the combo box selection 'Uses Black Ev and White Ev' is 'Sigmoid and Log encoding Q' or 'Log encoding instead of Sigmoid' checked. This algorithm compress the data above the threshold slider value. The last value stands for brightness (Q) and should be close as possible to the value 'Compression threshold' (calculate when 'Auto threshold" checked, often > 1). -!TP_LOCALLAB_SIGMOIDSENSI;Adaptability -!TP_LOCALLAB_SIGMOIDWHITESCIE_TOOLTIP;Allows you, in Automatic when the dynamic range of the image is high, to change the distribution of lights in whites and deep blacks.\nCan be used with Log encoding or Sigmoid with Black Ev and White Ev enabled.\n\nThe algorithm does not change the basic data, but acts on the components necessary to calculate the Dynamic range, Black Ev, White Ev and the Gray point. -!TP_LOCALLAB_SIGSLOPJCIE;Slope -!TP_LOCALLAB_SIGTRCCIE;Source Data Adjustments -!TP_LOCALLAB_SIGWHITESCIE;Whites distribution -!TP_LOCALLAB_SLOPESMOOTH;Gray balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHB;Blue balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHG;Green balance (Slope) -!TP_LOCALLAB_SLOPESMOOTHR;Red balance (Slope) -!TP_LOCALLAB_SMOOTHCIE;Highlight Attenuation -!TP_LOCALLAB_SMOOTHCIE_LUM;Luminosity mode -!TP_LOCALLAB_SMOOTHCIE_SCA;Scale Yb Scene -!TP_LOCALLAB_SMOOTHCIE_TOOLTIP;Completes the processing carried out by gamma, slope and midtones by causing a slight lowering of lights. Please note this does not replace Highlight reconstruction.\n\nGamma based and Slope based (Standard and Advanced) allow you to simulate a tone mapping using:\na) Scene conditions: Black-Ev, White-Ev, Mean luminance (Yb%)\nb) Viewing conditions: Mean luminance (Yb%).\n\nScale Yb Scene is function of White-Ev. -!TP_LOCALLAB_SMOOTHCIE_YB;Scale Yb Viewing -!TP_LOCALLAB_STRENGTHCIELOG;Strength -!TP_LOCALLAB_TRCFRAME;Tone Response Curve & Midtones -!TP_WBALANCE_ITCWB_PRECIS;Precision algorithm - scale used -!TP_WBALANCE_ITCWB_SIZE;Size of ref. color compare to histogram From d3ad7581c28f001987157707ad9a58c161ce75c5 Mon Sep 17 00:00:00 2001 From: Martin <78749513+marter001@users.noreply.github.com> Date: Sun, 11 Aug 2024 08:00:26 +0200 Subject: [PATCH 288/291] Update Deutsch --- rtdata/languages/Deutsch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index ebec02af0..d71e7592d 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -86,6 +86,7 @@ #84 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 #85 29.07.2022 Erweiterung (marter, mozzihh) RT 5.9 #86 29.08.2024 (marter) RT 5.11 + #100 #101 @LANGUAGE_DISPLAY_NAME=Deutsch ABOUT_TAB_BUILD;Version @@ -1466,7 +1467,7 @@ HISTORY_MSG_1147;(sel. Editieren - CIECAM)\nSigmoid Jz\nVerwendet Schwarz-Ev Wei HISTORY_MSG_1148;(sel. Editieren - CIECAM)\nSigmoid Jz HISTORY_MSG_1149;(sel. Editieren - CIECAM)\nSigmoid Q HISTORY_MSG_1150;(sel. Editieren - CIECAM)\nSigmoid\nQuellen-Daten\nLOG-Kodierung -HISTORY_MSG_BLSHAPE;(Erweitert - Wavelet)\nUnschärfeebenen\nUnschärfe nach Ebenen +HISTORY_MSG_BLSHAPE;(Erweitert - Wavelet)\nUnschärfeebenen\nUnschärfe nach Ebenena HISTORY_MSG_BLURCWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Buntheit HISTORY_MSG_BLURWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Helligkeit HISTORY_MSG_BLUWAV;(Erweitert - Wavelet)\nUnschärfeebenen\nDämpfungsreaktion @@ -1495,7 +1496,7 @@ HISTORY_MSG_DEHAZE_ENABLED;(Details - Bildschleier entfernen) HISTORY_MSG_DEHAZE_SATURATION;(Details - Bildschleier entfernen)\nSättigung HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;(Details - Bildschleier entfernen)\nMaske anzeigen HISTORY_MSG_DEHAZE_STRENGTH;(Details - Bildschleier entfernen)\nIntensität -HISTORY_MSG_DIRPYRDENOISE_GAIN;Details - Rauschminderung)\nKompensation nach Bildhelligkeit +HISTORY_MSG_DIRPYRDENOISE_GAIN;(Details - Rauschminderung)\nKompensation nach Bildhelligkeit HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;(RAW - Sensor-Matrix)\nFarbinterpolation\nAuto-Kontrastschwelle HISTORY_MSG_DUALDEMOSAIC_CONTRAST;(RAW - Sensor-Matrix)\nFarbinterpolation\nKontrastschwelle HISTORY_MSG_EDGEFFECT;(Erweitert - Wavelet)\nKantenschärfung\nDämpfungsreaktion From 5a832468da8f6ce2bd363cf6beb2e2887da387b5 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 11 Aug 2024 11:43:57 -0700 Subject: [PATCH 289/291] Clean up German translation --- rtdata/languages/Deutsch | 118 +++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index d71e7592d..72bdae9fa 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -84,11 +84,12 @@ #83 06.07.2019 Erweiterung (TooWaBoo) RT 5.6 #84 06.10.2019 Erweiterung (TooWaBoo) RT 5.7 #84 18.07.2019 Erweiterung (TooWaBoo) RT 5.6 -#85 29.07.2022 Erweiterung (marter, mozzihh) RT 5.9 -#86 29.08.2024 (marter) RT 5.11 - +#85 29.07.2022 Erweiterung (marter, mozzihh) RT 5.9 +#86 2023-09, Version RT 5.10 (marter) +#87 29.08.2024 (marter) RT 5.11 #100 #101 @LANGUAGE_DISPLAY_NAME=Deutsch + ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen ABOUT_TAB_LICENSE;Lizenz @@ -195,7 +196,7 @@ EXPORT_PUTTOQUEUEFAST;Zur Warteschlange 'Schneller Export' hinzufügen EXPORT_RAW_DMETHOD;Demosaikmethode EXPORT_USE_FAST_PIPELINE;Priorität Geschwindigkeit EXPORT_USE_FAST_PIPELINE_TOOLTIP;Wendet alle Bearbeitungsschritte, im Gegensatz zu 'Standard', auf das bereits skalierte Bild an.\nDadurch steigt die Verarbeitungsgeschwindigkeit auf Kosten der Qualität. -EXPORT_USE_NORMAL_PIPELINE;Standard (überspringt einige Schritte, Skalieren zuletzt) +EXPORT_USE_NORMAL_PIPELINE;Standard (überspringt einige Schritte, Skalieren zuletzt) EXTPROGTARGET_1;RAW EXTPROGTARGET_2;Stapelverarbeitung beendet FILEBROWSER_APPLYPROFILE;Profil anwenden @@ -351,7 +352,7 @@ HISTOGRAM_TOOLTIP_TRACE_BRIGHTNESS;Helligkeitsbereich anpassen HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogramm HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw-Histogramm HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB-Parade -HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Vektorskop Farbton-Chroma +HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Vektorskop Farbton-Chroma HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Vektorskop Farbton-Sättigung HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Wellenform HISTORY_CHANGED;Geändert @@ -495,7 +496,7 @@ HISTORY_MSG_153;(Farbe - Dynamik)\nGesättigte Töne HISTORY_MSG_154;(Farbe - Dynamik)\nHautfarbtöne schützen HISTORY_MSG_155;(Farbe - Dynamik)\nFarbverschiebungen vermeiden HISTORY_MSG_156;(Farbe - Dynamik)\nPastell- und gesättigte Töne koppeln -HISTORY_MSG_157;(Farbe - Dynamik)\nSchwelle: Pastell- / gesättigte Töne +HISTORY_MSG_157;(Farbe - Dynamik)\nSchwelle: Pastell- / gesättigte Töne HISTORY_MSG_158;(Belichtung - Tonwertkorrektur)\nIntensität HISTORY_MSG_159;(Belichtung - Tonwertkorrektur)\nKantenschutz HISTORY_MSG_160;(Belichtung - Tonwertkorrektur)\nFaktor @@ -861,7 +862,7 @@ HISTORY_MSG_527;(sel. Editieren - Farbe-Licht)\nInvertieren HISTORY_MSG_528;(sel. Editieren - Dynamik u. Belichtung) HISTORY_MSG_529;(sel. Editieren - Dynamik u. Belichtung)\nKompression HISTORY_MSG_530;(sel. Editieren - Dynamik u. Belichtung)\nLichterkompression -HISTORY_MSG_531;(sel. Editieren - Dynamik u. Belichtung)\nLichterkompression\nSchwellenwert +HISTORY_MSG_531;(sel. Editieren - Dynamik u. Belichtung)\nLichterkompression\nSchwellenwert HISTORY_MSG_532;(sel. Editieren - Dynamik u. Belichtung)\nSchwarzwert HISTORY_MSG_533;(sel. Editieren - Dynamik u. Belichtung)\nSchattenkompression HISTORY_MSG_534;(sel. Editieren - Farbtemperatur)\nTönung @@ -1113,7 +1114,7 @@ HISTORY_MSG_786;(sel. Editieren - Schatten/Lichter)\nMethode HISTORY_MSG_787;(sel. Editieren - Schatten/Lichter)\nTonwert-Equalizer\nWerte HISTORY_MSG_788;(sel. Editieren - Schatten/Lichter)\nTonwert-Equalizer\nDetails HISTORY_MSG_789;(sel. Editieren - Schatten/Lichter)\nMaske\nIntensität -HISTORY_MSG_790;(sel. Editieren - Schatten/Lichter)\nMaske Ankerpunkt +HISTORY_MSG_790;(sel. Editieren - Schatten/Lichter)\nMaske Ankerpunkt HISTORY_MSG_791;(sel. Editieren - Maske)\nShort L-Kurve HISTORY_MSG_792;(sel. Editieren - Spot)\nMaskieren\nHintergrund Maske HISTORY_MSG_793;(sel. Editieren - Schatten/Lichter)\nGamma Farbtonkennlinie @@ -1125,7 +1126,7 @@ HISTORY_MSG_798;(sel. Editieren - Farbe-Licht)\nZusammenführen\nDeckkraft HISTORY_MSG_799;(sel. Editieren - Farbe-Licht)\nRGB-Kurve HISTORY_MSG_800;(sel. Editieren - Farbe-Licht)\nMethode RGB-Kurven HISTORY_MSG_801;(sel. Editieren - Farbe-Licht)\nSpezielle Verwendung RGB-Kurven -HISTORY_MSG_802;(sel. Editieren - Farbe-Licht)\nZusammenführen\nSchwellenwert Kontrast +HISTORY_MSG_802;(sel. Editieren - Farbe-Licht)\nZusammenführen\nSchwellenwert Kontrast HISTORY_MSG_803;(sel. Editieren - Farbe-Licht)\nZusammenführen HISTORY_MSG_804;(sel. Editieren - Farbe-Licht)\nIntensität Strukturmaske HISTORY_MSG_805;(sel. Editieren - Unschärfe)\nIntensität Strukturmaske @@ -1178,7 +1179,7 @@ HISTORY_MSG_853;(sel. Editieren - LOG-Kodierung)\nLokaler Kontrast HISTORY_MSG_854;(sel. Editieren - LOG-Kodierung)\nBereich HISTORY_MSG_855;(sel. Editieren - LOG-Kodierung)\nGesamtes Bild HISTORY_MSG_856;(sel. Editieren - LOG-Kodierung)\nBereich Schatten -HISTORY_MSG_857;(sel. Editieren - Wavelet)\nUnschärfeebenen\nVerbleibende Unschärfe +HISTORY_MSG_857;(sel. Editieren - Wavelet)\nUnschärfeebenen\nVerbleibende Unschärfe HISTORY_MSG_858;(sel. Editieren - Wavelet)\nUnschärfeebenen\nNur Luminanz HISTORY_MSG_859;(sel. Editieren - Wavelet)\nUnschärfeebenen\nMaximum HISTORY_MSG_860;(sel. Editieren - Wavelet)\nUnschärfeebenen @@ -1236,7 +1237,7 @@ HISTORY_MSG_915;(sel. Editieren - Wavelet)\nKantenschärfe\nDämpfungsreaktion HISTORY_MSG_916;(sel. Editieren - Wavelet)\nRestbild Schatten HISTORY_MSG_917;(sel. Editieren - Wavelet)\nRestbild\nSchwellenwert Schatten HISTORY_MSG_918;(sel. Editieren - Wavelet)\nRestbild Lichter -HISTORY_MSG_919;(sel. Editieren - Wavelet)\nRestbild\nSchwellenwert Lichter +HISTORY_MSG_919;(sel. Editieren - Wavelet)\nRestbild\nSchwellenwert Lichter HISTORY_MSG_920;(sel. Editieren - Wavelet)\nKontrast\nDämpfungsreaktion HISTORY_MSG_921;(sel. Editieren - Wavelet)\nVerlaufsfilter\nDämpfungsreaktion HISTORY_MSG_922;(sel. Editieren - Spot)\nSpeziell\nÄnderungen in Schwarz-Weiß erzwingen @@ -1267,14 +1268,14 @@ HISTORY_MSG_946;(sel. Editieren - Normale Farbmaske)\nSchatten HISTORY_MSG_947;(sel. Editieren - Normale Farbmaske)\nKontrastkurve HISTORY_MSG_948;(sel. Editieren - Normale Farbmaske)\nWavelet-Kurve HISTORY_MSG_949;(sel. Editieren - Normale Farbmaske)\nWavelet-Ebenen -HISTORY_MSG_950;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nIntensität +HISTORY_MSG_950;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nIntensität HISTORY_MSG_951;(sel. Editieren - Normale Farbmaske)\nVerlaufsfiltermaske\nRotationswinkel HISTORY_MSG_952;(sel. Editieren - Normale Farbmaske)\nRadius HISTORY_MSG_953;(sel. Editieren - Normale Farbmaske)\nÜberlagerung Chrominanzmaske HISTORY_MSG_954;(sel. Editieren)\nWerkzeuge einblenden/ausblenden HISTORY_MSG_955;(sel. Editieren) - Spot aktivieren HISTORY_MSG_956;(sel. Editieren - Farbe-Licht)\nCH-Kurve -HISTORY_MSG_957;(sel. Editieren - Rauschminderung)\nModus +HISTORY_MSG_957;(sel. Editieren - Rauschminderung)\nModus HISTORY_MSG_958;(sel. Editieren) - Zus. Einstellungen HISTORY_MSG_959;(sel. Editieren - Unschärfe)\nInvertieren HISTORY_MSG_960;(sel. Editieren - LOG-Kodierung)\nCAT16 @@ -1312,7 +1313,7 @@ HISTORY_MSG_992;(sel. Editieren - Rauschminderung)\nSchwellenwert Maske hell HISTORY_MSG_993;(sel. Editieren - Rauschminderung)\nInvertieren HISTORY_MSG_994;(sel. Editieren - Verlaufsfilter)\nInvertieren HISTORY_MSG_995;(sel. Editieren - Rauschminderung)\nZerfallrate -HISTORY_MSG_996;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwelle +HISTORY_MSG_996;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwelle HISTORY_MSG_997;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwellenwert dunkel HISTORY_MSG_998;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nSchwellenwert hell HISTORY_MSG_999;(sel. Editieren - Farbe-Licht)\nWiederherstellung\nZerfallrate @@ -1411,7 +1412,7 @@ HISTORY_MSG_1091;(sel. Editieren - CIECAM)\nSigmoid Jz\nÜberlagern HISTORY_MSG_1092;(sel. Editieren - CIECAM)\nJz Zuordnung\nAnpassung HISTORY_MSG_1093;(sel. Editieren - CIECAM)\nCAM Modell HISTORY_MSG_1094;(sel. Editieren - CIECAM)\nJz Lichter -HISTORY_MSG_1095;(sel. Editieren - CIECAM)\nTonwertbreite Jz Lichter +HISTORY_MSG_1095;(sel. Editieren - CIECAM)\nTonwertbreite Jz Lichter HISTORY_MSG_1096;(sel. Editieren - CIECAM)\nJz Schatten HISTORY_MSG_1097;(sel. Editieren - CIECAM)\nTonwertbreite Jz Schatten HISTORY_MSG_1098;(sel. Editieren - CIECAM)\nJz Radius @@ -1425,8 +1426,8 @@ HISTORY_MSG_1105;(sel. Editieren - CIECAM)\nTonmethode HISTORY_MSG_1106;(sel. Editieren - CIECAM)\nTonkurve HISTORY_MSG_1107;(sel. Editieren - CIECAM)\nFarbmethode HISTORY_MSG_1108;(sel. Editieren - CIECAM)\nFarbkurve -HISTORY_MSG_1109;(sel. Editieren - CIECAM)\nKurve Jz(Jz) -HISTORY_MSG_1110;(sel. Editieren - CIECAM)\nKurve Cz(Cz) +HISTORY_MSG_1109;(sel. Editieren - CIECAM)\nKurve Jz(Jz) +HISTORY_MSG_1110;(sel. Editieren - CIECAM)\nKurve Cz(Cz) HISTORY_MSG_1111;(sel. Editieren - CIECAM)\nKurve Cz(Jz) HISTORY_MSG_1112;(sel. Editieren - CIECAM)\nErzwinge Jz HISTORY_MSG_1113;(sel. Editieren - CIECAM)\nCAM16\nHDR PQ @@ -1455,19 +1456,19 @@ HISTORY_MSG_1135;(sel. Editieren - CIECAM)\nWavelet Jz\nLuma zusammenführen HISTORY_MSG_1136;(sel. Editieren - CIECAM)\nWavelet Jz\nChroma zusammenführen HISTORY_MSG_1137;(sel. Editieren - CIECAM)\nWavelet Jz\nGlättradius HISTORY_MSG_1138;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurve Hz(Hz) -HISTORY_MSG_1139;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurven H\nGlättradius +HISTORY_MSG_1139;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurven H\nGlättradius HISTORY_MSG_1140;(sel. Editieren - CIECAM)\nJz Cz Hz\nKurve Jz(Hz)\nSchwelle Chroma HISTORY_MSG_1141;(sel. Editieren - CIECAM)\nChroma-Kurve Jz(Hz) HISTORY_MSG_1142;(sel. Editieren) - Stärke Glätten HISTORY_MSG_1143;(sel. Editieren - CIECAM)\nSchwarz-Ev -HISTORY_MSG_1144;(sel. Editieren - CIECAM)\nWeiß-Ev +HISTORY_MSG_1144;(sel. Editieren - CIECAM)\nWeiß-Ev HISTORY_MSG_1145;(sel. Editieren - CIECAM)\nLOG-Kodierung Jz HISTORY_MSG_1146;(sel. Editieren - CIECAM)\nLOG-Kodierung Jz\nMittlere Helligkeit HISTORY_MSG_1147;(sel. Editieren - CIECAM)\nSigmoid Jz\nVerwendet Schwarz-Ev Weiß-Ev HISTORY_MSG_1148;(sel. Editieren - CIECAM)\nSigmoid Jz HISTORY_MSG_1149;(sel. Editieren - CIECAM)\nSigmoid Q HISTORY_MSG_1150;(sel. Editieren - CIECAM)\nSigmoid\nQuellen-Daten\nLOG-Kodierung -HISTORY_MSG_BLSHAPE;(Erweitert - Wavelet)\nUnschärfeebenen\nUnschärfe nach Ebenena +HISTORY_MSG_BLSHAPE;(Erweitert - Wavelet)\nUnschärfeebenen\nUnschärfe nach Ebenen HISTORY_MSG_BLURCWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Buntheit HISTORY_MSG_BLURWAV;(Erweitert - Wavelet)\nRestbild - Unschärfe\nUnschärfe Helligkeit HISTORY_MSG_BLUWAV;(Erweitert - Wavelet)\nUnschärfeebenen\nDämpfungsreaktion @@ -1595,7 +1596,7 @@ HISTORY_MSG_LOCAL_CIE_STRGRAD;(sel. Editieren - CIECAM)\nVerlaufsfilter\nVerlauf HISTORY_MSG_LOCAL_CIE_STRLOG;(sel. Editieren - CIECAM)\nQuellen-Daten\nLOG-Kodierung Stärke HISTORY_MSG_LOCAL_CIE_TRC;(sel. Editieren - CIECAM)\Farbtonkennlinie HISTORY_MSG_LOCAL_CIE_WHITES;(sel. Editieren - CIECAM)\nWeiß-Verteilung -HISTORY_MSG_LOCAL_DEHAZE_BLACK;(sel. Editieren - Dunst entfernen\nSchwarzpunkt +HISTORY_MSG_LOCAL_DEHAZE_BLACK;(sel. Editieren - Dunst entfernen)\nSchwarzpunkt HISTORY_MSG_LOCAL_FEATHERCIE;(sel. Editieren - CIECAM)\nVerlaufsfilter\nVerlaufsbreite HISTORY_MSG_LOCAL_FEATHERCOL;(sel. Editieren - Farbe-Licht)\nVerlaufsfilter\nVerlaufsbreite HISTORY_MSG_LOCAL_FEATHEREXE;(sel. Editieren - Dynamik u. Belichtung)\nVerlaufsfilter\nVerlaufsbreite @@ -1664,7 +1665,7 @@ HISTORY_MSG_TRANS_METHOD;(Transformieren - Objektivkorrektur)\nMethode HISTORY_MSG_WAVBALCHROM;(Erweitert - Wavelet)\nRauschreduzierung\nFarb-Equalizer HISTORY_MSG_WAVBALLUM;(Erweitert - Wavelet)\nRauschreduzierung\nEqualizer Luminanz HISTORY_MSG_WAVBL;(Erweitert - Wavelet)\nUnschärfeebenen -HISTORY_MSG_WAVCHR;(Erweitert - Wavelet)\nUnschärfeebenen\nChroma-Unschärfe +HISTORY_MSG_WAVCHR;(Erweitert - Wavelet)\nUnschärfeebenen\nChroma-Unschärfe HISTORY_MSG_WAVCHROMCO;(Erweitert - Wavelet)\nRauschreduzierung\nChrominanz grob HISTORY_MSG_WAVCHROMFI;(Erweitert - Wavelet)\nRauschreduzierung\nChrominanz fein HISTORY_MSG_WAVCLARI;(Erweitert - Wavelet)\nSchärfemaske und Klarheit @@ -1689,7 +1690,7 @@ HISTORY_MSG_WAVOLDSH;(Erweitert - Wavelet)\nAlter Algorithmus HISTORY_MSG_WAVQUAMET;(Erweitert - Wavelet)\nRauschreduzierung\nModus HISTORY_MSG_WAVRADIUS;(Erweitert - Wavelet)\nRestbild - Schatten/Lichter\nRadius HISTORY_MSG_WAVSCALE;(Erweitert - Wavelet)\nRestbild - Kompression\nSkalieren -HISTORY_MSG_WAVSHOWMASK;(Erweitert - Wavelet)\nSchärfemaske und Klarheit\nWaveletmaske anzeigen +HISTORY_MSG_WAVSHOWMASK;(Erweitert - Wavelet)\nSchärfemaske und Klarheit\nWaveletmaske anzeigen HISTORY_MSG_WAVSIGM;(Erweitert - Wavelet)\nKontrast\nSigma HISTORY_MSG_WAVSIGMA;(Erweitert - Wavelet)\nKontrast\nDämpfungsreaktion HISTORY_MSG_WAVSLIMET;(Erweitert - Wavelet)\nRauschreduzierung\nMethode @@ -1712,7 +1713,6 @@ HISTORY_MSG_WBITC_PONDER;(Farbe - Weißabgleich)\ngemäßigt HISTORY_MSG_WBITC_PRECIS;(Farbe - Weißabgleich)\nPräzision HISTORY_MSG_WBITC_PRIM;(Farbe - Weißabgleich)\nWahl der Abtastung HISTORY_MSG_WBITC_RGREEN;(Farbe - Weißabgleich)\nGrünbereich -!HISTORY_MSG_WBITC_SAMPLING;Low sampling HISTORY_MSG_WBITC_SIZE;(Farbe - Weißabgleich)\nGröße HISTORY_MSG_WBITC_SORTED;(Farbe - Weißabgleich)\ngemäßigt HISTORY_MSG_WBITC_THRES;(Farbe - Weißabgleich)\nSchwellenwert @@ -1733,7 +1733,7 @@ ICCPROFCREATOR_ILL_41;D41 ICCPROFCREATOR_ILL_50;D50 ICCPROFCREATOR_ILL_55;D55 ICCPROFCREATOR_ILL_60;D60 -ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater +ICCPROFCREATOR_ILL_63;D63 : DCI-P3 Theater ICCPROFCREATOR_ILL_65;D65 ICCPROFCREATOR_ILL_80;D80 ICCPROFCREATOR_ILL_DEF;Vorgabe @@ -1848,14 +1848,14 @@ MAIN_TAB_COLOR;Farbe MAIN_TAB_COLOR_TOOLTIP;Taste: Alt + c MAIN_TAB_DETAIL;Details MAIN_TAB_DETAIL_TOOLTIP;Taste: Alt + d -MAIN_TAB_DEVELOP;Batchbearbeitung +MAIN_TAB_DEVELOP;Batchbearbeitung MAIN_TAB_EXIF;Exif -MAIN_TAB_EXPORT;Schnell-Export +MAIN_TAB_EXPORT;Schnell-Export MAIN_TAB_EXPOSURE;Belichtung MAIN_TAB_EXPOSURE_TOOLTIP;Taste: Alt + e MAIN_TAB_FAVORITES;Favoriten MAIN_TAB_FAVORITES_TOOLTIP;Taste: Alt + u -MAIN_TAB_FILTER;Filter +MAIN_TAB_FILTER;Filter MAIN_TAB_INSPECT;Inspektor MAIN_TAB_IPTC;IPTC MAIN_TAB_LOCALLAB;Selektives Editieren @@ -2192,7 +2192,7 @@ PREFERENCES_TAB_PERFORMANCE;Performance PREFERENCES_TAB_SOUND;Klänge PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Eingebundenes JPEG PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Bildanzeige -PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrales RAW-Bild +PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutrales RAW-Bild PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Eingebundenes JPEG wenn in Originalgröße, sonst neutrales RAW-Bild PREFERENCES_THUMBNAIL_RANK_COLOR_MODE;Laden/Speichern Miniaturbilder Bewertung und Farbe von/nach XMP Bearbeitungsprofil (sidecar) PREFERENCES_TOOLPANEL_AVAILABLETOOLS;Verfügbare Werkzeuge @@ -2207,14 +2207,11 @@ PREFERENCES_USEBUNDLEDPROFILES;Standardprofile verwenden PREFERENCES_WBA;Weißabgleich PREFERENCES_WBACORR;Weißabgleich - automatische Temperaturkorrelation PREFERENCES_WBACORR_TOOLTIP;Diese Einstellungen ermöglichen, abhängig von den Bildern (Art der Rohdatei, Farbmetrik usw.), eine Anpassung des Algorithmus 'Temperaturkorrelation', um die besten Gesamtergebnisse zu erzielen. Es gibt keine absolute Regel, diese Parameter mit den erhaltenen Ergebnissen zu verknüpfen.\n\nEs gibt drei Arten von Einstellungen: \n* solche, die für den Benutzer über die GUI zugänglich sind.\n* solche, die nur beim Lesen aus jeder pp3-Datei zugänglich sind\n* diejenigen, auf die der Benutzer in 'Optionen' zugreifen kann (siehe Rawpedia)\n Sie können 'AWB-Temperatur-Bias' und 'Grün-Verfeinerung' verwenden, um die Ergebnisse anzupassen. Jede Veränderung führt zu einer Neuberechnung von Temperatur, Farbton und Bezug.\n\nBitte beachten Sie, dass die drei Indikatoren 'Bezugsfaktor', 'Patch-Chroma' und ΔE nur zur Information dienen. Nur weil einer dieser Indikatoren besser ist, ist das Ergebnis nicht zwangsläufig besser. -PREFERENCES_WBAENA;Zeige Einstellungen der Temperaturkorrelation bei automatischem Weißabgleich +PREFERENCES_WBAENA;Zeige Einstellungen der Temperaturkorrelation bei automatischem Weißabgleich PREFERENCES_WBAENACUSTOM;Benutzerdefinierte Temperatur und Tönung PREFERENCES_WBAFORC;Erzwingt extra Algorithmus -!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) -PREFERENCES_WBANOPURP;Keine lila Farben verwendet -!PREFERENCES_WBAPATCH;Number maximum of colors used in picture +PREFERENCES_WBANOPURP;Keine lila Farben verwendet PREFERENCES_WBAPRECIS;Präzision Algorithmus - skaliert -!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color PREFERENCES_WBASORT;Chromatische Sortierung anstatt nach Histogramm PREFERENCES_WORKFLOW;Layout PREFERENCES_XMP_SIDECAR_MODE;Datei-Endung für XMP (Sidecar) @@ -2817,8 +2814,8 @@ TP_ICM_NEUTRAL;Zurücksetzen TP_ICM_NOICM;Kein ICM: sRGB-Ausgabe TP_ICM_OUTPUTPROFILE;Ausgabeprofil TP_ICM_OUTPUTPROFILE_TOOLTIP;Standardmäßig sind alle RTv4- oder RTv2-Profile mit TRC - sRGB: g=2.4 s=12.92 voreingestellt.\n\nMit 'ICC Profile Creator' können Sie v4- oder v2-Profile mit den folgenden Auswahlmöglichkeiten erstellen:\n- Primär: Aces AP0, Aces AP1 , AdobeRGB, Prophoto, Rec2020, sRGB, Widegamut, BestRGB, BetaRGB, BruceRGB, Benutzerdefiniert\n- TRC: BT709, sRGB, linear, Standard g=2,2, Standard g=1,8, Benutzerdefiniert\n- Lichtart: D41, D50, D55 , D60, D65, D80, stdA 2856K -TP_ICM_PRIMBLU_TOOLTIP;Primäreinstellungen Blau:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 -TP_ICM_PRIMGRE_TOOLTIP;Primäreinstellungen Grün:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 +TP_ICM_PRIMBLU_TOOLTIP;Primäreinstellungen Blau:\nsRGB x=0.15 y=0.06\nAdobe x=0.15 y=0.06\nWidegamut x=0.157 y=0.018\nRec2020 x=0.131 y=0.046\nACES P1 x=0.128 y= 0.044\nACES P0 x=0.0001 y=-0.077\nProphoto x=0.0366 y=0.0001\nBruceRGB x=0.15 y=0.06\nBeta RGB x=0.1265 y=0.0352\nBestRGB x=0.131 y=0.046 +TP_ICM_PRIMGRE_TOOLTIP;Primäreinstellungen Grün:\nsRGB x=0.3 y=0.6\nAdobe x=0.21 y=0.71\nWidegamut x=0.115 y=0.826\nRec2020 x=0.17 y=0.797\nACES P1 x=0.165 y= 0.83\nACES P0 x=0.0 y=1.0\nProphoto x=0.1596 y=0.8404\nBruceRGB x=0.28 y=0.65\nBeta RGB x=0.1986 y=0.7551\nBest RGB x=0.2150 0.7750 TP_ICM_PRIMILLUM_TOOLTIP;Sie können ein Bild von seinem ursprünglichen Modus 'Arbeitsprofil' in einen anderen Modus 'Ziel-Primärdateien' ändern. Wenn Sie für ein Bild einen anderen Farbmodus auswählen, ändern Sie dauerhaft die Farbwerte im Bild.\n\nDas Ändern der 'Primärfarben' ist ziemlich komplex und schwierig zu verwenden. Es erfordert viel Experimentieren.\nEs ist in der Lage, exotische Farbanpassungen als Kanalmixer-Primärfarben vorzunehmen.\nErmöglicht Ihnen, die Kamerakalibrierung mit Benutzerdefiniert (Schieberegler) zu ändern. TP_ICM_PRIMRED_TOOLTIP;Primäreinstellungen Rot:\nsRGB x=0.64 y=0.33\nAdobe x=0.64 y=0.33\nWidegamut x=0.735 y=0.265\nRec2020 x=0.708 y=0.292\nACES P1 x=0.713 y= 0.293\nACES P0 x=0.7347 y=0.2653\nProphoto x=0.7347 y=0.2653\nBruceRGB x=0.64 y=0.33\nBeta RGB x=0.688 y=0.3112\nBestRGB x=0.7347 y=0.2653 TP_ICM_PROFILEINTENT;Wiedergabe @@ -2990,7 +2987,7 @@ TP_LOCALLAB_BLURMASK_TOOLTIP;Verwendet eine große Radius-Unschärfe für eine M TP_LOCALLAB_BLURRMASK_TOOLTIP;Verändert den Radius der Gauß'schen Unschärfe (0 bis 1000). TP_LOCALLAB_BLUR_TOOLNAME;Unschärfe und Rauschreduzierung TP_LOCALLAB_BLWH;Alle Änderungen in Schwarz-Weiß erzwingen -TP_LOCALLAB_BLWH_TOOLTIP;Setzt Farbkomponenten 'a' und 'b' auf Null.\nHilfreich für Schwarz/Weiß-Entwicklung oder Filmsimulation. +TP_LOCALLAB_BLWH_TOOLTIP;Setzt Farbkomponenten 'a' und 'b' auf Null.\nHilfreich für Schwarz/Weiß-Entwicklung oder Filmsimulation. TP_LOCALLAB_BUTTON_ADD;Hinzufügen TP_LOCALLAB_BUTTON_DEL;Löschen TP_LOCALLAB_BUTTON_DUPL;Duplizieren @@ -3029,7 +3026,7 @@ TP_LOCALLAB_CHROML;Chroma (C) TP_LOCALLAB_CHRRT;Chrominanz TP_LOCALLAB_CIE;CIECAM (CAM16 & JzCzHz) TP_LOCALLAB_CIEC;Ciecam Umgebungs Parameter verwenden -TP_LOCALLAB_CIECAMLOG_TOOLTIP;Dieses Modul basiert auf dem CIECAM-Farberscheinungsmodell, das entwickelt wurde, um das Sehen der menschlichen Farbwahrnehmung unter verschiedenen Lichtbedingungen zu simulieren.\nDer erste CIECAM-Prozess 'Szenebasierte Bedingungen' wird per LOG-Kodierung durchgeführt und verwendet 'Absolute Luminanz' zum Zeitpunkt der Aufnahme.\nDer zweite CIECAM-Prozess 'Bildkorrektur' wurde vereinfacht und nutzt nur 3 Variablen ('Lokaler Kontrast', 'Kontrast J', 'Sättigung s').\nDer dritte CIECAM-Prozess 'Anzeigebedingungen' passt die Ausgabe an das beabsichtigte Anzeigegerät (Monitor, TV, Projektor, Drucker, etc.) an, damit das chromatische und kontrastreiche Erscheinungsbild in der gesamten Anzeigeumgebung erhalten bleibt. +TP_LOCALLAB_CIECAMLOG_TOOLTIP;Dieses Modul basiert auf dem CIECAM-Farberscheinungsmodell, das entwickelt wurde, um das Sehen der menschlichen Farbwahrnehmung unter verschiedenen Lichtbedingungen zu simulieren.\nDer erste CIECAM-Prozess 'Szenebasierte Bedingungen' wird per LOG-Kodierung durchgeführt und verwendet 'Absolute Luminanz' zum Zeitpunkt der Aufnahme.\nDer zweite CIECAM-Prozess 'Bildkorrektur' wurde vereinfacht und nutzt nur 3 Variablen ('Lokaler Kontrast', 'Kontrast J', 'Sättigung s').\nDer dritte CIECAM-Prozess 'Anzeigebedingungen' passt die Ausgabe an das beabsichtigte Anzeigegerät (Monitor, TV, Projektor, Drucker, etc.) an, damit das chromatische und kontrastreiche Erscheinungsbild in der gesamten Anzeigeumgebung erhalten bleibt. TP_LOCALLAB_CIECOLORFRA;Farbe TP_LOCALLAB_CIECONTFRA;Kontrast TP_LOCALLAB_CIELIGHTCONTFRA;Beleuchtung & Kontrast @@ -3076,7 +3073,7 @@ TP_LOCALLAB_COMPRCIE;Helligkeits-Kompression TP_LOCALLAB_COMPRCIETH;Kompression Schwellenwert TP_LOCALLAB_COMPREFRA;Tonwertkorrektur TP_LOCALLAB_COMPRLOG_TOOLTIP;Dieser Algorithmus komprimiert die Daten vor der Log-Konvertierung über den Schwellenwert des Schiebereglers. Zu verwenden in Verbindung mit der Weiß-Verteilung. -TP_LOCALLAB_CONTCOL;Schwellenwert Kontrast +TP_LOCALLAB_CONTCOL;Schwellenwert Kontrast TP_LOCALLAB_CONTFRA;Ebenenkontrast TP_LOCALLAB_CONTRAST;Kontrast TP_LOCALLAB_CONTRASTCURVMASK_TOOLTIP;Ermöglicht das freie Ändern des Kontrasts der Maske.\nHat eine ähnliche Funktion wie die Regler 'Gamma' und 'Neigung'.\nMit dieser Funktion können Sie bestimmte Bereiche des Bildes (normalerweise die hellsten Bereiche der Maske) anvisieren, indem mit Hilfe der Kurve dunklere Bereiche ausgeschlossen werden). Kann Artefakte erzeugen. @@ -3157,7 +3154,7 @@ TP_LOCALLAB_EXFULL;Gesamtes Bild TP_LOCALLAB_EXMAIN;Global TP_LOCALLAB_EXNORM;Normaler Spot TP_LOCALLAB_EXPCBDL_TOOLTIP;Kann zur Entfernung von Sensorflecken oder Objektivfehlern verwendet werden, indem Kontrast auf der entsprechenden Detailebene verringert wird. -TP_LOCALLAB_EXPCHROMA;Kompensation Farbsättigung +TP_LOCALLAB_EXPCHROMA;Kompensation Farbsättigung TP_LOCALLAB_EXPCHROMA_TOOLTIP;In Verbindung mit 'Belichtungskorrektur' und 'Kontrastdämpfung' kann eine Entsättigung der Farben vermieden werden. TP_LOCALLAB_EXPCOLOR_TOOLTIP;Passt Farbe, Luminanz, Kontrast an und korrigiert kleinere Defekte, wie rote Augen, Sensorstaub etc. TP_LOCALLAB_EXPCOMP;Belichtungsausgleich ƒ @@ -3167,12 +3164,12 @@ TP_LOCALLAB_EXPCONTRASTPYR_TOOLTIP;Siehe Dokumentation für Wavelet-Ebenen.\nEs TP_LOCALLAB_EXPCONTRAST_TOOLTIP;Vermeiden Sie zu kleine Spots (<32 x 32 Pixel).\nVerwenden Sie niedrige 'Übergangswerte' und hohe Werte für 'Übergangszerfallrate' und 'Bereich,' um kleine Spots zu simulieren und Fehler zu beheben.\nVerwenden Sie 'Klarheit & Schärfemaske und Überlagern & Abschwächen' wenn nötig, indem Sie den 'Radius' anpassen, um Artefakte zu reduzieren. TP_LOCALLAB_EXPCURV;Kurven TP_LOCALLAB_EXPGRAD;Verlaufsfilter -TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Verlaufsfilter stehen in den folgenden Werkzeugen zur Verfügung: 'Farbe und Licht (Luminanz, Chrominanz, Farbtonverlauf, und Zusammenführen)', 'Belichtung (Luminanz grad.)', 'Belichtungsmaske (Luminanz grad.)', 'Schatten/Lichter (Luminanz grad.)', 'Dynamik (Luminanz, Chrominanz & Farbton)', 'Lokaler Kontrast & Wavelet Pyramide (lokaler Kontrast grad.)'.\nDer Zerfall wird in den Einstellungen definiert. +TP_LOCALLAB_EXPGRADCOL_TOOLTIP;Verlaufsfilter stehen in den folgenden Werkzeugen zur Verfügung: 'Farbe und Licht (Luminanz, Chrominanz, Farbtonverlauf, und Zusammenführen)', 'Belichtung (Luminanz grad.)', 'Belichtungsmaske (Luminanz grad.)', 'Schatten/Lichter (Luminanz grad.)', 'Dynamik (Luminanz, Chrominanz & Farbton)', 'Lokaler Kontrast & Wavelet Pyramide (lokaler Kontrast grad.)'.\nDer Zerfall wird in den Einstellungen definiert. TP_LOCALLAB_EXPLAPBAL_TOOLTIP;Ändert die Mischung von geändertem/ursprünglichem Bild. TP_LOCALLAB_EXPLAPGAMM_TOOLTIP;Verändert das Verhalten des Bildes mit wenig oder zu wenig Kontrast, indem vorher eine Gammakurve und nachher eine Laplace-Transformation hinzugefügt werden. TP_LOCALLAB_EXPLAPLIN_TOOLTIP;Verändert das Verhalten unterbelichteter Bilder indem eine lineare Komponente vor Anwendung der Laplace-Transformation hinzugefügt wird. TP_LOCALLAB_EXPLAP_TOOLTIP;Regler nach rechts reduziert schrittweise den Kontrast. -TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Ermöglicht die Verwendung von GIMP oder Photoshop-Ebenen-Mischmodi wie Differenz, Multiplikation, Weiches Licht, Überlagerung etc., mit Transparenzkontrolle.\nOriginalbild: Führe aktuellen RT-Spot mit Original zusammen.\nVorheriger Spot: Führe aktuellen RT-Spot mit vorherigem zusammen - bei nur einem vorherigen = Original.\nHintergrund: Führe aktuellen RT-Spot mit einem Farb- oder Luminanzhintergrund zusammen (weniger Möglichkeiten). +TP_LOCALLAB_EXPMERGEFILE_TOOLTIP;Ermöglicht die Verwendung von GIMP oder Photoshop-Ebenen-Mischmodi wie Differenz, Multiplikation, Weiches Licht, Überlagerung etc., mit Transparenzkontrolle.\nOriginalbild: Führe aktuellen RT-Spot mit Original zusammen.\nVorheriger Spot: Führe aktuellen RT-Spot mit vorherigem zusammen - bei nur einem vorherigen = Original.\nHintergrund: Führe aktuellen RT-Spot mit einem Farb- oder Luminanzhintergrund zusammen (weniger Möglichkeiten). TP_LOCALLAB_EXPNOISEMETHOD_TOOLTIP;Wendet einen Median-Filter vor der Laplace-Transformation an, um (Rausch-)Artefakte zu vermeiden.\nAlternativ kann das Werkzeug zur Rauschreduzierung angewendet werden. TP_LOCALLAB_EXPOSE;Dynamik und Belichtung TP_LOCALLAB_EXPOSURE_TOOLTIP;Anpassung der Belichtung im L*a*b-Raum mittels Laplace PDE-Algorithmus um ΔE zu berücksichtigen und Artefakte zu minimieren. @@ -3257,8 +3254,8 @@ TP_LOCALLAB_JZ100_TOOLTIP;Passt automatisch den Referenz-Jz-Pegel von 100 cd/m2 TP_LOCALLAB_JZADAP;PU Anpassung TP_LOCALLAB_JZCH;Chroma TP_LOCALLAB_JZCHROM;Chroma -TP_LOCALLAB_JZCLARICRES;Chroma zusammenführen Cz -TP_LOCALLAB_JZCLARILRES;Luma zusammenführen Jz +TP_LOCALLAB_JZCLARICRES;Chroma zusammenführen Cz +TP_LOCALLAB_JZCLARILRES;Luma zusammenführen Jz TP_LOCALLAB_JZCONT;Kontrast TP_LOCALLAB_JZFORCE;Erzwinge max. Jz auf 1 TP_LOCALLAB_JZFORCE_TOOLTIP;Ermöglicht, den Jz-Wert für eine bessere Regler- und Kurvenreaktion auf 1 anzuheben. @@ -3350,7 +3347,7 @@ TP_LOCALLAB_LOGFRA;Szenebasierte Bedingungen TP_LOCALLAB_LOGFRAME_TOOLTIP;Ermöglicht die Berechnung und Anpassung der Ev-Pegel und der 'Mittleren Luminanz Yb%' (Quellgraupunkt) für den Spot-Bereich. Die resultierenden Werte werden von allen Lab-Vorgängen und den meisten RGB-Vorgängen in der Pipeline verwendet.\nBerechnet auch die absolute Luminanz zum Zeitpunkt der Aufnahme. TP_LOCALLAB_LOGIMAGE_TOOLTIP;Berücksichtigt entsprechende CIECAM-Variablen wie Kontrast (J) und Sättigung (s) aber auch Kontrast (Q) , Helligkeit (Q), Helligkeit (J), Farbigkeit (M) im Modus 'Erweitert'. TP_LOCALLAB_LOGLIGHTL;Helligkeit (J) -TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Ähnlich Helligkeit (L*a*b*), berücksichtigt die Zunahme der wahrgenommenen Färbung. +TP_LOCALLAB_LOGLIGHTL_TOOLTIP;Ähnlich Helligkeit (L*a*b*), berücksichtigt die Zunahme der wahrgenommenen Färbung. TP_LOCALLAB_LOGLIGHTQ;Helligkeit (Q) TP_LOCALLAB_LOGLIGHTQ_TOOLTIP;Wahrgenommene Lichtmenge, die von einer Quelle ausgeht.\nIndikator dafür, dass eine Quelle mehr oder weniger hell und klar zu sein scheint. TP_LOCALLAB_LOGLIN;Logarithmischer Modus @@ -3370,13 +3367,13 @@ TP_LOCALLAB_LUMASK;Hintergrundfarbe für Luminanzmaske TP_LOCALLAB_LUMASK_TOOLTIP;Passt den Grauton oder die Farbe des Maskenhintergrundes an (Maske und Anpassungen - Maske anzeigen). TP_LOCALLAB_LUMAWHITESEST;Hellste TP_LOCALLAB_LUMFRA;L*a*b* Standard -TP_LOCALLAB_LUMLABEL;Luminanz Ebenen 0123: Mittel=%1 Hoch=%2 +TP_LOCALLAB_LUMLABEL;Luminanz Ebenen 0123: Mittel=%1 Hoch=%2 TP_LOCALLAB_MASFRAME;Maskieren und Zusammenführen TP_LOCALLAB_MASFRAME_TOOLTIP;Für alle Masken.\nBerücksichtigt das ΔE-Bild, um zu vermeiden, dass der Auswahlbereich geändert wird, wenn die folgenden Maskenwerkzeuge verwendet werden: 'Gamma', 'Steigung', 'Chroma', 'Kontrastkurve', 'Lokaler Kontrast' (nach Wavelet-Ebene), 'Unschärfemaske' und 'Strukturmaske' (falls aktiviert).\nDeaktiviert, wenn der Inverse-Modus verwendet wird. TP_LOCALLAB_MASK;Kontrast TP_LOCALLAB_MASK2;Kontrastkurve TP_LOCALLAB_MASKCOM;Normale Farbmaske -TP_LOCALLAB_MASKCOM_TOOLNAME;Normale Farbmaske +TP_LOCALLAB_MASKCOM_TOOLNAME;Normale Farbmaske TP_LOCALLAB_MASKCOM_TOOLTIP;Ein eigenständiges Werkzeug.\nKann verwendet werden, um das Erscheinungsbild (Chrominanz, Luminanz, Kontrast) und die Textur in Abhängigkeit des Bereiches anzupassen. TP_LOCALLAB_MASKCURVE_TOOLTIP;Die 3 Kurven sind standardmäßig auf 1 (maximal) eingestellt:\nC=f(C) Die Farbintensität variiert je nach Chrominanz. Sie können die Chrominanz verringern, um die Auswahl zu verbessern. Wenn Sie diese Kurve nahe Null setzen (mit einem niedrigen Wert von C, um die Kurve zu aktivieren), können Sie den Hintergrund im inversen Modus entsättigen.\nL= f(L) Die Luminanz variiert je nach Luminanz, so dass Sie die Helligkeit verringern können um die Auswahl zu verbessern.\nL und C = f(H) Luminanz und Chrominanz variieren mit dem Farbton, sodass Sie Luminanz und Chrominanz verringern können, um die Auswahl zu verbessern. TP_LOCALLAB_MASKDDECAY;Zerfallrate @@ -3400,7 +3397,7 @@ TP_LOCALLAB_MASKLCTHR;Schwellenwert helle Bereiche TP_LOCALLAB_MASKLCTHR2;Schwelle helle Bereiche TP_LOCALLAB_MASKLCTHRLOW;Schwellenwert dunkle Bereiche TP_LOCALLAB_MASKLCTHRLOW2;Schwelle dunkle Bereiche -TP_LOCALLAB_MASKLCTHRMID;Luminanz Graubereiche +TP_LOCALLAB_MASKLCTHRMID;Luminanz Graubereiche TP_LOCALLAB_MASKLCTHRMIDCH;Chrominanz Graubereiche TP_LOCALLAB_MASKLC_TOOLTIP;Wird von der Wavelet-Luminanz verwendet.\nDamit können Sie die Rauschunterdrückung basierend auf den Bildluminanzinformationen festlegen, die in der L(L)- oder LC(H)-Maske (Maske und Modifikationen) enthalten sind.\nDie L(L)-Maske oder die LC(H)-Maske muss aktiviert sein, m diese Funktion nutzen zu können.\n'Schwellenwert für die Luminanz dunkler Bereiche'. Ist 'Rauschunterdrückung in dunklen und hellen Bereichen verstärken' > 1, wird die Rauschunterdrückung schrittweise von 0 % auf 100 % beim maximalen Schwarzwert (bestimmt durch die Maske) erhöht.\n'Schwellenwert für die Luminanz für helle Bereiche'. Die Rauschunterdrückung wird schrittweise von 100 % auf 0 % beim maximalen Weißwert (bestimmt durch die Maske) verringert.\n Im Bereich zwischen den beiden Schwellenwerten werden die Rauschunterdrückungseinstellungen von der Maske nicht beeinflusst. TP_LOCALLAB_MASKLNOISELOW;In dunklen und hellen Bereichen verstärken @@ -3548,7 +3545,7 @@ TP_LOCALLAB_RESIDCONT;Kontrast Restbild TP_LOCALLAB_RESIDHI;Lichter TP_LOCALLAB_RESIDHITHR;Schwellenwert Lichter TP_LOCALLAB_RESIDSHA;Schatten -TP_LOCALLAB_RESIDSHATHR;Schwellenwert Schatten +TP_LOCALLAB_RESIDSHATHR;Schwellenwert Schatten TP_LOCALLAB_RETI;Dunst entfernen u. Retinex TP_LOCALLAB_RETIFRA;Retinex TP_LOCALLAB_RETIFRAME_TOOLTIP;Retinex kann für die Verarbeitung von Bildern folgender Art nützlich sein:\nDie unscharf, neblig oder trüb sind (zusätzlich zu 'Dunst entfernen').\nDie große Unterschiede in der Luminanz enthalten.\nEs kann auch für Spezialeffekte (Tonzuordnung) verwendet werden. @@ -3592,7 +3589,7 @@ TP_LOCALLAB_SHAMASKCOL;Schatten TP_LOCALLAB_SHAPETYPE;Spot Form TP_LOCALLAB_SHAPE_TOOLTIP;'Ellipse' ist der normale Modus.\n'Rechteck' kann in einigen Fällen hilfreich sein, z.B. um die Trennzeichen im Vollbild-Modus außerhalb des Voransichtsbereiches zu setzen. In diesem Falle ist Transition = 100 zu setzen.\n\nZukünftige Versionen werden auch Polygone und Bezierkurven unterstützen. TP_LOCALLAB_SHARAMOUNT;Intensität -TP_LOCALLAB_SHARBLUR;Unschärferadius +TP_LOCALLAB_SHARBLUR;Unschärferadius TP_LOCALLAB_SHARDAMPING;Dämpfung TP_LOCALLAB_SHARFRAME;Veränderungen TP_LOCALLAB_SHARITER;Iterationen @@ -4220,7 +4217,7 @@ TP_WAVELET_DAUBLOCAL;Wavelet Kantenperformance TP_WAVELET_DAUB_TOOLTIP;Ändert den Daubechies-Koeffizienten:\nD4 = Standard\nD14 = Häufig bestes Ergebnis auf Kosten von ca. 10% längerer Verarbeitungszeit.\n\nVerbessert die Kantenerkennung sowie die Qualität der ersten Waveletebene. Jedoch hängt die Qualität nicht ausschließlich mit diesem Koeffizienten zusammen und kann je nach Bild und Einsatz variieren. TP_WAVELET_DEN5THR;Schwellenwert TP_WAVELET_DENCURV;Kurve -TP_WAVELET_DENL;Korrektur Struktur +TP_WAVELET_DENL;Korrektur Struktur TP_WAVELET_DENLH;Schwellenwert Ebenen 1-4 TP_WAVELET_DENLOCAL_TOOLTIP;Verwenden Sie eine Kurve, um die Rauschreduzierung entsprechend dem lokalen Kontrast anzupassen.\nFlächen werden entrauscht, die Strukturen bleiben erhalten. TP_WAVELET_DENMIX_TOOLTIP;Der vom anpassbaren Filter genutzte Referenzwert für den lokalen Kontrast.\nJe nach Bild können die Ergebnisse variieren, je nachdem, ob das Rauschen vor oder nach der Rauschunterdrückung gemessen wird. Mit diesen vier Auswahlmöglichkeiten können verschiedene Kombinationen von Original- und modifizierten (entrauschten) Bildern berücksichtigt werden, um den besten Kompromiss zu finden. @@ -4278,7 +4275,7 @@ TP_WAVELET_LABEL;Wavelet TP_WAVELET_LABGRID_VALUES;oben(a)=%1\noben(b)=%2\nunten(a)=%3\nunten(b)=%4 TP_WAVELET_LARGEST;Grob TP_WAVELET_LEVCH;Farbe -TP_WAVELET_LEVDEN;Rauschreduzierung Ebenen 5-6 +TP_WAVELET_LEVDEN;Rauschreduzierung Ebenen 5-6 TP_WAVELET_LEVDIR_ALL;Alle Ebenen und Richtungen TP_WAVELET_LEVDIR_INF;Kleiner oder gleich der Ebene TP_WAVELET_LEVDIR_ONE;Diese Ebene @@ -4346,7 +4343,7 @@ TP_WAVELET_SAT;Gesättigte Farben TP_WAVELET_SETTINGS;Einstellungen TP_WAVELET_SHA;Schärfemaske TP_WAVELET_SHFRAME;Schatten/Lichter -TP_WAVELET_SHOWMASK;Wavelet 'Maske' anzeigen +TP_WAVELET_SHOWMASK;Wavelet 'Maske' anzeigen TP_WAVELET_SIGM;Radius TP_WAVELET_SIGMA;Dämpfungsreaktion TP_WAVELET_SIGMAFIN;Dämpfungsreaktion @@ -4360,7 +4357,7 @@ TP_WAVELET_STREN;Intensität TP_WAVELET_STREND;Intensität TP_WAVELET_STRENGTH;Intensität TP_WAVELET_SUPE;Extra -TP_WAVELET_THR;Schwelle Schatten +TP_WAVELET_THR;Schwelle Schatten TP_WAVELET_THRDEN_TOOLTIP;Erzeugt eine abgestufte Kurve, die verwendet wird, um die Rauschreduzierung als Funktion des lokalen Kontrasts zu führen. Die Rauschreduzierung wird gleichmäßig auf Bereiche mit geringem lokalem Kontrast angewendet. Bereiche mit Details (höherer lokaler Kontrast) bleiben erhalten. TP_WAVELET_THREND;Schwellenwert Lokaler Kontrast TP_WAVELET_THRESHOLD;Lichterebenen @@ -4418,7 +4415,7 @@ TP_WBALANCE_ITCWALG_TOOLTIP;Ermöglicht Ihnen, wenn möglich, zur anderen altern TP_WBALANCE_ITCWBDELTA_TOOLTIP;Für jede versuchte "grüne" Iteration wurde der zu berücksichtigende Temperaturunterschied festgelegt. TP_WBALANCE_ITCWBFGREEN_TOOLTIP;Finden Sie den besten Kompromiss zwischen Kandidat und Grün. TP_WBALANCE_ITCWBMINSIZEPATCH_TOOLTIP;Ermöglicht Ihnen, den minimalen Patch-Wert festzulegen. Zu niedrige Werte können zu einer fehlenden Korrelation führen. -!TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Ermöglicht das Filtern von Magenta-/Lila-Daten aus dem Bild. Wenn das Kontrollkästchen aktiviert ist, wird ein Filter angewandt, der den Wert von Y begrenzt. Standardmäßig beträgt dieser Wert 0,4. Sie können es in 'Optionen' Iterativer temperaturbezogener Weißabgleich Y lila ändern (maximal 1). +TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;Ermöglicht das Filtern von Magenta-/Lila-Daten aus dem Bild. Wenn das Kontrollkästchen aktiviert ist, wird ein Filter angewandt, der den Wert von Y begrenzt. Standardmäßig beträgt dieser Wert 0,4. Sie können es in 'Optionen' Iterativer temperaturbezogener Weißabgleich Y lila ändern (maximal 1). TP_WBALANCE_ITCWBPRECIS_TOOLTIP;Je niedriger der Wert, desto relevanter sind die Daten, aber desto länger dauert die Verarbeitung. Da die Verarbeitungszeit gering ist, sollte dieser Parameter grundsätzlich auf dem Standardwert bleiben können. TP_WBALANCE_ITCWBRGREEN_TOOLTIP;Legt die Amplitude der Grünwertüberprüfung in Iterationen fest, von der niedrigen Amplitude 0,82 bis 1,25 bis zur maximalen Amplitude 0,4 bis 4. TP_WBALANCE_ITCWBSIZEPATCH_TOOLTIP;Definiert die Anzahl der Farben die vom Algorithmus verwendet werden. @@ -4494,3 +4491,14 @@ ZOOMPANEL_ZOOMFITCROPSCREEN;Ausschnitt an Bildschirm anpassen.\nTaste: f ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen.\nTaste: Alt + f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!HISTORY_MSG_WBITC_SAMPLING;Low sampling +!PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) +!PREFERENCES_WBAPATCH;Number maximum of colors used in picture +!PREFERENCES_WBASIZEREF;Size of reference color compare to size of histogram color +!//TP_WBALANCE_ITCWBNOPURPLE_TOOLTIP;By default when "Inpaint opposed" is activated, purple colors are not taken into account. However, if the image does not need highlight reconstruction, or if this image naturally contains purple tints (flowers, etc.), it may be necessary to deactivate, to take into account all the colors. +!//TP_WBALANCE_ITCWB_FORCED;Forces use of the entire CIE diagram From 1096cc0898e128b4dddb72e2b27aaa0a3b429104 Mon Sep 17 00:00:00 2001 From: Richard E Barber Date: Sun, 11 Aug 2024 17:49:56 -0700 Subject: [PATCH 290/291] mac: CI/bundle update (#7166) * Merge mac package updates fix11 (#36) * Update macOS CI workflow Adds ad-hoc codesign directive, fixes launch test on arm64 * mac bundle: staple notary ticket to app * mac: draw version number on fancy dmg background * Delete tools/osx/rtdmg-bkgd.png * mac: hidpi compatible fancy dmg background image * mac: fix fancy dmg background * Mac: remove license file from fancy dmg root License displays properly in dmg EULA pop-up window. * mac CI: show build info in GITHUB_STEP_SUMMARY (#37) * mac CI: output step summaries * mac CI: add summary for test launch * test -cli on both builds * mac: remove an errant fullstop * mac CI: reorder test launches * mac CI: specify full path of app to test launch * mac CI: add missing file extension * mac CI: test running app in osascript (#38) * Simplifies launch test * macCI: use fancy dmg message to warn users that CI build not intended for user testing. * mac: draw optional user message on fancy dmg used by CI to display a user warning --- .github/workflows/macos.yml | 86 +++++++++++++++++++++++++----------- tools/osx/macosx_bundle.sh | 22 ++++----- tools/osx/rtdmg-bkgd.png | Bin 399285 -> 919229 bytes 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 824d87d1d..6f601d4e8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -18,20 +18,25 @@ jobs: build: runs-on: macos-12 steps: - - uses: actions/checkout@v4 + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-tags: '0' + fetch-depth: '0' - name: Install dependencies run: | date -u mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog + brew install imagemagick create-dmg libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring - zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Configure build system env: + IDENT: '-' CMAKE_CXX_STANDARD: 11 PKG_CONFIG_PATH: /usr/local/opt/libtiff/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig:/usr/local/opt/expat/lib/pkgconfig C_FLAGS: > @@ -47,12 +52,12 @@ jobs: cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libiconv/lib -L/usr/local/opt/libomp/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libffi/lib -L/usr/local/opt/libxml2/lib -L/usr/local/opt/expat/lib" \ + -DCMAKE_EXE_LINKER_FLAGS="-L. -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/opt/gdk-pixbuf/lib -L/usr/local/opt/libomp/lib -L/usr/local/opt/expat/lib" \ -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_VERSION}-${REF}" \ -DPROC_TARGET_NUMBER="1" \ -DPROC_LABEL="generic processor" \ -DCMAKE_OSX_ARCHITECTURES=$(uname -m) \ - -DWITH_LTO="OFF" \ + -DWITH_LTO="ON" \ -DLENSFUNDBDIR="/Applications/RawTherapee.app/Contents/Resources/share/lensfun" \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ @@ -67,28 +72,30 @@ jobs: -DCMAKE_RANLIB=/usr/bin/ranlib \ -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 \ -DCONTINUOUS=ON \ - -DCODESIGNID:STRING="-" \ + -DCODESIGNID:STRING="$IDENT" \ + -DFANCY_DMG="ON" \ .. - zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' + zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Compile RawTherapee run: | date -u && date +%s > build/compilestamp cd build export REF=${GITHUB_REF##*/} make -j$(sysctl -a | grep machdep.cpu.thread_count | tail -c 2) install - zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' + zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Create application bundle run: | zsh date +%s > build/bundlestamp && date -u && cd build - export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle + echo "Automated Build! WARNING:\nNot intended for end-user testing." > message + export REF=${GITHUB_REF##*/} && sudo make macosx_bundle export ARTIFACT=(RawTherapee*${CMAKE_BUILD_TYPE}.zip) echo "=== artifact: ${ARTIFACT}" # defining environment variables for next step as per # https://github.com/actions/starter-workflows/issues/68 echo "ARTIFACT_PATH=${GITHUB_WORKSPACE}/build/${ARTIFACT}" >> $GITHUB_ENV echo "ARTIFACT_FILE=${ARTIFACT}" >> $GITHUB_ENV - zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' + zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY printf '%s\n' \ "REF: ${REF}" \ "ARTIFACT: ${ARTIFACT}" \ @@ -103,15 +110,23 @@ jobs: - name: Finish build run: | date -u - zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY + - name: Test-launch the app run: | cd build sudo cp -R RawTherapee.app /Applications - open -a RawTherapee + open -a /Applications/RawTherapee.app sleep 5 - osascript -e 'tell application "Finder"' -e 'get the name of every process whose visible is true' -e 'end tell' + echo "Applications running: $(osascript -e 'tell application "Finder" to get the name of every process whose visible is true')" >> $GITHUB_STEP_SUMMARY + osascript -e 'if application "RawTherapee" is not running then do shell script "exit 1"' osascript -e 'tell application "RawTherapee" to if it is running then quit' + + - name: Test the -cli + run: | + cd build + echo "$(RawTherapee*folder/rawtherapee-cli --version)" >> $GITHUB_STEP_SUMMARY + - name: Publish artifacts uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} @@ -119,24 +134,30 @@ jobs: tag_name: nightly-github-actions files: | ${{env.ARTIFACT_PATH}} + armbuild: runs-on: macos-14 steps: - - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-tags: '0' + fetch-depth: '0' - name: Install dependencies run: | date -u mkdir build date +%s > build/stamp brew uninstall --ignore-dependencies libtiff - brew install libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog + brew install imagemagick create-dmg libtiff gtk+3 gtkmm3 gtk-mac-integration adwaita-icon-theme libsigc++@2 little-cms2 libiptcdata fftw lensfun expat pkgconfig llvm shared-mime-info exiv2 jpeg-xl libomp automake libtool | tee -a depslog date -u echo "----====Pourage====----" cat depslog | grep Pouring - zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + zsh -c 'echo "Completed installation of dependencies in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Configure build system env: + IDENT: '-' CMAKE_CXX_STANDARD: 11 PKG_CONFIG_PATH: /opt/homebrew/opt/libtiff/lib/pkgconfig:opt/homebrew/opt/libffi/lib/pkgconfig:/ope/homebrew/opt/expat/lib/pkgconfig C_FLAGS: > @@ -152,7 +173,7 @@ jobs: cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCMAKE_EXE_LINKER_FLAGS="-L. -L/opt/homebrew/lib -Wl,-rpath -Wl,/opt/homebrew/lib -L/opt/homebrew/opt/gdk-pixbuf/lib -L/opt/homebrew/opt/libiconv/lib -L/opt/homebrew/opt/libomp/lib -L/opt/homebrew/opt/libffi/lib -L/opt/homebrew/opt/libffi/lib -L/opt/homebrew/opt/libxml2/lib -L/opt/homebrew/opt/expat/lib" \ + -DCMAKE_EXE_LINKER_FLAGS="-L. -L/opt/homebrew/lib -Wl,-rpath -Wl,/opt/homebrew/lib -L/opt/homebrew/opt/gdk-pixbuf/lib -L/opt/homebrew/opt/libomp/lib -L/opt/homebrew/opt/expat/lib" \ -DCACHE_NAME_SUFFIX="${RAW_THERAPEE_VERSION}-${REF}" \ -DCMAKE_OSX_ARCHITECTURES=arm64 \ -DWITH_LTO="ON" \ @@ -170,28 +191,31 @@ jobs: -DCMAKE_RANLIB=/usr/bin/ranlib \ -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \ -DCONTINUOUS=ON \ - -DCODESIGNID:STRING="-" \ + -DCODESIGNID:STRING="$IDENT" \ + -DLOCAL_PREFIX=/opt/homebrew \ + -DFANCY_DMG="ON" \ .. - zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' + zsh -c 'echo "Configured in $(printf "%0.2f" $(($[$(date +%s)-$(cat configstamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Compile RawTherapee run: | date -u && date +%s > build/compilestamp cd build export REF=${GITHUB_REF##*/} make -j$(sysctl -a | grep machdep.cpu.thread_count | tail -c 2) install - zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' + zsh -c 'echo "Compiled in $(printf "%0.2f" $(($[$(date +%s)-$(cat compilestamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY - name: Create application bundle run: | zsh date +%s > build/bundlestamp && date -u && cd build - export REF=${GITHUB_REF##*/} && export LOCAL_PREFIX=/usr && sudo make macosx_bundle + echo "Automated Build! WARNING:\nNot intended for end-user testing." > message + export REF=${GITHUB_REF##*/} && sudo make macosx_bundle export ARTIFACT=(RawTherapee*${CMAKE_BUILD_TYPE}.zip) echo "=== artifact: ${ARTIFACT}" # defining environment variables for next step as per # https://github.com/actions/starter-workflows/issues/68 echo "ARTIFACT_PATH=${GITHUB_WORKSPACE}/build/${ARTIFACT}" >> $GITHUB_ENV echo "ARTIFACT_FILE=${ARTIFACT}" >> $GITHUB_ENV - zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' + zsh -c 'echo "Bundled in $(printf "%0.2f" $(($[$(date +%s)-$(cat bundlestamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY printf '%s\n' \ "REF: ${REF}" \ "ARTIFACT: ${ARTIFACT}" \ @@ -199,6 +223,7 @@ jobs: "ARTIFACT_FILE: ${ARTIFACT_FILE}" \ "PUBLISH_NAME: ${PUBLISH_NAME}" exit + - uses: actions/upload-artifact@v4 with: name: ${{env.ARTIFACT_FILE}} @@ -206,12 +231,23 @@ jobs: - name: Finish build run: | date -u - zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' + zsh -c 'echo "Build completed in $(printf "%0.2f" $(($[$(date +%s)-$(cat build/stamp)]/$((60.))))) minutes"' >> $GITHUB_STEP_SUMMARY + - name: Test-launch the app run: | - cd build + cd build sudo cp -R RawTherapee.app /Applications - time RawTherapee_*/rawtherapee-cli + open -a /Applications/RawTherapee.app + sleep 5 + echo "Applications running: $(osascript -e 'tell application "Finder" to get the name of every process whose visible is true')" >> $GITHUB_STEP_SUMMARY + osascript -e 'if application "RawTherapee" is not running then do shell script "exit 1"' + osascript -e 'tell application "RawTherapee" to if it is running then quit' + + - name: Test the -cli + run: | + cd build + echo "$(RawTherapee*folder/rawtherapee-cli --version)" >> $GITHUB_STEP_SUMMARY + - name: Publish artifacts uses: softprops/action-gh-release@v2 if: ${{github.ref_type == 'tag' || github.ref_name == 'dev'}} diff --git a/tools/osx/macosx_bundle.sh b/tools/osx/macosx_bundle.sh index aaceb27be..d6f460904 100644 --- a/tools/osx/macosx_bundle.sh +++ b/tools/osx/macosx_bundle.sh @@ -394,6 +394,7 @@ if [[ -n $NOTARY ]]; then ditto -c -k --sequesterRsrc --keepParent "${APP}" "${APP}.zip" echo "Uploading..." sudo xcrun notarytool submit "${APP}.zip" ${NOTARY} --wait + sudo xcrun stapler staple "${APP}" fi function CreateDmg { @@ -401,7 +402,6 @@ function CreateDmg { msg "Preparing disk image sources at ${srcDir}:" cp -R "${APP}" "${srcDir}" - cp "${RESOURCES}"/LICENSE "${srcDir}" ln -s /Applications "${srcDir}" # Web bookmarks @@ -427,21 +427,23 @@ function CreateDmg { msg "Creating disk image:" if [[ $FANCY_DMG == "ON" ]]; then echo "Building Fancy .dmg" + MESSAGE="$(cat message)" + magick ${PROJECT_SOURCE_DATA_DIR}/rtdmg-bkgd.png -pointsize 80 -fill Black -draw "text 14,1307 '${PROJECT_FULL_VERSION}'" -fill Salmon -draw "text 10,1300 '${PROJECT_FULL_VERSION}'" ./rtdmg-bkgd.png + magick ./rtdmg-bkgd.png -pointsize 90 -fill Black -gravity center -font Menlo-Bold -draw "text 5,120 \"$MESSAGE\"" -fill Red -gravity center -font Menlo-Bold -draw "text 1,124 \"$MESSAGE\"" ./rtdmg-bkgd.png create-dmg \ - --background ${PROJECT_SOURCE_DATA_DIR}/rtdmg-bkgd.png \ + --background ./rtdmg-bkgd.png \ --volname ${PROJECT_NAME}_${PROJECT_FULL_VERSION} \ --volicon ${PROJECT_SOURCE_DATA_DIR}/rtdmg.icns \ --window-pos 72 72 \ - --window-size 1000 689 \ + --window-size 1000 692 \ --text-size 16 \ --icon-size 80 \ - --icon LICENSE 810 0 \ - --icon RawTherapee.app 250 178 \ - --icon Applications 700 178 \ - --icon Website.webloc 300 423 \ - --icon Forum.webloc 420 423 \ - --icon Report\ Bug.webloc 540 423 \ - --icon Documentation.webloc 680 423 \ + --icon RawTherapee.app 250 238 \ + --icon Applications 700 238 \ + --icon Website.webloc 300 487 \ + --icon Forum.webloc 420 487 \ + --icon Report\ Bug.webloc 540 487 \ + --icon Documentation.webloc 680 487 \ --no-internet-enable \ --eula ${PROJECT_SOURCE_DATA_DIR}/../../LICENSE \ --hdiutil-verbose \ diff --git a/tools/osx/rtdmg-bkgd.png b/tools/osx/rtdmg-bkgd.png index 23d4342905dd9619bacab54e8a0763c5bc411794..88e441ff89998212e8337c0e3886670c6033b564 100644 GIT binary patch literal 919229 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 UNyNuT0Hc!5^0#)E1xxzr4alf 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

    =Yqqe$U@&NT>&v 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

    vmt4#eH+>?W9?sb)r|El0{$t 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%0De>fD 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 z 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%0Axhsg#UCc= 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 z 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ⓈuDbA7kQ^wvKA-4EaOFgO1!L{G%#b0M+vTL(K!-9 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 Date: Tue, 13 Aug 2024 07:43:17 +0200 Subject: [PATCH 291/291] Bad behavior with blackwhite and gamma - after change avoid color shift - issue 7159 (#7165) * Bad behavior with blackwhite and gamma - after change avoid color shift * Change with code Lawrence37 - chprov1 sincosval --- rtengine/improcfun.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 2e02a352c..79bd81c65 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4778,13 +4778,22 @@ void ImProcFunctions::chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, histLCurve[Lprov1 * histLFactor]++; } - Chprov1 = sqrt(SQR(atmp) + SQR(btmp)) / 327.68f; // labCurve.bwtoning option allows to decouple modulation of a & b curves by saturation // with bwtoning enabled the net effect of a & b curves is visible if (bwToning) { atmp -= lold->a[i][j]; btmp -= lold->b[i][j]; + Chprov1 = sqrt(SQR(atmp) + SQR(btmp)) / 327.68f; + if (Chprov1 == 0.f) { + sincosval.x = 0.f; + sincosval.y = 1.f; + } else { + sincosval.x = btmp / (327.68f * Chprov1); + sincosval.y = atmp / (327.68f * Chprov1); + } + } else { + Chprov1 = sqrt(SQR(atmp) + SQR(btmp)) / 327.68f; } lnew->L[i][j] = Lprov1 * 327.68f;